Просмотр исходного кода

Merge pull request #281 from smiclea/network-info

Remove references to API's migration 'info' field
Dorin Paslaru 7 лет назад
Родитель
Сommit
bcb979b431

+ 16 - 10
src/components/organisms/MainDetails/MainDetails.jsx

@@ -25,6 +25,7 @@ import StatusImage from '../../atoms/StatusImage'
 import Table from '../../molecules/Table'
 import CopyMultilineValue from '../../atoms/CopyMultilineValue'
 
+import type { Instance } from '../../../types/Instance'
 import type { MainItem } from '../../../types/MainItem'
 import type { Endpoint } from '../../../types/Endpoint'
 import StyleProps from '../../styleUtils/StyleProps'
@@ -113,6 +114,8 @@ const PropertyValue = styled.div`
 
 type Props = {
   item: ?MainItem,
+  instancesDetails: Instance[],
+  instancesDetailsLoading: boolean,
   endpoints: Endpoint[],
   bottomControls: React.Node,
   loading: boolean,
@@ -138,19 +141,22 @@ class MainDetails extends React.Component<Props> {
   }
 
   getConnectedVms(networkId: string) {
-    let vms = []
+    if (this.props.instancesDetailsLoading) {
+      return 'Loading...'
+    }
+
     if (!this.props.item) {
       return '-'
     }
-    Object.keys(this.props.item.info).forEach(key => {
-      // $FlowIssue
-      let instance = this.props.item.info[key]
-      if (instance.export_info && instance.export_info.devices.nics.length) {
-        instance.export_info.devices.nics.forEach(nic => {
-          if (nic.network_name === networkId) {
-            vms.push(key)
-          }
-        })
+
+    let vms: string[] = []
+
+    this.props.instancesDetails.forEach(instanceDet => {
+      if (
+        instanceDet.devices && instanceDet.devices.nics && instanceDet.devices.nics.find &&
+        instanceDet.devices.nics.find(n => n.network_name === networkId)
+      ) {
+        vms.push(instanceDet.instance_name)
       }
     })
 

+ 13 - 7
src/components/organisms/MainDetails/test.jsx

@@ -34,15 +34,21 @@ let item = {
   destination_endpoint_id: 'endpoint-2',
   id: 'item-id',
   created_at: new Date(2017, 10, 24, 16, 15),
-  info: { instance: { export_info: { devices: { nics: [{ network_name: 'map_1' }] } } } },
+  instances: ['instance_1'],
   destination_environment: {
     description: 'A description',
     network_map: {
-      map_1: 'Mapping 1',
+      network_1: 'Mapping 1',
     },
   },
   type: 'Replica',
 }
+let instancesDetails = [
+  {
+    instance_name: 'instance_1',
+    devices: { nics: [{ network_name: 'network_1' }] },
+  },
+]
 
 describe('MainDetails Component', () => {
   it('renders with endpoint missing', () => {
@@ -52,7 +58,7 @@ describe('MainDetails Component', () => {
   })
 
   it('renders endpoint info', () => {
-    let wrapper = wrap({ item, endpoints })
+    let wrapper = wrap({ item, endpoints, instancesDetails })
     expect(wrapper.find('id').prop('value')).toBe('item-id')
     const localDate = moment(item.created_at).add(-new Date().getTimezoneOffset(), 'minutes')
     expect(wrapper.find('created').prop('value')).toBe(localDate.format('YYYY-MM-DD HH:mm:ss'))
@@ -62,18 +68,18 @@ describe('MainDetails Component', () => {
   })
 
   it('renders endpoints logos', () => {
-    let wrapper = wrap({ item, endpoints })
+    let wrapper = wrap({ item, endpoints, instancesDetails })
     expect(wrapper.find('sourceLogo').prop('endpoint')).toBe('openstack')
     expect(wrapper.find('targetLogo').prop('endpoint')).toBe('azure')
   })
 
   it('renders network_map', () => {
-    let wrapper = wrap({ item, endpoints })
+    let wrapper = wrap({ item, endpoints, instancesDetails })
     let tableItems = wrapper.find('networksTable').prop('items')
     expect(tableItems.length).toBe(1)
     expect(tableItems[0].length).toBe(4)
-    expect(tableItems[0][0]).toBe('map_1')
-    expect(tableItems[0][1][0]).toBe('instance')
+    expect(tableItems[0][0]).toBe('network_1')
+    expect(tableItems[0][1][0]).toBe('instance_1')
     expect(tableItems[0][2]).toBe('Mapping 1')
     expect(tableItems[0][3]).toBe('Existing network')
     expect(wrapper.find('loading').length).toBe(0)

+ 5 - 0
src/components/organisms/MigrationDetailsContent/MigrationDetailsContent.jsx

@@ -24,6 +24,7 @@ import MainDetails from '../../organisms/MainDetails'
 import Tasks from '../../organisms/Tasks'
 import StyleProps from '../../styleUtils/StyleProps'
 
+import type { Instance } from '../../../types/Instance'
 import type { MainItem } from '../../../types/MainItem'
 import type { Endpoint } from '../../../types/Endpoint'
 
@@ -54,6 +55,8 @@ const NavigationItems = [
 type Props = {
   item: ?MainItem,
   detailsLoading: boolean,
+  instancesDetails: Instance[],
+  instancesDetailsLoading: boolean,
   endpoints: Endpoint[],
   page: string,
   onDeleteMigrationClick: () => void,
@@ -80,6 +83,8 @@ class MigrationDetailsContent extends React.Component<Props> {
     return (
       <MainDetails
         item={this.props.item}
+        instancesDetails={this.props.instancesDetails}
+        instancesDetailsLoading={this.props.instancesDetailsLoading}
         endpoints={this.props.endpoints}
         bottomControls={this.renderBottomControls()}
         loading={this.props.detailsLoading}

+ 5 - 0
src/components/organisms/ReplicaDetailsContent/ReplicaDetailsContent.jsx

@@ -24,6 +24,7 @@ import DetailsNavigation from '../../molecules/DetailsNavigation'
 import MainDetails from '../../organisms/MainDetails'
 import Executions from '../../organisms/Executions'
 import Schedule from '../../organisms/Schedule'
+import type { Instance } from '../../../types/Instance'
 import type { MainItem } from '../../../types/MainItem'
 import type { Endpoint } from '../../../types/Endpoint'
 import type { Execution } from '../../../types/Execution'
@@ -71,6 +72,8 @@ type TimezoneValue = 'utc' | 'local'
 type Props = {
   item: ?MainItem,
   endpoints: Endpoint[],
+  instancesDetails: Instance[],
+  instancesDetailsLoading: boolean,
   scheduleStore: typeof scheduleStore,
   page: string,
   detailsLoading: boolean,
@@ -154,6 +157,8 @@ class ReplicaDetailsContent extends React.Component<Props, State> {
     return (
       <MainDetails
         item={this.props.item}
+        instancesDetails={this.props.instancesDetails}
+        instancesDetailsLoading={this.props.instancesDetailsLoading}
         loading={this.props.detailsLoading}
         endpoints={this.props.endpoints}
         bottomControls={this.renderBottomControls()}

+ 18 - 4
src/components/pages/MigrationDetailsPage/MigrationDetailsPage.jsx

@@ -28,6 +28,7 @@ import migrationStore from '../../../stores/MigrationStore'
 import userStore from '../../../stores/UserStore'
 import endpointStore from '../../../stores/EndpointStore'
 import notificationStore from '../../../stores/NotificationStore'
+import instanceStore from '../../../stores/InstanceStore'
 import { requestPollTimeout } from '../../../config'
 
 import migrationImage from './images/migration.svg'
@@ -54,13 +55,13 @@ class MigrationDetailsPage extends React.Component<Props, State> {
     document.title = 'Migration Details'
 
     endpointStore.getEndpoints()
-    this.pollData(true)
+    this.loadMigrationWithInstances()
     this.pollInterval = setInterval(() => { this.pollData() }, requestPollTimeout)
   }
 
   componentWillReceiveProps(newProps: any) {
     if (newProps.match.params.id !== this.props.match.params.id) {
-      migrationStore.getMigration(newProps.match.params.id, true)
+      this.loadMigrationWithInstances()
     }
   }
 
@@ -69,6 +70,17 @@ class MigrationDetailsPage extends React.Component<Props, State> {
     clearInterval(this.pollInterval)
   }
 
+  loadMigrationWithInstances() {
+    migrationStore.getMigration(this.props.match.params.id, true).then(() => {
+      if (migrationStore.migrationDetails) {
+        instanceStore.loadInstancesDetails(
+          migrationStore.migrationDetails.origin_endpoint_id,
+          // $FlowIgnore
+          migrationStore.migrationDetails.instances.map(n => { return { instance_name: n } }))
+      }
+    })
+  }
+
   handleUserItemClick(item: { value: string }) {
     switch (item.value) {
       case 'signout':
@@ -123,8 +135,8 @@ class MigrationDetailsPage extends React.Component<Props, State> {
     })
   }
 
-  pollData(showLoading?: boolean) {
-    migrationStore.getMigration(this.props.match.params.id, showLoading || false)
+  pollData() {
+    migrationStore.getMigration(this.props.match.params.id, false)
   }
 
   render() {
@@ -144,6 +156,8 @@ class MigrationDetailsPage extends React.Component<Props, State> {
           />}
           contentComponent={<MigrationDetailsContent
             item={migrationStore.migrationDetails}
+            instancesDetails={instanceStore.instancesDetails}
+            instancesDetailsLoading={instanceStore.loadingInstancesDetails}
             endpoints={endpointStore.endpoints}
             page={this.props.match.params.page || ''}
             detailsLoading={endpointStore.loading || migrationStore.detailsLoading}

+ 16 - 2
src/components/pages/ReplicaDetailsPage/ReplicaDetailsPage.jsx

@@ -36,6 +36,7 @@ import migrationStore from '../../../stores/MigrationStore'
 import userStore from '../../../stores/UserStore'
 import endpointStore from '../../../stores/EndpointStore'
 import scheduleStore from '../../../stores/ScheduleStore'
+import instanceStore from '../../../stores/InstanceStore'
 import { requestPollTimeout } from '../../../config'
 
 import replicaImage from './images/replica.svg'
@@ -71,7 +72,7 @@ class ReplicaDetailsPage extends React.Component<Props, State> {
   componentDidMount() {
     document.title = 'Replica Details'
 
-    replicaStore.getReplica(this.props.match.params.id)
+    this.loadReplicaWithInstances()
     endpointStore.getEndpoints()
     scheduleStore.getSchedules(this.props.match.params.id)
     this.pollData(true)
@@ -79,7 +80,7 @@ class ReplicaDetailsPage extends React.Component<Props, State> {
 
   componentWillReceiveProps(newProps: any) {
     if (newProps.match.params.id !== this.props.match.params.id) {
-      replicaStore.getReplica(newProps.match.params.id)
+      this.loadReplicaWithInstances()
       scheduleStore.getSchedules(newProps.match.params.id)
     }
   }
@@ -90,6 +91,17 @@ class ReplicaDetailsPage extends React.Component<Props, State> {
     clearTimeout(this.pollTimeout)
   }
 
+  loadReplicaWithInstances() {
+    replicaStore.getReplica(this.props.match.params.id).then(() => {
+      if (replicaStore.replicaDetails) {
+        instanceStore.loadInstancesDetails(
+          replicaStore.replicaDetails.origin_endpoint_id,
+          // $FlowIgnore
+          replicaStore.replicaDetails.instances.map(n => { return { instance_name: n } }))
+      }
+    })
+  }
+
   isActionButtonDisabled() {
     let originEndpoint = endpointStore.endpoints.find(e => replicaStore.replicaDetails && e.id === replicaStore.replicaDetails.origin_endpoint_id)
     let targetEndpoint = endpointStore.endpoints.find(e => replicaStore.replicaDetails && e.id === replicaStore.replicaDetails.destination_endpoint_id)
@@ -264,6 +276,8 @@ class ReplicaDetailsPage extends React.Component<Props, State> {
           />}
           contentComponent={<ReplicaDetailsContent
             item={replicaStore.replicaDetails}
+            instancesDetails={instanceStore.instancesDetails}
+            instancesDetailsLoading={instanceStore.loadingInstancesDetails}
             endpoints={endpointStore.endpoints}
             scheduleStore={scheduleStore}
             detailsLoading={replicaStore.detailsLoading || endpointStore.loading}

+ 5 - 3
src/stores/InstanceStore.js

@@ -165,7 +165,7 @@ class InstanceStore {
     InstanceSource.cancelInstancesDetailsRequests(this.reqId - 1)
 
     instancesInfo.sort((a, b) => a.instance_name.localeCompare(b.instance_name))
-    let hash = i => `${i.instance_name}-${i.id}`
+    let hash = i => `${i.instance_name}-${i.id || endpointId}`
     if (this.instancesDetails.map(hash).join('_') === instancesInfo.map(hash).join('_')) {
       return Promise.resolve()
     }
@@ -202,11 +202,13 @@ class InstanceStore {
             resolve()
           }
         }).catch((resp?: { reqId: number }) => {
+          this.instancesDetailsRemaining -= 1
+          this.loadingInstancesDetails = this.instancesDetailsRemaining > 0
+
           if (!resp || resp.reqId !== this.reqId) {
             return
           }
-          this.instancesDetailsRemaining -= 1
-          this.loadingInstancesDetails = this.instancesDetailsRemaining > 0
+
           if (count === 0) {
             resolve()
           }