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