summaryrefslogtreecommitdiffstats
path: root/appc-oam/appc-oam-bundle/src/main/java/org/openecomp/appc/oam/util/OperationHelper.java
blob: 9eec0b67bb53a6449fe4b7208cb39ae76833eb24 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
/*-
 * ============LICENSE_START=======================================================
 * ONAP : APPC
 * ================================================================================
 * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
 * ================================================================================
 * Copyright (C) 2017 Amdocs
 * =============================================================================
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * 
 *      http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 * 
 * ECOMP is a trademark and service mark of AT&T Intellectual Property.
 * ============LICENSE_END=========================================================
 */

package org.onap.appc.oam.util;

import com.att.eelf.configuration.EELFLogger;
import com.att.eelf.configuration.EELFManager;
import org.opendaylight.yang.gen.v1.org.onap.appc.oam.rev170303.MaintenanceModeInput;
import org.opendaylight.yang.gen.v1.org.onap.appc.oam.rev170303.RestartInput;
import org.opendaylight.yang.gen.v1.org.onap.appc.oam.rev170303.StartInput;
import org.opendaylight.yang.gen.v1.org.onap.appc.oam.rev170303.StopInput;
import org.opendaylight.yang.gen.v1.org.onap.appc.oam.rev170303.common.header.CommonHeader;
import org.opendaylight.yang.gen.v1.org.onap.appc.oam.rev170303.common.header.common.header.Flags;
import org.opendaylight.yang.gen.v1.org.onap.appc.oam.rev170303.status.Status;
import org.onap.appc.exceptions.APPCException;
import org.onap.appc.exceptions.InvalidInputException;
import org.onap.appc.exceptions.InvalidStateException;
import org.onap.appc.lifecyclemanager.LifecycleManager;
import org.onap.appc.lifecyclemanager.objects.LifecycleException;
import org.onap.appc.lifecyclemanager.objects.NoTransitionDefinedException;
import org.onap.appc.oam.AppcOam;
import org.onap.appc.oam.messageadapter.MessageAdapter;
import org.onap.appc.oam.messageadapter.OAMContext;
import org.onap.appc.statemachine.impl.readers.AppcOamMetaDataReader;
import org.onap.appc.statemachine.impl.readers.AppcOamStates;
import org.osgi.framework.BundleContext;
import org.osgi.framework.FrameworkUtil;
import org.osgi.framework.ServiceReference;

/**
 * Utility class provides general operational helps.
 */
@SuppressWarnings("unchecked")
public class OperationHelper {
    final String MISSING_COMMON_HEADER_MESSAGE = "Missing common header";
    final String MISSING_FIELD_MESSAGE = "Common header must have both originatorId and requestId";
    final String NOT_SUPPORT_FLAG = "Flags is not supported by this operation";
    final String NO_SERVICE_REF_FORMAT = "Using the BundleContext failed to get service reference for %s";

    private final EELFLogger logger = EELFManager.getInstance().getLogger(OperationHelper.class);
    private LifecycleManager lifecycleMgr;
    private MessageAdapter messageAdapter;

    public OperationHelper() {
        // do nothing
    }

    /**
     * This method is used to validate OAM REST API input due to the following ODL bugs results no validation : </tt>
     * <p>  - <a href="https://bugs.opendaylight.org/show_bug.cgi?id=8088">
     *       Bug 8088 - Mandatory attributes in RPC input are not honoured</a>
     * <p>  - <a href="https://bugs.opendaylight.org/show_bug.cgi?id=5830">
     *       Bug 5830 - Mandatory leaf enforcement is not correct with presence container</a>
     *
     * @param inputObject object from the OAM REST API input object
     * @throws InvalidInputException is thrown when the commonHeader is invalid
     */
    public void isInputValid(final Object inputObject) throws InvalidInputException {
        CommonHeader commonHeader = getCommonHeader(inputObject);
        if (commonHeader == null) {
            throw new InvalidInputException(MISSING_COMMON_HEADER_MESSAGE);
        }

        if (commonHeader.getOriginatorId() == null
                || commonHeader.getRequestId() == null) {
            throw new InvalidInputException(MISSING_FIELD_MESSAGE);
        }

        // check Flags
        if (inputObject instanceof MaintenanceModeInput
                && commonHeader.getFlags() != null) {
            throw new InvalidInputException(NOT_SUPPORT_FLAG);
        }
    }

