Merge of new rebased code
Change-Id: I9b8d1f69eb3e0af1935ed8304fea4bf54c1aac47
Signed-off-by: Patrick Brady <pb071s@att.com>
diff --git a/appc-oam/appc-oam-bundle/pom.xml b/appc-oam/appc-oam-bundle/pom.xml
new file mode 100644
index 0000000..1da4a7e
--- /dev/null
+++ b/appc-oam/appc-oam-bundle/pom.xml
@@ -0,0 +1,244 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <artifactId>appc-oam</artifactId>
+ <groupId>org.openecomp.appc</groupId>
+ <version>1.1.0-SNAPSHOT</version>
+ </parent>
+ <artifactId>appc-oam-bundle</artifactId>
+ <packaging>bundle</packaging>
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.felix</groupId>
+ <artifactId>maven-bundle-plugin</artifactId>
+ <extensions>true</extensions>
+ <configuration>
+ <instructions>
+ <Export-Package>org.opendaylight.controller.config.yang.config.sample_oam.impl</Export-Package>
+ <Export-Package>org.openecomp.appc.oam</Export-Package>
+ <Import-Package>
+ org.openecomp.appc.i18n,
+ org.openecomp.appc.logging,
+ org.openecomp.appc.util,
+ com.att.eelf.configuration,
+ com.att.eelf.i18n,
+ org.openecomp.appc.adapter.messaging.*,
+ org.openecomp.appc.adapter.message.*,
+ org.openecomp.appc.adapter.factory.*,
+ org.openecomp.appc.listener.*,
+ *;resolution:=optional
+ </Import-Package>
+ <Embed-Dependency>
+ appc-common;scope=compile|runtime;inline=false
+ </Embed-Dependency>
+ <Embed-Transitive>true</Embed-Transitive>
+ </instructions>
+ </configuration>
+ </plugin>
+ <plugin>
+ <groupId>org.opendaylight.yangtools</groupId>
+ <artifactId>yang-maven-plugin</artifactId>
+ <executions>
+ <execution>
+ <id>config</id>
+ <goals>
+ <goal>generate-sources</goal>
+ </goals>
+ <configuration>
+ <codeGenerators>
+ <generator>
+ <codeGeneratorClass>
+ org.opendaylight.controller.config.yangjmxgenerator.plugin.JMXGenerator
+ </codeGeneratorClass>
+ <outputBaseDir>${jmxGeneratorPath}</outputBaseDir>
+ <additionalConfiguration>
+ <namespaceToPackage1>
+ urn:opendaylight:params:xml:ns:yang:controller==org.opendaylight.controller.config.yang
+ </namespaceToPackage1>
+ </additionalConfiguration>
+ </generator>
+ <generator>
+ <codeGeneratorClass>
+ org.opendaylight.yangtools.maven.sal.api.gen.plugin.CodeGeneratorImpl
+ </codeGeneratorClass>
+ <outputBaseDir>${salGeneratorPath}</outputBaseDir>
+ </generator>
+ </codeGenerators>
+ <inspectDependencies>true</inspectDependencies>
+ </configuration>
+ </execution>
+ </executions>
+ <dependencies>
+ <dependency>
+ <groupId>org.opendaylight.mdsal</groupId>
+ <artifactId>maven-sal-api-gen-plugin</artifactId>
+ <version>${odl.sal.api.gen.plugin.version}</version>
+ <type>jar</type>
+ </dependency>
+ <dependency>
+ <groupId>org.opendaylight.controller</groupId>
+ <artifactId>yang-jmx-generator-plugin</artifactId>
+ <version>${odl.yang.jmx.generator.version}</version>
+ </dependency>
+ </dependencies>
+ </plugin>
+ <plugin>
+ <groupId>org.codehaus.mojo</groupId>
+ <artifactId>build-helper-maven-plugin</artifactId>
+ <executions>
+ <execution>
+ <id>attach-artifacts</id>
+ <goals>
+ <goal>attach-artifact</goal>
+ </goals>
+ <phase>package</phase>
+ <configuration>
+ <artifacts>
+ <artifact>
+ <file>${project.build.directory}/classes/initial/appc-oam.xml</file>
+ <type>xml</type>
+ <classifier>config</classifier>
+ </artifact>
+ </artifacts>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ <pluginManagement>
+ <plugins>
+ <!--This plugin's configuration is used to store Eclipse m2e settings only. It has no influence on the Maven build itself.-->
+ <plugin>
+ <groupId>org.eclipse.m2e</groupId>
+ <artifactId>lifecycle-mapping</artifactId>
+ <version>1.0.0</version>
+ <configuration>
+ <lifecycleMappingMetadata>
+ <pluginExecutions>
+ <pluginExecution>
+ <pluginExecutionFilter>
+ <groupId>org.codehaus.mojo</groupId>
+ <artifactId>build-helper-maven-plugin</artifactId>
+ <versionRange>[1.9.1,)</versionRange>
+ <goals>
+ <goal>add-source</goal>
+ </goals>
+ </pluginExecutionFilter>
+ <action>
+ <ignore/>
+ </action>
+ </pluginExecution>
+ </pluginExecutions>
+ </lifecycleMappingMetadata>
+ </configuration>
+ </plugin>
+ </plugins>
+ </pluginManagement>
+ </build>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.openecomp.appc</groupId>
+ <artifactId>appc-common</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.openecomp.appc</groupId>
+ <artifactId>appc-oam-model</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.openecomp.appc</groupId>
+ <artifactId>appc-metric-bundle</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+
+ <dependency>
+ <groupId>org.openecomp.appc</groupId>
+ <artifactId>appc-request-handler-api</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+
+
+ <dependency>
+ <groupId>org.opendaylight.controller</groupId>
+ <artifactId>config-api</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.opendaylight.controller</groupId>
+ <artifactId>sal-binding-config</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.opendaylight.controller</groupId>
+ <artifactId>sal-binding-api</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.opendaylight.controller</groupId>
+ <artifactId>sal-common-util</artifactId>
+ </dependency>
+ <dependency>
+ <artifactId>sal-test-model</artifactId>
+ <groupId>org.opendaylight.controller</groupId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <artifactId>sal-rest-connector</artifactId>
+ <groupId>org.opendaylight.netconf</groupId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.opendaylight.controller</groupId>
+ <artifactId>sal-binding-broker-impl</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.opendaylight.controller</groupId>
+ <artifactId>sal-binding-broker-impl</artifactId>
+ <classifier>tests</classifier>
+ <version>${odl.mdsal.version}</version>
+ <type>test-jar</type>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <!-- TEMP CODE -->
+ <dependency>
+ <groupId>org.json</groupId>
+ <artifactId>json</artifactId>
+ </dependency>
+
+
+ <dependency>
+ <groupId>org.openecomp.appc</groupId>
+ <artifactId>appc-message-adapter-api</artifactId>
+ <version>${project.version}</version>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.openecomp.appc</groupId>
+ <artifactId>appc-message-adapter-factory</artifactId>
+ <version>${project.version}</version>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.openecomp.appc</groupId>
+ <artifactId>appc-dmaap-adapter-bundle</artifactId>
+ <version>${project.version}</version>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.openecomp.appc</groupId>
+ <artifactId>appc-event-listener-bundle</artifactId>
+ <version>${project.version}</version>
+ <scope>provided</scope>
+ </dependency>
+
+ </dependencies>
+
+</project>
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
new file mode 100644
index 0000000..93af458
--- /dev/null
+++ b/appc-oam/appc-oam-bundle/src/main/java/org/opendaylight/yang/gen/v1/org/openecomp/appc/oam/impl/rev170303/AppcOamModule.java
@@ -0,0 +1,52 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * openECOMP : APP-C
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights
+ * reserved.
+ * ================================================================================
+ * 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.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.opendaylight.yang.gen.v1.org.openecomp.appc.oam.impl.rev170303;
+
+import org.openecomp.appc.oam.AppcOam;
+
+public class AppcOamModule extends org.opendaylight.yang.gen.v1.org.openecomp.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.openecomp.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
new file mode 100644
index 0000000..9bbd38e
--- /dev/null
+++ b/appc-oam/appc-oam-bundle/src/main/java/org/opendaylight/yang/gen/v1/org/openecomp/appc/oam/impl/rev170303/AppcOamModuleFactory.java
@@ -0,0 +1,34 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * openECOMP : APP-C
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights
+ * reserved.
+ * ================================================================================
+ * 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.
+ * ============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.openecomp.appc.oam.impl.rev170303;
+public class AppcOamModuleFactory extends org.opendaylight.yang.gen.v1.org.openecomp.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
new file mode 100644
index 0000000..d255f50
--- /dev/null
+++ b/appc-oam/appc-oam-bundle/src/main/java/org/openecomp/appc/oam/AppcOam.java
@@ -0,0 +1,582 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * openECOMP : APP-C
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights
+ * reserved.
+ * ================================================================================
+ * 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.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.openecomp.appc.oam;
+
+import org.openecomp.appc.Constants;
+import org.openecomp.appc.configuration.Configuration;
+import org.openecomp.appc.configuration.ConfigurationFactory;
+import org.openecomp.appc.exceptions.APPCException;
+import org.openecomp.appc.executor.objects.Params;
+import org.openecomp.appc.i18n.Msg;
+import org.openecomp.appc.logging.LoggingConstants;
+import org.openecomp.appc.logging.LoggingUtils;
+import org.openecomp.appc.metricservice.MetricRegistry;
+import org.openecomp.appc.metricservice.MetricService;
+import org.openecomp.appc.metricservice.metric.Metric;
+import org.openecomp.appc.requesthandler.LCMStateManager;
+import org.openecomp.appc.requesthandler.RequestHandler;
+import com.att.eelf.configuration.EELFLogger;
+import com.att.eelf.configuration.EELFManager;
+import com.att.eelf.i18n.EELFResourceManager;
+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.openecomp.appc.oam.rev170303.*;
+import org.opendaylight.yang.gen.v1.org.openecomp.appc.oam.rev170303.common.header.CommonHeader;
+import org.opendaylight.yang.gen.v1.org.openecomp.appc.oam.rev170303.get.metrics.output.Metrics;
+import org.opendaylight.yang.gen.v1.org.openecomp.appc.oam.rev170303.get.metrics.output.MetricsBuilder;
+import org.opendaylight.yang.gen.v1.org.openecomp.appc.oam.rev170303.get.metrics.output.metrics.KpiValues;
+import org.opendaylight.yang.gen.v1.org.openecomp.appc.oam.rev170303.get.metrics.output.metrics.KpiValuesBuilder;
+import org.opendaylight.yang.gen.v1.org.openecomp.appc.oam.rev170303.status.Status;
+import org.opendaylight.yang.gen.v1.org.openecomp.appc.oam.rev170303.status.StatusBuilder;
+import org.opendaylight.yangtools.yang.common.RpcError;
+import org.opendaylight.yangtools.yang.common.RpcResult;
+import org.opendaylight.yangtools.yang.common.RpcResultBuilder;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.FrameworkUtil;
+import org.osgi.framework.ServiceReference;
+import org.slf4j.MDC;
+
+import java.net.InetAddress;
+import java.util.*;
+import java.util.concurrent.*;
+
+import org.openecomp.appc.oam.messageadapter.*;
+
+
+import static com.att.eelf.configuration.Configuration.*;
+
+import org.opendaylight.yangtools.yang.common.RpcResultBuilder;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.FrameworkUtil;
+import org.osgi.framework.ServiceReference;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.Properties;
+import java.util.concurrent.Executors;
+import java.util.concurrent.Future;
+
+
+public class AppcOam implements AutoCloseable, AppcOamService {
+
+ private Configuration configuration = ConfigurationFactory.getConfiguration();
+ private final EELFLogger logger = EELFManager.getInstance().getLogger(AppcOam.class);
+
+ private boolean isMetricEnabled = false;
+
+
+ private final ScheduledExecutorService scheduledExecutorService;
+
+ private volatile ScheduledFuture<?> outstandingLCMRequestMonitorSheduledFuture;
+
+
+ private MessageAdapter messageAdapter;
+
+
+ /**
+ * 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.
+ */
+ private DataBroker dataBroker;
+
+ /**
+ * ODL Notification Service that provides publish/subscribe capabilities for YANG modeled notifications.
+ */
+ private NotificationProviderService notificationService;
+
+ /**
+ * Provides a registry for Remote Procedure Call (RPC) service implementations. The RPCs are defined in YANG models.
+ */
+ private RpcProviderRegistry rpcRegistry;
+
+ /**
+ * Represents our RPC implementation registration
+ */
+ private BindingAwareBroker.RpcRegistration<AppcOamService> rpcRegistration;
+
+
+ /**
+ * The yang rpc names
+ */
+ public enum RPC {
+ start,
+ stop,
+ ;
+ }
+
+
+ /**
+ * @param dataBroker
+ * @param notificationProviderService
+ * @param rpcProviderRegistry
+ */
+ @SuppressWarnings({
+ "javadoc", "nls"
+ })
+ public AppcOam(DataBroker dataBroker, NotificationProviderService notificationProviderService,
+ RpcProviderRegistry rpcProviderRegistry) {
+
+ String appName = configuration.getProperty(Constants.PROPERTY_APPLICATION_NAME);
+ logger.info(Msg.COMPONENT_INITIALIZING, appName, "oam");
+
+ this.dataBroker = dataBroker;
+ this.notificationService = notificationProviderService;
+ this.rpcRegistry = rpcProviderRegistry;
+
+ if (this.rpcRegistry != null) {
+ rpcRegistration = rpcRegistry.addRpcImplementation(AppcOamService.class, this);
+ }
+
+ Properties properties = configuration.getProperties();
+ if (properties != null && properties.getProperty("metric.enabled") != null) {
+ isMetricEnabled = Boolean.valueOf(properties.getProperty("metric.enabled"));
+ }
+
+
+ messageAdapter = new MessageAdapter();
+ messageAdapter.init();
+
+
+ scheduledExecutorService = Executors.newSingleThreadScheduledExecutor(
+ new ThreadFactory(){
+
+ @Override
+ public Thread newThread(Runnable runnable) {
+ Bundle bundle = FrameworkUtil.getBundle(AppcOam.class);
+ return new Thread(runnable,bundle.getSymbolicName() + " scheduledExecutor");
+ }
+ }
+ );
+
+ logger.info(Msg.COMPONENT_INITIALIZED, appName, "oam");
+ }
+
+ /**
+ * Implements the close of the service
+ *
+ * @see AutoCloseable#close()
+ */
+ @SuppressWarnings("nls")
+ @Override
+ public void close() throws Exception {
+ String appName = configuration.getProperty(Constants.PROPERTY_APPLICATION_NAME);
+ logger.info(Msg.COMPONENT_TERMINATING, appName, "oam");
+ scheduledExecutorService.shutdown();
+ if (rpcRegistration != null) {
+ rpcRegistration.close();
+ }
+ logger.info(Msg.COMPONENT_TERMINATED, appName, "oam");
+ }
+
+ @Override
+ public Future<RpcResult<GetMetricsOutput>> getMetrics() {
+
+ GetMetricsOutputBuilder outputBuilder = new GetMetricsOutputBuilder();
+
+ if (!isMetricEnabled){
+ logger.error("Metric Service not enabled returning failure");
+ RpcResult<GetMetricsOutput> result = RpcResultBuilder.<GetMetricsOutput> status(false).withError(RpcError.ErrorType.APPLICATION,"Metric Service not enabled").build();
+ return Futures.immediateFuture(result);
+ }
+
+ MetricService metricService = null;
+ try {
+ metricService = getService(MetricService.class);
+ } catch (APPCException e){
+ logger.error("MetricService not found",e);
+ RpcResult<GetMetricsOutput> result = RpcResultBuilder.<GetMetricsOutput> status(false).withError(RpcError.ErrorType.APPLICATION,"Metric Service not found").build();
+ return Futures.immediateFuture(result);
+ }
+ Map<String,MetricRegistry> allMetricRegitry = metricService.getAllRegistry();
+
+ if(allMetricRegitry == null || allMetricRegitry.isEmpty()){
+ logger.error("No metrics registered returning failure");
+ RpcResult<GetMetricsOutput> result = RpcResultBuilder.<GetMetricsOutput> status(false).withError(RpcError.ErrorType.APPLICATION,"No metrics Registered").build();
+ return Futures.immediateFuture(result);
+ }
+ List<Metrics> 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<KpiValues> kpiList = new ArrayList<>();
+ Map<String, String> metricsOutput = metric.getMetricsOutput();
+ for (Map.Entry<String, String> 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());
+ }
+ }
+ }
+ outputBuilder.setMetrics(metricsList);
+ RpcResult<GetMetricsOutput> result = RpcResultBuilder.<GetMetricsOutput> status(true).withResult(outputBuilder.build()).build();
+ return Futures.immediateFuture(result);
+ }
+
+ @Override
+ public Future<RpcResult<StopOutput>> stop(StopInput stopInput){
+ logger.debug("Input received : " + stopInput);
+ final Date startTime = new Date();
+ Status status = this.buildStatus(OAMCommandStatus.ACCEPTED);
+ final CommonHeader commonHeader = stopInput.getCommonHeader();
+
+ try {
+ setInitialLogProperties(commonHeader,RPC.stop);
+
+ //Close the gate so that no more new LCM request will be excepted.
+ LCMStateManager lcmStateManager = getService(LCMStateManager.class);
+ lcmStateManager.disableLCMOperations();
+ //Begin monitoring outstanding LCM request
+ scheduleOutstandingLCMRequestMonitor(commonHeader,startTime);
+ } catch(Throwable t) {
+ status = unexpectedOAMError(t,RPC.stop);
+ }
+ finally {
+ LoggingUtils.auditWarn(startTime.toInstant(),
+ new Date(System.currentTimeMillis()).toInstant(),
+ String.valueOf(status.getCode()),
+ status.getMessage(),
+ this.getClass().getCanonicalName(),
+ Msg.OAM_OPERATION_STOPPING,
+ getAppcName()
+ );
+ this.clearRequestLogProperties();
+ }
+
+ StopOutputBuilder stopOutputBuilder = new StopOutputBuilder();
+ stopOutputBuilder.setStatus(status);
+ stopOutputBuilder.setCommonHeader(commonHeader);
+ StopOutput stopOutput = stopOutputBuilder.build();
+ return RpcResultBuilder.success(stopOutput).buildFuture();
+ }
+
+ @Override
+ public Future<RpcResult<StartOutput>> start(StartInput startInput){
+ logger.debug("Input received : " + startInput);
+ final Date startTime = new Date();
+ Status status = this.buildStatus(OAMCommandStatus.ACCEPTED);
+ final CommonHeader commonHeader = startInput.getCommonHeader();
+
+ try {
+
+
+ setInitialLogProperties(commonHeader,RPC.start);
+
+ this.scheduleStartingAPPC(commonHeader,startTime);
+ } catch(Throwable t) {
+ status = unexpectedOAMError(t,RPC.start);
+ }
+ finally {
+ LoggingUtils.auditWarn(startTime.toInstant(),
+ new Date(System.currentTimeMillis()).toInstant(),
+ String.valueOf(status.getCode()),
+ status.getMessage(),
+ this.getClass().getCanonicalName(),
+ Msg.OAM_OPERATION_STARTING,
+ getAppcName()
+ );
+ this.clearRequestLogProperties();
+ }
+
+ StartOutputBuilder startOutputBuilder = new StartOutputBuilder();
+ startOutputBuilder.setStatus(status);
+ startOutputBuilder.setCommonHeader(commonHeader);
+ StartOutput startOutput = startOutputBuilder.build();
+ return RpcResultBuilder.success(startOutput).buildFuture();
+ }
+
+ private <T> T getService(Class<T> _class) throws APPCException {
+ BundleContext bctx = FrameworkUtil.getBundle(_class).getBundleContext();
+ ServiceReference sref = bctx.getServiceReference(_class.getName());
+ if (sref != null) {
+ if(logger.isTraceEnabled()) {
+ logger.debug("Using the BundleContext to fetched the service reference for " + _class.getName());
+
+ }
+ return (T) bctx.getService(sref);
+ } else {
+ throw new APPCException("Using the BundleContext failed to to fetch service reference for " + _class.getName());
+ }
+ }
+
+ private Status buildStatus(OAMCommandStatus osmCommandStatus){
+ StatusBuilder status = new StatusBuilder();
+ status.setCode(osmCommandStatus.getResponseCode());
+ status.setMessage(osmCommandStatus.getResponseMessage());
+ return status.build();
+ }
+
+ private Status buildStatus(OAMCommandStatus osmCommandStatus,Params params){
+ StatusBuilder status = new StatusBuilder();
+ status.setCode(osmCommandStatus.getResponseCode());
+ status.setMessage(osmCommandStatus.getFormattedMessage(params));
+ return status.build();
+ }
+
+
+
+ private void clearRequestLogProperties() {
+ try {
+ MDC.remove(MDC_KEY_REQUEST_ID);
+ MDC.remove(MDC_SERVICE_INSTANCE_ID);
+ MDC.remove(MDC_SERVICE_NAME);
+ MDC.remove(LoggingConstants.MDCKeys.PARTNER_NAME);
+ MDC.remove(LoggingConstants.MDCKeys.TARGET_VIRTUAL_ENTITY);
+ } catch (Exception e) {
+
+ }
+ }
+
+ private void setInitialLogProperties(CommonHeader commonHeader,RPC action) {
+
+ try {
+ 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
+ try {
+ MDC.put(MDC_SERVER_FQDN, InetAddress.getLocalHost().getCanonicalHostName()); //Don't change it to a .getHostName() again please. It's wrong!
+ MDC.put(MDC_SERVER_IP_ADDRESS, InetAddress.getLocalHost().getHostAddress());
+ MDC.put(LoggingConstants.MDCKeys.SERVER_NAME, InetAddress.getLocalHost().getHostName());
+ MDC.put(MDC_SERVICE_NAME, action.name());
+ } catch (Exception e) {
+ logger.debug("MDC constant error",e);
+ }
+ } catch (RuntimeException e) {
+ //ignore
+ }
+ }
+
+
+ private void storeErrorMessageToLog(Status status, String additionalMessage) {
+ LoggingUtils.logErrorMessage(
+ String.valueOf(status.getCode()),
+ status.getMessage(),
+ LoggingConstants.TargetNames.APPC,
+ LoggingConstants.TargetNames.APPC_OAM_PROVIDER,
+ additionalMessage,
+ this.getClass().getCanonicalName());
+ }
+
+ private String getAppcName(){
+ return configuration.getProperty(Constants.PROPERTY_APPLICATION_NAME);
+ }
+
+ private Status unexpectedOAMError(Throwable t,RPC action){
+ final String appName = getAppcName();
+
+ String exceptionMessage = t.getMessage() != null ? t.getMessage() : t.toString();
+
+ String errorMessage = EELFResourceManager.format(Msg.OAM_OPERATION_EXCEPTION, t, appName, t.getClass().getSimpleName(), action.name(), exceptionMessage);
+
+ Params params = new Params().addParam("errorMsg", exceptionMessage);
+ Status status = buildStatus(
+ OAMCommandStatus.UNEXPECTED_ERROR,
+ params
+ );
+
+ storeErrorMessageToLog(status,errorMessage);
+ return status;
+ }
+
+
+ private int getInprogressLCMRequestCount() throws APPCException {
+ RequestHandler requestHandler = getService(RequestHandler.class);
+
+ if(requestHandler == null) {
+ return 0;
+ }
+
+ int inprogressRequestCount = requestHandler.getInprogressRequestCount();
+ return inprogressRequestCount;
+ }
+
+
+
+ private void scheduleOutstandingLCMRequestMonitor(final CommonHeader commonHeader,final Date startTime){
+
+
+ class MyCommand implements Runnable{
+
+ public ScheduledFuture<?> myScheduledFuture = null;
+
+ @Override
+ public void run() {
+ try {
+ setInitialLogProperties(commonHeader, RPC.stop);
+
+
+ logDebug("Executing stopping task ");
+
+ ScheduledFuture<?> currentScheduledFuture = AppcOam.this.outstandingLCMRequestMonitorSheduledFuture;
+
+ //cancel myself if I am not the current outstandingLCMRequestMonitor
+ if(currentScheduledFuture != myScheduledFuture){
+ myScheduledFuture.cancel(false);
+ return;
+ }
+
+ Status status = buildStatus(OAMCommandStatus.SUCCESS);
+
+
+ try {
+
+ //log status and return if there are still LCM request in progress
+ int inprogressRequestCount = getInprogressLCMRequestCount();
+ if (inprogressRequestCount > 0) {
+ logDebug("The application '%s' has '%s' outstanding LCM request to complete before coming to a complete stop. ",
+ getAppcName(),
+ inprogressRequestCount
+ );
+ return;
+ }
+
+ } catch (Throwable t) {
+ status = unexpectedOAMError(t, RPC.stop);
+ myScheduledFuture.cancel(false);
+ }
+
+ try {
+ OAMContext oamContext = new OAMContext();
+ oamContext.setRpcName(RPC.stop);
+ oamContext.setCommonHeader(commonHeader);
+ oamContext.setStatus(status);
+ messageAdapter.post(oamContext);
+ } catch(Throwable t) {
+ status = unexpectedOAMError(t,RPC.stop);
+ }
+
+ LoggingUtils.auditWarn(startTime.toInstant(),
+ new Date(System.currentTimeMillis()).toInstant(),
+ String.valueOf(status.getCode()),
+ status.getMessage(),
+ this.getClass().getCanonicalName(),
+ Msg.OAM_OPERATION_STOPPED,
+ getAppcName()
+ );
+ myScheduledFuture.cancel(false);
+
+ } finally {
+ clearRequestLogProperties();
+ }
+ }
+ };
+
+ MyCommand command = new MyCommand();
+
+ long initialDelay = 10000;
+ long delay = initialDelay;
+
+
+ command.myScheduledFuture = scheduledExecutorService.scheduleWithFixedDelay(
+ command,
+ initialDelay,
+ delay,
+ TimeUnit.MILLISECONDS
+ );
+ this.outstandingLCMRequestMonitorSheduledFuture = command.myScheduledFuture;
+ }
+
+
+
+
+ private void scheduleStartingAPPC(final CommonHeader commonHeader,final Date startTime){
+
+
+ class MyCommand implements Runnable{
+
+
+ @Override
+ public void run() {
+ try {
+ setInitialLogProperties(commonHeader, RPC.start);
+
+ logDebug("Executing starting task ");
+
+ Status status = buildStatus(OAMCommandStatus.SUCCESS);
+
+ try {
+ LCMStateManager lcmStateManager = getService(LCMStateManager.class);
+ lcmStateManager.enableLCMOperations();
+ //cancel the current outstandingLCMRequestMonitor
+ outstandingLCMRequestMonitorSheduledFuture = null;
+ } catch(Throwable t) {
+ status = unexpectedOAMError(t,RPC.start);
+ }
+
+ try {
+ OAMContext oamContext = new OAMContext();
+ oamContext.setRpcName(RPC.start);
+ oamContext.setCommonHeader(commonHeader);
+ oamContext.setStatus(status);
+ messageAdapter.post(oamContext);
+ } catch(Throwable t) {
+ status = unexpectedOAMError(t,RPC.start);
+ }
+
+ LoggingUtils.auditWarn(startTime.toInstant(),
+ new Date(System.currentTimeMillis()).toInstant(),
+ String.valueOf(status.getCode()),
+ status.getMessage(),
+ this.getClass().getCanonicalName(),
+ Msg.OAM_OPERATION_STARTED,
+ getAppcName()
+ );
+ } finally {
+ clearRequestLogProperties();
+ }
+ }
+ };
+
+ MyCommand command = new MyCommand();
+ long initialDelay = 1000;
+
+ scheduledExecutorService.schedule(
+ command,
+ initialDelay,
+ TimeUnit.MILLISECONDS
+ );
+ }
+
+
+ private 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/OAMCommandStatus.java b/appc-oam/appc-oam-bundle/src/main/java/org/openecomp/appc/oam/OAMCommandStatus.java
new file mode 100644
index 0000000..aebfaf1
--- /dev/null
+++ b/appc-oam/appc-oam-bundle/src/main/java/org/openecomp/appc/oam/OAMCommandStatus.java
@@ -0,0 +1,87 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * openECOMP : APP-C
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights
+ * reserved.
+ * ================================================================================
+ * 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.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.openecomp.appc.oam;
+
+
+import org.openecomp.appc.executor.objects.Params;
+import org.openecomp.appc.util.MessageFormatter;
+
+import java.util.Map;
+
+public enum OAMCommandStatus {
+
+ ACCEPTED(100,"ACCEPTED - request accepted"),
+
+ //ERROR(2xx) – request can’t be handled due to some technical error
+ UNEXPECTED_ERROR(200,"UNEXPECTED ERROR - ${errorMsg}"),
+
+ SUCCESS(400,"SUCCESS - request has been processed successfully"),
+ ;
+
+
+ public static final String errorDgMessageParamName = "errorDgMessage";
+
+ 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;
+ }
+
+
+ /**
+ *
+ * @return messageTemplate
+ */
+
+
+ public String getFormattedMessage(Params params){
+ Map<String,Object> paramsMap = params != null ? params.getParams() : null;
+ return MessageFormatter.format(getResponseMessage(),paramsMap);
+
+ }
+
+ public String getFormattedMessageWithCode(Params params){
+ return getResponseCode()+"-" + getFormattedMessage(params);
+ }
+
+ @Override
+ public String toString() {
+ return "OAMCommandStatus{" +
+ "responseCode=" + responseCode +
+ ", responseMessage='" + 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
new file mode 100644
index 0000000..4895e23
--- /dev/null
+++ b/appc-oam/appc-oam-bundle/src/main/java/org/openecomp/appc/oam/messageadapter/Converter.java
@@ -0,0 +1,133 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * openECOMP : APP-C
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights
+ * reserved.
+ * ================================================================================
+ * 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.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.openecomp.appc.oam.messageadapter;
+
+import org.openecomp.appc.oam.AppcOam;
+import com.att.eelf.configuration.EELFLogger;
+import com.att.eelf.configuration.EELFManager;
+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.openecomp.appc.oam.rev170303.*;
+import org.opendaylight.yang.gen.v1.org.openecomp.appc.oam.rev170303.common.header.CommonHeader;
+import org.opendaylight.yang.gen.v1.org.openecomp.appc.oam.rev170303.status.Status;
+import org.opendaylight.yangtools.concepts.Builder;
+import org.opendaylight.yangtools.yang.binding.DataContainer;
+
+
+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);
+ private static final EELFLogger logger = EELFManager.getInstance().getLogger(Converter.class);
+ static {
+ isoFormatter.setTimeZone(TimeZone.getTimeZone("UTC"));
+ }
+
+
+ private static Builder<?> convAsyncResponseToBuilder1(AppcOam.RPC rpcName, CommonHeader commonHeader, Status status) {
+ Builder<?> outObj = null;
+ 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 stop:
+ outObj = new StopOutputBuilder();
+ ((StopOutputBuilder)outObj).setCommonHeader(commonHeader);
+ ((StopOutputBuilder)outObj).setStatus(status);
+ return outObj;
+
+ case start:
+ outObj = new StartOutputBuilder();
+ ((StartOutputBuilder)outObj).setCommonHeader(commonHeader);
+ ((StartOutputBuilder)outObj).setStatus(status);
+ return outObj;
+ default:
+ throw new IllegalArgumentException(rpcName+" action is not supported");
+ }
+ }
+
+ public 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 {
+ @JsonIgnore
+ abstract Class<? extends DataContainer> getImplementedInterface(); // to be removed during serialization
+
+ @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
new file mode 100644
index 0000000..351984d
--- /dev/null
+++ b/appc-oam/appc-oam-bundle/src/main/java/org/openecomp/appc/oam/messageadapter/DmaapOutgoingMessage.java
@@ -0,0 +1,134 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * openECOMP : APP-C
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights
+ * reserved.
+ * ================================================================================
+ * 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.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.openecomp.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.openecomp.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
new file mode 100644
index 0000000..2ba76d4
--- /dev/null
+++ b/appc-oam/appc-oam-bundle/src/main/java/org/openecomp/appc/oam/messageadapter/MessageAdapter.java
@@ -0,0 +1,131 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * openECOMP : APP-C
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights
+ * reserved.
+ * ================================================================================
+ * 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.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.openecomp.appc.oam.messageadapter;
+
+import org.openecomp.appc.adapter.message.MessageAdapterFactory;
+import org.openecomp.appc.adapter.message.Producer;
+import org.openecomp.appc.configuration.Configuration;
+import org.openecomp.appc.configuration.ConfigurationFactory;
+import org.openecomp.appc.listener.impl.EventHandlerImpl;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.FrameworkUtil;
+import org.osgi.framework.ServiceReference;
+
+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 java.util.HashSet;
+import java.util.Properties;
+
+public class MessageAdapter {
+
+ private Producer producer;
+ private String partition ;
+ private Configuration configuration;
+ private HashSet<String> pool;
+ private String writeTopic;
+ private String apiKey;
+ private String apiSecret;
+
+ private static final EELFLogger logger = EELFManager.getInstance().getLogger(MessageAdapter.class);
+
+ /**
+ * Initialize producer client to post messages using configuration properties
+ */
+ public void init(){
+ this.producer = getProducer();
+ }
+
+ private Producer getProducer() {
+ configuration = ConfigurationFactory.getConfiguration();
+ Properties properties=configuration.getProperties();
+ updateProperties(properties);
+ Producer localProducer = null;
+
+ BundleContext ctx = FrameworkUtil.getBundle(EventHandlerImpl.class).getBundleContext();
+ if (ctx != null) {
+ ServiceReference svcRef = ctx.getServiceReference(MessageAdapterFactory.class.getName());
+ if (svcRef != null) {
+ 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;
+ }
+ }
+ }
+ }
+
+ return localProducer;
+ }
+
+ private void updateProperties(Properties props) {
+ if (logger.isTraceEnabled()) {
+ logger.trace("Entering to updateProperties with Properties = "+ ObjectUtils.toString(props));
+ }
+ pool = new HashSet<>();
+ if (props != null) {
+ writeTopic = props.getProperty("appc.OAM.topic.write");
+ apiKey = props.getProperty("appc.OAM.client.key");
+ apiSecret = props.getProperty("appc.OAM.client.secret");
+ String hostnames = props.getProperty("appc.OAM.poolMembers");
+ if (hostnames != null && !hostnames.isEmpty()) {
+ for (String name : hostnames.split(",")) {
+ pool.add(name);
+ }
+ }
+ }
+ }
+
+ /**
+ * 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).
+ * @return True if message is postes successfully else False
+ */
+ public boolean post(OAMContext oamContext){
+ boolean success;
+ if (logger.isTraceEnabled()) {
+ logger.trace("Entering to post with AsyncResponse = " + ObjectUtils.toString(oamContext));
+ }
+
+ String jsonMessage;
+ try {
+ jsonMessage = Converter.convAsyncResponseToUebOutgoingMessageJsonString(oamContext);
+ if (logger.isDebugEnabled()) {
+ logger.debug("UEB Response = " + jsonMessage);
+ }
+ success = producer.post(this.partition, jsonMessage);
+ } catch (JsonProcessingException e1) {
+ logger.error("Error generating Jason from UEB message "+ e1.getMessage());
+ success= false;
+ }catch (Exception e){
+ logger.error("Error sending message to UEB "+e.getMessage());
+ success= false;
+ }
+ if (logger.isTraceEnabled()) {
+ logger.trace("Exiting from post with (success = "+ ObjectUtils.toString(success)+")");
+ }
+ return success;
+ }
+}
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
new file mode 100644
index 0000000..68ea95b
--- /dev/null
+++ b/appc-oam/appc-oam-bundle/src/main/java/org/openecomp/appc/oam/messageadapter/OAMContext.java
@@ -0,0 +1,72 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * openECOMP : APP-C
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights
+ * reserved.
+ * ================================================================================
+ * 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.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.openecomp.appc.oam.messageadapter;
+
+
+
+
+import org.opendaylight.yang.gen.v1.org.openecomp.appc.oam.rev170303.*;
+import org.opendaylight.yang.gen.v1.org.openecomp.appc.oam.rev170303.common.header.CommonHeader;
+import org.opendaylight.yang.gen.v1.org.openecomp.appc.oam.rev170303.common.header.CommonHeaderBuilder;
+import org.opendaylight.yang.gen.v1.org.openecomp.appc.oam.rev170303.status.Status;import org.openecomp.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/resources/OSGI-INF/blueprint/blueprint.xml b/appc-oam/appc-oam-bundle/src/main/resources/OSGI-INF/blueprint/blueprint.xml
new file mode 100644
index 0000000..6073488
--- /dev/null
+++ b/appc-oam/appc-oam-bundle/src/main/resources/OSGI-INF/blueprint/blueprint.xml
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ============LICENSE_START=======================================================
+ openECOMP : APP-C
+ ================================================================================
+ Copyright (C) 2017 AT&T Intellectual Property. All rights
+ reserved.
+ ================================================================================
+ 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.
+ ============LICENSE_END=========================================================
+ -->
+
+<!--
+ Starter Blueprint Camel Definition appc-aai-adapter-blueprint
+-->
+<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://www.osgi.org/xmlns/blueprint/v1.0.0 http://www.osgi.org/xmlns/blueprint/v1.0.0/blueprint.xsd">
+
+</blueprint>
diff --git a/appc-oam/appc-oam-bundle/src/main/resources/initial/appc-oam.xml b/appc-oam/appc-oam-bundle/src/main/resources/initial/appc-oam.xml
new file mode 100644
index 0000000..6b4cd3c
--- /dev/null
+++ b/appc-oam/appc-oam-bundle/src/main/resources/initial/appc-oam.xml
@@ -0,0 +1,77 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ============LICENSE_START=======================================================
+ openECOMP : APP-C
+ ================================================================================
+ Copyright (C) 2017 AT&T Intellectual Property. All rights
+ reserved.
+ ================================================================================
+ 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.
+ ============LICENSE_END=========================================================
+ -->
+
+<!-- vi: set et smarttab sw=4 tabstop=4: -->
+<snapshot>
+ <configuration>
+ <data xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
+ <modules xmlns="urn:opendaylight:params:xml:ns:yang:controller:config">
+ <module>
+
+ <!-- This xmlns:prefix should match the namespace in the *-oam-impl.yang
+ file The prefix: inside type should match the prefix of the yang file. -->
+ <type xmlns:prefix="org:openecomp:appc:oam:impl">
+ prefix:appc-oam-impl
+ </type>
+ <name>appc-oam-impl</name>
+
+ <!-- The following sections contain bindings to services defined in
+ the *-oam-impl yang file. For example the rpc-registry is required because
+ we have a dependency (or augmentation) named "rpc-registry" and which binds
+ to the md-sa-binding-registry. If you remove those dependencies from the
+ yang file then you can remove them from here. -->
+ <rpc-registry>
+ <type
+ xmlns:binding="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding">binding:binding-rpc-registry</type>
+ <name>binding-rpc-broker</name>
+ </rpc-registry>
+
+ <data-broker>
+ <type
+ xmlns:binding="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding">binding:binding-async-data-broker</type>
+ <name>binding-data-broker</name>
+ </data-broker>
+
+ <notification-service>
+ <type
+ xmlns:binding="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding">
+ binding:binding-notification-service
+ </type>
+ <name>binding-notification-broker</name>
+ </notification-service>
+ </module>
+
+ </modules>
+ </data>
+
+ </configuration>
+
+ <!-- Required capabilities are basically a listing of all modules that need
+ to be imported before our service can be resolved. Capabilities for dependencies
+ defined above are implied which is why we do not have define a required capability
+ for the data broker, for example. -->
+ <required-capabilities>
+ <capability>org:openecomp:appc:oam:impl?module=appc-oam-impl&revision=2017-03-03
+ </capability>
+ </required-capabilities>
+
+</snapshot>
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
new file mode 100644
index 0000000..b22ced0
--- /dev/null
+++ b/appc-oam/appc-oam-bundle/src/main/resources/org/openecomp/appc/default.properties
@@ -0,0 +1,49 @@
+###
+# ============LICENSE_START=======================================================
+# openECOMP : APP-C
+# ================================================================================
+# Copyright (C) 2017 AT&T Intellectual Property. All rights
+# reserved.
+# ================================================================================
+# 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.
+# ============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.openecomp.appc.bootstrap.path=/opt/openecomp/appc/data/properties,${user.home},.
+org.openecomp.appc.bootstrap.file=appc.properties
+
+appc.application.name=APPC
+
+#
+# The path to search for logging configuration document, and the name of the document
+#
+org.openecomp.appc.logging.path=${user.home},etc,../etc,.
+org.openecomp.appc.logging.file=logback.xml
+
+
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
new file mode 100644
index 0000000..8d47c6c
--- /dev/null
+++ b/appc-oam/appc-oam-bundle/src/main/resources/org/openecomp/appc/logback.xml
@@ -0,0 +1,284 @@
+<!--
+ ============LICENSE_START=======================================================
+ openECOMP : APP-C
+ ================================================================================
+ Copyright (C) 2017 AT&T Intellectual Property. All rights
+ reserved.
+ ================================================================================
+ 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.
+ ============LICENSE_END=========================================================
+ -->
+
+<configuration scan="true" scanPeriod="3 seconds" debug="true">
+ <!--<jmxConfigurator /> -->
+ <property name="logDirectory" value="logs" />
+ <property name="debugLogDirectory" value="debug-logs" />
+ <!-- Example evaluator filter applied against console appender -->
+ <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
+ <encoder>
+ <pattern>%d{MM/dd-HH:mm:ss.SSS} [%-16thread] %.-5level
+ %-36.36logger - %msg%n</pattern>
+ </encoder>
+ </appender>
+
+ <!-- ============================================================================ -->
+ <!-- CDP Appenders -->
+ <!-- ============================================================================ -->
+
+ <!-- The CDPAppender is used to record events to the general CDP application
+ log. This is the log file used by default as the application root log, if
+ no other log is defined or the application creates specialized loggers of
+ the form com.att.cdp.x.y.z where the name occupied by the "x" is NOT security,
+ perf, server, coordinator, gui, or policy. These are defined as specialization
+ loggers for various business purposes. -->
+ <appender name="CDP"
+ class="ch.qos.logback.core.rolling.RollingFileAppender">
+ <file>${logDirectory}/cdp.log</file>
+ <rollingPolicy
+ class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy">
+ <fileNamePattern>${logDirectory}/cdp.%i.log.zip
+ </fileNamePattern>
+ <minIndex>1</minIndex>
+ <maxIndex>9</maxIndex>
+ </rollingPolicy>
+ <triggeringPolicy
+ class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
+ <maxFileSize>5MB</maxFileSize>
+ </triggeringPolicy>
+ <encoder>
+ <!-- <pattern>"%d{HH:mm:ss.SSS} [%thread] %-5level %logger{1024} -
+ %msg%n"</pattern> -->
+ <pattern>%d{MM/dd-HH:mm:ss.SSS} [%-16thread] %.-5level
+ %-36.36logger [%X{User} %X{RemoteHost} %X{RequestId} %X{Method}
+ %X{Path}] - %msg%n</pattern>
+ </encoder>
+ </appender>
+ <appender name="asyncCDP" class="ch.qos.logback.classic.AsyncAppender">
+ <queueSize>256</queueSize>
+ <appender-ref ref="CDP" />
+ </appender>
+
+ <!-- CDP Security Appender. This appender is used to record security events
+ to the security log file. Security events are separate from other loggers
+ in CDP so that security log records can be captured and managed in a secure
+ way separate from the other logs. This appender is set to never discard any
+ events. -->
+ <appender name="CDPSecurity"
+ class="ch.qos.logback.core.rolling.RollingFileAppender">
+ <file>${logDirectory}/cdp-security.log</file>
+ <rollingPolicy
+ class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy">
+ <fileNamePattern>${logDirectory}/cdp-security.%i.log.zip
+ </fileNamePattern>
+ <minIndex>1</minIndex>
+ <maxIndex>9</maxIndex>
+ </rollingPolicy>
+ <triggeringPolicy
+ class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
+ <maxFileSize>5MB</maxFileSize>
+ </triggeringPolicy>
+ <encoder>
+ <!-- <pattern>"%d{HH:mm:ss.SSS} [%thread] %-5level %logger{1024} -
+ %msg%n"</pattern> -->
+ <pattern>%d{MM/dd-HH:mm:ss.SSS} [%-16thread] %.-5level
+ %-36.36logger [%X{User} %X{RemoteHost} %X{RequestId} %X{Method}
+ %X{Path}] - %msg%n</pattern>
+ </encoder>
+ </appender>
+ <appender name="asyncCDPSecurity" class="ch.qos.logback.classic.AsyncAppender">
+ <queueSize>256</queueSize>
+ <discardingThreshold>0</discardingThreshold>
+ <appender-ref ref="CDPSecurity" />
+ </appender>
+
+ <!-- CDP Performance Appender. This appender is used to record performance
+ records. -->
+ <appender name="CDPPerformance"
+ class="ch.qos.logback.core.rolling.RollingFileAppender">
+ <file>${logDirectory}/cdp-performance.log</file>
+ <rollingPolicy
+ class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy">
+ <fileNamePattern>${logDirectory}/cdp-performance.%i.log.zip
+ </fileNamePattern>
+ <minIndex>1</minIndex>
+ <maxIndex>9</maxIndex>
+ </rollingPolicy>
+ <triggeringPolicy
+ class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
+ <maxFileSize>5MB</maxFileSize>
+ </triggeringPolicy>
+ <encoder>
+ <outputPatternAsHeader>true</outputPatternAsHeader>
+ <pattern>%d{MM/dd-HH:mm:ss.SSS} [%-16thread] %.-5level
+ %-36.36logger [%X{User} %X{RemoteHost} %X{RequestId} %X{Method}
+ %X{Path}] - %msg%n</pattern>
+ </encoder>
+ </appender>
+ <appender name="asyncCDPPerformance" class="ch.qos.logback.classic.AsyncAppender">
+ <queueSize>256</queueSize>
+ <appender-ref ref="CDPPerformance" />
+ </appender>
+
+ <!-- CDP Server Appender. This appender is used to record Server related
+ logging events. The Server logger and appender are specializations of the
+ CDP application root logger and appender. This can be used to segregate Server
+ events from other components, or it can be eliminated to record these events
+ as part of the application root log. -->
+ <appender name="CDPServer"
+ class="ch.qos.logback.core.rolling.RollingFileAppender">
+ <file>${logDirectory}/cdp-server.log</file>
+ <rollingPolicy
+ class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy">
+ <fileNamePattern>${logDirectory}/cdp-server.%i.log.zip
+ </fileNamePattern>
+ <minIndex>1</minIndex>
+ <maxIndex>9</maxIndex>
+ </rollingPolicy>
+ <triggeringPolicy
+ class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
+ <maxFileSize>5MB</maxFileSize>
+ </triggeringPolicy>
+ <encoder>
+ <!-- <pattern>"%d{HH:mm:ss.SSS} [%thread] %-5level %logger{1024} -
+ %msg%n"</pattern> -->
+ <pattern>%d{MM/dd-HH:mm:ss.SSS} [%-16thread] %.-5level
+ %-36.36logger [%X{User} %X{RemoteHost} %X{RequestId} %X{Method}
+ %X{Path}] - %msg%n</pattern>
+ </encoder>
+ </appender>
+ <appender name="asyncCDPServer" class="ch.qos.logback.classic.AsyncAppender">
+ <queueSize>256</queueSize>
+ <appender-ref ref="CDPServer" />
+ </appender>
+
+ <!-- CDP Coordinator Appender. This appender is used to record Coordinator
+ related logging events. The Coordinator logger and appender are specializations
+ of the CDP application root logger and appender. This can be used to segregate
+ Coordinator events from other components, or it can be eliminated to record
+ these events as part of the application root log. -->
+ <appender name="CDPCoordinator"
+ class="ch.qos.logback.core.rolling.RollingFileAppender">
+ <file>${logDirectory}/cdp-coordinator.log</file>
+ <rollingPolicy
+ class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy">
+ <fileNamePattern>${logDirectory}/cdp-coordinator.%i.log.zip
+ </fileNamePattern>
+ <minIndex>1</minIndex>
+ <maxIndex>9</maxIndex>
+ </rollingPolicy>
+ <triggeringPolicy
+ class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
+ <maxFileSize>5MB</maxFileSize>
+ </triggeringPolicy>
+ <encoder>
+ <!-- <pattern>"%d{HH:mm:ss.SSS} [%thread] %-5level %logger{1024} -
+ %msg%n"</pattern> -->
+ <pattern>%d{MM/dd-HH:mm:ss.SSS} [%-16thread] %.-5level
+ %-36.36logger - %msg%n</pattern>
+ </encoder>
+ </appender>
+ <appender name="asyncCDPCoordinator" class="ch.qos.logback.classic.AsyncAppender">
+ <queueSize>256</queueSize>
+ <appender-ref ref="CDPCoordinator" />
+ </appender>
+
+ <!-- CDP Policy Appender. This appender is used to record Policy engine
+ related logging events. The Policy logger and appender are specializations
+ of the CDP application root logger and appender. This can be used to segregate
+ Policy engine events from other components, or it can be eliminated to record
+ these events as part of the application root log. -->
+ <appender name="CDPPolicy"
+ class="ch.qos.logback.core.rolling.RollingFileAppender">
+ <file>${logDirectory}/cdp-policy.log</file>
+ <rollingPolicy
+ class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy">
+ <fileNamePattern>${logDirectory}/cdp-policy.%i.log.zip
+ </fileNamePattern>
+ <minIndex>1</minIndex>
+ <maxIndex>9</maxIndex>
+ </rollingPolicy>
+ <triggeringPolicy
+ class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
+ <maxFileSize>5MB</maxFileSize>
+ </triggeringPolicy>
+ <encoder>
+ <!-- <pattern>"%d{HH:mm:ss.SSS} [%thread] %-5level %logger{1024} -
+ %msg%n"</pattern> -->
+ <pattern>%d{MM/dd-HH:mm:ss.SSS} [%-16thread] %.-5level
+ %-36.36logger - %msg%n</pattern>
+ </encoder>
+ </appender>
+ <appender name="asyncCDPPolicy" class="ch.qos.logback.classic.AsyncAppender">
+ <queueSize>256</queueSize>
+ <appender-ref ref="CDPPolicy" />
+ </appender>
+ <appender name="CommandExecutor"
+ class="ch.qos.logback.core.rolling.RollingFileAppender">
+ <file>${debugLogDirectory}/appc-debug.log</file>
+ <rollingPolicy
+ class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy">
+ <fileNamePattern>${logDirectory}/command-executor.%i.log.zip
+ </fileNamePattern>
+ <minIndex>1</minIndex>
+ <maxIndex>9</maxIndex>
+ </rollingPolicy>
+ <triggeringPolicy
+ class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
+ <maxFileSize>5MB</maxFileSize>
+ </triggeringPolicy>
+ <encoder>
+ <!--<Pattern>
+ %d{yyyy-MM-dd'T'HH:mm:ss.SSSZ}|%X{RequestID}|%X{ServiceInstanceID}|%thread|%X{ServerName}|%X{ServiceName}|%X{UUID}|%-5.5p|%X{Severity}|%X{ServerIPAddress}|%X{Server}|%X{IPAddress}|[%c{3}]|%X{Timer}| - %msg%n
+ </Pattern>-->
+ <Pattern>
+ %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
+ </Pattern>
+ </encoder>
+ </appender>
+
+ <logger name="org.openecomp.appc" level="DEBUG" additivity="false">
+ <appender-ref ref="CommandExecutor" />
+ </logger>
+
+ <!-- ============================================================================ -->
+ <!-- CDP loggers -->
+ <!-- ============================================================================ -->
+ <logger name="com.att.cdp" level="info" additivity="false">
+ <appender-ref ref="asyncCDP" />
+ </logger>
+ <logger name="com.att.cdp.security" level="info" additivity="false">
+ <appender-ref ref="asyncCDPSecurity" />
+ </logger>
+ <logger name="com.att.cdp.perf" level="info" additivity="false">
+ <appender-ref ref="asyncCDPPerformance" />
+ </logger>
+ <logger name="com.att.cdp.server" level="debug" additivity="false">
+ <appender-ref ref="asyncCDPServer" />
+ </logger>
+ <logger name="com.att.cdp.coordinator" level="info" additivity="false">
+ <appender-ref ref="asyncCDPCoordinator" />
+ </logger>
+ <logger name="com.att.cdp.policy" level="info" additivity="false">
+ <appender-ref ref="asyncCDPPolicy" />
+ </logger>
+
+ <!-- The OpenStack connector logger -->
+ <logger name="os" level="debug" additivity="false">
+ <appender-ref ref="asyncCDPServer" />
+ </logger>
+
+ <root level="WARN">
+ <appender-ref ref="STDOUT" />
+ </root>
+
+</configuration>
diff --git a/appc-oam/appc-oam-bundle/src/main/resources/org/openecomp/appc/org.ops4j.pax.logging.cfg b/appc-oam/appc-oam-bundle/src/main/resources/org/openecomp/appc/org.ops4j.pax.logging.cfg
new file mode 100644
index 0000000..be58632
--- /dev/null
+++ b/appc-oam/appc-oam-bundle/src/main/resources/org/openecomp/appc/org.ops4j.pax.logging.cfg
@@ -0,0 +1,144 @@
+ ################################################################################
+ #
+ # Licensed to the Apache Software Foundation (ASF) under one or more
+ # contributor license agreements. See the NOTICE file distributed with
+ # this work for additional information regarding copyright ownership.
+ # The ASF licenses this file to You 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,
+ # WITH WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ # See the License for the specific language governing permissions and
+ # limitations under the License.
+ #
+ ################################################################################
+
+ # Root
+ #log4j.rootLogger=TRACE, osgi:VmLogAppender
+ log4j.rootLogger=TRACE, out, sift, osgi:*
+ log4j.throwableRenderer=org.apache.log4j.OsgiThrowableRenderer
+
+ # CONSOLE appender not used by default
+ log4j.appender.stdout=org.apache.log4j.ConsoleAppender
+ log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
+ log4j.appender.stdout.layout.ConversionPattern=%d{ISO8601} | %-5.5p | %-16.16t | %-32.32c{1} | %X{bundle.id} - %X{bundle.name} - %X{bundle.version} | %m%n
+
+ # Async appender forwarding to file appender
+ log4j.appender.async=org.apache.log4j.AsyncAppender
+ log4j.appender.async.appenders=out
+
+ # Karaf appenders
+ # File appender
+ log4j.appender.out=org.apache.log4j.RollingFileAppender
+ log4j.appender.out.layout=org.apache.log4j.PatternLayout
+ log4j.appender.out.layout.ConversionPattern=%d{ISO8601} | %-5.5p | %-16.16t | %-32.32c{1} | %X{bundle.id} - %X{bundle.name} - %X{bundle.version} | %m%n
+ log4j.appender.out.file=${karaf.data}/log/karaf.log
+ log4j.appender.out.append=true
+ log4j.appender.out.maxFileSize=10MB
+ log4j.appender.out.maxBackupIndex=100
+
+
+ # Sift appender
+ log4j.appender.sift=org.apache.log4j.sift.MDCSiftingAppender
+ log4j.appender.sift.key=bundle.name
+ log4j.appender.sift.default=karaf
+ log4j.appender.sift.appender=org.apache.log4j.RollingFileAppender
+ log4j.appender.sift.appender.layout=org.apache.log4j.PatternLayout
+ log4j.appender.sift.appender.layout.ConversionPattern=%d{MM/dd-HH:mm:ss.SSS}|%X{RequestId}|%X{ServiceInstanceId}|%t|%X{ServiceName} - %X{bundle.id} - %X{bundle.name} - %X{bundle.version}|%-5.5p|%X{AlertSeverity}|%X{ServerFQDN}|%X{ServerIPAddress}|[%c{3}]|%m%n
+ log4j.appender.sift.appender.file=${karaf.data}/log/eelf/karaf.log
+ log4j.appender.sift.appender.append=true
+
+ log4j.category.org.opendaylight.controller.netconf.persist.impl.osgi.ConfigPusherImpl=DEBUG
+ log4j.category.org.opendaylight.controller.netconf.persist.impl.osgi.ConfigPersisterActivator=DEBUG
+
+
+ #ECOMP Debug appender
+ log4j.appender.debug=org.apache.log4j.RollingFileAppender
+ log4j.appender.debug.key=bundle.name
+ log4j.appender.debug.default=karaf
+
+ log4j.appender.debug.appName=EELFDebug
+ log4j.appender.debug.layout=org.apache.log4j.PatternLayout
+ log4j.appender.debug.layout.ConversionPattern=%d{yyyy-MM-dd'T'hh:mm:ss.SSSXXX}|%X{RequestId}|%m%n
+ #log4j.appender.debug.filter.f1=org.apache.log4j.varia.LevelRangeFilter
+ #log4j.appender.debug.filter.f1.LevelMax=WARN
+ #log4j.appender.debug.filter.f1.LevelMin=TRACE
+
+
+ log4j.appender.debug.file=${karaf.data}/log/APPC/appc-debug.log
+ log4j.appender.debug.append=true
+ log4j.appender.debug.maxFileSize=100MB
+ log4j.appender.debug.maxBackupIndex=10
+
+
+ #Error appender
+ log4j.appender.error=org.apache.log4j.RollingFileAppender
+ log4j.appender.error.appName=EELFError
+ log4j.appender.error.File=${karaf.data}/log/APPC/appc-error.log
+ log4j.appender.error.Threshold=ERROR
+ log4j.appender.error.MaxBackupIndex=1
+ log4j.appender.error.MaxFileSize=100MB
+ log4j.appender.error.layout=org.apache.log4j.PatternLayout
+ log4j.appender.error.layout.ConversionPattern=%d{yyyy-MM-dd'T'hh:mm:ss.SSSXXX}|%X{RequestId}|%t|%X{ServiceName}|%X{PartnerName}|%X{TargetEntity}|%X{TargetServiceName}|%-5.5p|%X{ErrorCode}|%X{ErrorDescription}|%m%n
+
+ #Metrics appender
+ log4j.appender.metric=org.apache.log4j.RollingFileAppender
+ log4j.appender.metric.appName=EELFMetrics
+ log4j.appender.metric.File=${karaf.data}/log/APPC/appc-metric.log
+ log4j.appender.metric.MaxBackupIndex=1
+ log4j.appender.metric.MaxFileSize=100MB
+ log4j.appender.metric.layout=org.apache.log4j.PatternLayout
+ log4j.appender.metric.layout.ConversionPattern=%X{BeginTimestamp}|%X{EndTimestamp}|%X{RequestId}|%X{ServiceInstanceId}|%t|%X{ServerName}|%X{ServiceName}|%X{PartnerName}|%X{TargetEntity}|%X{TargetServiceName}|%X{StatusCode}|%X{ResponseCode}|%X{ResponseDescription}|%X{InstanceUUID}|%-5.5p|%X{Severity}|%X{ServerIPAddress}|%X{ElapsedTime}|%X{ServerFQDN}|%X{ClientIPAddress}|%X{ClassName}||%X{ProcessKey}|%X{TargetVirtualEntity}|%X{CustomField1}|%X{CustomField2}|%X{CustomField3}|%X{CustomField4}|%m%n
+
+ #Audit appender
+ log4j.appender.audit=org.apache.log4j.RollingFileAppender
+ log4j.appender.audit.appName=EELFAudit
+ log4j.appender.audit.File=${karaf.data}/log/APPC/appc-audit.log
+ log4j.appender.audit.MaxBackupIndex=1
+ log4j.appender.audit.MaxFileSize=100MB
+ log4j.appender.audit.layout=org.apache.log4j.PatternLayout
+ log4j.appender.audit.layout.ConversionPattern=%X{BeginTimestamp}|%X{EndTimestamp}|%X{RequestId}|%X{ServiceInstanceId}|%t|%X{ServerName}|%X{ServiceName}|%X{PartnerName}|%X{StatusCode}|%X{ResponseCode}|%X{ResponseDescription}|%X{InstanceUUID}|%-5.5p|%X{Severity}|%X{ServerIPAddress}|%X{ElapsedTime}|%X{ServerFQDN}|%X{ClientIPAddress}|%X{ClassName}||%X{ProcessKey}|%X{CustomField1}|%X{CustomField2}|%X{CustomField3}|%X{CustomField4}|%m%n
+
+ #Loggers
+ #Routing of all messages from root logger
+ log4j.logger.com.att=TRACE, debug, error
+ #Store to the same log file messages from upper level appender or not
+ log4j.additivity.com.att=false
+
+ #EELFManager loggers
+ #EELF parent logger
+ log4j.logger.com.att.eelf=TRACE, debug
+ log4j.additivity.com.att.eelf=false
+
+ #Audit logger routing
+ log4j.logger.com.att.eelf.audit=DEBUG, audit
+ log4j.additivity.com.att.eelf.audit=false
+
+ #Metric logger routing
+ log4j.logger.com.att.eelf.metrics=DEBUG, metric
+ log4j.additivity.com.att.eelf.metrics=false
+
+ #Performance logger routing
+ log4j.logger.com.att.eelf.perf=DEBUG, metric
+ log4j.additivity.com.att.eelf.perf=false
+
+ #Server logger routing
+ log4j.logger.com.att.eelf.server=DEBUG, debug
+ log4j.additivity.com.att.eelf.server=false
+
+ #Policy logger routing
+ log4j.logger.com.att.eelf.policy=DEBUG, debug
+ log4j.additivity.com.att.eelf.policy=false
+
+ #Error logger routing
+ log4j.logger.com.att.eelf.error=DEBUG, error
+ log4j.additivity.com.att.eelf.error=false
+
+ #Debug logger routing
+ log4j.logger.com.att.eelf.debug=DEBUG, debug
+ log4j.additivity.com.att.eelf.debug=false
+
diff --git a/appc-oam/appc-oam-bundle/src/main/yang/appc-oam.yang b/appc-oam/appc-oam-bundle/src/main/yang/appc-oam.yang
new file mode 100644
index 0000000..364707e
--- /dev/null
+++ b/appc-oam/appc-oam-bundle/src/main/yang/appc-oam.yang
@@ -0,0 +1,61 @@
+module appc-oam-impl {
+
+ yang-version 1;
+ namespace "org:openecomp:appc:oam:impl";
+ prefix "appc-oam-impl";
+
+ import config { prefix config; revision-date 2013-04-05; }
+ import opendaylight-md-sal-binding { prefix mdsal; revision-date 2013-10-28; }
+
+ description
+ "This module contains the base YANG definitions for
+ appc-oam implementation.";
+
+ revision "2017-03-03" {
+ description
+ "Initial revision.";
+ }
+
+ // This is the definition of the service implementation as a module identity.
+ identity appc-oam-impl {
+ base config:module-type;
+
+ // Specifies the prefix for generated java classes.
+ config:java-name-prefix AppcOam;
+ }
+
+ // Augments the 'configuration' choice node under modules/module.
+ // We consume the three main services, RPCs, DataStore, and Notifications
+ augment "/config:modules/config:module/config:configuration" {
+ case appc-oam-impl {
+ when "/config:modules/config:module/config:type = 'appc-oam-impl'";
+
+ container rpc-registry {
+ uses config:service-ref {
+ refine type {
+ mandatory true;
+ config:required-identity mdsal:binding-rpc-registry;
+ }
+ }
+ }
+
+ container notification-service {
+ uses config:service-ref {
+ refine type {
+ mandatory true;
+ config:required-identity mdsal:binding-notification-service;
+ }
+ }
+ }
+
+ container data-broker {
+ uses config:service-ref {
+ refine type {
+ mandatory false;
+ config:required-identity mdsal:binding-async-data-broker;
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/appc-oam/appc-oam-features/pom.xml b/appc-oam/appc-oam-features/pom.xml
new file mode 100644
index 0000000..a8a9a44
--- /dev/null
+++ b/appc-oam/appc-oam-features/pom.xml
@@ -0,0 +1,126 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <artifactId>appc-oam</artifactId>
+ <groupId>org.openecomp.appc</groupId>
+ <version>1.1.0-SNAPSHOT</version>
+ </parent>
+ <name>appc-oam-features</name>
+ <artifactId>appc-oam-features</artifactId>
+
+ <packaging>jar</packaging>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.openecomp.appc</groupId>
+ <artifactId>appc-oam-model</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+
+ <dependency>
+ <groupId>org.openecomp.appc</groupId>
+ <artifactId>appc-oam-bundle</artifactId>
+ <classifier>config</classifier>
+ <type>xml</type>
+ <version>${project.version}</version>
+ </dependency>
+
+ <dependency>
+ <groupId>org.openecomp.appc</groupId>
+ <artifactId>appc-oam-bundle</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+
+ <dependency>
+ <groupId>org.opendaylight.mdsal</groupId>
+ <artifactId>features-mdsal</artifactId>
+ <classifier>features</classifier>
+ <type>xml</type>
+
+ <scope>runtime</scope>
+ </dependency>
+
+ <dependency>
+ <groupId>org.opendaylight.yangtools</groupId>
+ <artifactId>features-yangtools</artifactId>
+ <classifier>features</classifier>
+ <type>xml</type>
+ <scope>runtime</scope>
+ </dependency>
+ </dependencies>
+
+ <build>
+ <resources>
+ <resource>
+ <filtering>true</filtering>
+ <directory>src/main/resources</directory>
+ </resource>
+ </resources>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-resources-plugin</artifactId>
+ <executions>
+ <execution>
+ <id>filter</id>
+ <goals>
+ <goal>resources</goal>
+ </goals>
+ <phase>generate-resources</phase>
+ </execution>
+ </executions>
+ </plugin>
+ <plugin>
+ <!-- launches the feature test, which validates that your karaf feature
+ can be installed inside of a karaf container. It doesn't validate that your
+ functionality works correctly, just that you have all of the dependent bundles
+ defined correctly. -->
+ <!-- Skipping ODL feature test -->
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-surefire-plugin</artifactId>
+ <configuration>
+ <systemPropertyVariables>
+ <karaf.distro.groupId>org.opendaylight.controller</karaf.distro.groupId>
+ <karaf.distro.artifactId>opendaylight-karaf-empty</karaf.distro.artifactId>
+ <karaf.distro.version>${odl.karaf.empty.distro.version}</karaf.distro.version>
+ </systemPropertyVariables>
+ <dependenciesToScan>
+ <dependency>org.opendaylight.yangtools:features-test</dependency>
+ </dependenciesToScan>
+ <classpathDependencyExcludes>
+ <!-- The dependencies which bring in AbstractDataBrokerTest class
+ brings in a second PaxExam container which results in the feature tests failing
+ with a message similar to: "ERROR o.ops4j.pax.exam.spi.PaxExamRuntime - Ambiguous
+ TestContainer ..." This excludes the container we don't want to use. -->
+ <classpathDependencyExcludes>org.ops4j.pax.exam:pax-exam-container-native</classpathDependencyExcludes>
+ </classpathDependencyExcludes>
+ <skipTests>true</skipTests>
+ </configuration>
+ </plugin>
+ <plugin>
+ <groupId>org.codehaus.mojo</groupId>
+ <artifactId>build-helper-maven-plugin</artifactId>
+ <executions>
+ <execution>
+ <id>attach-artifacts</id>
+ <goals>
+ <goal>attach-artifact</goal>
+ </goals>
+ <phase>package</phase>
+ <configuration>
+ <artifacts>
+ <artifact>
+ <file>${project.build.directory}/classes/${features.file}</file>
+ <type>xml</type>
+ <classifier>features</classifier>
+ </artifact>
+ </artifacts>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+
+ </plugins>
+ </build>
+</project>
diff --git a/appc-oam/appc-oam-features/src/main/resources/features.xml b/appc-oam/appc-oam-features/src/main/resources/features.xml
new file mode 100644
index 0000000..cec3bf5
--- /dev/null
+++ b/appc-oam/appc-oam-features/src/main/resources/features.xml
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ============LICENSE_START=======================================================
+ openECOMP : APP-C
+ ================================================================================
+ Copyright (C) 2017 AT&T Intellectual Property. All rights
+ reserved.
+ ================================================================================
+ 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.
+ ============LICENSE_END=========================================================
+ -->
+
+
+<features name="appc-${project.version}" xmlns="http://karaf.apache.org/xmlns/features/v1.2.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://karaf.apache.org/xmlns/features/v1.2.0 http://karaf.apache.org/xmlns/features/v1.2.0">
+
+ <repository>mvn:org.opendaylight.mdsal/features-mdsal/${odl.mdsal.features.version}/xml/features</repository>
+
+ <feature name='appc-oam' description="appc oam module" version='${project.version}'>
+ <feature version="${broker-mdsal.version}">odl-mdsal-broker</feature>
+ <bundle>mvn:org.openecomp.appc/appc-oam-model/${project.version}</bundle>
+ <bundle>mvn:org.openecomp.appc/appc-oam-bundle/${project.version}</bundle>
+ <configfile finalname="etc/opendaylight/karaf/201-appc-oam.xml">mvn:org.openecomp.appc/appc-oam-bundle/${project.version}/xml/config</configfile>
+ </feature>
+
+</features>
diff --git a/appc-oam/appc-oam-installer/.gitignore b/appc-oam/appc-oam-installer/.gitignore
new file mode 100644
index 0000000..731eb43
--- /dev/null
+++ b/appc-oam/appc-oam-installer/.gitignore
@@ -0,0 +1,2 @@
+/target/
+/.settings/
diff --git a/appc-oam/appc-oam-installer/pom.xml b/appc-oam/appc-oam-installer/pom.xml
new file mode 100644
index 0000000..02c6ee8
--- /dev/null
+++ b/appc-oam/appc-oam-installer/pom.xml
@@ -0,0 +1,143 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <artifactId>appc-oam</artifactId>
+ <groupId>org.openecomp.appc</groupId>
+ <version>1.1.0-SNAPSHOT</version>
+ </parent>
+
+ <artifactId>appc-oam-installer</artifactId>
+ <name>APPC OAM - Karaf Installer</name>
+ <packaging>pom</packaging>
+
+ <properties>
+ <application.name>appc-oam</application.name>
+ <features.boot>appc-oam</features.boot>
+ <features.repositories>mvn:org.openecomp.appc/appc-oam-features/${project.version}/xml/features</features.repositories>
+ <include.transitive.dependencies>false</include.transitive.dependencies>
+ </properties>
+
+ <dependencies>
+
+ <dependency>
+ <groupId>org.openecomp.appc</groupId>
+ <artifactId>appc-oam-features</artifactId>
+ <version>${project.version}</version>
+ <classifier>features</classifier>
+ <type>xml</type>
+ <exclusions>
+ <exclusion>
+ <groupId>*</groupId>
+ <artifactId>*</artifactId>
+ </exclusion>
+ </exclusions>
+ </dependency>
+
+ <dependency>
+ <groupId>org.openecomp.appc</groupId>
+ <artifactId>appc-oam-bundle</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+
+ <dependency>
+ <groupId>org.openecomp.appc</groupId>
+ <artifactId>appc-oam-bundle</artifactId>
+ <version>${project.version}</version>
+ <classifier>config</classifier>
+ <type>xml</type>
+ </dependency>
+
+ </dependencies>
+
+ <build>
+ <plugins>
+ <plugin>
+ <artifactId>maven-assembly-plugin</artifactId>
+ <executions>
+ <execution>
+ <id>maven-repo-zip</id>
+ <goals>
+ <goal>single</goal>
+ </goals>
+ <phase>package</phase>
+ <configuration>
+ <appendAssemblyId>false</appendAssemblyId>
+ <attach>false</attach>
+ <finalName>stage/${application.name}-${project.version}</finalName>
+ <descriptors>
+ <descriptor>src/assembly/assemble_mvnrepo_zip.xml</descriptor>
+ </descriptors>
+ </configuration>
+ </execution>
+ <execution>
+ <id>installer-zip</id>
+ <goals>
+ <goal>single</goal>
+ </goals>
+ <phase>package</phase>
+ <configuration>
+ <appendAssemblyId>false</appendAssemblyId>
+ <attach>true</attach>
+ <finalName>${application.name}-${project.version}</finalName>
+ <descriptors>
+ <descriptor>src/assembly/assemble_installer_zip.xml</descriptor>
+ </descriptors>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-dependency-plugin</artifactId>
+ <executions>
+ <execution>
+ <id>copy-dependencies</id>
+ <goals>
+ <goal>copy-dependencies</goal>
+ </goals>
+ <phase>prepare-package</phase>
+ <configuration>
+ <transitive>false</transitive>
+ <outputDirectory>${project.build.directory}/assembly/system</outputDirectory>
+ <overWriteReleases>false</overWriteReleases>
+ <overWriteSnapshots>true</overWriteSnapshots>
+ <overWriteIfNewer>true</overWriteIfNewer>
+ <useRepositoryLayout>true</useRepositoryLayout>
+ <addParentPoms>false</addParentPoms>
+ <copyPom>false</copyPom>
+ <excludeGroupIds>org.opendaylight</excludeGroupIds>
+ <scope>provided</scope>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+ <plugin>
+ <artifactId>maven-resources-plugin</artifactId>
+ <executions>
+ <execution>
+ <id>copy-version</id>
+ <goals>
+ <goal>copy-resources</goal>
+ </goals>
+ <!-- here the phase you need -->
+ <phase>validate</phase>
+ <configuration>
+ <outputDirectory>${basedir}/target/stage</outputDirectory>
+ <resources>
+ <resource>
+ <directory>src/main/resources/scripts</directory>
+ <includes>
+ <include>install-feature.sh</include>
+ </includes>
+ <filtering>true</filtering>
+ </resource>
+ </resources>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
+
+</project>
diff --git a/appc-oam/appc-oam-installer/src/assembly/assemble_installer_zip.xml b/appc-oam/appc-oam-installer/src/assembly/assemble_installer_zip.xml
new file mode 100644
index 0000000..8948a33
--- /dev/null
+++ b/appc-oam/appc-oam-installer/src/assembly/assemble_installer_zip.xml
@@ -0,0 +1,59 @@
+<!--
+ ============LICENSE_START=======================================================
+ openECOMP : APP-C
+ ================================================================================
+ Copyright (C) 2017 AT&T Intellectual Property. All rights
+ reserved.
+ ================================================================================
+ 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.
+ ============LICENSE_END=========================================================
+ -->
+
+<!-- Defines how we build the .zip file which is our distribution. -->
+
+<assembly
+ xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0 http://maven.apache.org/xsd/assembly-1.1.0.xsd">
+ <id>controller</id>
+ <formats>
+ <format>zip</format>
+ </formats>
+
+ <!-- we want "system" and related files right at the root level
+ as this file is suppose to be unzip on top of a karaf
+ distro. -->
+ <includeBaseDirectory>false</includeBaseDirectory>
+
+ <fileSets>
+ <fileSet>
+ <directory>target/stage/</directory>
+ <outputDirectory>${application.name}</outputDirectory>
+ <fileMode>755</fileMode>
+ <includes>
+ <include>*.sh</include>
+ </includes>
+ </fileSet>
+ <fileSet>
+ <directory>target/stage/</directory>
+ <outputDirectory>${application.name}</outputDirectory>
+ <fileMode>644</fileMode>
+ <excludes>
+ <exclude>*.sh</exclude>
+ </excludes>
+ </fileSet>
+ </fileSets>
+
+
+
+</assembly>
diff --git a/appc-oam/appc-oam-installer/src/assembly/assemble_mvnrepo_zip.xml b/appc-oam/appc-oam-installer/src/assembly/assemble_mvnrepo_zip.xml
new file mode 100644
index 0000000..d88eaaa
--- /dev/null
+++ b/appc-oam/appc-oam-installer/src/assembly/assemble_mvnrepo_zip.xml
@@ -0,0 +1,54 @@
+<!--
+ ============LICENSE_START=======================================================
+ openECOMP : APP-C
+ ================================================================================
+ Copyright (C) 2017 AT&T Intellectual Property. All rights
+ reserved.
+ ================================================================================
+ 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.
+ ============LICENSE_END=========================================================
+ -->
+
+<!-- Defines how we build the .zip file which is our distribution. -->
+
+<assembly
+ xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0 http://maven.apache.org/xsd/assembly-1.1.0.xsd">
+ <id>controller</id>
+ <formats>
+ <format>zip</format>
+ </formats>
+
+ <!-- we want "system" and related files right at the root level
+ as this file is suppose to be unzip on top of a karaf
+ distro. -->
+ <includeBaseDirectory>false</includeBaseDirectory>
+
+ <fileSets>
+ <fileSet>
+ <directory>target/assembly/</directory>
+ <outputDirectory>.</outputDirectory>
+ <excludes>
+ </excludes>
+ </fileSet>
+ </fileSets>
+
+ <files>
+ <file>
+ <source>../${feature-name}-bundle/src/main/resources/initial/${feature-name}.xml</source>
+ <destName>./etc/opendaylight/karaf/201-${feature-name}.xml</destName>
+ </file>
+ </files>
+
+</assembly>
diff --git a/appc-oam/appc-oam-installer/src/main/resources/scripts/install-feature.sh b/appc-oam/appc-oam-installer/src/main/resources/scripts/install-feature.sh
new file mode 100644
index 0000000..1d769fa
--- /dev/null
+++ b/appc-oam/appc-oam-installer/src/main/resources/scripts/install-feature.sh
@@ -0,0 +1,40 @@
+###
+# ============LICENSE_START=======================================================
+# openECOMP : APP-C
+# ================================================================================
+# Copyright (C) 2017 AT&T Intellectual Property. All rights
+# reserved.
+# ================================================================================
+# 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.
+# ============LICENSE_END=========================================================
+###
+
+#!/bin/bash
+
+ODL_HOME=${ODL_HOME:-/opt/opendaylight/current}
+ODL_KARAF_CLIENT=${ODL_KARAF_CLIENT:-${ODL_HOME}/bin/client}
+ODL_KARAF_CLIENT_OPTS=${ODL_KARAF_CLIENT_OPTS:-"-u karaf"}
+INSTALLERDIR=$(dirname $0)
+
+REPOZIP=${INSTALLERDIR}/${features.boot}-${project.version}.zip
+
+if [ -f ${REPOZIP} ]
+then
+ unzip -n -d ${ODL_HOME} ${REPOZIP}
+else
+ echo "ERROR : repo zip ($REPOZIP) not found"
+ exit 1
+fi
+
+${ODL_KARAF_CLIENT} ${ODL_KARAF_CLIENT_OPTS} feature:repo-add ${features.repositories}
+${ODL_KARAF_CLIENT} ${ODL_KARAF_CLIENT_OPTS} feature:install ${features.boot}
diff --git a/appc-oam/appc-oam-model/pom.xml b/appc-oam/appc-oam-model/pom.xml
new file mode 100644
index 0000000..e44d9a0
--- /dev/null
+++ b/appc-oam/appc-oam-model/pom.xml
@@ -0,0 +1,98 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <artifactId>appc-oam</artifactId>
+ <groupId>org.openecomp.appc</groupId>
+ <version>1.1.0-SNAPSHOT</version>
+ </parent>
+ <artifactId>appc-oam-model</artifactId>
+ <packaging>bundle</packaging>
+
+ <build>
+
+ <plugins>
+ <plugin>
+ <groupId>org.apache.felix</groupId>
+ <artifactId>maven-bundle-plugin</artifactId>
+ <extensions>true</extensions>
+ <configuration>
+ <instructions>
+ <Import-Package>*</Import-Package>
+ </instructions>
+ </configuration>
+ </plugin>
+ <plugin>
+ <groupId>org.opendaylight.yangtools</groupId>
+ <artifactId>yang-maven-plugin</artifactId>
+ <version>${odl.yangtools.version}</version>
+ <dependencies>
+ <dependency>
+ <groupId>org.opendaylight.mdsal</groupId>
+ <artifactId>maven-sal-api-gen-plugin</artifactId>
+ <version>${odl.sal.api.gen.plugin.version}</version>
+ <type>jar</type>
+ </dependency>
+ </dependencies>
+ <executions>
+ <execution>
+ <goals>
+ <goal>generate-sources</goal>
+ </goals>
+ <configuration>
+ <yangFilesRootDir>${yang.file.directory}</yangFilesRootDir>
+ <codeGenerators>
+ <generator>
+ <codeGeneratorClass>org.opendaylight.yangtools.maven.sal.api.gen.plugin.CodeGeneratorImpl</codeGeneratorClass>
+ <outputBaseDir>${salGeneratorPath}</outputBaseDir>
+ </generator>
+ </codeGenerators>
+ <inspectDependencies>true</inspectDependencies>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-install-plugin</artifactId>
+ <version>2.5.2</version>
+ <executions>
+ <execution>
+ <id>yang</id>
+ <phase>initialize</phase>
+ <goals>
+ <goal>install-file</goal>
+ </goals>
+ <configuration>
+ <file>${project.basedir}/src/main/yang/appc-oam.yang</file>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>${project.artifactId}</artifactId>
+ <version>${project.version}</version>
+ <packaging>yang</packaging>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+
+ </build>
+ <dependencies>
+ <dependency>
+ <groupId>org.opendaylight.mdsal</groupId>
+ <artifactId>yang-binding</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.opendaylight.yangtools</groupId>
+ <artifactId>yang-common</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.opendaylight.mdsal.model</groupId>
+ <artifactId>ietf-inet-types</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.opendaylight.mdsal.model</groupId>
+ <artifactId>ietf-yang-types</artifactId>
+ </dependency>
+ </dependencies>
+</project>
diff --git a/appc-oam/appc-oam-model/src/main/yang/appc-oam.yang b/appc-oam/appc-oam-model/src/main/yang/appc-oam.yang
new file mode 100644
index 0000000..4611a32
--- /dev/null
+++ b/appc-oam/appc-oam-model/src/main/yang/appc-oam.yang
@@ -0,0 +1,137 @@
+/*
+ * Yang model for the OAM component of Application Controller (APP-C) component of ONAP
+ *
+ * This model is used to define the data and services of the OAM component of APP-C.
+ *
+ * The services exposed by this component are:
+ *
+ * get-metrics:
+ * Used to retrieve current metric data from APP-C.
+ *
+ */
+
+module appc-oam {
+
+ yang-version 1;
+ namespace "org:openecomp:appc:oam";
+ prefix appc-oam;
+ organization "Copyright 2017 AT&T Intellectual Property.";
+
+ description
+ "Defines the services and request/response requirements for the
+ APP-C OAM component.";
+
+ /*
+ * Note, the revision changes the package name of the generated java code. Do not
+ * change the revision unless you also update all references to the bindings.
+ */
+ revision "2017-03-03" {
+ description
+ "APP-C OAM interface version 1.5.00";
+ }
+
+ grouping common-header {
+ description "A common header for all APP-C requests";
+ container common-header {
+ description "A common header for all APP-C requests";
+
+ leaf originator-id {
+ description "originator-id an identifier of the calling system which can be
+ used addressing purposes, i.e. returning asynchronous response
+ to the proper destination over UEB (especially in case of multiple
+ consumers of APP-C APIs)";
+ type string;
+ mandatory true;
+ }
+
+ leaf request-id {
+ description "UUID for the request ID. An OSS/BSS identifier for the request
+ that caused the current action. Multiple API calls may be made
+ with the same request-id The request-id shall be recorded throughout
+ the operations on a single request";
+ type string;
+ mandatory true;
+ }
+
+ }
+ }
+
+ grouping status {
+ description "The specific response codes are to be aligned with ASDC reference
+ doc (main table removed to avoid duplication and digression from
+ main table). See ASDC and ECOMP Distribution Consumer Interface
+ Agreement";
+ container status {
+ description "The specific response codes are to be aligned with ASDC reference
+ doc (main table removed to avoid duplication and digression from
+ main table). See ASDC and ECOMP Distribution Consumer Interface
+ Agreement";
+ leaf code {
+ description "Response code";
+ type uint16;
+ mandatory true;
+ }
+ leaf message {
+ description "Response message";
+ type string;
+ mandatory true;
+ }
+ }
+ }
+
+ rpc get-metrics {
+ description "An operation to get list of registered Metrics in APP-C";
+ output {
+ list metrics {
+ key kpi-name;
+ description "KPI metrics definition";
+ leaf kpi-name {
+ description "metrics name";
+ type string;
+ mandatory true;
+ }
+ leaf last-reset-time {
+ description "Last reset time";
+ type string;
+ mandatory true;
+ }
+ list kpi-values {
+ key name;
+ description "KPI properties in form of key value pairs";
+ leaf name {
+ description "KPI property name";
+ type string;
+ }
+ leaf value {
+ description "KPI property value";
+ type string;
+ }
+ }
+ }
+ }
+ }
+
+ rpc stop {
+ description "An operation that disables appc-provider-lcm so that it no longer accepts LCM request. This
+ operation has no impact on queued and currently executing LCM request. A notification will be
+ sent out indicating the APP-C is idle once all LCM request have completed execution. ";
+ input {
+ uses common-header;
+ }
+ output {
+ uses common-header;
+ uses status;
+ }
+ }
+
+ rpc start {
+ description "An operation that enables appc-provider-lcm so that it can begin to accepts LCM request. ";
+ input {
+ uses common-header;
+ }
+ output {
+ uses common-header;
+ uses status;
+ }
+ }
+}
diff --git a/appc-oam/pom.xml b/appc-oam/pom.xml
new file mode 100644
index 0000000..7378d23
--- /dev/null
+++ b/appc-oam/pom.xml
@@ -0,0 +1,26 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <groupId>org.openecomp.appc</groupId>
+ <artifactId>appc</artifactId>
+ <version>1.1.0-SNAPSHOT</version>
+ </parent>
+ <artifactId>appc-oam</artifactId>
+ <packaging>pom</packaging>
+ <name>APPC OAM</name>
+ <description>The app-c OAM api bundle</description>
+ <properties>
+ <feature-name>appc-oam</feature-name>
+ </properties>
+
+ <!-- ================================================================================== -->
+ <!-- The modules we build -->
+ <!-- ================================================================================== -->
+ <modules>
+ <module>appc-oam-model</module>
+ <module>appc-oam-features</module>
+ <module>appc-oam-installer</module>
+ <module>appc-oam-bundle</module>
+ </modules>
+
+</project>