2 * ============LICENSE_START=======================================================
4 * ================================================================================
5 * Copyright (C) 2017-2018 AT&T Intellectual Property. All rights reserved.
6 * ================================================================================
7 * Copyright (C) 2017 Amdocs
8 * ================================================================================
9 * Modifications (C) 2018 Ericsson
10 * =============================================================================
11 * Licensed under the Apache License, Version 2.0 (the "License");
12 * you may not use this file except in compliance with the License.
13 * You may obtain a copy of the License at
15 * http://www.apache.org/licenses/LICENSE-2.0
17 * Unless required by applicable law or agreed to in writing, software
18 * distributed under the License is distributed on an "AS IS" BASIS,
19 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
20 * See the License for the specific language governing permissions and
21 * limitations under the License.
23 * ============LICENSE_END=========================================================
26 package org.onap.appc.oam.util;
28 import com.att.eelf.configuration.EELFLogger;
29 import org.apache.commons.lang3.ArrayUtils;
30 import org.onap.appc.exceptions.APPCException;
31 import org.onap.appc.oam.AppcOam;
32 import org.onap.appc.oam.processor.BaseCommon;
33 import org.onap.appc.statemachine.impl.readers.AppcOamStates;
34 import org.osgi.framework.Bundle;
35 import org.osgi.framework.BundleContext;
36 import org.osgi.framework.BundleException;
37 import org.osgi.framework.FrameworkUtil;
40 import java.util.concurrent.Callable;
41 import java.util.concurrent.Future;
44 * Utility class provides general bundle operational helps.
46 public class BundleHelper {
47 private final static String PROP_BUNDLE_TO_STOP = "appc.OAM.ToStop.properties";
48 private final static String PROP_BUNDLES_TO_NOT_STOP = "appc.OAM.ToNotStop.properties";
50 private final EELFLogger logger;
51 private final StateHelper stateHelper;
52 private final ConfigurationHelper configurationHelper;
57 * @param eelfLogger of the logger
58 * @param configurationHelperIn of ConfigurationHelper instance
59 * @param stateHelperIn of StateHelper instance
61 public BundleHelper(EELFLogger eelfLogger,
62 ConfigurationHelper configurationHelperIn,
63 StateHelper stateHelperIn) {
65 configurationHelper = configurationHelperIn;
66 stateHelper = stateHelperIn;
70 * Handle bundle operations, such as stop or start bundle.
72 * @param rpc enum indicate if the operation is to stop, start or restart
73 * @return boolean to indicate if the operation is successful (true) or failed (false)
74 * @throws APPCException when error occurs
76 public boolean bundleOperations(AppcOam.RPC rpc,
77 Map<String, Future<?>> threads,
78 AsyncTaskHelper taskHelper,
79 BaseCommon baseCommon)
80 throws APPCException {
81 long mStartTime = System.currentTimeMillis();
82 logDebug(String.format("Entering OAM bundleOperations with rpc (%s).", rpc.name()));
84 String action = rpc.getAppcOperation().toString();
85 if (rpc != AppcOam.RPC.stop && rpc != AppcOam.RPC.start) {
86 throw new APPCException("rpc(" + rpc + ") is not supported by bundleOperation.");
89 AppcOamStates originalState = stateHelper.getState();
91 boolean isBundleOperationComplete = true;
93 Map<String, Bundle> appcLcmBundles = getAppcLcmBundles();
94 for (Map.Entry<String, Bundle> bundleEntry : appcLcmBundles.entrySet()) {
95 String bundleName = bundleEntry.getKey();
96 Bundle bundle = bundleEntry.getValue();
98 logDebug("OAM launch thread for %s bundle %s", action, bundleName);
99 if (rpc == AppcOam.RPC.start) {
100 // Abort in the interruption case.
101 // such as when a Stop request is receive while APPC is still trying to Start Up.
102 if (!stateHelper.isSameState(originalState)) {
103 logger.warn("OAM %s bundle operation aborted since OAM state is no longer %s!",
104 originalState.name());
105 isBundleOperationComplete = false;
110 threads.put(bundleName,
111 taskHelper.submitBaseSubCallable(new BundleTask(rpc, bundle,baseCommon)));
114 logDebug(String.format("Leaving OAM bundleOperations with rpc (%s) with complete(%s), elasped (%d) ms.",
115 rpc.name(), Boolean.toString(isBundleOperationComplete), getElapseTimeMs(mStartTime)));
117 return isBundleOperationComplete;
120 private long getElapseTimeMs(long mStartTime) {
121 return System.currentTimeMillis() - mStartTime;
125 * Check if all BundleTasks are completed
126 * @param bundleNameFutureMap with bundle name and BundleTask Future object
127 * @return true if all are done, otherwise, false
129 public boolean isAllTaskDone(Map<String, Future<?>> bundleNameFutureMap) {
130 boolean anyNotDone = bundleNameFutureMap.values().stream().anyMatch((f) -> !f.isDone());
135 * Cancel BundleTasks which are not finished
136 * @param bundleNameFutureMap with bundle name and BundleTask Future object
138 public void cancelUnfinished(Map<String, Future<?>> bundleNameFutureMap) {
139 bundleNameFutureMap.values().stream().filter((f)
140 -> !f.isDone()).forEach((f)
145 * Get number of failed BundleTasks
146 * @param bundleNameFutureMap with bundle name and BundleTask Future object
147 * @return number(long) of the failed BundleTasks
149 public long getFailedMetrics(Map<String, Future<?>> bundleNameFutureMap) {
150 return bundleNameFutureMap.values().stream().map((f) -> {
153 } catch (Exception e) {
154 // should not get here
155 throw new RuntimeException(e);
157 }).filter((b) -> ((BundleTask)b).failException != null).count();
161 * Gets the list of Appc-bundles to be stopped/started
163 * @return Map of bundle symbolic name and bundle instance
165 Map<String, Bundle> getAppcLcmBundles() {
166 logDebug("In getAppcLcmBundles");
168 String[] bundlesToStop = readPropsFromPropListName(PROP_BUNDLE_TO_STOP);
169 String[] regExBundleNotStop = readPropsFromPropListName(PROP_BUNDLES_TO_NOT_STOP);
171 BundleFilter bundleList = getBundleFilter(bundlesToStop, regExBundleNotStop, getBundleList());
173 logger.info(String.format("(%d) APPC bundles to Stop/Start: %s.", bundleList.getBundlesToStop().size(),
174 bundleList.getBundlesToStop().toString()));
176 logger.debug(String.format("(%d) APPC bundles that won't be Stopped/Started: %s.",
177 bundleList.getBundlesToNotStop().size(), bundleList.getBundlesToNotStop().toString()));
179 return bundleList.getBundlesToStop();
183 * Gets a list of all user desired bundles that should be stopped/Started as part of
184 * OAM Stop and Start API
186 * @param propListKey String of the properties list property name
187 * @return properties values of the related
189 String[] readPropsFromPropListName(String propListKey) {
190 // get properties list by properties list name
191 String[] propNames = configurationHelper.readProperty(propListKey);
192 // go through each property to get the property values
193 String[] propValue = ArrayUtils.EMPTY_STRING_ARRAY;
194 if (propNames != null) {
195 for (String aPropName : propNames) {
196 propValue = ArrayUtils.addAll(propValue, configurationHelper.readProperty(aPropName));
203 * Get all bundle list of APP-C
204 * @return Array of Bundle
206 Bundle[] getBundleList() {
207 BundleContext myBundleContext = FrameworkUtil.getBundle(this.getClass()).getBundleContext();
208 if (myBundleContext != null) {
209 return myBundleContext.getBundles();
215 * Genral debug log when debug logging level is enabled.
216 * @param message of the log message format
217 * @param args of the objects listed in the message format
219 private void logDebug(String message, Object... args) {
220 if (logger.isDebugEnabled()) {
221 logger.debug(String.format(message, args));
225 protected BundleFilter getBundleFilter(String[] stopRegexes, String[] exceptRegexes, Bundle[] bundles) {
226 return new BundleFilter(stopRegexes, exceptRegexes, bundles);
230 * Runnable to execute bundle operations: start or stop
232 class BundleTask implements Callable<BundleTask> {
233 Exception failException;
235 private AppcOam.RPC rpc;
236 private Bundle bundle;
237 private String bundleName;
238 private String actionName;
239 private final BaseCommon baseCommon;
241 BundleTask(AppcOam.RPC rpcIn, Bundle bundleIn, BaseCommon baseCommon) {
243 actionName = rpc.getAppcOperation().toString();
245 bundleName = bundle.getSymbolicName();
246 this.baseCommon = baseCommon;
250 public BundleTask call() throws Exception {
252 baseCommon.setInitialLogProperties();
254 long bundleOperStartTime = System.currentTimeMillis();
255 logDebug(String.format("OAM %s bundle %s ===>", actionName, bundleName));
266 logDebug(String.format("OAM %s bundle %s completed <=== elasped %d",
267 actionName, bundleName, getElapseTimeMs(bundleOperStartTime)));
268 } catch (BundleException e) {
269 logger.error(String.format("Exception encountered when OAM %s bundle %s ",
270 actionName, bundleName), e);
274 baseCommon.clearRequestLogProperties();