Unverified Commit 834291a7 authored by Kevin Di Lallo's avatar Kevin Di Lallo Committed by GitHub
Browse files

Merge pull request #305 from supermikii/my_sp37_mapcomponentui

Frontend client to sandbox controller API Applications & frontend UI
parents d32c652e 5da8bfa4
Loading
Loading
Loading
Loading
+23 −13
Original line number Diff line number Diff line
@@ -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
@@ -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>';
@@ -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);
@@ -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
  };
};

+67 −36
Original line number Diff line number Diff line
@@ -98,7 +98,9 @@ import {
  corePodsRunning,
  corePodsErrors,
  execVisFilteredData,
  execChangeReplayStatus
  execChangeReplayStatus,
  execChangeAppInstanceTable,
  execChangeMap
} from '../state/exec';

import {
@@ -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();
@@ -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();
            }
          }
        }
      },
@@ -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);
    });
  }

  /**
@@ -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)
    );
  }

@@ -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))
  };
};

+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;
  }
}
+4 −1
Original line number Diff line number Diff line
@@ -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';
@@ -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;

@@ -169,7 +171,8 @@ const execReducer = combineReducers({
  table: execTableReducer,
  selectedScenarioElement: execSelectedScenarioElement,
  apiResults: execApiResultsReducer,
  elementConfiguration: execElementConfigurationReducer
  elementConfiguration: execElementConfigurationReducer,
  appInstanceTable: appInstanceTableReducer 
});

export default execReducer;