2 * ============LICENSE_START=======================================================
3 * controlloop event manager
4 * ================================================================================
5 * Copyright (C) 2017-2018 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.eventmanager;
23 import java.io.Serializable;
24 import java.io.UnsupportedEncodingException;
25 import java.net.URLDecoder;
26 import java.util.ArrayList;
27 import java.util.Collection;
28 import java.util.HashMap;
29 import java.util.LinkedList;
30 import java.util.List;
32 import java.util.UUID;
34 import org.onap.policy.aai.AaiGetVnfResponse;
35 import org.onap.policy.aai.AaiGetVserverResponse;
36 import org.onap.policy.aai.AaiManager;
37 import org.onap.policy.aai.AaiNqInstanceFilters;
38 import org.onap.policy.aai.AaiNqNamedQuery;
39 import org.onap.policy.aai.AaiNqQueryParameters;
40 import org.onap.policy.aai.AaiNqRequest;
41 import org.onap.policy.aai.AaiNqResponse;
42 import org.onap.policy.aai.AaiNqResponseWrapper;
43 import org.onap.policy.aai.AaiNqVServer;
44 import org.onap.policy.aai.util.AaiException;
45 import org.onap.policy.controlloop.ControlLoopEventStatus;
46 import org.onap.policy.controlloop.ControlLoopException;
47 import org.onap.policy.controlloop.ControlLoopNotificationType;
48 import org.onap.policy.controlloop.ControlLoopOperation;
49 import org.onap.policy.controlloop.VirtualControlLoopEvent;
50 import org.onap.policy.controlloop.VirtualControlLoopNotification;
51 import org.onap.policy.controlloop.policy.FinalResult;
52 import org.onap.policy.controlloop.policy.Policy;
53 import org.onap.policy.controlloop.processor.ControlLoopProcessor;
54 import org.onap.policy.drools.system.PolicyEngine;
55 import org.onap.policy.guard.GuardResult;
56 import org.onap.policy.guard.LockCallback;
57 import org.onap.policy.guard.PolicyGuard;
58 import org.onap.policy.guard.PolicyGuard.LockResult;
59 import org.onap.policy.guard.TargetLock;
60 import org.onap.policy.rest.RESTManager;
61 import org.onap.policy.so.util.Serialization;
62 import org.slf4j.Logger;
63 import org.slf4j.LoggerFactory;
65 public class ControlLoopEventManager implements LockCallback, Serializable {
66 public static final String PROV_STATUS_ACTIVE = "ACTIVE";
67 private static final String VM_NAME = "VM_NAME";
68 private static final String VNF_NAME = "VNF_NAME";
69 public static final String GENERIC_VNF_VNF_ID = "generic-vnf.vnf-id";
70 public static final String GENERIC_VNF_VNF_NAME = "generic-vnf.vnf-name";
71 public static final String VSERVER_VSERVER_NAME = "vserver.vserver-name";
72 public static final String GENERIC_VNF_IS_CLOSED_LOOP_DISABLED = "generic-vnf.is-closed-loop-disabled";
73 public static final String VSERVER_IS_CLOSED_LOOP_DISABLED = "vserver.is-closed-loop-disabled";
74 public static final String GENERIC_VNF_PROV_STATUS = "generic-vnf.prov-status";
75 public static final String VSERVER_PROV_STATUS = "vserver.prov-status";
77 private static final String QUERY_AAI_ERROR_MSG = "Exception from queryAai: ";
80 * Additional time, in seconds, to add to a "lock" request. This ensures that the lock
81 * won't expire right before an operation completes.
83 private static final int ADDITIONAL_LOCK_SEC = 60;
85 private static final Logger logger = LoggerFactory.getLogger(ControlLoopEventManager.class);
87 private static final long serialVersionUID = -1216568161322872641L;
88 public final String closedLoopControlName;
89 public final UUID requestID;
91 private String controlLoopResult;
92 private transient ControlLoopProcessor processor = null;
93 private VirtualControlLoopEvent onset;
94 private Integer numOnsets = 0;
95 private Integer numAbatements = 0;
96 private VirtualControlLoopEvent abatement;
97 private FinalResult controlLoopTimedOut = null;
99 private boolean isActivated = false;
100 private LinkedList<ControlLoopOperation> controlLoopHistory = new LinkedList<>();
101 private ControlLoopOperationManager currentOperation = null;
102 private transient TargetLock targetLock = null;
103 private AaiGetVnfResponse vnfResponse = null;
104 private AaiGetVserverResponse vserverResponse = null;
107 * Wrapper for AAI vserver named-query response. This is initialized in a lazy
110 private AaiNqResponseWrapper nqVserverResponse = null;
112 private static Collection<String> requiredAAIKeys = new ArrayList<>();
115 requiredAAIKeys.add("AICVServerSelfLink");
116 requiredAAIKeys.add("AICIdentity");
117 requiredAAIKeys.add("is_closed_loop_disabled");
118 requiredAAIKeys.add(VM_NAME);
121 public ControlLoopEventManager(String closedLoopControlName, UUID requestID) {
122 this.closedLoopControlName = closedLoopControlName;
123 this.requestID = requestID;
126 public String getClosedLoopControlName() {
127 return closedLoopControlName;
130 public String getControlLoopResult() {
131 return controlLoopResult;
134 public void setControlLoopResult(String controlLoopResult) {
135 this.controlLoopResult = controlLoopResult;
138 public Integer getNumOnsets() {
142 public void setNumOnsets(Integer numOnsets) {
143 this.numOnsets = numOnsets;
146 public Integer getNumAbatements() {
147 return numAbatements;
150 public void setNumAbatements(Integer numAbatements) {
151 this.numAbatements = numAbatements;
154 public boolean isActivated() {
158 public void setActivated(boolean isActivated) {
159 this.isActivated = isActivated;
162 public VirtualControlLoopEvent getOnsetEvent() {
166 public VirtualControlLoopEvent getAbatementEvent() {
167 return this.abatement;
170 public ControlLoopProcessor getProcessor() {
171 return this.processor;
174 public UUID getRequestID() {
179 * Activate a control loop event.
181 * @param event the event
182 * @return the VirtualControlLoopNotification
184 public VirtualControlLoopNotification activate(VirtualControlLoopEvent event) {
185 VirtualControlLoopNotification notification = new VirtualControlLoopNotification(event);
188 // This method should ONLY be called ONCE
190 if (this.isActivated) {
191 throw new ControlLoopException("ControlLoopEventManager has already been activated.");
194 // Syntax check the event
196 checkEventSyntax(event);
199 // At this point we are good to go with this event
204 notification.setNotification(ControlLoopNotificationType.ACTIVE);
206 // Set ourselves as active
208 this.isActivated = true;
209 } catch (ControlLoopException e) {
210 logger.error("{}: activate by event threw: ", this, e);
211 notification.setNotification(ControlLoopNotificationType.REJECTED);
212 notification.setMessage(e.getMessage());
218 * Activate a control loop event.
220 * @param yamlSpecification the yaml specification
221 * @param event the event
222 * @return the VirtualControlLoopNotification
224 public VirtualControlLoopNotification activate(String yamlSpecification, VirtualControlLoopEvent event) {
225 VirtualControlLoopNotification notification = new VirtualControlLoopNotification(event);
228 // This method should ONLY be called ONCE
230 if (this.isActivated) {
231 throw new ControlLoopException("ControlLoopEventManager has already been activated.");
234 // Syntax check the event
236 checkEventSyntax(event);
241 if (yamlSpecification == null || yamlSpecification.length() < 1) {
242 throw new ControlLoopException("yaml specification is null or 0 length");
244 } catch (ControlLoopException e) {
245 logger.error("{}: activate by YAML specification and event threw: ", this, e);
246 notification.setNotification(ControlLoopNotificationType.REJECTED);
247 notification.setMessage(e.getMessage());
251 String decodedYaml = null;
253 decodedYaml = URLDecoder.decode(yamlSpecification, "UTF-8");
254 if (decodedYaml != null && decodedYaml.length() > 0) {
255 yamlSpecification = decodedYaml;
257 } catch (UnsupportedEncodingException e) {
258 logger.error("{}: YAML decode in activate by YAML specification and event threw: ", this, e);
259 notification.setNotification(ControlLoopNotificationType.REJECTED);
260 notification.setMessage(e.getMessage());
266 // Parse the YAML specification
268 this.processor = new ControlLoopProcessor(yamlSpecification);
271 // At this point we are good to go with this event
278 notification.setNotification(ControlLoopNotificationType.ACTIVE);
280 // Set ourselves as active
282 this.isActivated = true;
283 } catch (ControlLoopException e) {
284 logger.error("{}: activate by YAML specification and event threw: ", this, e);
285 notification.setNotification(ControlLoopNotificationType.REJECTED);
286 notification.setMessage(e.getMessage());
292 * Check if the control loop is final.
294 * @return a VirtualControlLoopNotification if the control loop is final, otherwise
295 * <code>null</code> is returned
296 * @throws ControlLoopException if an error occurs
298 public VirtualControlLoopNotification isControlLoopFinal() throws ControlLoopException {
300 // Check if they activated us
302 if (!this.isActivated) {
303 throw new ControlLoopException("ControlLoopEventManager MUST be activated first.");
306 // Make sure we are expecting this call.
308 if (this.onset == null) {
309 throw new ControlLoopException("No onset event for ControlLoopEventManager.");
312 // Ok, start creating the notification
314 VirtualControlLoopNotification notification = new VirtualControlLoopNotification(this.onset);
316 // Check if the overall control loop has timed out
318 if (this.isControlLoopTimedOut()) {
320 // Yes we have timed out
322 notification.setNotification(ControlLoopNotificationType.FINAL_FAILURE);
323 notification.setMessage("Control Loop timed out");
324 notification.getHistory().addAll(this.controlLoopHistory);
328 // Check if the current policy is Final
330 FinalResult result = this.processor.checkIsCurrentPolicyFinal();
331 if (result == null) {
333 // we are not at a final result
339 case FINAL_FAILURE_EXCEPTION:
340 notification.setNotification(ControlLoopNotificationType.FINAL_FAILURE);
341 notification.setMessage("Exception in processing closed loop");
344 case FINAL_FAILURE_RETRIES:
345 case FINAL_FAILURE_TIMEOUT:
346 case FINAL_FAILURE_GUARD:
347 notification.setNotification(ControlLoopNotificationType.FINAL_FAILURE);
350 notification.setNotification(ControlLoopNotificationType.FINAL_OPENLOOP);
353 notification.setNotification(ControlLoopNotificationType.FINAL_SUCCESS);
359 // Be sure to add all the history
361 notification.getHistory().addAll(this.controlLoopHistory);
366 * Process the control loop.
368 * @return a ControlLoopOperationManager
369 * @throws ControlLoopException if an error occurs
370 * @throws AaiException if an error occurs retrieving information from A&AI
372 public ControlLoopOperationManager processControlLoop() throws ControlLoopException, AaiException {
374 // Check if they activated us
376 if (!this.isActivated) {
377 throw new ControlLoopException("ControlLoopEventManager MUST be activated first.");
380 // Make sure we are expecting this call.
382 if (this.onset == null) {
383 throw new ControlLoopException("No onset event for ControlLoopEventManager.");
386 // Is there a current operation?
388 if (this.currentOperation != null) {
390 // Throw an exception, or simply return the current operation?
392 throw new ControlLoopException("Already working an Operation, do not call this method.");
395 // Ensure we are not FINAL
397 VirtualControlLoopNotification notification = this.isControlLoopFinal();
398 if (notification != null) {
400 // This is weird, we require them to call the isControlLoopFinal() method first
402 // We should really abstract this and avoid throwing an exception, because it really
403 // isn't an exception.
405 throw new ControlLoopException("Control Loop is in FINAL state, do not call this method.");
408 // Not final so get the policy that needs to be worked on.
410 Policy policy = this.processor.getCurrentPolicy();
411 if (policy == null) {
412 throw new ControlLoopException("ControlLoopEventManager: processor came upon null Policy.");
415 // And setup an operation
417 this.currentOperation = new ControlLoopOperationManager(this.onset, policy, this);
421 return this.currentOperation;
425 * Finish an operation.
427 * @param operation the operation
429 public void finishOperation(ControlLoopOperationManager operation) throws ControlLoopException {
431 // Verify we have a current operation
433 if (this.currentOperation != null) {
435 // Validate they are finishing the current operation
436 // PLD - this is simply comparing the policy. Do we want to equals the whole object?
438 if (this.currentOperation.policy.equals(operation.policy)) {
439 logger.debug("Finishing {} result is {}", this.currentOperation.policy.getRecipe(),
440 this.currentOperation.getOperationResult());
444 this.controlLoopHistory.addAll(this.currentOperation.getHistory());
446 // Move to the next Policy
448 this.processor.nextPolicyForResult(this.currentOperation.getOperationResult());
450 // Just null this out
452 this.currentOperation = null;
454 // TODO: Release our lock
458 logger.debug("Cannot finish current operation {} does not match given operation {}",
459 this.currentOperation.policy, operation.policy);
462 throw new ControlLoopException("No operation to finish.");
466 * Obtain a lock for the current operation.
468 * @return the lock result
469 * @throws ControlLoopException if an error occurs
471 public synchronized LockResult<GuardResult, TargetLock> lockCurrentOperation() throws ControlLoopException {
475 if (this.currentOperation == null) {
476 throw new ControlLoopException("Do not have a current operation.");
479 // Have we acquired it already?
481 if (this.targetLock != null) {
483 // TODO: Make sure the current lock is for the same target.
484 // Currently, it should be. But in the future it may not.
486 GuardResult result = PolicyGuard.lockTarget(targetLock,
487 this.currentOperation.getOperationTimeout() + ADDITIONAL_LOCK_SEC);
488 return new LockResult<>(result, this.targetLock);
493 LockResult<GuardResult, TargetLock> lockResult =
494 PolicyGuard.lockTarget(this.currentOperation.policy.getTarget().getType(),
495 this.currentOperation.getTargetEntity(), this.onset.getRequestId(), this,
496 this.currentOperation.getOperationTimeout() + ADDITIONAL_LOCK_SEC);
500 if (lockResult.getA().equals(GuardResult.LOCK_ACQUIRED)) {
502 // Yes, let's save it
504 this.targetLock = lockResult.getB();
511 * Release the lock for the current operation.
513 * @return the target lock
515 public synchronized TargetLock unlockCurrentOperation() {
516 if (this.targetLock == null) {
520 TargetLock returnLock = this.targetLock;
521 this.targetLock = null;
523 PolicyGuard.unlockTarget(returnLock);
525 // always return the old target lock so rules can retract it
529 public enum NEW_EVENT_STATUS {
530 FIRST_ONSET, SUBSEQUENT_ONSET, FIRST_ABATEMENT, SUBSEQUENT_ABATEMENT, SYNTAX_ERROR;
534 * An event onset/abatement.
536 * @param event the event
538 * @throws AaiException if an error occurs retrieving information from A&AI
540 public NEW_EVENT_STATUS onNewEvent(VirtualControlLoopEvent event) throws AaiException {
542 this.checkEventSyntax(event);
543 if (event.getClosedLoopEventStatus() == ControlLoopEventStatus.ONSET) {
545 // Check if this is our original ONSET
547 if (event.equals(this.onset)) {
549 // Query A&AI if needed
556 return NEW_EVENT_STATUS.FIRST_ONSET;
559 // Log that we got an onset
562 return NEW_EVENT_STATUS.SUBSEQUENT_ONSET;
563 } else if (event.getClosedLoopEventStatus() == ControlLoopEventStatus.ABATED) {
565 // Have we already got an abatement?
567 if (this.abatement == null) {
571 this.abatement = event;
573 // Keep track that we received another
575 this.numAbatements++;
579 return NEW_EVENT_STATUS.FIRST_ABATEMENT;
582 // Keep track that we received another
584 this.numAbatements++;
588 return NEW_EVENT_STATUS.SUBSEQUENT_ABATEMENT;
591 } catch (ControlLoopException e) {
592 logger.error("{}: onNewEvent threw: ", this, e);
594 return NEW_EVENT_STATUS.SYNTAX_ERROR;
598 * Set the control loop time out.
600 * @return a VirtualControlLoopNotification
602 public VirtualControlLoopNotification setControlLoopTimedOut() {
603 this.controlLoopTimedOut = FinalResult.FINAL_FAILURE_TIMEOUT;
604 VirtualControlLoopNotification notification = new VirtualControlLoopNotification(this.onset);
605 notification.setNotification(ControlLoopNotificationType.FINAL_FAILURE);
606 notification.setMessage("Control Loop timed out");
607 notification.getHistory().addAll(this.controlLoopHistory);
611 public boolean isControlLoopTimedOut() {
612 return (this.controlLoopTimedOut == FinalResult.FINAL_FAILURE_TIMEOUT);
616 * Get the control loop timeout.
618 * @param defaultTimeout the default timeout
619 * @return the timeout
621 public int getControlLoopTimeout(Integer defaultTimeout) {
622 if (this.processor != null && this.processor.getControlLoop() != null) {
623 return this.processor.getControlLoop().getTimeout();
625 if (defaultTimeout != null) {
626 return defaultTimeout;
631 public AaiGetVnfResponse getVnfResponse() {
635 public AaiGetVserverResponse getVserverResponse() {
636 return vserverResponse;
640 * Check an event syntax.
642 * @param event the event syntax
643 * @throws ControlLoopException if an error occurs
645 public void checkEventSyntax(VirtualControlLoopEvent event) throws ControlLoopException {
646 if (event.getClosedLoopEventStatus() == null
647 || (event.getClosedLoopEventStatus() != ControlLoopEventStatus.ONSET
648 && event.getClosedLoopEventStatus() != ControlLoopEventStatus.ABATED)) {
649 throw new ControlLoopException("Invalid value in closedLoopEventStatus");
651 if (event.getClosedLoopControlName() == null || event.getClosedLoopControlName().length() < 1) {
652 throw new ControlLoopException("No control loop name");
654 if (event.getRequestId() == null) {
655 throw new ControlLoopException("No request ID");
657 if (event.getClosedLoopEventStatus() == ControlLoopEventStatus.ABATED) {
660 if (event.getTarget() == null || event.getTarget().length() < 1) {
661 throw new ControlLoopException("No target field");
662 } else if (!VM_NAME.equalsIgnoreCase(event.getTarget()) && !VNF_NAME.equalsIgnoreCase(event.getTarget())
663 && !VSERVER_VSERVER_NAME.equalsIgnoreCase(event.getTarget())
664 && !GENERIC_VNF_VNF_ID.equalsIgnoreCase(event.getTarget())
665 && !GENERIC_VNF_VNF_NAME.equalsIgnoreCase(event.getTarget())) {
666 throw new ControlLoopException("target field invalid - expecting VM_NAME or VNF_NAME");
668 if (event.getAai() == null) {
669 throw new ControlLoopException("AAI is null");
671 if (event.getAai().get(GENERIC_VNF_VNF_ID) == null && event.getAai().get(VSERVER_VSERVER_NAME) == null
672 && event.getAai().get(GENERIC_VNF_VNF_NAME) == null) {
673 throw new ControlLoopException(
674 "generic-vnf.vnf-id or generic-vnf.vnf-name or vserver.vserver-name information missing");
679 * Query A&AI for an event.
681 * @param event the event
682 * @throws AaiException if an error occurs retrieving information from A&AI
684 public void queryAai(VirtualControlLoopEvent event) throws AaiException {
686 Map<String, String> aai = event.getAai();
688 if (aai.containsKey(VSERVER_IS_CLOSED_LOOP_DISABLED) || aai.containsKey(GENERIC_VNF_IS_CLOSED_LOOP_DISABLED)) {
690 if (isClosedLoopDisabled(event)) {
691 throw new AaiException("is-closed-loop-disabled is set to true on VServer or VNF");
694 if (isProvStatusInactive(event)) {
695 throw new AaiException("prov-status is not ACTIVE on VServer or VNF");
698 // no need to query, as we already have the data
702 if (vnfResponse != null || vserverResponse != null) {
703 // query has already been performed
708 if (aai.containsKey(GENERIC_VNF_VNF_ID) || aai.containsKey(GENERIC_VNF_VNF_NAME)) {
709 vnfResponse = getAAIVnfInfo(event);
710 processVNFResponse(vnfResponse, aai.containsKey(GENERIC_VNF_VNF_ID));
711 } else if (aai.containsKey(VSERVER_VSERVER_NAME)) {
712 vserverResponse = getAAIVserverInfo(event);
713 processVServerResponse(vserverResponse);
715 } catch (AaiException e) {
716 logger.error(QUERY_AAI_ERROR_MSG, e);
718 } catch (Exception e) {
719 logger.error(QUERY_AAI_ERROR_MSG, e);
720 throw new AaiException(QUERY_AAI_ERROR_MSG + e.toString());
725 * Process a response from A&AI for a VNF.
727 * @param aaiResponse the response from A&AI
728 * @param queryByVnfId <code>true</code> if the query was based on vnf-id,
729 * <code>false</code> if the query was based on vnf-name
730 * @throws AaiException if an error occurs processing the response
732 private static void processVNFResponse(AaiGetVnfResponse aaiResponse, boolean queryByVNFID) throws AaiException {
733 String queryTypeString = (queryByVNFID ? "vnf-id" : "vnf-name");
735 if (aaiResponse == null) {
736 throw new AaiException("AAI Response is null (query by " + queryTypeString + ")");
738 if (aaiResponse.getRequestError() != null) {
739 throw new AaiException("AAI Responded with a request error (query by " + queryTypeString + ")");
742 if (aaiResponse.getIsClosedLoopDisabled()) {
743 throw new AaiException("is-closed-loop-disabled is set to true (query by " + queryTypeString + ")");
746 if (!PROV_STATUS_ACTIVE.equals(aaiResponse.getProvStatus())) {
747 throw new AaiException("prov-status is not ACTIVE (query by " + queryTypeString + ")");
752 * Process a response from A&AI for a VServer.
754 * @param aaiResponse the response from A&AI
755 * @throws AaiException if an error occurs processing the response
757 private static void processVServerResponse(AaiGetVserverResponse aaiResponse) throws AaiException {
758 if (aaiResponse == null) {
759 throw new AaiException("AAI Response is null (query by vserver-name)");
761 if (aaiResponse.getRequestError() != null) {
762 throw new AaiException("AAI Responded with a request error (query by vserver-name)");
765 List<AaiNqVServer> lst = aaiResponse.getVserver();
770 AaiNqVServer svr = lst.get(0);
771 if (svr.getIsClosedLoopDisabled()) {
772 throw new AaiException("is-closed-loop-disabled is set to true (query by vserver-name)");
775 if (!PROV_STATUS_ACTIVE.equals(svr.getProvStatus())) {
776 throw new AaiException("prov-status is not ACTIVE (query by vserver-name)");
781 * Is closed loop disabled for an event.
783 * @param event the event
784 * @return <code>true</code> if the control loop is disabled, <code>false</code>
787 public static boolean isClosedLoopDisabled(VirtualControlLoopEvent event) {
788 Map<String, String> aai = event.getAai();
789 return (isAaiTrue(aai.get(VSERVER_IS_CLOSED_LOOP_DISABLED))
790 || isAaiTrue(aai.get(GENERIC_VNF_IS_CLOSED_LOOP_DISABLED)));
794 * Does provisioning status, for an event, have a value other than ACTIVE.
796 * @param event the event
797 * @return {@code true} if the provisioning status is neither ACTIVE nor {@code null},
798 * {@code false} otherwise
800 protected static boolean isProvStatusInactive(VirtualControlLoopEvent event) {
801 Map<String, String> aai = event.getAai();
802 return (!PROV_STATUS_ACTIVE.equals(aai.getOrDefault(VSERVER_PROV_STATUS, PROV_STATUS_ACTIVE))
803 || !PROV_STATUS_ACTIVE.equals(aai.getOrDefault(GENERIC_VNF_PROV_STATUS, PROV_STATUS_ACTIVE)));
807 * Determines the boolean value represented by the given AAI field value.
809 * @param aaiValue value to be examined
810 * @return the boolean value represented by the field value, or {@code false} if the
811 * value is {@code null}
813 protected static boolean isAaiTrue(String aaiValue) {
814 return ("true".equalsIgnoreCase(aaiValue) || "T".equalsIgnoreCase(aaiValue) || "yes".equalsIgnoreCase(aaiValue)
815 || "Y".equalsIgnoreCase(aaiValue));
819 * Get the A&AI VService information for an event.
821 * @param event the event
822 * @return a AaiGetVserverResponse
823 * @throws ControlLoopException if an error occurs
825 public static AaiGetVserverResponse getAAIVserverInfo(VirtualControlLoopEvent event) throws ControlLoopException {
826 UUID requestId = event.getRequestId();
827 AaiGetVserverResponse response = null;
828 String vserverName = event.getAai().get(VSERVER_VSERVER_NAME);
831 if (vserverName != null) {
832 String aaiHostUrl = PolicyEngine.manager.getEnvironmentProperty("aai.url");
833 String aaiUser = PolicyEngine.manager.getEnvironmentProperty("aai.username");
834 String aaiPassword = PolicyEngine.manager.getEnvironmentProperty("aai.password");
835 String aaiGetQueryByVserver = "/aai/v11/nodes/vservers?vserver-name=";
836 String url = aaiHostUrl + aaiGetQueryByVserver;
837 logger.info("AAI Host URL by VServer: {}", url);
838 response = new AaiManager(new RESTManager()).getQueryByVserverName(url, aaiUser, aaiPassword, requestId,
841 } catch (Exception e) {
842 logger.error("getAAIVserverInfo exception: ", e);
843 throw new ControlLoopException("Exception in getAAIVserverInfo: ", e);
850 * Get A&AI VNF information for an event.
852 * @param event the event
853 * @return a AaiGetVnfResponse
854 * @throws ControlLoopException if an error occurs
856 public static AaiGetVnfResponse getAAIVnfInfo(VirtualControlLoopEvent event) throws ControlLoopException {
857 UUID requestId = event.getRequestId();
858 AaiGetVnfResponse response = null;
859 String vnfName = event.getAai().get(GENERIC_VNF_VNF_NAME);
860 String vnfId = event.getAai().get(GENERIC_VNF_VNF_ID);
862 String aaiHostUrl = PolicyEngine.manager.getEnvironmentProperty("aai.url");
863 String aaiUser = PolicyEngine.manager.getEnvironmentProperty("aai.username");
864 String aaiPassword = PolicyEngine.manager.getEnvironmentProperty("aai.password");
867 if (vnfName != null) {
868 String aaiGetQueryByVnfName = "/aai/v11/network/generic-vnfs/generic-vnf?vnf-name=";
869 String url = aaiHostUrl + aaiGetQueryByVnfName;
870 logger.info("AAI Host URL by VNF name: {}", url);
871 response = new AaiManager(new RESTManager()).getQueryByVnfName(url, aaiUser, aaiPassword, requestId,
873 } else if (vnfId != null) {
874 String aaiGetQueryByVnfId = "/aai/v11/network/generic-vnfs/generic-vnf/";
875 String url = aaiHostUrl + aaiGetQueryByVnfId;
876 logger.info("AAI Host URL by VNF ID: {}", url);
878 new AaiManager(new RESTManager()).getQueryByVnfId(url, aaiUser, aaiPassword, requestId, vnfId);
880 } catch (Exception e) {
881 logger.error("getAAIVnfInfo exception: ", e);
882 throw new ControlLoopException("Exception in getAAIVnfInfo: ", e);
889 * Gets the output from the AAI vserver named-query, using the cache, if appropriate.
890 * @return output from the AAI vserver named-query
892 public AaiNqResponseWrapper getNqVserverFromAai() {
893 if (nqVserverResponse != null) {
895 return nqVserverResponse;
898 String vserverName = onset.getAai().get(VSERVER_VSERVER_NAME);
899 if (vserverName == null) {
900 logger.warn("Missing vserver-name for AAI request {}", onset.getRequestId());
904 // create AAI named-query request with UUID started with ""
905 AaiNqRequest aaiNqRequest = new AaiNqRequest();
906 AaiNqQueryParameters aaiNqQueryParam = new AaiNqQueryParameters();
907 AaiNqNamedQuery aaiNqNamedQuery = new AaiNqNamedQuery();
908 final AaiNqInstanceFilters aaiNqInstanceFilter = new AaiNqInstanceFilters();
911 // TODO: UUID.fromString($params.getAaiNamedQueryUUID()) AaiNamedQueryUUID
912 aaiNqNamedQuery.setNamedQueryUuid(UUID.fromString("4ff56a54-9e3f-46b7-a337-07a1d3c6b469"));
913 aaiNqQueryParam.setNamedQuery(aaiNqNamedQuery);
914 aaiNqRequest.setQueryParameters(aaiNqQueryParam);
918 Map<String, Map<String, String>> aaiNqInstanceFilterMap = new HashMap<>();
919 Map<String, String> aaiNqInstanceFilterMapItem = new HashMap<>();
920 aaiNqInstanceFilterMapItem.put("vserver-name", vserverName);
921 aaiNqInstanceFilterMap.put("vserver", aaiNqInstanceFilterMapItem);
922 aaiNqInstanceFilter.getInstanceFilter().add(aaiNqInstanceFilterMap);
923 aaiNqRequest.setInstanceFilters(aaiNqInstanceFilter);
925 if (logger.isDebugEnabled()) {
926 logger.debug("AAI Request sent: {}", Serialization.gsonPretty.toJson(aaiNqRequest));
929 AaiNqResponse aaiNqResponse = new AaiManager(new RESTManager()).postQuery(getPeManagerEnvProperty("aai.url"),
930 getPeManagerEnvProperty("aai.username"), getPeManagerEnvProperty("aai.password"), aaiNqRequest,
931 onset.getRequestId());
933 // Check AAI response
934 if (aaiNqResponse == null) {
935 logger.warn("No response received from AAI for request {}", aaiNqRequest);
939 // Create AAINQResponseWrapper
940 nqVserverResponse = new AaiNqResponseWrapper(onset.getRequestId(), aaiNqResponse);
942 if (logger.isDebugEnabled()) {
943 logger.debug("AAI Named Query Response: ");
944 logger.debug(Serialization.gsonPretty.toJson(nqVserverResponse.getAaiNqResponse()));
947 return nqVserverResponse;
951 * This method reads and validates environmental properties coming from the policy engine. Null
952 * properties cause an {@link IllegalArgumentException} runtime exception to be thrown
954 * @param enginePropertyName the name of the parameter to retrieve
955 * @return the property value
957 private static String getPeManagerEnvProperty(String enginePropertyName) {
958 String enginePropertyValue = PolicyEngine.manager.getEnvironmentProperty(enginePropertyName);
959 if (enginePropertyValue == null) {
960 throw new IllegalArgumentException("The value of policy engine manager environment property \""
961 + enginePropertyName + "\" may not be null");
963 return enginePropertyValue;
967 public boolean isActive() {
973 public boolean releaseLock() {
979 public String toString() {
980 return "ControlLoopEventManager [closedLoopControlName=" + closedLoopControlName + ", requestID=" + requestID
981 + ", processor=" + processor + ", onset=" + (onset != null ? onset.getRequestId() : "null")
982 + ", numOnsets=" + numOnsets + ", numAbatements=" + numAbatements + ", isActivated=" + isActivated
983 + ", currentOperation=" + currentOperation + ", targetLock=" + targetLock + "]";