2  * ============LICENSE_START=======================================================
 
   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
 
  13  *      http://www.apache.org/licenses/LICENSE-2.0
 
  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=========================================================
 
  23 package org.onap.so.bpmn.infrastructure.workflow.service;
 
  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;
 
  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;
 
  78 public class ServicePluginFactory {
 
  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;
 
  85     static JsonUtils jsonUtil = new JsonUtils();
 
  87     private static Logger logger = LoggerFactory.getLogger(ServicePluginFactory.class);
 
  89     private static ServicePluginFactory instance;
 
  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};
 
 100         try (InputStream is = ClassLoader.class.getResourceAsStream("/application.properties")) {
 
 102                 Properties prop = new Properties();
 
 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");
 
 108                 logger.error("Failed to load property file, Either property file is missing or empty!");
 
 110         } catch (IOException e) {
 
 111             logger.error("Failed to load property file!", e);
 
 115     private ServicePluginFactory() {
 
 119     public static synchronized ServicePluginFactory getInstance() {
 
 120         if (null == instance) {
 
 121             instance = new ServicePluginFactory();
 
 127     private String getInventoryOSSEndPoint() {
 
 128         return UrnPropertiesReader.getVariable("mso.service-plugin.inventory-oss-endpoint",
 
 129                 INVENTORY_OSS_DEFAULT_ENDPOINT);
 
 132     private String getThirdSPEndPoint() {
 
 133         return UrnPropertiesReader.getVariable("mso.service-plugin.third-sp-endpoint", THIRD_SP_DEFAULT_ENDPOINT);
 
 136     private String getOOFCalcEndPoint() {
 
 137         return UrnPropertiesReader.getVariable("mso.service-plugin.oof-calc-endpoint", OOF_DEFAULT_ENDPOINT);
 
 140     @SuppressWarnings("unchecked")
 
 141     public String doProcessSiteLocation(ServiceDecomposition serviceDecomposition, String uuiRequest) {
 
 142         if (!isNeedProcessSite(uuiRequest)) {
 
 146         Map<String, Object> uuiObject = getJsonObject(uuiRequest, Map.class);
 
 147         if (uuiObject == null) {
 
 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());
 
 159         if (isSiteLocationLocal(serviceRequestInputs, resources)) {
 
 160             // resources changed : added TP info
 
 161             return getJsonString(uuiObject);
 
 164         List<Resource> addResourceList = new ArrayList<>();
 
 165         addResourceList.addAll(serviceDecomposition.getServiceResources());
 
 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);
 
 183     private boolean isNeedProcessSite(String uuiRequest) {
 
 184         return uuiRequest.toLowerCase().contains("address") && uuiRequest.toLowerCase().contains("clientsignal");
 
 187     @SuppressWarnings("unchecked")
 
 188     private boolean isSiteLocationLocal(Map<String, Object> serviceRequestInputs, List<Object> resources) {
 
 189         Map<String, Object> tpInfoMap = getTPforVPNAttachment(serviceRequestInputs);
 
 191         if (tpInfoMap.isEmpty()) {
 
 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()) {
 
 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"));
 
 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);
 
 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");
 
 229                 if (attacmentResName.equals(curResourceName)) {
 
 230                     logger.info("found match to add site tp info using customized resource name");
 
 231                     putResourceRequestInputs(resource, accessTPInfo);
 
 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;
 
 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();
 
 252             if (key.toLowerCase().contains("clientsignal")) {
 
 253                 clientSignal = entry.getValue();
 
 254                 vpnAttachmentResourceName = key.substring(0, key.indexOf("_"));
 
 258         Map<String, Object> tpInfoMap = new HashMap<>();
 
 260         // Site resource has location param and SOTNAttachment resource has clientSignal param
 
 261         if (location == null || clientSignal == null) {
 
 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)) {
 
 275                     tpInfoMap.put("resourceName", vpnAttachmentResourceName);
 
 276                     logger.info("*** we will try to find resourcename(" + vpnAttachmentResourceName
 
 277                             + ") to add resource input ***");
 
 281             logger.info("Get Terminal TP from InventoryOSS: " + tpInfoMap);
 
 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);
 
 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);
 
 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);
 
 315                     resParametersObject.put("requestInputs", resRequestInputs);
 
 318                 resParametersObject.putAll(resourceRequestInputs);
 
 321             resource.putAll(resourceParametersObject);
 
 329     @SuppressWarnings("unchecked")
 
 330     public String doTPResourcesAllocation(DelegateExecution execution, String uuiRequest) {
 
 331         Map<String, Object> uuiObject = getJsonObject(uuiRequest, Map.class);
 
 332         if (uuiObject == null) {
 
 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());
 
 342         if (!isNeedAllocateCrossTPResources(serviceRequestInputs)) {
 
 346         allocateCrossTPResources(execution, serviceRequestInputs);
 
 347         return getJsonString(uuiObject);
 
 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)) {
 
 358         for (String input : serviceRequestInputs.keySet()) {
 
 359             if (input.toLowerCase().contains("sotnconnectivity")) {
 
 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");
 
 373             String localTP = (String) crossTps.get("local-access-ltp-id");
 
 374             String remoteTP = (String) crossTps.get("remote-access-ltp-id");
 
 376             if (localTPs.contains(localTP) && remoteTPs.contains(remoteTP)) {
 
 377                 logger.info("using same tp returned from AAI");
 
 381             crossTps.put("local-access-ltp-id", localTPs.split(",")[0]);
 
 382             crossTps.put("remote-access-ltp-id", remoteTPs.split(",")[0]);
 
 384         logger.info("cross TP info:" + crossTps);
 
 387     @SuppressWarnings("unchecked")
 
 388     private void allocateCrossTPResources(DelegateExecution execution, Map<String, Object> serviceRequestInputs) {
 
 390         String serviceName = (String) execution.getVariable("serviceInstanceName");
 
 391         Map<String, Object> crossTPs = this.getTPsfromAAI(serviceName);
 
 392         // customizeTP(crossTPs, serviceName, execution);
 
 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", "");
 
 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"));
 
 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()) {
 
 423             String[] allowedList =
 
 424                     UrnPropertiesReader.getVariable(CUSTOM_RESOURCE_TP + "." + customType.get() + ".local").split(",");
 
 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());
 
 439             logger.error("There is no matching logical link for allowed list :{}", Arrays.toString(allowedList));
 
 442             logger.info("link customization is not required");
 
 443             return logicalLinks.get(0);
 
 447     // This method returns Local and remote TPs information from AAI
 
 448     public Map getTPsfromAAI(String serviceName) {
 
 449         Map<String, Object> tpInfo = new HashMap<>();
 
 451         AAIPluralResourceUri uri = AAIUriFactory.createResourceUri(AAIObjectPlurals.LOGICAL_LINK);
 
 452         AAIResourcesClient client = new AAIResourcesClient();
 
 453         Optional<LogicalLinks> result = client.get(LogicalLinks.class, uri);
 
 455         if (result.isPresent()) {
 
 456             LogicalLinks links = result.get();
 
 457             LogicalLink link = selectLogicalLink(links.getLogicalLink(), serviceName);
 
 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()) {
 
 470                     pInterfaces.addAll(relationships.getRelatedAAIUris(AAIObjectType.P_INTERFACE));
 
 472                         // find remote p interface
 
 473                         AAIResourceUri localTP = null;
 
 474                         AAIResourceUri remoteTP = null;
 
 476                         AAIResourceUri pInterface0 = pInterfaces.get(0);
 
 478                         if (isRemotePInterface(client, pInterface0)) {
 
 479                             remoteTP = pInterfaces.get(0);
 
 480                             localTP = pInterfaces.get(1);
 
 482                             localTP = pInterfaces.get(0);
 
 483                             remoteTP = pInterfaces.get(1);
 
 486                         tpInfo = getTPInfo(client, localTP, remoteTP);
 
 494     private Map<String, Object> getTPInfo(AAIResourcesClient client, AAIResourceUri localTP, AAIResourceUri remoteTP) {
 
 496         Map<String, Object> tpInfo = new HashMap<>();
 
 498         if (localTP != null && remoteTP != null) {
 
 500             String tpUrl = localTP.build().toString();
 
 501             String localNodeId = tpUrl.split("/")[4];
 
 502             tpInfo.put("local-access-node-id", localNodeId);
 
 504             logger.info("Get info for local TP :{}", localNodeId);
 
 505             Optional<Pnf> optLocalPnf =
 
 506                     client.get(Pnf.class, AAIUriFactory.createResourceUri(AAIObjectType.PNF, localNodeId));
 
 509             getTpInfoFromLocalTp(tpInfo, optLocalPnf);
 
 511             String ltpIdStr = tpUrl.substring(tpUrl.lastIndexOf("/") + 1);
 
 512             if (ltpIdStr.contains("-")) {
 
 513                 tpInfo.put("local-access-ltp-id", ltpIdStr.substring(ltpIdStr.lastIndexOf("-") + 1));
 
 517             tpUrl = remoteTP.build().toString();
 
 518             PInterface intfRemote = client.get(PInterface.class, remoteTP).get();
 
 520             String remoteNodeId = tpUrl.split("/")[4];
 
 521             tpInfo.put("remote-access-node-id", remoteNodeId);
 
 523             logger.info("Get info for remote TP:{}", remoteNodeId);
 
 525             String[] networkRefRemote = intfRemote.getNetworkRef().split("-");
 
 526             Optional<Pnf> optRemotePnf =
 
 527                     client.get(Pnf.class, AAIUriFactory.createResourceUri(AAIObjectType.PNF, remoteNodeId));
 
 529             getTpInfoFromRemoteTp(tpInfo, networkRefRemote, optRemotePnf);
 
 531             String ltpIdStrR = tpUrl.substring(tpUrl.lastIndexOf("/") + 1);
 
 532             if (ltpIdStrR.contains("-")) {
 
 533                 tpInfo.put("remote-access-ltp-id", ltpIdStrR.substring(ltpIdStr.lastIndexOf("-") + 1));
 
 541     private void getTpInfoFromLocalTp(Map<String, Object> tpInfo, Optional<Pnf> optLocalPnf) {
 
 542         if (optLocalPnf.isPresent()) {
 
 543             Pnf localPnf = optLocalPnf.get();
 
 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]);
 
 559     private void getTpInfoFromRemoteTp(Map<String, Object> tpInfo, String[] networkRefRemote,
 
 560             Optional<Pnf> optRemotePnf) {
 
 561         if (optRemotePnf.isPresent()) {
 
 562             Pnf remotePnf = optRemotePnf.get();
 
 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]);
 
 579     // this method check if pInterface is remote
 
 580     private boolean isRemotePInterface(AAIResourcesClient client, AAIResourceUri uri) {
 
 582         String uriString = uri.build().toString();
 
 584         if (uriString != null) {
 
 586             String[] token = uriString.split("/");
 
 587             AAIResourceUri parent = AAIUriFactory.createResourceUri(AAIObjectType.PNF, token[4]);
 
 589             AAIResultWrapper wrapper = client.get(parent);
 
 590             Optional<Relationships> optRelationships = wrapper.getRelationships();
 
 591             if (optRelationships.isPresent()) {
 
 592                 Relationships relationships = optRelationships.get();
 
 594                 return !relationships.getRelatedAAIUris(AAIObjectType.EXT_AAI_NETWORK).isEmpty();
 
 601     public String preProcessService(ServiceDecomposition serviceDecomposition, String uuiRequest) {
 
 604         if (isSOTN(serviceDecomposition, uuiRequest)) {
 
 605             // We Need to query the terminalpoint of the VPN by site location
 
 607             return preProcessSOTNService(serviceDecomposition, uuiRequest);
 
 612     public String doServiceHoming(ServiceDecomposition serviceDecomposition, String uuiRequest) {
 
 614         if (isSOTN(serviceDecomposition, uuiRequest)) {
 
 615             return doSOTNServiceHoming(serviceDecomposition, uuiRequest);
 
 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");
 
 625     @SuppressWarnings("unchecked")
 
 626     private String preProcessSOTNService(ServiceDecomposition serviceDecomposition, String uuiRequest) {
 
 627         Map<String, Object> uuiObject = getJsonObject(uuiRequest, Map.class);
 
 628         if (uuiObject == null) {
 
 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();
 
 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();
 
 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();
 
 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();
 
 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);
 
 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);
 
 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);
 
 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"));
 
 713         String newRequest = getJsonString(uuiObject);
 
 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);
 
 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;
 
 751     public static void main(String args[]) {
 
 753                 "restconf/config/GENERIC-RESOURCE-API:services/service/eca7e542-12ba-48de-8544-fac59303b14e/service-data/networks/network/aec07806-1671-4af2-b722-53c8e320a633/network-data/";
 
 755         int index1 = str.indexOf("/network/");
 
 756         int index2 = str.indexOf("/network-data");
 
 758         String str1 = str.substring(index1 + "/network/".length(), index2);
 
 759         System.out.println(str1);
 
 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) {
 
 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);
 
 793         List<Object> returnList = new ArrayList<>();
 
 794         if (null != responseContent) {
 
 795             returnList = getJsonObject(responseContent, List.class);
 
 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);
 
 803         return getJsonString(uuiObject);
 
 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));
 
 817             } else if ("102".equals(accessTopoId)) {
 
 818                 for (String key : returnVpnInfo.keySet()) {
 
 819                     returnRoute.put("domain2-" + key, returnVpnInfo.get(key));
 
 822                 for (String key : returnVpnInfo.keySet()) {
 
 823                     returnRoute.put("domain" + accessTopoId + "-" + key, returnVpnInfo.get(key));
 
 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");
 
 843         Map<String, Object> resourceInputsFromUuiMap = getJsonObject(resourceInputsFromUui, Map.class);
 
 844         return resourceInputsFromUuiMap;
 
 847     private static <T> T getJsonObject(String jsonstr, Class<T> type) {
 
 848         ObjectMapper mapper = new ObjectMapper();
 
 849         mapper.configure(SerializationFeature.WRAP_ROOT_VALUE, true);
 
 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);
 
 859     public static String getJsonString(Object srcObj) {
 
 860         ObjectMapper mapper = new ObjectMapper();
 
 861         mapper.configure(SerializationFeature.WRAP_ROOT_VALUE, false);
 
 862         String jsonStr = null;
 
 864             jsonStr = mapper.writeValueAsString(srcObj);
 
 865         } catch (JsonProcessingException e) {
 
 866             logger.debug("SdcToscaParserException", e);
 
 871     private static String sendRequest(String url, String methodType, String content) {
 
 874         HttpRequestBase method = null;
 
 875         HttpResponse httpResponse = null;
 
 877         try (CloseableHttpClient client = HttpClientBuilder.create().build()) {
 
 878             int timeout = DEFAULT_TIME_OUT;
 
 880             RequestConfig requestConfig = RequestConfig.custom().setSocketTimeout(timeout).setConnectTimeout(timeout)
 
 881                     .setConnectionRequestTimeout(timeout).build();
 
 883             if ("POST".equalsIgnoreCase(methodType)) {
 
 884                 HttpPost httpPost = new HttpPost(msbUrl);
 
 885                 httpPost.setConfig(requestConfig);
 
 886                 httpPost.setEntity(new StringEntity(content, ContentType.APPLICATION_JSON));
 
 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));
 
 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");
 
 899             } else if ("DELETE".equalsIgnoreCase(methodType)) {
 
 900                 HttpDelete httpDelete = new HttpDelete(msbUrl);
 
 901                 httpDelete.setConfig(requestConfig);
 
 905             httpResponse = client.execute(method);
 
 906             String responseContent = null;
 
 907             if (null != httpResponse && httpResponse.getEntity() != null) {
 
 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);
 
 916             if (null != method) {
 
 920             return responseContent;
 
 922         } catch (Exception e) {
 
 923             logger.debug("Exception in sendRequest", e);
 
 927             if (httpResponse != null) {
 
 929                     EntityUtils.consume(httpResponse.getEntity());
 
 930                 } catch (Exception e) {
 
 931                     logger.debug("Exception while executing finally block", e);
 
 934             if (method != null) {
 
 937                 } catch (Exception e) {
 
 938                     logger.debug("Exception while executing finally block", e);