8fe7e4f868255dfea95848006e3b8ed1110f668d
[so.git] /
1 /*-
2  * ============LICENSE_START=======================================================
3  * ONAP - SO
4  * ================================================================================
5  * Copyright (C) 2018 Huawei Intellectual Property. All rights reserved.
6  * ================================================================================
7  * Modifications Copyright (c) 2019 Samsung
8  * ================================================================================
9  * Licensed under the Apache License, Version 2.0 (the "License");
10  * you may not use this file except in compliance with the License.
11  * You may obtain a copy of the License at
12  *
13  *      http://www.apache.org/licenses/LICENSE-2.0
14  *
15  * Unless required by applicable law or agreed to in writing, software
16  * distributed under the License is distributed on an "AS IS" BASIS,
17  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18  * See the License for the specific language governing permissions and
19  * limitations under the License.
20  * ============LICENSE_END=========================================================
21  */
22
23 package org.onap.so.bpmn.infrastructure.workflow.service;
24
25 import com.fasterxml.jackson.core.JsonProcessingException;
26 import com.fasterxml.jackson.databind.ObjectMapper;
27 import com.fasterxml.jackson.databind.SerializationFeature;
28 import java.io.IOException;
29 import java.io.InputStream;
30 import java.net.SocketTimeoutException;
31 import java.util.ArrayList;
32 import java.util.Collections;
33 import java.util.HashMap;
34 import java.util.List;
35 import java.util.Map;
36 import java.util.Map.Entry;
37 import java.util.Optional;
38 import java.util.Properties;
39 import org.apache.commons.lang3.StringUtils;
40 import org.apache.http.HttpResponse;
41 import org.apache.http.ParseException;
42 import org.apache.http.client.HttpClient;
43 import org.apache.http.client.config.RequestConfig;
44 import org.apache.http.client.methods.HttpDelete;
45 import org.apache.http.client.methods.HttpGet;
46 import org.apache.http.client.methods.HttpPost;
47 import org.apache.http.client.methods.HttpPut;
48 import org.apache.http.client.methods.HttpRequestBase;
49 import org.apache.http.conn.ConnectTimeoutException;
50 import org.apache.http.entity.ContentType;
51 import org.apache.http.entity.StringEntity;
52 import org.apache.http.impl.client.HttpClientBuilder;
53 import org.apache.http.util.EntityUtils;
54 import org.camunda.bpm.engine.delegate.DelegateExecution;
55 import org.camunda.bpm.engine.runtime.Execution;
56 import org.onap.aai.domain.yang.LogicalLink;
57 import org.onap.aai.domain.yang.LogicalLinks;
58 import org.onap.aai.domain.yang.PInterface;
59 import org.onap.so.bpmn.core.UrnPropertiesReader;
60 import org.onap.so.bpmn.core.domain.Resource;
61 import org.onap.so.bpmn.core.domain.ServiceDecomposition;
62 import org.onap.so.bpmn.core.json.JsonUtils;
63 import org.onap.so.client.aai.AAIObjectPlurals;
64 import org.onap.so.client.aai.AAIObjectType;
65 import org.onap.so.client.aai.AAIResourcesClient;
66 import org.onap.so.client.aai.entities.AAIResultWrapper;
67 import org.onap.so.client.aai.entities.Relationships;
68 import org.onap.so.client.aai.entities.uri.AAIResourceUri;
69 import org.onap.so.client.aai.entities.uri.AAIUriFactory;
70 import org.onap.so.logger.ErrorCode;
71 import org.onap.so.logger.MessageEnum;
72 import org.slf4j.Logger;
73 import org.slf4j.LoggerFactory;
74 import org.springframework.web.util.UriUtils;
75
76 public class ServicePluginFactory {
77
78     private static String OOF_DEFAULT_ENDPOINT;
79     private static String THIRD_SP_DEFAULT_ENDPOINT;
80     private static String INVENTORY_OSS_DEFAULT_ENDPOINT;
81     private static final int DEFAULT_TIME_OUT = 60000;
82
83     static JsonUtils jsonUtil = new JsonUtils();
84
85     private static Logger logger = LoggerFactory.getLogger(ServicePluginFactory.class);
86
87     private static ServicePluginFactory instance;
88
89     static {
90         try (InputStream is = ClassLoader.class.getResourceAsStream("/application.properties")) {
91             Properties prop = new Properties();
92             prop.load(is);
93             OOF_DEFAULT_ENDPOINT = prop.getProperty("oof.default.endpoint");
94             THIRD_SP_DEFAULT_ENDPOINT = prop.getProperty("third.sp.default.endpoint");
95             INVENTORY_OSS_DEFAULT_ENDPOINT = prop.getProperty("inventory.oss.default.endpoint");
96         } catch (IOException e) {
97             e.printStackTrace();
98         }
99     }
100
101     public static synchronized ServicePluginFactory getInstance() {
102         if (null == instance) {
103             instance = new ServicePluginFactory();
104         }
105         return instance;
106     }
107
108     private ServicePluginFactory() {
109
110     }
111
112     private String getInventoryOSSEndPoint() {
113         return UrnPropertiesReader.getVariable("mso.service-plugin.inventory-oss-endpoint",
114                 INVENTORY_OSS_DEFAULT_ENDPOINT);
115     }
116
117     private String getThirdSPEndPoint() {
118         return UrnPropertiesReader.getVariable("mso.service-plugin.third-sp-endpoint", THIRD_SP_DEFAULT_ENDPOINT);
119     }
120
121     private String getOOFCalcEndPoint() {
122         return UrnPropertiesReader.getVariable("mso.service-plugin.oof-calc-endpoint", OOF_DEFAULT_ENDPOINT);
123     }
124
125     @SuppressWarnings("unchecked")
126     public String doProcessSiteLocation(ServiceDecomposition serviceDecomposition, String uuiRequest) {
127         if (!isNeedProcessSite(uuiRequest)) {
128             return uuiRequest;
129         }
130
131         Map<String, Object> uuiObject = getJsonObject(uuiRequest, Map.class);
132         if (uuiObject == null) {
133             return uuiRequest;
134         }
135         Map<String, Object> serviceObject =
136                 (Map<String, Object>) uuiObject.getOrDefault("service", Collections.emptyMap());
137         Map<String, Object> serviceParametersObject =
138                 (Map<String, Object>) serviceObject.getOrDefault("parameters", Collections.emptyMap());
139         Map<String, Object> serviceRequestInputs =
140                 (Map<String, Object>) serviceParametersObject.getOrDefault("requestInputs", Collections.emptyMap());
141         List<Object> resources =
142                 (List<Object>) serviceParametersObject.getOrDefault("resources", Collections.emptyList());
143
144         if (isSiteLocationLocal(serviceRequestInputs, resources)) {
145             // resources changed : added TP info
146             return getJsonString(uuiObject);
147         }
148
149         List<Resource> addResourceList = new ArrayList<>();
150         addResourceList.addAll(serviceDecomposition.getServiceResources());
151
152         serviceDecomposition.setVnfResources(null);
153         serviceDecomposition.setAllottedResources(null);
154         serviceDecomposition.setNetworkResources(null);
155         serviceDecomposition.setConfigResources(null);
156         for (Resource resource : addResourceList) {
157             String resourcemodelName = resource.getModelInfo().getModelName();
158             if (StringUtils.containsIgnoreCase(resourcemodelName, "sppartner")) {
159                 // change serviceDecomposition
160                 serviceDecomposition.addResource(resource);
161                 break;
162             }
163         }
164
165         return uuiRequest;
166     }
167
168     private boolean isNeedProcessSite(String uuiRequest) {
169         return uuiRequest.toLowerCase().contains("site_address")
170                 && uuiRequest.toLowerCase().contains("sotncondition_clientsignal");
171     }
172
173     @SuppressWarnings("unchecked")
174     private boolean isSiteLocationLocal(Map<String, Object> serviceRequestInputs, List<Object> resources) {
175         Map<String, Object> tpInfoMap = getTPforVPNAttachment(serviceRequestInputs);
176
177         if (tpInfoMap.isEmpty()) {
178             return true;
179         }
180         String host = (String) tpInfoMap.get("host");
181         // host is empty means TP is in local, not empty means TP is in remote ONAP
182         if (!host.isEmpty()) {
183             return false;
184         }
185
186         Map<String, Object> accessTPInfo = new HashMap<String, Object>();
187         accessTPInfo.put("access-provider-id", tpInfoMap.get("access-provider-id"));
188         accessTPInfo.put("access-client-id", tpInfoMap.get("access-client-id"));
189         accessTPInfo.put("access-topology-id", tpInfoMap.get("access-topology-id"));
190         accessTPInfo.put("access-node-id", tpInfoMap.get("access-node-id"));
191         accessTPInfo.put("access-ltp-id", tpInfoMap.get("access-ltp-id"));
192
193         // change resources
194         String resourceName = (String) tpInfoMap.get("resourceName");
195         for (Object curResource : resources) {
196             Map<String, Object> resource = (Map<String, Object>) curResource;
197             String curResourceName = (String) resource.get("resourceName");
198             curResourceName = curResourceName.replaceAll(" ", "");
199             if (resourceName.equalsIgnoreCase(curResourceName)) {
200                 putResourceRequestInputs(resource, accessTPInfo);
201                 break;
202             }
203         }
204
205         return true;
206     }
207
208     @SuppressWarnings("unchecked")
209     private Map<String, Object> getTPforVPNAttachment(Map<String, Object> serviceRequestInputs) {
210         Object location = null;
211         Object clientSignal = null;
212         String vpnAttachmentResourceName = null;
213
214         // support R2 uuiReq and R1 uuiReq
215         // logic for R2 uuiRequest params in service level
216         for (Entry<String, Object> entry : serviceRequestInputs.entrySet()) {
217             String key = entry.getKey();
218             if (key.toLowerCase().contains("site_address")) {
219                 location = entry.getValue();
220             }
221             if (key.toLowerCase().contains("sotncondition_clientsignal")) {
222                 clientSignal = entry.getValue();
223                 vpnAttachmentResourceName = key.substring(0, key.indexOf("_"));
224             }
225         }
226
227         Map<String, Object> tpInfoMap = new HashMap<String, Object>();
228
229         // Site resource has location param and SOTNAttachment resource has clientSignal param
230         if (location == null || clientSignal == null) {
231             return tpInfoMap;
232         }
233
234         // Query terminal points from InventoryOSS system by location.
235         String locationAddress = (String) location;
236         List<Object> locationTPList = queryAccessTPbyLocationFromInventoryOSS(locationAddress);
237         if (locationTPList != null && !locationTPList.isEmpty()) {
238             for (Object tp : locationTPList) {
239                 Map<String, Object> tpJson = (Map<String, Object>) tp;
240                 String loc = (String) tpJson.get("location");
241                 if (StringUtils.equalsIgnoreCase(locationAddress, loc)) {
242                     tpInfoMap = tpJson;
243                     // add resourceName
244                     tpInfoMap.put("resourceName", vpnAttachmentResourceName);
245                     break;
246                 }
247             }
248             logger.debug("Get Terminal TP from InventoryOSS");
249             return tpInfoMap;
250         }
251
252         return tpInfoMap;
253     }
254
255     @SuppressWarnings("unchecked")
256     private List<Object> queryAccessTPbyLocationFromInventoryOSS(String locationAddress) {
257         String url = getInventoryOSSEndPoint();
258         url += "/oss/inventory?location=" + UriUtils.encode(locationAddress, "UTF-8");
259         String responseContent = sendRequest(url, "GET", "");
260         List<Object> accessTPs = new ArrayList<>();
261         if (null != responseContent) {
262             accessTPs = getJsonObject(responseContent, List.class);
263         }
264         return accessTPs;
265     }
266
267     @SuppressWarnings("unchecked")
268     private void putResourceRequestInputs(Map<String, Object> resource, Map<String, Object> resourceInputs) {
269         Map<String, Object> resourceParametersObject = new HashMap<>();
270         Map<String, Object> resourceRequestInputs = new HashMap<>();
271         resourceRequestInputs.put("requestInputs", resourceInputs);
272         resourceParametersObject.put("parameters", resourceRequestInputs);
273
274         if (resource.containsKey("parameters")) {
275             Map<String, Object> resParametersObject = (Map<String, Object>) resource.get("parameters");
276             if (resParametersObject.containsKey("requestInputs")) {
277                 Map<String, Object> resRequestInputs = (Map<String, Object>) resourceRequestInputs.get("requestInputs");
278                 Map<String, Object> oldRequestInputs = (Map<String, Object>) resParametersObject.get("requestInputs");
279                 if (oldRequestInputs != null) {
280                     oldRequestInputs.putAll(resRequestInputs);
281                 } else {
282                     resParametersObject.put("requestInputs", resRequestInputs);
283                 }
284             } else {
285                 resParametersObject.putAll(resourceRequestInputs);
286             }
287         } else {
288             resource.putAll(resourceParametersObject);
289         }
290
291         return;
292     }
293
294
295
296     @SuppressWarnings("unchecked")
297     public String doTPResourcesAllocation(DelegateExecution execution, String uuiRequest) {
298         Map<String, Object> uuiObject = getJsonObject(uuiRequest, Map.class);
299         if (uuiObject == null) {
300             return uuiRequest;
301         }
302         Map<String, Object> serviceObject =
303                 (Map<String, Object>) uuiObject.getOrDefault("service", Collections.emptyMap());
304         Map<String, Object> serviceParametersObject =
305                 (Map<String, Object>) serviceObject.getOrDefault("parameters", Collections.emptyMap());
306         Map<String, Object> serviceRequestInputs =
307                 (Map<String, Object>) serviceParametersObject.getOrDefault("requestInputs", Collections.emptyMap());
308
309         if (!isNeedAllocateCrossTPResources(serviceRequestInputs)) {
310             return uuiRequest;
311         }
312
313         allocateCrossTPResources(execution, serviceRequestInputs);
314         return getJsonString(uuiObject);
315     }
316
317     @SuppressWarnings("unchecked")
318     private boolean isNeedAllocateCrossTPResources(Map<String, Object> serviceRequestInputs) {
319         if (serviceRequestInputs.containsKey("CallSource")) {
320             String callSource = (String) serviceRequestInputs.get("CallSource");
321             if ("ExternalAPI".equalsIgnoreCase(callSource)) {
322                 return false;
323             }
324         }
325         for (String input : serviceRequestInputs.keySet()) {
326             if (input.toLowerCase().contains("sotnconnectivity")) {
327                 return true;
328             }
329         }
330         return false;
331     }
332
333     @SuppressWarnings("unchecked")
334     private void allocateCrossTPResources(DelegateExecution execution, Map<String, Object> serviceRequestInputs) {
335
336         Map<String, Object> crossTPs = this.getTPsfromAAI();
337
338         if (crossTPs == null || crossTPs.isEmpty()) {
339             serviceRequestInputs.put("local-access-provider-id", "");
340             serviceRequestInputs.put("local-access-client-id", "");
341             serviceRequestInputs.put("local-access-topology-id", "");
342             serviceRequestInputs.put("local-access-node-id", "");
343             serviceRequestInputs.put("local-access-ltp-id", "");
344             serviceRequestInputs.put("remote-access-provider-id", "");
345             serviceRequestInputs.put("remote-access-client-id", "");
346             serviceRequestInputs.put("remote-access-topology-id", "");
347             serviceRequestInputs.put("remote-access-node-id", "");
348             serviceRequestInputs.put("remote-access-ltp-id", "");
349         } else {
350             serviceRequestInputs.put("local-access-provider-id", crossTPs.get("local-access-provider-id"));
351             serviceRequestInputs.put("local-access-client-id", crossTPs.get("local-access-client-id"));
352             serviceRequestInputs.put("local-access-topology-id", crossTPs.get("local-access-topology-id"));
353             serviceRequestInputs.put("local-access-node-id", crossTPs.get("local-access-node-id"));
354             serviceRequestInputs.put("local-access-ltp-id", crossTPs.get("local-access-ltp-id"));
355             serviceRequestInputs.put("remote-access-provider-id", crossTPs.get("remote-access-provider-id"));
356             serviceRequestInputs.put("remote-access-client-id", crossTPs.get("remote-client-id"));
357             serviceRequestInputs.put("remote-access-topology-id", crossTPs.get("remote-topology-id"));
358             serviceRequestInputs.put("remote-access-node-id", crossTPs.get("remote-node-id"));
359             serviceRequestInputs.put("remote-access-ltp-id", crossTPs.get("remote-ltp-id"));
360         }
361
362         return;
363     }
364
365     // This method returns Local and remote TPs information from AAI
366     public Map getTPsfromAAI() {
367         Map<String, Object> tpInfo = new HashMap<>();
368
369         AAIResourceUri uri = AAIUriFactory.createResourceUri(AAIObjectPlurals.LOGICAL_LINK);
370         AAIResourcesClient client = new AAIResourcesClient();
371         Optional<LogicalLinks> result = client.get(LogicalLinks.class, uri);
372
373         if (result.isPresent()) {
374             LogicalLinks links = result.get();
375             boolean isRemoteLink = false;
376
377             links.getLogicalLink();
378
379             for (LogicalLink link : links.getLogicalLink()) {
380                 AAIResultWrapper wrapper = new AAIResultWrapper(link);
381                 Optional<Relationships> optRelationships = wrapper.getRelationships();
382                 List<AAIResourceUri> pInterfaces = new ArrayList<>();
383                 if (optRelationships.isPresent()) {
384                     Relationships relationships = optRelationships.get();
385                     if (!relationships.getRelatedAAIUris(AAIObjectType.EXT_AAI_NETWORK).isEmpty()) {
386                         isRemoteLink = true;
387                     }
388                     pInterfaces.addAll(relationships.getRelatedAAIUris(AAIObjectType.P_INTERFACE));
389                 }
390
391                 if (isRemoteLink) {
392                     // find remote p interface
393                     AAIResourceUri localTP = null;
394                     AAIResourceUri remoteTP = null;
395
396                     AAIResourceUri pInterface0 = pInterfaces.get(0);
397
398                     if (isRemotePInterface(client, pInterface0)) {
399                         remoteTP = pInterfaces.get(0);
400                         localTP = pInterfaces.get(1);
401                     } else {
402                         localTP = pInterfaces.get(0);
403                         remoteTP = pInterfaces.get(1);
404                     }
405
406                     if (localTP != null && remoteTP != null) {
407                         // give local tp
408                         String tpUrl = localTP.build().toString();
409                         PInterface intfLocal = client.get(PInterface.class, localTP).get();
410                         tpInfo.put("local-access-node-id", tpUrl.split("/")[6]);
411
412                         String[] networkRef = intfLocal.getNetworkRef().split("/");
413                         if (networkRef.length == 6) {
414                             tpInfo.put("local-access-provider-id", networkRef[1]);
415                             tpInfo.put("local-access-client-id", networkRef[3]);
416                             tpInfo.put("local-access-topology-id", networkRef[5]);
417                         }
418                         String ltpIdStr = tpUrl.substring(tpUrl.lastIndexOf("/") + 1);
419                         if (ltpIdStr.contains("-")) {
420                             tpInfo.put("local-access-ltp-id", ltpIdStr.substring(ltpIdStr.lastIndexOf("-") + 1));
421                         }
422
423                         // give remote tp
424                         tpUrl = remoteTP.build().toString();
425                         PInterface intfRemote = client.get(PInterface.class, remoteTP).get();
426                         tpInfo.put("remote-access-node-id", tpUrl.split("/")[6]);
427
428                         String[] networkRefRemote = intfRemote.getNetworkRef().split("/");
429
430                         if (networkRefRemote.length == 6) {
431                             tpInfo.put("remote-access-provider-id", networkRefRemote[1]);
432                             tpInfo.put("remote-access-client-id", networkRefRemote[3]);
433                             tpInfo.put("remote-access-topology-id", networkRefRemote[5]);
434                         }
435                         String ltpIdStrR = tpUrl.substring(tpUrl.lastIndexOf("/") + 1);
436                         if (ltpIdStrR.contains("-")) {
437                             tpInfo.put("remote-access-ltp-id", ltpIdStrR.substring(ltpIdStr.lastIndexOf("-") + 1));
438                         }
439                         return tpInfo;
440                     }
441                 }
442             }
443         }
444         return tpInfo;
445     }
446
447     // this method check if pInterface is remote
448     private boolean isRemotePInterface(AAIResourcesClient client, AAIResourceUri uri) {
449
450         String uriString = uri.build().toString();
451
452         if (uriString != null) {
453             // get the pnfname
454             String[] token = uriString.split("/");
455             AAIResourceUri parent = AAIUriFactory.createResourceUri(AAIObjectType.PNF, token[4]);
456
457             AAIResultWrapper wrapper = client.get(parent);
458             Optional<Relationships> optRelationships = wrapper.getRelationships();
459             if (optRelationships.isPresent()) {
460                 Relationships relationships = optRelationships.get();
461
462                 return !relationships.getRelatedAAIUris(AAIObjectType.EXT_AAI_NETWORK).isEmpty();
463             }
464         }
465
466         return false;
467     }
468
469     public String preProcessService(ServiceDecomposition serviceDecomposition, String uuiRequest) {
470
471         // now only for sotn
472         if (isSOTN(serviceDecomposition, uuiRequest)) {
473             // We Need to query the terminalpoint of the VPN by site location
474             // info
475             return preProcessSOTNService(serviceDecomposition, uuiRequest);
476         }
477         return uuiRequest;
478     }
479
480     public String doServiceHoming(ServiceDecomposition serviceDecomposition, String uuiRequest) {
481         // now only for sotn
482         if (isSOTN(serviceDecomposition, uuiRequest)) {
483             return doSOTNServiceHoming(serviceDecomposition, uuiRequest);
484         }
485         return uuiRequest;
486     }
487
488     private boolean isSOTN(ServiceDecomposition serviceDecomposition, String uuiRequest) {
489         // there should be a register platform , we check it very simple here.
490         return uuiRequest.contains("clientSignal") && uuiRequest.contains("vpnType");
491     }
492
493     @SuppressWarnings("unchecked")
494     private String preProcessSOTNService(ServiceDecomposition serviceDecomposition, String uuiRequest) {
495         Map<String, Object> uuiObject = getJsonObject(uuiRequest, Map.class);
496         if (uuiObject == null) {
497             return uuiRequest;
498         }
499         Map<String, Object> serviceObject =
500                 (Map<String, Object>) uuiObject.getOrDefault("service", Collections.emptyMap());
501         Map<String, Object> serviceParametersObject =
502                 (Map<String, Object>) serviceObject.getOrDefault("parameters", Collections.emptyMap());
503         Map<String, Object> serviceRequestInputs =
504                 (Map<String, Object>) serviceParametersObject.getOrDefault("requestInputs", Collections.emptyMap());
505         List<Object> resources =
506                 (List<Object>) serviceParametersObject.getOrDefault("resources", Collections.emptyList());
507         // This is a logic for demo , it could not be finalized to community.
508         String srcLocation = "";
509         String dstLocation = "";
510         String srcClientSignal = "";
511         String dstClientSignal = "";
512         // support R2 uuiReq and R1 uuiReq
513         // logic for R2 uuiRequest params in service level
514         for (Entry<String, Object> entry : serviceRequestInputs.entrySet()) {
515             if (entry.getKey().toLowerCase().contains("location")) {
516                 if ("".equals(srcLocation)) {
517                     srcLocation = (String) entry.getValue();
518                 } else if ("".equals(dstLocation)) {
519                     dstLocation = (String) entry.getValue();
520                 }
521             }
522             if (entry.getKey().toLowerCase().contains("clientsignal")) {
523                 if ("".equals(srcClientSignal)) {
524                     srcClientSignal = (String) entry.getValue();
525                 } else if ("".equals(dstClientSignal)) {
526                     dstClientSignal = (String) entry.getValue();
527                 }
528             }
529         }
530
531         // logic for R1 uuiRequest, params in resource level
532         for (Object resource : resources) {
533             Map<String, Object> resourceObject = (Map<String, Object>) resource;
534             Map<String, Object> resourceParametersObject = (Map<String, Object>) resourceObject.get("parameters");
535             Map<String, Object> resourceRequestInputs =
536                     (Map<String, Object>) resourceParametersObject.get("requestInputs");
537             for (Entry<String, Object> entry : resourceRequestInputs.entrySet()) {
538                 if (entry.getKey().toLowerCase().contains("location")) {
539                     if ("".equals(srcLocation)) {
540                         srcLocation = (String) entry.getValue();
541                     } else if ("".equals(dstLocation)) {
542                         dstLocation = (String) entry.getValue();
543                     }
544                 }
545                 if (entry.getKey().toLowerCase().contains("clientsignal")) {
546                     if ("".equals(srcClientSignal)) {
547                         srcClientSignal = (String) entry.getValue();
548                     } else if ("".equals(dstClientSignal)) {
549                         dstClientSignal = (String) entry.getValue();
550                     }
551                 }
552             }
553         }
554
555         Map<String, Object> vpnRequestInputs = getVPNResourceRequestInputs(resources);
556         // here we put client signal to vpn resource inputs
557         if (null != vpnRequestInputs) {
558             vpnRequestInputs.put("src-client-signal", srcClientSignal);
559             vpnRequestInputs.put("dst-client-signal", dstClientSignal);
560         }
561
562
563         // Now we need to query terminal points from SP resourcemgr system.
564         List<Object> locationTerminalPointList = queryTerminalPointsFromServiceProviderSystem(srcLocation, dstLocation);
565         if (locationTerminalPointList != null) {
566             Map<String, Object> tpInfoMap = (Map<String, Object>) locationTerminalPointList.get(0);
567
568             serviceRequestInputs.put("inner-src-access-provider-id", tpInfoMap.get("access-provider-id"));
569             serviceRequestInputs.put("inner-src-access-client-id", tpInfoMap.get("access-client-id"));
570             serviceRequestInputs.put("inner-src-access-topology-id", tpInfoMap.get("access-topology-id"));
571             serviceRequestInputs.put("inner-src-access-node-id", tpInfoMap.get("access-node-id"));
572             serviceRequestInputs.put("inner-src-access-ltp-id", tpInfoMap.get("access-ltp-id"));
573             tpInfoMap = (Map<String, Object>) locationTerminalPointList.get(1);
574
575             serviceRequestInputs.put("inner-dst-access-provider-id", tpInfoMap.get("access-provider-id"));
576             serviceRequestInputs.put("inner-dst-access-client-id", tpInfoMap.get("access-client-id"));
577             serviceRequestInputs.put("inner-dst-access-topology-id", tpInfoMap.get("access-topology-id"));
578             serviceRequestInputs.put("inner-dst-access-node-id", tpInfoMap.get("access-node-id"));
579             serviceRequestInputs.put("inner-dst-access-ltp-id", tpInfoMap.get("access-ltp-id"));
580         }
581         String newRequest = getJsonString(uuiObject);
582         return newRequest;
583     }
584
585     private List<Object> queryTerminalPointsFromServiceProviderSystem(String srcLocation, String dstLocation) {
586         Map<String, String> locationSrc = new HashMap<>();
587         locationSrc.put("location", srcLocation);
588         Map<String, String> locationDst = new HashMap<>();
589         locationDst.put("location", dstLocation);
590         List<Map<String, String>> locations = new ArrayList<>();
591         locations.add(locationSrc);
592         locations.add(locationDst);
593         List<Object> returnList = new ArrayList<>();
594         String reqContent = getJsonString(locations);
595         String url = getThirdSPEndPoint();
596         String responseContent = sendRequest(url, "POST", reqContent);
597         if (null != responseContent) {
598             returnList = getJsonObject(responseContent, List.class);
599         }
600         return returnList;
601     }
602
603     @SuppressWarnings("unchecked")
604     private Map<String, Object> getVPNResourceRequestInputs(List<Object> resources) {
605         for (Object resource : resources) {
606             Map<String, Object> resourceObject = (Map<String, Object>) resource;
607             Map<String, Object> resourceParametersObject = (Map<String, Object>) resourceObject.get("parameters");
608             Map<String, Object> resourceRequestInputs =
609                     (Map<String, Object>) resourceParametersObject.get("requestInputs");
610             for (Entry<String, Object> entry : resourceRequestInputs.entrySet()) {
611                 if (entry.getKey().toLowerCase().contains("vpntype")) {
612                     return resourceRequestInputs;
613                 }
614             }
615         }
616         return null;
617     }
618
619     public static void main(String args[]) {
620         String str =
621                 "restconf/config/GENERIC-RESOURCE-API:services/service/eca7e542-12ba-48de-8544-fac59303b14e/service-data/networks/network/aec07806-1671-4af2-b722-53c8e320a633/network-data/";
622
623         int index1 = str.indexOf("/network/");
624         int index2 = str.indexOf("/network-data");
625
626         String str1 = str.substring(index1 + "/network/".length(), index2);
627         System.out.println(str1);
628
629     }
630
631     @SuppressWarnings("unchecked")
632     private String doSOTNServiceHoming(ServiceDecomposition serviceDecomposition, String uuiRequest) {
633         // query the route for the service.
634         Map<String, Object> uuiObject = getJsonObject(uuiRequest, Map.class);
635         if (uuiObject == null) {
636             return uuiRequest;
637         }
638         Map<String, Object> serviceObject =
639                 (Map<String, Object>) uuiObject.getOrDefault("service", Collections.emptyMap());
640         Map<String, Object> serviceParametersObject =
641                 (Map<String, Object>) serviceObject.getOrDefault("parameters", Collections.emptyMap());
642         Map<String, Object> serviceRequestInputs =
643                 (Map<String, Object>) serviceParametersObject.getOrDefault("requestInputs", Collections.emptyMap());
644         Map<String, Object> oofQueryObject = new HashMap<>();
645         List<Object> resources =
646                 (List<Object>) serviceParametersObject.getOrDefault("resources", Collections.emptyList());
647         oofQueryObject.put("src-access-provider-id", serviceRequestInputs.get("inner-src-access-provider-id"));
648         oofQueryObject.put("src-access-client-id", serviceRequestInputs.get("inner-src-access-client-id"));
649         oofQueryObject.put("src-access-topology-id", serviceRequestInputs.get("inner-src-access-topology-id"));
650         oofQueryObject.put("src-access-node-id", serviceRequestInputs.get("inner-src-access-node-id"));
651         oofQueryObject.put("src-access-ltp-id", serviceRequestInputs.get("inner-src-access-ltp-id"));
652         oofQueryObject.put("dst-access-provider-id", serviceRequestInputs.get("inner-dst-access-provider-id"));
653         oofQueryObject.put("dst-access-client-id", serviceRequestInputs.get("inner-dst-access-client-id"));
654         oofQueryObject.put("dst-access-topology-id", serviceRequestInputs.get("inner-dst-access-topology-id"));
655         oofQueryObject.put("dst-access-node-id", serviceRequestInputs.get("inner-dst-access-node-id"));
656         oofQueryObject.put("dst-access-ltp-id", serviceRequestInputs.get("inner-dst-access-ltp-id"));
657         String oofRequestReq = getJsonString(oofQueryObject);
658         String url = getOOFCalcEndPoint();
659         String responseContent = sendRequest(url, "POST", oofRequestReq);
660
661         List<Object> returnList = new ArrayList<>();
662         if (null != responseContent) {
663             returnList = getJsonObject(responseContent, List.class);
664         }
665         // in demo we have only one VPN. no cross VPNs, so get first item.
666         Map<String, Object> returnRoute = getReturnRoute(returnList);
667         Map<String, Object> vpnRequestInputs = getVPNResourceRequestInputs(resources);
668         if (null != vpnRequestInputs) {
669             vpnRequestInputs.putAll(returnRoute);
670         }
671         return getJsonString(uuiObject);
672     }
673
674     private Map<String, Object> getReturnRoute(List<Object> returnList) {
675         Map<String, Object> returnRoute = new HashMap<>();
676         for (Object returnVpn : returnList) {
677             Map<String, Object> returnVpnInfo = (Map<String, Object>) returnVpn;
678             String accessTopoId = (String) returnVpnInfo.get("access-topology-id");
679             if ("100".equals(accessTopoId)) {
680                 returnRoute.putAll(returnVpnInfo);
681             } else if ("101".equals(accessTopoId)) {
682                 for (String key : returnVpnInfo.keySet()) {
683                     returnRoute.put("domain1-" + key, returnVpnInfo.get(key));
684                 }
685             } else if ("102".equals(accessTopoId)) {
686                 for (String key : returnVpnInfo.keySet()) {
687                     returnRoute.put("domain2-" + key, returnVpnInfo.get(key));
688                 }
689             } else {
690                 for (String key : returnVpnInfo.keySet()) {
691                     returnRoute.put("domain" + accessTopoId + "-" + key, returnVpnInfo.get(key));
692                 }
693             }
694         }
695         return returnRoute;
696     }
697
698     private Map<String, Object> getResourceParams(Execution execution, String resourceCustomizationUuid,
699             String serviceParameters) {
700         List<String> resourceList =
701                 jsonUtil.StringArrayToList(execution, JsonUtils.getJsonValue(serviceParameters, "resources"));
702         // Get the right location str for resource. default is an empty array.
703         String resourceInputsFromUui = "";
704         for (String resource : resourceList) {
705             String resCusUuid = JsonUtils.getJsonValue(resource, "resourceCustomizationUuid");
706             if (resourceCustomizationUuid.equals(resCusUuid)) {
707                 String resourceParameters = JsonUtils.getJsonValue(resource, "parameters");
708                 resourceInputsFromUui = JsonUtils.getJsonValue(resourceParameters, "requestInputs");
709             }
710         }
711         Map<String, Object> resourceInputsFromUuiMap = getJsonObject(resourceInputsFromUui, Map.class);
712         return resourceInputsFromUuiMap;
713     }
714
715     private static <T> T getJsonObject(String jsonstr, Class<T> type) {
716         ObjectMapper mapper = new ObjectMapper();
717         mapper.configure(SerializationFeature.WRAP_ROOT_VALUE, true);
718         try {
719             return mapper.readValue(jsonstr, type);
720         } catch (IOException e) {
721             logger.error("{} {} fail to unMarshal json", MessageEnum.RA_NS_EXC.toString(),
722                     ErrorCode.BusinessProcesssError.getValue(), e);
723         }
724         return null;
725     }
726
727     public static String getJsonString(Object srcObj) {
728         ObjectMapper mapper = new ObjectMapper();
729         mapper.configure(SerializationFeature.WRAP_ROOT_VALUE, false);
730         String jsonStr = null;
731         try {
732             jsonStr = mapper.writeValueAsString(srcObj);
733         } catch (JsonProcessingException e) {
734             logger.debug("SdcToscaParserException", e);
735         }
736         return jsonStr;
737     }
738
739     private static String sendRequest(String url, String methodType, String content) {
740
741         String msbUrl = url;
742         HttpRequestBase method = null;
743         HttpResponse httpResponse = null;
744
745         try {
746             int timeout = DEFAULT_TIME_OUT;
747
748             RequestConfig requestConfig = RequestConfig.custom().setSocketTimeout(timeout).setConnectTimeout(timeout)
749                     .setConnectionRequestTimeout(timeout).build();
750
751             HttpClient client = HttpClientBuilder.create().build();
752
753             if ("POST".equals(methodType.toUpperCase())) {
754                 HttpPost httpPost = new HttpPost(msbUrl);
755                 httpPost.setConfig(requestConfig);
756                 httpPost.setEntity(new StringEntity(content, ContentType.APPLICATION_JSON));
757                 method = httpPost;
758             } else if ("PUT".equals(methodType.toUpperCase())) {
759                 HttpPut httpPut = new HttpPut(msbUrl);
760                 httpPut.setConfig(requestConfig);
761                 httpPut.setEntity(new StringEntity(content, ContentType.APPLICATION_JSON));
762                 method = httpPut;
763             } else if ("GET".equals(methodType.toUpperCase())) {
764                 HttpGet httpGet = new HttpGet(msbUrl);
765                 httpGet.setConfig(requestConfig);
766                 httpGet.addHeader("X-FromAppId", "MSO");
767                 httpGet.addHeader("Accept", "application/json");
768                 method = httpGet;
769             } else if ("DELETE".equals(methodType.toUpperCase())) {
770                 HttpDelete httpDelete = new HttpDelete(msbUrl);
771                 httpDelete.setConfig(requestConfig);
772                 method = httpDelete;
773             }
774
775             httpResponse = client.execute(method);
776             String responseContent = null;
777             if (null != httpResponse && httpResponse.getEntity() != null) {
778                 try {
779                     responseContent = EntityUtils.toString(httpResponse.getEntity(), "UTF-8");
780                 } catch (ParseException e) {
781                     logger.debug("ParseException in sendrequest", e);
782                 } catch (IOException e) {
783                     logger.debug("IOException in sendrequest", e);
784                 }
785             }
786             if (null != method) {
787                 method.reset();
788             }
789             method = null;
790             return responseContent;
791
792         } catch (SocketTimeoutException | ConnectTimeoutException e) {
793             return null;
794
795         } catch (Exception e) {
796             return null;
797
798         } finally {
799             if (httpResponse != null) {
800                 try {
801                     EntityUtils.consume(httpResponse.getEntity());
802                 } catch (Exception e) {
803                 }
804             }
805             if (method != null) {
806                 try {
807                     method.reset();
808                 } catch (Exception e) {
809
810                 }
811             }
812         }
813     }
814
815 }