39a4886a237155a7c6d569915bb4a62d044bfa2b
[policy/drools-applications.git] /
1 /*-
2  * ============LICENSE_START=======================================================
3  * controlloop event manager
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
10  * 
11  *      http://www.apache.org/licenses/LICENSE-2.0
12  * 
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=========================================================
19  */
20
21 package org.onap.policy.controlloop.eventmanager;
22
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.LinkedList;
29 import java.util.UUID;
30
31 import org.onap.policy.aai.AaiGetVnfResponse;
32 import org.onap.policy.aai.AaiGetVserverResponse;
33 import org.onap.policy.aai.AaiManager;
34 import org.onap.policy.aai.util.AaiException;
35 import org.onap.policy.controlloop.ControlLoopEventStatus;
36 import org.onap.policy.controlloop.ControlLoopException;
37 import org.onap.policy.controlloop.ControlLoopNotificationType;
38 import org.onap.policy.controlloop.ControlLoopOperation;
39 import org.onap.policy.controlloop.VirtualControlLoopEvent;
40 import org.onap.policy.controlloop.VirtualControlLoopNotification;
41 import org.onap.policy.controlloop.policy.FinalResult;
42 import org.onap.policy.controlloop.policy.Policy;
43 import org.onap.policy.controlloop.processor.ControlLoopProcessor;
44 import org.onap.policy.drools.system.PolicyEngine;
45 import org.onap.policy.guard.GuardResult;
46 import org.onap.policy.guard.LockCallback;
47 import org.onap.policy.guard.PolicyGuard;
48 import org.onap.policy.guard.PolicyGuard.LockResult;
49 import org.onap.policy.guard.TargetLock;
50 import org.onap.policy.rest.RESTManager;
51 import org.slf4j.Logger;
52 import org.slf4j.LoggerFactory;
53
54 public class ControlLoopEventManager implements LockCallback, Serializable {
55     private static final String VM_NAME = "VM_NAME";
56     private static final String VNF_NAME = "VNF_NAME";
57     private static final String GENERIC_VNF_VNF_ID = "generic-vnf.vnf-id";
58     private static final String GENERIC_VNF_VNF_NAME = "generic-vnf.vnf-name";
59     private static final String VSERVER_VSERVER_NAME = "vserver.vserver-name";
60     private static final String GENERIC_VNF_IS_CLOSED_LOOP_DISABLED = "generic-vnf.is-closed-loop-disabled";
61     private static final String VSERVER_IS_CLOSED_LOOP_DISABLED = "vserver.is-closed-loop-disabled";
62
63     private static final Logger logger = LoggerFactory.getLogger(ControlLoopEventManager.class);
64
65     private static final long serialVersionUID = -1216568161322872641L;
66     public final String closedLoopControlName;
67     public final UUID requestID;
68
69     private String controlLoopResult;
70     private transient ControlLoopProcessor processor = null;
71     private VirtualControlLoopEvent onset;
72     private Integer numOnsets = 0;
73     private Integer numAbatements = 0;
74     private VirtualControlLoopEvent abatement;
75     private FinalResult controlLoopTimedOut = null;
76
77     private boolean isActivated = false;
78     private LinkedList<ControlLoopOperation> controlLoopHistory = new LinkedList<>();
79     private ControlLoopOperationManager currentOperation = null;
80     private transient TargetLock targetLock = null;
81     private AaiGetVnfResponse vnfResponse = null;
82     private AaiGetVserverResponse vserverResponse = null;
83     private static String aaiHostURL;
84     private static String aaiUser;
85     private static String aaiPassword;
86
87     private static Collection<String> requiredAAIKeys = new ArrayList<>();
88
89     static {
90         requiredAAIKeys.add("AICVServerSelfLink");
91         requiredAAIKeys.add("AICIdentity");
92         requiredAAIKeys.add("is_closed_loop_disabled");
93         requiredAAIKeys.add(VM_NAME);
94     }
95
96     public ControlLoopEventManager(String closedLoopControlName, UUID requestID) {
97         this.closedLoopControlName = closedLoopControlName;
98         this.requestID = requestID;
99     }
100
101     public String getControlLoopResult() {
102         return controlLoopResult;
103     }
104
105     public void setControlLoopResult(String controlLoopResult) {
106         this.controlLoopResult = controlLoopResult;
107     }
108
109     public Integer getNumOnsets() {
110         return numOnsets;
111     }
112
113     public void setNumOnsets(Integer numOnsets) {
114         this.numOnsets = numOnsets;
115     }
116
117     public Integer getNumAbatements() {
118         return numAbatements;
119     }
120
121     public void setNumAbatements(Integer numAbatements) {
122         this.numAbatements = numAbatements;
123     }
124
125     public boolean isActivated() {
126         return isActivated;
127     }
128
129     public void setActivated(boolean isActivated) {
130         this.isActivated = isActivated;
131     }
132
133     public VirtualControlLoopEvent getOnsetEvent() {
134         return this.onset;
135     }
136
137     public VirtualControlLoopEvent getAbatementEvent() {
138         return this.abatement;
139     }
140
141     public ControlLoopProcessor getProcessor() {
142         return this.processor;
143     }
144
145     /**
146      * Activate a control loop event.
147      * 
148      * @param event the event
149      * @return the VirtualControlLoopNotification
150      */
151     public VirtualControlLoopNotification activate(VirtualControlLoopEvent event) {
152         VirtualControlLoopNotification notification = new VirtualControlLoopNotification(event);
153         try {
154             //
155             // This method should ONLY be called ONCE
156             //
157             if (this.isActivated) {
158                 throw new ControlLoopException("ControlLoopEventManager has already been activated.");
159             }
160             //
161             // Syntax check the event
162             //
163             checkEventSyntax(event);
164
165             //
166             // At this point we are good to go with this event
167             //
168             this.onset = event;
169             this.numOnsets = 1;
170             //
171             notification.setNotification(ControlLoopNotificationType.ACTIVE);
172             //
173             // Set ourselves as active
174             //
175             this.isActivated = true;
176         } catch (ControlLoopException e) {
177             logger.error("{}: activate by event threw: ", this, e);
178             notification.setNotification(ControlLoopNotificationType.REJECTED);
179             notification.setMessage(e.getMessage());
180         }
181         return notification;
182     }
183
184     /**
185      * Activate a control loop event.
186      * 
187      * @param yamlSpecification the yaml specification
188      * @param event the event
189      * @return the VirtualControlLoopNotification
190      */
191     public VirtualControlLoopNotification activate(String yamlSpecification, VirtualControlLoopEvent event) {
192         VirtualControlLoopNotification notification = new VirtualControlLoopNotification(event);
193         try {
194             //
195             // This method should ONLY be called ONCE
196             //
197             if (this.isActivated) {
198                 throw new ControlLoopException("ControlLoopEventManager has already been activated.");
199             }
200             //
201             // Syntax check the event
202             //
203             checkEventSyntax(event);
204
205             //
206             // Check the YAML
207             //
208             if (yamlSpecification == null || yamlSpecification.length() < 1) {
209                 throw new ControlLoopException("yaml specification is null or 0 length");
210             }
211         } catch (ControlLoopException e) {
212             logger.error("{}: activate by YAML specification and event threw: ", this, e);
213             notification.setNotification(ControlLoopNotificationType.REJECTED);
214             notification.setMessage(e.getMessage());
215             return notification;
216         }
217
218         String decodedYaml = null;
219         try {
220             decodedYaml = URLDecoder.decode(yamlSpecification, "UTF-8");
221             if (decodedYaml != null && decodedYaml.length() > 0) {
222                 yamlSpecification = decodedYaml;
223             }
224         } catch (UnsupportedEncodingException e) {
225             logger.error("{}: YAML decode in activate by YAML specification and event threw: ", this, e);
226             notification.setNotification(ControlLoopNotificationType.REJECTED);
227             notification.setMessage(e.getMessage());
228             return notification;
229         }
230
231         try {
232             //
233             // Parse the YAML specification
234             //
235             this.processor = new ControlLoopProcessor(yamlSpecification);
236
237             //
238             // At this point we are good to go with this event
239             //
240             this.onset = event;
241             this.numOnsets = 1;
242             //
243             //
244             //
245             notification.setNotification(ControlLoopNotificationType.ACTIVE);
246             //
247             // Set ourselves as active
248             //
249             this.isActivated = true;
250         } catch (ControlLoopException e) {
251             logger.error("{}: activate by YAML specification and event threw: ", this, e);
252             notification.setNotification(ControlLoopNotificationType.REJECTED);
253             notification.setMessage(e.getMessage());
254         }
255         return notification;
256     }
257
258     /**
259      * Check if the control loop is final.
260      * 
261      * @return a VirtualControlLoopNotification if the control loop is final, otherwise
262      *         <code>null</code> is returned
263      * @throws ControlLoopException if an error occurs
264      */
265     public VirtualControlLoopNotification isControlLoopFinal() throws ControlLoopException {
266         //
267         // Check if they activated us
268         //
269         if (!this.isActivated) {
270             throw new ControlLoopException("ControlLoopEventManager MUST be activated first.");
271         }
272         //
273         // Make sure we are expecting this call.
274         //
275         if (this.onset == null) {
276             throw new ControlLoopException("No onset event for ControlLoopEventManager.");
277         }
278         //
279         // Ok, start creating the notification
280         //
281         VirtualControlLoopNotification notification = new VirtualControlLoopNotification(this.onset);
282         //
283         // Check if the overall control loop has timed out
284         //
285         if (this.isControlLoopTimedOut()) {
286             //
287             // Yes we have timed out
288             //
289             notification.setNotification(ControlLoopNotificationType.FINAL_FAILURE);
290             notification.setMessage("Control Loop timed out");
291             notification.getHistory().addAll(this.controlLoopHistory);
292             return notification;
293         }
294         //
295         // Check if the current policy is Final
296         //
297         FinalResult result = this.processor.checkIsCurrentPolicyFinal();
298         if (result == null) {
299             //
300             // we are not at a final result
301             //
302             return null;
303         }
304
305         switch (result) {
306             case FINAL_FAILURE_EXCEPTION:
307                 notification.setNotification(ControlLoopNotificationType.FINAL_FAILURE);
308                 notification.setMessage("Exception in processing closed loop");
309                 break;
310             case FINAL_FAILURE:
311             case FINAL_FAILURE_RETRIES:
312             case FINAL_FAILURE_TIMEOUT:
313             case FINAL_FAILURE_GUARD:
314                 notification.setNotification(ControlLoopNotificationType.FINAL_FAILURE);
315                 break;
316             case FINAL_OPENLOOP:
317                 notification.setNotification(ControlLoopNotificationType.FINAL_OPENLOOP);
318                 break;
319             case FINAL_SUCCESS:
320                 notification.setNotification(ControlLoopNotificationType.FINAL_SUCCESS);
321                 break;
322             default:
323                 return null;
324         }
325         //
326         // Be sure to add all the history
327         //
328         notification.getHistory().addAll(this.controlLoopHistory);
329         return notification;
330     }
331
332     /**
333      * Process the control loop.
334      * 
335      * @return a ControlLoopOperationManager
336      * @throws ControlLoopException if an error occurs
337      * @throws AaiException if an error occurs retrieving information from A&AI
338      */
339     public ControlLoopOperationManager processControlLoop() throws ControlLoopException, AaiException {
340         //
341         // Check if they activated us
342         //
343         if (!this.isActivated) {
344             throw new ControlLoopException("ControlLoopEventManager MUST be activated first.");
345         }
346         //
347         // Make sure we are expecting this call.
348         //
349         if (this.onset == null) {
350             throw new ControlLoopException("No onset event for ControlLoopEventManager.");
351         }
352         //
353         // Is there a current operation?
354         //
355         if (this.currentOperation != null) {
356             //
357             // Throw an exception, or simply return the current operation?
358             //
359             throw new ControlLoopException("Already working an Operation, do not call this method.");
360         }
361         //
362         // Ensure we are not FINAL
363         //
364         VirtualControlLoopNotification notification = this.isControlLoopFinal();
365         if (notification != null) {
366             //
367             // This is weird, we require them to call the isControlLoopFinal() method first
368             //
369             // We should really abstract this and avoid throwing an exception, because it really
370             // isn't an exception.
371             //
372             throw new ControlLoopException("Control Loop is in FINAL state, do not call this method.");
373         }
374         //
375         // Not final so get the policy that needs to be worked on.
376         //
377         Policy policy = this.processor.getCurrentPolicy();
378         if (policy == null) {
379             throw new ControlLoopException("ControlLoopEventManager: processor came upon null Policy.");
380         }
381         //
382         // And setup an operation
383         //
384         this.currentOperation = new ControlLoopOperationManager(this.onset, policy, this);
385         //
386         // Return it
387         //
388         return this.currentOperation;
389     }
390
391     /**
392      * Finish an operation.
393      * 
394      * @param operation the operation
395      */
396     public void finishOperation(ControlLoopOperationManager operation) throws ControlLoopException {
397         //
398         // Verify we have a current operation
399         //
400         if (this.currentOperation != null) {
401             //
402             // Validate they are finishing the current operation
403             // PLD - this is simply comparing the policy. Do we want to equals the whole object?
404             //
405             if (this.currentOperation.policy.equals(operation.policy)) {
406                 logger.debug("Finishing {} result is {}", this.currentOperation.policy.getRecipe(),
407                         this.currentOperation.getOperationResult());
408                 //
409                 // Save history
410                 //
411                 this.controlLoopHistory.addAll(this.currentOperation.getHistory());
412                 //
413                 // Move to the next Policy
414                 //
415                 this.processor.nextPolicyForResult(this.currentOperation.getOperationResult());
416                 //
417                 // Just null this out
418                 //
419                 this.currentOperation = null;
420                 //
421                 // TODO: Release our lock
422                 //
423                 return;
424             }
425             logger.debug("Cannot finish current operation {} does not match given operation {}",
426                     this.currentOperation.policy, operation.policy);
427             return;
428         }
429         throw new ControlLoopException("No operation to finish.");
430     }
431
432     /**
433      * Obtain a lock for the current operation.
434      * 
435      * @return the lock result
436      * @throws ControlLoopException if an error occurs
437      */
438     public synchronized LockResult<GuardResult, TargetLock> lockCurrentOperation() throws ControlLoopException {
439         //
440         // Sanity check
441         //
442         if (this.currentOperation == null) {
443             throw new ControlLoopException("Do not have a current operation.");
444         }
445         //
446         // Have we acquired it already?
447         //
448         if (this.targetLock != null) {
449             //
450             // TODO: Make sure the current lock is for the same target.
451             // Currently, it should be. But in the future it may not.
452             //
453             return new LockResult<>(GuardResult.LOCK_ACQUIRED, this.targetLock);
454         } else {
455             //
456             // Ask the Guard
457             //
458             LockResult<GuardResult, TargetLock> lockResult =
459                     PolicyGuard.lockTarget(this.currentOperation.policy.getTarget().getType(),
460                             this.currentOperation.getTargetEntity(), this.onset.getRequestID(), this);
461             //
462             // Was it acquired?
463             //
464             if (lockResult.getA().equals(GuardResult.LOCK_ACQUIRED)) {
465                 //
466                 // Yes, let's save it
467                 //
468                 this.targetLock = lockResult.getB();
469             }
470             return lockResult;
471         }
472     }
473
474     /**
475      * Release the lock for the current operation.
476      * 
477      * @return the target lock
478      */
479     public synchronized TargetLock unlockCurrentOperation() {
480         if (this.targetLock == null) {
481             return null;
482         }
483         if (PolicyGuard.unlockTarget(this.targetLock)) {
484             TargetLock returnLock = this.targetLock;
485             this.targetLock = null;
486             return returnLock;
487         }
488         return null;
489     }
490
491     public enum NEW_EVENT_STATUS {
492         FIRST_ONSET, SUBSEQUENT_ONSET, FIRST_ABATEMENT, SUBSEQUENT_ABATEMENT, SYNTAX_ERROR;
493     }
494
495     /**
496      * An event onset/abatement.
497      * 
498      * @param event the event
499      * @return the status
500      * @throws AaiException if an error occurs retrieving information from A&AI
501      */
502     public NEW_EVENT_STATUS onNewEvent(VirtualControlLoopEvent event) throws AaiException {
503         try {
504             this.checkEventSyntax(event);
505             if (event.getClosedLoopEventStatus() == ControlLoopEventStatus.ONSET) {
506                 //
507                 // Check if this is our original ONSET
508                 //
509                 if (event.equals(this.onset)) {
510                     //
511                     // Query A&AI if needed
512                     //
513                     queryAai(event);
514
515                     //
516                     // DO NOT retract it
517                     //
518                     return NEW_EVENT_STATUS.FIRST_ONSET;
519                 }
520                 //
521                 // Log that we got an onset
522                 //
523                 this.numOnsets++;
524                 return NEW_EVENT_STATUS.SUBSEQUENT_ONSET;
525             } else if (event.getClosedLoopEventStatus() == ControlLoopEventStatus.ABATED) {
526                 //
527                 // Have we already got an abatement?
528                 //
529                 if (this.abatement == null) {
530                     //
531                     // Save this
532                     //
533                     this.abatement = event;
534                     //
535                     // Keep track that we received another
536                     //
537                     this.numAbatements++;
538                     //
539                     //
540                     //
541                     return NEW_EVENT_STATUS.FIRST_ABATEMENT;
542                 } else {
543                     //
544                     // Keep track that we received another
545                     //
546                     this.numAbatements++;
547                     //
548                     //
549                     //
550                     return NEW_EVENT_STATUS.SUBSEQUENT_ABATEMENT;
551                 }
552             }
553         } catch (ControlLoopException e) {
554             logger.error("{}: onNewEvent threw: ", this, e);
555         }
556         return NEW_EVENT_STATUS.SYNTAX_ERROR;
557     }
558
559     /**
560      * Set the control loop time out.
561      * 
562      * @return a VirtualControlLoopNotification
563      */
564     public VirtualControlLoopNotification setControlLoopTimedOut() {
565         this.controlLoopTimedOut = FinalResult.FINAL_FAILURE_TIMEOUT;
566         VirtualControlLoopNotification notification = new VirtualControlLoopNotification(this.onset);
567         notification.setNotification(ControlLoopNotificationType.FINAL_FAILURE);
568         notification.setMessage("Control Loop timed out");
569         notification.getHistory().addAll(this.controlLoopHistory);
570         return notification;
571     }
572
573     public boolean isControlLoopTimedOut() {
574         return (this.controlLoopTimedOut == FinalResult.FINAL_FAILURE_TIMEOUT);
575     }
576
577     /**
578      * Get the control loop timeout.
579      * 
580      * @param defaultTimeout the default timeout
581      * @return the timeout
582      */
583     public int getControlLoopTimeout(Integer defaultTimeout) {
584         if (this.processor != null && this.processor.getControlLoop() != null) {
585             return this.processor.getControlLoop().getTimeout();
586         }
587         if (defaultTimeout != null) {
588             return defaultTimeout;
589         }
590         return 0;
591     }
592
593     public AaiGetVnfResponse getVnfResponse() {
594         return vnfResponse;
595     }
596
597     public AaiGetVserverResponse getVserverResponse() {
598         return vserverResponse;
599     }
600
601     /**
602      * Check an event syntax.
603      * 
604      * @param event the event syntax
605      * @throws ControlLoopException if an error occurs
606      */
607     public void checkEventSyntax(VirtualControlLoopEvent event) throws ControlLoopException {
608         if (event.getClosedLoopEventStatus() == null
609                 || (event.getClosedLoopEventStatus() != ControlLoopEventStatus.ONSET
610                         && event.getClosedLoopEventStatus() != ControlLoopEventStatus.ABATED)) {
611             throw new ControlLoopException("Invalid value in closedLoopEventStatus");
612         }
613         if (event.getClosedLoopControlName() == null || event.getClosedLoopControlName().length() < 1) {
614             throw new ControlLoopException("No control loop name");
615         }
616         if (event.getRequestID() == null) {
617             throw new ControlLoopException("No request ID");
618         }
619         if (event.getClosedLoopEventStatus() == ControlLoopEventStatus.ABATED) {
620             return;
621         }
622         if (event.getTarget() == null || event.getTarget().length() < 1) {
623             throw new ControlLoopException("No target field");
624         } else if (!VM_NAME.equalsIgnoreCase(event.getTarget()) && !VNF_NAME.equalsIgnoreCase(event.getTarget())
625                 && !VSERVER_VSERVER_NAME.equalsIgnoreCase(event.getTarget())
626                 && !GENERIC_VNF_VNF_ID.equalsIgnoreCase(event.getTarget())
627                 && !GENERIC_VNF_VNF_NAME.equalsIgnoreCase(event.getTarget())) {
628             throw new ControlLoopException("target field invalid - expecting VM_NAME or VNF_NAME");
629         }
630         if (event.getAAI() == null) {
631             throw new ControlLoopException("AAI is null");
632         }
633         if (event.getAAI().get(GENERIC_VNF_VNF_ID) == null && event.getAAI().get(VSERVER_VSERVER_NAME) == null
634                 && event.getAAI().get(GENERIC_VNF_VNF_NAME) == null) {
635             throw new ControlLoopException(
636                     "generic-vnf.vnf-id or generic-vnf.vnf-name or vserver.vserver-name information missing");
637         }
638     }
639
640     /**
641      * Query A&AI for an event.
642      * 
643      * @param event the event
644      * @throws AaiException if an error occurs retrieving information from A&AI
645      */
646     public void queryAai(VirtualControlLoopEvent event) throws AaiException {
647         if ((event.getAAI().get(VSERVER_IS_CLOSED_LOOP_DISABLED) != null
648                 || event.getAAI().get(GENERIC_VNF_IS_CLOSED_LOOP_DISABLED) != null) && isClosedLoopDisabled(event)) {
649             throw new AaiException("is-closed-loop-disabled is set to true on VServer or VNF");
650         }
651
652         try {
653             if (event.getAAI().get(GENERIC_VNF_VNF_ID) != null || event.getAAI().get(GENERIC_VNF_VNF_NAME) != null) {
654                 vnfResponse = getAAIVnfInfo(event);
655                 processVNFResponse(vnfResponse, event.getAAI().get(GENERIC_VNF_VNF_ID) != null);
656             } else if (event.getAAI().get(VSERVER_VSERVER_NAME) != null) {
657                 vserverResponse = getAAIVserverInfo(event);
658                 processVServerResponse(vserverResponse);
659             }
660         } catch (Exception e) {
661             logger.error("Exception from queryAai: ", e);
662             throw new AaiException("Exception from queryAai: " + e.toString());
663         }
664     }
665
666     /**
667      * Process a response from A&AI for a VNF.
668      * 
669      * @param aaiResponse the response from A&AI
670      * @param queryByVnfId <code>true</code> if the query was based on vnf-id, <code>false</code> if
671      *        the query was based on vnf-name
672      * @throws AaiException if an error occurs processing the response
673      */
674     private static void processVNFResponse(AaiGetVnfResponse aaiResponse, boolean queryByVNFID) throws AaiException {
675         String queryTypeString = (queryByVNFID ? "vnf-id" : "vnf-name");
676
677         if (aaiResponse == null) {
678             throw new AaiException("AAI Response is null (query by " + queryTypeString + ")");
679         }
680         if (aaiResponse.getRequestError() != null) {
681             throw new AaiException("AAI Responded with a request error (query by " + queryTypeString + ")");
682         }
683
684         if (aaiResponse.getIsClosedLoopDisabled() != null) {
685             String value = aaiResponse.getIsClosedLoopDisabled();
686             if ("true".equalsIgnoreCase(value) || "T".equalsIgnoreCase(value) || "yes".equalsIgnoreCase(value)
687                     || "Y".equalsIgnoreCase(value)) {
688                 throw new AaiException("is-closed-loop-disabled is set to true (query by " + queryTypeString + ")");
689             }
690         }
691     }
692
693     private static void processVServerResponse(AaiGetVserverResponse aaiResponse) throws AaiException {
694         if (aaiResponse == null) {
695             throw new AaiException("AAI Response is null (query by vserver-name)");
696         }
697         if (aaiResponse.getRequestError() != null) {
698             throw new AaiException("AAI responded with a request error (query by vserver-name)");
699         }
700
701         if (aaiResponse.getIsClosedLoopDisabled() != null) {
702             String value = aaiResponse.getIsClosedLoopDisabled();
703             if ("true".equalsIgnoreCase(value) || "T".equalsIgnoreCase(value) || "yes".equalsIgnoreCase(value)
704                     || "Y".equalsIgnoreCase(value)) {
705                 throw new AaiException("is-closed-loop-disabled is set to true (query by vserver-name)");
706             }
707         }
708     }
709
710     /**
711      * Is closed loop disabled for an event.
712      * 
713      * @param event the event
714      * @return <code>true</code> if the contol loop is disabled, <code>false</code> otherwise
715      */
716     public static boolean isClosedLoopDisabled(VirtualControlLoopEvent event) {
717         if ("true".equalsIgnoreCase(event.getAAI().get(VSERVER_IS_CLOSED_LOOP_DISABLED))
718                 || "T".equalsIgnoreCase(event.getAAI().get(VSERVER_IS_CLOSED_LOOP_DISABLED))
719                 || "yes".equalsIgnoreCase(event.getAAI().get(VSERVER_IS_CLOSED_LOOP_DISABLED))
720                 || "Y".equalsIgnoreCase(event.getAAI().get(VSERVER_IS_CLOSED_LOOP_DISABLED))) {
721             return true;
722         }
723         return ("true".equalsIgnoreCase(event.getAAI().get(GENERIC_VNF_IS_CLOSED_LOOP_DISABLED))
724                 || "T".equalsIgnoreCase(event.getAAI().get(GENERIC_VNF_IS_CLOSED_LOOP_DISABLED))
725                 || "yes".equalsIgnoreCase(event.getAAI().get(GENERIC_VNF_IS_CLOSED_LOOP_DISABLED))
726                 || "Y".equalsIgnoreCase(event.getAAI().get(GENERIC_VNF_IS_CLOSED_LOOP_DISABLED)));
727     }
728
729     /**
730      * Get the A&AI VService information for an event.
731      * 
732      * @param event the event
733      * @return a AaiGetVserverResponse
734      * @throws ControlLoopException if an error occurs
735      */
736     public static AaiGetVserverResponse getAAIVserverInfo(VirtualControlLoopEvent event) throws ControlLoopException {
737         UUID requestId = event.getRequestID();
738         AaiGetVserverResponse response = null;
739         String vserverName = event.getAAI().get(VSERVER_VSERVER_NAME);
740
741         try {
742             if (vserverName != null) {
743                 aaiHostURL = PolicyEngine.manager.getEnvironmentProperty("aai.url");
744                 aaiUser = PolicyEngine.manager.getEnvironmentProperty("aai.username");
745                 aaiPassword = PolicyEngine.manager.getEnvironmentProperty("aai.password");
746                 String aaiGetQueryByVserver = "/aai/v11/nodes/vservers?vserver-name=";
747                 String url = aaiHostURL + aaiGetQueryByVserver;
748                 logger.info("AAI Host URL by VServer: {}", url);
749                 response = new AaiManager(new RESTManager()).getQueryByVserverName(url, aaiUser, aaiPassword, requestId,
750                         vserverName);
751             }
752         } catch (Exception e) {
753             logger.error("getAAIVserverInfo exception: ", e);
754             throw new ControlLoopException("Exception in getAAIVserverInfo: ", e);
755         }
756
757         return response;
758     }
759
760     /**
761      * Get A&AI VNF information for an event.
762      * 
763      * @param event the event
764      * @return a AaiGetVnfResponse
765      * @throws ControlLoopException if an error occurs
766      */
767     public static AaiGetVnfResponse getAAIVnfInfo(VirtualControlLoopEvent event) throws ControlLoopException {
768         UUID requestId = event.getRequestID();
769         AaiGetVnfResponse response = null;
770         String vnfName = event.getAAI().get(GENERIC_VNF_VNF_NAME);
771         String vnfId = event.getAAI().get(GENERIC_VNF_VNF_ID);
772
773         aaiHostURL = PolicyEngine.manager.getEnvironmentProperty("aai.url");
774         aaiUser = PolicyEngine.manager.getEnvironmentProperty("aai.username");
775         aaiPassword = PolicyEngine.manager.getEnvironmentProperty("aai.password");
776
777         try {
778             if (vnfName != null) {
779                 String aaiGetQueryByVnfName = "/aai/v11/network/generic-vnfs/generic-vnf?vnf-name=";
780                 String url = aaiHostURL + aaiGetQueryByVnfName;
781                 logger.info("AAI Host URL by VNF name: {}", url);
782                 response = new AaiManager(new RESTManager()).getQueryByVnfName(url, aaiUser, aaiPassword, requestId,
783                         vnfName);
784             } else if (vnfId != null) {
785                 String aaiGetQueryByVnfId = "/aai/v11/network/generic-vnfs/generic-vnf/";
786                 String url = aaiHostURL + aaiGetQueryByVnfId;
787                 logger.info("AAI Host URL by VNF ID: {}", url);
788                 response =
789                         new AaiManager(new RESTManager()).getQueryByVnfId(url, aaiUser, aaiPassword, requestId, vnfId);
790             }
791         } catch (Exception e) {
792             logger.error("getAAIVnfInfo exception: ", e);
793             throw new ControlLoopException("Exception in getAAIVnfInfo: ", e);
794         }
795
796         return response;
797     }
798
799     @Override
800     public boolean isActive() {
801         // TODO
802         return true;
803     }
804
805     @Override
806     public boolean releaseLock() {
807         // TODO
808         return false;
809     }
810
811     @Override
812     public String toString() {
813         return "ControlLoopEventManager [closedLoopControlName=" + closedLoopControlName + ", requestID=" + requestID
814                 + ", processor=" + processor + ", onset=" + (onset != null ? onset.getRequestID() : "null")
815                 + ", numOnsets=" + numOnsets + ", numAbatements=" + numAbatements + ", isActivated=" + isActivated
816                 + ", currentOperation=" + currentOperation + ", targetLock=" + targetLock + "]";
817     }
818
819 }