0b20104f41728582a9e5fab7c43b7b38e0cb0c60
[appc.git] / appc-oam / appc-oam-bundle / src / main / java / org / openecomp / appc / oam / util / OperationHelper.java
1 /*-
2  * ============LICENSE_START=======================================================
3  * ONAP : APPC
4  * ================================================================================
5  * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
6  * ================================================================================
7  * Copyright (C) 2017 Amdocs
8  * =============================================================================
9  * Licensed under the Apache License, Version 2.0 (the "License");
10  * you may not use this file except in compliance with the License.
11  * You may obtain a copy of the License at
12  * 
13  *      http://www.apache.org/licenses/LICENSE-2.0
14  * 
15  * Unless required by applicable law or agreed to in writing, software
16  * distributed under the License is distributed on an "AS IS" BASIS,
17  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18  * See the License for the specific language governing permissions and
19  * limitations under the License.
20  * 
21  * ECOMP is a trademark and service mark of AT&T Intellectual Property.
22  * ============LICENSE_END=========================================================
23  */
24
25 package org.openecomp.appc.oam.util;
26
27 import com.att.eelf.configuration.EELFLogger;
28 import com.att.eelf.configuration.EELFManager;
29 import org.opendaylight.yang.gen.v1.org.openecomp.appc.oam.rev170303.MaintenanceModeInput;
30 import org.opendaylight.yang.gen.v1.org.openecomp.appc.oam.rev170303.RestartInput;
31 import org.opendaylight.yang.gen.v1.org.openecomp.appc.oam.rev170303.StartInput;
32 import org.opendaylight.yang.gen.v1.org.openecomp.appc.oam.rev170303.StopInput;
33 import org.opendaylight.yang.gen.v1.org.openecomp.appc.oam.rev170303.common.header.CommonHeader;
34 import org.opendaylight.yang.gen.v1.org.openecomp.appc.oam.rev170303.common.header.common.header.Flags;
35 import org.opendaylight.yang.gen.v1.org.openecomp.appc.oam.rev170303.status.Status;
36 import org.openecomp.appc.exceptions.APPCException;
37 import org.openecomp.appc.exceptions.InvalidInputException;
38 import org.openecomp.appc.exceptions.InvalidStateException;
39 import org.openecomp.appc.lifecyclemanager.LifecycleManager;
40 import org.openecomp.appc.lifecyclemanager.objects.LifecycleException;
41 import org.openecomp.appc.lifecyclemanager.objects.NoTransitionDefinedException;
42 import org.openecomp.appc.oam.AppcOam;
43 import org.openecomp.appc.oam.messageadapter.MessageAdapter;
44 import org.openecomp.appc.oam.messageadapter.OAMContext;
45 import org.openecomp.appc.statemachine.impl.readers.AppcOamMetaDataReader;
46 import org.openecomp.appc.statemachine.impl.readers.AppcOamStates;
47 import org.osgi.framework.BundleContext;
48 import org.osgi.framework.FrameworkUtil;
49 import org.osgi.framework.ServiceReference;
50
51 /**
52  * Utility class provides general operational helps.
53  */
54 @SuppressWarnings("unchecked")
55 public class OperationHelper {
56     final String MISSING_COMMON_HEADER_MESSAGE = "Missing common header";
57     final String MISSING_FIELD_MESSAGE = "Common header must have both originatorId and requestId";
58     final String NOT_SUPPORT_FLAG = "Flags is not supported by this operation";
59     final String NO_SERVICE_REF_FORMAT = "Using the BundleContext failed to get service reference for %s";
60
61     private final EELFLogger logger = EELFManager.getInstance().getLogger(OperationHelper.class);
62     private LifecycleManager lifecycleMgr;
63     private MessageAdapter messageAdapter;
64
65     public OperationHelper() {
66         // do nothing
67     }
68
69     /**
70      * This method is used to validate OAM REST API input due to the following ODL bugs results no validation : </tt>
71      * <p>  - <a href="https://bugs.opendaylight.org/show_bug.cgi?id=8088">
72      *       Bug 8088 - Mandatory attributes in RPC input are not honoured</a>
73      * <p>  - <a href="https://bugs.opendaylight.org/show_bug.cgi?id=5830">
74      *       Bug 5830 - Mandatory leaf enforcement is not correct with presence container</a>
75      *
76      * @param inputObject object from the OAM REST API input object
77      * @throws InvalidInputException is thrown when the commonHeader is invalid
78      */
79     public void isInputValid(final Object inputObject) throws InvalidInputException {
80         CommonHeader commonHeader = getCommonHeader(inputObject);
81         if (commonHeader == null) {
82             throw new InvalidInputException(MISSING_COMMON_HEADER_MESSAGE);
83         }
84
85         if (commonHeader.getOriginatorId() == null
86                 || commonHeader.getRequestId() == null) {
87             throw new InvalidInputException(MISSING_FIELD_MESSAGE);
88         }
89
90         // check Flags
91         if (inputObject instanceof MaintenanceModeInput
92                 && commonHeader.getFlags() != null) {
93             throw new InvalidInputException(NOT_SUPPORT_FLAG);
94         }
95     }
96
97     /**
98      * Get commonHead of the inputObject (expecting the inputObject of OAM REST API)
99      * @param inputObject the OAM REST API input object
100      * @return CommonHeader of the inputObject. If the inputObject is not a OAM REST API input, null is returned.
101      */
102     public CommonHeader getCommonHeader(final Object inputObject) {
103         if (inputObject instanceof StartInput) {
104             return ((StartInput)inputObject).getCommonHeader();
105         }
106         if (inputObject instanceof StopInput) {
107             return ((StopInput)inputObject).getCommonHeader();
108         }
109         if (inputObject instanceof MaintenanceModeInput) {
110             return ((MaintenanceModeInput)inputObject).getCommonHeader();
111         }
112         if (inputObject instanceof RestartInput) {
113             return ((RestartInput)inputObject).getCommonHeader();
114         }
115         return null;
116     }
117
118     public Integer getParamRequestTimeout(final Object inputObject) {
119         if (inputObject instanceof MaintenanceModeInput) {
120             // maintanence mode, we do not support request timeout
121             return 0;
122         }
123
124         CommonHeader commonHeader = getCommonHeader(inputObject);
125         if (commonHeader == null) {
126             return 0;
127         }
128
129         Flags inputFlags = commonHeader.getFlags();
130         if (inputFlags == null) {
131             return null;
132         }
133         return inputFlags.getRequestTimeout();
134     }
135     /**
136      * Get service instance using bundle context.
137      *
138      * @param _class of the expected service instance
139      * @param <T> of the expected service instance
140      * @return service instance of the expected
141      * @throws APPCException when cannot find service reference or service isntance
142      */
143     public <T> T getService(Class<T> _class) throws APPCException {
144         BundleContext bctx = FrameworkUtil.getBundle(_class).getBundleContext();
145         if (bctx != null) {
146             ServiceReference sref = bctx.getServiceReference(_class.getName());
147             if (sref != null) {
148                 if (logger.isTraceEnabled()) {
149                     logger.debug("Using the BundleContext got the service reference for " + _class.getName());
150                 }
151                 return (T) bctx.getService(sref);
152             }
153         }
154
155         throw new APPCException(String.format(NO_SERVICE_REF_FORMAT, _class.getName()));
156     }
157
158     /**
159      * Get next valid state from life cycle manager.
160      *
161      * @param operation of the AppcOperation for the state changes
162      * @param currentState of AppcOamStates
163      * @return next AppcOamStates based on the currentState and operation
164      * @throws APPCException If life cycle manager instance cannot be retrieved
165      * @throws InvalidStateException when the operation is not supported on the currentState
166      */
167     public AppcOamStates getNextState(AppcOamMetaDataReader.AppcOperation operation, AppcOamStates currentState)
168             throws APPCException, InvalidStateException {
169         if (lifecycleMgr == null) {
170             lifecycleMgr = getService(LifecycleManager.class);
171         }
172
173         try {
174             String nextState = lifecycleMgr.getNextState("APPC", currentState.name(), operation.toString());
175             if (nextState != null) {
176                 return AppcOamStates.valueOf(nextState);
177             }
178         } catch (LifecycleException |NoTransitionDefinedException ex) {
179             logger.error("Invalid next state based on the current state and attempted Operation " + ex.getMessage());
180         }
181
182         throw new InvalidStateException(String.format(AppcOam.INVALID_STATE_MESSAGE_FORMAT, operation, "APPC", currentState));
183     }
184
185     /**
186      * Post notification through MessageAdapter.
187      *
188      * @param rpc of REST API RPC
189      * @param commonHeader of REST API request common header
190      * @param status of the to be post message
191      */
192     public void sendNotificationMessage(AppcOam.RPC rpc, CommonHeader commonHeader, Status status) {
193         if (messageAdapter == null) {
194             messageAdapter = new MessageAdapter();
195             messageAdapter.init();
196
197         }
198
199         OAMContext oamContext = new OAMContext();
200         oamContext.setRpcName(rpc);
201         oamContext.setCommonHeader(commonHeader);
202         oamContext.setStatus(status);
203         messageAdapter.post(oamContext);
204     }
205 }