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