2  * ============LICENSE_START=======================================================
 
   3  * SOActorServiceProvider
 
   4  * ================================================================================
 
   5  * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
 
   6  * ================================================================================
 
   7  * Licensed under the Apache License, Version 2.0 (the "License");
 
   8  * you may not use this file except in compliance with the License.
 
   9  * You may obtain a copy of the License at
 
  11  *      http://www.apache.org/licenses/LICENSE-2.0
 
  13  * Unless required by applicable law or agreed to in writing, software
 
  14  * distributed under the License is distributed on an "AS IS" BASIS,
 
  15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 
  16  * See the License for the specific language governing permissions and
 
  17  * limitations under the License.
 
  18  * ============LICENSE_END=========================================================
 
  21 package org.onap.policy.controlloop.actor.so;
 
  23 import java.util.Collections;
 
  24 import java.util.HashMap;
 
  25 import java.util.List;
 
  27 import java.util.UUID;
 
  29 import org.drools.core.WorkingMemory;
 
  30 import org.onap.policy.aai.AAIManager;
 
  31 import org.onap.policy.aai.AAINQInstanceFilters;
 
  32 import org.onap.policy.aai.AAINQInventoryResponseItem;
 
  33 import org.onap.policy.aai.AAINQNamedQuery;
 
  34 import org.onap.policy.aai.AAINQQueryParameters;
 
  35 import org.onap.policy.aai.AAINQRequest;
 
  36 import org.onap.policy.aai.AAINQResponse;
 
  37 import org.onap.policy.aai.AAINQResponseWrapper;
 
  38 import org.onap.policy.controlloop.ControlLoopOperation;
 
  39 import org.onap.policy.controlloop.VirtualControlLoopEvent;
 
  40 import org.onap.policy.controlloop.actorServiceProvider.spi.Actor;
 
  41 import org.onap.policy.controlloop.policy.Policy;
 
  42 import org.onap.policy.drools.system.PolicyEngine;
 
  43 import org.onap.policy.rest.RESTManager;
 
  44 import org.onap.policy.so.SOCloudConfiguration;
 
  45 import org.onap.policy.so.SOManager;
 
  46 import org.onap.policy.so.SOModelInfo;
 
  47 import org.onap.policy.so.SORelatedInstance;
 
  48 import org.onap.policy.so.SORelatedInstanceListElement;
 
  49 import org.onap.policy.so.SORequest;
 
  50 import org.onap.policy.so.SORequestDetails;
 
  51 import org.onap.policy.so.SORequestInfo;
 
  52 import org.onap.policy.so.SORequestParameters;
 
  53 import org.onap.policy.so.util.Serialization;
 
  54 import org.slf4j.Logger;
 
  55 import org.slf4j.LoggerFactory;
 
  57 import com.google.common.collect.ImmutableList;
 
  58 import com.google.common.collect.ImmutableMap;
 
  60 public class SOActorServiceProvider implements Actor {
 
  61         private static final Logger logger = LoggerFactory.getLogger(SOActorServiceProvider.class);
 
  63         // Strings for SO Actor
 
  64         private static final String SO_ACTOR  = "SO";
 
  66         // Strings for targets
 
  67         private static final String TARGET_VFC = "VFC";
 
  69         // Strings for recipes
 
  70         private static final String RECIPE_VF_MODULE_CREATE = "VF Module Create";
 
  72         private static final ImmutableList<String> recipes = ImmutableList.of(RECIPE_VF_MODULE_CREATE);
 
  73         private static final ImmutableMap<String, List<String>> targets = new ImmutableMap.Builder<String, List<String>>()
 
  74                         .put(RECIPE_VF_MODULE_CREATE, ImmutableList.of(TARGET_VFC))
 
  77         // Static variables required to hold the IDs of the last service item and VNF item. Note that in a multithreaded deployment this WILL break
 
  78         private static String lastVNFItemVnfId;
 
  79         private static String lastServiceItemServiceInstanceId;
 
  82         public String actor() {
 
  87         public List<String> recipes() {
 
  88                 return ImmutableList.copyOf(recipes);
 
  92         public List<String> recipeTargets(String recipe) {
 
  93                 return ImmutableList.copyOf(targets.getOrDefault(recipe, Collections.emptyList()));
 
  97         public List<String> recipePayloads(String recipe) {
 
  98                 return Collections.emptyList();
 
 102          * Constructs a SO request conforming to the lcm API.
 
 103          * The actual request is constructed and then placed in a 
 
 104          * wrapper object used to send through DMAAP.
 
 107          *            the event that is reporting the alert for policy
 
 108          *            to perform an action        
 
 110          *            the control loop operation specifying the actor,
 
 111          *            operation, target, etc.  
 
 113          *            the policy the was specified from the yaml generated
 
 114          *            by CLAMP or through the Policy GUI/API                        
 
 115          * @return a SO request conforming to the lcm API using the DMAAP wrapper
 
 117         public SORequest constructRequest(VirtualControlLoopEvent onset, ControlLoopOperation operation, Policy policy) {
 
 118                 if (!SO_ACTOR.equals(policy.getActor()) || !RECIPE_VF_MODULE_CREATE.equals(policy.getRecipe())) {
 
 119                         // for future extension
 
 123                 // Perform named query request and handle response
 
 124                 AAINQResponseWrapper aaiResponseWrapper = performAaiNamedQueryRequest(onset);
 
 125                 if (aaiResponseWrapper == null) {
 
 126                         // Tracing and error handling handied in the "performAaiNamedQueryRequest()" method
 
 130                 AAINQInventoryResponseItem vnfItem = null;
 
 131                 AAINQInventoryResponseItem vnfServiceItem = null;
 
 132                 AAINQInventoryResponseItem tenantItem = null;
 
 134                 // Extract the items we're interested in from the response
 
 136                         vnfItem = aaiResponseWrapper.getAainqresponse().getInventoryResponseItems().get(0).getItems().getInventoryResponseItems().get(0);
 
 138                 catch (Exception e) {
 
 139                         logger.error("VNF Item not found in AAI response {}", Serialization.gsonPretty.toJson(aaiResponseWrapper));
 
 144                         vnfServiceItem = vnfItem.getItems().getInventoryResponseItems().get(0);
 
 146                 catch (Exception e) {
 
 147                         logger.error("VNF Service Item not found in AAI response {}", Serialization.gsonPretty.toJson(aaiResponseWrapper));
 
 152                         tenantItem = aaiResponseWrapper.getAainqresponse().getInventoryResponseItems().get(0).getItems().getInventoryResponseItems().get(1);
 
 154                 catch (Exception e) {
 
 155                         logger.error("Tenant Item not found in AAI response {}", Serialization.gsonPretty.toJson(aaiResponseWrapper));
 
 159                 // Find the index for base vf module and non-base vf module
 
 160                 int baseIndex = findIndex(vnfItem.getItems().getInventoryResponseItems(), true);
 
 161                 int nonBaseIndex = findIndex(vnfItem.getItems().getInventoryResponseItems(), false);
 
 163                 // Report the error if either base vf module or non-base vf module is not found
 
 164                 if (baseIndex == -1 || nonBaseIndex == -1) {
 
 165                         logger.error("Either base or non-base vf module is not found from AAI response.");
 
 169                 // Construct SO Request
 
 170                 SORequest request = new SORequest();
 
 171                 request.setRequestId(onset.getRequestID());
 
 172                 request.setRequestDetails(new SORequestDetails());
 
 173                 request.getRequestDetails().setModelInfo(new SOModelInfo());
 
 174                 request.getRequestDetails().setCloudConfiguration(new SOCloudConfiguration());
 
 175                 request.getRequestDetails().setRequestInfo(new SORequestInfo());
 
 176                 request.getRequestDetails().setRequestParameters(new SORequestParameters());
 
 177                 request.getRequestDetails().getRequestParameters().setUserParams(null);
 
 180                 // cloudConfiguration
 
 182                 request.getRequestDetails().getCloudConfiguration().setTenantId(tenantItem.getTenant().getTenantId());
 
 183                 request.getRequestDetails().getCloudConfiguration().setLcpCloudRegionId(tenantItem.getItems().getInventoryResponseItems().get(0).getCloudRegion().getCloudRegionId());
 
 188                 AAINQInventoryResponseItem vfModuleItem = vnfItem.getItems().getInventoryResponseItems().get(nonBaseIndex);
 
 190                 request.getRequestDetails().getModelInfo().setModelType("vfModule");
 
 191                 request.getRequestDetails().getModelInfo().setModelInvariantId(vfModuleItem.getVfModule().getModelInvariantId());
 
 192                 request.getRequestDetails().getModelInfo().setModelVersionId(vfModuleItem.getVfModule().getModelVersionId());
 
 193                 request.getRequestDetails().getModelInfo().setModelName(vfModuleItem.getExtraProperties().getExtraProperty().get(1).getPropertyValue());
 
 194                 request.getRequestDetails().getModelInfo().setModelVersion(vfModuleItem.getExtraProperties().getExtraProperty().get(4).getPropertyValue());
 
 199                 request.getRequestDetails().getRequestInfo().setInstanceName(vnfItem.getItems().getInventoryResponseItems().get(baseIndex).getVfModule().getVfModuleName().replace("Vfmodule", "vDNS"));
 
 200                 request.getRequestDetails().getRequestInfo().setSource("POLICY");
 
 201                 request.getRequestDetails().getRequestInfo().setSuppressRollback(false);
 
 202                 request.getRequestDetails().getRequestInfo().setRequestorId("policy");
 
 205                 // relatedInstanceList
 
 207                 SORelatedInstanceListElement relatedInstanceListElement1 = new SORelatedInstanceListElement();
 
 208                 SORelatedInstanceListElement relatedInstanceListElement2 = new SORelatedInstanceListElement();
 
 209                 relatedInstanceListElement1.setRelatedInstance(new SORelatedInstance());
 
 210                 relatedInstanceListElement2.setRelatedInstance(new SORelatedInstance());
 
 213                 relatedInstanceListElement1.getRelatedInstance().setInstanceId(vnfServiceItem.getServiceInstance().getServiceInstanceID());
 
 214                 relatedInstanceListElement1.getRelatedInstance().setModelInfo(new SOModelInfo());
 
 215                 relatedInstanceListElement1.getRelatedInstance().getModelInfo().setModelType("service");
 
 216                 relatedInstanceListElement1.getRelatedInstance().getModelInfo().setModelInvariantId(vnfServiceItem.getServiceInstance().getModelInvariantId());
 
 217                 relatedInstanceListElement1.getRelatedInstance().getModelInfo().setModelVersionId(vnfServiceItem.getServiceInstance().getModelVersionId());
 
 218                 relatedInstanceListElement1.getRelatedInstance().getModelInfo().setModelName(vnfServiceItem.getExtraProperties().getExtraProperty().get(1).getPropertyValue());
 
 219                 relatedInstanceListElement1.getRelatedInstance().getModelInfo().setModelVersion(vnfServiceItem.getExtraProperties().getExtraProperty().get(4).getPropertyValue());
 
 222                 relatedInstanceListElement2.getRelatedInstance().setInstanceId(vnfItem.getGenericVNF().getVnfID());
 
 223                 relatedInstanceListElement2.getRelatedInstance().setModelInfo(new SOModelInfo());
 
 224                 relatedInstanceListElement2.getRelatedInstance().getModelInfo().setModelType("vnf");
 
 225                 relatedInstanceListElement2.getRelatedInstance().getModelInfo().setModelInvariantId(vnfItem.getGenericVNF().getModelInvariantId());
 
 226                 relatedInstanceListElement2.getRelatedInstance().getModelInfo().setModelVersionId(vnfItem.getExtraProperties().getExtraProperty().get(0).getPropertyValue());
 
 227                 relatedInstanceListElement2.getRelatedInstance().getModelInfo().setModelName(vnfItem.getExtraProperties().getExtraProperty().get(1).getPropertyValue());
 
 228                 relatedInstanceListElement2.getRelatedInstance().getModelInfo().setModelVersion(vnfItem.getExtraProperties().getExtraProperty().get(4).getPropertyValue());
 
 229                 relatedInstanceListElement2.getRelatedInstance().getModelInfo().setModelCustomizationName(vnfItem.getGenericVNF().getVnfType().substring(vnfItem.getGenericVNF().getVnfType().lastIndexOf('/') + 1));
 
 231                 // Insert the Service Item and VNF Item 
 
 232                 request.getRequestDetails().getRelatedInstanceList().add(relatedInstanceListElement1);
 
 233                 request.getRequestDetails().getRelatedInstanceList().add(relatedInstanceListElement2);
 
 235                 // Save the instance IDs for the VNF and service to static fields
 
 236                 preserveInstanceIDs(vnfItem.getGenericVNF().getVnfID(), vnfServiceItem.getServiceInstance().getServiceInstanceID());
 
 238                 if (logger.isDebugEnabled()) {
 
 239                         logger.debug("SO request sent: {}", Serialization.gsonPretty.toJson(request));
 
 246          * This method is needed to get the serviceInstanceId and vnfInstanceId which is used
 
 247          * in the asyncSORestCall 
 
 252         public static void sendRequest(String requestID, WorkingMemory wm, Object request) {
 
 253                 SOManager soManager = new SOManager();
 
 254                 soManager.asyncSORestCall(requestID, wm, lastServiceItemServiceInstanceId, lastVNFItemVnfId, (SORequest)request);
 
 258          * Constructs and sends an AAI vserver Named Query
 
 261          * @returns the response to the AAI Named Query
 
 263         private AAINQResponseWrapper performAaiNamedQueryRequest(VirtualControlLoopEvent onset) {
 
 265                 // create AAI named-query request with UUID started with ""
 
 266                 AAINQRequest aainqrequest = new AAINQRequest();
 
 267                 AAINQQueryParameters aainqqueryparam = new AAINQQueryParameters();
 
 268                 AAINQNamedQuery aainqnamedquery = new AAINQNamedQuery();
 
 269                 AAINQInstanceFilters aainqinstancefilter = new AAINQInstanceFilters();
 
 272                 aainqnamedquery.setNamedQueryUUID(UUID.fromString("4ff56a54-9e3f-46b7-a337-07a1d3c6b469")); // UUID.fromString($params.getAaiNamedQueryUUID()) TO DO: AaiNamedQueryUUID 
 
 273                 aainqqueryparam.setNamedQuery(aainqnamedquery);
 
 274                 aainqrequest.setQueryParameters(aainqqueryparam);
 
 278                 Map<String, Map<String, String>> aainqinstancefiltermap = new HashMap<>();
 
 279                 Map<String, String> aainqinstancefiltermapitem = new HashMap<>();
 
 280                 aainqinstancefiltermapitem.put("vserver-name", onset.getAAI().get("vserver.vserver-name")); // TO DO: get vserver.vname from dcae onset.AAI.get("vserver.vserver-name")
 
 281                 aainqinstancefiltermap.put("vserver", aainqinstancefiltermapitem);
 
 282                 aainqinstancefilter.getInstanceFilter().add(aainqinstancefiltermap);
 
 283                 aainqrequest.setInstanceFilters(aainqinstancefilter);
 
 285                 if (logger.isDebugEnabled()) {
 
 286                         logger.debug("AAI Request sent: {}", Serialization.gsonPretty.toJson(aainqrequest));
 
 289                 AAINQResponse aainqresponse = new AAIManager(new RESTManager()).postQuery(
 
 290                                 getPEManagerEnvProperty("aai.url"),
 
 291                                 getPEManagerEnvProperty("aai.username"),
 
 292                                 getPEManagerEnvProperty("aai.password"),
 
 293                                 aainqrequest, onset.getRequestID());
 
 295                 // Check AAI response
 
 296                 if (aainqresponse == null) {
 
 297                         logger.warn("No response received from AAI for request {}", aainqrequest);
 
 301                 // Create AAINQResponseWrapper
 
 302                 AAINQResponseWrapper aainqResponseWrapper = new AAINQResponseWrapper(onset.getRequestID(), aainqresponse);
 
 304                 if (logger.isDebugEnabled()) {
 
 305                         logger.debug("AAI Named Query Response: ");
 
 306                         logger.debug(Serialization.gsonPretty.toJson(aainqResponseWrapper.getAainqresponse()));
 
 309                 return aainqResponseWrapper;
 
 313          * Find the base index or non base index in a list of inventory response items
 
 314          * @param inventoryResponseItems
 
 315          * @param baseIndexFlag true if we are searching for the base index, false if we are searching for hte non base index
 
 316          * @return the base or non base index or -1 if the index was not found
 
 318         private int findIndex(List<AAINQInventoryResponseItem> inventoryResponseItems, boolean baseIndexFlag) {
 
 319                 for (AAINQInventoryResponseItem invenoryResponseItem : inventoryResponseItems) {
 
 320                         if (invenoryResponseItem.getVfModule() != null && baseIndexFlag == invenoryResponseItem.getVfModule().getIsBaseVfModule()) {
 
 321                                 return inventoryResponseItems.indexOf(invenoryResponseItem);
 
 329          * This method is called to remember the last service instance ID and VNF Item VNF ID. Note these fields are static, beware for multithreaded deployments
 
 330          * @param vnfInstanceID update the last VNF instance ID to this value
 
 331          * @param serviceInstanceID update the last service instance ID to this value
 
 333         private static void preserveInstanceIDs(final String vnfInstanceID, final String serviceInstanceID) {
 
 334                 lastVNFItemVnfId = vnfInstanceID;
 
 335                 lastServiceItemServiceInstanceId = serviceInstanceID;
 
 339          * This method reads and validates environmental properties coming from the policy engine. Null properties cause
 
 340          * an {@link IllegalArgumentException} runtime exception to be thrown 
 
 341          * @param string the name of the parameter to retrieve
 
 342          * @return the property value
 
 344         private static String getPEManagerEnvProperty(String enginePropertyName) {
 
 345                 String enginePropertyValue = PolicyEngine.manager.getEnvironmentProperty(enginePropertyName);
 
 346                 if (enginePropertyValue == null) {
 
 347                         throw new IllegalArgumentException("The value of policy engine manager environment property \"" + enginePropertyName + "\" may not be null");
 
 349                 return enginePropertyValue;