From: Ed Warnicke Date: Wed, 27 Nov 2013 21:16:42 +0000 (+0000) Subject: Merge "Enabled documentation generator for models." X-Git-Tag: jenkins-controller-bulk-release-prepare-only-2-1~329 X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?a=commitdiff_plain;h=0f4cc2d53eba0394556d689459009a538493970d;hp=659acfaa5edb05aa5363243ea6f839b084ba5e5f;p=controller.git Merge "Enabled documentation generator for models." --- diff --git a/opendaylight/distribution/opendaylight/pom.xml b/opendaylight/distribution/opendaylight/pom.xml index 55ab5caeeb..5b08af79f8 100644 --- a/opendaylight/distribution/opendaylight/pom.xml +++ b/opendaylight/distribution/opendaylight/pom.xml @@ -39,6 +39,11 @@ sal-common-util ${mdsal.version} + + org.opendaylight.controller + sal-netconf-connector + ${mdsal.version} + org.opendaylight.controller sal-core-api @@ -129,7 +134,11 @@ forwardingrules-manager ${mdsal.version} - + + org.opendaylight.controller.md + statistics-manager + ${mdsal.version} + org.opendaylight.controller concepts @@ -157,6 +166,31 @@ yang-jmx-generator ${config.version} + + org.opendaylight.controller + netty-event-executor-config + ${config.version} + + + org.opendaylight.controller + netty-threadgroup-config + ${config.version} + + + org.opendaylight.controller + threadpool-config-api + ${config.version} + + + org.opendaylight.controller + threadpool-config-impl + ${config.version} + + + org.opendaylight.controller + yang-store-api + ${config.version} + org.opendaylight.controller yang-store-api diff --git a/opendaylight/md-sal/model/model-flow-base/src/main/yang/flow-types.yang b/opendaylight/md-sal/model/model-flow-base/src/main/yang/flow-types.yang index 67c6933cc7..29ea8ddf18 100644 --- a/opendaylight/md-sal/model/model-flow-base/src/main/yang/flow-types.yang +++ b/opendaylight/md-sal/model/model-flow-base/src/main/yang/flow-types.yang @@ -4,7 +4,7 @@ module opendaylight-flow-types { import ietf-inet-types {prefix inet; revision-date "2010-09-24";} import ietf-yang-types {prefix yang; revision-date "2010-09-24";} - import opendaylight-match-types {prefix match; revision-date 2013-10-26";} + import opendaylight-match-types {prefix match; revision-date "2013-10-26";} import opendaylight-action-types {prefix action;} revision "2013-10-26" { diff --git a/opendaylight/md-sal/model/model-flow-base/src/main/yang/table-types.yang b/opendaylight/md-sal/model/model-flow-base/src/main/yang/table-types.yang index 2a16bfcf50..1b6a689750 100644 --- a/opendaylight/md-sal/model/model-flow-base/src/main/yang/table-types.yang +++ b/opendaylight/md-sal/model/model-flow-base/src/main/yang/table-types.yang @@ -4,7 +4,7 @@ module opendaylight-table-types { import ietf-inet-types {prefix inet; revision-date "2010-09-24";} import ietf-yang-types {prefix yang; revision-date "2010-09-24";} - import opendaylight-flow-types {prefix flow;revision-date 2013-10-26";} + import opendaylight-flow-types {prefix flow;revision-date "2013-10-26";} import opendaylight-action-types {prefix action;} revision "2013-10-26" { diff --git a/opendaylight/md-sal/model/model-flow-service/src/main/yang/port-service.yang b/opendaylight/md-sal/model/model-flow-service/src/main/yang/port-service.yang index 9588652a1c..d49675ad39 100644 --- a/opendaylight/md-sal/model/model-flow-service/src/main/yang/port-service.yang +++ b/opendaylight/md-sal/model/model-flow-service/src/main/yang/port-service.yang @@ -5,6 +5,7 @@ module sal-port { import yang-ext {prefix ext; revision-date "2013-07-09";} import opendaylight-inventory {prefix inv;revision-date "2013-08-19";} import opendaylight-port-types {prefix port-type;revision-date "2013-09-25";} + import flow-capable-transaction {prefix tr;} revision "2013-11-07" { description "Initial revision of port service"; @@ -31,6 +32,10 @@ module sal-port { rpc update-port { input { uses port-update; + uses tr:transaction-aware; + } + output { + uses tr:transaction-aware; } } diff --git a/opendaylight/md-sal/pom.xml b/opendaylight/md-sal/pom.xml index bdbcce0950..94c31dd041 100644 --- a/opendaylight/md-sal/pom.xml +++ b/opendaylight/md-sal/pom.xml @@ -40,7 +40,8 @@ sal-connector-api sal-rest-connector - + sal-netconf-connector + clustered-data-store/implementation diff --git a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/dom/serializer/impl/RuntimeGeneratedMappingServiceImpl.xtend b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/dom/serializer/impl/RuntimeGeneratedMappingServiceImpl.xtend index 0ddc2c88c8..ec69fd3b68 100644 --- a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/dom/serializer/impl/RuntimeGeneratedMappingServiceImpl.xtend +++ b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/dom/serializer/impl/RuntimeGeneratedMappingServiceImpl.xtend @@ -33,6 +33,8 @@ import org.opendaylight.yangtools.binding.generator.util.Types import org.osgi.framework.BundleContext import java.util.Hashtable import org.osgi.framework.ServiceRegistration +import org.opendaylight.controller.sal.binding.impl.connect.dom.DeserializationException +import java.util.concurrent.Callable class RuntimeGeneratedMappingServiceImpl implements BindingIndependentMappingService, SchemaServiceListener, AutoCloseable { @@ -59,7 +61,7 @@ class RuntimeGeneratedMappingServiceImpl implements BindingIndependentMappingSer val promisedTypeDefinitions = HashMultimap.>create; val promisedSchemas = HashMultimap.>create; - + ServiceRegistration listenerRegistration override onGlobalContextUpdated(SchemaContext arg0) { @@ -79,7 +81,6 @@ class RuntimeGeneratedMappingServiceImpl implements BindingIndependentMappingSer val context = entry.value; updateBindingFor(context.childNodes, schemaContext); updateBindingFor(context.cases, schemaContext); - val typedefs = context.typedefs; for (typedef : typedefs.values) { @@ -89,7 +90,7 @@ class RuntimeGeneratedMappingServiceImpl implements BindingIndependentMappingSer for (augmentation : augmentations) { binding.typeToDefinition.put(augmentation, augmentation); } - + binding.typeToAugmentation.putAll(context.typeToAugmentation); } } @@ -127,22 +128,36 @@ class RuntimeGeneratedMappingServiceImpl implements BindingIndependentMappingSer } override dataObjectFromDataDom(InstanceIdentifier path, CompositeNode node) { - if (node == null) { - return null; - } - val targetType = path.targetType - val transformer = registry.getCodecForDataObject(targetType); - val ret = transformer.deserialize(node)?.value as DataObject; - return ret; + return tryDeserialization[ | + if (node == null) { + return null; + } + val targetType = path.targetType + val transformer = registry.getCodecForDataObject(targetType); + val ret = transformer.deserialize(node)?.value as DataObject; + return ret; + ] } - + override fromDataDom(org.opendaylight.yangtools.yang.data.api.InstanceIdentifier entry) { - return registry.instanceIdentifierCodec.deserialize(entry); + return tryDeserialization[ | + registry.instanceIdentifierCodec.deserialize(entry); + ] + } + + private static def T tryDeserialization(Callable deserializationBlock) throws DeserializationException { + try { + deserializationBlock.call() + } catch (Exception e) { + // FIXME: Make this block providing more information. + throw new DeserializationException(e); + } } private def void updateBindingFor(Map map, SchemaContext module) { for (entry : map.entrySet) { val schemaNode = SchemaContextUtil.findDataSchemaNode(module, entry.key); + //LOG.info("{} : {}",entry.key,entry.value.fullyQualifiedName) if (schemaNode != null) { typeToSchemaNode.put(entry.value, schemaNode); @@ -162,8 +177,8 @@ class RuntimeGeneratedMappingServiceImpl implements BindingIndependentMappingSer binding.typeToDefinition = typeToDefinition binding.typeToSchemaNode = typeToSchemaNode binding.typeDefinitions = typeDefinitions - if(ctx !== null) { - listenerRegistration = ctx.registerService(SchemaServiceListener,this,new Hashtable()); + if (ctx !== null) { + listenerRegistration = ctx.registerService(SchemaServiceListener, this, new Hashtable()); } } @@ -217,9 +232,9 @@ class RuntimeGeneratedMappingServiceImpl implements BindingIndependentMappingSer } promisedSchemas.removeAll(builder); } - + override close() throws Exception { listenerRegistration?.unregister(); } - + } diff --git a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/connect/dom/BindingIndependentDataServiceConnector.java b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/connect/dom/BindingIndependentDataServiceConnector.java index ccd6079cc9..7a72afc885 100644 --- a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/connect/dom/BindingIndependentDataServiceConnector.java +++ b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/connect/dom/BindingIndependentDataServiceConnector.java @@ -32,7 +32,7 @@ import org.slf4j.LoggerFactory; public class BindingIndependentDataServiceConnector implements // RuntimeDataProvider, // - Provider { + Provider, AutoCloseable { private final Logger LOG = LoggerFactory.getLogger(BindingIndependentDataServiceConnector.class); @@ -59,16 +59,24 @@ public class BindingIndependentDataServiceConnector implements // @Override public DataObject readOperationalData(InstanceIdentifier path) { - org.opendaylight.yangtools.yang.data.api.InstanceIdentifier biPath = mappingService.toDataDom(path); - CompositeNode result = biDataService.readOperationalData(biPath); - return mappingService.dataObjectFromDataDom(path, result); + try { + org.opendaylight.yangtools.yang.data.api.InstanceIdentifier biPath = mappingService.toDataDom(path); + CompositeNode result = biDataService.readOperationalData(biPath); + return mappingService.dataObjectFromDataDom(path, result); + } catch (DeserializationException e) { + throw new IllegalStateException(e); + } } @Override public DataObject readConfigurationData(InstanceIdentifier path) { - org.opendaylight.yangtools.yang.data.api.InstanceIdentifier biPath = mappingService.toDataDom(path); - CompositeNode result = biDataService.readConfigurationData(biPath); - return mappingService.dataObjectFromDataDom(path, result); + try { + org.opendaylight.yangtools.yang.data.api.InstanceIdentifier biPath = mappingService.toDataDom(path); + CompositeNode result = biDataService.readConfigurationData(biPath); + return mappingService.dataObjectFromDataDom(path, result); + } catch (DeserializationException e) { + throw new IllegalStateException(e); + } } private DataModificationTransaction createBindingToDomTransaction( @@ -103,23 +111,42 @@ public class BindingIndependentDataServiceConnector implements // .beginTransaction(); for (Entry entry : source .getUpdatedConfigurationData().entrySet()) { - InstanceIdentifier baKey = mappingService.fromDataDom(entry.getKey()); - DataObject baData = mappingService.dataObjectFromDataDom(baKey, entry.getValue()); - target.putConfigurationData(baKey, baData); + try { + InstanceIdentifier baKey = mappingService.fromDataDom(entry.getKey()); + DataObject baData = mappingService.dataObjectFromDataDom(baKey, entry.getValue()); + target.putConfigurationData(baKey, baData); + } catch (DeserializationException e) { + LOG.error("Ommiting from BA transaction: {}. Reason{}.", entry.getKey(), e); + } } for (Entry entry : source .getUpdatedOperationalData().entrySet()) { - InstanceIdentifier baKey = mappingService.fromDataDom(entry.getKey()); - DataObject baData = mappingService.dataObjectFromDataDom(baKey, entry.getValue()); - target.putOperationalData(baKey, baData); + try { + + InstanceIdentifier baKey = mappingService.fromDataDom(entry.getKey()); + DataObject baData = mappingService.dataObjectFromDataDom(baKey, entry.getValue()); + target.putOperationalData(baKey, baData); + } catch (DeserializationException e) { + LOG.error("Ommiting from BA transaction: {}. Reason{}.", entry.getKey(), e); + } } for (org.opendaylight.yangtools.yang.data.api.InstanceIdentifier entry : source.getRemovedConfigurationData()) { - InstanceIdentifier baEntry = mappingService.fromDataDom(entry); - target.removeConfigurationData(baEntry); + try { + + InstanceIdentifier baEntry = mappingService.fromDataDom(entry); + target.removeConfigurationData(baEntry); + } catch (DeserializationException e) { + LOG.error("Ommiting from BA transaction: {}. Reason{}.", entry, e); + } } for (org.opendaylight.yangtools.yang.data.api.InstanceIdentifier entry : source.getRemovedOperationalData()) { - InstanceIdentifier baEntry = mappingService.fromDataDom(entry); - target.removeOperationalData(baEntry); + try { + + InstanceIdentifier baEntry = mappingService.fromDataDom(entry); + target.removeOperationalData(baEntry); + } catch (DeserializationException e) { + LOG.error("Ommiting from BA transaction: {}. Reason{}.", entry, e); + } } return target; } @@ -162,6 +189,18 @@ public class BindingIndependentDataServiceConnector implements // start(); } + @Override + public void close() throws Exception { + + if (baCommitHandlerRegistration != null) { + baCommitHandlerRegistration.close(); + } + if (biCommitHandlerRegistration != null) { + biCommitHandlerRegistration.close(); + } + + } + private class DomToBindingTransaction implements DataCommitTransaction { @@ -271,10 +310,11 @@ public class BindingIndependentDataServiceConnector implements // @Override public void onRegister(DataCommitHandlerRegistration, DataObject> registration) { - - org.opendaylight.yangtools.yang.data.api.InstanceIdentifier domPath = mappingService.toDataDom(registration.getPath()); + + org.opendaylight.yangtools.yang.data.api.InstanceIdentifier domPath = mappingService.toDataDom(registration + .getPath()); // FIXME: do registration based on only active commit handlers. - + } @Override diff --git a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/connect/dom/BindingIndependentMappingService.java b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/connect/dom/BindingIndependentMappingService.java index 9e175b8cb0..b1983fe224 100644 --- a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/connect/dom/BindingIndependentMappingService.java +++ b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/connect/dom/BindingIndependentMappingService.java @@ -16,8 +16,8 @@ public interface BindingIndependentMappingService { org.opendaylight.yangtools.yang.data.api.InstanceIdentifier toDataDom(InstanceIdentifier path); - DataObject dataObjectFromDataDom(InstanceIdentifier path, CompositeNode result); + DataObject dataObjectFromDataDom(InstanceIdentifier path, CompositeNode result) throws DeserializationException; - InstanceIdentifier fromDataDom(org.opendaylight.yangtools.yang.data.api.InstanceIdentifier entry); + InstanceIdentifier fromDataDom(org.opendaylight.yangtools.yang.data.api.InstanceIdentifier entry) throws DeserializationException; } diff --git a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/connect/dom/DeserializationException.java b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/connect/dom/DeserializationException.java new file mode 100644 index 0000000000..9331899686 --- /dev/null +++ b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/connect/dom/DeserializationException.java @@ -0,0 +1,24 @@ +package org.opendaylight.controller.sal.binding.impl.connect.dom; + +public class DeserializationException extends Exception { + + public DeserializationException() { + } + + public DeserializationException(String message) { + super(message); + } + + public DeserializationException(Throwable cause) { + super(cause); + } + + public DeserializationException(String message, Throwable cause) { + super(message, cause); + } + + public DeserializationException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) { + super(message, cause, enableSuppression, writableStackTrace); + } + +} diff --git a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/sal/dom/broker/impl/DataReaderRouter.xtend b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/sal/dom/broker/impl/DataReaderRouter.xtend index fbed2ca113..504a3d6394 100644 --- a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/sal/dom/broker/impl/DataReaderRouter.xtend +++ b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/sal/dom/broker/impl/DataReaderRouter.xtend @@ -4,15 +4,100 @@ import org.opendaylight.controller.md.sal.common.impl.routing.AbstractDataReadRo import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier import org.opendaylight.yangtools.yang.data.api.CompositeNode import org.opendaylight.controller.md.sal.common.api.data.DataReader +import org.opendaylight.yangtools.yang.common.QName +import java.net.URI +import java.util.List +import org.opendaylight.yangtools.yang.data.api.Node +import java.util.ArrayList +import org.opendaylight.yangtools.yang.data.impl.SimpleNodeTOImpl +import java.util.Map +import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.PathArgument +import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.NodeIdentifier +import org.opendaylight.yangtools.yang.data.api.SimpleNode +import java.util.Collections +import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.NodeIdentifierWithPredicates +import java.util.HashMap +import static com.google.common.base.Preconditions.*; +import java.util.Collection +import java.util.Set +import java.util.Map.Entry +import org.slf4j.LoggerFactory +import org.opendaylight.yangtools.yang.data.impl.CompositeNodeTOImpl class DataReaderRouter extends AbstractDataReadRouter { + private static val LOG = LoggerFactory.getLogger(DataReaderRouter); + private static val NETCONF_NAMESPACE = URI.create("urn:ietf:params:xml:ns:netconf:base:1.0") + private static val NETCONF_DATA = new QName(NETCONF_NAMESPACE,"data"); override protected merge(InstanceIdentifier path, Iterable data) { + val pathArgument = path.path.last; + var empty = true; + var name = pathArgument?.nodeType; + val nodes = new ArrayList>(); + val keyNodes = new HashMap>(); val iterator = data.iterator; - if(iterator.hasNext) { - return data.iterator.next + for(dataBit : data) { + try { + if(pathArgument != null && dataBit != null) { + empty = false; + val keyNodesLocal = getKeyNodes(pathArgument,dataBit); + nodes.addAll(dataBit.childrenWithout(keyNodesLocal.entrySet)); + } else if (dataBit != null) { + empty = false; + nodes.addAll(dataBit.children) + } + } catch (IllegalStateException e) { + LOG.error("BUG: Readed data for path {} was invalid",path,e); + } } - return null; + if(empty) { + return null; + } + /** + * Reading from Root + * + */ + if(pathArgument == null) { + return new CompositeNodeTOImpl(NETCONF_DATA,null,nodes); + } + val finalNodes = new ArrayList>(); + finalNodes.addAll(keyNodes.values); + finalNodes.addAll(nodes); + return new CompositeNodeTOImpl(name,null,finalNodes); } - + + + + dispatch def Map> getKeyNodes(PathArgument argument, CompositeNode node) { + return Collections.emptyMap(); + } + + dispatch def getKeyNodes(NodeIdentifierWithPredicates argument, CompositeNode node) { + val ret = new HashMap>(); + for (keyValue : argument.keyValues.entrySet) { + val simpleNode = node.getSimpleNodesByName(keyValue.key); + if(simpleNode !== null && !simpleNode.empty) { + checkState(simpleNode.size <= 1,"Only one simple node for key $s is allowed in node $s",keyValue.key,node); + checkState(simpleNode.get(0).value == keyValue.value,"Key node must equals to instance identifier value"); + ret.put(keyValue.key,simpleNode.get(0)); + } + val compositeNode = node.getCompositesByName(keyValue.key); + checkState(compositeNode === null || compositeNode.empty,"Key node must be Simple Node, not composite node."); + } + return ret; + } + + def Collection> childrenWithout(CompositeNode node, Set>> entries) { + if(entries.empty) { + return node.children; + } + val filteredNodes = new ArrayList>(); + for(scannedNode : node.children) { + if(!entries.contains(scannedNode.nodeType)) { + filteredNodes.add(scannedNode); + } + } + return filteredNodes; + } + } diff --git a/opendaylight/md-sal/sal-netconf-connector/pom.xml b/opendaylight/md-sal/sal-netconf-connector/pom.xml index 6ef5780c8a..e790a9dbb1 100644 --- a/opendaylight/md-sal/sal-netconf-connector/pom.xml +++ b/opendaylight/md-sal/sal-netconf-connector/pom.xml @@ -30,6 +30,11 @@ org.eclipse.xtend org.eclipse.xtend.lib + + org.opendaylight.controller + netty-threadgroup-config + 0.2.3-SNAPSHOT + org.opendaylight.controller netconf-client @@ -62,7 +67,7 @@ ${project.groupId} config-api ${netconf.version} - test + provided ${project.groupId} @@ -76,12 +81,6 @@ ${netconf.version} test - - ${project.groupId} - netconf-api - ${netconf.version} - test - org.opendaylight.bgpcep util @@ -91,7 +90,6 @@ ${project.groupId} netconf-client - test ${netconf.version} @@ -172,6 +170,21 @@ org.slf4j slf4j-api + + org.opendaylight.yangtools.model + ietf-inet-types + 2010.09.24.2-SNAPSHOT + + + org.opendaylight.controller + threadpool-config-api + 0.2.3-SNAPSHOT + + + org.opendaylight.controller + netty-config-api + 0.2.3-SNAPSHOT + bundle @@ -181,11 +194,65 @@ org.apache.felix maven-bundle-plugin - - - org.opendaylight.controller.sal.connect.netconf.NetconfProvider - - + + + org.opendaylight.yangtools + yang-maven-plugin + 0.5.9-SNAPSHOT + + + + generate-sources + + + + + + org.opendaylight.controller.config.yangjmxgenerator.plugin.JMXGenerator + + ${project.build.directory}/generated-sources/config + + + urn:opendaylight:params:xml:ns:yang:controller==org.opendaylight.controller.config.yang + + + + + true + + + + + + org.opendaylight.controller + yang-jmx-generator-plugin + 0.2.3-SNAPSHOT + + + + + org.codehaus.mojo + build-helper-maven-plugin + 1.8 + + + add-source + generate-sources + + add-source + + + + ${project.build.directory}/generated-sources/config + + + + + + + + org.eclipse.xtend + xtend-maven-plugin diff --git a/opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/config/yang/md/sal/connector/netconf/NetconfConnectorModule.java b/opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/config/yang/md/sal/connector/netconf/NetconfConnectorModule.java new file mode 100644 index 0000000000..2a556c9be4 --- /dev/null +++ b/opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/config/yang/md/sal/connector/netconf/NetconfConnectorModule.java @@ -0,0 +1,89 @@ +/** +* Generated file + +* Generated from: yang module name: opendaylight-sal-netconf-connector yang module local name: sal-netconf-connector +* Generated by: org.opendaylight.controller.config.yangjmxgenerator.plugin.JMXGenerator +* Generated at: Mon Nov 18 09:44:16 CET 2013 +* +* Do not modify this file unless it is present under src/main directory +*/ +package org.opendaylight.controller.config.yang.md.sal.connector.netconf; + +import io.netty.channel.EventLoopGroup; + +import java.net.InetAddress; +import java.net.InetSocketAddress; + +import javax.net.ssl.SSLContext; + +import org.opendaylight.controller.netconf.client.NetconfClientDispatcher; +import org.opendaylight.controller.sal.connect.netconf.NetconfDevice; +import org.osgi.framework.BundleContext; + +import static com.google.common.base.Preconditions.*; + +import com.google.common.base.Optional; +import com.google.common.net.InetAddresses; + +/** +* +*/ +public final class NetconfConnectorModule extends org.opendaylight.controller.config.yang.md.sal.connector.netconf.AbstractNetconfConnectorModule +{ + + private BundleContext bundleContext; + + public NetconfConnectorModule(org.opendaylight.controller.config.api.ModuleIdentifier identifier, org.opendaylight.controller.config.api.DependencyResolver dependencyResolver) { + super(identifier, dependencyResolver); + } + + public NetconfConnectorModule(org.opendaylight.controller.config.api.ModuleIdentifier identifier, org.opendaylight.controller.config.api.DependencyResolver dependencyResolver, NetconfConnectorModule oldModule, java.lang.AutoCloseable oldInstance) { + super(identifier, dependencyResolver, oldModule, oldInstance); + } + + @Override + public void validate(){ + super.validate(); + checkState(getAddress() != null,"Address must be set."); + //checkState(getAddress().getIpv4Address() != null || getAddress().getIpv6Address() != null,"Address must be set."); + checkState(getPort() != null,"Port must be set."); + checkState(getDomRegistry() != null,"Dom Registry must be provided."); + } + + + @Override + public java.lang.AutoCloseable createInstance() { + + getDomRegistryDependency(); + NetconfDevice device = new NetconfDevice(getIdentifier().getInstanceName()); + String addressValue = getAddress(); + + + /* + * Uncomment after Switch to IP Address + if(getAddress().getIpv4Address() != null) { + addressValue = getAddress().getIpv4Address().getValue(); + } else { + addressValue = getAddress().getIpv6Address().getValue(); + } + + */ + InetAddress addr = InetAddresses.forString(addressValue); + InetSocketAddress socketAddress = new InetSocketAddress(addr , getPort().intValue()); + device.setSocketAddress(socketAddress); + + EventLoopGroup bossGroup = getBossThreadGroupDependency(); + EventLoopGroup workerGroup = getWorkerThreadGroupDependency(); + Optional maybeContext = Optional.absent(); + NetconfClientDispatcher dispatcher = new NetconfClientDispatcher(maybeContext , bossGroup, workerGroup); + + getDomRegistryDependency().registerProvider(device, bundleContext); + + device.start(dispatcher); + return device; + } + + public void setBundleContext(BundleContext bundleContext) { + this.bundleContext = bundleContext; + } +} diff --git a/opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/config/yang/md/sal/connector/netconf/NetconfConnectorModuleFactory.java b/opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/config/yang/md/sal/connector/netconf/NetconfConnectorModuleFactory.java new file mode 100644 index 0000000000..51e288d597 --- /dev/null +++ b/opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/config/yang/md/sal/connector/netconf/NetconfConnectorModuleFactory.java @@ -0,0 +1,39 @@ +/** + * Generated file + + * Generated from: yang module name: opendaylight-sal-netconf-connector yang module local name: sal-netconf-connector + * Generated by: org.opendaylight.controller.config.yangjmxgenerator.plugin.JMXGenerator + * Generated at: Mon Nov 18 09:44:16 CET 2013 + * + * Do not modify this file unless it is present under src/main directory + */ +package org.opendaylight.controller.config.yang.md.sal.connector.netconf; + +import org.opendaylight.controller.config.api.DependencyResolver; +import org.opendaylight.controller.config.api.DynamicMBeanWithInstance; +import org.opendaylight.controller.config.spi.Module; +import org.osgi.framework.BundleContext; + +/** +* +*/ +public class NetconfConnectorModuleFactory extends + org.opendaylight.controller.config.yang.md.sal.connector.netconf.AbstractNetconfConnectorModuleFactory { + + @Override + public Module createModule(String instanceName, DependencyResolver dependencyResolver, + DynamicMBeanWithInstance old, BundleContext bundleContext) throws Exception { + NetconfConnectorModule module = (NetconfConnectorModule) super.createModule(instanceName, dependencyResolver, + old, bundleContext); + module.setBundleContext(bundleContext); + return module; + } + + @Override + public Module createModule(String instanceName, DependencyResolver dependencyResolver, BundleContext bundleContext) { + NetconfConnectorModule module = (NetconfConnectorModule) super.createModule(instanceName, dependencyResolver, + bundleContext); + module.setBundleContext(bundleContext); + return module; + } +} diff --git a/opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/NetconfDevice.xtend b/opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/NetconfDevice.xtend index 0171c1f9e3..49d9757f42 100644 --- a/opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/NetconfDevice.xtend +++ b/opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/NetconfDevice.xtend @@ -14,8 +14,16 @@ import org.opendaylight.yangtools.yang.common.QName import java.util.Collections import org.opendaylight.controller.netconf.client.NetconfClientDispatcher import org.opendaylight.yangtools.concepts.Registration +import org.opendaylight.controller.sal.core.api.Provider +import org.opendaylight.controller.sal.core.api.Broker.ProviderSession +import org.opendaylight.controller.sal.core.api.mount.MountProvisionService +import static org.opendaylight.controller.sal.connect.netconf.InventoryUtils.*; +import org.opendaylight.controller.sal.core.api.data.DataBrokerService +import org.opendaylight.controller.sal.core.api.data.DataModificationTransaction +import org.opendaylight.yangtools.yang.data.impl.SimpleNodeTOImpl +import org.opendaylight.yangtools.yang.data.impl.CompositeNodeTOImpl -class NetconfDevice implements DataReader, RpcImplementation { +class NetconfDevice implements Provider, DataReader, RpcImplementation, AutoCloseable { var NetconfClient client; @@ -23,25 +31,29 @@ class NetconfDevice implements DataReader, Rp var InetSocketAddress socketAddress; @Property - val MountProvisionInstance mountInstance; + var MountProvisionInstance mountInstance; @Property - val InstanceIdentifier path; - - Registration> operReaderReg - - Registration> confReaderReg - - public new(MountProvisionInstance mount,InstanceIdentifier path) { - _mountInstance = mount; - _path = path; + var InstanceIdentifier path; + + Registration> operReaderReg + + Registration> confReaderReg + + String name + + MountProvisionService mountService + + public new(String name) { + this.name = name; + this.path = InstanceIdentifier.builder(INVENTORY_PATH).nodeWithKey(INVENTORY_NODE, + Collections.singletonMap(INVENTORY_ID, name)).toInstance; } def start(NetconfClientDispatcher dispatcher) { - client = new NetconfClient("sal-netconf-connector", socketAddress, dispatcher); - - confReaderReg = mountInstance.registerConfigurationReader(path,this); - operReaderReg = mountInstance.registerOperationalReader(path,this); + client = new NetconfClient(name, socketAddress, dispatcher); + confReaderReg = mountInstance.registerConfigurationReader(path, this); + operReaderReg = mountInstance.registerOperationalReader(path, this); } override readConfigurationData(InstanceIdentifier path) { @@ -66,6 +78,40 @@ class NetconfDevice implements DataReader, Rp return result.toRpcResult(); } + override getProviderFunctionality() { + Collections.emptySet + } + + override onSessionInitiated(ProviderSession session) { + val dataBroker = session.getService(DataBrokerService); + + + + val transaction = dataBroker.beginTransaction + if(transaction.operationalNodeNotExisting) { + transaction.putOperationalData(path,nodeWithId) + } + if(transaction.configurationNodeNotExisting) { + transaction.putConfigurationData(path,nodeWithId) + } + transaction.commit().get(); + mountService = session.getService(MountProvisionService); + mountInstance = mountService.createOrGetMountPoint(path); + } + + def getNodeWithId() { + val id = new SimpleNodeTOImpl(INVENTORY_ID,null,name); + return new CompositeNodeTOImpl(INVENTORY_NODE,null,Collections.singletonList(id)); + } + + def boolean configurationNodeNotExisting(DataModificationTransaction transaction) { + return null === transaction.readConfigurationData(path); + } + + def boolean operationalNodeNotExisting(DataModificationTransaction transaction) { + return null === transaction.readOperationalData(path); + } + def Node findNode(CompositeNode node, InstanceIdentifier identifier) { var Node current = node; @@ -86,10 +132,11 @@ class NetconfDevice implements DataReader, Rp } return current; } - - public def stop() { + + override close() { confReaderReg?.close() operReaderReg?.close() + client?.close() } } diff --git a/opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/NetconfDeviceManager.xtend b/opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/NetconfDeviceManager.xtend deleted file mode 100644 index 2fe145e18a..0000000000 --- a/opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/NetconfDeviceManager.xtend +++ /dev/null @@ -1,84 +0,0 @@ -package org.opendaylight.controller.sal.connect.netconf - -import org.opendaylight.controller.sal.core.api.Broker.ProviderSession -import org.opendaylight.controller.sal.core.api.mount.MountProvisionService -import org.opendaylight.controller.md.sal.common.api.data.DataProvisionService -import org.opendaylight.controller.sal.core.api.data.DataProviderService -import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier -import org.opendaylight.yangtools.yang.common.QName -import static org.opendaylight.controller.sal.connect.netconf.InventoryUtils.*; -import static extension org.opendaylight.controller.sal.connect.netconf.NetconfInventoryUtils.*; - -import org.opendaylight.controller.sal.core.api.data.DataChangeListener -import org.opendaylight.yangtools.yang.data.api.CompositeNode -import org.opendaylight.controller.md.sal.common.api.data.DataChangeEvent -import java.util.Map -import java.util.concurrent.ConcurrentHashMap -import org.opendaylight.controller.sal.core.api.mount.MountProvisionInstance -import org.opendaylight.controller.netconf.client.NetconfClientDispatcher -import java.io.OptionalDataException -import com.google.common.base.Optional -import java.net.SocketAddress -import java.net.InetSocketAddress - -class NetconfDeviceManager { - - val Map devices = new ConcurrentHashMap; - - var ProviderSession session; - - @Property - var DataProviderService dataService; - - @Property - var MountProvisionService mountService; - - val nodeUpdateListener = new NetconfInventoryListener(this); - - - @Property - var NetconfClientDispatcher dispatcher; - - def void start() { - dataService?.registerDataChangeListener(INVENTORY_PATH, nodeUpdateListener); - if(dispatcher == null) { - dispatcher = new NetconfClientDispatcher(Optional.absent); - } - } - - def netconfNodeAdded(InstanceIdentifier path, CompositeNode node) { - val address = node.endpointAddress; - val port = Integer.parseInt(node.endpointPort); - netconfNodeAdded(path,new InetSocketAddress(address,port)) - - } - - def netconfNodeAdded(InstanceIdentifier path, InetSocketAddress address) { - - val mountPointPath = path; - val mountPoint = mountService.createOrGetMountPoint(mountPointPath); - val localPath = InstanceIdentifier.builder().toInstance; - val netconfDevice = new NetconfDevice(mountPoint,localPath); - netconfDevice.setSocketAddress(address); - netconfDevice.start(dispatcher); - } - - def netconfNodeRemoved(InstanceIdentifier path) { - - } - -} - -class NetconfInventoryListener implements DataChangeListener { - - val NetconfDeviceManager manager; - - new(NetconfDeviceManager manager) { - this.manager = manager; - } - - override onDataChanged(DataChangeEvent change) { - - //manager.netconfNodeAdded(path, change); - } -} diff --git a/opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/NetconfProvider.java b/opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/NetconfProvider.java deleted file mode 100644 index 8cf5f0274c..0000000000 --- a/opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/NetconfProvider.java +++ /dev/null @@ -1,35 +0,0 @@ -package org.opendaylight.controller.sal.connect.netconf; - -import java.util.Hashtable; - -import org.opendaylight.controller.sal.core.api.AbstractProvider; -import org.opendaylight.controller.sal.core.api.Broker.ProviderSession; -import org.opendaylight.controller.sal.core.api.data.DataProviderService; -import org.opendaylight.controller.sal.core.api.mount.MountProvisionService; -import org.osgi.framework.BundleContext; - -public class NetconfProvider extends AbstractProvider { - - private NetconfDeviceManager netconfDeviceManager; - - @Override - protected void startImpl(BundleContext context) { - netconfDeviceManager = new NetconfDeviceManager(); - context.registerService(NetconfDeviceManager.class, netconfDeviceManager, new Hashtable()); - } - - - @Override - public void onSessionInitiated(ProviderSession session) { - MountProvisionService mountService = session.getService(MountProvisionService.class); - - - netconfDeviceManager.setMountService(mountService); - netconfDeviceManager.start(); - } - - @Override - protected void stopImpl(BundleContext context) { - - } -} diff --git a/opendaylight/md-sal/sal-netconf-connector/src/main/yang/odl-sal-netconf-connector-cfg.yang b/opendaylight/md-sal/sal-netconf-connector/src/main/yang/odl-sal-netconf-connector-cfg.yang new file mode 100644 index 0000000000..45f10162ca --- /dev/null +++ b/opendaylight/md-sal/sal-netconf-connector/src/main/yang/odl-sal-netconf-connector-cfg.yang @@ -0,0 +1,75 @@ +module odl-sal-netconf-connector-cfg { + yang-version 1; + namespace "urn:opendaylight:params:xml:ns:yang:controller:md:sal:connector:netconf"; + prefix "sal-netconf"; + + import config { prefix config; revision-date 2013-04-05; } + import threadpool {prefix th;} + import netty {prefix netty;} + import ietf-inet-types {prefix inet;} + import opendaylight-md-sal-dom {prefix dom;} + + description + "Service definition for Binding Aware MD-SAL."; + + revision "2013-10-28" { + description + "Initial revision"; + } + + identity sal-netconf-connector { + base config:module-type; + config:java-name-prefix NetconfConnector; + } + + + grouping server { + leaf address { + type string; + } + + leaf port { + type uint32; + } + } + + + augment "/config:modules/config:module/config:configuration" { + case sal-netconf-connector { + when "/config:modules/config:module/config:type = 'sal-netconf-connector'"; + + leaf address { + type string; + } + + leaf port { + type uint32; + } + + container dom-registry { + uses config:service-ref { + refine type { + mandatory true; + config:required-identity dom:dom-broker-osgi-registry; + } + } + } + + container boss-thread-group { + uses config:service-ref { + refine type { + config:required-identity netty:netty-threadgroup; + } + } + } + + container worker-thread-group { + uses config:service-ref { + refine type { + config:required-identity netty:netty-threadgroup; + } + } + } + } + } +} \ No newline at end of file diff --git a/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/rest/api/Draft01.java b/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/rest/api/Draft01.java new file mode 100644 index 0000000000..557adb6129 --- /dev/null +++ b/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/rest/api/Draft01.java @@ -0,0 +1,19 @@ +/* + * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ +package org.opendaylight.controller.sal.rest.api; + +public class Draft01 { + public static class MediaTypes { + public static final String API = "application/vnd.yang.api"; + public static final String DATASTORE = "application/vnd.yang.datastore"; + public static final String DATA = "application/vnd.yang.data"; + public static final String EVENT = "application/vnd.yang.event"; + public static final String OPERATION = "application/vnd.yang.operation"; + public static final String PATCH = "application/vnd.yang.patch"; + } +} diff --git a/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/rest/api/RestconfService.java b/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/rest/api/RestconfService.java index a22ea62397..5d08b3e7b6 100644 --- a/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/rest/api/RestconfService.java +++ b/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/rest/api/RestconfService.java @@ -7,14 +7,13 @@ */ package org.opendaylight.controller.sal.rest.api; -import static org.opendaylight.controller.sal.restconf.impl.MediaTypes.API; - import javax.ws.rs.GET; import javax.ws.rs.POST; import javax.ws.rs.PUT; import javax.ws.rs.Path; import javax.ws.rs.PathParam; import javax.ws.rs.Produces; +import javax.ws.rs.core.MediaType; import javax.ws.rs.core.Response; import org.opendaylight.controller.sal.restconf.impl.StructuredData; @@ -58,42 +57,51 @@ public interface RestconfService extends RestconfServiceLegacy { @GET @Path("/modules") - @Produces({API+JSON,API+XML}) + @Produces({Draft01.MediaTypes.API+JSON,Draft01.MediaTypes.API+XML, + Draft02.MediaTypes.API+JSON,Draft02.MediaTypes.API+XML}) public StructuredData getModules(); @POST @Path("/operations/{identifier}") - @Produces({Draft02.MediaTypes.API+JSON,Draft02.MediaTypes.API+XML,API+JSON,API+XML}) + @Produces({Draft01.MediaTypes.DATA+JSON,Draft01.MediaTypes.DATA+XML, + Draft02.MediaTypes.DATA+JSON,Draft02.MediaTypes.DATA+XML, + MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML, MediaType.TEXT_XML}) public StructuredData invokeRpc(@PathParam("identifier") String identifier, CompositeNode payload); @GET @Path("/config/{identifier:.+}") - @Produces({Draft02.MediaTypes.DATA+JSON,Draft02.MediaTypes.DATA+XML}) + @Produces({Draft02.MediaTypes.DATA+JSON,Draft02.MediaTypes.DATA+XML, + MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML, MediaType.TEXT_XML}) public StructuredData readConfigurationData(@PathParam("identifier") String identifier); - @PUT + @POST @Path("/config/{identifier:.+}") - @Produces({API+JSON,API+XML}) + @Produces({Draft02.MediaTypes.DATA+JSON,Draft02.MediaTypes.DATA+XML, + MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML, MediaType.TEXT_XML}) public Response createConfigurationData(@PathParam("identifier") String identifier, CompositeNode payload); - @POST + @PUT @Path("/config/{identifier:.+}") - @Produces({API+JSON,API+XML}) + @Produces({Draft02.MediaTypes.DATA+JSON,Draft02.MediaTypes.DATA+XML, + MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML, MediaType.TEXT_XML}) public Response updateConfigurationData(@PathParam("identifier") String identifier, CompositeNode payload); @GET @Path("/operational/{identifier:.+}") - @Produces({Draft02.MediaTypes.DATA+JSON,Draft02.MediaTypes.DATA+XML}) + @Produces({Draft02.MediaTypes.DATA+JSON,Draft02.MediaTypes.DATA+XML, + MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML, MediaType.TEXT_XML}) public StructuredData readOperationalData(@PathParam("identifier") String identifier); - @PUT + @POST @Path("/operational/{identifier:.+}") - @Produces({API+JSON,API+XML}) + @Produces({Draft02.MediaTypes.DATA+JSON,Draft02.MediaTypes.DATA+XML, + MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML, MediaType.TEXT_XML}) public Response createOperationalData(@PathParam("identifier") String identifier, CompositeNode payload); - @POST + @PUT @Path("/operational/{identifier:.+}") - @Produces({API+JSON,API+XML}) + @Produces({Draft02.MediaTypes.DATA+JSON,Draft02.MediaTypes.DATA+XML, + MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML, MediaType.TEXT_XML}) public Response updateOperationalData(@PathParam("identifier") String identifier, CompositeNode payload); } diff --git a/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/rest/api/RestconfServiceLegacy.java b/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/rest/api/RestconfServiceLegacy.java index 242e7f3150..35da98b1a0 100644 --- a/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/rest/api/RestconfServiceLegacy.java +++ b/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/rest/api/RestconfServiceLegacy.java @@ -1,13 +1,12 @@ package org.opendaylight.controller.sal.rest.api; -import static org.opendaylight.controller.sal.restconf.impl.MediaTypes.API; - import javax.ws.rs.GET; import javax.ws.rs.POST; import javax.ws.rs.PUT; import javax.ws.rs.Path; import javax.ws.rs.PathParam; import javax.ws.rs.Produces; +import javax.ws.rs.core.MediaType; import javax.ws.rs.core.Response; import org.opendaylight.controller.sal.restconf.impl.StructuredData; @@ -21,25 +20,28 @@ public interface RestconfServiceLegacy { @Deprecated @GET @Path("/datastore") - @Produces({API+JSON,API+XML}) + @Produces({Draft01.MediaTypes.DATASTORE+JSON,Draft01.MediaTypes.DATASTORE+XML}) public StructuredData readAllData(); @Deprecated @GET @Path("/datastore/{identifier:.+}") - @Produces({API+JSON,API+XML}) + @Produces({Draft01.MediaTypes.DATA+JSON,Draft01.MediaTypes.DATA+XML, + MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML, MediaType.TEXT_XML}) public StructuredData readData(@PathParam("identifier") String identifier); @Deprecated - @PUT + @POST @Path("/datastore/{identifier:.+}") - @Produces({API+JSON,API+XML}) + @Produces({Draft01.MediaTypes.DATA+JSON,Draft01.MediaTypes.DATA+XML, + MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML, MediaType.TEXT_XML}) public Response createConfigurationDataLegacy(@PathParam("identifier") String identifier, CompositeNode payload); @Deprecated - @POST + @PUT @Path("/datastore/{identifier:.+}") - @Produces({API+JSON,API+XML}) + @Produces({Draft01.MediaTypes.DATA+JSON,Draft01.MediaTypes.DATA+XML, + MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML, MediaType.TEXT_XML}) public Response updateConfigurationDataLegacy(@PathParam("identifier") String identifier, CompositeNode payload); } diff --git a/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/rest/impl/JsonMapper.java b/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/rest/impl/JsonMapper.java index 073b24e033..351ae6ebbe 100644 --- a/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/rest/impl/JsonMapper.java +++ b/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/rest/impl/JsonMapper.java @@ -7,9 +7,8 @@ import java.util.*; import javax.activation.UnsupportedDataTypeException; -import org.opendaylight.yangtools.yang.data.api.CompositeNode; -import org.opendaylight.yangtools.yang.data.api.Node; -import org.opendaylight.yangtools.yang.data.api.SimpleNode; +import org.opendaylight.controller.sal.restconf.impl.ControllerContext; +import org.opendaylight.yangtools.yang.data.api.*; import org.opendaylight.yangtools.yang.model.api.*; import org.opendaylight.yangtools.yang.model.api.type.*; @@ -103,14 +102,15 @@ class JsonMapper { } private void writeContainer(JsonWriter writer, CompositeNode node, ContainerSchemaNode schema) throws IOException { - writer.name(node.getNodeType().getLocalName()); + writeName(node, schema, writer); writer.beginObject(); writeChildrenOfParent(writer, node, schema); writer.endObject(); } - private void writeList(JsonWriter writer, CompositeNode nodeParent, CompositeNode node, ListSchemaNode schema) throws IOException { - writer.name(node.getNodeType().getLocalName()); + private void writeList(JsonWriter writer, CompositeNode nodeParent, CompositeNode node, ListSchemaNode schema) + throws IOException { + writeName(node, schema, writer); writer.beginArray(); if (nodeParent != null) { @@ -129,8 +129,9 @@ class JsonMapper { writer.endArray(); } - private void writeLeafList(JsonWriter writer, CompositeNode nodeParent, SimpleNode node, LeafListSchemaNode schema) throws IOException { - writer.name(node.getNodeType().getLocalName()); + private void writeLeafList(JsonWriter writer, CompositeNode nodeParent, SimpleNode node, + LeafListSchemaNode schema) throws IOException { + writeName(node, schema, writer); writer.beginArray(); List> nodeLeafLists = nodeParent.getSimpleNodesByName(node.getNodeType()); @@ -142,17 +143,14 @@ class JsonMapper { } private void writeLeaf(JsonWriter writer, SimpleNode node, LeafSchemaNode schema) throws IOException { - writer.name(node.getNodeType().getLocalName()); + writeName(node, schema, writer); writeValueOfNodeByType(writer, node, schema.getType()); } private void writeValueOfNodeByType(JsonWriter writer, SimpleNode node, TypeDefinition type) throws IOException { - if (!(node.getValue() instanceof String)) { - throw new IllegalStateException("Value in SimpleNode should be type String"); - } - String value = (String) node.getValue(); + String value = String.valueOf(node.getValue()); // TODO check Leafref, InstanceIdentifierTypeDefinition, // IdentityrefTypeDefinition, UnionTypeDefinition TypeDefinition baseType = resolveBaseTypeFrom(type); @@ -168,7 +166,7 @@ class JsonMapper { } else if (baseType instanceof EmptyTypeDefinition) { writeEmptyDataTypeToJson(writer); } else { - writer.value(value != null ? value : ""); + writer.value(value.equals("null") ? "" : value); } } @@ -244,6 +242,19 @@ class JsonMapper { return type.getBaseType() != null ? resolveBaseTypeFrom(type.getBaseType()) : type; } + private void writeName(Node node, DataSchemaNode schema, JsonWriter writer) throws IOException { + String nameForOutput = node.getNodeType().getLocalName(); + if (schema.isAugmenting()) { + ControllerContext contContext = ControllerContext.getInstance(); + CharSequence moduleName; + moduleName = contContext.toRestconfIdentifier(schema.getQName()); + if (moduleName != null) { + nameForOutput = moduleName.toString(); + } + } + writer.name(nameForOutput); + } + private static final class NumberForJsonWriter extends Number { private static final long serialVersionUID = -3147729419814417666L; diff --git a/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/rest/impl/JsonToCompositeNodeProvider.java b/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/rest/impl/JsonToCompositeNodeProvider.java index dea4a73cd1..2b1abaa987 100644 --- a/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/rest/impl/JsonToCompositeNodeProvider.java +++ b/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/rest/impl/JsonToCompositeNodeProvider.java @@ -1,7 +1,5 @@ package org.opendaylight.controller.sal.rest.impl; -import static org.opendaylight.controller.sal.restconf.impl.MediaTypes.API; - import java.io.IOException; import java.io.InputStream; import java.lang.annotation.Annotation; @@ -15,14 +13,17 @@ import javax.ws.rs.core.Response; import javax.ws.rs.ext.MessageBodyReader; import javax.ws.rs.ext.Provider; +import org.opendaylight.controller.sal.rest.api.Draft01; +import org.opendaylight.controller.sal.rest.api.Draft02; import org.opendaylight.controller.sal.rest.api.RestconfService; import org.opendaylight.yangtools.yang.data.api.CompositeNode; @Provider -@Consumes({API+RestconfService.JSON}) +@Consumes({ Draft01.MediaTypes.DATA + RestconfService.JSON, Draft02.MediaTypes.DATA + RestconfService.JSON, + MediaType.APPLICATION_JSON }) public enum JsonToCompositeNodeProvider implements MessageBodyReader { INSTANCE; - + @Override public boolean isReadable(Class type, Type genericType, Annotation[] annotations, MediaType mediaType) { return true; @@ -36,8 +37,8 @@ public enum JsonToCompositeNodeProvider implements MessageBodyReader { INSTANCE; - + @Override public boolean isWriteable(Class type, Type genericType, Annotation[] annotations, MediaType mediaType) { return true; diff --git a/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/rest/impl/StructuredDataToXmlProvider.java b/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/rest/impl/StructuredDataToXmlProvider.java index 9f41b571da..d0c0077952 100644 --- a/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/rest/impl/StructuredDataToXmlProvider.java +++ b/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/rest/impl/StructuredDataToXmlProvider.java @@ -1,7 +1,5 @@ package org.opendaylight.controller.sal.rest.impl; -import static org.opendaylight.controller.sal.restconf.impl.MediaTypes.API; - import java.io.IOException; import java.io.OutputStream; import java.lang.annotation.Annotation; @@ -21,7 +19,10 @@ import javax.xml.transform.TransformerFactory; import javax.xml.transform.dom.DOMSource; import javax.xml.transform.stream.StreamResult; +import org.opendaylight.controller.sal.rest.api.Draft01; +import org.opendaylight.controller.sal.rest.api.Draft02; import org.opendaylight.controller.sal.rest.api.RestconfService; +import org.opendaylight.controller.sal.restconf.impl.ResponseException; import org.opendaylight.controller.sal.restconf.impl.StructuredData; import org.opendaylight.yangtools.yang.data.api.CompositeNode; import org.opendaylight.yangtools.yang.data.impl.NodeUtils; @@ -30,10 +31,11 @@ import org.slf4j.LoggerFactory; import org.w3c.dom.Document; @Provider -@Produces({API+RestconfService.XML}) +@Produces({ Draft01.MediaTypes.DATA + RestconfService.XML, Draft02.MediaTypes.DATA + RestconfService.XML, + MediaType.APPLICATION_XML, MediaType.TEXT_XML }) public enum StructuredDataToXmlProvider implements MessageBodyWriter { INSTANCE; - + private final static Logger logger = LoggerFactory.getLogger(StructuredDataToXmlProvider.class); @Override @@ -52,9 +54,9 @@ public enum StructuredDataToXmlProvider implements MessageBodyWriter { INSTANCE; @@ -37,8 +39,7 @@ public enum XmlToCompositeNodeProvider implements MessageBodyReader { private def void checkPreconditions() { if (context === null || dataService === null) { - throw new WebApplicationException(Response.status(Response.Status.SERVICE_UNAVAILABLE) - .entity(RestconfProvider::NOT_INITALIZED_MSG).build()) + throw new ResponseException(Response.Status.SERVICE_UNAVAILABLE, RestconfProvider::NOT_INITALIZED_MSG) } } diff --git a/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/restconf/impl/ControllerContext.xtend b/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/restconf/impl/ControllerContext.xtend index c2b0ae8bdb..065d01e8e9 100644 --- a/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/restconf/impl/ControllerContext.xtend +++ b/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/restconf/impl/ControllerContext.xtend @@ -9,7 +9,6 @@ import java.util.HashMap import java.util.List import java.util.Map import java.util.concurrent.ConcurrentHashMap -import javax.ws.rs.WebApplicationException import javax.ws.rs.core.Response import org.opendaylight.controller.sal.core.api.model.SchemaServiceListener import org.opendaylight.controller.sal.rest.impl.RestconfProvider @@ -57,8 +56,7 @@ class ControllerContext implements SchemaServiceListener { private def void checkPreconditions() { if (schemas === null) { - throw new WebApplicationException(Response.status(Response.Status.SERVICE_UNAVAILABLE) - .entity(RestconfProvider::NOT_INITALIZED_MSG).build()) + throw new ResponseException(Response.Status.SERVICE_UNAVAILABLE, RestconfProvider::NOT_INITALIZED_MSG) } } @@ -196,6 +194,9 @@ class ControllerContext implements SchemaServiceListener { private def DataSchemaNode collectPathArguments(InstanceIdentifierBuilder builder, List strings, DataNodeContainer parentNode) { checkNotNull(strings) + if (parentNode === null) { + return null; + } if (strings.empty) { return parentNode as DataSchemaNode; } diff --git a/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/restconf/impl/MediaTypes.java b/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/restconf/impl/MediaTypes.java deleted file mode 100644 index af18828bfb..0000000000 --- a/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/restconf/impl/MediaTypes.java +++ /dev/null @@ -1,17 +0,0 @@ -/* - * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved. - * - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0 which accompanies this distribution, - * and is available at http://www.eclipse.org/legal/epl-v10.html - */ -package org.opendaylight.controller.sal.restconf.impl; - -public class MediaTypes { - public static final String API = "application/vnd.yang.api"; - public static final String DATASTORE = "application/vnd.yang.datastore"; - public static final String DATA = "application/vnd.yang.data"; - public static final String EVENT = "application/vnd.yang.event"; - public static final String OPERATION = "application/vnd.yang.operation"; - public static final String PATCH = "application/vnd.yang.patch"; -} diff --git a/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/restconf/impl/ResponseException.java b/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/restconf/impl/ResponseException.java new file mode 100644 index 0000000000..e2edd5dcb2 --- /dev/null +++ b/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/restconf/impl/ResponseException.java @@ -0,0 +1,15 @@ +package org.opendaylight.controller.sal.restconf.impl; + +import javax.ws.rs.WebApplicationException; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; +import javax.ws.rs.core.Response.Status; + +public class ResponseException extends WebApplicationException { + + private static final long serialVersionUID = -5320114450593021655L; + + public ResponseException(Status status, String msg) { + super(Response.status(status).type(MediaType.TEXT_PLAIN_TYPE).entity(msg).build()); + } +} diff --git a/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/restconf/impl/RestconfImpl.xtend b/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/restconf/impl/RestconfImpl.xtend index a4587fa787..8f6ca1685b 100644 --- a/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/restconf/impl/RestconfImpl.xtend +++ b/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/restconf/impl/RestconfImpl.xtend @@ -119,8 +119,7 @@ class RestconfImpl implements RestconfService { private def InstanceIdWithSchemaNode resolveInstanceIdentifier(String identifier) { val identifierWithSchemaNode = identifier.toInstanceIdentifier if (identifierWithSchemaNode === null) { - throw new WebApplicationException(Response.status(Response.Status.BAD_REQUEST).entity("URI has bad format") - .build()); + throw new ResponseException(Response.Status.BAD_REQUEST, "URI has bad format"); } return identifierWithSchemaNode } diff --git a/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/restconf/impl/StructuredData.java b/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/restconf/impl/StructuredData.java index 12f33d4562..62a9ae0581 100644 --- a/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/restconf/impl/StructuredData.java +++ b/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/restconf/impl/StructuredData.java @@ -1,13 +1,13 @@ package org.opendaylight.controller.sal.restconf.impl; import org.opendaylight.yangtools.yang.data.api.CompositeNode; -import org.opendaylight.yangtools.yang.model.api.DataSchemaNode; +import org.opendaylight.yangtools.yang.model.api.*; public class StructuredData { - + private final CompositeNode data; private final DataSchemaNode schema; - + public StructuredData(CompositeNode data, DataSchemaNode schema) { this.data = data; this.schema = schema; @@ -20,5 +20,4 @@ public class StructuredData { public DataSchemaNode getSchema() { return schema; } - } diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/TestUtils.java b/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/TestUtils.java index c43de5d9e8..bc941b997e 100644 --- a/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/TestUtils.java +++ b/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/TestUtils.java @@ -13,9 +13,7 @@ import java.util.*; import java.util.concurrent.Future; import javax.ws.rs.WebApplicationException; -import javax.xml.parsers.DocumentBuilder; -import javax.xml.parsers.DocumentBuilderFactory; -import javax.xml.parsers.ParserConfigurationException; +import javax.xml.parsers.*; import javax.xml.stream.XMLStreamException; import javax.xml.transform.*; import javax.xml.transform.dom.DOMSource; @@ -24,8 +22,7 @@ import javax.xml.transform.stream.StreamResult; import org.opendaylight.controller.md.sal.common.api.TransactionStatus; import org.opendaylight.controller.sal.rest.impl.StructuredDataToJsonProvider; import org.opendaylight.controller.sal.restconf.impl.*; -import org.opendaylight.yangtools.yang.common.QName; -import org.opendaylight.yangtools.yang.common.RpcResult; +import org.opendaylight.yangtools.yang.common.*; import org.opendaylight.yangtools.yang.data.api.*; import org.opendaylight.yangtools.yang.data.impl.XmlTreeBuilder; import org.opendaylight.yangtools.yang.model.api.*; @@ -99,7 +96,7 @@ final class TestUtils { } return (CompositeNode) dataTree; } - + public static Document loadDocumentFrom(InputStream inputStream) { try { DocumentBuilderFactory dbfac = DocumentBuilderFactory.newInstance(); @@ -135,6 +132,11 @@ final class TestUtils { } static String convertCompositeNodeDataAndYangToJson(CompositeNode compositeNode, String yangPath, String outputPath) { + return convertCompositeNodeDataAndYangToJson(compositeNode, yangPath, outputPath, null, null); + } + + static String convertCompositeNodeDataAndYangToJson(CompositeNode compositeNode, String yangPath, + String outputPath, String searchedModuleName, String searchedDataSchemaName) { String jsonResult = null; Set modules = null; @@ -145,30 +147,54 @@ final class TestUtils { } assertNotNull("modules can't be null.", modules); + Module module = null; + if (searchedModuleName != null) { + for (Module m : modules) { + if (m.getName().equals(searchedModuleName)) { + module = m; + break; + } + } + } else if (modules.size() == 1) { + module = modules.iterator().next(); + } + assertNotNull("Module is missing", module); + assertNotNull("Composite node can't be null", compositeNode); StructuredDataToJsonProvider structuredDataToJsonProvider = StructuredDataToJsonProvider.INSTANCE; - for (Module module : modules) { - ByteArrayOutputStream byteArrayOS = new ByteArrayOutputStream(); - for (DataSchemaNode dataSchemaNode : module.getChildNodes()) { - StructuredData structuredData = new StructuredData(compositeNode, dataSchemaNode); - try { - structuredDataToJsonProvider.writeTo(structuredData, null, null, null, null, null, byteArrayOS); - } catch (WebApplicationException | IOException e) { - e.printStackTrace(); + ByteArrayOutputStream byteArrayOS = new ByteArrayOutputStream(); + DataSchemaNode dataSchemaNode = null; + if (searchedDataSchemaName != null) { + for (DataSchemaNode dsn : module.getChildNodes()) { + if (dsn.getQName().getLocalName().equals(searchedDataSchemaName)) { + dataSchemaNode = dsn; } - assertFalse( - "Returning JSON string can't be empty for node " + dataSchemaNode.getQName().getLocalName(), - byteArrayOS.toString().isEmpty()); - } - jsonResult = byteArrayOS.toString(); - try { - outputToFile(byteArrayOS, outputPath); - } catch (IOException e) { - System.out.println("Output file wasn't cloased sucessfuly."); } + } else if (module.getChildNodes().size() == 1) { + dataSchemaNode = module.getChildNodes().iterator().next(); + } + assertNotNull(dataSchemaNode); + // SchemaContextUtil. + ControllerContext controllerContext = ControllerContext.getInstance(); + controllerContext.setSchemas(loadSchemaContext(modules)); + StructuredData structuredData = new StructuredData(compositeNode, dataSchemaNode); + try { + structuredDataToJsonProvider.writeTo(structuredData, null, null, null, null, null, byteArrayOS); + } catch (WebApplicationException | IOException e) { + e.printStackTrace(); } + assertFalse("Returning JSON string can't be empty for node " + dataSchemaNode.getQName().getLocalName(), + byteArrayOS.toString().isEmpty()); + + jsonResult = byteArrayOS.toString(); + try { + outputToFile(byteArrayOS, outputPath); + } catch (IOException e) { + System.out.println("Output file wasn't cloased sucessfuly."); + } + return jsonResult; } @@ -296,7 +322,8 @@ final class TestUtils { RpcResult rpcResult = DummyRpcResult.builder().result(TransactionStatus.COMMITED).build(); Future> future = DummyFuture.builder().rpcResult(rpcResult).build(); when(controllerContext.toInstanceIdentifier(any(String.class))).thenReturn(instIdAndSchema); - when(broker.commitConfigurationDataPut(any(InstanceIdentifier.class), any(CompositeNode.class))).thenReturn(future); + when(broker.commitConfigurationDataPut(any(InstanceIdentifier.class), any(CompositeNode.class))).thenReturn( + future); restconf.setControllerContext(controllerContext); restconf.setBroker(broker); diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/ToJsonWithAugmentTest.java b/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/ToJsonWithAugmentTest.java new file mode 100644 index 0000000000..994916dea5 --- /dev/null +++ b/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/ToJsonWithAugmentTest.java @@ -0,0 +1,27 @@ +package org.opendaylight.controller.sal.restconf.impl.test; + +import static org.junit.Assert.assertTrue; + +import org.junit.Test; + +public class ToJsonWithAugmentTest { + + /** + * Test of json output when as input are specified composite node with empty + * data + YANG file + */ + @Test + public void augmentedElementsToJson() { + String jsonOutput = TestUtils.convertCompositeNodeDataAndYangToJson( + TestUtils.loadCompositeNode("/yang-to-json-conversion/augmentation/xml/data.xml"), + "/yang-to-json-conversion/augmentation", "/yang-to-json-conversion/augmentation/xml", "yang", "cont"); + + assertTrue(jsonOutput.contains("\"augment-leaf:lf2\": \"lf2\"")); + assertTrue(jsonOutput.contains("\"augment-container:cont1\": {")); + assertTrue(jsonOutput.contains("\"augment-container:lf11\": \"lf11\"")); + assertTrue(jsonOutput.contains("\"augment-list:lst1\": [")); + assertTrue(jsonOutput.contains("\"augment-list:lf11\": \"lf1_1\"")); + assertTrue(jsonOutput.contains("\"augment-list:lf11\": \"lf1_2\"")); + assertTrue(jsonOutput.contains("\"augment-leaflist:lflst1\": [")); + } +} diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/XmlProvidersTest.java b/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/XmlProvidersTest.java index 015dfc8ad9..4336ac8a83 100644 --- a/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/XmlProvidersTest.java +++ b/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/XmlProvidersTest.java @@ -29,12 +29,12 @@ import org.junit.Before; import org.junit.BeforeClass; import org.junit.Test; import org.opendaylight.controller.md.sal.common.api.TransactionStatus; +import org.opendaylight.controller.sal.rest.api.Draft01; import org.opendaylight.controller.sal.rest.api.RestconfService; import org.opendaylight.controller.sal.rest.impl.StructuredDataToXmlProvider; import org.opendaylight.controller.sal.rest.impl.XmlToCompositeNodeProvider; import org.opendaylight.controller.sal.restconf.impl.BrokerFacade; import org.opendaylight.controller.sal.restconf.impl.ControllerContext; -import org.opendaylight.controller.sal.restconf.impl.MediaTypes; import org.opendaylight.controller.sal.restconf.impl.RestconfImpl; import org.opendaylight.yangtools.yang.common.RpcResult; import org.opendaylight.yangtools.yang.data.api.CompositeNode; @@ -49,7 +49,8 @@ public class XmlProvidersTest extends JerseyTest { private static ControllerContext controllerContext; private static BrokerFacade brokerFacade; private static RestconfImpl restconfImpl; - private static final MediaType MEDIA_TYPE = new MediaType("application", "vnd.yang.api+xml"); + private static final MediaType MEDIA_TYPE = new MediaType("application", "vnd.yang.data+xml"); + private static final MediaType MEDIA_TYPE_DRAFT02 = new MediaType("application", "yang.data+xml"); @BeforeClass public static void init() throws FileNotFoundException { @@ -87,11 +88,11 @@ public class XmlProvidersTest extends JerseyTest { public void testBadFormatXmlToCompositeNodeProvider() throws UnsupportedEncodingException, URISyntaxException { String uri = createUri("/operations/", "ietf-interfaces:interfaces/interface/eth0"); - Response response = target(uri).request(MediaTypes.API + RestconfService.XML).post( + Response response = target(uri).request(Draft01.MediaTypes.DATA + RestconfService.XML).post( Entity.entity("", MEDIA_TYPE)); assertEquals(400, response.getStatus()); - response = target(uri).request(MediaTypes.API + RestconfService.XML).post( + response = target(uri).request(Draft01.MediaTypes.DATA + RestconfService.XML).post( Entity.entity("", MEDIA_TYPE)); assertEquals(400, response.getStatus()); } @@ -102,7 +103,7 @@ public class XmlProvidersTest extends JerseyTest { when(brokerFacade.readOperationalData(any(InstanceIdentifier.class))).thenReturn(null); - Response response = target(uri).request(MediaTypes.API+RestconfService.XML).get(); + Response response = target(uri).request(Draft01.MediaTypes.DATA+RestconfService.XML).get(); assertEquals(404, response.getStatus()); } @@ -112,7 +113,7 @@ public class XmlProvidersTest extends JerseyTest { when(brokerFacade.readOperationalData(any(InstanceIdentifier.class))).thenReturn(null); - Response response = target(uri).request(MediaTypes.API+RestconfService.XML).get(); + Response response = target(uri).request(Draft01.MediaTypes.DATA+RestconfService.XML).get(); assertEquals(400, response.getStatus()); } @@ -120,51 +121,51 @@ public class XmlProvidersTest extends JerseyTest { public void testRpcResultCommitedToStatusCodes() throws UnsupportedEncodingException { InputStream xmlStream = RestconfImplTest.class.getResourceAsStream("/parts/ietf-interfaces_interfaces.xml"); String xml = TestUtils.getDocumentInPrintableForm(TestUtils.loadDocumentFrom(xmlStream)); - Entity entity = Entity.entity(xml, MEDIA_TYPE); + Entity entity = Entity.entity(xml, MEDIA_TYPE_DRAFT02); RpcResult rpcResult = DummyRpcResult.builder().result(TransactionStatus.COMMITED).build(); Future> dummyFuture = DummyFuture.builder().rpcResult(rpcResult).build(); when(brokerFacade.commitOperationalDataPut(any(InstanceIdentifier.class), any(CompositeNode.class))).thenReturn(dummyFuture); when(brokerFacade.commitConfigurationDataPut(any(InstanceIdentifier.class), any(CompositeNode.class))).thenReturn(dummyFuture); String uri = createUri("/config/", "ietf-interfaces:interfaces/interface/eth0"); - Response response = target(uri).request(MEDIA_TYPE).put(entity); - assertEquals(200, response.getStatus()); - response = target(uri).request(MEDIA_TYPE).post(entity); + Response response = target(uri).request(MEDIA_TYPE_DRAFT02).put(entity); assertEquals(204, response.getStatus()); + response = target(uri).request(MEDIA_TYPE_DRAFT02).post(entity); + assertEquals(200, response.getStatus()); uri = createUri("/operational/", "ietf-interfaces:interfaces/interface/eth0"); - response = target(uri).request(MEDIA_TYPE).put(entity); - assertEquals(200, response.getStatus()); - response = target(uri).request(MEDIA_TYPE).post(entity); + response = target(uri).request(MEDIA_TYPE_DRAFT02).put(entity); assertEquals(204, response.getStatus()); + response = target(uri).request(MEDIA_TYPE_DRAFT02).post(entity); + assertEquals(200, response.getStatus()); uri = createUri("/datastore/", "ietf-interfaces:interfaces/interface/eth0"); response = target(uri).request(MEDIA_TYPE).put(entity); - assertEquals(200, response.getStatus()); - response = target(uri).request(MEDIA_TYPE).post(entity); assertEquals(204, response.getStatus()); + response = target(uri).request(MEDIA_TYPE).post(entity); + assertEquals(200, response.getStatus()); } @Test public void testRpcResultOtherToStatusCodes() throws UnsupportedEncodingException { InputStream xmlStream = RestconfImplTest.class.getResourceAsStream("/parts/ietf-interfaces_interfaces.xml"); String xml = TestUtils.getDocumentInPrintableForm(TestUtils.loadDocumentFrom(xmlStream)); - Entity entity = Entity.entity(xml, MEDIA_TYPE); + Entity entity = Entity.entity(xml, MEDIA_TYPE_DRAFT02); RpcResult rpcResult = DummyRpcResult.builder().result(TransactionStatus.FAILED).build(); Future> dummyFuture = DummyFuture.builder().rpcResult(rpcResult).build(); when(brokerFacade.commitOperationalDataPut(any(InstanceIdentifier.class), any(CompositeNode.class))).thenReturn(dummyFuture); when(brokerFacade.commitConfigurationDataPut(any(InstanceIdentifier.class), any(CompositeNode.class))).thenReturn(dummyFuture); String uri = createUri("/config/", "ietf-interfaces:interfaces/interface/eth0"); - Response response = target(uri).request(MEDIA_TYPE).put(entity); + Response response = target(uri).request(MEDIA_TYPE_DRAFT02).put(entity); assertEquals(500, response.getStatus()); - response = target(uri).request(MEDIA_TYPE).post(entity); + response = target(uri).request(MEDIA_TYPE_DRAFT02).post(entity); assertEquals(500, response.getStatus()); uri = createUri("/operational/", "ietf-interfaces:interfaces/interface/eth0"); - response = target(uri).request(MEDIA_TYPE).put(entity); + response = target(uri).request(MEDIA_TYPE_DRAFT02).put(entity); assertEquals(500, response.getStatus()); - response = target(uri).request(MEDIA_TYPE).post(entity); + response = target(uri).request(MEDIA_TYPE_DRAFT02).post(entity); assertEquals(500, response.getStatus()); uri = createUri("/datastore/", "ietf-interfaces:interfaces/interface/eth0"); diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/resources/yang-to-json-conversion/augmentation/augment-container.yang b/opendaylight/md-sal/sal-rest-connector/src/test/resources/yang-to-json-conversion/augmentation/augment-container.yang new file mode 100644 index 0000000000..7efe4f75e9 --- /dev/null +++ b/opendaylight/md-sal/sal-rest-connector/src/test/resources/yang-to-json-conversion/augmentation/augment-container.yang @@ -0,0 +1,22 @@ +module augment-container { + namespace "ns:augment:container"; + prefix "augcont"; + + + import yang {prefix yng; revision-date 2013-11-26;} + + + revision "2013-11-26" { + } + + augment "/yng:cont" { + container cont1 { + leaf lf11 { + type string; + } + } + } + + + +} \ No newline at end of file diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/resources/yang-to-json-conversion/augmentation/augment-leaf.yang b/opendaylight/md-sal/sal-rest-connector/src/test/resources/yang-to-json-conversion/augmentation/augment-leaf.yang new file mode 100644 index 0000000000..248d3bb8b0 --- /dev/null +++ b/opendaylight/md-sal/sal-rest-connector/src/test/resources/yang-to-json-conversion/augmentation/augment-leaf.yang @@ -0,0 +1,18 @@ +module augment-leaf { + namespace "ns:augment:leaf"; + prefix "auglf"; + + + import yang {prefix yng; revision-date 2013-11-26;} + + + revision "2013-11-26" { + } + + augment "/yng:cont" { + leaf lf2 { + type string; + } + } + +} \ No newline at end of file diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/resources/yang-to-json-conversion/augmentation/augment-leaflist.yang b/opendaylight/md-sal/sal-rest-connector/src/test/resources/yang-to-json-conversion/augmentation/augment-leaflist.yang new file mode 100644 index 0000000000..1f4b93702f --- /dev/null +++ b/opendaylight/md-sal/sal-rest-connector/src/test/resources/yang-to-json-conversion/augmentation/augment-leaflist.yang @@ -0,0 +1,20 @@ +module augment-leaflist { + namespace "ns:augment:leaflist"; + prefix "auglflst"; + + + import yang {prefix yng; revision-date 2013-11-26;} + + + revision "2013-11-26" { + } + + augment "/yng:cont" { + leaf-list lflst1 { + type string; + } + } + + + +} \ No newline at end of file diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/resources/yang-to-json-conversion/augmentation/augment-list.yang b/opendaylight/md-sal/sal-rest-connector/src/test/resources/yang-to-json-conversion/augmentation/augment-list.yang new file mode 100644 index 0000000000..a35a87e90e --- /dev/null +++ b/opendaylight/md-sal/sal-rest-connector/src/test/resources/yang-to-json-conversion/augmentation/augment-list.yang @@ -0,0 +1,22 @@ +module augment-list { + namespace "ns:augment:list"; + prefix "auglst"; + + + import yang {prefix yng; revision-date 2013-11-26;} + + + revision "2013-11-26" { + } + + augment "/yng:cont" { + list lst1 { + leaf lf11 { + type string; + } + } + } + + + +} \ No newline at end of file diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/resources/yang-to-json-conversion/augmentation/xml/data.xml b/opendaylight/md-sal/sal-rest-connector/src/test/resources/yang-to-json-conversion/augmentation/xml/data.xml new file mode 100644 index 0000000000..08cdb34290 --- /dev/null +++ b/opendaylight/md-sal/sal-rest-connector/src/test/resources/yang-to-json-conversion/augmentation/xml/data.xml @@ -0,0 +1,16 @@ + + lf1 + lf2 + + lf11 + + + lf1_1 + + + lf1_2 + + lflst1_1 + lflst1_2 + lflst1_3 + \ No newline at end of file diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/resources/yang-to-json-conversion/augmentation/yang.yang b/opendaylight/md-sal/sal-rest-connector/src/test/resources/yang-to-json-conversion/augmentation/yang.yang new file mode 100644 index 0000000000..aeb973704d --- /dev/null +++ b/opendaylight/md-sal/sal-rest-connector/src/test/resources/yang-to-json-conversion/augmentation/yang.yang @@ -0,0 +1,17 @@ +module yang { + namespace "ns:yang"; + + prefix "yng"; + revision 2013-11-26 { + } + + container cont { + leaf lf1 { + type string; + } + + } + + + +} \ No newline at end of file diff --git a/opendaylight/md-sal/statistics-manager/src/main/java/org/opendaylight/controller/md/statistics/manager/StatisticsManagerActivator.java b/opendaylight/md-sal/statistics-manager/src/main/java/org/opendaylight/controller/md/statistics/manager/StatisticsManagerActivator.java index 7cbd2314b6..521de7e394 100644 --- a/opendaylight/md-sal/statistics-manager/src/main/java/org/opendaylight/controller/md/statistics/manager/StatisticsManagerActivator.java +++ b/opendaylight/md-sal/statistics-manager/src/main/java/org/opendaylight/controller/md/statistics/manager/StatisticsManagerActivator.java @@ -28,6 +28,7 @@ public class StatisticsManagerActivator extends AbstractBindingAwareProvider { @Override public void onSessionInitiated(ProviderContext session) { + pSession = session; DataProviderService dps = session.getSALService(DataProviderService.class); StatisticsManagerActivator.statsProvider.setDataService(dps); NotificationProviderService nps = session.getSALService(NotificationProviderService.class); diff --git a/opendaylight/md-sal/statistics-manager/src/main/java/org/opendaylight/controller/md/statistics/manager/StatisticsProvider.java b/opendaylight/md-sal/statistics-manager/src/main/java/org/opendaylight/controller/md/statistics/manager/StatisticsProvider.java index 5218d051fa..d1ab351503 100644 --- a/opendaylight/md-sal/statistics-manager/src/main/java/org/opendaylight/controller/md/statistics/manager/StatisticsProvider.java +++ b/opendaylight/md-sal/statistics-manager/src/main/java/org/opendaylight/controller/md/statistics/manager/StatisticsProvider.java @@ -100,8 +100,6 @@ public class StatisticsProvider implements AutoCloseable { public void run() { while(true){ try { - spLogger.info("Statistics requester thread started with timer interval : {}",5000); - statsRequestSender(); Thread.sleep(5000); @@ -111,6 +109,11 @@ public class StatisticsProvider implements AutoCloseable { } } }); + + spLogger.debug("Statistics requester thread started with timer interval : {}",5000); + + statisticsRequesterThread.start(); + spLogger.info("Statistics Provider started."); } @@ -124,6 +127,9 @@ public class StatisticsProvider implements AutoCloseable { //Need to call API to receive all the nodes connected to controller. List targetNodes = getAllConnectedNodes(); + + if(targetNodes == null) + return; for (Node targetNode : targetNodes){ spLogger.info("Send request for stats collection to node : {})",targetNode.getId()); @@ -212,6 +218,9 @@ public class StatisticsProvider implements AutoCloseable { private List getAllConnectedNodes(){ Nodes nodes = (Nodes) dps.readOperationalData(nodesIdentifier); + if(nodes == null) + return null; + spLogger.info("Number of connected nodes : {}",nodes.getNode().size()); return nodes.getNode(); } diff --git a/opendaylight/md-sal/test/sal-rest-connector-it/src/test/java/org/opendaylight/controller/test/restconf/it/ServiceProviderController.java b/opendaylight/md-sal/test/sal-rest-connector-it/src/test/java/org/opendaylight/controller/test/restconf/it/ServiceProviderController.java index 23ba8aaea4..41ae52b3bf 100644 --- a/opendaylight/md-sal/test/sal-rest-connector-it/src/test/java/org/opendaylight/controller/test/restconf/it/ServiceProviderController.java +++ b/opendaylight/md-sal/test/sal-rest-connector-it/src/test/java/org/opendaylight/controller/test/restconf/it/ServiceProviderController.java @@ -21,7 +21,6 @@ import org.junit.Test; import org.junit.runner.RunWith; import org.opendaylight.controller.sal.binding.api.BindingAwareBroker; import org.opendaylight.controller.sal.connect.netconf.InventoryUtils; -import org.opendaylight.controller.sal.connect.netconf.NetconfDeviceManager; import org.opendaylight.controller.sal.connect.netconf.NetconfInventoryUtils; import org.opendaylight.controller.sal.core.api.data.DataBrokerService; import org.opendaylight.controller.sal.core.api.mount.MountProvisionInstance; @@ -61,9 +60,6 @@ public class ServiceProviderController { @Inject DataBrokerService dataBroker; - @Inject - NetconfDeviceManager netconfManager; - @Test public void properInitialized() throws Exception { @@ -72,8 +68,6 @@ public class ServiceProviderController { InstanceIdentifier path = InstanceIdentifier.builder(InventoryUtils.INVENTORY_PATH) .nodeWithKey(InventoryUtils.INVENTORY_NODE, InventoryUtils.INVENTORY_ID, "foo").toInstance(); - netconfManager.netconfNodeAdded(path, new InetSocketAddress("127.0.0.1", 8383)); - InstanceIdentifier mountPointPath = path;