aboutsummaryrefslogtreecommitdiffstats
path: root/sdnr/wt/odlux/apps/connectApp
diff options
context:
space:
mode:
Diffstat (limited to 'sdnr/wt/odlux/apps/connectApp')
-rw-r--r--sdnr/wt/odlux/apps/connectApp/package.json26
-rw-r--r--sdnr/wt/odlux/apps/connectApp/pom.xml56
-rw-r--r--sdnr/wt/odlux/apps/connectApp/src/actions/commonNetworkElementsActions.ts113
-rw-r--r--sdnr/wt/odlux/apps/connectApp/src/actions/infoNetworkElementActions.ts57
-rw-r--r--sdnr/wt/odlux/apps/connectApp/src/actions/mountedNetworkElementsActions.ts106
-rw-r--r--sdnr/wt/odlux/apps/connectApp/src/actions/networkElementsActions.ts61
-rw-r--r--sdnr/wt/odlux/apps/connectApp/src/actions/requiredNetworkElementsActions.ts55
-rw-r--r--sdnr/wt/odlux/apps/connectApp/src/components/connectionStatusLog.tsx19
-rw-r--r--sdnr/wt/odlux/apps/connectApp/src/components/editNetworkElementDialog.tsx184
-rw-r--r--sdnr/wt/odlux/apps/connectApp/src/components/infoNetworkElementDialog.tsx154
-rw-r--r--sdnr/wt/odlux/apps/connectApp/src/components/networkElements.tsx259
-rw-r--r--sdnr/wt/odlux/apps/connectApp/src/components/requiredNetworkElements.tsx210
-rw-r--r--sdnr/wt/odlux/apps/connectApp/src/components/unknownNetworkElements.tsx211
-rw-r--r--sdnr/wt/odlux/apps/connectApp/src/handlers/connectAppRootHandler.ts83
-rw-r--r--sdnr/wt/odlux/apps/connectApp/src/handlers/connectAppRootHandler.tsx42
-rw-r--r--sdnr/wt/odlux/apps/connectApp/src/handlers/connectionStatusLogHandler.ts (renamed from sdnr/wt/odlux/apps/connectApp/src/handlers/requiredNetworkElementsHandler.tsx)16
-rw-r--r--sdnr/wt/odlux/apps/connectApp/src/handlers/connectionStatusLogHandler.tsx51
-rw-r--r--sdnr/wt/odlux/apps/connectApp/src/handlers/infoNetworkElementHandler.ts60
-rw-r--r--sdnr/wt/odlux/apps/connectApp/src/handlers/mountedNetworkElementsHandler.tsx111
-rw-r--r--sdnr/wt/odlux/apps/connectApp/src/handlers/networkElementsHandler.ts58
-rw-r--r--sdnr/wt/odlux/apps/connectApp/src/index.html5
-rw-r--r--sdnr/wt/odlux/apps/connectApp/src/models/guiCutTrough.ts1
-rw-r--r--sdnr/wt/odlux/apps/connectApp/src/models/networkElementConnection.ts36
-rw-r--r--sdnr/wt/odlux/apps/connectApp/src/models/networkElementConnectionLog.ts (renamed from sdnr/wt/odlux/apps/connectApp/src/models/requiredNetworkElements.ts)12
-rw-r--r--sdnr/wt/odlux/apps/connectApp/src/models/panelId.ts1
-rw-r--r--sdnr/wt/odlux/apps/connectApp/src/models/topologyNetconf.ts17
-rw-r--r--sdnr/wt/odlux/apps/connectApp/src/models/yangCapabilitiesType.ts (renamed from sdnr/wt/odlux/apps/connectApp/src/models/mountedNetworkElements.ts)14
-rw-r--r--sdnr/wt/odlux/apps/connectApp/src/pluginConnect.tsx (renamed from sdnr/wt/odlux/apps/connectApp/src/plugin.tsx)19
-rw-r--r--sdnr/wt/odlux/apps/connectApp/src/services/connectService.ts246
-rw-r--r--sdnr/wt/odlux/apps/connectApp/src/views/connectView.tsx113
-rw-r--r--sdnr/wt/odlux/apps/connectApp/webpack.config.js24
31 files changed, 1263 insertions, 1157 deletions
diff --git a/sdnr/wt/odlux/apps/connectApp/package.json b/sdnr/wt/odlux/apps/connectApp/package.json
index 269fa2a8c..04653d520 100644
--- a/sdnr/wt/odlux/apps/connectApp/package.json
+++ b/sdnr/wt/odlux/apps/connectApp/package.json
@@ -21,20 +21,20 @@
"author": "Matthias Fischer",
"license": "Apache-2.0",
"dependencies": {
- "@odlux/framework" : "*"
+ "@odlux/framework": "*"
},
"peerDependencies": {
- "@types/react": "16.4.14",
- "@types/react-dom": "16.0.8",
- "@types/react-router-dom": "4.3.1",
- "@material-ui/core": "3.8.3",
- "@material-ui/icons": "3.0.2",
- "@types/classnames": "2.2.6",
- "@types/flux": "3.1.8",
- "@types/jquery": "3.3.10",
- "jquery": "3.3.1",
- "react": "16.5.2",
- "react-dom": "16.5.2",
- "react-router-dom": "4.3.1"
+ "@types/react": "16.9.11",
+ "@types/react-dom": "16.9.4",
+ "@types/react-router-dom": "4.3.1",
+ "@material-ui/core": "4.6.1",
+ "@material-ui/icons": "4.5.1",
+ "@types/classnames": "2.2.6",
+ "@types/flux": "3.1.8",
+ "@types/jquery": "3.3.10",
+ "jquery": "3.3.1",
+ "react": "16.11.0",
+ "react-dom": "16.11.0",
+ "react-router-dom": "4.3.1"
}
} \ No newline at end of file
diff --git a/sdnr/wt/odlux/apps/connectApp/pom.xml b/sdnr/wt/odlux/apps/connectApp/pom.xml
index 3da282c39..36a5cf8bf 100644
--- a/sdnr/wt/odlux/apps/connectApp/pom.xml
+++ b/sdnr/wt/odlux/apps/connectApp/pom.xml
@@ -1,5 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.onap.ccsdk.parent</groupId>
@@ -7,18 +8,20 @@
<version>1.5.1-SNAPSHOT</version>
<relativePath/>
</parent>
- <modelVersion>4.0.0</modelVersion>
+
<groupId>org.onap.ccsdk.features.sdnr.wt</groupId>
<artifactId>sdnr-wt-odlux-app-connectApp</artifactId>
<version>0.7.0-SNAPSHOT</version>
<packaging>bundle</packaging>
- <name>sdnr-wt-odlux-app-connectApp</name>
+
+ <name>ccsdk-features :: ${project.artifactId}</name>
<licenses>
<license>
<name>Apache License, Version 2.0</name>
<url>http://www.apache.org/licenses/LICENSE-2.0</url>
</license>
</licenses>
+
<dependencies>
<dependency>
<groupId>${project.groupId}</groupId>
@@ -37,8 +40,21 @@
<scope>test</scope>
</dependency>
</dependencies>
+
<build>
<sourceDirectory>src2/main/java</sourceDirectory>
+ <resources>
+ <resource>
+ <directory>dist</directory>
+ <targetPath>odlux</targetPath>
+ </resource>
+ <resource>
+ <directory>src2/main/resources</directory>
+ </resource>
+ <resource>
+ <directory>src2/test/resources</directory>
+ </resource>
+ </resources>
<plugins>
<plugin>
<artifactId>maven-clean-plugin</artifactId>
@@ -61,10 +77,10 @@
<followSymlinks>false</followSymlinks>
</fileset>
<!-- eclipse bug build bin folder in basedir -->
- <fileset>
- <directory>bin</directory>
- <followSymlinks>false</followSymlinks>
- </fileset>
+ <fileset>
+ <directory>bin</directory>
+ <followSymlinks>false</followSymlinks>
+ </fileset>
</filesets>
</configuration>
</plugin>
@@ -87,7 +103,7 @@
</executions>
</plugin>
<plugin>
- <groupId>de.jacksitlab</groupId>
+ <groupId>de.jacks-it-lab</groupId>
<artifactId>frontend-maven-plugin</artifactId>
<version>1.7.1</version>
<executions>
@@ -99,8 +115,8 @@
<!-- optional: default phase is "generate-resources" -->
<phase>initialize</phase>
<configuration>
- <nodeVersion>v8.10.0</nodeVersion>
- <yarnVersion>v1.12.3</yarnVersion>
+ <nodeVersion>v10.16.3</nodeVersion>
+ <yarnVersion>v1.19.0</yarnVersion>
</configuration>
</execution>
<execution>
@@ -130,27 +146,5 @@
</configuration>
</plugin>
</plugins>
- <resources>
- <resource>
- <directory>dist</directory>
- <targetPath>odlux</targetPath>
- </resource>
- <resource>
- <directory>src2/main/resources</directory>
- </resource>
- <resource>
- <directory>src2/test/resources</directory>
- </resource>
- </resources>
</build>
- <pluginRepositories>
- <pluginRepository>
- <id>highstreet repo</id>
- <url>https://cloud-highstreet-technologies.com/mvn/</url>
- <snapshots>
- <enabled>true</enabled>
- <updatePolicy>always</updatePolicy>
- </snapshots>
- </pluginRepository>
- </pluginRepositories>
</project>
diff --git a/sdnr/wt/odlux/apps/connectApp/src/actions/commonNetworkElementsActions.ts b/sdnr/wt/odlux/apps/connectApp/src/actions/commonNetworkElementsActions.ts
new file mode 100644
index 000000000..bf4778b5b
--- /dev/null
+++ b/sdnr/wt/odlux/apps/connectApp/src/actions/commonNetworkElementsActions.ts
@@ -0,0 +1,113 @@
+// update action erstellen, die unterscheiden kann, ob die eine oder die andere Ansicht gerade aktive ist und diese katualisiert.
+// Diese action wird dann bei jeder aktualisierung in den anderen Actions und bei eintreffen von notifikationen verwendet.
+
+/**
+ * ============LICENSE_START========================================================================
+ * ONAP : ccsdk feature sdnr wt odlux
+ * =================================================================================================
+ * Copyright (C) 2019 highstreet technologies GmbH Intellectual Property. All rights reserved.
+ * =================================================================================================
+ * 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.
+ * ============LICENSE_END==========================================================================
+ */
+
+import { Action } from '../../../../framework/src/flux/action';
+import { Dispatch } from '../../../../framework/src/flux/store';
+import { IApplicationStoreState } from '../../../../framework/src/store/applicationStore';
+
+import { networkElementsReloadAction } from '../handlers/networkElementsHandler';
+import { connectionStatusLogReloadAction } from '../handlers/connectionStatusLogHandler';
+
+import { PanelId } from '../models/panelId';
+import { guiCutThrough } from '../models/guiCutTrough';
+import connectService from '../services/connectService';
+import { NetworkElementConnection } from '../models/networkElementConnection';
+
+export class SetPanelAction extends Action {
+ constructor(public panelId: PanelId) {
+ super();
+ }
+}
+
+export class AddWebUriList extends Action {
+ constructor(public element: guiCutThrough[], public knownElements: string[]) {
+ super();
+ }
+}
+
+export class RemoveWebUri extends Action {
+ constructor(public element: string) {
+ super();
+ }
+}
+
+export const removeWebUriAction = (nodeId: string) => {
+ return new RemoveWebUri(nodeId);
+}
+
+let isBusy = false;
+export const findWebUrisForGuiCutThroughAsyncAction = (dispatcher: Dispatch) => (networkElements: NetworkElementConnection[], knownElements: string[]) => {
+
+ // keep method from executing simultanously; state not used because change of iu isn't needed
+ if (isBusy)
+ return;
+ isBusy = true;
+
+ const nodeIds = networkElements.map(element => { return element.id as string });
+
+ if (knownElements.length > 0) {
+
+ let elementsToSearch: string[] = [];
+
+ nodeIds.forEach(element => {
+ // find index of nodeId
+ const index = knownElements.indexOf(element);
+
+ // if element dosen't exist, add it to list
+ if (index === -1) {
+ elementsToSearch.push(element)
+ }
+ });
+
+ // if new elements were found, search for weburi
+ if (elementsToSearch.length > 0) {
+ const foundWebUris = connectService.getAllWebUriExtensionsForNetworkElementListAsync(elementsToSearch);
+ foundWebUris.then(result => {
+ dispatcher(new AddWebUriList(result, elementsToSearch));
+ isBusy = false;
+ })
+
+ } else {
+ isBusy = false;
+ }
+
+ } else {
+ connectService.getAllWebUriExtensionsForNetworkElementListAsync(nodeIds).then(result => {
+ dispatcher(new AddWebUriList(result, nodeIds));
+ isBusy = false;
+ })
+ }
+}
+
+export const setPanelAction = (panelId: PanelId) => {
+ return new SetPanelAction(panelId);
+}
+
+export const updateCurrentViewAsyncAction = () => (dispatch: Dispatch, getState: () => IApplicationStoreState) => {
+ const { connect: { currentOpenPanel } } = getState();
+ if (currentOpenPanel === "NetworkElements") {
+ return dispatch(networkElementsReloadAction);
+ }
+ else {
+ return dispatch(connectionStatusLogReloadAction);
+ }
+};
+
diff --git a/sdnr/wt/odlux/apps/connectApp/src/actions/infoNetworkElementActions.ts b/sdnr/wt/odlux/apps/connectApp/src/actions/infoNetworkElementActions.ts
new file mode 100644
index 000000000..4ae28aab2
--- /dev/null
+++ b/sdnr/wt/odlux/apps/connectApp/src/actions/infoNetworkElementActions.ts
@@ -0,0 +1,57 @@
+/**
+ * ============LICENSE_START========================================================================
+ * ONAP : ccsdk feature sdnr wt odlux
+ * =================================================================================================
+ * Copyright (C) 2019 highstreet technologies GmbH Intellectual Property. All rights reserved.
+ * =================================================================================================
+ * 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.
+ * ============LICENSE_END==========================================================================
+ */
+import { Action } from '../../../../framework/src/flux/action';
+import { Dispatch } from '../../../../framework/src/flux/store';
+
+import { TopologyNode } from '../models/topologyNetconf';
+import { connectService } from '../services/connectService';
+
+/**
+ * Represents the base action.
+ */
+export class BaseAction extends Action { }
+
+/**
+ * Represents an action causing the store to load all element Yang capabilities.
+ */
+export class LoadAllElementInfoAction extends BaseAction { }
+
+/**
+ * Represents an action causing the store to update element Yang capabilities.
+ */
+export class AllElementInfoLoadedAction extends BaseAction {
+ /**
+ * Initialize this instance.
+ * @param elementInfo The information of the element which is returned.
+ */
+ constructor(public elementInfo: TopologyNode | null, public error?: string) {
+ super();
+ }
+}
+
+/**
+ * Represents an asynchronous thunk action to load all yang capabilities.
+ */
+export const loadAllInfoElementAsync = (nodeId: string) => (dispatch: Dispatch) => {
+ dispatch(new LoadAllElementInfoAction());
+ connectService.infoNetworkElement(nodeId).then(info => {
+ dispatch(new AllElementInfoLoadedAction(info));
+ }, error => {
+ dispatch(new AllElementInfoLoadedAction(null, error));
+ });
+} \ No newline at end of file
diff --git a/sdnr/wt/odlux/apps/connectApp/src/actions/mountedNetworkElementsActions.ts b/sdnr/wt/odlux/apps/connectApp/src/actions/mountedNetworkElementsActions.ts
index 12f7c8594..84e73ae5a 100644
--- a/sdnr/wt/odlux/apps/connectApp/src/actions/mountedNetworkElementsActions.ts
+++ b/sdnr/wt/odlux/apps/connectApp/src/actions/mountedNetworkElementsActions.ts
@@ -15,107 +15,45 @@
* the License.
* ============LICENSE_END==========================================================================
*/
+
import { Action } from '../../../../framework/src/flux/action';
import { Dispatch } from '../../../../framework/src/flux/store';
-import { MountedNetworkElementType } from '../models/mountedNetworkElements';
-import { RequiredNetworkElementType } from '../models/requiredNetworkElements';
-
import { connectService } from '../services/connectService';
+import { NetworkElementConnection } from '../models/networkElementConnection';
import { AddSnackbarNotification } from '../../../../framework/src/actions/snackbarActions';
+import { updateCurrentViewAsyncAction } from './commonNetworkElementsActions';
/** Represents the base action. */
export class BaseAction extends Action { }
-/** Represents an action causing the store to load all mounted network elements. */
-export class LoadAllMountedNetworkElementsAction extends BaseAction { }
-
-/** Represents an action causing the store to update all mounted network elements. */
-export class AllMountedNetworkElementsLoadedAction extends BaseAction {
- constructor(public mountedNetworkElements: MountedNetworkElementType[] | null, public error?: string) {
- super();
- }
-}
-
-/** Represents an action causing the store to update all mounted network elements. */
-export class AddOrUpdateMountedNetworkElement extends BaseAction {
- constructor(public mountedNetworkElement: MountedNetworkElementType | null, public error?: string) {
- super();
- }
-}
-
-export class RemoveMountedNetworkElement extends BaseAction {
- constructor(public mountId: string) {
- super();
- }
-}
-
-export class UpdateConnectionStateMountedNetworkElement extends BaseAction {
- constructor(public mountId: string, connectionState: string) {
- super();
- }
-}
-
-
-export class UpdateRequiredMountedNetworkElement extends BaseAction {
- constructor(public mountId: string, public required: boolean) {
- super();
- }
-}
-
-/**
- * Represents an action crator for a async thunk action to add an allready mounted element to the state of this app.
- * Note: Use this action to add created object notified by the websocket.
-*/
-export const addMountedNetworkElementAsyncActionCreator = (mountId: string) => async (dispatch: Dispatch) => {
- return connectService.getMountedNetworkElementByMountId(mountId).then(mountedNetworkElement => {
- mountedNetworkElement && dispatch(new AddOrUpdateMountedNetworkElement(mountedNetworkElement));
- }).catch(error => {
- dispatch(new AddOrUpdateMountedNetworkElement(null, error));
- });
-};
-
-export const updateMountedNetworkElementAsyncActionCreator = (mountId: string) => async (dispatch: Dispatch) => {
- return connectService.getMountedNetworkElementByMountId(mountId).then(mountedNetworkElement => {
- if (mountedNetworkElement) {
- dispatch(new AddOrUpdateMountedNetworkElement(mountedNetworkElement));
- } else {
- dispatch(new RemoveMountedNetworkElement(mountId));
- }
- }).catch(error => {
- dispatch(new AddOrUpdateMountedNetworkElement(null, error));
- });
-};
-
-/** Represents an async thunk action to load all mounted network elements. */
-export const loadAllMountedNetworkElementsAsync = (dispatch: Dispatch) => {
- dispatch(new LoadAllMountedNetworkElementsAction());
- return connectService.getMountedNetworkElementsList().then(mountedNetworkElements => {
- mountedNetworkElements && dispatch(new AllMountedNetworkElementsLoadedAction(mountedNetworkElements));
- }).catch(error => {
- dispatch(new AllMountedNetworkElementsLoadedAction(null, error));
- });
-};
-
/** Represents an action crator for a async thunk action to mount a network element. */
-export const mountNetworkElementAsyncActionCreator = (networkElement: RequiredNetworkElementType) => (dispatch: Dispatch) => {
+export const mountNetworkElementAsyncActionCreator = (networkElement: NetworkElementConnection) => (dispatch: Dispatch) => {
return connectService.mountNetworkElement(networkElement).then((success) => {
- success && (
- dispatch(addMountedNetworkElementAsyncActionCreator(networkElement.mountId)) &&
- dispatch(new AddSnackbarNotification({ message: `Requesting mount [${networkElement.mountId}]`, options: { variant: 'info' } }))
- ) || dispatch(new AddSnackbarNotification({ message: `Failed to mount [${ networkElement.mountId }]`, options: { variant: 'warning' } }));
+ if (success) {
+ dispatch(updateCurrentViewAsyncAction());
+ dispatch(new AddSnackbarNotification({ message: `Requesting mount [${networkElement.nodeId}]`, options: { variant: 'info' } }))
+ } else {
+ dispatch(new AddSnackbarNotification({ message: `Failed to mount [${networkElement.nodeId}]`, options: { variant: 'warning' } }));
+ }
}).catch(error => {
- dispatch(new AddOrUpdateMountedNetworkElement(null, error));
+ dispatch(new AddSnackbarNotification({ message: `Failed to mount [${networkElement.nodeId}]`, options: { variant: 'error' } }));
+ console.error(error);
});
};
/** Represents an action crator for a async thunk action to unmount a network element. */
-export const unmountNetworkElementAsyncActionCreator = (mountId: string) => (dispatch: Dispatch) => {
- return connectService.unmountNetworkElement(mountId).then((success) => {
- success && dispatch(new AddSnackbarNotification({ message: `Requesting unmount [${ mountId }]`, options: { variant: 'info' } }))
- || dispatch(new AddSnackbarNotification({ message: `Failed to unmount [${ mountId }]`, options: { variant: 'warning' } }));
+export const unmountNetworkElementAsyncActionCreator = (nodeId: string) => (dispatch: Dispatch) => {
+ return connectService.unmountNetworkElement(nodeId).then((success) => {
+ if (success) {
+ dispatch(updateCurrentViewAsyncAction());
+ dispatch(new AddSnackbarNotification({ message: `Requesting unmount [${nodeId}]`, options: { variant: 'info' } }));
+ } else {
+ dispatch(new AddSnackbarNotification({ message: `Failed to unmount [${nodeId}]`, options: { variant: 'warning' } }));
+ }
}).catch(error => {
- dispatch(new AddOrUpdateMountedNetworkElement(null, error));
+ dispatch(new AddSnackbarNotification({ message: `Failed to unmount [${nodeId}]`, options: { variant: 'error' } }));
+ console.error(error);
});
};
diff --git a/sdnr/wt/odlux/apps/connectApp/src/actions/networkElementsActions.ts b/sdnr/wt/odlux/apps/connectApp/src/actions/networkElementsActions.ts
new file mode 100644
index 000000000..1a86f94b1
--- /dev/null
+++ b/sdnr/wt/odlux/apps/connectApp/src/actions/networkElementsActions.ts
@@ -0,0 +1,61 @@
+/**
+ * ============LICENSE_START========================================================================
+ * ONAP : ccsdk feature sdnr wt odlux
+ * =================================================================================================
+ * Copyright (C) 2019 highstreet technologies GmbH Intellectual Property. All rights reserved.
+ * =================================================================================================
+ * 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.
+ * ============LICENSE_END==========================================================================
+ */
+import { Action } from '../../../../framework/src/flux/action';
+import { Dispatch } from '../../../../framework/src/flux/store';
+
+import { AddSnackbarNotification } from '../../../../framework/src/actions/snackbarActions';
+
+import { NetworkElementConnection, ConnectionStatus, UpdateNetworkElement } from '../models/networkElementConnection';
+import { connectService } from '../services/connectService';
+import { updateCurrentViewAsyncAction } from './commonNetworkElementsActions';
+import { unmountNetworkElementAsyncActionCreator } from './mountedNetworkElementsActions';
+
+/** Represents the base action. */
+export class BaseAction extends Action { }
+
+/** Represents an async thunk action creator to add an element to the network elements. */
+export const addNewNetworkElementAsyncActionCreator = (element: NetworkElementConnection) => async (dispatch: Dispatch) => {
+ const res = await connectService.createNetworkElement({ ...element });
+ dispatch(updateCurrentViewAsyncAction());
+ dispatch(new AddSnackbarNotification({ message: `Successfully added [${element.nodeId}]`, options: { variant: 'success' } }));
+};
+
+/** Represents an async thunk action creator to edit network element. */
+export const editNetworkElementAsyncActionCreator = (element: UpdateNetworkElement) => async (dispatch: Dispatch) => {
+ const connectionStatus: ConnectionStatus[] = await connectService.getNetworkElementConnectionStatus(element.id).then(ne => (ne)) || [];
+ const currentConnectionStatus = connectionStatus[0].status;
+ if (currentConnectionStatus === "Disconnected") {
+ const res = await connectService.deleteNetworkElement(element);
+ }
+ else {
+ const res = await connectService.updateNetworkElement(element);
+ }
+ dispatch(updateCurrentViewAsyncAction());
+ dispatch(new AddSnackbarNotification({ message: `Successfully modified [${element.id}]`, options: { variant: 'success' } }));
+};
+
+
+/** Represents an async thunk action creator to delete an element from network elements. */
+export const removeNetworkElementAsyncActionCreator = (element: UpdateNetworkElement) => async (dispatch: Dispatch) => {
+ const res = await connectService.deleteNetworkElement(element);
+ await dispatch(unmountNetworkElementAsyncActionCreator(element && element.id));
+ dispatch(updateCurrentViewAsyncAction());
+};
+
+
+
diff --git a/sdnr/wt/odlux/apps/connectApp/src/actions/requiredNetworkElementsActions.ts b/sdnr/wt/odlux/apps/connectApp/src/actions/requiredNetworkElementsActions.ts
deleted file mode 100644
index 0e55cadf4..000000000
--- a/sdnr/wt/odlux/apps/connectApp/src/actions/requiredNetworkElementsActions.ts
+++ /dev/null
@@ -1,55 +0,0 @@
-/**
- * ============LICENSE_START========================================================================
- * ONAP : ccsdk feature sdnr wt odlux
- * =================================================================================================
- * Copyright (C) 2019 highstreet technologies GmbH Intellectual Property. All rights reserved.
- * =================================================================================================
- * 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.
- * ============LICENSE_END==========================================================================
- */
-import { Action } from '../../../../framework/src/flux/action';
-import { Dispatch } from '../../../../framework/src/flux/store';
-import { RequiredNetworkElementType } from '../models/requiredNetworkElements';
-import { requiredNetworkElementsReloadAction } from '../handlers/requiredNetworkElementsHandler';
-import { UpdateRequiredMountedNetworkElement } from '../actions/mountedNetworkElementsActions';
-
-import { AddSnackbarNotification } from '../../../../framework/src/actions/snackbarActions';
-
-import { connectService } from '../services/connectService';
-
-/** Represents the base action. */
-export class BaseAction extends Action { }
-
-
-/** Represents an async thunk action creator to add an element to the required network elements. */
-export const addToRequiredNetworkElementsAsyncActionCreator = (element: RequiredNetworkElementType) => (dispatch: Dispatch) => {
- connectService.insertRequiredNetworkElement(element).then(_ => {
- window.setTimeout(() => {
- dispatch(requiredNetworkElementsReloadAction);
- dispatch(new UpdateRequiredMountedNetworkElement(element.mountId, true));
- dispatch(new AddSnackbarNotification({ message: `Successfully added [${ element.mountId }]`, options: { variant: 'success' } }));
- }, 900);
- });
-};
-
-/** Represents an async thunk action creator to delete an element from the required network elements. */
-export const removeFromRequiredNetworkElementsAsyncActionCreator = (element: RequiredNetworkElementType) => (dispatch: Dispatch) => {
- connectService.deleteRequiredNetworkElement(element).then(_ => {
- window.setTimeout(() => {
- dispatch(requiredNetworkElementsReloadAction);
- dispatch(new UpdateRequiredMountedNetworkElement(element.mountId, false));
- dispatch(new AddSnackbarNotification({ message: `Successfully removed [${ element.mountId }]`, options: { variant: 'success' } }));
- }, 900);
- });
-};
-
-
-
diff --git a/sdnr/wt/odlux/apps/connectApp/src/components/connectionStatusLog.tsx b/sdnr/wt/odlux/apps/connectApp/src/components/connectionStatusLog.tsx
index 3cc104836..4e5ca65e1 100644
--- a/sdnr/wt/odlux/apps/connectApp/src/components/connectionStatusLog.tsx
+++ b/sdnr/wt/odlux/apps/connectApp/src/components/connectionStatusLog.tsx
@@ -21,32 +21,31 @@ import { IApplicationStoreState } from '../../../../framework/src/store/applicat
import { MaterialTable, ColumnType, MaterialTableCtorType } from '../../../../framework/src/components/material-table';
import { createConnectionStatusLogActions, createConnectionStatusLogProperties } from '../handlers/connectionStatusLogHandler';
-import { ConnectionStatusLogType } from '../models/connectionStatusLog';
+import { NetworkElementConnectionLog } from '../models/networkElementConnectionLog';
const mapProps = (state: IApplicationStoreState) => ({
connectionStatusLogProperties: createConnectionStatusLogProperties(state),
});
const mapDispatch = (dispatcher: IDispatcher) => ({
- connectionStatusLogActions: createConnectionStatusLogActions(dispatcher.dispatch),
+ connectionStatusLogActions: createConnectionStatusLogActions(dispatcher.dispatch),
});
-
-const ConnectionStatusTable = MaterialTable as MaterialTableCtorType<ConnectionStatusLogType>;
+
+const ConnectionStatusTable = MaterialTable as MaterialTableCtorType<NetworkElementConnectionLog>;
type ConnectionStatusLogComponentProps = Connect<typeof mapProps, typeof mapDispatch>;
class ConnectionStatusLogComponent extends React.Component<ConnectionStatusLogComponentProps> {
render(): JSX.Element {
return (
- <ConnectionStatusTable columns={ [
- { property: "timeStamp", title: "Time", type: ColumnType.text },
- { property: "objectId", title: "Name", type: ColumnType.text },
- { property: "elementStatus", title: "Connection status", type: ColumnType.text, disableFilter: true, disableSorting: true },
- ] } idProperty="_id" { ...this.props.connectionStatusLogActions } {...this.props.connectionStatusLogProperties } >
+ <ConnectionStatusTable tableId="connection-status-table" columns={[
+ { property: "timestamp", title: "Time", type: ColumnType.text },
+ { property: "nodeId", title: "Node Name", type: ColumnType.text },
+ { property: "status", title: "Connection status", type: ColumnType.text },
+ ]} idProperty="id" {...this.props.connectionStatusLogActions} {...this.props.connectionStatusLogProperties} >
</ConnectionStatusTable>
);
};
-
}
export const ConnectionStatusLog = connect(mapProps, mapDispatch)(ConnectionStatusLogComponent);
diff --git a/sdnr/wt/odlux/apps/connectApp/src/components/editNetworkElementDialog.tsx b/sdnr/wt/odlux/apps/connectApp/src/components/editNetworkElementDialog.tsx
index 32b23a41e..1e1f11523 100644
--- a/sdnr/wt/odlux/apps/connectApp/src/components/editNetworkElementDialog.tsx
+++ b/sdnr/wt/odlux/apps/connectApp/src/components/editNetworkElementDialog.tsx
@@ -24,46 +24,47 @@ import DialogActions from '@material-ui/core/DialogActions';
import DialogContent from '@material-ui/core/DialogContent';
import DialogContentText from '@material-ui/core/DialogContentText';
import DialogTitle from '@material-ui/core/DialogTitle';
+import { FormControl, InputLabel, Select, MenuItem } from '@material-ui/core';
import { IDispatcher, connect, Connect } from '../../../../framework/src/flux/connect';
import {
- addToRequiredNetworkElementsAsyncActionCreator,
- removeFromRequiredNetworkElementsAsyncActionCreator
-} from '../actions/requiredNetworkElementsActions';
+ editNetworkElementAsyncActionCreator,
+ addNewNetworkElementAsyncActionCreator,
+ removeNetworkElementAsyncActionCreator
+} from '../actions/networkElementsActions';
import { unmountNetworkElementAsyncActionCreator, mountNetworkElementAsyncActionCreator } from '../actions/mountedNetworkElementsActions';
-import { RequiredNetworkElementType } from '../models/requiredNetworkElements';
+import { NetworkElementConnection, UpdateNetworkElement } from '../models/networkElementConnection';
+import { removeWebUriAction } from '../actions/commonNetworkElementsActions';
export enum EditNetworkElementDialogMode {
None = "none",
- UnknownNetworkElementToRequiredNetworkElements = "unknownNetworkElementToRequiredNetworkElements",
- RequiredNetworkElementToUnknownNetworkElements = "requiredNetworkElementToUnknownNetworkElements",
- MountNetworkElementToRequiredNetworkElements = "mountNetworkElementToRequiredNetworkElements",
- MountNetworkElementToUnknonwNetworkElements = "mountNetworkElementToRequiredUnknownElements",
+ EditNetworkElement = "editNetworkElement",
+ RemoveNetworkElement = "removeNetworkElement",
+ AddNewNetworkElement = "addNewNetworkElement",
MountNetworkElement = "mountNetworkElement",
UnmountNetworkElement = "unmountNetworkElement",
}
const mapDispatch = (dispatcher: IDispatcher) => ({
- addToRequiredNetworkElements: (element: RequiredNetworkElementType) => {
- dispatcher.dispatch(addToRequiredNetworkElementsAsyncActionCreator(element));
+ addNewNetworkElement: async (element: NetworkElementConnection) => {
+ await dispatcher.dispatch(addNewNetworkElementAsyncActionCreator(element));
+ await dispatcher.dispatch(mountNetworkElementAsyncActionCreator(element));
},
- removeFromRequiredNetworkElements: (element: RequiredNetworkElementType) => {
- dispatcher.dispatch(removeFromRequiredNetworkElementsAsyncActionCreator(element));
+ mountNetworkElement: (element: NetworkElementConnection) => dispatcher.dispatch(mountNetworkElementAsyncActionCreator(element)),
+ unmountNetworkElement: (element: NetworkElementConnection) => {
+ dispatcher.dispatch(unmountNetworkElementAsyncActionCreator(element && element.nodeId));
},
- mountNetworkElement: (element: RequiredNetworkElementType) => {
- dispatcher.dispatch(mountNetworkElementAsyncActionCreator(element));
+ editNetworkElement: async (element: UpdateNetworkElement, mountElement: NetworkElementConnection) => {
+ await dispatcher.dispatch(editNetworkElementAsyncActionCreator(element));
+ await dispatcher.dispatch(mountNetworkElementAsyncActionCreator(mountElement));
},
- mountAndRquireNetworkElement: (element: RequiredNetworkElementType) => {
- dispatcher.dispatch(addToRequiredNetworkElementsAsyncActionCreator(element));
- dispatcher.dispatch(mountNetworkElementAsyncActionCreator(element));
- },
- unmountNetworkElement: (element: RequiredNetworkElementType) => {
- dispatcher.dispatch(unmountNetworkElementAsyncActionCreator(element && element.mountId));
+ removeNetworkElement: (element: UpdateNetworkElement) => {
+ dispatcher.dispatch(removeNetworkElementAsyncActionCreator(element));
+ dispatcher.dispatch(removeWebUriAction(element.id));
}
-}
-);
+});
type DialogSettings = {
dialogTitle: string,
@@ -85,37 +86,11 @@ const settings: { [key: string]: DialogSettings } = {
enableUsernameEditor: false,
enableExtendedEditor: false,
},
- [EditNetworkElementDialogMode.UnknownNetworkElementToRequiredNetworkElements] : {
- dialogTitle: "Add to required network elements" ,
- dialogDescription: "Create a new NetworkElement in planning database as clone of existing real NetworkElement." ,
- applyButtonText: "Add to required network elements" ,
- cancelButtonText: "Cancel",
- enableMountIdEditor: false,
- enableUsernameEditor: true,
- enableExtendedEditor: false,
- },
- [EditNetworkElementDialogMode.RequiredNetworkElementToUnknownNetworkElements]: {
- dialogTitle: "Remove from required network elements",
- dialogDescription: "Do you really want to remove the required element:",
- applyButtonText: "Remove network element",
- cancelButtonText: "Cancel",
- enableMountIdEditor: false,
- enableUsernameEditor: false,
- enableExtendedEditor: false,
- },
- [EditNetworkElementDialogMode.MountNetworkElementToUnknonwNetworkElements]: {
- dialogTitle: "Mount to unknown network elements",
- dialogDescription: "Mount this network element:",
- applyButtonText: "Mount network element",
- cancelButtonText: "Cancel",
- enableMountIdEditor: true,
- enableUsernameEditor: true,
- enableExtendedEditor: true,
- },
- [EditNetworkElementDialogMode.MountNetworkElementToRequiredNetworkElements]: {
- dialogTitle: "Mount to required network elements",
- dialogDescription: "Mount this network element:",
- applyButtonText: "Mount network element",
+
+ [EditNetworkElementDialogMode.AddNewNetworkElement]: {
+ dialogTitle: "Add new network element",
+ dialogDescription: "Add this new network element:",
+ applyButtonText: "Add network element",
cancelButtonText: "Cancel",
enableMountIdEditor: true,
enableUsernameEditor: true,
@@ -139,83 +114,102 @@ const settings: { [key: string]: DialogSettings } = {
enableUsernameEditor: false,
enableExtendedEditor: false,
},
+ [EditNetworkElementDialogMode.EditNetworkElement]: {
+ dialogTitle: "Modify the network elements",
+ dialogDescription: "Modify this network element",
+ applyButtonText: "Modify",
+ cancelButtonText: "Cancel",
+ enableMountIdEditor: false,
+ enableUsernameEditor: true,
+ enableExtendedEditor: false,
+ },
+ [EditNetworkElementDialogMode.RemoveNetworkElement]: {
+ dialogTitle: "Remove network element",
+ dialogDescription: "Do you really want to remove this network element:",
+ applyButtonText: "Remove network element",
+ cancelButtonText: "Cancel",
+ enableMountIdEditor: false,
+ enableUsernameEditor: false,
+ enableExtendedEditor: false,
+ }
}
-type EditNetworkElementDialogComponentProps = Connect<undefined,typeof mapDispatch> & {
+type EditNetworkElementDialogComponentProps = Connect<undefined, typeof mapDispatch> & {
mode: EditNetworkElementDialogMode;
- initialNetworkElement: RequiredNetworkElementType;
+ initialNetworkElement: NetworkElementConnection;
onClose: () => void;
};
-type EditNetworkElementDialogComponentState = RequiredNetworkElementType & {
- required: boolean;
-};
+type EditNetworkElementDialogComponentState = NetworkElementConnection;
class EditNetworkElementDialogComponent extends React.Component<EditNetworkElementDialogComponentProps, EditNetworkElementDialogComponentState> {
constructor(props: EditNetworkElementDialogComponentProps) {
super(props);
this.state = {
- mountId: this.props.initialNetworkElement.mountId,
+ nodeId: this.props.initialNetworkElement.nodeId,
+ isRequired: false,
host: this.props.initialNetworkElement.host,
port: this.props.initialNetworkElement.port,
- password: this.props.initialNetworkElement.password,
- username: this.props.initialNetworkElement.username,
- required: false
};
}
render(): JSX.Element {
const setting = settings[this.props.mode];
return (
- <Dialog open={ this.props.mode !== EditNetworkElementDialogMode.None }>
- <DialogTitle id="form-dialog-title">{ setting.dialogTitle }</DialogTitle>
+ <Dialog open={this.props.mode !== EditNetworkElementDialogMode.None}>
+ <DialogTitle id="form-dialog-title">{setting.dialogTitle}</DialogTitle>
<DialogContent>
<DialogContentText>
- { setting.dialogDescription }
+ {setting.dialogDescription}
</DialogContentText>
- <TextField disabled={ !setting.enableMountIdEditor } spellCheck={false} autoFocus margin="dense" id="name" label="Name" type="text" fullWidth value={ this.state.mountId } onChange={(event)=>{ this.setState({mountId: event.target.value}); } } />
- <TextField disabled={ !setting.enableMountIdEditor } spellCheck={false} margin="dense" id="ipaddress" label="IP address" type="text" fullWidth value={ this.state.host } onChange={(event)=>{ this.setState({host: event.target.value}); } }/>
- <TextField disabled={ !setting.enableMountIdEditor } spellCheck={false} margin="dense" id="netconfport" label="NetConf port" type="number" fullWidth value={ this.state.port.toString() } onChange={(event)=>{ this.setState({port: +event.target.value}); } }/>
- { setting.enableUsernameEditor && <TextField disabled={ !setting.enableUsernameEditor } spellCheck={ false } margin="dense" id="username" label="Username" type="text" fullWidth value={ this.state.username } onChange={ (event) => { this.setState({ username: event.target.value }); } } /> || null }
- { setting.enableUsernameEditor && <TextField disabled={ !setting.enableUsernameEditor } spellCheck={ false } margin="dense" id="password" label="Password" type="password" fullWidth value={ this.state.password } onChange={ (event) => { this.setState({ password: event.target.value }); } } /> || null }
+ <TextField disabled={!setting.enableMountIdEditor} spellCheck={false} autoFocus margin="dense" id="name" label="Name" aria-label="name" type="text" fullWidth value={this.state.nodeId} onChange={(event) => { this.setState({ nodeId: event.target.value }); }} />
+ <TextField disabled={!setting.enableMountIdEditor} spellCheck={false} margin="dense" id="ipaddress" label="IP address" aria-label="ip adress" type="text" fullWidth value={this.state.host} onChange={(event) => { this.setState({ host: event.target.value }); }} />
+ <TextField disabled={!setting.enableMountIdEditor} spellCheck={false} margin="dense" id="netconfport" label="NetConf port" aria-label="netconf port" type="number" fullWidth value={this.state.port.toString()} onChange={(event) => { this.setState({ port: +event.target.value }); }} />
+ {setting.enableUsernameEditor && <TextField disabled={!setting.enableUsernameEditor} spellCheck={false} margin="dense" id="username" label="Username" aria-label="username" type="text" fullWidth value={this.state.username} onChange={(event) => { this.setState({ username: event.target.value }); }} /> || null}
+ {setting.enableUsernameEditor && <TextField disabled={!setting.enableUsernameEditor} spellCheck={false} margin="dense" id="password" label="Password" aria-label="password" type="password" fullWidth value={this.state.password} onChange={(event) => { this.setState({ password: event.target.value }); }} /> || null}
+ <FormControl fullWidth disabled={!setting.enableUsernameEditor}>
+ <InputLabel htmlFor="active">Required</InputLabel>
+ <Select value={this.state.isRequired || false} onChange={(event) => {
+ this.setState({ isRequired: event.target.value as any as boolean });
+ }} inputProps={{ name: 'required', id: 'required' }} fullWidth >
+ <MenuItem value={true as any as string} >True</MenuItem>
+ <MenuItem value={false as any as string} >False</MenuItem>
+ </Select>
+ </FormControl>
</DialogContent>
<DialogActions>
- <Button onClick={ (event) => {
+ <Button onClick={(event) => {
this.onApply({
- mountId: this.state.mountId,
+ isRequired: this.state.isRequired,
+ id: this.state.nodeId,
+ nodeId: this.state.nodeId,
host: this.state.host,
port: this.state.port,
username: this.state.username,
- password: this.state.password
+ password: this.state.password,
});
event.preventDefault();
event.stopPropagation();
- } } > { setting.applyButtonText } </Button>
- <Button onClick={ (event) => {
+ }} > {setting.applyButtonText} </Button>
+ <Button onClick={(event) => {
this.onCancel();
event.preventDefault();
event.stopPropagation();
- } } color="secondary"> { setting.cancelButtonText } </Button>
+ }} color="secondary"> {setting.cancelButtonText} </Button>
</DialogActions>
</Dialog>
)
}
- private onApply = (element: RequiredNetworkElementType) => {
+ private onApply = (element: NetworkElementConnection) => {
this.props.onClose && this.props.onClose();
+ let updateElement: UpdateNetworkElement = {
+ id: this.state.nodeId
+ }
switch (this.props.mode) {
- case EditNetworkElementDialogMode.UnknownNetworkElementToRequiredNetworkElements:
- element && this.props.addToRequiredNetworkElements(element);
- break;
- case EditNetworkElementDialogMode.RequiredNetworkElementToUnknownNetworkElements:
- element && this.props.removeFromRequiredNetworkElements(element);
- break;
- case EditNetworkElementDialogMode.MountNetworkElementToUnknonwNetworkElements:
- element && this.props.mountNetworkElement(element);
- break;
- case EditNetworkElementDialogMode.MountNetworkElementToRequiredNetworkElements:
- element && this.props.mountAndRquireNetworkElement(element);
+ case EditNetworkElementDialogMode.AddNewNetworkElement:
+ element && this.props.addNewNetworkElement(element);
break;
case EditNetworkElementDialogMode.MountNetworkElement:
element && this.props.mountNetworkElement(element);
@@ -223,6 +217,18 @@ class EditNetworkElementDialogComponent extends React.Component<EditNetworkEleme
case EditNetworkElementDialogMode.UnmountNetworkElement:
element && this.props.unmountNetworkElement(element);
break;
+ case EditNetworkElementDialogMode.EditNetworkElement:
+ if (this.props.initialNetworkElement.isRequired !== this.state.isRequired)
+ updateElement.isRequired = this.state.isRequired;
+ if (this.props.initialNetworkElement.username !== this.state.username)
+ updateElement.username = this.state.username;
+ if (this.props.initialNetworkElement.password !== this.state.password)
+ updateElement.password = this.state.password;
+ element && this.props.editNetworkElement(updateElement, element);
+ break;
+ case EditNetworkElementDialogMode.RemoveNetworkElement:
+ element && this.props.removeNetworkElement(updateElement);
+ break;
}
};
@@ -230,7 +236,7 @@ class EditNetworkElementDialogComponent extends React.Component<EditNetworkEleme
this.props.onClose && this.props.onClose();
}
- static getDerivedStateFromProps(props: EditNetworkElementDialogComponentProps, state: EditNetworkElementDialogComponentState & { _initialNetworkElement: RequiredNetworkElementType }): EditNetworkElementDialogComponentState & { _initialNetworkElement: RequiredNetworkElementType } {
+ static getDerivedStateFromProps(props: EditNetworkElementDialogComponentProps, state: EditNetworkElementDialogComponentState & { _initialNetworkElement: NetworkElementConnection }): EditNetworkElementDialogComponentState & { _initialNetworkElement: NetworkElementConnection } {
if (props.initialNetworkElement !== state._initialNetworkElement) {
state = {
...state,
diff --git a/sdnr/wt/odlux/apps/connectApp/src/components/infoNetworkElementDialog.tsx b/sdnr/wt/odlux/apps/connectApp/src/components/infoNetworkElementDialog.tsx
new file mode 100644
index 000000000..ea9d419ec
--- /dev/null
+++ b/sdnr/wt/odlux/apps/connectApp/src/components/infoNetworkElementDialog.tsx
@@ -0,0 +1,154 @@
+/**
+ * ============LICENSE_START========================================================================
+ * ONAP : ccsdk feature sdnr wt odlux
+ * =================================================================================================
+ * Copyright (C) 2019 highstreet technologies GmbH Intellectual Property. All rights reserved.
+ * =================================================================================================
+ * 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.
+ * ============LICENSE_END==========================================================================
+ */
+import * as React from 'react';
+
+import Button from '@material-ui/core/Button';
+import Dialog from '@material-ui/core/Dialog';
+import DialogActions from '@material-ui/core/DialogActions';
+import DialogContent from '@material-ui/core/DialogContent';
+import DialogContentText from '@material-ui/core/DialogContentText';
+import DialogTitle from '@material-ui/core/DialogTitle';
+import Table from '@material-ui/core/Table';
+import TableBody from '@material-ui/core/TableBody';
+import TableCell from '@material-ui/core/TableCell';
+import TableHead from '@material-ui/core/TableHead';
+import TableRow from '@material-ui/core/TableRow';
+import { IDispatcher, connect, Connect } from '../../../../framework/src/flux/connect';
+
+import { NetworkElementConnection } from '../models/networkElementConnection';
+import { AvailableCapabilities } from '../models/yangCapabilitiesType'
+
+export enum InfoNetworkElementDialogMode {
+ None = "none",
+ InfoNetworkElement = "infoNetworkElement"
+}
+
+const mapDispatch = (dispatcher: IDispatcher) => ({
+});
+
+type DialogSettings = {
+ dialogTitle: string,
+ dialogDescription: string,
+ cancelButtonText: string,
+}
+
+const settings: { [key: string]: DialogSettings } = {
+ [InfoNetworkElementDialogMode.None]: {
+ dialogTitle: "",
+ dialogDescription: "",
+ cancelButtonText: "",
+ },
+ [InfoNetworkElementDialogMode.InfoNetworkElement]: {
+ dialogTitle: "Yang capabilities of the network element",
+ dialogDescription: "Available capabilities of the network element",
+ cancelButtonText: "Cancel",
+ }
+}
+
+type InfoNetworkElementDialogComponentProps = Connect<undefined, typeof mapDispatch> & {
+ mode: InfoNetworkElementDialogMode;
+ initialNetworkElement: NetworkElementConnection;
+ onClose: () => void;
+};
+
+type InfoNetworkElementDialogComponentState = NetworkElementConnection;
+
+class InfoNetworkElementDialogComponent extends React.Component<InfoNetworkElementDialogComponentProps, InfoNetworkElementDialogComponentState> {
+ constructor(props: InfoNetworkElementDialogComponentProps) {
+ super(props);
+
+ this.state = {
+ nodeId: this.props.initialNetworkElement.nodeId,
+ isRequired: false,
+ host: this.props.initialNetworkElement.host,
+ port: this.props.initialNetworkElement.port,
+ };
+ }
+
+ render(): JSX.Element {
+ const setting = settings[this.props.mode];
+ const availableCapabilities = this.props.state.connect.elementInfo.elementInfo["netconf-node-topology:available-capabilities"]["available-capability"];
+ let yangCapabilities: AvailableCapabilities[] = [];
+
+ availableCapabilities.forEach(value => {
+ const capabilty = value.capability;
+ const indexRevision = capabilty.indexOf("revision=");
+ const indexModule = capabilty.indexOf(")", indexRevision);
+ if (indexRevision > 0 && indexModule > 0) {
+ yangCapabilities.push({
+ module: capabilty.substr(indexModule + 1),
+ revision: capabilty.substr(indexRevision + 9, 10)
+ });
+ }
+ });
+
+ return (
+ <Dialog open={this.props.mode !== InfoNetworkElementDialogMode.None}>
+ <DialogTitle id="form-dialog-title">{setting.dialogTitle}</DialogTitle>
+ <DialogContent>
+ <DialogContentText>
+ {setting.dialogDescription + " " + this.state.nodeId}
+ </DialogContentText>
+ <Table >
+ <TableHead>
+ <TableRow>
+ <TableCell align="right">S.No</TableCell>
+ <TableCell >Module</TableCell>
+ <TableCell >Revision</TableCell>
+ </TableRow>
+ </TableHead>
+ <TableBody>
+ {yangCapabilities.map((yang, index) => (
+ <TableRow>
+ <TableCell>{index + 1}</TableCell>
+ <TableCell>{yang.module}</TableCell>
+ <TableCell>{yang.revision}</TableCell>
+ </TableRow>
+ ))}
+ </TableBody>
+ </Table>
+ </DialogContent>
+ <DialogActions>
+ <Button onClick={(event) => {
+ this.onCancel();
+ event.preventDefault();
+ event.stopPropagation();
+ }} color="secondary"> {setting.cancelButtonText} </Button>
+ </DialogActions>
+ </Dialog>
+ )
+ }
+
+ private onCancel = () => {
+ this.props.onClose();
+ }
+
+ static getDerivedStateFromProps(props: InfoNetworkElementDialogComponentProps, state: InfoNetworkElementDialogComponentState & { _initialNetworkElement: NetworkElementConnection }): InfoNetworkElementDialogComponentState & { _initialNetworkElement: NetworkElementConnection } {
+ if (props.initialNetworkElement !== state._initialNetworkElement) {
+ state = {
+ ...state,
+ ...props.initialNetworkElement,
+ _initialNetworkElement: props.initialNetworkElement,
+ };
+ }
+ return state;
+ }
+}
+
+export const InfoNetworkElementDialog = connect(undefined, mapDispatch)(InfoNetworkElementDialogComponent);
+export default InfoNetworkElementDialog; \ No newline at end of file
diff --git a/sdnr/wt/odlux/apps/connectApp/src/components/networkElements.tsx b/sdnr/wt/odlux/apps/connectApp/src/components/networkElements.tsx
new file mode 100644
index 000000000..0f4b0e8ff
--- /dev/null
+++ b/sdnr/wt/odlux/apps/connectApp/src/components/networkElements.tsx
@@ -0,0 +1,259 @@
+/**
+* ============LICENSE_START========================================================================
+* ONAP : ccsdk feature sdnr wt odlux
+* =================================================================================================
+* Copyright (C) 2019 highstreet technologies GmbH Intellectual Property. All rights reserved.
+* =================================================================================================
+* 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.
+* ============LICENSE_END==========================================================================
+*/
+import * as React from 'react';
+import { Theme, createStyles, withStyles, WithStyles } from '@material-ui/core/styles';
+
+import AddIcon from '@material-ui/icons/Add';
+import LinkIcon from '@material-ui/icons/Link';
+import LinkOffIcon from '@material-ui/icons/LinkOff';
+import RemoveIcon from '@material-ui/icons/RemoveCircleOutline';
+import EditIcon from '@material-ui/icons/Edit';
+import Info from '@material-ui/icons/Info';
+import ComputerIcon from '@material-ui/icons/Computer';
+
+import Button from '@material-ui/core/Button';
+import IconButton from '@material-ui/core/IconButton';
+import Tooltip from '@material-ui/core/Tooltip';
+
+import { MaterialTable, ColumnType, MaterialTableCtorType } from '../../../../framework/src/components/material-table';
+import { IApplicationStoreState } from '../../../../framework/src/store/applicationStore';
+import { connect, Connect, IDispatcher } from '../../../../framework/src/flux/connect';
+import { NavigateToApplication } from '../../../../framework/src/actions/navigationActions';
+
+import { createNetworkElementsActions, createNetworkElementsProperties } from '../handlers/networkElementsHandler';
+
+import { NetworkElementConnection } from '../models/networkElementConnection';
+import EditNetworkElementDialog, { EditNetworkElementDialogMode } from './editNetworkElementDialog';
+
+import InfoNetworkElementDialog, { InfoNetworkElementDialogMode } from './infoNetworkElementDialog';
+import { loadAllInfoElementAsync } from '../actions/infoNetworkElementActions';
+import { TopologyNode } from '../models/topologyNetconf';
+
+const styles = (theme: Theme) => createStyles({
+ connectionStatusConnected: {
+ color: 'darkgreen',
+ },
+ connectionStatusConnecting: {
+ color: 'blue',
+ },
+ connectionStatusDisconnected: {
+ color: 'red',
+ },
+ button: {
+ margin: 0,
+ padding: "6px 6px",
+ minWidth: 'unset'
+ },
+ spacer: {
+ marginLeft: theme.spacing(1),
+ marginRight: theme.spacing(1),
+ display: "inline"
+ }
+});
+
+const mapProps = (state: IApplicationStoreState) => ({
+ networkElementsProperties: createNetworkElementsProperties(state),
+});
+
+const mapDispatch = (dispatcher: IDispatcher) => ({
+ networkElementsActions: createNetworkElementsActions(dispatcher.dispatch),
+ navigateToApplication: (applicationName: string, path?: string) => dispatcher.dispatch(new NavigateToApplication(applicationName, path)),
+ networkElementInfo: async (nodeId: string) => await dispatcher.dispatch(loadAllInfoElementAsync(nodeId)),
+});
+
+type NetworkElementsListComponentProps = WithStyles<typeof styles> & Connect<typeof mapProps, typeof mapDispatch>;
+type NetworkElementsListComponentState = {
+ networkElementToEdit: NetworkElementConnection,
+ networkElementEditorMode: EditNetworkElementDialogMode,
+ infoNetworkElementEditorMode: InfoNetworkElementDialogMode,
+ elementInfo: TopologyNode | null
+}
+
+const emptyRequireNetworkElement: NetworkElementConnection = { id: "", nodeId: "", host: "", port: 0, status: "Disconnected", isRequired: false };
+
+const NetworkElementTable = MaterialTable as MaterialTableCtorType<NetworkElementConnection>;
+
+export class NetworkElementsListComponent extends React.Component<NetworkElementsListComponentProps, NetworkElementsListComponentState> {
+
+ constructor(props: NetworkElementsListComponentProps) {
+ super(props);
+
+ this.state = {
+ networkElementToEdit: emptyRequireNetworkElement,
+ networkElementEditorMode: EditNetworkElementDialogMode.None,
+ elementInfo: null,
+ infoNetworkElementEditorMode: InfoNetworkElementDialogMode.None
+ };
+ }
+
+ // private navigationCreator
+
+ render(): JSX.Element {
+ const { classes } = this.props;
+ const { networkElementToEdit } = this.state;
+ const addRequireNetworkElementAction = {
+ icon: AddIcon, tooltip: 'Add', onClick: () => {
+ this.setState({
+ networkElementEditorMode: EditNetworkElementDialogMode.AddNewNetworkElement,
+ networkElementToEdit: emptyRequireNetworkElement,
+ });
+ }
+ };
+ let counter = 0;
+ return (
+ <>
+ <NetworkElementTable tableId="network-element-table" customActionButtons={[addRequireNetworkElementAction]} columns={[
+ { property: "nodeId", title: "Node Name", type: ColumnType.text },
+ { property: "isRequired", title: "Required", type: ColumnType.boolean },
+ { property: "status", title: "Connection Status", type: ColumnType.text },
+ { property: "host", title: "Host", type: ColumnType.text },
+ { property: "port", title: "Port", type: ColumnType.numeric },
+ { property: "coreModelCapability", title: "Core Model", type: ColumnType.text },
+ { property: "deviceType", title: "Type", type: ColumnType.text },
+ {
+ property: "actions", title: "Actions", type: ColumnType.custom, customControl: ({ rowData }) => {
+ counter++;
+ return (
+ <>
+ <div className={classes.spacer}>
+ {
+ rowData.webUri && <Tooltip title={"Web Client"} ><IconButton aria-label={"web-client-button-" + counter} className={classes.button} onClick={event => { console.log(rowData); window.open(rowData.webUri, "_blank") }}><ComputerIcon /></IconButton></Tooltip>
+ }
+ <Tooltip title={"Mount"} >
+ <IconButton aria-label={"mount-button-" + counter} className={classes.button} onClick={event => this.onOpenMountdNetworkElementsDialog(event, rowData)} >
+ <LinkIcon /></IconButton>
+ </Tooltip>
+ <Tooltip title={"Unmount"} >
+ <IconButton aria-label={"unmount-button-" + counter} className={classes.button} onClick={event => this.onOpenUnmountdNetworkElementsDialog(event, rowData)} >
+ <LinkOffIcon /></IconButton>
+ </Tooltip>
+ <Tooltip title={"Info"} ><IconButton aria-label={"info-button-" + counter} className={classes.button} onClick={event => this.onOpenInfoNetworkElementDialog(event, rowData)} disabled={rowData.status === "Connecting" || rowData.status === "Disconnected"} >
+ <Info /></IconButton>
+ </Tooltip>
+ <Tooltip title={"Edit"} ><IconButton aria-label={"edit-button-" + counter} className={classes.button} onClick={event => this.onOpenEditNetworkElementDialog(event, rowData)} ><EditIcon /></IconButton></Tooltip>
+ <Tooltip title={"Remove"} ><IconButton aria-label={"remove-button-" + counter} className={classes.button} onClick={event => this.onOpenRemoveNetworkElementDialog(event, rowData)} ><RemoveIcon /></IconButton></Tooltip>
+ </div>
+ <div className={classes.spacer}>
+ <Tooltip title={"Inventory"} ><Button aria-label={"inventory-button-" + counter} className={classes.button} onClick={this.navigateToApplicationHandlerCreator("inventory", rowData)} >I</Button></Tooltip>
+ </div>
+ <div className={classes.spacer}>
+ <Tooltip title={"Fault"} ><Button aria-label={"fault-button-" + counter} className={classes.button} onClick={this.navigateToApplicationHandlerCreator("fault", rowData)} >F</Button></Tooltip>
+ <Tooltip title={"Configure"} ><Button aria-label={"configure-button-" + counter} className={classes.button} onClick={this.navigateToApplicationHandlerCreator("configuration", rowData)} >C</Button></Tooltip>
+ <Tooltip title={"Accounting "} ><Button className={classes.button} onClick={this.navigateToApplicationHandlerCreator("accounting", rowData)} disabled={true} >A</Button></Tooltip>
+ <Tooltip title={"Performance"} ><Button aria-label={"performance-button-" + counter} className={classes.button} onClick={this.navigateToApplicationHandlerCreator("performanceHistory", rowData)}>P</Button></Tooltip>
+ <Tooltip title={"Security"} ><Button className={classes.button} onClick={this.navigateToApplicationHandlerCreator("security", rowData)} disabled={true} >S</Button></Tooltip>
+ </div>
+ </>
+ )
+ }
+ },
+ ]} idProperty="id" {...this.props.networkElementsActions} {...this.props.networkElementsProperties} asynchronus >
+ </NetworkElementTable>
+ <EditNetworkElementDialog
+ initialNetworkElement={networkElementToEdit}
+ mode={this.state.networkElementEditorMode}
+ onClose={this.onCloseEditNetworkElementDialog}
+ />
+ <InfoNetworkElementDialog
+ initialNetworkElement={networkElementToEdit}
+ mode={this.state.infoNetworkElementEditorMode}
+ onClose={this.onCloseInfoNetworkElementDialog}
+ />
+ </>
+ );
+ };
+
+ public componentDidMount() {
+ this.props.networkElementsActions.onRefresh();
+ }
+
+ private onOpenRemoveNetworkElementDialog = (event: React.MouseEvent<HTMLElement>, element: NetworkElementConnection) => {
+ this.setState({
+ networkElementToEdit: element,
+ networkElementEditorMode: EditNetworkElementDialogMode.RemoveNetworkElement
+ });
+ event.preventDefault();
+ event.stopPropagation();
+ }
+
+ private onOpenEditNetworkElementDialog = (event: React.MouseEvent<HTMLElement>, element: NetworkElementConnection) => {
+ this.setState({
+ networkElementToEdit: {
+ nodeId: element.nodeId,
+ isRequired: element.isRequired,
+ host: element.host,
+ port: element.port,
+ username: element.username,
+ password: element.password,
+ },
+ networkElementEditorMode: EditNetworkElementDialogMode.EditNetworkElement
+ });
+ event.preventDefault();
+ event.stopPropagation();
+ }
+
+ private onOpenUnmountdNetworkElementsDialog = (event: React.MouseEvent<HTMLElement>, element: NetworkElementConnection) => {
+ this.setState({
+ networkElementToEdit: element,
+ networkElementEditorMode: EditNetworkElementDialogMode.UnmountNetworkElement
+ });
+ event.preventDefault();
+ event.stopPropagation();
+ }
+
+ private onOpenMountdNetworkElementsDialog = (event: React.MouseEvent<HTMLElement>, element: NetworkElementConnection) => {
+ this.setState({
+ networkElementToEdit: element,
+ networkElementEditorMode: EditNetworkElementDialogMode.MountNetworkElement
+ });
+ event.preventDefault();
+ event.stopPropagation();
+ }
+
+ private onOpenInfoNetworkElementDialog = (event: React.MouseEvent<HTMLElement>, element: NetworkElementConnection) => {
+ this.props.networkElementInfo(element.nodeId);
+ this.setState({
+ networkElementToEdit: element,
+ infoNetworkElementEditorMode: InfoNetworkElementDialogMode.InfoNetworkElement,
+ });
+ event.preventDefault();
+ event.stopPropagation();
+ }
+
+ private onCloseEditNetworkElementDialog = () => {
+ this.setState({
+ networkElementEditorMode: EditNetworkElementDialogMode.None,
+ networkElementToEdit: emptyRequireNetworkElement,
+ });
+ }
+ private onCloseInfoNetworkElementDialog = () => {
+ this.setState({
+ infoNetworkElementEditorMode: InfoNetworkElementDialogMode.None,
+ networkElementToEdit: emptyRequireNetworkElement,
+ });
+ }
+
+ private navigateToApplicationHandlerCreator = (applicationName: string, element: NetworkElementConnection) => (event: React.MouseEvent<HTMLElement>) => {
+ this.props.navigateToApplication(applicationName, element.nodeId);
+ event.preventDefault();
+ event.stopPropagation();
+ }
+}
+
+export const NetworkElementsList = withStyles(styles)(connect(mapProps, mapDispatch)(NetworkElementsListComponent));
+export default NetworkElementsList; \ No newline at end of file
diff --git a/sdnr/wt/odlux/apps/connectApp/src/components/requiredNetworkElements.tsx b/sdnr/wt/odlux/apps/connectApp/src/components/requiredNetworkElements.tsx
deleted file mode 100644
index 2fb7594aa..000000000
--- a/sdnr/wt/odlux/apps/connectApp/src/components/requiredNetworkElements.tsx
+++ /dev/null
@@ -1,210 +0,0 @@
-/**
- * ============LICENSE_START========================================================================
- * ONAP : ccsdk feature sdnr wt odlux
- * =================================================================================================
- * Copyright (C) 2019 highstreet technologies GmbH Intellectual Property. All rights reserved.
- * =================================================================================================
- * 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.
- * ============LICENSE_END==========================================================================
- */
-import * as React from 'react';
-import { Theme, createStyles, withStyles, WithStyles } from '@material-ui/core/styles';
-
-import AddIcon from '@material-ui/icons/Add';
-import LinkIcon from '@material-ui/icons/Link';
-import LinkOffIcon from '@material-ui/icons/LinkOff';
-import RemoveIcon from '@material-ui/icons/RemoveCircleOutline';
-
-import Button from '@material-ui/core/Button';
-import IconButton from '@material-ui/core/IconButton';
-
-import { MaterialTable, ColumnType, MaterialTableCtorType } from '../../../../framework/src/components/material-table';
-import { IApplicationStoreState } from '../../../../framework/src/store/applicationStore';
-import { connect, Connect, IDispatcher } from '../../../../framework/src/flux/connect';
-import { NavigateToApplication } from '../../../../framework/src/actions/navigationActions';
-
-import { RequiredNetworkElementType } from '../models/requiredNetworkElements';
-import { createRequiredNetworkElementsActions, createRequiredNetworkElementsProperties } from '../handlers/requiredNetworkElementsHandler';
-
-import EditNetworkElementDialog, { EditNetworkElementDialogMode } from './editNetworkElementDialog';
-import { Tooltip } from '@material-ui/core';
-import { NetworkElementBaseType } from 'models/networkElementBase';
-
-const styles = (theme: Theme) => createStyles({
- connectionStatusConnected: {
- color: 'darkgreen',
- },
- connectionStatusConnecting: {
- color: 'blue',
- },
- connectionStatusDisconnected: {
- color: 'red',
- },
- button: {
- margin: 0,
- padding: "6px 6px",
- minWidth: 'unset'
- },
- spacer: {
- marginLeft: theme.spacing.unit,
- marginRight: theme.spacing.unit,
- display: "inline"
- }
-});
-
-const mapProps = (state: IApplicationStoreState) => ({
- requiredNetworkElementsProperties: createRequiredNetworkElementsProperties(state),
- mountedNetworkElements: state.connect.mountedNetworkElements
-});
-
-const mapDispatch = (dispatcher: IDispatcher) => ({
- requiredNetworkElementsActions: createRequiredNetworkElementsActions(dispatcher.dispatch),
- navigateToApplication: (applicationName: string, path?: string) => dispatcher.dispatch(new NavigateToApplication(applicationName, path)),
-});
-
-type RequiredNetworkElementsListComponentProps = WithStyles<typeof styles> & Connect<typeof mapProps, typeof mapDispatch>;
-type RequiredNetworkElementsListComponentState = {
- networkElementToEdit: RequiredNetworkElementType,
- networkElementEditorMode: EditNetworkElementDialogMode
-}
-
-const emptyRequireNetworkElement = { mountId: '', host: '', port: 0 };
-
-const RequiredNetworkElementTable = MaterialTable as MaterialTableCtorType<RequiredNetworkElementType>;
-
-export class RequiredNetworkElementsListComponent extends React.Component<RequiredNetworkElementsListComponentProps, RequiredNetworkElementsListComponentState> {
-
- constructor(props: RequiredNetworkElementsListComponentProps) {
- super(props);
-
- this.state = {
- networkElementToEdit: emptyRequireNetworkElement,
- networkElementEditorMode: EditNetworkElementDialogMode.None
- };
- }
-
- // private navigationCreator
-
- render(): JSX.Element {
- const { classes } = this.props;
- const { networkElementToEdit } = this.state;
- const addRequireNetworkElementAction = {
- icon: AddIcon, tooltip: 'Add', onClick: () => {
- this.setState({
- networkElementEditorMode: EditNetworkElementDialogMode.MountNetworkElementToRequiredNetworkElements,
- networkElementToEdit: emptyRequireNetworkElement,
- });
- }
- };
- return (
- <>
- <RequiredNetworkElementTable customActionButtons={ [addRequireNetworkElementAction] } columns={ [
- { property: "mountId", title: "Name", type: ColumnType.text },
- {
- property: "connectionStatus", title: "Connection Status", type: ColumnType.custom, disableFilter: true, disableSorting: true, customControl: ({ rowData }) => {
- const unknownNetworkElement = this.props.mountedNetworkElements.elements.find(el => el.mountId === rowData.mountId);
- const connectionStatus = unknownNetworkElement && unknownNetworkElement.connectionStatus || 'disconnected';
- const cssClasses = connectionStatus === "connected"
- ? classes.connectionStatusConnected
- : connectionStatus === "disconnected"
- ? classes.connectionStatusDisconnected
- : classes.connectionStatusConnecting
- return <div className={ cssClasses } >{ connectionStatus } </div>
-
- }
- },
- { property: "host", title: "Host", type: ColumnType.text },
- { property: "port", title: "Port", type: ColumnType.text },
- // { property: "username", title: "Username", type: ColumnType.text },
- // { property: "password", title: "Password", type: ColumnType.text },
- {
- property: "actions", title: "Actions", type: ColumnType.custom, customControl: ({ rowData }) => {
- const unknownNetworkElement = this.props.mountedNetworkElements.elements.find(el => el.mountId === rowData.mountId);
- const connectionStatus = unknownNetworkElement && unknownNetworkElement.connectionStatus || 'disconnected';
- return (
- <>
- <div className={ classes.spacer }>
- <Tooltip title={ "Mount" } ><IconButton className={ classes.button } onClick={ event => this.onOpenMountdNetworkElementsDialog(event, rowData) }><LinkIcon /></IconButton></Tooltip>
- <Tooltip title={ "Unmount" } ><IconButton className={ classes.button } onClick={ event => this.onOpenUnmountdNetworkElementsDialog(event, rowData) }><LinkOffIcon /></IconButton></Tooltip>
- <Tooltip title={ "Remove" } ><IconButton className={ classes.button } onClick={ event => this.onOpenRemoveRequiredNetworkElementDialog(event, rowData) } ><RemoveIcon /></IconButton></Tooltip>
- </div>
- <div className={ classes.spacer }>
- <Tooltip title={ "Info" } ><Button className={ classes.button } >I</Button></Tooltip>
- </div>
- <div className={ classes.spacer }>
- <Tooltip title={ "Fault" } ><Button className={ classes.button } onClick={ this.navigateToApplicationHandlerCreator("fault", rowData) } >F</Button></Tooltip>
- <Tooltip title={"Configure"} ><Button className={classes.button} onClick={this.navigateToApplicationHandlerCreator("configuration", rowData)} >C</Button></Tooltip>
- <Tooltip title={ "Accounting " } ><Button className={ classes.button } onClick={ this.navigateToApplicationHandlerCreator("accounting", rowData) }>A</Button></Tooltip>
- <Tooltip title={ "Performance" } ><Button className={ classes.button } onClick={ this.navigateToApplicationHandlerCreator("performance", rowData) }>P</Button></Tooltip>
- <Tooltip title={ "Security" } ><Button className={ classes.button } onClick={ this.navigateToApplicationHandlerCreator("security", rowData) }>S</Button></Tooltip>
- </div>
- </>
- )
- }
- },
- ] } idProperty="mountId" { ...this.props.requiredNetworkElementsActions } { ...this.props.requiredNetworkElementsProperties } asynchronus >
- </RequiredNetworkElementTable>
- <EditNetworkElementDialog
- initialNetworkElement={ networkElementToEdit }
- mode={ this.state.networkElementEditorMode }
- onClose={ this.onCloseEditNetworkElementDialog }
- />
- </>
- );
- };
-
- public componentDidMount() {
- this.props.requiredNetworkElementsActions.onRefresh();
- }
-
- private onOpenRemoveRequiredNetworkElementDialog = (event: React.MouseEvent<HTMLElement>, element: RequiredNetworkElementType) => {
- this.setState({
- networkElementToEdit: element,
- networkElementEditorMode: EditNetworkElementDialogMode.RequiredNetworkElementToUnknownNetworkElements
- });
- event.preventDefault();
- event.stopPropagation();
- }
-
- private onOpenUnmountdNetworkElementsDialog = (event: React.MouseEvent<HTMLElement>, element: RequiredNetworkElementType) => {
- this.setState({
- networkElementToEdit: element,
- networkElementEditorMode: EditNetworkElementDialogMode.UnmountNetworkElement
- });
- event.preventDefault();
- event.stopPropagation();
- }
-
- private onOpenMountdNetworkElementsDialog = (event: React.MouseEvent<HTMLElement>, element: RequiredNetworkElementType) => {
- this.setState({
- networkElementToEdit: element,
- networkElementEditorMode: EditNetworkElementDialogMode.MountNetworkElement
- });
- event.preventDefault();
- event.stopPropagation();
- }
-
- private onCloseEditNetworkElementDialog = () => {
- this.setState({
- networkElementEditorMode: EditNetworkElementDialogMode.None,
- networkElementToEdit: emptyRequireNetworkElement,
- });
- }
-
- private navigateToApplicationHandlerCreator = (applicationName: string, element: NetworkElementBaseType) => (event: React.MouseEvent<HTMLElement>) => {
- this.props.navigateToApplication(applicationName, element.mountId);
- event.preventDefault();
- event.stopPropagation();
- }
-}
-
-export const RequiredNetworkElementsList = withStyles(styles)(connect(mapProps, mapDispatch)(RequiredNetworkElementsListComponent));
-export default RequiredNetworkElementsList; \ No newline at end of file
diff --git a/sdnr/wt/odlux/apps/connectApp/src/components/unknownNetworkElements.tsx b/sdnr/wt/odlux/apps/connectApp/src/components/unknownNetworkElements.tsx
deleted file mode 100644
index 62b969575..000000000
--- a/sdnr/wt/odlux/apps/connectApp/src/components/unknownNetworkElements.tsx
+++ /dev/null
@@ -1,211 +0,0 @@
-/**
- * ============LICENSE_START========================================================================
- * ONAP : ccsdk feature sdnr wt odlux
- * =================================================================================================
- * Copyright (C) 2019 highstreet technologies GmbH Intellectual Property. All rights reserved.
- * =================================================================================================
- * 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.
- * ============LICENSE_END==========================================================================
- */
-import * as React from 'react';
-import { Theme, createStyles, WithStyles, withStyles, Tooltip } from '@material-ui/core';
-
-import AddIcon from '@material-ui/icons/Add';
-import LinkOffIcon from '@material-ui/icons/LinkOff';
-import AddCircleIcon from '@material-ui/icons/AddCircleOutline';
-
-import Button from '@material-ui/core/Button';
-import IconButton from '@material-ui/core/IconButton';
-
-import { IApplicationStoreState } from '../../../../framework/src/store/applicationStore';
-import { MaterialTable, ColumnType, MaterialTableCtorType } from '../../../../framework/src/components/material-table';
-import { Connect, connect, IDispatcher } from '../../../../framework/src/flux/connect';
-import { NavigateToApplication } from '../../../../framework/src/actions/navigationActions';
-
-import { RequiredNetworkElementType } from '../models/requiredNetworkElements';
-import { IMountedNetworkElementsState } from '../handlers/mountedNetworkElementsHandler';
-import EditNetworkElementDialog, { EditNetworkElementDialogMode } from './editNetworkElementDialog';
-import { NetworkElementBaseType } from 'models/networkElementBase';
-
-
-const styles = (theme: Theme) => createStyles({
- button: {
- margin: 0,
- padding: "6px 6px",
- minWidth: 'unset'
- },
- spacer: {
- marginLeft: theme.spacing.unit,
- marginRight: theme.spacing.unit,
- display: "inline"
- }
-});
-
-const mapProps = ({ connect: state }: IApplicationStoreState) => ({
- mountedNetworkElements: state.mountedNetworkElements
-});
-
-const mapDispatch = (dispatcher: IDispatcher) => ({
- navigateToApplication: (applicationName: string, path?: string) => dispatcher.dispatch(new NavigateToApplication(applicationName, path)),
-});
-type UnknownNetworkElementDisplayType = NetworkElementBaseType & {
- connectionStatus: string,
- coreModelRev: string,
- airInterfaceRev: string
-}
-
-type UnknownNetworkElementsListProps = WithStyles<typeof styles> & Connect<typeof mapProps, typeof mapDispatch> & {}
-
-type UnknownNetworkElementsListState = {
-
- unknownNetworkElements: UnknownNetworkElementDisplayType[];
-
- networkElementToEdit: RequiredNetworkElementType;
- networkElementEditorMode: EditNetworkElementDialogMode;
-}
-
-
-const emptyRequireNetworkElement = { mountId: '', host: '', port: 0 };
-const UnknownNetworkElementTable = MaterialTable as MaterialTableCtorType<UnknownNetworkElementDisplayType>;
-export class UnknownNetworkElementsListComponent extends React.Component<UnknownNetworkElementsListProps, UnknownNetworkElementsListState> {
-
- constructor(props: UnknownNetworkElementsListProps) {
- super(props);
-
- this.state = {
- unknownNetworkElements: [],
- networkElementToEdit: emptyRequireNetworkElement,
- networkElementEditorMode: EditNetworkElementDialogMode.None,
- };
- }
-
- static getDerivedStateFromProps(props: UnknownNetworkElementsListProps, state: UnknownNetworkElementsListState & { _mountedNetworkElements: IMountedNetworkElementsState }) {
- if (props.mountedNetworkElements != state._mountedNetworkElements) {
- state.unknownNetworkElements = props.mountedNetworkElements.elements.filter(element => !element.required).map(element => {
-
- // handle onfCoreModelRevision
- const onfCoreModelRevision = element.capabilities.find((cap) => {
- return cap.module === 'core-model' || cap.module === 'CoreModel-CoreNetworkModule-ObjectClasses' ;
- });
- const onfAirInterfaceRevision = element.capabilities.find((cap) => {
- return cap.module === 'microwave-model' || cap.module === 'MicrowaveModel-ObjectClasses-AirInterface' ;
- });
- return {
- mountId: element.mountId,
- host: element.host,
- port: element.port,
- connectionStatus: element.connectionStatus,
- coreModelRev: onfCoreModelRevision && onfCoreModelRevision.revision || 'unknown',
- airInterfaceRev: onfAirInterfaceRevision && onfAirInterfaceRevision.revision || 'unknown'
- }
- }
- );
- }
- return state;
- }
-
- render(): JSX.Element {
- const { classes } = this.props;
- const { networkElementToEdit, networkElementEditorMode, unknownNetworkElements } = this.state;
- const addRequireNetworkElementAction = {
- icon: AddIcon, tooltip: 'Add', onClick: () => {
- this.setState({
- networkElementEditorMode: EditNetworkElementDialogMode.MountNetworkElementToUnknonwNetworkElements,
- networkElementToEdit: emptyRequireNetworkElement,
- });
- }
- };
- return (
- <>
- <UnknownNetworkElementTable customActionButtons={ [addRequireNetworkElementAction] } asynchronus rows={ unknownNetworkElements } columns={ [
- { property: "mountId", title: "Name", type: ColumnType.text },
- { property: "connectionStatus", title: "Connection Status", type: ColumnType.text },
- { property: "host", title: "Host", type: ColumnType.text },
- { property: "port", title: "Port", type: ColumnType.text },
- { property: "coreModelRev", title: "Core Model", type: ColumnType.text },
- { property: "airInterfaceRev", title: "Air interface", type: ColumnType.text },
- {
- property: "actions", title: "Actions", type: ColumnType.custom, customControl: ({ rowData }) => (
- <>
- <div className={ classes.spacer }>
- <Tooltip title={ "Unmount" } ><IconButton className={ classes.button } onClick={ event => this.onOpenUnmountdNetworkElementsDialog(event, rowData) } ><LinkOffIcon /></IconButton></Tooltip>
- <Tooltip title={ "Add to required" } ><IconButton className={ classes.button } onClick={ event => this.onOpenAddToRequiredNetworkElementsDialog(event, rowData) } ><AddCircleIcon /></IconButton></Tooltip>
- </div>
- <div className={ classes.spacer }>
- <Tooltip title={ "Info" } ><Button className={ classes.button } >I</Button></Tooltip>
- </div>
- <div className={ classes.spacer }>
- <Tooltip title={ "Fault" } ><Button className={ classes.button } onClick={ this.navigateToApplicationHandlerCreator("fault", rowData) } >F</Button></Tooltip>
- <Tooltip title={ "Configure" } ><Button className={ classes.button } onClick={ this.navigateToApplicationHandlerCreator("configuration", rowData) } >C</Button></Tooltip>
- <Tooltip title={ "Accounting " } ><Button className={ classes.button } onClick={ this.navigateToApplicationHandlerCreator("accounting", rowData) }>A</Button></Tooltip>
- <Tooltip title={ "Performance" } ><Button className={ classes.button } onClick={ this.navigateToApplicationHandlerCreator("performance", rowData) }>P</Button></Tooltip>
- <Tooltip title={ "Security" } ><Button className={ classes.button } onClick={ this.navigateToApplicationHandlerCreator("security", rowData) }>S</Button></Tooltip>
- </div>
- </>
- )
- },
- ] } idProperty="mountId" >
- </UnknownNetworkElementTable>
-
- <EditNetworkElementDialog
- mode={ networkElementEditorMode }
- initialNetworkElement={ networkElementToEdit }
- onClose={ this.onCloseEditNetworkElementDialog }
- />
- </>
- );
- };
-
- private onOpenAddToRequiredNetworkElementsDialog = (event: React.MouseEvent<HTMLElement>, element: UnknownNetworkElementDisplayType) => {
- this.setState({
- networkElementToEdit: {
- mountId: element.mountId,
- host: element.host,
- port: element.port,
- username: 'admin',
- password: 'admin',
- },
- networkElementEditorMode: EditNetworkElementDialogMode.UnknownNetworkElementToRequiredNetworkElements
- });
- event.preventDefault();
- event.stopPropagation();
- }
-
- private onOpenUnmountdNetworkElementsDialog = (event: React.MouseEvent<HTMLElement>, element: UnknownNetworkElementDisplayType) => {
- this.setState({
- networkElementToEdit: {
- mountId: element.mountId,
- host: element.host,
- port: element.port
- },
- networkElementEditorMode: EditNetworkElementDialogMode.UnmountNetworkElement
- });
- event.preventDefault();
- event.stopPropagation();
- }
-
- private onCloseEditNetworkElementDialog = () => {
- this.setState({
- networkElementEditorMode: EditNetworkElementDialogMode.None,
- networkElementToEdit: emptyRequireNetworkElement,
- });
- }
-
- private navigateToApplicationHandlerCreator = (applicationName: string, element: NetworkElementBaseType) => (event: React.MouseEvent<HTMLElement>) => {
- this.props.navigateToApplication(applicationName, element.mountId);
- event.preventDefault();
- event.stopPropagation();
- }
-
-}
-
-export const UnknownNetworkElementsList = withStyles(styles)(connect(mapProps, mapDispatch)(UnknownNetworkElementsListComponent));
-export default UnknownNetworkElementsList;
diff --git a/sdnr/wt/odlux/apps/connectApp/src/handlers/connectAppRootHandler.ts b/sdnr/wt/odlux/apps/connectApp/src/handlers/connectAppRootHandler.ts
new file mode 100644
index 000000000..1440599fd
--- /dev/null
+++ b/sdnr/wt/odlux/apps/connectApp/src/handlers/connectAppRootHandler.ts
@@ -0,0 +1,83 @@
+/**
+ * ============LICENSE_START========================================================================
+ * ONAP : ccsdk feature sdnr wt odlux
+ * =================================================================================================
+ * Copyright (C) 2019 highstreet technologies GmbH Intellectual Property. All rights reserved.
+ * =================================================================================================
+ * 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.
+ * ============LICENSE_END==========================================================================
+ */
+
+import { IActionHandler } from '../../../../framework/src/flux/action';
+import { combineActionHandler } from '../../../../framework/src/flux/middleware';
+import { INetworkElementsState, networkElementsActionHandler } from './networkElementsHandler';
+import { IConnectionStatusLogState, connectionStatusLogActionHandler } from './connectionStatusLogHandler';
+import { IInfoNetworkElementsState, infoNetworkElementsActionHandler } from './infoNetworkElementHandler';
+import { SetPanelAction, AddWebUriList, RemoveWebUri } from '../actions/commonNetworkElementsActions';
+import { PanelId } from '../models/panelId';
+import { guiCutThrough } from '../models/guiCutTrough';
+
+export interface IConnectAppStoreState {
+ networkElements: INetworkElementsState;
+ connectionStatusLog: IConnectionStatusLogState;
+ currentOpenPanel: PanelId;
+ elementInfo: IInfoNetworkElementsState;
+ guiCutThrough: guiCutThroughState;
+}
+
+const currentOpenPanelHandler: IActionHandler<PanelId> = (state = null, action) => {
+ if (action instanceof SetPanelAction) {
+ state = action.panelId;
+ }
+ return state;
+}
+
+interface guiCutThroughState {
+ availableWebUris: guiCutThrough[];
+ knownElements: string[];
+}
+
+const guiCutThroughHandler: IActionHandler<guiCutThroughState> = (state = { availableWebUris: [], knownElements: [] }, action) => {
+ if (action instanceof AddWebUriList) {
+ let knownElements: string[];
+ let availableWebUris: guiCutThrough[];
+
+ knownElements = state.knownElements.concat(action.knownElements);
+
+ availableWebUris = state.availableWebUris.concat(action.element);
+
+ state = { availableWebUris: availableWebUris, knownElements: knownElements }
+
+ } else if (action instanceof RemoveWebUri) {
+ const nodeId = action.element;
+ const webUris = state.availableWebUris.filter(item => item.nodeId !== nodeId);
+ const knownElements = state.knownElements.filter(item => item !== nodeId);
+ state = { knownElements: knownElements, availableWebUris: webUris };
+ }
+ return state;
+}
+
+declare module '../../../../framework/src/store/applicationStore' {
+ interface IApplicationStoreState {
+ connect: IConnectAppStoreState
+ }
+}
+
+const actionHandlers = {
+ networkElements: networkElementsActionHandler,
+ connectionStatusLog: connectionStatusLogActionHandler,
+ currentOpenPanel: currentOpenPanelHandler,
+ elementInfo: infoNetworkElementsActionHandler,
+ guiCutThrough: guiCutThroughHandler
+};
+
+export const connectAppRootHandler = combineActionHandler<IConnectAppStoreState>(actionHandlers);
+export default connectAppRootHandler;
diff --git a/sdnr/wt/odlux/apps/connectApp/src/handlers/connectAppRootHandler.tsx b/sdnr/wt/odlux/apps/connectApp/src/handlers/connectAppRootHandler.tsx
deleted file mode 100644
index 1c27f4b32..000000000
--- a/sdnr/wt/odlux/apps/connectApp/src/handlers/connectAppRootHandler.tsx
+++ /dev/null
@@ -1,42 +0,0 @@
-/**
- * ============LICENSE_START========================================================================
- * ONAP : ccsdk feature sdnr wt odlux
- * =================================================================================================
- * Copyright (C) 2019 highstreet technologies GmbH Intellectual Property. All rights reserved.
- * =================================================================================================
- * 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.
- * ============LICENSE_END==========================================================================
- */
-import { combineActionHandler } from '../../../../framework/src/flux/middleware';
-import { IRequiredNetworkElementsState, requiredNetworkElementsActionHandler } from './requiredNetworkElementsHandler';
-import { IMountedNetworkElementsState, mountedNetworkElementsActionHandler } from './mountedNetworkElementsHandler';
-import { IConnectionStatusLogState, connectionStatusLogActionHandler } from './connectionStatusLogHandler';
-
-export interface IConnectAppStoreState {
- requiredNetworkElements: IRequiredNetworkElementsState;
- mountedNetworkElements: IMountedNetworkElementsState;
- connectionStatusLog: IConnectionStatusLogState;
-}
-
-declare module '../../../../framework/src/store/applicationStore' {
- interface IApplicationStoreState {
- connect: IConnectAppStoreState
- }
-}
-
-const actionHandlers = {
- requiredNetworkElements: requiredNetworkElementsActionHandler,
- mountedNetworkElements: mountedNetworkElementsActionHandler,
- connectionStatusLog: connectionStatusLogActionHandler
-};
-
-export const connectAppRootHandler = combineActionHandler <IConnectAppStoreState>(actionHandlers);
-export default connectAppRootHandler;
diff --git a/sdnr/wt/odlux/apps/connectApp/src/handlers/requiredNetworkElementsHandler.tsx b/sdnr/wt/odlux/apps/connectApp/src/handlers/connectionStatusLogHandler.ts
index 10b3b1b07..6863ec33b 100644
--- a/sdnr/wt/odlux/apps/connectApp/src/handlers/requiredNetworkElementsHandler.tsx
+++ b/sdnr/wt/odlux/apps/connectApp/src/handlers/connectionStatusLogHandler.ts
@@ -18,18 +18,18 @@
import { createExternal,IExternalTableState } from '../../../../framework/src/components/material-table/utilities';
import { createSearchDataHandler } from '../../../../framework/src/utilities/elasticSearch';
-import { RequiredNetworkElementType } from '../models/requiredNetworkElements';
-export interface IRequiredNetworkElementsState extends IExternalTableState<RequiredNetworkElementType> { }
+import { NetworkElementConnectionLog } from '../models/networkElementConnectionLog';
+export interface IConnectionStatusLogState extends IExternalTableState<NetworkElementConnectionLog> { }
// create eleactic search material data fetch handler
-const requiredNetworkElementsSearchHandler = createSearchDataHandler<RequiredNetworkElementType>('mwtn/required-networkelement');
+const connectionStatusLogSearchHandler = createSearchDataHandler<NetworkElementConnectionLog>('connectionlog');
export const {
- actionHandler: requiredNetworkElementsActionHandler,
- createActions: createRequiredNetworkElementsActions,
- createProperties: createRequiredNetworkElementsProperties,
- reloadAction: requiredNetworkElementsReloadAction,
+ actionHandler: connectionStatusLogActionHandler,
+ createActions: createConnectionStatusLogActions,
+ createProperties: createConnectionStatusLogProperties,
+ reloadAction: connectionStatusLogReloadAction,
// set value action, to change a value
-} = createExternal<RequiredNetworkElementType>(requiredNetworkElementsSearchHandler, appState => appState.connect.requiredNetworkElements);
+} = createExternal<NetworkElementConnectionLog>(connectionStatusLogSearchHandler, appState => appState.connect.connectionStatusLog);
diff --git a/sdnr/wt/odlux/apps/connectApp/src/handlers/connectionStatusLogHandler.tsx b/sdnr/wt/odlux/apps/connectApp/src/handlers/connectionStatusLogHandler.tsx
deleted file mode 100644
index 57e1930ed..000000000
--- a/sdnr/wt/odlux/apps/connectApp/src/handlers/connectionStatusLogHandler.tsx
+++ /dev/null
@@ -1,51 +0,0 @@
-/**
- * ============LICENSE_START========================================================================
- * ONAP : ccsdk feature sdnr wt odlux
- * =================================================================================================
- * Copyright (C) 2019 highstreet technologies GmbH Intellectual Property. All rights reserved.
- * =================================================================================================
- * 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.
- * ============LICENSE_END==========================================================================
- */
-import { createExternal,IExternalTableState } from '../../../../framework/src/components/material-table/utilities';
-import { createSearchDataHandler } from '../../../../framework/src/utilities/elasticSearch';
-
-import { ConnectionStatusLogType } from '../models/connectionStatusLog';
-export interface IConnectionStatusLogState extends IExternalTableState<ConnectionStatusLogType> { }
-
-// create eleactic search material data fetch handler
-const connectionStatusLogSearchHandler = createSearchDataHandler<{ event: ConnectionStatusLogType }, ConnectionStatusLogType>('sdnevents_v1/eventlog', null,
- (event) => ({
- _id: event._id,
- timeStamp: event._source.event.timeStamp,
- objectId: event._source.event.objectId,
- type: event._source.event.type,
- elementStatus: event._source.event.type === 'ObjectCreationNotificationXml'
- ? 'mounted'
- : event._source.event.type === 'ObjectDeletionNotificationXml'
- ? 'unmounted'
- : event._source.event.type === 'AttributeValueChangedNotificationXml'
- ? event._source.event.newValue
- : 'unknown',
- newValue: ''
-
- }),
- (name) => `event.${ name }`);
-
-export const {
- actionHandler: connectionStatusLogActionHandler,
- createActions: createConnectionStatusLogActions,
- createProperties: createConnectionStatusLogProperties,
- reloadAction: connectionStatusLogReloadAction,
-
- // set value action, to change a value
-} = createExternal<ConnectionStatusLogType>(connectionStatusLogSearchHandler, appState => appState.connect.connectionStatusLog);
-
diff --git a/sdnr/wt/odlux/apps/connectApp/src/handlers/infoNetworkElementHandler.ts b/sdnr/wt/odlux/apps/connectApp/src/handlers/infoNetworkElementHandler.ts
new file mode 100644
index 000000000..d67a81ec4
--- /dev/null
+++ b/sdnr/wt/odlux/apps/connectApp/src/handlers/infoNetworkElementHandler.ts
@@ -0,0 +1,60 @@
+/**
+ * ============LICENSE_START========================================================================
+ * ONAP : ccsdk feature sdnr wt odlux
+ * =================================================================================================
+ * Copyright (C) 2019 highstreet technologies GmbH Intellectual Property. All rights reserved.
+ * =================================================================================================
+ * 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.
+ * ============LICENSE_END==========================================================================
+ */
+import { IActionHandler } from '../../../../framework/src/flux/action';
+
+import { AllElementInfoLoadedAction, LoadAllElementInfoAction } from '../actions/infoNetworkElementActions';
+
+import { TopologyNode } from '../models/topologyNetconf';
+
+export interface IInfoNetworkElementsState {
+ elementInfo: TopologyNode;
+ busy: boolean;
+}
+
+const infoNetworkElementsStateInit: IInfoNetworkElementsState = {
+ elementInfo: {
+ "node-id": "",
+ "netconf-node-topology:available-capabilities": {
+ "available-capability": []
+ }
+ },
+ busy: false
+};
+
+export const infoNetworkElementsActionHandler: IActionHandler<IInfoNetworkElementsState> = (state = infoNetworkElementsStateInit, action) => {
+ if (action instanceof LoadAllElementInfoAction) {
+ state = {
+ ...state,
+ busy: true
+ };
+ } else if (action instanceof AllElementInfoLoadedAction) {
+ if (!action.error && action.elementInfo) {
+ state = {
+ ...state,
+ elementInfo: action.elementInfo,
+ busy: false
+ };
+ } else {
+ state = {
+ ...state,
+ busy: false
+ };
+ }
+ }
+ return state;
+}; \ No newline at end of file
diff --git a/sdnr/wt/odlux/apps/connectApp/src/handlers/mountedNetworkElementsHandler.tsx b/sdnr/wt/odlux/apps/connectApp/src/handlers/mountedNetworkElementsHandler.tsx
deleted file mode 100644
index 089268946..000000000
--- a/sdnr/wt/odlux/apps/connectApp/src/handlers/mountedNetworkElementsHandler.tsx
+++ /dev/null
@@ -1,111 +0,0 @@
-/**
- * ============LICENSE_START========================================================================
- * ONAP : ccsdk feature sdnr wt odlux
- * =================================================================================================
- * Copyright (C) 2019 highstreet technologies GmbH Intellectual Property. All rights reserved.
- * =================================================================================================
- * 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.
- * ============LICENSE_END==========================================================================
- */
-import { IActionHandler } from '../../../../framework/src/flux/action';
-
-import {
- AddOrUpdateMountedNetworkElement,
- AllMountedNetworkElementsLoadedAction,
- LoadAllMountedNetworkElementsAction,
- RemoveMountedNetworkElement,
- UpdateConnectionStateMountedNetworkElement,
- UpdateRequiredMountedNetworkElement
-} from '../actions/mountedNetworkElementsActions';
-
-import { MountedNetworkElementType } from '../models/mountedNetworkElements';
-
-export interface IMountedNetworkElementsState {
- elements: MountedNetworkElementType[];
- busy: boolean;
-}
-
-const mountedNetworkElementsStateInit: IMountedNetworkElementsState = {
- elements: [],
- busy: false
-};
-
-export const mountedNetworkElementsActionHandler: IActionHandler<IMountedNetworkElementsState> = (state = mountedNetworkElementsStateInit, action) => {
- if (action instanceof LoadAllMountedNetworkElementsAction) {
-
- state = {
- ...state,
- busy: true
- };
-
- } else if (action instanceof AllMountedNetworkElementsLoadedAction) {
- if (!action.error && action.mountedNetworkElements) {
- state = {
- ...state,
- elements: action.mountedNetworkElements,
- busy: false
- };
- } else {
- state = {
- ...state,
- busy: false
- };
- }
- } else if (action instanceof AddOrUpdateMountedNetworkElement) {
- if (!action.mountedNetworkElement) return state; // should handle error here
- const index = state.elements.findIndex(el => el.mountId === (action.mountedNetworkElement && action.mountedNetworkElement.mountId));
- if (index > -1) {
- state = {
- ...state,
- elements: [
- ...state.elements.slice(0, index),
- action.mountedNetworkElement,
- ...state.elements.slice(index + 1)
- ]
- }
- } else {
- state = {
- ...state,
- elements: [...state.elements, action.mountedNetworkElement],
- }
- };
- } else if (action instanceof RemoveMountedNetworkElement) {
- state = {
- ...state,
- elements: state.elements.filter(e => e.mountId !== action.mountId),
- };
- } else if (action instanceof UpdateConnectionStateMountedNetworkElement) {
- const index = state.elements.findIndex(el => el.mountId === action.mountId);
- if (index > -1) {
- state = {
- ...state,
- elements: [
- ...state.elements.slice(0, index),
- { ...state.elements[index], connectionStatus: action.mountId },
- ...state.elements.slice(index + 1)
- ]
- }
- }
- } else if (action instanceof UpdateRequiredMountedNetworkElement) {
- const index = state.elements.findIndex(el => el.mountId === action.mountId);
- if (index > -1 && (state.elements[index].required !== action.required)) {
- state = {
- ...state,
- elements: [
- ...state.elements.slice(0, index),
- { ...state.elements[index], required: action.required },
- ...state.elements.slice(index + 1)
- ]
- }
- }
- };
- return state;
-}; \ No newline at end of file
diff --git a/sdnr/wt/odlux/apps/connectApp/src/handlers/networkElementsHandler.ts b/sdnr/wt/odlux/apps/connectApp/src/handlers/networkElementsHandler.ts
new file mode 100644
index 000000000..78c7000d2
--- /dev/null
+++ b/sdnr/wt/odlux/apps/connectApp/src/handlers/networkElementsHandler.ts
@@ -0,0 +1,58 @@
+/**
+ * ============LICENSE_START========================================================================
+ * ONAP : ccsdk feature sdnr wt odlux
+ * =================================================================================================
+ * Copyright (C) 2019 highstreet technologies GmbH Intellectual Property. All rights reserved.
+ * =================================================================================================
+ * 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.
+ * ============LICENSE_END==========================================================================
+ */
+import { createExternal, IExternalTableState } from '../../../../framework/src/components/material-table/utilities';
+import { createSearchDataHandler } from '../../../../framework/src/utilities/elasticSearch';
+
+import { NetworkElementConnection } from '../models/networkElementConnection';
+import connectService from '../services/connectService';
+import { requestRest } from '../../../../framework/src/services/restService';
+export interface INetworkElementsState extends IExternalTableState<NetworkElementConnection> { }
+
+// create eleactic search material data fetch handler
+const networkElementsSearchHandler = createSearchDataHandler<NetworkElementConnection>('network-element-connection');
+
+export const {
+ actionHandler: networkElementsActionHandler,
+ createActions: createNetworkElementsActions,
+ createProperties: createNetworkElementsProperties,
+ reloadAction: networkElementsReloadAction,
+
+ // set value action, to change a value
+} = createExternal<NetworkElementConnection>(networkElementsSearchHandler, appState => {
+
+ const webUris = appState.connect.guiCutThrough.availableWebUris;
+ if (appState.connect.networkElements.rows && webUris.length > 0) {
+
+ appState.connect.networkElements.rows.forEach(element => {
+
+ if (element.status === "Connected") {
+ const webUri = webUris.find(item => item.nodeId === element.id as string);
+ if (webUri) {
+ element.webUri = webUri.webUri;
+ element.isWebUriUnreachable = false;
+ }
+ else {
+ element.isWebUriUnreachable = true
+ }
+ }
+ });
+ }
+
+ return appState.connect.networkElements
+});
+
diff --git a/sdnr/wt/odlux/apps/connectApp/src/index.html b/sdnr/wt/odlux/apps/connectApp/src/index.html
index 0f95005de..9c8a2063e 100644
--- a/sdnr/wt/odlux/apps/connectApp/src/index.html
+++ b/sdnr/wt/odlux/apps/connectApp/src/index.html
@@ -5,7 +5,7 @@
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
- <link rel="stylesheet" href="./vendor.css" >
+ <link rel="stylesheet" href="./vendor.css">
<title>connectApp</title>
</head>
@@ -15,9 +15,10 @@
<script type="text/javascript" src="./config.js"></script>
<script>
// run the application
- require(["app","connectApp", "faultApp"], function (app, connectApp, faultApp) {
+ require(["app", "connectApp", "faultApp", "inventoryApp", "configurationApp"], function (app, connectApp, faultApp, inventoryApp, configurationApp) {
connectApp.register();
faultApp.register();
+ inventoryApp.register();
app("./app.tsx").runApplication();
});
</script>
diff --git a/sdnr/wt/odlux/apps/connectApp/src/models/guiCutTrough.ts b/sdnr/wt/odlux/apps/connectApp/src/models/guiCutTrough.ts
new file mode 100644
index 000000000..4b443bac8
--- /dev/null
+++ b/sdnr/wt/odlux/apps/connectApp/src/models/guiCutTrough.ts
@@ -0,0 +1 @@
+export type guiCutThrough = { webUri: string, nodeId: string } \ No newline at end of file
diff --git a/sdnr/wt/odlux/apps/connectApp/src/models/networkElementConnection.ts b/sdnr/wt/odlux/apps/connectApp/src/models/networkElementConnection.ts
new file mode 100644
index 000000000..4c2dc9b09
--- /dev/null
+++ b/sdnr/wt/odlux/apps/connectApp/src/models/networkElementConnection.ts
@@ -0,0 +1,36 @@
+export type NetworkElementConnection = {
+ id?: string;
+ nodeId: string;
+ isRequired: boolean;
+ host: string;
+ port: number;
+ username?: string;
+ password?: string;
+ webUri?: string;
+ isWebUriUnreachable?: boolean;
+ status?: "Connected" | "mounted" | "unmounted" | "Connecting" | "Disconnected" | "idle";
+ coreModelCapability?: string;
+ deviceType?: string;
+ nodeDetails?: {
+ availableCapabilites: {
+ capabilityOrigin: string;
+ capability: string;
+ }[];
+ unavailableCapabilities: {
+ failureReason: string;
+ capability: string;
+ }[];
+ }
+}
+
+
+export type UpdateNetworkElement = {
+ id: string;
+ isRequired?: boolean;
+ username?: string;
+ password?: string;
+}
+
+export type ConnectionStatus = {
+ status: string
+} \ No newline at end of file
diff --git a/sdnr/wt/odlux/apps/connectApp/src/models/requiredNetworkElements.ts b/sdnr/wt/odlux/apps/connectApp/src/models/networkElementConnectionLog.ts
index 42d22afc0..a1535cbe5 100644
--- a/sdnr/wt/odlux/apps/connectApp/src/models/requiredNetworkElements.ts
+++ b/sdnr/wt/odlux/apps/connectApp/src/models/networkElementConnectionLog.ts
@@ -15,13 +15,11 @@
* the License.
* ============LICENSE_END==========================================================================
*/
-import { NetworkElementBaseType } from "./networkElementBase";
-/**
-* Represents data of Required Network Elements.
-*/
-export type RequiredNetworkElementType = NetworkElementBaseType & {
- username?: string;
- password?: string;
+export type NetworkElementConnectionLog = {
+ id: string;
+ nodeId: string;
+ status: "connected" | "mounted" | "unmounted" | "connecting" | "disconnected" | "idle";
+ timestamp: string;
}
diff --git a/sdnr/wt/odlux/apps/connectApp/src/models/panelId.ts b/sdnr/wt/odlux/apps/connectApp/src/models/panelId.ts
new file mode 100644
index 000000000..b51412055
--- /dev/null
+++ b/sdnr/wt/odlux/apps/connectApp/src/models/panelId.ts
@@ -0,0 +1 @@
+export type PanelId = null | "NetworkElements" | "ConnectionStatusLog"; \ No newline at end of file
diff --git a/sdnr/wt/odlux/apps/connectApp/src/models/topologyNetconf.ts b/sdnr/wt/odlux/apps/connectApp/src/models/topologyNetconf.ts
index 357245d46..694009d1b 100644
--- a/sdnr/wt/odlux/apps/connectApp/src/models/topologyNetconf.ts
+++ b/sdnr/wt/odlux/apps/connectApp/src/models/topologyNetconf.ts
@@ -15,14 +15,6 @@
* the License.
* ============LICENSE_END==========================================================================
*/
-export interface UnavailableCapability {
- capability: string;
- "failure-reason": string;
-}
-
-export interface NetconfNodeTopologyUnavailableCapabilities {
- "unavailable-capability": UnavailableCapability[];
-}
export interface AvailableCapability {
"capability-origin": string;
@@ -33,18 +25,9 @@ export interface NetconfNodeTopologyAvailableCapabilities {
"available-capability": AvailableCapability[];
}
-export interface NetconfNodeTopologyClusteredConnectionStatus {
- "netconf-master-node": string
-}
-
export interface TopologyNode {
"node-id": string;
- "netconf-node-topology:clustered-connection-status": NetconfNodeTopologyClusteredConnectionStatus;
- "netconf-node-topology:unavailable-capabilities": NetconfNodeTopologyUnavailableCapabilities;
"netconf-node-topology:available-capabilities": NetconfNodeTopologyAvailableCapabilities;
- "netconf-node-topology:host": string;
- "netconf-node-topology:connection-status": string;
- "netconf-node-topology:port": number;
}
export interface Topology {
diff --git a/sdnr/wt/odlux/apps/connectApp/src/models/mountedNetworkElements.ts b/sdnr/wt/odlux/apps/connectApp/src/models/yangCapabilitiesType.ts
index 0be38a615..230468287 100644
--- a/sdnr/wt/odlux/apps/connectApp/src/models/mountedNetworkElements.ts
+++ b/sdnr/wt/odlux/apps/connectApp/src/models/yangCapabilitiesType.ts
@@ -15,14 +15,8 @@
* the License.
* ============LICENSE_END==========================================================================
*/
-import { NetworkElementBaseType } from "./networkElementBase";
-
-/**
-* Represents data of an mounted network elements.
-*/
-export type MountedNetworkElementType = NetworkElementBaseType & {
- connectionStatus: string;
- required: boolean;
- capabilities: { module: string, revision: string }[];
-};
+export type AvailableCapabilities = {
+ module: string,
+ revision: string
+} \ No newline at end of file
diff --git a/sdnr/wt/odlux/apps/connectApp/src/plugin.tsx b/sdnr/wt/odlux/apps/connectApp/src/pluginConnect.tsx
index aa08e7b15..f711c440c 100644
--- a/sdnr/wt/odlux/apps/connectApp/src/plugin.tsx
+++ b/sdnr/wt/odlux/apps/connectApp/src/pluginConnect.tsx
@@ -22,15 +22,10 @@ import applicationManager from '../../../framework/src/services/applicationManag
import { subscribe, IFormatedMessage } from '../../../framework/src/services/notificationService';
import connectAppRootHandler from './handlers/connectAppRootHandler';
-import ConnectApplication from './views/connectView';
-
-import {
- addMountedNetworkElementAsyncActionCreator,
- updateMountedNetworkElementAsyncActionCreator,
- loadAllMountedNetworkElementsAsync
-} from './actions/mountedNetworkElementsActions';
+import ConnectApplication from './views/connectView';
import { AddSnackbarNotification } from '../../../framework/src/actions/snackbarActions';
+import { updateCurrentViewAsyncAction } from './actions/commonNetworkElementsActions';
type ObjectNotification = {
counter: string;
@@ -48,22 +43,14 @@ export function register() {
menuEntry: "Connect"
});
- const updateAllMountedNetworkElements = () => {
- applicationApi.applicationStoreInitialized.then(applicationStore => { applicationStore.dispatch(loadAllMountedNetworkElementsAsync); })
- };
-
- applicationApi.loginEvent.addHandler(updateAllMountedNetworkElements);
- updateAllMountedNetworkElements();
-
// subscribe to the websocket notifications
subscribe<ObjectNotification & IFormatedMessage>(["ObjectCreationNotification", "ObjectDeletionNotification", "AttributeValueChangedNotification"], (msg => {
const store = applicationApi.applicationStore;
if (msg && msg.notifType === "ObjectCreationNotification" && store) {
- store.dispatch(addMountedNetworkElementAsyncActionCreator(msg.objectId));
store.dispatch(new AddSnackbarNotification({ message: `Adding network element [${msg.objectId}]`, options: { variant: 'info' } }));
} else if (msg && (msg.notifType === "ObjectDeletionNotification" || msg.notifType === "AttributeValueChangedNotification") && store) {
store.dispatch(new AddSnackbarNotification({ message: `Updating network element [${msg.objectId}]`, options: { variant: 'info' } }));
- store.dispatch(updateMountedNetworkElementAsyncActionCreator(msg.objectId));
}
+ store && store.dispatch(updateCurrentViewAsyncAction());
}));
} \ No newline at end of file
diff --git a/sdnr/wt/odlux/apps/connectApp/src/services/connectService.ts b/sdnr/wt/odlux/apps/connectApp/src/services/connectService.ts
index b50a06ee1..7a410f4ae 100644
--- a/sdnr/wt/odlux/apps/connectApp/src/services/connectService.ts
+++ b/sdnr/wt/odlux/apps/connectApp/src/services/connectService.ts
@@ -15,150 +15,66 @@
* the License.
* ============LICENSE_END==========================================================================
*/
-import { RequiredNetworkElementType } from '../models/requiredNetworkElements';
-import { MountedNetworkElementType } from '../models/mountedNetworkElements';
-import { Topology, TopologyNode } from '../models/topologyNetconf';
import { requestRest } from '../../../../framework/src/services/restService';
-import { Result, HitEntry } from '../../../../framework/src/models/elasticSearch';
+import { NetworkElementConnection, ConnectionStatus, UpdateNetworkElement } from '../models/networkElementConnection';
+import { convertPropertyNames, replaceUpperCase } from '../../../../framework/src/utilities/yangHelper';
+import { Result } from '../../../../framework/src/models/elasticSearch';
+import { Topology, TopologyNode } from '../models/topologyNetconf';
+import { guiCutThrough } from '../models/guiCutTrough';
/**
- * Represents a web api accessor service for all Network Elements actions.
- */
+* Represents a web api accessor service for all Network Elements actions.
+*/
class ConnectService {
- /**
- * Gets all known required network elements from the backend.
- */
- public async getAllRequiredNetworkElements(): Promise<(RequiredNetworkElementType & { _id: string })[] | null> {
- const path = 'database/mwtn/required-networkelement/_search';
- const query = { "query": { "match_all": {} } };
-
- const result = await requestRest<Result<RequiredNetworkElementType>>(path, { method: "POST", body: JSON.stringify(query) });
- return result && result.hits && result.hits.hits && result.hits.hits.map(ne => ({
- _id: ne._id,
- mountId: ne._source && ne._source.mountId,
- host: ne._source && ne._source.host,
- port: ne._source && ne._source.port,
- username: ne._source && ne._source.username,
- password: ne._source && ne._source.password,
- })) || null;
- }
- public async getRequiredNetworkElementByMountId(mountId:string): Promise<(RequiredNetworkElementType & { _id: string }) | null> {
- const path = `database/mwtn/required-networkelement/${mountId}`;
-
- const result = await requestRest<HitEntry<RequiredNetworkElementType> & { found: boolean }>(path, { method: "GET" });
- return result && result.found && result._source && {
- _id: result._id,
- mountId: result._source.mountId,
- host: result._source.host,
- port: result._source.port,
- username: result._source.username,
- password: result._source.password,
- } || null;
+ /**
+ * Inserts a network elements.
+ */
+ public async createNetworkElement(element: NetworkElementConnection): Promise<NetworkElementConnection | null> {
+ const path = `/restconf/operations/data-provider:create-network-element-connection`;
+ const result = await requestRest<NetworkElementConnection>(path, {
+ method: "POST", body: JSON.stringify(convertPropertyNames({ input: element }, replaceUpperCase))
+ });
+ return result || null;
}
/**
- * Inserts data into the required network elements table.
- */
- public async insertRequiredNetworkElement(element: RequiredNetworkElementType): Promise<RequiredNetworkElementType | null> {
- const path = `database/mwtn/required-networkelement/${ element.mountId }`;
- const result = await requestRest<RequiredNetworkElementType>(path, { method: "POST", body: JSON.stringify(element) });
+ * Updates a network element.
+ */
+ public async updateNetworkElement(element: UpdateNetworkElement): Promise<NetworkElementConnection | null> {
+ const path = `/restconf/operations/data-provider:update-network-element-connection`;
+ const result = await requestRest<NetworkElementConnection>(path, {
+ method: "POST", body: JSON.stringify(convertPropertyNames({ input: element }, replaceUpperCase))
+ });
return result || null;
}
/**
- * Deletes data from the Required Network Elements backend.
+ * Deletes a network element.
*/
- public async deleteRequiredNetworkElement(element: RequiredNetworkElementType): Promise<RequiredNetworkElementType | null> {
- const path = `database/mwtn/required-networkelement/${ element.mountId }`;
- const result = await requestRest<RequiredNetworkElementType>(path, { method: "DELETE", body: JSON.stringify(element) });
+ public async deleteNetworkElement(element: UpdateNetworkElement): Promise<NetworkElementConnection | null> {
+ const query = {
+ "id": element.id
+ };
+ const path = `/restconf/operations/data-provider:delete-network-element-connection`;
+ const result = await requestRest<NetworkElementConnection>(path, {
+ method: "POST", body: JSON.stringify(convertPropertyNames({ input: query }, replaceUpperCase))
+ });
return result || null;
}
- private static mapTopologyNode = (mountPoint: TopologyNode, required: boolean ) => {
- // handle onfCapabilities
- let onfCapabilities: { module: string, revision: string }[] | undefined = undefined;
-
- const capId = 'netconf-node-topology:available-capabilities';
- if (mountPoint[capId] && mountPoint[capId]['available-capability']) {
- onfCapabilities = mountPoint[capId]['available-capability'].filter((cap) => {
- return cap.capability.includes('?revision=');
- }).map((cap) => {
- return {
- module: cap.capability.split(')')[1],
- revision: cap.capability.split('?revision=')[1].substring(0, 10)
- };
- }).sort((a, b) => {
- if (a.module < b.module) return -1;
- if (a.module > b.module) return 1;
- return 0;
- });
- }
-
- // handle clustered-connection-status
- const statusId = 'netconf-node-topology:clustered-connection-status';
- let client = 'localhost';
-
- if (mountPoint[statusId] && mountPoint[statusId]['netconf-master-node']) {
- let node = mountPoint[statusId]['netconf-master-node'];
- node = node.substring(node.indexOf('@'));
- client = node.substring(1, node.indexOf(':'));
- }
- const mountId = mountPoint["node-id"];
- return {
- mountId: mountId,
- host: mountPoint["netconf-node-topology:host"],
- port: mountPoint["netconf-node-topology:port"],
- connectionStatus: mountPoint['netconf-node-topology:connection-status'],
- capabilities: onfCapabilities || [],
- required: required,
- client
- }
- }
-
- /** Get all mounted network elements and fills the property required according to the database contents. */
- public async getMountedNetworkElementsList(): Promise<MountedNetworkElementType[] | null> {
- const path = 'restconf/operational/network-topology:network-topology/topology/topology-netconf';
-
- const topologyRequestPomise = requestRest<{ topology: Topology[] | null }>(path, { method: "GET" });
- const requiredNetworkElementsPromise = this.getAllRequiredNetworkElements();
-
- const [netconfResponse, requiredNetworkElements] = await Promise.all([topologyRequestPomise, requiredNetworkElementsPromise]);
-
- // process topologyNetconf (get all known network elements)
- const topologyNetconf = netconfResponse && netconfResponse.topology && netconfResponse.topology.find(topology => topology["topology-id"] === 'topology-netconf');
- let mountPoints = topologyNetconf && topologyNetconf.node && topologyNetconf.node.filter(
- mountPoint => mountPoint['node-id'] !== 'controller-config').map(mountedElement => {
- const required = requiredNetworkElements && requiredNetworkElements.some(
- requiredElement => requiredElement.mountId === mountedElement["node-id"]);
- return ConnectService.mapTopologyNode(mountedElement, !!required);
- });
-
- return mountPoints || [];
- }
-
- /** Get one mounted network element. */
- public async getMountedNetworkElementByMountId(mountId: string): Promise<MountedNetworkElementType | null> {
- const path = 'restconf/operational/network-topology:network-topology/topology/topology-netconf/node/' + mountId;
- const getMountedNetworkElementByMountIdPromise = requestRest<{ node: TopologyNode[] | null }>(path, { method: "GET" });
- const getRequiredNetworkElementByMountIdPromise = this.getRequiredNetworkElementByMountId(mountId);
-
- const [mountedNetworkElement, requiredNetworkElement] = await Promise.all([getMountedNetworkElementByMountIdPromise, getRequiredNetworkElementByMountIdPromise]);
- return mountedNetworkElement && mountedNetworkElement.node && ConnectService.mapTopologyNode(mountedNetworkElement.node[0], requiredNetworkElement && requiredNetworkElement.mountId === mountedNetworkElement.node[0]["node-id"] || false) || null;
- }
-
- /** Mounts an required network element. */
- public async mountNetworkElement(networkElement: RequiredNetworkElementType): Promise<boolean> {
- const path = 'restconf/config/network-topology:network-topology/topology/topology-netconf/node/' + networkElement.mountId;
+ /** Mounts network element. */
+ public async mountNetworkElement(networkElement: NetworkElementConnection): Promise<boolean> {
+ const path = 'restconf/config/network-topology:network-topology/topology/topology-netconf/node/' + networkElement.nodeId;
const mountXml = [
'<node xmlns="urn:TBD:params:xml:ns:yang:network-topology">',
- `<node-id>${ networkElement.mountId }</node-id>`,
- `<host xmlns="urn:opendaylight:netconf-node-topology">${ networkElement.host }</host>`,
- `<port xmlns="urn:opendaylight:netconf-node-topology">${ networkElement.port }</port>`,
- `<username xmlns="urn:opendaylight:netconf-node-topology">${ networkElement.username }</username>`,
- `<password xmlns="urn:opendaylight:netconf-node-topology">${ networkElement.password }</password>`,
+ `<node-id>${networkElement.nodeId}</node-id>`,
+ `<host xmlns="urn:opendaylight:netconf-node-topology">${networkElement.host}</host>`,
+ `<port xmlns="urn:opendaylight:netconf-node-topology">${networkElement.port}</port>`,
+ `<username xmlns="urn:opendaylight:netconf-node-topology">${networkElement.username}</username>`,
+ `<password xmlns="urn:opendaylight:netconf-node-topology">${networkElement.password}</password>`,
' <tcp-only xmlns="urn:opendaylight:netconf-node-topology">false</tcp-only>',
' <!-- non-mandatory fields with default values, you can safely remove these if you do not wish to override any of these values-->',
@@ -189,8 +105,8 @@ class ConnectService {
};
/** Unmounts a network element by its id. */
- public async unmountNetworkElement(mountId: string): Promise<boolean> {
- const path = 'restconf/config/network-topology:network-topology/topology/topology-netconf/node/' + mountId;
+ public async unmountNetworkElement(nodeId: string): Promise<boolean> {
+ const path = 'restconf/config/network-topology:network-topology/topology/topology-netconf/node/' + nodeId;
try {
const result = await requestRest<string>(path, {
@@ -208,6 +124,84 @@ class ConnectService {
}
};
+ /** Yang capabilities of the selected network elements. */
+ public async infoNetworkElement(nodeId: string): Promise<TopologyNode | null> {
+ const path = 'restconf/operational/network-topology:network-topology/topology/topology-netconf/node/' + nodeId;
+ const topologyRequestPomise = requestRest<Topology>(path, { method: "GET" });
+
+ return topologyRequestPomise && topologyRequestPomise.then(result => {
+ return result && result.node && result.node[0] || null;
+ });
+ }
+
+ /**
+ * Get the connection state of the network element.
+ */
+ public async getNetworkElementConnectionStatus(element: string): Promise<(ConnectionStatus)[] | null> {
+ const path = `/restconf/operations/data-provider:read-network-element-connection-list`;
+ const query = {
+ "input": {
+ "filter": [{
+ "property": "node-id",
+ "filtervalue": element
+ }],
+ "pagination": {
+ "size": 20,
+ "page": 1
+ }
+ }
+ }
+ const result = await requestRest<Result<ConnectionStatus>>(path, { method: "POST", body: JSON.stringify(query) });
+ return result && result.output && result.output.data && result.output.data.map(ne => ({
+ status: ne.status
+ })) || null;
+ }
+
+ public async getWebUriExtensionForNetworkElementAsync(ne: string) {
+ const path = 'restconf/config/network-topology:network-topology/topology/topology-netconf/node/' + ne + '/yang-ext:mount/core-model:network-element';
+ try {
+ const result = await requestRest<any>(path, { method: "GET" });
+
+ if (result['network-element'].extension) {
+ const webUri = result['network-element'].extension.find((item: any) => item['value-name'] === "webUri")
+ if (webUri) {
+ return webUri.value as string;
+ }
+ }
+ } catch (error) {
+ console.log(ne + ' unrechable: ' + error)
+ }
+
+ return undefined;
+
+ }
+
+ public getAllWebUriExtensionsForNetworkElementListAsync(ne: string[]) {
+
+ let promises: any[] = [];
+ let webUris: guiCutThrough[] = []
+
+ ne.forEach(nodeId => {
+ const path = 'restconf/config/network-topology:network-topology/topology/topology-netconf/node/' + nodeId + '/yang-ext:mount/core-model:network-element';
+
+ // add search request to array
+ promises.push(requestRest<any>(path, { method: "GET" })
+ .then(result => {
+
+ if (result['network-element'] && result['network-element'].extension) {
+ const webUri = result['network-element'].extension.find((item: any) => item['value-name'] === "webUri")
+ if (webUri) {
+ webUris.push({ webUri: webUri.value, nodeId: nodeId });
+ }
+ }
+ })
+ .catch(error => console.log("network element is unreachable: " + error)))
+
+ })
+
+ // wait until all promises are done and return weburis
+ return Promise.all(promises).then(result => { return webUris });
+ }
}
export const connectService = new ConnectService();
diff --git a/sdnr/wt/odlux/apps/connectApp/src/views/connectView.tsx b/sdnr/wt/odlux/apps/connectApp/src/views/connectView.tsx
index c86b384e1..aa3391c47 100644
--- a/sdnr/wt/odlux/apps/connectApp/src/views/connectView.tsx
+++ b/sdnr/wt/odlux/apps/connectApp/src/views/connectView.tsx
@@ -18,99 +18,94 @@
import * as React from 'react';
import connect, { IDispatcher, Connect } from '../../../../framework/src/flux/connect';
+import { IApplicationStoreState } from '../../../../framework/src/store/applicationStore';
import { Panel } from '../../../../framework/src/components/material-ui';
-
-import { requiredNetworkElementsReloadAction, createRequiredNetworkElementsActions } from '../handlers/requiredNetworkElementsHandler';
-import { loadAllMountedNetworkElementsAsync } from '../actions/mountedNetworkElementsActions';
+import { networkElementsReloadAction, createNetworkElementsActions } from '../handlers/networkElementsHandler';
import { connectionStatusLogReloadAction, createConnectionStatusLogActions } from '../handlers/connectionStatusLogHandler';
-import { RequiredNetworkElementsList } from '../components/requiredNetworkElements';
+import { NetworkElementsList } from '../components/networkElements';
import { ConnectionStatusLog } from '../components/connectionStatusLog';
-import { UnknownNetworkElementsList } from '../components/unknownNetworkElements';
+import { setPanelAction, findWebUrisForGuiCutThroughAsyncAction } from '../actions/commonNetworkElementsActions';
+import { PanelId } from '../models/panelId';
+import { NetworkElementConnection } from 'models/networkElementConnection';
+
+const mapProps = (state: IApplicationStoreState) => ({
+ panelId: state.connect.currentOpenPanel,
+ user: state.framework.authenticationState.user,
+ netWorkElements: state.connect.networkElements,
+ availableGuiCutroughs: state.connect.guiCutThrough
+});
const mapDispatcher = (dispatcher: IDispatcher) => ({
- requiredNetworkElementsActions: createRequiredNetworkElementsActions(dispatcher.dispatch),
+ networkElementsActions: createNetworkElementsActions(dispatcher.dispatch),
connectionStatusLogActions: createConnectionStatusLogActions(dispatcher.dispatch),
- onLoadUnknownNetworkElements: () => {
- dispatcher.dispatch(loadAllMountedNetworkElementsAsync);
- },
- onLoadRequiredNetworkElements: () => {
- dispatcher.dispatch(requiredNetworkElementsReloadAction);
+ onLoadNetworkElements: () => {
+ dispatcher.dispatch(networkElementsReloadAction);
},
+ loadWebUris: findWebUrisForGuiCutThroughAsyncAction(dispatcher.dispatch),
onLoadConnectionStatusLog: () => {
dispatcher.dispatch(connectionStatusLogReloadAction);
+ },
+ switchActivePanel: (panelId: PanelId) => {
+ dispatcher.dispatch(setPanelAction(panelId));
}
});
-type PanelId = null | "RequiredNetworkElements" | "UnknownNetworkElements" | "ConnectionStatusLog";
+type ConnectApplicationComponentProps = Connect<typeof mapProps, typeof mapDispatcher>;
-type ConnectApplicationComponentProps = Connect<undefined, typeof mapDispatcher> ;
+class ConnectApplicationComponent extends React.Component<ConnectApplicationComponentProps>{
-type ConnectApplicationComponentState = {
- activePanel: PanelId;
-};
+ componentDidUpdate = () => {
+ // search for guicutthroughs after networkelements were found
+ const networkElements = this.props.netWorkElements;
+ const guiCuttrough = this.props.availableGuiCutroughs;
-class ConnectApplicationComponent extends React.Component<ConnectApplicationComponentProps, ConnectApplicationComponentState>{
- /**
- * Initialises this instance
- */
- constructor(props: ConnectApplicationComponentProps) {
- super(props);
-
- this.state = {
- activePanel: null
- };
+ if (networkElements.rows.length > 0 && networkElements.total !== guiCuttrough.knownElements.length) {
+ this.props.loadWebUris(networkElements.rows, guiCuttrough.knownElements);
+ }
}
private onTogglePanel = (panelId: PanelId) => {
- const nextActivePanel = panelId === this.state.activePanel ? null : panelId;
- this.setState({
- activePanel: nextActivePanel
- }, () => {
- switch (nextActivePanel) {
- case 'RequiredNetworkElements':
- this.props.onLoadRequiredNetworkElements();
- break;
- case 'UnknownNetworkElements':
- // todo: should we update the application state ?
- break;
- case 'ConnectionStatusLog':
- this.props.onLoadConnectionStatusLog();
- break;
- case null:
- // do nothing if all panels are closed
- break;
- default:
- console.warn("Unknown nextActivePanel [" + nextActivePanel + "] in connectView");
- break;
- }
- });
+ const nextActivePanel = panelId === this.props.panelId ? null : panelId;
+ this.props.switchActivePanel(nextActivePanel);
+
+ switch (nextActivePanel) {
+ case 'NetworkElements':
+ this.props.onLoadNetworkElements();
+ break;
+ case 'ConnectionStatusLog':
+ this.props.onLoadConnectionStatusLog();
+ break;
+ case null:
+ // do nothing if all panels are closed
+ break;
+ default:
+ console.warn("Unknown nextActivePanel [" + nextActivePanel + "] in connectView");
+ break;
+ }
+
};
render(): JSX.Element {
- const { activePanel } = this.state;
+ const { panelId } = this.props;
return (
<>
- <Panel activePanel={ activePanel } panelId={ 'RequiredNetworkElements' } onToggle={ this.onTogglePanel } title={ "Required Network Elements" }>
- <RequiredNetworkElementsList />
- </Panel>
- <Panel activePanel={ activePanel } panelId={ 'UnknownNetworkElements' } onToggle={ this.onTogglePanel } title={ "Unknown Network Elements" }>
- <UnknownNetworkElementsList />
+ <Panel activePanel={panelId} panelId={'NetworkElements'} onToggle={this.onTogglePanel} title={"Network Elements"}>
+ <NetworkElementsList />
</Panel>
- <Panel activePanel={ activePanel } panelId={ 'ConnectionStatusLog' } onToggle={ this.onTogglePanel } title={ "Connection Status Log" }>
+ <Panel activePanel={panelId} panelId={'ConnectionStatusLog'} onToggle={this.onTogglePanel} title={"Connection Status Log"}>
<ConnectionStatusLog />
</Panel>
</>
);
};
public componentDidMount() {
- this.onTogglePanel("RequiredNetworkElements");
- this.props.onLoadUnknownNetworkElements();
- this.props.requiredNetworkElementsActions.onToggleFilter();
+ this.onTogglePanel("NetworkElements");
+ this.props.networkElementsActions.onToggleFilter();
this.props.connectionStatusLogActions.onToggleFilter();
}
}
-export const ConnectApplication = (connect(undefined, mapDispatcher)(ConnectApplicationComponent));
+export const ConnectApplication = (connect(mapProps, mapDispatcher)(ConnectApplicationComponent));
export default ConnectApplication; \ No newline at end of file
diff --git a/sdnr/wt/odlux/apps/connectApp/webpack.config.js b/sdnr/wt/odlux/apps/connectApp/webpack.config.js
index a70e62976..6d70b04b0 100644
--- a/sdnr/wt/odlux/apps/connectApp/webpack.config.js
+++ b/sdnr/wt/odlux/apps/connectApp/webpack.config.js
@@ -26,7 +26,7 @@ module.exports = (env) => {
context: path.resolve(__dirname, "src"),
entry: {
- connectApp: ["./plugin.tsx"]
+ connectApp: ["./pluginConnect.tsx"]
},
devtool: env === "release" ? false : "source-map",
@@ -125,12 +125,26 @@ module.exports = (env) => {
colors: true
},
proxy: {
- "/restconf": {
- target: "http://localhost:8181",
+ "/oauth2/": {
+ target: "http://10.20.6.29:28181",
secure: false
},
- "/database": {
- target: "http://localhost:8181",
+ "/database/": {
+ target: "http://10.20.6.29:28181",
+ secure: false
+ },
+ "/restconf/": {
+ target: "http://10.20.6.29:28181",
+ secure: false
+ },
+ "/help/": {
+ target: "http://10.20.6.29:28181",
+ secure: false
+ },
+ "/websocket": {
+ target: "http://10.20.6.29:28181",
+ ws: true,
+ changeOrigin: true,
secure: false
}
}