diff options
Diffstat (limited to 'sliapi/provider')
7 files changed, 967 insertions, 0 deletions
diff --git a/sliapi/provider/pom.xml b/sliapi/provider/pom.xml new file mode 100755 index 000000000..b4a6ff0f5 --- /dev/null +++ b/sliapi/provider/pom.xml @@ -0,0 +1,144 @@ +<?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>sliapi</artifactId> + <groupId>org.openecomp.sdnc.core</groupId> + <version>0.0.1-SNAPSHOT</version> + </parent> + <artifactId>sliapi-provider</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.sliapi.impl</Export-Package> + <Import-Package>*</Import-Package> + </instructions> + </configuration> + </plugin> + <plugin> + <groupId>org.opendaylight.yangtools</groupId> + <artifactId>yang-maven-plugin</artifactId> + <version>${odl.yangtools.yang.maven.plugin.version}</version> + <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/sliapi-provider.xml</file> + <type>xml</type> + <classifier>config</classifier> + </artifact> + </artifacts> + </configuration> + </execution> + </executions> + </plugin> + </plugins> + </build> + + <dependencies> + <dependency> + <groupId>org.openecomp.sdnc.core</groupId> + <artifactId>sliapi-model</artifactId> + </dependency> + <dependency> + <groupId>org.opendaylight.controller</groupId> + <artifactId>config-api</artifactId> + <version>${odl.controller.config.api.version}</version> + </dependency> + + + <dependency> + <groupId>org.opendaylight.controller</groupId> + <artifactId>sal-binding-config</artifactId> + <version>${odl.mdsal.version}</version> + </dependency> + + <dependency> + <groupId>org.opendaylight.controller</groupId> + <artifactId>sal-binding-api</artifactId> + <version>${odl.mdsal.version}</version> + </dependency> + + <dependency> + <groupId>org.opendaylight.controller</groupId> + <artifactId>sal-common-util</artifactId> + <version>${odl.mdsal.version}</version> + </dependency> + + + <dependency> + <groupId>org.openecomp.sdnc.core</groupId> + <artifactId>sli-common</artifactId> + <version>${project.version}</version> + </dependency> + <dependency> + <groupId>org.openecomp.sdnc.core</groupId> + <artifactId>sli-provider</artifactId> + <version>${project.version}</version> + </dependency> + <dependency> + <groupId>org.opendaylight.controller</groupId> + <artifactId>sal-core-api</artifactId> + <version>${odl.mdsal.version}</version> + </dependency> + <dependency> + <groupId>org.opendaylight.yangtools</groupId> + <artifactId>yang-data-impl</artifactId> + <version>${odl.yangtools.version}</version> + </dependency> + </dependencies> +</project> diff --git a/sliapi/provider/src/main/java/org/opendaylight/yang/gen/v1/org/openecomp/sdnc/sliapi/provider/impl/rev140523/SliapiProviderModule.java b/sliapi/provider/src/main/java/org/opendaylight/yang/gen/v1/org/openecomp/sdnc/sliapi/provider/impl/rev140523/SliapiProviderModule.java new file mode 100644 index 000000000..e05103cd5 --- /dev/null +++ b/sliapi/provider/src/main/java/org/opendaylight/yang/gen/v1/org/openecomp/sdnc/sliapi/provider/impl/rev140523/SliapiProviderModule.java @@ -0,0 +1,59 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : SDN-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.sdnc.sliapi.provider.impl.rev140523; + +import org.openecomp.sdnc.sliapi.sliapiProvider; + +public class SliapiProviderModule extends org.opendaylight.yang.gen.v1.org.openecomp.sdnc.sliapi.provider.impl.rev140523.AbstractSliapiProviderModule { + public SliapiProviderModule(org.opendaylight.controller.config.api.ModuleIdentifier identifier, org.opendaylight.controller.config.api.DependencyResolver dependencyResolver) { + super(identifier, dependencyResolver); + } + + public SliapiProviderModule(org.opendaylight.controller.config.api.ModuleIdentifier identifier, org.opendaylight.controller.config.api.DependencyResolver dependencyResolver, org.opendaylight.yang.gen.v1.org.openecomp.sdnc.sliapi.provider.impl.rev140523.SliapiProviderModule 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 sliapiProvider provider = new sliapiProvider(); + provider.setDataBroker( getDataBrokerDependency() ); + provider.setNotificationService( getNotificationServiceDependency() ); + provider.setRpcRegistry( getRpcRegistryDependency() ); + provider.initialize(); + return new AutoCloseable() { + + @Override + public void close() throws Exception { + //TODO: CLOSE ANY REGISTRATION OBJECTS CREATED USING ABOVE BROKER/NOTIFICATION + //SERVIE/RPC REGISTRY + provider.close(); + } + }; + } + +} diff --git a/sliapi/provider/src/main/java/org/opendaylight/yang/gen/v1/org/openecomp/sdnc/sliapi/provider/impl/rev140523/SliapiProviderModuleFactory.java b/sliapi/provider/src/main/java/org/opendaylight/yang/gen/v1/org/openecomp/sdnc/sliapi/provider/impl/rev140523/SliapiProviderModuleFactory.java new file mode 100644 index 000000000..fbd20365f --- /dev/null +++ b/sliapi/provider/src/main/java/org/opendaylight/yang/gen/v1/org/openecomp/sdnc/sliapi/provider/impl/rev140523/SliapiProviderModuleFactory.java @@ -0,0 +1,34 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : SDN-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: slitester-provider-impl yang module local name: sliapi-provider-impl +* Generated by: org.opendaylight.controller.config.yangjmxgenerator.plugin.JMXGenerator +* Generated at: Fri Oct 21 10:42:49 EDT 2016 +* +* Do not modify this file unless it is present under src/main directory +*/ +package org.opendaylight.yang.gen.v1.org.openecomp.sdnc.sliapi.provider.impl.rev140523; +public class SliapiProviderModuleFactory extends org.opendaylight.yang.gen.v1.org.openecomp.sdnc.sliapi.provider.impl.rev140523.AbstractSliapiProviderModuleFactory { + +} diff --git a/sliapi/provider/src/main/java/org/openecomp/sdnc/sliapi/SliapiHelper.java b/sliapi/provider/src/main/java/org/openecomp/sdnc/sliapi/SliapiHelper.java new file mode 100644 index 000000000..4ad4f0166 --- /dev/null +++ b/sliapi/provider/src/main/java/org/openecomp/sdnc/sliapi/SliapiHelper.java @@ -0,0 +1,40 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : SDN-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.sdnc.sliapi; + +import org.opendaylight.yang.gen.v1.org.openecomp.sdnc.sliapi.rev161110.ExecuteGraphInputBuilder; +import org.opendaylight.yang.gen.v1.org.openecomp.sdnc.sliapi.rev161110.execute.graph.input.SliParameterBuilder; +import org.openecomp.sdnc.sli.provider.MdsalHelper; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class SliapiHelper extends MdsalHelper { + + private static final Logger LOG = LoggerFactory.getLogger(SliapiHelper.class); + + static { + ExecuteGraphInputBuilder b1 = new ExecuteGraphInputBuilder(); + SliParameterBuilder b2 = new SliParameterBuilder(); + + } + +} diff --git a/sliapi/provider/src/main/java/org/openecomp/sdnc/sliapi/sliapiProvider.java b/sliapi/provider/src/main/java/org/openecomp/sdnc/sliapi/sliapiProvider.java new file mode 100644 index 000000000..705277c6e --- /dev/null +++ b/sliapi/provider/src/main/java/org/openecomp/sdnc/sliapi/sliapiProvider.java @@ -0,0 +1,557 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : SDN-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.sdnc.sliapi; + +import java.util.Enumeration; +import java.util.LinkedList; +import java.util.Properties; +import java.util.concurrent.Future; + +import org.opendaylight.controller.md.sal.binding.api.DataBroker; +import org.opendaylight.controller.md.sal.binding.api.WriteTransaction; +import org.opendaylight.controller.md.sal.binding.impl.AbstractForwardedDataBroker; +import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType; +import org.opendaylight.controller.md.sal.common.api.data.OptimisticLockFailedException; +import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException; +import org.opendaylight.controller.md.sal.dom.api.DOMDataBroker; +import org.opendaylight.controller.md.sal.dom.api.DOMDataWriteTransaction; +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.sdnc.sliapi.rev161110.ExecuteGraphInput; +import org.opendaylight.yang.gen.v1.org.openecomp.sdnc.sliapi.rev161110.ExecuteGraphInput.Mode; +import org.opendaylight.yang.gen.v1.org.openecomp.sdnc.sliapi.rev161110.ExecuteGraphInputBuilder; +import org.opendaylight.yang.gen.v1.org.openecomp.sdnc.sliapi.rev161110.ExecuteGraphOutput; +import org.opendaylight.yang.gen.v1.org.openecomp.sdnc.sliapi.rev161110.ExecuteGraphOutputBuilder; +import org.opendaylight.yang.gen.v1.org.openecomp.sdnc.sliapi.rev161110.HealthcheckOutput; +import org.opendaylight.yang.gen.v1.org.openecomp.sdnc.sliapi.rev161110.HealthcheckOutputBuilder; +import org.opendaylight.yang.gen.v1.org.openecomp.sdnc.sliapi.rev161110.SLIAPIService; +import org.opendaylight.yang.gen.v1.org.openecomp.sdnc.sliapi.rev161110.TestResults; +import org.opendaylight.yang.gen.v1.org.openecomp.sdnc.sliapi.rev161110.execute.graph.input.SliParameter; +import org.opendaylight.yang.gen.v1.org.openecomp.sdnc.sliapi.rev161110.test.results.TestResult; +import org.opendaylight.yang.gen.v1.org.openecomp.sdnc.sliapi.rev161110.test.results.TestResultBuilder; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; +import org.opendaylight.yangtools.yang.common.QName; +import org.opendaylight.yangtools.yang.common.RpcResult; +import org.opendaylight.yangtools.yang.common.RpcResultBuilder; +import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier; +import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier; +import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifierWithPredicates; +import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeWithValue; +import org.opendaylight.yangtools.yang.data.api.schema.LeafSetEntryNode; +import org.opendaylight.yangtools.yang.data.api.schema.LeafSetNode; +import org.opendaylight.yangtools.yang.data.api.schema.MapEntryNode; +import org.opendaylight.yangtools.yang.data.impl.schema.ImmutableNodes; +import org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.ImmutableLeafSetEntryNodeBuilder; +import org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.ImmutableLeafSetNodeBuilder; +import org.openecomp.sdnc.sli.provider.SvcLogicService; +import org.osgi.framework.BundleContext; +import org.osgi.framework.FrameworkUtil; +import org.osgi.framework.ServiceReference; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.google.common.util.concurrent.Futures; + + +/** + * Defines a base implementation for your provider. This class extends from a helper class + * which provides storage for the most commonly used components of the MD-SAL. Additionally the + * base class provides some basic logging and initialization / clean up methods. + * + * To use this, copy and paste (overwrite) the following method into the TestApplicationProviderModule + * class which is auto generated under src/main/java in this project + * (created only once during first compilation): + * + * <pre> + + @Override + public java.lang.AutoCloseable createInstance() { + + final sliapiProvider provider = new sliapiProvider(); + provider.setDataBroker( getDataBrokerDependency() ); + provider.setNotificationService( getNotificationServiceDependency() ); + provider.setRpcRegistry( getRpcRegistryDependency() ); + provider.initialize(); + return new AutoCloseable() { + + @Override + public void close() throws Exception { + //TODO: CLOSE ANY REGISTRATION OBJECTS CREATED USING ABOVE BROKER/NOTIFICATION + //SERVIE/RPC REGISTRY + provider.close(); + } + }; + } + + + </pre> + */ +public class sliapiProvider implements AutoCloseable, SLIAPIService{ + + private final Logger LOG = LoggerFactory.getLogger( sliapiProvider.class ); + private final String appName = "slitester"; + + protected DataBroker dataBroker; + protected DOMDataBroker domDataBroker; + protected NotificationProviderService notificationService; + protected RpcProviderRegistry rpcRegistry; + + protected BindingAwareBroker.RpcRegistration<SLIAPIService> rpcRegistration; + + private static String SLIAPI_NAMESPACE = "org:openecomp:sdnc:sliapi"; + private static String SLIAPI_REVISION = "2016-11-10"; + + private static QName TEST_RESULTS_QNAME = null; + private static QName TEST_RESULT_QNAME = null; + private static QName TEST_ID_QNAME = null; + private static QName RESULTS_QNAME = null; + + static { + + TEST_RESULTS_QNAME = QName.create(SLIAPI_NAMESPACE, SLIAPI_REVISION, "test-results"); + TEST_RESULT_QNAME = QName.create(TEST_RESULTS_QNAME, "test-result"); + TEST_ID_QNAME = QName.create(TEST_RESULT_QNAME, "test-identifier"); + RESULTS_QNAME = QName.create(TEST_RESULT_QNAME, "results"); + } + + + public sliapiProvider() { + this.LOG.info( "Creating provider for " + appName ); + } + + public void initialize(){ + LOG.info( "Initializing provider for " + appName ); + //initialization code goes here. + + rpcRegistration = rpcRegistry.addRpcImplementation(SLIAPIService.class, this); + LOG.info( "Initialization complete for " + appName ); + } + + protected void initializeChild() { + //Override if you have custom initialization intelligence + } + + @Override + public void close() throws Exception { + LOG.info( "Closing provider for " + appName ); + //closing code goes here + + rpcRegistration.close(); + LOG.info( "Successfully closed provider for " + appName ); + } + + public void setDataBroker(DataBroker dataBroker) { + this.dataBroker = dataBroker; + if (dataBroker instanceof AbstractForwardedDataBroker) { + domDataBroker = ((AbstractForwardedDataBroker) dataBroker).getDelegate(); + } + if( LOG.isDebugEnabled() ){ + LOG.debug( "DataBroker set to " + (dataBroker==null?"null":"non-null") + "." ); + } + } + + public void setNotificationService( + NotificationProviderService notificationService) { + this.notificationService = notificationService; + if( LOG.isDebugEnabled() ){ + LOG.debug( "Notification Service set to " + (notificationService==null?"null":"non-null") + "." ); + } + } + + public void setRpcRegistry(RpcProviderRegistry rpcRegistry) { + this.rpcRegistry = rpcRegistry; + if( LOG.isDebugEnabled() ){ + LOG.debug( "RpcRegistry set to " + (rpcRegistry==null?"null":"non-null") + "." ); + } + } + + @Override + public Future<RpcResult<ExecuteGraphOutput>> executeGraph(ExecuteGraphInput input) { + RpcResult<ExecuteGraphOutput> rpcResult = null; + + SvcLogicService svcLogic = getSvcLogicService(); + ExecuteGraphOutputBuilder respBuilder = new ExecuteGraphOutputBuilder(); + + String calledModule = input.getModuleName(); + String calledRpc = input.getRpcName(); + Mode calledMode = input.getMode(); + String modeStr = "sync"; + + if (calledMode == Mode.Async) { + modeStr = "async"; + } + + if (svcLogic == null) { + respBuilder.setResponseCode("500"); + respBuilder.setResponseMessage("Could not locate OSGi SvcLogicService service"); + respBuilder.setAckFinalIndicator("Y"); + + rpcResult = RpcResultBuilder.<ExecuteGraphOutput> status(true).withResult(respBuilder.build()).build(); + return(Futures.immediateFuture(rpcResult)); + } + + + try { + if (!svcLogic.hasGraph(calledModule, calledRpc, null, modeStr)) { + respBuilder.setResponseCode("404"); + respBuilder.setResponseMessage("Directed graph for "+calledModule+"/"+calledRpc+"/"+modeStr+" not found"); + respBuilder.setAckFinalIndicator("Y"); + + rpcResult = RpcResultBuilder.<ExecuteGraphOutput> status(true).withResult(respBuilder.build()).build(); + return(Futures.immediateFuture(rpcResult)); + } + } catch (Exception e) { + LOG.error("Caught exception looking for directed graph for "+calledModule+"/"+calledRpc+"/"+modeStr, e); + + respBuilder.setResponseCode("500"); + respBuilder.setResponseMessage("Internal error : could not determine if target graph exists"); + respBuilder.setAckFinalIndicator("Y"); + + rpcResult = RpcResultBuilder.<ExecuteGraphOutput> status(true).withResult(respBuilder.build()).build(); + return(Futures.immediateFuture(rpcResult)); + } + + // Load properties + Properties parms = new Properties(); + + // Pass properties using names from sli-parameters + for (SliParameter sliParm : input.getSliParameter()) { + + String propValue = ""; + + Boolean boolval = sliParm.isBooleanValue(); + + if (boolval != null) { + propValue = boolval.toString(); + } else { + Integer intval = sliParm.getIntValue(); + if (intval != null) { + propValue = intval.toString(); + } else { + propValue = sliParm.getStringValue(); + if (propValue == null) { + propValue = ""; + } + } + } + parms.setProperty(sliParm.getParameterName(), propValue); + } + + // Also, pass "meta" properties (i.e. pass SliParameter objects themselves) + ExecuteGraphInputBuilder inputBuilder = new ExecuteGraphInputBuilder(input); + + SliapiHelper.toProperties(parms, "input", inputBuilder); + + try { + LOG.info("Calling directed graph for "+calledModule+"/"+calledRpc+"/"+modeStr); + + if (LOG.isTraceEnabled()) { + StringBuffer argList = new StringBuffer(); + argList.append("Parameters : {"); + Enumeration e = parms.propertyNames(); + while (e.hasMoreElements()) { + String propName = (String) e.nextElement(); + argList.append(" ("+propName+","+parms.getProperty(propName)+") "); + } + argList.append("}"); + LOG.trace(argList.toString()); + argList = null; + } + + + + Properties respProps = svcLogic.execute(calledModule, calledRpc, + null, modeStr, parms, domDataBroker); + + StringBuilder sb = new StringBuilder("{"); + + for (Object key : respProps.keySet()) { + String keyValue = (String) key; + if (keyValue != null && !"".equals(keyValue) && !keyValue.contains("input.sli-parameter")) { + sb.append("\"").append(keyValue).append("\": \"").append(respProps.getProperty(keyValue)).append("\","); + } + } + + sb.setLength(sb.length() - 1); + sb.append("}"); + + respBuilder.setResponseCode(respProps.getProperty("error-code", "0")); + respBuilder.setResponseMessage(respProps.getProperty("error-message", ""));// TODO change response-text to response-message to match other BVC APIs + respBuilder.setAckFinalIndicator(respProps.getProperty("ack-final", "Y")); + respBuilder.setContextMemoryJson(sb.toString()); + + TestResultBuilder testResultBuilder = new TestResultBuilder(); + + SliapiHelper.toBuilder(respProps, testResultBuilder); + + String testIdentifier = testResultBuilder.getTestIdentifier(); + + if ((testIdentifier != null) && (testIdentifier.length() > 0)) { + + // Add test results to config tree + LOG.debug("Saving test results for test id "+testIdentifier); + + DomSaveTestResult(testResultBuilder.build(), true, LogicalDatastoreType.CONFIGURATION); + + } + + } catch (Exception e) { + LOG.error("Caught exception executing directed graph for" + + calledModule + ":" + calledRpc + "," + modeStr + ">", e); + + respBuilder.setResponseCode("500"); + respBuilder + .setResponseMessage("Internal error : caught exception executing directed graph " + + calledModule + + "/" + + calledRpc + + "/" + + modeStr); + respBuilder.setAckFinalIndicator("Y"); + + } + + rpcResult = RpcResultBuilder.<ExecuteGraphOutput> status(true) + .withResult(respBuilder.build()).build(); + return (Futures.immediateFuture(rpcResult)); + } + + + private SvcLogicService getSvcLogicService() { + BundleContext bctx = FrameworkUtil.getBundle(SvcLogicService.class).getBundleContext(); + + SvcLogicService svcLogic = null; + + // Get SvcLogicService reference + ServiceReference sref = bctx.getServiceReference(SvcLogicService.NAME); + if (sref != null) + { + svcLogic = (SvcLogicService) bctx.getService(sref); + + } + else + { + LOG.warn("Cannot find service reference for "+SvcLogicService.NAME); + + } + + return(svcLogic); + } + + @Override + public Future<RpcResult<HealthcheckOutput>> healthcheck() { + + RpcResult<HealthcheckOutput> rpcResult = null; + SvcLogicService svcLogic = getSvcLogicService(); + + HealthcheckOutputBuilder respBuilder = new HealthcheckOutputBuilder(); + + String calledModule = "sli"; + String calledRpc = "healthcheck"; + String modeStr = "sync"; + + if (svcLogic == null) { + respBuilder.setResponseCode("500"); + respBuilder.setResponseMessage("Could not locate OSGi SvcLogicService service"); + respBuilder.setAckFinalIndicator("Y"); + + rpcResult = RpcResultBuilder.<HealthcheckOutput> failed().withResult(respBuilder.build()).build(); + return(Futures.immediateFuture(rpcResult)); + } + + try { + if (!svcLogic.hasGraph(calledModule, calledRpc, null, modeStr)) { + respBuilder.setResponseCode("404"); + respBuilder.setResponseMessage("Directed graph for "+calledModule+"/"+calledRpc+"/"+modeStr+" not found"); + + respBuilder.setAckFinalIndicator("Y"); + + rpcResult = RpcResultBuilder.<HealthcheckOutput> status(true).withResult(respBuilder.build()).build(); + return(Futures.immediateFuture(rpcResult)); + } + } catch (Exception e) { + LOG.error("Caught exception looking for directed graph for "+calledModule+"/"+calledRpc+"/"+modeStr, e); + + respBuilder.setResponseCode("500"); + respBuilder.setResponseMessage("Internal error : could not determine if target graph exists"); + respBuilder.setAckFinalIndicator("Y"); + + rpcResult = RpcResultBuilder.<HealthcheckOutput> failed().withResult(respBuilder.build()).build(); + return(Futures.immediateFuture(rpcResult)); + } + + try { + LOG.info("Calling directed graph for "+calledModule+"/"+calledRpc+"/"+modeStr); + + Properties parms = new Properties(); + + Properties respProps = svcLogic.execute(calledModule, calledRpc, + null, modeStr, parms); + + respBuilder.setResponseCode(respProps.getProperty("error-code", "0")); + respBuilder.setResponseMessage(respProps.getProperty("error-message", "")); + respBuilder.setAckFinalIndicator(respProps.getProperty("ack-final", "Y")); + + } catch (Exception e) { + LOG.error("Caught exception executing directed graph for" + + calledModule + ":" + calledRpc + "," + modeStr + ">", e); + + respBuilder.setResponseCode("500"); + respBuilder + .setResponseMessage("Internal error : caught exception executing directed graph " + + calledModule + + "/" + + calledRpc + + "/" + + modeStr); + respBuilder.setAckFinalIndicator("Y"); + + } + + rpcResult = RpcResultBuilder.<HealthcheckOutput> status(true) + .withResult(respBuilder.build()).build(); + return (Futures.immediateFuture(rpcResult)); + } + + private void DomSaveTestResult(final TestResult entry, boolean merge, LogicalDatastoreType storeType) { + + + if (domDataBroker == null) { + LOG.error("domDataBroker unset - cannot save test result using DOMDataBroker"); + return; + } + + MapEntryNode resultNode = null; + + try { + resultNode = toMapEntryNode(entry); + } catch (Exception e) { + LOG.error("Caught exception trying to create map entry node", e); + } + + if (resultNode == null) { + LOG.error("Could not convert entry to MapEntryNode"); + return; + } + + + YangInstanceIdentifier testResultsPid = YangInstanceIdentifier.builder().node(TEST_RESULTS_QNAME).node(QName.create(TEST_RESULTS_QNAME, "test-result")).build(); + YangInstanceIdentifier testResultPid = testResultsPid.node(new NodeIdentifierWithPredicates(TEST_RESULT_QNAME, resultNode.getIdentifier().getKeyValues())); + + + + int tries = 2; + while(true) { + try { + DOMDataWriteTransaction wtx = domDataBroker.newWriteOnlyTransaction(); + if (merge) { + LOG.info("Merging test identifier "+entry.getTestIdentifier()); + wtx.merge(storeType, testResultPid, resultNode); + } else { + LOG.info("Putting test identifier "+entry.getTestIdentifier()); + wtx.put(storeType, testResultPid, resultNode); + } + wtx.submit().checkedGet(); + LOG.trace("Update DataStore succeeded"); + break; + } catch (final TransactionCommitFailedException e) { + if(e instanceof OptimisticLockFailedException) { + if(--tries <= 0) { + LOG.trace("Got OptimisticLockFailedException on last try - failing "); + throw new IllegalStateException(e); + } + LOG.trace("Got OptimisticLockFailedException - trying again "); + } else { + LOG.trace("Update DataStore failed"); + throw new IllegalStateException(e); + } + } + } + + } + + private void SaveTestResult(final TestResult entry, boolean merge, LogicalDatastoreType storeType) throws IllegalStateException + { + // Each entry will be identifiable by a unique key, we have to create that identifier + InstanceIdentifier.InstanceIdentifierBuilder<TestResult> testResultIdBuilder = + InstanceIdentifier.<TestResults>builder(TestResults.class) + .child(TestResult.class, entry.getKey()); + InstanceIdentifier<TestResult> path = testResultIdBuilder.toInstance(); + int tries = 2; + while(true) { + try { + WriteTransaction tx = dataBroker.newWriteOnlyTransaction(); + if (merge) { + tx.merge(storeType, path, entry); + } else { + tx.put(storeType, path, entry); + } + tx.submit().checkedGet(); + LOG.trace("Update DataStore succeeded"); + break; + } catch (final TransactionCommitFailedException e) { + if(e instanceof OptimisticLockFailedException) { + if(--tries <= 0) { + LOG.trace("Got OptimisticLockFailedException on last try - failing "); + throw new IllegalStateException(e); + } + LOG.trace("Got OptimisticLockFailedException - trying again "); + } else { + LOG.trace("Update DataStore failed"); + throw new IllegalStateException(e); + } + } + } + } + + private MapEntryNode toMapEntryNode(TestResult testResult) { + + + YangInstanceIdentifier testResultId = YangInstanceIdentifier.builder().node(TEST_RESULTS_QNAME).node(TEST_RESULT_QNAME).build(); + + // Construct results list + LinkedList<LeafSetEntryNode<Object>> entryList = new LinkedList<LeafSetEntryNode<Object>>(); + for (String result : testResult.getResults()) { + LeafSetEntryNode<Object> leafSetEntryNode = ImmutableLeafSetEntryNodeBuilder.create() + .withNodeIdentifier(new NodeWithValue(RESULTS_QNAME, result)) + .withValue(result) + .build(); + entryList.add(leafSetEntryNode); + } + // Construct results LeafSetNode + LeafSetNode<?> resultsNode = ImmutableLeafSetNodeBuilder.create().withNodeIdentifier(new NodeIdentifier(RESULTS_QNAME)).withValue(entryList).build(); + + + + // Construct test result ContainerNode with 2 children - test-identifier leaf and results leaf-set + MapEntryNode testResultNode = ImmutableNodes.mapEntryBuilder() + .withNodeIdentifier(new NodeIdentifierWithPredicates(TEST_RESULT_QNAME, TEST_ID_QNAME, testResult.getTestIdentifier())) + .withChild(ImmutableNodes.leafNode(TEST_ID_QNAME, testResult.getTestIdentifier())) + .withChild(resultsNode) + .build(); + + return(testResultNode); + + } + +} diff --git a/sliapi/provider/src/main/resources/initial/sliapi-provider.xml b/sliapi/provider/src/main/resources/initial/sliapi-provider.xml new file mode 100644 index 000000000..fd2ccbeeb --- /dev/null +++ b/sliapi/provider/src/main/resources/initial/sliapi-provider.xml @@ -0,0 +1,72 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ============LICENSE_START======================================================= + openECOMP : SDN-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 *-provider-impl.yang file + The prefix: inside type should match the prefix of the yang file. --> + <type xmlns:prefix="org:openecomp:sdnc:sliapi:provider:impl"> + prefix:sliapi-provider-impl + </type> + <name>sliapi-provider-impl</name> + + <!-- The following sections contain bindings to services defined in the + *-provider-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:sdnc:sliapi:provider:impl?module=sliapi-provider-impl&revision=2014-05-23</capability> + </required-capabilities> + +</snapshot> diff --git a/sliapi/provider/src/main/yang/sliapi-provider-impl.yang b/sliapi/provider/src/main/yang/sliapi-provider-impl.yang new file mode 100755 index 000000000..b32ff6c3d --- /dev/null +++ b/sliapi/provider/src/main/yang/sliapi-provider-impl.yang @@ -0,0 +1,61 @@ +module sliapi-provider-impl { + + yang-version 1; + namespace "org:openecomp:sdnc:sliapi:provider:impl"; + prefix "sliapi-provider-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 + sliapi-provider impl implementation."; + + revision "2014-05-23" { + description + "Initial revision."; + } + + // This is the definition of the service implementation as a module identity. + identity sliapi-provider-impl { + base config:module-type; + + // Specifies the prefix for generated java classes. + config:java-name-prefix sliapiProvider; + } + + // 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 sliapi-provider-impl { + when "/config:modules/config:module/config:type = 'sliapi-provider-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; + } + } + } + } + } +} |