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