diff options
author | PATTANAYAK, SAUMYA SWARUP (sp931a) <sp931a@att.com> | 2021-09-22 10:22:53 -0400 |
---|---|---|
committer | PATTANAYAK, SAUMYA SWARUP (sp931a) <sp931a@att.com> | 2021-09-29 10:28:22 -0400 |
commit | f78df9f30d5b7bda1b291bff34dd85bdd9411c12 (patch) | |
tree | 3bdcae2f31ebdbb6bb2ff21e13a26d83f2e74a00 /vid-app-common/src | |
parent | a1d209deac01bc0f8f7be96a585bdbef9cc0cdb9 (diff) |
AAI Query optimization for VID
Issue-ID: VID-986
Change-Id: Ia3e012c41df4e9049ce9a1ae56ec83b276e11611
Signed-off-by: PATTANAYAK, SAUMYA SWARUP (sp931a) <sp931a@att.com>
Diffstat (limited to 'vid-app-common/src')
19 files changed, 1197 insertions, 15 deletions
diff --git a/vid-app-common/src/main/java/org/onap/vid/aai/AaiClient.java b/vid-app-common/src/main/java/org/onap/vid/aai/AaiClient.java index 00137b60c..d37adba7f 100644 --- a/vid-app-common/src/main/java/org/onap/vid/aai/AaiClient.java +++ b/vid-app-common/src/main/java/org/onap/vid/aai/AaiClient.java @@ -109,7 +109,7 @@ public class AaiClient implements AaiClientInterface { private static final String BUSINESS_CUSTOMER = "/business/customers/customer/"; private static final String SERVICE_INSTANCE = "/service-instances/service-instance/"; private static final String BUSINESS_CUSTOMERS_CUSTOMER = "business/customers/customer/"; - + private static final String QUERY_FORMAT_RESOURCE_DSL = "dsl?format=resource&nodesOnly=true&depth=0&as-tree=true"; protected String fromAppId = "VidAaiController"; private PortDetailsTranslator portDetailsTranslator; @@ -919,6 +919,39 @@ public class AaiClient implements AaiClientInterface { } @Override + public AaiResponse<DSLQuerySimpleResponse> getServiceInstanceBySubscriberIdAndInstanceIdentifier(String globalCustomerId, String identifierType, String serviceIdentifier) { + ResponseWithRequestInfo response; + String payload = getDSLQueryPayloadByServiceIdentifier(globalCustomerId,identifierType,serviceIdentifier); +// Response resp = doAaiPut(QUERY_FORMAT_RESOURCE_DSL, payload, false); +// resp.bufferEntity(); +// String rawPayload = resp.readEntity(String.class); +// AaiResponse<DSLQuerySimpleResponse> aaiResponse = processAaiResponse(resp, DSLQuerySimpleResponse.class, rawPayload); + + response = doAaiPut(QUERY_FORMAT_RESOURCE_DSL, payload, false, false); + AaiResponseWithRequestInfo<DSLQuerySimpleResponse> aaiResponse = processAaiResponse(response, DSLQuerySimpleResponse.class, false); + verifyAaiResponseValidityOrThrowExc(aaiResponse, aaiResponse.getAaiResponse().getHttpCode()); + return aaiResponse.getAaiResponse(); + } + + private String getDSLQueryPayloadByServiceIdentifier(String globalCustomerId, String identifierType, String serviceIdentifier) { + String query = null; + String payLoad = null; + if(globalCustomerId != null && identifierType != null && serviceIdentifier != null) { + if(identifierType.equalsIgnoreCase("Service Instance Id")) { + query = "customer*('global-customer-id','"+globalCustomerId+"')>" + + "service-subscription>service-instance*('service-instance-id','"+serviceIdentifier+"')"; + payLoad = "{\"dsl\":\"" + query + "\"}"; + } else { + query = "customer*('global-customer-id','"+globalCustomerId+"')>" + + "service-subscription>service-instance*('service-instance-name','"+serviceIdentifier+"')"; + payLoad = "{\"dsl\":\"" + query + "\"}"; + } + + } + return payLoad; + } + + @Override public void resetCache(String cacheName) { cacheProvider.resetCache(cacheName); } diff --git a/vid-app-common/src/main/java/org/onap/vid/aai/AaiClientInterface.java b/vid-app-common/src/main/java/org/onap/vid/aai/AaiClientInterface.java index c322afa22..a1edc8d5c 100644 --- a/vid-app-common/src/main/java/org/onap/vid/aai/AaiClientInterface.java +++ b/vid-app-common/src/main/java/org/onap/vid/aai/AaiClientInterface.java @@ -108,4 +108,6 @@ public interface AaiClientInterface extends ProbeInterface { Map<String, Properties> getCloudRegionAndTenantByVnfId(String vnfId); AaiResponse<AaiGetVnfResponse> getVnfsByParamsForChangeManagement(String subscriberId, String serviceType, String nfRole, String cloudRegion); + + AaiResponse getServiceInstanceBySubscriberIdAndInstanceIdentifier(String globalCustomerId, String identifierType, String serviceIdentifier); } diff --git a/vid-app-common/src/main/java/org/onap/vid/aai/Customer.java b/vid-app-common/src/main/java/org/onap/vid/aai/Customer.java new file mode 100644 index 000000000..a28b3c396 --- /dev/null +++ b/vid-app-common/src/main/java/org/onap/vid/aai/Customer.java @@ -0,0 +1,84 @@ +/*- + * ============LICENSE_START======================================================= + * VID + * ================================================================================ + * Copyright (C) 2017 - 2019 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.onap.vid.aai; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonProperty; +import java.util.List; + +@JsonIgnoreProperties(ignoreUnknown = true) +public class Customer { + + @JsonProperty("global-customer-id") + public String globalCustomerId; + + @JsonProperty("subscriber-name") + public String subscriberName; + + public String getGlobalCustomerId() { + return globalCustomerId; + } + + public void setGlobalCustomerId(String globalCustomerId) { + this.globalCustomerId = globalCustomerId; + } + + public String getSubscriberName() { + return subscriberName; + } + + public void setSubscriberName(String subscriberName) { + this.subscriberName = subscriberName; + } + + public String getSubscriberType() { + return subscriberType; + } + + public void setSubscriberType(String subscriberType) { + this.subscriberType = subscriberType; + } + + public String getResourceVersion() { + return resourceVersion; + } + + public void setResourceVersion(String resourceVersion) { + this.resourceVersion = resourceVersion; + } + + public List<CustomerRelatedNodes> getCustomerRelatedNodes() { + return customerRelatedNodes; + } + + public void setCustomerRelatedNodes(List<CustomerRelatedNodes> customerRelatedNodes) { + this.customerRelatedNodes = customerRelatedNodes; + } + + @JsonProperty("subscriber-type") + public String subscriberType; + + @JsonProperty("resource-version") + public String resourceVersion; + + @JsonProperty("related-nodes") + public List<CustomerRelatedNodes> customerRelatedNodes; +} diff --git a/vid-app-common/src/main/java/org/onap/vid/aai/CustomerRelatedNodes.java b/vid-app-common/src/main/java/org/onap/vid/aai/CustomerRelatedNodes.java new file mode 100644 index 000000000..7637e312e --- /dev/null +++ b/vid-app-common/src/main/java/org/onap/vid/aai/CustomerRelatedNodes.java @@ -0,0 +1,40 @@ +/*- + * ============LICENSE_START======================================================= + * VID + * ================================================================================ + * Copyright (C) 2017 - 2019 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.onap.vid.aai; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonProperty; + +@JsonIgnoreProperties(ignoreUnknown = true) +public class CustomerRelatedNodes { + + public CustomerServiceSubscription getCustomerServiceSubscription() { + return customerServiceSubscription; + } + + public void setCustomerServiceSubscription(CustomerServiceSubscription customerServiceSubscription) { + this.customerServiceSubscription = customerServiceSubscription; + } + + @JsonProperty("service-subscription") + public CustomerServiceSubscription customerServiceSubscription; + +} diff --git a/vid-app-common/src/main/java/org/onap/vid/aai/CustomerServiceSubscription.java b/vid-app-common/src/main/java/org/onap/vid/aai/CustomerServiceSubscription.java new file mode 100644 index 000000000..9b94cf66b --- /dev/null +++ b/vid-app-common/src/main/java/org/onap/vid/aai/CustomerServiceSubscription.java @@ -0,0 +1,62 @@ +/*- + * ============LICENSE_START======================================================= + * VID + * ================================================================================ + * Copyright (C) 2017 - 2019 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.onap.vid.aai; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonProperty; +import java.util.List; + +@JsonIgnoreProperties(ignoreUnknown = true) +public class CustomerServiceSubscription { + + @JsonProperty("service-type") + public String serviceType; + + public String getServiceType() { + return serviceType; + } + + public void setServiceType(String serviceType) { + this.serviceType = serviceType; + } + + public String getResourceVersion() { + return resourceVersion; + } + + public void setResourceVersion(String resourceVersion) { + this.resourceVersion = resourceVersion; + } + + public List<ServiceSubscriptionRelatedNodes> getServiceSubscriptionRelatedNodes() { + return serviceSubscriptionRelatedNodes; + } + + public void setServiceSubscriptionRelatedNodes(List<ServiceSubscriptionRelatedNodes> serviceSubscriptionRelatedNodes) { + this.serviceSubscriptionRelatedNodes = serviceSubscriptionRelatedNodes; + } + + @JsonProperty("resource-version") + public String resourceVersion; + + @JsonProperty("related-nodes") + public List<ServiceSubscriptionRelatedNodes> serviceSubscriptionRelatedNodes; +} diff --git a/vid-app-common/src/main/java/org/onap/vid/aai/CustomerSpecificServiceInstance.java b/vid-app-common/src/main/java/org/onap/vid/aai/CustomerSpecificServiceInstance.java new file mode 100644 index 000000000..ef6f49833 --- /dev/null +++ b/vid-app-common/src/main/java/org/onap/vid/aai/CustomerSpecificServiceInstance.java @@ -0,0 +1,150 @@ +/*- + * ============LICENSE_START======================================================= + * VID + * ================================================================================ + * Copyright (C) 2017 - 2019 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.onap.vid.aai; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonProperty; + +@JsonIgnoreProperties(ignoreUnknown = true) +public class CustomerSpecificServiceInstance { + + @JsonProperty("service-instance-id") + public String serviceInstanceId; + + @JsonProperty("service-instance-name") + public String serviceInstanceName; + + @JsonProperty("orchestration-status") + public String orchestrationStatus; + + @JsonProperty("model-invariant-id") + public String modelInvariantId; + + @JsonProperty("model-version-id") + public String modelVersionId; + + public String getServiceInstanceId() { + return serviceInstanceId; + } + + public void setServiceInstanceId(String serviceInstanceId) { + this.serviceInstanceId = serviceInstanceId; + } + + public String getServiceInstanceName() { + return serviceInstanceName; + } + + public void setServiceInstanceName(String serviceInstanceName) { + this.serviceInstanceName = serviceInstanceName; + } + + public String getOrchestrationStatus() { + return orchestrationStatus; + } + + public void setOrchestrationStatus(String orchestrationStatus) { + this.orchestrationStatus = orchestrationStatus; + } + + public String getModelInvariantId() { + return modelInvariantId; + } + + public void setModelInvariantId(String modelInvariantId) { + this.modelInvariantId = modelInvariantId; + } + + public String getModelVersionId() { + return modelVersionId; + } + + public void setModelVersionId(String modelVersionId) { + this.modelVersionId = modelVersionId; + } + + public String getSelfLink() { + return selfLink; + } + + public void setSelfLink(String selfLink) { + this.selfLink = selfLink; + } + + public String getServiceRole() { + return serviceRole; + } + + public void setServiceRole(String serviceRole) { + this.serviceRole = serviceRole; + } + + public String getServiceType() { + return serviceType; + } + + public void setServiceType(String serviceType) { + this.serviceType = serviceType; + } + + public String getEnvironmentContext() { + return environmentContext; + } + + public void setEnvironmentContext(String environmentContext) { + this.environmentContext = environmentContext; + } + + public String getWorkloadContext() { + return workloadContext; + } + + public void setWorkloadContext(String workloadContext) { + this.workloadContext = workloadContext; + } + + public String getResourceVersion() { + return resourceVersion; + } + + public void setResourceVersion(String resourceVersion) { + this.resourceVersion = resourceVersion; + } + + @JsonProperty("selflink") + public String selfLink; + + @JsonProperty("service-role") + public String serviceRole; + + @JsonProperty("service-type") + public String serviceType; + + @JsonProperty("environment-context") + public String environmentContext; + + @JsonProperty("workload-context") + public String workloadContext; + + @JsonProperty("resource-version") + public String resourceVersion; + +} diff --git a/vid-app-common/src/main/java/org/onap/vid/aai/DSLQuerySimpleResponse.java b/vid-app-common/src/main/java/org/onap/vid/aai/DSLQuerySimpleResponse.java new file mode 100644 index 000000000..e151ffd97 --- /dev/null +++ b/vid-app-common/src/main/java/org/onap/vid/aai/DSLQuerySimpleResponse.java @@ -0,0 +1,45 @@ +/*- + * ============LICENSE_START======================================================= + * VID + * ================================================================================ + * Copyright (C) 2017 - 2019 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.onap.vid.aai; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonProperty; +import java.util.List; + +//@JsonInclude(JsonInclude.Include.NON_NULL) +//@JsonPropertyOrder({ +// "results" +//}) +@JsonIgnoreProperties(ignoreUnknown = true) +public class DSLQuerySimpleResponse { + + private final List<ServiceInstanceResponseBySubscriber> results; + + public DSLQuerySimpleResponse(@JsonProperty("results") List<ServiceInstanceResponseBySubscriber> results) { + this.results = results; + } + + public List<ServiceInstanceResponseBySubscriber> getResults() { + return results; + } + + +} diff --git a/vid-app-common/src/main/java/org/onap/vid/aai/ServiceInstanceResponseBySubscriber.java b/vid-app-common/src/main/java/org/onap/vid/aai/ServiceInstanceResponseBySubscriber.java new file mode 100644 index 000000000..3c4071e9e --- /dev/null +++ b/vid-app-common/src/main/java/org/onap/vid/aai/ServiceInstanceResponseBySubscriber.java @@ -0,0 +1,43 @@ +/*- + * ============LICENSE_START======================================================= + * VID + * ================================================================================ + * Copyright (C) 2017 - 2019 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.onap.vid.aai; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonProperty; + +//@JsonInclude(JsonInclude.Include.NON_NULL) +//@JsonPropertyOrder({ +// "results" +//}) +@JsonIgnoreProperties(ignoreUnknown = true) +public class ServiceInstanceResponseBySubscriber { + + public Customer getCustomer() { + return customer; + } + + public void setCustomer(Customer customer) { + this.customer = customer; + } + + @JsonProperty("customer") + public Customer customer; +} diff --git a/vid-app-common/src/main/java/org/onap/vid/aai/ServiceSubscriptionRelatedNodes.java b/vid-app-common/src/main/java/org/onap/vid/aai/ServiceSubscriptionRelatedNodes.java new file mode 100644 index 000000000..a991b980d --- /dev/null +++ b/vid-app-common/src/main/java/org/onap/vid/aai/ServiceSubscriptionRelatedNodes.java @@ -0,0 +1,39 @@ +/*- + * ============LICENSE_START======================================================= + * VID + * ================================================================================ + * Copyright (C) 2017 - 2019 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.onap.vid.aai; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonProperty; + +@JsonIgnoreProperties(ignoreUnknown = true) +public class ServiceSubscriptionRelatedNodes { + + public CustomerSpecificServiceInstance getServiceInstance() { + return serviceInstance; + } + + public void setServiceInstance(CustomerSpecificServiceInstance serviceInstance) { + this.serviceInstance = serviceInstance; + } + + @JsonProperty("service-instance") + public CustomerSpecificServiceInstance serviceInstance; +} diff --git a/vid-app-common/src/main/java/org/onap/vid/aai/model/ViewEditSIResult.java b/vid-app-common/src/main/java/org/onap/vid/aai/model/ViewEditSIResult.java new file mode 100644 index 000000000..f06cd9169 --- /dev/null +++ b/vid-app-common/src/main/java/org/onap/vid/aai/model/ViewEditSIResult.java @@ -0,0 +1,94 @@ +/*- + * ============LICENSE_START======================================================= + * VID + * ================================================================================ + * Copyright (C) 2017 - 2019 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.onap.vid.aai.model; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonProperty; + +@JsonIgnoreProperties(ignoreUnknown = true) +public class ViewEditSIResult { + + private String serviceInstanceId; + + public String getServiceInstanceId() { + return serviceInstanceId; + } + + @JsonProperty("serviceInstanceId") + public void setServiceInstanceId(String serviceInstanceId) { + this.serviceInstanceId = serviceInstanceId; + } + + public String getServiceInstanceName() { + return serviceInstanceName; + } + + @JsonProperty("serviceInstanceName") + public void setServiceInstanceName(String serviceInstanceName) { + this.serviceInstanceName = serviceInstanceName; + } + + public String getModelVersionId() { + return modelVersionId; + } + + @JsonProperty("modelVersionId") + public void setModelVersionId(String modelVersionId) { + this.modelVersionId = modelVersionId; + } + + public String getModelInvariantId() { + return modelInvariantId; + } + @JsonProperty("modelInvariantId") + public void setModelInvariantId(String modelInvariantId) { + this.modelInvariantId = modelInvariantId; + } + + public String getOrchestrationStatus() { + return orchestrationStatus; + } + @JsonProperty("orchestrationStatus") + public void setOrchestrationStatus(String orchestrationStatus) { + this.orchestrationStatus = orchestrationStatus; + } + + public String getSubscriberName() { + return subscriberName; + } + @JsonProperty("subscriberName") + public void setSubscriberName(String subscriberName) { + this.subscriberName = subscriberName; + } + + private String serviceInstanceName; + private String modelVersionId; + private String modelInvariantId; + private String orchestrationStatus; + private String subscriberName; + + + + + + + +} diff --git a/vid-app-common/src/main/java/org/onap/vid/controller/AaiController.java b/vid-app-common/src/main/java/org/onap/vid/controller/AaiController.java index a9ce40bba..e4fbecaf3 100644 --- a/vid-app-common/src/main/java/org/onap/vid/controller/AaiController.java +++ b/vid-app-common/src/main/java/org/onap/vid/controller/AaiController.java @@ -27,6 +27,7 @@ import com.fasterxml.jackson.databind.ObjectMapper; import java.io.IOException; import java.util.List; import java.util.Map; +import java.util.Optional; import java.util.UUID; import java.util.stream.Collectors; import javax.servlet.http.HttpServletRequest; @@ -68,6 +69,16 @@ import org.springframework.web.servlet.HandlerMapping; import org.springframework.web.servlet.ModelAndView; import org.togglz.core.manager.FeatureManager; +import org.json.JSONException; +import org.json.JSONObject; +import org.json.simple.JSONArray; +import org.json.simple.parser.JSONParser; +import org.json.simple.parser.ParseException; +import org.onap.vid.aai.CustomerSpecificServiceInstance; +import org.onap.vid.aai.DSLQuerySimpleResponse; +import org.onap.vid.aai.model.ServiceRelationships; +import org.onap.vid.aai.model.ViewEditSIResult; + @RestController public class AaiController extends RestrictedBaseController { @@ -268,14 +279,27 @@ public class AaiController extends RestrictedBaseController { public ResponseEntity<String> SearchServiceInstances(HttpServletRequest request, @RequestParam(value = "subscriberId", required = false) String subscriberId, @RequestParam(value = "serviceInstanceIdentifier", required = false) String instanceIdentifier, + @RequestParam(value = "serviceInstanceIdentifierType", required = false) String instanceIdentifierType, @RequestParam(value = "project", required = false) List<String> projects, @RequestParam(value = "owningEntity", required = false) List<String> owningEntities) throws IOException { ResponseEntity responseEntity; RoleValidator roleValidator = roleProvider.getUserRolesValidator(request); - AaiResponse<ServiceInstancesSearchResults> searchResult = aaiService - .getServiceInstanceSearchResults(subscriberId, instanceIdentifier, roleValidator, owningEntities, projects); + AaiResponse<ServiceInstancesSearchResults> searchResult = null; + + if( instanceIdentifier != null && isValidInstanceIdentifierType(instanceIdentifierType)) { + LOGGER.debug(EELFLoggerDelegate.debugLogger, "<== search_service_instances search by subscriberId " + + " instanceIdentifier and instanceIdentifierType start"); + searchResult = aaiService + .getServiceInstanceSearchResultsByIdentifierType(subscriberId, instanceIdentifier, + instanceIdentifierType, roleValidator, owningEntities, projects); + } else { + LOGGER.debug(EELFLoggerDelegate.debugLogger, "<== search_service_instances search by subscriberId " + + "instanceIdentifier instanceIdentifier and instanceIdentifierType start"); + searchResult = aaiService + .getServiceInstanceSearchResults(subscriberId, instanceIdentifier, roleValidator, owningEntities, projects); + } String httpMessage = searchResult.getT() != null ? objectMapper.writeValueAsString(searchResult.getT()) : @@ -291,6 +315,85 @@ public class AaiController extends RestrictedBaseController { return responseEntity; } + @RequestMapping(value = { + "/aai_get_service_instance_by_id_and_type/{globalCustomerId}/{serviceInstanceIdentifier}/{serviceIdentifierType}/{subscriberName}", + "/aai_get_service_instance_by_id_and_type/{globalCustomerId}/{serviceInstanceIdentifier}/{serviceIdentifierType}"}, + method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE) + public ResponseEntity<String> doGetServiceInstanceByIdAndType( + @PathVariable("globalCustomerId") String globalCustomerId, + @PathVariable("serviceInstanceIdentifier") String serviceInstanceIdentifier, + @PathVariable("serviceIdentifierType") String serviceIdentifierType, + @PathVariable("subscriberName") java.util.Optional<String> subscriberName) throws IOException { + + AaiResponse aaiResponse = null; + String orchStatus = null; + String siid, siName, modelVerId, modelInvId = null; + String errorMessage = null; + int statusCode = -1; + ViewEditSIResult viewEditSIResult = new ViewEditSIResult(); + if(!subscriberName.equals(Optional.empty()) && serviceInstanceIdentifier != null) { + LOGGER.debug(EELFLoggerDelegate.debugLogger, "<== " + ".aai_get_service_instance_by_id_and_type. " + + "Search node query to get Service Type: "+serviceInstanceIdentifier); + ResponseEntity entity = convertResponseToResponseEntity(doAaiGet( + "search/nodes-query?search-node-type=service-instance&filter=service-instance-id:EQUALS:" + + serviceInstanceIdentifier, false)); + JSONParser jsonParser = new JSONParser(); + try { + if(entity != null) { + org.json.simple.JSONObject jsonObject = (org.json.simple.JSONObject) jsonParser.parse( + entity.getBody().toString()); + JSONArray jSONArray = (JSONArray)jsonObject.get("result-data"); + org.json.simple.JSONObject jSONObject = (org.json.simple.JSONObject)jSONArray.get(0); + String resourceLink = jSONObject.get("resource-link").toString(); + String serviceType = resourceLink.split("/")[9]; + aaiResponse = aaiService.getServiceInstanceBySubscriberIdAndSIID(globalCustomerId,serviceType, + serviceInstanceIdentifier); + if(aaiResponse != null && aaiResponse.getT() != null) { + viewEditSIResult.setOrchestrationStatus(((ServiceRelationships) aaiResponse.getT()).orchestrationStatus); + viewEditSIResult.setServiceInstanceId(((ServiceRelationships) aaiResponse.getT()).serviceInstanceId); + viewEditSIResult.setServiceInstanceName(((ServiceRelationships) aaiResponse.getT()).serviceInstanceName); + viewEditSIResult.setModelVersionId(((ServiceRelationships) aaiResponse.getT()).modelVersionId); + viewEditSIResult.setModelInvariantId(((ServiceRelationships) aaiResponse.getT()).modelInvariantId); + viewEditSIResult.setSubscriberName(subscriberName.get()); + } else { + LOGGER.info(EELFLoggerDelegate.errorLogger, "<== " + ".aai_get_service_instance_by_id_and_type. No response for getServiceInstanceBySubscriberIdAndSIID: "+serviceInstanceIdentifier); + errorMessage = aaiResponse.getErrorMessage(); + } + statusCode = aaiResponse.getHttpCode(); + } else { + LOGGER.info(EELFLoggerDelegate.errorLogger, "<== " + ".aai_get_service_instance_by_id_and_type. No response for nodes-query for siid: "+serviceInstanceIdentifier); + statusCode = entity.getStatusCode().value(); + errorMessage = aaiResponse.getErrorMessage(); + } + } catch (Exception e) { + LOGGER.info(EELFLoggerDelegate.errorLogger, "<== " + ".aai_get_service_instance_by_id_and_type" + e.toString()); + LOGGER.debug(EELFLoggerDelegate.debugLogger, "<== " + ".aai_get_service_instance_by_id_and_type" + e.toString()); + } + } else { + LOGGER.debug(EELFLoggerDelegate.debugLogger, "<== " + ".aai_get_service_instance_by_id_and_type. Use DSL query to get SI details."+serviceInstanceIdentifier); + aaiResponse = aaiService + .getServiceInstanceBySubscriberIdAndInstanceIdentifier(globalCustomerId, serviceIdentifierType, serviceInstanceIdentifier); + if(aaiResponse != null && aaiResponse.getT() != null) { + CustomerSpecificServiceInstance siData = ((DSLQuerySimpleResponse)aaiResponse.getT()).getResults().get(0).getCustomer(). + customerRelatedNodes.get(0).getCustomerServiceSubscription(). + getServiceSubscriptionRelatedNodes().get(0).getServiceInstance(); + viewEditSIResult.setOrchestrationStatus(siData.getOrchestrationStatus()); + viewEditSIResult.setServiceInstanceId(siData.serviceInstanceId); + viewEditSIResult.setServiceInstanceName(siData.serviceInstanceName); + viewEditSIResult.setModelVersionId(siData.modelVersionId); + viewEditSIResult.setModelInvariantId(siData.modelInvariantId); + viewEditSIResult.setSubscriberName(((DSLQuerySimpleResponse)aaiResponse.getT()).getResults().get(0).getCustomer().subscriberName); + } else { + LOGGER.info(EELFLoggerDelegate.errorLogger, "<== " + ".aai_get_service_instance_by_id_and_type. No result for DSL query :"+serviceInstanceIdentifier); + errorMessage = aaiResponse.getErrorMessage(); + } + statusCode = aaiResponse.getHttpCode(); + } + String httpMessage = viewEditSIResult != null ? objectMapper.writeValueAsString(viewEditSIResult) : errorMessage; + return new ResponseEntity<>(httpMessage,HttpStatus.valueOf(statusCode)); + } + + @RequestMapping(value = "/aai_sub_viewedit/{namedQueryId}/{globalCustomerId}/{serviceType}/{serviceInstance}", method = RequestMethod.GET) public ResponseEntity<String> viewEditGetComponentList( @PathVariable("namedQueryId") String namedQueryId, @@ -577,4 +680,9 @@ public class AaiController extends RestrictedBaseController { return null; } } + private boolean isValidInstanceIdentifierType(String instanceIdentifierType) { + return instanceIdentifierType != null + && ( instanceIdentifierType.equalsIgnoreCase("Service Instance Id") || + instanceIdentifierType.equalsIgnoreCase("Service Instance Name")); + } } diff --git a/vid-app-common/src/main/java/org/onap/vid/services/AaiService.java b/vid-app-common/src/main/java/org/onap/vid/services/AaiService.java index bc26b5eb0..7be2dd2ee 100644 --- a/vid-app-common/src/main/java/org/onap/vid/services/AaiService.java +++ b/vid-app-common/src/main/java/org/onap/vid/services/AaiService.java @@ -102,4 +102,8 @@ public interface AaiService { List<Network> getL3NetworksByCloudRegion(String cloudRegionId, String tenantId, String networkRole); ModelVer getNewestModelVersionByInvariantId(String modelInvariantId); + + AaiResponse getServiceInstanceBySubscriberIdAndInstanceIdentifier(String globalCustomerId, String identifierType, String serviceIdentifier); + AaiResponse getServiceInstanceSearchResultsByIdentifierType(String subscriberId, String instanceIdentifier, String instanceIdentifierType, RoleValidator roleValidator, List<String> owningEntities, List<String> projects); + AaiResponse getServiceInstanceBySubscriberIdAndSIID(String globalCustomerId, String serviceType, String serviceId); } diff --git a/vid-app-common/src/main/java/org/onap/vid/services/AaiServiceImpl.java b/vid-app-common/src/main/java/org/onap/vid/services/AaiServiceImpl.java index 1e79ab4c8..21e5409c3 100644 --- a/vid-app-common/src/main/java/org/onap/vid/services/AaiServiceImpl.java +++ b/vid-app-common/src/main/java/org/onap/vid/services/AaiServiceImpl.java @@ -48,8 +48,12 @@ import org.onap.vid.aai.AaiClientInterface; import org.onap.vid.aai.AaiGetVnfResponse; import org.onap.vid.aai.AaiResponse; import org.onap.vid.aai.AaiResponseTranslator; +import org.onap.vid.aai.Customer; +import org.onap.vid.aai.CustomerSpecificServiceInstance; +import org.onap.vid.aai.DSLQuerySimpleResponse; import org.onap.vid.aai.ExceptionWithRequestInfo; import org.onap.vid.aai.ServiceInstance; +import org.onap.vid.aai.ServiceInstanceResponseBySubscriber; import org.onap.vid.aai.ServiceInstancesSearchResults; import org.onap.vid.aai.ServiceSubscription; import org.onap.vid.aai.ServiceSubscriptions; @@ -750,4 +754,94 @@ public class AaiServiceImpl implements AaiService { public ModelVer getNewestModelVersionByInvariantId(String modelInvariantId){ return aaiClient.getLatestVersionByInvariantId(modelInvariantId); } + + @Override + public AaiResponse getServiceInstanceBySubscriberIdAndInstanceIdentifier(String globalCustomerId, String identifierType, String serviceIdentifier) { + return aaiClient.getServiceInstanceBySubscriberIdAndInstanceIdentifier(globalCustomerId,identifierType,serviceIdentifier); + } + + @Override + public AaiResponse getServiceInstanceSearchResultsByIdentifierType(String subscriberId, String instanceIdentifier, + String instanceIdentifierType, + RoleValidator roleValidator, + List<String> owningEntities, List<String> projects) { + List<List<ServiceInstanceSearchResult>> resultList = new ArrayList<>(); + ServiceInstancesSearchResults serviceInstancesSearchResults = new ServiceInstancesSearchResults(); + + if (subscriberId != null && instanceIdentifier != null && isValidInstanceIdentifierType(instanceIdentifierType)) { + resultList.add(getServicesBySubscriberAndServiceInstance(subscriberId, instanceIdentifier, instanceIdentifierType, roleValidator)); + } + if (owningEntities != null) { + resultList.add(getServicesByOwningEntityId(owningEntities, roleValidator)); + } + if (projects != null) { + resultList.add(getServicesByProjectNames(projects, roleValidator)); + } + if (!resultList.isEmpty()) { + serviceInstancesSearchResults.serviceInstances = Intersection.of(resultList); + } + + return new AaiResponse<>(serviceInstancesSearchResults, null, HttpStatus.SC_OK); + } + + private boolean isValidInstanceIdentifierType(String instanceIdentifierType) { + return instanceIdentifierType != null + && ( instanceIdentifierType.equalsIgnoreCase("Service Instance Id") || + instanceIdentifierType.equalsIgnoreCase("Service Instance Name")); + } + private List<ServiceInstanceSearchResult> getServicesBySubscriberAndServiceInstance(String subscriberId, + String instanceIdentifier, + String instanceIdentifierType, + RoleValidator roleValidator) { + LOGGER.info("Starting getServicesBySubscriberAndServiceInstance subscriberId : {}, " + + "instanceIdentifier : {}, instanceIdentifierType: {} ", + subscriberId,instanceIdentifier, instanceIdentifierType); + ArrayList<ServiceInstanceSearchResult> results = new ArrayList<>(); + if( instanceIdentifier == null || instanceIdentifierType == null) { + return results; + } + ServiceInstanceResponseBySubscriber serviceInstanceResponseBySubscriber = null; + Customer customer = null; + CustomerSpecificServiceInstance serviceInstance = null; + String subscriberName,serviceType,serviceInstanceId, serviceInstanceName,modelInvariantId,modelVersionId= null; + ServiceInstanceSearchResult serviceInstanceSearchResult = null; + + AaiResponse<DSLQuerySimpleResponse> aaiResponse = + aaiClient.getServiceInstanceBySubscriberIdAndInstanceIdentifier(subscriberId,instanceIdentifierType, + instanceIdentifier); + if( aaiResponse != null && aaiResponse.getT() !=null && aaiResponse.getT().getResults() != null){ + serviceInstanceResponseBySubscriber = aaiResponse.getT().getResults().get(0); + customer = serviceInstanceResponseBySubscriber.getCustomer(); + serviceInstance = customer.getCustomerRelatedNodes().get(0).getCustomerServiceSubscription(). + getServiceSubscriptionRelatedNodes().get(0).getServiceInstance(); + subscriberName = customer.getSubscriberName(); + serviceType = customer.getCustomerRelatedNodes().get(0).getCustomerServiceSubscription().getServiceType(); + serviceInstanceId = serviceInstance.getServiceInstanceId(); + serviceInstanceName = serviceInstance.getServiceInstanceName(); + modelInvariantId = serviceInstance.getModelInvariantId(); + modelVersionId = serviceInstance.getModelVersionId(); + + serviceInstanceSearchResult = + new ServiceInstanceSearchResult(serviceInstanceId, subscriberId, serviceType, + serviceInstanceName, subscriberName, modelInvariantId, + modelVersionId, null, false); + serviceInstanceSearchResult.setIsPermitted(roleValidator.isServicePermitted(serviceInstanceSearchResult)); + + LOGGER.info("Result from AAI, getServicesBySubscriberAndServiceInstance serviceType : {}, " + + "serviceInstanceId : {}, serviceInstanceName: {} , modelInvariantId : {}, " + + "modelVersionId :{}, permission :{}", + serviceType, serviceInstanceId, serviceInstanceName, modelInvariantId, + modelVersionId, serviceInstanceSearchResult.getIsPermitted()); + results.add(serviceInstanceSearchResult); + } else { + LOGGER.error("Inside getServicesBySubscriberAndServiceInstance response NULL"); + } + + return results; + } + + @Override + public AaiResponse getServiceInstanceBySubscriberIdAndSIID(String globalCustomerId, String serviceType, String serviceId) { + return aaiClient.getServiceInstance(globalCustomerId, serviceType, serviceId); + } } diff --git a/vid-app-common/src/main/webapp/app/vid/scripts/constants/componentConstants.js b/vid-app-common/src/main/webapp/app/vid/scripts/constants/componentConstants.js index 337ad4686..366f05782 100755 --- a/vid-app-common/src/main/webapp/app/vid/scripts/constants/componentConstants.js +++ b/vid-app-common/src/main/webapp/app/vid/scripts/constants/componentConstants.js @@ -113,6 +113,9 @@ appDS2 VPN_ID_1: "1a2b3c4d5e6f", // PATHS + //2011 AAI query optimization work + AAI_SUB_DETAILS_SERVICE_INSTANCE_PATH: "aai_get_service_instance_by_id_and_type/", + SELECTED_SERVICE_INSTANCE_TYPE_SUB_PATH: "serviceInstanceIdentifierType=", CHANGE_MANAGEMENT_OPERATION_NO_SCHEDULER: "change-management/workflow/@vnfName", GET_WORKFLOW: "change-management/get_vnf_workflow_relation", GET_SO_WORKFLOWS: "workflows-management/workflows", diff --git a/vid-app-common/src/main/webapp/app/vid/scripts/controller/aaiSubscriberController.js b/vid-app-common/src/main/webapp/app/vid/scripts/controller/aaiSubscriberController.js index 2701e3e9e..2f0765276 100755 --- a/vid-app-common/src/main/webapp/app/vid/scripts/controller/aaiSubscriberController.js +++ b/vid-app-common/src/main/webapp/app/vid/scripts/controller/aaiSubscriberController.js @@ -522,7 +522,7 @@ appDS2.controller("aaiSubscriberController", ["COMPONENT", "FIELD", "PARAMETER", var deferred = $q.defer();
AaiService.searchServiceInstances(
'?subscriberId=' + $location.search().subscriberId +
- '&serviceInstanceIdentifier=' + $location.search().serviceInstanceId)
+ '&serviceInstanceIdentifier=' + $location.search().serviceInstanceId + '&serviceInstanceIdentifierType=Service Instance Id')
.then(function (response) {
if (response.displayData && response.displayData.length) {
var first = response.displayData[0];
@@ -589,7 +589,14 @@ appDS2.controller("aaiSubscriberController", ["COMPONENT", "FIELD", "PARAMETER", $scope.hasFabricConfigurations = !UtilityService.isObjectEmpty($scope.service.model.fabricConfigurations);
return AaiService.runNamedQuery($scope.namedQueryId, $scope.globalCustomerId, $scope.serviceType, $scope.serviceInstanceId,
function (response) { //success
- $scope.handleInitialResponseInventoryItems(response);
+ try {
+ $log.debug("Getting inventory reponse items from Named Query with AAI query optimization - Before ");
+ $scope.handleInitialResponseInventoryItemsOptimized(response);
+ $log.debug("Getting inventory reponse items from Named Query with AAI query optimization - After ");
+ }catch (error) {
+ $log.error("Exception: Fallback to original method of getting subscriber name and SI orch status.");
+ $scope.handleInitialResponseInventoryItems(response);
+ }
$scope.setProgress(100); // done
$scope.status = FIELD.STATUS.DONE;
$scope.isSpinnerVisible = false;
@@ -630,7 +637,7 @@ appDS2.controller("aaiSubscriberController", ["COMPONENT", "FIELD", "PARAMETER", return $q.resolve($scope.modelVersionIdForServiceInstance.aaiModelVersionId);
} else {
$scope.status = FIELD.STATUS.FETCHING_SERVICE_INST_DATA + $scope.serviceInstanceId;
- return AaiService.getModelVersionId(instance.globalCustomerId, instance.serviceInstanceId)
+ return AaiService.getModelVersionId(instance.globalCustomerId, instance.serviceInstanceId, 'Service Instance Id')
.then(function (aaiModelVersionId) {
$scope.modelVersionIdForServiceInstance = {
globalCustomerId: instance.globalCustomerId,
@@ -827,6 +834,298 @@ appDS2.controller("aaiSubscriberController", ["COMPONENT", "FIELD", "PARAMETER", return _.includes(vfModuleStatusHasAllowedResume, vfModuleStatus) && !$scope.isActivateDeactivateEnabled("activate");
};
+ $scope.handleInitialResponseInventoryItemsOptimized = function (response) {
+
+ $scope.inventoryResponseItemList = response.data[FIELD.ID.INVENTORY_RESPONSE_ITEM]; // get data from json
+ $log.debug($scope.inventoryResponseItemList);
+
+ $scope.displayData = [];
+ $scope.vnfs = [];
+
+ $scope.counter = 100;
+
+ $scope.subscriberName = $location.search().subscriberName;
+
+ $scope.allConfigurationsAssigned = true;
+ // look up the subscriber name and service orchestration status from A&AI here...
+ AaiService.getSubscriberNameAndServiceInstanceInfo( $scope.globalCustomerId,
+ $scope.serviceInstanceId,
+ 'Service Instance Id',$scope.subscriberName, function (response) {
+ $scope.subscriberName = response['subscriberName'];
+ DataService.setSubscriberName($scope.subscriberName);
+ $scope.serviceOrchestrationStatus = response['orchestrationStatus'];
+ if ($scope.serviceOrchestrationStatus.toLowerCase() !== FIELD.STATUS.ASSIGNED.toLowerCase()) {
+ $scope.allConfigurationsAssigned = false;
+ }
+ angular.forEach($scope.inventoryResponseItemList, function (inventoryResponseItem, key) {
+
+ $scope.inventoryResponseItem = inventoryResponseItem;
+
+ $scope.service.instance = {
+ "name": $scope.inventoryResponseItem[FIELD.ID.SERVICE_INSTANCE][FIELD.ID.SERVICE_INSTANCE_NAME],
+ "serviceInstanceId": $scope.serviceInstanceId,
+ "serviceType": $scope.serviceType,
+ "globalCustomerId": $scope.globalCustomerId,
+ "subscriberName": $scope.subscriberName,
+ "id": $scope.serviceInstanceId,
+ "inputs": {
+ "a": {
+ "type": PARAMETER.STRING,
+ "description": FIELD.PROMPT.VAR_DESCRIPTION_A,
+ "default": FIELD.PROMPT.DEFAULT_A
+ },
+ "b": {
+ "type": PARAMETER.STRING,
+ "description": FIELD.PROMPT.VAR_DESCRIPTION_B,
+ "default": FIELD.PROMPT.DEFAULT_B
+ }
+ },
+ "object": $scope.inventoryResponseItem[FIELD.ID.SERVICE_INSTANCE],
+ "vnfs": [],
+ "networks": [],
+ "configurations": []
+ };
+
+ var portMirroringConfigurationIds = [];
+ if (inventoryResponseItem[FIELD.ID.INVENTORY_RESPONSE_ITEMS] != null) {
+
+ angular.forEach(inventoryResponseItem[FIELD.ID.INVENTORY_RESPONSE_ITEMS][FIELD.ID.INVENTORY_RESPONSE_ITEM], function (subInventoryResponseItem, key) {
+ // i expect to find vnfs now
+
+ if (subInventoryResponseItem[FIELD.ID.L3_NETWORK] != null) {
+ var l3NetworkObject = subInventoryResponseItem[FIELD.ID.L3_NETWORK];
+ var l3Network = {
+ "id": $scope.counter++,
+ "name": l3NetworkObject[FIELD.ID.NETWORK_NAME],
+ "itemType": FIELD.ID.L3_NETWORK,
+ "nodeId": l3NetworkObject[FIELD.ID.NETWORK_ID],
+ "nodeType": l3NetworkObject[FIELD.ID.NETWORK_TYPE],
+ "nodeStatus": l3NetworkObject[FIELD.ID.ORCHESTRATION_STATUS],
+ "object": l3NetworkObject,
+ "nodes": [],
+ "subnets": [],
+ "vlans": []
+ };
+ if (subInventoryResponseItem[FIELD.ID.INVENTORY_RESPONSE_ITEMS] != null) {
+ //console.log ("subInventoryResponseItem[FIELD.ID.INVENTORY_RESPONSE_ITEMS]=");
+ //console.log (JSON.stringify (subInventoryResponseItem[FIELD.ID.INVENTORY_RESPONSE_ITEMS], null, 4 ));
+ angular.forEach(subInventoryResponseItem[FIELD.ID.INVENTORY_RESPONSE_ITEMS][FIELD.ID.INVENTORY_RESPONSE_ITEM], function (subSubInventoryResponseItem, key) {
+ //console.log (JSON.stringify (subSubInventoryResponseItem, null, 4 ));
+ var subnet = {};
+ var subnetObject;
+ if (subSubInventoryResponseItem[FIELD.ID.SUB_NET] != null) {
+ subnetObject = subSubInventoryResponseItem[FIELD.ID.SUB_NET];
+ subnet = {
+ "subnet-id": subnetObject[FIELD.ID.SUBNET_ID],
+ "subnet-name": subnetObject[FIELD.ID.SUBNET_NAME],
+ "gateway-address": subnetObject[FIELD.ID.GATEWAY_ADDRESS],
+ "network-start-address": subnetObject[FIELD.ID.NETWORK_START_ADDRESS],
+ "cidr-mask": subnetObject[FIELD.ID.CIDR_MASK]
+ };
+ l3Network.subnets.push(subnet);
+ }
+ });
+ }
+
+
+ var networkObj = _.find(serviceNetworkVlans, { 'networkId': l3Network.nodeId});
+ if (networkObj !== undefined && networkObj.vlans !== undefined) {
+ l3Network["vlans"] = networkObj.vlans;
+ }
+ $scope.service.instance[FIELD.ID.NETWORKS].push(l3Network);
+ }
+
+ if (subInventoryResponseItem[FIELD.ID.GENERIC_VNF] != null) {
+ var genericVnfObject = subInventoryResponseItem[FIELD.ID.GENERIC_VNF];
+
+ var genericVnf = {
+ "name": genericVnfObject[FIELD.ID.VNF_NAME],
+ "id": $scope.counter++,
+ "itemType": COMPONENT.VNF,
+ "nodeType": genericVnfObject[FIELD.ID.VNF_TYPE],
+ "nodeId": genericVnfObject[FIELD.ID.VNF_ID],
+ "nodeStatus": genericVnfObject[FIELD.ID.ORCHESTRATION_STATUS],
+ "modelVersionId" : genericVnfObject[FIELD.ID.MODEL_VERSION_ID],
+ "object": genericVnfObject,
+ "vfModules": [],
+ "volumeGroups": [],
+ "instanceGroups": [],
+ "availableVolumeGroups": [],
+ "networks": []
+ };
+
+ var vnfNetworkObj = _.find(vnfNetworksAndVlans, { 'vnfId': genericVnf.nodeId});
+ if (vnfNetworkObj !== undefined && vnfNetworkObj.networks !== undefined) {
+ genericVnf["networks"] = vnfNetworkObj.networks;
+ }
+
+ $scope.service.instance[FIELD.ID.VNFS].push(genericVnf);
+ getRelatedInstanceGroupsByVnfId(genericVnf);
+
+
+
+ // look for volume-groups
+ if (subInventoryResponseItem[FIELD.ID.INVENTORY_RESPONSE_ITEMS] != null) {
+ angular.forEach(subInventoryResponseItem[FIELD.ID.INVENTORY_RESPONSE_ITEMS][FIELD.ID.INVENTORY_RESPONSE_ITEM], function (vfmodules, key) {
+
+ if (vfmodules[FIELD.ID.VOLUME_GROUP] != null) {
+ var volumeGroupObject = vfmodules[FIELD.ID.VOLUME_GROUP];
+ var volumeGroup = {
+ "id": $scope.counter++,
+ "name": volumeGroupObject[FIELD.ID.VOLUME_GROUP_NAME],
+ "itemType": FIELD.ID.VOLUME_GROUP,
+ "nodeId": volumeGroupObject[FIELD.ID.VOLUME_GROUP_ID],
+ "nodeType": volumeGroupObject[FIELD.ID.VNF_TYPE],
+ "nodeStatus": volumeGroupObject[FIELD.ID.ORCHESTRATION_STATUS],
+ "object": volumeGroupObject,
+ "nodes": []
+ };
+ genericVnf[FIELD.ID.VOLUMEGROUPS].push(volumeGroup);
+ genericVnf[FIELD.ID.AVAILABLEVOLUMEGROUPS].push(volumeGroup);
+ }
+ });
+ }
+ // now we've loaded up the availableVolumeGroups, we can use it
+ if (subInventoryResponseItem[FIELD.ID.INVENTORY_RESPONSE_ITEMS] != null) {
+ angular.forEach(subInventoryResponseItem[FIELD.ID.INVENTORY_RESPONSE_ITEMS][FIELD.ID.INVENTORY_RESPONSE_ITEM], function (vfmodules, key) {
+
+ if (vfmodules[FIELD.ID.VF_MODULE] != null) {
+ var vfModuleObject = vfmodules[FIELD.ID.VF_MODULE];
+ var vfModule = {
+ "id": $scope.counter++,
+ "name": vfModuleObject[FIELD.ID.VF_MODULE_NAME],
+ "itemType": FIELD.ID.VF_MODULE,
+ "nodeType": FIELD.ID.VF_MODULE,
+ "nodeStatus": vfModuleObject[FIELD.ID.ORCHESTRATION_STATUS],
+ "volumeGroups": [],
+ "object": vfModuleObject,
+ "networks": []
+ };
+ genericVnf[FIELD.ID.VF_MODULES].push(vfModule);
+ if (vfmodules[FIELD.ID.INVENTORY_RESPONSE_ITEMS] != null) {
+ angular.forEach(vfmodules[FIELD.ID.INVENTORY_RESPONSE_ITEMS][FIELD.ID.INVENTORY_RESPONSE_ITEM], function (networks, key) {
+ if (networks[FIELD.ID.L3_NETWORK] != null) {
+ var l3NetworkObject = networks[FIELD.ID.L3_NETWORK];
+ var l3Network = {
+ "id": $scope.counter++,
+ "name": l3NetworkObject[FIELD.ID.NETWORK_NAME],
+ "itemType": FIELD.ID.L3_NETWORK,
+ "nodeId": l3NetworkObject[FIELD.ID.NETWORK_ID],
+ "nodeType": l3NetworkObject[FIELD.ID.NETWORK_TYPE],
+ "nodeStatus": l3NetworkObject[FIELD.ID.ORCHESTRATION_STATUS],
+ "object": l3NetworkObject,
+ "nodes": []
+ };
+ vfModule[FIELD.ID.NETWORKS].push(l3Network);
+ }
+ if (networks[FIELD.ID.VOLUME_GROUP] != null) {
+ var volumeGroupObject = networks[FIELD.ID.VOLUME_GROUP];
+
+ var volumeGroup = {
+ "id": $scope.counter++,
+ "name": volumeGroupObject[FIELD.ID.VOLUME_GROUP_NAME],
+ "itemType": FIELD.ID.VOLUME_GROUP,
+ "nodeId": volumeGroupObject[FIELD.ID.VOLUME_GROUP_ID],
+ "nodeType": volumeGroupObject[FIELD.ID.VNF_TYPE],
+ "nodeStatus": volumeGroupObject[FIELD.ID.ORCHESTRATION_STATUS],
+ "object": volumeGroupObject,
+ "nodes": []
+ };
+ var tmpVolGroup = [];
+
+ angular.forEach(genericVnf[FIELD.ID.AVAILABLEVOLUMEGROUPS], function (avgroup, key) {
+ if (avgroup.name != volumeGroup.name) {
+ tmpVolGroup.push(avgroup);
+ }
+ });
+
+ genericVnf[FIELD.ID.AVAILABLEVOLUMEGROUPS] = tmpVolGroup;
+
+ vfModule[FIELD.ID.VOLUMEGROUPS].push(volumeGroup);
+ }
+
+ });
+ }
+ }
+ });
+ }
+ }
+
+
+ if (subInventoryResponseItem[FIELD.ID.GENERIC_CONFIGURATION] != null) {
+ var configObject = subInventoryResponseItem[FIELD.ID.GENERIC_CONFIGURATION];
+ var config = {
+ "id": $scope.counter++,
+ "name": configObject[FIELD.ID.CONFIGURATION_NAME],
+ "itemType": FIELD.ID.CONFIGURATION,
+ "nodeId": configObject[FIELD.ID.CONFIGURATION_ID],
+ "nodeType": configObject[FIELD.ID.CONFIGURATION_TYPE],
+ "nodeStatus": configObject[FIELD.ID.ORCHESTRATION_STATUS],
+ "modelInvariantId": configObject[FIELD.ID.MODEL_INVAR_ID],
+ "modelVersionId": configObject[FIELD.ID.MODEL_VERSION_ID],
+ "modelCustomizationId": configObject[FIELD.ID.MODEL_CUSTOMIZATION_ID],
+ "object": configObject,
+ "ports": [],
+ "configData" : null
+ };
+ if( !$scope.hasFabricConfigurations ) {
+ portMirroringConfigurationIds.push(configObject[FIELD.ID.CONFIGURATION_ID]);
+ $scope.service.instance[FIELD.ID.CONFIGURATIONS].push(config);
+ } else {
+ if (config.nodeStatus.toLowerCase() !== FIELD.STATUS.ASSIGNED.toLowerCase()) {
+ $scope.allConfigurationsAssigned = false;
+ if ($scope.isActivateFabricConfiguration()) {
+ $scope.errorMsg = "Activate fabric configuration button is not available as some of the configuration objects are not in Assigned status. Check MSO logs for the reasons for this abnormal case.";
+ }
+ }
+ }
+ }
+
+ });
+
+ AaiService.getPortMirroringData(portMirroringConfigurationIds).then(function(result){
+ angular.forEach($scope.service.instance[FIELD.ID.CONFIGURATIONS], function(config){
+ config['configData'] = result.data[config['nodeId']];
+
+ if (config.configData && config.configData.errorDescription) {
+ $scope.errorMsg = ($scope.errorMsg ? $scope.errorMsg + "\n" : "") +
+ "Cannot read cloud-region for configuration \"" + config.name + "\": " +
+ config.configData.errorDescription;
+ }
+ });
+ });
+
+ AaiService.getPortMirroringSourcePorts(portMirroringConfigurationIds).then(function(result){
+ angular.forEach($scope.service.instance[FIELD.ID.CONFIGURATIONS], function(config){
+ angular.forEach(result.data[config['nodeId']], function(port){
+ if (port.errorDescription) {
+ $scope.errorMsg = ($scope.errorMsg ? $scope.errorMsg + "\n" : "") +
+ "Cannot read a source port for configuration \"" + config.name + "\": " +
+ port.errorDescription;
+ } else {
+ config.ports.push({
+ "portId": port[FIELD.ID.PORT_ID],
+ "portName": port[FIELD.ID.PORT_NAME],
+ "portStatus": port[FIELD.ID.PORT_MIRRORED] === true ? FIELD.STATUS.AAI_ENABLED : FIELD.STATUS.AAI_DISABLED
+ });
+ }
+ });
+ });
+ });
+
+ }
+ });
+
+ var aaiNetworkIds = _.map(serviceNetworkVlans, 'networkId');
+ var serviceInstanceNetworkIds = _.map($scope.service.instance[FIELD.ID.NETWORKS], 'nodeId');
+ var isContains = aaiNetworkIds.every(function(val) { return serviceInstanceNetworkIds.indexOf(val) >= 0; });
+ if (aaiNetworkIds.length && !isContains) {
+ $log.error("vlansByNetworks contain network that not found in service instance", aaiNetworkIds, serviceInstanceNetworkIds);
+ }
+
+ });
+ };
+
$scope.handleInitialResponseInventoryItems = function (response) {
$scope.inventoryResponseItemList = response.data[FIELD.ID.INVENTORY_RESPONSE_ITEM]; // get data from json
@@ -1521,12 +1820,13 @@ appDS2.controller("aaiSubscriberController", ["COMPONENT", "FIELD", "PARAMETER", $scope.serviceInstanceses = [{"sinstance": FIELD.NAME.SERVICE_INSTANCE_Id}, {"sinstance": FIELD.NAME.SERVICE_INSTANCE_NAME}];
- function navigateToSearchResultsPage(globalCustomerId, selectedServiceInstance, selectedProjects, selectedOwningEntities) {
+ function navigateToSearchResultsPage(globalCustomerId, selectedServiceInstance, selectedProjects, selectedOwningEntities, selectedInstanceIdentifierType) {
var projectQuery = AaiService.getMultipleValueParamQueryString(_.map(selectedProjects, 'id'), COMPONENT.PROJECT_SUB_PATH);
var owningEntityQuery = AaiService.getMultipleValueParamQueryString(_.map(selectedOwningEntities, 'id'), COMPONENT.OWNING_ENTITY_SUB_PATH);
var globalCustomerIdQuery = globalCustomerId ? COMPONENT.SELECTED_SUBSCRIBER_SUB_PATH + globalCustomerId : null;
var serviceInstanceQuery = selectedServiceInstance ? COMPONENT.SELECTED_SERVICE_INSTANCE_SUB_PATH + selectedServiceInstance : null;
- var query = AaiService.getJoinedQueryString([projectQuery, owningEntityQuery, globalCustomerIdQuery, serviceInstanceQuery]);
+ var serviceInstanceTypeQuery = selectedInstanceIdentifierType ? COMPONENT.SELECTED_SERVICE_INSTANCE_TYPE_SUB_PATH + selectedInstanceIdentifierType : null;
+ var query = AaiService.getJoinedQueryString([projectQuery, owningEntityQuery, globalCustomerIdQuery, serviceInstanceQuery, serviceInstanceTypeQuery]);
window.location.href = COMPONENT.SELECTED_SERVICE_SUB_PATH + query;
}
@@ -1542,7 +1842,7 @@ appDS2.controller("aaiSubscriberController", ["COMPONENT", "FIELD", "PARAMETER", .getGlobalCustomerIdByInstanceIdentifier(selectedServiceInstance, selectedInstanceIdentifierType)
.then(handleCustomerIdResponse);
} else {
- navigateToSearchResultsPage(selectedCustomer, null, selectedProject, selectedOwningEntity);
+ navigateToSearchResultsPage(selectedCustomer, null, selectedProject, selectedOwningEntity, selectedInstanceIdentifierType);
}
} else {
alert(FIELD.ERROR.SELECT);
@@ -1550,7 +1850,7 @@ appDS2.controller("aaiSubscriberController", ["COMPONENT", "FIELD", "PARAMETER", function handleCustomerIdResponse(globalCustomerId) {
if (UtilityService.hasContents(globalCustomerId)) {
- navigateToSearchResultsPage(globalCustomerId, selectedServiceInstance, selectedProject, selectedOwningEntity);
+ navigateToSearchResultsPage(globalCustomerId, selectedServiceInstance, selectedProject, selectedOwningEntity, selectedInstanceIdentifierType);
} else {
alert(FIELD.ERROR.SERVICE_INST_DNE);
}
diff --git a/vid-app-common/src/main/webapp/app/vid/scripts/controller/aaiSubscriberController.test.js b/vid-app-common/src/main/webapp/app/vid/scripts/controller/aaiSubscriberController.test.js index 03a299877..2478797fb 100644 --- a/vid-app-common/src/main/webapp/app/vid/scripts/controller/aaiSubscriberController.test.js +++ b/vid-app-common/src/main/webapp/app/vid/scripts/controller/aaiSubscriberController.test.js @@ -691,6 +691,14 @@ describe('aaiSubscriberController testing', () => { }); }; + mockAaiService.getSubscriberNameAndServiceInstanceInfo = (customerId, serviceInstanceId, serviceIdentifierType, subscriberName, successFunction) => { + successFunction({"serviceInstanceId":"5d942bc7-3acf-4e35-836a-393619ebde66", + "serviceInstanceName":"dpa2actsf5001v_Port_Mirroring_dpa2a_SVC", + "modelVersionId":"a9088517-efe8-4bed-9c54-534462cb08c2", + "modelInvariantId":"0757d856-a9c6-450d-b494-e1c0a4aab76f", + "orchestrationStatus":"Active","subscriberName":"Mobility"}); + }; + mock_.map = (serviceNetworkVlans, networkId) => { return ["aaiNetworkId1","aaiNetworkId2"]; }; diff --git a/vid-app-common/src/main/webapp/app/vid/scripts/services/aaiService.js b/vid-app-common/src/main/webapp/app/vid/scripts/services/aaiService.js index cfab522c7..49245c570 100755 --- a/vid-app-common/src/main/webapp/app/vid/scripts/services/aaiService.js +++ b/vid-app-common/src/main/webapp/app/vid/scripts/services/aaiService.js @@ -125,7 +125,28 @@ var AaiService = function ($http, $log, PropertyService, UtilityService, COMPONE })["catch"] (UtilityService.runHttpErrorHandler); }, - + getSubscriberNameAndServiceInstanceInfo: function (subscriberUuid, serviceInstanceIdentifier, + serviceInstanceIdentifierType, subscriberName, successCallbackFunction ) { + $log.debug("AaiService:getSubscriberNameAndServiceInstanceInfo: subscriberUuid: " + subscriberUuid + + ",serviceInstanceIdentifier :"+serviceInstanceIdentifier + + " , serviceInstanceIdentifierType="+serviceInstanceIdentifierType +",subscriberName="+subscriberName); + + if (UtilityService.hasContents(subscriberUuid) && UtilityService.hasContents(serviceInstanceIdentifier) && + UtilityService.hasContents(serviceInstanceIdentifierType) ) { + $http.get(COMPONENT.AAI_SUB_DETAILS_SERVICE_INSTANCE_PATH + + subscriberUuid + COMPONENT.FORWARD_SLASH + serviceInstanceIdentifier + COMPONENT.FORWARD_SLASH + + serviceInstanceIdentifierType + COMPONENT.FORWARD_SLASH + subscriberName + COMPONENT.ASSIGN + Math.random(), + { + timeout: PropertyService.getServerResponseTimeoutMsec() + }).then(function (response) { + var result = {}; + if (response.data) { + result = response.data; + } + successCallbackFunction(result); + })["catch"] + (UtilityService.runHttpErrorHandler); + }}, runNamedQuery: function (namedQueryId, globalCustomerId, serviceType, serviceInstanceId, successCallback, errorCallback) { var url = COMPONENT.AAI_SUB_VIEWEDIT_PATH + @@ -209,11 +230,11 @@ var AaiService = function ($http, $log, PropertyService, UtilityService, COMPONE searchServiceInstances: searchServiceInstances, - getModelVersionId: function (subscriberId, instanceId) { + getModelVersionId: function (subscriberId, instanceId, identifierType) { var globalCustomerIdQuery = COMPONENT.SELECTED_SUBSCRIBER_SUB_PATH + subscriberId; var serviceInstanceQuery = COMPONENT.SELECTED_SERVICE_INSTANCE_SUB_PATH + instanceId; - - var query = "?" + getJoinedQueryString([globalCustomerIdQuery, serviceInstanceQuery]); + var serviceIdentifierType = COMPONENT.SELECTED_SERVICE_INSTANCE_TYPE_SUB_PATH + identifierType; + var query = "?" + getJoinedQueryString([globalCustomerIdQuery, serviceInstanceQuery, serviceIdentifierType]); var deferred = $q.defer(); @@ -695,7 +716,7 @@ var AaiService = function ($http, $log, PropertyService, UtilityService, COMPONE $log.debug("AaiService:getSubscriberServiceTypes: subscriberUuid: " + subscriberUuid); if (UtilityService.hasContents(subscriberUuid)) { - $http.get(COMPONENT.AAI_SUB_DETAILS_PATH + subscriberUuid + COMPONENT.ASSIGN + Math.random()) + $http.get(COMPONENT.AAI_SUB_DETAILS_PATH + subscriberUuid + COMPONENT.ASSIGN + Math.random()+ COMPONENT.AAI_OMIT_SERVICE_INSTANCES + true) .success(function (response) { if (response && [FIELD.ID.SERVICE_SUBSCRIPTIONS]) { deferred.resolve({data: response[FIELD.ID.SERVICE_SUBSCRIPTIONS][FIELD.ID.SERVICE_SUBSCRIPTION]}); diff --git a/vid-app-common/src/test/java/org/onap/vid/aai/AaiClientTest.java b/vid-app-common/src/test/java/org/onap/vid/aai/AaiClientTest.java index 1a75c555c..ecfe5a005 100644 --- a/vid-app-common/src/test/java/org/onap/vid/aai/AaiClientTest.java +++ b/vid-app-common/src/test/java/org/onap/vid/aai/AaiClientTest.java @@ -148,6 +148,9 @@ public class AaiClientTest { private static String responseJsonNfRole = "/payload_jsons/changeManagement/vnfs-fromServiceInstance-filterNfRole.json"; private static String responseJsonCloudRegion ="/payload_jsons/changeManagement/vnfs-fromServiceInstance-filterByCloudRegion.json"; + private static String responseJsonDSLServiceInstance ="/payload_jsons/service-instance-by-subscriberid.json"; + private static String dslQueryPayloadByServiceInstanceId = "{\"dsl\":\"customer*('global-customer-id','SOME_GLOBAL_CUST_ID')>service-subscription>service-instance*('service-instance-id','SOME_SERVICE_INSTANCE_ID')\"}"; + private static String dslQueryPayloadByServiceInstanceName = "{\"dsl\":\"customer*('global-customer-id','SOME_GLOBAL_CUST_ID')>service-subscription>service-instance*('service-instance-name','SOME_SERVICE_INSTANCE_NAME')\"}"; @DataProvider public static Object[][] aaiPutCustomQueryData() { @@ -952,6 +955,54 @@ public class AaiClientTest { Mockito.verify(aaiClientMock).doAaiGet(argThat(s -> s.contains("customer/" + subscriberId + "?") && s.contains("depth=" + depth)),any(Boolean.class)); } + + @DataProvider + public static Object[][] aaiDSLPutServiceInstanceQueryData() { + return new Object[][] { + {"SOME_GLOBAL_CUST_ID", "Service Instance Id", "SOME_SERVICE_INSTANCE_ID", + dslQueryPayloadByServiceInstanceId, responseJsonDSLServiceInstance, "SOME_SERVICE_INSTANCE_ID", 200}, + {"SOME_GLOBAL_CUST_ID", "Service Instance Name", "SOME_SERVICE_INSTANCE_NAME", + dslQueryPayloadByServiceInstanceName, responseJsonDSLServiceInstance, "SOME_SERVICE_INSTANCE_ID", 200}, + {"SOME_GLOBAL_CUST_ID", "Service Instance Name", "SOME_SERVICE_INSTANCE_NAME", + dslQueryPayloadByServiceInstanceName, responseJsonDSLServiceInstance, "SOME_SERVICE_INSTANCE_ID",200}, + + }; + } + + @Test(dataProvider = "aaiDSLPutServiceInstanceQueryData") + public void testAaiDSLPutServiceInstanceQueryByParams( String globalCustomerId, + String identifierType, + String identifier, + String expectedPayload, + String responseBody, + String expectedSiId, + int responseHttpCode) { + + String queryFormat = "dsl?format=resource&nodesOnly=true&depth=0&as-tree=true"; + + final ResponseWithRequestInfo mockedResponseWithRequestInfo = mockedResponseWithRequestInfo(Response.Status.OK, + TestUtils.readFileAsString(responseBody), + "dsl?format=resource&nodesOnly=true&depth=0&as-tree=true&Mock=True", + HttpMethod.PUT); + + when(aaiClientMock.doAaiPut(eq(queryFormat), anyString(), anyBoolean(), anyBoolean())).thenReturn(mockedResponseWithRequestInfo); + when(aaiClientMock.getServiceInstanceBySubscriberIdAndInstanceIdentifier(anyString(), anyString(), anyString())).thenCallRealMethod(); + + AaiResponse<DSLQuerySimpleResponse> response = aaiClientMock.getServiceInstanceBySubscriberIdAndInstanceIdentifier(globalCustomerId, identifierType, identifier); + + verify(aaiClientMock).doAaiPut(eq(queryFormat), eq(expectedPayload), eq(false), eq(false)); + + assertEquals(response.getHttpCode(), responseHttpCode); + assertEquals(response.getT().getResults().get(0).getCustomer().getCustomerRelatedNodes().get(0).getCustomerServiceSubscription(). + getServiceSubscriptionRelatedNodes().get(0).getServiceInstance().serviceInstanceId, expectedSiId); + + assertEquals(response.getT().getResults().get(0).getCustomer().getSubscriberName(), "Mobility"); + + assertEquals(response.getT().getResults().get(0).getCustomer().getCustomerRelatedNodes().get(0).getCustomerServiceSubscription(). + getServiceSubscriptionRelatedNodes().get(0).getServiceInstance().orchestrationStatus, "SOME_ORCH_STATUS"); + + } + @Test public void testToModelVerStream() throws IOException { diff --git a/vid-app-common/src/test/resources/payload_jsons/service-instance-by-subscriberid.json b/vid-app-common/src/test/resources/payload_jsons/service-instance-by-subscriberid.json new file mode 100644 index 000000000..fbf8cb162 --- /dev/null +++ b/vid-app-common/src/test/resources/payload_jsons/service-instance-by-subscriberid.json @@ -0,0 +1 @@ +{"results": [{"customer": {"global-customer-id": "SOME_GLOBAL_CUST_ID", "subscriber-name": "Mobility", "subscriber-type": "INFRA", "resource-version": "1602518417955", "related-nodes": [{"service-subscription": {"service-type": "VPMS", "resource-version": "1629183620246","related-nodes": [{"service-instance": {"service-instance-id": "SOME_SERVICE_INSTANCE_ID", "service-instance-name": "SOME_SERVICE_INSTANCE_NAME", "service-type": "PORT-MIRROR", "service-role": "VPROBE", "environment-context": "General_Revenue-Bearing", "workload-context": "Production", "model-invariant-id": "0757d856-a9c6-450d-b494-e1c0a4aab76f","model-version-id": "a9088517-efe8-4bed-9c54-534462cb08c2","resource-version": "1615330529236","selflink": "SOME_SELF_LINK","orchestration-status": "SOME_ORCH_STATUS" }}]}}]}} ]}
\ No newline at end of file |