2 * ============LICENSE_START=======================================================
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
13 * http://www.apache.org/licenses/LICENSE-2.0
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.
21 * ECOMP is a trademark and service mark of AT&T Intellectual Property.
22 * ============LICENSE_END=========================================================
25 package org.openecomp.appc.oam.util;
27 import com.att.eelf.configuration.EELFLogger;
28 import org.apache.commons.lang3.ArrayUtils;
29 import org.openecomp.appc.exceptions.APPCException;
30 import org.openecomp.appc.oam.AppcOam;
31 import org.openecomp.appc.oam.processor.BaseCommon;
32 import org.openecomp.appc.statemachine.impl.readers.AppcOamStates;
33 import org.osgi.framework.Bundle;
34 import org.osgi.framework.BundleContext;
35 import org.osgi.framework.BundleException;
36 import org.osgi.framework.FrameworkUtil;
39 import java.util.concurrent.Callable;
40 import java.util.concurrent.Future;
43 * Utility class provides general bundle operational helps.
45 public class BundleHelper {
46 private final static String PROP_BUNDLE_TO_STOP = "appc.OAM.ToStop.properties";
47 private final static String PROP_BUNDLES_TO_NOT_STOP = "appc.OAM.ToNotStop.properties";
49 private final EELFLogger logger;
50 private final StateHelper stateHelper;
51 private final ConfigurationHelper configurationHelper;
56 * @param eelfLogger of the logger
57 * @param configurationHelperIn of ConfigurationHelper instance
58 * @param stateHelperIn of StateHelper instance
60 public BundleHelper(EELFLogger eelfLogger,
61 ConfigurationHelper configurationHelperIn,
62 StateHelper stateHelperIn) {
64 configurationHelper = configurationHelperIn;
65 stateHelper = stateHelperIn;
69 * Handle bundle operations, such as stop or start bundle.
71 * @param rpc enum indicate if the operation is to stop, start or restart
72 * @return boolean to indicate if the operation is successful (true) or failed (false)
73 * @throws APPCException when error occurs
75 public boolean bundleOperations(AppcOam.RPC rpc,
76 Map<String, Future<?>> threads,
77 AsyncTaskHelper taskHelper,
78 BaseCommon baseCommon)
79 throws APPCException {
80 long mStartTime = System.currentTimeMillis();
81 logDebug(String.format("Entering OAM bundleOperations with rpc (%s).", rpc.name()));
83 String action = rpc.getAppcOperation().toString();
84 if (rpc != AppcOam.RPC.stop && rpc != AppcOam.RPC.start) {
85 throw new APPCException("rpc(" + rpc + ") is not supported by bundleOperation.");
88 AppcOamStates originalState = stateHelper.getState();
90 boolean isBundleOperationComplete = true;
92 Map<String, Bundle> appcLcmBundles = getAppcLcmBundles();
93 for (Map.Entry<String, Bundle> bundleEntry : appcLcmBundles.entrySet()) {
94 String bundleName = bundleEntry.getKey();
95 Bundle bundle = bundleEntry.getValue();
97 logDebug("OAM launch thread for %s bundle %s", action, bundleName);
98 if (rpc == AppcOam.RPC.start) {
99 // Abort in the interruption case.
100 // such as when a Stop request is receive while APPC is still trying to Start Up.
101 if (!stateHelper.isSameState(originalState)) {
102 logger.warn("OAM %s bundle operation aborted since OAM state is no longer %s!",
103 originalState.name());
104 isBundleOperationComplete = false;
109 threads.put(bundleName,
110 taskHelper.submitBaseSubCallable(new BundleTask(rpc, bundle,baseCommon)));
113 logDebug(String.format("Leaving OAM bundleOperations with rpc (%s) with complete(%s), elasped (%d) ms.",
114 rpc.name(), Boolean.toString(isBundleOperationComplete), getElapseTimeMs(mStartTime)));
116 return isBundleOperationComplete;
119 private long getElapseTimeMs(long mStartTime) {
120 return System.currentTimeMillis() - mStartTime;
124 * Check if all BundleTasks are completed
125 * @param bundleNameFutureMap with bundle name and BundleTask Future object
126 * @return true if all are done, otherwise, false
128 public boolean isAllTaskDone(Map<String, Future<?>> bundleNameFutureMap) {
129 boolean anyNotDone = bundleNameFutureMap.values().stream().anyMatch((f) -> !f.isDone());
134 * Cancel BundleTasks which are not finished
135 * @param bundleNameFutureMap with bundle name and BundleTask Future object
137 public void cancelUnfinished(Map<String, Future<?>> bundleNameFutureMap) {
138 bundleNameFutureMap.values().stream().filter((f)
139 -> !f.isDone()).forEach((f)
144 * Get number of failed BundleTasks
145 * @param bundleNameFutureMap with bundle name and BundleTask Future object
146 * @return number(long) of the failed BundleTasks
148 public long getFailedMetrics(Map<String, Future<?>> bundleNameFutureMap) {
149 return bundleNameFutureMap.values().stream().map((f) -> {
152 } catch (Exception e) {
153 // should not get here
154 throw new RuntimeException(e);
156 }).filter((b) -> ((BundleTask)b).failException != null).count();
160 * Gets the list of Appc-bundles to be stopped/started
162 * @return Map of bundle symbolic name and bundle instance
164 Map<String, Bundle> getAppcLcmBundles() {
165 logDebug("In getAppcLcmBundles");
167 String[] bundlesToStop = readPropsFromPropListName(PROP_BUNDLE_TO_STOP);
168 String[] regExBundleNotStop = readPropsFromPropListName(PROP_BUNDLES_TO_NOT_STOP);
170 BundleFilter bundleList = new BundleFilter(bundlesToStop, regExBundleNotStop, getBundleList());
172 logger.info(String.format("(%d) APPC bundles to Stop/Start: %s.", bundleList.getBundlesToStop().size(),
173 bundleList.getBundlesToStop().toString()));
175 logger.debug(String.format("(%d) APPC bundles that won't be Stopped/Started: %s.",
176 bundleList.getBundlesToNotStop().size(), bundleList.getBundlesToNotStop().toString()));
178 return bundleList.getBundlesToStop();
182 * Gets a list of all user desired bundles that should be stopped/Started as part of
183 * OAM Stop and Start API
185 * @param propListKey String of the properties list property name
186 * @return properties values of the related
188 String[] readPropsFromPropListName(String propListKey) {
189 // get properties list by properties list name
190 String[] propNames = configurationHelper.readProperty(propListKey);
191 // go through each property to get the property values
192 String[] propValue = ArrayUtils.EMPTY_STRING_ARRAY;
193 if (propNames != null) {
194 for (String aPropName : propNames) {
195 propValue = ArrayUtils.addAll(propValue, configurationHelper.readProperty(aPropName));
202 * Get all bundle list of APP-C
203 * @return Array of Bundle
205 Bundle[] getBundleList() {
206 BundleContext myBundleContext = FrameworkUtil.getBundle(this.getClass()).getBundleContext();
207 if (myBundleContext != null) {
208 return myBundleContext.getBundles();
214 * Genral debug log when debug logging level is enabled.
215 * @param message of the log message format
216 * @param args of the objects listed in the message format
218 private void logDebug(String message, Object... args) {
219 if (logger.isDebugEnabled()) {
220 logger.debug(String.format(message, args));
225 * Runnable to execute bundle operations: start or stop
227 class BundleTask implements Callable<BundleTask> {
228 Exception failException;
230 private AppcOam.RPC rpc;
231 private Bundle bundle;
232 private String bundleName;
233 private String actionName;
234 private final BaseCommon baseCommon;
236 BundleTask(AppcOam.RPC rpcIn, Bundle bundleIn, BaseCommon baseCommon) {
238 actionName = rpc.getAppcOperation().toString();
240 bundleName = bundle.getSymbolicName();
241 this.baseCommon = baseCommon;
245 public BundleTask call() throws Exception {
247 baseCommon.setInitialLogProperties();
249 long bundleOperStartTime = System.currentTimeMillis();
250 logDebug(String.format("OAM %s bundle %s ===>", actionName, bundleName));
261 logDebug(String.format("OAM %s bundle %s completed <=== elasped %d",
262 actionName, bundleName, getElapseTimeMs(bundleOperStartTime)));
263 } catch (BundleException e) {
264 logger.error(String.format("Exception encountered when OAM %s bundle %s ",
265 actionName, bundleName), e);
269 baseCommon.clearRequestLogProperties();