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;
33 import java.util.NoSuchElementException;
35 import org.onap.policy.aai.AaiGetVnfResponse;
36 import org.onap.policy.aai.AaiGetVserverResponse;
37 import org.onap.policy.aai.AaiManager;
38 import org.onap.policy.aai.AaiNqInstanceFilters;
39 import org.onap.policy.aai.AaiNqNamedQuery;
40 import org.onap.policy.aai.AaiNqQueryParameters;
41 import org.onap.policy.aai.AaiNqRequest;
42 import org.onap.policy.aai.AaiNqResponse;
43 import org.onap.policy.aai.AaiNqResponseWrapper;
44 import org.onap.policy.aai.AaiNqVServer;
45 import org.onap.policy.aai.util.AaiException;
46 import org.onap.policy.controlloop.ControlLoopEventStatus;
47 import org.onap.policy.controlloop.ControlLoopException;
48 import org.onap.policy.controlloop.ControlLoopNotificationType;
49 import org.onap.policy.controlloop.ControlLoopOperation;
50 import org.onap.policy.controlloop.VirtualControlLoopEvent;
51 import org.onap.policy.controlloop.VirtualControlLoopNotification;
52 import org.onap.policy.controlloop.policy.FinalResult;
53 import org.onap.policy.controlloop.policy.Policy;
54 import org.onap.policy.controlloop.processor.ControlLoopProcessor;
55 import org.onap.policy.drools.system.PolicyEngine;
56 import org.onap.policy.guard.GuardResult;
57 import org.onap.policy.guard.LockCallback;
58 import org.onap.policy.guard.PolicyGuard;
59 import org.onap.policy.guard.PolicyGuard.LockResult;
60 import org.onap.policy.guard.TargetLock;
61 import org.onap.policy.rest.RESTManager;
62 import org.onap.policy.so.util.Serialization;
63 import org.slf4j.Logger;
64 import org.slf4j.LoggerFactory;
66 public class ControlLoopEventManager implements LockCallback, Serializable {
67 public static final String PROV_STATUS_ACTIVE = "ACTIVE";
68 private static final String VM_NAME = "VM_NAME";
69 private static final String VNF_NAME = "VNF_NAME";
70 public static final String GENERIC_VNF_VNF_ID = "generic-vnf.vnf-id";
71 public static final String GENERIC_VNF_VNF_NAME = "generic-vnf.vnf-name";
72 public static final String VSERVER_VSERVER_NAME = "vserver.vserver-name";
73 public static final String GENERIC_VNF_IS_CLOSED_LOOP_DISABLED = "generic-vnf.is-closed-loop-disabled";
74 public static final String VSERVER_IS_CLOSED_LOOP_DISABLED = "vserver.is-closed-loop-disabled";
75 public static final String GENERIC_VNF_PROV_STATUS = "generic-vnf.prov-status";
76 public static final String VSERVER_PROV_STATUS = "vserver.prov-status";
78 private static final String QUERY_AAI_ERROR_MSG = "Exception from queryAai: ";
81 * Additional time, in seconds, to add to a "lock" request. This ensures that the lock
82 * won't expire right before an operation completes.
84 private static final int ADDITIONAL_LOCK_SEC = 60;
86 private static final Logger logger = LoggerFactory.getLogger(ControlLoopEventManager.class);
88 private static final long serialVersionUID = -1216568161322872641L;
89 public final String closedLoopControlName;
90 public final UUID requestID;
92 private String controlLoopResult;
93 private ControlLoopProcessor processor = null;
94 private VirtualControlLoopEvent onset;
95 private Integer numOnsets = 0;
96 private Integer numAbatements = 0;
97 private VirtualControlLoopEvent abatement;
98 private FinalResult controlLoopTimedOut = null;
100 private boolean isActivated = false;
101 private LinkedList<ControlLoopOperation> controlLoopHistory = new LinkedList<>();
102 private ControlLoopOperationManager currentOperation = null;
103 private ControlLoopOperationManager lastOperationManager = null;
104 private TargetLock targetLock = null;
105 private AaiGetVnfResponse vnfResponse = null;
106 private AaiGetVserverResponse vserverResponse = null;
109 * Wrapper for AAI vserver named-query response. This is initialized in a lazy
112 private AaiNqResponseWrapper nqVserverResponse = null;
114 private static Collection<String> requiredAAIKeys = new ArrayList<>();
117 requiredAAIKeys.add("AICVServerSelfLink");
118 requiredAAIKeys.add("AICIdentity");
119 requiredAAIKeys.add("is_closed_loop_disabled");
120 requiredAAIKeys.add(VM_NAME);
123 public ControlLoopEventManager(String closedLoopControlName, UUID requestID) {
124 this.closedLoopControlName = closedLoopControlName;
125 this.requestID = requestID;
128 public String getClosedLoopControlName() {
129 return closedLoopControlName;
132 public String getControlLoopResult() {
133 return controlLoopResult;
136 public void setControlLoopResult(String controlLoopResult) {
137 this.controlLoopResult = controlLoopResult;
140 public Integer getNumOnsets() {
144 public void setNumOnsets(Integer numOnsets) {
145 this.numOnsets = numOnsets;
148 public Integer getNumAbatements() {
149 return numAbatements;
152 public void setNumAbatements(Integer numAbatements) {
153 this.numAbatements = numAbatements;
156 public boolean isActivated() {
160 public void setActivated(boolean isActivated) {
161 this.isActivated = isActivated;
164 public VirtualControlLoopEvent getOnsetEvent() {
168 public VirtualControlLoopEvent getAbatementEvent() {
169 return this.abatement;
172 public ControlLoopProcessor getProcessor() {
173 return this.processor;
176 public UUID getRequestID() {
181 * Activate a control loop event.
183 * @param event the event
184 * @return the VirtualControlLoopNotification
186 public VirtualControlLoopNotification activate(VirtualControlLoopEvent event) {
187 VirtualControlLoopNotification notification = new VirtualControlLoopNotification(event);
190 // This method should ONLY be called ONCE
192 if (this.isActivated) {
193 throw new ControlLoopException("ControlLoopEventManager has already been activated.");
196 // Syntax check the event
198 checkEventSyntax(event);
201 // At this point we are good to go with this event
206 notification.setNotification(ControlLoopNotificationType.ACTIVE);
208 // Set ourselves as active
210 this.isActivated = true;
211 } catch (ControlLoopException e) {
212 logger.error("{}: activate by event threw: ", this, e);
213 notification.setNotification(ControlLoopNotificationType.REJECTED);
214 notification.setMessage(e.getMessage());
220 * Activate a control loop event.
222 * @param yamlSpecification the yaml specification
223 * @param event the event
224 * @return the VirtualControlLoopNotification
226 public VirtualControlLoopNotification activate(String yamlSpecification, VirtualControlLoopEvent event) {
227 VirtualControlLoopNotification notification = new VirtualControlLoopNotification(event);
230 // This method should ONLY be called ONCE
232 if (this.isActivated) {
233 throw new ControlLoopException("ControlLoopEventManager has already been activated.");
236 // Syntax check the event
238 checkEventSyntax(event);
243 if (yamlSpecification == null || yamlSpecification.length() < 1) {
244 throw new ControlLoopException("yaml specification is null or 0 length");
246 } catch (ControlLoopException e) {
247 logger.error("{}: activate by YAML specification and event threw: ", this, e);
248 notification.setNotification(ControlLoopNotificationType.REJECTED);
249 notification.setMessage(e.getMessage());
253 String decodedYaml = null;
255 decodedYaml = URLDecoder.decode(yamlSpecification, "UTF-8");
256 if (decodedYaml != null && decodedYaml.length() > 0) {
257 yamlSpecification = decodedYaml;
259 } catch (UnsupportedEncodingException e) {
260 logger.error("{}: YAML decode in activate by YAML specification and event threw: ", this, e);
261 notification.setNotification(ControlLoopNotificationType.REJECTED);
262 notification.setMessage(e.getMessage());
268 // Parse the YAML specification
270 this.processor = new ControlLoopProcessor(yamlSpecification);
273 // At this point we are good to go with this event
280 notification.setNotification(ControlLoopNotificationType.ACTIVE);
282 // Set ourselves as active
284 this.isActivated = true;
285 } catch (ControlLoopException e) {
286 logger.error("{}: activate by YAML specification and event threw: ", this, e);
287 notification.setNotification(ControlLoopNotificationType.REJECTED);
288 notification.setMessage(e.getMessage());
294 * Check if the control loop is final.
296 * @return a VirtualControlLoopNotification if the control loop is final, otherwise
297 * <code>null</code> is returned
298 * @throws ControlLoopException if an error occurs
300 public VirtualControlLoopNotification isControlLoopFinal() throws ControlLoopException {
302 // Check if they activated us
304 if (!this.isActivated) {
305 throw new ControlLoopException("ControlLoopEventManager MUST be activated first.");
308 // Make sure we are expecting this call.
310 if (this.onset == null) {
311 throw new ControlLoopException("No onset event for ControlLoopEventManager.");
314 // Ok, start creating the notification
316 VirtualControlLoopNotification notification = new VirtualControlLoopNotification(this.onset);
318 // Check if the overall control loop has timed out
320 if (this.isControlLoopTimedOut()) {
322 // Yes we have timed out
324 notification.setNotification(ControlLoopNotificationType.FINAL_FAILURE);
325 notification.setMessage("Control Loop timed out");
326 notification.getHistory().addAll(this.controlLoopHistory);
330 // Check if the current policy is Final
332 FinalResult result = this.processor.checkIsCurrentPolicyFinal();
333 if (result == null) {
335 // we are not at a final result
341 case FINAL_FAILURE_EXCEPTION:
342 notification.setNotification(ControlLoopNotificationType.FINAL_FAILURE);
343 notification.setMessage("Exception in processing closed loop");
346 case FINAL_FAILURE_RETRIES:
347 case FINAL_FAILURE_TIMEOUT:
348 case FINAL_FAILURE_GUARD:
349 notification.setNotification(ControlLoopNotificationType.FINAL_FAILURE);
352 notification.setNotification(ControlLoopNotificationType.FINAL_OPENLOOP);
355 notification.setNotification(ControlLoopNotificationType.FINAL_SUCCESS);
361 // Be sure to add all the history
363 notification.getHistory().addAll(this.controlLoopHistory);
368 * Process the control loop.
370 * @return a ControlLoopOperationManager
371 * @throws ControlLoopException if an error occurs
372 * @throws AaiException if an error occurs retrieving information from A&AI
374 public ControlLoopOperationManager processControlLoop() throws ControlLoopException, AaiException {
376 // Check if they activated us
378 if (!this.isActivated) {
379 throw new ControlLoopException("ControlLoopEventManager MUST be activated first.");
382 // Make sure we are expecting this call.
384 if (this.onset == null) {
385 throw new ControlLoopException("No onset event for ControlLoopEventManager.");
388 // Is there a current operation?
390 if (this.currentOperation != null) {
392 // Throw an exception, or simply return the current operation?
394 throw new ControlLoopException("Already working an Operation, do not call this method.");
397 // Ensure we are not FINAL
399 VirtualControlLoopNotification notification = this.isControlLoopFinal();
400 if (notification != null) {
402 // This is weird, we require them to call the isControlLoopFinal() method first
404 // We should really abstract this and avoid throwing an exception, because it really
405 // isn't an exception.
407 throw new ControlLoopException("Control Loop is in FINAL state, do not call this method.");
410 // Not final so get the policy that needs to be worked on.
412 Policy policy = this.processor.getCurrentPolicy();
413 if (policy == null) {
414 throw new ControlLoopException("ControlLoopEventManager: processor came upon null Policy.");
417 // And setup an operation
419 this.lastOperationManager = this.currentOperation;
420 this.currentOperation = new ControlLoopOperationManager(this.onset, policy, this);
424 return this.currentOperation;
428 * Finish an operation.
430 * @param operation the operation
432 public void finishOperation(ControlLoopOperationManager operation) throws ControlLoopException {
434 // Verify we have a current operation
436 if (this.currentOperation != null) {
438 // Validate they are finishing the current operation
439 // PLD - this is simply comparing the policy. Do we want to equals the whole object?
441 if (this.currentOperation.policy.equals(operation.policy)) {
442 logger.debug("Finishing {} result is {}", this.currentOperation.policy.getRecipe(),
443 this.currentOperation.getOperationResult());
447 this.controlLoopHistory.addAll(this.currentOperation.getHistory());
449 // Move to the next Policy
451 this.processor.nextPolicyForResult(this.currentOperation.getOperationResult());
453 // Just null this out
455 this.lastOperationManager = this.currentOperation;
456 this.currentOperation = null;
458 // TODO: Release our lock
462 logger.debug("Cannot finish current operation {} does not match given operation {}",
463 this.currentOperation.policy, operation.policy);
466 throw new ControlLoopException("No operation to finish.");
470 * Obtain a lock for the current operation.
472 * @return the lock result
473 * @throws ControlLoopException if an error occurs
475 public synchronized LockResult<GuardResult, TargetLock> lockCurrentOperation() throws ControlLoopException {
479 if (this.currentOperation == null) {
480 throw new ControlLoopException("Do not have a current operation.");
483 // Have we acquired it already?
485 if (this.targetLock != null) {
487 // TODO: Make sure the current lock is for the same target.
488 // Currently, it should be. But in the future it may not.
490 GuardResult result = PolicyGuard.lockTarget(targetLock,
491 this.currentOperation.getOperationTimeout() + ADDITIONAL_LOCK_SEC);
492 return new LockResult<>(result, this.targetLock);
497 LockResult<GuardResult, TargetLock> lockResult =
498 PolicyGuard.lockTarget(this.currentOperation.policy.getTarget().getType(),
499 this.currentOperation.getTargetEntity(), this.onset.getRequestId(), this,
500 this.currentOperation.getOperationTimeout() + ADDITIONAL_LOCK_SEC);
504 if (lockResult.getA().equals(GuardResult.LOCK_ACQUIRED)) {
506 // Yes, let's save it
508 this.targetLock = lockResult.getB();
515 * Release the lock for the current operation.
517 * @return the target lock
519 public synchronized TargetLock unlockCurrentOperation() {
520 if (this.targetLock == null) {
524 TargetLock returnLock = this.targetLock;
525 this.targetLock = null;
527 PolicyGuard.unlockTarget(returnLock);
529 // always return the old target lock so rules can retract it
533 public enum NEW_EVENT_STATUS {
534 FIRST_ONSET, SUBSEQUENT_ONSET, FIRST_ABATEMENT, SUBSEQUENT_ABATEMENT, SYNTAX_ERROR;
538 * An event onset/abatement.
540 * @param event the event
542 * @throws AaiException if an error occurs retrieving information from A&AI
544 public NEW_EVENT_STATUS onNewEvent(VirtualControlLoopEvent event) throws AaiException {
546 this.checkEventSyntax(event);
547 if (event.getClosedLoopEventStatus() == ControlLoopEventStatus.ONSET) {
549 // Check if this is our original ONSET
551 if (event.equals(this.onset)) {
553 // Query A&AI if needed
560 return NEW_EVENT_STATUS.FIRST_ONSET;
563 // Log that we got an onset
566 return NEW_EVENT_STATUS.SUBSEQUENT_ONSET;
567 } else if (event.getClosedLoopEventStatus() == ControlLoopEventStatus.ABATED) {
569 // Have we already got an abatement?
571 if (this.abatement == null) {
575 this.abatement = event;
577 // Keep track that we received another
579 this.numAbatements++;
583 return NEW_EVENT_STATUS.FIRST_ABATEMENT;
586 // Keep track that we received another
588 this.numAbatements++;
592 return NEW_EVENT_STATUS.SUBSEQUENT_ABATEMENT;
595 } catch (ControlLoopException e) {
596 logger.error("{}: onNewEvent threw: ", this, e);
598 return NEW_EVENT_STATUS.SYNTAX_ERROR;
603 * Commit the abatement to the history database.
605 * @param message the abatement message
606 * @param outcome the abatement outcome
608 public void commitAbatement(String message, String outcome) {
609 if (this.lastOperationManager == null) {
610 logger.error("{}: commitAbatement: no operation manager", this);
614 this.lastOperationManager.commitAbatement(message,outcome);
615 } catch (NoSuchElementException e) {
616 logger.error("{}: commitAbatement threw an exception ", this, e);
622 * Set the control loop time out.
624 * @return a VirtualControlLoopNotification
626 public VirtualControlLoopNotification setControlLoopTimedOut() {
627 this.controlLoopTimedOut = FinalResult.FINAL_FAILURE_TIMEOUT;
628 VirtualControlLoopNotification notification = new VirtualControlLoopNotification(this.onset);
629 notification.setNotification(ControlLoopNotificationType.FINAL_FAILURE);
630 notification.setMessage("Control Loop timed out");
631 notification.getHistory().addAll(this.controlLoopHistory);
635 public boolean isControlLoopTimedOut() {
636 return (this.controlLoopTimedOut == FinalResult.FINAL_FAILURE_TIMEOUT);
640 * Get the control loop timeout.
642 * @param defaultTimeout the default timeout
643 * @return the timeout
645 public int getControlLoopTimeout(Integer defaultTimeout) {
646 if (this.processor != null && this.processor.getControlLoop() != null) {
647 return this.processor.getControlLoop().getTimeout();
649 if (defaultTimeout != null) {
650 return defaultTimeout;
655 public AaiGetVnfResponse getVnfResponse() {
659 public AaiGetVserverResponse getVserverResponse() {
660 return vserverResponse;
664 * Check an event syntax.
666 * @param event the event syntax
667 * @throws ControlLoopException if an error occurs
669 public void checkEventSyntax(VirtualControlLoopEvent event) throws ControlLoopException {
670 if (event.getClosedLoopEventStatus() == null
671 || (event.getClosedLoopEventStatus() != ControlLoopEventStatus.ONSET
672 && event.getClosedLoopEventStatus() != ControlLoopEventStatus.ABATED)) {
673 throw new ControlLoopException("Invalid value in closedLoopEventStatus");
675 if (event.getClosedLoopControlName() == null || event.getClosedLoopControlName().length() < 1) {
676 throw new ControlLoopException("No control loop name");
678 if (event.getRequestId() == null) {
679 throw new ControlLoopException("No request ID");
681 if (event.getClosedLoopEventStatus() == ControlLoopEventStatus.ABATED) {
684 if (event.getTarget() == null || event.getTarget().length() < 1) {
685 throw new ControlLoopException("No target field");
686 } else if (!VM_NAME.equalsIgnoreCase(event.getTarget()) && !VNF_NAME.equalsIgnoreCase(event.getTarget())
687 && !VSERVER_VSERVER_NAME.equalsIgnoreCase(event.getTarget())
688 && !GENERIC_VNF_VNF_ID.equalsIgnoreCase(event.getTarget())
689 && !GENERIC_VNF_VNF_NAME.equalsIgnoreCase(event.getTarget())) {
690 throw new ControlLoopException("target field invalid - expecting VM_NAME or VNF_NAME");
692 if (event.getAai() == null) {
693 throw new ControlLoopException("AAI is null");
695 if (event.getAai().get(GENERIC_VNF_VNF_ID) == null && event.getAai().get(VSERVER_VSERVER_NAME) == null
696 && event.getAai().get(GENERIC_VNF_VNF_NAME) == null) {
697 throw new ControlLoopException(
698 "generic-vnf.vnf-id or generic-vnf.vnf-name or vserver.vserver-name information missing");
703 * Query A&AI for an event.
705 * @param event the event
706 * @throws AaiException if an error occurs retrieving information from A&AI
708 public void queryAai(VirtualControlLoopEvent event) throws AaiException {
710 Map<String, String> aai = event.getAai();
712 if (aai.containsKey(VSERVER_IS_CLOSED_LOOP_DISABLED) || aai.containsKey(GENERIC_VNF_IS_CLOSED_LOOP_DISABLED)) {
714 if (isClosedLoopDisabled(event)) {
715 throw new AaiException("is-closed-loop-disabled is set to true on VServer or VNF");
718 if (isProvStatusInactive(event)) {
719 throw new AaiException("prov-status is not ACTIVE on VServer or VNF");
722 // no need to query, as we already have the data
726 if (vnfResponse != null || vserverResponse != null) {
727 // query has already been performed
732 if (aai.containsKey(GENERIC_VNF_VNF_ID) || aai.containsKey(GENERIC_VNF_VNF_NAME)) {
733 vnfResponse = getAAIVnfInfo(event);
734 processVNFResponse(vnfResponse, aai.containsKey(GENERIC_VNF_VNF_ID));
735 } else if (aai.containsKey(VSERVER_VSERVER_NAME)) {
736 vserverResponse = getAAIVserverInfo(event);
737 processVServerResponse(vserverResponse);
739 } catch (AaiException e) {
740 logger.error(QUERY_AAI_ERROR_MSG, e);
742 } catch (Exception e) {
743 logger.error(QUERY_AAI_ERROR_MSG, e);
744 throw new AaiException(QUERY_AAI_ERROR_MSG + e.toString());
749 * Process a response from A&AI for a VNF.
751 * @param aaiResponse the response from A&AI
752 * @param queryByVnfId <code>true</code> if the query was based on vnf-id,
753 * <code>false</code> if the query was based on vnf-name
754 * @throws AaiException if an error occurs processing the response
756 private static void processVNFResponse(AaiGetVnfResponse aaiResponse, boolean queryByVNFID) throws AaiException {
757 String queryTypeString = (queryByVNFID ? "vnf-id" : "vnf-name");
759 if (aaiResponse == null) {
760 throw new AaiException("AAI Response is null (query by " + queryTypeString + ")");
762 if (aaiResponse.getRequestError() != null) {
763 throw new AaiException("AAI Responded with a request error (query by " + queryTypeString + ")");
766 if (aaiResponse.getIsClosedLoopDisabled()) {
767 throw new AaiException("is-closed-loop-disabled is set to true (query by " + queryTypeString + ")");
770 if (!PROV_STATUS_ACTIVE.equals(aaiResponse.getProvStatus())) {
771 throw new AaiException("prov-status is not ACTIVE (query by " + queryTypeString + ")");
776 * Process a response from A&AI for a VServer.
778 * @param aaiResponse the response from A&AI
779 * @throws AaiException if an error occurs processing the response
781 private static void processVServerResponse(AaiGetVserverResponse aaiResponse) throws AaiException {
782 if (aaiResponse == null) {
783 throw new AaiException("AAI Response is null (query by vserver-name)");
785 if (aaiResponse.getRequestError() != null) {
786 throw new AaiException("AAI Responded with a request error (query by vserver-name)");
789 List<AaiNqVServer> lst = aaiResponse.getVserver();
794 AaiNqVServer svr = lst.get(0);
795 if (svr.getIsClosedLoopDisabled()) {
796 throw new AaiException("is-closed-loop-disabled is set to true (query by vserver-name)");
799 if (!PROV_STATUS_ACTIVE.equals(svr.getProvStatus())) {
800 throw new AaiException("prov-status is not ACTIVE (query by vserver-name)");
805 * Is closed loop disabled for an event.
807 * @param event the event
808 * @return <code>true</code> if the control loop is disabled, <code>false</code>
811 public static boolean isClosedLoopDisabled(VirtualControlLoopEvent event) {
812 Map<String, String> aai = event.getAai();
813 return (isAaiTrue(aai.get(VSERVER_IS_CLOSED_LOOP_DISABLED))
814 || isAaiTrue(aai.get(GENERIC_VNF_IS_CLOSED_LOOP_DISABLED)));
818 * Does provisioning status, for an event, have a value other than ACTIVE.
820 * @param event the event
821 * @return {@code true} if the provisioning status is neither ACTIVE nor {@code null},
822 * {@code false} otherwise
824 protected static boolean isProvStatusInactive(VirtualControlLoopEvent event) {
825 Map<String, String> aai = event.getAai();
826 return (!PROV_STATUS_ACTIVE.equals(aai.getOrDefault(VSERVER_PROV_STATUS, PROV_STATUS_ACTIVE))
827 || !PROV_STATUS_ACTIVE.equals(aai.getOrDefault(GENERIC_VNF_PROV_STATUS, PROV_STATUS_ACTIVE)));
831 * Determines the boolean value represented by the given AAI field value.
833 * @param aaiValue value to be examined
834 * @return the boolean value represented by the field value, or {@code false} if the
835 * value is {@code null}
837 protected static boolean isAaiTrue(String aaiValue) {
838 return ("true".equalsIgnoreCase(aaiValue) || "T".equalsIgnoreCase(aaiValue) || "yes".equalsIgnoreCase(aaiValue)
839 || "Y".equalsIgnoreCase(aaiValue));
843 * Get the A&AI VService information for an event.
845 * @param event the event
846 * @return a AaiGetVserverResponse
847 * @throws ControlLoopException if an error occurs
849 public static AaiGetVserverResponse getAAIVserverInfo(VirtualControlLoopEvent event) throws ControlLoopException {
850 UUID requestId = event.getRequestId();
851 AaiGetVserverResponse response = null;
852 String vserverName = event.getAai().get(VSERVER_VSERVER_NAME);
855 if (vserverName != null) {
856 String aaiHostUrl = PolicyEngine.manager.getEnvironmentProperty("aai.url");
857 String aaiUser = PolicyEngine.manager.getEnvironmentProperty("aai.username");
858 String aaiPassword = PolicyEngine.manager.getEnvironmentProperty("aai.password");
859 String aaiGetQueryByVserver = "/aai/v11/nodes/vservers?vserver-name=";
860 String url = aaiHostUrl + aaiGetQueryByVserver;
861 logger.info("AAI Host URL by VServer: {}", url);
862 response = new AaiManager(new RESTManager()).getQueryByVserverName(url, aaiUser, aaiPassword, requestId,
865 } catch (Exception e) {
866 logger.error("getAAIVserverInfo exception: ", e);
867 throw new ControlLoopException("Exception in getAAIVserverInfo: ", e);
874 * Get A&AI VNF information for an event.
876 * @param event the event
877 * @return a AaiGetVnfResponse
878 * @throws ControlLoopException if an error occurs
880 public static AaiGetVnfResponse getAAIVnfInfo(VirtualControlLoopEvent event) throws ControlLoopException {
881 UUID requestId = event.getRequestId();
882 AaiGetVnfResponse response = null;
883 String vnfName = event.getAai().get(GENERIC_VNF_VNF_NAME);
884 String vnfId = event.getAai().get(GENERIC_VNF_VNF_ID);
886 String aaiHostUrl = PolicyEngine.manager.getEnvironmentProperty("aai.url");
887 String aaiUser = PolicyEngine.manager.getEnvironmentProperty("aai.username");
888 String aaiPassword = PolicyEngine.manager.getEnvironmentProperty("aai.password");
891 if (vnfName != null) {
892 String aaiGetQueryByVnfName = "/aai/v11/network/generic-vnfs/generic-vnf?vnf-name=";
893 String url = aaiHostUrl + aaiGetQueryByVnfName;
894 logger.info("AAI Host URL by VNF name: {}", url);
895 response = new AaiManager(new RESTManager()).getQueryByVnfName(url, aaiUser, aaiPassword, requestId,
897 } else if (vnfId != null) {
898 String aaiGetQueryByVnfId = "/aai/v11/network/generic-vnfs/generic-vnf/";
899 String url = aaiHostUrl + aaiGetQueryByVnfId;
900 logger.info("AAI Host URL by VNF ID: {}", url);
902 new AaiManager(new RESTManager()).getQueryByVnfId(url, aaiUser, aaiPassword, requestId, vnfId);
904 } catch (Exception e) {
905 logger.error("getAAIVnfInfo exception: ", e);
906 throw new ControlLoopException("Exception in getAAIVnfInfo: ", e);
913 * Gets the output from the AAI vserver named-query, using the cache, if appropriate.
914 * @return output from the AAI vserver named-query
916 public AaiNqResponseWrapper getNqVserverFromAai() {
917 if (nqVserverResponse != null) {
919 return nqVserverResponse;
922 String vserverName = onset.getAai().get(VSERVER_VSERVER_NAME);
923 if (vserverName == null) {
924 logger.warn("Missing vserver-name for AAI request {}", onset.getRequestId());
928 // create AAI named-query request with UUID started with ""
929 AaiNqRequest aaiNqRequest = new AaiNqRequest();
930 AaiNqQueryParameters aaiNqQueryParam = new AaiNqQueryParameters();
931 AaiNqNamedQuery aaiNqNamedQuery = new AaiNqNamedQuery();
932 final AaiNqInstanceFilters aaiNqInstanceFilter = new AaiNqInstanceFilters();
935 // TODO: UUID.fromString($params.getAaiNamedQueryUUID()) AaiNamedQueryUUID
936 aaiNqNamedQuery.setNamedQueryUuid(UUID.fromString("4ff56a54-9e3f-46b7-a337-07a1d3c6b469"));
937 aaiNqQueryParam.setNamedQuery(aaiNqNamedQuery);
938 aaiNqRequest.setQueryParameters(aaiNqQueryParam);
942 Map<String, Map<String, String>> aaiNqInstanceFilterMap = new HashMap<>();
943 Map<String, String> aaiNqInstanceFilterMapItem = new HashMap<>();
944 aaiNqInstanceFilterMapItem.put("vserver-name", vserverName);
945 aaiNqInstanceFilterMap.put("vserver", aaiNqInstanceFilterMapItem);
946 aaiNqInstanceFilter.getInstanceFilter().add(aaiNqInstanceFilterMap);
947 aaiNqRequest.setInstanceFilters(aaiNqInstanceFilter);
949 if (logger.isDebugEnabled()) {
950 logger.debug("AAI Request sent: {}", Serialization.gsonPretty.toJson(aaiNqRequest));
953 AaiNqResponse aaiNqResponse = new AaiManager(new RESTManager()).postQuery(getPeManagerEnvProperty("aai.url"),
954 getPeManagerEnvProperty("aai.username"), getPeManagerEnvProperty("aai.password"), aaiNqRequest,
955 onset.getRequestId());
957 // Check AAI response
958 if (aaiNqResponse == null) {
959 logger.warn("No response received from AAI for request {}", aaiNqRequest);
963 // Create AAINQResponseWrapper
964 nqVserverResponse = new AaiNqResponseWrapper(onset.getRequestId(), aaiNqResponse);
966 if (logger.isDebugEnabled()) {
967 logger.debug("AAI Named Query Response: ");
968 logger.debug(Serialization.gsonPretty.toJson(nqVserverResponse.getAaiNqResponse()));
971 return nqVserverResponse;
975 * This method reads and validates environmental properties coming from the policy engine. Null
976 * properties cause an {@link IllegalArgumentException} runtime exception to be thrown
978 * @param enginePropertyName the name of the parameter to retrieve
979 * @return the property value
981 private static String getPeManagerEnvProperty(String enginePropertyName) {
982 String enginePropertyValue = PolicyEngine.manager.getEnvironmentProperty(enginePropertyName);
983 if (enginePropertyValue == null) {
984 throw new IllegalArgumentException("The value of policy engine manager environment property \""
985 + enginePropertyName + "\" may not be null");
987 return enginePropertyValue;
991 public boolean isActive() {
997 public boolean releaseLock() {
1003 public String toString() {
1004 return "ControlLoopEventManager [closedLoopControlName=" + closedLoopControlName + ", requestID=" + requestID
1005 + ", processor=" + processor + ", onset=" + (onset != null ? onset.getRequestId() : "null")
1006 + ", numOnsets=" + numOnsets + ", numAbatements=" + numAbatements + ", isActivated=" + isActivated
1007 + ", currentOperation=" + currentOperation + ", targetLock=" + targetLock + "]";