    /**
     * Get commonHead of the inputObject (expecting the inputObject of OAM REST API)
     * @param inputObject the OAM REST API input object
     * @return CommonHeader of the inputObject. If the inputObject is not a OAM REST API input, null is returned.
     */
    public CommonHeader getCommonHeader(final Object inputObject) {
        if (inputObject instanceof StartInput) {
            return ((StartInput)inputObject).getCommonHeader();
        }
        if (inputObject instanceof StopInput) {
            return ((StopInput)inputObject).getCommonHeader();
        }
        if (inputObject instanceof MaintenanceModeInput) {
            return ((MaintenanceModeInput)inputObject).getCommonHeader();
        }
        if (inputObject instanceof RestartInput) {
            return ((RestartInput)inputObject).getCommonHeader();
        }
        return null;
    }

    public Integer getParamRequestTimeout(final Object inputObject) {
        if (inputObject instanceof MaintenanceModeInput) {
            // maintanence mode, we do not support request timeout
            return 0;
        }

        CommonHeader commonHeader = getCommonHeader(inputObject);
        if (commonHeader == null) {
            return 0;
        }

        Flags inputFlags = commonHeader.getFlags();
        if (inputFlags == null) {
            return null;
        }
        return inputFlags.getRequestTimeout();
    }
    /**
     * Get service instance using bundle context.
     *
     * @param _class of the expected service instance
     * @param <T> of the expected service instance
     * @return service instance of the expected
     * @throws APPCException when cannot find service reference or service isntance
     */
    public <T> T getService(Class<T> _class) throws APPCException {
        BundleContext bctx = FrameworkUtil.getBundle(_class).getBundleContext();
        if (bctx != null) {
            ServiceReference sref = bctx.getServiceReference(_class.getName());
            if (sref != null) {
                if (logger.isTraceEnabled()) {
                    logger.debug("Using the BundleContext got the service reference for " + _class.getName());
                }
                return (T) bctx.getService(sref);
            }
        }

        throw new APPCException(String.format(NO_SERVICE_REF_FORMAT, _class.getName()));
    }

    /**
     * Get next valid state from life cycle manager.
     *
     * @param operation of the AppcOperation for the state changes
     * @param currentState of AppcOamStates
     * @return next AppcOamStates based on the currentState and operation
     * @throws APPCException If life cycle manager instance cannot be retrieved
     * @throws InvalidStateException when the operation is not supported on the currentState
     */
    public AppcOamStates getNextState(AppcOamMetaDataReader.AppcOperation operation, AppcOamStates currentState)
            throws APPCException, InvalidStateException {
        if (lifecycleMgr == null) {
            lifecycleMgr = getService(LifecycleManager.class);
        }

        try {
            String nextState = lifecycleMgr.getNextState("APPC", currentState.name(), operation.toString());
            if (nextState != null) {
                return AppcOamStates.valueOf(nextState);
            }
        } catch (LifecycleException |NoTransitionDefinedException ex) {
            logger.error("Invalid next state based on the current state and attempted Operation " + ex.getMessage());
        }

        throw new InvalidStateException(String.format(AppcOam.INVALID_STATE_MESSAGE_FORMAT, operation, "APPC", currentState));
    }

    /**
     * Post notification through MessageAdapter.
     *
     * @param rpc of REST API RPC
     * @param commonHeader of REST API request common header
     * @param status of the to be post message
     */
    public void sendNotificationMessage(AppcOam.RPC rpc, CommonHeader commonHeader, Status status) {
        if (messageAdapter == null) {
            messageAdapter = new MessageAdapter();
            messageAdapter.init();

        }

        OAMContext oamContext = new OAMContext();
        oamContext.setRpcName(rpc);
        oamContext.setCommonHeader(commonHeader);
        oamContext.setStatus(status);
        messageAdapter.post(oamContext);
    }
}