aboutsummaryrefslogtreecommitdiffstats
path: root/appc-oam/appc-oam-bundle/src/main/java/org/openecomp/appc/oam/util/BundleHelper.java
diff options
context:
space:
mode:
Diffstat (limited to 'appc-oam/appc-oam-bundle/src/main/java/org/openecomp/appc/oam/util/BundleHelper.java')
-rw-r--r--appc-oam/appc-oam-bundle/src/main/java/org/openecomp/appc/oam/util/BundleHelper.java265
1 files changed, 265 insertions, 0 deletions
diff --git a/appc-oam/appc-oam-bundle/src/main/java/org/openecomp/appc/oam/util/BundleHelper.java b/appc-oam/appc-oam-bundle/src/main/java/org/openecomp/appc/oam/util/BundleHelper.java
new file mode 100644
index 000000000..7fbb3c453
--- /dev/null
+++ b/appc-oam/appc-oam-bundle/src/main/java/org/openecomp/appc/oam/util/BundleHelper.java
@@ -0,0 +1,265 @@
+/*-
+ * ============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.openecomp.appc.oam.util;
+
+import com.att.eelf.configuration.EELFLogger;
+import org.apache.commons.lang3.ArrayUtils;
+import org.openecomp.appc.exceptions.APPCException;
+import org.openecomp.appc.oam.AppcOam;
+import org.openecomp.appc.statemachine.impl.readers.AppcOamStates;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.BundleException;
+import org.osgi.framework.FrameworkUtil;
+
+import java.util.Map;
+import java.util.concurrent.Callable;
+import java.util.concurrent.Future;
+
+/**
+ * Utility class provides general bundle operational helps.
+ */
+public class BundleHelper {
+ private final static String PROP_BUNDLE_TO_STOP = "appc.OAM.ToStop.properties";
+ private final static String PROP_BUNDLES_TO_NOT_STOP = "appc.OAM.ToNotStop.properties";
+
+ private final EELFLogger logger;
+ private final StateHelper stateHelper;
+ private final ConfigurationHelper configurationHelper;
+
+ /**
+ * Constructor
+ *
+ * @param eelfLogger of the logger
+ * @param configurationHelperIn of ConfigurationHelper instance
+ * @param stateHelperIn of StateHelper instance
+ */
+ public BundleHelper(EELFLogger eelfLogger,
+ ConfigurationHelper configurationHelperIn,
+ StateHelper stateHelperIn) {
+ logger = eelfLogger;
+ configurationHelper = configurationHelperIn;
+ stateHelper = stateHelperIn;
+ }
+
+ /**
+ * Handle bundle operations, such as stop or start bundle.
+ *
+ * @param rpc enum indicate if the operation is to stop, start or restart
+ * @return boolean to indicate if the operation is successful (true) or failed (false)
+ * @throws APPCException when error occurs
+ */
+ public boolean bundleOperations(AppcOam.RPC rpc,
+ Map<String, Future<?>> threads,
+ AsyncTaskHelper taskHelper)
+ throws APPCException {
+ long mStartTime = System.currentTimeMillis();
+ logDebug(String.format("Entering OAM bundleOperations with rpc (%s).", rpc.name()));
+
+ String action = rpc.getAppcOperation().toString();
+ if (rpc != AppcOam.RPC.stop && rpc != AppcOam.RPC.start) {
+ throw new APPCException("rpc(" + rpc + ") is not supported by bundleOperation.");
+ }
+
+ AppcOamStates originalState = stateHelper.getState();
+
+ boolean isBundleOperationComplete = true;
+
+ Map<String, Bundle> appcLcmBundles = getAppcLcmBundles();
+ taskHelper.addThreadsToPool();
+ for (Map.Entry<String, Bundle> bundleEntry : appcLcmBundles.entrySet()) {
+ String bundleName = bundleEntry.getKey();
+ Bundle bundle = bundleEntry.getValue();
+
+ logDebug("OAM launch thread for %s bundle %s", action, bundleName);
+ if (rpc == AppcOam.RPC.start) {
+ // Abort in the interruption case.
+ // such as when a Stop request is receive while APPC is still trying to Start Up.
+ if (!stateHelper.isSameState(originalState)) {
+ logger.warn("OAM %s bundle operation aborted since OAM state is no longer %s!",
+ originalState.name());
+ isBundleOperationComplete = false;
+ break;
+ }
+ }
+
+ threads.put(bundleName,
+ taskHelper.submitBundleLcOperation(new BundleTask(rpc, bundle)));
+ }
+ taskHelper.removeThreadsFromPoolWhenDone();
+
+ logDebug(String.format("Leaving OAM bundleOperations with rpc (%s) with complete(%s), elasped (%d) ms.",
+ rpc.name(), Boolean.toString(isBundleOperationComplete), getElaspeTimeMs(mStartTime)));
+
+ return isBundleOperationComplete;
+ }
+
+ private long getElaspeTimeMs(long mStartTime) {
+ return System.currentTimeMillis() - mStartTime;
+ }
+
+ /**
+ * Check if all BundleTasks are completed
+ * @param bundleNameFutureMap with bundler name and BundleTask Future object
+ * @return true if all are done, otherwise, false
+ */
+ public boolean isAllTaskDone(Map<String, Future<?>> bundleNameFutureMap) {
+ boolean anyNotDone = bundleNameFutureMap.values().stream().anyMatch((f) -> !f.isDone());
+ return !anyNotDone;
+ }
+
+ /**
+ * Cancel BunldeTasks which are not finished
+ * @param bundleNameFutureMap with bundler name and BundleTask Future object
+ */
+ public void cancelUnfinished(Map<String, Future<?>> bundleNameFutureMap) {
+ bundleNameFutureMap.values().stream().filter((f) -> !f.isDone()).forEach((f) -> f.cancel(true));
+ }
+
+ /**
+ * Get number of failed BundleTasks
+ * @param bundleNameFurtureMap with bundler name and BundleTask Future object
+ * @return number(long) of the failed BundleTasks
+ */
+ public long getFailedMetrics(Map<String, Future<?>> bundleNameFurtureMap) {
+ return bundleNameFurtureMap.values().stream().map((f) -> {
+ try {
+ return f.get();
+ } catch (Exception e) {
+ // should not get here
+ throw new RuntimeException(e);
+ }
+ }).filter((b) -> ((BundleTask)b).failException != null).count();
+ }
+
+ /**
+ * Gets the list of Appc-bundles to be stopped/started
+ *
+ * @return Map of bundle symbolic name and bundle instance
+ */
+ Map<String, Bundle> getAppcLcmBundles() {
+ logDebug("In getAppcLcmBundles");
+
+ String[] bundlesToStop = readPropsFromPropListName(PROP_BUNDLE_TO_STOP);
+ String[] regExBundleNotStop = readPropsFromPropListName(PROP_BUNDLES_TO_NOT_STOP);
+
+ BundleFilter bundleList = new BundleFilter(bundlesToStop, regExBundleNotStop, getBundleList());
+
+ logger.info(String.format("(%d) APPC bundles to Stop/Start: %s.", bundleList.getBundlesToStop().size(),
+ bundleList.getBundlesToStop().toString()));
+
+ logger.debug(String.format("(%d) APPC bundles that won't be Stopped/Started: %s.",
+ bundleList.getBundlesToNotStop().size(), bundleList.getBundlesToNotStop().toString()));
+
+ return bundleList.getBundlesToStop();
+ }
+
+ /**
+ * Gets a list of all user desired bundles that should be stopped/Started as part of
+ * OAM Stop and Start API
+ *
+ * @param propListKey String of the properties list property name
+ * @return properties values of the related
+ */
+ String[] readPropsFromPropListName(String propListKey) {
+ // get properties list by properties list name
+ String[] propNames = configurationHelper.readProperty(propListKey);
+ // go through each property to get the property values
+ String[] propValue = ArrayUtils.EMPTY_STRING_ARRAY;
+ if (propNames != null) {
+ for (String aPropName : propNames) {
+ propValue = ArrayUtils.addAll(propValue, configurationHelper.readProperty(aPropName));
+ }
+ }
+ return propValue;
+ }
+
+ /**
+ * Get all bundle list of APP-C
+ * @return Array of Bundle
+ */
+ Bundle[] getBundleList() {
+ BundleContext myBundleContext = FrameworkUtil.getBundle(this.getClass()).getBundleContext();
+ if (myBundleContext != null) {
+ return myBundleContext.getBundles();
+ }
+ return null;
+ }
+
+ /**
+ * Genral debug log when debug logging level is enabled.
+ * @param message of the log message format
+ * @param args of the objects listed in the message format
+ */
+ private void logDebug(String message, Object... args) {
+ if (logger.isDebugEnabled()) {
+ logger.debug(String.format(message, args));
+ }
+ }
+
+ /**
+ * Runnable to execute bundle operations: start or stop
+ */
+ class BundleTask implements Callable<BundleTask> {
+ Exception failException;
+
+ private AppcOam.RPC rpc;
+ private Bundle bundle;
+ private String bundleName;
+ private String actionName;
+
+ BundleTask(AppcOam.RPC rpcIn, Bundle bundleIn) {
+ rpc = rpcIn;
+ actionName = rpc.getAppcOperation().toString();
+ bundle = bundleIn;
+ bundleName = bundle.getSymbolicName();
+ }
+
+ @Override
+ public BundleTask call() throws Exception {
+ try {
+ long bundleOperStartTime = System.currentTimeMillis();
+ logDebug(String.format("OAM %s bundle %s ===>", actionName, bundleName));
+ switch (rpc) {
+ case start:
+ bundle.start();
+ break;
+ case stop:
+ bundle.stop();
+ break;
+ default:
+ // should do nothing
+ }
+ logDebug(String.format("OAM %s bundle %s completed <=== elasped %d",
+ actionName, bundleName, getElaspeTimeMs(bundleOperStartTime)));
+ } catch (BundleException e) {
+ logger.error(String.format("Exception encountered when OAM %s bundle %s ",
+ actionName, bundleName), e);
+ failException = e;
+ }
+ return this;
+ }
+ }
+}