Merge "SDN-R add updated featureaggregator"
[ccsdk/features.git] / sdnr / wt / odlux / apps / connectApp / src / services / connectService.ts
1 /**
2  * ============LICENSE_START========================================================================
3  * ONAP : ccsdk feature sdnr wt odlux
4  * =================================================================================================
5  * Copyright (C) 2019 highstreet technologies GmbH Intellectual Property. All rights reserved.
6  * =================================================================================================
7  * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
8  * in compliance with the License. You may obtain a copy of the License at
9  *
10  * http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software distributed under the License
13  * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
14  * or implied. See the License for the specific language governing permissions and limitations under
15  * the License.
16  * ============LICENSE_END==========================================================================
17  */
18
19 import { requestRest } from '../../../../framework/src/services/restService';
20 import { NetworkElementConnection, ConnectionStatus, UpdateNetworkElement } from '../models/networkElementConnection';
21 import { convertPropertyNames, replaceUpperCase } from '../../../../framework/src/utilities/yangHelper';
22 import { Result } from '../../../../framework/src/models/elasticSearch';
23
24 import { Topology, TopologyNode } from '../models/topologyNetconf';
25 import { guiCutThrough } from '../models/guiCutTrough';
26
27 /**
28 * Represents a web api accessor service for all Network Elements actions.
29 */
30 class ConnectService {
31
32   /**
33    * Inserts a network elements.
34    */
35   public async createNetworkElement(element: NetworkElementConnection): Promise<NetworkElementConnection | null> {
36     const path = `/restconf/operations/data-provider:create-network-element-connection`;
37     const result = await requestRest<NetworkElementConnection>(path, {
38       method: "POST", body: JSON.stringify(convertPropertyNames({ input: element }, replaceUpperCase))
39     });
40     return result || null;
41   }
42
43   /**
44   * Updates a network element.
45   */
46   public async updateNetworkElement(element: UpdateNetworkElement): Promise<NetworkElementConnection | null> {
47     const path = `/restconf/operations/data-provider:update-network-element-connection`;
48     const result = await requestRest<NetworkElementConnection>(path, {
49       method: "POST", body: JSON.stringify(convertPropertyNames({ input: element }, replaceUpperCase))
50     });
51     return result || null;
52   }
53
54   /**
55     * Deletes a network element.
56     */
57   public async deleteNetworkElement(element: UpdateNetworkElement): Promise<NetworkElementConnection | null> {
58     const query = {
59       "id": element.id
60     };
61     const path = `/restconf/operations/data-provider:delete-network-element-connection`;
62     const result = await requestRest<NetworkElementConnection>(path, {
63       method: "POST", body: JSON.stringify(convertPropertyNames({ input: query }, replaceUpperCase))
64     });
65     return result || null;
66   }
67
68   /** Mounts network element. */
69   public async mountNetworkElement(networkElement: NetworkElementConnection): Promise<boolean> {
70     const path = 'restconf/config/network-topology:network-topology/topology/topology-netconf/node/' + networkElement.nodeId;
71     const mountXml = [
72       '<node xmlns="urn:TBD:params:xml:ns:yang:network-topology">',
73       `<node-id>${networkElement.nodeId}</node-id>`,
74       `<host xmlns="urn:opendaylight:netconf-node-topology">${networkElement.host}</host>`,
75       `<port xmlns="urn:opendaylight:netconf-node-topology">${networkElement.port}</port>`,
76       `<username xmlns="urn:opendaylight:netconf-node-topology">${networkElement.username}</username>`,
77       `<password xmlns="urn:opendaylight:netconf-node-topology">${networkElement.password}</password>`,
78       '  <tcp-only xmlns="urn:opendaylight:netconf-node-topology">false</tcp-only>',
79
80       '  <!-- non-mandatory fields with default values, you can safely remove these if you do not wish to override any of these values-->',
81       '  <reconnect-on-changed-schema xmlns="urn:opendaylight:netconf-node-topology">false</reconnect-on-changed-schema>',
82       '  <connection-timeout-millis xmlns="urn:opendaylight:netconf-node-topology">20000</connection-timeout-millis>',
83       '  <max-connection-attempts xmlns="urn:opendaylight:netconf-node-topology">100</max-connection-attempts>',
84       '  <between-attempts-timeout-millis xmlns="urn:opendaylight:netconf-node-topology">2000</between-attempts-timeout-millis>',
85       '  <sleep-factor xmlns="urn:opendaylight:netconf-node-topology">1.5</sleep-factor>',
86
87       '  <!-- keepalive-delay set to 0 turns off keepalives-->',
88       '  <keepalive-delay xmlns="urn:opendaylight:netconf-node-topology">120</keepalive-delay>',
89       '</node>'].join('');
90
91     try {
92       const result = await requestRest<string>(path, {
93         method: 'PUT',
94         headers: {
95           'Content-Type': 'application/xml',
96           'Accept': 'application/xml'
97         },
98         body: mountXml
99       });
100       // expect an empty answer
101       return result !== null;
102     } catch {
103       return false;
104     }
105   };
106
107   /** Unmounts a network element by its id. */
108   public async unmountNetworkElement(nodeId: string): Promise<boolean> {
109     const path = 'restconf/config/network-topology:network-topology/topology/topology-netconf/node/' + nodeId;
110
111     try {
112       const result = await requestRest<string>(path, {
113         method: 'DELETE',
114         headers: {
115           'Content-Type': 'application/xml',
116           'Accept': 'application/xml'
117         },
118       });
119       // expect an empty answer
120       return result !== null;
121
122     } catch {
123       return false;
124     }
125   };
126
127   /** Yang capabilities of the selected network elements. */
128   public async infoNetworkElement(nodeId: string): Promise<TopologyNode | null> {
129     const path = 'restconf/operational/network-topology:network-topology/topology/topology-netconf/node/' + nodeId;
130     const topologyRequestPomise = requestRest<Topology>(path, { method: "GET" });
131
132     return topologyRequestPomise && topologyRequestPomise.then(result => {
133       return result && result.node && result.node[0] || null;
134     });
135   }
136
137   /**
138    * Get the connection state of the network element.
139    */
140   public async getNetworkElementConnectionStatus(element: string): Promise<(ConnectionStatus)[] | null> {
141     const path = `/restconf/operations/data-provider:read-network-element-connection-list`;
142     const query = {
143       "input": {
144         "filter": [{
145           "property": "node-id",
146           "filtervalue": element
147         }],
148         "pagination": {
149           "size": 20,
150           "page": 1
151         }
152       }
153     }
154     const result = await requestRest<Result<ConnectionStatus>>(path, { method: "POST", body: JSON.stringify(query) });
155     return result && result.output && result.output.data && result.output.data.map(ne => ({
156       status: ne.status
157     })) || null;
158   }
159
160   public async getWebUriExtensionForNetworkElementAsync(ne: string) {
161     const path = 'restconf/config/network-topology:network-topology/topology/topology-netconf/node/' + ne + '/yang-ext:mount/core-model:network-element';
162     try {
163       const result = await requestRest<any>(path, { method: "GET" });
164
165       if (result['network-element'].extension) {
166         const webUri = result['network-element'].extension.find((item: any) => item['value-name'] === "webUri")
167         if (webUri) {
168           return webUri.value as string;
169         }
170       }
171     } catch (error) {
172       console.log(ne + ' unrechable: ' + error)
173     }
174
175     return undefined;
176
177   }
178
179   public getAllWebUriExtensionsForNetworkElementListAsync(ne: string[]) {
180
181     let promises: any[] = [];
182     let webUris: guiCutThrough[] = []
183
184     ne.forEach(nodeId => {
185       const path = 'restconf/config/network-topology:network-topology/topology/topology-netconf/node/' + nodeId + '/yang-ext:mount/core-model:network-element';
186
187       // add search request to array
188       promises.push(requestRest<any>(path, { method: "GET" })
189         .then(result => {
190
191           if (result != null && result['network-element'] && result['network-element'].extension) {
192             const webUri = result['network-element'].extension.find((item: any) => item['value-name'] === "webUri")
193             if (webUri) {
194               webUris.push({ webUri: webUri.value, nodeId: nodeId });
195             } else {
196               webUris.push({ webUri: undefined, nodeId: nodeId });
197             }
198           } else {
199             webUris.push({ webUri: undefined, nodeId: nodeId });
200           }
201         })
202         .catch(error => {
203           webUris.push({ webUri: undefined, nodeId: nodeId });
204         }))
205
206     })
207
208     // wait until all promises are done and return weburis
209     return Promise.all(promises).then(result => { return webUris });
210   }
211
212 }
213 export const connectService = new ConnectService();
214 export default connectService;