From 636a1b2fcafa5249cf2bf380dfb6e20f6fe98691 Mon Sep 17 00:00:00 2001 From: Bruno Sakoto Date: Fri, 27 Sep 2019 16:15:49 -0400 Subject: Integrate cds actor service provider * Add request enrichment with aai service instance id and vnf id * Implement cds grpc request * Implement VfwControlLoopCdsTest Issue-ID: POLICY-2088 Signed-off-by: Bruno Sakoto Change-Id: Ib44d447d6a3a70ff800a5760032b676fdfa32d9c --- .../eventmanager/ControlLoopEventManager.java | 7 +- .../eventmanager/ControlLoopOperationManager.java | 124 +++++++++++++++++++-- .../ControlLoopOperationManagerTest.java | 43 +++++++ .../eventmanager/src/test/resources/test-cds.yaml | 46 ++++++++ 4 files changed, 211 insertions(+), 9 deletions(-) create mode 100644 controlloop/common/eventmanager/src/test/resources/test-cds.yaml (limited to 'controlloop/common/eventmanager/src') diff --git a/controlloop/common/eventmanager/src/main/java/org/onap/policy/controlloop/eventmanager/ControlLoopEventManager.java b/controlloop/common/eventmanager/src/main/java/org/onap/policy/controlloop/eventmanager/ControlLoopEventManager.java index aaccef60b..f6cfe5594 100644 --- a/controlloop/common/eventmanager/src/main/java/org/onap/policy/controlloop/eventmanager/ControlLoopEventManager.java +++ b/controlloop/common/eventmanager/src/main/java/org/onap/policy/controlloop/eventmanager/ControlLoopEventManager.java @@ -1056,7 +1056,7 @@ public class ControlLoopEventManager implements LockCallback, Serializable { * This function calls Aai Custom Query and responds with the AaiCqResponse. * * @param event input event - * @return AaiCqResponse Response from Aai for custom query + * @return AaiCqResponse Response from Aai for custom query. Can not be null. * @throws AaiException if error occurs */ public AaiCqResponse getCqResponse(VirtualControlLoopEvent event) throws AaiException { @@ -1088,6 +1088,11 @@ public class ControlLoopEventManager implements LockCallback, Serializable { response = new AaiManager(new RestManager()).getCustomQueryResponse(aaiHostUrl, aaiUser, aaiPassword, reqId, vserverId); + + if (response == null) { + throw new AaiException("Aai response is undefined"); + } + return response; } diff --git a/controlloop/common/eventmanager/src/main/java/org/onap/policy/controlloop/eventmanager/ControlLoopOperationManager.java b/controlloop/common/eventmanager/src/main/java/org/onap/policy/controlloop/eventmanager/ControlLoopOperationManager.java index 293fa43aa..eb1901937 100644 --- a/controlloop/common/eventmanager/src/main/java/org/onap/policy/controlloop/eventmanager/ControlLoopOperationManager.java +++ b/controlloop/common/eventmanager/src/main/java/org/onap/policy/controlloop/eventmanager/ControlLoopOperationManager.java @@ -5,6 +5,7 @@ * Copyright (C) 2017-2019 AT&T Intellectual Property. All rights reserved. * Modifications Copyright (C) 2019 Huawei Technologies Co., Ltd. All rights reserved. * Modifications Copyright (C) 2019 Tech Mahindra + * Modifications Copyright (C) 2019 Bell Canada. * ================================================================================ * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -26,18 +27,26 @@ import java.io.Serializable; import java.sql.Timestamp; import java.time.Instant; import java.util.AbstractMap; +import java.util.HashMap; import java.util.LinkedList; import java.util.List; +import java.util.Map; import java.util.NoSuchElementException; +import java.util.Optional; import java.util.Properties; import javax.persistence.EntityManager; import javax.persistence.Persistence; + import org.eclipse.persistence.config.PersistenceUnitProperties; import org.onap.aai.domain.yang.GenericVnf; +import org.onap.aai.domain.yang.ServiceInstance; +import org.onap.ccsdk.cds.controllerblueprints.processing.api.ExecutionServiceInput; +import org.onap.policy.aai.AaiCqResponse; import org.onap.policy.aai.util.AaiException; import org.onap.policy.appc.Response; import org.onap.policy.appc.ResponseCode; import org.onap.policy.appclcm.LcmResponseWrapper; +import org.onap.policy.cds.CdsResponse; import org.onap.policy.controlloop.ControlLoopEvent; import org.onap.policy.controlloop.ControlLoopException; import org.onap.policy.controlloop.ControlLoopOperation; @@ -45,12 +54,15 @@ import org.onap.policy.controlloop.ControlLoopResponse; import org.onap.policy.controlloop.VirtualControlLoopEvent; import org.onap.policy.controlloop.actor.appc.AppcActorServiceProvider; import org.onap.policy.controlloop.actor.appclcm.AppcLcmActorServiceProvider; +import org.onap.policy.controlloop.actor.cds.CdsActorServiceProvider; +import org.onap.policy.controlloop.actor.cds.constants.CdsActorConstants; import org.onap.policy.controlloop.actor.sdnc.SdncActorServiceProvider; import org.onap.policy.controlloop.actor.sdnr.SdnrActorServiceProvider; import org.onap.policy.controlloop.actor.so.SoActorServiceProvider; import org.onap.policy.controlloop.actor.vfc.VfcActorServiceProvider; import org.onap.policy.controlloop.policy.Policy; import org.onap.policy.controlloop.policy.PolicyResult; +import org.onap.policy.controlloop.policy.TargetType; import org.onap.policy.database.operationshistory.Dbao; import org.onap.policy.drools.system.PolicyEngineConstants; import org.onap.policy.guard.Util; @@ -72,6 +84,8 @@ public class ControlLoopOperationManager implements Serializable { private static final String GENERIC_VNF_VNF_NAME = "generic-vnf.vnf-name"; private static final String GENERIC_VNF_VNF_ID = "generic-vnf.vnf-id"; + private static final String AAI_SERVICE_INSTANCE_ID_KEY = "service-instance.service-instance-id"; + // // These properties are not changeable, but accessible // for Drools Rule statements. @@ -89,6 +103,7 @@ public class ControlLoopOperationManager implements Serializable { private ControlLoopEventManager eventManager = null; private String targetEntity; private String guardApprovalStatus = "NONE";// "NONE", "PERMIT", "DENY" + private AaiCqResponse aaiCqResponse; private transient Object operationRequest; /** @@ -106,10 +121,15 @@ public class ControlLoopOperationManager implements Serializable { this.policy = policy; this.guardApprovalStatus = "NONE"; this.eventManager = em; - this.targetEntity = getTarget(policy); try { + if (Boolean.valueOf(PolicyEngineConstants.getManager().getEnvironmentProperty(AAI_CUSTOM_QUERY))) { + this.aaiCqResponse = this.eventManager.getCqResponse((VirtualControlLoopEvent) onset); + } + + this.targetEntity = getTarget(policy); + // // Let's make a sanity check // @@ -125,6 +145,8 @@ public class ControlLoopOperationManager implements Serializable { break; case "SDNC": break; + case "CDS": + break; default: throw new ControlLoopException("ControlLoopEventManager: policy has an unknown actor."); } @@ -142,8 +164,8 @@ public class ControlLoopOperationManager implements Serializable { * vnf-id is retrieved by a named query to A&AI. */ if (Boolean.valueOf(PolicyEngineConstants.getManager().getEnvironmentProperty(AAI_CUSTOM_QUERY))) { - GenericVnf genvnf = this.eventManager.getCqResponse((VirtualControlLoopEvent) onset) - .getGenericVnfByModelInvariantId(policy.getTarget().getResourceID()); + GenericVnf genvnf = + this.aaiCqResponse.getGenericVnfByModelInvariantId(policy.getTarget().getResourceID()); if (genvnf == null) { logger.info("Target entity could not be found"); throw new AaiException("Target vnf-id could not be found"); @@ -261,8 +283,7 @@ public class ControlLoopOperationManager implements Serializable { try { String vnfId; if (Boolean.valueOf(PolicyEngineConstants.getManager().getEnvironmentProperty(AAI_CUSTOM_QUERY))) { - vnfId = this.eventManager.getCqResponse((VirtualControlLoopEvent) onset).getDefaultGenericVnf() - .getVnfId(); + vnfId = this.aaiCqResponse.getDefaultGenericVnf().getVnfId(); } else { vnfId = this.eventManager.getVnfResponse().getVnfId(); } @@ -314,6 +335,8 @@ public class ControlLoopOperationManager implements Serializable { return startSdnrOperation(onset, operation); case "SDNC": return startSdncOperation(onset, operation); + case "CDS": + return startCdsOperation(onset, operation); default: throw new ControlLoopException("invalid actor " + policy.getActor() + " on policy"); } @@ -350,7 +373,7 @@ public class ControlLoopOperationManager implements Serializable { if (Boolean.valueOf(PolicyEngineConstants.getManager().getEnvironmentProperty(AAI_CUSTOM_QUERY))) { this.operationRequest = soActorSp.constructRequestCq((VirtualControlLoopEvent) onset, operation.clOperation, - this.policy, eventManager.getCqResponse((VirtualControlLoopEvent) onset)); + this.policy, this.aaiCqResponse); } else { this.operationRequest = soActorSp.constructRequest((VirtualControlLoopEvent) onset, operation.clOperation, this.policy, eventManager.getNqVserverFromAai()); @@ -370,8 +393,7 @@ public class ControlLoopOperationManager implements Serializable { private Object startVfcOperation(ControlLoopEvent onset, Operation operation) throws AaiException { if (Boolean.valueOf(PolicyEngineConstants.getManager().getEnvironmentProperty(AAI_CUSTOM_QUERY))) { this.operationRequest = VfcActorServiceProvider.constructRequestCq((VirtualControlLoopEvent) onset, - operation.clOperation, this.policy, - eventManager.getCqResponse((VirtualControlLoopEvent) onset)); + operation.clOperation, this.policy, this.aaiCqResponse); } else { this.operationRequest = VfcActorServiceProvider.constructRequest((VirtualControlLoopEvent) onset, operation.clOperation, this.policy, this.eventManager.getVnfResponse(), @@ -416,6 +438,60 @@ public class ControlLoopOperationManager implements Serializable { return operationRequest; } + private Object startCdsOperation(ControlLoopEvent onset, Operation operation) throws AaiException { + + CdsActorServiceProvider provider = new CdsActorServiceProvider(); + Optional optionalRequest = provider.constructRequest( + (VirtualControlLoopEvent) onset, operation.clOperation, this.policy, this.buildAaiParams()); + + this.currentOperation = operation; + if (optionalRequest.isPresent()) { + this.operationRequest = optionalRequest.get(); + } else { + this.operationRequest = null; + this.policyResult = PolicyResult.FAILURE; + } + + return this.operationRequest; + } + + /** + * Build AAI parameters for CDS operation. + * @return a map containing vnf id key and value for the vnf to apply the action to. + * @throws AaiException if the vnf can not be found. + */ + private Map buildAaiParams() throws AaiException { + + Map result = new HashMap<>(); + + if (TargetType.VNF.equals(policy.getTarget().getType()) + || TargetType.VFMODULE.equals(policy.getTarget().getType())) { + + if (Boolean.valueOf(PolicyEngineConstants.getManager().getEnvironmentProperty(AAI_CUSTOM_QUERY))) { + + ServiceInstance serviceInstance = this.aaiCqResponse.getServiceInstance(); + if (serviceInstance == null) { + logger.info("Target entity service instance could not be found"); + throw new AaiException("Target service instance could not be found"); + } + + GenericVnf genericVnf = + this.aaiCqResponse.getGenericVnfByModelInvariantId(policy.getTarget().getResourceID()); + if (genericVnf == null) { + logger.info("Target entity generic vnf could not be found"); + throw new AaiException("Target generic vnf could not be found"); + } + + result.put(AAI_SERVICE_INSTANCE_ID_KEY, serviceInstance.getServiceInstanceId()); + result.put(GENERIC_VNF_VNF_ID, genericVnf.getVnfId()); + } + + } + + return result; + + } + /** * Handle a response. * @@ -456,6 +532,11 @@ public class ControlLoopOperationManager implements Serializable { // Cast SDNC response and handle it // return onResponse((SdncResponse) response); + } else if (response instanceof CdsResponse) { + // + // Cast CDS response and handle it + // + return onResponse((CdsResponse) response); } else { return null; } @@ -694,6 +775,33 @@ public class ControlLoopOperationManager implements Serializable { } } + /** + * This method handles operation responses from CDS. + * + * @param response the CDS response + * @return The result of the response handling + */ + private PolicyResult onResponse(CdsResponse response) { + if (response != null && CdsActorConstants.SUCCESS.equals(response.getStatus())) { + // + // Consider it as success + // + this.completeOperation(this.attempts, SUCCESS_MSG, PolicyResult.SUCCESS); + return getTimeoutResult(PolicyResult.SUCCESS); + } else { + // + // Consider it as failure + // + this.completeOperation(this.attempts, FAILED_MSG, PolicyResult.FAILURE); + if (PolicyResult.FAILURE_TIMEOUT.equals(this.policyResult)) { + return null; + } + // increment operation attempts for retries + this.attempts += 1; + return PolicyResult.FAILURE; + } + } + private PolicyResult getTimeoutResult(PolicyResult result) { return (PolicyResult.FAILURE_TIMEOUT.equals(this.policyResult) ? null : result); } diff --git a/controlloop/common/eventmanager/src/test/java/org/onap/policy/controlloop/eventmanager/ControlLoopOperationManagerTest.java b/controlloop/common/eventmanager/src/test/java/org/onap/policy/controlloop/eventmanager/ControlLoopOperationManagerTest.java index 9b1633521..914eb7664 100644 --- a/controlloop/common/eventmanager/src/test/java/org/onap/policy/controlloop/eventmanager/ControlLoopOperationManagerTest.java +++ b/controlloop/common/eventmanager/src/test/java/org/onap/policy/controlloop/eventmanager/ControlLoopOperationManagerTest.java @@ -3,6 +3,7 @@ * unit test * ================================================================================ * Copyright (C) 2017-2019 AT&T Intellectual Property. All rights reserved. + * Modifications Copyright (C) 2019 Bell Canada. * ================================================================================ * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -43,6 +44,7 @@ import org.apache.commons.io.IOUtils; import org.junit.AfterClass; import org.junit.BeforeClass; import org.junit.Test; +import org.onap.ccsdk.cds.controllerblueprints.processing.api.ExecutionServiceInput; import org.onap.policy.aai.util.AaiException; import org.onap.policy.appc.CommonHeader; import org.onap.policy.appc.Response; @@ -79,6 +81,7 @@ import org.slf4j.LoggerFactory; public class ControlLoopOperationManagerTest { private static final String VSERVER_NAME = "vserver.vserver-name"; private static final String TEST_YAML = "src/test/resources/test.yaml"; + private static final String TEST_CDS_YAML = "src/test/resources/test-cds.yaml"; private static final String ONSET_ONE = "onsetOne"; private static final String VNF_NAME = "generic-vnf.vnf-name"; private static final String VNF_ID = "generic-vnf.vnf-id"; @@ -745,6 +748,46 @@ public class ControlLoopOperationManagerTest { assertEquals(PolicyResult.FAILURE, clom.onResponse(soRw)); } + @Test + public void testStartCdsOperation() throws ControlLoopException, IOException { + + // Prepare + String yamlString; + try (InputStream is = new FileInputStream(new File(TEST_CDS_YAML))) { + yamlString = IOUtils.toString(is, StandardCharsets.UTF_8); + } + + UUID requestId = UUID.randomUUID(); + VirtualControlLoopEvent event = new VirtualControlLoopEvent(); + event.setClosedLoopControlName(TWO_ONSET_TEST); + event.setRequestId(requestId); + event.setTarget(VNF_ID); + event.setClosedLoopAlarmStart(Instant.now()); + event.setClosedLoopEventStatus(ControlLoopEventStatus.ONSET); + event.setAai(new HashMap<>()); + event.getAai().put(VNF_NAME, ONSET_ONE); + event.getAai().put(VSERVER_NAME, "OzVServer"); + + ControlLoopEventManager eventManager = + new ControlLoopEventManager(event.getClosedLoopControlName(), event.getRequestId()); + VirtualControlLoopNotification notification = eventManager.activate(yamlString, event); + assertNotNull(notification); + assertEquals(ControlLoopNotificationType.ACTIVE, notification.getNotification()); + + Policy policy = eventManager.getProcessor().getCurrentPolicy(); + ControlLoopOperationManager operationManager = new ControlLoopOperationManager(event, policy, eventManager); + + // Run + Object result = operationManager.startOperation(event); + + // Verify + assertNotNull(result); + assertTrue(result instanceof ExecutionServiceInput); + ExecutionServiceInput request = (ExecutionServiceInput) result; + logger.debug("request: " + request); + + } + @Test public void testCommitAbatement() throws Exception { diff --git a/controlloop/common/eventmanager/src/test/resources/test-cds.yaml b/controlloop/common/eventmanager/src/test/resources/test-cds.yaml new file mode 100644 index 000000000..332c724b2 --- /dev/null +++ b/controlloop/common/eventmanager/src/test/resources/test-cds.yaml @@ -0,0 +1,46 @@ +# Copyright (C) 2019 Bell Canada. +# +# 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. +controlLoop: + version: 2.0.0 + controlLoopName: ControlLoop-vFirewall-d0a1dfc6-94f5-4fd4-a5b5-4630b438850a + services: + - serviceInvariantUUID: 5cfe6f4a-41bc-4247-8674-ebd4b98e35cc + serviceUUID: 0f40bba5-986e-4b3c-803f-ddd1b7b25f24 + serviceName: 57e66ea7-0ed6-45c7-970f + trigger_policy: unique-policy-id-1-modifyConfig + timeout: 60 + abatement: true + +policies: + - id: unique-policy-id-1-modifyConfig + name: modify packet gen config + description: + actor: CDS + recipe: ModifyConfig + target: + resourceID: bbb3cefd-01c8-413c-9bdd-2b92f9ca3d38 + type: VNF + payload: + artifact_name: vfw-cds + artifact_version: 1.0.0 + mode: async + data: '{"mapInfo":{"key":"val"},"arrayInfo":["one","two"],"paramInfo":"val"}' + retry: 0 + timeout: 30 + success: final_success + failure: final_failure + failure_timeout: final_failure_timeout + failure_retries: final_failure_retries + failure_exception: final_failure_exception + failure_guard: final_failure_guard \ No newline at end of file -- cgit 1.2.3-korg