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.statemachine.impl.readers.AppcOamStates;
32 import org.osgi.framework.Bundle;
33 import org.osgi.framework.BundleContext;
34 import org.osgi.framework.BundleException;
35 import org.osgi.framework.FrameworkUtil;
38 import java.util.concurrent.Callable;
39 import java.util.concurrent.Future;
42 * Utility class provides general bundle operational helps.
44 public class BundleHelper {
45 private final static String PROP_BUNDLE_TO_STOP = "appc.OAM.ToStop.properties";
46 private final static String PROP_BUNDLES_TO_NOT_STOP = "appc.OAM.ToNotStop.properties";
48 private final EELFLogger logger;
49 private final StateHelper stateHelper;
50 private final ConfigurationHelper configurationHelper;
55 * @param eelfLogger of the logger
56 * @param configurationHelperIn of ConfigurationHelper instance
57 * @param stateHelperIn of StateHelper instance
59 public BundleHelper(EELFLogger eelfLogger,
60 ConfigurationHelper configurationHelperIn,
61 StateHelper stateHelperIn) {
63 configurationHelper = configurationHelperIn;
64 stateHelper = stateHelperIn;
68 * Handle bundle operations, such as stop or start bundle.
70 * @param rpc enum indicate if the operation is to stop, start or restart
71 * @return boolean to indicate if the operation is successful (true) or failed (false)
72 * @throws APPCException when error occurs
74 public boolean bundleOperations(AppcOam.RPC rpc,
75 Map<String, Future<?>> threads,
76 AsyncTaskHelper taskHelper)
77 throws APPCException {
78 long mStartTime = System.currentTimeMillis();
79 logDebug(String.format("Entering OAM bundleOperations with rpc (%s).", rpc.name()));
81 String action = rpc.getAppcOperation().toString();
82 if (rpc != AppcOam.RPC.stop && rpc != AppcOam.RPC.start) {
83 throw new APPCException("rpc(" + rpc + ") is not supported by bundleOperation.");
86 AppcOamStates originalState = stateHelper.getState();
88 boolean isBundleOperationComplete = true;
90 Map<String, Bundle> appcLcmBundles = getAppcLcmBundles();
91 taskHelper.addThreadsToPool();
92 for (Map.Entry<String, Bundle> bundleEntry : appcLcmBundles.entrySet()) {
93 String bundleName = bundleEntry.getKey();
94 Bundle bundle = bundleEntry.getValue();
96 logDebug("OAM launch thread for %s bundle %s", action, bundleName);
97 if (rpc == AppcOam.RPC.start) {
98 // Abort in the interruption case.
99 // such as when a Stop request is receive while APPC is still trying to Start Up.
100 if (!stateHelper.isSameState(originalState)) {
101 logger.warn("OAM %s bundle operation aborted since OAM state is no longer %s!",
102 originalState.name());
103 isBundleOperationComplete = false;
108 threads.put(bundleName,
109 taskHelper.submitBundleLcOperation(new BundleTask(rpc, bundle)));
111 taskHelper.removeThreadsFromPoolWhenDone();
113 logDebug(String.format("Leaving OAM bundleOperations with rpc (%s) with complete(%s), elasped (%d) ms.",
114 rpc.name(), Boolean.toString(isBundleOperationComplete), getElaspeTimeMs(mStartTime)));
116 return isBundleOperationComplete;
119 private long getElaspeTimeMs(long mStartTime) {
120 return System.currentTimeMillis() - mStartTime;
124 * Check if all BundleTasks are completed
125 * @param bundleNameFutureMap with bundler 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 BunldeTasks which are not finished
135 * @param bundleNameFutureMap with bundler name and BundleTask Future object
137 public void cancelUnfinished(Map<String, Future<?>> bundleNameFutureMap) {
138 bundleNameFutureMap.values().stream().filter((f) -> !f.isDone()).forEach((f) -> f.cancel(true));
142 * Get number of failed BundleTasks
143 * @param bundleNameFurtureMap with bundler name and BundleTask Future object
144 * @return number(long) of the failed BundleTasks
146 public long getFailedMetrics(Map<String, Future<?>> bundleNameFurtureMap) {
147 return bundleNameFurtureMap.values().stream().map((f) -> {
150 } catch (Exception e) {
151 // should not get here
152 throw new RuntimeException(e);
154 }).filter((b) -> ((BundleTask)b).failException != null).count();
158 * Gets the list of Appc-bundles to be stopped/started
160 * @return Map of bundle symbolic name and bundle instance
162 Map<String, Bundle> getAppcLcmBundles() {
163 logDebug("In getAppcLcmBundles");
165 String[] bundlesToStop = readPropsFromPropListName(PROP_BUNDLE_TO_STOP);
166 String[] regExBundleNotStop = readPropsFromPropListName(PROP_BUNDLES_TO_NOT_STOP);
168 BundleFilter bundleList = new BundleFilter(bundlesToStop, regExBundleNotStop, getBundleList());
170 logger.info(String.format("(%d) APPC bundles to Stop/Start: %s.", bundleList.getBundlesToStop().size(),
171 bundleList.getBundlesToStop().toString()));
173 logger.debug(String.format("(%d) APPC bundles that won't be Stopped/Started: %s.",
174 bundleList.getBundlesToNotStop().size(), bundleList.getBundlesToNotStop().toString()));
176 return bundleList.getBundlesToStop();
180 * Gets a list of all user desired bundles that should be stopped/Started as part of
181 * OAM Stop and Start API
183 * @param propListKey String of the properties list property name
184 * @return properties values of the related
186 String[] readPropsFromPropListName(String propListKey) {
187 // get properties list by properties list name
188 String[] propNames = configurationHelper.readProperty(propListKey);
189 // go through each property to get the property values
190 String[] propValue = ArrayUtils.EMPTY_STRING_ARRAY;
191 if (propNames != null) {
192 for (String aPropName : propNames) {
193 propValue = ArrayUtils.addAll(propValue, configurationHelper.readProperty(aPropName));
200 * Get all bundle list of APP-C
201 * @return Array of Bundle
203 Bundle[] getBundleList() {
204 BundleContext myBundleContext = FrameworkUtil.getBundle(this.getClass()).getBundleContext();
205 if (myBundleContext != null) {
206 return myBundleContext.getBundles();
212 * Genral debug log when debug logging level is enabled.
213 * @param message of the log message format
214 * @param args of the objects listed in the message format
216 private void logDebug(String message, Object... args) {
217 if (logger.isDebugEnabled()) {
218 logger.debug(String.format(message, args));
223 * Runnable to execute bundle operations: start or stop
225 class BundleTask implements Callable<BundleTask> {
226 Exception failException;
228 private AppcOam.RPC rpc;
229 private Bundle bundle;
230 private String bundleName;
231 private String actionName;
233 BundleTask(AppcOam.RPC rpcIn, Bundle bundleIn) {
235 actionName = rpc.getAppcOperation().toString();
237 bundleName = bundle.getSymbolicName();
241 public BundleTask call() throws Exception {
243 long bundleOperStartTime = System.currentTimeMillis();
244 logDebug(String.format("OAM %s bundle %s ===>", actionName, bundleName));
255 logDebug(String.format("OAM %s bundle %s completed <=== elasped %d",
256 actionName, bundleName, getElaspeTimeMs(bundleOperStartTime)));
257 } catch (BundleException e) {
258 logger.error(String.format("Exception encountered when OAM %s bundle %s ",
259 actionName, bundleName), e);