From 781b1a6df324419c846c84ea983c18fc8362bfd3 Mon Sep 17 00:00:00 2001 From: Patrick Brady Date: Wed, 13 Dec 2017 11:19:06 -0800 Subject: Third part of onap rename This part of the commit changes the folder structure on all other folders of appc. Change-Id: I8acfa11cdfcdcd36be0e137245d1dd7324f1abd3 Signed-off-by: Patrick Brady Issue-ID: APPC-13 --- .../src/main/java/org/onap/appc/oam/AppcOam.java | 339 +++++++++++ .../java/org/onap/appc/oam/OAMCommandStatus.java | 74 +++ .../onap/appc/oam/messageadapter/Converter.java | 156 +++++ .../oam/messageadapter/DmaapOutgoingMessage.java | 137 +++++ .../appc/oam/messageadapter/MessageAdapter.java | 183 ++++++ .../onap/appc/oam/messageadapter/OAMContext.java | 75 +++ .../appc/oam/processor/BaseActionRunnable.java | 254 ++++++++ .../org/onap/appc/oam/processor/BaseCommon.java | 265 ++++++++ .../org/onap/appc/oam/processor/BaseProcessor.java | 216 +++++++ .../onap/appc/oam/processor/OamMmodeProcessor.java | 170 ++++++ .../appc/oam/processor/OamRestartProcessor.java | 208 +++++++ .../onap/appc/oam/processor/OamStartProcessor.java | 151 +++++ .../onap/appc/oam/processor/OamStopProcessor.java | 120 ++++ .../org/onap/appc/oam/util/AsyncTaskHelper.java | 394 ++++++++++++ .../java/org/onap/appc/oam/util/BundleFilter.java | 128 ++++ .../java/org/onap/appc/oam/util/BundleHelper.java | 274 +++++++++ .../onap/appc/oam/util/ConfigurationHelper.java | 106 ++++ .../org/onap/appc/oam/util/OperationHelper.java | 205 +++++++ .../java/org/onap/appc/oam/util/StateHelper.java | 144 +++++ .../appc/oam/impl/rev170303/AppcOamModule.java | 55 ++ .../oam/impl/rev170303/AppcOamModuleFactory.java | 37 ++ .../appc/oam/impl/rev170303/AppcOamModule.java | 55 -- .../oam/impl/rev170303/AppcOamModuleFactory.java | 37 -- .../main/java/org/openecomp/appc/oam/AppcOam.java | 339 ----------- .../org/openecomp/appc/oam/OAMCommandStatus.java | 74 --- .../appc/oam/messageadapter/Converter.java | 156 ----- .../oam/messageadapter/DmaapOutgoingMessage.java | 137 ----- .../appc/oam/messageadapter/MessageAdapter.java | 183 ------ .../appc/oam/messageadapter/OAMContext.java | 75 --- .../appc/oam/processor/BaseActionRunnable.java | 254 -------- .../openecomp/appc/oam/processor/BaseCommon.java | 265 -------- .../appc/oam/processor/BaseProcessor.java | 216 ------- .../appc/oam/processor/OamMmodeProcessor.java | 170 ------ .../appc/oam/processor/OamRestartProcessor.java | 208 ------- .../appc/oam/processor/OamStartProcessor.java | 151 ----- .../appc/oam/processor/OamStopProcessor.java | 120 ---- .../openecomp/appc/oam/util/AsyncTaskHelper.java | 394 ------------ .../org/openecomp/appc/oam/util/BundleFilter.java | 128 ---- .../org/openecomp/appc/oam/util/BundleHelper.java | 274 --------- .../appc/oam/util/ConfigurationHelper.java | 106 ---- .../openecomp/appc/oam/util/OperationHelper.java | 205 ------- .../org/openecomp/appc/oam/util/StateHelper.java | 144 ----- .../resources/org/onap/appc/default.properties | 90 +++ .../src/main/resources/org/onap/appc/logback.xml | 287 +++++++++ .../org/openecomp/appc/default.properties | 90 --- .../main/resources/org/openecomp/appc/logback.xml | 287 --------- .../test/java/org/onap/appc/oam/AppcOamTest.java | 166 +++++ .../org/onap/appc/oam/OAMCommandStatusTest.java | 99 +++ .../oam/messageadapter/MessageAdapterTest.java | 115 ++++ .../appc/oam/processor/BaseActionRunnableTest.java | 293 +++++++++ .../onap/appc/oam/processor/BaseCommonTest.java | 182 ++++++ .../onap/appc/oam/processor/BaseProcessorTest.java | 174 ++++++ .../onap/appc/oam/util/AsyncTaskHelperTest.java | 665 +++++++++++++++++++++ .../org/onap/appc/oam/util/BundleHelperTest.java | 180 ++++++ .../appc/oam/util/ConfigurationHelperTest.java | 128 ++++ .../onap/appc/oam/util/OperationHelperTest.java | 240 ++++++++ .../org/onap/appc/oam/util/StateHelperTest.java | 173 ++++++ .../java/org/openecomp/appc/oam/AppcOamTest.java | 166 ----- .../openecomp/appc/oam/OAMCommandStatusTest.java | 99 --- .../oam/messageadapter/MessageAdapterTest.java | 115 ---- .../appc/oam/processor/BaseActionRunnableTest.java | 293 --------- .../appc/oam/processor/BaseCommonTest.java | 182 ------ .../appc/oam/processor/BaseProcessorTest.java | 174 ------ .../appc/oam/util/AsyncTaskHelperTest.java | 665 --------------------- .../openecomp/appc/oam/util/BundleHelperTest.java | 180 ------ .../appc/oam/util/ConfigurationHelperTest.java | 128 ---- .../appc/oam/util/OperationHelperTest.java | 240 -------- .../openecomp/appc/oam/util/StateHelperTest.java | 173 ------ 68 files changed, 6483 insertions(+), 6483 deletions(-) create mode 100644 appc-oam/appc-oam-bundle/src/main/java/org/onap/appc/oam/AppcOam.java create mode 100644 appc-oam/appc-oam-bundle/src/main/java/org/onap/appc/oam/OAMCommandStatus.java create mode 100644 appc-oam/appc-oam-bundle/src/main/java/org/onap/appc/oam/messageadapter/Converter.java create mode 100644 appc-oam/appc-oam-bundle/src/main/java/org/onap/appc/oam/messageadapter/DmaapOutgoingMessage.java create mode 100644 appc-oam/appc-oam-bundle/src/main/java/org/onap/appc/oam/messageadapter/MessageAdapter.java create mode 100644 appc-oam/appc-oam-bundle/src/main/java/org/onap/appc/oam/messageadapter/OAMContext.java create mode 100644 appc-oam/appc-oam-bundle/src/main/java/org/onap/appc/oam/processor/BaseActionRunnable.java create mode 100644 appc-oam/appc-oam-bundle/src/main/java/org/onap/appc/oam/processor/BaseCommon.java create mode 100644 appc-oam/appc-oam-bundle/src/main/java/org/onap/appc/oam/processor/BaseProcessor.java create mode 100644 appc-oam/appc-oam-bundle/src/main/java/org/onap/appc/oam/processor/OamMmodeProcessor.java create mode 100644 appc-oam/appc-oam-bundle/src/main/java/org/onap/appc/oam/processor/OamRestartProcessor.java create mode 100644 appc-oam/appc-oam-bundle/src/main/java/org/onap/appc/oam/processor/OamStartProcessor.java create mode 100644 appc-oam/appc-oam-bundle/src/main/java/org/onap/appc/oam/processor/OamStopProcessor.java create mode 100644 appc-oam/appc-oam-bundle/src/main/java/org/onap/appc/oam/util/AsyncTaskHelper.java create mode 100644 appc-oam/appc-oam-bundle/src/main/java/org/onap/appc/oam/util/BundleFilter.java create mode 100644 appc-oam/appc-oam-bundle/src/main/java/org/onap/appc/oam/util/BundleHelper.java create mode 100644 appc-oam/appc-oam-bundle/src/main/java/org/onap/appc/oam/util/ConfigurationHelper.java create mode 100644 appc-oam/appc-oam-bundle/src/main/java/org/onap/appc/oam/util/OperationHelper.java create mode 100644 appc-oam/appc-oam-bundle/src/main/java/org/onap/appc/oam/util/StateHelper.java create mode 100644 appc-oam/appc-oam-bundle/src/main/java/org/opendaylight/yang/gen/v1/org/onap/appc/oam/impl/rev170303/AppcOamModule.java create mode 100644 appc-oam/appc-oam-bundle/src/main/java/org/opendaylight/yang/gen/v1/org/onap/appc/oam/impl/rev170303/AppcOamModuleFactory.java delete mode 100644 appc-oam/appc-oam-bundle/src/main/java/org/opendaylight/yang/gen/v1/org/openecomp/appc/oam/impl/rev170303/AppcOamModule.java delete mode 100644 appc-oam/appc-oam-bundle/src/main/java/org/opendaylight/yang/gen/v1/org/openecomp/appc/oam/impl/rev170303/AppcOamModuleFactory.java delete mode 100644 appc-oam/appc-oam-bundle/src/main/java/org/openecomp/appc/oam/AppcOam.java delete mode 100644 appc-oam/appc-oam-bundle/src/main/java/org/openecomp/appc/oam/OAMCommandStatus.java delete mode 100644 appc-oam/appc-oam-bundle/src/main/java/org/openecomp/appc/oam/messageadapter/Converter.java delete mode 100644 appc-oam/appc-oam-bundle/src/main/java/org/openecomp/appc/oam/messageadapter/DmaapOutgoingMessage.java delete mode 100644 appc-oam/appc-oam-bundle/src/main/java/org/openecomp/appc/oam/messageadapter/MessageAdapter.java delete mode 100644 appc-oam/appc-oam-bundle/src/main/java/org/openecomp/appc/oam/messageadapter/OAMContext.java delete mode 100644 appc-oam/appc-oam-bundle/src/main/java/org/openecomp/appc/oam/processor/BaseActionRunnable.java delete mode 100644 appc-oam/appc-oam-bundle/src/main/java/org/openecomp/appc/oam/processor/BaseCommon.java delete mode 100644 appc-oam/appc-oam-bundle/src/main/java/org/openecomp/appc/oam/processor/BaseProcessor.java delete mode 100644 appc-oam/appc-oam-bundle/src/main/java/org/openecomp/appc/oam/processor/OamMmodeProcessor.java delete mode 100644 appc-oam/appc-oam-bundle/src/main/java/org/openecomp/appc/oam/processor/OamRestartProcessor.java delete mode 100644 appc-oam/appc-oam-bundle/src/main/java/org/openecomp/appc/oam/processor/OamStartProcessor.java delete mode 100644 appc-oam/appc-oam-bundle/src/main/java/org/openecomp/appc/oam/processor/OamStopProcessor.java delete mode 100644 appc-oam/appc-oam-bundle/src/main/java/org/openecomp/appc/oam/util/AsyncTaskHelper.java delete mode 100644 appc-oam/appc-oam-bundle/src/main/java/org/openecomp/appc/oam/util/BundleFilter.java delete mode 100644 appc-oam/appc-oam-bundle/src/main/java/org/openecomp/appc/oam/util/BundleHelper.java delete mode 100644 appc-oam/appc-oam-bundle/src/main/java/org/openecomp/appc/oam/util/ConfigurationHelper.java delete mode 100644 appc-oam/appc-oam-bundle/src/main/java/org/openecomp/appc/oam/util/OperationHelper.java delete mode 100644 appc-oam/appc-oam-bundle/src/main/java/org/openecomp/appc/oam/util/StateHelper.java create mode 100644 appc-oam/appc-oam-bundle/src/main/resources/org/onap/appc/default.properties create mode 100644 appc-oam/appc-oam-bundle/src/main/resources/org/onap/appc/logback.xml delete mode 100644 appc-oam/appc-oam-bundle/src/main/resources/org/openecomp/appc/default.properties delete mode 100644 appc-oam/appc-oam-bundle/src/main/resources/org/openecomp/appc/logback.xml create mode 100644 appc-oam/appc-oam-bundle/src/test/java/org/onap/appc/oam/AppcOamTest.java create mode 100644 appc-oam/appc-oam-bundle/src/test/java/org/onap/appc/oam/OAMCommandStatusTest.java create mode 100644 appc-oam/appc-oam-bundle/src/test/java/org/onap/appc/oam/messageadapter/MessageAdapterTest.java create mode 100644 appc-oam/appc-oam-bundle/src/test/java/org/onap/appc/oam/processor/BaseActionRunnableTest.java create mode 100644 appc-oam/appc-oam-bundle/src/test/java/org/onap/appc/oam/processor/BaseCommonTest.java create mode 100644 appc-oam/appc-oam-bundle/src/test/java/org/onap/appc/oam/processor/BaseProcessorTest.java create mode 100644 appc-oam/appc-oam-bundle/src/test/java/org/onap/appc/oam/util/AsyncTaskHelperTest.java create mode 100644 appc-oam/appc-oam-bundle/src/test/java/org/onap/appc/oam/util/BundleHelperTest.java create mode 100644 appc-oam/appc-oam-bundle/src/test/java/org/onap/appc/oam/util/ConfigurationHelperTest.java create mode 100644 appc-oam/appc-oam-bundle/src/test/java/org/onap/appc/oam/util/OperationHelperTest.java create mode 100644 appc-oam/appc-oam-bundle/src/test/java/org/onap/appc/oam/util/StateHelperTest.java delete mode 100644 appc-oam/appc-oam-bundle/src/test/java/org/openecomp/appc/oam/AppcOamTest.java delete mode 100644 appc-oam/appc-oam-bundle/src/test/java/org/openecomp/appc/oam/OAMCommandStatusTest.java delete mode 100644 appc-oam/appc-oam-bundle/src/test/java/org/openecomp/appc/oam/messageadapter/MessageAdapterTest.java delete mode 100644 appc-oam/appc-oam-bundle/src/test/java/org/openecomp/appc/oam/processor/BaseActionRunnableTest.java delete mode 100644 appc-oam/appc-oam-bundle/src/test/java/org/openecomp/appc/oam/processor/BaseCommonTest.java delete mode 100644 appc-oam/appc-oam-bundle/src/test/java/org/openecomp/appc/oam/processor/BaseProcessorTest.java delete mode 100644 appc-oam/appc-oam-bundle/src/test/java/org/openecomp/appc/oam/util/AsyncTaskHelperTest.java delete mode 100644 appc-oam/appc-oam-bundle/src/test/java/org/openecomp/appc/oam/util/BundleHelperTest.java delete mode 100644 appc-oam/appc-oam-bundle/src/test/java/org/openecomp/appc/oam/util/ConfigurationHelperTest.java delete mode 100644 appc-oam/appc-oam-bundle/src/test/java/org/openecomp/appc/oam/util/OperationHelperTest.java delete mode 100644 appc-oam/appc-oam-bundle/src/test/java/org/openecomp/appc/oam/util/StateHelperTest.java (limited to 'appc-oam') diff --git a/appc-oam/appc-oam-bundle/src/main/java/org/onap/appc/oam/AppcOam.java b/appc-oam/appc-oam-bundle/src/main/java/org/onap/appc/oam/AppcOam.java new file mode 100644 index 000000000..97938339c --- /dev/null +++ b/appc-oam/appc-oam-bundle/src/main/java/org/onap/appc/oam/AppcOam.java @@ -0,0 +1,339 @@ +/*- + * ============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; + +import com.att.eelf.configuration.EELFLogger; +import com.att.eelf.configuration.EELFManager; +import com.google.common.util.concurrent.Futures; +import org.opendaylight.controller.md.sal.binding.api.DataBroker; +import org.opendaylight.controller.sal.binding.api.BindingAwareBroker; +import org.opendaylight.controller.sal.binding.api.NotificationProviderService; +import org.opendaylight.controller.sal.binding.api.RpcProviderRegistry; +import org.opendaylight.yang.gen.v1.org.onap.appc.oam.rev170303.AppcOamService; +import org.opendaylight.yang.gen.v1.org.onap.appc.oam.rev170303.AppcState; +import org.opendaylight.yang.gen.v1.org.onap.appc.oam.rev170303.GetAppcStateOutput; +import org.opendaylight.yang.gen.v1.org.onap.appc.oam.rev170303.GetAppcStateOutputBuilder; +import org.opendaylight.yang.gen.v1.org.onap.appc.oam.rev170303.GetMetricsOutput; +import org.opendaylight.yang.gen.v1.org.onap.appc.oam.rev170303.GetMetricsOutputBuilder; +import org.opendaylight.yang.gen.v1.org.onap.appc.oam.rev170303.MaintenanceModeInput; +import org.opendaylight.yang.gen.v1.org.onap.appc.oam.rev170303.MaintenanceModeOutput; +import org.opendaylight.yang.gen.v1.org.onap.appc.oam.rev170303.MaintenanceModeOutputBuilder; +import org.opendaylight.yang.gen.v1.org.onap.appc.oam.rev170303.RestartInput; +import org.opendaylight.yang.gen.v1.org.onap.appc.oam.rev170303.RestartOutput; +import org.opendaylight.yang.gen.v1.org.onap.appc.oam.rev170303.RestartOutputBuilder; +import org.opendaylight.yang.gen.v1.org.onap.appc.oam.rev170303.StartInput; +import org.opendaylight.yang.gen.v1.org.onap.appc.oam.rev170303.StartOutput; +import org.opendaylight.yang.gen.v1.org.onap.appc.oam.rev170303.StartOutputBuilder; +import org.opendaylight.yang.gen.v1.org.onap.appc.oam.rev170303.StopInput; +import org.opendaylight.yang.gen.v1.org.onap.appc.oam.rev170303.StopOutput; +import org.opendaylight.yang.gen.v1.org.onap.appc.oam.rev170303.StopOutputBuilder; +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.get.metrics.output.Metrics; +import org.opendaylight.yang.gen.v1.org.onap.appc.oam.rev170303.get.metrics.output.MetricsBuilder; +import org.opendaylight.yang.gen.v1.org.onap.appc.oam.rev170303.get.metrics.output.metrics.KpiValues; +import org.opendaylight.yang.gen.v1.org.onap.appc.oam.rev170303.get.metrics.output.metrics.KpiValuesBuilder; +import org.opendaylight.yang.gen.v1.org.onap.appc.oam.rev170303.status.Status; +import org.opendaylight.yangtools.yang.common.RpcError; +import org.opendaylight.yangtools.yang.common.RpcResult; +import org.opendaylight.yangtools.yang.common.RpcResultBuilder; +import org.onap.appc.exceptions.APPCException; +import org.onap.appc.i18n.Msg; +import org.onap.appc.metricservice.MetricRegistry; +import org.onap.appc.metricservice.MetricService; +import org.onap.appc.metricservice.metric.Metric; +import org.onap.appc.oam.processor.OamMmodeProcessor; +import org.onap.appc.oam.processor.OamRestartProcessor; +import org.onap.appc.oam.processor.OamStartProcessor; +import org.onap.appc.oam.processor.OamStopProcessor; +import org.onap.appc.oam.util.AsyncTaskHelper; +import org.onap.appc.oam.util.ConfigurationHelper; +import org.onap.appc.oam.util.OperationHelper; +import org.onap.appc.oam.util.StateHelper; +import org.onap.appc.statemachine.impl.readers.AppcOamMetaDataReader.AppcOperation; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.concurrent.Future; + +/** + * RPC class of APP-C OAM API. + *

Implement all the RPCs defined in AppcOamService through yang model definition. + *

All RPC methods' JAVADOC are using "inheritDoc" to use the description from the yang model file. + */ +public class AppcOam implements AutoCloseable, AppcOamService { + /** + * Invalid state message format with fliexible operation, appc name and state values + */ + public final static String INVALID_STATE_MESSAGE_FORMAT = "%s API is not allowed when %s is in the %s state."; + + private final EELFLogger logger = EELFManager.getInstance().getLogger(AppcOam.class); + + private boolean isMetricEnabled = false; + + /** + * Represents our RPC implementation registration + */ + private BindingAwareBroker.RpcRegistration rpcRegistration; + + + /** + * The yang rpc names with value mapping to AppcOperation + */ + public enum RPC { + maintenance_mode(AppcOperation.MaintenanceMode), + start(AppcOperation.Start), + stop(AppcOperation.Stop), + restart(AppcOperation.Restart); + + AppcOperation appcOperation; + + RPC(AppcOperation appcOperation) { + this.appcOperation = appcOperation; + } + + public AppcOperation getAppcOperation() { + return appcOperation; + } + } + + private AsyncTaskHelper asyncTaskHelper; + private ConfigurationHelper configurationHelper; + private OperationHelper operationHelper; + private StateHelper stateHelper; + + /** + * APP-C OAM contructor + * + * @param dataBroker object of The ODL data store broker. Provides access to a conceptual data + * tree store + * and also provides the ability to subscribe for changes to data under a + * given branch + * of the tree. Not used in this class. + * @param notificationProviderService object of ODL Notification Service that provides publish/subscribe + * capabilities for YANG modeled notifications. Not used in this class. + * @param rpcProviderRegistry object of RpcProviderResigstry. Used to register our RPCs. + */ + @SuppressWarnings({"unused", "nls"}) + public AppcOam(DataBroker dataBroker, + NotificationProviderService notificationProviderService, + RpcProviderRegistry rpcProviderRegistry) { + + configurationHelper = new ConfigurationHelper(logger); + String appName = configurationHelper.getAppcName(); + logger.info(Msg.COMPONENT_INITIALIZING, appName, "oam"); + + if (rpcProviderRegistry != null) { + rpcRegistration = rpcProviderRegistry.addRpcImplementation(AppcOamService.class, this); + } + + isMetricEnabled = configurationHelper.isMetricEnabled(); + + initHelpers(); + + logger.info(Msg.COMPONENT_INITIALIZED, appName, "oam"); + } + + /** + * Initialize helper classes. + *

Note: ConfigurationHelper initializetion is in included here + * because it is needed for extracting the AppName used in the debug logs within the constructor. + */ + private void initHelpers() { + operationHelper = new OperationHelper(); + asyncTaskHelper = new AsyncTaskHelper(logger); + stateHelper = new StateHelper(logger, configurationHelper); + } + + /** + * Implements the close of the service + * + * @see AutoCloseable#close() + */ + @SuppressWarnings("nls") + @Override + public void close() throws Exception { + String appName = configurationHelper.getAppcName(); + logger.info(Msg.COMPONENT_TERMINATING, appName, "oam"); + + asyncTaskHelper.close(); + + if (rpcRegistration != null) { + rpcRegistration.close(); + } + logger.info(Msg.COMPONENT_TERMINATED, appName, "oam"); + } + + /** + * {@inheritDoc} + */ + @Override + public Future> getMetrics() { + + if (!isMetricEnabled) { + logger.error("Metric Service not enabled returning failure"); + RpcResult result = RpcResultBuilder. + status(false).withError(RpcError.ErrorType.APPLICATION, "Metric Service not enabled").build(); + return Futures.immediateFuture(result); + } + + MetricService metricService; + try { + metricService = operationHelper.getService(MetricService.class); + } catch (APPCException e) { + logger.error("MetricService not found", e); + RpcResult result = RpcResultBuilder. + status(false).withError(RpcError.ErrorType.APPLICATION, "Metric Service not found").build(); + return Futures.immediateFuture(result); + } + + Map allMetricRegitry = metricService.getAllRegistry(); + if (allMetricRegitry == null || allMetricRegitry.isEmpty()) { + logger.error("No metrics registered returning failure"); + RpcResult result = RpcResultBuilder. + status(false).withError(RpcError.ErrorType.APPLICATION, "No metrics Registered").build(); + return Futures.immediateFuture(result); + } + + List metricsList = new ArrayList<>(); + + logger.debug("Iterating metric registry list"); + for (MetricRegistry metricRegistry : allMetricRegitry.values()) { + logger.debug("Iterating metric registry :" + metricRegistry.toString()); + Metric[] metrics = metricRegistry.metrics(); + if (metrics != null && metrics.length > 0) { + logger.debug("Iterating though metrics in registry"); + for (Metric metric : metrics) { + logger.debug("Iterating though metrics: " + metric.name()); + MetricsBuilder metricsBuilder = new MetricsBuilder(); + metricsBuilder.setKpiName(metric.name()); + metricsBuilder.setLastResetTime(metric.getLastModified()); + List kpiList = new ArrayList<>(); + Map metricsOutput = metric.getMetricsOutput(); + for (Map.Entry kpi : metricsOutput.entrySet()) { + KpiValuesBuilder kpiValuesBuilder = new KpiValuesBuilder(); + kpiValuesBuilder.setName(kpi.getKey()); + kpiValuesBuilder.setValue(kpi.getValue()); + kpiList.add(kpiValuesBuilder.build()); + } + metricsBuilder.setKpiValues(kpiList); + metricsList.add(metricsBuilder.build()); + } + } + } + + GetMetricsOutputBuilder outputBuilder = new GetMetricsOutputBuilder(); + outputBuilder.setMetrics(metricsList); + RpcResult result = RpcResultBuilder. + status(true).withResult(outputBuilder.build()).build(); + return Futures.immediateFuture(result); + } + + /** + * {@inheritDoc} + */ + @Override + public Future> stop(StopInput stopInput) { + logger.debug("Entering Stop with Input : " + stopInput); + final CommonHeader commonHeader = stopInput.getCommonHeader(); + + OamStopProcessor oamStopProcessor = + new OamStopProcessor(logger, configurationHelper, stateHelper, asyncTaskHelper, operationHelper); + Status status = oamStopProcessor.processRequest(stopInput); + + StopOutputBuilder stopOutputBuilder = new StopOutputBuilder(); + stopOutputBuilder.setStatus(status); + stopOutputBuilder.setCommonHeader(commonHeader); + return RpcResultBuilder.success(stopOutputBuilder.build()).buildFuture(); + } + + /** + * {@inheritDoc} + */ + @Override + public Future> restart(RestartInput input) { + logger.debug("Entering restart with Input : " + input); + final CommonHeader commonHeader = input.getCommonHeader(); + + OamRestartProcessor oamRestartProcessor = + new OamRestartProcessor(logger, configurationHelper, stateHelper, asyncTaskHelper, operationHelper); + Status status = oamRestartProcessor.processRequest(input); + + RestartOutputBuilder restartOutputBuilder = new RestartOutputBuilder(); + restartOutputBuilder.setStatus(status); + restartOutputBuilder.setCommonHeader(commonHeader); + + return RpcResultBuilder.success(restartOutputBuilder.build()).buildFuture(); + } + + /** + * {@inheritDoc} + */ + @Override + public Future> maintenanceMode(MaintenanceModeInput maintenanceModeInput) { + logger.debug("Entering MaintenanceMode with Input : " + maintenanceModeInput); + final CommonHeader commonHeader = maintenanceModeInput.getCommonHeader(); + + OamMmodeProcessor oamMmodeProcessor = + new OamMmodeProcessor(logger, configurationHelper, stateHelper, asyncTaskHelper, operationHelper); + Status status = oamMmodeProcessor.processRequest(maintenanceModeInput); + + MaintenanceModeOutputBuilder maintenanceModeOutputBuilder = new MaintenanceModeOutputBuilder(); + maintenanceModeOutputBuilder.setStatus(status); + maintenanceModeOutputBuilder.setCommonHeader(commonHeader); + return RpcResultBuilder.success(maintenanceModeOutputBuilder.build()).buildFuture(); + } + + /** + * {@inheritDoc} + */ + @Override + public Future> getAppcState() { + AppcState appcState = stateHelper.getCurrentOamYangState(); + + GetAppcStateOutputBuilder builder = new GetAppcStateOutputBuilder(); + builder.setState(appcState); + return RpcResultBuilder.success(builder.build()).buildFuture(); + } + + /** + * {@inheritDoc} + */ + @Override + public Future> start(StartInput startInput) { + logger.debug("Input received : " + startInput); + final CommonHeader commonHeader = startInput.getCommonHeader(); + + OamStartProcessor oamStartProcessor = + new OamStartProcessor(logger, configurationHelper, stateHelper, asyncTaskHelper, operationHelper); + Status status = oamStartProcessor.processRequest(startInput); + + StartOutputBuilder startOutputBuilder = new StartOutputBuilder(); + startOutputBuilder.setStatus(status); + startOutputBuilder.setCommonHeader(commonHeader); + StartOutput startOutput = startOutputBuilder.build(); + return RpcResultBuilder.success(startOutput).buildFuture(); + } +} diff --git a/appc-oam/appc-oam-bundle/src/main/java/org/onap/appc/oam/OAMCommandStatus.java b/appc-oam/appc-oam-bundle/src/main/java/org/onap/appc/oam/OAMCommandStatus.java new file mode 100644 index 000000000..294b9d2cf --- /dev/null +++ b/appc-oam/appc-oam-bundle/src/main/java/org/onap/appc/oam/OAMCommandStatus.java @@ -0,0 +1,74 @@ +/*- + * ============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; + +import org.onap.appc.executor.objects.Params; +import org.onap.appc.util.MessageFormatter; + +import java.util.Map; + +public enum OAMCommandStatus { + + ACCEPTED(100, "ACCEPTED - request accepted"), + UNEXPECTED_ERROR(200, "UNEXPECTED ERROR - ${errorMsg}"), + REJECTED(300, "REJECTED - ${errorMsg}"), + INVALID_PARAMETER(302, "INVALID PARAMETER - ${errorMsg}" ), + TIMEOUT(303, "OPERATION TIMEOUT REACHED - ${errorMsg}"), + ABORT(304, "OPERATION ABORT - ${errorMsg}"), + SUCCESS(400, "SUCCESS - request has been processed successfully"); + + final String TO_STRING_FORMAT = "OAMCommandStatus{responseCode=%d, responseMessage='%s'}"; + + private int responseCode; + private String responseMessage; + + OAMCommandStatus(int responseCode, String responseMessage) { + this.responseCode = responseCode; + this.responseMessage = responseMessage; + } + + public String getResponseMessage() { + return responseMessage; + } + + public int getResponseCode() { + return responseCode; + } + + /** + * Get formated message of passed in params + * + * @param params of Params object with name value pairs for message + * @return message string + */ + public String getFormattedMessage(Params params) { + Map paramsMap = params != null ? params.getParams() : null; + return MessageFormatter.format(getResponseMessage(), paramsMap); + } + + @Override + public String toString() { + return String.format(TO_STRING_FORMAT, responseCode, responseMessage); + }} diff --git a/appc-oam/appc-oam-bundle/src/main/java/org/onap/appc/oam/messageadapter/Converter.java b/appc-oam/appc-oam-bundle/src/main/java/org/onap/appc/oam/messageadapter/Converter.java new file mode 100644 index 000000000..152ffc9cc --- /dev/null +++ b/appc-oam/appc-oam-bundle/src/main/java/org/onap/appc/oam/messageadapter/Converter.java @@ -0,0 +1,156 @@ +/*-/*- + * ============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.messageadapter; + +import com.fasterxml.jackson.annotation.JsonIgnore; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonValue; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.MapperFeature; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.ObjectWriter; +import org.opendaylight.yang.gen.v1.org.onap.appc.oam.rev170303.MaintenanceModeOutputBuilder; +import org.opendaylight.yang.gen.v1.org.onap.appc.oam.rev170303.RestartOutputBuilder; +import org.opendaylight.yang.gen.v1.org.onap.appc.oam.rev170303.StartOutputBuilder; +import org.opendaylight.yang.gen.v1.org.onap.appc.oam.rev170303.StopOutputBuilder; +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.status.Status; +import org.opendaylight.yangtools.concepts.Builder; +import org.opendaylight.yangtools.yang.binding.DataContainer; +import org.onap.appc.oam.AppcOam; + +import java.text.SimpleDateFormat; +import java.util.TimeZone; + +public class Converter { + private static final String ISO_FORMAT = "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'"; + private static final SimpleDateFormat isoFormatter = new SimpleDateFormat(ISO_FORMAT); + + static { + isoFormatter.setTimeZone(TimeZone.getTimeZone("UTC")); + } + + + private static Builder convAsyncResponseToBuilder1(AppcOam.RPC rpcName, + CommonHeader commonHeader, + Status status) { + Builder outObj; + if (rpcName == null) { + throw new IllegalArgumentException("empty asyncResponse.rpcName"); + } + if (commonHeader == null) { + throw new IllegalArgumentException("empty asyncResponse.commonHeader"); + } + if (status == null) { + throw new IllegalArgumentException("empty asyncResponse.status"); + } + switch (rpcName) { + case maintenance_mode: + outObj = new MaintenanceModeOutputBuilder(); + ((MaintenanceModeOutputBuilder) outObj).setCommonHeader(commonHeader); + ((MaintenanceModeOutputBuilder) outObj).setStatus(status); + return outObj; + + case start: + outObj = new StartOutputBuilder(); + ((StartOutputBuilder) outObj).setCommonHeader(commonHeader); + ((StartOutputBuilder) outObj).setStatus(status); + return outObj; + + case stop: + outObj = new StopOutputBuilder(); + ((StopOutputBuilder) outObj).setCommonHeader(commonHeader); + ((StopOutputBuilder) outObj).setStatus(status); + return outObj; + + case restart: + outObj = new RestartOutputBuilder(); + ((RestartOutputBuilder) outObj).setCommonHeader(commonHeader); + ((RestartOutputBuilder) outObj).setStatus(status); + return outObj; + + default: + throw new IllegalArgumentException(rpcName + " action is not supported"); + } + } + + static String convAsyncResponseToUebOutgoingMessageJsonString(OAMContext oamContext) throws + JsonProcessingException { + AppcOam.RPC rpcName = oamContext.getRpcName(); + CommonHeader commonHeader = oamContext.getCommonHeader(); + Status status = oamContext.getStatus(); + + DmaapOutgoingMessage dmaapOutgoingMessage = convAsyncResponseToUebOutgoingMessage(rpcName, commonHeader, + status); + ObjectMapper objectMapper = new ObjectMapper(); + objectMapper.addMixInAnnotations(dmaapOutgoingMessage.getBody().getOutput().getClass(), + MixInFlagsMessage.class); + objectMapper.addMixInAnnotations(Status.class, MixIn.class); + objectMapper.addMixInAnnotations(CommonHeader.class, MixInCommonHeader.class); + ObjectWriter writer = objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL).configure + (MapperFeature.SORT_PROPERTIES_ALPHABETICALLY, true).writer(); + return writer.writeValueAsString(dmaapOutgoingMessage); + } + + private static DmaapOutgoingMessage convAsyncResponseToUebOutgoingMessage(AppcOam.RPC rpcName, CommonHeader + commonHeader, Status status) throws JsonProcessingException { + DmaapOutgoingMessage outObj = new DmaapOutgoingMessage(); + String correlationID = commonHeader.getRequestId(); + outObj.setCorrelationID(correlationID); + outObj.setType("response"); + outObj.setRpcName(rpcName.name()); + Builder builder = Converter.convAsyncResponseToBuilder1(rpcName, commonHeader, status); + Object messageBody = builder.build(); + + DmaapOutgoingMessage.Body body = new DmaapOutgoingMessage.Body(messageBody); + outObj.setBody(body); + return outObj; + } + + + abstract class MixIn { + // to be removed during serialization + @JsonIgnore + abstract Class getImplementedInterface(); + + @JsonValue + abstract java.lang.String getValue(); + } + + abstract class MixInCommonHeader extends MixIn { + @JsonProperty("request-id") + abstract java.lang.String getRequestId(); + + @JsonProperty("originator-id") + abstract java.lang.String getOriginatorId(); + + } + + abstract class MixInFlagsMessage extends MixIn { + @JsonProperty("common-header") + abstract CommonHeader getCommonHeader(); + } +} diff --git a/appc-oam/appc-oam-bundle/src/main/java/org/onap/appc/oam/messageadapter/DmaapOutgoingMessage.java b/appc-oam/appc-oam-bundle/src/main/java/org/onap/appc/oam/messageadapter/DmaapOutgoingMessage.java new file mode 100644 index 000000000..25bf0cf8b --- /dev/null +++ b/appc-oam/appc-oam-bundle/src/main/java/org/onap/appc/oam/messageadapter/DmaapOutgoingMessage.java @@ -0,0 +1,137 @@ +/*- + * ============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.messageadapter; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; + +/** + * This class represents a message being sent out to DMaaP by APPC as async response. + * note the structure of this class must be adapted to the sync message sent to DMaaP represented in org.onap.appc.listener.LCM.domainmodel.DmaapOutgoingMessage + * + */ +@JsonSerialize(include = JsonSerialize.Inclusion.NON_NULL) +@JsonIgnoreProperties(ignoreUnknown = true) +public class DmaapOutgoingMessage { + + @JsonProperty("type") + private String type; + + @JsonProperty("correlation-id") + private String correlationID; + + private final static String defaultCambriaPartition = "MSO"; + @JsonProperty("cambria.partition") + private String cambriaPartition = defaultCambriaPartition; + + @JsonProperty("rpc-name") + private String rpcName; + + @JsonProperty("body") + private Body body; + + public DmaapOutgoingMessage() { + } + + public String getType() { + return type; + } + + public void setType(String type) { + this.type = type; + } + + public String getCorrelationID() { + return correlationID; + } + + public void setCorrelationID(String correlationID) { + this.correlationID = correlationID; + } + + public String getCambriaPartition() { + return cambriaPartition; + } + + public void setCambriaPartition(String cambriaPartition) { + this.cambriaPartition = cambriaPartition; + } + + public String getRpcName() { + return rpcName; + } + + public void setRpcName(String rpcName) { + this.rpcName = rpcName; + } + + public Body getBody() { + return body; + } + + public void setBody(Body body) { + this.body = body; + } + + @Override + public String toString() { + return "DmaapOutgoingMessage{" + + "cambriaPartition='" + cambriaPartition + '\'' + + ", rpcName='" + rpcName + '\'' + + ", body=" + body + + '}'; + } + + @JsonSerialize(include = JsonSerialize.Inclusion.NON_NULL) + @JsonIgnoreProperties(ignoreUnknown = true) + public static class Body { + public Body() { + } + + public Body(Object output) { + this.output = output; + } + + @JsonProperty("output") + private Object output; + + public Object getOutput() { + return output; + } + + public void setOutput(Object body) { + this.output = body; + } + + @Override + public String toString() { + return "Body{" + + "output=" + output + + '}'; + } + } +} + diff --git a/appc-oam/appc-oam-bundle/src/main/java/org/onap/appc/oam/messageadapter/MessageAdapter.java b/appc-oam/appc-oam-bundle/src/main/java/org/onap/appc/oam/messageadapter/MessageAdapter.java new file mode 100644 index 000000000..91836cb40 --- /dev/null +++ b/appc-oam/appc-oam-bundle/src/main/java/org/onap/appc/oam/messageadapter/MessageAdapter.java @@ -0,0 +1,183 @@ +/*- + * ============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.messageadapter; + +import com.att.eelf.configuration.EELFLogger; +import com.att.eelf.configuration.EELFManager; +import com.fasterxml.jackson.core.JsonProcessingException; +import org.apache.commons.lang.ObjectUtils; +import org.onap.appc.adapter.message.MessageAdapterFactory; +import org.onap.appc.adapter.message.Producer; +import org.onap.appc.configuration.Configuration; +import org.onap.appc.configuration.ConfigurationFactory; +import org.osgi.framework.BundleContext; +import org.osgi.framework.FrameworkUtil; +import org.osgi.framework.ServiceReference; + +import java.util.HashSet; +import java.util.Properties; + +public class MessageAdapter { + + private final EELFLogger logger = EELFManager.getInstance().getLogger(MessageAdapter.class); + + private final String PROP_APPC_OAM_DISABLED = "appc.OAM.disabled"; + private final String PROP_APPC_OAM_TOPIC_WRITE = "appc.OAM.topic.write"; + private String PROP_APPC_OAM_CLIENT_KEY = "appc.OAM.client.key"; + private String PROP_APPC_OAM_CLIENT_SECRET = "appc.OAM.client.secret"; + private String PROP_APPC_OAM_POOLMEMBERS = "appc.OAM.poolMembers"; + + private Producer producer; + private String partition; + private Configuration configuration; + private HashSet pool; + private String writeTopic; + private String apiKey; + private String apiSecret; + private boolean isDisabled; + + /** + * Initialize producer client to post messages using configuration properties. + */ + public void init() { + configuration = ConfigurationFactory.getConfiguration(); + Properties properties = configuration.getProperties(); + updateProperties(properties); + + if (isAppcOamPropsListenerEnabled()) { + createProducer(); + } else { + logger.warn(String.format("The listener %s is disabled and will not be run", "appc.OAM")); + } + } + + /** + * Create producer using MessageAdapterFactory which is found through bundle context. + */ + void createProducer() { + BundleContext ctx = FrameworkUtil.getBundle(MessageAdapter.class).getBundleContext(); + if (ctx == null) { + logger.warn("MessageAdapter cannot create producer due to no bundle context."); + return; + } + + ServiceReference svcRef = ctx.getServiceReference(MessageAdapterFactory.class.getName()); + if (svcRef == null) { + logger.warn("MessageAdapter cannot create producer due to no MessageAdapterFactory service reference."); + return; + } + + Producer localProducer = ((MessageAdapterFactory) ctx.getService(svcRef)).createProducer(pool, writeTopic, + apiKey, apiSecret); + + for (String url : pool) { + if (url.contains("3905") || url.contains("https")) { + localProducer.useHttps(true); + break; + } + } + + producer = localProducer; + + logger.debug("MessageAdapter created producer."); + } + + /** + * Read property value to set writeTopic, apiKey, apiSecret and pool. + * + * @param props of configuration + */ + private void updateProperties(Properties props) { + logger.trace("Entering to updateProperties with Properties = " + ObjectUtils.toString(props)); + + pool = new HashSet<>(); + if (props != null) { + isDisabled = Boolean.parseBoolean(props.getProperty(PROP_APPC_OAM_DISABLED)); + writeTopic = props.getProperty(PROP_APPC_OAM_TOPIC_WRITE); + apiKey = props.getProperty(PROP_APPC_OAM_CLIENT_KEY); + apiSecret = props.getProperty(PROP_APPC_OAM_CLIENT_SECRET); + String hostnames = props.getProperty(PROP_APPC_OAM_POOLMEMBERS); + if (hostnames != null && !hostnames.isEmpty()) { + for (String name : hostnames.split(",")) { + pool.add(name); + } + } + } + } + + /** + * Get producer. If it is null, call createProducer to create it again. + * + * @return Producer + */ + Producer getProducer() { + if (producer == null) { + // In case, producer was not properly set yet, set it again. + logger.info("Calling createProducer as producer is null."); + createProducer(); + } + + return producer; + } + + /** + * Posts message to UEB. As UEB accepts only json messages this method first convert uebMessage to json format + * and post it to UEB. + * + * @param oamContext response data that based on it a message will be send to UEB (the format of the message that + * will be sent to UEB based on the action and its YANG domainmodel). + */ + public void post(OAMContext oamContext) { + if (logger.isTraceEnabled()) { + logger.trace("Entering to post with AsyncResponse = " + ObjectUtils.toString(oamContext)); + } + + boolean success; + String jsonMessage; + try { + jsonMessage = Converter.convAsyncResponseToUebOutgoingMessageJsonString(oamContext); + if (logger.isDebugEnabled()) { + logger.debug("UEB Response = " + jsonMessage); + } + + Producer myProducer = getProducer(); + success = myProducer != null && myProducer.post(this.partition, jsonMessage); + } catch (JsonProcessingException e1) { + logger.error("Error generating Json from UEB message " + e1.getMessage()); + success = false; + } catch (Exception e) { + logger.error("Error sending message to UEB " + e.getMessage(), e); + success = false; + } + + if (logger.isTraceEnabled()) { + logger.trace("Exiting from post with (success = " + ObjectUtils.toString(success) + ")"); + } + } + + private boolean isAppcOamPropsListenerEnabled() { + return !isDisabled; + } +} diff --git a/appc-oam/appc-oam-bundle/src/main/java/org/onap/appc/oam/messageadapter/OAMContext.java b/appc-oam/appc-oam-bundle/src/main/java/org/onap/appc/oam/messageadapter/OAMContext.java new file mode 100644 index 000000000..3af395923 --- /dev/null +++ b/appc-oam/appc-oam-bundle/src/main/java/org/onap/appc/oam/messageadapter/OAMContext.java @@ -0,0 +1,75 @@ +/*- + * ============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.messageadapter; + + + + +import org.opendaylight.yang.gen.v1.org.onap.appc.oam.rev170303.*; +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.CommonHeaderBuilder; +import org.opendaylight.yang.gen.v1.org.onap.appc.oam.rev170303.status.Status;import org.onap.appc.oam.AppcOam; + +public class OAMContext { + + private AppcOam.RPC rpcName; + private CommonHeader commonHeader; + private Status status; + + + public AppcOam.RPC getRpcName() { + return rpcName; + } + + public void setRpcName(AppcOam.RPC rpcName) { + this.rpcName = rpcName; + } + + public CommonHeader getCommonHeader() { + return commonHeader; + } + + public void setCommonHeader(CommonHeader commonHeader) { + this.commonHeader = commonHeader; + } + + public Status getStatus() { + return status; + } + + public void setStatus(Status status) { + this.status = status; + } + + + @Override + public String toString() { + return "OAMContext {" + + "rpcName=" + rpcName + + ", commonHeader=" + commonHeader + + ", status=" + status + + '}'; + } +} diff --git a/appc-oam/appc-oam-bundle/src/main/java/org/onap/appc/oam/processor/BaseActionRunnable.java b/appc-oam/appc-oam-bundle/src/main/java/org/onap/appc/oam/processor/BaseActionRunnable.java new file mode 100644 index 000000000..927334670 --- /dev/null +++ b/appc-oam/appc-oam-bundle/src/main/java/org/onap/appc/oam/processor/BaseActionRunnable.java @@ -0,0 +1,254 @@ +/*- + * ============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.processor; + +import org.onap.appc.i18n.Msg; +import org.onap.appc.oam.AppcOam; +import org.onap.appc.oam.OAMCommandStatus; +import org.onap.appc.statemachine.impl.readers.AppcOamStates; + +import java.util.HashMap; +import java.util.Map; +import java.util.concurrent.Future; + +/** + * Base runnable actions for OAM APIs, such as maintenance mode, restart, start and stop API. + * + *

This class holds the general action async handling methods for all OAM APIs. + *

Specific API action runnable will overwrite the general methods to add specific behaviors. + * + *

Subclass constructor must set the following class variables: + *
- actionName + *
- auditMsg + *
- finalState + */ +public abstract class BaseActionRunnable extends BaseCommon implements Runnable { + /** Abort due to rejection message format with flexible operation name */ + final String ABORT_MESSAGE_FORMAT = "Aborting %s operation due to %s."; + /** Timeout message format with flexible operation name */ + final String TIMEOUT_MESSAGE_FORMAT = "%s operation has reached timeout %d milliseconds."; + /** Failure message format with flexible number of bundles */ + final String BUNDLE_OPERATION_FAILED_FORMAT = "%d bundle(s) failed, see logs for details."; + final String NEW_RPC_OPERATION_REQUEST = "new %s operation request"; + final String DUE_TO_EXECUTION_ERROR = "due to execution error."; + + private boolean isWaiting = false; + long startTimeMs = 0; + long timeoutMs = 0; + boolean doTimeoutChecking = false; + + String actionName = "Need to be reset"; + Msg auditMsg; + AppcOamStates finalState; + + BaseProcessor myParent; + Map> bundleNameToFuture = new HashMap<>(); + + /** + * Constructor + * + * @param parent BaseProcessor who has called this constructor. + */ + BaseActionRunnable(BaseProcessor parent) { + super(parent.logger, parent.configurationHelper, parent.stateHelper, parent.operationHelper); + + rpc = parent.rpc; + commonHeader = parent.commonHeader; + myParent = parent; + setTimeoutValues(); + } + + /** + * Collect the timeout value for this {@link BaseActionRunnable} + */ + void setTimeoutValues() { + startTime = myParent.startTime; + timeoutMs = myParent.getTimeoutMilliseconds(); + doTimeoutChecking = timeoutMs != 0; + if (doTimeoutChecking) { + startTimeMs = startTime.getTime(); + } + logDebug("%s action runnable check timeout (%s) with timeout (%d)ms, and startMs (%d)", + rpc.name(), Boolean.toString(doTimeoutChecking), timeoutMs, startTimeMs); + } + + + /** + * Abort operation handling due to outside interruption, does
+ * - set ABORT status
+ * - send notification message
+ * - add audit log + * + * @param newRpc of the new AppcOam.RPC operation. + */ + void abortRunnable(final AppcOam.RPC newRpc) { + resetLogProperties(false); + + String additionalMsg = String.format(NEW_RPC_OPERATION_REQUEST, newRpc); + logDebug("%s action aborted due to %s", rpc.name(), additionalMsg); + setStatus(OAMCommandStatus.ABORT, String.format(ABORT_MESSAGE_FORMAT, rpc.name(), additionalMsg)); + operationHelper.sendNotificationMessage(rpc, commonHeader, status); + auditInfoLog(auditMsg); + + resetLogProperties(true); + } + + @Override + public void run() { + try { + setInitialLogProperties(); + logDebug(String.format("===========in %s run (waiting: %s)=======", + actionName, Boolean.toString(isWaiting))); + + if (isWaiting) { + if (!checkState()) { + keepWaiting(); + } + } else { + if (doAction()) { + isWaiting = !checkState(); + } else { + postDoAction(false); + } + } + } catch (Exception e) { + logDebug(String.format("%s got exception %s", actionName, e.getMessage())); + logger.error(actionName + " exception", e); + + } finally { + clearRequestLogProperties(); + } + } + + /** + * Keep waiting to be override by children classes for different behaviors. + * Timeout is validated here. + */ + void keepWaiting() { + logDebug(String.format("%s runnable waiting, current state is %s.", + actionName, stateHelper.getCurrentOamState())); + + isTimeout("keepWaiting"); + } + + /** + * Check if the timeout milliseconds has reached. + * + * @param parentName String of the caller, for logging purpose. + * @return true if the timeout has reached, otherwise false. + */ + boolean isTimeout(String parentName) { + logDebug(String.format("%s task isTimeout called from %s", actionName, parentName)); + if (doTimeoutChecking + && System.currentTimeMillis() - startTimeMs > timeoutMs) { + logger.error(String.format("%s operation timeout (%d) ms has reached, abort with error state.", + actionName, timeoutMs)); + + setStatus(OAMCommandStatus.TIMEOUT, String.format(TIMEOUT_MESSAGE_FORMAT, rpc.name(), timeoutMs)); + postAction(AppcOamStates.Error); + return true; + } + return false; + } + + /** + * Check if all bundle operations are successful through BundleHelper. + * If there's failed bundler operation, set error status and trigger postAction with Error state. + * + * @return true if bundler operations have failure, otherwise false. + */ + boolean hasBundleOperationFailure() { + long failedTask = myParent.bundleHelper.getFailedMetrics(bundleNameToFuture); + if (failedTask == 0) { + return false; + } + + setStatus(OAMCommandStatus.UNEXPECTED_ERROR, String.format(BUNDLE_OPERATION_FAILED_FORMAT, failedTask)); + postAction(AppcOamStates.Error); + return true; + } + + /** + * Set class status to ABORT with abort message. + */ + void setAbortStatus() { + setStatus(OAMCommandStatus.ABORT, String.format(ABORT_MESSAGE_FORMAT, rpc.name(), DUE_TO_EXECUTION_ERROR)); + } + + /** + * Final handling. The thread is cancelled. + * + * @param setState boolean to indicate if set OAM state or not + */ + void postDoAction(boolean setState) { + logDebug(String.format("Finished %s task", actionName)); + } + + /** + * Handling for after doAction. does post notification, issue audit log and set OAM state based on input. + * + * @param state of AppcOamState to be set as OAM state when it is not null. + */ + void postAction(AppcOamStates state) { + operationHelper.sendNotificationMessage(rpc, commonHeader, status); + + if (state != null) { + stateHelper.setState(state); + } + + auditInfoLog(auditMsg); + + myParent.cancelAsyncTask(); + } + + /** + * Check state + * + * @return true if final state reached, otherwise return false + */ + boolean checkState() { + if (isTimeout("checkState")) { + myParent.bundleHelper.cancelUnfinished(bundleNameToFuture); + return true; + } + + if (!myParent.bundleHelper.isAllTaskDone(bundleNameToFuture)) { + return false; + } + + if (hasBundleOperationFailure()) { + return true; + } + + if (stateHelper.getBundlesState() == finalState) { + setStatus(OAMCommandStatus.SUCCESS); + postDoAction(true); + return true; + } + return false; + } + + abstract boolean doAction(); +} diff --git a/appc-oam/appc-oam-bundle/src/main/java/org/onap/appc/oam/processor/BaseCommon.java b/appc-oam/appc-oam-bundle/src/main/java/org/onap/appc/oam/processor/BaseCommon.java new file mode 100644 index 000000000..93e79dd2f --- /dev/null +++ b/appc-oam/appc-oam-bundle/src/main/java/org/onap/appc/oam/processor/BaseCommon.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.onap.appc.oam.processor; + +import com.att.eelf.configuration.EELFLogger; +import com.att.eelf.i18n.EELFResourceManager; +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.status.Status; +import org.opendaylight.yang.gen.v1.org.onap.appc.oam.rev170303.status.StatusBuilder; +import org.onap.appc.exceptions.InvalidInputException; +import org.onap.appc.exceptions.InvalidStateException; +import org.onap.appc.executor.objects.Params; +import org.onap.appc.i18n.Msg; +import org.onap.appc.logging.LoggingConstants; +import org.onap.appc.logging.LoggingUtils; +import org.onap.appc.oam.AppcOam; +import org.onap.appc.oam.OAMCommandStatus; +import org.onap.appc.oam.util.ConfigurationHelper; +import org.onap.appc.oam.util.OperationHelper; +import org.onap.appc.oam.util.StateHelper; +import org.slf4j.MDC; + +import java.net.InetAddress; +import java.time.Instant; +import java.util.Arrays; +import java.util.Date; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.concurrent.TimeoutException; + +import static com.att.eelf.configuration.Configuration.MDC_INSTANCE_UUID; +import static com.att.eelf.configuration.Configuration.MDC_KEY_REQUEST_ID; +import static com.att.eelf.configuration.Configuration.MDC_SERVER_FQDN; +import static com.att.eelf.configuration.Configuration.MDC_SERVER_IP_ADDRESS; +import static com.att.eelf.configuration.Configuration.MDC_SERVICE_NAME; + +/** + * Common handling methods of
+ * - BaseProcessor (for REST sync handling)
+ * - BaseActionRunnable (for REST async handling) + */ +public abstract class BaseCommon { + final EELFLogger logger; + final ConfigurationHelper configurationHelper; + final StateHelper stateHelper; + final OperationHelper operationHelper; + + Status status; + Date startTime; + + AppcOam.RPC rpc; + CommonHeader commonHeader; + + private final List MDC_KEYS = Arrays.asList( + LoggingConstants.MDCKeys.PARTNER_NAME, + LoggingConstants.MDCKeys.SERVER_NAME, + MDC_INSTANCE_UUID, + MDC_KEY_REQUEST_ID, + MDC_SERVER_FQDN, + MDC_SERVER_IP_ADDRESS, + MDC_SERVICE_NAME + ); + private Map oldMdcContent = new HashMap<>(); + + /** + * Constructor + * + * @param eelfLogger for logging + * @param configurationHelperIn for property reading + * @param stateHelperIn for APP-C OAM state checking + * @param operationHelperIn for operational helper + */ + BaseCommon(EELFLogger eelfLogger, + ConfigurationHelper configurationHelperIn, + StateHelper stateHelperIn, + OperationHelper operationHelperIn) { + logger = eelfLogger; + configurationHelper = configurationHelperIn; + stateHelper = stateHelperIn; + operationHelper = operationHelperIn; + } + + /** + * Audit log the passed in message at INFO level. + * @param msg the Msg to be audit logged. + */ + void auditInfoLog(Msg msg) { + LoggingUtils.auditInfo(startTime.toInstant(), + Instant.now(), + String.valueOf(status.getCode()), + status.getMessage(), + getClass().getCanonicalName(), + msg, + configurationHelper.getAppcName(), + stateHelper.getCurrentOamState().toString() + ); + } + + /** + * Set MDC properties. + */ + public final void setInitialLogProperties() { + MDC.put(MDC_KEY_REQUEST_ID, commonHeader.getRequestId()); + MDC.put(LoggingConstants.MDCKeys.PARTNER_NAME, commonHeader.getOriginatorId()); + MDC.put(MDC_INSTANCE_UUID, ""); // value should be created in the future + MDC.put(MDC_SERVICE_NAME, rpc.name()); + try { + //!!!Don't change the following to a .getHostName() again please. It's wrong!MDC.put(MDC_SERVER_FQDN, + // InetAddress.getLocalHost().getCanonicalHostName()); + MDC.put(MDC_SERVER_FQDN, InetAddress.getLocalHost().getCanonicalHostName()); + MDC.put(MDC_SERVER_IP_ADDRESS, InetAddress.getLocalHost().getHostAddress()); + MDC.put(LoggingConstants.MDCKeys.SERVER_NAME, InetAddress.getLocalHost().getHostName()); + } catch (Exception e) { + logger.error("MDC constant error", e); + } + } + + /** + * Clear MDC properties. + */ + public final void clearRequestLogProperties() { + for (String key : MDC_KEYS) { + try { + MDC.remove(key); + } catch (Exception e) { + logger.error( + String.format("Unable to clear the Log properties (%s) due to exception: %s", key, e.getMessage())); + } + } + } + + /** + * Reset MDC log properties based on passed in condition. does:
+ * - persist existing MDC setting and set my MDC log properties
+ * - or re-apply persisted MDC log properties + * @param useMdcMap boolean to indicate whether to persist the existing MDC setting and set my MDC log properties, + * or to re-apply the persisted MDC log properties. + */ + void resetLogProperties(boolean useMdcMap) { + if (useMdcMap) { + for (Map.Entry aEntry : oldMdcContent.entrySet()) { + MDC.put(aEntry.getKey(), aEntry.getValue()); + } + return; + } + + // persist existing log properties and set my log properties + oldMdcContent.clear(); + for (String key : MDC_KEYS) { + String value = MDC.get(key); + if (value != null) { + oldMdcContent.put(key, value); + } + } + setInitialLogProperties(); + } + + /** + * Set class status by calling setStatus(OAMCommandStatus, Params) with null paramter. + * @see #setStatus(OAMCommandStatus, String) + * + * @param oamCommandStatus of the to be set new state + */ + void setStatus(OAMCommandStatus oamCommandStatus) { + setStatus(oamCommandStatus, null); + } + + /** + * Create Status based on the passed in parameter, then set the class status with it. + * + * @param oamCommandStatus of the current OAM command status + * @param message to be set in the new status + */ + void setStatus(OAMCommandStatus oamCommandStatus, String message) { + Params params = new Params().addParam("errorMsg", message); + + StatusBuilder statusBuilder = new StatusBuilder(); + statusBuilder.setCode(oamCommandStatus.getResponseCode()); + if (params != null) { + statusBuilder.setMessage(oamCommandStatus.getFormattedMessage(params)); + } else { + statusBuilder.setMessage(oamCommandStatus.getResponseMessage()); + } + + status = statusBuilder.build(); + } + + /** + * Set class status with error status calculated from the passed in paremeter + * and audit log the error message. + * @param t of the error Throwable. + */ + void setErrorStatus(Throwable t) { + resetLogProperties(false); + + final String appName = configurationHelper.getAppcName(); + String exceptionMessage = t.getMessage() != null ? t.getMessage() : t.toString(); + + OAMCommandStatus oamCommandStatus; + String errorMessage; + if (t instanceof InvalidInputException) { + oamCommandStatus = OAMCommandStatus.INVALID_PARAMETER; + errorMessage = EELFResourceManager.format(Msg.OAM_OPERATION_INVALID_INPUT, t.getMessage()); + } else if (t instanceof InvalidStateException) { + exceptionMessage = String.format(AppcOam.INVALID_STATE_MESSAGE_FORMAT, + rpc.getAppcOperation(), appName, stateHelper.getCurrentOamState()); + oamCommandStatus = OAMCommandStatus.REJECTED; + errorMessage = EELFResourceManager.format(Msg.INVALID_STATE_TRANSITION, exceptionMessage); + } else if (t instanceof TimeoutException) { + oamCommandStatus = OAMCommandStatus.TIMEOUT; + errorMessage = EELFResourceManager.format(Msg.OAM_OPERATION_EXCEPTION, t, + appName, t.getClass().getSimpleName(), rpc.name(), exceptionMessage); + } else { + oamCommandStatus = OAMCommandStatus.UNEXPECTED_ERROR; + errorMessage = EELFResourceManager.format(Msg.OAM_OPERATION_EXCEPTION, t, + appName, t.getClass().getSimpleName(), rpc.name(), exceptionMessage); + } + + setStatus(oamCommandStatus, exceptionMessage); + + LoggingUtils.logErrorMessage( + String.valueOf(status.getCode()), + status.getMessage(), + LoggingConstants.TargetNames.APPC, + LoggingConstants.TargetNames.APPC_OAM_PROVIDER, + errorMessage, + AppcOam.class.getCanonicalName()); + + resetLogProperties(true); + } + + /** + * 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 + */ + void logDebug(String message, Object... args) { + if (logger.isDebugEnabled()) { + logger.debug(String.format(message, args)); + } + } +} diff --git a/appc-oam/appc-oam-bundle/src/main/java/org/onap/appc/oam/processor/BaseProcessor.java b/appc-oam/appc-oam-bundle/src/main/java/org/onap/appc/oam/processor/BaseProcessor.java new file mode 100644 index 000000000..414b94605 --- /dev/null +++ b/appc-oam/appc-oam-bundle/src/main/java/org/onap/appc/oam/processor/BaseProcessor.java @@ -0,0 +1,216 @@ +/*- + * ============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.processor; + +import com.att.eelf.configuration.EELFLogger; +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.i18n.Msg; +import org.onap.appc.oam.OAMCommandStatus; +import org.onap.appc.oam.util.AsyncTaskHelper; +import org.onap.appc.oam.util.BundleHelper; +import org.onap.appc.oam.util.ConfigurationHelper; +import org.onap.appc.oam.util.OperationHelper; +import org.onap.appc.oam.util.StateHelper; +import org.onap.appc.statemachine.impl.readers.AppcOamStates; + +import java.util.Date; +import java.util.concurrent.Future; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.TimeoutException; + +/** + * Base processor for OAM APIs, such as maintenance mode, restart, start and stop API. + * + *

This class holds the general API request sync handling methods for all OAM APIs. + *

Specific API processor will overwrite the general methods to add specific behaviors. + */ +public abstract class BaseProcessor extends BaseCommon { + /** lock to serialize incoming OAM operations. */ + private static final Object LOCK = new Object(); + + final AsyncTaskHelper asyncTaskHelper; + final BundleHelper bundleHelper; + + /** the requestTimeoutSeconds to use for this OAM operation */ + private Integer requestTimeoutSeconds; + Msg auditMsg; + BaseActionRunnable runnable; + private Future scheduledRunnable = null; + + /** + * Constructor + * + * @param eelfLogger for logging + * @param configurationHelperIn for property reading + * @param stateHelperIn for APP-C OAM state checking + * @param asyncTaskHelperIn for scheduling async task + * @param operationHelperIn for operational helper + */ + BaseProcessor(EELFLogger eelfLogger, + ConfigurationHelper configurationHelperIn, + StateHelper stateHelperIn, + AsyncTaskHelper asyncTaskHelperIn, + OperationHelper operationHelperIn) { + super(eelfLogger, configurationHelperIn, stateHelperIn, operationHelperIn); + + asyncTaskHelper = asyncTaskHelperIn; + bundleHelper = new BundleHelper(eelfLogger, configurationHelper, stateHelper); + } + + /** + * Process synch handling and schedule asynch task + * + * @param requestInput of REST API request + * @return Status of new APP-C OAM state + */ + public Status processRequest(final Object requestInput) { + startTime = new Date(); + commonHeader = operationHelper.getCommonHeader(requestInput); + setStatus(OAMCommandStatus.ACCEPTED); + + try { + preProcess(requestInput); + scheduleAsyncTask(); + } catch (Exception e) { + setErrorStatus(e); + } finally { + postProcess(); + } + + return status; + } + + /** + * Preprocess before actual handling of the REST API call. Does: + *

- commonHeader validation + *

- get NextState as well as validate if next state is valid + *

- set logging properties + *

- set appcCurrentState to next state + * + * @throws InvalidInputException when commonHeader validation failed + * @throws APPCException when state validation failed + */ + protected void preProcess(final Object requestInput) + throws InvalidInputException, APPCException, InvalidStateException,InterruptedException,TimeoutException { + setInitialLogProperties(); + operationHelper.isInputValid(requestInput); + + //The OAM request may specify timeout value + requestTimeoutSeconds = operationHelper.getParamRequestTimeout(requestInput); + + //All OAM operation pass through here first to validate if an OAM state change is allowed. + //If a state change is allowed cancel the occurring OAM (if any) before starting this one. + //we will synchronized so that only one can do this at any given time. + synchronized(LOCK) { + AppcOamStates currentOamState = stateHelper.getCurrentOamState(); + + //make sure this OAM operation can transition to the desired OAM operation + AppcOamStates nextState = operationHelper.getNextState( + rpc.getAppcOperation(), currentOamState); + + stateHelper.setState(nextState); + + + try { + //cancel the BaseActionRunnable currently executing + //it got to be completely terminated before proceeding + asyncTaskHelper.cancelBaseActionRunnable( + rpc, + currentOamState, + getTimeoutMilliseconds(), + TimeUnit.MILLISECONDS + ); + } catch (TimeoutException e) { + stateHelper.setState(AppcOamStates.Error); + throw e; + } + + + } + } + + /** + * Post process includes audit logging as well as clear MDC properties. + */ + private void postProcess() { + auditInfoLog(auditMsg); + clearRequestLogProperties(); + } + + /** + * Schedule async task through AsyncTaskHelper. + */ + protected void scheduleAsyncTask() { + if (runnable == null) { + logger.error(String.format( + "Skipped schedule async task for rpc(%s) due to runnable is null", rpc.name())); + return; + } + + scheduledRunnable = asyncTaskHelper.scheduleBaseRunnable( + runnable, runnable::abortRunnable, getInitialDelayMillis(), getDelayMillis()); + } + + + /** + * The timeout for this OAM operation. The timeout source is chosen in the following order: + * request, config file, default value + * @return - the timeout for this OAM operation. + */ + long getTimeoutMilliseconds() { + return configurationHelper.getOAMOperationTimeoutValue(this.requestTimeoutSeconds); + } + + + /** + * @return initialDelayMillis - the time to delay first execution of {@link BaseActionRunnable} + */ + protected long getInitialDelayMillis(){ + return 0L; + } + + /** + * @return delayMillis the delay between the consecutive executions of {@link BaseActionRunnable} + */ + private long getDelayMillis(){ + return 1000L; + } + + /** + * Cancel the scheduled {@link BaseActionRunnable} through AsyncTaskHelper + */ + void cancelAsyncTask() { + if (scheduledRunnable == null) { + logger.error(String.format( + "Skipped cancel schedule async task for rpc(%s) due to scheduledRunnable is null", rpc.name())); + return; + } + scheduledRunnable.cancel(true); + } + +} diff --git a/appc-oam/appc-oam-bundle/src/main/java/org/onap/appc/oam/processor/OamMmodeProcessor.java b/appc-oam/appc-oam-bundle/src/main/java/org/onap/appc/oam/processor/OamMmodeProcessor.java new file mode 100644 index 000000000..23f9fd130 --- /dev/null +++ b/appc-oam/appc-oam-bundle/src/main/java/org/onap/appc/oam/processor/OamMmodeProcessor.java @@ -0,0 +1,170 @@ +/*- + * ============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.processor; + +import com.att.eelf.configuration.EELFLogger; +import org.onap.appc.exceptions.APPCException; +import org.onap.appc.exceptions.InvalidInputException; +import org.onap.appc.exceptions.InvalidStateException; +import org.onap.appc.i18n.Msg; +import org.onap.appc.oam.AppcOam; +import org.onap.appc.oam.OAMCommandStatus; +import org.onap.appc.oam.util.AsyncTaskHelper; +import org.onap.appc.oam.util.ConfigurationHelper; +import org.onap.appc.oam.util.OperationHelper; +import org.onap.appc.oam.util.StateHelper; +import org.onap.appc.requesthandler.LCMStateManager; +import org.onap.appc.requesthandler.RequestHandler; +import org.onap.appc.statemachine.impl.readers.AppcOamStates; + +import java.util.concurrent.TimeoutException; + +/** + * Processor to handle maintenance mode OAM API. + */ +public class OamMmodeProcessor extends BaseProcessor { + /** + * Constructor + * + * @param eelfLogger for logging + * @param configurationHelper for property reading + * @param stateHelper for APP-C OAM state checking + * @param asyncTaskHelper for scheduling async task + * @param operationHelper for operational helper + */ + public OamMmodeProcessor(EELFLogger eelfLogger, + ConfigurationHelper configurationHelper, + StateHelper stateHelper, + AsyncTaskHelper asyncTaskHelper, + OperationHelper operationHelper) { + super(eelfLogger, configurationHelper, stateHelper, asyncTaskHelper, operationHelper); + + rpc = AppcOam.RPC.maintenance_mode; + auditMsg = Msg.OAM_OPERATION_ENTERING_MAINTENANCE_MODE; + } + + @Override + protected void preProcess(final Object requestInput) + throws InvalidInputException, InvalidStateException, APPCException, InterruptedException, TimeoutException { + super.preProcess(requestInput); + + //Close the gate so that no more new LCM request will be excepted. + LCMStateManager lcmStateManager = operationHelper.getService(LCMStateManager.class); + lcmStateManager.disableLCMOperations(); + } + + @Override + protected void scheduleAsyncTask() { + runnable = new MyRunnable(this); + super.scheduleAsyncTask(); + } + + /** + * {@inheritDoc} + * For maintenance mode we want a longer delay before initial execution of {@link BaseActionRunnable} + * so that any accepted LCM actions have time to git scheduled in the Dispatcher. + */ + @Override + protected long getInitialDelayMillis(){ + //wait ten seconds before + return 10000L; + } + + /** + * This runnable does the async handling for the maintenance mode REST API, and will be scheduled to run + * until terminating condition reaches. + * + *

The runnable will continue run if:
+ * - the runnable is not canceled outside
+ * - the in progress LCM request count is not zero
+ *

When LCM request count reaches to zero, this runnable will:
+ * - post message through operationHelper
+ * - set APP-C OAM state to maintenance mode
+ * - audit log the state
+ * - terminate this runnable itself
+ */ + class MyRunnable extends BaseActionRunnable { + private int inprogressRequestCount; + + MyRunnable(BaseProcessor parent) { + super(parent); + + actionName = "OAM Maintenance mode"; + auditMsg = Msg.OAM_OPERATION_MAINTENANCE_MODE; + finalState = AppcOamStates.MaintenanceMode; + } + + @Override + boolean doAction() { + // always return true, so that we can check the LCM request count + return true; + } + + @Override + boolean checkState() { + logDebug(String.format("Executing %s task", actionName)); + + + boolean hasError = false; + try { + inprogressRequestCount = getInprogressLCMRequestCount(); + if (inprogressRequestCount > 0) { + // if there are still LCM request in progress, keep waiting + return false; + } + + setStatus(OAMCommandStatus.SUCCESS); + } catch (Exception e) { + setErrorStatus(e); + hasError = true; + } + + postAction(hasError ? AppcOamStates.Error : finalState); + return true; + } + + /** + * Get in progress LCM request count through RequestHandler. + * @return thecount of in progress LCM request + * @throws APPCException if RequestHandler throws it. + */ + private int getInprogressLCMRequestCount() throws APPCException { + RequestHandler requestHandler = operationHelper.getService(RequestHandler.class); + + if (requestHandler == null) { + return 0; + } + + return requestHandler.getInprogressRequestCount(); + } + + @Override + void keepWaiting() { + logDebug("The application '%s' has '%s' outstanding LCM request to complete" + + " before coming to a complete maintenance_mode.", + configurationHelper.getAppcName(), inprogressRequestCount); + } + } +} diff --git a/appc-oam/appc-oam-bundle/src/main/java/org/onap/appc/oam/processor/OamRestartProcessor.java b/appc-oam/appc-oam-bundle/src/main/java/org/onap/appc/oam/processor/OamRestartProcessor.java new file mode 100644 index 000000000..b23b4d2aa --- /dev/null +++ b/appc-oam/appc-oam-bundle/src/main/java/org/onap/appc/oam/processor/OamRestartProcessor.java @@ -0,0 +1,208 @@ +/*- + * ============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.processor; + +import com.att.eelf.configuration.EELFLogger; +import org.onap.appc.exceptions.APPCException; +import org.onap.appc.i18n.Msg; +import org.onap.appc.oam.AppcOam; +import org.onap.appc.oam.util.AsyncTaskHelper; +import org.onap.appc.oam.util.ConfigurationHelper; +import org.onap.appc.oam.util.OperationHelper; +import org.onap.appc.oam.util.StateHelper; +import org.onap.appc.requesthandler.LCMStateManager; +import org.onap.appc.statemachine.impl.readers.AppcOamStates; + +/** + * Processor to handle restart OAM API. + */ +public class OamRestartProcessor extends BaseProcessor { + /** + * Action phases: + *
-ToStop: call bundles stop + *
-Stopped: check if all bundle state reached stopped + *
-ToStart: call bundles start + *
-Started: action is full completed + *
-Error: indication of error, such as timeout reached, bundler operation failure and etc. + */ + private enum ActionPhases { + ToStop, + Stopped, + ToStart, + Started, + Error + } + + /** + * Constructor + * + * @param eelfLogger for logging + * @param configurationHelper for property reading + * @param stateHelper for APP-C OAM state checking + * @param asyncTaskHelper for scheduling async task + * @param operationHelper for operational helper + */ + public OamRestartProcessor(EELFLogger eelfLogger, + ConfigurationHelper configurationHelper, + StateHelper stateHelper, + AsyncTaskHelper asyncTaskHelper, + OperationHelper operationHelper) { + super(eelfLogger, configurationHelper, stateHelper, asyncTaskHelper, operationHelper); + + rpc = AppcOam.RPC.restart; + auditMsg = Msg.OAM_OPERATION_RESTARTING; + } + + @Override + protected void scheduleAsyncTask() { + runnable = new MyRunnable(this); + super.scheduleAsyncTask(); + } + + /** + * This runnable does the async handling for the restart REST API. And it will be scheduled to run one time. + * + *

This runnable will the following operations:
+ * - do APP-C OAM bundle stop and then start through BundlerHelper
+ * - and always enable LCM operation handling (which can be disabled through maintenance mode API).
+ *

Once above operations are done, the runnale will
+ * - post message through operatonHelper
+ * - set APP-C OAM state to started
+ * - audit log the state
+ */ + class MyRunnable extends BaseActionRunnable { + + ActionPhases currentPhase = ActionPhases.ToStop; + private LCMStateManager lcmStateManager; + + MyRunnable(BaseProcessor parent) { + super(parent); + + actionName = "OAM Restart"; + auditMsg = Msg.OAM_OPERATION_RESTARTED; + finalState = AppcOamStates.Started; + } + + /** + * Do restart action, include stop then start and always enable LCM operation. + * @return true if action is successful, false when aciton is failed or aborted + */ + @Override + boolean doAction() { + logDebug(String.format("Executing %s task at phase (%s)", + actionName, currentPhase == null ? "null" : currentPhase.name())); + + boolean isBundleOperationCompleted = true; + try { + switch (currentPhase) { + case ToStop: + isBundleOperationCompleted = bundleHelper.bundleOperations( + AppcOam.RPC.stop, bundleNameToFuture, myParent.asyncTaskHelper, this); + currentPhase = ActionPhases.Stopped; + break; + case Stopped: + // check state + AppcOamStates currentState = stateHelper.getBundlesState(); + if (currentState == AppcOamStates.Stopped) { + currentPhase = ActionPhases.ToStart; + } else { + logDebug(String.format("%s task is waiting in stopped phase, current state is %s", + actionName, currentState)); + } + break; + case ToStart: + isBundleOperationCompleted = bundleHelper.bundleOperations( + AppcOam.RPC.start, bundleNameToFuture, myParent.asyncTaskHelper, this); + currentPhase = ActionPhases.Started; + break; + case Error: + // do nothing + break; + default: + // Should not reach log it and return false; + logger.error("%s task doAction reached %s phase. not supported. return false.", + actionName, currentPhase.name()); + stateHelper.setState(AppcOamStates.Error); + return false; + } + + if (isTimeout("restart doAction") + || hasBundleOperationFailure()) { + currentPhase = ActionPhases.Error; + return true; + } + if (isBundleOperationCompleted) { + return true; + } + + setAbortStatus(); + } catch (APPCException e) { + setErrorStatus(e); + stateHelper.setState(AppcOamStates.Error); + } + + return false; + } + + /** + * With additional to get the LCMStateManager service + * @see BaseActionRunnable#checkState() + */ + @Override + boolean checkState() { + switch (currentPhase) { + case Started: + try { + lcmStateManager = operationHelper.getService(LCMStateManager.class); + return super.checkState(); + } catch (APPCException e) { + logDebug("LCMStateManager is not available."); + } + break; + default: + // in all the other ActionPhase, we want the run go back to doAction + return true; + } + return false; + } + + /** + * Final handling. The thread is cancelled. + * @param setState boolean to indicate if set OAM state or not + */ + @Override + void postDoAction(boolean setState) { + AppcOamStates newState = null; + if (setState) { + logDebug("Always enable LCM operation"); + lcmStateManager.enableLCMOperations(); + newState = finalState; + } + postAction(newState); + super.postDoAction(setState); + } + + } +} diff --git a/appc-oam/appc-oam-bundle/src/main/java/org/onap/appc/oam/processor/OamStartProcessor.java b/appc-oam/appc-oam-bundle/src/main/java/org/onap/appc/oam/processor/OamStartProcessor.java new file mode 100644 index 000000000..2ca353244 --- /dev/null +++ b/appc-oam/appc-oam-bundle/src/main/java/org/onap/appc/oam/processor/OamStartProcessor.java @@ -0,0 +1,151 @@ +/*- + * ============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.processor; + +import com.att.eelf.configuration.EELFLogger; +import org.onap.appc.exceptions.APPCException; +import org.onap.appc.i18n.Msg; +import org.onap.appc.oam.AppcOam; +import org.onap.appc.oam.util.AsyncTaskHelper; +import org.onap.appc.oam.util.ConfigurationHelper; +import org.onap.appc.oam.util.OperationHelper; +import org.onap.appc.oam.util.StateHelper; +import org.onap.appc.requesthandler.LCMStateManager; +import org.onap.appc.statemachine.impl.readers.AppcOamStates; + +/** + * Processor to handle start OAM API. + */ +public class OamStartProcessor extends BaseProcessor { + + /** + * Constructor + * + * @param eelfLogger for logging + * @param configurationHelper for property reading + * @param stateHelper for APP-C OAM state checking + * @param asyncTaskHelper for scheduling async task + * @param operationHelper for operational helper + */ + public OamStartProcessor(EELFLogger eelfLogger, + ConfigurationHelper configurationHelper, + StateHelper stateHelper, + AsyncTaskHelper asyncTaskHelper, + OperationHelper operationHelper) { + super(eelfLogger, configurationHelper, stateHelper, asyncTaskHelper, operationHelper); + + rpc = AppcOam.RPC.start; + auditMsg = Msg.OAM_OPERATION_STARTING; + } + + @Override + protected void scheduleAsyncTask() { + runnable = new MyRunnable(this); + super.scheduleAsyncTask(); + } + + /** + * This runnable does the async handling for the start REST API. And it will be scheduled to run one time. + * + *

This runnable will the following operations:
+ * - do APP-C OAM bundle start through BundlerHelper
+ * - and always enable LCM operation handling (which can be disabled through maintenance mode API).
+ *

Once above operations are done, the runnale will
+ * - post message through operatonHelper
+ * - set APP-C OAM state to started
+ * - audit log the state
+ */ + class MyRunnable extends BaseActionRunnable { + + private LCMStateManager lcmStateManager; + + MyRunnable(BaseProcessor parent) { + super(parent); + actionName = "OAM Start"; + auditMsg = Msg.OAM_OPERATION_STARTED; + finalState = AppcOamStates.Started; + } + + /** + * Do start action, include start bundle if needed and always enable LCM operation. + * @return true if action is successful, false when aciton is failed or aborted + */ + @Override + boolean doAction() { + logDebug(String.format("Executing %s task", actionName)); + + boolean isBundleOperationCompleted = true; + try { + if (stateHelper.getState() != AppcOamStates.Started) { + logDebug("Start - APPC OAM state is not started, start the bundles"); + isBundleOperationCompleted = bundleHelper.bundleOperations( + rpc, bundleNameToFuture, myParent.asyncTaskHelper, this); + } + + if (isBundleOperationCompleted) { + return true; + } + + setAbortStatus(); + } catch (APPCException e) { + setErrorStatus(e); + stateHelper.setState(AppcOamStates.Error); + } + + return false; + } + + /** + * With additional to get the LCMStateManager service + * @see BaseActionRunnable#checkState() + */ + @Override + boolean checkState() { + try { + lcmStateManager = operationHelper.getService(LCMStateManager.class); + return super.checkState(); + } catch (APPCException e) { + logDebug("LCMStateManager is not available."); + return false; + } + } + + /** + * Final handling + * @param setState boolean to indicate if set OAM state or not + */ + @Override + void postDoAction(boolean setState) { + AppcOamStates newState = null; + if (setState) { + logDebug("Always enable LCM operation"); + lcmStateManager.enableLCMOperations(); + newState = finalState; + } + postAction(newState); + super.postDoAction(setState); + } + } +} diff --git a/appc-oam/appc-oam-bundle/src/main/java/org/onap/appc/oam/processor/OamStopProcessor.java b/appc-oam/appc-oam-bundle/src/main/java/org/onap/appc/oam/processor/OamStopProcessor.java new file mode 100644 index 000000000..8710e0f08 --- /dev/null +++ b/appc-oam/appc-oam-bundle/src/main/java/org/onap/appc/oam/processor/OamStopProcessor.java @@ -0,0 +1,120 @@ +/*- + * ============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.processor; + +import com.att.eelf.configuration.EELFLogger; +import org.onap.appc.exceptions.APPCException; +import org.onap.appc.i18n.Msg; +import org.onap.appc.oam.AppcOam; +import org.onap.appc.oam.util.AsyncTaskHelper; +import org.onap.appc.oam.util.ConfigurationHelper; +import org.onap.appc.oam.util.OperationHelper; +import org.onap.appc.oam.util.StateHelper; +import org.onap.appc.statemachine.impl.readers.AppcOamStates; + +/** + * Processor to handle stop OAM API. + */ +public class OamStopProcessor extends BaseProcessor { + /** + * Constructor + * + * @param eelfLogger for logging + * @param configurationHelper for property reading + * @param stateHelper for APP-C OAM state checking + * @param asyncTaskHelper for scheduling async task + * @param operationHelper for operational helper + */ + public OamStopProcessor(EELFLogger eelfLogger, + ConfigurationHelper configurationHelper, + StateHelper stateHelper, + AsyncTaskHelper asyncTaskHelper, + OperationHelper operationHelper) { + super(eelfLogger, configurationHelper, stateHelper, asyncTaskHelper, operationHelper); + + rpc = AppcOam.RPC.stop; + auditMsg = Msg.OAM_OPERATION_STOPPING; + } + + + @Override + protected void scheduleAsyncTask() { + runnable = new MyRunnable(this); + super.scheduleAsyncTask(); + } + + /** + * This runnable does the async handling for the stop REST API. And it will be scheduled to run one time. + * + *

This runnable will the following operations:
+ * - do APP-C OAM bundle stop and then refresh through BundlerHelper
+ *

Once above operations are done, the runnale will
+ * - post message through operatonHelper
+ * - set APP-C OAM state to started
+ * - audit log the state
+ */ + class MyRunnable extends BaseActionRunnable { + + MyRunnable(BaseProcessor parent) { + super(parent); + actionName = "OAM Stop"; + auditMsg = Msg.OAM_OPERATION_STOPPED; + finalState = AppcOamStates.Stopped; + } + + /** + * Do stop action, include stop bundle . + * @return true if action is successful, false when aciton is failed. + */ + @Override + boolean doAction() { + logDebug(String.format("Executing %s task", actionName)); + + try { + boolean isBundleOperationCompleted = bundleHelper.bundleOperations( + rpc, bundleNameToFuture, myParent.asyncTaskHelper, this); + if (isBundleOperationCompleted) { + return true; + } + + setAbortStatus(); + } catch (APPCException e) { + setErrorStatus(e); + stateHelper.setState(AppcOamStates.Error); + } + return false; + } + + /** + * Final handling + * @param setState boolean to indicate if set OAM state or not + */ + @Override + void postDoAction(boolean setState) { + postAction(setState ? finalState : null); + super.postDoAction(setState); + } + } +} diff --git a/appc-oam/appc-oam-bundle/src/main/java/org/onap/appc/oam/util/AsyncTaskHelper.java b/appc-oam/appc-oam-bundle/src/main/java/org/onap/appc/oam/util/AsyncTaskHelper.java new file mode 100644 index 000000000..2f74bf5a9 --- /dev/null +++ b/appc-oam/appc-oam-bundle/src/main/java/org/onap/appc/oam/util/AsyncTaskHelper.java @@ -0,0 +1,394 @@ +/*- + * ============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 org.onap.appc.oam.AppcOam; +import org.onap.appc.oam.processor.BaseActionRunnable; +import org.onap.appc.statemachine.impl.readers.AppcOamStates; +import org.osgi.framework.Bundle; +import org.osgi.framework.FrameworkUtil; + +import java.util.HashSet; +import java.util.Set; +import java.util.concurrent.Callable; +import java.util.concurrent.CancellationException; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.Executors; +import java.util.concurrent.Future; +import java.util.concurrent.LinkedBlockingQueue; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.ThreadPoolExecutor; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.TimeoutException; +import java.util.function.Consumer; + +/** + * The AsyncTaskHelper class manages an internal parent child data structure. The parent is a transient singleton, + * meaning only one can exist at any given time. The parent is scheduled with the + * {@link #scheduleBaseRunnable(Runnable, Consumer, long, long)} and is executed at configured interval. It can be + * terminated by using the {@link Future#cancel(boolean)} or the {@link Future#cancel(boolean)} returned from \ + * {@link #scheduleBaseRunnable(Runnable, Consumer, long, long)}. + *

+ * The children are scheduled using {@link #submitBaseSubCallable(Callable)}} and can only be scheduled if a parent + * is scheduled. Children only execute once, but can be terminated preemptively by the {@link Future#cancel(boolean)} + * returned from {@link #submitBaseSubCallable(Callable)} or indirectly by terminating the parent via the method + * described above. + *

+ * This class augments the meaning of {@link Future#isDone()} in that it guarantees that this method only returns true + * if the scheduled {@link Runnable} or {@link Callable} is not currently executing and is not going to execute in the + * future. This is different than the Java core implementation of {@link Future#isDone()} in which it will return + * true immediately after the {@link Future#cancel(boolean)} is called. Even if a Thread is actively executing the + * {@link Runnable} or {@link Callable} and has not return yet. See Java BUG JDK-8073704 + *

+ * The parent {@link Future#isDone()} has an additional augmentation in that it will not return true until all of its + * children's {@link Future#isDone()} also return true. + * + */ +@SuppressWarnings("unchecked") +public class AsyncTaskHelper { + + private final EELFLogger logger; + private final ScheduledExecutorService scheduledExecutorService; + private final ThreadPoolExecutor bundleOperationService; + + /** Reference to {@link MyFuture} return from {@link #scheduleBaseRunnable(Runnable, Consumer, long, long)} */ + private MyFuture backgroundBaseRunnableFuture; + + /** The cancel Callback from {@link #scheduleBaseRunnable(Runnable, Consumer, long, long)} */ + private Consumer cancelCallBackForBaseRunnable; + + /** All Futures created by thus calls which have not completed -- {@link Future#isDone()} equals false */ + private Set myFutureSet = new HashSet<>(); + + /** + * Constructor + * @param eelfLogger of the logger + */ + public AsyncTaskHelper(EELFLogger eelfLogger) { + logger = eelfLogger; + + scheduledExecutorService = Executors.newSingleThreadScheduledExecutor( + (runnable) -> { + Bundle bundle = FrameworkUtil.getBundle(AppcOam.class); + return new Thread(runnable, bundle.getSymbolicName() + " scheduledExecutor"); + } + ); + + bundleOperationService = new ThreadPoolExecutor( + 0, + 10, + 10, + TimeUnit.SECONDS, + new LinkedBlockingQueue(), //BlockingQueue workQueue + (runnable) -> { + Bundle bundle = FrameworkUtil.getBundle(AppcOam.class); + return new Thread(runnable, bundle.getSymbolicName() + " bundle operation executor"); + } + ); + } + + /** + * Terminate the class ScheduledExecutorService + */ + public void close() { + logDebug("Start shutdown scheduleExcutorService."); + bundleOperationService.shutdownNow(); + scheduledExecutorService.shutdownNow(); + logDebug("Completed shutdown scheduleExcutorService."); + } + + + /** + * Cancel currently executing {@link BaseActionRunnable} if any. + * This method returns immediately if there is currently no {@link BaseActionRunnable} actively executing. + * @param rpcCausingAbort - The RPC causing the abort + * @param stateBeingAbborted - The current state being canceled + * @param timeout - The amount of time to wait for a cancel to complete + * @param timeUnit - The unit of time of timeout + * @throws TimeoutException - If {@link BaseActionRunnable} has not completely cancelled within the timeout period + * @throws InterruptedException - If the Thread waiting for the abort + */ + public synchronized void cancelBaseActionRunnable(final AppcOam.RPC rpcCausingAbort, + AppcOamStates stateBeingAbborted, + long timeout, TimeUnit timeUnit) + throws TimeoutException,InterruptedException { + + final MyFuture localBackgroundBaseRunnableFuture = backgroundBaseRunnableFuture; + final Consumer localCancelCallBackForBaseRunnable = cancelCallBackForBaseRunnable; + + if (localBackgroundBaseRunnableFuture == null || localBackgroundBaseRunnableFuture.isDone()) { + return; + } + + if (localCancelCallBackForBaseRunnable != null) { + localCancelCallBackForBaseRunnable.accept(rpcCausingAbort); + } + localBackgroundBaseRunnableFuture.cancel(true); + + long timeoutMillis = timeUnit.toMillis(timeout); + long expiryTime = System.currentTimeMillis() + timeoutMillis; + while (!(localBackgroundBaseRunnableFuture.isDone())) { + long sleepTime = expiryTime - System.currentTimeMillis(); + if (sleepTime < 1) { + break; + } + this.wait(sleepTime); + } + + if (!localBackgroundBaseRunnableFuture.isDone()) { + throw new TimeoutException(String.format("Unable to abort %s in timely manner.",stateBeingAbborted)); + } + } + + /** + * Schedule a {@link BaseActionRunnable} to begin async execution. This is the Parent {@link Runnable} for the + * children that are submitted by {@link #submitBaseSubCallable(Callable)} + * + * The currently executing {@link BaseActionRunnable} must fully be terminated before the next can be scheduled. + * This means all Tasks' {@link MyFuture#isDone()} must equal true and all threads must return to their respective + * thread pools. + * + * @param runnable of the to be scheduled service. + * @param cancelCallBack to be invoked when + * {@link #cancelBaseActionRunnable(AppcOam.RPC, AppcOamStates, long, TimeUnit)} is invoked. + * @param initialDelayMillis the time to delay first execution + * @param delayMillis the delay between the termination of one + * execution and the commencement of the next + * @return The {@link BaseActionRunnable}'s {@link Future} + * @throws IllegalStateException if there is currently executing Task + */ + public synchronized Future scheduleBaseRunnable(final Runnable runnable, + final Consumer cancelCallBack, + long initialDelayMillis, + long delayMillis) + throws IllegalStateException { + + if (backgroundBaseRunnableFuture != null && !backgroundBaseRunnableFuture.isDone()) { + throw new IllegalStateException("Unable to schedule background task when one is already running. All task must fully terminated before another can be scheduled. "); + } + + this.cancelCallBackForBaseRunnable = cancelCallBack; + + backgroundBaseRunnableFuture = new MyFuture(runnable) { + /** + * augments the cancel operation to cancel all subTack too, + */ + @Override + public boolean cancel(final boolean mayInterruptIfRunning) { + boolean cancel; + synchronized (AsyncTaskHelper.this) { + cancel = super.cancel(mayInterruptIfRunning); + //clone the set to prevent java.util.ConcurrentModificationException. The synchronized prevents + //other threads from modifying this set, but not itself. The f->f.cancel may modify myFutureSet by + //removing an entry which breaks the iteration in the forEach. + (new HashSet(myFutureSet)) + .stream().filter(f->!this.equals(f)).forEach(f->f.cancel(mayInterruptIfRunning)); + } + return cancel; + } + + /** + * augments the isDone operation to return false until all subTask have completed too. + */ + @Override + public boolean isDone() { + synchronized (AsyncTaskHelper.this) { + return myFutureSet.isEmpty(); + } + } + }; + backgroundBaseRunnableFuture.setFuture( + scheduledExecutorService.scheduleWithFixedDelay( + backgroundBaseRunnableFuture, initialDelayMillis, delayMillis, TimeUnit.MILLISECONDS) + ); + return backgroundBaseRunnableFuture; + } + + /** + * Submits children {@link Callable} to be executed as soon as possible, A parent must have been scheduled + * previously via {@link #scheduleBaseRunnable(Runnable, Consumer, long, long)} + * @param callable the Callable to be submitted + * @return The {@link Callable}'s {@link Future} + */ + synchronized Future submitBaseSubCallable(final Callable callable) { + + if (backgroundBaseRunnableFuture == null + || backgroundBaseRunnableFuture.isCancelled() + || backgroundBaseRunnableFuture.isDone()){ + throw new IllegalStateException("Unable to schedule subCallable when a base Runnable is not running."); + } + + //Make sure the pool is ready to go + if(bundleOperationService.getPoolSize() != bundleOperationService.getMaximumPoolSize()){ + bundleOperationService.setCorePoolSize(bundleOperationService.getMaximumPoolSize()); + bundleOperationService.prestartAllCoreThreads(); + bundleOperationService.setCorePoolSize(0); + } + + MyFuture myFuture = new MyFuture(callable); + myFuture.setFuture(bundleOperationService.submit((Callable)myFuture)); + return myFuture; + } + + /** + * 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)); + } + } + + /** + * This class has two purposes. First it insures {@link #isDone()} only returns true if the deligate is not + * currently running and will not be running in the future: See Java BUG JDK-8073704 Second this class maintains + * the {@link #myFutureSet } by insurring that itself is removed when {@link #isDone()} returns true. + * + * See {@link #scheduleBaseRunnable(Runnable, Consumer, long, long)} and {@link #submitBaseSubCallable(Callable)} + * for usage of this class + */ + private class MyFuture implements Future, Runnable, Callable { + + private Future future; + private final Runnable runnable; + private final Callable callable; + private boolean isRunning; + + MyFuture(Runnable runnable) { + this.runnable = runnable; + this.callable = null; + myFutureSet.add(this); + } + + MyFuture(Callable callable) { + this.runnable = null; + this.callable = callable; + myFutureSet.add(this); + } + + void setFuture(Future future) { + this.future = future; + } + + @Override + public boolean cancel(boolean mayInterruptIfRunning) { + synchronized (AsyncTaskHelper.this) { + if (!isRunning) { + myFutureSetRemove(); + } + + return future.cancel(mayInterruptIfRunning); + } + } + + @Override + public boolean isCancelled() { + synchronized (AsyncTaskHelper.this) { + return future.isCancelled(); + } + } + + @Override + public boolean isDone() { + synchronized (AsyncTaskHelper.this) { + return future.isDone() && !isRunning; + } + } + + @Override + public T get() throws InterruptedException, ExecutionException { + return future.get(); + } + + @Override + public T get(long timeout, TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException { + return future.get(timeout, unit); + } + + @Override + public void run() { + synchronized (AsyncTaskHelper.this) { + if(future.isCancelled()){ + return; + } + isRunning = true; + } + try { + runnable.run(); + } finally { + synchronized (AsyncTaskHelper.this) { + isRunning = false; + + //The Base Runnable is expected to run again. + //unless it has been canceled. + //so only removed if it is canceled. + if (future.isCancelled()) { + myFutureSetRemove(); + } + } + } + } + + @Override + public T call() throws Exception { + synchronized (AsyncTaskHelper.this) { + if(future.isCancelled()){ + throw new CancellationException(); + } + isRunning = true; + } + try { + return callable.call(); + } finally { + synchronized (AsyncTaskHelper.this){ + isRunning = false; + myFutureSetRemove(); + } + } + } + + + /** + * Removes this from the the myFutureSet. + * When all the BaseActionRunnable is Done notify any thread waiting in + * {@link AsyncTaskHelper#cancelBaseActionRunnable(AppcOam.RPC, AppcOamStates, long, TimeUnit)} + */ + void myFutureSetRemove(){ + synchronized (AsyncTaskHelper.this) { + myFutureSet.remove(this); + if(myFutureSet.isEmpty()){ + backgroundBaseRunnableFuture = null; + cancelCallBackForBaseRunnable = null; + AsyncTaskHelper.this.notifyAll(); + + } + } + } + + } +} diff --git a/appc-oam/appc-oam-bundle/src/main/java/org/onap/appc/oam/util/BundleFilter.java b/appc-oam/appc-oam-bundle/src/main/java/org/onap/appc/oam/util/BundleFilter.java new file mode 100644 index 000000000..6dd98f165 --- /dev/null +++ b/appc-oam/appc-oam-bundle/src/main/java/org/onap/appc/oam/util/BundleFilter.java @@ -0,0 +1,128 @@ +/*- + * ============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 org.osgi.framework.Bundle; + +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; +import java.util.regex.Pattern; + + + +/** + * + * Utility Class that splits a given bundleSet into two sets: bundleToStopSet and + * bundleToNotStopSet + * + * The bundleToStopSet is defined as: all bundles which match at least one of + * the stopRegexes but exceptRegexes none of the + * + * The bundleToNotStopSet is defined as all bundles which are not a member of + * the bundleToStopSet + * + */ +class BundleFilter { + + private final Map bundleToStopSet; + private final Map bundleToNotStopSet; + + + /** + * BundleFilter a bundle filter + * @param stopRegexes - An array of regular expression used to pick out which bundles are candidates for stopping + * @param exceptRegexes - An array of regular expression used to override which bundles are candidates for stopping + * @param bundles - An array of the bundle to be split into {@link #getBundlesToStop()} {@link #getBundlesToNotStop()} + */ + BundleFilter(String[] stopRegexes, String[] exceptRegexes, Bundle[] bundles) { + + Pattern[] stopPatterns = toPattern(stopRegexes); + Pattern[] exceptPatterns = toPattern(exceptRegexes); + + Map bundleToStop = new HashMap<>(); + Map bundleToNotStop = new HashMap<>(); + + for (Bundle bundle : bundles) { + String symbolicName = bundle.getSymbolicName(); + if (isMatch(symbolicName,stopPatterns) && !isMatch(symbolicName,exceptPatterns)) { + bundleToStop.put(symbolicName, bundle); + } else { + bundleToNotStop.put(symbolicName, bundle); + } + } + + this.bundleToStopSet = Collections.unmodifiableMap(bundleToStop); + this.bundleToNotStopSet = Collections.unmodifiableMap(bundleToNotStop); + } + + /** + * Determines if the value matches any of the regular expressions. + * + * @param value + * - the value that is to be matched + * @param patterns + * - the array of {@link Pattern} to match the value against + * @return boolean true if there is a match + */ + private boolean isMatch(String value,Pattern[] patterns) { + for (Pattern pattern : patterns) { + if (pattern.matcher(value).matches()) { + return true; + } + } + return false; + } + + /** + * This method converts an Array of regular expression in String form into a + * Array of {@link Pattern} + * + * @param regex + * - A string array of regular expressions + * @return Pattern Array of compiled regular expressions + */ + private Pattern[] toPattern(String[] regex) { + Pattern[] pattern = new Pattern[regex.length]; + for (int i = 0; i < regex.length; i++ ) { + pattern[i] = Pattern.compile(regex[i]); + } + return pattern; + } + + + /**@return Map of bundles that are to be stopped */ + Map getBundlesToStop(){ + return bundleToStopSet; + } + + /** + * + * @return Map of bundles that are not to be stopped + */ + Map getBundlesToNotStop() { + return bundleToNotStopSet; + } +} diff --git a/appc-oam/appc-oam-bundle/src/main/java/org/onap/appc/oam/util/BundleHelper.java b/appc-oam/appc-oam-bundle/src/main/java/org/onap/appc/oam/util/BundleHelper.java new file mode 100644 index 000000000..3a4602542 --- /dev/null +++ b/appc-oam/appc-oam-bundle/src/main/java/org/onap/appc/oam/util/BundleHelper.java @@ -0,0 +1,274 @@ +/*- + * ============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 org.apache.commons.lang3.ArrayUtils; +import org.onap.appc.exceptions.APPCException; +import org.onap.appc.oam.AppcOam; +import org.onap.appc.oam.processor.BaseCommon; +import org.onap.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> threads, + AsyncTaskHelper taskHelper, + BaseCommon baseCommon) + 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 appcLcmBundles = getAppcLcmBundles(); + for (Map.Entry 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.submitBaseSubCallable(new BundleTask(rpc, bundle,baseCommon))); + } + + logDebug(String.format("Leaving OAM bundleOperations with rpc (%s) with complete(%s), elasped (%d) ms.", + rpc.name(), Boolean.toString(isBundleOperationComplete), getElapseTimeMs(mStartTime))); + + return isBundleOperationComplete; + } + + private long getElapseTimeMs(long mStartTime) { + return System.currentTimeMillis() - mStartTime; + } + + /** + * Check if all BundleTasks are completed + * @param bundleNameFutureMap with bundle name and BundleTask Future object + * @return true if all are done, otherwise, false + */ + public boolean isAllTaskDone(Map> bundleNameFutureMap) { + boolean anyNotDone = bundleNameFutureMap.values().stream().anyMatch((f) -> !f.isDone()); + return !anyNotDone; + } + + /** + * Cancel BundleTasks which are not finished + * @param bundleNameFutureMap with bundle name and BundleTask Future object + */ + public void cancelUnfinished(Map> bundleNameFutureMap) { + bundleNameFutureMap.values().stream().filter((f) + -> !f.isDone()).forEach((f) + -> f.cancel(true)); + } + + /** + * Get number of failed BundleTasks + * @param bundleNameFutureMap with bundle name and BundleTask Future object + * @return number(long) of the failed BundleTasks + */ + public long getFailedMetrics(Map> bundleNameFutureMap) { + return bundleNameFutureMap.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 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 { + Exception failException; + + private AppcOam.RPC rpc; + private Bundle bundle; + private String bundleName; + private String actionName; + private final BaseCommon baseCommon; + + BundleTask(AppcOam.RPC rpcIn, Bundle bundleIn, BaseCommon baseCommon) { + rpc = rpcIn; + actionName = rpc.getAppcOperation().toString(); + bundle = bundleIn; + bundleName = bundle.getSymbolicName(); + this.baseCommon = baseCommon; + } + + @Override + public BundleTask call() throws Exception { + try { + baseCommon.setInitialLogProperties(); + + 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, getElapseTimeMs(bundleOperStartTime))); + } catch (BundleException e) { + logger.error(String.format("Exception encountered when OAM %s bundle %s ", + actionName, bundleName), e); + failException = e; + } + finally { + baseCommon.clearRequestLogProperties(); + } + return this; + } + } +} diff --git a/appc-oam/appc-oam-bundle/src/main/java/org/onap/appc/oam/util/ConfigurationHelper.java b/appc-oam/appc-oam-bundle/src/main/java/org/onap/appc/oam/util/ConfigurationHelper.java new file mode 100644 index 000000000..3c5629f11 --- /dev/null +++ b/appc-oam/appc-oam-bundle/src/main/java/org/onap/appc/oam/util/ConfigurationHelper.java @@ -0,0 +1,106 @@ +/*- + * ============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 org.apache.commons.lang3.ArrayUtils; +import org.onap.appc.Constants; +import org.onap.appc.configuration.Configuration; +import org.onap.appc.configuration.ConfigurationFactory; + +import java.util.concurrent.TimeUnit; + +/** + * Utility class provides general configuration helps + */ +public class ConfigurationHelper { + final static String PROP_KEY_APPC_NAME = Constants.PROPERTY_APPLICATION_NAME; + final static String PROP_KEY_METRIC_STATE = "metric.enabled"; + private final String OAM_OPERATION_TIMEOUT_SECOND = "appc.OAM.api.timeout"; + /** Default operation timeout set to 1 minute */ + private final int DEFAULT_OAM_OPERATION_TIMEOUT = 60; + + private final EELFLogger logger; + private Configuration configuration = ConfigurationFactory.getConfiguration(); + + public ConfigurationHelper(EELFLogger eelfLogger) { + logger = eelfLogger; + } + + public String getAppcName() { + return configuration.getProperty(PROP_KEY_APPC_NAME); + } + + public boolean isMetricEnabled() { + return configuration.getBooleanProperty(PROP_KEY_METRIC_STATE, false); + } + + public Configuration getConfig() { + return configuration; + } + + /** + * Read property value of a specified property key + * + * @param propertyKey string of the property key + * @return String[] of the property values associated with the propertyKey + */ + String[] readProperty(String propertyKey) { + String propertyValue = configuration.getProperty(propertyKey); + if (propertyValue == null) { + return ArrayUtils.EMPTY_STRING_ARRAY; + } + + if (logger.isDebugEnabled()) { + logger.debug(String.format("Property[%s] has value (%s).", propertyKey, propertyValue)); + } + + if (propertyValue.contains(",")) { + return propertyValue.split("\\s*,\\s*"); + } + return new String[]{propertyValue}; + } + + + + + + /** + * This method returns timeout in milliseconds. The source is chosen in the following order: + * The overrideTimeoutSeconds argument + * or {@link #OAM_OPERATION_TIMEOUT_SECOND} found in the configuration file + * or the {@link #DEFAULT_OAM_OPERATION_TIMEOUT} + * @param overrideTimeoutSeconds or null to us the other sources + * @return timeout in milliseconds + */ + public long getOAMOperationTimeoutValue(Integer overrideTimeoutSeconds) { + return TimeUnit.SECONDS.toMillis( + overrideTimeoutSeconds == null ? + getConfig().getIntegerProperty(OAM_OPERATION_TIMEOUT_SECOND, DEFAULT_OAM_OPERATION_TIMEOUT) + : + overrideTimeoutSeconds + ); + } +} diff --git a/appc-oam/appc-oam-bundle/src/main/java/org/onap/appc/oam/util/OperationHelper.java b/appc-oam/appc-oam-bundle/src/main/java/org/onap/appc/oam/util/OperationHelper.java new file mode 100644 index 000000000..9eec0b67b --- /dev/null +++ b/appc-oam/appc-oam-bundle/src/main/java/org/onap/appc/oam/util/OperationHelper.java @@ -0,0 +1,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 : + *

- + * Bug 8088 - Mandatory attributes in RPC input are not honoured + *

- + * Bug 5830 - Mandatory leaf enforcement is not correct with presence container + * + * @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 of the expected service instance + * @return service instance of the expected + * @throws APPCException when cannot find service reference or service isntance + */ + public T getService(Class _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); + } +} diff --git a/appc-oam/appc-oam-bundle/src/main/java/org/onap/appc/oam/util/StateHelper.java b/appc-oam/appc-oam-bundle/src/main/java/org/onap/appc/oam/util/StateHelper.java new file mode 100644 index 000000000..871a07676 --- /dev/null +++ b/appc-oam/appc-oam-bundle/src/main/java/org/onap/appc/oam/util/StateHelper.java @@ -0,0 +1,144 @@ +/*- + * ============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 org.opendaylight.yang.gen.v1.org.onap.appc.oam.rev170303.AppcState; +import org.onap.appc.statemachine.impl.readers.AppcOamStates; +import org.osgi.framework.Bundle; + +import java.util.Map; + +/* + * Utility class provides general state helps + */ +public class StateHelper { + /** logger inherited from AppcOam */ + private final EELFLogger logger; + private ConfigurationHelper configurationHelper; + /** APP-C OAM current state in AppcOamStates value */ + private volatile AppcOamStates appcOamCurrentState; + + /** + * Constructor + * + * @param eelfLogger of the logger + */ + public StateHelper(EELFLogger eelfLogger, ConfigurationHelper cHelper) { + logger = eelfLogger; + configurationHelper = cHelper; + appcOamCurrentState = AppcOamStates.Unknown; + } + + /** + * Set the passed in state to the class appOamCurrentState. + * + * @param appcOamStates of the new state + */ + public void setState(AppcOamStates appcOamStates) { + appcOamCurrentState = appcOamStates; + } + + /** + * Get the state + * @return the class appOamCurrentState + */ + public AppcOamStates getState() { + return appcOamCurrentState; + } + + /** + * Validate if the passed in state is the same as the class appOamCurrentState. + * + * @param appcOamStates of the to be compared state + * @return true if they are the same, otherwise false + */ + boolean isSameState(AppcOamStates appcOamStates) { + return appcOamCurrentState == appcOamStates; + } + + /** + * Get APP-C OAM current state + * + *

When appcOamCurrentState is null or unknown, reset it with APPC LCM bundle state. + * + * @return AppcOamStates of the current APP-C OAM state + */ + public AppcOamStates getCurrentOamState() { + if (appcOamCurrentState == null || appcOamCurrentState.equals(AppcOamStates.Unknown)) { + appcOamCurrentState = getBundlesState(); + } + return appcOamCurrentState; + } + + /** + * Use getCurrentOamState to get current OAM AppcOamStates and then convert to AppcState of Yang. + * + * @return AppcState of current OAM state + */ + public AppcState getCurrentOamYangState() { + try { + AppcOamStates appcOamStates = getCurrentOamState(); + return AppcState.valueOf(appcOamStates.name()); + } catch (Exception ex) { + logger.error(String.format("Unable to determine the current APP-C OAM state due to %s.", ex.getMessage())); + } + return AppcState.Unknown; + } + + /** + * Get APPC state from the state of the set of APPC LCM bundles. + *

The state of each bundle will be checked and the lowest state will be uses as the returning AppcOamStates. + *

The bundle state order are defined in OSGI bundle (@see org.osgi.framework.Bundle) class + * as the int value assigned to each state as the following:
+ * - UNINSTALLED (1)
+ * - INSTALLED (2)
+ * - RESOLVED (4)
+ * - STARTING (8)
+ * - STOPPING (16)
+ * - ACTIVE (32)
+ * + * @return AppcOamStates + */ + public AppcOamStates getBundlesState() { + BundleHelper bundleHelper = new BundleHelper(logger, configurationHelper, this); + Map lcmBundleMap = bundleHelper.getAppcLcmBundles(); + if (lcmBundleMap == null || lcmBundleMap.isEmpty()) { + return AppcOamStates.Unknown; + } + + // As we are picking up the lowest bundle state as general APP-C state, we will start with ACTIVE + int currentState = Bundle.ACTIVE; + for (Bundle bundle : lcmBundleMap.values()) { + int bundleState = bundle.getState(); + logger.trace(String.format("getBundlesState: [%s] has state (%d)", bundle.getSymbolicName(), bundleState)); + if (bundleState < currentState) { + currentState = bundleState; + } + } + return AppcOamStates.getOamStateFromBundleState(currentState); + } + +} diff --git a/appc-oam/appc-oam-bundle/src/main/java/org/opendaylight/yang/gen/v1/org/onap/appc/oam/impl/rev170303/AppcOamModule.java b/appc-oam/appc-oam-bundle/src/main/java/org/opendaylight/yang/gen/v1/org/onap/appc/oam/impl/rev170303/AppcOamModule.java new file mode 100644 index 000000000..c978e3a45 --- /dev/null +++ b/appc-oam/appc-oam-bundle/src/main/java/org/opendaylight/yang/gen/v1/org/onap/appc/oam/impl/rev170303/AppcOamModule.java @@ -0,0 +1,55 @@ +/*- + * ============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.opendaylight.yang.gen.v1.org.onap.appc.oam.impl.rev170303; + +import org.onap.appc.oam.AppcOam; + +public class AppcOamModule extends org.opendaylight.yang.gen.v1.org.onap.appc.oam.impl.rev170303.AbstractAppcOamModule { + public AppcOamModule(org.opendaylight.controller.config.api.ModuleIdentifier identifier, org.opendaylight.controller.config.api.DependencyResolver dependencyResolver) { + super(identifier, dependencyResolver); + } + + public AppcOamModule(org.opendaylight.controller.config.api.ModuleIdentifier identifier, org.opendaylight.controller.config.api.DependencyResolver dependencyResolver, org.opendaylight.yang.gen.v1.org.onap.appc.oam.impl.rev170303.AppcOamModule oldModule, java.lang.AutoCloseable oldInstance) { + super(identifier, dependencyResolver, oldModule, oldInstance); + } + + @Override + public void customValidation() { + // add custom validation form module attributes here. + } + + @Override + public java.lang.AutoCloseable createInstance() { + final AppcOam oam = new AppcOam(getDataBrokerDependency(), getNotificationServiceDependency(), getRpcRegistryDependency()); + return new AutoCloseable() { + + @Override + public void close() throws Exception { + oam.close(); + } + }; + } + +} diff --git a/appc-oam/appc-oam-bundle/src/main/java/org/opendaylight/yang/gen/v1/org/onap/appc/oam/impl/rev170303/AppcOamModuleFactory.java b/appc-oam/appc-oam-bundle/src/main/java/org/opendaylight/yang/gen/v1/org/onap/appc/oam/impl/rev170303/AppcOamModuleFactory.java new file mode 100644 index 000000000..6913a68f0 --- /dev/null +++ b/appc-oam/appc-oam-bundle/src/main/java/org/opendaylight/yang/gen/v1/org/onap/appc/oam/impl/rev170303/AppcOamModuleFactory.java @@ -0,0 +1,37 @@ +/*- + * ============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========================================================= + */ + +/* +* Generated file +* +* Generated from: yang module name: appc-oam-impl yang module local name: appc-oam-impl +* Generated by: org.opendaylight.controller.config.yangjmxgenerator.plugin.JMXGenerator +* Generated at: Mon Apr 24 16:25:46 IST 2017 +* +* Do not modify this file unless it is present under src/main directory +*/ +package org.opendaylight.yang.gen.v1.org.onap.appc.oam.impl.rev170303; +public class AppcOamModuleFactory extends org.opendaylight.yang.gen.v1.org.onap.appc.oam.impl.rev170303.AbstractAppcOamModuleFactory { + +} diff --git a/appc-oam/appc-oam-bundle/src/main/java/org/opendaylight/yang/gen/v1/org/openecomp/appc/oam/impl/rev170303/AppcOamModule.java b/appc-oam/appc-oam-bundle/src/main/java/org/opendaylight/yang/gen/v1/org/openecomp/appc/oam/impl/rev170303/AppcOamModule.java deleted file mode 100644 index c978e3a45..000000000 --- a/appc-oam/appc-oam-bundle/src/main/java/org/opendaylight/yang/gen/v1/org/openecomp/appc/oam/impl/rev170303/AppcOamModule.java +++ /dev/null @@ -1,55 +0,0 @@ -/*- - * ============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.opendaylight.yang.gen.v1.org.onap.appc.oam.impl.rev170303; - -import org.onap.appc.oam.AppcOam; - -public class AppcOamModule extends org.opendaylight.yang.gen.v1.org.onap.appc.oam.impl.rev170303.AbstractAppcOamModule { - public AppcOamModule(org.opendaylight.controller.config.api.ModuleIdentifier identifier, org.opendaylight.controller.config.api.DependencyResolver dependencyResolver) { - super(identifier, dependencyResolver); - } - - public AppcOamModule(org.opendaylight.controller.config.api.ModuleIdentifier identifier, org.opendaylight.controller.config.api.DependencyResolver dependencyResolver, org.opendaylight.yang.gen.v1.org.onap.appc.oam.impl.rev170303.AppcOamModule oldModule, java.lang.AutoCloseable oldInstance) { - super(identifier, dependencyResolver, oldModule, oldInstance); - } - - @Override - public void customValidation() { - // add custom validation form module attributes here. - } - - @Override - public java.lang.AutoCloseable createInstance() { - final AppcOam oam = new AppcOam(getDataBrokerDependency(), getNotificationServiceDependency(), getRpcRegistryDependency()); - return new AutoCloseable() { - - @Override - public void close() throws Exception { - oam.close(); - } - }; - } - -} diff --git a/appc-oam/appc-oam-bundle/src/main/java/org/opendaylight/yang/gen/v1/org/openecomp/appc/oam/impl/rev170303/AppcOamModuleFactory.java b/appc-oam/appc-oam-bundle/src/main/java/org/opendaylight/yang/gen/v1/org/openecomp/appc/oam/impl/rev170303/AppcOamModuleFactory.java deleted file mode 100644 index 6913a68f0..000000000 --- a/appc-oam/appc-oam-bundle/src/main/java/org/opendaylight/yang/gen/v1/org/openecomp/appc/oam/impl/rev170303/AppcOamModuleFactory.java +++ /dev/null @@ -1,37 +0,0 @@ -/*- - * ============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========================================================= - */ - -/* -* Generated file -* -* Generated from: yang module name: appc-oam-impl yang module local name: appc-oam-impl -* Generated by: org.opendaylight.controller.config.yangjmxgenerator.plugin.JMXGenerator -* Generated at: Mon Apr 24 16:25:46 IST 2017 -* -* Do not modify this file unless it is present under src/main directory -*/ -package org.opendaylight.yang.gen.v1.org.onap.appc.oam.impl.rev170303; -public class AppcOamModuleFactory extends org.opendaylight.yang.gen.v1.org.onap.appc.oam.impl.rev170303.AbstractAppcOamModuleFactory { - -} diff --git a/appc-oam/appc-oam-bundle/src/main/java/org/openecomp/appc/oam/AppcOam.java b/appc-oam/appc-oam-bundle/src/main/java/org/openecomp/appc/oam/AppcOam.java deleted file mode 100644 index 97938339c..000000000 --- a/appc-oam/appc-oam-bundle/src/main/java/org/openecomp/appc/oam/AppcOam.java +++ /dev/null @@ -1,339 +0,0 @@ -/*- - * ============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; - -import com.att.eelf.configuration.EELFLogger; -import com.att.eelf.configuration.EELFManager; -import com.google.common.util.concurrent.Futures; -import org.opendaylight.controller.md.sal.binding.api.DataBroker; -import org.opendaylight.controller.sal.binding.api.BindingAwareBroker; -import org.opendaylight.controller.sal.binding.api.NotificationProviderService; -import org.opendaylight.controller.sal.binding.api.RpcProviderRegistry; -import org.opendaylight.yang.gen.v1.org.onap.appc.oam.rev170303.AppcOamService; -import org.opendaylight.yang.gen.v1.org.onap.appc.oam.rev170303.AppcState; -import org.opendaylight.yang.gen.v1.org.onap.appc.oam.rev170303.GetAppcStateOutput; -import org.opendaylight.yang.gen.v1.org.onap.appc.oam.rev170303.GetAppcStateOutputBuilder; -import org.opendaylight.yang.gen.v1.org.onap.appc.oam.rev170303.GetMetricsOutput; -import org.opendaylight.yang.gen.v1.org.onap.appc.oam.rev170303.GetMetricsOutputBuilder; -import org.opendaylight.yang.gen.v1.org.onap.appc.oam.rev170303.MaintenanceModeInput; -import org.opendaylight.yang.gen.v1.org.onap.appc.oam.rev170303.MaintenanceModeOutput; -import org.opendaylight.yang.gen.v1.org.onap.appc.oam.rev170303.MaintenanceModeOutputBuilder; -import org.opendaylight.yang.gen.v1.org.onap.appc.oam.rev170303.RestartInput; -import org.opendaylight.yang.gen.v1.org.onap.appc.oam.rev170303.RestartOutput; -import org.opendaylight.yang.gen.v1.org.onap.appc.oam.rev170303.RestartOutputBuilder; -import org.opendaylight.yang.gen.v1.org.onap.appc.oam.rev170303.StartInput; -import org.opendaylight.yang.gen.v1.org.onap.appc.oam.rev170303.StartOutput; -import org.opendaylight.yang.gen.v1.org.onap.appc.oam.rev170303.StartOutputBuilder; -import org.opendaylight.yang.gen.v1.org.onap.appc.oam.rev170303.StopInput; -import org.opendaylight.yang.gen.v1.org.onap.appc.oam.rev170303.StopOutput; -import org.opendaylight.yang.gen.v1.org.onap.appc.oam.rev170303.StopOutputBuilder; -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.get.metrics.output.Metrics; -import org.opendaylight.yang.gen.v1.org.onap.appc.oam.rev170303.get.metrics.output.MetricsBuilder; -import org.opendaylight.yang.gen.v1.org.onap.appc.oam.rev170303.get.metrics.output.metrics.KpiValues; -import org.opendaylight.yang.gen.v1.org.onap.appc.oam.rev170303.get.metrics.output.metrics.KpiValuesBuilder; -import org.opendaylight.yang.gen.v1.org.onap.appc.oam.rev170303.status.Status; -import org.opendaylight.yangtools.yang.common.RpcError; -import org.opendaylight.yangtools.yang.common.RpcResult; -import org.opendaylight.yangtools.yang.common.RpcResultBuilder; -import org.onap.appc.exceptions.APPCException; -import org.onap.appc.i18n.Msg; -import org.onap.appc.metricservice.MetricRegistry; -import org.onap.appc.metricservice.MetricService; -import org.onap.appc.metricservice.metric.Metric; -import org.onap.appc.oam.processor.OamMmodeProcessor; -import org.onap.appc.oam.processor.OamRestartProcessor; -import org.onap.appc.oam.processor.OamStartProcessor; -import org.onap.appc.oam.processor.OamStopProcessor; -import org.onap.appc.oam.util.AsyncTaskHelper; -import org.onap.appc.oam.util.ConfigurationHelper; -import org.onap.appc.oam.util.OperationHelper; -import org.onap.appc.oam.util.StateHelper; -import org.onap.appc.statemachine.impl.readers.AppcOamMetaDataReader.AppcOperation; - -import java.util.ArrayList; -import java.util.List; -import java.util.Map; -import java.util.concurrent.Future; - -/** - * RPC class of APP-C OAM API. - *

Implement all the RPCs defined in AppcOamService through yang model definition. - *

All RPC methods' JAVADOC are using "inheritDoc" to use the description from the yang model file. - */ -public class AppcOam implements AutoCloseable, AppcOamService { - /** - * Invalid state message format with fliexible operation, appc name and state values - */ - public final static String INVALID_STATE_MESSAGE_FORMAT = "%s API is not allowed when %s is in the %s state."; - - private final EELFLogger logger = EELFManager.getInstance().getLogger(AppcOam.class); - - private boolean isMetricEnabled = false; - - /** - * Represents our RPC implementation registration - */ - private BindingAwareBroker.RpcRegistration rpcRegistration; - - - /** - * The yang rpc names with value mapping to AppcOperation - */ - public enum RPC { - maintenance_mode(AppcOperation.MaintenanceMode), - start(AppcOperation.Start), - stop(AppcOperation.Stop), - restart(AppcOperation.Restart); - - AppcOperation appcOperation; - - RPC(AppcOperation appcOperation) { - this.appcOperation = appcOperation; - } - - public AppcOperation getAppcOperation() { - return appcOperation; - } - } - - private AsyncTaskHelper asyncTaskHelper; - private ConfigurationHelper configurationHelper; - private OperationHelper operationHelper; - private StateHelper stateHelper; - - /** - * APP-C OAM contructor - * - * @param dataBroker object of The ODL data store broker. Provides access to a conceptual data - * tree store - * and also provides the ability to subscribe for changes to data under a - * given branch - * of the tree. Not used in this class. - * @param notificationProviderService object of ODL Notification Service that provides publish/subscribe - * capabilities for YANG modeled notifications. Not used in this class. - * @param rpcProviderRegistry object of RpcProviderResigstry. Used to register our RPCs. - */ - @SuppressWarnings({"unused", "nls"}) - public AppcOam(DataBroker dataBroker, - NotificationProviderService notificationProviderService, - RpcProviderRegistry rpcProviderRegistry) { - - configurationHelper = new ConfigurationHelper(logger); - String appName = configurationHelper.getAppcName(); - logger.info(Msg.COMPONENT_INITIALIZING, appName, "oam"); - - if (rpcProviderRegistry != null) { - rpcRegistration = rpcProviderRegistry.addRpcImplementation(AppcOamService.class, this); - } - - isMetricEnabled = configurationHelper.isMetricEnabled(); - - initHelpers(); - - logger.info(Msg.COMPONENT_INITIALIZED, appName, "oam"); - } - - /** - * Initialize helper classes. - *

Note: ConfigurationHelper initializetion is in included here - * because it is needed for extracting the AppName used in the debug logs within the constructor. - */ - private void initHelpers() { - operationHelper = new OperationHelper(); - asyncTaskHelper = new AsyncTaskHelper(logger); - stateHelper = new StateHelper(logger, configurationHelper); - } - - /** - * Implements the close of the service - * - * @see AutoCloseable#close() - */ - @SuppressWarnings("nls") - @Override - public void close() throws Exception { - String appName = configurationHelper.getAppcName(); - logger.info(Msg.COMPONENT_TERMINATING, appName, "oam"); - - asyncTaskHelper.close(); - - if (rpcRegistration != null) { - rpcRegistration.close(); - } - logger.info(Msg.COMPONENT_TERMINATED, appName, "oam"); - } - - /** - * {@inheritDoc} - */ - @Override - public Future> getMetrics() { - - if (!isMetricEnabled) { - logger.error("Metric Service not enabled returning failure"); - RpcResult result = RpcResultBuilder. - status(false).withError(RpcError.ErrorType.APPLICATION, "Metric Service not enabled").build(); - return Futures.immediateFuture(result); - } - - MetricService metricService; - try { - metricService = operationHelper.getService(MetricService.class); - } catch (APPCException e) { - logger.error("MetricService not found", e); - RpcResult result = RpcResultBuilder. - status(false).withError(RpcError.ErrorType.APPLICATION, "Metric Service not found").build(); - return Futures.immediateFuture(result); - } - - Map allMetricRegitry = metricService.getAllRegistry(); - if (allMetricRegitry == null || allMetricRegitry.isEmpty()) { - logger.error("No metrics registered returning failure"); - RpcResult result = RpcResultBuilder. - status(false).withError(RpcError.ErrorType.APPLICATION, "No metrics Registered").build(); - return Futures.immediateFuture(result); - } - - List metricsList = new ArrayList<>(); - - logger.debug("Iterating metric registry list"); - for (MetricRegistry metricRegistry : allMetricRegitry.values()) { - logger.debug("Iterating metric registry :" + metricRegistry.toString()); - Metric[] metrics = metricRegistry.metrics(); - if (metrics != null && metrics.length > 0) { - logger.debug("Iterating though metrics in registry"); - for (Metric metric : metrics) { - logger.debug("Iterating though metrics: " + metric.name()); - MetricsBuilder metricsBuilder = new MetricsBuilder(); - metricsBuilder.setKpiName(metric.name()); - metricsBuilder.setLastResetTime(metric.getLastModified()); - List kpiList = new ArrayList<>(); - Map metricsOutput = metric.getMetricsOutput(); - for (Map.Entry kpi : metricsOutput.entrySet()) { - KpiValuesBuilder kpiValuesBuilder = new KpiValuesBuilder(); - kpiValuesBuilder.setName(kpi.getKey()); - kpiValuesBuilder.setValue(kpi.getValue()); - kpiList.add(kpiValuesBuilder.build()); - } - metricsBuilder.setKpiValues(kpiList); - metricsList.add(metricsBuilder.build()); - } - } - } - - GetMetricsOutputBuilder outputBuilder = new GetMetricsOutputBuilder(); - outputBuilder.setMetrics(metricsList); - RpcResult result = RpcResultBuilder. - status(true).withResult(outputBuilder.build()).build(); - return Futures.immediateFuture(result); - } - - /** - * {@inheritDoc} - */ - @Override - public Future> stop(StopInput stopInput) { - logger.debug("Entering Stop with Input : " + stopInput); - final CommonHeader commonHeader = stopInput.getCommonHeader(); - - OamStopProcessor oamStopProcessor = - new OamStopProcessor(logger, configurationHelper, stateHelper, asyncTaskHelper, operationHelper); - Status status = oamStopProcessor.processRequest(stopInput); - - StopOutputBuilder stopOutputBuilder = new StopOutputBuilder(); - stopOutputBuilder.setStatus(status); - stopOutputBuilder.setCommonHeader(commonHeader); - return RpcResultBuilder.success(stopOutputBuilder.build()).buildFuture(); - } - - /** - * {@inheritDoc} - */ - @Override - public Future> restart(RestartInput input) { - logger.debug("Entering restart with Input : " + input); - final CommonHeader commonHeader = input.getCommonHeader(); - - OamRestartProcessor oamRestartProcessor = - new OamRestartProcessor(logger, configurationHelper, stateHelper, asyncTaskHelper, operationHelper); - Status status = oamRestartProcessor.processRequest(input); - - RestartOutputBuilder restartOutputBuilder = new RestartOutputBuilder(); - restartOutputBuilder.setStatus(status); - restartOutputBuilder.setCommonHeader(commonHeader); - - return RpcResultBuilder.success(restartOutputBuilder.build()).buildFuture(); - } - - /** - * {@inheritDoc} - */ - @Override - public Future> maintenanceMode(MaintenanceModeInput maintenanceModeInput) { - logger.debug("Entering MaintenanceMode with Input : " + maintenanceModeInput); - final CommonHeader commonHeader = maintenanceModeInput.getCommonHeader(); - - OamMmodeProcessor oamMmodeProcessor = - new OamMmodeProcessor(logger, configurationHelper, stateHelper, asyncTaskHelper, operationHelper); - Status status = oamMmodeProcessor.processRequest(maintenanceModeInput); - - MaintenanceModeOutputBuilder maintenanceModeOutputBuilder = new MaintenanceModeOutputBuilder(); - maintenanceModeOutputBuilder.setStatus(status); - maintenanceModeOutputBuilder.setCommonHeader(commonHeader); - return RpcResultBuilder.success(maintenanceModeOutputBuilder.build()).buildFuture(); - } - - /** - * {@inheritDoc} - */ - @Override - public Future> getAppcState() { - AppcState appcState = stateHelper.getCurrentOamYangState(); - - GetAppcStateOutputBuilder builder = new GetAppcStateOutputBuilder(); - builder.setState(appcState); - return RpcResultBuilder.success(builder.build()).buildFuture(); - } - - /** - * {@inheritDoc} - */ - @Override - public Future> start(StartInput startInput) { - logger.debug("Input received : " + startInput); - final CommonHeader commonHeader = startInput.getCommonHeader(); - - OamStartProcessor oamStartProcessor = - new OamStartProcessor(logger, configurationHelper, stateHelper, asyncTaskHelper, operationHelper); - Status status = oamStartProcessor.processRequest(startInput); - - StartOutputBuilder startOutputBuilder = new StartOutputBuilder(); - startOutputBuilder.setStatus(status); - startOutputBuilder.setCommonHeader(commonHeader); - StartOutput startOutput = startOutputBuilder.build(); - return RpcResultBuilder.success(startOutput).buildFuture(); - } -} diff --git a/appc-oam/appc-oam-bundle/src/main/java/org/openecomp/appc/oam/OAMCommandStatus.java b/appc-oam/appc-oam-bundle/src/main/java/org/openecomp/appc/oam/OAMCommandStatus.java deleted file mode 100644 index 294b9d2cf..000000000 --- a/appc-oam/appc-oam-bundle/src/main/java/org/openecomp/appc/oam/OAMCommandStatus.java +++ /dev/null @@ -1,74 +0,0 @@ -/*- - * ============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; - -import org.onap.appc.executor.objects.Params; -import org.onap.appc.util.MessageFormatter; - -import java.util.Map; - -public enum OAMCommandStatus { - - ACCEPTED(100, "ACCEPTED - request accepted"), - UNEXPECTED_ERROR(200, "UNEXPECTED ERROR - ${errorMsg}"), - REJECTED(300, "REJECTED - ${errorMsg}"), - INVALID_PARAMETER(302, "INVALID PARAMETER - ${errorMsg}" ), - TIMEOUT(303, "OPERATION TIMEOUT REACHED - ${errorMsg}"), - ABORT(304, "OPERATION ABORT - ${errorMsg}"), - SUCCESS(400, "SUCCESS - request has been processed successfully"); - - final String TO_STRING_FORMAT = "OAMCommandStatus{responseCode=%d, responseMessage='%s'}"; - - private int responseCode; - private String responseMessage; - - OAMCommandStatus(int responseCode, String responseMessage) { - this.responseCode = responseCode; - this.responseMessage = responseMessage; - } - - public String getResponseMessage() { - return responseMessage; - } - - public int getResponseCode() { - return responseCode; - } - - /** - * Get formated message of passed in params - * - * @param params of Params object with name value pairs for message - * @return message string - */ - public String getFormattedMessage(Params params) { - Map paramsMap = params != null ? params.getParams() : null; - return MessageFormatter.format(getResponseMessage(), paramsMap); - } - - @Override - public String toString() { - return String.format(TO_STRING_FORMAT, responseCode, responseMessage); - }} diff --git a/appc-oam/appc-oam-bundle/src/main/java/org/openecomp/appc/oam/messageadapter/Converter.java b/appc-oam/appc-oam-bundle/src/main/java/org/openecomp/appc/oam/messageadapter/Converter.java deleted file mode 100644 index 152ffc9cc..000000000 --- a/appc-oam/appc-oam-bundle/src/main/java/org/openecomp/appc/oam/messageadapter/Converter.java +++ /dev/null @@ -1,156 +0,0 @@ -/*-/*- - * ============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.messageadapter; - -import com.fasterxml.jackson.annotation.JsonIgnore; -import com.fasterxml.jackson.annotation.JsonInclude; -import com.fasterxml.jackson.annotation.JsonProperty; -import com.fasterxml.jackson.annotation.JsonValue; -import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.databind.MapperFeature; -import com.fasterxml.jackson.databind.ObjectMapper; -import com.fasterxml.jackson.databind.ObjectWriter; -import org.opendaylight.yang.gen.v1.org.onap.appc.oam.rev170303.MaintenanceModeOutputBuilder; -import org.opendaylight.yang.gen.v1.org.onap.appc.oam.rev170303.RestartOutputBuilder; -import org.opendaylight.yang.gen.v1.org.onap.appc.oam.rev170303.StartOutputBuilder; -import org.opendaylight.yang.gen.v1.org.onap.appc.oam.rev170303.StopOutputBuilder; -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.status.Status; -import org.opendaylight.yangtools.concepts.Builder; -import org.opendaylight.yangtools.yang.binding.DataContainer; -import org.onap.appc.oam.AppcOam; - -import java.text.SimpleDateFormat; -import java.util.TimeZone; - -public class Converter { - private static final String ISO_FORMAT = "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'"; - private static final SimpleDateFormat isoFormatter = new SimpleDateFormat(ISO_FORMAT); - - static { - isoFormatter.setTimeZone(TimeZone.getTimeZone("UTC")); - } - - - private static Builder convAsyncResponseToBuilder1(AppcOam.RPC rpcName, - CommonHeader commonHeader, - Status status) { - Builder outObj; - if (rpcName == null) { - throw new IllegalArgumentException("empty asyncResponse.rpcName"); - } - if (commonHeader == null) { - throw new IllegalArgumentException("empty asyncResponse.commonHeader"); - } - if (status == null) { - throw new IllegalArgumentException("empty asyncResponse.status"); - } - switch (rpcName) { - case maintenance_mode: - outObj = new MaintenanceModeOutputBuilder(); - ((MaintenanceModeOutputBuilder) outObj).setCommonHeader(commonHeader); - ((MaintenanceModeOutputBuilder) outObj).setStatus(status); - return outObj; - - case start: - outObj = new StartOutputBuilder(); - ((StartOutputBuilder) outObj).setCommonHeader(commonHeader); - ((StartOutputBuilder) outObj).setStatus(status); - return outObj; - - case stop: - outObj = new StopOutputBuilder(); - ((StopOutputBuilder) outObj).setCommonHeader(commonHeader); - ((StopOutputBuilder) outObj).setStatus(status); - return outObj; - - case restart: - outObj = new RestartOutputBuilder(); - ((RestartOutputBuilder) outObj).setCommonHeader(commonHeader); - ((RestartOutputBuilder) outObj).setStatus(status); - return outObj; - - default: - throw new IllegalArgumentException(rpcName + " action is not supported"); - } - } - - static String convAsyncResponseToUebOutgoingMessageJsonString(OAMContext oamContext) throws - JsonProcessingException { - AppcOam.RPC rpcName = oamContext.getRpcName(); - CommonHeader commonHeader = oamContext.getCommonHeader(); - Status status = oamContext.getStatus(); - - DmaapOutgoingMessage dmaapOutgoingMessage = convAsyncResponseToUebOutgoingMessage(rpcName, commonHeader, - status); - ObjectMapper objectMapper = new ObjectMapper(); - objectMapper.addMixInAnnotations(dmaapOutgoingMessage.getBody().getOutput().getClass(), - MixInFlagsMessage.class); - objectMapper.addMixInAnnotations(Status.class, MixIn.class); - objectMapper.addMixInAnnotations(CommonHeader.class, MixInCommonHeader.class); - ObjectWriter writer = objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL).configure - (MapperFeature.SORT_PROPERTIES_ALPHABETICALLY, true).writer(); - return writer.writeValueAsString(dmaapOutgoingMessage); - } - - private static DmaapOutgoingMessage convAsyncResponseToUebOutgoingMessage(AppcOam.RPC rpcName, CommonHeader - commonHeader, Status status) throws JsonProcessingException { - DmaapOutgoingMessage outObj = new DmaapOutgoingMessage(); - String correlationID = commonHeader.getRequestId(); - outObj.setCorrelationID(correlationID); - outObj.setType("response"); - outObj.setRpcName(rpcName.name()); - Builder builder = Converter.convAsyncResponseToBuilder1(rpcName, commonHeader, status); - Object messageBody = builder.build(); - - DmaapOutgoingMessage.Body body = new DmaapOutgoingMessage.Body(messageBody); - outObj.setBody(body); - return outObj; - } - - - abstract class MixIn { - // to be removed during serialization - @JsonIgnore - abstract Class getImplementedInterface(); - - @JsonValue - abstract java.lang.String getValue(); - } - - abstract class MixInCommonHeader extends MixIn { - @JsonProperty("request-id") - abstract java.lang.String getRequestId(); - - @JsonProperty("originator-id") - abstract java.lang.String getOriginatorId(); - - } - - abstract class MixInFlagsMessage extends MixIn { - @JsonProperty("common-header") - abstract CommonHeader getCommonHeader(); - } -} diff --git a/appc-oam/appc-oam-bundle/src/main/java/org/openecomp/appc/oam/messageadapter/DmaapOutgoingMessage.java b/appc-oam/appc-oam-bundle/src/main/java/org/openecomp/appc/oam/messageadapter/DmaapOutgoingMessage.java deleted file mode 100644 index 25bf0cf8b..000000000 --- a/appc-oam/appc-oam-bundle/src/main/java/org/openecomp/appc/oam/messageadapter/DmaapOutgoingMessage.java +++ /dev/null @@ -1,137 +0,0 @@ -/*- - * ============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.messageadapter; - -import com.fasterxml.jackson.annotation.JsonIgnoreProperties; -import com.fasterxml.jackson.annotation.JsonProperty; -import com.fasterxml.jackson.databind.annotation.JsonSerialize; - -/** - * This class represents a message being sent out to DMaaP by APPC as async response. - * note the structure of this class must be adapted to the sync message sent to DMaaP represented in org.onap.appc.listener.LCM.domainmodel.DmaapOutgoingMessage - * - */ -@JsonSerialize(include = JsonSerialize.Inclusion.NON_NULL) -@JsonIgnoreProperties(ignoreUnknown = true) -public class DmaapOutgoingMessage { - - @JsonProperty("type") - private String type; - - @JsonProperty("correlation-id") - private String correlationID; - - private final static String defaultCambriaPartition = "MSO"; - @JsonProperty("cambria.partition") - private String cambriaPartition = defaultCambriaPartition; - - @JsonProperty("rpc-name") - private String rpcName; - - @JsonProperty("body") - private Body body; - - public DmaapOutgoingMessage() { - } - - public String getType() { - return type; - } - - public void setType(String type) { - this.type = type; - } - - public String getCorrelationID() { - return correlationID; - } - - public void setCorrelationID(String correlationID) { - this.correlationID = correlationID; - } - - public String getCambriaPartition() { - return cambriaPartition; - } - - public void setCambriaPartition(String cambriaPartition) { - this.cambriaPartition = cambriaPartition; - } - - public String getRpcName() { - return rpcName; - } - - public void setRpcName(String rpcName) { - this.rpcName = rpcName; - } - - public Body getBody() { - return body; - } - - public void setBody(Body body) { - this.body = body; - } - - @Override - public String toString() { - return "DmaapOutgoingMessage{" + - "cambriaPartition='" + cambriaPartition + '\'' + - ", rpcName='" + rpcName + '\'' + - ", body=" + body + - '}'; - } - - @JsonSerialize(include = JsonSerialize.Inclusion.NON_NULL) - @JsonIgnoreProperties(ignoreUnknown = true) - public static class Body { - public Body() { - } - - public Body(Object output) { - this.output = output; - } - - @JsonProperty("output") - private Object output; - - public Object getOutput() { - return output; - } - - public void setOutput(Object body) { - this.output = body; - } - - @Override - public String toString() { - return "Body{" + - "output=" + output + - '}'; - } - } -} - diff --git a/appc-oam/appc-oam-bundle/src/main/java/org/openecomp/appc/oam/messageadapter/MessageAdapter.java b/appc-oam/appc-oam-bundle/src/main/java/org/openecomp/appc/oam/messageadapter/MessageAdapter.java deleted file mode 100644 index 91836cb40..000000000 --- a/appc-oam/appc-oam-bundle/src/main/java/org/openecomp/appc/oam/messageadapter/MessageAdapter.java +++ /dev/null @@ -1,183 +0,0 @@ -/*- - * ============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.messageadapter; - -import com.att.eelf.configuration.EELFLogger; -import com.att.eelf.configuration.EELFManager; -import com.fasterxml.jackson.core.JsonProcessingException; -import org.apache.commons.lang.ObjectUtils; -import org.onap.appc.adapter.message.MessageAdapterFactory; -import org.onap.appc.adapter.message.Producer; -import org.onap.appc.configuration.Configuration; -import org.onap.appc.configuration.ConfigurationFactory; -import org.osgi.framework.BundleContext; -import org.osgi.framework.FrameworkUtil; -import org.osgi.framework.ServiceReference; - -import java.util.HashSet; -import java.util.Properties; - -public class MessageAdapter { - - private final EELFLogger logger = EELFManager.getInstance().getLogger(MessageAdapter.class); - - private final String PROP_APPC_OAM_DISABLED = "appc.OAM.disabled"; - private final String PROP_APPC_OAM_TOPIC_WRITE = "appc.OAM.topic.write"; - private String PROP_APPC_OAM_CLIENT_KEY = "appc.OAM.client.key"; - private String PROP_APPC_OAM_CLIENT_SECRET = "appc.OAM.client.secret"; - private String PROP_APPC_OAM_POOLMEMBERS = "appc.OAM.poolMembers"; - - private Producer producer; - private String partition; - private Configuration configuration; - private HashSet pool; - private String writeTopic; - private String apiKey; - private String apiSecret; - private boolean isDisabled; - - /** - * Initialize producer client to post messages using configuration properties. - */ - public void init() { - configuration = ConfigurationFactory.getConfiguration(); - Properties properties = configuration.getProperties(); - updateProperties(properties); - - if (isAppcOamPropsListenerEnabled()) { - createProducer(); - } else { - logger.warn(String.format("The listener %s is disabled and will not be run", "appc.OAM")); - } - } - - /** - * Create producer using MessageAdapterFactory which is found through bundle context. - */ - void createProducer() { - BundleContext ctx = FrameworkUtil.getBundle(MessageAdapter.class).getBundleContext(); - if (ctx == null) { - logger.warn("MessageAdapter cannot create producer due to no bundle context."); - return; - } - - ServiceReference svcRef = ctx.getServiceReference(MessageAdapterFactory.class.getName()); - if (svcRef == null) { - logger.warn("MessageAdapter cannot create producer due to no MessageAdapterFactory service reference."); - return; - } - - Producer localProducer = ((MessageAdapterFactory) ctx.getService(svcRef)).createProducer(pool, writeTopic, - apiKey, apiSecret); - - for (String url : pool) { - if (url.contains("3905") || url.contains("https")) { - localProducer.useHttps(true); - break; - } - } - - producer = localProducer; - - logger.debug("MessageAdapter created producer."); - } - - /** - * Read property value to set writeTopic, apiKey, apiSecret and pool. - * - * @param props of configuration - */ - private void updateProperties(Properties props) { - logger.trace("Entering to updateProperties with Properties = " + ObjectUtils.toString(props)); - - pool = new HashSet<>(); - if (props != null) { - isDisabled = Boolean.parseBoolean(props.getProperty(PROP_APPC_OAM_DISABLED)); - writeTopic = props.getProperty(PROP_APPC_OAM_TOPIC_WRITE); - apiKey = props.getProperty(PROP_APPC_OAM_CLIENT_KEY); - apiSecret = props.getProperty(PROP_APPC_OAM_CLIENT_SECRET); - String hostnames = props.getProperty(PROP_APPC_OAM_POOLMEMBERS); - if (hostnames != null && !hostnames.isEmpty()) { - for (String name : hostnames.split(",")) { - pool.add(name); - } - } - } - } - - /** - * Get producer. If it is null, call createProducer to create it again. - * - * @return Producer - */ - Producer getProducer() { - if (producer == null) { - // In case, producer was not properly set yet, set it again. - logger.info("Calling createProducer as producer is null."); - createProducer(); - } - - return producer; - } - - /** - * Posts message to UEB. As UEB accepts only json messages this method first convert uebMessage to json format - * and post it to UEB. - * - * @param oamContext response data that based on it a message will be send to UEB (the format of the message that - * will be sent to UEB based on the action and its YANG domainmodel). - */ - public void post(OAMContext oamContext) { - if (logger.isTraceEnabled()) { - logger.trace("Entering to post with AsyncResponse = " + ObjectUtils.toString(oamContext)); - } - - boolean success; - String jsonMessage; - try { - jsonMessage = Converter.convAsyncResponseToUebOutgoingMessageJsonString(oamContext); - if (logger.isDebugEnabled()) { - logger.debug("UEB Response = " + jsonMessage); - } - - Producer myProducer = getProducer(); - success = myProducer != null && myProducer.post(this.partition, jsonMessage); - } catch (JsonProcessingException e1) { - logger.error("Error generating Json from UEB message " + e1.getMessage()); - success = false; - } catch (Exception e) { - logger.error("Error sending message to UEB " + e.getMessage(), e); - success = false; - } - - if (logger.isTraceEnabled()) { - logger.trace("Exiting from post with (success = " + ObjectUtils.toString(success) + ")"); - } - } - - private boolean isAppcOamPropsListenerEnabled() { - return !isDisabled; - } -} diff --git a/appc-oam/appc-oam-bundle/src/main/java/org/openecomp/appc/oam/messageadapter/OAMContext.java b/appc-oam/appc-oam-bundle/src/main/java/org/openecomp/appc/oam/messageadapter/OAMContext.java deleted file mode 100644 index 3af395923..000000000 --- a/appc-oam/appc-oam-bundle/src/main/java/org/openecomp/appc/oam/messageadapter/OAMContext.java +++ /dev/null @@ -1,75 +0,0 @@ -/*- - * ============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.messageadapter; - - - - -import org.opendaylight.yang.gen.v1.org.onap.appc.oam.rev170303.*; -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.CommonHeaderBuilder; -import org.opendaylight.yang.gen.v1.org.onap.appc.oam.rev170303.status.Status;import org.onap.appc.oam.AppcOam; - -public class OAMContext { - - private AppcOam.RPC rpcName; - private CommonHeader commonHeader; - private Status status; - - - public AppcOam.RPC getRpcName() { - return rpcName; - } - - public void setRpcName(AppcOam.RPC rpcName) { - this.rpcName = rpcName; - } - - public CommonHeader getCommonHeader() { - return commonHeader; - } - - public void setCommonHeader(CommonHeader commonHeader) { - this.commonHeader = commonHeader; - } - - public Status getStatus() { - return status; - } - - public void setStatus(Status status) { - this.status = status; - } - - - @Override - public String toString() { - return "OAMContext {" + - "rpcName=" + rpcName + - ", commonHeader=" + commonHeader + - ", status=" + status + - '}'; - } -} diff --git a/appc-oam/appc-oam-bundle/src/main/java/org/openecomp/appc/oam/processor/BaseActionRunnable.java b/appc-oam/appc-oam-bundle/src/main/java/org/openecomp/appc/oam/processor/BaseActionRunnable.java deleted file mode 100644 index 927334670..000000000 --- a/appc-oam/appc-oam-bundle/src/main/java/org/openecomp/appc/oam/processor/BaseActionRunnable.java +++ /dev/null @@ -1,254 +0,0 @@ -/*- - * ============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.processor; - -import org.onap.appc.i18n.Msg; -import org.onap.appc.oam.AppcOam; -import org.onap.appc.oam.OAMCommandStatus; -import org.onap.appc.statemachine.impl.readers.AppcOamStates; - -import java.util.HashMap; -import java.util.Map; -import java.util.concurrent.Future; - -/** - * Base runnable actions for OAM APIs, such as maintenance mode, restart, start and stop API. - * - *

This class holds the general action async handling methods for all OAM APIs. - *

Specific API action runnable will overwrite the general methods to add specific behaviors. - * - *

Subclass constructor must set the following class variables: - *
- actionName - *
- auditMsg - *
- finalState - */ -public abstract class BaseActionRunnable extends BaseCommon implements Runnable { - /** Abort due to rejection message format with flexible operation name */ - final String ABORT_MESSAGE_FORMAT = "Aborting %s operation due to %s."; - /** Timeout message format with flexible operation name */ - final String TIMEOUT_MESSAGE_FORMAT = "%s operation has reached timeout %d milliseconds."; - /** Failure message format with flexible number of bundles */ - final String BUNDLE_OPERATION_FAILED_FORMAT = "%d bundle(s) failed, see logs for details."; - final String NEW_RPC_OPERATION_REQUEST = "new %s operation request"; - final String DUE_TO_EXECUTION_ERROR = "due to execution error."; - - private boolean isWaiting = false; - long startTimeMs = 0; - long timeoutMs = 0; - boolean doTimeoutChecking = false; - - String actionName = "Need to be reset"; - Msg auditMsg; - AppcOamStates finalState; - - BaseProcessor myParent; - Map> bundleNameToFuture = new HashMap<>(); - - /** - * Constructor - * - * @param parent BaseProcessor who has called this constructor. - */ - BaseActionRunnable(BaseProcessor parent) { - super(parent.logger, parent.configurationHelper, parent.stateHelper, parent.operationHelper); - - rpc = parent.rpc; - commonHeader = parent.commonHeader; - myParent = parent; - setTimeoutValues(); - } - - /** - * Collect the timeout value for this {@link BaseActionRunnable} - */ - void setTimeoutValues() { - startTime = myParent.startTime; - timeoutMs = myParent.getTimeoutMilliseconds(); - doTimeoutChecking = timeoutMs != 0; - if (doTimeoutChecking) { - startTimeMs = startTime.getTime(); - } - logDebug("%s action runnable check timeout (%s) with timeout (%d)ms, and startMs (%d)", - rpc.name(), Boolean.toString(doTimeoutChecking), timeoutMs, startTimeMs); - } - - - /** - * Abort operation handling due to outside interruption, does
- * - set ABORT status
- * - send notification message
- * - add audit log - * - * @param newRpc of the new AppcOam.RPC operation. - */ - void abortRunnable(final AppcOam.RPC newRpc) { - resetLogProperties(false); - - String additionalMsg = String.format(NEW_RPC_OPERATION_REQUEST, newRpc); - logDebug("%s action aborted due to %s", rpc.name(), additionalMsg); - setStatus(OAMCommandStatus.ABORT, String.format(ABORT_MESSAGE_FORMAT, rpc.name(), additionalMsg)); - operationHelper.sendNotificationMessage(rpc, commonHeader, status); - auditInfoLog(auditMsg); - - resetLogProperties(true); - } - - @Override - public void run() { - try { - setInitialLogProperties(); - logDebug(String.format("===========in %s run (waiting: %s)=======", - actionName, Boolean.toString(isWaiting))); - - if (isWaiting) { - if (!checkState()) { - keepWaiting(); - } - } else { - if (doAction()) { - isWaiting = !checkState(); - } else { - postDoAction(false); - } - } - } catch (Exception e) { - logDebug(String.format("%s got exception %s", actionName, e.getMessage())); - logger.error(actionName + " exception", e); - - } finally { - clearRequestLogProperties(); - } - } - - /** - * Keep waiting to be override by children classes for different behaviors. - * Timeout is validated here. - */ - void keepWaiting() { - logDebug(String.format("%s runnable waiting, current state is %s.", - actionName, stateHelper.getCurrentOamState())); - - isTimeout("keepWaiting"); - } - - /** - * Check if the timeout milliseconds has reached. - * - * @param parentName String of the caller, for logging purpose. - * @return true if the timeout has reached, otherwise false. - */ - boolean isTimeout(String parentName) { - logDebug(String.format("%s task isTimeout called from %s", actionName, parentName)); - if (doTimeoutChecking - && System.currentTimeMillis() - startTimeMs > timeoutMs) { - logger.error(String.format("%s operation timeout (%d) ms has reached, abort with error state.", - actionName, timeoutMs)); - - setStatus(OAMCommandStatus.TIMEOUT, String.format(TIMEOUT_MESSAGE_FORMAT, rpc.name(), timeoutMs)); - postAction(AppcOamStates.Error); - return true; - } - return false; - } - - /** - * Check if all bundle operations are successful through BundleHelper. - * If there's failed bundler operation, set error status and trigger postAction with Error state. - * - * @return true if bundler operations have failure, otherwise false. - */ - boolean hasBundleOperationFailure() { - long failedTask = myParent.bundleHelper.getFailedMetrics(bundleNameToFuture); - if (failedTask == 0) { - return false; - } - - setStatus(OAMCommandStatus.UNEXPECTED_ERROR, String.format(BUNDLE_OPERATION_FAILED_FORMAT, failedTask)); - postAction(AppcOamStates.Error); - return true; - } - - /** - * Set class status to ABORT with abort message. - */ - void setAbortStatus() { - setStatus(OAMCommandStatus.ABORT, String.format(ABORT_MESSAGE_FORMAT, rpc.name(), DUE_TO_EXECUTION_ERROR)); - } - - /** - * Final handling. The thread is cancelled. - * - * @param setState boolean to indicate if set OAM state or not - */ - void postDoAction(boolean setState) { - logDebug(String.format("Finished %s task", actionName)); - } - - /** - * Handling for after doAction. does post notification, issue audit log and set OAM state based on input. - * - * @param state of AppcOamState to be set as OAM state when it is not null. - */ - void postAction(AppcOamStates state) { - operationHelper.sendNotificationMessage(rpc, commonHeader, status); - - if (state != null) { - stateHelper.setState(state); - } - - auditInfoLog(auditMsg); - - myParent.cancelAsyncTask(); - } - - /** - * Check state - * - * @return true if final state reached, otherwise return false - */ - boolean checkState() { - if (isTimeout("checkState")) { - myParent.bundleHelper.cancelUnfinished(bundleNameToFuture); - return true; - } - - if (!myParent.bundleHelper.isAllTaskDone(bundleNameToFuture)) { - return false; - } - - if (hasBundleOperationFailure()) { - return true; - } - - if (stateHelper.getBundlesState() == finalState) { - setStatus(OAMCommandStatus.SUCCESS); - postDoAction(true); - return true; - } - return false; - } - - abstract boolean doAction(); -} diff --git a/appc-oam/appc-oam-bundle/src/main/java/org/openecomp/appc/oam/processor/BaseCommon.java b/appc-oam/appc-oam-bundle/src/main/java/org/openecomp/appc/oam/processor/BaseCommon.java deleted file mode 100644 index 93e79dd2f..000000000 --- a/appc-oam/appc-oam-bundle/src/main/java/org/openecomp/appc/oam/processor/BaseCommon.java +++ /dev/null @@ -1,265 +0,0 @@ -/*- - * ============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.processor; - -import com.att.eelf.configuration.EELFLogger; -import com.att.eelf.i18n.EELFResourceManager; -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.status.Status; -import org.opendaylight.yang.gen.v1.org.onap.appc.oam.rev170303.status.StatusBuilder; -import org.onap.appc.exceptions.InvalidInputException; -import org.onap.appc.exceptions.InvalidStateException; -import org.onap.appc.executor.objects.Params; -import org.onap.appc.i18n.Msg; -import org.onap.appc.logging.LoggingConstants; -import org.onap.appc.logging.LoggingUtils; -import org.onap.appc.oam.AppcOam; -import org.onap.appc.oam.OAMCommandStatus; -import org.onap.appc.oam.util.ConfigurationHelper; -import org.onap.appc.oam.util.OperationHelper; -import org.onap.appc.oam.util.StateHelper; -import org.slf4j.MDC; - -import java.net.InetAddress; -import java.time.Instant; -import java.util.Arrays; -import java.util.Date; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.concurrent.TimeoutException; - -import static com.att.eelf.configuration.Configuration.MDC_INSTANCE_UUID; -import static com.att.eelf.configuration.Configuration.MDC_KEY_REQUEST_ID; -import static com.att.eelf.configuration.Configuration.MDC_SERVER_FQDN; -import static com.att.eelf.configuration.Configuration.MDC_SERVER_IP_ADDRESS; -import static com.att.eelf.configuration.Configuration.MDC_SERVICE_NAME; - -/** - * Common handling methods of
- * - BaseProcessor (for REST sync handling)
- * - BaseActionRunnable (for REST async handling) - */ -public abstract class BaseCommon { - final EELFLogger logger; - final ConfigurationHelper configurationHelper; - final StateHelper stateHelper; - final OperationHelper operationHelper; - - Status status; - Date startTime; - - AppcOam.RPC rpc; - CommonHeader commonHeader; - - private final List MDC_KEYS = Arrays.asList( - LoggingConstants.MDCKeys.PARTNER_NAME, - LoggingConstants.MDCKeys.SERVER_NAME, - MDC_INSTANCE_UUID, - MDC_KEY_REQUEST_ID, - MDC_SERVER_FQDN, - MDC_SERVER_IP_ADDRESS, - MDC_SERVICE_NAME - ); - private Map oldMdcContent = new HashMap<>(); - - /** - * Constructor - * - * @param eelfLogger for logging - * @param configurationHelperIn for property reading - * @param stateHelperIn for APP-C OAM state checking - * @param operationHelperIn for operational helper - */ - BaseCommon(EELFLogger eelfLogger, - ConfigurationHelper configurationHelperIn, - StateHelper stateHelperIn, - OperationHelper operationHelperIn) { - logger = eelfLogger; - configurationHelper = configurationHelperIn; - stateHelper = stateHelperIn; - operationHelper = operationHelperIn; - } - - /** - * Audit log the passed in message at INFO level. - * @param msg the Msg to be audit logged. - */ - void auditInfoLog(Msg msg) { - LoggingUtils.auditInfo(startTime.toInstant(), - Instant.now(), - String.valueOf(status.getCode()), - status.getMessage(), - getClass().getCanonicalName(), - msg, - configurationHelper.getAppcName(), - stateHelper.getCurrentOamState().toString() - ); - } - - /** - * Set MDC properties. - */ - public final void setInitialLogProperties() { - MDC.put(MDC_KEY_REQUEST_ID, commonHeader.getRequestId()); - MDC.put(LoggingConstants.MDCKeys.PARTNER_NAME, commonHeader.getOriginatorId()); - MDC.put(MDC_INSTANCE_UUID, ""); // value should be created in the future - MDC.put(MDC_SERVICE_NAME, rpc.name()); - try { - //!!!Don't change the following to a .getHostName() again please. It's wrong!MDC.put(MDC_SERVER_FQDN, - // InetAddress.getLocalHost().getCanonicalHostName()); - MDC.put(MDC_SERVER_FQDN, InetAddress.getLocalHost().getCanonicalHostName()); - MDC.put(MDC_SERVER_IP_ADDRESS, InetAddress.getLocalHost().getHostAddress()); - MDC.put(LoggingConstants.MDCKeys.SERVER_NAME, InetAddress.getLocalHost().getHostName()); - } catch (Exception e) { - logger.error("MDC constant error", e); - } - } - - /** - * Clear MDC properties. - */ - public final void clearRequestLogProperties() { - for (String key : MDC_KEYS) { - try { - MDC.remove(key); - } catch (Exception e) { - logger.error( - String.format("Unable to clear the Log properties (%s) due to exception: %s", key, e.getMessage())); - } - } - } - - /** - * Reset MDC log properties based on passed in condition. does:
- * - persist existing MDC setting and set my MDC log properties
- * - or re-apply persisted MDC log properties - * @param useMdcMap boolean to indicate whether to persist the existing MDC setting and set my MDC log properties, - * or to re-apply the persisted MDC log properties. - */ - void resetLogProperties(boolean useMdcMap) { - if (useMdcMap) { - for (Map.Entry aEntry : oldMdcContent.entrySet()) { - MDC.put(aEntry.getKey(), aEntry.getValue()); - } - return; - } - - // persist existing log properties and set my log properties - oldMdcContent.clear(); - for (String key : MDC_KEYS) { - String value = MDC.get(key); - if (value != null) { - oldMdcContent.put(key, value); - } - } - setInitialLogProperties(); - } - - /** - * Set class status by calling setStatus(OAMCommandStatus, Params) with null paramter. - * @see #setStatus(OAMCommandStatus, String) - * - * @param oamCommandStatus of the to be set new state - */ - void setStatus(OAMCommandStatus oamCommandStatus) { - setStatus(oamCommandStatus, null); - } - - /** - * Create Status based on the passed in parameter, then set the class status with it. - * - * @param oamCommandStatus of the current OAM command status - * @param message to be set in the new status - */ - void setStatus(OAMCommandStatus oamCommandStatus, String message) { - Params params = new Params().addParam("errorMsg", message); - - StatusBuilder statusBuilder = new StatusBuilder(); - statusBuilder.setCode(oamCommandStatus.getResponseCode()); - if (params != null) { - statusBuilder.setMessage(oamCommandStatus.getFormattedMessage(params)); - } else { - statusBuilder.setMessage(oamCommandStatus.getResponseMessage()); - } - - status = statusBuilder.build(); - } - - /** - * Set class status with error status calculated from the passed in paremeter - * and audit log the error message. - * @param t of the error Throwable. - */ - void setErrorStatus(Throwable t) { - resetLogProperties(false); - - final String appName = configurationHelper.getAppcName(); - String exceptionMessage = t.getMessage() != null ? t.getMessage() : t.toString(); - - OAMCommandStatus oamCommandStatus; - String errorMessage; - if (t instanceof InvalidInputException) { - oamCommandStatus = OAMCommandStatus.INVALID_PARAMETER; - errorMessage = EELFResourceManager.format(Msg.OAM_OPERATION_INVALID_INPUT, t.getMessage()); - } else if (t instanceof InvalidStateException) { - exceptionMessage = String.format(AppcOam.INVALID_STATE_MESSAGE_FORMAT, - rpc.getAppcOperation(), appName, stateHelper.getCurrentOamState()); - oamCommandStatus = OAMCommandStatus.REJECTED; - errorMessage = EELFResourceManager.format(Msg.INVALID_STATE_TRANSITION, exceptionMessage); - } else if (t instanceof TimeoutException) { - oamCommandStatus = OAMCommandStatus.TIMEOUT; - errorMessage = EELFResourceManager.format(Msg.OAM_OPERATION_EXCEPTION, t, - appName, t.getClass().getSimpleName(), rpc.name(), exceptionMessage); - } else { - oamCommandStatus = OAMCommandStatus.UNEXPECTED_ERROR; - errorMessage = EELFResourceManager.format(Msg.OAM_OPERATION_EXCEPTION, t, - appName, t.getClass().getSimpleName(), rpc.name(), exceptionMessage); - } - - setStatus(oamCommandStatus, exceptionMessage); - - LoggingUtils.logErrorMessage( - String.valueOf(status.getCode()), - status.getMessage(), - LoggingConstants.TargetNames.APPC, - LoggingConstants.TargetNames.APPC_OAM_PROVIDER, - errorMessage, - AppcOam.class.getCanonicalName()); - - resetLogProperties(true); - } - - /** - * 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 - */ - void logDebug(String message, Object... args) { - if (logger.isDebugEnabled()) { - logger.debug(String.format(message, args)); - } - } -} diff --git a/appc-oam/appc-oam-bundle/src/main/java/org/openecomp/appc/oam/processor/BaseProcessor.java b/appc-oam/appc-oam-bundle/src/main/java/org/openecomp/appc/oam/processor/BaseProcessor.java deleted file mode 100644 index 414b94605..000000000 --- a/appc-oam/appc-oam-bundle/src/main/java/org/openecomp/appc/oam/processor/BaseProcessor.java +++ /dev/null @@ -1,216 +0,0 @@ -/*- - * ============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.processor; - -import com.att.eelf.configuration.EELFLogger; -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.i18n.Msg; -import org.onap.appc.oam.OAMCommandStatus; -import org.onap.appc.oam.util.AsyncTaskHelper; -import org.onap.appc.oam.util.BundleHelper; -import org.onap.appc.oam.util.ConfigurationHelper; -import org.onap.appc.oam.util.OperationHelper; -import org.onap.appc.oam.util.StateHelper; -import org.onap.appc.statemachine.impl.readers.AppcOamStates; - -import java.util.Date; -import java.util.concurrent.Future; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.TimeoutException; - -/** - * Base processor for OAM APIs, such as maintenance mode, restart, start and stop API. - * - *

This class holds the general API request sync handling methods for all OAM APIs. - *

Specific API processor will overwrite the general methods to add specific behaviors. - */ -public abstract class BaseProcessor extends BaseCommon { - /** lock to serialize incoming OAM operations. */ - private static final Object LOCK = new Object(); - - final AsyncTaskHelper asyncTaskHelper; - final BundleHelper bundleHelper; - - /** the requestTimeoutSeconds to use for this OAM operation */ - private Integer requestTimeoutSeconds; - Msg auditMsg; - BaseActionRunnable runnable; - private Future scheduledRunnable = null; - - /** - * Constructor - * - * @param eelfLogger for logging - * @param configurationHelperIn for property reading - * @param stateHelperIn for APP-C OAM state checking - * @param asyncTaskHelperIn for scheduling async task - * @param operationHelperIn for operational helper - */ - BaseProcessor(EELFLogger eelfLogger, - ConfigurationHelper configurationHelperIn, - StateHelper stateHelperIn, - AsyncTaskHelper asyncTaskHelperIn, - OperationHelper operationHelperIn) { - super(eelfLogger, configurationHelperIn, stateHelperIn, operationHelperIn); - - asyncTaskHelper = asyncTaskHelperIn; - bundleHelper = new BundleHelper(eelfLogger, configurationHelper, stateHelper); - } - - /** - * Process synch handling and schedule asynch task - * - * @param requestInput of REST API request - * @return Status of new APP-C OAM state - */ - public Status processRequest(final Object requestInput) { - startTime = new Date(); - commonHeader = operationHelper.getCommonHeader(requestInput); - setStatus(OAMCommandStatus.ACCEPTED); - - try { - preProcess(requestInput); - scheduleAsyncTask(); - } catch (Exception e) { - setErrorStatus(e); - } finally { - postProcess(); - } - - return status; - } - - /** - * Preprocess before actual handling of the REST API call. Does: - *

- commonHeader validation - *

- get NextState as well as validate if next state is valid - *

- set logging properties - *

- set appcCurrentState to next state - * - * @throws InvalidInputException when commonHeader validation failed - * @throws APPCException when state validation failed - */ - protected void preProcess(final Object requestInput) - throws InvalidInputException, APPCException, InvalidStateException,InterruptedException,TimeoutException { - setInitialLogProperties(); - operationHelper.isInputValid(requestInput); - - //The OAM request may specify timeout value - requestTimeoutSeconds = operationHelper.getParamRequestTimeout(requestInput); - - //All OAM operation pass through here first to validate if an OAM state change is allowed. - //If a state change is allowed cancel the occurring OAM (if any) before starting this one. - //we will synchronized so that only one can do this at any given time. - synchronized(LOCK) { - AppcOamStates currentOamState = stateHelper.getCurrentOamState(); - - //make sure this OAM operation can transition to the desired OAM operation - AppcOamStates nextState = operationHelper.getNextState( - rpc.getAppcOperation(), currentOamState); - - stateHelper.setState(nextState); - - - try { - //cancel the BaseActionRunnable currently executing - //it got to be completely terminated before proceeding - asyncTaskHelper.cancelBaseActionRunnable( - rpc, - currentOamState, - getTimeoutMilliseconds(), - TimeUnit.MILLISECONDS - ); - } catch (TimeoutException e) { - stateHelper.setState(AppcOamStates.Error); - throw e; - } - - - } - } - - /** - * Post process includes audit logging as well as clear MDC properties. - */ - private void postProcess() { - auditInfoLog(auditMsg); - clearRequestLogProperties(); - } - - /** - * Schedule async task through AsyncTaskHelper. - */ - protected void scheduleAsyncTask() { - if (runnable == null) { - logger.error(String.format( - "Skipped schedule async task for rpc(%s) due to runnable is null", rpc.name())); - return; - } - - scheduledRunnable = asyncTaskHelper.scheduleBaseRunnable( - runnable, runnable::abortRunnable, getInitialDelayMillis(), getDelayMillis()); - } - - - /** - * The timeout for this OAM operation. The timeout source is chosen in the following order: - * request, config file, default value - * @return - the timeout for this OAM operation. - */ - long getTimeoutMilliseconds() { - return configurationHelper.getOAMOperationTimeoutValue(this.requestTimeoutSeconds); - } - - - /** - * @return initialDelayMillis - the time to delay first execution of {@link BaseActionRunnable} - */ - protected long getInitialDelayMillis(){ - return 0L; - } - - /** - * @return delayMillis the delay between the consecutive executions of {@link BaseActionRunnable} - */ - private long getDelayMillis(){ - return 1000L; - } - - /** - * Cancel the scheduled {@link BaseActionRunnable} through AsyncTaskHelper - */ - void cancelAsyncTask() { - if (scheduledRunnable == null) { - logger.error(String.format( - "Skipped cancel schedule async task for rpc(%s) due to scheduledRunnable is null", rpc.name())); - return; - } - scheduledRunnable.cancel(true); - } - -} diff --git a/appc-oam/appc-oam-bundle/src/main/java/org/openecomp/appc/oam/processor/OamMmodeProcessor.java b/appc-oam/appc-oam-bundle/src/main/java/org/openecomp/appc/oam/processor/OamMmodeProcessor.java deleted file mode 100644 index 23f9fd130..000000000 --- a/appc-oam/appc-oam-bundle/src/main/java/org/openecomp/appc/oam/processor/OamMmodeProcessor.java +++ /dev/null @@ -1,170 +0,0 @@ -/*- - * ============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.processor; - -import com.att.eelf.configuration.EELFLogger; -import org.onap.appc.exceptions.APPCException; -import org.onap.appc.exceptions.InvalidInputException; -import org.onap.appc.exceptions.InvalidStateException; -import org.onap.appc.i18n.Msg; -import org.onap.appc.oam.AppcOam; -import org.onap.appc.oam.OAMCommandStatus; -import org.onap.appc.oam.util.AsyncTaskHelper; -import org.onap.appc.oam.util.ConfigurationHelper; -import org.onap.appc.oam.util.OperationHelper; -import org.onap.appc.oam.util.StateHelper; -import org.onap.appc.requesthandler.LCMStateManager; -import org.onap.appc.requesthandler.RequestHandler; -import org.onap.appc.statemachine.impl.readers.AppcOamStates; - -import java.util.concurrent.TimeoutException; - -/** - * Processor to handle maintenance mode OAM API. - */ -public class OamMmodeProcessor extends BaseProcessor { - /** - * Constructor - * - * @param eelfLogger for logging - * @param configurationHelper for property reading - * @param stateHelper for APP-C OAM state checking - * @param asyncTaskHelper for scheduling async task - * @param operationHelper for operational helper - */ - public OamMmodeProcessor(EELFLogger eelfLogger, - ConfigurationHelper configurationHelper, - StateHelper stateHelper, - AsyncTaskHelper asyncTaskHelper, - OperationHelper operationHelper) { - super(eelfLogger, configurationHelper, stateHelper, asyncTaskHelper, operationHelper); - - rpc = AppcOam.RPC.maintenance_mode; - auditMsg = Msg.OAM_OPERATION_ENTERING_MAINTENANCE_MODE; - } - - @Override - protected void preProcess(final Object requestInput) - throws InvalidInputException, InvalidStateException, APPCException, InterruptedException, TimeoutException { - super.preProcess(requestInput); - - //Close the gate so that no more new LCM request will be excepted. - LCMStateManager lcmStateManager = operationHelper.getService(LCMStateManager.class); - lcmStateManager.disableLCMOperations(); - } - - @Override - protected void scheduleAsyncTask() { - runnable = new MyRunnable(this); - super.scheduleAsyncTask(); - } - - /** - * {@inheritDoc} - * For maintenance mode we want a longer delay before initial execution of {@link BaseActionRunnable} - * so that any accepted LCM actions have time to git scheduled in the Dispatcher. - */ - @Override - protected long getInitialDelayMillis(){ - //wait ten seconds before - return 10000L; - } - - /** - * This runnable does the async handling for the maintenance mode REST API, and will be scheduled to run - * until terminating condition reaches. - * - *

The runnable will continue run if:
- * - the runnable is not canceled outside
- * - the in progress LCM request count is not zero
- *

When LCM request count reaches to zero, this runnable will:
- * - post message through operationHelper
- * - set APP-C OAM state to maintenance mode
- * - audit log the state
- * - terminate this runnable itself
- */ - class MyRunnable extends BaseActionRunnable { - private int inprogressRequestCount; - - MyRunnable(BaseProcessor parent) { - super(parent); - - actionName = "OAM Maintenance mode"; - auditMsg = Msg.OAM_OPERATION_MAINTENANCE_MODE; - finalState = AppcOamStates.MaintenanceMode; - } - - @Override - boolean doAction() { - // always return true, so that we can check the LCM request count - return true; - } - - @Override - boolean checkState() { - logDebug(String.format("Executing %s task", actionName)); - - - boolean hasError = false; - try { - inprogressRequestCount = getInprogressLCMRequestCount(); - if (inprogressRequestCount > 0) { - // if there are still LCM request in progress, keep waiting - return false; - } - - setStatus(OAMCommandStatus.SUCCESS); - } catch (Exception e) { - setErrorStatus(e); - hasError = true; - } - - postAction(hasError ? AppcOamStates.Error : finalState); - return true; - } - - /** - * Get in progress LCM request count through RequestHandler. - * @return thecount of in progress LCM request - * @throws APPCException if RequestHandler throws it. - */ - private int getInprogressLCMRequestCount() throws APPCException { - RequestHandler requestHandler = operationHelper.getService(RequestHandler.class); - - if (requestHandler == null) { - return 0; - } - - return requestHandler.getInprogressRequestCount(); - } - - @Override - void keepWaiting() { - logDebug("The application '%s' has '%s' outstanding LCM request to complete" + - " before coming to a complete maintenance_mode.", - configurationHelper.getAppcName(), inprogressRequestCount); - } - } -} diff --git a/appc-oam/appc-oam-bundle/src/main/java/org/openecomp/appc/oam/processor/OamRestartProcessor.java b/appc-oam/appc-oam-bundle/src/main/java/org/openecomp/appc/oam/processor/OamRestartProcessor.java deleted file mode 100644 index b23b4d2aa..000000000 --- a/appc-oam/appc-oam-bundle/src/main/java/org/openecomp/appc/oam/processor/OamRestartProcessor.java +++ /dev/null @@ -1,208 +0,0 @@ -/*- - * ============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.processor; - -import com.att.eelf.configuration.EELFLogger; -import org.onap.appc.exceptions.APPCException; -import org.onap.appc.i18n.Msg; -import org.onap.appc.oam.AppcOam; -import org.onap.appc.oam.util.AsyncTaskHelper; -import org.onap.appc.oam.util.ConfigurationHelper; -import org.onap.appc.oam.util.OperationHelper; -import org.onap.appc.oam.util.StateHelper; -import org.onap.appc.requesthandler.LCMStateManager; -import org.onap.appc.statemachine.impl.readers.AppcOamStates; - -/** - * Processor to handle restart OAM API. - */ -public class OamRestartProcessor extends BaseProcessor { - /** - * Action phases: - *
-ToStop: call bundles stop - *
-Stopped: check if all bundle state reached stopped - *
-ToStart: call bundles start - *
-Started: action is full completed - *
-Error: indication of error, such as timeout reached, bundler operation failure and etc. - */ - private enum ActionPhases { - ToStop, - Stopped, - ToStart, - Started, - Error - } - - /** - * Constructor - * - * @param eelfLogger for logging - * @param configurationHelper for property reading - * @param stateHelper for APP-C OAM state checking - * @param asyncTaskHelper for scheduling async task - * @param operationHelper for operational helper - */ - public OamRestartProcessor(EELFLogger eelfLogger, - ConfigurationHelper configurationHelper, - StateHelper stateHelper, - AsyncTaskHelper asyncTaskHelper, - OperationHelper operationHelper) { - super(eelfLogger, configurationHelper, stateHelper, asyncTaskHelper, operationHelper); - - rpc = AppcOam.RPC.restart; - auditMsg = Msg.OAM_OPERATION_RESTARTING; - } - - @Override - protected void scheduleAsyncTask() { - runnable = new MyRunnable(this); - super.scheduleAsyncTask(); - } - - /** - * This runnable does the async handling for the restart REST API. And it will be scheduled to run one time. - * - *

This runnable will the following operations:
- * - do APP-C OAM bundle stop and then start through BundlerHelper
- * - and always enable LCM operation handling (which can be disabled through maintenance mode API).
- *

Once above operations are done, the runnale will
- * - post message through operatonHelper
- * - set APP-C OAM state to started
- * - audit log the state
- */ - class MyRunnable extends BaseActionRunnable { - - ActionPhases currentPhase = ActionPhases.ToStop; - private LCMStateManager lcmStateManager; - - MyRunnable(BaseProcessor parent) { - super(parent); - - actionName = "OAM Restart"; - auditMsg = Msg.OAM_OPERATION_RESTARTED; - finalState = AppcOamStates.Started; - } - - /** - * Do restart action, include stop then start and always enable LCM operation. - * @return true if action is successful, false when aciton is failed or aborted - */ - @Override - boolean doAction() { - logDebug(String.format("Executing %s task at phase (%s)", - actionName, currentPhase == null ? "null" : currentPhase.name())); - - boolean isBundleOperationCompleted = true; - try { - switch (currentPhase) { - case ToStop: - isBundleOperationCompleted = bundleHelper.bundleOperations( - AppcOam.RPC.stop, bundleNameToFuture, myParent.asyncTaskHelper, this); - currentPhase = ActionPhases.Stopped; - break; - case Stopped: - // check state - AppcOamStates currentState = stateHelper.getBundlesState(); - if (currentState == AppcOamStates.Stopped) { - currentPhase = ActionPhases.ToStart; - } else { - logDebug(String.format("%s task is waiting in stopped phase, current state is %s", - actionName, currentState)); - } - break; - case ToStart: - isBundleOperationCompleted = bundleHelper.bundleOperations( - AppcOam.RPC.start, bundleNameToFuture, myParent.asyncTaskHelper, this); - currentPhase = ActionPhases.Started; - break; - case Error: - // do nothing - break; - default: - // Should not reach log it and return false; - logger.error("%s task doAction reached %s phase. not supported. return false.", - actionName, currentPhase.name()); - stateHelper.setState(AppcOamStates.Error); - return false; - } - - if (isTimeout("restart doAction") - || hasBundleOperationFailure()) { - currentPhase = ActionPhases.Error; - return true; - } - if (isBundleOperationCompleted) { - return true; - } - - setAbortStatus(); - } catch (APPCException e) { - setErrorStatus(e); - stateHelper.setState(AppcOamStates.Error); - } - - return false; - } - - /** - * With additional to get the LCMStateManager service - * @see BaseActionRunnable#checkState() - */ - @Override - boolean checkState() { - switch (currentPhase) { - case Started: - try { - lcmStateManager = operationHelper.getService(LCMStateManager.class); - return super.checkState(); - } catch (APPCException e) { - logDebug("LCMStateManager is not available."); - } - break; - default: - // in all the other ActionPhase, we want the run go back to doAction - return true; - } - return false; - } - - /** - * Final handling. The thread is cancelled. - * @param setState boolean to indicate if set OAM state or not - */ - @Override - void postDoAction(boolean setState) { - AppcOamStates newState = null; - if (setState) { - logDebug("Always enable LCM operation"); - lcmStateManager.enableLCMOperations(); - newState = finalState; - } - postAction(newState); - super.postDoAction(setState); - } - - } -} diff --git a/appc-oam/appc-oam-bundle/src/main/java/org/openecomp/appc/oam/processor/OamStartProcessor.java b/appc-oam/appc-oam-bundle/src/main/java/org/openecomp/appc/oam/processor/OamStartProcessor.java deleted file mode 100644 index 2ca353244..000000000 --- a/appc-oam/appc-oam-bundle/src/main/java/org/openecomp/appc/oam/processor/OamStartProcessor.java +++ /dev/null @@ -1,151 +0,0 @@ -/*- - * ============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.processor; - -import com.att.eelf.configuration.EELFLogger; -import org.onap.appc.exceptions.APPCException; -import org.onap.appc.i18n.Msg; -import org.onap.appc.oam.AppcOam; -import org.onap.appc.oam.util.AsyncTaskHelper; -import org.onap.appc.oam.util.ConfigurationHelper; -import org.onap.appc.oam.util.OperationHelper; -import org.onap.appc.oam.util.StateHelper; -import org.onap.appc.requesthandler.LCMStateManager; -import org.onap.appc.statemachine.impl.readers.AppcOamStates; - -/** - * Processor to handle start OAM API. - */ -public class OamStartProcessor extends BaseProcessor { - - /** - * Constructor - * - * @param eelfLogger for logging - * @param configurationHelper for property reading - * @param stateHelper for APP-C OAM state checking - * @param asyncTaskHelper for scheduling async task - * @param operationHelper for operational helper - */ - public OamStartProcessor(EELFLogger eelfLogger, - ConfigurationHelper configurationHelper, - StateHelper stateHelper, - AsyncTaskHelper asyncTaskHelper, - OperationHelper operationHelper) { - super(eelfLogger, configurationHelper, stateHelper, asyncTaskHelper, operationHelper); - - rpc = AppcOam.RPC.start; - auditMsg = Msg.OAM_OPERATION_STARTING; - } - - @Override - protected void scheduleAsyncTask() { - runnable = new MyRunnable(this); - super.scheduleAsyncTask(); - } - - /** - * This runnable does the async handling for the start REST API. And it will be scheduled to run one time. - * - *

This runnable will the following operations:
- * - do APP-C OAM bundle start through BundlerHelper
- * - and always enable LCM operation handling (which can be disabled through maintenance mode API).
- *

Once above operations are done, the runnale will
- * - post message through operatonHelper
- * - set APP-C OAM state to started
- * - audit log the state
- */ - class MyRunnable extends BaseActionRunnable { - - private LCMStateManager lcmStateManager; - - MyRunnable(BaseProcessor parent) { - super(parent); - actionName = "OAM Start"; - auditMsg = Msg.OAM_OPERATION_STARTED; - finalState = AppcOamStates.Started; - } - - /** - * Do start action, include start bundle if needed and always enable LCM operation. - * @return true if action is successful, false when aciton is failed or aborted - */ - @Override - boolean doAction() { - logDebug(String.format("Executing %s task", actionName)); - - boolean isBundleOperationCompleted = true; - try { - if (stateHelper.getState() != AppcOamStates.Started) { - logDebug("Start - APPC OAM state is not started, start the bundles"); - isBundleOperationCompleted = bundleHelper.bundleOperations( - rpc, bundleNameToFuture, myParent.asyncTaskHelper, this); - } - - if (isBundleOperationCompleted) { - return true; - } - - setAbortStatus(); - } catch (APPCException e) { - setErrorStatus(e); - stateHelper.setState(AppcOamStates.Error); - } - - return false; - } - - /** - * With additional to get the LCMStateManager service - * @see BaseActionRunnable#checkState() - */ - @Override - boolean checkState() { - try { - lcmStateManager = operationHelper.getService(LCMStateManager.class); - return super.checkState(); - } catch (APPCException e) { - logDebug("LCMStateManager is not available."); - return false; - } - } - - /** - * Final handling - * @param setState boolean to indicate if set OAM state or not - */ - @Override - void postDoAction(boolean setState) { - AppcOamStates newState = null; - if (setState) { - logDebug("Always enable LCM operation"); - lcmStateManager.enableLCMOperations(); - newState = finalState; - } - postAction(newState); - super.postDoAction(setState); - } - } -} diff --git a/appc-oam/appc-oam-bundle/src/main/java/org/openecomp/appc/oam/processor/OamStopProcessor.java b/appc-oam/appc-oam-bundle/src/main/java/org/openecomp/appc/oam/processor/OamStopProcessor.java deleted file mode 100644 index 8710e0f08..000000000 --- a/appc-oam/appc-oam-bundle/src/main/java/org/openecomp/appc/oam/processor/OamStopProcessor.java +++ /dev/null @@ -1,120 +0,0 @@ -/*- - * ============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.processor; - -import com.att.eelf.configuration.EELFLogger; -import org.onap.appc.exceptions.APPCException; -import org.onap.appc.i18n.Msg; -import org.onap.appc.oam.AppcOam; -import org.onap.appc.oam.util.AsyncTaskHelper; -import org.onap.appc.oam.util.ConfigurationHelper; -import org.onap.appc.oam.util.OperationHelper; -import org.onap.appc.oam.util.StateHelper; -import org.onap.appc.statemachine.impl.readers.AppcOamStates; - -/** - * Processor to handle stop OAM API. - */ -public class OamStopProcessor extends BaseProcessor { - /** - * Constructor - * - * @param eelfLogger for logging - * @param configurationHelper for property reading - * @param stateHelper for APP-C OAM state checking - * @param asyncTaskHelper for scheduling async task - * @param operationHelper for operational helper - */ - public OamStopProcessor(EELFLogger eelfLogger, - ConfigurationHelper configurationHelper, - StateHelper stateHelper, - AsyncTaskHelper asyncTaskHelper, - OperationHelper operationHelper) { - super(eelfLogger, configurationHelper, stateHelper, asyncTaskHelper, operationHelper); - - rpc = AppcOam.RPC.stop; - auditMsg = Msg.OAM_OPERATION_STOPPING; - } - - - @Override - protected void scheduleAsyncTask() { - runnable = new MyRunnable(this); - super.scheduleAsyncTask(); - } - - /** - * This runnable does the async handling for the stop REST API. And it will be scheduled to run one time. - * - *

This runnable will the following operations:
- * - do APP-C OAM bundle stop and then refresh through BundlerHelper
- *

Once above operations are done, the runnale will
- * - post message through operatonHelper
- * - set APP-C OAM state to started
- * - audit log the state
- */ - class MyRunnable extends BaseActionRunnable { - - MyRunnable(BaseProcessor parent) { - super(parent); - actionName = "OAM Stop"; - auditMsg = Msg.OAM_OPERATION_STOPPED; - finalState = AppcOamStates.Stopped; - } - - /** - * Do stop action, include stop bundle . - * @return true if action is successful, false when aciton is failed. - */ - @Override - boolean doAction() { - logDebug(String.format("Executing %s task", actionName)); - - try { - boolean isBundleOperationCompleted = bundleHelper.bundleOperations( - rpc, bundleNameToFuture, myParent.asyncTaskHelper, this); - if (isBundleOperationCompleted) { - return true; - } - - setAbortStatus(); - } catch (APPCException e) { - setErrorStatus(e); - stateHelper.setState(AppcOamStates.Error); - } - return false; - } - - /** - * Final handling - * @param setState boolean to indicate if set OAM state or not - */ - @Override - void postDoAction(boolean setState) { - postAction(setState ? finalState : null); - super.postDoAction(setState); - } - } -} diff --git a/appc-oam/appc-oam-bundle/src/main/java/org/openecomp/appc/oam/util/AsyncTaskHelper.java b/appc-oam/appc-oam-bundle/src/main/java/org/openecomp/appc/oam/util/AsyncTaskHelper.java deleted file mode 100644 index 2f74bf5a9..000000000 --- a/appc-oam/appc-oam-bundle/src/main/java/org/openecomp/appc/oam/util/AsyncTaskHelper.java +++ /dev/null @@ -1,394 +0,0 @@ -/*- - * ============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 org.onap.appc.oam.AppcOam; -import org.onap.appc.oam.processor.BaseActionRunnable; -import org.onap.appc.statemachine.impl.readers.AppcOamStates; -import org.osgi.framework.Bundle; -import org.osgi.framework.FrameworkUtil; - -import java.util.HashSet; -import java.util.Set; -import java.util.concurrent.Callable; -import java.util.concurrent.CancellationException; -import java.util.concurrent.ExecutionException; -import java.util.concurrent.Executors; -import java.util.concurrent.Future; -import java.util.concurrent.LinkedBlockingQueue; -import java.util.concurrent.ScheduledExecutorService; -import java.util.concurrent.ThreadPoolExecutor; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.TimeoutException; -import java.util.function.Consumer; - -/** - * The AsyncTaskHelper class manages an internal parent child data structure. The parent is a transient singleton, - * meaning only one can exist at any given time. The parent is scheduled with the - * {@link #scheduleBaseRunnable(Runnable, Consumer, long, long)} and is executed at configured interval. It can be - * terminated by using the {@link Future#cancel(boolean)} or the {@link Future#cancel(boolean)} returned from \ - * {@link #scheduleBaseRunnable(Runnable, Consumer, long, long)}. - *

- * The children are scheduled using {@link #submitBaseSubCallable(Callable)}} and can only be scheduled if a parent - * is scheduled. Children only execute once, but can be terminated preemptively by the {@link Future#cancel(boolean)} - * returned from {@link #submitBaseSubCallable(Callable)} or indirectly by terminating the parent via the method - * described above. - *

- * This class augments the meaning of {@link Future#isDone()} in that it guarantees that this method only returns true - * if the scheduled {@link Runnable} or {@link Callable} is not currently executing and is not going to execute in the - * future. This is different than the Java core implementation of {@link Future#isDone()} in which it will return - * true immediately after the {@link Future#cancel(boolean)} is called. Even if a Thread is actively executing the - * {@link Runnable} or {@link Callable} and has not return yet. See Java BUG JDK-8073704 - *

- * The parent {@link Future#isDone()} has an additional augmentation in that it will not return true until all of its - * children's {@link Future#isDone()} also return true. - * - */ -@SuppressWarnings("unchecked") -public class AsyncTaskHelper { - - private final EELFLogger logger; - private final ScheduledExecutorService scheduledExecutorService; - private final ThreadPoolExecutor bundleOperationService; - - /** Reference to {@link MyFuture} return from {@link #scheduleBaseRunnable(Runnable, Consumer, long, long)} */ - private MyFuture backgroundBaseRunnableFuture; - - /** The cancel Callback from {@link #scheduleBaseRunnable(Runnable, Consumer, long, long)} */ - private Consumer cancelCallBackForBaseRunnable; - - /** All Futures created by thus calls which have not completed -- {@link Future#isDone()} equals false */ - private Set myFutureSet = new HashSet<>(); - - /** - * Constructor - * @param eelfLogger of the logger - */ - public AsyncTaskHelper(EELFLogger eelfLogger) { - logger = eelfLogger; - - scheduledExecutorService = Executors.newSingleThreadScheduledExecutor( - (runnable) -> { - Bundle bundle = FrameworkUtil.getBundle(AppcOam.class); - return new Thread(runnable, bundle.getSymbolicName() + " scheduledExecutor"); - } - ); - - bundleOperationService = new ThreadPoolExecutor( - 0, - 10, - 10, - TimeUnit.SECONDS, - new LinkedBlockingQueue(), //BlockingQueue workQueue - (runnable) -> { - Bundle bundle = FrameworkUtil.getBundle(AppcOam.class); - return new Thread(runnable, bundle.getSymbolicName() + " bundle operation executor"); - } - ); - } - - /** - * Terminate the class ScheduledExecutorService - */ - public void close() { - logDebug("Start shutdown scheduleExcutorService."); - bundleOperationService.shutdownNow(); - scheduledExecutorService.shutdownNow(); - logDebug("Completed shutdown scheduleExcutorService."); - } - - - /** - * Cancel currently executing {@link BaseActionRunnable} if any. - * This method returns immediately if there is currently no {@link BaseActionRunnable} actively executing. - * @param rpcCausingAbort - The RPC causing the abort - * @param stateBeingAbborted - The current state being canceled - * @param timeout - The amount of time to wait for a cancel to complete - * @param timeUnit - The unit of time of timeout - * @throws TimeoutException - If {@link BaseActionRunnable} has not completely cancelled within the timeout period - * @throws InterruptedException - If the Thread waiting for the abort - */ - public synchronized void cancelBaseActionRunnable(final AppcOam.RPC rpcCausingAbort, - AppcOamStates stateBeingAbborted, - long timeout, TimeUnit timeUnit) - throws TimeoutException,InterruptedException { - - final MyFuture localBackgroundBaseRunnableFuture = backgroundBaseRunnableFuture; - final Consumer localCancelCallBackForBaseRunnable = cancelCallBackForBaseRunnable; - - if (localBackgroundBaseRunnableFuture == null || localBackgroundBaseRunnableFuture.isDone()) { - return; - } - - if (localCancelCallBackForBaseRunnable != null) { - localCancelCallBackForBaseRunnable.accept(rpcCausingAbort); - } - localBackgroundBaseRunnableFuture.cancel(true); - - long timeoutMillis = timeUnit.toMillis(timeout); - long expiryTime = System.currentTimeMillis() + timeoutMillis; - while (!(localBackgroundBaseRunnableFuture.isDone())) { - long sleepTime = expiryTime - System.currentTimeMillis(); - if (sleepTime < 1) { - break; - } - this.wait(sleepTime); - } - - if (!localBackgroundBaseRunnableFuture.isDone()) { - throw new TimeoutException(String.format("Unable to abort %s in timely manner.",stateBeingAbborted)); - } - } - - /** - * Schedule a {@link BaseActionRunnable} to begin async execution. This is the Parent {@link Runnable} for the - * children that are submitted by {@link #submitBaseSubCallable(Callable)} - * - * The currently executing {@link BaseActionRunnable} must fully be terminated before the next can be scheduled. - * This means all Tasks' {@link MyFuture#isDone()} must equal true and all threads must return to their respective - * thread pools. - * - * @param runnable of the to be scheduled service. - * @param cancelCallBack to be invoked when - * {@link #cancelBaseActionRunnable(AppcOam.RPC, AppcOamStates, long, TimeUnit)} is invoked. - * @param initialDelayMillis the time to delay first execution - * @param delayMillis the delay between the termination of one - * execution and the commencement of the next - * @return The {@link BaseActionRunnable}'s {@link Future} - * @throws IllegalStateException if there is currently executing Task - */ - public synchronized Future scheduleBaseRunnable(final Runnable runnable, - final Consumer cancelCallBack, - long initialDelayMillis, - long delayMillis) - throws IllegalStateException { - - if (backgroundBaseRunnableFuture != null && !backgroundBaseRunnableFuture.isDone()) { - throw new IllegalStateException("Unable to schedule background task when one is already running. All task must fully terminated before another can be scheduled. "); - } - - this.cancelCallBackForBaseRunnable = cancelCallBack; - - backgroundBaseRunnableFuture = new MyFuture(runnable) { - /** - * augments the cancel operation to cancel all subTack too, - */ - @Override - public boolean cancel(final boolean mayInterruptIfRunning) { - boolean cancel; - synchronized (AsyncTaskHelper.this) { - cancel = super.cancel(mayInterruptIfRunning); - //clone the set to prevent java.util.ConcurrentModificationException. The synchronized prevents - //other threads from modifying this set, but not itself. The f->f.cancel may modify myFutureSet by - //removing an entry which breaks the iteration in the forEach. - (new HashSet(myFutureSet)) - .stream().filter(f->!this.equals(f)).forEach(f->f.cancel(mayInterruptIfRunning)); - } - return cancel; - } - - /** - * augments the isDone operation to return false until all subTask have completed too. - */ - @Override - public boolean isDone() { - synchronized (AsyncTaskHelper.this) { - return myFutureSet.isEmpty(); - } - } - }; - backgroundBaseRunnableFuture.setFuture( - scheduledExecutorService.scheduleWithFixedDelay( - backgroundBaseRunnableFuture, initialDelayMillis, delayMillis, TimeUnit.MILLISECONDS) - ); - return backgroundBaseRunnableFuture; - } - - /** - * Submits children {@link Callable} to be executed as soon as possible, A parent must have been scheduled - * previously via {@link #scheduleBaseRunnable(Runnable, Consumer, long, long)} - * @param callable the Callable to be submitted - * @return The {@link Callable}'s {@link Future} - */ - synchronized Future submitBaseSubCallable(final Callable callable) { - - if (backgroundBaseRunnableFuture == null - || backgroundBaseRunnableFuture.isCancelled() - || backgroundBaseRunnableFuture.isDone()){ - throw new IllegalStateException("Unable to schedule subCallable when a base Runnable is not running."); - } - - //Make sure the pool is ready to go - if(bundleOperationService.getPoolSize() != bundleOperationService.getMaximumPoolSize()){ - bundleOperationService.setCorePoolSize(bundleOperationService.getMaximumPoolSize()); - bundleOperationService.prestartAllCoreThreads(); - bundleOperationService.setCorePoolSize(0); - } - - MyFuture myFuture = new MyFuture(callable); - myFuture.setFuture(bundleOperationService.submit((Callable)myFuture)); - return myFuture; - } - - /** - * 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)); - } - } - - /** - * This class has two purposes. First it insures {@link #isDone()} only returns true if the deligate is not - * currently running and will not be running in the future: See Java BUG JDK-8073704 Second this class maintains - * the {@link #myFutureSet } by insurring that itself is removed when {@link #isDone()} returns true. - * - * See {@link #scheduleBaseRunnable(Runnable, Consumer, long, long)} and {@link #submitBaseSubCallable(Callable)} - * for usage of this class - */ - private class MyFuture implements Future, Runnable, Callable { - - private Future future; - private final Runnable runnable; - private final Callable callable; - private boolean isRunning; - - MyFuture(Runnable runnable) { - this.runnable = runnable; - this.callable = null; - myFutureSet.add(this); - } - - MyFuture(Callable callable) { - this.runnable = null; - this.callable = callable; - myFutureSet.add(this); - } - - void setFuture(Future future) { - this.future = future; - } - - @Override - public boolean cancel(boolean mayInterruptIfRunning) { - synchronized (AsyncTaskHelper.this) { - if (!isRunning) { - myFutureSetRemove(); - } - - return future.cancel(mayInterruptIfRunning); - } - } - - @Override - public boolean isCancelled() { - synchronized (AsyncTaskHelper.this) { - return future.isCancelled(); - } - } - - @Override - public boolean isDone() { - synchronized (AsyncTaskHelper.this) { - return future.isDone() && !isRunning; - } - } - - @Override - public T get() throws InterruptedException, ExecutionException { - return future.get(); - } - - @Override - public T get(long timeout, TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException { - return future.get(timeout, unit); - } - - @Override - public void run() { - synchronized (AsyncTaskHelper.this) { - if(future.isCancelled()){ - return; - } - isRunning = true; - } - try { - runnable.run(); - } finally { - synchronized (AsyncTaskHelper.this) { - isRunning = false; - - //The Base Runnable is expected to run again. - //unless it has been canceled. - //so only removed if it is canceled. - if (future.isCancelled()) { - myFutureSetRemove(); - } - } - } - } - - @Override - public T call() throws Exception { - synchronized (AsyncTaskHelper.this) { - if(future.isCancelled()){ - throw new CancellationException(); - } - isRunning = true; - } - try { - return callable.call(); - } finally { - synchronized (AsyncTaskHelper.this){ - isRunning = false; - myFutureSetRemove(); - } - } - } - - - /** - * Removes this from the the myFutureSet. - * When all the BaseActionRunnable is Done notify any thread waiting in - * {@link AsyncTaskHelper#cancelBaseActionRunnable(AppcOam.RPC, AppcOamStates, long, TimeUnit)} - */ - void myFutureSetRemove(){ - synchronized (AsyncTaskHelper.this) { - myFutureSet.remove(this); - if(myFutureSet.isEmpty()){ - backgroundBaseRunnableFuture = null; - cancelCallBackForBaseRunnable = null; - AsyncTaskHelper.this.notifyAll(); - - } - } - } - - } -} diff --git a/appc-oam/appc-oam-bundle/src/main/java/org/openecomp/appc/oam/util/BundleFilter.java b/appc-oam/appc-oam-bundle/src/main/java/org/openecomp/appc/oam/util/BundleFilter.java deleted file mode 100644 index 6dd98f165..000000000 --- a/appc-oam/appc-oam-bundle/src/main/java/org/openecomp/appc/oam/util/BundleFilter.java +++ /dev/null @@ -1,128 +0,0 @@ -/*- - * ============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 org.osgi.framework.Bundle; - -import java.util.Collections; -import java.util.HashMap; -import java.util.Map; -import java.util.regex.Pattern; - - - -/** - * - * Utility Class that splits a given bundleSet into two sets: bundleToStopSet and - * bundleToNotStopSet - * - * The bundleToStopSet is defined as: all bundles which match at least one of - * the stopRegexes but exceptRegexes none of the - * - * The bundleToNotStopSet is defined as all bundles which are not a member of - * the bundleToStopSet - * - */ -class BundleFilter { - - private final Map bundleToStopSet; - private final Map bundleToNotStopSet; - - - /** - * BundleFilter a bundle filter - * @param stopRegexes - An array of regular expression used to pick out which bundles are candidates for stopping - * @param exceptRegexes - An array of regular expression used to override which bundles are candidates for stopping - * @param bundles - An array of the bundle to be split into {@link #getBundlesToStop()} {@link #getBundlesToNotStop()} - */ - BundleFilter(String[] stopRegexes, String[] exceptRegexes, Bundle[] bundles) { - - Pattern[] stopPatterns = toPattern(stopRegexes); - Pattern[] exceptPatterns = toPattern(exceptRegexes); - - Map bundleToStop = new HashMap<>(); - Map bundleToNotStop = new HashMap<>(); - - for (Bundle bundle : bundles) { - String symbolicName = bundle.getSymbolicName(); - if (isMatch(symbolicName,stopPatterns) && !isMatch(symbolicName,exceptPatterns)) { - bundleToStop.put(symbolicName, bundle); - } else { - bundleToNotStop.put(symbolicName, bundle); - } - } - - this.bundleToStopSet = Collections.unmodifiableMap(bundleToStop); - this.bundleToNotStopSet = Collections.unmodifiableMap(bundleToNotStop); - } - - /** - * Determines if the value matches any of the regular expressions. - * - * @param value - * - the value that is to be matched - * @param patterns - * - the array of {@link Pattern} to match the value against - * @return boolean true if there is a match - */ - private boolean isMatch(String value,Pattern[] patterns) { - for (Pattern pattern : patterns) { - if (pattern.matcher(value).matches()) { - return true; - } - } - return false; - } - - /** - * This method converts an Array of regular expression in String form into a - * Array of {@link Pattern} - * - * @param regex - * - A string array of regular expressions - * @return Pattern Array of compiled regular expressions - */ - private Pattern[] toPattern(String[] regex) { - Pattern[] pattern = new Pattern[regex.length]; - for (int i = 0; i < regex.length; i++ ) { - pattern[i] = Pattern.compile(regex[i]); - } - return pattern; - } - - - /**@return Map of bundles that are to be stopped */ - Map getBundlesToStop(){ - return bundleToStopSet; - } - - /** - * - * @return Map of bundles that are not to be stopped - */ - Map getBundlesToNotStop() { - return bundleToNotStopSet; - } -} 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 deleted file mode 100644 index 3a4602542..000000000 --- a/appc-oam/appc-oam-bundle/src/main/java/org/openecomp/appc/oam/util/BundleHelper.java +++ /dev/null @@ -1,274 +0,0 @@ -/*- - * ============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 org.apache.commons.lang3.ArrayUtils; -import org.onap.appc.exceptions.APPCException; -import org.onap.appc.oam.AppcOam; -import org.onap.appc.oam.processor.BaseCommon; -import org.onap.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> threads, - AsyncTaskHelper taskHelper, - BaseCommon baseCommon) - 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 appcLcmBundles = getAppcLcmBundles(); - for (Map.Entry 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.submitBaseSubCallable(new BundleTask(rpc, bundle,baseCommon))); - } - - logDebug(String.format("Leaving OAM bundleOperations with rpc (%s) with complete(%s), elasped (%d) ms.", - rpc.name(), Boolean.toString(isBundleOperationComplete), getElapseTimeMs(mStartTime))); - - return isBundleOperationComplete; - } - - private long getElapseTimeMs(long mStartTime) { - return System.currentTimeMillis() - mStartTime; - } - - /** - * Check if all BundleTasks are completed - * @param bundleNameFutureMap with bundle name and BundleTask Future object - * @return true if all are done, otherwise, false - */ - public boolean isAllTaskDone(Map> bundleNameFutureMap) { - boolean anyNotDone = bundleNameFutureMap.values().stream().anyMatch((f) -> !f.isDone()); - return !anyNotDone; - } - - /** - * Cancel BundleTasks which are not finished - * @param bundleNameFutureMap with bundle name and BundleTask Future object - */ - public void cancelUnfinished(Map> bundleNameFutureMap) { - bundleNameFutureMap.values().stream().filter((f) - -> !f.isDone()).forEach((f) - -> f.cancel(true)); - } - - /** - * Get number of failed BundleTasks - * @param bundleNameFutureMap with bundle name and BundleTask Future object - * @return number(long) of the failed BundleTasks - */ - public long getFailedMetrics(Map> bundleNameFutureMap) { - return bundleNameFutureMap.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 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 { - Exception failException; - - private AppcOam.RPC rpc; - private Bundle bundle; - private String bundleName; - private String actionName; - private final BaseCommon baseCommon; - - BundleTask(AppcOam.RPC rpcIn, Bundle bundleIn, BaseCommon baseCommon) { - rpc = rpcIn; - actionName = rpc.getAppcOperation().toString(); - bundle = bundleIn; - bundleName = bundle.getSymbolicName(); - this.baseCommon = baseCommon; - } - - @Override - public BundleTask call() throws Exception { - try { - baseCommon.setInitialLogProperties(); - - 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, getElapseTimeMs(bundleOperStartTime))); - } catch (BundleException e) { - logger.error(String.format("Exception encountered when OAM %s bundle %s ", - actionName, bundleName), e); - failException = e; - } - finally { - baseCommon.clearRequestLogProperties(); - } - return this; - } - } -} diff --git a/appc-oam/appc-oam-bundle/src/main/java/org/openecomp/appc/oam/util/ConfigurationHelper.java b/appc-oam/appc-oam-bundle/src/main/java/org/openecomp/appc/oam/util/ConfigurationHelper.java deleted file mode 100644 index 3c5629f11..000000000 --- a/appc-oam/appc-oam-bundle/src/main/java/org/openecomp/appc/oam/util/ConfigurationHelper.java +++ /dev/null @@ -1,106 +0,0 @@ -/*- - * ============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 org.apache.commons.lang3.ArrayUtils; -import org.onap.appc.Constants; -import org.onap.appc.configuration.Configuration; -import org.onap.appc.configuration.ConfigurationFactory; - -import java.util.concurrent.TimeUnit; - -/** - * Utility class provides general configuration helps - */ -public class ConfigurationHelper { - final static String PROP_KEY_APPC_NAME = Constants.PROPERTY_APPLICATION_NAME; - final static String PROP_KEY_METRIC_STATE = "metric.enabled"; - private final String OAM_OPERATION_TIMEOUT_SECOND = "appc.OAM.api.timeout"; - /** Default operation timeout set to 1 minute */ - private final int DEFAULT_OAM_OPERATION_TIMEOUT = 60; - - private final EELFLogger logger; - private Configuration configuration = ConfigurationFactory.getConfiguration(); - - public ConfigurationHelper(EELFLogger eelfLogger) { - logger = eelfLogger; - } - - public String getAppcName() { - return configuration.getProperty(PROP_KEY_APPC_NAME); - } - - public boolean isMetricEnabled() { - return configuration.getBooleanProperty(PROP_KEY_METRIC_STATE, false); - } - - public Configuration getConfig() { - return configuration; - } - - /** - * Read property value of a specified property key - * - * @param propertyKey string of the property key - * @return String[] of the property values associated with the propertyKey - */ - String[] readProperty(String propertyKey) { - String propertyValue = configuration.getProperty(propertyKey); - if (propertyValue == null) { - return ArrayUtils.EMPTY_STRING_ARRAY; - } - - if (logger.isDebugEnabled()) { - logger.debug(String.format("Property[%s] has value (%s).", propertyKey, propertyValue)); - } - - if (propertyValue.contains(",")) { - return propertyValue.split("\\s*,\\s*"); - } - return new String[]{propertyValue}; - } - - - - - - /** - * This method returns timeout in milliseconds. The source is chosen in the following order: - * The overrideTimeoutSeconds argument - * or {@link #OAM_OPERATION_TIMEOUT_SECOND} found in the configuration file - * or the {@link #DEFAULT_OAM_OPERATION_TIMEOUT} - * @param overrideTimeoutSeconds or null to us the other sources - * @return timeout in milliseconds - */ - public long getOAMOperationTimeoutValue(Integer overrideTimeoutSeconds) { - return TimeUnit.SECONDS.toMillis( - overrideTimeoutSeconds == null ? - getConfig().getIntegerProperty(OAM_OPERATION_TIMEOUT_SECOND, DEFAULT_OAM_OPERATION_TIMEOUT) - : - overrideTimeoutSeconds - ); - } -} diff --git a/appc-oam/appc-oam-bundle/src/main/java/org/openecomp/appc/oam/util/OperationHelper.java b/appc-oam/appc-oam-bundle/src/main/java/org/openecomp/appc/oam/util/OperationHelper.java deleted file mode 100644 index 9eec0b67b..000000000 --- a/appc-oam/appc-oam-bundle/src/main/java/org/openecomp/appc/oam/util/OperationHelper.java +++ /dev/null @@ -1,205 +0,0 @@ -/*- - * ============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 : - *

- - * Bug 8088 - Mandatory attributes in RPC input are not honoured - *

- - * Bug 5830 - Mandatory leaf enforcement is not correct with presence container - * - * @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 of the expected service instance - * @return service instance of the expected - * @throws APPCException when cannot find service reference or service isntance - */ - public T getService(Class _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); - } -} diff --git a/appc-oam/appc-oam-bundle/src/main/java/org/openecomp/appc/oam/util/StateHelper.java b/appc-oam/appc-oam-bundle/src/main/java/org/openecomp/appc/oam/util/StateHelper.java deleted file mode 100644 index 871a07676..000000000 --- a/appc-oam/appc-oam-bundle/src/main/java/org/openecomp/appc/oam/util/StateHelper.java +++ /dev/null @@ -1,144 +0,0 @@ -/*- - * ============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 org.opendaylight.yang.gen.v1.org.onap.appc.oam.rev170303.AppcState; -import org.onap.appc.statemachine.impl.readers.AppcOamStates; -import org.osgi.framework.Bundle; - -import java.util.Map; - -/* - * Utility class provides general state helps - */ -public class StateHelper { - /** logger inherited from AppcOam */ - private final EELFLogger logger; - private ConfigurationHelper configurationHelper; - /** APP-C OAM current state in AppcOamStates value */ - private volatile AppcOamStates appcOamCurrentState; - - /** - * Constructor - * - * @param eelfLogger of the logger - */ - public StateHelper(EELFLogger eelfLogger, ConfigurationHelper cHelper) { - logger = eelfLogger; - configurationHelper = cHelper; - appcOamCurrentState = AppcOamStates.Unknown; - } - - /** - * Set the passed in state to the class appOamCurrentState. - * - * @param appcOamStates of the new state - */ - public void setState(AppcOamStates appcOamStates) { - appcOamCurrentState = appcOamStates; - } - - /** - * Get the state - * @return the class appOamCurrentState - */ - public AppcOamStates getState() { - return appcOamCurrentState; - } - - /** - * Validate if the passed in state is the same as the class appOamCurrentState. - * - * @param appcOamStates of the to be compared state - * @return true if they are the same, otherwise false - */ - boolean isSameState(AppcOamStates appcOamStates) { - return appcOamCurrentState == appcOamStates; - } - - /** - * Get APP-C OAM current state - * - *

When appcOamCurrentState is null or unknown, reset it with APPC LCM bundle state. - * - * @return AppcOamStates of the current APP-C OAM state - */ - public AppcOamStates getCurrentOamState() { - if (appcOamCurrentState == null || appcOamCurrentState.equals(AppcOamStates.Unknown)) { - appcOamCurrentState = getBundlesState(); - } - return appcOamCurrentState; - } - - /** - * Use getCurrentOamState to get current OAM AppcOamStates and then convert to AppcState of Yang. - * - * @return AppcState of current OAM state - */ - public AppcState getCurrentOamYangState() { - try { - AppcOamStates appcOamStates = getCurrentOamState(); - return AppcState.valueOf(appcOamStates.name()); - } catch (Exception ex) { - logger.error(String.format("Unable to determine the current APP-C OAM state due to %s.", ex.getMessage())); - } - return AppcState.Unknown; - } - - /** - * Get APPC state from the state of the set of APPC LCM bundles. - *

The state of each bundle will be checked and the lowest state will be uses as the returning AppcOamStates. - *

The bundle state order are defined in OSGI bundle (@see org.osgi.framework.Bundle) class - * as the int value assigned to each state as the following:
- * - UNINSTALLED (1)
- * - INSTALLED (2)
- * - RESOLVED (4)
- * - STARTING (8)
- * - STOPPING (16)
- * - ACTIVE (32)
- * - * @return AppcOamStates - */ - public AppcOamStates getBundlesState() { - BundleHelper bundleHelper = new BundleHelper(logger, configurationHelper, this); - Map lcmBundleMap = bundleHelper.getAppcLcmBundles(); - if (lcmBundleMap == null || lcmBundleMap.isEmpty()) { - return AppcOamStates.Unknown; - } - - // As we are picking up the lowest bundle state as general APP-C state, we will start with ACTIVE - int currentState = Bundle.ACTIVE; - for (Bundle bundle : lcmBundleMap.values()) { - int bundleState = bundle.getState(); - logger.trace(String.format("getBundlesState: [%s] has state (%d)", bundle.getSymbolicName(), bundleState)); - if (bundleState < currentState) { - currentState = bundleState; - } - } - return AppcOamStates.getOamStateFromBundleState(currentState); - } - -} diff --git a/appc-oam/appc-oam-bundle/src/main/resources/org/onap/appc/default.properties b/appc-oam/appc-oam-bundle/src/main/resources/org/onap/appc/default.properties new file mode 100644 index 000000000..964040a18 --- /dev/null +++ b/appc-oam/appc-oam-bundle/src/main/resources/org/onap/appc/default.properties @@ -0,0 +1,90 @@ +### +# ============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========================================================= +### + +# +# This property file supplies the configuration defaults for the APP-C controller +# +# Default values are supplied so that all defined properties have well-known values and are +# valid even if a configuration file is not supplied. This is done to ensure that a runnable, +# stable, and defined configuration exists at all times. The reason the defaults are supplied +# via this property file and not in the code is so that the properties can be changed +# easily if needed in the future. Use of the "getProperty(name, default)" method is +# discouraged because if the default value needs to be changed, everywhere in the code it +# is used would have to be changed. By loading the defaults in this property file, all +# values can be defined in one place and support is easier. This does mean that all +# properties that are defined must have a default value supplied here. Which also means +# this file documents all defined properties (not a bad thing either). +# +#-------------------------------------------------------------------------------------------- +# The path and file used to load user-supplied configuration settings, if any +org.onap.appc.bootstrap.path=/opt/openecomp/appc/data/properties,${user.home},. +org.onap.appc.bootstrap.file=appc.properties + +appc.application.name=APPC + +# +# The path to search for logging configuration document, and the name of the document +# +org.onap.appc.logging.path=${user.home},etc,../etc,. +org.onap.appc.logging.file=logback.xml + + +# +# The properties would be used by OAM's Stop/Start APIs to stop/start the bundles +# +appc.OAM.ToStop.properties=appc.OAM.AppcBundlesToStop\ +,appc.OAM.OtherBundlesToStop +appc.OAM.ToNotStop.properties=appc.OAM.AppcBundlesToNotStop\ +,appc.OAM.OtherBundlesToNotStop + +# These following properties represent the Regular-Expression which would be evaluated against the +# running Bundles's Symbolic-Name: +# - appc.OAM.AppcBundlesToStop +# - appc.OAM.OtherBundlesToStop +# - appc.OAM.AppcBundlesToNotStop +# - appc.OAM.OtherBundlesToNotStop +appc.OAM.AppcBundlesToStop=.*appc.*\ +,domain-model-lib\ +,execution-queue-management-lib\ +,lock-manager-impl\ +,org.openecomp.sdnc.config.params\ +,org.openecomp.sdnc.config.audit\ +,org.openecomp.sdnc.config.generator\ +,org.openecomp.sdnc.dg.loader\ +,transaction-recorder + +appc.OAM.OtherBundlesToStop=.*app-cntrl.*\ +,com.att.sdnctl.sli.adaptor.asyncresponse + +appc.OAM.AppcBundlesToNotStop=.*appc.oam.*\ +,appc-common\ +,appc-command-executor-api\ +,appc-lifecycle-management-api\ +,appc-lifecycle-management-core\ +,appc-metric-bundle\ +,org.onap.appc.listener\ +,state-machine-lib + +appc.OAM.OtherBundlesToNotStop=app-cntrl-message-adapter-factory\ +,app-cntrl-aaf-filters diff --git a/appc-oam/appc-oam-bundle/src/main/resources/org/onap/appc/logback.xml b/appc-oam/appc-oam-bundle/src/main/resources/org/onap/appc/logback.xml new file mode 100644 index 000000000..0dffe75e0 --- /dev/null +++ b/appc-oam/appc-oam-bundle/src/main/resources/org/onap/appc/logback.xml @@ -0,0 +1,287 @@ + + + + + + + + + + %d{MM/dd-HH:mm:ss.SSS} [%-16thread] %.-5level + %-36.36logger - %msg%n + + + + + + + + + + ${logDirectory}/cdp.log + + ${logDirectory}/cdp.%i.log.zip + + 1 + 9 + + + 5MB + + + + %d{MM/dd-HH:mm:ss.SSS} [%-16thread] %.-5level + %-36.36logger [%X{User} %X{RemoteHost} %X{RequestId} %X{Method} + %X{Path}] - %msg%n + + + + 256 + + + + + + ${logDirectory}/cdp-security.log + + ${logDirectory}/cdp-security.%i.log.zip + + 1 + 9 + + + 5MB + + + + %d{MM/dd-HH:mm:ss.SSS} [%-16thread] %.-5level + %-36.36logger [%X{User} %X{RemoteHost} %X{RequestId} %X{Method} + %X{Path}] - %msg%n + + + + 256 + 0 + + + + + + ${logDirectory}/cdp-performance.log + + ${logDirectory}/cdp-performance.%i.log.zip + + 1 + 9 + + + 5MB + + + true + %d{MM/dd-HH:mm:ss.SSS} [%-16thread] %.-5level + %-36.36logger [%X{User} %X{RemoteHost} %X{RequestId} %X{Method} + %X{Path}] - %msg%n + + + + 256 + + + + + + ${logDirectory}/cdp-server.log + + ${logDirectory}/cdp-server.%i.log.zip + + 1 + 9 + + + 5MB + + + + %d{MM/dd-HH:mm:ss.SSS} [%-16thread] %.-5level + %-36.36logger [%X{User} %X{RemoteHost} %X{RequestId} %X{Method} + %X{Path}] - %msg%n + + + + 256 + + + + + + ${logDirectory}/cdp-coordinator.log + + ${logDirectory}/cdp-coordinator.%i.log.zip + + 1 + 9 + + + 5MB + + + + %d{MM/dd-HH:mm:ss.SSS} [%-16thread] %.-5level + %-36.36logger - %msg%n + + + + 256 + + + + + + ${logDirectory}/cdp-policy.log + + ${logDirectory}/cdp-policy.%i.log.zip + + 1 + 9 + + + 5MB + + + + %d{MM/dd-HH:mm:ss.SSS} [%-16thread] %.-5level + %-36.36logger - %msg%n + + + + 256 + + + + ${debugLogDirectory}/appc-debug.log + + ${logDirectory}/command-executor.%i.log.zip + + 1 + 9 + + + 5MB + + + + + %d{MM/dd-HH:mm:ss.SSS}|%X{RequestId}|%X{ServiceInstanceId}|%t|%X{ServiceName} - %X{bundle.id} - %X{bundle.name} - %X{bundle.version}|%X{InstanceUUID}|%-5.5p|%X{AlertSeverity}|%X{ServerIPAddress}|%X{ServerFQDN}|%X{RemoteHost}|%X{Timer}|[%c{3}]|%m%n + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/appc-oam/appc-oam-bundle/src/main/resources/org/openecomp/appc/default.properties b/appc-oam/appc-oam-bundle/src/main/resources/org/openecomp/appc/default.properties deleted file mode 100644 index 964040a18..000000000 --- a/appc-oam/appc-oam-bundle/src/main/resources/org/openecomp/appc/default.properties +++ /dev/null @@ -1,90 +0,0 @@ -### -# ============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========================================================= -### - -# -# This property file supplies the configuration defaults for the APP-C controller -# -# Default values are supplied so that all defined properties have well-known values and are -# valid even if a configuration file is not supplied. This is done to ensure that a runnable, -# stable, and defined configuration exists at all times. The reason the defaults are supplied -# via this property file and not in the code is so that the properties can be changed -# easily if needed in the future. Use of the "getProperty(name, default)" method is -# discouraged because if the default value needs to be changed, everywhere in the code it -# is used would have to be changed. By loading the defaults in this property file, all -# values can be defined in one place and support is easier. This does mean that all -# properties that are defined must have a default value supplied here. Which also means -# this file documents all defined properties (not a bad thing either). -# -#-------------------------------------------------------------------------------------------- -# The path and file used to load user-supplied configuration settings, if any -org.onap.appc.bootstrap.path=/opt/openecomp/appc/data/properties,${user.home},. -org.onap.appc.bootstrap.file=appc.properties - -appc.application.name=APPC - -# -# The path to search for logging configuration document, and the name of the document -# -org.onap.appc.logging.path=${user.home},etc,../etc,. -org.onap.appc.logging.file=logback.xml - - -# -# The properties would be used by OAM's Stop/Start APIs to stop/start the bundles -# -appc.OAM.ToStop.properties=appc.OAM.AppcBundlesToStop\ -,appc.OAM.OtherBundlesToStop -appc.OAM.ToNotStop.properties=appc.OAM.AppcBundlesToNotStop\ -,appc.OAM.OtherBundlesToNotStop - -# These following properties represent the Regular-Expression which would be evaluated against the -# running Bundles's Symbolic-Name: -# - appc.OAM.AppcBundlesToStop -# - appc.OAM.OtherBundlesToStop -# - appc.OAM.AppcBundlesToNotStop -# - appc.OAM.OtherBundlesToNotStop -appc.OAM.AppcBundlesToStop=.*appc.*\ -,domain-model-lib\ -,execution-queue-management-lib\ -,lock-manager-impl\ -,org.openecomp.sdnc.config.params\ -,org.openecomp.sdnc.config.audit\ -,org.openecomp.sdnc.config.generator\ -,org.openecomp.sdnc.dg.loader\ -,transaction-recorder - -appc.OAM.OtherBundlesToStop=.*app-cntrl.*\ -,com.att.sdnctl.sli.adaptor.asyncresponse - -appc.OAM.AppcBundlesToNotStop=.*appc.oam.*\ -,appc-common\ -,appc-command-executor-api\ -,appc-lifecycle-management-api\ -,appc-lifecycle-management-core\ -,appc-metric-bundle\ -,org.onap.appc.listener\ -,state-machine-lib - -appc.OAM.OtherBundlesToNotStop=app-cntrl-message-adapter-factory\ -,app-cntrl-aaf-filters diff --git a/appc-oam/appc-oam-bundle/src/main/resources/org/openecomp/appc/logback.xml b/appc-oam/appc-oam-bundle/src/main/resources/org/openecomp/appc/logback.xml deleted file mode 100644 index 0dffe75e0..000000000 --- a/appc-oam/appc-oam-bundle/src/main/resources/org/openecomp/appc/logback.xml +++ /dev/null @@ -1,287 +0,0 @@ - - - - - - - - - - %d{MM/dd-HH:mm:ss.SSS} [%-16thread] %.-5level - %-36.36logger - %msg%n - - - - - - - - - - ${logDirectory}/cdp.log - - ${logDirectory}/cdp.%i.log.zip - - 1 - 9 - - - 5MB - - - - %d{MM/dd-HH:mm:ss.SSS} [%-16thread] %.-5level - %-36.36logger [%X{User} %X{RemoteHost} %X{RequestId} %X{Method} - %X{Path}] - %msg%n - - - - 256 - - - - - - ${logDirectory}/cdp-security.log - - ${logDirectory}/cdp-security.%i.log.zip - - 1 - 9 - - - 5MB - - - - %d{MM/dd-HH:mm:ss.SSS} [%-16thread] %.-5level - %-36.36logger [%X{User} %X{RemoteHost} %X{RequestId} %X{Method} - %X{Path}] - %msg%n - - - - 256 - 0 - - - - - - ${logDirectory}/cdp-performance.log - - ${logDirectory}/cdp-performance.%i.log.zip - - 1 - 9 - - - 5MB - - - true - %d{MM/dd-HH:mm:ss.SSS} [%-16thread] %.-5level - %-36.36logger [%X{User} %X{RemoteHost} %X{RequestId} %X{Method} - %X{Path}] - %msg%n - - - - 256 - - - - - - ${logDirectory}/cdp-server.log - - ${logDirectory}/cdp-server.%i.log.zip - - 1 - 9 - - - 5MB - - - - %d{MM/dd-HH:mm:ss.SSS} [%-16thread] %.-5level - %-36.36logger [%X{User} %X{RemoteHost} %X{RequestId} %X{Method} - %X{Path}] - %msg%n - - - - 256 - - - - - - ${logDirectory}/cdp-coordinator.log - - ${logDirectory}/cdp-coordinator.%i.log.zip - - 1 - 9 - - - 5MB - - - - %d{MM/dd-HH:mm:ss.SSS} [%-16thread] %.-5level - %-36.36logger - %msg%n - - - - 256 - - - - - - ${logDirectory}/cdp-policy.log - - ${logDirectory}/cdp-policy.%i.log.zip - - 1 - 9 - - - 5MB - - - - %d{MM/dd-HH:mm:ss.SSS} [%-16thread] %.-5level - %-36.36logger - %msg%n - - - - 256 - - - - ${debugLogDirectory}/appc-debug.log - - ${logDirectory}/command-executor.%i.log.zip - - 1 - 9 - - - 5MB - - - - - %d{MM/dd-HH:mm:ss.SSS}|%X{RequestId}|%X{ServiceInstanceId}|%t|%X{ServiceName} - %X{bundle.id} - %X{bundle.name} - %X{bundle.version}|%X{InstanceUUID}|%-5.5p|%X{AlertSeverity}|%X{ServerIPAddress}|%X{ServerFQDN}|%X{RemoteHost}|%X{Timer}|[%c{3}]|%m%n - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/appc-oam/appc-oam-bundle/src/test/java/org/onap/appc/oam/AppcOamTest.java b/appc-oam/appc-oam-bundle/src/test/java/org/onap/appc/oam/AppcOamTest.java new file mode 100644 index 000000000..110198370 --- /dev/null +++ b/appc-oam/appc-oam-bundle/src/test/java/org/onap/appc/oam/AppcOamTest.java @@ -0,0 +1,166 @@ +/*- + * ============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; + +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mockito; +import org.opendaylight.yang.gen.v1.org.onap.appc.oam.rev170303.AppcState; +import org.opendaylight.yang.gen.v1.org.onap.appc.oam.rev170303.GetAppcStateOutput; +import org.opendaylight.yang.gen.v1.org.onap.appc.oam.rev170303.MaintenanceModeInput; +import org.opendaylight.yang.gen.v1.org.onap.appc.oam.rev170303.MaintenanceModeOutput; +import org.opendaylight.yang.gen.v1.org.onap.appc.oam.rev170303.RestartInput; +import org.opendaylight.yang.gen.v1.org.onap.appc.oam.rev170303.RestartOutput; +import org.opendaylight.yang.gen.v1.org.onap.appc.oam.rev170303.StartInput; +import org.opendaylight.yang.gen.v1.org.onap.appc.oam.rev170303.StartOutput; +import org.opendaylight.yang.gen.v1.org.onap.appc.oam.rev170303.StopInput; +import org.opendaylight.yang.gen.v1.org.onap.appc.oam.rev170303.StopOutput; +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.status.Status; +import org.opendaylight.yangtools.yang.common.RpcResult; +import org.onap.appc.oam.processor.OamMmodeProcessor; +import org.onap.appc.oam.processor.OamRestartProcessor; +import org.onap.appc.oam.processor.OamStartProcessor; +import org.onap.appc.oam.processor.OamStopProcessor; +import org.onap.appc.oam.util.OperationHelper; +import org.onap.appc.oam.util.StateHelper; +import org.osgi.framework.FrameworkUtil; +import org.powermock.api.mockito.PowerMockito; +import org.powermock.core.classloader.annotations.PrepareForTest; +import org.powermock.modules.junit4.PowerMockRunner; +import org.powermock.reflect.Whitebox; + +import java.util.concurrent.Executors; +import java.util.concurrent.Future; + +import static org.mockito.Mockito.mock; +import static org.powermock.api.mockito.PowerMockito.spy; + +@RunWith(PowerMockRunner.class) +@PrepareForTest({AppcOam.class, FrameworkUtil.class, Executors.class}) +public class AppcOamTest { + + private AppcOam appcOam; + private CommonHeader mockCommonHeader = mock(CommonHeader.class); + private Status mockStatus = mock(Status.class); + private OperationHelper mockOperationHelper = mock(OperationHelper.class); + private StateHelper mockStateHelper = mock(StateHelper.class); + + @Before + public void setUp() throws Exception { + appcOam = spy(new AppcOam(null, null, null)); + + Whitebox.setInternalState(appcOam, "stateHelper", mockStateHelper); + Whitebox.setInternalState(appcOam, "operationHelper", mockOperationHelper); + } + + @Test + public void testMaintenanceMode() throws Exception { + // mock processor creation + OamMmodeProcessor mockProcessor = mock(OamMmodeProcessor.class); + PowerMockito.mockStatic(OamMmodeProcessor.class); + PowerMockito.whenNew(OamMmodeProcessor.class).withAnyArguments().thenReturn(mockProcessor); + // mock input + MaintenanceModeInput mockInput = mock(MaintenanceModeInput.class); + Mockito.doReturn(mockCommonHeader).when(mockInput).getCommonHeader(); + // mock processor result + Mockito.doReturn(mockStatus).when(mockProcessor).processRequest(mockInput); + + Future> response = appcOam.maintenanceMode(mockInput); + + Assert.assertEquals("Should have common header", mockCommonHeader, + response.get().getResult().getCommonHeader()); + Assert.assertEquals("Should have status", mockStatus, response.get().getResult().getStatus()); + } + + @Test + public void testStart() throws Exception { + // mock processor creation + OamStartProcessor mockProcessor = mock(OamStartProcessor.class); + PowerMockito.mockStatic(OamStartProcessor.class); + PowerMockito.whenNew(OamStartProcessor.class).withAnyArguments().thenReturn(mockProcessor); + // mock input + StartInput mockInput = mock(StartInput.class); + Mockito.doReturn(mockCommonHeader).when(mockInput).getCommonHeader(); + // mock processor result + Mockito.doReturn(mockStatus).when(mockProcessor).processRequest(mockInput); + + Future> response = appcOam.start(mockInput); + + Assert.assertEquals("Should have common header", mockCommonHeader, + response.get().getResult().getCommonHeader()); + Assert.assertEquals("Should have status", mockStatus, response.get().getResult().getStatus()); + } + + @Test + public void testStop() throws Exception { + // mock processor creation + OamStopProcessor mockProcessor = mock(OamStopProcessor.class); + PowerMockito.mockStatic(OamStopProcessor.class); + PowerMockito.whenNew(OamStopProcessor.class).withAnyArguments().thenReturn(mockProcessor); + // mock input + StopInput mockInput = mock(StopInput.class); + Mockito.doReturn(mockCommonHeader).when(mockInput).getCommonHeader(); + // mock processor result + Mockito.doReturn(mockStatus).when(mockProcessor).processRequest(mockInput); + + Future> response = appcOam.stop(mockInput); + + Assert.assertEquals("Should have common header", mockCommonHeader, + response.get().getResult().getCommonHeader()); + Assert.assertEquals("Should have status", mockStatus, response.get().getResult().getStatus()); + } + + @Test + public void testRestart() throws Exception { + // mock processor creation + OamRestartProcessor mockProcessor = mock(OamRestartProcessor.class); + PowerMockito.mockStatic(OamRestartProcessor.class); + PowerMockito.whenNew(OamRestartProcessor.class).withAnyArguments().thenReturn(mockProcessor); + // mock input + RestartInput mockInput = mock(RestartInput.class); + Mockito.doReturn(mockCommonHeader).when(mockInput).getCommonHeader(); + // mock processor result + Mockito.doReturn(mockStatus).when(mockProcessor).processRequest(mockInput); + + Future> response = appcOam.restart(mockInput); + + Assert.assertEquals("Should have common header", mockCommonHeader, + response.get().getResult().getCommonHeader()); + Assert.assertEquals("Should have status", mockStatus, response.get().getResult().getStatus()); + } + + @Test + public void testGetAppcState() throws Exception { + AppcState appcState = AppcState.Started; + Mockito.doReturn(appcState).when(mockStateHelper).getCurrentOamYangState(); + + Future> state = appcOam.getAppcState(); + Assert.assertEquals("Should return the same state", + appcState, state.get().getResult().getState()); + } +} diff --git a/appc-oam/appc-oam-bundle/src/test/java/org/onap/appc/oam/OAMCommandStatusTest.java b/appc-oam/appc-oam-bundle/src/test/java/org/onap/appc/oam/OAMCommandStatusTest.java new file mode 100644 index 000000000..269c4f811 --- /dev/null +++ b/appc-oam/appc-oam-bundle/src/test/java/org/onap/appc/oam/OAMCommandStatusTest.java @@ -0,0 +1,99 @@ +/*- + * ============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; + +import org.junit.Assert; +import org.junit.Test; +import org.onap.appc.executor.objects.Params; + +import java.util.HashMap; +import java.util.Map; + +public class OAMCommandStatusTest { + private Map CODE_MAP = new HashMap() { + { + put(OAMCommandStatus.ABORT, 304); + put(OAMCommandStatus.ACCEPTED, 100); + put(OAMCommandStatus.INVALID_PARAMETER, 302); + put(OAMCommandStatus.REJECTED, 300); + put(OAMCommandStatus.SUCCESS, 400); + put(OAMCommandStatus.TIMEOUT, 303); + put(OAMCommandStatus.UNEXPECTED_ERROR, 200); + } + }; + private Map MSG_MAP = new HashMap() { + { + put(OAMCommandStatus.ABORT, "OPERATION ABORT - ${errorMsg}"); + put(OAMCommandStatus.ACCEPTED, "ACCEPTED - request accepted"); + put(OAMCommandStatus.INVALID_PARAMETER, "INVALID PARAMETER - ${errorMsg}"); + put(OAMCommandStatus.REJECTED, "REJECTED - ${errorMsg}"); + put(OAMCommandStatus.SUCCESS, "SUCCESS - request has been processed successfully"); + put(OAMCommandStatus.TIMEOUT, "OPERATION TIMEOUT REACHED - ${errorMsg}"); + put(OAMCommandStatus.UNEXPECTED_ERROR, "UNEXPECTED ERROR - ${errorMsg}"); + } + }; + + @Test + public void testGetResponseMessage() throws Exception { + for (OAMCommandStatus oamCommandStatus : OAMCommandStatus.values()) { + String expectedMsg = MSG_MAP.get(oamCommandStatus); + Assert.assertEquals(String.format("Should have message (%s).", expectedMsg), + expectedMsg, oamCommandStatus.getResponseMessage()); + } + } + + @Test + public void testGetResponseCode() throws Exception { + for (OAMCommandStatus oamCommandStatus : OAMCommandStatus.values()) { + Integer expectedCode = CODE_MAP.get(oamCommandStatus); + Assert.assertEquals(String.format("Should have code (%d).", expectedCode), + expectedCode, Integer.valueOf(oamCommandStatus.getResponseCode())); + } + } + + @Test + public void testGetFormattedMessage() throws Exception { + String message = "test message"; + Params params = new Params().addParam("errorMsg", message); + for (OAMCommandStatus oamCommandStatus : OAMCommandStatus.values()) { + String expectedMsg1 = MSG_MAP.get(oamCommandStatus); + String expectedMsg2 = expectedMsg1.replaceAll("\\$\\{errorMsg\\}", message); + Assert.assertEquals("Should returned " + expectedMsg1, + expectedMsg1, oamCommandStatus.getFormattedMessage(null)); + Assert.assertEquals("Should returned " + expectedMsg2, + expectedMsg2, oamCommandStatus.getFormattedMessage(params)); + } + } + + @Test + public void testToString() throws Exception { + for (OAMCommandStatus oamCommandStatus : OAMCommandStatus.values()) { + String expectedString = String.format(oamCommandStatus.TO_STRING_FORMAT, + CODE_MAP.get(oamCommandStatus), MSG_MAP.get(oamCommandStatus)); + Assert.assertEquals(String.format("Should have string (%s).", expectedString), + expectedString, oamCommandStatus.toString()); + } + } +} diff --git a/appc-oam/appc-oam-bundle/src/test/java/org/onap/appc/oam/messageadapter/MessageAdapterTest.java b/appc-oam/appc-oam-bundle/src/test/java/org/onap/appc/oam/messageadapter/MessageAdapterTest.java new file mode 100644 index 000000000..d3ebfda51 --- /dev/null +++ b/appc-oam/appc-oam-bundle/src/test/java/org/onap/appc/oam/messageadapter/MessageAdapterTest.java @@ -0,0 +1,115 @@ +/*- + * ============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.messageadapter; + +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.onap.appc.adapter.message.MessageAdapterFactory; +import org.onap.appc.adapter.message.Producer; + +import org.mockito.Mockito; +import org.osgi.framework.Bundle; +import org.osgi.framework.BundleContext; +import org.osgi.framework.FrameworkUtil; +import org.osgi.framework.ServiceReference; +import org.powermock.api.mockito.PowerMockito; +import org.powermock.core.classloader.annotations.PrepareForTest; +import org.powermock.modules.junit4.PowerMockRunner; +import org.powermock.reflect.Whitebox; + +import java.util.HashSet; + +import static org.mockito.Mockito.mock; +import static org.powermock.api.mockito.PowerMockito.mockStatic; + + +@RunWith(PowerMockRunner.class) +@PrepareForTest({MessageAdapter.class, FrameworkUtil.class}) +public class MessageAdapterTest { + + private Producer fakeProducer; + + private MessageAdapter messageAdapter; + + + @Before + public final void setup() throws Exception { + fakeProducer = mock(Producer.class); + messageAdapter = new MessageAdapter(); + } + + @Test + public void testGetProducerReturnsNull() throws Exception { + MessageAdapter maSpy = Mockito.spy(messageAdapter); + Mockito.doNothing().when(maSpy).createProducer(); + + Producer producer = maSpy.getProducer(); + Assert.assertTrue("getProducer() did not return null", producer == null); + Producer mySpyProducer = Whitebox.getInternalState(maSpy, "producer"); + Assert.assertTrue("MessageAdapter producer is not null", mySpyProducer == null); + Mockito.verify(maSpy, Mockito.times(1)).createProducer(); + } + + @Test + public void testGetProducerWithExistingProducer() throws Exception { + MessageAdapter maSpy = Mockito.spy(messageAdapter); + Whitebox.setInternalState(maSpy, "producer", fakeProducer); + + Producer producer = maSpy.getProducer(); + Assert.assertTrue("getProducer() returned null", producer == fakeProducer); + Mockito.verify(maSpy, Mockito.times(0)).createProducer(); + } + + @Test + public void testGetProducerWithCreateProducer() throws Exception { + MessageAdapter maSpy = Mockito.spy(messageAdapter); + Whitebox.setInternalState(maSpy, "producer", (Object) null); + HashSet pool = new HashSet<>(); + Whitebox.setInternalState(maSpy, "pool", pool); + + // Prepare all mocks + mockStatic(FrameworkUtil.class); + Bundle maBundle = mock(Bundle.class); + PowerMockito.when(FrameworkUtil.getBundle(MessageAdapter.class)).thenReturn(maBundle); + + BundleContext maBundleContext = mock(BundleContext.class); + Mockito.when(maBundle.getBundleContext()).thenReturn(maBundleContext); + + ServiceReference svcRef = mock(ServiceReference.class); + Mockito.when(maBundleContext.getServiceReference(MessageAdapterFactory.class.getName())).thenReturn(svcRef); + + MessageAdapterFactory maFactory = mock(MessageAdapterFactory.class); + Mockito.when(maBundleContext.getService(svcRef)).thenReturn(maFactory); + Mockito.when(maFactory.createProducer(pool, (String) null, null, null)).thenReturn(fakeProducer); + + Producer producer = maSpy.getProducer(); + Assert.assertTrue("getProducer() result does not match", producer == fakeProducer); + Producer mySpyProducer = Whitebox.getInternalState(maSpy, "producer"); + Assert.assertTrue("MessageAdapter producer does not match",mySpyProducer == fakeProducer); + Mockito.verify(maSpy, Mockito.times(1)).createProducer(); + } +} diff --git a/appc-oam/appc-oam-bundle/src/test/java/org/onap/appc/oam/processor/BaseActionRunnableTest.java b/appc-oam/appc-oam-bundle/src/test/java/org/onap/appc/oam/processor/BaseActionRunnableTest.java new file mode 100644 index 000000000..daf0f6e07 --- /dev/null +++ b/appc-oam/appc-oam-bundle/src/test/java/org/onap/appc/oam/processor/BaseActionRunnableTest.java @@ -0,0 +1,293 @@ +/*- + * ============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.processor; + +import com.att.eelf.configuration.EELFLogger; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import org.mockito.Mockito; +import org.opendaylight.yang.gen.v1.org.onap.appc.oam.rev170303.common.header.CommonHeader; +import org.onap.appc.i18n.Msg; +import org.onap.appc.oam.AppcOam; +import org.onap.appc.oam.OAMCommandStatus; +import org.onap.appc.oam.util.AsyncTaskHelper; +import org.onap.appc.oam.util.BundleHelper; +import org.onap.appc.oam.util.ConfigurationHelper; +import org.onap.appc.oam.util.OperationHelper; +import org.onap.appc.oam.util.StateHelper; +import org.onap.appc.statemachine.impl.readers.AppcOamStates; +import org.powermock.reflect.Whitebox; + +import java.util.Date; + +import static org.mockito.Matchers.any; +import static org.mockito.Matchers.anyMap; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.spy; +import static org.mockito.Mockito.times; + +public class BaseActionRunnableTest { + private AppcOam.RPC testRpc = AppcOam.RPC.maintenance_mode; + private AppcOamStates targetState = AppcOamStates.MaintenanceMode; + + private class TestProcessor extends BaseProcessor { + /** + * Constructor + * + * @param eelfLogger for logging + * @param configurationHelperIn for property reading + * @param stateHelperIn for APP-C OAM state checking + * @param asyncTaskHelperIn for scheduling async task + * @param operationHelperIn for operational helper + */ + TestProcessor(EELFLogger eelfLogger, + ConfigurationHelper configurationHelperIn, + StateHelper stateHelperIn, + AsyncTaskHelper asyncTaskHelperIn, + OperationHelper operationHelperIn) { + super(eelfLogger, configurationHelperIn, stateHelperIn, asyncTaskHelperIn, operationHelperIn); + + // must set rpc and auditMsg + rpc = testRpc; + auditMsg = Msg.OAM_OPERATION_STARTING; + startTime = new Date(); + } + } + + class TestAbc extends BaseActionRunnable { + boolean doActionResult; + + TestAbc(BaseProcessor parent) { + super(parent); + + actionName = "testing"; + auditMsg = Msg.OAM_OPERATION_MAINTENANCE_MODE; + finalState = targetState; + } + + @Override + boolean doAction() { + return doActionResult; + } + } + + private TestAbc testBaseAcionRunnable; + private BaseProcessor testProcessor; + private StateHelper mockStateHelper = mock(StateHelper.class); + private OperationHelper mockOperHelper = mock(OperationHelper.class); + private ConfigurationHelper mockConfigHelper = mock(ConfigurationHelper.class); + private BundleHelper mockBundleHelper = mock(BundleHelper.class); + + @SuppressWarnings("ResultOfMethodCallIgnored") + @Before + public void setUp() throws Exception { + // to avoid operation on logger fail, mock up the logger + EELFLogger mockLogger = mock(EELFLogger.class); + + testProcessor = spy( + new TestProcessor(mockLogger, mockConfigHelper, mockStateHelper, null, mockOperHelper)); + Whitebox.setInternalState(testProcessor, "bundleHelper", mockBundleHelper); + + testBaseAcionRunnable = spy(new TestAbc(testProcessor)); + Whitebox.setInternalState(testBaseAcionRunnable, "commonHeader", mock(CommonHeader.class)); + } + + @Test + public void testSetTimeoutValues() throws Exception { + Whitebox.setInternalState(testBaseAcionRunnable, "timeoutMs", 0); + Whitebox.setInternalState(testBaseAcionRunnable, "startTimeMs", 0); + Whitebox.setInternalState(testBaseAcionRunnable, "doTimeoutChecking", false); + long expectedTimeout = 10000L; + Mockito.doReturn(expectedTimeout).when(mockConfigHelper).getOAMOperationTimeoutValue(any()); + testBaseAcionRunnable.setTimeoutValues(); + Assert.assertEquals("Should set timeoutMs", expectedTimeout, testBaseAcionRunnable.timeoutMs); + Assert.assertTrue("Should set start time MS", testBaseAcionRunnable.startTimeMs != 0); + Assert.assertTrue("Should do check", testBaseAcionRunnable.doTimeoutChecking); + + Whitebox.setInternalState(testBaseAcionRunnable, "timeoutMs", 0); + Whitebox.setInternalState(testBaseAcionRunnable, "startTimeMs", 0); + Whitebox.setInternalState(testBaseAcionRunnable, "doTimeoutChecking", false); + expectedTimeout = 20000L; + Mockito.doReturn(expectedTimeout).when(mockConfigHelper).getOAMOperationTimeoutValue(any()); + testBaseAcionRunnable.setTimeoutValues(); + Assert.assertEquals("Should set timeoutMs", expectedTimeout, testBaseAcionRunnable.timeoutMs); + Assert.assertTrue("Should set start time MS", testBaseAcionRunnable.startTimeMs != 0); + Assert.assertTrue("Should do check", testBaseAcionRunnable.doTimeoutChecking); + + Whitebox.setInternalState(testBaseAcionRunnable, "timeoutMs", 0); + Whitebox.setInternalState(testBaseAcionRunnable, "startTimeMs", 0); + Whitebox.setInternalState(testBaseAcionRunnable, "doTimeoutChecking", false); + expectedTimeout = 0L; + Mockito.doReturn(expectedTimeout).when(mockConfigHelper).getOAMOperationTimeoutValue(any()); + testBaseAcionRunnable.setTimeoutValues(); + Assert.assertEquals("Should set timeoutMs", expectedTimeout, testBaseAcionRunnable.timeoutMs); + Assert.assertTrue("Should not set start time MS", testBaseAcionRunnable.startTimeMs == 0); + Assert.assertFalse("Should not do check", testBaseAcionRunnable.doTimeoutChecking); + } + + @Test + public void testRun() throws Exception { + // test doAction failed + Whitebox.setInternalState(testBaseAcionRunnable, "doActionResult", false); + testBaseAcionRunnable.run(); + Assert.assertFalse("isWaiting should still be false", + Whitebox.getInternalState(testBaseAcionRunnable, "isWaiting")); + + // test doAction success + Whitebox.setInternalState(testBaseAcionRunnable, "doActionResult", true); + + // with checkState return true + Mockito.doReturn(true).when(testBaseAcionRunnable).checkState(); + testBaseAcionRunnable.run(); + Assert.assertFalse("isWaiting should still be false", + Whitebox.getInternalState(testBaseAcionRunnable, "isWaiting")); + + // with checkState return false + Mockito.doReturn(false).when(testBaseAcionRunnable).checkState(); + testBaseAcionRunnable.run(); + Assert.assertTrue("isWaiting should still be true", + Whitebox.getInternalState(testBaseAcionRunnable, "isWaiting")); + + // should stay + testBaseAcionRunnable.run(); + Mockito.verify(testBaseAcionRunnable, times(1)).keepWaiting(); + } + + @Test + public void testSetAbortStatus() throws Exception { + testBaseAcionRunnable.setAbortStatus(); + Assert.assertEquals("Should return abort code", OAMCommandStatus.ABORT.getResponseCode(), + testBaseAcionRunnable.status.getCode().intValue()); + Assert.assertTrue("Should set abort due to execution error message", + testBaseAcionRunnable.status.getMessage().endsWith( + String.format(testBaseAcionRunnable.ABORT_MESSAGE_FORMAT, + testRpc.name(), testBaseAcionRunnable.DUE_TO_EXECUTION_ERROR))); + } + + @Test + public void testCheckState() throws Exception { + // 1. with isTimeout true + Mockito.doReturn(true).when(testBaseAcionRunnable).isTimeout("checkState"); + Assert.assertTrue("Should return true", testBaseAcionRunnable.checkState()); + + // 2. with isTimeout false and + Mockito.doReturn(false).when(testBaseAcionRunnable).isTimeout("checkState"); + + // 2.1 with task not all done + Mockito.doReturn(false).when(mockBundleHelper).isAllTaskDone(any()); + Assert.assertFalse("Should return false", testBaseAcionRunnable.checkState()); + + // 2. 2 with task all done + Mockito.doReturn(true).when(mockBundleHelper).isAllTaskDone(any()); + + // 2.2.1 with has bundle failure + Mockito.doReturn(true).when(testBaseAcionRunnable).hasBundleOperationFailure(); + Assert.assertTrue("Should return true", testBaseAcionRunnable.checkState()); + + // 2.2.2 with no bundle failure + Mockito.doReturn(false).when(testBaseAcionRunnable).hasBundleOperationFailure(); + + Mockito.doReturn(targetState).when(mockStateHelper).getBundlesState(); + Assert.assertTrue("Should return true", testBaseAcionRunnable.checkState()); + + Mockito.doReturn(AppcOamStates.Started).when(mockStateHelper).getBundlesState(); + Assert.assertFalse("Should return false", testBaseAcionRunnable.checkState()); + } + + @Test + public void testPostAction() throws Exception { + Mockito.doReturn(AppcOamStates.Started).when(mockStateHelper).getCurrentOamState(); + // set status to avoid NPE when using status + testBaseAcionRunnable.setAbortStatus(); + + // test no parameter + testBaseAcionRunnable.postAction(null); + Mockito.verify(mockOperHelper, times(1)).sendNotificationMessage(any(), any(), any()); + Mockito.verify(mockStateHelper, times(0)).setState(any()); + Mockito.verify(testProcessor, times(1)).cancelAsyncTask(); + + // test with parameter + testBaseAcionRunnable.postAction(AppcOamStates.Error); + Mockito.verify(mockOperHelper, times(2)).sendNotificationMessage(any(), any(), any()); + Mockito.verify(mockStateHelper, times(1)).setState(any()); + Mockito.verify(testProcessor, times(2)).cancelAsyncTask(); + } + + @Test + public void testIsTimeout() throws Exception { + String parentName = "testing"; + Whitebox.setInternalState(testBaseAcionRunnable, "doTimeoutChecking", false); + Assert.assertFalse("Should not be timeout", testBaseAcionRunnable.isTimeout(parentName)); + + Mockito.doReturn(AppcOamStates.Started).when(mockStateHelper).getCurrentOamState(); + Whitebox.setInternalState(testBaseAcionRunnable, "doTimeoutChecking", true); + Whitebox.setInternalState(testBaseAcionRunnable, "timeoutMs", System.currentTimeMillis() + 100); + Whitebox.setInternalState(testBaseAcionRunnable, "startTimeMs", 2); + Assert.assertFalse("Should not be timeout", testBaseAcionRunnable.isTimeout(parentName)); + + long timeoutMs = 1; + Whitebox.setInternalState(testBaseAcionRunnable, "timeoutMs", timeoutMs); + Whitebox.setInternalState(testBaseAcionRunnable, "startTimeMs", 2); + Assert.assertTrue("Should be timeout", testBaseAcionRunnable.isTimeout(parentName)); + Mockito.verify(testBaseAcionRunnable, times(1)).postAction(any()); + Assert.assertEquals("Should return timeout code", OAMCommandStatus.TIMEOUT.getResponseCode(), + testBaseAcionRunnable.status.getCode().intValue()); + Assert.assertTrue("Should set timeout message", + testBaseAcionRunnable.status.getMessage().endsWith( + String.format(testBaseAcionRunnable.TIMEOUT_MESSAGE_FORMAT, testRpc.name(), timeoutMs))); + } + + @SuppressWarnings("unchecked") + @Test + public void testHasBundleOperationFailure() throws Exception { + Mockito.when(mockBundleHelper.getFailedMetrics(anyMap())).thenReturn(Long.valueOf("0")); + Assert.assertFalse("should return false", testBaseAcionRunnable.hasBundleOperationFailure()); + + Mockito.when(mockStateHelper.getCurrentOamState()).thenReturn(AppcOamStates.Restarting); + long failedNumber = 1; + Mockito.doReturn(failedNumber).when(mockBundleHelper).getFailedMetrics(anyMap()); + Assert.assertTrue("should return true", testBaseAcionRunnable.hasBundleOperationFailure()); + Mockito.verify(testBaseAcionRunnable, times(1)).setStatus(OAMCommandStatus.UNEXPECTED_ERROR, + String.format(testBaseAcionRunnable.BUNDLE_OPERATION_FAILED_FORMAT, failedNumber)); + Mockito.verify(testBaseAcionRunnable, times(1)).postAction(AppcOamStates.Error); + } + + @Test + public void testAbortRunnable() throws Exception { + Mockito.doReturn(AppcOamStates.Restarting).when(mockStateHelper).getCurrentOamState(); + AppcOam.RPC newRpc = AppcOam.RPC.restart; + testBaseAcionRunnable.abortRunnable(newRpc); + Assert.assertEquals("Should return abort code", OAMCommandStatus.ABORT.getResponseCode(), + testBaseAcionRunnable.status.getCode().intValue()); + Assert.assertTrue("Should set abort due to new request message", + testBaseAcionRunnable.status.getMessage().endsWith( + String.format(testBaseAcionRunnable.ABORT_MESSAGE_FORMAT, testRpc.name(), + String.format(testBaseAcionRunnable.NEW_RPC_OPERATION_REQUEST, newRpc.name())))); + Mockito.verify(mockOperHelper, times(1)).sendNotificationMessage(any(), any(), any()); + Mockito.verify(testBaseAcionRunnable, times(1)).resetLogProperties(false); + Mockito.verify(testBaseAcionRunnable, times(1)).resetLogProperties(true); + } +} diff --git a/appc-oam/appc-oam-bundle/src/test/java/org/onap/appc/oam/processor/BaseCommonTest.java b/appc-oam/appc-oam-bundle/src/test/java/org/onap/appc/oam/processor/BaseCommonTest.java new file mode 100644 index 000000000..59bddb0e4 --- /dev/null +++ b/appc-oam/appc-oam-bundle/src/test/java/org/onap/appc/oam/processor/BaseCommonTest.java @@ -0,0 +1,182 @@ +/*- + * ============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.processor; + +import com.att.eelf.configuration.EELFLogger; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mockito; +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.status.Status; +import org.onap.appc.exceptions.InvalidInputException; +import org.onap.appc.exceptions.InvalidStateException; +import org.onap.appc.oam.AppcOam; +import org.onap.appc.oam.OAMCommandStatus; +import org.onap.appc.oam.util.ConfigurationHelper; +import org.onap.appc.oam.util.OperationHelper; +import org.onap.appc.oam.util.StateHelper; +import org.onap.appc.statemachine.impl.readers.AppcOamStates; +import org.powermock.api.mockito.PowerMockito; +import org.powermock.core.classloader.annotations.PrepareForTest; +import org.powermock.modules.junit4.PowerMockRunner; +import org.powermock.reflect.Whitebox; +import org.slf4j.MDC; + +import java.util.Map; + +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.spy; +import static org.mockito.Mockito.times; +import static org.powermock.api.mockito.PowerMockito.mockStatic; + +@RunWith(PowerMockRunner.class) +@PrepareForTest({BaseCommon.class, MDC.class}) +public class BaseCommonTest { + private class TestAbc extends BaseCommon { + + /** + * Constructor + * + * @param eelfLogger for logging + * @param configurationHelperIn for property reading + * @param stateHelperIn for APP-C OAM state checking + * @param operationHelperIn for operational helper + */ + TestAbc(EELFLogger eelfLogger, + ConfigurationHelper configurationHelperIn, + StateHelper stateHelperIn, + OperationHelper operationHelperIn) { + super(eelfLogger, configurationHelperIn, stateHelperIn, operationHelperIn); + } + } + + private TestAbc testBaseCommon; + private ConfigurationHelper mockConfigHelper = mock(ConfigurationHelper.class); + private StateHelper mockStateHelper = mock(StateHelper.class); + private CommonHeader mockCommonHeader = mock(CommonHeader.class); + + @Before + public void setUp() throws Exception { + testBaseCommon = spy(new TestAbc(null, mockConfigHelper, mockStateHelper, null)); + + Whitebox.setInternalState(testBaseCommon, "commonHeader", mockCommonHeader); + Whitebox.setInternalState(testBaseCommon, "rpc", AppcOam.RPC.maintenance_mode); + + // to avoid operation on logger fail, mock up the logger + EELFLogger mockLogger = mock(EELFLogger.class); + Whitebox.setInternalState(testBaseCommon, "logger", mockLogger); + } + + @Test + public void testSetStatus() throws Exception { + OAMCommandStatus oamCommandStatus = OAMCommandStatus.ACCEPTED; + testBaseCommon.setStatus(oamCommandStatus); + Status status = testBaseCommon.status; + Assert.assertEquals("Should have code", oamCommandStatus.getResponseCode(), status.getCode().intValue()); + Assert.assertEquals("Should have message", oamCommandStatus.getResponseMessage(), status.getMessage()); + } + + @Test + public void testSetStatusWithParams() throws Exception { + String message = "testing"; + OAMCommandStatus oamCommandStatus = OAMCommandStatus.REJECTED; + testBaseCommon.setStatus(oamCommandStatus, message); + Status status = testBaseCommon.status; + Assert.assertEquals("Should have code", oamCommandStatus.getResponseCode(), status.getCode().intValue()); + Assert.assertTrue("Should have message", status.getMessage().endsWith(message)); + } + + @Test + public void testSetErrorStatus() throws Exception { + Mockito.doReturn("testName").when(mockConfigHelper).getAppcName(); + Mockito.doReturn(AppcOamStates.Started).when(mockStateHelper).getCurrentOamState(); + Mockito.doReturn("testRequestId").when(mockCommonHeader).getRequestId(); + Mockito.doReturn("testOrigId").when(mockCommonHeader).getOriginatorId(); + + String exceptionMessage = "testing"; + + OAMCommandStatus oamCommandStatus = OAMCommandStatus.INVALID_PARAMETER; + Throwable t = new InvalidInputException(exceptionMessage); + testBaseCommon.setErrorStatus(t); + Status status = testBaseCommon.status; + Assert.assertEquals("Should have code", oamCommandStatus.getResponseCode(), status.getCode().intValue()); + Mockito.verify(testBaseCommon, times(1)).resetLogProperties(false); + Mockito.verify(testBaseCommon, times(1)).resetLogProperties(true); + + oamCommandStatus = OAMCommandStatus.REJECTED; + t = new InvalidStateException(exceptionMessage); + testBaseCommon.setErrorStatus(t); + status = testBaseCommon.status; + Assert.assertEquals("Should have code", oamCommandStatus.getResponseCode(), status.getCode().intValue()); + Mockito.verify(testBaseCommon, times(2)).resetLogProperties(false); + Mockito.verify(testBaseCommon, times(2)).resetLogProperties(true); + + oamCommandStatus = OAMCommandStatus.UNEXPECTED_ERROR; + t = new NullPointerException(exceptionMessage); + testBaseCommon.setErrorStatus(t); + status = testBaseCommon.status; + Assert.assertEquals("Should have code", oamCommandStatus.getResponseCode(), status.getCode().intValue()); + Mockito.verify(testBaseCommon, times(3)).resetLogProperties(false); + Mockito.verify(testBaseCommon, times(3)).resetLogProperties(true); + } + + @Test + public void testSetInitialLogProperties() throws Exception { + mockStatic(MDC.class); + testBaseCommon.setInitialLogProperties(); + PowerMockito.verifyStatic(times(5)); + } + + @Test + public void testClearRequestLogProperties() throws Exception { + mockStatic(MDC.class); + testBaseCommon.clearRequestLogProperties(); + PowerMockito.verifyStatic(times(5)); + } + + @Test + public void testResetLogProperties() throws Exception { + testBaseCommon.setInitialLogProperties(); + + testBaseCommon.resetLogProperties(false); + Mockito.verify(mockCommonHeader, times(2)).getRequestId(); + Mockito.verify(mockCommonHeader, times(2)).getOriginatorId(); + Map oldMdcMap = Whitebox.getInternalState(testBaseCommon, "oldMdcContent"); + Assert.assertTrue("Should have 5 entries in persisted map", oldMdcMap.size() == 5); + + testBaseCommon.resetLogProperties(false); + Mockito.verify(mockCommonHeader, times(3)).getRequestId(); + Mockito.verify(mockCommonHeader, times(3)).getOriginatorId(); + + // test oldMdcMap is cleared + testBaseCommon.resetLogProperties(false); + Mockito.verify(mockCommonHeader, times(4)).getRequestId(); + Mockito.verify(mockCommonHeader, times(4)).getOriginatorId(); + oldMdcMap = Whitebox.getInternalState(testBaseCommon, "oldMdcContent"); + Assert.assertTrue("Should have 5 entries in persisted map", oldMdcMap.size() == 5); + } +} diff --git a/appc-oam/appc-oam-bundle/src/test/java/org/onap/appc/oam/processor/BaseProcessorTest.java b/appc-oam/appc-oam-bundle/src/test/java/org/onap/appc/oam/processor/BaseProcessorTest.java new file mode 100644 index 000000000..6769352c6 --- /dev/null +++ b/appc-oam/appc-oam-bundle/src/test/java/org/onap/appc/oam/processor/BaseProcessorTest.java @@ -0,0 +1,174 @@ +/*- + * ============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.processor; + +import com.att.eelf.configuration.EELFLogger; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import org.mockito.Mockito; +import org.opendaylight.yang.gen.v1.org.onap.appc.oam.rev170303.StartInput; +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.status.Status; +import org.onap.appc.exceptions.APPCException; +import org.onap.appc.exceptions.InvalidInputException; +import org.onap.appc.exceptions.InvalidStateException; +import org.onap.appc.i18n.Msg; +import org.onap.appc.oam.AppcOam; +import org.onap.appc.oam.OAMCommandStatus; +import org.onap.appc.oam.util.AsyncTaskHelper; +import org.onap.appc.oam.util.ConfigurationHelper; +import org.onap.appc.oam.util.OperationHelper; +import org.onap.appc.oam.util.StateHelper; +import org.onap.appc.statemachine.impl.readers.AppcOamStates; +import org.powermock.reflect.Whitebox; + +import static org.mockito.Matchers.any; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.spy; +import static org.mockito.Mockito.times; + +@SuppressWarnings("ResultOfMethodCallIgnored") +public class BaseProcessorTest { + private AppcOam.RPC testRpc = AppcOam.RPC.start; + private AppcOamStates currentState = AppcOamStates.Stopped; + + private class TestAbc extends BaseProcessor { + + /** + * Constructor + * + * @param eelfLogger for logging + * @param configurationHelperIn for property reading + * @param stateHelperIn for APP-C OAM state checking + * @param asyncTaskHelperIn for scheduling async task + * @param operationHelperIn for operational helper + */ + TestAbc(EELFLogger eelfLogger, + ConfigurationHelper configurationHelperIn, + StateHelper stateHelperIn, + AsyncTaskHelper asyncTaskHelperIn, + OperationHelper operationHelperIn) { + super(eelfLogger, configurationHelperIn, stateHelperIn, asyncTaskHelperIn, operationHelperIn); + + // must set rpc and auditMsg + rpc = testRpc; + auditMsg = Msg.OAM_OPERATION_STARTING; + } + } + + private TestAbc testBaseProcessor; + private ConfigurationHelper mockConfigHelper = mock(ConfigurationHelper.class); + private StateHelper mockStateHelper = mock(StateHelper.class); + private AsyncTaskHelper mockTaskHelper = mock(AsyncTaskHelper.class); + private OperationHelper mockOperHelper = mock(OperationHelper.class); + + private StartInput mockInput = mock(StartInput.class); + private CommonHeader mockCommonHeader = mock(CommonHeader.class); + + @Before + public void setUp() throws Exception { + Mockito.doReturn(mockCommonHeader).when(mockOperHelper).getCommonHeader(mockInput); + Mockito.doReturn(mockCommonHeader).when(mockInput).getCommonHeader(); + + testBaseProcessor = spy( + new TestAbc(null, mockConfigHelper, mockStateHelper, mockTaskHelper, mockOperHelper)); + + Whitebox.setInternalState(testBaseProcessor, "commonHeader", mockCommonHeader); + + // to avoid operation on logger fail, mock up the logger + EELFLogger mockLogger = mock(EELFLogger.class); + Whitebox.setInternalState(testBaseProcessor, "logger", mockLogger); + } + + @Test + public void testProcessRequestError() throws Exception { + Mockito.doReturn(currentState).when(mockStateHelper).getCurrentOamState(); + Mockito.doThrow(new InvalidInputException("test")).when(mockOperHelper).isInputValid(mockInput); + Status status = testBaseProcessor.processRequest(mockInput); + Assert.assertEquals("Should return reject", + OAMCommandStatus.INVALID_PARAMETER.getResponseCode(), status.getCode().intValue()); + } + + @Test + public void testProcessRequest() throws Exception { + Mockito.doReturn(currentState).when(mockStateHelper).getCurrentOamState(); + Mockito.doReturn(AppcOamStates.Starting).when(mockOperHelper).getNextState(any(), any()); + Mockito.doReturn(mockCommonHeader).when(mockInput).getCommonHeader(); + Status status = testBaseProcessor.processRequest(mockInput); + Assert.assertEquals("Should return success", + OAMCommandStatus.ACCEPTED.getResponseCode(), status.getCode().intValue()); + } + + @Test(expected = InvalidInputException.class) + public void testPreProcessWithInvalidInput() throws Exception { + Mockito.doThrow(new InvalidInputException("test")).when(mockOperHelper).isInputValid(mockInput); + testBaseProcessor.preProcess(mockInput); + } + + @Test(expected = InvalidStateException.class) + public void testPreProcessWithInvalidState() throws Exception { + Mockito.doReturn(currentState).when(mockStateHelper).getCurrentOamState(); + Mockito.doThrow(new InvalidStateException("test")) + .when(mockOperHelper).getNextState(testRpc.getAppcOperation(), currentState); + testBaseProcessor.preProcess(mockInput); + } + + @Test(expected = APPCException.class) + public void testPreProcessWithAppcException() throws Exception { + Mockito.doReturn(currentState).when(mockStateHelper).getCurrentOamState(); + Mockito.doThrow(new APPCException("test")) + .when(mockOperHelper).getNextState(testRpc.getAppcOperation(), currentState); + testBaseProcessor.preProcess(mockInput); + } + + @Test + public void testPreProcess() throws Exception { + Mockito.doReturn(currentState).when(mockStateHelper).getCurrentOamState(); + AppcOamStates nextState = AppcOamStates.Starting; + Mockito.doReturn(nextState) + .when(mockOperHelper).getNextState(testRpc.getAppcOperation(), currentState); + testBaseProcessor.preProcess(mockInput); + Mockito.verify(mockOperHelper, times(1)).isInputValid(mockInput); + Mockito.verify(mockOperHelper, times(1)).getNextState(testRpc.getAppcOperation(), currentState); + Mockito.verify(mockStateHelper, times(1)).setState(nextState); + } + + @Test + public void testScheduleAsyncTask() throws Exception { + // test no runnable + testBaseProcessor.scheduleAsyncTask(); + Assert.assertTrue(Whitebox.getInternalState(testBaseProcessor, "runnable") == null); + Assert.assertTrue(Whitebox.getInternalState(testBaseProcessor, "scheduledRunnable") == null); + + BaseActionRunnable mockRunnable = mock(BaseActionRunnable.class); + Whitebox.setInternalState(testBaseProcessor, "runnable", mockRunnable); + testBaseProcessor.scheduleAsyncTask(); + // scheduledRunnable should still be null, there's no mock done + // as I have trouble to make mockTaskHelper.scheduleBaseRunnable to return a proper Future + Assert.assertTrue(Whitebox.getInternalState(testBaseProcessor, "scheduledRunnable") == null); + } + +} diff --git a/appc-oam/appc-oam-bundle/src/test/java/org/onap/appc/oam/util/AsyncTaskHelperTest.java b/appc-oam/appc-oam-bundle/src/test/java/org/onap/appc/oam/util/AsyncTaskHelperTest.java new file mode 100644 index 000000000..ddeb99440 --- /dev/null +++ b/appc-oam/appc-oam-bundle/src/test/java/org/onap/appc/oam/util/AsyncTaskHelperTest.java @@ -0,0 +1,665 @@ +/*- + * ============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 org.junit.After; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mockito; +import org.onap.appc.oam.AppcOam; +import org.onap.appc.statemachine.impl.readers.AppcOamStates; +import org.osgi.framework.Bundle; +import org.osgi.framework.FrameworkUtil; +import org.powermock.api.mockito.PowerMockito; +import org.powermock.core.classloader.annotations.PrepareForTest; +import org.powermock.modules.junit4.PowerMockRunner; + +import java.util.LinkedList; +import java.util.concurrent.Future; +import java.util.concurrent.Semaphore; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.TimeoutException; +import java.util.concurrent.atomic.AtomicReference; +import java.util.function.Supplier; + +import static org.mockito.Matchers.any; +import static org.mockito.Mockito.mock; +import static org.powermock.api.mockito.PowerMockito.mockStatic; + + +@RunWith(PowerMockRunner.class) +@PrepareForTest({FrameworkUtil.class}) +public class AsyncTaskHelperTest { + private AsyncTaskHelper asyncTaskHelper; + + private long initialDelayMillis = 0; + private long delayMillis = 10; + + + @Before + public void setUp() throws Exception { + + // to avoid operation on logger fail, mock up the logger + EELFLogger mockLogger = mock(EELFLogger.class); + + + mockStatic(FrameworkUtil.class); + Bundle myBundle = mock(Bundle.class); + Mockito.doReturn("TestBundle").when(myBundle).getSymbolicName(); + PowerMockito.when(FrameworkUtil.getBundle(any())).thenReturn(myBundle); + + asyncTaskHelper = new AsyncTaskHelper(mockLogger); + + + } + + + @After + public void shutdown(){ + asyncTaskHelper.close(); + } + + + /** + * Test that Base Runnable + * + * Runs at a fix rate; + * Only one Base Runnable can be scheduled at time; + * Future.cancle stops the Base Runnable; + * That another Base Runnable can be scheduled once the previous isDone. + */ + @Test + public void test_scheduleBaseRunnable_Base_isDone() throws Exception{ + + + + //loop is to test we can run consecutive Base Runnable + for(int testIteration = 0; testIteration < 3;testIteration++){ + final ExecuteTest et = new ExecuteTest(); + + Future future = asyncTaskHelper.scheduleBaseRunnable( + et::test + , s -> { } + ,initialDelayMillis + ,delayMillis + ); + + //make sure it is running at a fix rate + Assert.assertTrue("It should be iterating", et.waitForTestExec(5000)); + Assert.assertFalse("It Should not be Done", future.isDone()); + Assert.assertTrue("It should be iterating", et.waitForTestExec(5000)); + Assert.assertFalse("It Should not be Done", future.isDone()); + + + //make sure a seconds Runnable cannot be scheduled when one is already running + try { + asyncTaskHelper.scheduleBaseRunnable(et::test + , s -> {} + ,initialDelayMillis + ,delayMillis + ); + Assert.fail("scheduling should have been prevented. "); + } catch (IllegalStateException e) { + //IllegalStateException means the second scheduling was not allowed. + } + + + //let it cancel itself + et.cancelSelfOnNextExecution(future); + + //it should be done after it executes itself one more time. + Assert.assertTrue("it should be done", waitFor(future::isDone, 5000)); + Assert.assertTrue("The test failed to execute", et.isExecuted); + } + + + } + + + /** + * Makes sure the Future.isDone one only returns true if its runnable is not currently executing and will not + * execute in the future. Default implementation of isDone() returns true immediately after the future is + * canceled -- Even if is there is still a thread actively executing the runnable + */ + @Test + public void test_scheduleBaseRunnable_Base_isDone_Ignore_Interrupt() throws Exception{ + + + final ExecuteTest et = new ExecuteTest(); + + //configure test to run long and ignore interrupt + et.isContinuous = true; + et.isIgnoreInterrupt = true; + + + + Future future = asyncTaskHelper.scheduleBaseRunnable( + et::test + , s->{} + ,initialDelayMillis + ,delayMillis + ); + + //make sure it is running + Assert.assertTrue("It should be running",waitFor(et::isExecuting,1000)); + Assert.assertTrue("It should be running",et.waitForTestExec(1000)); + Assert.assertFalse("It Should not be Done", future.isDone()); + + //cancel it and make sure it is still running + future.cancel(true); + Assert.assertTrue("It should be running",waitFor(et::isExecuting,1000)); + Assert.assertTrue("It should be running",et.waitForTestExec(1000)); + Assert.assertFalse("It Should not be Done", future.isDone()); + + //let the thread die and then make sure its done + et.isContinuous = false; + Assert.assertTrue("It should not be running",waitForNot(et::isExecuting,1000)); + Assert.assertTrue("It Should be Done", future.isDone()); + + } + + + + + /** + * Make sure the base Future.isDone returns false until the sub callable has completed execution. + */ + @Test + public void test_scheduleBaseRunnable_SubTask_isDone_Ignore_Interrupt() throws Exception{ + + + final ExecuteTest baseET = new ExecuteTest(); + final ExecuteTest subET = new ExecuteTest(); + + //configure sub test to run long and ignore interrupt + subET.isContinuous = true; + subET.isIgnoreInterrupt = true; + + + //schedule the Base test to run and make sure it is running. + Future baseFuture = asyncTaskHelper.scheduleBaseRunnable( + baseET::test + ,s->{} + ,initialDelayMillis + ,delayMillis + ); + Assert.assertTrue("baseET should be running",waitFor(baseET::isExecuted,1000)); + Assert.assertFalse("baseET Should not be Done because it runs at a fix rate", baseFuture.isDone()); + + + //schedule the sub task and make sure it is running + Future subFuture = asyncTaskHelper.submitBaseSubCallable(subET::test); + Assert.assertTrue("subET should be running",waitFor(subET::isExecuting,1000)); + Assert.assertTrue("subET should be running",subET.waitForTestExec(1000)); + Assert.assertFalse("subET Should not be Done", subFuture.isDone()); + Assert.assertFalse("baseET Should not be Done", baseFuture.isDone()); + + //cancel the base task and make sure isDone is still false + baseFuture.cancel(true); + Assert.assertTrue("subET should be running",waitFor(subET::isExecuting,1000)); + Assert.assertTrue("subET should be running",subET.waitForTestExec(1000)); + Assert.assertFalse("subET Should not be Done",subFuture.isDone()); + Assert.assertFalse("baseET Should not be Done", baseFuture.isDone()); + + + //let the sub task die and and make sure the base is now finally done + subET.isContinuous = false; + Assert.assertTrue("subET should not be running",waitForNot(subET::isExecuting,1000)); + Assert.assertTrue("subET Should be Done", subFuture.isDone()); + Assert.assertTrue("baseET Should be Done", baseFuture.isDone()); + + } + + + /** + * Make sure the base Future.isDone returns false until the 3 sub callable has completed execution. + * Each sub callable will be shutdown one at a time. + */ + @Test + public void test_scheduleBaseRunnable_SubTasks_isDone() throws Exception { + + + //loop is to test we can run consecutive Base Runnable + for (int testIteration = 0; testIteration < 3; testIteration++) { + final ExecuteTest baseET = new ExecuteTest(); + final LinkedList subList = new LinkedList<>(); + for (int i = 0; i < 3; i++) { + Sub sub = new Sub(); + sub.et.isContinuous = true; + subList.add(sub); + } + + + //schedule the base runnable and make sure it is running + Future baseFuture = asyncTaskHelper.scheduleBaseRunnable( + baseET::test + , s -> { + } + , initialDelayMillis + , delayMillis + ); + Assert.assertTrue("baseET should be running", waitFor(baseET::isExecuted, 1000)); + Assert.assertFalse("baseET Should not be Done because it runs at a fix rate", baseFuture.isDone()); + + + //schedule the sub Callables and make sure these are running + subList.forEach(sub -> sub.future = asyncTaskHelper.submitBaseSubCallable(sub.et::test)); + for (Sub sub : subList) { + Assert.assertTrue("subET should be running", waitFor(sub.et::isExecuting, 100)); + Assert.assertTrue("subET should be running", sub.et.waitForTestExec(1000)); + Assert.assertFalse("subET Should not be Done", sub.future.isDone()); + } + Assert.assertFalse("baseET Should not be Done", baseFuture.isDone()); + + + //On each iteration shut down a sub callable. Make sure it stops, the others are still running and the + // //base is still running. + while (!subList.isEmpty()) { + + //stop one sub and make sure it stopped + { + Sub sub = subList.removeFirst(); + Assert.assertTrue("subET should be running", waitFor(sub.et::isExecuting, 1000)); + sub.et.isContinuous = false; + Assert.assertTrue("subET should not be running", waitForNot(sub.et::isExecuting,1000)); + Assert.assertTrue("subET Should not be Done", sub.future.isDone()); + } + + //make sure the other are still running + for (Sub sub : subList) { + Assert.assertTrue("subET should be running", waitFor(sub.et::isExecuting, 1000)); + Assert.assertTrue("subET should be running", sub.et.waitForTestExec(1000)); + Assert.assertFalse("subET Should not be Done", sub.future.isDone()); + } + + //Make sure the Base is still running + Assert.assertFalse("baseET Should not be Done", baseFuture.isDone()); + } + + //let the base cancel itself and make sure it stops + baseET.cancelSelfOnNextExecution(baseFuture); + Assert.assertTrue("baseET should be done", waitFor(baseFuture::isDone, 1000)); + } + } + + + /** + * Make sure SubCallable cannot be scheduled when there is not BaseRunnable + */ + @Test(expected=IllegalStateException.class) + public void test_SubTasksScheduleFailWhenNoBase() throws Exception { + asyncTaskHelper.submitBaseSubCallable(()->null); + } + + + + /** + * Make sure SubCallable cannot be scheduled when BaseRunnable is cancelled but is still actively running. + */ + @Test(expected=IllegalStateException.class) + public void test_SubTasksScheduleFailWhenBaseCanceledBeforeisDone() throws Exception { + + final ExecuteTest et = new ExecuteTest(); + et.isContinuous = true; + + Future future = asyncTaskHelper.scheduleBaseRunnable( + et::test + , s -> { } + ,initialDelayMillis + ,delayMillis + ); + + Assert.assertTrue("It should be running",waitFor(et::isExecuting,1000)); + future.cancel(false); + Assert.assertTrue("It should be running",waitFor(et::isExecuting,1000)); + + try { + asyncTaskHelper.submitBaseSubCallable(() -> null); + } finally { + et.isContinuous = false; + } + + + + } + + + /** + * Make sure SubCallable cannot be scheduled after a BaseRunnable has completed + */ + @Test(expected=IllegalStateException.class) + public void test_SubTasksScheduleFailAfterBaseDone() throws Exception { + + final ExecuteTest et = new ExecuteTest(); + + Future future = asyncTaskHelper.scheduleBaseRunnable( + et::test + , s -> { } + ,initialDelayMillis + ,delayMillis + ); + + + future.cancel(false); + Assert.assertTrue("It should not be running",waitFor(future::isDone,1000)); + + try { + asyncTaskHelper.submitBaseSubCallable(() -> null); + } finally { + et.isContinuous = false; + } + + } + + + /** + * Test {@link AsyncTaskHelper#cancelBaseActionRunnable(AppcOam.RPC, AppcOamStates, long, TimeUnit)}} + * Test cancel does not block when BaseRunnable is not scheduled + */ + @Test + public void test_cancel_noBlockingWhenBaseRunnableNotScheduled() throws Exception{ + //nothing is running so this should return immediately without TimeoutException + asyncTaskHelper.cancelBaseActionRunnable(AppcOam.RPC.stop , AppcOamStates.Started , 1, TimeUnit.MILLISECONDS); + } + + + + /** + * Test {@link AsyncTaskHelper#cancelBaseActionRunnable(AppcOam.RPC, AppcOamStates, long, TimeUnit)}} + * Test cancel does blocks until BaseRunnable is done scheduled + */ + @Test() + public void test_cancel_BlockingWhenBaseRunnableNotDone() throws Exception { + + + final ExecuteTest et = new ExecuteTest(); + et.isContinuous = true; + et.isIgnoreInterrupt = true; + asyncTaskHelper.scheduleBaseRunnable( + et::test + , s -> { + } + , initialDelayMillis + , delayMillis + ); + + Assert.assertTrue("It should be running", waitFor(et::isExecuting, 1000)); + + + //we should get a timeout + try { + asyncTaskHelper.cancelBaseActionRunnable( + AppcOam.RPC.stop, + AppcOamStates.Started, + 1, + TimeUnit.MILLISECONDS); + Assert.fail("Should have gotten TimeoutException"); + } catch (TimeoutException e) { + //just ignore as it is expected + } + + + //release the test thread + et.isContinuous = false; + + + //we should not get a timeout + asyncTaskHelper.cancelBaseActionRunnable( + AppcOam.RPC.stop, + AppcOamStates.Started, + 1000, + TimeUnit.MILLISECONDS); + + } + + + + /** + * Test {@link AsyncTaskHelper#cancelBaseActionRunnable(AppcOam.RPC, AppcOamStates, long, TimeUnit)}} + * Test cancel does not block when BaseRunnable is not scheduled + */ + @Test + public void test_BaseRunnableCancelCallback() throws Exception{ + + AtomicReference cancelCallback = new AtomicReference<>(null); + + final ExecuteTest et = new ExecuteTest(); + et.isContinuous = true; + Future future = asyncTaskHelper.scheduleBaseRunnable( + et::test + , cancelCallback::set + , initialDelayMillis + , delayMillis + ); + + Assert.assertTrue("It should be running", waitFor(et::isExecuting, 1000)); + Assert.assertTrue("It should be running", waitForNot(future::isDone, 1000)); + + + try { + asyncTaskHelper.cancelBaseActionRunnable( + AppcOam.RPC.stop, + AppcOamStates.Started, + 1, + TimeUnit.MILLISECONDS); + Assert.fail("Should have gotten TimeoutException"); + } catch (TimeoutException e) { + //just ignore as it is expected + } + + + Assert.assertEquals("Unexpected rpc in call back",AppcOam.RPC.stop,cancelCallback.get()); + } + + + + + + + + + /** + * @return true if the negation of the expected value is returned from the supplier within the specified + * amount of time + */ + private static boolean waitForNot(Supplier s,long timeoutMillis)throws Exception{ + return waitFor(()->!s.get(),timeoutMillis); + } + + + /** + * @return true if the expected value is returned from the supplier within the specified + * amount of time + */ + private static boolean waitFor(Supplier s,long timeoutMillis) throws Exception { + long timeout = TimeUnit.MILLISECONDS.toMillis(timeoutMillis); + long expiryTime = System.currentTimeMillis() + timeout; + long elapsedTime; + while(!s.get()){ + elapsedTime = expiryTime - System.currentTimeMillis(); + if(elapsedTime < 1) { + break; + } + Thread.sleep(10); + } + return s.get(); + } + + + /** + * This class is used control a thread executed in th {@link #test()} + */ + @SuppressWarnings("unused") + private static class ExecuteTest { + + + /** A fail safe to insure this TEst does not run indefinitely */ + private final long EXPIRY_TIME = System.currentTimeMillis() + 10000; + + + + /** A thread sets this value to true when it has completed the execution the of executes {@link #test()} */ + private volatile boolean isExecuted = false; + + /** + * A thread sets this value to true when it is actively executing {@link #test()} and back to false when + * it is not + */ + private volatile boolean isExecuting = false; + + /** + * While this value is true, a thread will not be allowed to return from {@link #test()} It will simulate a + * long execution. + */ + private volatile boolean isContinuous = false; + + /** + * When this value is set to true, an ongoing simulation of a long execution of {@link #test()} cannot be force + * to abort via a {@link Thread#interrupt()} + */ + private volatile boolean isIgnoreInterrupt = false; + + + + /** Use to send a signal to the thread executing {@link #notifyTestExcuted(long)} */ + private Semaphore inner = new Semaphore(0); + + /** Use to send a signal to the thread executing {@link #waitForTestExec(long)} */ + private Semaphore outer = new Semaphore(0); + + /** The {@link Future} of the Thread executing {@link #test()}*/ + private volatile Future future; + + /** + * When set the Thread executing {@link #test()} will cancel itself + * @param future - The {@link Future} of the Thread executing {@link #test()} + */ + private void cancelSelfOnNextExecution(Future future) { + this.future = future; + } + + + private boolean isExecuted() { + return isExecuted; + } + + private boolean isExecuting() { + return isExecuting; + } + + + private boolean isContinuous() { + return isContinuous; + } + + + private boolean isIgnoreInterrupt() { + return isIgnoreInterrupt; + } + + + + /** + * The thread executing this method if blocked from returning until the thread executing + * {@link #test()} invokes {@link #notifyTestExcuted(long)} or the specified time elapses + * @param timeoutMillis - the amount of time to wait for a execution iteration. + * @return true if the Thread is released because of an invocation of {@link #notifyTestExcuted(long)} + * @throws InterruptedException - If the Caller thread is interrupted. + */ + private boolean waitForTestExec(long timeoutMillis) throws InterruptedException { + inner.release(); + return outer.tryAcquire(timeoutMillis,TimeUnit.MILLISECONDS); + } + + + /** + * Test simulator + * @return Always returns true. + */ + private Boolean test() { + isTestExpired(); + System.out.println("started"); + isExecuting = true; + try { + if (future != null) { + future.cancel(false); + } + if(!isContinuous){ + notifyTestExcuted(1); + } + + while(isContinuous){ + notifyTestExcuted(100); + isTestExpired(); + } + + } finally { + isExecuting = false; + isExecuted = true; + } + return true; + } + + + /** @throws RuntimeException if the test has bee running too long */ + private void isTestExpired(){ + if(System.currentTimeMillis() > EXPIRY_TIME){ + throw new RuntimeException("Something went wrong the test expired."); + } + } + + + /** + * The thread executing {@link #test()} if blocked from returning until another thread invokes + * {@link #waitForTestExec(long)} or the specified time elapses + * @param timeoutMillis - the amount of time to wait for a execution iteration. + * @return true if the Thread is released because of an invocation of {@link #waitForTestExec(long)} + */ + private boolean notifyTestExcuted(long timeoutMillis){ + try { + boolean acquire = inner.tryAcquire(timeoutMillis,TimeUnit.MILLISECONDS); + if(acquire){ + outer.release(); + System.out.println("release"); + } + } catch (InterruptedException e) { + if(!isIgnoreInterrupt){ + return false; + } + } + return true; + } + } + + + static class Sub { + ExecuteTest et = new ExecuteTest(); + Future future = null; + } + +} diff --git a/appc-oam/appc-oam-bundle/src/test/java/org/onap/appc/oam/util/BundleHelperTest.java b/appc-oam/appc-oam-bundle/src/test/java/org/onap/appc/oam/util/BundleHelperTest.java new file mode 100644 index 000000000..433e87517 --- /dev/null +++ b/appc-oam/appc-oam-bundle/src/test/java/org/onap/appc/oam/util/BundleHelperTest.java @@ -0,0 +1,180 @@ +/*- + * ============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 org.apache.commons.lang.ArrayUtils; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mockito; +import org.onap.appc.configuration.Configuration; +import org.onap.appc.exceptions.APPCException; +import org.onap.appc.oam.AppcOam; +import org.onap.appc.statemachine.impl.readers.AppcOamStates; +import org.osgi.framework.Bundle; +import org.osgi.framework.BundleContext; +import org.osgi.framework.FrameworkUtil; +import org.powermock.api.mockito.PowerMockito; +import org.powermock.api.support.membermodification.MemberMatcher; +import org.powermock.core.classloader.annotations.PrepareForTest; +import org.powermock.modules.junit4.PowerMockRunner; +import org.powermock.reflect.Whitebox; + +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import static org.mockito.Matchers.any; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.times; +import static org.powermock.api.mockito.PowerMockito.mockStatic; +import static org.powermock.api.mockito.PowerMockito.spy; + +@SuppressWarnings("ResultOfMethodCallIgnored") +@RunWith(PowerMockRunner.class) +@PrepareForTest({BundleHelper.class, FrameworkUtil.class}) +public class BundleHelperTest { + private BundleHelper bundleHelper; + private AsyncTaskHelper mockTaskHelper = mock(AsyncTaskHelper.class); + + @Before + public void setUp() throws Exception { + bundleHelper = spy(new BundleHelper(null, null, null)); + + // to avoid operation on logger fail, mock up the logger + EELFLogger mockLogger = mock(EELFLogger.class); + Whitebox.setInternalState(bundleHelper, "logger", mockLogger); + } + + @Test + public void testBundleOperations() throws Exception { + // spy mocked bundle for calls to method statr or stop. + // Note: the time of method calls are accumulated in this test method. + Bundle mockBundle = spy(Mockito.mock(Bundle.class)); + Map mapFromGetAppcLcmBundles = new HashMap<>(); + mapFromGetAppcLcmBundles.put("BundleString", mockBundle); + + PowerMockito.doReturn(mapFromGetAppcLcmBundles).when(bundleHelper, MemberMatcher.method( + BundleHelper.class, "getAppcLcmBundles")).withNoArguments(); + + StateHelper mockStateHelper = mock(StateHelper.class); + Whitebox.setInternalState(bundleHelper, "stateHelper", mockStateHelper); + + AppcOamStates appcOamStates = AppcOamStates.Stopped; + Mockito.doReturn(appcOamStates).when(mockStateHelper).getState(); + + // test start + Mockito.doReturn(true).when(mockStateHelper).isSameState(appcOamStates); + boolean result = bundleHelper.bundleOperations(AppcOam.RPC.start, new HashMap<>(), mockTaskHelper,null); + Assert.assertTrue("Should be completed", result); + Mockito.verify(mockTaskHelper, times(1)).submitBaseSubCallable(any()); + + // test start aborted + Mockito.doReturn(false).when(mockStateHelper).isSameState(appcOamStates); + result = bundleHelper.bundleOperations(AppcOam.RPC.start, new HashMap<>(), mockTaskHelper,null); + Assert.assertFalse("Should be abort", result); + Mockito.verify(mockTaskHelper, times(1)).submitBaseSubCallable(any()); + + // test stop + result = bundleHelper.bundleOperations(AppcOam.RPC.stop, new HashMap<>(), mockTaskHelper,null); + Assert.assertTrue("Should be completed", result); + Mockito.verify(mockTaskHelper, times(2)).submitBaseSubCallable(any()); + } + + @Test(expected = APPCException.class) + public void testBundleOperationsRpcException() throws Exception { + bundleHelper.bundleOperations(AppcOam.RPC.maintenance_mode, new HashMap<>(), mockTaskHelper,null); + } + + @Test + public void testGetBundleList() throws Exception { + mockStatic(FrameworkUtil.class); + Bundle myBundle = mock(Bundle.class); + PowerMockito.when(FrameworkUtil.getBundle(any())).thenReturn(myBundle); + + // test bundle context is null + Mockito.when(myBundle.getBundleContext()).thenReturn(null); + Assert.assertTrue("Should return null", bundleHelper.getBundleList() == null); + + BundleContext myBundleContext = mock(BundleContext.class); + Mockito.when(myBundle.getBundleContext()).thenReturn(myBundleContext); + + // test bundle list is empty + Bundle[] bundleArray = {}; + Mockito.when(myBundleContext.getBundles()).thenReturn(bundleArray); + Bundle[] results = bundleHelper.getBundleList(); + Assert.assertTrue("Should not be null", results != null); + Assert.assertTrue("Should not have any element", results.length == 0); + + // test bundle list has at one bundle + bundleArray = new Bundle[] { myBundle }; + Mockito.when(myBundleContext.getBundles()).thenReturn(bundleArray); + results = bundleHelper.getBundleList(); + Assert.assertTrue("Should not be null", results != null); + Assert.assertTrue("Should have one element", results.length == 1); + Assert.assertEquals("Should be the mock bundle", myBundle, results[0]); + } + + @Test + public void testReadPropsFromPropListName() throws Exception { + // mock configuarion helper + ConfigurationHelper configurationHelper = new ConfigurationHelper(null); + EELFLogger fakeLogger = mock(EELFLogger.class); + Whitebox.setInternalState(configurationHelper, "logger", fakeLogger); + Configuration fakeConf = mock(Configuration.class); + Whitebox.setInternalState(configurationHelper, "configuration", fakeConf); + + Whitebox.setInternalState(bundleHelper, "configurationHelper", configurationHelper); + + String propKey = "testing"; + // Property does not exist + Mockito.doReturn(null).when(fakeConf).getProperty(propKey); + String[] propResult = bundleHelper.readPropsFromPropListName(propKey); + Assert.assertArrayEquals("PropertyResult should be empty string array", + ArrayUtils.EMPTY_STRING_ARRAY, propResult); + // Property has one entry + String propValue1 = "1234"; + String propValue2 = "5678"; + Mockito.doReturn(propValue1).when(fakeConf).getProperty(propKey); + Mockito.doReturn(propValue2).when(fakeConf).getProperty(propValue1); + propResult = bundleHelper.readPropsFromPropListName(propKey); + Assert.assertTrue("PropertyResult should have only one element", propResult.length == 1); + Assert.assertEquals("PropertyResult should martch propertyValue", propValue2, propResult[0]); + // Property has two entries + propValue1 = "1234\n,4321"; + String propValue3 = "8765"; + Mockito.doReturn(propValue1).when(fakeConf).getProperty(propKey); + Mockito.doReturn(propValue2).when(fakeConf).getProperty(propValue1); + Mockito.doReturn(propValue3).when(fakeConf).getProperty("4321"); + propResult = bundleHelper.readPropsFromPropListName(propKey); + Assert.assertTrue("PropertyResult should have two elements", propResult.length == 2); + List propResultList = Arrays.asList(propResult); + Assert.assertTrue("PropertyResult should have propertyValue2", propResultList.contains(propValue2)); + Assert.assertTrue("PropertyResult should have propertyValue2", propResultList.contains(propValue3)); + } +} diff --git a/appc-oam/appc-oam-bundle/src/test/java/org/onap/appc/oam/util/ConfigurationHelperTest.java b/appc-oam/appc-oam-bundle/src/test/java/org/onap/appc/oam/util/ConfigurationHelperTest.java new file mode 100644 index 000000000..348517b72 --- /dev/null +++ b/appc-oam/appc-oam-bundle/src/test/java/org/onap/appc/oam/util/ConfigurationHelperTest.java @@ -0,0 +1,128 @@ +/*- + * ============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 org.apache.commons.lang3.ArrayUtils; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import org.mockito.Mockito; +import org.onap.appc.configuration.Configuration; +import org.powermock.reflect.Whitebox; + +import static org.mockito.Mockito.mock; + +public class ConfigurationHelperTest { + private ConfigurationHelper configurationHelper; + + private Configuration mockConf; + private Configuration origConf; + + @Before + public void setUp() throws Exception { + mockConf = mock(Configuration.class); + + configurationHelper = new ConfigurationHelper(null); + + // to avoid operation on logger fail, mock up the logger + EELFLogger fakeLogger = mock(EELFLogger.class); + Whitebox.setInternalState(configurationHelper, "logger", fakeLogger); + } + + private void setMockConf() { + origConf = Whitebox.getInternalState(configurationHelper, "configuration"); + Whitebox.setInternalState(configurationHelper, "configuration", mockConf); + } + + private void resetOrigConfig() { + Whitebox.setInternalState(configurationHelper, "configuration", origConf); + origConf = null; + } + + @Test + public void getAppcName() throws Exception { + // test with existing properties file + Assert.assertEquals("Should return value(APPC).", "APPC", configurationHelper.getAppcName()); + + // test with mockup + setMockConf(); + + String propValue = "testing"; + Mockito.doReturn(propValue).when(mockConf).getProperty(ConfigurationHelper.PROP_KEY_APPC_NAME); + Assert.assertEquals(String.format("Should return value(%s).", propValue), propValue, + configurationHelper.getAppcName()); + + resetOrigConfig(); + } + + @Test + public void isMetricEnabled() throws Exception { + // test with mockup + setMockConf(); + + Mockito.doReturn(false).when(mockConf).getBooleanProperty( + ConfigurationHelper.PROP_KEY_METRIC_STATE, false); + Assert.assertFalse("Should return false", configurationHelper.isMetricEnabled()); + + Mockito.doReturn(true).when(mockConf).getBooleanProperty( + ConfigurationHelper.PROP_KEY_METRIC_STATE, false); + Assert.assertTrue("Should return true", configurationHelper.isMetricEnabled()); + } + + @Test + public void testReadPropertyNotStop() throws Exception { + String[] str = configurationHelper.readProperty("appc.OAM.AppcBundlesToNotStop"); + Assert.assertTrue(str.length > 0); + Assert.assertTrue(str[0].equals(".*appc.oam.*")); + } + + @Test + public void testReadPropertyStop() throws Exception { + String[] str = configurationHelper.readProperty("appc.OAM.AppcBundlesToStop"); + Assert.assertTrue(str.length > 0); + Assert.assertTrue(str[0].equals(".*appc.*")); + } + + @Test + public void testReadPropertyWithMockup() throws Exception { + setMockConf(); + + String propKey = "testing"; + // Property does not exist + Mockito.doReturn(null).when(mockConf).getProperty(propKey); + String[] propResult = configurationHelper.readProperty(propKey); + Assert.assertArrayEquals("PropertyResult should be empty string array", + ArrayUtils.EMPTY_STRING_ARRAY, propResult); + // Property has one entry + String propValue = "1234"; + Mockito.doReturn(propValue).when(mockConf).getProperty(propKey); + propResult = configurationHelper.readProperty(propKey); + Assert.assertTrue("PropertyResult should have only one element", propResult.length == 1); + Assert.assertEquals("PropertyResult should martch propertyValue", propValue, propResult[0]); + + resetOrigConfig(); + } +} diff --git a/appc-oam/appc-oam-bundle/src/test/java/org/onap/appc/oam/util/OperationHelperTest.java b/appc-oam/appc-oam-bundle/src/test/java/org/onap/appc/oam/util/OperationHelperTest.java new file mode 100644 index 000000000..77edd1701 --- /dev/null +++ b/appc-oam/appc-oam-bundle/src/test/java/org/onap/appc/oam/util/OperationHelperTest.java @@ -0,0 +1,240 @@ +/*- + * ============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 org.junit.Assert; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.ExpectedException; +import org.junit.runner.RunWith; +import org.mockito.Mockito; +import org.opendaylight.yang.gen.v1.org.onap.appc.oam.rev170303.MaintenanceModeInput; +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.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.statemachine.impl.readers.AppcOamMetaDataReader; +import org.onap.appc.statemachine.impl.readers.AppcOamStates; +import org.osgi.framework.Bundle; +import org.osgi.framework.BundleContext; +import org.osgi.framework.FrameworkUtil; +import org.osgi.framework.ServiceReference; +import org.powermock.api.mockito.PowerMockito; +import org.powermock.core.classloader.annotations.PrepareForTest; +import org.powermock.modules.junit4.PowerMockRunner; +import org.powermock.reflect.Whitebox; + +import static org.mockito.Mockito.mock; +import static org.powermock.api.mockito.PowerMockito.mockStatic; + +@RunWith(PowerMockRunner.class) +@PrepareForTest({FrameworkUtil.class}) +public class OperationHelperTest { + private OperationHelper operationHelper; + private LifecycleManager lifecycleManager = mock(LifecycleManager.class); + private CommonHeader mockCommonHeader = mock(CommonHeader.class); + + @Rule + public ExpectedException expectedException = ExpectedException.none(); + + @Before + public void setUp() throws Exception { + operationHelper = new OperationHelper(); + Whitebox.setInternalState(operationHelper, "lifecycleMgr", lifecycleManager); + } + + @Test + public void testIsInputValidWithMissingInput() throws Exception { + expectedException.expect(InvalidInputException.class); + expectedException.expectMessage(operationHelper.MISSING_COMMON_HEADER_MESSAGE); + + operationHelper.isInputValid(null); + expectedException = ExpectedException.none(); + } + + @Test + public void testIsInputValidWithMissingCommonHeader() throws Exception { + StartInput mockInput = mock(StartInput.class); + expectedException.expect(InvalidInputException.class); + expectedException.expectMessage(operationHelper.MISSING_COMMON_HEADER_MESSAGE); + + operationHelper.isInputValid(mockInput); + expectedException = ExpectedException.none(); + } + + @Test + public void testIsInputValidWithMissingOid() throws Exception { + StartInput mockInput = mock(StartInput.class); + Mockito.doReturn(mockCommonHeader).when(mockInput).getCommonHeader(); + Mockito.doReturn(null).when(mockCommonHeader).getOriginatorId(); + expectedException.expect(InvalidInputException.class); + expectedException.expectMessage(operationHelper.MISSING_FIELD_MESSAGE); + + operationHelper.isInputValid(mockInput); + expectedException = ExpectedException.none(); + } + + @Test + public void testIsInputValidWithMissingRid() throws Exception { + StartInput mockInput = mock(StartInput.class); + Mockito.doReturn(mockCommonHeader).when(mockInput).getCommonHeader(); + Mockito.doReturn("originalId").when(mockCommonHeader).getOriginatorId(); + Mockito.doReturn(null).when(mockCommonHeader).getRequestId(); + expectedException.expect(InvalidInputException.class); + expectedException.expectMessage(operationHelper.MISSING_FIELD_MESSAGE); + + operationHelper.isInputValid(mockInput); + expectedException = ExpectedException.none(); + } + + @Test + public void testIsInputValidWithMmodeFlags() throws Exception { + MaintenanceModeInput mockInput = mock(MaintenanceModeInput.class); + Mockito.doReturn(mockCommonHeader).when(mockInput).getCommonHeader(); + Mockito.doReturn("originalId").when(mockCommonHeader).getOriginatorId(); + Mockito.doReturn("requestId").when(mockCommonHeader).getRequestId(); + Mockito.doReturn(mock(Flags.class)).when(mockCommonHeader).getFlags(); + expectedException.expect(InvalidInputException.class); + expectedException.expectMessage(operationHelper.NOT_SUPPORT_FLAG); + + operationHelper.isInputValid(mockInput); + expectedException = ExpectedException.none(); + } + + @Test + public void testIsInputValidPass() throws Exception { + StartInput mockInput = mock(StartInput.class); + Mockito.doReturn(mockCommonHeader).when(mockInput).getCommonHeader(); + Mockito.doReturn("originalId").when(mockCommonHeader).getOriginatorId(); + Mockito.doReturn("requestId").when(mockCommonHeader).getRequestId(); + + //with Flags + Mockito.doReturn(mock(Flags.class)).when(mockCommonHeader).getFlags(); + operationHelper.isInputValid(mockInput); + + //without Flags + Mockito.doReturn(null).when(mockCommonHeader).getFlags(); + operationHelper.isInputValid(mockInput); + + // MaintenanceMode without Flags + MaintenanceModeInput mockInput1 = mock(MaintenanceModeInput.class); + Mockito.doReturn(mockCommonHeader).when(mockInput1).getCommonHeader(); + operationHelper.isInputValid(mockInput1); + } + + @Test + public void testGetCommonHeader() throws Exception { + CommonHeader commonHeader = mock(CommonHeader.class); + // for StartInput + StartInput startInput = mock(StartInput.class); + Mockito.doReturn(commonHeader).when(startInput).getCommonHeader(); + Assert.assertEquals("Should return startInput commonHeader", commonHeader, + operationHelper.getCommonHeader(startInput)); + + // for StopInput + StopInput stopInput = mock(StopInput.class); + Mockito.doReturn(commonHeader).when(stopInput).getCommonHeader(); + Assert.assertEquals("Should return stopInput commonHeader", commonHeader, + operationHelper.getCommonHeader(stopInput)); + + // for MaintenanceModeInput + MaintenanceModeInput mmInput = mock(MaintenanceModeInput.class); + Mockito.doReturn(commonHeader).when(mmInput).getCommonHeader(); + Assert.assertEquals("Should return MaintenanceModeInput commonHeader", commonHeader, + operationHelper.getCommonHeader(mmInput)); + + // unsupported type + Assert.assertTrue("should return null", + operationHelper.getCommonHeader(new Object()) == null); + } + + @SuppressWarnings("unchecked") + @Test + public void testGetService() throws Exception { + Class operationHelperClass = OperationHelper.class; + String className = operationHelperClass.getName(); + String exceptionMsg = String.format(operationHelper.NO_SERVICE_REF_FORMAT, className); + + mockStatic(FrameworkUtil.class); + Bundle bundle = mock(Bundle.class); + PowerMockito.when(FrameworkUtil.getBundle(operationHelperClass)).thenReturn(bundle); + + // No bundle context + Mockito.when(bundle.getBundleContext()).thenReturn(null); + expectedException.expect(APPCException.class); + expectedException.expectMessage(exceptionMsg); + operationHelper.getService(operationHelperClass); + + // No service reference + BundleContext bundleContext = mock(BundleContext.class); + Mockito.when(bundle.getBundleContext()).thenReturn(bundleContext); + Mockito.when(bundleContext.getServiceReference(className)).thenReturn(null); + expectedException.expect(APPCException.class); + expectedException.expectMessage(exceptionMsg); + operationHelper.getService(operationHelperClass); + + // Success path + ServiceReference svcRef = mock(ServiceReference.class); + Mockito.when(bundleContext.getServiceReference(className)).thenReturn(svcRef); + expectedException = ExpectedException.none(); + Assert.assertTrue("should not be null", operationHelper.getService(operationHelperClass) != null); + } + + @Test + public void testGetNextState() throws Exception { + AppcOamMetaDataReader.AppcOperation operation = AppcOamMetaDataReader.AppcOperation.Start; + AppcOamStates currentState = AppcOamStates.Stopped; + String exceptionMsg = String.format(AppcOam.INVALID_STATE_MESSAGE_FORMAT, operation, "APPC", currentState); + + // got LifecycleException + Mockito.doThrow(LifecycleException.class).when(lifecycleManager) + .getNextState("APPC", operation.name(), currentState.name()); + expectedException.expect(InvalidStateException.class); + expectedException.expectMessage(exceptionMsg); + operationHelper.getNextState(operation, currentState); + + // got NoTransitionDefinedException + Mockito.doThrow(NoTransitionDefinedException.class).when(lifecycleManager) + .getNextState("APPC", operation.name(), currentState.name()); + expectedException.expect(InvalidStateException.class); + expectedException.expectMessage(exceptionMsg); + operationHelper.getNextState(operation, currentState); + + // Success path + expectedException = ExpectedException.none(); + Mockito.doReturn("starting").when(lifecycleManager) + .getNextState("APPC", operation.name(), currentState.name()); + Assert.assertEquals("Should return proper Starting state", AppcOamStates.Starting, + operationHelper.getNextState(operation, currentState)); + } +} diff --git a/appc-oam/appc-oam-bundle/src/test/java/org/onap/appc/oam/util/StateHelperTest.java b/appc-oam/appc-oam-bundle/src/test/java/org/onap/appc/oam/util/StateHelperTest.java new file mode 100644 index 000000000..9a3050e84 --- /dev/null +++ b/appc-oam/appc-oam-bundle/src/test/java/org/onap/appc/oam/util/StateHelperTest.java @@ -0,0 +1,173 @@ +/*- + * ============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 org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mockito; +import org.opendaylight.yang.gen.v1.org.onap.appc.oam.rev170303.AppcState; +import org.onap.appc.statemachine.impl.readers.AppcOamStates; +import org.osgi.framework.Bundle; +import org.powermock.api.mockito.PowerMockito; +import org.powermock.core.classloader.annotations.PrepareForTest; +import org.powermock.modules.junit4.PowerMockRunner; +import org.powermock.reflect.Whitebox; + +import java.util.HashMap; +import java.util.Map; + +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.times; + +@RunWith(PowerMockRunner.class) +@PrepareForTest({StateHelper.class}) +public class StateHelperTest { + private StateHelper stateHelper; + + @Before + public void setUp() throws Exception { + stateHelper = PowerMockito.spy(new StateHelper(null, null)); + + // to avoid operation on logger fail, mock up the logger + EELFLogger mockLogger = mock(EELFLogger.class); + Whitebox.setInternalState(stateHelper, "logger", mockLogger); + } + + @Test + public void testSetState() throws Exception { + AppcOamStates appcOamStates = AppcOamStates.Started; + stateHelper.setState(appcOamStates); + Assert.assertEquals("Should have the new value", appcOamStates, + Whitebox.getInternalState(stateHelper, "appcOamCurrentState")); + // reest to default value + stateHelper.setState(AppcOamStates.Unknown); + } + + @Test + public void testGetState() throws Exception { + AppcOamStates appcOamStates = stateHelper.getState(); + Assert.assertEquals("Should have the class value", appcOamStates, + Whitebox.getInternalState(stateHelper, "appcOamCurrentState")); + } + + @Test + public void testIsSameState() throws Exception { + AppcOamStates classValue = Whitebox.getInternalState(stateHelper, "appcOamCurrentState"); + for (AppcOamStates appcOamStates : AppcOamStates.values()) { + boolean isSame = stateHelper.isSameState(appcOamStates); + if (appcOamStates == classValue) { + Assert.assertTrue("Should be the same", isSame); + } else { + Assert.assertFalse("Should not be the same", isSame); + } + } + } + + @Test + public void testGetCurrentOamState() throws Exception { + AppcOamStates mockResult = AppcOamStates.Started; + // mock getBundlesState, as we are testin it separately + PowerMockito.doReturn(mockResult).when(stateHelper, "getBundlesState"); + + Whitebox.setInternalState(stateHelper, "appcOamCurrentState", AppcOamStates.Unknown); + Assert.assertEquals("Should call deriveStatte and return mockeResult", + mockResult, stateHelper.getCurrentOamState()); + Mockito.verify(stateHelper, times(1)).getBundlesState(); + + + Whitebox.setInternalState(stateHelper, "appcOamCurrentState", AppcOamStates.Unknown); + Assert.assertEquals("Should call deriveStatte and return mockeResult", + mockResult, stateHelper.getCurrentOamState()); + Mockito.verify(stateHelper, times(2)).getBundlesState(); + + Whitebox.setInternalState(stateHelper, "appcOamCurrentState", mockResult); + Assert.assertEquals("Should just return mockeResult", mockResult, stateHelper.getCurrentOamState()); + Mockito.verify(stateHelper, times(2)).getBundlesState(); + } + + @Test + public void testGetCurrentOamYangState() throws Exception { + Map stateMap = new HashMap() { + { + put(AppcOamStates.EnteringMaintenanceMode, AppcState.EnteringMaintenanceMode); + put(AppcOamStates.MaintenanceMode, AppcState.MaintenanceMode); + put(AppcOamStates.Instantiated, AppcState.Instantiated); + put(AppcOamStates.NotInstantiated, AppcState.NotInstantiated); + put(AppcOamStates.Restarting, AppcState.Restarting); + put(AppcOamStates.Started, AppcState.Started); + put(AppcOamStates.Starting, AppcState.Starting); + put(AppcOamStates.Stopped, AppcState.Stopped); + put(AppcOamStates.Stopping, AppcState.Stopping); + put(AppcOamStates.Error, AppcState.Error); + put(AppcOamStates.Unknown, AppcState.Unknown); + } + }; + for (Map.Entry aEntry : stateMap.entrySet()) { + AppcOamStates aState = aEntry.getKey(); + AppcState appcState = aEntry.getValue(); + + PowerMockito.doReturn(aState).when(stateHelper, "getCurrentOamState"); + + AppcState resultState = stateHelper.getCurrentOamYangState(); + Assert.assertEquals( + String.format("%s state, returned(%s),should return(%s) state", aState, resultState, appcState), + appcState, resultState); + + } + } + + @Test + public void testGetBundlesState() throws Exception { + BundleHelper mockBundlerHelper = mock(BundleHelper.class); + PowerMockito.whenNew(BundleHelper.class).withAnyArguments().thenReturn(mockBundlerHelper); + + // test null bundle map + Mockito.when(mockBundlerHelper.getAppcLcmBundles()).thenReturn(null); + Assert.assertEquals("Should return unknown state", AppcOamStates.Unknown, stateHelper.getBundlesState()); + + // tet empty bundle map + Map bundleMap = new HashMap<>(); + Mockito.when(mockBundlerHelper.getAppcLcmBundles()).thenReturn(bundleMap); + Assert.assertEquals("Should return unknown state", AppcOamStates.Unknown, stateHelper.getBundlesState()); + + Bundle mockBundle1 = mock(Bundle.class); + Bundle mockBundle2 = mock(Bundle.class); + bundleMap.put("1", mockBundle1); + bundleMap.put("2", mockBundle2); + Mockito.when(mockBundlerHelper.getAppcLcmBundles()).thenReturn(bundleMap); + + // test bundles have differnt states + Mockito.doReturn(Bundle.RESOLVED).when(mockBundle1).getState(); + Mockito.doReturn(Bundle.ACTIVE).when(mockBundle2).getState(); + Assert.assertEquals("Should return lower state", AppcOamStates.Stopped, stateHelper.getBundlesState()); + + // test bundles have the same state + Mockito.doReturn(Bundle.ACTIVE).when(mockBundle1).getState(); + Assert.assertEquals("Should return the state", AppcOamStates.Started, stateHelper.getBundlesState()); + } +} diff --git a/appc-oam/appc-oam-bundle/src/test/java/org/openecomp/appc/oam/AppcOamTest.java b/appc-oam/appc-oam-bundle/src/test/java/org/openecomp/appc/oam/AppcOamTest.java deleted file mode 100644 index 110198370..000000000 --- a/appc-oam/appc-oam-bundle/src/test/java/org/openecomp/appc/oam/AppcOamTest.java +++ /dev/null @@ -1,166 +0,0 @@ -/*- - * ============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; - -import org.junit.Assert; -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.Mockito; -import org.opendaylight.yang.gen.v1.org.onap.appc.oam.rev170303.AppcState; -import org.opendaylight.yang.gen.v1.org.onap.appc.oam.rev170303.GetAppcStateOutput; -import org.opendaylight.yang.gen.v1.org.onap.appc.oam.rev170303.MaintenanceModeInput; -import org.opendaylight.yang.gen.v1.org.onap.appc.oam.rev170303.MaintenanceModeOutput; -import org.opendaylight.yang.gen.v1.org.onap.appc.oam.rev170303.RestartInput; -import org.opendaylight.yang.gen.v1.org.onap.appc.oam.rev170303.RestartOutput; -import org.opendaylight.yang.gen.v1.org.onap.appc.oam.rev170303.StartInput; -import org.opendaylight.yang.gen.v1.org.onap.appc.oam.rev170303.StartOutput; -import org.opendaylight.yang.gen.v1.org.onap.appc.oam.rev170303.StopInput; -import org.opendaylight.yang.gen.v1.org.onap.appc.oam.rev170303.StopOutput; -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.status.Status; -import org.opendaylight.yangtools.yang.common.RpcResult; -import org.onap.appc.oam.processor.OamMmodeProcessor; -import org.onap.appc.oam.processor.OamRestartProcessor; -import org.onap.appc.oam.processor.OamStartProcessor; -import org.onap.appc.oam.processor.OamStopProcessor; -import org.onap.appc.oam.util.OperationHelper; -import org.onap.appc.oam.util.StateHelper; -import org.osgi.framework.FrameworkUtil; -import org.powermock.api.mockito.PowerMockito; -import org.powermock.core.classloader.annotations.PrepareForTest; -import org.powermock.modules.junit4.PowerMockRunner; -import org.powermock.reflect.Whitebox; - -import java.util.concurrent.Executors; -import java.util.concurrent.Future; - -import static org.mockito.Mockito.mock; -import static org.powermock.api.mockito.PowerMockito.spy; - -@RunWith(PowerMockRunner.class) -@PrepareForTest({AppcOam.class, FrameworkUtil.class, Executors.class}) -public class AppcOamTest { - - private AppcOam appcOam; - private CommonHeader mockCommonHeader = mock(CommonHeader.class); - private Status mockStatus = mock(Status.class); - private OperationHelper mockOperationHelper = mock(OperationHelper.class); - private StateHelper mockStateHelper = mock(StateHelper.class); - - @Before - public void setUp() throws Exception { - appcOam = spy(new AppcOam(null, null, null)); - - Whitebox.setInternalState(appcOam, "stateHelper", mockStateHelper); - Whitebox.setInternalState(appcOam, "operationHelper", mockOperationHelper); - } - - @Test - public void testMaintenanceMode() throws Exception { - // mock processor creation - OamMmodeProcessor mockProcessor = mock(OamMmodeProcessor.class); - PowerMockito.mockStatic(OamMmodeProcessor.class); - PowerMockito.whenNew(OamMmodeProcessor.class).withAnyArguments().thenReturn(mockProcessor); - // mock input - MaintenanceModeInput mockInput = mock(MaintenanceModeInput.class); - Mockito.doReturn(mockCommonHeader).when(mockInput).getCommonHeader(); - // mock processor result - Mockito.doReturn(mockStatus).when(mockProcessor).processRequest(mockInput); - - Future> response = appcOam.maintenanceMode(mockInput); - - Assert.assertEquals("Should have common header", mockCommonHeader, - response.get().getResult().getCommonHeader()); - Assert.assertEquals("Should have status", mockStatus, response.get().getResult().getStatus()); - } - - @Test - public void testStart() throws Exception { - // mock processor creation - OamStartProcessor mockProcessor = mock(OamStartProcessor.class); - PowerMockito.mockStatic(OamStartProcessor.class); - PowerMockito.whenNew(OamStartProcessor.class).withAnyArguments().thenReturn(mockProcessor); - // mock input - StartInput mockInput = mock(StartInput.class); - Mockito.doReturn(mockCommonHeader).when(mockInput).getCommonHeader(); - // mock processor result - Mockito.doReturn(mockStatus).when(mockProcessor).processRequest(mockInput); - - Future> response = appcOam.start(mockInput); - - Assert.assertEquals("Should have common header", mockCommonHeader, - response.get().getResult().getCommonHeader()); - Assert.assertEquals("Should have status", mockStatus, response.get().getResult().getStatus()); - } - - @Test - public void testStop() throws Exception { - // mock processor creation - OamStopProcessor mockProcessor = mock(OamStopProcessor.class); - PowerMockito.mockStatic(OamStopProcessor.class); - PowerMockito.whenNew(OamStopProcessor.class).withAnyArguments().thenReturn(mockProcessor); - // mock input - StopInput mockInput = mock(StopInput.class); - Mockito.doReturn(mockCommonHeader).when(mockInput).getCommonHeader(); - // mock processor result - Mockito.doReturn(mockStatus).when(mockProcessor).processRequest(mockInput); - - Future> response = appcOam.stop(mockInput); - - Assert.assertEquals("Should have common header", mockCommonHeader, - response.get().getResult().getCommonHeader()); - Assert.assertEquals("Should have status", mockStatus, response.get().getResult().getStatus()); - } - - @Test - public void testRestart() throws Exception { - // mock processor creation - OamRestartProcessor mockProcessor = mock(OamRestartProcessor.class); - PowerMockito.mockStatic(OamRestartProcessor.class); - PowerMockito.whenNew(OamRestartProcessor.class).withAnyArguments().thenReturn(mockProcessor); - // mock input - RestartInput mockInput = mock(RestartInput.class); - Mockito.doReturn(mockCommonHeader).when(mockInput).getCommonHeader(); - // mock processor result - Mockito.doReturn(mockStatus).when(mockProcessor).processRequest(mockInput); - - Future> response = appcOam.restart(mockInput); - - Assert.assertEquals("Should have common header", mockCommonHeader, - response.get().getResult().getCommonHeader()); - Assert.assertEquals("Should have status", mockStatus, response.get().getResult().getStatus()); - } - - @Test - public void testGetAppcState() throws Exception { - AppcState appcState = AppcState.Started; - Mockito.doReturn(appcState).when(mockStateHelper).getCurrentOamYangState(); - - Future> state = appcOam.getAppcState(); - Assert.assertEquals("Should return the same state", - appcState, state.get().getResult().getState()); - } -} diff --git a/appc-oam/appc-oam-bundle/src/test/java/org/openecomp/appc/oam/OAMCommandStatusTest.java b/appc-oam/appc-oam-bundle/src/test/java/org/openecomp/appc/oam/OAMCommandStatusTest.java deleted file mode 100644 index 269c4f811..000000000 --- a/appc-oam/appc-oam-bundle/src/test/java/org/openecomp/appc/oam/OAMCommandStatusTest.java +++ /dev/null @@ -1,99 +0,0 @@ -/*- - * ============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; - -import org.junit.Assert; -import org.junit.Test; -import org.onap.appc.executor.objects.Params; - -import java.util.HashMap; -import java.util.Map; - -public class OAMCommandStatusTest { - private Map CODE_MAP = new HashMap() { - { - put(OAMCommandStatus.ABORT, 304); - put(OAMCommandStatus.ACCEPTED, 100); - put(OAMCommandStatus.INVALID_PARAMETER, 302); - put(OAMCommandStatus.REJECTED, 300); - put(OAMCommandStatus.SUCCESS, 400); - put(OAMCommandStatus.TIMEOUT, 303); - put(OAMCommandStatus.UNEXPECTED_ERROR, 200); - } - }; - private Map MSG_MAP = new HashMap() { - { - put(OAMCommandStatus.ABORT, "OPERATION ABORT - ${errorMsg}"); - put(OAMCommandStatus.ACCEPTED, "ACCEPTED - request accepted"); - put(OAMCommandStatus.INVALID_PARAMETER, "INVALID PARAMETER - ${errorMsg}"); - put(OAMCommandStatus.REJECTED, "REJECTED - ${errorMsg}"); - put(OAMCommandStatus.SUCCESS, "SUCCESS - request has been processed successfully"); - put(OAMCommandStatus.TIMEOUT, "OPERATION TIMEOUT REACHED - ${errorMsg}"); - put(OAMCommandStatus.UNEXPECTED_ERROR, "UNEXPECTED ERROR - ${errorMsg}"); - } - }; - - @Test - public void testGetResponseMessage() throws Exception { - for (OAMCommandStatus oamCommandStatus : OAMCommandStatus.values()) { - String expectedMsg = MSG_MAP.get(oamCommandStatus); - Assert.assertEquals(String.format("Should have message (%s).", expectedMsg), - expectedMsg, oamCommandStatus.getResponseMessage()); - } - } - - @Test - public void testGetResponseCode() throws Exception { - for (OAMCommandStatus oamCommandStatus : OAMCommandStatus.values()) { - Integer expectedCode = CODE_MAP.get(oamCommandStatus); - Assert.assertEquals(String.format("Should have code (%d).", expectedCode), - expectedCode, Integer.valueOf(oamCommandStatus.getResponseCode())); - } - } - - @Test - public void testGetFormattedMessage() throws Exception { - String message = "test message"; - Params params = new Params().addParam("errorMsg", message); - for (OAMCommandStatus oamCommandStatus : OAMCommandStatus.values()) { - String expectedMsg1 = MSG_MAP.get(oamCommandStatus); - String expectedMsg2 = expectedMsg1.replaceAll("\\$\\{errorMsg\\}", message); - Assert.assertEquals("Should returned " + expectedMsg1, - expectedMsg1, oamCommandStatus.getFormattedMessage(null)); - Assert.assertEquals("Should returned " + expectedMsg2, - expectedMsg2, oamCommandStatus.getFormattedMessage(params)); - } - } - - @Test - public void testToString() throws Exception { - for (OAMCommandStatus oamCommandStatus : OAMCommandStatus.values()) { - String expectedString = String.format(oamCommandStatus.TO_STRING_FORMAT, - CODE_MAP.get(oamCommandStatus), MSG_MAP.get(oamCommandStatus)); - Assert.assertEquals(String.format("Should have string (%s).", expectedString), - expectedString, oamCommandStatus.toString()); - } - } -} diff --git a/appc-oam/appc-oam-bundle/src/test/java/org/openecomp/appc/oam/messageadapter/MessageAdapterTest.java b/appc-oam/appc-oam-bundle/src/test/java/org/openecomp/appc/oam/messageadapter/MessageAdapterTest.java deleted file mode 100644 index d3ebfda51..000000000 --- a/appc-oam/appc-oam-bundle/src/test/java/org/openecomp/appc/oam/messageadapter/MessageAdapterTest.java +++ /dev/null @@ -1,115 +0,0 @@ -/*- - * ============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.messageadapter; - -import org.junit.Assert; -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.onap.appc.adapter.message.MessageAdapterFactory; -import org.onap.appc.adapter.message.Producer; - -import org.mockito.Mockito; -import org.osgi.framework.Bundle; -import org.osgi.framework.BundleContext; -import org.osgi.framework.FrameworkUtil; -import org.osgi.framework.ServiceReference; -import org.powermock.api.mockito.PowerMockito; -import org.powermock.core.classloader.annotations.PrepareForTest; -import org.powermock.modules.junit4.PowerMockRunner; -import org.powermock.reflect.Whitebox; - -import java.util.HashSet; - -import static org.mockito.Mockito.mock; -import static org.powermock.api.mockito.PowerMockito.mockStatic; - - -@RunWith(PowerMockRunner.class) -@PrepareForTest({MessageAdapter.class, FrameworkUtil.class}) -public class MessageAdapterTest { - - private Producer fakeProducer; - - private MessageAdapter messageAdapter; - - - @Before - public final void setup() throws Exception { - fakeProducer = mock(Producer.class); - messageAdapter = new MessageAdapter(); - } - - @Test - public void testGetProducerReturnsNull() throws Exception { - MessageAdapter maSpy = Mockito.spy(messageAdapter); - Mockito.doNothing().when(maSpy).createProducer(); - - Producer producer = maSpy.getProducer(); - Assert.assertTrue("getProducer() did not return null", producer == null); - Producer mySpyProducer = Whitebox.getInternalState(maSpy, "producer"); - Assert.assertTrue("MessageAdapter producer is not null", mySpyProducer == null); - Mockito.verify(maSpy, Mockito.times(1)).createProducer(); - } - - @Test - public void testGetProducerWithExistingProducer() throws Exception { - MessageAdapter maSpy = Mockito.spy(messageAdapter); - Whitebox.setInternalState(maSpy, "producer", fakeProducer); - - Producer producer = maSpy.getProducer(); - Assert.assertTrue("getProducer() returned null", producer == fakeProducer); - Mockito.verify(maSpy, Mockito.times(0)).createProducer(); - } - - @Test - public void testGetProducerWithCreateProducer() throws Exception { - MessageAdapter maSpy = Mockito.spy(messageAdapter); - Whitebox.setInternalState(maSpy, "producer", (Object) null); - HashSet pool = new HashSet<>(); - Whitebox.setInternalState(maSpy, "pool", pool); - - // Prepare all mocks - mockStatic(FrameworkUtil.class); - Bundle maBundle = mock(Bundle.class); - PowerMockito.when(FrameworkUtil.getBundle(MessageAdapter.class)).thenReturn(maBundle); - - BundleContext maBundleContext = mock(BundleContext.class); - Mockito.when(maBundle.getBundleContext()).thenReturn(maBundleContext); - - ServiceReference svcRef = mock(ServiceReference.class); - Mockito.when(maBundleContext.getServiceReference(MessageAdapterFactory.class.getName())).thenReturn(svcRef); - - MessageAdapterFactory maFactory = mock(MessageAdapterFactory.class); - Mockito.when(maBundleContext.getService(svcRef)).thenReturn(maFactory); - Mockito.when(maFactory.createProducer(pool, (String) null, null, null)).thenReturn(fakeProducer); - - Producer producer = maSpy.getProducer(); - Assert.assertTrue("getProducer() result does not match", producer == fakeProducer); - Producer mySpyProducer = Whitebox.getInternalState(maSpy, "producer"); - Assert.assertTrue("MessageAdapter producer does not match",mySpyProducer == fakeProducer); - Mockito.verify(maSpy, Mockito.times(1)).createProducer(); - } -} diff --git a/appc-oam/appc-oam-bundle/src/test/java/org/openecomp/appc/oam/processor/BaseActionRunnableTest.java b/appc-oam/appc-oam-bundle/src/test/java/org/openecomp/appc/oam/processor/BaseActionRunnableTest.java deleted file mode 100644 index daf0f6e07..000000000 --- a/appc-oam/appc-oam-bundle/src/test/java/org/openecomp/appc/oam/processor/BaseActionRunnableTest.java +++ /dev/null @@ -1,293 +0,0 @@ -/*- - * ============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.processor; - -import com.att.eelf.configuration.EELFLogger; -import org.junit.Assert; -import org.junit.Before; -import org.junit.Test; -import org.mockito.Mockito; -import org.opendaylight.yang.gen.v1.org.onap.appc.oam.rev170303.common.header.CommonHeader; -import org.onap.appc.i18n.Msg; -import org.onap.appc.oam.AppcOam; -import org.onap.appc.oam.OAMCommandStatus; -import org.onap.appc.oam.util.AsyncTaskHelper; -import org.onap.appc.oam.util.BundleHelper; -import org.onap.appc.oam.util.ConfigurationHelper; -import org.onap.appc.oam.util.OperationHelper; -import org.onap.appc.oam.util.StateHelper; -import org.onap.appc.statemachine.impl.readers.AppcOamStates; -import org.powermock.reflect.Whitebox; - -import java.util.Date; - -import static org.mockito.Matchers.any; -import static org.mockito.Matchers.anyMap; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.spy; -import static org.mockito.Mockito.times; - -public class BaseActionRunnableTest { - private AppcOam.RPC testRpc = AppcOam.RPC.maintenance_mode; - private AppcOamStates targetState = AppcOamStates.MaintenanceMode; - - private class TestProcessor extends BaseProcessor { - /** - * Constructor - * - * @param eelfLogger for logging - * @param configurationHelperIn for property reading - * @param stateHelperIn for APP-C OAM state checking - * @param asyncTaskHelperIn for scheduling async task - * @param operationHelperIn for operational helper - */ - TestProcessor(EELFLogger eelfLogger, - ConfigurationHelper configurationHelperIn, - StateHelper stateHelperIn, - AsyncTaskHelper asyncTaskHelperIn, - OperationHelper operationHelperIn) { - super(eelfLogger, configurationHelperIn, stateHelperIn, asyncTaskHelperIn, operationHelperIn); - - // must set rpc and auditMsg - rpc = testRpc; - auditMsg = Msg.OAM_OPERATION_STARTING; - startTime = new Date(); - } - } - - class TestAbc extends BaseActionRunnable { - boolean doActionResult; - - TestAbc(BaseProcessor parent) { - super(parent); - - actionName = "testing"; - auditMsg = Msg.OAM_OPERATION_MAINTENANCE_MODE; - finalState = targetState; - } - - @Override - boolean doAction() { - return doActionResult; - } - } - - private TestAbc testBaseAcionRunnable; - private BaseProcessor testProcessor; - private StateHelper mockStateHelper = mock(StateHelper.class); - private OperationHelper mockOperHelper = mock(OperationHelper.class); - private ConfigurationHelper mockConfigHelper = mock(ConfigurationHelper.class); - private BundleHelper mockBundleHelper = mock(BundleHelper.class); - - @SuppressWarnings("ResultOfMethodCallIgnored") - @Before - public void setUp() throws Exception { - // to avoid operation on logger fail, mock up the logger - EELFLogger mockLogger = mock(EELFLogger.class); - - testProcessor = spy( - new TestProcessor(mockLogger, mockConfigHelper, mockStateHelper, null, mockOperHelper)); - Whitebox.setInternalState(testProcessor, "bundleHelper", mockBundleHelper); - - testBaseAcionRunnable = spy(new TestAbc(testProcessor)); - Whitebox.setInternalState(testBaseAcionRunnable, "commonHeader", mock(CommonHeader.class)); - } - - @Test - public void testSetTimeoutValues() throws Exception { - Whitebox.setInternalState(testBaseAcionRunnable, "timeoutMs", 0); - Whitebox.setInternalState(testBaseAcionRunnable, "startTimeMs", 0); - Whitebox.setInternalState(testBaseAcionRunnable, "doTimeoutChecking", false); - long expectedTimeout = 10000L; - Mockito.doReturn(expectedTimeout).when(mockConfigHelper).getOAMOperationTimeoutValue(any()); - testBaseAcionRunnable.setTimeoutValues(); - Assert.assertEquals("Should set timeoutMs", expectedTimeout, testBaseAcionRunnable.timeoutMs); - Assert.assertTrue("Should set start time MS", testBaseAcionRunnable.startTimeMs != 0); - Assert.assertTrue("Should do check", testBaseAcionRunnable.doTimeoutChecking); - - Whitebox.setInternalState(testBaseAcionRunnable, "timeoutMs", 0); - Whitebox.setInternalState(testBaseAcionRunnable, "startTimeMs", 0); - Whitebox.setInternalState(testBaseAcionRunnable, "doTimeoutChecking", false); - expectedTimeout = 20000L; - Mockito.doReturn(expectedTimeout).when(mockConfigHelper).getOAMOperationTimeoutValue(any()); - testBaseAcionRunnable.setTimeoutValues(); - Assert.assertEquals("Should set timeoutMs", expectedTimeout, testBaseAcionRunnable.timeoutMs); - Assert.assertTrue("Should set start time MS", testBaseAcionRunnable.startTimeMs != 0); - Assert.assertTrue("Should do check", testBaseAcionRunnable.doTimeoutChecking); - - Whitebox.setInternalState(testBaseAcionRunnable, "timeoutMs", 0); - Whitebox.setInternalState(testBaseAcionRunnable, "startTimeMs", 0); - Whitebox.setInternalState(testBaseAcionRunnable, "doTimeoutChecking", false); - expectedTimeout = 0L; - Mockito.doReturn(expectedTimeout).when(mockConfigHelper).getOAMOperationTimeoutValue(any()); - testBaseAcionRunnable.setTimeoutValues(); - Assert.assertEquals("Should set timeoutMs", expectedTimeout, testBaseAcionRunnable.timeoutMs); - Assert.assertTrue("Should not set start time MS", testBaseAcionRunnable.startTimeMs == 0); - Assert.assertFalse("Should not do check", testBaseAcionRunnable.doTimeoutChecking); - } - - @Test - public void testRun() throws Exception { - // test doAction failed - Whitebox.setInternalState(testBaseAcionRunnable, "doActionResult", false); - testBaseAcionRunnable.run(); - Assert.assertFalse("isWaiting should still be false", - Whitebox.getInternalState(testBaseAcionRunnable, "isWaiting")); - - // test doAction success - Whitebox.setInternalState(testBaseAcionRunnable, "doActionResult", true); - - // with checkState return true - Mockito.doReturn(true).when(testBaseAcionRunnable).checkState(); - testBaseAcionRunnable.run(); - Assert.assertFalse("isWaiting should still be false", - Whitebox.getInternalState(testBaseAcionRunnable, "isWaiting")); - - // with checkState return false - Mockito.doReturn(false).when(testBaseAcionRunnable).checkState(); - testBaseAcionRunnable.run(); - Assert.assertTrue("isWaiting should still be true", - Whitebox.getInternalState(testBaseAcionRunnable, "isWaiting")); - - // should stay - testBaseAcionRunnable.run(); - Mockito.verify(testBaseAcionRunnable, times(1)).keepWaiting(); - } - - @Test - public void testSetAbortStatus() throws Exception { - testBaseAcionRunnable.setAbortStatus(); - Assert.assertEquals("Should return abort code", OAMCommandStatus.ABORT.getResponseCode(), - testBaseAcionRunnable.status.getCode().intValue()); - Assert.assertTrue("Should set abort due to execution error message", - testBaseAcionRunnable.status.getMessage().endsWith( - String.format(testBaseAcionRunnable.ABORT_MESSAGE_FORMAT, - testRpc.name(), testBaseAcionRunnable.DUE_TO_EXECUTION_ERROR))); - } - - @Test - public void testCheckState() throws Exception { - // 1. with isTimeout true - Mockito.doReturn(true).when(testBaseAcionRunnable).isTimeout("checkState"); - Assert.assertTrue("Should return true", testBaseAcionRunnable.checkState()); - - // 2. with isTimeout false and - Mockito.doReturn(false).when(testBaseAcionRunnable).isTimeout("checkState"); - - // 2.1 with task not all done - Mockito.doReturn(false).when(mockBundleHelper).isAllTaskDone(any()); - Assert.assertFalse("Should return false", testBaseAcionRunnable.checkState()); - - // 2. 2 with task all done - Mockito.doReturn(true).when(mockBundleHelper).isAllTaskDone(any()); - - // 2.2.1 with has bundle failure - Mockito.doReturn(true).when(testBaseAcionRunnable).hasBundleOperationFailure(); - Assert.assertTrue("Should return true", testBaseAcionRunnable.checkState()); - - // 2.2.2 with no bundle failure - Mockito.doReturn(false).when(testBaseAcionRunnable).hasBundleOperationFailure(); - - Mockito.doReturn(targetState).when(mockStateHelper).getBundlesState(); - Assert.assertTrue("Should return true", testBaseAcionRunnable.checkState()); - - Mockito.doReturn(AppcOamStates.Started).when(mockStateHelper).getBundlesState(); - Assert.assertFalse("Should return false", testBaseAcionRunnable.checkState()); - } - - @Test - public void testPostAction() throws Exception { - Mockito.doReturn(AppcOamStates.Started).when(mockStateHelper).getCurrentOamState(); - // set status to avoid NPE when using status - testBaseAcionRunnable.setAbortStatus(); - - // test no parameter - testBaseAcionRunnable.postAction(null); - Mockito.verify(mockOperHelper, times(1)).sendNotificationMessage(any(), any(), any()); - Mockito.verify(mockStateHelper, times(0)).setState(any()); - Mockito.verify(testProcessor, times(1)).cancelAsyncTask(); - - // test with parameter - testBaseAcionRunnable.postAction(AppcOamStates.Error); - Mockito.verify(mockOperHelper, times(2)).sendNotificationMessage(any(), any(), any()); - Mockito.verify(mockStateHelper, times(1)).setState(any()); - Mockito.verify(testProcessor, times(2)).cancelAsyncTask(); - } - - @Test - public void testIsTimeout() throws Exception { - String parentName = "testing"; - Whitebox.setInternalState(testBaseAcionRunnable, "doTimeoutChecking", false); - Assert.assertFalse("Should not be timeout", testBaseAcionRunnable.isTimeout(parentName)); - - Mockito.doReturn(AppcOamStates.Started).when(mockStateHelper).getCurrentOamState(); - Whitebox.setInternalState(testBaseAcionRunnable, "doTimeoutChecking", true); - Whitebox.setInternalState(testBaseAcionRunnable, "timeoutMs", System.currentTimeMillis() + 100); - Whitebox.setInternalState(testBaseAcionRunnable, "startTimeMs", 2); - Assert.assertFalse("Should not be timeout", testBaseAcionRunnable.isTimeout(parentName)); - - long timeoutMs = 1; - Whitebox.setInternalState(testBaseAcionRunnable, "timeoutMs", timeoutMs); - Whitebox.setInternalState(testBaseAcionRunnable, "startTimeMs", 2); - Assert.assertTrue("Should be timeout", testBaseAcionRunnable.isTimeout(parentName)); - Mockito.verify(testBaseAcionRunnable, times(1)).postAction(any()); - Assert.assertEquals("Should return timeout code", OAMCommandStatus.TIMEOUT.getResponseCode(), - testBaseAcionRunnable.status.getCode().intValue()); - Assert.assertTrue("Should set timeout message", - testBaseAcionRunnable.status.getMessage().endsWith( - String.format(testBaseAcionRunnable.TIMEOUT_MESSAGE_FORMAT, testRpc.name(), timeoutMs))); - } - - @SuppressWarnings("unchecked") - @Test - public void testHasBundleOperationFailure() throws Exception { - Mockito.when(mockBundleHelper.getFailedMetrics(anyMap())).thenReturn(Long.valueOf("0")); - Assert.assertFalse("should return false", testBaseAcionRunnable.hasBundleOperationFailure()); - - Mockito.when(mockStateHelper.getCurrentOamState()).thenReturn(AppcOamStates.Restarting); - long failedNumber = 1; - Mockito.doReturn(failedNumber).when(mockBundleHelper).getFailedMetrics(anyMap()); - Assert.assertTrue("should return true", testBaseAcionRunnable.hasBundleOperationFailure()); - Mockito.verify(testBaseAcionRunnable, times(1)).setStatus(OAMCommandStatus.UNEXPECTED_ERROR, - String.format(testBaseAcionRunnable.BUNDLE_OPERATION_FAILED_FORMAT, failedNumber)); - Mockito.verify(testBaseAcionRunnable, times(1)).postAction(AppcOamStates.Error); - } - - @Test - public void testAbortRunnable() throws Exception { - Mockito.doReturn(AppcOamStates.Restarting).when(mockStateHelper).getCurrentOamState(); - AppcOam.RPC newRpc = AppcOam.RPC.restart; - testBaseAcionRunnable.abortRunnable(newRpc); - Assert.assertEquals("Should return abort code", OAMCommandStatus.ABORT.getResponseCode(), - testBaseAcionRunnable.status.getCode().intValue()); - Assert.assertTrue("Should set abort due to new request message", - testBaseAcionRunnable.status.getMessage().endsWith( - String.format(testBaseAcionRunnable.ABORT_MESSAGE_FORMAT, testRpc.name(), - String.format(testBaseAcionRunnable.NEW_RPC_OPERATION_REQUEST, newRpc.name())))); - Mockito.verify(mockOperHelper, times(1)).sendNotificationMessage(any(), any(), any()); - Mockito.verify(testBaseAcionRunnable, times(1)).resetLogProperties(false); - Mockito.verify(testBaseAcionRunnable, times(1)).resetLogProperties(true); - } -} diff --git a/appc-oam/appc-oam-bundle/src/test/java/org/openecomp/appc/oam/processor/BaseCommonTest.java b/appc-oam/appc-oam-bundle/src/test/java/org/openecomp/appc/oam/processor/BaseCommonTest.java deleted file mode 100644 index 59bddb0e4..000000000 --- a/appc-oam/appc-oam-bundle/src/test/java/org/openecomp/appc/oam/processor/BaseCommonTest.java +++ /dev/null @@ -1,182 +0,0 @@ -/*- - * ============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.processor; - -import com.att.eelf.configuration.EELFLogger; -import org.junit.Assert; -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.Mockito; -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.status.Status; -import org.onap.appc.exceptions.InvalidInputException; -import org.onap.appc.exceptions.InvalidStateException; -import org.onap.appc.oam.AppcOam; -import org.onap.appc.oam.OAMCommandStatus; -import org.onap.appc.oam.util.ConfigurationHelper; -import org.onap.appc.oam.util.OperationHelper; -import org.onap.appc.oam.util.StateHelper; -import org.onap.appc.statemachine.impl.readers.AppcOamStates; -import org.powermock.api.mockito.PowerMockito; -import org.powermock.core.classloader.annotations.PrepareForTest; -import org.powermock.modules.junit4.PowerMockRunner; -import org.powermock.reflect.Whitebox; -import org.slf4j.MDC; - -import java.util.Map; - -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.spy; -import static org.mockito.Mockito.times; -import static org.powermock.api.mockito.PowerMockito.mockStatic; - -@RunWith(PowerMockRunner.class) -@PrepareForTest({BaseCommon.class, MDC.class}) -public class BaseCommonTest { - private class TestAbc extends BaseCommon { - - /** - * Constructor - * - * @param eelfLogger for logging - * @param configurationHelperIn for property reading - * @param stateHelperIn for APP-C OAM state checking - * @param operationHelperIn for operational helper - */ - TestAbc(EELFLogger eelfLogger, - ConfigurationHelper configurationHelperIn, - StateHelper stateHelperIn, - OperationHelper operationHelperIn) { - super(eelfLogger, configurationHelperIn, stateHelperIn, operationHelperIn); - } - } - - private TestAbc testBaseCommon; - private ConfigurationHelper mockConfigHelper = mock(ConfigurationHelper.class); - private StateHelper mockStateHelper = mock(StateHelper.class); - private CommonHeader mockCommonHeader = mock(CommonHeader.class); - - @Before - public void setUp() throws Exception { - testBaseCommon = spy(new TestAbc(null, mockConfigHelper, mockStateHelper, null)); - - Whitebox.setInternalState(testBaseCommon, "commonHeader", mockCommonHeader); - Whitebox.setInternalState(testBaseCommon, "rpc", AppcOam.RPC.maintenance_mode); - - // to avoid operation on logger fail, mock up the logger - EELFLogger mockLogger = mock(EELFLogger.class); - Whitebox.setInternalState(testBaseCommon, "logger", mockLogger); - } - - @Test - public void testSetStatus() throws Exception { - OAMCommandStatus oamCommandStatus = OAMCommandStatus.ACCEPTED; - testBaseCommon.setStatus(oamCommandStatus); - Status status = testBaseCommon.status; - Assert.assertEquals("Should have code", oamCommandStatus.getResponseCode(), status.getCode().intValue()); - Assert.assertEquals("Should have message", oamCommandStatus.getResponseMessage(), status.getMessage()); - } - - @Test - public void testSetStatusWithParams() throws Exception { - String message = "testing"; - OAMCommandStatus oamCommandStatus = OAMCommandStatus.REJECTED; - testBaseCommon.setStatus(oamCommandStatus, message); - Status status = testBaseCommon.status; - Assert.assertEquals("Should have code", oamCommandStatus.getResponseCode(), status.getCode().intValue()); - Assert.assertTrue("Should have message", status.getMessage().endsWith(message)); - } - - @Test - public void testSetErrorStatus() throws Exception { - Mockito.doReturn("testName").when(mockConfigHelper).getAppcName(); - Mockito.doReturn(AppcOamStates.Started).when(mockStateHelper).getCurrentOamState(); - Mockito.doReturn("testRequestId").when(mockCommonHeader).getRequestId(); - Mockito.doReturn("testOrigId").when(mockCommonHeader).getOriginatorId(); - - String exceptionMessage = "testing"; - - OAMCommandStatus oamCommandStatus = OAMCommandStatus.INVALID_PARAMETER; - Throwable t = new InvalidInputException(exceptionMessage); - testBaseCommon.setErrorStatus(t); - Status status = testBaseCommon.status; - Assert.assertEquals("Should have code", oamCommandStatus.getResponseCode(), status.getCode().intValue()); - Mockito.verify(testBaseCommon, times(1)).resetLogProperties(false); - Mockito.verify(testBaseCommon, times(1)).resetLogProperties(true); - - oamCommandStatus = OAMCommandStatus.REJECTED; - t = new InvalidStateException(exceptionMessage); - testBaseCommon.setErrorStatus(t); - status = testBaseCommon.status; - Assert.assertEquals("Should have code", oamCommandStatus.getResponseCode(), status.getCode().intValue()); - Mockito.verify(testBaseCommon, times(2)).resetLogProperties(false); - Mockito.verify(testBaseCommon, times(2)).resetLogProperties(true); - - oamCommandStatus = OAMCommandStatus.UNEXPECTED_ERROR; - t = new NullPointerException(exceptionMessage); - testBaseCommon.setErrorStatus(t); - status = testBaseCommon.status; - Assert.assertEquals("Should have code", oamCommandStatus.getResponseCode(), status.getCode().intValue()); - Mockito.verify(testBaseCommon, times(3)).resetLogProperties(false); - Mockito.verify(testBaseCommon, times(3)).resetLogProperties(true); - } - - @Test - public void testSetInitialLogProperties() throws Exception { - mockStatic(MDC.class); - testBaseCommon.setInitialLogProperties(); - PowerMockito.verifyStatic(times(5)); - } - - @Test - public void testClearRequestLogProperties() throws Exception { - mockStatic(MDC.class); - testBaseCommon.clearRequestLogProperties(); - PowerMockito.verifyStatic(times(5)); - } - - @Test - public void testResetLogProperties() throws Exception { - testBaseCommon.setInitialLogProperties(); - - testBaseCommon.resetLogProperties(false); - Mockito.verify(mockCommonHeader, times(2)).getRequestId(); - Mockito.verify(mockCommonHeader, times(2)).getOriginatorId(); - Map oldMdcMap = Whitebox.getInternalState(testBaseCommon, "oldMdcContent"); - Assert.assertTrue("Should have 5 entries in persisted map", oldMdcMap.size() == 5); - - testBaseCommon.resetLogProperties(false); - Mockito.verify(mockCommonHeader, times(3)).getRequestId(); - Mockito.verify(mockCommonHeader, times(3)).getOriginatorId(); - - // test oldMdcMap is cleared - testBaseCommon.resetLogProperties(false); - Mockito.verify(mockCommonHeader, times(4)).getRequestId(); - Mockito.verify(mockCommonHeader, times(4)).getOriginatorId(); - oldMdcMap = Whitebox.getInternalState(testBaseCommon, "oldMdcContent"); - Assert.assertTrue("Should have 5 entries in persisted map", oldMdcMap.size() == 5); - } -} diff --git a/appc-oam/appc-oam-bundle/src/test/java/org/openecomp/appc/oam/processor/BaseProcessorTest.java b/appc-oam/appc-oam-bundle/src/test/java/org/openecomp/appc/oam/processor/BaseProcessorTest.java deleted file mode 100644 index 6769352c6..000000000 --- a/appc-oam/appc-oam-bundle/src/test/java/org/openecomp/appc/oam/processor/BaseProcessorTest.java +++ /dev/null @@ -1,174 +0,0 @@ -/*- - * ============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.processor; - -import com.att.eelf.configuration.EELFLogger; -import org.junit.Assert; -import org.junit.Before; -import org.junit.Test; -import org.mockito.Mockito; -import org.opendaylight.yang.gen.v1.org.onap.appc.oam.rev170303.StartInput; -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.status.Status; -import org.onap.appc.exceptions.APPCException; -import org.onap.appc.exceptions.InvalidInputException; -import org.onap.appc.exceptions.InvalidStateException; -import org.onap.appc.i18n.Msg; -import org.onap.appc.oam.AppcOam; -import org.onap.appc.oam.OAMCommandStatus; -import org.onap.appc.oam.util.AsyncTaskHelper; -import org.onap.appc.oam.util.ConfigurationHelper; -import org.onap.appc.oam.util.OperationHelper; -import org.onap.appc.oam.util.StateHelper; -import org.onap.appc.statemachine.impl.readers.AppcOamStates; -import org.powermock.reflect.Whitebox; - -import static org.mockito.Matchers.any; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.spy; -import static org.mockito.Mockito.times; - -@SuppressWarnings("ResultOfMethodCallIgnored") -public class BaseProcessorTest { - private AppcOam.RPC testRpc = AppcOam.RPC.start; - private AppcOamStates currentState = AppcOamStates.Stopped; - - private class TestAbc extends BaseProcessor { - - /** - * Constructor - * - * @param eelfLogger for logging - * @param configurationHelperIn for property reading - * @param stateHelperIn for APP-C OAM state checking - * @param asyncTaskHelperIn for scheduling async task - * @param operationHelperIn for operational helper - */ - TestAbc(EELFLogger eelfLogger, - ConfigurationHelper configurationHelperIn, - StateHelper stateHelperIn, - AsyncTaskHelper asyncTaskHelperIn, - OperationHelper operationHelperIn) { - super(eelfLogger, configurationHelperIn, stateHelperIn, asyncTaskHelperIn, operationHelperIn); - - // must set rpc and auditMsg - rpc = testRpc; - auditMsg = Msg.OAM_OPERATION_STARTING; - } - } - - private TestAbc testBaseProcessor; - private ConfigurationHelper mockConfigHelper = mock(ConfigurationHelper.class); - private StateHelper mockStateHelper = mock(StateHelper.class); - private AsyncTaskHelper mockTaskHelper = mock(AsyncTaskHelper.class); - private OperationHelper mockOperHelper = mock(OperationHelper.class); - - private StartInput mockInput = mock(StartInput.class); - private CommonHeader mockCommonHeader = mock(CommonHeader.class); - - @Before - public void setUp() throws Exception { - Mockito.doReturn(mockCommonHeader).when(mockOperHelper).getCommonHeader(mockInput); - Mockito.doReturn(mockCommonHeader).when(mockInput).getCommonHeader(); - - testBaseProcessor = spy( - new TestAbc(null, mockConfigHelper, mockStateHelper, mockTaskHelper, mockOperHelper)); - - Whitebox.setInternalState(testBaseProcessor, "commonHeader", mockCommonHeader); - - // to avoid operation on logger fail, mock up the logger - EELFLogger mockLogger = mock(EELFLogger.class); - Whitebox.setInternalState(testBaseProcessor, "logger", mockLogger); - } - - @Test - public void testProcessRequestError() throws Exception { - Mockito.doReturn(currentState).when(mockStateHelper).getCurrentOamState(); - Mockito.doThrow(new InvalidInputException("test")).when(mockOperHelper).isInputValid(mockInput); - Status status = testBaseProcessor.processRequest(mockInput); - Assert.assertEquals("Should return reject", - OAMCommandStatus.INVALID_PARAMETER.getResponseCode(), status.getCode().intValue()); - } - - @Test - public void testProcessRequest() throws Exception { - Mockito.doReturn(currentState).when(mockStateHelper).getCurrentOamState(); - Mockito.doReturn(AppcOamStates.Starting).when(mockOperHelper).getNextState(any(), any()); - Mockito.doReturn(mockCommonHeader).when(mockInput).getCommonHeader(); - Status status = testBaseProcessor.processRequest(mockInput); - Assert.assertEquals("Should return success", - OAMCommandStatus.ACCEPTED.getResponseCode(), status.getCode().intValue()); - } - - @Test(expected = InvalidInputException.class) - public void testPreProcessWithInvalidInput() throws Exception { - Mockito.doThrow(new InvalidInputException("test")).when(mockOperHelper).isInputValid(mockInput); - testBaseProcessor.preProcess(mockInput); - } - - @Test(expected = InvalidStateException.class) - public void testPreProcessWithInvalidState() throws Exception { - Mockito.doReturn(currentState).when(mockStateHelper).getCurrentOamState(); - Mockito.doThrow(new InvalidStateException("test")) - .when(mockOperHelper).getNextState(testRpc.getAppcOperation(), currentState); - testBaseProcessor.preProcess(mockInput); - } - - @Test(expected = APPCException.class) - public void testPreProcessWithAppcException() throws Exception { - Mockito.doReturn(currentState).when(mockStateHelper).getCurrentOamState(); - Mockito.doThrow(new APPCException("test")) - .when(mockOperHelper).getNextState(testRpc.getAppcOperation(), currentState); - testBaseProcessor.preProcess(mockInput); - } - - @Test - public void testPreProcess() throws Exception { - Mockito.doReturn(currentState).when(mockStateHelper).getCurrentOamState(); - AppcOamStates nextState = AppcOamStates.Starting; - Mockito.doReturn(nextState) - .when(mockOperHelper).getNextState(testRpc.getAppcOperation(), currentState); - testBaseProcessor.preProcess(mockInput); - Mockito.verify(mockOperHelper, times(1)).isInputValid(mockInput); - Mockito.verify(mockOperHelper, times(1)).getNextState(testRpc.getAppcOperation(), currentState); - Mockito.verify(mockStateHelper, times(1)).setState(nextState); - } - - @Test - public void testScheduleAsyncTask() throws Exception { - // test no runnable - testBaseProcessor.scheduleAsyncTask(); - Assert.assertTrue(Whitebox.getInternalState(testBaseProcessor, "runnable") == null); - Assert.assertTrue(Whitebox.getInternalState(testBaseProcessor, "scheduledRunnable") == null); - - BaseActionRunnable mockRunnable = mock(BaseActionRunnable.class); - Whitebox.setInternalState(testBaseProcessor, "runnable", mockRunnable); - testBaseProcessor.scheduleAsyncTask(); - // scheduledRunnable should still be null, there's no mock done - // as I have trouble to make mockTaskHelper.scheduleBaseRunnable to return a proper Future - Assert.assertTrue(Whitebox.getInternalState(testBaseProcessor, "scheduledRunnable") == null); - } - -} diff --git a/appc-oam/appc-oam-bundle/src/test/java/org/openecomp/appc/oam/util/AsyncTaskHelperTest.java b/appc-oam/appc-oam-bundle/src/test/java/org/openecomp/appc/oam/util/AsyncTaskHelperTest.java deleted file mode 100644 index ddeb99440..000000000 --- a/appc-oam/appc-oam-bundle/src/test/java/org/openecomp/appc/oam/util/AsyncTaskHelperTest.java +++ /dev/null @@ -1,665 +0,0 @@ -/*- - * ============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 org.junit.After; -import org.junit.Assert; -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.Mockito; -import org.onap.appc.oam.AppcOam; -import org.onap.appc.statemachine.impl.readers.AppcOamStates; -import org.osgi.framework.Bundle; -import org.osgi.framework.FrameworkUtil; -import org.powermock.api.mockito.PowerMockito; -import org.powermock.core.classloader.annotations.PrepareForTest; -import org.powermock.modules.junit4.PowerMockRunner; - -import java.util.LinkedList; -import java.util.concurrent.Future; -import java.util.concurrent.Semaphore; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.TimeoutException; -import java.util.concurrent.atomic.AtomicReference; -import java.util.function.Supplier; - -import static org.mockito.Matchers.any; -import static org.mockito.Mockito.mock; -import static org.powermock.api.mockito.PowerMockito.mockStatic; - - -@RunWith(PowerMockRunner.class) -@PrepareForTest({FrameworkUtil.class}) -public class AsyncTaskHelperTest { - private AsyncTaskHelper asyncTaskHelper; - - private long initialDelayMillis = 0; - private long delayMillis = 10; - - - @Before - public void setUp() throws Exception { - - // to avoid operation on logger fail, mock up the logger - EELFLogger mockLogger = mock(EELFLogger.class); - - - mockStatic(FrameworkUtil.class); - Bundle myBundle = mock(Bundle.class); - Mockito.doReturn("TestBundle").when(myBundle).getSymbolicName(); - PowerMockito.when(FrameworkUtil.getBundle(any())).thenReturn(myBundle); - - asyncTaskHelper = new AsyncTaskHelper(mockLogger); - - - } - - - @After - public void shutdown(){ - asyncTaskHelper.close(); - } - - - /** - * Test that Base Runnable - * - * Runs at a fix rate; - * Only one Base Runnable can be scheduled at time; - * Future.cancle stops the Base Runnable; - * That another Base Runnable can be scheduled once the previous isDone. - */ - @Test - public void test_scheduleBaseRunnable_Base_isDone() throws Exception{ - - - - //loop is to test we can run consecutive Base Runnable - for(int testIteration = 0; testIteration < 3;testIteration++){ - final ExecuteTest et = new ExecuteTest(); - - Future future = asyncTaskHelper.scheduleBaseRunnable( - et::test - , s -> { } - ,initialDelayMillis - ,delayMillis - ); - - //make sure it is running at a fix rate - Assert.assertTrue("It should be iterating", et.waitForTestExec(5000)); - Assert.assertFalse("It Should not be Done", future.isDone()); - Assert.assertTrue("It should be iterating", et.waitForTestExec(5000)); - Assert.assertFalse("It Should not be Done", future.isDone()); - - - //make sure a seconds Runnable cannot be scheduled when one is already running - try { - asyncTaskHelper.scheduleBaseRunnable(et::test - , s -> {} - ,initialDelayMillis - ,delayMillis - ); - Assert.fail("scheduling should have been prevented. "); - } catch (IllegalStateException e) { - //IllegalStateException means the second scheduling was not allowed. - } - - - //let it cancel itself - et.cancelSelfOnNextExecution(future); - - //it should be done after it executes itself one more time. - Assert.assertTrue("it should be done", waitFor(future::isDone, 5000)); - Assert.assertTrue("The test failed to execute", et.isExecuted); - } - - - } - - - /** - * Makes sure the Future.isDone one only returns true if its runnable is not currently executing and will not - * execute in the future. Default implementation of isDone() returns true immediately after the future is - * canceled -- Even if is there is still a thread actively executing the runnable - */ - @Test - public void test_scheduleBaseRunnable_Base_isDone_Ignore_Interrupt() throws Exception{ - - - final ExecuteTest et = new ExecuteTest(); - - //configure test to run long and ignore interrupt - et.isContinuous = true; - et.isIgnoreInterrupt = true; - - - - Future future = asyncTaskHelper.scheduleBaseRunnable( - et::test - , s->{} - ,initialDelayMillis - ,delayMillis - ); - - //make sure it is running - Assert.assertTrue("It should be running",waitFor(et::isExecuting,1000)); - Assert.assertTrue("It should be running",et.waitForTestExec(1000)); - Assert.assertFalse("It Should not be Done", future.isDone()); - - //cancel it and make sure it is still running - future.cancel(true); - Assert.assertTrue("It should be running",waitFor(et::isExecuting,1000)); - Assert.assertTrue("It should be running",et.waitForTestExec(1000)); - Assert.assertFalse("It Should not be Done", future.isDone()); - - //let the thread die and then make sure its done - et.isContinuous = false; - Assert.assertTrue("It should not be running",waitForNot(et::isExecuting,1000)); - Assert.assertTrue("It Should be Done", future.isDone()); - - } - - - - - /** - * Make sure the base Future.isDone returns false until the sub callable has completed execution. - */ - @Test - public void test_scheduleBaseRunnable_SubTask_isDone_Ignore_Interrupt() throws Exception{ - - - final ExecuteTest baseET = new ExecuteTest(); - final ExecuteTest subET = new ExecuteTest(); - - //configure sub test to run long and ignore interrupt - subET.isContinuous = true; - subET.isIgnoreInterrupt = true; - - - //schedule the Base test to run and make sure it is running. - Future baseFuture = asyncTaskHelper.scheduleBaseRunnable( - baseET::test - ,s->{} - ,initialDelayMillis - ,delayMillis - ); - Assert.assertTrue("baseET should be running",waitFor(baseET::isExecuted,1000)); - Assert.assertFalse("baseET Should not be Done because it runs at a fix rate", baseFuture.isDone()); - - - //schedule the sub task and make sure it is running - Future subFuture = asyncTaskHelper.submitBaseSubCallable(subET::test); - Assert.assertTrue("subET should be running",waitFor(subET::isExecuting,1000)); - Assert.assertTrue("subET should be running",subET.waitForTestExec(1000)); - Assert.assertFalse("subET Should not be Done", subFuture.isDone()); - Assert.assertFalse("baseET Should not be Done", baseFuture.isDone()); - - //cancel the base task and make sure isDone is still false - baseFuture.cancel(true); - Assert.assertTrue("subET should be running",waitFor(subET::isExecuting,1000)); - Assert.assertTrue("subET should be running",subET.waitForTestExec(1000)); - Assert.assertFalse("subET Should not be Done",subFuture.isDone()); - Assert.assertFalse("baseET Should not be Done", baseFuture.isDone()); - - - //let the sub task die and and make sure the base is now finally done - subET.isContinuous = false; - Assert.assertTrue("subET should not be running",waitForNot(subET::isExecuting,1000)); - Assert.assertTrue("subET Should be Done", subFuture.isDone()); - Assert.assertTrue("baseET Should be Done", baseFuture.isDone()); - - } - - - /** - * Make sure the base Future.isDone returns false until the 3 sub callable has completed execution. - * Each sub callable will be shutdown one at a time. - */ - @Test - public void test_scheduleBaseRunnable_SubTasks_isDone() throws Exception { - - - //loop is to test we can run consecutive Base Runnable - for (int testIteration = 0; testIteration < 3; testIteration++) { - final ExecuteTest baseET = new ExecuteTest(); - final LinkedList subList = new LinkedList<>(); - for (int i = 0; i < 3; i++) { - Sub sub = new Sub(); - sub.et.isContinuous = true; - subList.add(sub); - } - - - //schedule the base runnable and make sure it is running - Future baseFuture = asyncTaskHelper.scheduleBaseRunnable( - baseET::test - , s -> { - } - , initialDelayMillis - , delayMillis - ); - Assert.assertTrue("baseET should be running", waitFor(baseET::isExecuted, 1000)); - Assert.assertFalse("baseET Should not be Done because it runs at a fix rate", baseFuture.isDone()); - - - //schedule the sub Callables and make sure these are running - subList.forEach(sub -> sub.future = asyncTaskHelper.submitBaseSubCallable(sub.et::test)); - for (Sub sub : subList) { - Assert.assertTrue("subET should be running", waitFor(sub.et::isExecuting, 100)); - Assert.assertTrue("subET should be running", sub.et.waitForTestExec(1000)); - Assert.assertFalse("subET Should not be Done", sub.future.isDone()); - } - Assert.assertFalse("baseET Should not be Done", baseFuture.isDone()); - - - //On each iteration shut down a sub callable. Make sure it stops, the others are still running and the - // //base is still running. - while (!subList.isEmpty()) { - - //stop one sub and make sure it stopped - { - Sub sub = subList.removeFirst(); - Assert.assertTrue("subET should be running", waitFor(sub.et::isExecuting, 1000)); - sub.et.isContinuous = false; - Assert.assertTrue("subET should not be running", waitForNot(sub.et::isExecuting,1000)); - Assert.assertTrue("subET Should not be Done", sub.future.isDone()); - } - - //make sure the other are still running - for (Sub sub : subList) { - Assert.assertTrue("subET should be running", waitFor(sub.et::isExecuting, 1000)); - Assert.assertTrue("subET should be running", sub.et.waitForTestExec(1000)); - Assert.assertFalse("subET Should not be Done", sub.future.isDone()); - } - - //Make sure the Base is still running - Assert.assertFalse("baseET Should not be Done", baseFuture.isDone()); - } - - //let the base cancel itself and make sure it stops - baseET.cancelSelfOnNextExecution(baseFuture); - Assert.assertTrue("baseET should be done", waitFor(baseFuture::isDone, 1000)); - } - } - - - /** - * Make sure SubCallable cannot be scheduled when there is not BaseRunnable - */ - @Test(expected=IllegalStateException.class) - public void test_SubTasksScheduleFailWhenNoBase() throws Exception { - asyncTaskHelper.submitBaseSubCallable(()->null); - } - - - - /** - * Make sure SubCallable cannot be scheduled when BaseRunnable is cancelled but is still actively running. - */ - @Test(expected=IllegalStateException.class) - public void test_SubTasksScheduleFailWhenBaseCanceledBeforeisDone() throws Exception { - - final ExecuteTest et = new ExecuteTest(); - et.isContinuous = true; - - Future future = asyncTaskHelper.scheduleBaseRunnable( - et::test - , s -> { } - ,initialDelayMillis - ,delayMillis - ); - - Assert.assertTrue("It should be running",waitFor(et::isExecuting,1000)); - future.cancel(false); - Assert.assertTrue("It should be running",waitFor(et::isExecuting,1000)); - - try { - asyncTaskHelper.submitBaseSubCallable(() -> null); - } finally { - et.isContinuous = false; - } - - - - } - - - /** - * Make sure SubCallable cannot be scheduled after a BaseRunnable has completed - */ - @Test(expected=IllegalStateException.class) - public void test_SubTasksScheduleFailAfterBaseDone() throws Exception { - - final ExecuteTest et = new ExecuteTest(); - - Future future = asyncTaskHelper.scheduleBaseRunnable( - et::test - , s -> { } - ,initialDelayMillis - ,delayMillis - ); - - - future.cancel(false); - Assert.assertTrue("It should not be running",waitFor(future::isDone,1000)); - - try { - asyncTaskHelper.submitBaseSubCallable(() -> null); - } finally { - et.isContinuous = false; - } - - } - - - /** - * Test {@link AsyncTaskHelper#cancelBaseActionRunnable(AppcOam.RPC, AppcOamStates, long, TimeUnit)}} - * Test cancel does not block when BaseRunnable is not scheduled - */ - @Test - public void test_cancel_noBlockingWhenBaseRunnableNotScheduled() throws Exception{ - //nothing is running so this should return immediately without TimeoutException - asyncTaskHelper.cancelBaseActionRunnable(AppcOam.RPC.stop , AppcOamStates.Started , 1, TimeUnit.MILLISECONDS); - } - - - - /** - * Test {@link AsyncTaskHelper#cancelBaseActionRunnable(AppcOam.RPC, AppcOamStates, long, TimeUnit)}} - * Test cancel does blocks until BaseRunnable is done scheduled - */ - @Test() - public void test_cancel_BlockingWhenBaseRunnableNotDone() throws Exception { - - - final ExecuteTest et = new ExecuteTest(); - et.isContinuous = true; - et.isIgnoreInterrupt = true; - asyncTaskHelper.scheduleBaseRunnable( - et::test - , s -> { - } - , initialDelayMillis - , delayMillis - ); - - Assert.assertTrue("It should be running", waitFor(et::isExecuting, 1000)); - - - //we should get a timeout - try { - asyncTaskHelper.cancelBaseActionRunnable( - AppcOam.RPC.stop, - AppcOamStates.Started, - 1, - TimeUnit.MILLISECONDS); - Assert.fail("Should have gotten TimeoutException"); - } catch (TimeoutException e) { - //just ignore as it is expected - } - - - //release the test thread - et.isContinuous = false; - - - //we should not get a timeout - asyncTaskHelper.cancelBaseActionRunnable( - AppcOam.RPC.stop, - AppcOamStates.Started, - 1000, - TimeUnit.MILLISECONDS); - - } - - - - /** - * Test {@link AsyncTaskHelper#cancelBaseActionRunnable(AppcOam.RPC, AppcOamStates, long, TimeUnit)}} - * Test cancel does not block when BaseRunnable is not scheduled - */ - @Test - public void test_BaseRunnableCancelCallback() throws Exception{ - - AtomicReference cancelCallback = new AtomicReference<>(null); - - final ExecuteTest et = new ExecuteTest(); - et.isContinuous = true; - Future future = asyncTaskHelper.scheduleBaseRunnable( - et::test - , cancelCallback::set - , initialDelayMillis - , delayMillis - ); - - Assert.assertTrue("It should be running", waitFor(et::isExecuting, 1000)); - Assert.assertTrue("It should be running", waitForNot(future::isDone, 1000)); - - - try { - asyncTaskHelper.cancelBaseActionRunnable( - AppcOam.RPC.stop, - AppcOamStates.Started, - 1, - TimeUnit.MILLISECONDS); - Assert.fail("Should have gotten TimeoutException"); - } catch (TimeoutException e) { - //just ignore as it is expected - } - - - Assert.assertEquals("Unexpected rpc in call back",AppcOam.RPC.stop,cancelCallback.get()); - } - - - - - - - - - /** - * @return true if the negation of the expected value is returned from the supplier within the specified - * amount of time - */ - private static boolean waitForNot(Supplier s,long timeoutMillis)throws Exception{ - return waitFor(()->!s.get(),timeoutMillis); - } - - - /** - * @return true if the expected value is returned from the supplier within the specified - * amount of time - */ - private static boolean waitFor(Supplier s,long timeoutMillis) throws Exception { - long timeout = TimeUnit.MILLISECONDS.toMillis(timeoutMillis); - long expiryTime = System.currentTimeMillis() + timeout; - long elapsedTime; - while(!s.get()){ - elapsedTime = expiryTime - System.currentTimeMillis(); - if(elapsedTime < 1) { - break; - } - Thread.sleep(10); - } - return s.get(); - } - - - /** - * This class is used control a thread executed in th {@link #test()} - */ - @SuppressWarnings("unused") - private static class ExecuteTest { - - - /** A fail safe to insure this TEst does not run indefinitely */ - private final long EXPIRY_TIME = System.currentTimeMillis() + 10000; - - - - /** A thread sets this value to true when it has completed the execution the of executes {@link #test()} */ - private volatile boolean isExecuted = false; - - /** - * A thread sets this value to true when it is actively executing {@link #test()} and back to false when - * it is not - */ - private volatile boolean isExecuting = false; - - /** - * While this value is true, a thread will not be allowed to return from {@link #test()} It will simulate a - * long execution. - */ - private volatile boolean isContinuous = false; - - /** - * When this value is set to true, an ongoing simulation of a long execution of {@link #test()} cannot be force - * to abort via a {@link Thread#interrupt()} - */ - private volatile boolean isIgnoreInterrupt = false; - - - - /** Use to send a signal to the thread executing {@link #notifyTestExcuted(long)} */ - private Semaphore inner = new Semaphore(0); - - /** Use to send a signal to the thread executing {@link #waitForTestExec(long)} */ - private Semaphore outer = new Semaphore(0); - - /** The {@link Future} of the Thread executing {@link #test()}*/ - private volatile Future future; - - /** - * When set the Thread executing {@link #test()} will cancel itself - * @param future - The {@link Future} of the Thread executing {@link #test()} - */ - private void cancelSelfOnNextExecution(Future future) { - this.future = future; - } - - - private boolean isExecuted() { - return isExecuted; - } - - private boolean isExecuting() { - return isExecuting; - } - - - private boolean isContinuous() { - return isContinuous; - } - - - private boolean isIgnoreInterrupt() { - return isIgnoreInterrupt; - } - - - - /** - * The thread executing this method if blocked from returning until the thread executing - * {@link #test()} invokes {@link #notifyTestExcuted(long)} or the specified time elapses - * @param timeoutMillis - the amount of time to wait for a execution iteration. - * @return true if the Thread is released because of an invocation of {@link #notifyTestExcuted(long)} - * @throws InterruptedException - If the Caller thread is interrupted. - */ - private boolean waitForTestExec(long timeoutMillis) throws InterruptedException { - inner.release(); - return outer.tryAcquire(timeoutMillis,TimeUnit.MILLISECONDS); - } - - - /** - * Test simulator - * @return Always returns true. - */ - private Boolean test() { - isTestExpired(); - System.out.println("started"); - isExecuting = true; - try { - if (future != null) { - future.cancel(false); - } - if(!isContinuous){ - notifyTestExcuted(1); - } - - while(isContinuous){ - notifyTestExcuted(100); - isTestExpired(); - } - - } finally { - isExecuting = false; - isExecuted = true; - } - return true; - } - - - /** @throws RuntimeException if the test has bee running too long */ - private void isTestExpired(){ - if(System.currentTimeMillis() > EXPIRY_TIME){ - throw new RuntimeException("Something went wrong the test expired."); - } - } - - - /** - * The thread executing {@link #test()} if blocked from returning until another thread invokes - * {@link #waitForTestExec(long)} or the specified time elapses - * @param timeoutMillis - the amount of time to wait for a execution iteration. - * @return true if the Thread is released because of an invocation of {@link #waitForTestExec(long)} - */ - private boolean notifyTestExcuted(long timeoutMillis){ - try { - boolean acquire = inner.tryAcquire(timeoutMillis,TimeUnit.MILLISECONDS); - if(acquire){ - outer.release(); - System.out.println("release"); - } - } catch (InterruptedException e) { - if(!isIgnoreInterrupt){ - return false; - } - } - return true; - } - } - - - static class Sub { - ExecuteTest et = new ExecuteTest(); - Future future = null; - } - -} diff --git a/appc-oam/appc-oam-bundle/src/test/java/org/openecomp/appc/oam/util/BundleHelperTest.java b/appc-oam/appc-oam-bundle/src/test/java/org/openecomp/appc/oam/util/BundleHelperTest.java deleted file mode 100644 index 433e87517..000000000 --- a/appc-oam/appc-oam-bundle/src/test/java/org/openecomp/appc/oam/util/BundleHelperTest.java +++ /dev/null @@ -1,180 +0,0 @@ -/*- - * ============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 org.apache.commons.lang.ArrayUtils; -import org.junit.Assert; -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.Mockito; -import org.onap.appc.configuration.Configuration; -import org.onap.appc.exceptions.APPCException; -import org.onap.appc.oam.AppcOam; -import org.onap.appc.statemachine.impl.readers.AppcOamStates; -import org.osgi.framework.Bundle; -import org.osgi.framework.BundleContext; -import org.osgi.framework.FrameworkUtil; -import org.powermock.api.mockito.PowerMockito; -import org.powermock.api.support.membermodification.MemberMatcher; -import org.powermock.core.classloader.annotations.PrepareForTest; -import org.powermock.modules.junit4.PowerMockRunner; -import org.powermock.reflect.Whitebox; - -import java.util.Arrays; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import static org.mockito.Matchers.any; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.times; -import static org.powermock.api.mockito.PowerMockito.mockStatic; -import static org.powermock.api.mockito.PowerMockito.spy; - -@SuppressWarnings("ResultOfMethodCallIgnored") -@RunWith(PowerMockRunner.class) -@PrepareForTest({BundleHelper.class, FrameworkUtil.class}) -public class BundleHelperTest { - private BundleHelper bundleHelper; - private AsyncTaskHelper mockTaskHelper = mock(AsyncTaskHelper.class); - - @Before - public void setUp() throws Exception { - bundleHelper = spy(new BundleHelper(null, null, null)); - - // to avoid operation on logger fail, mock up the logger - EELFLogger mockLogger = mock(EELFLogger.class); - Whitebox.setInternalState(bundleHelper, "logger", mockLogger); - } - - @Test - public void testBundleOperations() throws Exception { - // spy mocked bundle for calls to method statr or stop. - // Note: the time of method calls are accumulated in this test method. - Bundle mockBundle = spy(Mockito.mock(Bundle.class)); - Map mapFromGetAppcLcmBundles = new HashMap<>(); - mapFromGetAppcLcmBundles.put("BundleString", mockBundle); - - PowerMockito.doReturn(mapFromGetAppcLcmBundles).when(bundleHelper, MemberMatcher.method( - BundleHelper.class, "getAppcLcmBundles")).withNoArguments(); - - StateHelper mockStateHelper = mock(StateHelper.class); - Whitebox.setInternalState(bundleHelper, "stateHelper", mockStateHelper); - - AppcOamStates appcOamStates = AppcOamStates.Stopped; - Mockito.doReturn(appcOamStates).when(mockStateHelper).getState(); - - // test start - Mockito.doReturn(true).when(mockStateHelper).isSameState(appcOamStates); - boolean result = bundleHelper.bundleOperations(AppcOam.RPC.start, new HashMap<>(), mockTaskHelper,null); - Assert.assertTrue("Should be completed", result); - Mockito.verify(mockTaskHelper, times(1)).submitBaseSubCallable(any()); - - // test start aborted - Mockito.doReturn(false).when(mockStateHelper).isSameState(appcOamStates); - result = bundleHelper.bundleOperations(AppcOam.RPC.start, new HashMap<>(), mockTaskHelper,null); - Assert.assertFalse("Should be abort", result); - Mockito.verify(mockTaskHelper, times(1)).submitBaseSubCallable(any()); - - // test stop - result = bundleHelper.bundleOperations(AppcOam.RPC.stop, new HashMap<>(), mockTaskHelper,null); - Assert.assertTrue("Should be completed", result); - Mockito.verify(mockTaskHelper, times(2)).submitBaseSubCallable(any()); - } - - @Test(expected = APPCException.class) - public void testBundleOperationsRpcException() throws Exception { - bundleHelper.bundleOperations(AppcOam.RPC.maintenance_mode, new HashMap<>(), mockTaskHelper,null); - } - - @Test - public void testGetBundleList() throws Exception { - mockStatic(FrameworkUtil.class); - Bundle myBundle = mock(Bundle.class); - PowerMockito.when(FrameworkUtil.getBundle(any())).thenReturn(myBundle); - - // test bundle context is null - Mockito.when(myBundle.getBundleContext()).thenReturn(null); - Assert.assertTrue("Should return null", bundleHelper.getBundleList() == null); - - BundleContext myBundleContext = mock(BundleContext.class); - Mockito.when(myBundle.getBundleContext()).thenReturn(myBundleContext); - - // test bundle list is empty - Bundle[] bundleArray = {}; - Mockito.when(myBundleContext.getBundles()).thenReturn(bundleArray); - Bundle[] results = bundleHelper.getBundleList(); - Assert.assertTrue("Should not be null", results != null); - Assert.assertTrue("Should not have any element", results.length == 0); - - // test bundle list has at one bundle - bundleArray = new Bundle[] { myBundle }; - Mockito.when(myBundleContext.getBundles()).thenReturn(bundleArray); - results = bundleHelper.getBundleList(); - Assert.assertTrue("Should not be null", results != null); - Assert.assertTrue("Should have one element", results.length == 1); - Assert.assertEquals("Should be the mock bundle", myBundle, results[0]); - } - - @Test - public void testReadPropsFromPropListName() throws Exception { - // mock configuarion helper - ConfigurationHelper configurationHelper = new ConfigurationHelper(null); - EELFLogger fakeLogger = mock(EELFLogger.class); - Whitebox.setInternalState(configurationHelper, "logger", fakeLogger); - Configuration fakeConf = mock(Configuration.class); - Whitebox.setInternalState(configurationHelper, "configuration", fakeConf); - - Whitebox.setInternalState(bundleHelper, "configurationHelper", configurationHelper); - - String propKey = "testing"; - // Property does not exist - Mockito.doReturn(null).when(fakeConf).getProperty(propKey); - String[] propResult = bundleHelper.readPropsFromPropListName(propKey); - Assert.assertArrayEquals("PropertyResult should be empty string array", - ArrayUtils.EMPTY_STRING_ARRAY, propResult); - // Property has one entry - String propValue1 = "1234"; - String propValue2 = "5678"; - Mockito.doReturn(propValue1).when(fakeConf).getProperty(propKey); - Mockito.doReturn(propValue2).when(fakeConf).getProperty(propValue1); - propResult = bundleHelper.readPropsFromPropListName(propKey); - Assert.assertTrue("PropertyResult should have only one element", propResult.length == 1); - Assert.assertEquals("PropertyResult should martch propertyValue", propValue2, propResult[0]); - // Property has two entries - propValue1 = "1234\n,4321"; - String propValue3 = "8765"; - Mockito.doReturn(propValue1).when(fakeConf).getProperty(propKey); - Mockito.doReturn(propValue2).when(fakeConf).getProperty(propValue1); - Mockito.doReturn(propValue3).when(fakeConf).getProperty("4321"); - propResult = bundleHelper.readPropsFromPropListName(propKey); - Assert.assertTrue("PropertyResult should have two elements", propResult.length == 2); - List propResultList = Arrays.asList(propResult); - Assert.assertTrue("PropertyResult should have propertyValue2", propResultList.contains(propValue2)); - Assert.assertTrue("PropertyResult should have propertyValue2", propResultList.contains(propValue3)); - } -} diff --git a/appc-oam/appc-oam-bundle/src/test/java/org/openecomp/appc/oam/util/ConfigurationHelperTest.java b/appc-oam/appc-oam-bundle/src/test/java/org/openecomp/appc/oam/util/ConfigurationHelperTest.java deleted file mode 100644 index 348517b72..000000000 --- a/appc-oam/appc-oam-bundle/src/test/java/org/openecomp/appc/oam/util/ConfigurationHelperTest.java +++ /dev/null @@ -1,128 +0,0 @@ -/*- - * ============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 org.apache.commons.lang3.ArrayUtils; -import org.junit.Assert; -import org.junit.Before; -import org.junit.Test; -import org.mockito.Mockito; -import org.onap.appc.configuration.Configuration; -import org.powermock.reflect.Whitebox; - -import static org.mockito.Mockito.mock; - -public class ConfigurationHelperTest { - private ConfigurationHelper configurationHelper; - - private Configuration mockConf; - private Configuration origConf; - - @Before - public void setUp() throws Exception { - mockConf = mock(Configuration.class); - - configurationHelper = new ConfigurationHelper(null); - - // to avoid operation on logger fail, mock up the logger - EELFLogger fakeLogger = mock(EELFLogger.class); - Whitebox.setInternalState(configurationHelper, "logger", fakeLogger); - } - - private void setMockConf() { - origConf = Whitebox.getInternalState(configurationHelper, "configuration"); - Whitebox.setInternalState(configurationHelper, "configuration", mockConf); - } - - private void resetOrigConfig() { - Whitebox.setInternalState(configurationHelper, "configuration", origConf); - origConf = null; - } - - @Test - public void getAppcName() throws Exception { - // test with existing properties file - Assert.assertEquals("Should return value(APPC).", "APPC", configurationHelper.getAppcName()); - - // test with mockup - setMockConf(); - - String propValue = "testing"; - Mockito.doReturn(propValue).when(mockConf).getProperty(ConfigurationHelper.PROP_KEY_APPC_NAME); - Assert.assertEquals(String.format("Should return value(%s).", propValue), propValue, - configurationHelper.getAppcName()); - - resetOrigConfig(); - } - - @Test - public void isMetricEnabled() throws Exception { - // test with mockup - setMockConf(); - - Mockito.doReturn(false).when(mockConf).getBooleanProperty( - ConfigurationHelper.PROP_KEY_METRIC_STATE, false); - Assert.assertFalse("Should return false", configurationHelper.isMetricEnabled()); - - Mockito.doReturn(true).when(mockConf).getBooleanProperty( - ConfigurationHelper.PROP_KEY_METRIC_STATE, false); - Assert.assertTrue("Should return true", configurationHelper.isMetricEnabled()); - } - - @Test - public void testReadPropertyNotStop() throws Exception { - String[] str = configurationHelper.readProperty("appc.OAM.AppcBundlesToNotStop"); - Assert.assertTrue(str.length > 0); - Assert.assertTrue(str[0].equals(".*appc.oam.*")); - } - - @Test - public void testReadPropertyStop() throws Exception { - String[] str = configurationHelper.readProperty("appc.OAM.AppcBundlesToStop"); - Assert.assertTrue(str.length > 0); - Assert.assertTrue(str[0].equals(".*appc.*")); - } - - @Test - public void testReadPropertyWithMockup() throws Exception { - setMockConf(); - - String propKey = "testing"; - // Property does not exist - Mockito.doReturn(null).when(mockConf).getProperty(propKey); - String[] propResult = configurationHelper.readProperty(propKey); - Assert.assertArrayEquals("PropertyResult should be empty string array", - ArrayUtils.EMPTY_STRING_ARRAY, propResult); - // Property has one entry - String propValue = "1234"; - Mockito.doReturn(propValue).when(mockConf).getProperty(propKey); - propResult = configurationHelper.readProperty(propKey); - Assert.assertTrue("PropertyResult should have only one element", propResult.length == 1); - Assert.assertEquals("PropertyResult should martch propertyValue", propValue, propResult[0]); - - resetOrigConfig(); - } -} diff --git a/appc-oam/appc-oam-bundle/src/test/java/org/openecomp/appc/oam/util/OperationHelperTest.java b/appc-oam/appc-oam-bundle/src/test/java/org/openecomp/appc/oam/util/OperationHelperTest.java deleted file mode 100644 index 77edd1701..000000000 --- a/appc-oam/appc-oam-bundle/src/test/java/org/openecomp/appc/oam/util/OperationHelperTest.java +++ /dev/null @@ -1,240 +0,0 @@ -/*- - * ============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 org.junit.Assert; -import org.junit.Before; -import org.junit.Rule; -import org.junit.Test; -import org.junit.rules.ExpectedException; -import org.junit.runner.RunWith; -import org.mockito.Mockito; -import org.opendaylight.yang.gen.v1.org.onap.appc.oam.rev170303.MaintenanceModeInput; -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.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.statemachine.impl.readers.AppcOamMetaDataReader; -import org.onap.appc.statemachine.impl.readers.AppcOamStates; -import org.osgi.framework.Bundle; -import org.osgi.framework.BundleContext; -import org.osgi.framework.FrameworkUtil; -import org.osgi.framework.ServiceReference; -import org.powermock.api.mockito.PowerMockito; -import org.powermock.core.classloader.annotations.PrepareForTest; -import org.powermock.modules.junit4.PowerMockRunner; -import org.powermock.reflect.Whitebox; - -import static org.mockito.Mockito.mock; -import static org.powermock.api.mockito.PowerMockito.mockStatic; - -@RunWith(PowerMockRunner.class) -@PrepareForTest({FrameworkUtil.class}) -public class OperationHelperTest { - private OperationHelper operationHelper; - private LifecycleManager lifecycleManager = mock(LifecycleManager.class); - private CommonHeader mockCommonHeader = mock(CommonHeader.class); - - @Rule - public ExpectedException expectedException = ExpectedException.none(); - - @Before - public void setUp() throws Exception { - operationHelper = new OperationHelper(); - Whitebox.setInternalState(operationHelper, "lifecycleMgr", lifecycleManager); - } - - @Test - public void testIsInputValidWithMissingInput() throws Exception { - expectedException.expect(InvalidInputException.class); - expectedException.expectMessage(operationHelper.MISSING_COMMON_HEADER_MESSAGE); - - operationHelper.isInputValid(null); - expectedException = ExpectedException.none(); - } - - @Test - public void testIsInputValidWithMissingCommonHeader() throws Exception { - StartInput mockInput = mock(StartInput.class); - expectedException.expect(InvalidInputException.class); - expectedException.expectMessage(operationHelper.MISSING_COMMON_HEADER_MESSAGE); - - operationHelper.isInputValid(mockInput); - expectedException = ExpectedException.none(); - } - - @Test - public void testIsInputValidWithMissingOid() throws Exception { - StartInput mockInput = mock(StartInput.class); - Mockito.doReturn(mockCommonHeader).when(mockInput).getCommonHeader(); - Mockito.doReturn(null).when(mockCommonHeader).getOriginatorId(); - expectedException.expect(InvalidInputException.class); - expectedException.expectMessage(operationHelper.MISSING_FIELD_MESSAGE); - - operationHelper.isInputValid(mockInput); - expectedException = ExpectedException.none(); - } - - @Test - public void testIsInputValidWithMissingRid() throws Exception { - StartInput mockInput = mock(StartInput.class); - Mockito.doReturn(mockCommonHeader).when(mockInput).getCommonHeader(); - Mockito.doReturn("originalId").when(mockCommonHeader).getOriginatorId(); - Mockito.doReturn(null).when(mockCommonHeader).getRequestId(); - expectedException.expect(InvalidInputException.class); - expectedException.expectMessage(operationHelper.MISSING_FIELD_MESSAGE); - - operationHelper.isInputValid(mockInput); - expectedException = ExpectedException.none(); - } - - @Test - public void testIsInputValidWithMmodeFlags() throws Exception { - MaintenanceModeInput mockInput = mock(MaintenanceModeInput.class); - Mockito.doReturn(mockCommonHeader).when(mockInput).getCommonHeader(); - Mockito.doReturn("originalId").when(mockCommonHeader).getOriginatorId(); - Mockito.doReturn("requestId").when(mockCommonHeader).getRequestId(); - Mockito.doReturn(mock(Flags.class)).when(mockCommonHeader).getFlags(); - expectedException.expect(InvalidInputException.class); - expectedException.expectMessage(operationHelper.NOT_SUPPORT_FLAG); - - operationHelper.isInputValid(mockInput); - expectedException = ExpectedException.none(); - } - - @Test - public void testIsInputValidPass() throws Exception { - StartInput mockInput = mock(StartInput.class); - Mockito.doReturn(mockCommonHeader).when(mockInput).getCommonHeader(); - Mockito.doReturn("originalId").when(mockCommonHeader).getOriginatorId(); - Mockito.doReturn("requestId").when(mockCommonHeader).getRequestId(); - - //with Flags - Mockito.doReturn(mock(Flags.class)).when(mockCommonHeader).getFlags(); - operationHelper.isInputValid(mockInput); - - //without Flags - Mockito.doReturn(null).when(mockCommonHeader).getFlags(); - operationHelper.isInputValid(mockInput); - - // MaintenanceMode without Flags - MaintenanceModeInput mockInput1 = mock(MaintenanceModeInput.class); - Mockito.doReturn(mockCommonHeader).when(mockInput1).getCommonHeader(); - operationHelper.isInputValid(mockInput1); - } - - @Test - public void testGetCommonHeader() throws Exception { - CommonHeader commonHeader = mock(CommonHeader.class); - // for StartInput - StartInput startInput = mock(StartInput.class); - Mockito.doReturn(commonHeader).when(startInput).getCommonHeader(); - Assert.assertEquals("Should return startInput commonHeader", commonHeader, - operationHelper.getCommonHeader(startInput)); - - // for StopInput - StopInput stopInput = mock(StopInput.class); - Mockito.doReturn(commonHeader).when(stopInput).getCommonHeader(); - Assert.assertEquals("Should return stopInput commonHeader", commonHeader, - operationHelper.getCommonHeader(stopInput)); - - // for MaintenanceModeInput - MaintenanceModeInput mmInput = mock(MaintenanceModeInput.class); - Mockito.doReturn(commonHeader).when(mmInput).getCommonHeader(); - Assert.assertEquals("Should return MaintenanceModeInput commonHeader", commonHeader, - operationHelper.getCommonHeader(mmInput)); - - // unsupported type - Assert.assertTrue("should return null", - operationHelper.getCommonHeader(new Object()) == null); - } - - @SuppressWarnings("unchecked") - @Test - public void testGetService() throws Exception { - Class operationHelperClass = OperationHelper.class; - String className = operationHelperClass.getName(); - String exceptionMsg = String.format(operationHelper.NO_SERVICE_REF_FORMAT, className); - - mockStatic(FrameworkUtil.class); - Bundle bundle = mock(Bundle.class); - PowerMockito.when(FrameworkUtil.getBundle(operationHelperClass)).thenReturn(bundle); - - // No bundle context - Mockito.when(bundle.getBundleContext()).thenReturn(null); - expectedException.expect(APPCException.class); - expectedException.expectMessage(exceptionMsg); - operationHelper.getService(operationHelperClass); - - // No service reference - BundleContext bundleContext = mock(BundleContext.class); - Mockito.when(bundle.getBundleContext()).thenReturn(bundleContext); - Mockito.when(bundleContext.getServiceReference(className)).thenReturn(null); - expectedException.expect(APPCException.class); - expectedException.expectMessage(exceptionMsg); - operationHelper.getService(operationHelperClass); - - // Success path - ServiceReference svcRef = mock(ServiceReference.class); - Mockito.when(bundleContext.getServiceReference(className)).thenReturn(svcRef); - expectedException = ExpectedException.none(); - Assert.assertTrue("should not be null", operationHelper.getService(operationHelperClass) != null); - } - - @Test - public void testGetNextState() throws Exception { - AppcOamMetaDataReader.AppcOperation operation = AppcOamMetaDataReader.AppcOperation.Start; - AppcOamStates currentState = AppcOamStates.Stopped; - String exceptionMsg = String.format(AppcOam.INVALID_STATE_MESSAGE_FORMAT, operation, "APPC", currentState); - - // got LifecycleException - Mockito.doThrow(LifecycleException.class).when(lifecycleManager) - .getNextState("APPC", operation.name(), currentState.name()); - expectedException.expect(InvalidStateException.class); - expectedException.expectMessage(exceptionMsg); - operationHelper.getNextState(operation, currentState); - - // got NoTransitionDefinedException - Mockito.doThrow(NoTransitionDefinedException.class).when(lifecycleManager) - .getNextState("APPC", operation.name(), currentState.name()); - expectedException.expect(InvalidStateException.class); - expectedException.expectMessage(exceptionMsg); - operationHelper.getNextState(operation, currentState); - - // Success path - expectedException = ExpectedException.none(); - Mockito.doReturn("starting").when(lifecycleManager) - .getNextState("APPC", operation.name(), currentState.name()); - Assert.assertEquals("Should return proper Starting state", AppcOamStates.Starting, - operationHelper.getNextState(operation, currentState)); - } -} diff --git a/appc-oam/appc-oam-bundle/src/test/java/org/openecomp/appc/oam/util/StateHelperTest.java b/appc-oam/appc-oam-bundle/src/test/java/org/openecomp/appc/oam/util/StateHelperTest.java deleted file mode 100644 index 9a3050e84..000000000 --- a/appc-oam/appc-oam-bundle/src/test/java/org/openecomp/appc/oam/util/StateHelperTest.java +++ /dev/null @@ -1,173 +0,0 @@ -/*- - * ============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 org.junit.Assert; -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.Mockito; -import org.opendaylight.yang.gen.v1.org.onap.appc.oam.rev170303.AppcState; -import org.onap.appc.statemachine.impl.readers.AppcOamStates; -import org.osgi.framework.Bundle; -import org.powermock.api.mockito.PowerMockito; -import org.powermock.core.classloader.annotations.PrepareForTest; -import org.powermock.modules.junit4.PowerMockRunner; -import org.powermock.reflect.Whitebox; - -import java.util.HashMap; -import java.util.Map; - -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.times; - -@RunWith(PowerMockRunner.class) -@PrepareForTest({StateHelper.class}) -public class StateHelperTest { - private StateHelper stateHelper; - - @Before - public void setUp() throws Exception { - stateHelper = PowerMockito.spy(new StateHelper(null, null)); - - // to avoid operation on logger fail, mock up the logger - EELFLogger mockLogger = mock(EELFLogger.class); - Whitebox.setInternalState(stateHelper, "logger", mockLogger); - } - - @Test - public void testSetState() throws Exception { - AppcOamStates appcOamStates = AppcOamStates.Started; - stateHelper.setState(appcOamStates); - Assert.assertEquals("Should have the new value", appcOamStates, - Whitebox.getInternalState(stateHelper, "appcOamCurrentState")); - // reest to default value - stateHelper.setState(AppcOamStates.Unknown); - } - - @Test - public void testGetState() throws Exception { - AppcOamStates appcOamStates = stateHelper.getState(); - Assert.assertEquals("Should have the class value", appcOamStates, - Whitebox.getInternalState(stateHelper, "appcOamCurrentState")); - } - - @Test - public void testIsSameState() throws Exception { - AppcOamStates classValue = Whitebox.getInternalState(stateHelper, "appcOamCurrentState"); - for (AppcOamStates appcOamStates : AppcOamStates.values()) { - boolean isSame = stateHelper.isSameState(appcOamStates); - if (appcOamStates == classValue) { - Assert.assertTrue("Should be the same", isSame); - } else { - Assert.assertFalse("Should not be the same", isSame); - } - } - } - - @Test - public void testGetCurrentOamState() throws Exception { - AppcOamStates mockResult = AppcOamStates.Started; - // mock getBundlesState, as we are testin it separately - PowerMockito.doReturn(mockResult).when(stateHelper, "getBundlesState"); - - Whitebox.setInternalState(stateHelper, "appcOamCurrentState", AppcOamStates.Unknown); - Assert.assertEquals("Should call deriveStatte and return mockeResult", - mockResult, stateHelper.getCurrentOamState()); - Mockito.verify(stateHelper, times(1)).getBundlesState(); - - - Whitebox.setInternalState(stateHelper, "appcOamCurrentState", AppcOamStates.Unknown); - Assert.assertEquals("Should call deriveStatte and return mockeResult", - mockResult, stateHelper.getCurrentOamState()); - Mockito.verify(stateHelper, times(2)).getBundlesState(); - - Whitebox.setInternalState(stateHelper, "appcOamCurrentState", mockResult); - Assert.assertEquals("Should just return mockeResult", mockResult, stateHelper.getCurrentOamState()); - Mockito.verify(stateHelper, times(2)).getBundlesState(); - } - - @Test - public void testGetCurrentOamYangState() throws Exception { - Map stateMap = new HashMap() { - { - put(AppcOamStates.EnteringMaintenanceMode, AppcState.EnteringMaintenanceMode); - put(AppcOamStates.MaintenanceMode, AppcState.MaintenanceMode); - put(AppcOamStates.Instantiated, AppcState.Instantiated); - put(AppcOamStates.NotInstantiated, AppcState.NotInstantiated); - put(AppcOamStates.Restarting, AppcState.Restarting); - put(AppcOamStates.Started, AppcState.Started); - put(AppcOamStates.Starting, AppcState.Starting); - put(AppcOamStates.Stopped, AppcState.Stopped); - put(AppcOamStates.Stopping, AppcState.Stopping); - put(AppcOamStates.Error, AppcState.Error); - put(AppcOamStates.Unknown, AppcState.Unknown); - } - }; - for (Map.Entry aEntry : stateMap.entrySet()) { - AppcOamStates aState = aEntry.getKey(); - AppcState appcState = aEntry.getValue(); - - PowerMockito.doReturn(aState).when(stateHelper, "getCurrentOamState"); - - AppcState resultState = stateHelper.getCurrentOamYangState(); - Assert.assertEquals( - String.format("%s state, returned(%s),should return(%s) state", aState, resultState, appcState), - appcState, resultState); - - } - } - - @Test - public void testGetBundlesState() throws Exception { - BundleHelper mockBundlerHelper = mock(BundleHelper.class); - PowerMockito.whenNew(BundleHelper.class).withAnyArguments().thenReturn(mockBundlerHelper); - - // test null bundle map - Mockito.when(mockBundlerHelper.getAppcLcmBundles()).thenReturn(null); - Assert.assertEquals("Should return unknown state", AppcOamStates.Unknown, stateHelper.getBundlesState()); - - // tet empty bundle map - Map bundleMap = new HashMap<>(); - Mockito.when(mockBundlerHelper.getAppcLcmBundles()).thenReturn(bundleMap); - Assert.assertEquals("Should return unknown state", AppcOamStates.Unknown, stateHelper.getBundlesState()); - - Bundle mockBundle1 = mock(Bundle.class); - Bundle mockBundle2 = mock(Bundle.class); - bundleMap.put("1", mockBundle1); - bundleMap.put("2", mockBundle2); - Mockito.when(mockBundlerHelper.getAppcLcmBundles()).thenReturn(bundleMap); - - // test bundles have differnt states - Mockito.doReturn(Bundle.RESOLVED).when(mockBundle1).getState(); - Mockito.doReturn(Bundle.ACTIVE).when(mockBundle2).getState(); - Assert.assertEquals("Should return lower state", AppcOamStates.Stopped, stateHelper.getBundlesState()); - - // test bundles have the same state - Mockito.doReturn(Bundle.ACTIVE).when(mockBundle1).getState(); - Assert.assertEquals("Should return the state", AppcOamStates.Started, stateHelper.getBundlesState()); - } -} -- cgit 1.2.3-korg