Loading js-apps/meep-frontend/src/js/containers/idc-map.js +23 −13 Original line number Diff line number Diff line Loading @@ -23,6 +23,7 @@ import 'mapbox-gl-leaflet'; import '@geoman-io/leaflet-geoman-free'; import deepEqual from 'deep-equal'; import tinycolor from 'tinycolor2'; import _ from 'lodash'; import { updateObject, deepCopy Loading Loading @@ -660,18 +661,24 @@ class IDCMap extends Component { // UE Marker Event Handler updateComputePopup(marker) { if (marker) { var latlng = marker.getLatLng(); var table = this.getTable(); var services = []; for (var i in table.entries) { if (table.entries[i].parent.val === marker.options.meep.compute.id) { services.push(table.entries[i].name.val); } } if (marker && table && table.entries) { // Retrieve state const networkName = getElemFieldVal(table.entries[marker.options.meep.compute.id], FIELD_DN_NAME); const edgeProvider = getElemFieldVal(table.entries[marker.options.meep.compute.id], FIELD_DN_ECSP); const ladn = getElemFieldVal(table.entries[marker.options.meep.compute.id], FIELD_DN_LADN); var appInstanceTable = this.props.appInstanceTable; var latlng = marker.getLatLng(); // Parse mec application state on current popup var appInstances = []; for (var i = 0; i < appInstanceTable.length ; i++) { if (appInstanceTable[i].mepName === marker.options.meep.compute.id) { appInstances.push(appInstanceTable[i]); } } // Sort parsed array of mec app var sortedAppInstances = _.sortBy(appInstances, ['name']); // Modify render message var msg = '<b>id: ' + marker.options.meep.compute.id + '</b><br>'; if (edgeProvider) { msg += 'service-provider: ' + edgeProvider + '<br>'; Loading @@ -683,9 +690,11 @@ class IDCMap extends Component { } msg += '<br>'; } if (services) { var serviceString = services.join(', '); msg += 'running-services: ' + serviceString + '<br>'; msg += 'applications: <br>'; if (appInstances) { sortedAppInstances.forEach(elem => { msg += '<li>' + elem.name + ' ' + '(id: ' + elem.id.substring(0,6) + '...' + elem.id.substring(elem.id.length - 6,elem.id.length + 1) + ')' + '<br>'; }); } msg += 'location: ' + this.getLocationStr(latlng); marker.getPopup().setContent(msg); Loading Loading @@ -1322,7 +1331,8 @@ const mapStateToProps = state => { execTable: state.exec.table, configuredElement: state.cfg.elementConfiguration.configuredElement, cfgView: state.ui.cfgView, cfgScenarioName: state.cfg.scenario.name cfgScenarioName: state.cfg.scenario.name, appInstanceTable: state.exec.appInstanceTable.data }; }; Loading js-apps/meep-frontend/src/js/containers/meep-container.js +67 −36 Original line number Diff line number Diff line Loading @@ -98,7 +98,9 @@ import { corePodsRunning, corePodsErrors, execVisFilteredData, execChangeReplayStatus execChangeReplayStatus, execChangeAppInstanceTable, execChangeMap } from '../state/exec'; import { Loading Loading @@ -141,6 +143,7 @@ class MeepContainer extends Component { this.replayStatusRefreshIntervalTimer = null; this.meepScenarioConfigurationApi = new meepPlatformCtrlRestApiClient.ScenarioConfigurationApi(); this.meepSandboxControlApi = new meepPlatformCtrlRestApiClient.SandboxControlApi(); this.meepAppInfoApi = new meepSandboxCtrlRestApiClient.ApplicationsApi(); this.meepActiveScenarioApi = new meepSandboxCtrlRestApiClient.ActiveScenarioApi(); this.meepEventsApi = new meepSandboxCtrlRestApiClient.EventsApi(); this.meepEventReplayApi = new meepSandboxCtrlRestApiClient.EventReplayApi(); Loading Loading @@ -235,6 +238,10 @@ class MeepContainer extends Component { this.refreshPduSessions(); this.refreshScenario(); this.refreshMap(); // Only update while scenario is running if (this.props.execScenarioState === 'DEPLOYED') { this.refreshAppInstancesTable(); } } } }, Loading Loading @@ -550,35 +557,31 @@ class MeepContainer extends Component { } /** * Callback function to receive the result of the getAssetData operation. * @callback module:api/GeospatialDataApi~getAssetDataCallback * Callback function to receive the result of the postHttpQuery operation. * @callback module:api/AppsApi~applicationsGET * @param {String} error Error message, if any. * @param {module:model/GeoDataAssetList} data The data returned by the service call. * @param {module:model/ApplicationInfo} data The data returned by the service call. * @param {String} response The complete HTTP response. */ getUeAssetDataCb(error, data) { getAppInstancesCb(error, data) { if (error !== null) { this.props.changeAppInstanceTable([]); return; } // Update UE list this.props.execChangeMapUeList(data.geoDataAssets ? _.sortBy(data.geoDataAssets, ['assetName']) : []); // Update App Instance table only if data is different var appInstances = data ? data : []; const isArrayEqual = (x, y) => _.isEmpty(_.xorWith(x, y, _.isEqual)); if (!isArrayEqual(this.props.appInstanceTable,appInstances)) { this.props.changeAppInstanceTable(appInstances); } /** * Callback function to receive the result of the getAssetData operation. * @callback module:api/GeospatialDataApi~getAssetDataCallback * @param {String} error Error message, if any. * @param {module:model/GeoDataAssetList} data The data returned by the service call. * @param {String} response The complete HTTP response. */ getPoaAssetDataCb(error, data) { if (error !== null) { return; } // Update POA list this.props.execChangeMapPoaList(data.geoDataAssets ? _.sortBy(data.geoDataAssets, ['assetName']) : []); // Refresh App Instances refreshAppInstancesTable() { this.meepAppInfoApi.applicationsGET(null, (error, data, response) => { this.getAppInstancesCb(error, data, response); }); } /** Loading @@ -588,25 +591,51 @@ class MeepContainer extends Component { * @param {module:model/GeoDataAssetList} data The data returned by the service call. * @param {String} response The complete HTTP response. */ getComputeAssetDataCb(error, data) { getAssetDataCb(error, data) { if (error !== null) { return; } // Update Compute list this.props.execChangeMapComputeList(data.geoDataAssets ? _.sortBy(data.geoDataAssets, ['assetName']) : []); var ueList = []; var poaList = []; var computeList = []; // Extract assets by type if (data.geoDataAssets) { _.forEach(data.geoDataAssets, asset => { switch (asset.assetType) { case 'UE': ueList.push(asset); break; case 'POA': poaList.push(asset); break; case 'COMPUTE': computeList.push(asset); break; default: break; } }); } // Update asset map var assetMap = { ueList: _.sortBy(ueList, ['assetName']), poaList: _.sortBy(poaList, ['assetName']), computeList: _.sortBy(computeList, ['assetName']) }; //Update UE LIST, COMPUTE LIST, POA list this.props.execChangeMap(assetMap); } // Refresh Map refreshMap() { this.meepGeoDataApi.getAssetData({assetType: 'UE'}, (error, data) => this.getUeAssetDataCb(error, data) ); this.meepGeoDataApi.getAssetData({assetType: 'POA'}, (error, data) => this.getPoaAssetDataCb(error, data) ); this.meepGeoDataApi.getAssetData({assetType: 'COMPUTE'}, (error, data) => this.getComputeAssetDataCb(error, data) this.meepGeoDataApi.getAssetData({}, (error, data) => this.getAssetDataCb(error, data) ); } Loading Loading @@ -926,13 +955,15 @@ const mapDispatchToProps = dispatch => { execChangeMapUeList: list => dispatch(execChangeMapUeList(list)), execChangeMapPoaList: list => dispatch(execChangeMapPoaList(list)), execChangeMapComputeList: list => dispatch(execChangeMapComputeList(list)), execChangeMap: list => dispatch(execChangeMap(list)), cfgChangeMap: map => dispatch(cfgChangeMap(map)), cfgChangeVisData: data => dispatch(cfgChangeVisData(data)), cfgChangeTable: data => dispatch(cfgChangeTable(data)), execChangeOkToTerminate: ok => dispatch(execChangeOkToTerminate(ok)), changeSignInStatus: status => dispatch(uiChangeSignInStatus(status)), changeSignInUsername: name => dispatch(uiChangeSignInUsername(name)), changeTabIndex: index => dispatch(uiChangeCurrentTab(index)) changeTabIndex: index => dispatch(uiChangeCurrentTab(index)), changeAppInstanceTable: value => dispatch(execChangeAppInstanceTable(value)) }; }; Loading js-apps/meep-frontend/src/js/state/exec/app-instance-table-reducer.js 0 → 100644 +39 −0 Original line number Diff line number Diff line /* * Copyright (c) 2021 InterDigital Communications, Inc * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ import { updateObject } from '../../util/object-util'; const initialState = { data: [] }; // ECEC_UPDATE_APP const EXEC_CHANGE_APP_INSTANCE_TABLE = 'EXEC_CHANGE_APP_INSTANCE_TABLE'; export function execChangeAppInstanceTable(data) { return { type: EXEC_CHANGE_APP_INSTANCE_TABLE, payload: data }; } export function appInstanceTableReducer(state = initialState, action) { switch (action.type) { case EXEC_CHANGE_APP_INSTANCE_TABLE: return updateObject(state, { data: action.payload }); default: return state; } } js-apps/meep-frontend/src/js/state/exec/index.js +4 −1 Original line number Diff line number Diff line Loading @@ -20,6 +20,7 @@ import { createSelector } from 'reselect'; import { typeReducer } from './type-reducer'; import { stateReducer } from './state-reducer'; import { appInstanceTableReducer} from './app-instance-table-reducer'; import { scenarioReducer } from './scenario-reducer'; import { displayedScenarioReducer } from './displayed-scenario-reducer'; import { execMapReducer } from './map-reducer'; Loading Loading @@ -58,6 +59,7 @@ export * from './table-reducer'; export * from './selected-scenario-element'; export * from './api-results'; export * from './element-configuration'; export * from './app-instance-table-reducer'; const execTableElements = state => state.exec.table.entries; Loading Loading @@ -169,7 +171,8 @@ const execReducer = combineReducers({ table: execTableReducer, selectedScenarioElement: execSelectedScenarioElement, apiResults: execApiResultsReducer, elementConfiguration: execElementConfigurationReducer elementConfiguration: execElementConfigurationReducer, appInstanceTable: appInstanceTableReducer }); export default execReducer; Loading
js-apps/meep-frontend/src/js/containers/idc-map.js +23 −13 Original line number Diff line number Diff line Loading @@ -23,6 +23,7 @@ import 'mapbox-gl-leaflet'; import '@geoman-io/leaflet-geoman-free'; import deepEqual from 'deep-equal'; import tinycolor from 'tinycolor2'; import _ from 'lodash'; import { updateObject, deepCopy Loading Loading @@ -660,18 +661,24 @@ class IDCMap extends Component { // UE Marker Event Handler updateComputePopup(marker) { if (marker) { var latlng = marker.getLatLng(); var table = this.getTable(); var services = []; for (var i in table.entries) { if (table.entries[i].parent.val === marker.options.meep.compute.id) { services.push(table.entries[i].name.val); } } if (marker && table && table.entries) { // Retrieve state const networkName = getElemFieldVal(table.entries[marker.options.meep.compute.id], FIELD_DN_NAME); const edgeProvider = getElemFieldVal(table.entries[marker.options.meep.compute.id], FIELD_DN_ECSP); const ladn = getElemFieldVal(table.entries[marker.options.meep.compute.id], FIELD_DN_LADN); var appInstanceTable = this.props.appInstanceTable; var latlng = marker.getLatLng(); // Parse mec application state on current popup var appInstances = []; for (var i = 0; i < appInstanceTable.length ; i++) { if (appInstanceTable[i].mepName === marker.options.meep.compute.id) { appInstances.push(appInstanceTable[i]); } } // Sort parsed array of mec app var sortedAppInstances = _.sortBy(appInstances, ['name']); // Modify render message var msg = '<b>id: ' + marker.options.meep.compute.id + '</b><br>'; if (edgeProvider) { msg += 'service-provider: ' + edgeProvider + '<br>'; Loading @@ -683,9 +690,11 @@ class IDCMap extends Component { } msg += '<br>'; } if (services) { var serviceString = services.join(', '); msg += 'running-services: ' + serviceString + '<br>'; msg += 'applications: <br>'; if (appInstances) { sortedAppInstances.forEach(elem => { msg += '<li>' + elem.name + ' ' + '(id: ' + elem.id.substring(0,6) + '...' + elem.id.substring(elem.id.length - 6,elem.id.length + 1) + ')' + '<br>'; }); } msg += 'location: ' + this.getLocationStr(latlng); marker.getPopup().setContent(msg); Loading Loading @@ -1322,7 +1331,8 @@ const mapStateToProps = state => { execTable: state.exec.table, configuredElement: state.cfg.elementConfiguration.configuredElement, cfgView: state.ui.cfgView, cfgScenarioName: state.cfg.scenario.name cfgScenarioName: state.cfg.scenario.name, appInstanceTable: state.exec.appInstanceTable.data }; }; Loading
js-apps/meep-frontend/src/js/containers/meep-container.js +67 −36 Original line number Diff line number Diff line Loading @@ -98,7 +98,9 @@ import { corePodsRunning, corePodsErrors, execVisFilteredData, execChangeReplayStatus execChangeReplayStatus, execChangeAppInstanceTable, execChangeMap } from '../state/exec'; import { Loading Loading @@ -141,6 +143,7 @@ class MeepContainer extends Component { this.replayStatusRefreshIntervalTimer = null; this.meepScenarioConfigurationApi = new meepPlatformCtrlRestApiClient.ScenarioConfigurationApi(); this.meepSandboxControlApi = new meepPlatformCtrlRestApiClient.SandboxControlApi(); this.meepAppInfoApi = new meepSandboxCtrlRestApiClient.ApplicationsApi(); this.meepActiveScenarioApi = new meepSandboxCtrlRestApiClient.ActiveScenarioApi(); this.meepEventsApi = new meepSandboxCtrlRestApiClient.EventsApi(); this.meepEventReplayApi = new meepSandboxCtrlRestApiClient.EventReplayApi(); Loading Loading @@ -235,6 +238,10 @@ class MeepContainer extends Component { this.refreshPduSessions(); this.refreshScenario(); this.refreshMap(); // Only update while scenario is running if (this.props.execScenarioState === 'DEPLOYED') { this.refreshAppInstancesTable(); } } } }, Loading Loading @@ -550,35 +557,31 @@ class MeepContainer extends Component { } /** * Callback function to receive the result of the getAssetData operation. * @callback module:api/GeospatialDataApi~getAssetDataCallback * Callback function to receive the result of the postHttpQuery operation. * @callback module:api/AppsApi~applicationsGET * @param {String} error Error message, if any. * @param {module:model/GeoDataAssetList} data The data returned by the service call. * @param {module:model/ApplicationInfo} data The data returned by the service call. * @param {String} response The complete HTTP response. */ getUeAssetDataCb(error, data) { getAppInstancesCb(error, data) { if (error !== null) { this.props.changeAppInstanceTable([]); return; } // Update UE list this.props.execChangeMapUeList(data.geoDataAssets ? _.sortBy(data.geoDataAssets, ['assetName']) : []); // Update App Instance table only if data is different var appInstances = data ? data : []; const isArrayEqual = (x, y) => _.isEmpty(_.xorWith(x, y, _.isEqual)); if (!isArrayEqual(this.props.appInstanceTable,appInstances)) { this.props.changeAppInstanceTable(appInstances); } /** * Callback function to receive the result of the getAssetData operation. * @callback module:api/GeospatialDataApi~getAssetDataCallback * @param {String} error Error message, if any. * @param {module:model/GeoDataAssetList} data The data returned by the service call. * @param {String} response The complete HTTP response. */ getPoaAssetDataCb(error, data) { if (error !== null) { return; } // Update POA list this.props.execChangeMapPoaList(data.geoDataAssets ? _.sortBy(data.geoDataAssets, ['assetName']) : []); // Refresh App Instances refreshAppInstancesTable() { this.meepAppInfoApi.applicationsGET(null, (error, data, response) => { this.getAppInstancesCb(error, data, response); }); } /** Loading @@ -588,25 +591,51 @@ class MeepContainer extends Component { * @param {module:model/GeoDataAssetList} data The data returned by the service call. * @param {String} response The complete HTTP response. */ getComputeAssetDataCb(error, data) { getAssetDataCb(error, data) { if (error !== null) { return; } // Update Compute list this.props.execChangeMapComputeList(data.geoDataAssets ? _.sortBy(data.geoDataAssets, ['assetName']) : []); var ueList = []; var poaList = []; var computeList = []; // Extract assets by type if (data.geoDataAssets) { _.forEach(data.geoDataAssets, asset => { switch (asset.assetType) { case 'UE': ueList.push(asset); break; case 'POA': poaList.push(asset); break; case 'COMPUTE': computeList.push(asset); break; default: break; } }); } // Update asset map var assetMap = { ueList: _.sortBy(ueList, ['assetName']), poaList: _.sortBy(poaList, ['assetName']), computeList: _.sortBy(computeList, ['assetName']) }; //Update UE LIST, COMPUTE LIST, POA list this.props.execChangeMap(assetMap); } // Refresh Map refreshMap() { this.meepGeoDataApi.getAssetData({assetType: 'UE'}, (error, data) => this.getUeAssetDataCb(error, data) ); this.meepGeoDataApi.getAssetData({assetType: 'POA'}, (error, data) => this.getPoaAssetDataCb(error, data) ); this.meepGeoDataApi.getAssetData({assetType: 'COMPUTE'}, (error, data) => this.getComputeAssetDataCb(error, data) this.meepGeoDataApi.getAssetData({}, (error, data) => this.getAssetDataCb(error, data) ); } Loading Loading @@ -926,13 +955,15 @@ const mapDispatchToProps = dispatch => { execChangeMapUeList: list => dispatch(execChangeMapUeList(list)), execChangeMapPoaList: list => dispatch(execChangeMapPoaList(list)), execChangeMapComputeList: list => dispatch(execChangeMapComputeList(list)), execChangeMap: list => dispatch(execChangeMap(list)), cfgChangeMap: map => dispatch(cfgChangeMap(map)), cfgChangeVisData: data => dispatch(cfgChangeVisData(data)), cfgChangeTable: data => dispatch(cfgChangeTable(data)), execChangeOkToTerminate: ok => dispatch(execChangeOkToTerminate(ok)), changeSignInStatus: status => dispatch(uiChangeSignInStatus(status)), changeSignInUsername: name => dispatch(uiChangeSignInUsername(name)), changeTabIndex: index => dispatch(uiChangeCurrentTab(index)) changeTabIndex: index => dispatch(uiChangeCurrentTab(index)), changeAppInstanceTable: value => dispatch(execChangeAppInstanceTable(value)) }; }; Loading
js-apps/meep-frontend/src/js/state/exec/app-instance-table-reducer.js 0 → 100644 +39 −0 Original line number Diff line number Diff line /* * Copyright (c) 2021 InterDigital Communications, Inc * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ import { updateObject } from '../../util/object-util'; const initialState = { data: [] }; // ECEC_UPDATE_APP const EXEC_CHANGE_APP_INSTANCE_TABLE = 'EXEC_CHANGE_APP_INSTANCE_TABLE'; export function execChangeAppInstanceTable(data) { return { type: EXEC_CHANGE_APP_INSTANCE_TABLE, payload: data }; } export function appInstanceTableReducer(state = initialState, action) { switch (action.type) { case EXEC_CHANGE_APP_INSTANCE_TABLE: return updateObject(state, { data: action.payload }); default: return state; } }
js-apps/meep-frontend/src/js/state/exec/index.js +4 −1 Original line number Diff line number Diff line Loading @@ -20,6 +20,7 @@ import { createSelector } from 'reselect'; import { typeReducer } from './type-reducer'; import { stateReducer } from './state-reducer'; import { appInstanceTableReducer} from './app-instance-table-reducer'; import { scenarioReducer } from './scenario-reducer'; import { displayedScenarioReducer } from './displayed-scenario-reducer'; import { execMapReducer } from './map-reducer'; Loading Loading @@ -58,6 +59,7 @@ export * from './table-reducer'; export * from './selected-scenario-element'; export * from './api-results'; export * from './element-configuration'; export * from './app-instance-table-reducer'; const execTableElements = state => state.exec.table.entries; Loading Loading @@ -169,7 +171,8 @@ const execReducer = combineReducers({ table: execTableReducer, selectedScenarioElement: execSelectedScenarioElement, apiResults: execApiResultsReducer, elementConfiguration: execElementConfigurationReducer elementConfiguration: execElementConfigurationReducer, appInstanceTable: appInstanceTableReducer }); export default execReducer;