From: Madhu Venugopal Date: Thu, 9 Jan 2014 08:10:31 +0000 (+0000) Subject: Merge "Declare a urlPrefix for reuse in NorthboundIT." X-Git-Tag: jenkins-controller-bulk-release-prepare-only-2-1~122 X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?a=commitdiff_plain;h=79eba117e59f10c8bff34d0dd6bbb67b8ccc3e10;hp=9033401b967fd6e3de4ec2500c209aa46e4a6c05;p=controller.git Merge "Declare a urlPrefix for reuse in NorthboundIT." --- diff --git a/.gitreview b/.gitreview new file mode 100644 index 0000000000..5c4f71de40 --- /dev/null +++ b/.gitreview @@ -0,0 +1,4 @@ +[gerrit] +host=git.opendaylight.org +port=29418 +project=controller.git diff --git a/opendaylight/clustering/services_implementation/src/main/java/org/opendaylight/controller/clustering/services_implementation/internal/ClusterManager.java b/opendaylight/clustering/services_implementation/src/main/java/org/opendaylight/controller/clustering/services_implementation/internal/ClusterManager.java index fcf71a90ac..65e7720dd3 100644 --- a/opendaylight/clustering/services_implementation/src/main/java/org/opendaylight/controller/clustering/services_implementation/internal/ClusterManager.java +++ b/opendaylight/clustering/services_implementation/src/main/java/org/opendaylight/controller/clustering/services_implementation/internal/ClusterManager.java @@ -68,7 +68,7 @@ public class ClusterManager implements IClusterServices { private HashSet roleChangeListeners; private ViewChangedListener cacheManagerListener; - private static String loopbackAddress = "127.0.0.1"; + private static String loopbackAddress = InetAddress.getLoopbackAddress().getHostAddress(); // defaultTransactionTimeout is 60 seconds private static int DEFAULT_TRANSACTION_TIMEOUT = 60; diff --git a/opendaylight/clustering/stub/src/main/java/org/opendaylight/controller/clustering/stub/internal/ClusterManagerCommon.java b/opendaylight/clustering/stub/src/main/java/org/opendaylight/controller/clustering/stub/internal/ClusterManagerCommon.java index fe73e240f9..f27e6f069f 100644 --- a/opendaylight/clustering/stub/src/main/java/org/opendaylight/controller/clustering/stub/internal/ClusterManagerCommon.java +++ b/opendaylight/clustering/stub/src/main/java/org/opendaylight/controller/clustering/stub/internal/ClusterManagerCommon.java @@ -43,7 +43,7 @@ public abstract class ClusterManagerCommon implements IClusterServicesCommon { private ConcurrentMap> caches = new ConcurrentHashMap>(); protected ClusterManagerCommon() throws UnknownHostException { - loopbackAddress = InetAddress.getByName("127.0.0.1"); + loopbackAddress = InetAddress.getLoopbackAddress(); } /** diff --git a/opendaylight/commons/opendaylight/pom.xml b/opendaylight/commons/opendaylight/pom.xml index 5183165752..8933b1442f 100644 --- a/opendaylight/commons/opendaylight/pom.xml +++ b/opendaylight/commons/opendaylight/pom.xml @@ -46,7 +46,7 @@ org.openflow.openflowj,net.sf.jung2 1.0.9 1.7.2 - 1.9.8 + 2.3.0 3.1.3.RELEASE 3.1.3.RELEASE 1.2.1 @@ -95,12 +95,21 @@ 0.0.1-SNAPSHOT 4.0.10.Final 2.4 - - jacoco - java + 0.4.1-SNAPSHOT + 0.4.1-SNAPSHOT 0.5.0-SNAPSHOT 0.5.0-SNAPSHOT 0.5.0-SNAPSHOT + 0.4.1-SNAPSHOT + 0.4.1-SNAPSHOT + + 1.18-SNAPSHOT + 7.0.43-SNAPSHOT + + 0.4.1-SNAPSHOT + + jacoco + java 2.5.1 1.7 1.7 @@ -149,26 +158,43 @@ logback-classic ${logback.version} - - org.codehaus.jackson - jackson-mapper-asl - ${jackson.version} - - - org.codehaus.jackson - jackson-core-asl + + + com.fasterxml.jackson.core + jackson-annotations + ${jackson.version} + + + + com.fasterxml.jackson.core + jackson-core + ${jackson.version} + + + + com.fasterxml.jackson.core + jackson-databind + ${jackson.version} + + + + com.fasterxml.jackson.jaxrs + jackson-jaxrs-base ${jackson.version} - - - org.codehaus.jackson - jackson-jaxrs + + + + com.fasterxml.jackson.jaxrs + jackson-jaxrs-json-provider ${jackson.version} - - - org.codehaus.jackson - jackson-xc + + + + com.fasterxml.jackson.module + jackson-module-jaxb-annotations ${jackson.version} - + + org.codehaus.jettison jettison @@ -577,11 +603,7 @@ jersey-client ${jersey.version} - - com.sun.jersey - jersey-json - ${jersey.version} - + org.ow2.asm asm-all @@ -621,12 +643,12 @@ org.opendaylight.controller.thirdparty com.sun.jersey.jersey-servlet - 1.17 + ${jersey-servlet.version} org.opendaylight.controller.thirdparty org.apache.catalina.filters.CorsFilter - 7.0.42 + ${corsfilter.version} org.opendaylight.controller.thirdparty @@ -726,7 +748,7 @@ org.opendaylight.controller switchmanager - 0.5.1-SNAPSHOT + ${switchmanager.api.version} diff --git a/opendaylight/config/config-manager/src/test/java/org/opendaylight/controller/config/manager/impl/AbstractConfigTest.java b/opendaylight/config/config-manager/src/test/java/org/opendaylight/controller/config/manager/impl/AbstractConfigTest.java index 81b0921660..028d7d1f40 100644 --- a/opendaylight/config/config-manager/src/test/java/org/opendaylight/controller/config/manager/impl/AbstractConfigTest.java +++ b/opendaylight/config/config-manager/src/test/java/org/opendaylight/controller/config/manager/impl/AbstractConfigTest.java @@ -8,7 +8,6 @@ package org.opendaylight.controller.config.manager.impl; import com.google.common.base.Preconditions; -import com.google.common.collect.Maps; import junit.framework.Assert; import org.junit.After; import org.mockito.Matchers; @@ -26,6 +25,8 @@ import org.opendaylight.controller.config.util.ConfigRegistryJMXClient; import org.opendaylight.controller.config.util.ConfigTransactionJMXClient; import org.osgi.framework.BundleContext; import org.osgi.framework.ServiceRegistration; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import javax.management.InstanceAlreadyExistsException; import javax.management.MBeanServer; @@ -38,7 +39,6 @@ import java.util.Collection; import java.util.Collections; import java.util.Dictionary; import java.util.List; -import java.util.Map; import java.util.Set; import static org.junit.Assert.assertEquals; @@ -66,8 +66,16 @@ public abstract class AbstractConfigTest extends protected BundleContext mockedContext = mock(BundleContext.class); protected ServiceRegistration mockedServiceRegistration; - protected Map getBundleContextServiceRegistrationHandlers() { - return Maps.newHashMap(); + private static final Logger logger = LoggerFactory.getLogger(AbstractConfigTest.class); + + // Default handler for OSGi service registration + private static final BundleContextServiceRegistrationHandler noopServiceRegHandler = new BundleContextServiceRegistrationHandler() { + @Override + public void handleServiceRegistration(Object serviceInstance) {} + }; + + protected BundleContextServiceRegistrationHandler getBundleContextServiceRegistrationHandler(Class serviceType) { + return noopServiceRegHandler; } // this method should be called in @Before @@ -166,9 +174,8 @@ public abstract class AbstractConfigTest extends protected ObjectName createTestConfigBean( ConfigTransactionJMXClient transaction, String implementationName, String name) throws InstanceAlreadyExistsException { - ObjectName nameCreated = transaction.createModule(implementationName, + return transaction.createModule(implementationName, name); - return nameCreated; } protected void assertBeanCount(int i, String configMXBeanName) { @@ -204,26 +211,42 @@ public abstract class AbstractConfigTest extends } private class RegisterServiceAnswer implements Answer { + @Override public Object answer(InvocationOnMock invocation) throws Throwable { Object[] args = invocation.getArguments(); - Preconditions.checkArgument(args.length == 3); + Preconditions.checkArgument(args.length == 3, "Unexpected arguments size (expected 3 was %s)", args.length); - Preconditions.checkArgument(args[0] instanceof Class); - Class serviceType = (Class) args[0]; + Object serviceTypeRaw = args[0]; Object serviceInstance = args[1]; - BundleContextServiceRegistrationHandler serviceRegistrationHandler = getBundleContextServiceRegistrationHandlers() - .get(serviceType); + if (serviceTypeRaw instanceof Class) { + Class serviceType = (Class) serviceTypeRaw; + invokeServiceHandler(serviceInstance, serviceType); + + } else if(serviceTypeRaw instanceof String[]) { + for (String className : (String[]) serviceTypeRaw) { + try { + Class serviceType = Class.forName(className); + invokeServiceHandler(serviceInstance, serviceType); + } catch (ClassNotFoundException e) { + logger.warn("Not handling service registration of type {} ", className, e); + } + } - Preconditions.checkArgument(serviceType.isAssignableFrom(serviceInstance.getClass())); + } else + logger.debug("Not handling service registration of type {}, Unknown type", serviceTypeRaw); + + return mockedServiceRegistration; + } + + private void invokeServiceHandler(Object serviceInstance, Class serviceType) { + BundleContextServiceRegistrationHandler serviceRegistrationHandler = getBundleContextServiceRegistrationHandler(serviceType); if (serviceRegistrationHandler != null) { serviceRegistrationHandler.handleServiceRegistration(serviceType.cast(serviceInstance)); } - - return mockedServiceRegistration; } } } diff --git a/opendaylight/config/pom.xml b/opendaylight/config/pom.xml index eba5e07c0f..9f9bca9d98 100644 --- a/opendaylight/config/pom.xml +++ b/opendaylight/config/pom.xml @@ -61,7 +61,7 @@ 1.7 1.7 4.10 - 2.3.7 + 2.4.0 5.0.0 0.6.2.201302030002 1.7.2 diff --git a/opendaylight/config/yang-store-impl/src/main/java/org/opendaylight/controller/config/yang/store/impl/ExtenderYangTracker.java b/opendaylight/config/yang-store-impl/src/main/java/org/opendaylight/controller/config/yang/store/impl/ExtenderYangTracker.java index 9356dd3752..0d704a8f6a 100644 --- a/opendaylight/config/yang-store-impl/src/main/java/org/opendaylight/controller/config/yang/store/impl/ExtenderYangTracker.java +++ b/opendaylight/config/yang-store-impl/src/main/java/org/opendaylight/controller/config/yang/store/impl/ExtenderYangTracker.java @@ -186,7 +186,15 @@ public class ExtenderYangTracker extends BundleTracker implements YangSt yangStoreSnapshot.countModuleMXBeanEntries(), multimap.values().size()); return yangStoreSnapshot; } catch (RuntimeException e) { - throw new YangStoreException("Unable to parse yang files from following URLs: " + multimap, e); + StringBuffer causeStr = new StringBuffer(); + Throwable cause = e; + while (cause != null) { + causeStr.append(e.getMessage()); + causeStr.append("\n"); + cause = e.getCause(); + } + throw new YangStoreException("Unable to parse yang files. \n" + causeStr.toString() + + "URLs: " + multimap, e); } } diff --git a/opendaylight/containermanager/api/src/main/java/org/opendaylight/controller/containermanager/ContainerFlowConfig.java b/opendaylight/containermanager/api/src/main/java/org/opendaylight/controller/containermanager/ContainerFlowConfig.java index 9740a92598..9d65ad343c 100644 --- a/opendaylight/containermanager/api/src/main/java/org/opendaylight/controller/containermanager/ContainerFlowConfig.java +++ b/opendaylight/containermanager/api/src/main/java/org/opendaylight/controller/containermanager/ContainerFlowConfig.java @@ -15,7 +15,9 @@ import java.net.Inet6Address; import java.net.InetAddress; import java.net.UnknownHostException; import java.util.ArrayList; +import java.util.HashSet; import java.util.List; +import java.util.Set; import javax.xml.bind.annotation.XmlAccessType; import javax.xml.bind.annotation.XmlAccessorType; @@ -308,9 +310,10 @@ public class ContainerFlowConfig implements Serializable { } /** - * Match Source IP Address. + * Match the set of these vlans with that of flowSpec's vlans. * - * @param flowSpec Flow Specification + * @param flowSpec + * Flow Specification * @return true, if successful */ private boolean matchDlVlan(ContainerFlowConfig flowSpec) { @@ -320,7 +323,8 @@ public class ContainerFlowConfig implements Serializable { if (dlVlan == null || flowSpec.dlVlan == null) { return false; } - return dlVlan.equals(flowSpec.dlVlan); + + return this.getVlanList().equals(flowSpec.getVlanList()); } /** @@ -404,18 +408,34 @@ public class ContainerFlowConfig implements Serializable { } /** - * Returns the vlan id number + * Returns the vlan id number for all vlans specified * - * @return the vlan id number + * @return the vlan id number for all vlans specified */ - public Short getVlanId() { - Short vlan = 0; + public Set getVlanList() { + /* + * example: Vlan = "1,3,5-12" + * elemArray = ["1" "3" "5-12"] + * elem[2] = "5-12" --> limits = ["5" "12"] + * vlanList = [1 3 5 6 7 8 9 10 11 12] + */ + Set vlanList = new HashSet(); try { - vlan = Short.parseShort(dlVlan); + String[] elemArray = dlVlan.split(","); + for (String elem : elemArray) { + if (elem.contains("-")) { + String[] limits = elem.split("-"); + for (short j = Short.valueOf(limits[0]); j <= Short.valueOf(limits[1]); j++) { + vlanList.add(Short.valueOf(j)); + } + } else { + vlanList.add(Short.valueOf(elem)); + } + } } catch (NumberFormatException e) { } - return vlan; + return vlanList; } /** @@ -617,13 +637,25 @@ public class ContainerFlowConfig implements Serializable { if (dlVlan != null) { short vlanId = 0; try { - vlanId = Short.parseShort(dlVlan); + String[] elemArray = dlVlan.split(","); + for (String elem : elemArray) { + if (elem.contains("-")) { + String[] limits = elem.split("-"); + if (Short.parseShort(limits[0]) < 0 + || Short.parseShort(limits[0]) >= Short.parseShort(limits[1]) + || Short.parseShort(limits[1]) > 0xfff) { + return new Status(StatusCode.BADREQUEST, "Invalid vlan id"); + } + } else { + vlanId = Short.parseShort(elem); + if (vlanId < 0 || vlanId > 0xfff) { + return new Status(StatusCode.BADREQUEST, "Invalid vlan id"); + } + } + } } catch (NumberFormatException e) { return new Status(StatusCode.BADREQUEST, "Invalid vlan id"); } - if (vlanId < 0 || vlanId > 0xfff) { - return new Status(StatusCode.BADREQUEST, "Invalid vlan id"); - } } return new Status(StatusCode.SUCCESS); } @@ -706,20 +738,46 @@ public class ContainerFlowConfig implements Serializable { /** * Returns the matches. - * If unidirectional flag is set, there will be only one match in the list - * If unidirectional flag is unset there will be two matches in the list, + * If unidirectional flag is set, there will be only one match per vlan in the list + * If unidirectional flag is unset there will be two matches per vlan in the list, * only if the specified flow has an intrinsic direction. * For Ex. if the cFlow only has the protocol field configured, no matter - * if unidirectional flag is set or not, only one match will be returned + * if unidirectional flag is set or not, only one match per vlan will be returned * The client just has to iterate over the returned list * @return the matches */ public List getMatches() { List matches = new ArrayList(); - Match match = new Match(); if (this.dlVlan != null && !this.dlVlan.isEmpty()) { - match.setField(MatchType.DL_VLAN, this.getVlanId()); + for(Short vlan:getVlanList()){ + Match match = getMatch(vlan); + matches.add(match); + } + } + else{ + Match match = getMatch(null); + matches.add(match); + } + + if (!ContainerFlowConfig.unidirectional) { + List forwardMatches = new ArrayList(matches); + for (Match match : forwardMatches) { + Match reverse = match.reverse(); + if (!match.equals(reverse)) { + matches.add(reverse); + } + } + } + + return matches; + } + + private Match getMatch(Short vlan){ + Match match = new Match(); + + if (vlan != null) { + match.setField(MatchType.DL_VLAN, vlan); } if (this.nwSrc != null && !this.nwSrc.trim().isEmpty()) { String parts[] = this.nwSrc.split("/"); @@ -756,15 +814,7 @@ public class ContainerFlowConfig implements Serializable { if (this.tpDst != null && !this.tpDst.trim().isEmpty()) { match.setField(MatchType.TP_DST, Integer.valueOf(tpDst).shortValue()); } - - matches.add(match); - if(!ContainerFlowConfig.unidirectional) { - Match reverse = match.reverse(); - if (!match.equals(reverse)) { - matches.add(reverse); - } - } - return matches; + return match; } /* diff --git a/opendaylight/distribution/opendaylight/opendaylight.target b/opendaylight/distribution/opendaylight/opendaylight.target index e3d1e5275d..7ae309cce4 100644 --- a/opendaylight/distribution/opendaylight/opendaylight.target +++ b/opendaylight/distribution/opendaylight/opendaylight.target @@ -51,7 +51,6 @@ - diff --git a/opendaylight/distribution/opendaylight/pom.xml b/opendaylight/distribution/opendaylight/pom.xml index b0f7ad89a4..6fca9db636 100644 --- a/opendaylight/distribution/opendaylight/pom.xml +++ b/opendaylight/distribution/opendaylight/pom.xml @@ -134,6 +134,31 @@ forwardingrules-manager ${mdsal.version} + + org.opendaylight.controller.md + topology-lldp-discovery + ${mdsal.version} + + + org.opendaylight.controller.md + topology-manager + ${mdsal.version} + + + org.opendaylight.controller.model + model-topology + 1.0-SNAPSHOT + + + org.opendaylight.yangtools.model + ietf-topology + 2013.07.12.2-SNAPSHOT + + + org.opendaylight.controller + sal-binding-util + 1.0-SNAPSHOT + org.opendaylight.controller.md statistics-manager @@ -903,22 +928,37 @@ ch.qos.logback logback-classic + - org.codehaus.jackson - jackson-mapper-asl + com.fasterxml.jackson.core + jackson-databind + - org.codehaus.jackson - jackson-core-asl + com.fasterxml.jackson.core + jackson-annotations + - org.codehaus.jackson - jackson-jaxrs + com.fasterxml.jackson.core + jackson-core + + + com.fasterxml.jackson.jaxrs + jackson-jaxrs-json-provider + + + + com.fasterxml.jackson.jaxrs + jackson-jaxrs-base + + - org.codehaus.jackson - jackson-xc + com.fasterxml.jackson.module + jackson-module-jaxb-annotations + org.codehaus.jettison jettison @@ -1244,11 +1284,7 @@ com.sun.jersey jersey-client - - com.sun.jersey - jersey-json - ${jersey.version} - + org.ow2.asm asm-all diff --git a/opendaylight/distribution/opendaylight/src/assemble/bin.xml b/opendaylight/distribution/opendaylight/src/assemble/bin.xml index 8fea175614..6f8878bee9 100644 --- a/opendaylight/distribution/opendaylight/src/assemble/bin.xml +++ b/opendaylight/distribution/opendaylight/src/assemble/bin.xml @@ -24,7 +24,6 @@ ch.qos.logback:logback-core ch.qos.logback:logback-classic com.sun.jersey:jersey-core - com.sun.jersey:jersey-json com.sun.jersey:jersey-server org.opendaylight.controller:logging.bridge org.opendaylight.controller:sanitytest @@ -52,7 +51,6 @@ ch.qos.logback:logback-core ch.qos.logback:logback-classic com.sun.jersey:jersey-core - com.sun.jersey:jersey-json com.sun.jersey:jersey-server org.opendaylight.controller:logging.bridge diff --git a/opendaylight/netconf/netconf-ssh/src/main/resources/RSA.pk b/opendaylight/distribution/opendaylight/src/main/resources/configuration/RSA.pk similarity index 100% rename from opendaylight/netconf/netconf-ssh/src/main/resources/RSA.pk rename to opendaylight/distribution/opendaylight/src/main/resources/configuration/RSA.pk diff --git a/opendaylight/distribution/opendaylight/src/main/resources/configuration/config.ini b/opendaylight/distribution/opendaylight/src/main/resources/configuration/config.ini index ba5d862c57..995e4076c2 100644 --- a/opendaylight/distribution/opendaylight/src/main/resources/configuration/config.ini +++ b/opendaylight/distribution/opendaylight/src/main/resources/configuration/config.ini @@ -10,7 +10,6 @@ osgi.bundles=\ reference\:file\:../lib/logback-core-1.0.9.jar@1:start,\ reference\:file\:../lib/logging.bridge-0.4.1-SNAPSHOT@1:start,\ reference\:file\:../lib/jersey-core-1.17.jar@2:start,\ - reference\:file\:../lib/jersey-json-1.17.jar@2:start,\ reference\:file\:../lib/jersey-server-1.17.jar@2:start # Netconf startup configuration @@ -22,6 +21,8 @@ netconf.tcp.client.port=8383 netconf.ssh.address=0.0.0.0 netconf.ssh.port=1830 +netconf.ssh.pk.path = ./configuration/RSA.pk + netconf.config.persister.active=1,2 # read startup configuration diff --git a/opendaylight/hosttracker/implementation/src/test/java/org/opendaylight/controller/hosttracker/internal/HostTrackerTest.java b/opendaylight/hosttracker/implementation/src/test/java/org/opendaylight/controller/hosttracker/internal/HostTrackerTest.java index d7c60e67a9..e222fcd7e4 100644 --- a/opendaylight/hosttracker/implementation/src/test/java/org/opendaylight/controller/hosttracker/internal/HostTrackerTest.java +++ b/opendaylight/hosttracker/implementation/src/test/java/org/opendaylight/controller/hosttracker/internal/HostTrackerTest.java @@ -25,7 +25,6 @@ public class HostTrackerTest extends TestCase { HostTracker hostTracker = null; hostTracker = new HostTracker(); - Assert.assertFalse(hostTracker == null); InetAddress hostIP = InetAddress.getByName("192.168.0.8"); IHostId id = IPHostId.fromIP(hostIP); @@ -44,7 +43,6 @@ public class HostTrackerTest extends TestCase { public void testHostTracker() throws UnknownHostException { HostTracker hostTracker = null; hostTracker = new HostTracker(); - Assert.assertFalse(hostTracker == null); InetAddress hostIP_1 = InetAddress.getByName("192.168.0.8"); IHostId id1 = IPHostId.fromIP(hostIP_1); diff --git a/opendaylight/md-sal/compatibility/inventory-topology-compatibility/src/main/java/org/opendaylight/controller/md/compatibility/switchmanager/CompatibleSwitchManager.xtend b/opendaylight/md-sal/compatibility/inventory-topology-compatibility/src/main/java/org/opendaylight/controller/md/compatibility/switchmanager/CompatibleSwitchManager.xtend index 430b5957ef..62e767b8da 100644 --- a/opendaylight/md-sal/compatibility/inventory-topology-compatibility/src/main/java/org/opendaylight/controller/md/compatibility/switchmanager/CompatibleSwitchManager.xtend +++ b/opendaylight/md-sal/compatibility/inventory-topology-compatibility/src/main/java/org/opendaylight/controller/md/compatibility/switchmanager/CompatibleSwitchManager.xtend @@ -225,7 +225,7 @@ class CompatibleSwitchManager extends ConfigurableSwitchManager implements ISwit val ret = new HashSet(); for (nc : data.nodeConnector) { val flowConn = nc.getAugmentation(FlowCapableNodeConnector); - if (flowConn != null && flowConn.state == PortState.Live) { + if (flowConn != null && flowConn.state != null && !flowConn.state.linkDown) { ret.add(new NodeConnector(MD_SAL_TYPE, nc.key, node)); } } diff --git a/opendaylight/md-sal/compatibility/sal-compatibility/pom.xml b/opendaylight/md-sal/compatibility/sal-compatibility/pom.xml index 15a9a689b3..f72e5b9bfa 100644 --- a/opendaylight/md-sal/compatibility/sal-compatibility/pom.xml +++ b/opendaylight/md-sal/compatibility/sal-compatibility/pom.xml @@ -20,6 +20,16 @@ model-flow-statistics 1.0-SNAPSHOT + + org.opendaylight.controller.model + model-topology + 1.0-SNAPSHOT + + + org.opendaylight.controller + sal-binding-util + 1.0-SNAPSHOT + bundle diff --git a/opendaylight/md-sal/compatibility/sal-compatibility/src/main/java/org/opendaylight/controller/sal/compatibility/ComponentActivator.xtend b/opendaylight/md-sal/compatibility/sal-compatibility/src/main/java/org/opendaylight/controller/sal/compatibility/ComponentActivator.xtend index 95acbcdb13..d7a345cfc8 100644 --- a/opendaylight/md-sal/compatibility/sal-compatibility/src/main/java/org/opendaylight/controller/sal/compatibility/ComponentActivator.xtend +++ b/opendaylight/md-sal/compatibility/sal-compatibility/src/main/java/org/opendaylight/controller/sal/compatibility/ComponentActivator.xtend @@ -1,37 +1,41 @@ package org.opendaylight.controller.sal.compatibility -import org.opendaylight.controller.sal.core.ComponentActivatorAbstractBase -import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeKey -import org.opendaylight.controller.sal.core.Node -import org.opendaylight.controller.sal.core.NodeConnector -import static org.opendaylight.controller.sal.compatibility.NodeMapping.* -import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnectorKey -import org.apache.felix.dm.Component import java.util.Arrays import java.util.Dictionary import java.util.Hashtable -import org.opendaylight.controller.sal.utils.GlobalConstants +import org.apache.felix.dm.Component import org.opendaylight.controller.sal.binding.api.BindingAwareBroker -import org.opendaylight.controller.sal.flowprogrammer.IPluginInFlowProgrammerService -import org.opendaylight.controller.sal.inventory.IPluginInInventoryService -import org.opendaylight.controller.sal.reader.IPluginInReadService -import org.opendaylight.controller.sal.flowprogrammer.IPluginOutFlowProgrammerService -import org.opendaylight.controller.sal.binding.api.BindingAwareConsumer import org.opendaylight.controller.sal.binding.api.BindingAwareBroker.ConsumerContext -import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.SalFlowService +import org.opendaylight.controller.sal.binding.api.BindingAwareConsumer import org.opendaylight.controller.sal.binding.api.NotificationService import org.opendaylight.controller.sal.binding.api.data.DataBrokerService -import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.OpendaylightFlowStatisticsService +import org.opendaylight.controller.sal.binding.api.data.DataProviderService +import org.opendaylight.controller.sal.compatibility.topology.TopologyAdapter +import org.opendaylight.controller.sal.core.ComponentActivatorAbstractBase +import org.opendaylight.controller.sal.core.Node +import org.opendaylight.controller.sal.core.NodeConnector +import org.opendaylight.controller.sal.discovery.IDiscoveryService +import org.opendaylight.controller.sal.flowprogrammer.IPluginInFlowProgrammerService +import org.opendaylight.controller.sal.flowprogrammer.IPluginOutFlowProgrammerService +import org.opendaylight.controller.sal.inventory.IPluginInInventoryService +import org.opendaylight.controller.sal.inventory.IPluginOutInventoryService import org.opendaylight.controller.sal.packet.IPluginOutDataPacketService -import org.osgi.framework.BundleContext +import org.opendaylight.controller.sal.reader.IPluginInReadService import org.opendaylight.controller.sal.reader.IPluginOutReadService -import org.opendaylight.controller.sal.inventory.IPluginOutInventoryService -import org.opendaylight.controller.sal.discovery.IDiscoveryService +import org.opendaylight.controller.sal.topology.IPluginInTopologyService import org.opendaylight.controller.sal.topology.IPluginOutTopologyService -import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.topology.discovery.rev130819.FlowTopologyDiscoveryService +import org.opendaylight.controller.sal.utils.GlobalConstants +import org.opendaylight.controller.sal.utils.INodeConnectorFactory +import org.opendaylight.controller.sal.utils.INodeFactory +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.SalFlowService +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.OpendaylightFlowStatisticsService import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.table.statistics.rev131215.OpendaylightFlowTableStatisticsService +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.topology.discovery.rev130819.FlowTopologyDiscoveryService import org.opendaylight.yang.gen.v1.urn.opendaylight.port.statistics.rev131214.OpendaylightPortStatisticsService -import org.opendaylight.controller.sal.binding.api.data.DataProviderService +import org.osgi.framework.BundleContext + +import static org.opendaylight.controller.sal.compatibility.NodeMapping.* +import org.opendaylight.controller.sal.compatibility.topology.TopologyProvider class ComponentActivator extends ComponentActivatorAbstractBase implements BindingAwareConsumer { @@ -47,10 +51,16 @@ class ComponentActivator extends ComponentActivatorAbstractBase implements Bindi DataPacketAdapter dataPacket = new DataPacketAdapter; @Property - org.opendaylight.controller.sal.utils.INodeFactory nodeFactory = new MDSalNodeFactory + INodeFactory nodeFactory = new MDSalNodeFactory @Property - org.opendaylight.controller.sal.utils.INodeConnectorFactory nodeConnectorFactory = new MDSalNodeConnectorFactory + INodeConnectorFactory nodeConnectorFactory = new MDSalNodeConnectorFactory + + @Property + TopologyAdapter topology = new TopologyAdapter + + @Property + TopologyProvider tpProvider = new TopologyProvider() override protected init() { @@ -72,6 +82,7 @@ class ComponentActivator extends ComponentActivatorAbstractBase implements Bindi // Registration of Flow Service flow.delegate = session.getRpcService(SalFlowService) + flow.dataBrokerService = session.getSALService(DataBrokerService); subscribe.registerNotificationListener(flow); // Data Packet Service @@ -84,13 +95,16 @@ class ComponentActivator extends ComponentActivatorAbstractBase implements Bindi inventory.nodeConnectorStatisticsService = session.getRpcService(OpendaylightPortStatisticsService); inventory.topologyDiscovery = session.getRpcService(FlowTopologyDiscoveryService); inventory.dataProviderService = session.getSALService(DataProviderService) + topology.dataService = session.getSALService(DataProviderService) + tpProvider.dataService = session.getSALService(DataProviderService) + tpProvider.start(); subscribe.registerNotificationListener(dataPacket) } override protected getGlobalImplementations() { - return Arrays.asList(this, flow, inventory, dataPacket, nodeFactory, nodeConnectorFactory) + return Arrays.asList(this, flow, inventory, dataPacket, nodeFactory, nodeConnectorFactory,topology,tpProvider) } override protected configureGlobalInstance(Component c, Object imp) { @@ -98,11 +112,11 @@ class ComponentActivator extends ComponentActivatorAbstractBase implements Bindi } private def dispatch configure(MDSalNodeFactory imp, Component it) { - setInterface(org.opendaylight.controller.sal.utils.INodeFactory.name, properties); + setInterface(INodeFactory.name, properties); } private def dispatch configure(MDSalNodeConnectorFactory imp, Component it) { - setInterface(org.opendaylight.controller.sal.utils.INodeConnectorFactory.name, properties); + setInterface(INodeConnectorFactory.name, properties); } private def dispatch configure(ComponentActivator imp, Component it) { @@ -143,17 +157,29 @@ class ComponentActivator extends ComponentActivatorAbstractBase implements Bindi .setService(IPluginOutInventoryService) // .setCallbacks("setInventoryPublisher", "setInventoryPublisher") // .setRequired(false)) + add( + createServiceDependency() // + .setService(IDiscoveryService) // + .setCallbacks("setDiscoveryPublisher", "setDiscoveryPublisher") // + .setRequired(false)) + + } + + private def dispatch configure (TopologyAdapter imp, Component it) { + setInterface(Arrays.asList(IPluginInTopologyService.name), properties) add( createServiceDependency() // .setService(IPluginOutTopologyService) // .setCallbacks("setTopologyPublisher", "setTopologyPublisher") // .setRequired(false)) + } + + private def dispatch configure (TopologyProvider imp, Component it) { add( createServiceDependency() // - .setService(IDiscoveryService) // - .setCallbacks("setDiscoveryPublisher", "setDiscoveryPublisher") // + .setService(IPluginOutTopologyService) // + .setCallbacks("setTopologyPublisher", "setTopologyPublisher") // .setRequired(false)) - } private def Dictionary properties() { diff --git a/opendaylight/md-sal/compatibility/sal-compatibility/src/main/java/org/opendaylight/controller/sal/compatibility/FlowProgrammerAdapter.xtend b/opendaylight/md-sal/compatibility/sal-compatibility/src/main/java/org/opendaylight/controller/sal/compatibility/FlowProgrammerAdapter.xtend index 2eae511e02..450c7f1f23 100644 --- a/opendaylight/md-sal/compatibility/sal-compatibility/src/main/java/org/opendaylight/controller/sal/compatibility/FlowProgrammerAdapter.xtend +++ b/opendaylight/md-sal/compatibility/sal-compatibility/src/main/java/org/opendaylight/controller/sal/compatibility/FlowProgrammerAdapter.xtend @@ -18,7 +18,24 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.Node import org.opendaylight.yangtools.yang.common.RpcResult import org.slf4j.LoggerFactory -import static org.opendaylight.controller.sal.compatibility.MDFlowMapping.* +import org.opendaylight.controller.sal.binding.api.data.DataBrokerService +import org.opendaylight.controller.md.sal.common.api.TransactionStatus +import org.opendaylight.controller.md.sal.common.api.data.DataModification +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.Table +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.TableKey +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.FlowKey +import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.Nodes +import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeKey +import org.opendaylight.yangtools.yang.binding.DataObject +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.AddFlowInput +import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.FlowKey +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowId + + +import static extension org.opendaylight.controller.sal.compatibility.MDFlowMapping.* import static extension org.opendaylight.controller.sal.compatibility.NodeMapping.* import static extension org.opendaylight.controller.sal.compatibility.ToSalConversionsUtils.* @@ -29,64 +46,52 @@ class FlowProgrammerAdapter implements IPluginInFlowProgrammerService, SalFlowLi @Property private SalFlowService delegate; + + @Property + private DataBrokerService dataBrokerService; @Property private IPluginOutFlowProgrammerService flowProgrammerPublisher; override addFlow(Node node, Flow flow) { - val input = addFlowInput(node, flow); - val future = delegate.addFlow(input); - try { - val result = future.get(); - return toStatus(result); // how get status from result? conversion? - } catch (Exception e) { - return processException(e); - } + return addFlowAsync(node,flow,0) } override modifyFlow(Node node, Flow oldFlow, Flow newFlow) { - val input = updateFlowInput(node, oldFlow, newFlow); - val future = delegate.updateFlow(input); - try { - val result = future.get(); - return toStatus(result); - } catch (Exception e) { - return processException(e); - } + return modifyFlowAsync(node, oldFlow,newFlow,0) } override removeFlow(Node node, Flow flow) { - val input = removeFlowInput(node, flow); - val future = delegate.removeFlow(input); - - try { - val result = future.get(); - return toStatus(result); - } catch (Exception e) { - return processException(e); - } + return removeFlowAsync(node, flow,0); } override addFlowAsync(Node node, Flow flow, long rid) { - val input = addFlowInput(node, flow); - delegate.addFlow(input); - return new Status(StatusCode.SUCCESS); + writeFlow(flow.toMDFlow, new NodeKey(new NodeId(node.getNodeIDString()))); + return toStatus(true); } override modifyFlowAsync(Node node, Flow oldFlow, Flow newFlow, long rid) { - val input = updateFlowInput(node, oldFlow, newFlow); - delegate.updateFlow(input); - return new Status(StatusCode.SUCCESS); + writeFlow(newFlow.toMDFlow, new NodeKey(new NodeId(node.getNodeIDString()))); + return toStatus(true); } - override removeFlowAsync(Node node, Flow flow, long rid) { - val input = removeFlowInput(node, flow); - delegate.removeFlow(input); - return new Status(StatusCode.SUCCESS); + override removeFlowAsync(Node node, Flow adflow, long rid) { + val flow = adflow.toMDFlow; + val modification = this._dataBrokerService.beginTransaction(); + val flowPath = InstanceIdentifier.builder(Nodes) + .child(org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node, new NodeKey(new NodeId(node.getNodeIDString()))) + .augmentation(FlowCapableNode) + .child(Table, new TableKey(flow.getTableId())) + .child(org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.Flow, new FlowKey(flow.id)) + .build; + modification.removeConfigurationData(flowPath); + val commitFuture = modification.commit(); + return toStatus(true); } override removeAllFlows(Node node) { - throw new UnsupportedOperationException("Not present in MD-SAL"); + // I know this looks like a copout... but its exactly what the legacy OFplugin did + return new Status(StatusCode.SUCCESS); } override syncSendBarrierMessage(Node node) { @@ -101,13 +106,38 @@ class FlowProgrammerAdapter implements IPluginInFlowProgrammerService, SalFlowLi return null; } - public static def toStatus(RpcResult result) { - if (result.isSuccessful()) { + private static def toStatus(boolean successful) { + if (successful) { return new Status(StatusCode.SUCCESS); } else { return new Status(StatusCode.INTERNALERROR); } } + + + private def writeFlow(org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.Flow flow, NodeKey nodeKey) { + val modification = this._dataBrokerService.beginTransaction(); + val flowPath = InstanceIdentifier.builder(Nodes) + .child(org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node, nodeKey) + .augmentation(FlowCapableNode) + .child(Table, new TableKey(flow.getTableId())) + .child(org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.Flow, new FlowKey(flow.id)) + .build; + modification.putConfigurationData(flowPath, flow); + val commitFuture = modification.commit(); + try { + val result = commitFuture.get(); + val status = result.getResult(); + } catch (InterruptedException e) { + LOG.error(e.getMessage(), e); + } catch (ExecutionException e) { + LOG.error(e.getMessage(), e); + } + } + + public static def toStatus(RpcResult result) { + return toStatus(result.isSuccessful()); + } private static dispatch def Status processException(InterruptedException e) { LOG.error("Interruption occured during processing flow",e); diff --git a/opendaylight/md-sal/compatibility/sal-compatibility/src/main/java/org/opendaylight/controller/sal/compatibility/FromSalConversionsUtils.java b/opendaylight/md-sal/compatibility/sal-compatibility/src/main/java/org/opendaylight/controller/sal/compatibility/FromSalConversionsUtils.java index 4e6e49eac7..eba4aa901b 100644 --- a/opendaylight/md-sal/compatibility/sal-compatibility/src/main/java/org/opendaylight/controller/sal/compatibility/FromSalConversionsUtils.java +++ b/opendaylight/md-sal/compatibility/sal-compatibility/src/main/java/org/opendaylight/controller/sal/compatibility/FromSalConversionsUtils.java @@ -12,6 +12,7 @@ import java.net.Inet4Address; import java.net.Inet6Address; import java.net.InetAddress; +import org.opendaylight.controller.sal.core.NodeConnector; import org.opendaylight.controller.sal.match.Match; import org.opendaylight.controller.sal.match.MatchField; import org.opendaylight.controller.sal.match.MatchType; @@ -26,6 +27,7 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.addr import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.address.address.Ipv6Builder; import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.Flow; import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.MatchBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId; import org.opendaylight.yang.gen.v1.urn.opendaylight.l2.types.rev130827.EtherType; import org.opendaylight.yang.gen.v1.urn.opendaylight.l2.types.rev130827.VlanId; import org.opendaylight.yang.gen.v1.urn.opendaylight.l2.types.rev130827.VlanPcp; @@ -83,6 +85,7 @@ public class FromSalConversionsUtils { targetBuilder.setVlanMatch(vlanMatch(sourceMatch)); targetBuilder.setLayer3Match(layer3Match(sourceMatch)); targetBuilder.setLayer4Match(layer4Match(sourceMatch)); + targetBuilder.setInPort(inPortMatch(sourceMatch)); return targetBuilder.build(); } @@ -90,6 +93,14 @@ public class FromSalConversionsUtils { } + private static NodeConnectorId inPortMatch(Match sourceMatch) { + MatchField inPort = sourceMatch.getField(MatchType.IN_PORT); + if(inPort != null && inPort.getValue() != null && (inPort.getValue() instanceof NodeConnector)) { + return new NodeConnectorId(((NodeConnector) inPort.getValue()).getNodeConnectorIdAsString()); + } + return null; + } + private static Layer4Match layer4Match(final Match sourceMatch) { MatchField nwProto = sourceMatch.getField(MatchType.NW_PROTO); Short nwProtocolSource = null; @@ -121,8 +132,10 @@ public class FromSalConversionsUtils { sctpMatchBuilder.setSctpDestinationPort(new PortNumber( destinationPort)); } - - return sctpMatchBuilder.build(); + if(sourcePort != null || destinationPort != null) { + return sctpMatchBuilder.build(); + } + return null; } private static Layer4Match Layer4MatchAsUdp(final Match sourceMatch) { @@ -140,8 +153,10 @@ public class FromSalConversionsUtils { udpMatchBuilder.setUdpDestinationPort(new PortNumber( destinationPort)); } - - return udpMatchBuilder.build(); + if(sourcePort != null || destinationPort != null) { + return udpMatchBuilder.build(); + } + return null; } private static Layer4Match Layer4MatchAsTcp(final Match sourceMatch) { @@ -158,8 +173,10 @@ public class FromSalConversionsUtils { tcpMatchBuilder.setTcpDestinationPort(new PortNumber( destinationPort)); } - - return tcpMatchBuilder.build(); + if(sourcePort != null || destinationPort != null) { + return tcpMatchBuilder.build(); + } + return null; } private static Integer transportPort(final Match sourceMatch, @@ -189,8 +206,10 @@ public class FromSalConversionsUtils { vlanMatchBuild.setVlanPcp(new VlanPcp((short) ((byte) vlanPriority .getValue()))); } - - return vlanMatchBuild.build(); + if((vlan != null && vlan.getValue() != null) || (vlanPriority != null && vlanPriority.getValue() != null)) { + return vlanMatchBuild.build(); + } + return null; } private static IpMatch ipMatch(final Match sourceMatch) { @@ -208,21 +227,24 @@ public class FromSalConversionsUtils { targetIpMatchBuild.setIpProtocol((short) ((byte) protocol .getValue())); } - - return targetIpMatchBuild.build(); - + if((networkTos != null && networkTos.getValue() != null) || (protocol != null && protocol.getValue() != null)) { + return targetIpMatchBuild.build(); + } + return null; } private static EthernetMatch ethernetMatch(final Match sourceMatch) { final EthernetMatchBuilder targetEthMatchBuild = new EthernetMatchBuilder(); - - EthernetSourceBuilder ethSourBuild = new EthernetSourceBuilder() - .setAddress(ethernetSourceAddress(sourceMatch)); - targetEthMatchBuild.setEthernetSource(ethSourBuild.build()); - - EthernetDestinationBuilder ethDestBuild = new EthernetDestinationBuilder() - .setAddress(ethernetDestAddress(sourceMatch)); - targetEthMatchBuild.setEthernetDestination(ethDestBuild.build()); + if(sourceMatch.getField(DL_SRC) != null && sourceMatch.getField(DL_SRC).getValue() != null) { + EthernetSourceBuilder ethSourBuild = new EthernetSourceBuilder() + .setAddress(ethernetSourceAddress(sourceMatch)); + targetEthMatchBuild.setEthernetSource(ethSourBuild.build()); + } + if(sourceMatch.getField(DL_DST) != null && sourceMatch.getField(DL_DST).getValue() != null) { + EthernetDestinationBuilder ethDestBuild = new EthernetDestinationBuilder() + .setAddress(ethernetDestAddress(sourceMatch)); + targetEthMatchBuild.setEthernetDestination(ethDestBuild.build()); + } final MatchField dataLinkType = sourceMatch.getField(MatchType.DL_TYPE); if (dataLinkType != null && dataLinkType.getValue() != null) { @@ -232,7 +254,12 @@ public class FromSalConversionsUtils { .setType(etherType); targetEthMatchBuild.setEthernetType(ethType.build()); } - return targetEthMatchBuild.build(); + if((sourceMatch.getField(DL_SRC) != null && sourceMatch.getField(DL_SRC).getValue() != null) || + (sourceMatch.getField(DL_DST) != null && sourceMatch.getField(DL_DST).getValue() != null)|| + dataLinkType != null ) { + return targetEthMatchBuild.build(); + } + return null; } private static MacAddress ethernetSourceAddress(final Match sourceMatch) { @@ -258,7 +285,7 @@ public class FromSalConversionsUtils { } if ((inetSourceAddress instanceof Inet4Address) - && (inetDestAddress instanceof Inet4Address)) { + || (inetDestAddress instanceof Inet4Address)) { MatchField dataLinkType = sourceMatch.getField(DL_TYPE); Short dLType = null; if (dataLinkType != null && dataLinkType.getValue() != null) { @@ -273,7 +300,7 @@ public class FromSalConversionsUtils { (Inet4Address) inetDestAddress); } } else if ((inetSourceAddress instanceof Inet6Address) - && (inetDestAddress instanceof Inet6Address)) { + || (inetDestAddress instanceof Inet6Address)) { return setLayer3MatchAsIpv6((Inet6Address) inetSourceAddress, (Inet6Address) inetDestAddress); } @@ -327,15 +354,18 @@ public class FromSalConversionsUtils { private static Layer3Match setLayer3MatchAsIpv4( final Inet4Address inetSourceAddress, final Inet4Address inetDestAddress) { - String inetSrcAddressString = InetAddresses - .toAddrString(inetSourceAddress); - String inetDstAddressString = InetAddresses - .toAddrString(inetDestAddress); - Ipv4MatchBuilder layer4MatchBuild = new Ipv4MatchBuilder(); - layer4MatchBuild.setIpv4Source(new Ipv4Prefix(inetSrcAddressString)); - layer4MatchBuild - .setIpv4Destination(new Ipv4Prefix(inetDstAddressString)); + if(inetSourceAddress != null) { + String inetSrcAddressString = InetAddresses + .toAddrString(inetSourceAddress); + layer4MatchBuild.setIpv4Source(new Ipv4Prefix(inetSrcAddressString)); + } + if(inetDestAddress != null) { + String inetDstAddressString = InetAddresses + .toAddrString(inetDestAddress); + layer4MatchBuild + .setIpv4Destination(new Ipv4Prefix(inetDstAddressString)); + } return layer4MatchBuild.build(); } @@ -343,15 +373,18 @@ public class FromSalConversionsUtils { private static Layer3Match setLayer3MatchAsIpv6( final Inet6Address inetSourceAddress, final Inet6Address inetDestAddress) { - String inetSrcAddressString = InetAddresses - .toAddrString(inetSourceAddress); - String inetDstAddressString = InetAddresses - .toAddrString(inetDestAddress); Ipv6MatchBuilder layer6MatchBuild = new Ipv6MatchBuilder(); - - layer6MatchBuild.setIpv6Source(new Ipv6Prefix(inetSrcAddressString)); - layer6MatchBuild - .setIpv6Destination(new Ipv6Prefix(inetDstAddressString)); + if(inetSourceAddress != null) { + String inetSrcAddressString = InetAddresses + .toAddrString(inetSourceAddress); + layer6MatchBuild.setIpv6Source(new Ipv6Prefix(inetSrcAddressString)); + } + if(inetDestAddress != null) { + String inetDstAddressString = InetAddresses + .toAddrString(inetDestAddress); + layer6MatchBuild + .setIpv6Destination(new Ipv6Prefix(inetDstAddressString)); + } return layer6MatchBuild.build(); } diff --git a/opendaylight/md-sal/compatibility/sal-compatibility/src/main/java/org/opendaylight/controller/sal/compatibility/InventoryAndReadAdapter.xtend b/opendaylight/md-sal/compatibility/sal-compatibility/src/main/java/org/opendaylight/controller/sal/compatibility/InventoryAndReadAdapter.xtend index 31ae745d73..56ca1b609c 100644 --- a/opendaylight/md-sal/compatibility/sal-compatibility/src/main/java/org/opendaylight/controller/sal/compatibility/InventoryAndReadAdapter.xtend +++ b/opendaylight/md-sal/compatibility/sal-compatibility/src/main/java/org/opendaylight/controller/sal/compatibility/InventoryAndReadAdapter.xtend @@ -1,83 +1,76 @@ package org.opendaylight.controller.sal.compatibility -import org.opendaylight.controller.sal.reader.IPluginInReadService -import org.opendaylight.controller.sal.core.NodeConnector +import java.util.ArrayList +import java.util.Collections +import java.util.List +import org.opendaylight.controller.sal.binding.api.data.DataBrokerService +import org.opendaylight.controller.sal.binding.api.data.DataProviderService +import org.opendaylight.controller.sal.core.Edge import org.opendaylight.controller.sal.core.Node -import org.opendaylight.controller.sal.flowprogrammer.Flow import org.opendaylight.controller.sal.core.NodeTable -import org.opendaylight.controller.sal.binding.api.data.DataBrokerService - -import static extension org.opendaylight.controller.sal.common.util.Arguments.* -import static extension org.opendaylight.controller.sal.compatibility.NodeMapping.* +import org.opendaylight.controller.sal.core.UpdateType +import org.opendaylight.controller.sal.flowprogrammer.Flow +import org.opendaylight.controller.sal.inventory.IPluginInInventoryService +import org.opendaylight.controller.sal.inventory.IPluginOutInventoryService +import org.opendaylight.controller.sal.reader.FlowOnNode +import org.opendaylight.controller.sal.reader.IPluginInReadService +import org.opendaylight.controller.sal.reader.IPluginOutReadService +import org.opendaylight.controller.sal.reader.NodeConnectorStatistics +import org.opendaylight.controller.sal.reader.NodeDescription +import org.opendaylight.controller.sal.reader.NodeTableStatistics import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNodeConnector -import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeRef -import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorRef +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.Table +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.TableKey +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.AggregateFlowStatisticsUpdate +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.FlowStatisticsData +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.FlowsStatisticsUpdate +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.GetAllFlowsStatisticsFromAllFlowTablesInputBuilder +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.GetFlowStatisticsFromFlowTableInputBuilder +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.OpendaylightFlowStatisticsListener import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.OpendaylightFlowStatisticsService -import org.opendaylight.controller.sal.reader.NodeConnectorStatistics -import org.opendaylight.controller.sal.reader.FlowOnNode -import org.opendaylight.controller.sal.reader.NodeDescription -import org.slf4j.LoggerFactory -import java.util.ArrayList -import org.opendaylight.controller.sal.inventory.IPluginInInventoryService -import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.OpendaylightInventoryListener -import org.opendaylight.controller.sal.inventory.IPluginOutInventoryService +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.flow.and.statistics.map.list.FlowAndStatisticsMapList +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.table.statistics.rev131215.FlowTableStatisticsData +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.table.statistics.rev131215.FlowTableStatisticsUpdate +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.table.statistics.rev131215.GetFlowTablesStatisticsInputBuilder +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.table.statistics.rev131215.OpendaylightFlowTableStatisticsListener +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.table.statistics.rev131215.OpendaylightFlowTableStatisticsService +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.table.statistics.rev131215.flow.table.statistics.FlowTableStatistics +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.topology.discovery.rev130819.FlowTopologyDiscoveryService +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.topology.discovery.rev130819.Link +import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId +import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorRef import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorRemoved import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorUpdated -import java.util.Collections -import org.opendaylight.controller.sal.core.UpdateType +import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId +import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeRef import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeRemoved import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeUpdated -import org.opendaylight.yangtools.yang.binding.InstanceIdentifier -import org.opendaylight.yangtools.yang.binding.DataObject -import org.opendaylight.controller.sal.topology.IPluginOutTopologyService -import org.opendaylight.controller.sal.topology.IPluginInTopologyService -import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.topology.discovery.rev130819.FlowTopologyDiscoveryService -import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.topology.discovery.rev130819.FlowTopologyDiscoveryListener -import org.opendaylight.controller.sal.core.Edge -import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.topology.discovery.rev130819.Link -import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.topology.discovery.rev130819.LinkDiscovered -import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.topology.discovery.rev130819.LinkOverutilized -import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.topology.discovery.rev130819.LinkRemoved -import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.topology.discovery.rev130819.LinkUtilizationNormal -import org.opendaylight.controller.sal.topology.TopoEdgeUpdate -import org.opendaylight.controller.sal.discovery.IDiscoveryService -import org.opendaylight.controller.sal.reader.IPluginOutReadService -import java.util.List -import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.OpendaylightFlowStatisticsListener -import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.table.statistics.rev131215.OpendaylightFlowTableStatisticsListener -import org.opendaylight.yang.gen.v1.urn.opendaylight.port.statistics.rev131214.OpendaylightPortStatisticsListener -import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.AggregateFlowStatisticsUpdate -import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.FlowsStatisticsUpdate -import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.table.statistics.rev131215.FlowTableStatisticsUpdate -import org.opendaylight.controller.sal.reader.NodeTableStatistics import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.Nodes -import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeKey +import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.OpendaylightInventoryListener +import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnector import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnectorKey -import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.flow.and.statistics.map.list.FlowAndStatisticsMapList -import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.GetAllFlowsStatisticsFromAllFlowTablesInputBuilder -import org.opendaylight.yang.gen.v1.urn.opendaylight.port.statistics.rev131214.OpendaylightPortStatisticsService -import org.opendaylight.yang.gen.v1.urn.opendaylight.port.statistics.rev131214.GetAllNodeConnectorsStatisticsInputBuilder -import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.table.statistics.rev131215.OpendaylightFlowTableStatisticsService -import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.Table -import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.TableKey -import org.opendaylight.controller.sal.binding.api.data.DataProviderService -import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.FlowStatisticsData -import org.opendaylight.yang.gen.v1.urn.opendaylight.port.statistics.rev131214.FlowCapableNodeConnectorStatisticsData +import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeKey import org.opendaylight.yang.gen.v1.urn.opendaylight.port.statistics.rev131214.FlowCapableNodeConnectorStatistics -import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.table.statistics.rev131215.FlowTableStatisticsData -import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.table.statistics.rev131215.GetFlowTablesStatisticsInputBuilder +import org.opendaylight.yang.gen.v1.urn.opendaylight.port.statistics.rev131214.FlowCapableNodeConnectorStatisticsData +import org.opendaylight.yang.gen.v1.urn.opendaylight.port.statistics.rev131214.GetAllNodeConnectorsStatisticsInputBuilder import org.opendaylight.yang.gen.v1.urn.opendaylight.port.statistics.rev131214.GetNodeConnectorStatisticsInputBuilder -import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId -import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId import org.opendaylight.yang.gen.v1.urn.opendaylight.port.statistics.rev131214.NodeConnectorStatisticsUpdate -import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.GetFlowStatisticsFromFlowTableInputBuilder +import org.opendaylight.yang.gen.v1.urn.opendaylight.port.statistics.rev131214.OpendaylightPortStatisticsListener +import org.opendaylight.yang.gen.v1.urn.opendaylight.port.statistics.rev131214.OpendaylightPortStatisticsService +import org.opendaylight.yangtools.yang.binding.DataObject +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier +import org.slf4j.LoggerFactory -class InventoryAndReadAdapter implements IPluginInTopologyService, - IPluginInReadService, +import static extension org.opendaylight.controller.sal.common.util.Arguments.* +import static extension org.opendaylight.controller.sal.compatibility.NodeMapping.* +import org.opendaylight.controller.md.sal.binding.util.TypeSafeDataReader +import java.util.concurrent.ConcurrentHashMap +import java.util.Map + +class InventoryAndReadAdapter implements IPluginInReadService, IPluginInInventoryService, OpendaylightInventoryListener, - FlowTopologyDiscoveryListener, OpendaylightFlowStatisticsListener, OpendaylightFlowTableStatisticsListener, OpendaylightPortStatisticsListener { @@ -103,12 +96,6 @@ class InventoryAndReadAdapter implements IPluginInTopologyService, @Property IPluginOutInventoryService inventoryPublisher; - @Property - IPluginOutTopologyService topologyPublisher; - - @Property - IDiscoveryService discoveryPublisher; - @Property FlowTopologyDiscoveryService topologyDiscovery; @@ -128,7 +115,7 @@ class InventoryAndReadAdapter implements IPluginInTopologyService, return dataProviderService.beginTransaction; } - override getTransmitRate(NodeConnector connector) { + override getTransmitRate(org.opendaylight.controller.sal.core.NodeConnector connector) { val nodeConnector = readFlowCapableNodeConnector(connector.toNodeConnectorRef); return nodeConnector.currentSpeed } @@ -191,10 +178,10 @@ class InventoryAndReadAdapter implements IPluginInTopologyService, for (dsNodeConnector : dsNode.nodeConnector){ val nodeConnectorRef = InstanceIdentifier.builder(Nodes) .child(org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node, InventoryMapping.toNodeKey(node)) - .child(org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnector, dsNodeConnector.key) + .child(NodeConnector, dsNodeConnector.key) .toInstance(); - val nodeConnectorFromDS = provider.readConfigurationData(nodeConnectorRef) as org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnector; + val nodeConnectorFromDS = provider.readConfigurationData(nodeConnectorRef) as NodeConnector; if(nodeConnectorFromDS != null){ val nodeConnectorStatsFromDs = nodeConnectorFromDS.getAugmentation(FlowCapableNodeConnectorStatisticsData) as FlowCapableNodeConnectorStatistics; @@ -281,16 +268,16 @@ class InventoryAndReadAdapter implements IPluginInTopologyService, } - override readNodeConnector(NodeConnector connector, boolean cached) { + override readNodeConnector(org.opendaylight.controller.sal.core.NodeConnector connector, boolean cached) { var NodeConnectorStatistics nodeConnectorStatistics = null; val nodeConnectorRef = InstanceIdentifier.builder(Nodes) .child(org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node, InventoryMapping.toNodeKey(connector.node)) - .child(org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnector, InventoryMapping.toNodeConnectorKey(connector)) + .child(NodeConnector, InventoryMapping.toNodeConnectorKey(connector)) .toInstance(); val provider = this.startChange(); - val nodeConnectorFromDS = provider.readConfigurationData(nodeConnectorRef) as org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnector; + val nodeConnectorFromDS = provider.readConfigurationData(nodeConnectorRef) as NodeConnector; if(nodeConnectorFromDS != null){ val nodeConnectorStatsFromDs = nodeConnectorFromDS.getAugmentation(FlowCapableNodeConnectorStatisticsData) as FlowCapableNodeConnectorStatistics; @@ -347,32 +334,25 @@ class InventoryAndReadAdapter implements IPluginInTopologyService, } override onNodeConnectorUpdated(NodeConnectorUpdated update) { - val properties = new java.util.HashSet(); - - - val org.opendaylight.yangtools.yang.binding.InstanceIdentifier identifier = update.nodeConnectorRef.value as org.opendaylight.yangtools.yang.binding.InstanceIdentifier; var updateType = UpdateType.CHANGED; - if ( this._dataService.readOperationalData(identifier) == null ){ + if ( this._dataService.readOperationalData(update.nodeConnectorRef.value as InstanceIdentifier) == null ){ updateType = UpdateType.ADDED; } var nodeConnector = update.nodeConnectorRef.toADNodeConnector - - properties.add(new org.opendaylight.controller.sal.core.Name(nodeConnector.ID.toString())); - - inventoryPublisher.updateNodeConnector(nodeConnector , updateType , properties); + inventoryPublisher.updateNodeConnector(nodeConnector , updateType , update.toADNodeConnectorProperties); } override onNodeUpdated(NodeUpdated notification) { val properties = Collections.emptySet(); - val org.opendaylight.yangtools.yang.binding.InstanceIdentifier identifier = notification.nodeRef.value as org.opendaylight.yangtools.yang.binding.InstanceIdentifier; + val InstanceIdentifier identifier = notification.nodeRef.value as InstanceIdentifier; var updateType = UpdateType.CHANGED; if ( this._dataService.readOperationalData(identifier) == null ){ updateType = UpdateType.ADDED; } - inventoryPublisher.updateNode(notification.nodeRef.toADNode, updateType, properties); + inventoryPublisher.updateNode(notification.nodeRef.toADNode, updateType, notification.toADNodeProperties); //Notify the listeners of IPluginOutReadService @@ -383,15 +363,64 @@ class InventoryAndReadAdapter implements IPluginInTopologyService, } override getNodeProps() { - - // FIXME: Read from MD-SAL inventory service - return null; + val props = new ConcurrentHashMap>() + + val nodes = readAllMDNodes() + for (node : nodes.node ) { + val fcn = node.getAugmentation(FlowCapableNode) + if(fcn != null) { + val perNodeProps = fcn.toADNodeProperties(node.id) + val perNodePropMap = new ConcurrentHashMap + if(perNodeProps != null ) { + for(perNodeProp : perNodeProps) { + perNodePropMap.put(perNodeProp.name,perNodeProp) + } + } + props.put(new Node(MD_SAL_TYPE, node.id.toADNodeId),perNodePropMap) + } + } + return props; + } + + private def readAllMDNodes() { + val nodesRef = InstanceIdentifier.builder(Nodes) + .toInstance + val reader = TypeSafeDataReader.forReader(dataService) + return reader.readOperationalData(nodesRef) + } + + private def readAllMDNodeConnectors(org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node node) { + val nodeRef = InstanceIdentifier.builder(Nodes) + .child(org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node,new NodeKey(node.id)) + .toInstance + val reader = TypeSafeDataReader.forReader(dataService) + return reader.readOperationalData(nodeRef).nodeConnector } override getNodeConnectorProps(Boolean refresh) { - - // FIXME: Read from MD-SAL Invcentory Service - return null; + // Note, because the MD-SAL has a unified data store, we can ignore the Boolean refresh, as we have no secondary + // data store to refresh from + val props = new ConcurrentHashMap>() + val nodes = readAllMDNodes() + for (node : nodes.node) { + val ncs = node.readAllMDNodeConnectors + if(ncs != null) { + for( nc : ncs ) { + val fcnc = nc.getAugmentation(FlowCapableNodeConnector) + if(fcnc != null) { + val ncps = fcnc.toADNodeConnectorProperties + val ncpsm = new ConcurrentHashMap + if(ncps != null) { + for(p : ncps) { + ncpsm.put(p.name,p) + } + } + props.put(nc.id.toADNodeConnector(node.id),ncpsm) + } + } + } + } + return props } private def FlowCapableNode readFlowCapableNode(NodeRef ref) { @@ -404,7 +433,7 @@ class InventoryAndReadAdapter implements IPluginInTopologyService, private def FlowCapableNodeConnector readFlowCapableNodeConnector(NodeConnectorRef ref) { val dataObject = dataService.readOperationalData(ref.value as InstanceIdentifier); val node = dataObject.checkInstanceOf( - org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnector); + NodeConnector); return node.getAugmentation(FlowCapableNodeConnector); } @@ -432,7 +461,7 @@ class InventoryAndReadAdapter implements IPluginInTopologyService, val nodeConnectorRef = InstanceIdentifier.builder(Nodes) .child(org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node,new NodeKey(nodeId)) - .child(org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnector,new NodeConnectorKey(nodeConnectorId)).toInstance; + .child(NodeConnector,new NodeConnectorKey(nodeConnectorId)).toInstance; nodeConnector = NodeMapping.toADNodeConnector(new NodeConnectorRef(nodeConnectorRef)); @@ -440,7 +469,7 @@ class InventoryAndReadAdapter implements IPluginInTopologyService, } private def toNodeTableStatistics( - org.opendaylight.yang.gen.v1.urn.opendaylight.flow.table.statistics.rev131215.flow.table.statistics.FlowTableStatistics tableStats, + FlowTableStatistics tableStats, Short tableId,Node node){ var it = new NodeTableStatistics(); @@ -463,29 +492,6 @@ class InventoryAndReadAdapter implements IPluginInTopologyService, return it; } - - override sollicitRefresh() { - topologyDiscovery.solicitRefresh - } - - override onLinkDiscovered(LinkDiscovered notification) { - val update = new TopoEdgeUpdate(notification.toADEdge,Collections.emptySet(),UpdateType.ADDED); - discoveryPublisher.notifyEdge(notification.toADEdge,UpdateType.ADDED,Collections.emptySet()); - topologyPublisher.edgeUpdate(Collections.singletonList(update)) - } - - override onLinkOverutilized(LinkOverutilized notification) { - topologyPublisher.edgeOverUtilized(notification.toADEdge) - } - - override onLinkRemoved(LinkRemoved notification) { - val update = new TopoEdgeUpdate(notification.toADEdge,Collections.emptySet(),UpdateType.REMOVED); - topologyPublisher.edgeUpdate(Collections.singletonList(update)) - } - - override onLinkUtilizationNormal(LinkUtilizationNormal notification) { - topologyPublisher.edgeUtilBackToNormal(notification.toADEdge) - } def Edge toADEdge(Link link) { diff --git a/opendaylight/md-sal/compatibility/sal-compatibility/src/main/java/org/opendaylight/controller/sal/compatibility/MDFlowMapping.xtend b/opendaylight/md-sal/compatibility/sal-compatibility/src/main/java/org/opendaylight/controller/sal/compatibility/MDFlowMapping.xtend index 2f458c41dd..b0f6065bac 100644 --- a/opendaylight/md-sal/compatibility/sal-compatibility/src/main/java/org/opendaylight/controller/sal/compatibility/MDFlowMapping.xtend +++ b/opendaylight/md-sal/compatibility/sal-compatibility/src/main/java/org/opendaylight/controller/sal/compatibility/MDFlowMapping.xtend @@ -105,6 +105,7 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instru import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.ApplyActionsCaseBuilder import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.FlowBuilder +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowId public class MDFlowMapping { @@ -129,14 +130,37 @@ public class MDFlowMapping { } instructions = targetActions.toApplyInstruction(); match = sourceFlow.match.toMatch(); + tableId = new Integer(0).shortValue return it.build(); } + public static def toMDFlow(Flow sourceFlow) { + if (sourceFlow == null) + throw new IllegalArgumentException(); + val it = new FlowBuilder(); + hardTimeout = sourceFlow.hardTimeout as int + idleTimeout = sourceFlow.idleTimeout as int + cookie = BigInteger.valueOf(sourceFlow.id) + priority = sourceFlow.priority as int + id = new FlowId(sourceFlow.id) + + val sourceActions = sourceFlow.actions; + val targetActions = new ArrayList(); + for (sourceAction : sourceActions) { + targetActions.add(sourceAction.toAction()); + } + instructions = targetActions.toApplyInstruction(); + match = sourceFlow.match.toMatch(); + tableId = new Integer(0).shortValue + return it.build(); + } + public static def Instructions toApplyInstruction(ArrayList actions) { val it = new InstructionsBuilder; val applyActions = new InstructionBuilder; applyActions.instruction = new ApplyActionsCaseBuilder().setApplyActions(new ApplyActionsBuilder().setAction(actions).build()).build() + applyActions.setOrder(new Integer(0)) instruction = Collections.singletonList(applyActions.build) return it.build; } @@ -144,12 +168,14 @@ public class MDFlowMapping { public static def removeFlowInput(Node sourceNode, Flow sourceFlow) { val source = flowAdded(sourceFlow); val it = new RemoveFlowInputBuilder(source as org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.Flow); + node = sourceNode.toNodeRef() return it.build(); } public static def addFlowInput(Node sourceNode, Flow sourceFlow) { val source = flowAdded(sourceFlow); val it = new AddFlowInputBuilder(source as org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.Flow); + it.setNode(sourceNode.toNodeRef) return it.build(); } diff --git a/opendaylight/md-sal/compatibility/sal-compatibility/src/main/java/org/opendaylight/controller/sal/compatibility/NodeMapping.xtend b/opendaylight/md-sal/compatibility/sal-compatibility/src/main/java/org/opendaylight/controller/sal/compatibility/NodeMapping.xtend index 6bfee578ab..4378e7dffe 100644 --- a/opendaylight/md-sal/compatibility/sal-compatibility/src/main/java/org/opendaylight/controller/sal/compatibility/NodeMapping.xtend +++ b/opendaylight/md-sal/compatibility/sal-compatibility/src/main/java/org/opendaylight/controller/sal/compatibility/NodeMapping.xtend @@ -7,6 +7,7 @@ import org.opendaylight.yangtools.yang.binding.InstanceIdentifier.IdentifiableIt import static com.google.common.base.Preconditions.*; import static extension org.opendaylight.controller.sal.common.util.Arguments.*; +import static extension org.opendaylight.controller.sal.compatibility.ToSalConversionsUtils.*; import org.opendaylight.yangtools.yang.binding.InstanceIdentifier import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorRef @@ -16,39 +17,121 @@ import org.opendaylight.controller.sal.core.ConstructionException import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeRef import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.Nodes import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId - +import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorUpdated +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNodeConnectorUpdated +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.port.rev130925.PortFeatures +import org.opendaylight.controller.sal.core.Bandwidth +import org.opendaylight.controller.sal.core.AdvertisedBandwidth +import org.opendaylight.controller.sal.core.SupportedBandwidth +import org.opendaylight.controller.sal.core.PeerBandwidth +import org.opendaylight.controller.sal.core.Name +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.port.rev130925.PortConfig +import org.opendaylight.controller.sal.core.Config +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.port.rev130925.flow.capable.port.State +import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeUpdated +import java.util.HashSet +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNodeUpdated +import org.opendaylight.controller.sal.core.Tables +import java.util.List +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FeatureCapability +import org.opendaylight.controller.sal.core.Buffers +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowFeatureCapabilityFlowStats +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowFeatureCapabilityTableStats +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowFeatureCapabilityIpReasm +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowFeatureCapabilityPortStats +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowFeatureCapabilityStp +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowFeatureCapabilityQueueStats +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowFeatureCapabilityArpMatchIp +import org.opendaylight.controller.sal.core.Capabilities +import org.opendaylight.controller.sal.core.MacAddress +import java.util.Date +import org.opendaylight.controller.sal.core.TimeStamp +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowNodeConnector +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowNode +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNodeConnector public class NodeMapping { public static val MD_SAL_TYPE = "MD_SAL"; private static val NODE_CLASS = org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node; - private static val NODECONNECTOR_CLASS = org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnector; + private static val NODECONNECTOR_CLASS = org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node. + NodeConnector; private new() { throw new UnsupportedOperationException("Utility class. Instantiation is not allowed."); } public static def toADNode(InstanceIdentifier node) throws ConstructionException { + return node.toNodeId.toADNode + } + + public static def toADNode(NodeId id) { + return new Node(MD_SAL_TYPE, id.toADNodeId); + } + + public static def toNodeId(InstanceIdentifier node) { checkNotNull(node); checkNotNull(node.getPath()); checkArgument(node.getPath().size() >= 2); val arg = node.getPath().get(1); val item = arg.checkInstanceOf(IdentifiableItem); val nodeKey = item.getKey().checkInstanceOf(NodeKey); - return new Node(MD_SAL_TYPE, nodeKey.getId().getValue().toString()); + return nodeKey.id + } + + public static def toADNodeId(NodeId nodeId) { + checkNotNull(nodeId); + return nodeId.value } public static def toADNodeConnector(NodeConnectorRef source) throws ConstructionException { checkNotNull(source); val InstanceIdentifier path = checkNotNull(source.getValue()); - val node = path.toADNode(); checkArgument(path.path.size() >= 3); val arg = path.getPath().get(2); val item = arg.checkInstanceOf(IdentifiableItem); val connectorKey = item.getKey().checkInstanceOf(NodeConnectorKey); - return new NodeConnector(MD_SAL_TYPE, connectorKey.getId().getValue().toString(), node); + return connectorKey.id.toADNodeConnector(path.toNodeId) } + public static def toADNodeConnector(org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId ncid, + org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId nid) { + return new NodeConnector(ncid.toNodeConnectorType(nid), + ncid.toADNodeConnectorId(nid), nid.toADNode); + } + + public static def toNodeConnectorType(NodeConnectorId ncId, NodeId nodeId) { + if (ncId.equals(nodeId.toLocalNodeConnectorId)) { + return NodeConnector.NodeConnectorIDType.SWSTACK + } else if (ncId.equals(nodeId.toNormalNodeConnectorId)) { + return NodeConnector.NodeConnectorIDType.HWPATH + } else if (ncId.equals(nodeId.toControllerNodeConnectorId)) { + return NodeConnector.NodeConnectorIDType.CONTROLLER + } + return MD_SAL_TYPE + } + + public static def toADNodeConnectorId(NodeConnectorId nodeConnectorId, NodeId nodeId) { + if (nodeConnectorId.equals(nodeId.toLocalNodeConnectorId) || + nodeConnectorId.equals(nodeId.toNormalNodeConnectorId) || + nodeConnectorId.equals(nodeId.toControllerNodeConnectorId)) { + return NodeConnector.SPECIALNODECONNECTORID + } + return nodeConnectorId.value + } + + public static def toControllerNodeConnectorId(NodeId node) { + return new NodeConnectorId(node.value + ":" + 4294967293L) + } + + public static def toLocalNodeConnectorId(NodeId node) { + return new NodeConnectorId(node.value + ":" + 4294967294L) + } + + public static def toNormalNodeConnectorId(NodeId node) { + return new NodeConnectorId(node.value + ":" + 4294967290L) + } + public static def toNodeRef(Node node) { checkArgument(MD_SAL_TYPE.equals(node.getType())); var nodeId = node.ID.checkInstanceOf(String) @@ -56,12 +139,23 @@ public class NodeMapping { val nodePath = InstanceIdentifier.builder().node(Nodes).child(NODE_CLASS, nodeKey).toInstance(); return new NodeRef(nodePath); } - + public static def toNodeConnectorRef(NodeConnector nodeConnector) { val node = nodeConnector.node.toNodeRef(); val nodePath = node.getValue() as InstanceIdentifier - var nodeConnectorId = nodeConnector.ID.checkInstanceOf(String) - val connectorKey = new NodeConnectorKey(new NodeConnectorId(nodeConnectorId)); + var NodeConnectorId nodeConnectorId + if (nodeConnector.ID.equals(NodeConnector.SPECIALNODECONNECTORID)) { + if (nodeConnector.type.equals(NodeConnector.NodeConnectorIDType.SWSTACK)) { + nodeConnectorId = nodePath.toNodeId.toLocalNodeConnectorId + } else if (nodeConnector.type.equals(NodeConnector.NodeConnectorIDType.HWPATH)) { + nodeConnectorId = nodePath.toNodeId.toNormalNodeConnectorId + } else if (nodeConnector.type.equals(NodeConnector.NodeConnectorIDType.CONTROLLER)) { + nodeConnectorId = nodePath.toNodeId.toControllerNodeConnectorId + } + } else { + nodeConnectorId = new NodeConnectorId(nodeConnector.ID.checkInstanceOf(String)) + } + val connectorKey = new NodeConnectorKey(nodeConnectorId); val path = InstanceIdentifier.builder(nodePath).child(NODECONNECTOR_CLASS, connectorKey).toInstance(); return new NodeConnectorRef(path); } @@ -69,5 +163,195 @@ public class NodeMapping { public static def toADNode(NodeRef node) throws ConstructionException { return toADNode(node.getValue()); } - + + public static def toADNodeConnectorProperties(NodeConnectorUpdated nc) { + val fcncu = nc.getAugmentation(FlowCapableNodeConnectorUpdated) + if (fcncu != null) { + return fcncu.toADNodeConnectorProperties + } + return new HashSet(); + } + + public static def toADNodeConnectorProperties(org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnector nc) { + val fcnc = nc.getAugmentation(FlowCapableNodeConnector) + if (fcnc != null) { + return fcnc.toADNodeConnectorProperties + } + return new HashSet(); + } + + public static def toADNodeConnectorProperties(FlowNodeConnector fcncu) { + val props = new HashSet(); + if (fcncu != null) { + if (fcncu.currentFeature != null && fcncu.currentFeature.toAdBandwidth != null) { + props.add(fcncu.currentFeature.toAdBandwidth) + } + if (fcncu.advertisedFeatures != null && fcncu.advertisedFeatures.toAdAdvertizedBandwidth != null) { + props.add(fcncu.advertisedFeatures.toAdAdvertizedBandwidth) + } + if (fcncu.supported != null && fcncu.supported.toAdSupportedBandwidth != null) { + props.add(fcncu.supported.toAdSupportedBandwidth) + } + if (fcncu.peerFeatures != null && fcncu.peerFeatures.toAdPeerBandwidth != null) { + props.add(fcncu.peerFeatures.toAdPeerBandwidth) + } + if (fcncu.name != null && fcncu.name.toAdName != null) { + props.add(fcncu.name.toAdName) + } + if (fcncu.configuration != null && fcncu.configuration.toAdConfig != null) { + props.add(fcncu.configuration.toAdConfig) + } + if (fcncu.state != null && fcncu.state.toAdState != null) { + props.add(fcncu.state.toAdState) + } + } + return props + } + + public static def toAdName(String name) { + return new Name(name) + } + + public static def toAdConfig(PortConfig pc) { + var Config config; + if (pc.PORTDOWN) { + config = new Config(Config.ADMIN_DOWN) + } else { + config = new Config(Config.ADMIN_UP) + } + return config + } + + public static def toAdState(State s) { + var org.opendaylight.controller.sal.core.State state + if (s.linkDown) { + state = new org.opendaylight.controller.sal.core.State(org.opendaylight.controller.sal.core.State.EDGE_DOWN) + } else { + state = new org.opendaylight.controller.sal.core.State(org.opendaylight.controller.sal.core.State.EDGE_UP) + } + return state + } + + public static def toAdBandwidth(PortFeatures pf) { + var Bandwidth bw = null + if (pf.is_10mbHd || pf.is_10mbFd) { + bw = new Bandwidth(Bandwidth.BW10Mbps) + } else if (pf.is_100mbHd || pf.is_100mbFd) { + bw = new Bandwidth(Bandwidth.BW100Mbps) + } else if (pf.is_1gbHd || pf.is_1gbFd) { + bw = new Bandwidth(Bandwidth.BW1Gbps) + } else if (pf.is_1gbFd) { + bw = new Bandwidth(Bandwidth.BW10Gbps) + } else if (pf.is_10gbFd) { + bw = new Bandwidth(Bandwidth.BW10Gbps) + } else if (pf.is_40gbFd) { + bw = new Bandwidth(Bandwidth.BW40Gbps) + } else if (pf.is_100gbFd) { + bw = new Bandwidth(Bandwidth.BW100Gbps) + } else if (pf.is_1tbFd) { + bw = new Bandwidth(Bandwidth.BW1Tbps) + } + return bw; + } + + public static def toAdAdvertizedBandwidth(PortFeatures pf) { + var AdvertisedBandwidth abw + val bw = pf.toAdBandwidth + if (bw != null) { + abw = new AdvertisedBandwidth(bw.value) + } + return abw + } + + public static def toAdSupportedBandwidth(PortFeatures pf) { + var SupportedBandwidth sbw + val bw = pf.toAdBandwidth + if (bw != null) { + sbw = new SupportedBandwidth(bw.value) + } + return sbw + } + + public static def toAdPeerBandwidth(PortFeatures pf) { + var PeerBandwidth pbw + val bw = pf.toAdBandwidth + if (bw != null) { + pbw = new PeerBandwidth(bw.value) + } + return pbw + } + + public static def toADNodeProperties(NodeUpdated nu) { + val fcnu = nu.getAugmentation(FlowCapableNodeUpdated) + if (fcnu != null) { + return fcnu.toADNodeProperties(nu.id) + } + return new HashSet(); + + } + + public static def toADNodeProperties(FlowNode fcnu, NodeId id) { + val props = new HashSet(); + if (fcnu != null) { + props.add(toADTimestamp) + + // props.add(fcnu.supportedActions.toADActions) - TODO + if (id != null) { + props.add(id.toADMacAddress) + } + if (fcnu.switchFeatures != null) { + if (fcnu.switchFeatures.maxTables != null) { + props.add(fcnu.switchFeatures.maxTables.toADTables) + } + if (fcnu.switchFeatures.capabilities != null) { + props.add(fcnu.switchFeatures.capabilities.toADCapabiliities) + } + if (fcnu.switchFeatures.maxBuffers != null) { + props.add(fcnu.switchFeatures.maxBuffers.toADBuffers) + } + } + } + return props; + } + + public static def toADTimestamp() { + val date = new Date(); + val timestamp = new TimeStamp(date.time, "connectedSince") + return timestamp; + } + + public static def toADMacAddress(NodeId id) { + return new MacAddress(Long.parseLong(id.value.replaceAll("openflow:", "")).longValue.bytesFromDpid) + } + + public static def toADTables(Short tables) { + return new Tables(tables.byteValue) + } + + public static def toADCapabiliities(List> capabilities) { + var int b + for (capability : capabilities) { + if (capability.equals(FlowFeatureCapabilityFlowStats)) { + b = Capabilities.CapabilitiesType.FLOW_STATS_CAPABILITY.value.bitwiseOr(b) + } else if (capability.equals(FlowFeatureCapabilityTableStats)) { + b = Capabilities.CapabilitiesType.TABLE_STATS_CAPABILITY.value.bitwiseOr(b) + } else if (capability.equals(FlowFeatureCapabilityPortStats)) { + b = Capabilities.CapabilitiesType.PORT_STATS_CAPABILITY.value.bitwiseOr(b) + } else if (capability.equals(FlowFeatureCapabilityStp)) { + b = Capabilities.CapabilitiesType.STP_CAPABILITY.value.bitwiseOr(b) + } else if (capability.equals(FlowFeatureCapabilityIpReasm)) { + b = Capabilities.CapabilitiesType.IP_REASSEM_CAPABILITY.value.bitwiseOr(b) + } else if (capability.equals(FlowFeatureCapabilityQueueStats)) { + b = Capabilities.CapabilitiesType.QUEUE_STATS_CAPABILITY.value.bitwiseOr(b) + } else if (capability.equals(FlowFeatureCapabilityArpMatchIp)) { + b = Capabilities.CapabilitiesType.ARP_MATCH_IP_CAPABILITY.value.bitwiseOr(b) + } + } + return new Capabilities(b) + } + + public static def toADBuffers(Long buffers) { + return new Buffers(buffers.intValue) + } + } diff --git a/opendaylight/md-sal/compatibility/sal-compatibility/src/main/java/org/opendaylight/controller/sal/compatibility/ToSalConversionsUtils.java b/opendaylight/md-sal/compatibility/sal-compatibility/src/main/java/org/opendaylight/controller/sal/compatibility/ToSalConversionsUtils.java index 37bb277858..46fd62f3f2 100644 --- a/opendaylight/md-sal/compatibility/sal-compatibility/src/main/java/org/opendaylight/controller/sal/compatibility/ToSalConversionsUtils.java +++ b/opendaylight/md-sal/compatibility/sal-compatibility/src/main/java/org/opendaylight/controller/sal/compatibility/ToSalConversionsUtils.java @@ -43,6 +43,7 @@ import org.opendaylight.controller.sal.action.SetVlanCfi; import org.opendaylight.controller.sal.action.SetVlanId; import org.opendaylight.controller.sal.action.SetVlanPcp; import org.opendaylight.controller.sal.action.SwPath; +import org.opendaylight.controller.sal.core.Capabilities; import org.opendaylight.controller.sal.core.NodeConnector; import org.opendaylight.controller.sal.flowprogrammer.Flow; import org.opendaylight.controller.sal.match.Match; @@ -85,6 +86,7 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.acti import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.address.Address; import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.address.address.Ipv4; import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.address.address.Ipv6; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FeatureCapability; import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.ApplyActionsCase; import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.Instruction; import org.opendaylight.yang.gen.v1.urn.opendaylight.l2.types.rev130827.EtherType; @@ -563,7 +565,7 @@ public class ToSalConversionsUtils { } } - private static byte[] bytesFrom(MacAddress address) { + public static byte[] bytesFrom(MacAddress address) { String[] mac = address.getValue().split(":"); byte[] macAddress = new byte[6]; // mac.length == 6 bytes for (int i = 0; i < mac.length; i++) { @@ -571,4 +573,15 @@ public class ToSalConversionsUtils { } return macAddress; } + + public static byte[] bytesFromDpid(long dpid) { + byte[] mac = new byte[] { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; + + for (short i = 0; i < 6; i++) { + mac[5 - i] = (byte) dpid; + dpid >>= 8; + } + + return mac; + } } diff --git a/opendaylight/md-sal/compatibility/sal-compatibility/src/main/java/org/opendaylight/controller/sal/compatibility/topology/TopologyAdapter.xtend b/opendaylight/md-sal/compatibility/sal-compatibility/src/main/java/org/opendaylight/controller/sal/compatibility/topology/TopologyAdapter.xtend new file mode 100644 index 0000000000..bd2590f18b --- /dev/null +++ b/opendaylight/md-sal/compatibility/sal-compatibility/src/main/java/org/opendaylight/controller/sal/compatibility/topology/TopologyAdapter.xtend @@ -0,0 +1,30 @@ +package org.opendaylight.controller.sal.compatibility.topology + +import org.opendaylight.controller.md.sal.binding.util.TypeSafeDataReader +import org.opendaylight.controller.sal.binding.api.data.DataProviderService +import org.opendaylight.controller.sal.topology.IPluginInTopologyService +import org.opendaylight.controller.sal.topology.IPluginOutTopologyService +import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev130712.NetworkTopology +import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev130712.TopologyId +import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev130712.network.topology.Topology +import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev130712.network.topology.TopologyKey +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier + +import static extension org.opendaylight.controller.sal.compatibility.topology.TopologyMapping.* + +class TopologyAdapter implements IPluginInTopologyService { + + @Property + DataProviderService dataService; + + @Property + IPluginOutTopologyService topologyPublisher; + + override sollicitRefresh() { + val path = InstanceIdentifier.builder(NetworkTopology).child(Topology,new TopologyKey(new TopologyId("flow:1"))).toInstance; + val reader = TypeSafeDataReader.forReader(dataService) + val topology = reader.readOperationalData(path) + topologyPublisher.edgeUpdate(topology.toADEdgeUpdates(reader)) + } + +} \ No newline at end of file diff --git a/opendaylight/md-sal/compatibility/sal-compatibility/src/main/java/org/opendaylight/controller/sal/compatibility/topology/TopologyCommitHandler.xtend b/opendaylight/md-sal/compatibility/sal-compatibility/src/main/java/org/opendaylight/controller/sal/compatibility/topology/TopologyCommitHandler.xtend new file mode 100644 index 0000000000..7d05ce60fa --- /dev/null +++ b/opendaylight/md-sal/compatibility/sal-compatibility/src/main/java/org/opendaylight/controller/sal/compatibility/topology/TopologyCommitHandler.xtend @@ -0,0 +1,62 @@ +package org.opendaylight.controller.sal.compatibility.topology + +import com.google.common.collect.FluentIterable +import java.util.concurrent.CopyOnWriteArrayList +import org.opendaylight.controller.md.sal.binding.util.TypeSafeDataReader +import org.opendaylight.controller.md.sal.common.api.data.DataCommitHandler +import org.opendaylight.controller.md.sal.common.api.data.DataModification +import org.opendaylight.controller.sal.binding.api.data.DataProviderService +import org.opendaylight.controller.sal.core.UpdateType +import org.opendaylight.controller.sal.topology.IPluginOutTopologyService +import org.opendaylight.controller.sal.topology.TopoEdgeUpdate +import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev130712.NetworkTopology +import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev130712.TopologyId +import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev130712.network.topology.Topology +import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev130712.network.topology.TopologyKey +import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev130712.network.topology.topology.Link +import org.opendaylight.yangtools.yang.binding.DataObject +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier +import static extension org.opendaylight.controller.sal.compatibility.topology.TopologyMapping.* +import org.slf4j.LoggerFactory + +class TopologyCommitHandler implements DataCommitHandler, DataObject> { + static val LOG = LoggerFactory.getLogger(TopologyCommitHandler); + @Property + IPluginOutTopologyService topologyPublisher; + + @Property + DataProviderService dataService; + + new(DataProviderService dataService) { + _topologyPublisher = topologyPublisher + _dataService = dataService + } + + override requestCommit(DataModification, DataObject> modification) { + val msg = new CopyOnWriteArrayList() + try { + val reader = TypeSafeDataReader.forReader(dataService) + val topologyPath = InstanceIdentifier.builder(NetworkTopology).child(Topology, new TopologyKey(new TopologyId("flow:1"))).toInstance + val topology = reader.readOperationalData(topologyPath) + val adds = FluentIterable.from(modification.createdOperationalData.entrySet) + .filter[value instanceof Link] + .transform[(value as Link).toAdEdge(topology).toTopoEdgeUpdate(UpdateType.ADDED,reader)] + .toList + val updates = FluentIterable.from(modification.updatedOperationalData.entrySet) + .filter[!modification.createdOperationalData.containsKey(key) && (value instanceof Link)] + .transform[(value as Link).toAdEdge(topology).toTopoEdgeUpdate(UpdateType.ADDED,reader)] // Evidently the ADSAL does not expect edge 'CHANGED" + .toList + val removes = FluentIterable.from(modification.removedOperationalData) + .transform[reader.readOperationalData(it as InstanceIdentifier)] + .filter[it instanceof Link] + .transform[(it as Link).toAdEdge(topology).toTopoEdgeUpdate(UpdateType.REMOVED,reader)] + .toList + msg.addAll(adds) + msg.addAll(updates) + msg.addAll(removes) + } catch (Exception e) { + LOG.error("Exception caught",e) + } + return new TopologyTransaction(modification,topologyPublisher,dataService,msg) + } +} \ No newline at end of file diff --git a/opendaylight/md-sal/compatibility/sal-compatibility/src/main/java/org/opendaylight/controller/sal/compatibility/topology/TopologyMapping.xtend b/opendaylight/md-sal/compatibility/sal-compatibility/src/main/java/org/opendaylight/controller/sal/compatibility/topology/TopologyMapping.xtend new file mode 100644 index 0000000000..62983ccce4 --- /dev/null +++ b/opendaylight/md-sal/compatibility/sal-compatibility/src/main/java/org/opendaylight/controller/sal/compatibility/topology/TopologyMapping.xtend @@ -0,0 +1,71 @@ +package org.opendaylight.controller.sal.compatibility.topology + +import com.google.common.collect.FluentIterable +import java.util.Collections +import java.util.List +import java.util.concurrent.CopyOnWriteArrayList +import org.opendaylight.controller.sal.core.ConstructionException +import org.opendaylight.controller.sal.core.Edge +import org.opendaylight.controller.sal.core.Node +import org.opendaylight.controller.sal.core.NodeConnector +import org.opendaylight.controller.sal.core.UpdateType +import org.opendaylight.controller.sal.topology.TopoEdgeUpdate +import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev130712.NodeId +import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev130712.TpId +import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev130712.network.topology.Topology +import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev130712.network.topology.topology.Link + +import static com.google.common.base.Preconditions.* +import static extension org.opendaylight.controller.sal.compatibility.NodeMapping.* +import org.opendaylight.controller.md.sal.binding.util.TypeSafeDataReader +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNodeConnector + +class TopologyMapping { + + private new() { + throw new UnsupportedOperationException("Utility class. Instantiation is not allowed."); + } + + public static def toADEdgeUpdates(Topology topology,TypeSafeDataReader reader) { + val List result = new CopyOnWriteArrayList() + return FluentIterable.from(topology.link).transform[toAdEdge(topology).toTopoEdgeUpdate(reader)].copyInto(result) + } + + public static def toAdEdge(Link link,Topology topology) { + val adSrc = link.source.sourceTp.toADNodeConnector(link.source.sourceNode) + val adDst = link.destination.destTp.toADNodeConnector(link.destination.destNode) + return new Edge(adSrc,adDst); + } + + public static def toTopoEdgeUpdate(Edge e,TypeSafeDataReader reader) { + return toTopoEdgeUpdate(e,UpdateType.ADDED,reader) + } + + public static def toTopoEdgeUpdate(Edge e,UpdateType type,TypeSafeDataReader reader) { + return new TopoEdgeUpdate(e,e.toAdEdgeProperties(reader),type) + } + + public static def toAdEdgeProperties(Edge e,TypeSafeDataReader reader) { + val nc = reader.readOperationalData(e.tailNodeConnector.toNodeConnectorRef.value as InstanceIdentifier) + return nc.toADNodeConnectorProperties + } + + public static def toADNodeId(NodeId nodeId) { + checkNotNull(nodeId); + return nodeId.value + } + public static def toADNodeConnector(TpId source,NodeId nodeId) throws ConstructionException { + checkNotNull(source); + return new NodeConnector(MD_SAL_TYPE,source.toADNodeConnectorId,nodeId.toADNode) + } + + public static def toADNodeConnectorId(TpId nodeConnectorId) { + return nodeConnectorId.value + } + + public static def toADNode(NodeId nodeId) { + checkNotNull(nodeId); + return new Node(MD_SAL_TYPE,nodeId.toADNodeId); + } +} \ No newline at end of file diff --git a/opendaylight/md-sal/compatibility/sal-compatibility/src/main/java/org/opendaylight/controller/sal/compatibility/topology/TopologyProvider.xtend b/opendaylight/md-sal/compatibility/sal-compatibility/src/main/java/org/opendaylight/controller/sal/compatibility/topology/TopologyProvider.xtend new file mode 100644 index 0000000000..1fde2820e2 --- /dev/null +++ b/opendaylight/md-sal/compatibility/sal-compatibility/src/main/java/org/opendaylight/controller/sal/compatibility/topology/TopologyProvider.xtend @@ -0,0 +1,48 @@ +package org.opendaylight.controller.sal.compatibility.topology + +import org.opendaylight.controller.sal.binding.api.data.DataProviderService +import org.opendaylight.controller.sal.topology.IPluginOutTopologyService +import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev130712.NetworkTopology +import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev130712.TopologyId +import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev130712.network.topology.Topology +import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev130712.network.topology.TopologyKey +import org.opendaylight.yangtools.yang.binding.DataObject +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier +import org.opendaylight.yangtools.concepts.Registration +import org.opendaylight.controller.md.sal.common.api.data.DataCommitHandler +import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev130712.network.topology.topology.Link +import org.slf4j.LoggerFactory + +class TopologyProvider implements AutoCloseable{ + static val LOG = LoggerFactory.getLogger(TopologyProvider); + TopologyCommitHandler commitHandler + + @Property + IPluginOutTopologyService topologyPublisher; + + @Property + DataProviderService dataService; + + Registration,DataObject>> commitHandlerRegistration; + + def void start() { + commitHandler = new TopologyCommitHandler(dataService) + commitHandler.setTopologyPublisher(topologyPublisher) + val InstanceIdentifier path = InstanceIdentifier.builder(NetworkTopology) + .child(Topology,new TopologyKey(new TopologyId("flow:1"))) + .child(Link) + .toInstance(); + commitHandlerRegistration = dataService.registerCommitHandler(path,commitHandler); + LOG.info("TopologyProvider started") + } + + override close() throws Exception { + commitHandlerRegistration.close + } + + def setTopologyPublisher(IPluginOutTopologyService topologyPublisher) { + _topologyPublisher = topologyPublisher; + commitHandler.setTopologyPublisher(topologyPublisher); + } + +} \ No newline at end of file diff --git a/opendaylight/md-sal/compatibility/sal-compatibility/src/main/java/org/opendaylight/controller/sal/compatibility/topology/TopologyTransaction.xtend b/opendaylight/md-sal/compatibility/sal-compatibility/src/main/java/org/opendaylight/controller/sal/compatibility/topology/TopologyTransaction.xtend new file mode 100644 index 0000000000..33927ff316 --- /dev/null +++ b/opendaylight/md-sal/compatibility/sal-compatibility/src/main/java/org/opendaylight/controller/sal/compatibility/topology/TopologyTransaction.xtend @@ -0,0 +1,66 @@ +package org.opendaylight.controller.sal.compatibility.topology + +import java.util.Collections +import java.util.List +import org.opendaylight.controller.md.sal.common.api.data.DataCommitHandler.DataCommitTransaction +import org.opendaylight.controller.md.sal.common.api.data.DataModification +import org.opendaylight.controller.sal.binding.api.data.DataProviderService +import org.opendaylight.controller.sal.topology.IPluginOutTopologyService +import org.opendaylight.controller.sal.topology.TopoEdgeUpdate +import org.opendaylight.yangtools.yang.binding.DataObject +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier +import org.opendaylight.yangtools.yang.common.RpcResult +import org.slf4j.LoggerFactory + +class TopologyTransaction implements DataCommitTransaction, DataObject> { + static val LOG = LoggerFactory.getLogger(TopologyTransaction); + @Property + val DataModification, DataObject> modification; + + @Property + IPluginOutTopologyService topologyPublisher; + + @Property + DataProviderService dataService; + @Property + List edgeUpdates; + + new(DataModification, DataObject> modification,IPluginOutTopologyService topologyPublisher, + DataProviderService dataService,List edgeUpdates) { + _modification = modification; + _topologyPublisher = topologyPublisher + _dataService = dataService + _edgeUpdates = edgeUpdates + } + override finish() throws IllegalStateException { + + if(topologyPublisher != null && _edgeUpdates != null && !edgeUpdates.empty) { + topologyPublisher.edgeUpdate(edgeUpdates) + } + + return new RpcResultTo() + } + + override getModification() { + return _modification; + } + + override rollback() throws IllegalStateException { + // NOOP + } +} +class RpcResultTo implements RpcResult { + + override getErrors() { + return Collections.emptySet + } + + override getResult() { + return null; + } + + override isSuccessful() { + return true; + } + +} \ No newline at end of file diff --git a/opendaylight/md-sal/inventory-manager/src/main/java/org/opendaylight/controller/md/inventory/manager/FlowCapableInventoryProvider.xtend b/opendaylight/md-sal/inventory-manager/src/main/java/org/opendaylight/controller/md/inventory/manager/FlowCapableInventoryProvider.xtend index 2b023a72e1..1a66b3ba16 100644 --- a/opendaylight/md-sal/inventory-manager/src/main/java/org/opendaylight/controller/md/inventory/manager/FlowCapableInventoryProvider.xtend +++ b/opendaylight/md-sal/inventory-manager/src/main/java/org/opendaylight/controller/md/inventory/manager/FlowCapableInventoryProvider.xtend @@ -76,7 +76,7 @@ class NodeChangeCommiter implements OpendaylightInventoryListener { // Check path val it = manager.startChange() - removeRuntimeData(ref.value as InstanceIdentifier); + removeOperationalData(ref.value as InstanceIdentifier); commit() } @@ -93,7 +93,7 @@ class NodeChangeCommiter implements OpendaylightInventoryListener { data.addAugmentation(FlowCapableNodeConnector, augment) } - putRuntimeData(ref.value as InstanceIdentifier, data.build()); + putOperationalData(ref.value as InstanceIdentifier, data.build()); commit() } @@ -101,7 +101,7 @@ class NodeChangeCommiter implements OpendaylightInventoryListener { val ref = node.nodeRef; val it = manager.startChange() - removeRuntimeData(ref.value as InstanceIdentifier); + removeOperationalData(ref.value as InstanceIdentifier); commit() } @@ -117,7 +117,7 @@ class NodeChangeCommiter implements OpendaylightInventoryListener { data.addAugmentation(FlowCapableNode, augment) } - putRuntimeData(ref.value as InstanceIdentifier, data.build()) + putOperationalData(ref.value as InstanceIdentifier, data.build()) commit() } } diff --git a/opendaylight/md-sal/model/model-flow-base/pom.xml b/opendaylight/md-sal/model/model-flow-base/pom.xml index 13ffa3f910..1c21effd05 100644 --- a/opendaylight/md-sal/model/model-flow-base/pom.xml +++ b/opendaylight/md-sal/model/model-flow-base/pom.xml @@ -21,6 +21,11 @@ opendaylight-l2-types 2013.08.27.0 + + ${project.groupId} + model-inventory + ${project.version} + bundle diff --git a/opendaylight/md-sal/model/model-flow-base/src/main/yang/match-types.yang b/opendaylight/md-sal/model/model-flow-base/src/main/yang/match-types.yang index 1ed1b6827b..31736d2737 100644 --- a/opendaylight/md-sal/model/model-flow-base/src/main/yang/match-types.yang +++ b/opendaylight/md-sal/model/model-flow-base/src/main/yang/match-types.yang @@ -5,6 +5,7 @@ module opendaylight-match-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-l2-types {prefix l2t;revision-date "2013-08-27";} + import opendaylight-inventory {prefix inv;revision-date "2013-08-19";} revision "2013-10-26" { description "Initial revision of macth types"; @@ -270,11 +271,11 @@ module opendaylight-match-types { grouping match { leaf in-port { - type uint32; + type inv:node-connector-id; } leaf in-phy-port { - type uint32; + type inv:node-connector-id; } container "metadata" { diff --git a/opendaylight/md-sal/model/model-flow-base/src/main/yang/port-types.yang b/opendaylight/md-sal/model/model-flow-base/src/main/yang/port-types.yang index bc05894da8..2554fffadb 100644 --- a/opendaylight/md-sal/model/model-flow-base/src/main/yang/port-types.yang +++ b/opendaylight/md-sal/model/model-flow-base/src/main/yang/port-types.yang @@ -27,11 +27,15 @@ module opendaylight-port-types { } } - typedef port-state { - type enumeration { - enum link-down; - enum blocked; - enum live; + grouping port-state { + leaf link-down { + type boolean; + } + leaf blocked { + type boolean; + } + leaf live { + type boolean; } } @@ -103,9 +107,9 @@ module opendaylight-port-types { description "Human readable name of the port"; } - leaf state { - type port-state; - description "Bit map of OFPPS-* flags"; + container state { + uses port-state; + description "Description of state of port"; } leaf current-feature { diff --git a/opendaylight/md-sal/model/model-topology/src/main/yang/opendaylight-topology-inventory.yang b/opendaylight/md-sal/model/model-topology/src/main/yang/opendaylight-topology-inventory.yang index 33c03ba059..ceeef45f23 100644 --- a/opendaylight/md-sal/model/model-topology/src/main/yang/opendaylight-topology-inventory.yang +++ b/opendaylight/md-sal/model/model-topology/src/main/yang/opendaylight-topology-inventory.yang @@ -21,12 +21,14 @@ module opendaylight-topology-inventory { augment "/topo:network-topology/topo:topology/topo:node" { ext:augment-identifier "inventory-node"; - uses inv:node-context-ref; + leaf inventory-node-ref { + type inv:node-ref; + } } augment "/topo:network-topology/topo:topology/topo:node/topo:termination-point" { ext:augment-identifier "inventory-node-connector"; - leaf node-connector { + leaf inventory-node-connector-ref { ext:context-reference "inv:node-connector-context"; type inv:node-connector-ref; } diff --git a/opendaylight/md-sal/model/pom.xml b/opendaylight/md-sal/model/pom.xml index c5f1dddc34..571e9d8df2 100644 --- a/opendaylight/md-sal/model/pom.xml +++ b/opendaylight/md-sal/model/pom.xml @@ -19,7 +19,7 @@ UTF-8 - 2.3.7 + 2.4.0 @@ -40,7 +40,7 @@ ${project.groupId}.${project.artifactId} - *,org.opendaylight.yangtools.yang.binding.annotations + org.opendaylight.yangtools.yang.binding.annotations, * @@ -68,6 +68,10 @@ org.opendaylight.yangtools.yang.unified.doc.generator.maven.DocumentationGeneratorImpl target/site/models + + org.opendaylight.yangtools.yang.wadl.generator.maven.WadlGenerator + target/site/models + true diff --git a/opendaylight/md-sal/pom.xml b/opendaylight/md-sal/pom.xml index 0d6523bc0b..efc84237b5 100644 --- a/opendaylight/md-sal/pom.xml +++ b/opendaylight/md-sal/pom.xml @@ -50,7 +50,9 @@ inventory-manager statistics-manager + topology-manager forwardingrules-manager + topology-lldp-discovery compatibility diff --git a/opendaylight/md-sal/remoterpc-routingtable/integrationtest/test-nb/pom.xml b/opendaylight/md-sal/remoterpc-routingtable/integrationtest/test-nb/pom.xml index 35b2a4b250..1fd4b762c1 100644 --- a/opendaylight/md-sal/remoterpc-routingtable/integrationtest/test-nb/pom.xml +++ b/opendaylight/md-sal/remoterpc-routingtable/integrationtest/test-nb/pom.xml @@ -25,7 +25,7 @@ com.sun.jersey.spi.container.servlet, - org.codehaus.jackson.annotate, + com.fasterxml.jackson.annotation, javax.ws.rs, javax.ws.rs.core, javax.xml.bind, diff --git a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/connect/dom/BindingIndependentConnector.java b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/connect/dom/BindingIndependentConnector.java index daa3914cf7..0a769921d8 100644 --- a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/connect/dom/BindingIndependentConnector.java +++ b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/connect/dom/BindingIndependentConnector.java @@ -115,32 +115,32 @@ public class BindingIndependentConnector implements // public DataObject readOperationalData(InstanceIdentifier path) { try { org.opendaylight.yangtools.yang.data.api.InstanceIdentifier biPath = mappingService.toDataDom(path); - CompositeNode result = biDataService.readOperationalData(biPath); - Class targetType = path.getTargetType(); - - if (Augmentation.class.isAssignableFrom(targetType)) { - path = mappingService.fromDataDom(biPath); - Class> augmentType = (Class>) targetType; - DataObject parentTo = mappingService.dataObjectFromDataDom(path, result); - if (parentTo instanceof Augmentable) { - return (DataObject) ((Augmentable) parentTo).getAugmentation(augmentType); - } - - } - return mappingService.dataObjectFromDataDom(path, result); - + return potentialAugmentationRead(path,biPath,result); } catch (DeserializationException e) { throw new IllegalStateException(e); } } + private DataObject potentialAugmentationRead(InstanceIdentifier path, org.opendaylight.yangtools.yang.data.api.InstanceIdentifier biPath, CompositeNode result) throws DeserializationException { + Class targetType = path.getTargetType(); + if (Augmentation.class.isAssignableFrom(targetType)) { + path = mappingService.fromDataDom(biPath); + Class> augmentType = (Class>) targetType; + DataObject parentTo = mappingService.dataObjectFromDataDom(path, result); + if (parentTo instanceof Augmentable) { + return (DataObject) ((Augmentable) parentTo).getAugmentation(augmentType); + } + } + return mappingService.dataObjectFromDataDom(path, result); + } + @Override public DataObject readConfigurationData(InstanceIdentifier path) { try { org.opendaylight.yangtools.yang.data.api.InstanceIdentifier biPath = mappingService.toDataDom(path); CompositeNode result = biDataService.readConfigurationData(biPath); - return mappingService.dataObjectFromDataDom(path, result); + return potentialAugmentationRead(path,biPath,result); } catch (DeserializationException e) { throw new IllegalStateException(e); } diff --git a/opendaylight/md-sal/sal-binding-dom-it/src/test/java/org/opendaylight/controller/sal/binding/test/bugfix/PutAugmentationTest.java b/opendaylight/md-sal/sal-binding-dom-it/src/test/java/org/opendaylight/controller/sal/binding/test/bugfix/PutAugmentationTest.java index 96d0361b1d..d9b16af469 100644 --- a/opendaylight/md-sal/sal-binding-dom-it/src/test/java/org/opendaylight/controller/sal/binding/test/bugfix/PutAugmentationTest.java +++ b/opendaylight/md-sal/sal-binding-dom-it/src/test/java/org/opendaylight/controller/sal/binding/test/bugfix/PutAugmentationTest.java @@ -12,6 +12,8 @@ import org.opendaylight.controller.sal.binding.api.data.DataChangeListener; import org.opendaylight.controller.sal.binding.api.data.DataModificationTransaction; import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode; import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNodeBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNodeConnector; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNodeConnectorBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.flow.node.SupportedActions; import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.flow.node.SupportedActionsBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.flow.node.supported.actions.ActionType; @@ -130,8 +132,60 @@ public class PutAugmentationTest extends AbstractDataServiceTest implements Data assertBindingIndependentVersion(NODE_INSTANCE_ID_BI); testNodeRemove(); } + + @Test + public void putNodeWithAugmentation() throws Exception { + + NodeBuilder nodeBuilder = new NodeBuilder(); + nodeBuilder.setId(new NodeId(NODE_ID)); + nodeBuilder.setKey(NODE_KEY); + FlowCapableNodeBuilder fnub = new FlowCapableNodeBuilder(); + fnub.setHardware("Hardware Foo"); + fnub.setManufacturer("Manufacturer Foo"); + fnub.setSerialNumber("Serial Foo"); + fnub.setDescription("Description Foo"); + fnub.setSoftware("JUnit emulated"); + FlowCapableNode fnu = fnub.build(); + + nodeBuilder.addAugmentation(FlowCapableNode.class, fnu); + DataModificationTransaction baseTransaction = baDataService.beginTransaction(); + baseTransaction.putOperationalData(NODE_INSTANCE_ID_BA, nodeBuilder.build()); + RpcResult result = baseTransaction.commit().get(); + assertEquals(TransactionStatus.COMMITED, result.getResult()); + + FlowCapableNode readedAugmentation = (FlowCapableNode) baDataService.readOperationalData(InstanceIdentifier.builder(NODE_INSTANCE_ID_BA).augmentation(FlowCapableNode.class).toInstance()); + assertNotNull(readedAugmentation); + assertEquals(fnu.getHardware(), readedAugmentation.getHardware()); + + testPutNodeConnectorWithAugmentation(); + testNodeRemove(); + } + private void testPutNodeConnectorWithAugmentation() throws Exception { + NodeConnectorKey ncKey = new NodeConnectorKey(new NodeConnectorId("test:0:0")); + InstanceIdentifier ncPath = InstanceIdentifier.builder(NODE_INSTANCE_ID_BA) + .child(NodeConnector.class, ncKey).toInstance(); + InstanceIdentifier ncAugmentPath = InstanceIdentifier.builder(ncPath) + .augmentation(FlowCapableNodeConnector.class).toInstance(); + + NodeConnectorBuilder nc = new NodeConnectorBuilder(); + nc.setKey(ncKey); + + FlowCapableNodeConnectorBuilder fncb = new FlowCapableNodeConnectorBuilder(); + fncb.setName("Baz"); + nc.addAugmentation(FlowCapableNodeConnector.class, fncb.build()); + + DataModificationTransaction baseTransaction = baDataService.beginTransaction(); + baseTransaction.putOperationalData(ncPath, nc.build()); + RpcResult result = baseTransaction.commit().get(); + assertEquals(TransactionStatus.COMMITED, result.getResult()); + + FlowCapableNodeConnector readedAugmentation = (FlowCapableNodeConnector) baDataService.readOperationalData(ncAugmentPath); + assertNotNull(readedAugmentation); + assertEquals(fncb.getName(), readedAugmentation.getName()); + } + private void testNodeRemove() throws Exception { DataModificationTransaction transaction = baDataService.beginTransaction(); transaction.removeOperationalData(NODE_INSTANCE_ID_BA); diff --git a/opendaylight/md-sal/sal-binding-util/src/main/java/org/opendaylight/controller/md/sal/binding/util/TypeSafeDataReader.java b/opendaylight/md-sal/sal-binding-util/src/main/java/org/opendaylight/controller/md/sal/binding/util/TypeSafeDataReader.java index 738a14a9bd..fd81af353c 100644 --- a/opendaylight/md-sal/sal-binding-util/src/main/java/org/opendaylight/controller/md/sal/binding/util/TypeSafeDataReader.java +++ b/opendaylight/md-sal/sal-binding-util/src/main/java/org/opendaylight/controller/md/sal/binding/util/TypeSafeDataReader.java @@ -7,7 +7,7 @@ import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; public final class TypeSafeDataReader { - private final DataReader,DataObject> delegate; + private final DataReader,DataObject> delegate; @@ -16,7 +16,7 @@ public final class TypeSafeDataReader { } - public TypeSafeDataReader(DataReader, DataObject> delegate) { + public TypeSafeDataReader(DataReader, DataObject> delegate) { this.delegate = delegate; } @@ -32,7 +32,7 @@ public final class TypeSafeDataReader { return (D) delegate.readOperationalData(path); } - public static TypeSafeDataReader forReader(DataReader, DataObject> delegate) { + public static TypeSafeDataReader forReader(DataReader, DataObject> delegate) { return new TypeSafeDataReader(delegate); } } diff --git a/opendaylight/md-sal/sal-dom-api/src/main/java/org/opendaylight/controller/sal/core/api/mount/MountInstance.java b/opendaylight/md-sal/sal-dom-api/src/main/java/org/opendaylight/controller/sal/core/api/mount/MountInstance.java index 1596165601..910c7cb623 100644 --- a/opendaylight/md-sal/sal-dom-api/src/main/java/org/opendaylight/controller/sal/core/api/mount/MountInstance.java +++ b/opendaylight/md-sal/sal-dom-api/src/main/java/org/opendaylight/controller/sal/core/api/mount/MountInstance.java @@ -16,8 +16,11 @@ import org.opendaylight.controller.sal.core.api.notify.NotificationService; import org.opendaylight.yangtools.yang.common.QName; import org.opendaylight.yangtools.yang.common.RpcResult; import org.opendaylight.yangtools.yang.data.api.CompositeNode; +import org.opendaylight.yangtools.yang.model.api.SchemaContext; public interface MountInstance extends NotificationService, DataBrokerService { Future> rpc(QName type, CompositeNode input); + + SchemaContext getSchemaContext(); } diff --git a/opendaylight/md-sal/sal-dom-api/src/main/java/org/opendaylight/controller/sal/core/api/mount/MountProvisionInstance.java b/opendaylight/md-sal/sal-dom-api/src/main/java/org/opendaylight/controller/sal/core/api/mount/MountProvisionInstance.java index 92542bc345..e5fc4b7aa4 100644 --- a/opendaylight/md-sal/sal-dom-api/src/main/java/org/opendaylight/controller/sal/core/api/mount/MountProvisionInstance.java +++ b/opendaylight/md-sal/sal-dom-api/src/main/java/org/opendaylight/controller/sal/core/api/mount/MountProvisionInstance.java @@ -3,6 +3,8 @@ package org.opendaylight.controller.sal.core.api.mount; import org.opendaylight.controller.sal.core.api.RpcProvisionRegistry; import org.opendaylight.controller.sal.core.api.data.DataProviderService; import org.opendaylight.controller.sal.core.api.notify.NotificationPublishService; +import com.google.common.base.Optional; +import org.opendaylight.yangtools.yang.model.api.SchemaContext; public interface MountProvisionInstance extends // MountInstance,// @@ -10,4 +12,6 @@ public interface MountProvisionInstance extends // RpcProvisionRegistry,// DataProviderService { + void setSchemaContext(SchemaContext optional); + } diff --git a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/sal/dom/broker/MountPointImpl.java b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/sal/dom/broker/MountPointImpl.java index 7509a38a14..ab5b145064 100644 --- a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/sal/dom/broker/MountPointImpl.java +++ b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/sal/dom/broker/MountPointImpl.java @@ -31,6 +31,7 @@ import org.opendaylight.yangtools.yang.data.api.CompositeNode; import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier; import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.InstanceIdentifierBuilder; import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.PathArgument; +import org.opendaylight.yangtools.yang.model.api.SchemaContext; public class MountPointImpl implements MountProvisionInstance { @@ -42,6 +43,8 @@ public class MountPointImpl implements MountProvisionInstance { private final InstanceIdentifier mountPath; + private SchemaContext schemaContext; + public MountPointImpl(InstanceIdentifier path) { this.mountPath = path; rpcs = new RpcRouterImpl(""); @@ -163,6 +166,14 @@ public class MountPointImpl implements MountProvisionInstance { // NOOP } + public SchemaContext getSchemaContext() { + return schemaContext; + } + + public void setSchemaContext(SchemaContext schemaContext) { + this.schemaContext = schemaContext; + } + class ReadWrapper implements DataReader { diff --git a/opendaylight/md-sal/sal-netconf-connector/pom.xml b/opendaylight/md-sal/sal-netconf-connector/pom.xml index fe613565a6..2323b09f99 100644 --- a/opendaylight/md-sal/sal-netconf-connector/pom.xml +++ b/opendaylight/md-sal/sal-netconf-connector/pom.xml @@ -170,6 +170,24 @@ org.slf4j slf4j-api + + org.opendaylight.controller + sal-binding-broker-impl + 1.0-SNAPSHOT + test + + + org.opendaylight.controller + sal-binding-broker-impl + 1.0-SNAPSHOT + test-jar + test + + + org.opendaylight.controller + ietf-netconf-monitoring + 0.2.3-SNAPSHOT + org.opendaylight.yangtools.model ietf-inet-types 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 index 55a1fbfe48..f5d592c007 100644 --- 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 @@ -12,8 +12,12 @@ package org.opendaylight.controller.config.yang.md.sal.connector.netconf; import io.netty.channel.EventLoopGroup; import io.netty.util.concurrent.GlobalEventExecutor; +import java.io.File; +import java.io.InputStream; import java.net.InetAddress; import java.net.InetSocketAddress; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; import javax.net.ssl.SSLContext; @@ -24,6 +28,10 @@ import org.opendaylight.controller.netconf.util.handler.ssh.authentication.Login import org.opendaylight.controller.sal.connect.netconf.NetconfDevice; import org.opendaylight.protocol.framework.ReconnectStrategy; import org.opendaylight.protocol.framework.TimedReconnectStrategy; +import org.opendaylight.yangtools.yang.model.util.repo.AbstractCachingSchemaSourceProvider; +import org.opendaylight.yangtools.yang.model.util.repo.FilesystemSchemaCachingProvider; +import org.opendaylight.yangtools.yang.model.util.repo.SchemaSourceProvider; +import org.opendaylight.yangtools.yang.model.util.repo.SchemaSourceProviders; import org.osgi.framework.BundleContext; import static com.google.common.base.Preconditions.*; @@ -37,6 +45,8 @@ import com.google.common.net.InetAddresses; public final class NetconfConnectorModule extends org.opendaylight.controller.config.yang.md.sal.connector.netconf.AbstractNetconfConnectorModule { + private static ExecutorService GLOBAL_PROCESSING_EXECUTOR = null; + private static AbstractCachingSchemaSourceProvider GLOBAL_NETCONF_SOURCE_PROVIDER = null; private BundleContext bundleContext; public NetconfConnectorModule(org.opendaylight.controller.config.api.ModuleIdentifier identifier, org.opendaylight.controller.config.api.DependencyResolver dependencyResolver) { @@ -74,31 +84,56 @@ public final class NetconfConnectorModule extends org.opendaylight.controller.co } else { addressValue = getAddress().getIpv6Address().getValue(); } - */ ReconnectStrategy strategy = new TimedReconnectStrategy(GlobalEventExecutor.INSTANCE, attemptMsTimeout, 1000, 1.0, null, Long.valueOf(connectionAttempts), null); - - device.setStrategy(strategy); + device.setReconnectStrategy(strategy); InetAddress addr = InetAddresses.forString(addressValue); InetSocketAddress socketAddress = new InetSocketAddress(addr , getPort().intValue()); + + + device.setProcessingExecutor(getGlobalProcessingExecutor()); + device.setSocketAddress(socketAddress); + device.setEventExecutor(getEventExecutorDependency()); + device.setDispatcher(createDispatcher()); + device.setSchemaSourceProvider(getGlobalNetconfSchemaProvider(bundleContext)); + getDomRegistryDependency().registerProvider(device, bundleContext); + device.start(); + return device; + } + + private ExecutorService getGlobalProcessingExecutor() { + if(GLOBAL_PROCESSING_EXECUTOR == null) { + + GLOBAL_PROCESSING_EXECUTOR = Executors.newCachedThreadPool(); + + } + return GLOBAL_PROCESSING_EXECUTOR; + } + + private synchronized AbstractCachingSchemaSourceProvider getGlobalNetconfSchemaProvider(BundleContext bundleContext) { + if(GLOBAL_NETCONF_SOURCE_PROVIDER == null) { + String storageFile = "cache/schema"; + File directory = bundleContext.getDataFile(storageFile); + SchemaSourceProvider defaultProvider = SchemaSourceProviders.noopProvider(); + GLOBAL_NETCONF_SOURCE_PROVIDER = FilesystemSchemaCachingProvider.createFromStringSourceProvider(defaultProvider, directory); + } + return GLOBAL_NETCONF_SOURCE_PROVIDER; + } + + private NetconfClientDispatcher createDispatcher() { EventLoopGroup bossGroup = getBossThreadGroupDependency(); EventLoopGroup workerGroup = getWorkerThreadGroupDependency(); - NetconfClientDispatcher dispatcher = null; if(getTcpOnly()) { - dispatcher = new NetconfClientDispatcher( bossGroup, workerGroup); + return new NetconfClientDispatcher( bossGroup, workerGroup); } else { AuthenticationHandler authHandler = new LoginPassword(getUsername(),getPassword()); - dispatcher = new NetconfSshClientDispatcher(authHandler , bossGroup, workerGroup); + return new NetconfSshClientDispatcher(authHandler , bossGroup, workerGroup); } - getDomRegistryDependency().registerProvider(device, bundleContext); - - device.start(dispatcher); - return device; } public void setBundleContext(BundleContext bundleContext) { 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 7c4bf5faca..bfe352ad41 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 @@ -25,13 +25,43 @@ import org.opendaylight.yangtools.yang.data.impl.CompositeNodeTOImpl import org.opendaylight.protocol.framework.ReconnectStrategy import org.opendaylight.controller.md.sal.common.api.data.DataCommitHandler import org.opendaylight.controller.md.sal.common.api.data.DataModification +import com.google.common.collect.FluentIterable +import org.opendaylight.yangtools.yang.model.api.SchemaContext +import org.opendaylight.yangtools.yang.data.impl.ImmutableCompositeNode +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.netconf.monitoring.rev101004.NetconfState +import org.opendaylight.yangtools.yang.parser.impl.YangParserImpl +import java.io.InputStream +import org.slf4j.LoggerFactory +import org.slf4j.Logger +import org.opendaylight.controller.netconf.client.AbstractNetconfClientNotifySessionListener +import org.opendaylight.controller.netconf.client.NetconfClientSession +import org.opendaylight.controller.netconf.api.NetconfMessage +import io.netty.util.concurrent.EventExecutor -class NetconfDevice implements - Provider, // - DataReader, // - DataCommitHandler, // - RpcImplementation, // - AutoCloseable { +import java.util.Map +import java.util.Set +import com.google.common.collect.ImmutableMap + +import org.opendaylight.yangtools.yang.model.util.repo.AbstractCachingSchemaSourceProvider +import org.opendaylight.yangtools.yang.model.util.repo.SchemaSourceProvider +import com.google.common.base.Optional +import com.google.common.collect.ImmutableList +import org.opendaylight.yangtools.yang.model.util.repo.SchemaSourceProviders +import static com.google.common.base.Preconditions.*; +import java.util.concurrent.ExecutorService +import java.util.concurrent.Future +import org.opendaylight.controller.netconf.client.NetconfClientSessionListener +import io.netty.util.concurrent.Promise +import org.opendaylight.controller.netconf.util.xml.XmlElement +import org.opendaylight.controller.netconf.util.xml.XmlNetconfConstants +import java.util.concurrent.ExecutionException +import java.util.concurrent.locks.ReentrantLock + +class NetconfDevice implements Provider, // +DataReader, // +DataCommitHandler, // +RpcImplementation, // +AutoCloseable { var NetconfClient client; @@ -41,35 +71,97 @@ class NetconfDevice implements @Property var MountProvisionInstance mountInstance; + @Property + var EventExecutor eventExecutor; + + @Property + var ExecutorService processingExecutor; + @Property var InstanceIdentifier path; @Property - var ReconnectStrategy strategy; + var ReconnectStrategy reconnectStrategy; + + @Property + var AbstractCachingSchemaSourceProvider schemaSourceProvider; + + private NetconfDeviceSchemaContextProvider schemaContextProvider + + protected val Logger logger Registration> operReaderReg Registration> confReaderReg Registration> commitHandlerReg - + val String name MountProvisionService mountService + + int messegeRetryCount = 5; + + int messageTimeoutCount = 5 * 1000; + + Set cachedCapabilities + + @Property + var NetconfClientDispatcher dispatcher - + static val InstanceIdentifier ROOT_PATH = InstanceIdentifier.builder().toInstance(); + public new(String name) { this.name = name; + this.logger = LoggerFactory.getLogger(NetconfDevice.name + "#" + name); this.path = InstanceIdentifier.builder(INVENTORY_PATH).nodeWithKey(INVENTORY_NODE, Collections.singletonMap(INVENTORY_ID, name)).toInstance; } - def start(NetconfClientDispatcher dispatcher) { - client = NetconfClient.clientFor(name, socketAddress, strategy, dispatcher); - confReaderReg = mountInstance.registerConfigurationReader(path, this); - operReaderReg = mountInstance.registerOperationalReader(path, this); - //commitHandlerReg = mountInstance.registerCommitHandler(path,this); + def start() { + checkState(dispatcher != null, "Dispatcher must be set."); + checkState(schemaSourceProvider != null, "Schema Source Provider must be set.") + checkState(eventExecutor != null, "Event executor must be set."); + + val listener = new NetconfDeviceListener(this,eventExecutor); + val task = startClientTask(dispatcher, listener) + if(mountInstance != null) { + confReaderReg = mountInstance.registerConfigurationReader(ROOT_PATH, this); + operReaderReg = mountInstance.registerOperationalReader(ROOT_PATH, this); + } + return processingExecutor.submit(task) as Future; + + //commitHandlerReg = mountInstance.registerCommitHandler(path,this); + } + + def Optional getSchemaContext() { + if (schemaContextProvider == null) { + return Optional.absent(); + } + return schemaContextProvider.currentContext; + } + + private def Runnable startClientTask(NetconfClientDispatcher dispatcher, NetconfDeviceListener listener) { + return [ | + logger.info("Starting Netconf Client on: {}", socketAddress); + client = NetconfClient.clientFor(name, socketAddress, reconnectStrategy, dispatcher, listener); + logger.debug("Initial capabilities {}", initialCapabilities); + var SchemaSourceProvider delegate; + if (initialCapabilities.contains(NetconfMapping.IETF_NETCONF_MONITORING_MODULE)) { + delegate = new NetconfDeviceSchemaSourceProvider(this); + } else { + logger.info("Device does not support IETF Netconf Monitoring.", socketAddress); + delegate = SchemaSourceProviders.noopProvider(); + } + val sourceProvider = schemaSourceProvider.createInstanceFor(delegate); + schemaContextProvider = new NetconfDeviceSchemaContextProvider(this, sourceProvider); + schemaContextProvider.createContextFromCapabilities(initialCapabilities); + if (mountInstance != null && schemaContext.isPresent) { + mountInstance.schemaContext = schemaContext.get(); + } + ] } override readConfigurationData(InstanceIdentifier path) { - val result = invokeRpc(NETCONF_GET_CONFIG_QNAME, wrap(NETCONF_GET_CONFIG_QNAME, CONFIG_SOURCE_RUNNING, path.toFilterStructure())); + val result = invokeRpc(NETCONF_GET_CONFIG_QNAME, + wrap(NETCONF_GET_CONFIG_QNAME, CONFIG_SOURCE_RUNNING, path.toFilterStructure())); val data = result.result.getFirstCompositeByName(NETCONF_DATA_QNAME); return data?.findNode(path) as CompositeNode; } @@ -83,10 +175,17 @@ class NetconfDevice implements override getSupportedRpcs() { Collections.emptySet; } + + def createSubscription(String streamName) { + val it = ImmutableCompositeNode.builder() + QName = NETCONF_CREATE_SUBSCRIPTION_QNAME + addLeaf("stream",streamName); + invokeRpc(QName,toInstance()) + } override invokeRpc(QName rpc, CompositeNode input) { val message = rpc.toRpcMessage(input); - val result = client.sendMessage(message); + val result = client.sendMessage(message, messegeRetryCount, messageTimeoutCount); return result.toRpcResult(); } @@ -96,30 +195,28 @@ class NetconfDevice implements override onSessionInitiated(ProviderSession session) { val dataBroker = session.getService(DataBrokerService); - - - + val transaction = dataBroker.beginTransaction - if(transaction.operationalNodeNotExisting) { - transaction.putOperationalData(path,nodeWithId) + if (transaction.operationalNodeNotExisting) { + transaction.putOperationalData(path, nodeWithId) } - if(transaction.configurationNodeNotExisting) { - transaction.putConfigurationData(path,nodeWithId) + if (transaction.configurationNodeNotExisting) { + transaction.putConfigurationData(path, nodeWithId) } transaction.commit().get(); mountService = session.getService(MountProvisionService); - mountInstance = mountService.createOrGetMountPoint(path); + mountInstance = mountService?.createOrGetMountPoint(path); } - + def getNodeWithId() { - val id = new SimpleNodeTOImpl(INVENTORY_ID,null,name); - return new CompositeNodeTOImpl(INVENTORY_NODE,null,Collections.singletonList(id)); + 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); } @@ -133,9 +230,9 @@ class NetconfDevice implements } else if (current instanceof CompositeNode) { val currentComposite = (current as CompositeNode); - current = currentComposite.getFirstCompositeByName(arg.nodeType); + current = currentComposite.getFirstCompositeByName(arg.nodeType.withoutRevision()); if (current == null) { - current = currentComposite.getFirstSimpleByName(arg.nodeType); + current = currentComposite.getFirstSimpleByName(arg.nodeType.withoutRevision()); } if (current == null) { return null; @@ -149,6 +246,25 @@ class NetconfDevice implements throw new UnsupportedOperationException("TODO: auto-generated method stub") } + def getInitialCapabilities() { + val capabilities = client?.capabilities; + if (capabilities == null) { + return null; + } + if (cachedCapabilities == null) { + cachedCapabilities = FluentIterable.from(capabilities).filter[ + contains("?") && contains("module=") && contains("revision=")].transform [ + val parts = split("\\?"); + val namespace = parts.get(0); + val queryParams = FluentIterable.from(parts.get(1).split("&")); + val revision = queryParams.findFirst[startsWith("revision=")].replaceAll("revision=", ""); + val moduleName = queryParams.findFirst[startsWith("module=")].replaceAll("module=", ""); + return QName.create(namespace, revision, moduleName); + ].toSet(); + } + return cachedCapabilities; + } + override close() { confReaderReg?.close() operReaderReg?.close() @@ -156,3 +272,165 @@ class NetconfDevice implements } } + +package class NetconfDeviceListener extends NetconfClientSessionListener { + + val NetconfDevice device + val EventExecutor eventExecutor + + new(NetconfDevice device,EventExecutor eventExecutor) { + this.device = device + this.eventExecutor = eventExecutor + } + + var Promise messagePromise; + val promiseLock = new ReentrantLock; + + override onMessage(NetconfClientSession session, NetconfMessage message) { + if (isNotification(message)) { + onNotification(session, message); + } else try { + promiseLock.lock + if (messagePromise != null) { + messagePromise.setSuccess(message); + messagePromise = null; + } + } finally { + promiseLock.unlock + } + } + + /** + * Method intended to customize notification processing. + * + * @param session + * {@see + * NetconfClientSessionListener#onMessage(NetconfClientSession, + * NetconfMessage)} + * @param message + * {@see + * NetconfClientSessionListener#onMessage(NetconfClientSession, + * NetconfMessage)} + */ + def void onNotification(NetconfClientSession session, NetconfMessage message) { + device.logger.debug("Received NETCONF notification.",message); + val domNotification = message?.toCompositeNode?.notificationBody; + if(domNotification != null) { + device?.mountInstance?.publish(domNotification); + } + } + + private static def CompositeNode getNotificationBody(CompositeNode node) { + for(child : node.children) { + if(child instanceof CompositeNode) { + return child as CompositeNode; + } + } + } + + override getLastMessage(int attempts, int attemptMsDelay) throws InterruptedException { + val promise = promiseReply(); + val messageAvailable = promise.await(attempts + attemptMsDelay); + if (messageAvailable) { + try { + return promise.get(); + } catch (ExecutionException e) { + throw new IllegalStateException(e); + } + } + + throw new IllegalStateException("Unsuccessful after " + attempts + " attempts."); + + // throw new TimeoutException("Message was not received on time."); + } + + def Promise promiseReply() { + promiseLock.lock + try { + if (messagePromise == null) { + messagePromise = eventExecutor.newPromise(); + return messagePromise; + } + return messagePromise; + } finally { + promiseLock.unlock + } + } + + def boolean isNotification(NetconfMessage message) { + val xmle = XmlElement.fromDomDocument(message.getDocument()); + return XmlNetconfConstants.NOTIFICATION_ELEMENT_NAME.equals(xmle.getName()); + } +} + +package class NetconfDeviceSchemaContextProvider { + + @Property + val NetconfDevice device; + + @Property + val SchemaSourceProvider sourceProvider; + + @Property + var Optional currentContext; + + new(NetconfDevice device, SchemaSourceProvider sourceProvider) { + _device = device + _sourceProvider = sourceProvider + } + + def createContextFromCapabilities(Iterable capabilities) { + + val modelsToParse = ImmutableMap.builder(); + for (cap : capabilities) { + val source = sourceProvider.getSchemaSource(cap.localName, Optional.fromNullable(cap.formattedRevision)); + if (source.present) { + modelsToParse.put(cap, source.get()); + } + } + val context = tryToCreateContext(modelsToParse.build); + currentContext = Optional.fromNullable(context); + } + + def SchemaContext tryToCreateContext(Map modelsToParse) { + val parser = new YangParserImpl(); + try { + val models = parser.parseYangModelsFromStreams(ImmutableList.copyOf(modelsToParse.values)); + val result = parser.resolveSchemaContext(models); + return result; + } catch (Exception e) { + device.logger.debug("Error occured during parsing YANG schemas", e); + return null; + } + } +} + +package class NetconfDeviceSchemaSourceProvider implements SchemaSourceProvider { + + val NetconfDevice device; + + new(NetconfDevice device) { + this.device = device; + } + + override getSchemaSource(String moduleName, Optional revision) { + val it = ImmutableCompositeNode.builder() // + setQName(QName::create(NetconfState.QNAME, "get-schema")) // + addLeaf("format", "yang") + addLeaf("identifier", moduleName) + if (revision.present) { + addLeaf("version", revision.get()) + } + + device.logger.info("Loading YANG schema source for {}:{}", moduleName, revision) + val schemaReply = device.invokeRpc(getQName(), toInstance()); + + if (schemaReply.successful) { + val schemaBody = schemaReply.result.getFirstSimpleByName( + QName::create(NetconfState.QNAME.namespace, null, "data"))?.value; + device.logger.info("YANG Schema successfully received for: {}:{}", moduleName, revision); + return Optional.of(schemaBody as String); + } + return Optional.absent(); + } +} diff --git a/opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/NetconfMapping.xtend b/opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/NetconfMapping.xtend index 78f6d59f77..794b58294e 100644 --- a/opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/NetconfMapping.xtend +++ b/opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/NetconfMapping.xtend @@ -20,51 +20,63 @@ import org.w3c.dom.Element import org.opendaylight.controller.sal.common.util.Rpcs import java.util.List import com.google.common.collect.ImmutableList +import org.opendaylight.yangtools.yang.data.api.SimpleNode +import org.opendaylight.yangtools.yang.data.impl.ImmutableCompositeNode class NetconfMapping { public static val NETCONF_URI = URI.create("urn:ietf:params:xml:ns:netconf:base:1.0") - public static val NETCONF_QNAME = new QName(NETCONF_URI,null,"netconf"); - public static val NETCONF_RPC_QNAME = new QName(NETCONF_QNAME,"rpc"); - public static val NETCONF_GET_QNAME = new QName(NETCONF_QNAME,"get"); - public static val NETCONF_GET_CONFIG_QNAME = new QName(NETCONF_QNAME,"get-config"); - public static val NETCONF_SOURCE_QNAME = new QName(NETCONF_QNAME,"source"); - public static val NETCONF_RUNNING_QNAME = new QName(NETCONF_QNAME,"running"); - public static val NETCONF_RPC_REPLY_QNAME = new QName(NETCONF_QNAME,"rpc-reply"); - public static val NETCONF_OK_QNAME = new QName(NETCONF_QNAME,"ok"); - public static val NETCONF_DATA_QNAME = new QName(NETCONF_QNAME,"data"); + public static val NETCONF_MONITORING_URI = "urn:ietf:params:xml:ns:yang:ietf-netconf-monitoring" + public static val NETCONF_NOTIFICATION_URI = URI.create("urn:ietf:params:xml:ns:netconf:notification:1.0") - static List> RUNNING = Collections.>singletonList(new SimpleNodeTOImpl(NETCONF_RUNNING_QNAME,null,null)); - public static val CONFIG_SOURCE_RUNNING = new CompositeNodeTOImpl(NETCONF_SOURCE_QNAME,null,RUNNING); - - static val messageId = new AtomicInteger(0); - + public static val NETCONF_QNAME = QName.create(NETCONF_URI, null, "netconf"); + public static val NETCONF_RPC_QNAME = QName.create(NETCONF_QNAME, "rpc"); + public static val NETCONF_GET_QNAME = QName.create(NETCONF_QNAME, "get"); + public static val NETCONF_FILTER_QNAME = QName.create(NETCONF_QNAME, "filter"); + public static val NETCONF_TYPE_QNAME = QName.create(NETCONF_QNAME, "type"); + public static val NETCONF_GET_CONFIG_QNAME = QName.create(NETCONF_QNAME, "get-config"); + public static val NETCONF_SOURCE_QNAME = QName.create(NETCONF_QNAME, "source"); + public static val NETCONF_RUNNING_QNAME = QName.create(NETCONF_QNAME, "running"); + public static val NETCONF_RPC_REPLY_QNAME = QName.create(NETCONF_QNAME, "rpc-reply"); + public static val NETCONF_OK_QNAME = QName.create(NETCONF_QNAME, "ok"); + public static val NETCONF_DATA_QNAME = QName.create(NETCONF_QNAME, "data"); + public static val NETCONF_CREATE_SUBSCRIPTION_QNAME = QName.create(NETCONF_NOTIFICATION_URI,null,"create-subscription"); + public static val NETCONF_CANCEL_SUBSCRIPTION_QNAME = QName.create(NETCONF_NOTIFICATION_URI,null,"cancel-subscription"); + public static val IETF_NETCONF_MONITORING_MODULE = QName.create(NETCONF_MONITORING_URI, "2010-10-04","ietf-netconf-monitoring"); + static List> RUNNING = Collections.>singletonList( + new SimpleNodeTOImpl(NETCONF_RUNNING_QNAME, null, null)); + public static val CONFIG_SOURCE_RUNNING = new CompositeNodeTOImpl(NETCONF_SOURCE_QNAME, null, RUNNING); + static val messageId = new AtomicInteger(0); static def Node toFilterStructure(InstanceIdentifier identifier) { var Node previous = null; - for (component : identifier.path.reverse) { + if(identifier.path.empty) { + return null; + } + + for (component : identifier.path.reverseView) { val Node current = component.toNode(previous); previous = current; } - return previous; + return filter("subtree",previous); } - + static def dispatch Node toNode(NodeIdentifierWithPredicates argument, Node node) { val list = new ArrayList>(); - for( arg : argument.keyValues.entrySet) { - list.add = new SimpleNodeTOImpl(arg.key,null,arg.value); + for (arg : argument.keyValues.entrySet) { + list.add = new SimpleNodeTOImpl(arg.key, null, arg.value); } - return new CompositeNodeTOImpl(argument.nodeType,null,list) + return new CompositeNodeTOImpl(argument.nodeType, null, list) } - + static def dispatch Node toNode(PathArgument argument, Node node) { - if(node != null) { - return new CompositeNodeTOImpl(argument.nodeType,null,Collections.singletonList(node)); + if (node != null) { + return new CompositeNodeTOImpl(argument.nodeType, null, Collections.singletonList(node)); } else { - return new SimpleNodeTOImpl(argument.nodeType,null,null); + return new SimpleNodeTOImpl(argument.nodeType, null, null); } } @@ -73,40 +85,62 @@ class NetconfMapping { } static def NetconfMessage toRpcMessage(QName rpc, CompositeNode node) { - val rpcPayload = wrap(NETCONF_RPC_QNAME,node); + val rpcPayload = wrap(NETCONF_RPC_QNAME, flattenInput(node)); val w3cPayload = NodeUtils.buildShadowDomTree(rpcPayload); - w3cPayload.documentElement.setAttribute("message-id","m-"+ messageId.andIncrement); + w3cPayload.documentElement.setAttribute("message-id", "m-" + messageId.andIncrement); return new NetconfMessage(w3cPayload); } + + def static flattenInput(CompositeNode node) { + val inputQName = QName.create(node.nodeType,"input"); + val input = node.getFirstCompositeByName(inputQName); + if(input == null) return node; + if(input instanceof CompositeNode) { + + val nodes = ImmutableList.builder() // + .addAll(input.children) // + .addAll(node.children.filter[nodeType != inputQName]) // + .build() + return ImmutableCompositeNode.create(node.nodeType,nodes); + } + + } static def RpcResult toRpcResult(NetconfMessage message) { val rawRpc = message.document.toCompositeNode() as CompositeNode; + //rawRpc. - - return Rpcs.getRpcResult(true,rawRpc,Collections.emptySet()); + return Rpcs.getRpcResult(true, rawRpc, Collections.emptySet()); } - - - static def wrap(QName name,Node node) { - if(node != null) { - return new CompositeNodeTOImpl(name,null,Collections.singletonList(node)); - } - else { - return new CompositeNodeTOImpl(name,null,Collections.emptyList()); + + static def wrap(QName name, Node node) { + if (node != null) { + return new CompositeNodeTOImpl(name, null, Collections.singletonList(node)); + } else { + return new CompositeNodeTOImpl(name, null, Collections.emptyList()); } } - - static def wrap(QName name,Node additional,Node node) { - if(node != null) { - return new CompositeNodeTOImpl(name,null,ImmutableList.of(additional,node)); + + static def wrap(QName name, Node additional, Node node) { + if (node != null) { + return new CompositeNodeTOImpl(name, null, ImmutableList.of(additional, node)); + } else { + return new CompositeNodeTOImpl(name, null, ImmutableList.of(additional)); } - else { - return new CompositeNodeTOImpl(name,null,ImmutableList.of(additional)); + } + + static def filter(String type, Node node) { + val it = ImmutableCompositeNode.builder(); // + setQName(NETCONF_FILTER_QNAME); + setAttribute(NETCONF_TYPE_QNAME,type); + if (node != null) { + return add(node).toInstance(); + } else { + return toInstance(); } } - - + public static def Node toCompositeNode(Document document) { - return XmlDocumentUtils.toCompositeNode(document) as Node + return XmlDocumentUtils.toNode(document) as Node } } diff --git a/opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/XmlDocumentUtils.java b/opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/XmlDocumentUtils.java index 3f6b4e1f4c..e151fca009 100644 --- a/opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/XmlDocumentUtils.java +++ b/opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/XmlDocumentUtils.java @@ -13,10 +13,12 @@ import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.NodeList; +import com.google.common.base.Strings; + public class XmlDocumentUtils { - public static CompositeNode toCompositeNode(Document doc) { - return (CompositeNode) toCompositeNode(doc.getDocumentElement()); + public static Node toNode(Document doc) { + return toCompositeNode(doc.getDocumentElement()); } private static Node toCompositeNode(Element element) { @@ -29,7 +31,7 @@ public class XmlDocumentUtils { List> values = new ArrayList<>(); NodeList nodes = element.getChildNodes(); - boolean isSimpleObject = false; + boolean isSimpleObject = true; String value = null; for (int i = 0; i < nodes.getLength(); i++) { org.w3c.dom.Node child = nodes.item(i); @@ -37,11 +39,10 @@ public class XmlDocumentUtils { isSimpleObject = false; values.add(toCompositeNode((Element) child)); } - if (!isSimpleObject && child instanceof org.w3c.dom.Text) { + if (isSimpleObject && child instanceof org.w3c.dom.Text) { value = element.getTextContent(); - if (value.matches(".*\\w.*")) { + if (!Strings.isNullOrEmpty(value)) { isSimpleObject = true; - break; } } } diff --git a/opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/YangModelInputStreamAdapter.java b/opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/YangModelInputStreamAdapter.java new file mode 100644 index 0000000000..0c0070ce9c --- /dev/null +++ b/opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/YangModelInputStreamAdapter.java @@ -0,0 +1,88 @@ +package org.opendaylight.controller.sal.connect.netconf; + +import java.io.IOException; +import java.io.InputStream; +import java.io.StringBufferInputStream; +import java.io.StringReader; + +import org.opendaylight.yangtools.concepts.Delegator; +import org.opendaylight.yangtools.yang.common.QName; + +/** + * + * + */ +public class YangModelInputStreamAdapter extends InputStream implements Delegator { + + final String source; + final QName moduleIdentifier; + final InputStream delegate; + + + + private YangModelInputStreamAdapter(String source, QName moduleIdentifier, InputStream delegate) { + super(); + this.source = source; + this.moduleIdentifier = moduleIdentifier; + this.delegate = delegate; + } + + public int read() throws IOException { + return delegate.read(); + } + + public int hashCode() { + return delegate.hashCode(); + } + + public int read(byte[] b) throws IOException { + return delegate.read(b); + } + + public boolean equals(Object obj) { + return delegate.equals(obj); + } + + public int read(byte[] b, int off, int len) throws IOException { + return delegate.read(b, off, len); + } + + public long skip(long n) throws IOException { + return delegate.skip(n); + } + + public int available() throws IOException { + return delegate.available(); + } + + public void close() throws IOException { + delegate.close(); + } + + public void mark(int readlimit) { + delegate.mark(readlimit); + } + + public void reset() throws IOException { + delegate.reset(); + } + + public boolean markSupported() { + return delegate.markSupported(); + } + + @Override + public InputStream getDelegate() { + return delegate; + } + + @Override + public String toString() { + return "YangModelInputStreamAdapter [moduleIdentifier=" + moduleIdentifier + ", delegate=" + delegate + "]"; + } + + public static YangModelInputStreamAdapter create(QName name, String module) { + InputStream stringInput = new StringBufferInputStream(module); + return new YangModelInputStreamAdapter(null, name, stringInput ); + } +} 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 index 9238514110..2fae7ee021 100644 --- 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 @@ -81,6 +81,14 @@ module odl-sal-netconf-connector-cfg { } } } + + container event-executor { + uses config:service-ref { + refine type { + config:required-identity netty:netty-event-executor; + } + } + } } } } \ No newline at end of file diff --git a/opendaylight/md-sal/sal-remoterpc-connector/implementation/pom.xml b/opendaylight/md-sal/sal-remoterpc-connector/implementation/pom.xml index c973498e85..6c72a610a7 100644 --- a/opendaylight/md-sal/sal-remoterpc-connector/implementation/pom.xml +++ b/opendaylight/md-sal/sal-remoterpc-connector/implementation/pom.xml @@ -14,7 +14,7 @@ 0.3.1 - 1.9.8 + 2.3.0 1.0.1 @@ -84,16 +84,25 @@ org.slf4j slf4j-api + - org.codehaus.jackson - jackson-core-asl + com.fasterxml.jackson.core + jackson-annotations ${jackson.version} + - org.codehaus.jackson - jackson-mapper-asl + com.fasterxml.jackson.core + jackson-core ${jackson.version} + + + com.fasterxml.jackson.core + jackson-databind + ${jackson.version} + + stax stax-api diff --git a/opendaylight/md-sal/sal-remoterpc-connector/implementation/src/main/java/org/opendaylight/controller/sal/connector/remoterpc/dto/RouteIdentifierImpl.java b/opendaylight/md-sal/sal-remoterpc-connector/implementation/src/main/java/org/opendaylight/controller/sal/connector/remoterpc/dto/RouteIdentifierImpl.java index 6c5e5fbf11..06107a8773 100644 --- a/opendaylight/md-sal/sal-remoterpc-connector/implementation/src/main/java/org/opendaylight/controller/sal/connector/remoterpc/dto/RouteIdentifierImpl.java +++ b/opendaylight/md-sal/sal-remoterpc-connector/implementation/src/main/java/org/opendaylight/controller/sal/connector/remoterpc/dto/RouteIdentifierImpl.java @@ -7,15 +7,15 @@ */ package org.opendaylight.controller.sal.connector.remoterpc.dto; -import org.codehaus.jackson.JsonNode; -import org.codehaus.jackson.map.ObjectMapper; +import java.io.Serializable; +import java.net.URI; + +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; import org.opendaylight.controller.sal.connector.api.RpcRouter; import org.opendaylight.yangtools.yang.common.QName; import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier; -import java.io.Serializable; -import java.net.URI; - public class RouteIdentifierImpl implements RpcRouter.RouteIdentifier,Serializable { transient ObjectMapper mapper = new ObjectMapper(); diff --git a/opendaylight/md-sal/sal-remoterpc-connector/implementation/src/test/java/org/opendaylight/controller/sal/connector/remoterpc/RouteIdentifierImplTest.java b/opendaylight/md-sal/sal-remoterpc-connector/implementation/src/test/java/org/opendaylight/controller/sal/connector/remoterpc/RouteIdentifierImplTest.java index 550d9ef125..f6b9004eae 100644 --- a/opendaylight/md-sal/sal-remoterpc-connector/implementation/src/test/java/org/opendaylight/controller/sal/connector/remoterpc/RouteIdentifierImplTest.java +++ b/opendaylight/md-sal/sal-remoterpc-connector/implementation/src/test/java/org/opendaylight/controller/sal/connector/remoterpc/RouteIdentifierImplTest.java @@ -1,6 +1,8 @@ package org.opendaylight.controller.sal.connector.remoterpc; -import org.codehaus.jackson.JsonParseException; +import java.net.URI; + +import com.fasterxml.jackson.core.JsonParseException; import org.junit.Assert; import org.junit.Test; import org.opendaylight.controller.sal.connector.remoterpc.dto.RouteIdentifierImpl; @@ -8,8 +10,6 @@ import org.opendaylight.yangtools.yang.common.QName; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import java.net.URI; - public class RouteIdentifierImplTest { Logger _logger = LoggerFactory.getLogger(RouteIdentifierImplTest.class); diff --git a/opendaylight/md-sal/sal-remoterpc-connector/integrationtest/test-it/pom.xml b/opendaylight/md-sal/sal-remoterpc-connector/integrationtest/test-it/pom.xml index 4305a283e2..8ee61c3a3f 100644 --- a/opendaylight/md-sal/sal-remoterpc-connector/integrationtest/test-it/pom.xml +++ b/opendaylight/md-sal/sal-remoterpc-connector/integrationtest/test-it/pom.xml @@ -14,6 +14,7 @@ + 2.3.0 3.0.0 1.5.0 0.2.3-SNAPSHOT @@ -389,20 +390,29 @@ - org.codehaus.jackson - jackson-mapper-asl - 1.9.2 + com.fasterxml.jackson.core + jackson-databind + ${jackson.version} + + + com.fasterxml.jackson.core + jackson-annotations + ${jackson.version} + + - org.codehaus.jackson - jackson-core-asl - 1.9.2 + com.fasterxml.jackson.core + jackson-core + ${jackson.version} + org.zeromq jeromq 0.3.1 + org.opendaylight.yangtools.thirdparty xtend-lib-osgi diff --git a/opendaylight/md-sal/sal-remoterpc-connector/integrationtest/test-it/src/test/java/org/opendaylight/controller/sample/zeromq/test/it/RouterTest.java b/opendaylight/md-sal/sal-remoterpc-connector/integrationtest/test-it/src/test/java/org/opendaylight/controller/sample/zeromq/test/it/RouterTest.java index 62c094d7a6..dd910ea34b 100644 --- a/opendaylight/md-sal/sal-remoterpc-connector/integrationtest/test-it/src/test/java/org/opendaylight/controller/sample/zeromq/test/it/RouterTest.java +++ b/opendaylight/md-sal/sal-remoterpc-connector/integrationtest/test-it/src/test/java/org/opendaylight/controller/sample/zeromq/test/it/RouterTest.java @@ -416,8 +416,9 @@ public class RouterTest { mavenBundle(YANG + ".thirdparty", "antlr4-runtime-osgi-nohead").versionAsInProject(), // mavenBundle("com.google.guava", "guava").versionAsInProject(), // mavenBundle("org.zeromq", "jeromq").versionAsInProject(), - mavenBundle("org.codehaus.jackson", "jackson-mapper-asl").versionAsInProject(), - mavenBundle("org.codehaus.jackson", "jackson-core-asl").versionAsInProject(), + mavenBundle("com.fasterxml.jackson.core", "jackson-annotations").versionAsInProject(), + mavenBundle("com.fasterxml.jackson.core", "jackson-core").versionAsInProject(), + mavenBundle("com.fasterxml.jackson.core", "jackson-databind").versionAsInProject(), //routingtable dependencies systemPackages("sun.reflect", "sun.reflect.misc", "sun.misc"), // List framework bundles 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 fb7872f8bc..8b1bdef8ba 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 @@ -43,7 +43,7 @@ class JsonMapper { private final Set foundLeafLists = new HashSet<>(); private final Set foundLists = new HashSet<>(); - private final Logger logger = LoggerFactory.getLogger(JsonMapper.class); + private final Logger logger = LoggerFactory.getLogger(JsonMapper.class); public void write(JsonWriter writer, CompositeNode data, DataNodeContainer schema) throws IOException { Preconditions.checkNotNull(writer); @@ -184,16 +184,23 @@ class JsonMapper { TypeDefinition baseType = RestUtil.resolveBaseTypeFrom(type); + if (node.getValue() == null && !(baseType instanceof EmptyTypeDefinition)) { + logger.debug("While generationg JSON output null value was found for type " + + baseType.getClass().getSimpleName() + "."); + } + // TODO check InstanceIdentifierTypeDefinition if (baseType instanceof IdentityrefTypeDefinition) { if (node.getValue() instanceof QName) { IdentityValuesDTO valueDTO = (IdentityValuesDTO) RestCodec.from(baseType).serialize(node.getValue()); IdentityValue valueFromDTO = valueDTO.getValuesWithNamespaces().get(0); - String moduleName = ControllerContext.getInstance().findModuleByNamespace(URI.create(valueFromDTO.getNamespace())); + String moduleName = ControllerContext.getInstance().findModuleByNamespace( + URI.create(valueFromDTO.getNamespace())); writer.value(moduleName + ":" + valueFromDTO.getValue()); } else { logger.debug("Value of " + baseType.getQName().getNamespace() + ":" - + baseType.getQName().getLocalName() + " is not instance of " + QName.class + " but is " + node.getValue().getClass()); + + baseType.getQName().getLocalName() + " is not instance of " + QName.class + " but is " + + node.getValue().getClass()); writer.value(String.valueOf(node.getValue())); } } else if (baseType instanceof DecimalTypeDefinition || baseType instanceof IntegerTypeDefinition diff --git a/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/rest/impl/RestconfProvider.java b/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/rest/impl/RestconfProvider.java index 242f18d240..1bceee88cb 100644 --- a/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/rest/impl/RestconfProvider.java +++ b/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/rest/impl/RestconfProvider.java @@ -9,6 +9,7 @@ import org.opendaylight.controller.sal.core.api.Provider; import org.opendaylight.controller.sal.core.api.data.DataBrokerService; import org.opendaylight.controller.sal.core.api.model.SchemaService; import org.opendaylight.controller.sal.core.api.model.SchemaServiceListener; +import org.opendaylight.controller.sal.core.api.mount.MountService; import org.opendaylight.controller.sal.restconf.impl.BrokerFacade; import org.opendaylight.controller.sal.restconf.impl.ControllerContext; import org.opendaylight.yangtools.concepts.ListenerRegistration; @@ -37,6 +38,7 @@ public class RestconfProvider implements BundleActivator, Provider, ServiceTrack SchemaService schemaService = session.getService(SchemaService.class); listenerRegistration = schemaService.registerSchemaServiceListener(ControllerContext.getInstance()); ControllerContext.getInstance().setSchemas(schemaService.getGlobalContext()); + ControllerContext.getInstance().setMountService(session.getService(MountService.class)); } @Override diff --git a/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/rest/impl/XmlMapper.java b/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/rest/impl/XmlMapper.java index a3d658e7bf..0dd4668a74 100644 --- a/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/rest/impl/XmlMapper.java +++ b/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/rest/impl/XmlMapper.java @@ -1,142 +1,60 @@ package org.opendaylight.controller.sal.rest.impl; -import java.util.Set; - import javax.activation.UnsupportedDataTypeException; -import javax.xml.parsers.DocumentBuilder; -import javax.xml.parsers.DocumentBuilderFactory; -import javax.xml.parsers.ParserConfigurationException; -import org.opendaylight.controller.sal.restconf.impl.IdentityValuesDTO; -import org.opendaylight.controller.sal.restconf.impl.IdentityValuesDTO.IdentityValue; -import org.opendaylight.controller.sal.restconf.impl.RestCodec; -import org.opendaylight.yangtools.yang.common.QName; 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.yangtools.yang.model.api.ChoiceCaseNode; -import org.opendaylight.yangtools.yang.model.api.ChoiceNode; -import org.opendaylight.yangtools.yang.model.api.ContainerSchemaNode; +import org.opendaylight.yangtools.yang.data.api.codec.LeafrefCodec; +import org.opendaylight.yangtools.yang.data.impl.codec.TypeDefinitionAwareCodec; +import org.opendaylight.yangtools.yang.data.impl.codec.xml.XmlCodecProvider; +import org.opendaylight.yangtools.yang.data.impl.codec.xml.XmlDocumentUtils; import org.opendaylight.yangtools.yang.model.api.DataNodeContainer; -import org.opendaylight.yangtools.yang.model.api.DataSchemaNode; -import org.opendaylight.yangtools.yang.model.api.LeafListSchemaNode; -import org.opendaylight.yangtools.yang.model.api.LeafSchemaNode; -import org.opendaylight.yangtools.yang.model.api.ListSchemaNode; import org.opendaylight.yangtools.yang.model.api.TypeDefinition; -import org.opendaylight.yangtools.yang.model.api.YangNode; -import org.opendaylight.yangtools.yang.model.api.type.IdentityrefTypeDefinition; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; +import org.opendaylight.yangtools.yang.model.api.type.LeafrefTypeDefinition; +import org.opendaylight.yangtools.yang.model.util.Leafref; import org.w3c.dom.Document; -import org.w3c.dom.Element; -import com.google.common.base.Preconditions; +import com.google.common.base.Optional; public class XmlMapper { - - private final Logger logger = LoggerFactory.getLogger(XmlMapper.class); + private static final LeafrefCodecImpl LEAFREF_DEFAULT_CODEC = new LeafrefCodecImpl( + Optional. absent()); - public Document write(CompositeNode data, DataNodeContainer schema) throws UnsupportedDataTypeException { - Preconditions.checkNotNull(data); - Preconditions.checkNotNull(schema); + private static class LeafrefCodecImpl extends TypeDefinitionAwareCodec implements + LeafrefCodec { - DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); - Document doc = null; - try { - DocumentBuilder bob = dbf.newDocumentBuilder(); - doc = bob.newDocument(); - } catch (ParserConfigurationException e) { - return null; + protected LeafrefCodecImpl(Optional typeDef) { + super(typeDef, Object.class); } - if (schema instanceof ContainerSchemaNode || schema instanceof ListSchemaNode) { - doc.appendChild(translateToXmlAndReturnRootElement(doc, data, schema)); - return doc; - } else { - throw new UnsupportedDataTypeException( - "Schema can be ContainerSchemaNode or ListSchemaNode. Other types are not supported yet."); + @Override + public String serialize(Object data) { + return String.valueOf(data); } - } - private Element translateToXmlAndReturnRootElement(Document doc, Node data, YangNode schema) - throws UnsupportedDataTypeException { - QName dataType = data.getNodeType(); - Element itemEl = doc.createElementNS(dataType.getNamespace().toString(), dataType.getLocalName()); - if (data instanceof SimpleNode) { - if (schema instanceof LeafListSchemaNode) { - writeValueOfNodeByType(itemEl, (SimpleNode) data, ((LeafListSchemaNode) schema).getType(), (DataSchemaNode) schema); - } else if (schema instanceof LeafSchemaNode) { - writeValueOfNodeByType(itemEl, (SimpleNode) data, ((LeafSchemaNode) schema).getType(), (DataSchemaNode) schema); - } else { - Object value = data.getValue(); - if (value != null) { - itemEl.setTextContent(String.valueOf(value)); - } - } - } else { // CompositeNode - for (Node child : ((CompositeNode) data).getChildren()) { - DataSchemaNode childSchema = null; - if(schema != null){ - childSchema = findFirstSchemaForNode(child, ((DataNodeContainer) schema).getChildNodes()); - if (logger.isDebugEnabled()) { - if (childSchema == null) { - logger.debug("Probably the data node \"" + ((child == null) ? "" : child.getNodeType().getLocalName()) - + "\" is not conform to schema"); - } - } - } - itemEl.appendChild(translateToXmlAndReturnRootElement(doc, child, childSchema)); - } + @Override + public Object deserialize(String data) { + return data; } - return itemEl; } - private void writeValueOfNodeByType(Element element, SimpleNode node, TypeDefinition type, DataSchemaNode schema) { - - TypeDefinition baseType = RestUtil.resolveBaseTypeFrom(type); + private static class XmlCodecProviderImpl implements XmlCodecProvider { + @Override + public TypeDefinitionAwareCodec> codecFor(TypeDefinition baseType) { + TypeDefinitionAwareCodec> codec = TypeDefinitionAwareCodec + .from(baseType); - if (baseType instanceof IdentityrefTypeDefinition) { - if (node.getValue() instanceof QName) { - IdentityValuesDTO valueDTO = (IdentityValuesDTO) RestCodec.from(type).serialize(node.getValue()); - IdentityValue value = valueDTO.getValuesWithNamespaces().get(0); - String prefix = "x"; - if (value.getPrefix() != null && !value.getPrefix().isEmpty()) { - prefix = value.getPrefix(); + if (codec == null) { + if (baseType instanceof Leafref) { + return LEAFREF_DEFAULT_CODEC; } - element.setAttribute("xmlns:" + prefix, value.getNamespace()); - element.setTextContent(prefix + ":" + value.getValue()); - } else { - logger.debug("Value of " + baseType.getQName().getNamespace() + ":" - + baseType.getQName().getLocalName() + " is not instance of " + QName.class + " but is " + node.getValue().getClass()); - element.setTextContent(String.valueOf(node.getValue())); - } - } else { - if (node.getValue() != null) { - String value = String.valueOf(RestCodec.from(baseType).serialize(node.getValue())); - if (value.equals("null")) { - value = String.valueOf(node.getValue()); - } - element.setTextContent(value); } + return codec; } } - private DataSchemaNode findFirstSchemaForNode(Node node, Set dataSchemaNode) { - if (dataSchemaNode != null && node != null) { - for (DataSchemaNode dsn : dataSchemaNode) { - if (node.getNodeType().getLocalName().equals(dsn.getQName().getLocalName())) { - return dsn; - } else if (dsn instanceof ChoiceNode) { - for (ChoiceCaseNode choiceCase : ((ChoiceNode) dsn).getCases()) { - DataSchemaNode foundDsn = findFirstSchemaForNode(node, choiceCase.getChildNodes()); - if (foundDsn != null) { - return foundDsn; - } - } - } - } - } - return null; - } + private static final XmlCodecProvider XML_CODEC_PROVIDER_IMPL = new XmlCodecProviderImpl(); + public Document write(CompositeNode data, DataNodeContainer schema) throws UnsupportedDataTypeException { + return XmlDocumentUtils.toDocument(data, schema, XML_CODEC_PROVIDER_IMPL); + } } 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 eec2d452a1..1a60e14589 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 @@ -34,13 +34,19 @@ import org.opendaylight.yangtools.yang.model.api.type.IdentityrefTypeDefinition import org.slf4j.LoggerFactory import static com.google.common.base.Preconditions.* +import org.opendaylight.controller.sal.core.api.mount.MountService +import org.opendaylight.yangtools.yang.model.api.LeafListSchemaNode class ControllerContext implements SchemaServiceListener { val static LOG = LoggerFactory.getLogger(ControllerContext) val static ControllerContext INSTANCE = new ControllerContext val static NULL_VALUE = "null" - var SchemaContext schemas; + @Property + var SchemaContext globalSchema; + + @Property + var MountService mountService; private val BiMap uriToModuleName = HashBiMap.create(); private val Map moduleNameToUri = uriToModuleName.inverse(); @@ -57,7 +63,7 @@ class ControllerContext implements SchemaServiceListener { } private def void checkPreconditions() { - if (schemas === null) { + if (globalSchema === null) { throw new ResponseException(Response.Status.SERVICE_UNAVAILABLE, RestconfProvider::NOT_INITALIZED_MSG) } } @@ -75,29 +81,24 @@ class ControllerContext implements SchemaServiceListener { if (pathArgs.head.empty) { pathArgs.remove(0) } - val schemaNode = ret.collectPathArguments(pathArgs, restconfInstance.findModule); + val schemaNode = ret.collectPathArguments(pathArgs, globalSchema.findModule(pathArgs.head)); if (schemaNode === null) { return null } return new InstanceIdWithSchemaNode(ret.toInstance, schemaNode) } - private def findModule(String restconfInstance) { - checkPreconditions - checkNotNull(restconfInstance); - val pathArgs = restconfInstance.split("/"); - if (pathArgs.empty) { - return null; - } - val modulWithFirstYangStatement = pathArgs.filter[s|s.contains(":")].head - val startModule = modulWithFirstYangStatement.toModuleName(); - return getLatestModule(startModule) + private static def findModule(SchemaContext context,String argument) { + //checkPreconditions + checkNotNull(argument); + val startModule = argument.toModuleName(); + return context.getLatestModule(startModule) } - def getLatestModule(String moduleName) { - checkPreconditions + static def getLatestModule(SchemaContext schema,String moduleName) { + checkArgument(schema != null); checkArgument(moduleName !== null && !moduleName.empty) - val modules = schemas.modules.filter[m|m.name == moduleName] + val modules = schema.modules.filter[m|m.name == moduleName] var latestModule = modules.head for (module : modules) { if (module.revision.after(latestModule.revision)) { @@ -112,7 +113,7 @@ class ControllerContext implements SchemaServiceListener { val elements = path.path; val ret = new StringBuilder(); val startQName = elements.get(0).nodeType; - val initialModule = schemas.findModuleByNamespaceAndRevision(startQName.namespace, startQName.revision) + val initialModule = globalSchema.findModuleByNamespaceAndRevision(startQName.namespace, startQName.revision) var node = initialModule as DataSchemaNode; for (element : elements) { node = node.childByQName(element.nodeType); @@ -139,7 +140,7 @@ class ControllerContext implements SchemaServiceListener { checkPreconditions var module = uriToModuleName.get(namespace) if (module === null) { - val moduleSchemas = schemas.findModuleByNamespace(namespace); + val moduleSchemas = globalSchema.findModuleByNamespace(namespace); if(moduleSchemas === null) return null var latestModule = moduleSchemas.head for (m : moduleSchemas) { @@ -157,7 +158,7 @@ class ControllerContext implements SchemaServiceListener { def findNamespaceByModule(String module) { var namespace = moduleNameToUri.get(module) if (namespace === null) { - val moduleSchemas = schemas.modules.filter[it|it.name.equals(module)] + val moduleSchemas = globalSchema.modules.filter[it|it.name.equals(module)] var latestModule = moduleSchemas.head for (m : moduleSchemas) { if (m.revision.after(latestModule.revision)) { @@ -175,7 +176,7 @@ class ControllerContext implements SchemaServiceListener { checkPreconditions var module = uriToModuleName.get(qname.namespace) if (module === null) { - val moduleSchema = schemas.findModuleByNamespaceAndRevision(qname.namespace, qname.revision); + val moduleSchema = globalSchema.findModuleByNamespaceAndRevision(qname.namespace, qname.revision); if(moduleSchema === null) throw new IllegalArgumentException() uriToModuleName.put(qname.namespace, moduleSchema.name) module = moduleSchema.name; @@ -244,25 +245,22 @@ class ControllerContext implements SchemaServiceListener { } val nodeRef = strings.head; - val nodeName = nodeRef.toNodeName(); - val targetNode = parentNode.getDataChildByName(nodeName); - if (targetNode === null) { - val children = parentNode.childNodes - for (child : children) { - if (child instanceof ChoiceNode) { - val choice = child as ChoiceNode - for (caze : choice.cases) { - val result = builder.collectPathArguments(strings, caze as DataNodeContainer); - if (result !== null) - return result - } - } - } + val nodeName = nodeRef.toNodeName; + var targetNode = parentNode.findInstanceDataChild(nodeName); + if (targetNode instanceof ChoiceNode) { return null } - if (targetNode instanceof ChoiceNode) { + + if (targetNode === null) { + // Node is possibly in other mount point + val partialPath = builder.toInstance; + val mountPointSchema = mountService?.getMountPoint(partialPath)?.schemaContext; + if(mountPointSchema != null) { + return builder.collectPathArguments(strings, mountPointSchema.findModule(strings.head)); + } return null } + // Number of consumed elements var consumed = 1; @@ -302,6 +300,32 @@ class ControllerContext implements SchemaServiceListener { return targetNode } + + static def DataSchemaNode findInstanceDataChild(DataNodeContainer container, String name) { + // FIXME: Add namespace comparison + var potentialNode = container.getDataChildByName(name); + if(potentialNode.instantiatedDataSchema) { + return potentialNode; + } + val allCases = container.childNodes.filter(ChoiceNode).map[cases].flatten + for (caze : allCases) { + potentialNode = caze.findInstanceDataChild(name); + if(potentialNode != null) { + return potentialNode; + } + } + return null; + } + + static def boolean isInstantiatedDataSchema(DataSchemaNode node) { + switch node { + LeafSchemaNode: return true + LeafListSchemaNode: return true + ContainerSchemaNode: return true + ListSchemaNode: return true + default: return false + } + } private def void addKeyValue(HashMap map, DataSchemaNode node, String uriValue) { checkNotNull(uriValue); @@ -319,7 +343,7 @@ class ControllerContext implements SchemaServiceListener { map.put(node.QName, decoded); } - private def String toModuleName(String str) { + private static def String toModuleName(String str) { checkNotNull(str) if (str.contains(":")) { val args = str.split(":"); @@ -343,7 +367,7 @@ class ControllerContext implements SchemaServiceListener { private def QName toQName(String name) { val module = name.toModuleName; val node = name.toNodeName; - val namespace = FluentIterable.from(schemas.modules.sort[o1,o2 | o1.revision.compareTo(o2.revision)]) // + val namespace = FluentIterable.from(globalSchema.modules.sort[o1,o2 | o1.revision.compareTo(o2.revision)]) // .transform[QName.create(namespace,revision,it.name)].findFirst[module == localName] ; return QName.create(namespace,node); @@ -354,7 +378,7 @@ class ControllerContext implements SchemaServiceListener { } override onGlobalContextUpdated(SchemaContext context) { - this.schemas = context; + this.globalSchema = context; for (operation : context.operations) { val qname = operation.QName; qnameToRpc.put(qname, operation); diff --git a/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/restconf/impl/RestCodec.java b/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/restconf/impl/RestCodec.java index 450ba02b56..40fba88356 100644 --- a/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/restconf/impl/RestCodec.java +++ b/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/restconf/impl/RestCodec.java @@ -19,16 +19,16 @@ public class RestCodec { private RestCodec() { } - + public static final Codec from(TypeDefinition typeDefinition) { return new ObjectCodec(typeDefinition); } - + @SuppressWarnings("rawtypes") public static final class ObjectCodec implements Codec { private final Logger logger = LoggerFactory.getLogger(RestCodec.class); - + public static final Codec IDENTITYREF_DEFAULT_CODEC = new IdentityrefCodecImpl(); public static final Codec LEAFREF_DEFAULT_CODEC = new LeafrefCodecImpl(); @@ -37,7 +37,7 @@ public class RestCodec { private ObjectCodec(TypeDefinition typeDefinition) { type = RestUtil.resolveBaseTypeFrom(typeDefinition); } - + @SuppressWarnings("unchecked") @Override public Object deserialize(Object input) { @@ -47,16 +47,21 @@ public class RestCodec { } else if (type instanceof LeafrefTypeDefinition) { return LEAFREF_DEFAULT_CODEC.deserialize(input); } else { - TypeDefinitionAwareCodec> typeAwarecodec = TypeDefinitionAwareCodec.from(type); + TypeDefinitionAwareCodec> typeAwarecodec = TypeDefinitionAwareCodec + .from(type); if (typeAwarecodec != null) { return typeAwarecodec.deserialize(String.valueOf(input)); } else { - logger.debug("Codec for type \"" + type.getQName().getLocalName() + "\" is not implemented yet."); + logger.debug("Codec for type \"" + type.getQName().getLocalName() + + "\" is not implemented yet."); return null; } } - } catch (ClassCastException e) { // TODO remove this catch when everyone use codecs - logger.error("ClassCastException was thrown when codec is invoked with parameter " + String.valueOf(input), e); + } catch (ClassCastException e) { // TODO remove this catch when + // everyone use codecs + logger.error( + "ClassCastException was thrown when codec is invoked with parameter " + String.valueOf(input), + e); return input; } } @@ -70,22 +75,27 @@ public class RestCodec { } else if (type instanceof LeafrefTypeDefinition) { return LEAFREF_DEFAULT_CODEC.serialize(input); } else { - TypeDefinitionAwareCodec> typeAwarecodec = TypeDefinitionAwareCodec.from(type); + TypeDefinitionAwareCodec> typeAwarecodec = TypeDefinitionAwareCodec + .from(type); if (typeAwarecodec != null) { return typeAwarecodec.serialize(input); } else { - logger.debug("Codec for type \"" + type.getQName().getLocalName() + "\" is not implemented yet."); + logger.debug("Codec for type \"" + type.getQName().getLocalName() + + "\" is not implemented yet."); return null; } } - } catch (ClassCastException e) { // TODO remove this catch when everyone use codecs - logger.error("ClassCastException was thrown when codec is invoked with parameter " + String.valueOf(input), e); + } catch (ClassCastException e) { // TODO remove this catch when + // everyone use codecs + logger.error( + "ClassCastException was thrown when codec is invoked with parameter " + String.valueOf(input), + e); return input; } } - + } - + public static class IdentityrefCodecImpl implements IdentityrefCodec { @Override @@ -105,7 +115,7 @@ public class RestCodec { } } - + public static class LeafrefCodecImpl implements LeafrefCodec { @Override @@ -117,7 +127,7 @@ public class RestCodec { public Object deserialize(String data) { return data; } - + } - + } diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/json/test/ToJsonBasicYangTypesTest.java b/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/json/test/CnSnJsonBasicYangTypesTest.java similarity index 90% rename from opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/json/test/ToJsonBasicYangTypesTest.java rename to opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/json/test/CnSnJsonBasicYangTypesTest.java index b01d4104b2..e754fdec5f 100644 --- a/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/json/test/ToJsonBasicYangTypesTest.java +++ b/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/json/test/CnSnJsonBasicYangTypesTest.java @@ -1,22 +1,44 @@ package org.opendaylight.controller.sal.restconf.impl.cnsn.to.json.test; -import static org.junit.Assert.*; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; import java.io.IOException; import java.io.StringReader; import java.util.Map; import java.util.Set; +import javax.ws.rs.WebApplicationException; + +import org.junit.BeforeClass; import org.junit.Test; +import org.opendaylight.controller.sal.rest.impl.StructuredDataToJsonProvider; +import org.opendaylight.controller.sal.rest.impl.XmlToCompositeNodeProvider; import org.opendaylight.controller.sal.restconf.impl.test.TestUtils; -import org.opendaylight.controller.sal.restconf.impl.test.structures.*; -import org.opendaylight.yangtools.yang.data.api.*; +import org.opendaylight.controller.sal.restconf.impl.test.YangAndXmlAndDataSchemaLoader; +import org.opendaylight.controller.sal.restconf.impl.test.structures.Cont; +import org.opendaylight.controller.sal.restconf.impl.test.structures.Lf; +import org.opendaylight.controller.sal.restconf.impl.test.structures.LfLst; +import org.opendaylight.controller.sal.restconf.impl.test.structures.Lst; +import org.opendaylight.controller.sal.restconf.impl.test.structures.LstItem; +import org.opendaylight.yangtools.yang.data.api.CompositeNode; +import org.opendaylight.yangtools.yang.data.api.ModifyAction; +import org.opendaylight.yangtools.yang.data.api.MutableCompositeNode; +import org.opendaylight.yangtools.yang.data.api.MutableSimpleNode; import org.opendaylight.yangtools.yang.data.impl.NodeFactory; import com.google.gson.stream.JsonReader; import com.google.gson.stream.JsonToken; -public class ToJsonBasicYangTypesTest { +public class CnSnJsonBasicYangTypesTest extends YangAndXmlAndDataSchemaLoader { + + @BeforeClass + public static void initialize() { + dataLoad("/cnsn-to-json/simple-yang-types", 1, "simple-yang-types", "cont1"); + } /** * Test of json output when as input are specified composite node with empty @@ -24,9 +46,16 @@ public class ToJsonBasicYangTypesTest { */ @Test public void compositeNodeAndYangWithJsonReaderEmptyDataTest() { - String jsonOutput = TestUtils.convertCompositeNodeDataAndYangToJson(prepareCompositeNodeWithEmpties(), - "/cnsn-to-json/simple-yang-types", "/cnsn-to-json/simple-yang-types/xml", "simple-yang-types", "cont1"); - verifyJsonOutputForEmpty(jsonOutput); + CompositeNode compositeNode = prepareCompositeNodeWithEmpties(); + TestUtils.normalizeCompositeNode(compositeNode, modules, searchedModuleName + ":" + searchedDataSchemaName); + String jsonOutput = null; + try { + jsonOutput = TestUtils.writeCompNodeWithSchemaContextToOutput(compositeNode, modules, dataSchemaNode, + StructuredDataToJsonProvider.INSTANCE); + } catch (WebApplicationException | IOException e) { + } + + verifyJsonOutputForEmptyData(jsonOutput); } /** @@ -35,13 +64,21 @@ public class ToJsonBasicYangTypesTest { */ @Test public void xmlAndYangTypesWithJsonReaderTest() { - String jsonOutput = TestUtils.convertCompositeNodeDataAndYangToJson( - TestUtils.loadCompositeNode("/cnsn-to-json/simple-yang-types/xml/data.xml"), - "/cnsn-to-json/simple-yang-types", "/cnsn-to-json/simple-yang-types/xml", "simple-yang-types", "cont1"); + CompositeNode compositeNode = TestUtils.readInputToCnSn("/cnsn-to-json/simple-yang-types/xml/data.xml", + XmlToCompositeNodeProvider.INSTANCE); + TestUtils.normalizeCompositeNode(compositeNode, modules, searchedModuleName + ":" + searchedDataSchemaName); + String jsonOutput = null; + try { + jsonOutput = TestUtils.writeCompNodeWithSchemaContextToOutput(compositeNode, modules, dataSchemaNode, + StructuredDataToJsonProvider.INSTANCE); + } catch (WebApplicationException | IOException e) { + } + verifyJsonOutput(jsonOutput); } - private void verifyJsonOutputForEmpty(String jsonOutput) { + private void verifyJsonOutputForEmptyData(String jsonOutput) { + assertNotNull(jsonOutput); StringReader strReader = new StringReader(jsonOutput); JsonReader jReader = new JsonReader(strReader); @@ -60,6 +97,7 @@ public class ToJsonBasicYangTypesTest { } private void verifyJsonOutput(String jsonOutput) { + assertNotNull(jsonOutput); StringReader strReader = new StringReader(jsonOutput); JsonReader jReader = new JsonReader(strReader); diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/json/test/ToJsonChoiceCaseTest.java b/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/json/test/CnSnJsonChoiceCaseTest.java similarity index 86% rename from opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/json/test/ToJsonChoiceCaseTest.java rename to opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/json/test/CnSnJsonChoiceCaseTest.java index b745411bf4..1eb3779730 100644 --- a/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/json/test/ToJsonChoiceCaseTest.java +++ b/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/json/test/CnSnJsonChoiceCaseTest.java @@ -8,11 +8,13 @@ import javax.ws.rs.WebApplicationException; import org.junit.BeforeClass; import org.junit.Test; +import org.opendaylight.controller.sal.rest.impl.StructuredDataToJsonProvider; +import org.opendaylight.controller.sal.rest.impl.XmlToCompositeNodeProvider; import org.opendaylight.controller.sal.restconf.impl.test.TestUtils; import org.opendaylight.controller.sal.restconf.impl.test.YangAndXmlAndDataSchemaLoader; import org.opendaylight.yangtools.yang.data.api.CompositeNode; -public class ToJsonChoiceCaseTest extends YangAndXmlAndDataSchemaLoader { +public class CnSnJsonChoiceCaseTest extends YangAndXmlAndDataSchemaLoader { @BeforeClass public static void initialization() { @@ -111,10 +113,11 @@ public class ToJsonChoiceCaseTest extends YangAndXmlAndDataSchemaLoader { } private void testWrapper(String xmlPath, String pathToSchemaNode) { - CompositeNode compNode = TestUtils.loadCompositeNode(xmlPath); - TestUtils.normalizeCompositeNode(compNode, modules, dataSchemaNode, pathToSchemaNode); + CompositeNode compNode = TestUtils.readInputToCnSn(xmlPath, XmlToCompositeNodeProvider.INSTANCE); + TestUtils.normalizeCompositeNode(compNode, modules, pathToSchemaNode); try { - TestUtils.writeCompNodeWithSchemaContextToJson(compNode, modules, dataSchemaNode); + TestUtils.writeCompNodeWithSchemaContextToOutput(compNode, modules, dataSchemaNode, + StructuredDataToJsonProvider.INSTANCE); } catch (WebApplicationException | IOException e) { // shouldn't end here assertTrue(false); diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/json/test/ToJsonBasicDataTypesTest.java b/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/json/test/CnSnToJsonBasicDataTypesTest.java similarity index 56% rename from opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/json/test/ToJsonBasicDataTypesTest.java rename to opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/json/test/CnSnToJsonBasicDataTypesTest.java index 73d0c82521..c45c0b3288 100644 --- a/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/json/test/ToJsonBasicDataTypesTest.java +++ b/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/json/test/CnSnToJsonBasicDataTypesTest.java @@ -1,153 +1,57 @@ package org.opendaylight.controller.sal.restconf.impl.cnsn.to.json.test; -import static org.junit.Assert.*; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; import java.io.IOException; import java.io.StringReader; -import java.math.BigDecimal; -import java.net.URI; -import java.net.URISyntaxException; -import java.util.*; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; import javax.ws.rs.WebApplicationException; -import javax.xml.bind.DatatypeConverter; +import org.junit.BeforeClass; import org.junit.Test; +import org.opendaylight.controller.sal.rest.impl.StructuredDataToJsonProvider; +import org.opendaylight.controller.sal.rest.impl.XmlToCompositeNodeProvider; import org.opendaylight.controller.sal.restconf.impl.test.TestUtils; -import org.opendaylight.yangtools.yang.common.QName; -import org.opendaylight.yangtools.yang.data.api.*; -import org.opendaylight.yangtools.yang.data.impl.NodeFactory; -import org.opendaylight.yangtools.yang.model.api.DataSchemaNode; -import org.opendaylight.yangtools.yang.model.api.Module; +import org.opendaylight.controller.sal.restconf.impl.test.YangAndXmlAndDataSchemaLoader; +import org.opendaylight.yangtools.yang.data.api.CompositeNode; import com.google.gson.stream.JsonReader; import com.google.gson.stream.JsonToken; -public class ToJsonBasicDataTypesTest { +public class CnSnToJsonBasicDataTypesTest extends YangAndXmlAndDataSchemaLoader { + + @BeforeClass + public static void initialize() { + dataLoad("/cnsn-to-json/simple-data-types"); + } @Test public void simpleYangDataTest() { - String jsonOutput = ""; - CompositeNode compositeNode = TestUtils.loadCompositeNode("/cnsn-to-json/simple-data-types/xml/data.xml"); - Set modules = TestUtils.resolveModules("/cnsn-to-json/simple-data-types"); - assertEquals(1, modules.size()); - Module module = TestUtils.resolveModule(null, modules); - assertNotNull(module); - DataSchemaNode dataSchemaNode = TestUtils.resolveDataSchemaNode(module, null); - assertNotNull(dataSchemaNode); + CompositeNode compositeNode = TestUtils.readInputToCnSn("/cnsn-to-json/simple-data-types/xml/data.xml", + XmlToCompositeNodeProvider.INSTANCE); - TestUtils.normalizeCompositeNode(compositeNode, modules, dataSchemaNode, "simple-data-types:cont"); + String jsonOutput = null; + + TestUtils.normalizeCompositeNode(compositeNode, modules, "simple-data-types:cont"); try { - jsonOutput = TestUtils.writeCompNodeWithSchemaContextToJson(compositeNode, modules, dataSchemaNode); + jsonOutput = TestUtils.writeCompNodeWithSchemaContextToOutput(compositeNode, modules, dataSchemaNode, + StructuredDataToJsonProvider.INSTANCE); } catch (WebApplicationException | IOException e) { - assertTrue(false); // shouldn't get here } + assertNotNull(jsonOutput); - System.out.println(jsonOutput); verifyJsonOutput(jsonOutput); } - private CompositeNode prepareData() { - MutableCompositeNode cont = NodeFactory.createMutableCompositeNode(TestUtils.buildQName("cont"), null, null, - ModifyAction.CREATE, null); - - List> childNodes = new ArrayList<>(); - childNodes.add(NodeFactory.createMutableSimpleNode(TestUtils.buildQName("lfnint8Min"), cont, (byte) -128, - ModifyAction.CREATE, null)); - childNodes.add(NodeFactory.createMutableSimpleNode(TestUtils.buildQName("lfnint8Max"), cont, (byte) 127, - ModifyAction.CREATE, null)); - childNodes.add(NodeFactory.createMutableSimpleNode(TestUtils.buildQName("lfnint16Min"), cont, (short) -32768, - ModifyAction.CREATE, null)); - childNodes.add(NodeFactory.createMutableSimpleNode(TestUtils.buildQName("lfnint16Max"), cont, (short) 32767, - ModifyAction.CREATE, null)); - childNodes.add(NodeFactory.createMutableSimpleNode(TestUtils.buildQName("lfnint32Min"), cont, - (int) -2147483648, ModifyAction.CREATE, null)); - childNodes.add(NodeFactory.createMutableSimpleNode(TestUtils.buildQName("lfnint32Max"), cont, (int) 2147483647, - ModifyAction.CREATE, null)); - childNodes.add(NodeFactory.createMutableSimpleNode(TestUtils.buildQName("lfnint64Min"), cont, new Long( - "-9223372036854775807"), ModifyAction.CREATE, null)); - childNodes.add(NodeFactory.createMutableSimpleNode(TestUtils.buildQName("lfnint64Max"), cont, new Long( - "9223372036854775807"), ModifyAction.CREATE, null)); - childNodes.add(NodeFactory.createMutableSimpleNode(TestUtils.buildQName("lfnuint8Max"), cont, (short) 255, - ModifyAction.CREATE, null)); - childNodes.add(NodeFactory.createMutableSimpleNode(TestUtils.buildQName("lfnuint16Max"), cont, (int) 65535, - ModifyAction.CREATE, null)); - childNodes.add(NodeFactory.createMutableSimpleNode(TestUtils.buildQName("lfnuint32Max"), cont, new Long( - "4294967295"), ModifyAction.CREATE, null)); - childNodes.add(NodeFactory.createMutableSimpleNode(TestUtils.buildQName("lfstr"), cont, "lfstr", - ModifyAction.CREATE, null)); - childNodes.add(NodeFactory.createMutableSimpleNode(TestUtils.buildQName("lfstr1"), cont, "", - ModifyAction.CREATE, null)); - childNodes.add(NodeFactory.createMutableSimpleNode(TestUtils.buildQName("lfbool1"), cont, Boolean.TRUE, - ModifyAction.CREATE, null)); - childNodes.add(NodeFactory.createMutableSimpleNode(TestUtils.buildQName("lfbool2"), cont, Boolean.FALSE, - ModifyAction.CREATE, null)); - childNodes.add(NodeFactory.createMutableSimpleNode(TestUtils.buildQName("lfdecimal1"), cont, new BigDecimal( - "43.32"), ModifyAction.CREATE, null)); - childNodes.add(NodeFactory.createMutableSimpleNode(TestUtils.buildQName("lfdecimal2"), cont, new BigDecimal( - "-0.43"), ModifyAction.CREATE, null)); - childNodes.add(NodeFactory.createMutableSimpleNode(TestUtils.buildQName("lfdecimal3"), cont, new BigDecimal( - "43"), ModifyAction.CREATE, null)); - childNodes.add(NodeFactory.createMutableSimpleNode(TestUtils.buildQName("lfdecimal4"), cont, new BigDecimal( - "43E3"), ModifyAction.CREATE, null)); - childNodes.add(NodeFactory.createMutableSimpleNode(TestUtils.buildQName("lfdecimal6"), cont, new BigDecimal( - "33.12345"), ModifyAction.CREATE, null)); - childNodes.add(NodeFactory.createMutableSimpleNode(TestUtils.buildQName("lfenum"), cont, "enum3", - ModifyAction.CREATE, null)); - - HashSet bits = new HashSet(); - bits.add("bit3"); - childNodes.add(NodeFactory.createMutableSimpleNode(TestUtils.buildQName("lfbits"), cont, bits, - ModifyAction.CREATE, null)); - - childNodes.add(NodeFactory.createMutableSimpleNode(TestUtils.buildQName("lfbinary"), cont, DatatypeConverter - .parseBase64Binary("AAaacdabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"), - ModifyAction.CREATE, null)); - childNodes.add(NodeFactory.createMutableSimpleNode(TestUtils.buildQName("lfempty"), cont, null, - ModifyAction.CREATE, null)); - childNodes.add(NodeFactory.createMutableSimpleNode(TestUtils.buildQName("lfunion1"), cont, (int) 324, - ModifyAction.CREATE, null)); - childNodes.add(NodeFactory.createMutableSimpleNode(TestUtils.buildQName("lfunion2"), cont, new BigDecimal( - "33.3"), ModifyAction.CREATE, null)); - childNodes.add(NodeFactory.createMutableSimpleNode(TestUtils.buildQName("lfunion3"), cont, "55", - ModifyAction.CREATE, null)); - childNodes.add(NodeFactory.createMutableSimpleNode(TestUtils.buildQName("lfunion4"), cont, Boolean.TRUE, - ModifyAction.CREATE, null)); - childNodes.add(NodeFactory.createMutableSimpleNode(TestUtils.buildQName("lfunion5"), cont, "true", - ModifyAction.CREATE, null)); - childNodes.add(NodeFactory.createMutableSimpleNode(TestUtils.buildQName("lfunion6"), cont, "false", - ModifyAction.CREATE, null)); - childNodes.add(NodeFactory.createMutableSimpleNode(TestUtils.buildQName("lfunion7"), cont, null, - ModifyAction.CREATE, null)); - childNodes.add(NodeFactory.createMutableSimpleNode(TestUtils.buildQName("lfunion8"), cont, "", - ModifyAction.CREATE, null)); - childNodes.add(NodeFactory.createMutableSimpleNode(TestUtils.buildQName("lfunion9"), cont, "", - ModifyAction.CREATE, null)); - - HashSet bits2 = new HashSet(); - bits2.add("bt1"); - childNodes.add(NodeFactory.createMutableSimpleNode(TestUtils.buildQName("lfunion10"), cont, bits2, - ModifyAction.CREATE, null)); - - childNodes.add(NodeFactory.createMutableSimpleNode(TestUtils.buildQName("lfunion11"), cont, (short) 33, - ModifyAction.CREATE, null)); - childNodes.add(NodeFactory.createMutableSimpleNode(TestUtils.buildQName("lfunion12"), cont, Boolean.FALSE, - ModifyAction.CREATE, null)); - try { - childNodes.add(NodeFactory.createMutableSimpleNode(TestUtils.buildQName("identityref1"), cont, new QName( - new URI("simple:data:types"), "iden"), ModifyAction.CREATE, null)); - } catch (URISyntaxException e) { - } - - cont.getChildren().addAll(childNodes); - - cont.init(); - - return cont; - } - private void verifyJsonOutput(String jsonOutput) { StringReader strReader = new StringReader(jsonOutput); JsonReader jReader = new JsonReader(strReader); @@ -178,7 +82,6 @@ public class ToJsonBasicDataTypesTest { private void jsonReadContElements(JsonReader jReader) throws IOException { jReader.beginObject(); List loadedLfs = new ArrayList<>(); - boolean exceptForDecimal5Raised = false; boolean enumChecked = false; boolean bitsChecked = false; boolean lfdecimal6Checked = false; @@ -190,7 +93,6 @@ public class ToJsonBasicDataTypesTest { boolean lfbool2Checked = false; boolean lfstrChecked = false; boolean lfbinaryChecked = false; - // boolean lfref1Checked = false; boolean lfemptyChecked = false; boolean lfstr1Checked = false; boolean lfidentityrefChecked = false; @@ -201,11 +103,7 @@ public class ToJsonBasicDataTypesTest { try { peek = jReader.peek(); } catch (IOException e) { - if (keyName.equals("lfdecimal5")) { - exceptForDecimal5Raised = true; - } else { - assertTrue("Key " + keyName + " has incorrect value for specifed type", false); - } + assertTrue("Key " + keyName + " has incorrect value for specifed type", false); } if (keyName.startsWith("lfnint") || keyName.startsWith("lfnuint")) { diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/json/test/ToJsonIdentityrefTest.java b/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/json/test/CnSnToJsonIdentityrefTest.java similarity index 56% rename from opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/json/test/ToJsonIdentityrefTest.java rename to opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/json/test/CnSnToJsonIdentityrefTest.java index 6d30559ccd..6920b0f1ff 100644 --- a/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/json/test/ToJsonIdentityrefTest.java +++ b/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/json/test/CnSnToJsonIdentityrefTest.java @@ -11,12 +11,14 @@ import javax.ws.rs.WebApplicationException; import org.junit.BeforeClass; import org.junit.Test; +import org.opendaylight.controller.sal.rest.impl.StructuredDataToJsonProvider; import org.opendaylight.controller.sal.restconf.impl.test.TestUtils; import org.opendaylight.controller.sal.restconf.impl.test.YangAndXmlAndDataSchemaLoader; +import org.opendaylight.yangtools.yang.common.QName; import org.opendaylight.yangtools.yang.data.api.*; import org.opendaylight.yangtools.yang.data.impl.NodeFactory; -public class ToJsonIdentityrefTest extends YangAndXmlAndDataSchemaLoader { +public class CnSnToJsonIdentityrefTest extends YangAndXmlAndDataSchemaLoader { @BeforeClass public static void initialization() { @@ -27,7 +29,9 @@ public class ToJsonIdentityrefTest extends YangAndXmlAndDataSchemaLoader { public void identityrefToJsonTest() { String json = null; try { - json = TestUtils.writeCompNodeWithSchemaContextToJson(prepareCompositeNode(), modules, dataSchemaNode); + QName valueAsQname = TestUtils.buildQName("name_test", "identityref:module", "2013-12-2"); + json = TestUtils.writeCompNodeWithSchemaContextToOutput(prepareCompositeNode(valueAsQname), modules, + dataSchemaNode, StructuredDataToJsonProvider.INSTANCE); } catch (WebApplicationException | IOException e) { // shouldn't end here assertTrue(false); @@ -40,15 +44,35 @@ public class ToJsonIdentityrefTest extends YangAndXmlAndDataSchemaLoader { assertTrue(mtch.matches()); } - private CompositeNode prepareCompositeNode() { + @Test + public void identityrefToJsonWithoutQNameTest() { + String json = null; + try { + String value = "not q name value"; + json = TestUtils.writeCompNodeWithSchemaContextToOutput(prepareCompositeNode(value), modules, + dataSchemaNode, StructuredDataToJsonProvider.INSTANCE); + } catch (WebApplicationException | IOException e) { + // shouldn't end here + assertTrue(false); + } + System.out.println(json); + assertNotNull(json); + Pattern ptrn = Pattern.compile(".*\"lf1\"\\p{Space}*:\\p{Space}*\"not q name value\".*", Pattern.DOTALL); + Matcher mtch = ptrn.matcher(json); + + assertTrue(mtch.matches()); + } + + private CompositeNode prepareCompositeNode(Object value) { MutableCompositeNode cont = NodeFactory.createMutableCompositeNode(TestUtils.buildQName("cont"), null, null, ModifyAction.CREATE, null); MutableCompositeNode cont1 = NodeFactory.createMutableCompositeNode(TestUtils.buildQName("cont1"), cont, null, ModifyAction.CREATE, null); cont.getChildren().add(cont1); - MutableSimpleNode lf1 = NodeFactory.createMutableSimpleNode(TestUtils.buildQName("lf1"), cont1, - TestUtils.buildQName("name_test", "identityref:module", "2013-12-2"), ModifyAction.CREATE, null); + MutableSimpleNode lf1 = NodeFactory.createMutableSimpleNode(TestUtils.buildQName("lf1"), cont1, value, + ModifyAction.CREATE, null); + cont1.getChildren().add(lf1); cont1.init(); cont.init(); diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/json/test/CnSnToJsonIncorrectTopLevelTest.java b/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/json/test/CnSnToJsonIncorrectTopLevelTest.java new file mode 100644 index 0000000000..6b5776263c --- /dev/null +++ b/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/json/test/CnSnToJsonIncorrectTopLevelTest.java @@ -0,0 +1,170 @@ +package org.opendaylight.controller.sal.restconf.impl.cnsn.to.json.test; + +import static org.junit.Assert.assertTrue; + +import java.io.IOException; +import java.util.List; +import java.util.Set; + +import javax.activation.UnsupportedDataTypeException; +import javax.ws.rs.WebApplicationException; + +import org.junit.BeforeClass; +import org.junit.Test; +import org.opendaylight.controller.sal.rest.impl.StructuredDataToJsonProvider; +import org.opendaylight.controller.sal.rest.impl.XmlToCompositeNodeProvider; +import org.opendaylight.controller.sal.restconf.impl.test.TestUtils; +import org.opendaylight.controller.sal.restconf.impl.test.YangAndXmlAndDataSchemaLoader; +import org.opendaylight.yangtools.yang.common.QName; +import org.opendaylight.yangtools.yang.data.api.CompositeNode; +import org.opendaylight.yangtools.yang.model.api.ConstraintDefinition; +import org.opendaylight.yangtools.yang.model.api.DataNodeContainer; +import org.opendaylight.yangtools.yang.model.api.DataSchemaNode; +import org.opendaylight.yangtools.yang.model.api.GroupingDefinition; +import org.opendaylight.yangtools.yang.model.api.SchemaPath; +import org.opendaylight.yangtools.yang.model.api.Status; +import org.opendaylight.yangtools.yang.model.api.TypeDefinition; +import org.opendaylight.yangtools.yang.model.api.UnknownSchemaNode; +import org.opendaylight.yangtools.yang.model.api.UsesNode; +import org.opendaylight.yangtools.yang.model.api.YangNode; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class CnSnToJsonIncorrectTopLevelTest extends YangAndXmlAndDataSchemaLoader { + + private static final Logger LOG = LoggerFactory.getLogger(CnSnToJsonIncorrectTopLevelTest.class); + + @BeforeClass + public static void initialize() { + dataLoad("/cnsn-to-json/simple-data-types"); + } + + private class IncorrectDataSchema implements DataSchemaNode, DataNodeContainer { + + @Override + public String getDescription() { + // TODO Auto-generated method stub + return null; + } + + @Override + public SchemaPath getPath() { + // TODO Auto-generated method stub + return null; + } + + @Override + public QName getQName() { + // TODO Auto-generated method stub + return null; + } + + @Override + public String getReference() { + // TODO Auto-generated method stub + return null; + } + + @Override + public Status getStatus() { + // TODO Auto-generated method stub + return null; + } + + @Override + public List getUnknownSchemaNodes() { + // TODO Auto-generated method stub + return null; + } + + @Override + public Set getChildNodes() { + // TODO Auto-generated method stub + return null; + } + + @Override + public DataSchemaNode getDataChildByName(QName arg0) { + // TODO Auto-generated method stub + return null; + } + + @Override + public DataSchemaNode getDataChildByName(String arg0) { + // TODO Auto-generated method stub + return null; + } + + @Override + public Set getGroupings() { + // TODO Auto-generated method stub + return null; + } + + @Override + public Set> getTypeDefinitions() { + // TODO Auto-generated method stub + return null; + } + + @Override + public Set getUses() { + // TODO Auto-generated method stub + return null; + } + + @Override + public ConstraintDefinition getConstraints() { + // TODO Auto-generated method stub + return null; + } + + @Override + public YangNode getParent() { + // TODO Auto-generated method stub + return null; + } + + @Override + public boolean isAddedByUses() { + // TODO Auto-generated method stub + return false; + } + + @Override + public boolean isAugmenting() { + // TODO Auto-generated method stub + return false; + } + + @Override + public boolean isConfiguration() { + // TODO Auto-generated method stub + return false; + } + + } + + @Test + public void incorrectTopLevelElementTest() { + + CompositeNode compositeNode = TestUtils.readInputToCnSn("/cnsn-to-json/simple-data-types/xml/data.xml", XmlToCompositeNodeProvider.INSTANCE); + DataSchemaNode incorrectDataSchema = null; + incorrectDataSchema = new IncorrectDataSchema(); + + TestUtils.normalizeCompositeNode(compositeNode, modules, "simple-data-types:cont"); + + boolean exceptionRaised = false; + try { + TestUtils.writeCompNodeWithSchemaContextToOutput(compositeNode, modules, incorrectDataSchema, + StructuredDataToJsonProvider.INSTANCE); + } catch (UnsupportedDataTypeException e) { + exceptionRaised = true; + } catch (WebApplicationException | IOException e) { + LOG.error("WebApplicationException or IOException was raised"); + } + + assertTrue(exceptionRaised); + } + +} diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/json/test/CnSnToJsonLeafrefType.java b/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/json/test/CnSnToJsonLeafrefType.java new file mode 100644 index 0000000000..3215e81719 --- /dev/null +++ b/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/json/test/CnSnToJsonLeafrefType.java @@ -0,0 +1,103 @@ +package org.opendaylight.controller.sal.restconf.impl.cnsn.to.json.test; + +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; + +import java.io.IOException; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import javax.ws.rs.WebApplicationException; + +import org.junit.BeforeClass; +import org.junit.Test; +import org.opendaylight.controller.sal.rest.impl.StructuredDataToJsonProvider; +import org.opendaylight.controller.sal.rest.impl.XmlToCompositeNodeProvider; +import org.opendaylight.controller.sal.restconf.impl.test.TestUtils; +import org.opendaylight.controller.sal.restconf.impl.test.YangAndXmlAndDataSchemaLoader; +import org.opendaylight.yangtools.yang.data.api.CompositeNode; + +/** + * + * All tests are commented now because leafref isn't supported now + * + */ + +public class CnSnToJsonLeafrefType extends YangAndXmlAndDataSchemaLoader { + + @BeforeClass + public static void initialization() { + dataLoad("/cnsn-to-json/leafref", 2, "main-module", "cont"); + } + + @Test + public void leafrefAbsolutePathToExistingLeafTest() { + String json = toJson("/cnsn-to-json/leafref/xml/data_absolut_ref_to_existing_leaf.xml"); + validateJson(".*\"lf3\":\\p{Blank}*\"true\".*", json); + } + + @Test + public void leafrefRelativePathToExistingLeafTest() { + String json = toJson("/cnsn-to-json/leafref/xml/data_relativ_ref_to_existing_leaf.xml"); + validateJson(".*\"lf2\":\\p{Blank}*\"121\".*", json); + } + + /** + * Tests case when reference to not existing element is present. In this + * case value from single node is printed as string. + */ + @Test + public void leafrefToNonExistingLeafTest() { + String json = toJson("/cnsn-to-json/leafref/xml/data_ref_to_non_existing_leaf.xml"); + validateJson(".*\"lf5\":\\p{Blank}*\"137\".*", json); + } + + /** + * Tests case when non leaf element is referenced. In this case value from + * single node is printed as string. + */ + @Test + public void leafrefToNotLeafTest() { + String json = toJson("/cnsn-to-json/leafref/xml/data_ref_to_not_leaf.xml"); + validateJson(".*\"cont-augment-module\\p{Blank}*:\\p{Blank}*lf6\":\\p{Blank}*\"44.33\".*", json); + } + + /** + * Tests case when leaflist element is refers to leaf. + */ + @Test + public void leafrefFromLeafListToLeafTest() { + String json = toJson("/cnsn-to-json/leafref/xml/data_relativ_ref_from_leaflist_to_existing_leaf.xml"); + validateJson( + ".*\"cont-augment-module\\p{Blank}*:\\p{Blank}*lflst1\":\\p{Blank}*.*\"345\",\\p{Space}*\"346\",\\p{Space}*\"347\".*", + json); + } + + /** + * Tests case when leaflist element is refers to leaf. + */ + @Test + public void leafrefFromLeafrefToLeafrefTest() { + String json = toJson("/cnsn-to-json/leafref/xml/data_from_leafref_to_leafref.xml"); + validateJson(".*\"cont-augment-module\\p{Blank}*:\\p{Blank}*lf7\":\\p{Blank}*\"200\".*", json); + } + + private void validateJson(String regex, String value) { + assertNotNull(value); + Pattern ptrn = Pattern.compile(regex, Pattern.DOTALL); + Matcher mtch = ptrn.matcher(value); + assertTrue(mtch.matches()); + } + + private String toJson(String xmlDataPath) { + try { + CompositeNode compositeNode = TestUtils.readInputToCnSn(xmlDataPath, XmlToCompositeNodeProvider.INSTANCE); + TestUtils.normalizeCompositeNode(compositeNode, modules, searchedModuleName + ":" + searchedDataSchemaName); + return TestUtils.writeCompNodeWithSchemaContextToOutput(compositeNode, modules, dataSchemaNode, + StructuredDataToJsonProvider.INSTANCE); + } catch (WebApplicationException | IOException e) { + } + return ""; + } + +} diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/json/test/CnSnToJsonNotExistingLeafTypeTest.java b/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/json/test/CnSnToJsonNotExistingLeafTypeTest.java new file mode 100644 index 0000000000..e5a317e2d5 --- /dev/null +++ b/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/json/test/CnSnToJsonNotExistingLeafTypeTest.java @@ -0,0 +1,72 @@ +package org.opendaylight.controller.sal.restconf.impl.cnsn.to.json.test; + +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; + +import java.io.IOException; +import java.util.Collections; +import java.util.Set; + +import javax.ws.rs.WebApplicationException; + +import org.junit.BeforeClass; +import org.junit.Test; +import org.opendaylight.controller.sal.rest.impl.StructuredDataToJsonProvider; +import org.opendaylight.controller.sal.restconf.impl.test.*; +import org.opendaylight.yangtools.yang.data.api.*; +import org.opendaylight.yangtools.yang.data.impl.NodeFactory; +import org.opendaylight.yangtools.yang.model.api.DataSchemaNode; +import org.opendaylight.yangtools.yang.model.api.Module; +import org.opendaylight.yangtools.yang.parser.builder.impl.ContainerSchemaNodeBuilder; +import org.opendaylight.yangtools.yang.parser.builder.impl.LeafSchemaNodeBuilder; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class CnSnToJsonNotExistingLeafTypeTest extends YangAndXmlAndDataSchemaLoader { + + private static final Logger LOG = LoggerFactory.getLogger(CnSnToJsonNotExistingLeafTypeTest.class); + + @BeforeClass + public static void initialize() { + dataLoad("/cnsn-to-json/simple-data-types"); + } + + @Test + public void incorrectTopLevelElementTest() { + + String jsonOutput = null; + try { + jsonOutput = TestUtils + .writeCompNodeWithSchemaContextToOutput(prepareCompositeNode(), + (Set) Collections.EMPTY_SET, prepareDataSchemaNode(), + StructuredDataToJsonProvider.INSTANCE); + } catch (WebApplicationException | IOException e) { + LOG.error("WebApplicationException or IOException was raised"); + } + assertNotNull(jsonOutput); + assertTrue(jsonOutput.contains("\"lf1\": \"\"")); + } + + private CompositeNode prepareCompositeNode() { + MutableCompositeNode cont = NodeFactory.createMutableCompositeNode( + TestUtils.buildQName("cont", "simple:uri", "2012-12-17"), null, null, ModifyAction.CREATE, null); + MutableSimpleNode lf1 = NodeFactory.createMutableSimpleNode( + TestUtils.buildQName("lf1", "simple:uri", "2012-12-17"), cont, "any value", ModifyAction.CREATE, null); + cont.getChildren().add(lf1); + cont.init(); + return cont; + } + + private DataSchemaNode prepareDataSchemaNode() { + ContainerSchemaNodeBuilder contBuild = new ContainerSchemaNodeBuilder("module", 1, TestUtils.buildQName("cont", + "simple:uri", "2012-12-17"), null); + LeafSchemaNodeBuilder leafBuild = new LeafSchemaNodeBuilder("module", 2, TestUtils.buildQName("lf1", + "simple:uri", "2012-12-17"), null); + leafBuild.setType(new DummyType()); + leafBuild.setConfiguration(true); + + contBuild.addChildNode(leafBuild); + return contBuild.build(null); + } + +} diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/json/test/CnSnToJsonWithAugmentTest.java b/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/json/test/CnSnToJsonWithAugmentTest.java new file mode 100644 index 0000000000..3c2325c0f3 --- /dev/null +++ b/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/json/test/CnSnToJsonWithAugmentTest.java @@ -0,0 +1,51 @@ +package org.opendaylight.controller.sal.restconf.impl.cnsn.to.json.test; + +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; + +import java.io.IOException; + +import javax.ws.rs.WebApplicationException; + +import org.junit.BeforeClass; +import org.junit.Test; +import org.opendaylight.controller.sal.rest.impl.StructuredDataToJsonProvider; +import org.opendaylight.controller.sal.rest.impl.XmlToCompositeNodeProvider; +import org.opendaylight.controller.sal.restconf.impl.test.TestUtils; +import org.opendaylight.controller.sal.restconf.impl.test.YangAndXmlAndDataSchemaLoader; +import org.opendaylight.yangtools.yang.data.api.CompositeNode; + +public class CnSnToJsonWithAugmentTest extends YangAndXmlAndDataSchemaLoader { + + @BeforeClass + public static void initialize() { + dataLoad("/cnsn-to-json/augmentation", 5, "yang", "cont"); + } + + /** + * Test of json output when as input are specified composite node with empty + * data + YANG file + */ + @Test + public void augmentedElementsToJson() { + CompositeNode compositeNode = TestUtils.readInputToCnSn("/cnsn-to-json/augmentation/xml/data.xml", + XmlToCompositeNodeProvider.INSTANCE); + TestUtils.normalizeCompositeNode(compositeNode, modules, searchedModuleName + ":" + searchedDataSchemaName); + + String jsonOutput = null; + try { + jsonOutput = TestUtils.writeCompNodeWithSchemaContextToOutput(compositeNode, modules, dataSchemaNode, + StructuredDataToJsonProvider.INSTANCE); + } catch (WebApplicationException | IOException e) { + } + assertNotNull(jsonOutput); + + 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/cnsn/to/json/test/ToJsonLeafrefType.java b/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/json/test/ToJsonLeafrefType.java deleted file mode 100644 index 1ac81a332f..0000000000 --- a/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/json/test/ToJsonLeafrefType.java +++ /dev/null @@ -1,161 +0,0 @@ -package org.opendaylight.controller.sal.restconf.impl.cnsn.to.json.test; - -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertTrue; - -import java.io.IOException; -import java.util.regex.Matcher; - -import javax.ws.rs.WebApplicationException; - -import org.junit.*; -import org.opendaylight.controller.sal.restconf.impl.test.TestUtils; -import org.opendaylight.controller.sal.restconf.impl.test.YangAndXmlAndDataSchemaLoader; - -/** - * - * All tests are commented now because leafref isn't supported now - * - */ - -public class ToJsonLeafrefType extends YangAndXmlAndDataSchemaLoader { - - @BeforeClass - public static void initialization() { - dataLoad("/cnsn-to-json/leafref", 2, "main-module", "cont"); - } - - @Ignore - @Test - public void leafrefAbsolutePathToExistingLeafTest() { - String json = null; - try { - json = TestUtils.writeCompNodeWithSchemaContextToJson( - TestUtils.loadCompositeNode("/cnsn-to-json/leafref/xml/data_absolut_ref_to_existing_leaf.xml"), - modules, dataSchemaNode); - } catch (WebApplicationException | IOException e) { - // shouldn't end here - assertTrue(false); - } - assertNotNull(json); - java.util.regex.Pattern ptrn = java.util.regex.Pattern.compile(".*\"lf3\":\\p{Blank}*true.*", - java.util.regex.Pattern.DOTALL); - Matcher mtch = ptrn.matcher(json); - assertTrue(mtch.matches()); - } - - @Ignore - @Test - public void leafrefRelativePathToExistingLeafTest() { - String json = null; - try { - json = TestUtils.writeCompNodeWithSchemaContextToJson( - TestUtils.loadCompositeNode("/cnsn-to-json/leafref/xml/data_relativ_ref_to_existing_leaf.xml"), - modules, dataSchemaNode); - } catch (WebApplicationException | IOException e) { - // shouldn't end here - assertTrue(false); - } - assertNotNull(json); - java.util.regex.Pattern ptrn = java.util.regex.Pattern.compile(".*\"lf2\":\\p{Blank}*121.*", - java.util.regex.Pattern.DOTALL); - Matcher mtch = ptrn.matcher(json); - assertTrue(mtch.matches()); - } - - /** - * Tests case when reference to not existing element is present. In this - * case value from single node is printed as string. - */ - @Ignore - @Test - public void leafrefToNonExistingLeafTest() { - String json = null; - try { - json = TestUtils.writeCompNodeWithSchemaContextToJson( - TestUtils.loadCompositeNode("/cnsn-to-json/leafref/xml/data_ref_to_non_existing_leaf.xml"), - modules, dataSchemaNode); - } catch (WebApplicationException | IOException e) { - // shouldn't end here - assertTrue(false); - } - assertNotNull(json); - java.util.regex.Pattern ptrn = java.util.regex.Pattern.compile(".*\"lf5\":\\p{Blank}*\"137\".*", - java.util.regex.Pattern.DOTALL); - Matcher mtch = ptrn.matcher(json); - assertTrue(mtch.matches()); - } - - /** - * Tests case when non leaf element is referenced. In this case value from - * single node is printed as string. - */ - @Ignore - @Test - public void leafrefToNotLeafTest() { - String json = null; - try { - json = TestUtils.writeCompNodeWithSchemaContextToJson( - TestUtils.loadCompositeNode("/cnsn-to-json/leafref/xml/data_ref_to_not_leaf.xml"), modules, - dataSchemaNode); - } catch (WebApplicationException | IOException e) { - // shouldn't end here - assertTrue(false); - } - assertNotNull(json); - java.util.regex.Pattern ptrn = java.util.regex.Pattern.compile( - ".*\"cont-augment-module\\p{Blank}*:\\p{Blank}*lf6\":\\p{Blank}*\"44.33\".*", - java.util.regex.Pattern.DOTALL); - Matcher mtch = ptrn.matcher(json); - assertTrue(mtch.matches()); - } - - /** - * Tests case when leaflist element is refers to leaf. - */ - @Ignore - @Test - public void leafrefFromLeafListToLeafTest() { - String json = null; - try { - json = TestUtils - .writeCompNodeWithSchemaContextToJson( - TestUtils - .loadCompositeNode("/cnsn-to-json/leafref/xml/data_relativ_ref_from_leaflist_to_existing_leaf.xml"), - modules, dataSchemaNode); - } catch (WebApplicationException | IOException e) { - // shouldn't end here - assertTrue(false); - } - assertNotNull(json); - java.util.regex.Pattern ptrn = java.util.regex.Pattern - .compile( - ".*\"cont-augment-module\\p{Blank}*:\\p{Blank}*lflst1\":\\p{Blank}*.*345,\\p{Space}*346,\\p{Space}*347.*", - java.util.regex.Pattern.DOTALL); - Matcher mtch = ptrn.matcher(json); - assertTrue(mtch.matches()); - } - - /** - * Tests case when leaflist element is refers to leaf. - */ - @Ignore - @Test - public void leafrefFromLeafrefToLeafrefTest() { - String json = null; - try { - json = TestUtils.writeCompNodeWithSchemaContextToJson( - TestUtils.loadCompositeNode("/cnsn-to-json/leafref/xml/data_from_leafref_to_leafref.xml"), modules, - dataSchemaNode); - } catch (WebApplicationException | IOException e) { - // shouldn't end here - assertTrue(false); - } - assertNotNull(json); - java.util.regex.Pattern ptrn = java.util.regex.Pattern.compile( - ".*\"cont-augment-module\\p{Blank}*:\\p{Blank}*lf7\":\\p{Blank}*200.*", java.util.regex.Pattern.DOTALL); - Matcher mtch = ptrn.matcher(json); - assertTrue(mtch.matches()); - } - -} diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/json/test/ToJsonWithAugmentTest.java b/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/json/test/ToJsonWithAugmentTest.java deleted file mode 100644 index 73bd178ff3..0000000000 --- a/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/json/test/ToJsonWithAugmentTest.java +++ /dev/null @@ -1,30 +0,0 @@ -package org.opendaylight.controller.sal.restconf.impl.cnsn.to.json.test; - -import static org.junit.Assert.assertTrue; - -import org.junit.Test; -import org.opendaylight.controller.sal.restconf.impl.test.TestUtils; -import org.opendaylight.yangtools.yang.data.api.CompositeNode; - -public class ToJsonWithAugmentTest { - - /** - * Test of json output when as input are specified composite node with empty - * data + YANG file - */ - @Test - public void augmentedElementsToJson() { - - CompositeNode compositeNode = TestUtils.loadCompositeNode("/cnsn-to-json/augmentation/xml/data.xml"); - String jsonOutput = TestUtils.convertCompositeNodeDataAndYangToJson(compositeNode, - "/cnsn-to-json/augmentation", "/cnsn-to-json/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/cnsn/to/xml/test/CnSnToXmlNotExistingLeafTypeTest.java b/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/xml/test/CnSnToXmlNotExistingLeafTypeTest.java new file mode 100644 index 0000000000..d779b5ce7b --- /dev/null +++ b/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/xml/test/CnSnToXmlNotExistingLeafTypeTest.java @@ -0,0 +1,70 @@ +package org.opendaylight.controller.sal.restconf.impl.cnsn.to.xml.test; + +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; + +import java.io.IOException; +import java.util.Collections; +import java.util.Set; + +import javax.ws.rs.WebApplicationException; + +import org.junit.Ignore; +import org.junit.Test; +import org.opendaylight.controller.sal.rest.impl.StructuredDataToXmlProvider; +import org.opendaylight.controller.sal.restconf.impl.test.DummyType; +import org.opendaylight.controller.sal.restconf.impl.test.TestUtils; +import org.opendaylight.yangtools.yang.data.api.*; +import org.opendaylight.yangtools.yang.data.impl.NodeFactory; +import org.opendaylight.yangtools.yang.model.api.DataSchemaNode; +import org.opendaylight.yangtools.yang.model.api.Module; +import org.opendaylight.yangtools.yang.parser.builder.impl.ContainerSchemaNodeBuilder; +import org.opendaylight.yangtools.yang.parser.builder.impl.LeafSchemaNodeBuilder; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class CnSnToXmlNotExistingLeafTypeTest { + + private static final Logger LOG = LoggerFactory.getLogger(CnSnToXmlNotExistingLeafTypeTest.class); + + @Ignore + @Test + public void incorrectTopLevelElementTest() { + + boolean nullPointerExceptionRaised = false; + try { + TestUtils.writeCompNodeWithSchemaContextToOutput(prepareCompositeNode(), + (Set) Collections.EMPTY_SET, prepareDataSchemaNode(), StructuredDataToXmlProvider.INSTANCE); + } catch (WebApplicationException | IOException e) { + LOG.error("WebApplicationException or IOException was raised"); + } catch (NullPointerException e) { + nullPointerExceptionRaised = true; + } + assertTrue(nullPointerExceptionRaised); + + } + + private CompositeNode prepareCompositeNode() { + MutableCompositeNode cont = NodeFactory.createMutableCompositeNode( + TestUtils.buildQName("cont", "simple:uri", "2012-12-17"), null, null, ModifyAction.CREATE, null); + MutableSimpleNode lf1 = NodeFactory.createMutableSimpleNode( + TestUtils.buildQName("lf1", "simple:uri", "2012-12-17"), cont, "any value", ModifyAction.CREATE, null); + cont.getChildren().add(lf1); + cont.init(); + return cont; + } + + private DataSchemaNode prepareDataSchemaNode() { + ContainerSchemaNodeBuilder contBuild = new ContainerSchemaNodeBuilder("module", 1, TestUtils.buildQName("cont", + "simple:uri", "2012-12-17"), null); + LeafSchemaNodeBuilder leafBuild = new LeafSchemaNodeBuilder("module", 2, TestUtils.buildQName("lf1", + "simple:uri", "2012-12-17"), null); + leafBuild.setType(new DummyType()); + leafBuild.setConfiguration(true); + + contBuild.addChildNode(leafBuild); + return contBuild.build(null); + + } + +} diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/xml/test/CnSnToXmlTest.java b/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/xml/test/CnSnToXmlTest.java index d04337865a..96e03a5a3c 100644 --- a/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/xml/test/CnSnToXmlTest.java +++ b/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/xml/test/CnSnToXmlTest.java @@ -1,24 +1,21 @@ package org.opendaylight.controller.sal.restconf.impl.cnsn.to.xml.test; -import static org.junit.Assert.*; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; -import java.io.StringWriter; -import java.util.Set; +import java.io.IOException; -import javax.activation.UnsupportedDataTypeException; -import javax.xml.transform.*; -import javax.xml.transform.dom.DOMSource; -import javax.xml.transform.stream.StreamResult; +import javax.ws.rs.WebApplicationException; +import javax.xml.transform.TransformerFactoryConfigurationError; import org.junit.BeforeClass; import org.junit.Test; -import org.opendaylight.controller.sal.rest.impl.XmlMapper; +import org.opendaylight.controller.sal.rest.impl.StructuredDataToXmlProvider; import org.opendaylight.controller.sal.restconf.impl.test.TestUtils; +import org.opendaylight.controller.sal.restconf.impl.test.YangAndXmlAndDataSchemaLoader; import org.opendaylight.yangtools.yang.data.api.*; import org.opendaylight.yangtools.yang.data.impl.NodeFactory; import org.opendaylight.yangtools.yang.data.impl.codec.TypeDefinitionAwareCodec; -import org.opendaylight.yangtools.yang.model.api.*; -import org.w3c.dom.Document; /** * @@ -27,25 +24,31 @@ import org.w3c.dom.Document; * XML file * */ -public class CnSnToXmlTest { - - private static Set modules; - private static DataSchemaNode dataSchemaNode; - +public class CnSnToXmlTest extends YangAndXmlAndDataSchemaLoader { @BeforeClass public static void initialization() { - modules = TestUtils.resolveModules("/cnsn-to-xml/yang"); - assertEquals(2, modules.size()); - Module module = TestUtils.resolveModule("basic-module", modules); - assertNotNull(module); - dataSchemaNode = TestUtils.resolveDataSchemaNode(module, "cont"); - assertNotNull(dataSchemaNode); - + dataLoad("/cnsn-to-xml/yang", 2, "basic-module", "cont"); } @Test public void snAsYangIdentityrefToXMLTest() { - serializeToXml(prepareIdentityrefData(), "x:iden"); + serializeToXml(prepareIdentityrefData(null, true), "x:iden"); + } + + @Test + public void snAsYangIdentityrefWithQNamePrefixToXMLTest() { + serializeToXml(prepareIdentityrefData("prefix", true), + "prefix:iden"); + } + + @Test + public void snAsYangIdentityrefWithPrefixToXMLTest() { + serializeToXml(prepareIdentityrefData("prefix", false), "no qname value"); + } + + @Test + public void snAsYangLeafrefWithPrefixToXMLTest() { + serializeToXml(prepareLeafrefData(), "true", "true"); } @Test @@ -186,22 +189,13 @@ public class CnSnToXmlTest { private void serializeToXml(CompositeNode compositeNode, String... xmlRepresentation) throws TransformerFactoryConfigurationError { - XmlMapper xmlMapper = new XmlMapper(); - String xmlString = null; - if (dataSchemaNode instanceof DataNodeContainer) { - try { - Document doc = xmlMapper.write(compositeNode, (DataNodeContainer) dataSchemaNode); - DOMSource domSource = new DOMSource(doc); - StringWriter writer = new StringWriter(); - StreamResult result = new StreamResult(writer); - TransformerFactory tf = TransformerFactory.newInstance(); - Transformer transformer = tf.newTransformer(); - transformer.transform(domSource, result); - xmlString = writer.toString(); - } catch (UnsupportedDataTypeException | TransformerException e) { - } + String xmlString = ""; + try { + xmlString = TestUtils.writeCompNodeWithSchemaContextToOutput(compositeNode, modules, dataSchemaNode, + StructuredDataToXmlProvider.INSTANCE); + } catch (WebApplicationException | IOException e) { } - assertNotNull(xmlMapper); + assertNotNull(xmlString); boolean containSearchedStr = false; String strRepresentation = ""; for (String searchedStr : xmlRepresentation) { @@ -215,16 +209,21 @@ public class CnSnToXmlTest { } - private CompositeNode prepareIdentityrefData() { + private CompositeNode prepareIdentityrefData(String prefix, boolean valueAsQName) { MutableCompositeNode cont = NodeFactory.createMutableCompositeNode( TestUtils.buildQName("cont", "basic:module", "2013-12-2"), null, null, ModifyAction.CREATE, null); MutableCompositeNode cont1 = NodeFactory.createMutableCompositeNode( TestUtils.buildQName("cont1", "basic:module", "2013-12-2"), cont, null, ModifyAction.CREATE, null); cont.getChildren().add(cont1); + Object value = null; + if (valueAsQName) { + value = TestUtils.buildQName("iden", "referenced:module", "2013-12-2", prefix); + } else { + value = "no qname value"; + } MutableSimpleNode lf11 = NodeFactory.createMutableSimpleNode( - TestUtils.buildQName("lf11", "basic:module", "2013-12-2"), cont1, - TestUtils.buildQName("iden", "referenced:module", "2013-12-2"), ModifyAction.CREATE, null); + TestUtils.buildQName("lf11", "basic:module", "2013-12-2"), cont1, value, ModifyAction.CREATE, null); cont1.getChildren().add(lf11); cont1.init(); cont.init(); @@ -244,4 +243,19 @@ public class CnSnToXmlTest { return cont; } + private CompositeNode prepareLeafrefData() { + MutableCompositeNode cont = NodeFactory.createMutableCompositeNode(TestUtils.buildQName("cont"), null, null, + ModifyAction.CREATE, null); + + MutableSimpleNode lfBoolean = NodeFactory.createMutableSimpleNode(TestUtils.buildQName("lfBoolean"), + cont, Boolean.TRUE, ModifyAction.CREATE, null); + MutableSimpleNode lfLfref = NodeFactory.createMutableSimpleNode(TestUtils.buildQName("lfLfref"), cont, + "true", ModifyAction.CREATE, null); + cont.getChildren().add(lfBoolean); + cont.getChildren().add(lfLfref); + cont.init(); + + return cont; + } + } diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/xml/test/CnSnToXmlWithChoiceTest.java b/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/xml/test/CnSnToXmlWithChoiceTest.java new file mode 100644 index 0000000000..a23501cbe6 --- /dev/null +++ b/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/xml/test/CnSnToXmlWithChoiceTest.java @@ -0,0 +1,64 @@ +package org.opendaylight.controller.sal.restconf.impl.cnsn.to.xml.test; + +import static org.junit.Assert.assertTrue; + +import java.io.IOException; + +import javax.ws.rs.WebApplicationException; + +import org.junit.BeforeClass; +import org.junit.Test; +import org.opendaylight.controller.sal.rest.impl.StructuredDataToXmlProvider; +import org.opendaylight.controller.sal.restconf.impl.test.TestUtils; +import org.opendaylight.controller.sal.restconf.impl.test.YangAndXmlAndDataSchemaLoader; +import org.opendaylight.yangtools.yang.data.api.*; +import org.opendaylight.yangtools.yang.data.impl.NodeFactory; + +/** + * + * CnSn = Composite node and Simple node data structure Class contains test of + * serializing simple nodes data values according data types from YANG schema to + * XML file + * + */ +public class CnSnToXmlWithChoiceTest extends YangAndXmlAndDataSchemaLoader { + @BeforeClass + public static void initialization() { + dataLoad("/cnsn-to-xml/choice", 1, "module-with-choice", "cont"); + } + + @Test + public void cnSnToXmlWithYangChoice() { + String xmlOutput = ""; + try { + xmlOutput = TestUtils.writeCompNodeWithSchemaContextToOutput( + prepareCnStructForYangData("lf1", "String data1"), modules, dataSchemaNode, + StructuredDataToXmlProvider.INSTANCE); + } catch (WebApplicationException | IOException e) { + } + + assertTrue(xmlOutput.contains("String data1")); + + try { + xmlOutput = TestUtils.writeCompNodeWithSchemaContextToOutput( + prepareCnStructForYangData("lf2", "String data2"), modules, dataSchemaNode, + StructuredDataToXmlProvider.INSTANCE); + } catch (WebApplicationException | IOException e) { + } + assertTrue(xmlOutput.contains("String data2")); + + } + + private CompositeNode prepareCnStructForYangData(String lfName, Object data) { + MutableCompositeNode cont = NodeFactory.createMutableCompositeNode(TestUtils.buildQName("cont"), null, null, + ModifyAction.CREATE, null); + + MutableSimpleNode lf1 = NodeFactory.createMutableSimpleNode(TestUtils.buildQName(lfName), cont, data, + ModifyAction.CREATE, null); + cont.getChildren().add(lf1); + cont.init(); + + return cont; + } + +} diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/json/to/cnsn/test/JsonIdentityrefToCnSnTest.java b/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/json/to/cnsn/test/JsonIdentityrefToCnSnTest.java new file mode 100644 index 0000000000..e9b1dbe1a5 --- /dev/null +++ b/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/json/to/cnsn/test/JsonIdentityrefToCnSnTest.java @@ -0,0 +1,74 @@ +package org.opendaylight.controller.sal.restconf.impl.json.to.cnsn.test; + +import static org.junit.Assert.*; + +import java.util.List; + +import org.junit.BeforeClass; +import org.junit.Test; +import org.opendaylight.controller.sal.rest.impl.JsonToCompositeNodeProvider; +import org.opendaylight.controller.sal.restconf.impl.test.TestUtils; +import org.opendaylight.controller.sal.restconf.impl.test.YangAndXmlAndDataSchemaLoader; +import org.opendaylight.yangtools.yang.common.QName; +import org.opendaylight.yangtools.yang.data.api.*; + +public class JsonIdentityrefToCnSnTest extends YangAndXmlAndDataSchemaLoader { + + @BeforeClass + public static void initialize() { + dataLoad("/json-to-cnsn/identityref", 2, "identityref-module", "cont"); + } + + @Test + public void jsonIdentityrefToCompositeNode() { + CompositeNode compositeNode = TestUtils.readInputToCnSn("/json-to-cnsn/identityref/json/data.json", false, + JsonToCompositeNodeProvider.INSTANCE); + assertNotNull(compositeNode); + + TestUtils.normalizeCompositeNode(compositeNode, modules, searchedModuleName + ":" + searchedDataSchemaName); + + assertEquals("cont", compositeNode.getNodeType().getLocalName()); + + List> childs = compositeNode.getChildren(); + assertEquals(1, childs.size()); + Node nd = childs.iterator().next(); + assertTrue(nd instanceof CompositeNode); + assertEquals("cont1", nd.getNodeType().getLocalName()); + + childs = ((CompositeNode) nd).getChildren(); + assertEquals(4, childs.size()); + SimpleNode lf11 = null; + SimpleNode lf12 = null; + SimpleNode lf13 = null; + SimpleNode lf14 = null; + for (Node child : childs) { + assertTrue(child instanceof SimpleNode); + if (child.getNodeType().getLocalName().equals("lf11")) { + lf11 = (SimpleNode) child; + } else if (child.getNodeType().getLocalName().equals("lf12")) { + lf12 = (SimpleNode) child; + } else if (child.getNodeType().getLocalName().equals("lf13")) { + lf13 = (SimpleNode) child; + } else if (child.getNodeType().getLocalName().equals("lf14")) { + lf14 = (SimpleNode) child; + } + } + + assertTrue(lf11.getValue() instanceof QName); + assertEquals("iden", ((QName) lf11.getValue()).getLocalName()); + assertEquals("identity:module", ((QName) lf11.getValue()).getNamespace().toString()); + + assertTrue(lf12.getValue() instanceof QName); + assertEquals("iden_local", ((QName) lf12.getValue()).getLocalName()); + assertEquals("identityref:module", ((QName) lf12.getValue()).getNamespace().toString()); + + assertTrue(lf13.getValue() instanceof QName); + assertEquals("iden_local", ((QName) lf13.getValue()).getLocalName()); + assertEquals("identityref:module", ((QName) lf13.getValue()).getNamespace().toString()); + + assertTrue(lf14.getValue() instanceof QName); + assertEquals("iden_local", ((QName) lf14.getValue()).getLocalName()); + assertEquals("identity:module", ((QName) lf14.getValue()).getNamespace().toString()); + } + +} diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/json/to/cnsn/test/JsonLeafrefToCnSnTest.java b/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/json/to/cnsn/test/JsonLeafrefToCnSnTest.java new file mode 100644 index 0000000000..2bb42d903a --- /dev/null +++ b/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/json/to/cnsn/test/JsonLeafrefToCnSnTest.java @@ -0,0 +1,48 @@ +package org.opendaylight.controller.sal.restconf.impl.json.to.cnsn.test; + +import static org.junit.Assert.*; + +import org.junit.BeforeClass; +import org.junit.Test; +import org.opendaylight.controller.sal.rest.impl.JsonToCompositeNodeProvider; +import org.opendaylight.controller.sal.restconf.impl.test.TestUtils; +import org.opendaylight.controller.sal.restconf.impl.test.YangAndXmlAndDataSchemaLoader; +import org.opendaylight.yangtools.yang.data.api.*; + +public class JsonLeafrefToCnSnTest extends YangAndXmlAndDataSchemaLoader { + + @BeforeClass + public static void initialize() { + dataLoad("/json-to-cnsn/leafref"); + } + + /** + * JSON values which represents leafref are always loaded to simple node as + * string + */ + @Test + public void jsonIdentityrefToCompositeNode() { + CompositeNode compositeNode = TestUtils.readInputToCnSn("/json-to-cnsn/leafref/json/data.json", false, + JsonToCompositeNodeProvider.INSTANCE); + assertNotNull(compositeNode); + TestUtils.normalizeCompositeNode(compositeNode, modules, searchedModuleName + ":" + searchedDataSchemaName); + + assertEquals("cont", compositeNode.getNodeType().getLocalName()); + + SimpleNode lf2 = null; + for (Node childNode : compositeNode.getChildren()) { + if (childNode instanceof SimpleNode) { + if (childNode.getNodeType().getLocalName().equals("lf2")) { + lf2 = (SimpleNode) childNode; + break; + } + } + } + + assertNotNull(lf2); + assertTrue(lf2.getValue() instanceof String); + assertEquals("121", (String) lf2.getValue()); + + } + +} diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/json/to/cnsn/test/JsonToCnSnTest.java b/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/json/to/cnsn/test/JsonToCnSnTest.java index b02ea9a3a2..f2c0c29bc4 100644 --- a/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/json/to/cnsn/test/JsonToCnSnTest.java +++ b/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/json/to/cnsn/test/JsonToCnSnTest.java @@ -1,9 +1,10 @@ package org.opendaylight.controller.sal.restconf.impl.json.to.cnsn.test; -import static org.junit.Assert.*; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; -import java.io.*; -import java.net.URISyntaxException; +import java.util.HashSet; import java.util.List; import java.util.Set; @@ -12,10 +13,12 @@ import javax.ws.rs.WebApplicationException; import org.junit.Test; import org.opendaylight.controller.sal.rest.impl.JsonToCompositeNodeProvider; import org.opendaylight.controller.sal.restconf.impl.CompositeNodeWrapper; +import org.opendaylight.controller.sal.restconf.impl.ResponseException; import org.opendaylight.controller.sal.restconf.impl.test.TestUtils; import org.opendaylight.yangtools.yang.common.QName; -import org.opendaylight.yangtools.yang.data.api.*; -import org.opendaylight.yangtools.yang.model.api.DataSchemaNode; +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.yangtools.yang.model.api.Module; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -28,7 +31,7 @@ public class JsonToCnSnTest { @Test public void simpleListTest() { - simpleTest("/json-to-cnsn/simple-list.json", "/json-to-cnsn/simple-list-yang", "lst", "simple:list:yang1", + simpleTest("/json-to-cnsn/simple-list.json", "/json-to-cnsn/simple-list-yang/1", "lst", "simple:list:yang1", "simple-list-yang1"); } @@ -43,7 +46,8 @@ public class JsonToCnSnTest { */ @Test public void multipleItemsInLeafList() { - CompositeNode compositeNode = compositeContainerFromJson("/json-to-cnsn/multiple-leaflist-items.json", true); + CompositeNode compositeNode = TestUtils.readInputToCnSn("/json-to-cnsn/multiple-leaflist-items.json", true, + JsonToCompositeNodeProvider.INSTANCE); assertNotNull(compositeNode); assertEquals(3, compositeNode.getChildren().size()); @@ -76,9 +80,10 @@ public class JsonToCnSnTest { */ @Test public void multipleItemsInListTest() { - CompositeNode compositeNode = compositeContainerFromJson("/json-to-cnsn/multiple-items-in-list.json", true); - assertNotNull(compositeNode); + CompositeNode compositeNode = TestUtils.readInputToCnSn("/json-to-cnsn/multiple-items-in-list.json", true, + JsonToCompositeNodeProvider.INSTANCE); + assertNotNull(compositeNode); assertEquals("lst", compositeNode.getNodeType().getLocalName()); verityMultipleItemsInList(compositeNode); @@ -86,7 +91,8 @@ public class JsonToCnSnTest { @Test public void nullArrayToSimpleNodeWithNullValueTest() { - CompositeNode compositeNode = compositeContainerFromJson("/json-to-cnsn/array-with-null.json", true); + CompositeNode compositeNode = TestUtils.readInputToCnSn("/json-to-cnsn/array-with-null.json", true, + JsonToCompositeNodeProvider.INSTANCE); assertNotNull(compositeNode); assertEquals("cont", compositeNode.getNodeType().getLocalName()); @@ -103,7 +109,8 @@ public class JsonToCnSnTest { public void incorrectTopLevelElementsTest() { Throwable cause1 = null; try { - compositeContainerFromJson("/json-to-cnsn/wrong-top-level1.json", true); + TestUtils + .readInputToCnSn("/json-to-cnsn/wrong-top-level1.json", true, JsonToCompositeNodeProvider.INSTANCE); } catch (WebApplicationException e) { cause1 = e; } @@ -117,7 +124,8 @@ public class JsonToCnSnTest { Throwable cause2 = null; try { - compositeContainerFromJson("/json-to-cnsn/wrong-top-level2.json", true); + TestUtils + .readInputToCnSn("/json-to-cnsn/wrong-top-level2.json", true, JsonToCompositeNodeProvider.INSTANCE); } catch (WebApplicationException e) { cause2 = e; } @@ -126,7 +134,8 @@ public class JsonToCnSnTest { Throwable cause3 = null; try { - compositeContainerFromJson("/json-to-cnsn/wrong-top-level3.json", true); + TestUtils + .readInputToCnSn("/json-to-cnsn/wrong-top-level3.json", true, JsonToCompositeNodeProvider.INSTANCE); } catch (WebApplicationException e) { cause3 = e; } @@ -145,7 +154,8 @@ public class JsonToCnSnTest { */ @Test public void emptyDataReadTest() { - CompositeNode compositeNode = compositeContainerFromJson("/json-to-cnsn/empty-data.json", true); + CompositeNode compositeNode = TestUtils.readInputToCnSn("/json-to-cnsn/empty-data.json", true, + JsonToCompositeNodeProvider.INSTANCE); assertNotNull(compositeNode); @@ -158,7 +168,7 @@ public class JsonToCnSnTest { String reason = null; try { - compositeContainerFromJson("/json-to-cnsn/empty-data1.json", true); + TestUtils.readInputToCnSn("/json-to-cnsn/empty-data1.json", true, JsonToCompositeNodeProvider.INSTANCE); } catch (JsonSyntaxException e) { reason = e.getMessage(); } @@ -176,24 +186,20 @@ public class JsonToCnSnTest { @Test public void notSupplyNamespaceIfAlreadySupplied() { - CompositeNode compositeNode = compositeContainerFromJson("/json-to-cnsn/simple-list.json"); + CompositeNode compositeNode = TestUtils.readInputToCnSn("/json-to-cnsn/simple-list.json", false, + JsonToCompositeNodeProvider.INSTANCE); assertNotNull(compositeNode); - DataSchemaNode dataSchemaNode1 = null; - DataSchemaNode dataSchemaNode2 = null; - try { - dataSchemaNode1 = TestUtils.obtainSchemaFromYang("/json-to-cnsn/simple-list-yang", "simple-list-yang1"); - dataSchemaNode2 = TestUtils.obtainSchemaFromYang("/json-to-cnsn/simple-list-yang", "simple-list-yang2"); - } catch (FileNotFoundException e) { - LOG.error(e.getMessage()); - assertTrue(false); - } - assertNotNull(dataSchemaNode1); - assertNotNull(dataSchemaNode2); - // supplement namespaces according to first data schema - // "simple:data:types1" - TestUtils.supplementNamespace(dataSchemaNode1, compositeNode); + Set modules1 = new HashSet<>(); + Set modules2 = new HashSet<>(); + modules1 = TestUtils.loadModulesFrom("/json-to-cnsn/simple-list-yang/1"); + modules2 = TestUtils.loadModulesFrom("/json-to-cnsn/simple-list-yang/2"); + assertNotNull(modules1); + assertNotNull(modules2); + + TestUtils.normalizeCompositeNode(compositeNode, modules1, "simple-list-yang1:lst"); assertTrue(compositeNode instanceof CompositeNodeWrapper); CompositeNode compNode = ((CompositeNodeWrapper) compositeNode).unwrap(); @@ -201,26 +207,27 @@ public class JsonToCnSnTest { assertEquals("lst", compNode.getNodeType().getLocalName()); verifyCompositeNode(compNode, "simple:list:yang1"); - // dataSchemaNode2 should't be taken into account, because compNode - // isn't CompositeNodeWrapper - TestUtils.supplementNamespace(dataSchemaNode2, compNode); - verifyCompositeNode(compNode, "simple:list:yang1"); + String exceptionMessage = ""; + try { + TestUtils.normalizeCompositeNode(compositeNode, modules2, "simple-list-yang2:lst"); + } catch (ResponseException e) { + exceptionMessage = String.valueOf(e.getResponse().getEntity()); + } + assertTrue(exceptionMessage + .contains("Data has bad format\nIf data is in XML format then namespace for lst should be simple:list:yang2.\n If data is in Json format then module name for lst should be simple-list-yang2.")); } @Test public void jsonIdentityrefToCompositeNode() { - CompositeNode compositeNode = compositeContainerFromJson("/json-to-cnsn/identityref/json/data.json"); + CompositeNode compositeNode = TestUtils.readInputToCnSn("/json-to-cnsn/identityref/json/data.json", false, + JsonToCompositeNodeProvider.INSTANCE); assertNotNull(compositeNode); - Set modules = TestUtils.resolveModules("/json-to-cnsn/identityref"); + Set modules = TestUtils.loadModulesFrom("/json-to-cnsn/identityref"); assertEquals(2, modules.size()); - Module module = TestUtils.resolveModule("identityref-module", modules); - assertNotNull(module); - DataSchemaNode dataSchemaNode = TestUtils.resolveDataSchemaNode(module, null); - assertNotNull(dataSchemaNode); - TestUtils.normalizeCompositeNode(compositeNode, modules, dataSchemaNode, "identityref-module:cont"); + TestUtils.normalizeCompositeNode(compositeNode, modules, "identityref-module:cont"); assertEquals("cont", compositeNode.getNodeType().getLocalName()); @@ -268,19 +275,14 @@ public class JsonToCnSnTest { private void simpleTest(String jsonPath, String yangPath, String topLevelElementName, String namespace, String moduleName) { - CompositeNode compositeNode = compositeContainerFromJson(jsonPath); + CompositeNode compositeNode = TestUtils.readInputToCnSn(jsonPath, false, JsonToCompositeNodeProvider.INSTANCE); assertNotNull(compositeNode); - DataSchemaNode dataSchemaNode = null; - try { - dataSchemaNode = TestUtils.obtainSchemaFromYang(yangPath, moduleName); - } catch (FileNotFoundException e) { - LOG.error(e.getMessage()); - assertTrue(false); - } - assertNotNull(dataSchemaNode); + Set modules = null; + modules = TestUtils.loadModulesFrom(yangPath); + assertNotNull(modules); - TestUtils.supplementNamespace(dataSchemaNode, compositeNode); + TestUtils.normalizeCompositeNode(compositeNode, modules, moduleName + ":" + topLevelElementName); assertTrue(compositeNode instanceof CompositeNodeWrapper); CompositeNode compNode = ((CompositeNodeWrapper) compositeNode).unwrap(); @@ -331,7 +333,8 @@ public class JsonToCnSnTest { boolean lflst1_2Found = false; boolean lf1Found = false; - assertEquals(namespace, compositeNode.getNodeType().getNamespace().toString()); + // assertEquals(namespace, + // compositeNode.getNodeType().getNamespace().toString()); for (Node node : compositeNode.getChildren()) { if (node.getNodeType().getLocalName().equals("cont1")) { @@ -369,34 +372,16 @@ public class JsonToCnSnTest { assertTrue(lf1Found); } - private CompositeNode compositeContainerFromJson(String jsonPath) { - return compositeContainerFromJson(jsonPath, false); - } - - private CompositeNode compositeContainerFromJson(String jsonPath, boolean dummyNamespaces) - throws WebApplicationException { - - JsonToCompositeNodeProvider jsonToCompositeNodeProvider = JsonToCompositeNodeProvider.INSTANCE; - InputStream jsonStream = JsonToCnSnTest.class.getResourceAsStream(jsonPath); + @Test + public void unsupportedDataFormatTest() { + String exceptionMessage = ""; try { - CompositeNode compositeNode = jsonToCompositeNodeProvider - .readFrom(null, null, null, null, null, jsonStream); - assertTrue(compositeNode instanceof CompositeNodeWrapper); - if (dummyNamespaces) { - try { - TestUtils.addDummyNamespaceToAllNodes((CompositeNodeWrapper) compositeNode); - return ((CompositeNodeWrapper) compositeNode).unwrap(); - } catch (URISyntaxException e) { - LOG.error(e.getMessage()); - assertTrue(e.getMessage(), false); - } - } - return compositeNode; - } catch (IOException e) { - LOG.error(e.getMessage()); - assertTrue(e.getMessage(), false); + TestUtils.readInputToCnSn("/json-to-cnsn/unsupported-json-format.json", true, + JsonToCompositeNodeProvider.INSTANCE); + } catch (WebApplicationException e) { + exceptionMessage = e.getCause().getMessage(); } - return null; + assertTrue(exceptionMessage.contains("Root element of Json has to be Object")); } } diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/ControllerContextTest.java b/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/ControllerContextTest.java index 39c0d3b34f..c68fcb9071 100644 --- a/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/ControllerContextTest.java +++ b/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/ControllerContextTest.java @@ -1,12 +1,20 @@ package org.opendaylight.controller.sal.restconf.impl.test; -import static org.junit.Assert.*; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; +import static org.mockito.Matchers.eq; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; import java.io.FileNotFoundException; import java.util.Set; import org.junit.BeforeClass; import org.junit.Test; +import org.opendaylight.controller.sal.core.api.mount.MountInstance; +import org.opendaylight.controller.sal.core.api.mount.MountService; import org.opendaylight.controller.sal.restconf.impl.ControllerContext; import org.opendaylight.controller.sal.restconf.impl.InstanceIdWithSchemaNode; import org.opendaylight.yangtools.yang.model.api.ContainerSchemaNode; @@ -19,14 +27,16 @@ public class ControllerContextTest { @BeforeClass public static void init() throws FileNotFoundException { - Set allModules = TestUtils.loadModules(ControllerContextTest.class.getResource("/full-versions/yangs").getPath()); + Set allModules = TestUtils.loadModulesFrom("/full-versions/yangs"); + assertNotNull(allModules); SchemaContext schemaContext = TestUtils.loadSchemaContext(allModules); controllerContext.setSchemas(schemaContext); } @Test public void testToInstanceIdentifierList() throws FileNotFoundException { - InstanceIdWithSchemaNode instanceIdentifier = controllerContext.toInstanceIdentifier("simple-nodes:userWithoutClass/foo"); + InstanceIdWithSchemaNode instanceIdentifier = controllerContext + .toInstanceIdentifier("simple-nodes:userWithoutClass/foo"); assertEquals(instanceIdentifier.getSchemaNode().getQName().getLocalName(), "userWithoutClass"); instanceIdentifier = controllerContext.toInstanceIdentifier("simple-nodes:userWithoutClass/foo/full-name"); @@ -49,28 +59,63 @@ public class ControllerContextTest { } + @Test + public void testToInstanceIdentifierMountPoint() throws FileNotFoundException { + try { + String mountPointPath = "simple-nodes:user/foo/boo"; + String nestedPath = "simple-nodes:user/foo/boo/simple-nodes:users"; + InstanceIdWithSchemaNode mountInstanceIdentifier = controllerContext.toInstanceIdentifier(mountPointPath); + assertEquals("user", mountInstanceIdentifier.getSchemaNode().getQName().getLocalName()); + + MountInstance mountInstance = mock(MountInstance.class); + MountService mountService = mock(MountService.class); + + controllerContext.setMountService(mountService); + // when(mountService.getMountPoint(any(InstanceIdentifier.class))).thenReturn(null); + + when(mountService.getMountPoint(eq(mountInstanceIdentifier.getInstanceIdentifier()))).thenReturn( + mountInstance); + + when(mountInstance.getSchemaContext()).thenReturn(controllerContext.getGlobalSchema()); + + InstanceIdWithSchemaNode mountedInstanceIdentifier = controllerContext.toInstanceIdentifier(nestedPath); + assertEquals("users", mountedInstanceIdentifier.getSchemaNode().getQName().getLocalName()); + + mountedInstanceIdentifier = controllerContext.toInstanceIdentifier(mountPointPath + "/" + mountPointPath); + assertEquals("user", mountedInstanceIdentifier.getSchemaNode().getQName().getLocalName()); + + mountedInstanceIdentifier = controllerContext + .toInstanceIdentifier("simple-nodes:user/foo/var/simple-nodes:users"); + assertNull(mountedInstanceIdentifier); + + } finally { + controllerContext.setMountService(null); + } + + } + @Test public void testToInstanceIdentifierContainer() throws FileNotFoundException { InstanceIdWithSchemaNode instanceIdentifier = controllerContext.toInstanceIdentifier("simple-nodes:users"); assertEquals(instanceIdentifier.getSchemaNode().getQName().getLocalName(), "users"); assertTrue(instanceIdentifier.getSchemaNode() instanceof ContainerSchemaNode); - assertEquals(2, ((ContainerSchemaNode)instanceIdentifier.getSchemaNode()).getChildNodes().size()); + assertEquals(2, ((ContainerSchemaNode) instanceIdentifier.getSchemaNode()).getChildNodes().size()); } @Test public void testToInstanceIdentifierChoice() throws FileNotFoundException { InstanceIdWithSchemaNode instanceIdentifier = controllerContext.toInstanceIdentifier("simple-nodes:food/beer"); assertEquals(instanceIdentifier.getSchemaNode().getQName().getLocalName(), "beer"); - + instanceIdentifier = controllerContext.toInstanceIdentifier("simple-nodes:food/snack"); assertNull(instanceIdentifier); - + instanceIdentifier = controllerContext.toInstanceIdentifier("simple-nodes:food/sports-arena"); assertNull(instanceIdentifier); - + instanceIdentifier = controllerContext.toInstanceIdentifier("simple-nodes:food/snack/sports-arena"); assertNull(instanceIdentifier); - + } } diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/DummyType.java b/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/DummyType.java new file mode 100644 index 0000000000..0876584cab --- /dev/null +++ b/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/DummyType.java @@ -0,0 +1,64 @@ +package org.opendaylight.controller.sal.restconf.impl.test; + +import java.util.List; + +import org.opendaylight.yangtools.yang.common.QName; +import org.opendaylight.yangtools.yang.model.api.*; + +public class DummyType implements TypeDefinition { + QName dummyQName = TestUtils.buildQName("dummy type", "simple:uri", "2012-12-17"); + + @Override + public QName getQName() { + return dummyQName; + } + + @Override + public SchemaPath getPath() { + // TODO Auto-generated method stub + return null; + } + + @Override + public String getDescription() { + // TODO Auto-generated method stub + return null; + } + + @Override + public String getReference() { + // TODO Auto-generated method stub + return null; + } + + @Override + public Status getStatus() { + // TODO Auto-generated method stub + return null; + } + + @Override + public List getUnknownSchemaNodes() { + // TODO Auto-generated method stub + return null; + } + + @Override + public DummyType getBaseType() { + // TODO Auto-generated method stub + return null; + } + + @Override + public String getUnits() { + // TODO Auto-generated method stub + return null; + } + + @Override + public Object getDefaultValue() { + // TODO Auto-generated method stub + return null; + } + +} diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/InvokeRpcMethodTest.java b/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/InvokeRpcMethodTest.java index d58b7e9dab..2370035861 100644 --- a/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/InvokeRpcMethodTest.java +++ b/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/InvokeRpcMethodTest.java @@ -7,15 +7,25 @@ import static org.mockito.Matchers.any; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; -import java.net.*; -import java.util.*; +import java.net.URI; +import java.net.URISyntaxException; +import java.util.Set; -import org.junit.*; +import org.junit.BeforeClass; +import org.junit.Test; import org.mockito.invocation.InvocationOnMock; import org.mockito.stubbing.Answer; -import org.opendaylight.controller.sal.restconf.impl.*; -import org.opendaylight.yangtools.yang.common.*; -import org.opendaylight.yangtools.yang.data.api.*; +import org.opendaylight.controller.sal.restconf.impl.BrokerFacade; +import org.opendaylight.controller.sal.restconf.impl.ControllerContext; +import org.opendaylight.controller.sal.restconf.impl.RestconfImpl; +import org.opendaylight.controller.sal.restconf.impl.StructuredData; +import org.opendaylight.yangtools.yang.common.QName; +import org.opendaylight.yangtools.yang.common.RpcResult; +import org.opendaylight.yangtools.yang.data.api.CompositeNode; +import org.opendaylight.yangtools.yang.data.api.ModifyAction; +import org.opendaylight.yangtools.yang.data.api.MutableCompositeNode; +import org.opendaylight.yangtools.yang.data.api.MutableSimpleNode; +import org.opendaylight.yangtools.yang.data.api.Node; import org.opendaylight.yangtools.yang.data.impl.NodeFactory; import org.opendaylight.yangtools.yang.model.api.Module; @@ -33,7 +43,7 @@ public class InvokeRpcMethodTest { @BeforeClass public static void initialization() { - modules = TestUtils.resolveModules("/invoke-rpc"); + modules = TestUtils.loadModulesFrom("/invoke-rpc"); assertEquals(1, modules.size()); Module module = TestUtils.resolveModule("invoke-rpc-module", modules); assertNotNull(module); diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/ReadConfAndOperDataTest.java b/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/ReadConfAndOperDataTest.java index cac77eb368..f2eea9dbd2 100644 --- a/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/ReadConfAndOperDataTest.java +++ b/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/ReadConfAndOperDataTest.java @@ -1,6 +1,7 @@ package org.opendaylight.controller.sal.restconf.impl.test; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; import static org.mockito.Matchers.any; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; @@ -45,8 +46,8 @@ public class ReadConfAndOperDataTest extends JerseyTest { @BeforeClass public static void init() throws FileNotFoundException { - Set allModules = TestUtils.loadModules(RestconfImplTest.class.getResource("/full-versions/yangs") - .getPath()); + Set allModules = TestUtils.loadModulesFrom("/full-versions/yangs"); + assertNotNull(allModules); SchemaContext schemaContext = TestUtils.loadSchemaContext(allModules); controllerContext = ControllerContext.getInstance(); controllerContext.setSchemas(schemaContext); @@ -69,15 +70,16 @@ public class ReadConfAndOperDataTest extends JerseyTest { String uri = createUri("/config/", "ietf-interfaces:interfaces/interface/eth0"); - CompositeNode loadedCompositeNode = TestUtils.loadCompositeNodeWithXmlTreeBuilder("/parts/ietf-interfaces_interfaces.xml"); + CompositeNode loadedCompositeNode = TestUtils.readInputToCnSn("/parts/ietf-interfaces_interfaces.xml", true, + XmlToCompositeNodeProvider.INSTANCE); when(brokerFacade.readConfigurationData(any(InstanceIdentifier.class))).thenReturn(loadedCompositeNode); Response response = target(uri).request(MEDIA_TYPE_DRAFT02).get(); assertEquals(200, response.getStatus()); - + uri = createUri("/config/", "ietf-interfaces:interfaces/interface/example"); when(brokerFacade.readConfigurationData(any(InstanceIdentifier.class))).thenReturn(null); - + response = target(uri).request(MEDIA_TYPE_DRAFT02).get(); assertEquals(404, response.getStatus()); } @@ -86,15 +88,17 @@ public class ReadConfAndOperDataTest extends JerseyTest { public void testReadOperationalData() throws UnsupportedEncodingException, FileNotFoundException { String uri = createUri("/operational/", "ietf-interfaces:interfaces/interface/eth0"); - CompositeNode loadedCompositeNode = TestUtils.loadCompositeNodeWithXmlTreeBuilder("/parts/ietf-interfaces_interfaces.xml"); + CompositeNode loadedCompositeNode = TestUtils.readInputToCnSn("/parts/ietf-interfaces_interfaces.xml", true, + XmlToCompositeNodeProvider.INSTANCE); + when(brokerFacade.readOperationalData(any(InstanceIdentifier.class))).thenReturn(loadedCompositeNode); Response response = target(uri).request(MEDIA_TYPE_DRAFT02).get(); assertEquals(200, response.getStatus()); - + uri = createUri("/config/", "ietf-interfaces:interfaces/interface/example"); when(brokerFacade.readConfigurationData(any(InstanceIdentifier.class))).thenReturn(null); - + response = target(uri).request(MEDIA_TYPE_DRAFT02).get(); assertEquals(404, response.getStatus()); } diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/RestCodecExceptionsTest.java b/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/RestCodecExceptionsTest.java new file mode 100644 index 0000000000..fcc4c02a6f --- /dev/null +++ b/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/RestCodecExceptionsTest.java @@ -0,0 +1,33 @@ +package org.opendaylight.controller.sal.restconf.impl.test; + +import static org.junit.Assert.assertEquals; +import static org.mockito.Mockito.mock; + +import org.junit.Test; +import org.opendaylight.controller.sal.restconf.impl.RestCodec; +import org.opendaylight.yangtools.concepts.Codec; +import org.opendaylight.yangtools.yang.model.api.type.IdentityrefTypeDefinition; +import org.opendaylight.yangtools.yang.model.util.BitsType; + +public class RestCodecExceptionsTest { + + @Test + public void serializeExceptionTest() { + Codec codec = RestCodec.from(new BitsType(null)); + String serializedValue = (String) codec.serialize("incorrect value"); // set + // expected + assertEquals("incorrect value", serializedValue); + } + + @Test + public void deserializeExceptionTest() { + IdentityrefTypeDefinition mockedIidentityrefType = mock(IdentityrefTypeDefinition.class); + + Codec codec = RestCodec.from(mockedIidentityrefType); + String serializedValue = (String) codec.deserialize("incorrect value"); // IdentityValuesDTO + // object + // expected + assertEquals("incorrect value", serializedValue); + } + +} diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/RestconfImplTest.java b/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/RestconfImplTest.java index 41cc0ddb51..c15cd53082 100644 --- a/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/RestconfImplTest.java +++ b/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/RestconfImplTest.java @@ -1,17 +1,20 @@ package org.opendaylight.controller.sal.restconf.impl.test; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; import static org.mockito.Matchers.any; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; import java.io.FileNotFoundException; -import java.io.InputStream; import java.util.Set; import org.junit.BeforeClass; import org.junit.Test; -import org.opendaylight.controller.sal.restconf.impl.*; +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.RestconfImpl; import org.opendaylight.yangtools.yang.data.api.CompositeNode; import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier; import org.opendaylight.yangtools.yang.model.api.Module; @@ -23,8 +26,8 @@ public class RestconfImplTest { @BeforeClass public static void init() throws FileNotFoundException { - Set allModules = TestUtils.loadModules(RestconfImplTest.class.getResource("/full-versions/yangs") - .getPath()); + Set allModules = TestUtils.loadModulesFrom("/full-versions/yangs"); + assertNotNull(allModules); SchemaContext schemaContext = TestUtils.loadSchemaContext(allModules); ControllerContext controllerContext = ControllerContext.getInstance(); controllerContext.setSchemas(schemaContext); @@ -33,8 +36,7 @@ public class RestconfImplTest { @Test public void testExample() throws FileNotFoundException { - InputStream xmlStream = RestconfImplTest.class.getResourceAsStream("/parts/ietf-interfaces_interfaces.xml"); - CompositeNode loadedCompositeNode = TestUtils.loadCompositeNodeWithXmlTreeBuilder(xmlStream); + CompositeNode loadedCompositeNode = TestUtils.readInputToCnSn("/parts/ietf-interfaces_interfaces.xml", XmlToCompositeNodeProvider.INSTANCE); BrokerFacade brokerFacade = mock(BrokerFacade.class); when(brokerFacade.readOperationalData(any(InstanceIdentifier.class))).thenReturn(loadedCompositeNode); assertEquals(loadedCompositeNode, brokerFacade.readOperationalData(null)); 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 366d99dbcb..4295c29a22 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 @@ -1,32 +1,50 @@ package org.opendaylight.controller.sal.restconf.impl.test; import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; import static org.mockito.Matchers.any; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; -import java.io.*; +import java.io.ByteArrayOutputStream; +import java.io.File; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStreamWriter; import java.net.URI; import java.net.URISyntaxException; import java.sql.Date; -import java.util.*; -import java.util.concurrent.Future; +import java.util.ArrayList; +import java.util.List; +import java.util.Set; import javax.ws.rs.WebApplicationException; -import javax.xml.parsers.*; -import javax.xml.stream.XMLStreamException; -import javax.xml.transform.*; +import javax.ws.rs.ext.MessageBodyReader; +import javax.ws.rs.ext.MessageBodyWriter; +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.ParserConfigurationException; +import javax.xml.transform.OutputKeys; +import javax.xml.transform.Transformer; +import javax.xml.transform.TransformerException; +import javax.xml.transform.TransformerFactory; import javax.xml.transform.dom.DOMSource; import javax.xml.transform.stream.StreamResult; import org.opendaylight.controller.md.sal.common.api.TransactionStatus; -import org.opendaylight.controller.sal.rest.impl.*; -import org.opendaylight.controller.sal.restconf.impl.*; +import org.opendaylight.controller.sal.restconf.impl.BrokerFacade; +import org.opendaylight.controller.sal.restconf.impl.CompositeNodeWrapper; +import org.opendaylight.controller.sal.restconf.impl.ControllerContext; +import org.opendaylight.controller.sal.restconf.impl.NodeWrapper; +import org.opendaylight.controller.sal.restconf.impl.RestconfImpl; +import org.opendaylight.controller.sal.restconf.impl.StructuredData; import org.opendaylight.yangtools.yang.common.QName; -import org.opendaylight.yangtools.yang.common.RpcResult; -import org.opendaylight.yangtools.yang.data.api.*; -import org.opendaylight.yangtools.yang.data.impl.XmlTreeBuilder; -import org.opendaylight.yangtools.yang.model.api.*; +import org.opendaylight.yangtools.yang.data.api.CompositeNode; +import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier; +import org.opendaylight.yangtools.yang.model.api.DataSchemaNode; +import org.opendaylight.yangtools.yang.model.api.Module; +import org.opendaylight.yangtools.yang.model.api.SchemaContext; import org.opendaylight.yangtools.yang.model.parser.api.YangModelParser; import org.opendaylight.yangtools.yang.parser.impl.YangParserImpl; import org.slf4j.Logger; @@ -38,11 +56,11 @@ import com.google.common.base.Preconditions; public final class TestUtils { - private static final Logger logger = LoggerFactory.getLogger(TestUtils.class); + private static final Logger LOG = LoggerFactory.getLogger(TestUtils.class); private final static YangModelParser parser = new YangParserImpl(); - public static Set loadModules(String resourceDirectory) throws FileNotFoundException { + private static Set loadModules(String resourceDirectory) throws FileNotFoundException { final File testDir = new File(resourceDirectory); final String[] fileList = testDir.list(); final List testFiles = new ArrayList(); @@ -58,34 +76,40 @@ public final class TestUtils { return parser.parseYangModels(testFiles); } + public static Set loadModulesFrom(String yangPath) { + try { + return TestUtils.loadModules(TestUtils.class.getResource(yangPath).getPath()); + } catch (FileNotFoundException e) { + LOG.error("Yang files at path: " + yangPath + " weren't loaded."); + } + + return null; + } + public static SchemaContext loadSchemaContext(Set modules) { return parser.resolveSchemaContext(modules); } public static SchemaContext loadSchemaContext(String resourceDirectory) throws FileNotFoundException { - return parser.resolveSchemaContext(loadModules(resourceDirectory)); + return parser.resolveSchemaContext(loadModulesFrom(resourceDirectory)); } public static Module findModule(Set modules, String moduleName) { - Module result = null; for (Module module : modules) { if (module.getName().equals(moduleName)) { - result = module; - break; + return module; } } - return result; + return null; } - - public static Document loadDocumentFrom(InputStream inputStream) { try { DocumentBuilderFactory dbfac = DocumentBuilderFactory.newInstance(); DocumentBuilder docBuilder = dbfac.newDocumentBuilder(); return docBuilder.parse(inputStream); } catch (SAXException | IOException | ParserConfigurationException e) { - logger.error("Error during loading Document from XML", e); + LOG.error("Error during loading Document from XML", e); return null; } } @@ -107,288 +131,84 @@ public final class TestUtils { return new String(charData, "UTF-8"); } catch (IOException | TransformerException e) { String msg = "Error during transformation of Document into String"; - logger.error(msg, e); + LOG.error(msg, e); return msg; } } - public static String convertCompositeNodeDataAndYangToJson(CompositeNode compositeNode, String yangPath, - String outputPath, String searchedModuleName, String searchedDataSchemaName) { - Set modules = resolveModules(yangPath); - Module module = resolveModule(searchedModuleName, modules); - DataSchemaNode dataSchemaNode = resolveDataSchemaNode(module, searchedDataSchemaName); - - normalizeCompositeNode(compositeNode, modules, dataSchemaNode, searchedModuleName + ":" - + searchedDataSchemaName); - - try { - return writeCompNodeWithSchemaContextToJson(compositeNode, modules, dataSchemaNode); - } catch (WebApplicationException | IOException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - return null; - - } - - public static void normalizeCompositeNode(CompositeNode compositeNode, Set modules, - DataSchemaNode dataSchemaNode, String schemaNodePath) { + /** + * + * Fill missing data (namespaces) and build correct data type in + * {@code compositeNode} according to {@code dataSchemaNode}. The method + * {@link RestconfImpl#createConfigurationData createConfigurationData} is + * used because it contains calling of method {code normalizeNode} + */ + public static void normalizeCompositeNode(CompositeNode compositeNode, Set modules, String schemaNodePath) { RestconfImpl restconf = RestconfImpl.getInstance(); ControllerContext.getInstance().setSchemas(TestUtils.loadSchemaContext(modules)); - TestUtils.prepareMockForRestconfBeforeNormalization(modules, dataSchemaNode, restconf); + prepareMocksForRestconf(modules, restconf); restconf.createConfigurationData(schemaNodePath, compositeNode); } + /** + * Searches module with name {@code searchedModuleName} in {@code modules}. + * If module name isn't specified and module set has only one element then + * this element is returned. + * + */ public static Module resolveModule(String searchedModuleName, Set modules) { - assertNotNull("modules can't be null.", modules); - Module module = null; + assertNotNull("Modules can't be null.", modules); if (searchedModuleName != null) { for (Module m : modules) { if (m.getName().equals(searchedModuleName)) { - module = m; - break; + return m; } } } else if (modules.size() == 1) { - module = modules.iterator().next(); + return modules.iterator().next(); } - return module; - } - - public static Set resolveModules(String yangPath) { - Set modules = null; - - try { - modules = TestUtils.loadModules(TestUtils.class.getResource(yangPath).getPath()); - } catch (FileNotFoundException e) { - e.printStackTrace(); - } - - return modules; + return null; } - public static DataSchemaNode resolveDataSchemaNode(Module module, String searchedDataSchemaName) { - assertNotNull("Module is missing", module); + public static DataSchemaNode resolveDataSchemaNode(String searchedDataSchemaName, Module module) { + assertNotNull("Module can't be null", module); - DataSchemaNode dataSchemaNode = null; if (searchedDataSchemaName != null) { for (DataSchemaNode dsn : module.getChildNodes()) { if (dsn.getQName().getLocalName().equals(searchedDataSchemaName)) { - dataSchemaNode = dsn; + return dsn; } } } else if (module.getChildNodes().size() == 1) { - dataSchemaNode = module.getChildNodes().iterator().next(); + return module.getChildNodes().iterator().next(); } - return dataSchemaNode; - } - - public static String writeCompNodeWithSchemaContextToJson(CompositeNode compositeNode, Set modules, - DataSchemaNode dataSchemaNode) throws IOException, WebApplicationException { - String jsonResult; - - assertNotNull(dataSchemaNode); - assertNotNull("Composite node can't be null", compositeNode); - ByteArrayOutputStream byteArrayOS = new ByteArrayOutputStream(); - - ControllerContext.getInstance().setSchemas(loadSchemaContext(modules)); - - StructuredDataToJsonProvider structuredDataToJsonProvider = StructuredDataToJsonProvider.INSTANCE; - structuredDataToJsonProvider.writeTo(new StructuredData(compositeNode, dataSchemaNode), null, null, null, null, - null, byteArrayOS); - - jsonResult = byteArrayOS.toString(); - - return jsonResult; - } - - public static CompositeNode loadCompositeNode(String xmlDataPath) { - InputStream xmlStream = TestUtils.class.getResourceAsStream(xmlDataPath); - CompositeNode compositeNode = null; - try { - XmlReader xmlReader = new XmlReader(); - compositeNode = xmlReader.read(xmlStream); - - } catch (UnsupportedFormatException | XMLStreamException e) { - e.printStackTrace(); - } - return compositeNode; - } - - static void outputToFile(ByteArrayOutputStream outputStream, String outputDir) throws IOException { - FileOutputStream fileOS = null; - try { - String path = TestUtils.class.getResource(outputDir).getPath(); - File outFile = new File(path + "/data.json"); - fileOS = new FileOutputStream(outFile); - try { - fileOS.write(outputStream.toByteArray()); - } catch (IOException e) { - e.printStackTrace(); - } - fileOS.close(); - } catch (FileNotFoundException e1) { - e1.printStackTrace(); - } - } - - static String readJsonFromFile(String path, boolean removeWhiteChars) { - FileReader fileReader = getFileReader(path); - - StringBuilder strBuilder = new StringBuilder(); - char[] buffer = new char[1000]; - - while (true) { - int loadedCharNum; - try { - loadedCharNum = fileReader.read(buffer); - } catch (IOException e) { - break; - } - if (loadedCharNum == -1) { - break; - } - strBuilder.append(buffer, 0, loadedCharNum); - } - try { - fileReader.close(); - } catch (IOException e) { - System.out.println("The file wasn't closed"); - } - String rawStr = strBuilder.toString(); - if (removeWhiteChars) { - rawStr = rawStr.replace("\n", ""); - rawStr = rawStr.replace("\r", ""); - rawStr = rawStr.replace("\t", ""); - rawStr = removeSpaces(rawStr); - } - - return rawStr; - } - - private static FileReader getFileReader(String path) { - String fullPath = TestUtils.class.getResource(path).getPath(); - assertNotNull("Path to file can't be null.", fullPath); - File file = new File(fullPath); - assertNotNull("File can't be null", file); - FileReader fileReader = null; - try { - fileReader = new FileReader(file); - } catch (FileNotFoundException e) { - e.printStackTrace(); - } - assertNotNull("File reader can't be null.", fileReader); - return fileReader; - } - - private static String removeSpaces(String rawStr) { - StringBuilder strBuilder = new StringBuilder(); - int i = 0; - int quoteCount = 0; - while (i < rawStr.length()) { - if (rawStr.substring(i, i + 1).equals("\"")) { - quoteCount++; - } - - if (!rawStr.substring(i, i + 1).equals(" ") || (quoteCount % 2 == 1)) { - strBuilder.append(rawStr.charAt(i)); - } - i++; - } - - return strBuilder.toString(); + return null; } - public static QName buildQName(String name, String uri, String date) { + public static QName buildQName(String name, String uri, String date, String prefix) { try { URI u = new URI(uri); Date dt = null; if (date != null) { dt = Date.valueOf(date); } - return new QName(u, dt, name); + return new QName(u, dt, prefix, name); } catch (URISyntaxException e) { return null; } } - public static QName buildQName(String name) { - return buildQName(name, "", null); - } - - public static void supplementNamespace(DataSchemaNode dataSchemaNode, CompositeNode compositeNode) { - RestconfImpl restconf = RestconfImpl.getInstance(); - - InstanceIdWithSchemaNode instIdAndSchema = new InstanceIdWithSchemaNode(mock(InstanceIdentifier.class), - dataSchemaNode); - - ControllerContext controllerContext = mock(ControllerContext.class); - BrokerFacade broker = mock(BrokerFacade.class); - - RpcResult rpcResult = new 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); - - restconf.setControllerContext(controllerContext); - restconf.setBroker(broker); - - // method is called only because it contains call of method which - // supplement namespaces to compositeNode - restconf.createConfigurationData("something", compositeNode); - } - - public static DataSchemaNode obtainSchemaFromYang(String yangFolder) throws FileNotFoundException { - return obtainSchemaFromYang(yangFolder, null); + public static QName buildQName(String name, String uri, String date) { + return buildQName(name, uri, date, null); } - public static DataSchemaNode obtainSchemaFromYang(String yangFolder, String moduleName) - throws FileNotFoundException { - Set modules = null; - modules = TestUtils.loadModules(TestUtils.class.getResource(yangFolder).getPath()); - - if (modules == null) { - return null; - } - if (modules.size() < 1) { - return null; - } - - Module moduleRes = null; - if (modules.size() > 1) { - if (moduleName == null) { - return null; - } else { - for (Module module : modules) { - if (module.getName().equals(moduleName)) { - moduleRes = module; - } - } - if (moduleRes == null) { - return null; - } - } - } else { - moduleRes = modules.iterator().next(); - } - - if (moduleRes.getChildNodes() == null) { - return null; - } - - if (moduleRes.getChildNodes().size() != 1) { - return null; - } - DataSchemaNode dataSchemaNode = moduleRes.getChildNodes().iterator().next(); - return dataSchemaNode; - + public static QName buildQName(String name) { + return buildQName(name, "", null); } - public static void addDummyNamespaceToAllNodes(NodeWrapper wrappedNode) throws URISyntaxException { + private static void addDummyNamespaceToAllNodes(NodeWrapper wrappedNode) throws URISyntaxException { wrappedNode.setNamespace(new URI("")); if (wrappedNode instanceof CompositeNodeWrapper) { for (NodeWrapper childNodeWrapper : ((CompositeNodeWrapper) wrappedNode).getValues()) { @@ -397,56 +217,63 @@ public final class TestUtils { } } - public static void prepareMockForRestconfBeforeNormalization(Set modules, DataSchemaNode dataSchemaNode, - RestconfImpl restconf) { - ControllerContext instance = ControllerContext.getInstance(); - instance.setSchemas(TestUtils.loadSchemaContext(modules)); - restconf.setControllerContext(ControllerContext.getInstance()); - + private static void prepareMocksForRestconf(Set modules, RestconfImpl restconf) { + ControllerContext controllerContext = ControllerContext.getInstance(); BrokerFacade mockedBrokerFacade = mock(BrokerFacade.class); + + controllerContext.setSchemas(TestUtils.loadSchemaContext(modules)); + when(mockedBrokerFacade.commitConfigurationDataPut(any(InstanceIdentifier.class), any(CompositeNode.class))) .thenReturn( new DummyFuture.Builder().rpcResult( new DummyRpcResult.Builder().result(TransactionStatus.COMMITED) .build()).build()); + + restconf.setControllerContext(controllerContext); restconf.setBroker(mockedBrokerFacade); } - - static CompositeNode loadCompositeNodeWithXmlTreeBuilder(String xmlDataPath) { - InputStream xmlStream = TestUtils.class.getResourceAsStream(xmlDataPath); - CompositeNode compositeNode = null; + + public static CompositeNode readInputToCnSn(String path, boolean dummyNamespaces, + MessageBodyReader reader) throws WebApplicationException { + + InputStream inputStream = TestUtils.class.getResourceAsStream(path); try { - compositeNode = TestUtils.loadCompositeNodeWithXmlTreeBuilder(xmlStream); - } catch (FileNotFoundException e) { - e.printStackTrace(); + CompositeNode compositeNode = reader.readFrom(null, null, null, null, null, inputStream); + assertTrue(compositeNode instanceof CompositeNodeWrapper); + if (dummyNamespaces) { + try { + TestUtils.addDummyNamespaceToAllNodes((CompositeNodeWrapper) compositeNode); + return ((CompositeNodeWrapper) compositeNode).unwrap(); + } catch (URISyntaxException e) { + LOG.error(e.getMessage()); + assertTrue(e.getMessage(), false); + } + } + return compositeNode; + } catch (IOException e) { + LOG.error(e.getMessage()); + assertTrue(e.getMessage(), false); } - return compositeNode; - - - + return null; } - - - public static CompositeNode loadCompositeNodeWithXmlTreeBuilder(InputStream xmlInputStream) throws FileNotFoundException { - if (xmlInputStream == null) { - throw new IllegalArgumentException(); - } - Node dataTree; - try { - dataTree = XmlTreeBuilder.buildDataTree(xmlInputStream); - } catch (XMLStreamException e) { - logger.error("Error during building data tree from XML", e); - return null; - } - if (dataTree == null) { - logger.error("data tree is null"); - return null; - } - if (dataTree instanceof SimpleNode) { - logger.error("RPC XML was resolved as SimpleNode"); - return null; - } - return (CompositeNode) dataTree; - } + public static CompositeNode readInputToCnSn(String path, MessageBodyReader reader) { + return readInputToCnSn(path, false, reader); + } + + public static String writeCompNodeWithSchemaContextToOutput(CompositeNode compositeNode, Set modules, + DataSchemaNode dataSchemaNode, MessageBodyWriter messageBodyWriter) throws IOException, + WebApplicationException { + + assertNotNull(dataSchemaNode); + assertNotNull("Composite node can't be null", compositeNode); + ByteArrayOutputStream byteArrayOS = new ByteArrayOutputStream(); + + ControllerContext.getInstance().setSchemas(loadSchemaContext(modules)); + + messageBodyWriter.writeTo(new StructuredData(compositeNode, dataSchemaNode), null, null, null, null, null, + byteArrayOS); + + return byteArrayOS.toString(); + } } 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 4cea120d4d..b18f526a23 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 @@ -1,6 +1,7 @@ package org.opendaylight.controller.sal.restconf.impl.test; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; import static org.mockito.Matchers.any; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; @@ -35,7 +36,6 @@ import org.opendaylight.controller.sal.rest.impl.XmlToCompositeNodeProvider; import org.opendaylight.controller.sal.restconf.impl.*; import org.opendaylight.yangtools.yang.common.RpcResult; import org.opendaylight.yangtools.yang.data.api.*; -import org.opendaylight.yangtools.yang.data.impl.NodeFactory; import org.opendaylight.yangtools.yang.model.api.Module; import org.opendaylight.yangtools.yang.model.api.SchemaContext; @@ -51,8 +51,8 @@ public class XmlProvidersTest extends JerseyTest { @BeforeClass public static void init() throws FileNotFoundException { - Set allModules = TestUtils.loadModules(RestconfImplTest.class.getResource("/full-versions/yangs") - .getPath()); + Set allModules = TestUtils.loadModulesFrom("/full-versions/yangs"); + assertNotNull(allModules); SchemaContext schemaContext = TestUtils.loadSchemaContext(allModules); controllerContext = ControllerContext.getInstance(); controllerContext.setSchemas(schemaContext); diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/YangAndXmlAndDataSchemaLoader.java b/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/YangAndXmlAndDataSchemaLoader.java index 7e3da0e4b4..3d24c6ba67 100644 --- a/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/YangAndXmlAndDataSchemaLoader.java +++ b/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/YangAndXmlAndDataSchemaLoader.java @@ -4,24 +4,32 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import java.util.Set; -import org.opendaylight.yangtools.yang.model.api.*; + +import org.opendaylight.yangtools.yang.model.api.DataSchemaNode; +import org.opendaylight.yangtools.yang.model.api.Module; public abstract class YangAndXmlAndDataSchemaLoader { protected static Set modules; protected static DataSchemaNode dataSchemaNode; + protected static String searchedModuleName; + protected static String searchedDataSchemaName; + protected static String schemaNodePath; protected static void dataLoad(String yangPath) { dataLoad(yangPath, 1, null, null); } protected static void dataLoad(String yangPath, int modulesNumber, String moduleName, String dataSchemaName) { - modules = TestUtils.resolveModules(yangPath); + modules = TestUtils.loadModulesFrom(yangPath); assertEquals(modulesNumber, modules.size()); Module module = TestUtils.resolveModule(moduleName, modules); + searchedModuleName = module == null ? "" : module.getName(); assertNotNull(module); - dataSchemaNode = TestUtils.resolveDataSchemaNode(module, dataSchemaName); + dataSchemaNode = TestUtils.resolveDataSchemaNode(dataSchemaName, module); + searchedDataSchemaName = dataSchemaNode == null ? "" : dataSchemaNode.getQName().getLocalName(); assertNotNull(dataSchemaNode); + schemaNodePath = searchedModuleName + ":" + searchedDataSchemaName; } } diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/xml/to/cnsn/test/XmlLeafrefToCnSnTest.java b/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/xml/to/cnsn/test/XmlLeafrefToCnSnTest.java new file mode 100644 index 0000000000..beff5724eb --- /dev/null +++ b/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/xml/to/cnsn/test/XmlLeafrefToCnSnTest.java @@ -0,0 +1,351 @@ +package org.opendaylight.controller.sal.restconf.impl.xml.to.cnsn.test; + +import static org.junit.Assert.*; + +import java.util.List; +import java.util.Set; + +import org.junit.Test; +import org.opendaylight.controller.sal.rest.impl.XmlToCompositeNodeProvider; +import org.opendaylight.controller.sal.restconf.impl.test.TestUtils; +import org.opendaylight.yangtools.yang.common.QName; +import org.opendaylight.yangtools.yang.data.api.*; +import org.opendaylight.yangtools.yang.model.api.Module; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class XmlLeafrefToCnSnTest { + private static final Logger LOG = LoggerFactory.getLogger(XmlLeafrefToCnSnTest.class); + + /** + * top level element represents container. second level element is list with + * two elements. + */ + @Test + public void testXmlDataContainer() { + CompositeNode compNode = TestUtils.readInputToCnSn("/xml-to-cnsn/data-container.xml", false, + XmlToCompositeNodeProvider.INSTANCE); + assertNotNull(compNode); + Set modules = TestUtils.loadModulesFrom("/xml-to-cnsn/data-container-yang"); + + assertNotNull(modules); + TestUtils.normalizeCompositeNode(compNode, modules, "data-container-yang:cont"); + + String nameSpace = "data:container:yang"; + assertEquals(nameSpace, compNode.getNodeType().getNamespace().toString()); + + verifyNullAndEmptyStringSingleNode(compNode, nameSpace); + verifyCommonPartAOfXml(compNode, "", nameSpace); + } + + private void verifyNullAndEmptyStringSingleNode(CompositeNode compNode, String nameSpace) { + assertEquals("cont", compNode.getNodeType().getLocalName()); + + SimpleNode lf2 = null; + SimpleNode lf3 = null; + int found = 0; + for (Node child : compNode.getChildren()) { + if (found == 0x3) + break; + if (child instanceof SimpleNode) { + SimpleNode childSimple = (SimpleNode) child; + if (childSimple.getNodeType().getLocalName().equals("lf3")) { + lf3 = childSimple; + found = found | (1 << 0); + } else if (childSimple.getNodeType().getLocalName().equals("lf2")) { + lf2 = childSimple; + found = found | (1 << 1); + } + } + assertEquals(nameSpace, child.getNodeType().getNamespace().toString()); + } + + assertEquals("", lf2.getValue()); + assertEquals(null, lf3.getValue()); + } + + @Test + public void testXmlDataList() { + CompositeNode compNode = TestUtils.readInputToCnSn("/xml-to-cnsn/data-list.xml", false, + XmlToCompositeNodeProvider.INSTANCE); + assertNotNull(compNode); + + Set modules = TestUtils.loadModulesFrom("/xml-to-cnsn/data-list-yang"); + assertNotNull(modules); + + TestUtils.normalizeCompositeNode(compNode, modules, "data-container-yang:cont"); + + String nameSpaceList = "data:list:yang"; + String nameSpaceCont = "data:container:yang"; + assertEquals(nameSpaceCont, compNode.getNodeType().getNamespace().toString()); + assertEquals("cont", compNode.getNodeType().getLocalName()); + assertEquals(3, compNode.getChildren().size()); + CompositeNode lst1_1 = null; + CompositeNode lst1_2 = null; + int loopCount = 0; + for (Node node : compNode.getChildren()) { + if (node.getNodeType().getLocalName().equals("lf1")) { + assertEquals(nameSpaceList, node.getNodeType().getNamespace().toString()); + assertTrue(node instanceof SimpleNode); + assertEquals("lf1", node.getValue()); + } else { + assertTrue(node instanceof CompositeNode); + switch (loopCount++) { + case 0: + lst1_1 = (CompositeNode) node; + break; + case 1: + lst1_2 = (CompositeNode) node; + break; + } + assertEquals(nameSpaceCont, node.getNodeType().getNamespace().toString()); + } + } + // lst1_1 + verifyCommonPartAOfXml(lst1_1, "1", nameSpaceCont); + // :lst1_1 + + // lst1_2 + SimpleNode lflst11 = null; + CompositeNode cont11 = null; + for (Node node : lst1_2.getChildren()) { + String nodeName = node.getNodeType().getLocalName(); + if (nodeName.equals("lflst11")) { + assertTrue(node instanceof SimpleNode); + lflst11 = (SimpleNode) node; + + } else if (nodeName.equals("cont11")) { + assertTrue(node instanceof CompositeNode); + cont11 = (CompositeNode) node; + } + assertEquals(nameSpaceCont, compNode.getNodeType().getNamespace().toString()); + } + assertEquals("221", lflst11.getValue()); + + assertEquals(1, cont11.getChildren().size()); + assertTrue(cont11.getChildren().get(0) instanceof SimpleNode); + SimpleNode cont11_lf111 = (SimpleNode) cont11.getChildren().get(0); + assertEquals(nameSpaceCont, cont11_lf111.getNodeType().getNamespace().toString()); + assertEquals("lf111", cont11_lf111.getNodeType().getLocalName()); + assertEquals((short) 100, cont11_lf111.getValue()); + // :lst1_2 + + } + + @Test + public void testXmlEmptyData() { + CompositeNode compNode = TestUtils.readInputToCnSn("/xml-to-cnsn/empty-data.xml", true, + XmlToCompositeNodeProvider.INSTANCE); + assertEquals("cont", compNode.getNodeType().getLocalName()); + SimpleNode lf1 = null; + SimpleNode lflst1_1 = null; + SimpleNode lflst1_2 = null; + CompositeNode lst1 = null; + int lflst1Count = 0; + for (Node node : compNode.getChildren()) { + if (node.getNodeType().getLocalName().equals("lf1")) { + assertTrue(node instanceof SimpleNode); + lf1 = (SimpleNode) node; + } else if (node.getNodeType().getLocalName().equals("lflst1")) { + assertTrue(node instanceof SimpleNode); + + switch (lflst1Count++) { + case 0: + lflst1_1 = (SimpleNode) node; + break; + case 1: + lflst1_2 = (SimpleNode) node; + break; + } + } else if (node.getNodeType().getLocalName().equals("lst1")) { + assertTrue(node instanceof CompositeNode); + lst1 = (CompositeNode) node; + } + } + + assertNotNull(lf1); + assertNotNull(lflst1_1); + assertNotNull(lflst1_2); + assertNotNull(lst1); + + assertEquals("", lf1.getValue()); + assertEquals("", lflst1_1.getValue()); + assertEquals("", lflst1_2.getValue()); + assertEquals(1, lst1.getChildren().size()); + assertEquals("lf11", lst1.getChildren().get(0).getNodeType().getLocalName()); + + assertTrue(lst1.getChildren().get(0) instanceof SimpleNode); + assertEquals("", lst1.getChildren().get(0).getValue()); + + } + + /** + * Test case like this x:identity + */ + @Test + public void testIdentityrefNmspcInElement() { + testIdentityrefToCnSn("/xml-to-cnsn/identityref/xml/data-nmspc-in-element.xml", "/xml-to-cnsn/identityref", + "identityref-module", "cont", 2, "iden", "identity:module"); + } + + /** + * + * Test case like identity + */ + + @Test + public void testIdentityrefDefaultNmspcInElement() { + testIdentityrefToCnSn("/xml-to-cnsn/identityref/xml/data-default-nmspc-in-element.xml", + "/xml-to-cnsn/identityref/yang-augments", "general-module", "cont", 3, "iden", "identityref:module"); + } + + /** + * + * Test case like identity + */ + @Test + public void testIdentityrefDefaultNmspcInParrentElement() { + testIdentityrefToCnSn("/xml-to-cnsn/identityref/xml/data-default-nmspc-in-parrent-element.xml", + "/xml-to-cnsn/identityref", "identityref-module", "cont", 2, "iden", "identityref:module"); + } + + /** + * + * Test case like + * x:identity + */ + @Test + public void testIdentityrefNmspcInParrentElement() { + testIdentityrefToCnSn("/xml-to-cnsn/identityref/xml/data-nmspc-in-parrent-element.xml", + "/xml-to-cnsn/identityref", "identityref-module", "cont", 2, "iden", "z:namespace"); + + } + + /** + * + * Test case like (without namespace in xml) x:identity + * + */ + @Test + public void testIdentityrefNoNmspcValueWithPrefix() { + testIdentityrefToCnSn("/xml-to-cnsn/identityref/xml/data-no-nmspc-value-with-prefix.xml", + "/xml-to-cnsn/identityref", "identityref-module", "cont", 2, "x:iden", "identityref:module"); + } + + /** + * + * Test case like (without namespace in xml) identity + * + */ + @Test + public void testIdentityrefNoNmspcValueWithoutPrefix() { + testIdentityrefToCnSn("/xml-to-cnsn/identityref/xml/data-no-nmspc-value-without-prefix.xml", + "/xml-to-cnsn/identityref", "identityref-module", "cont", 2, "iden", "identityref:module"); + } + + private void verifyCommonPartAOfXml(CompositeNode compNode, String suf, String nameSpace) { + SimpleNode lf1suf = null; + SimpleNode lflst1suf_1 = null; + SimpleNode lflst1suf_2 = null; + SimpleNode lflst1suf_3 = null; + CompositeNode cont1suf = null; + CompositeNode lst1suf = null; + + int lflstCount = 0; + + for (Node node : compNode.getChildren()) { + String localName = node.getNodeType().getLocalName(); + if (localName.equals("lf1" + suf)) { + assertTrue(node instanceof SimpleNode); + lf1suf = (SimpleNode) node; + } else if (localName.equals("lflst1" + suf)) { + assertTrue(node instanceof SimpleNode); + switch (lflstCount++) { + case 0: + lflst1suf_1 = (SimpleNode) node; + break; + case 1: + lflst1suf_2 = (SimpleNode) node; + break; + case 2: + lflst1suf_3 = (SimpleNode) node; + break; + } + } else if (localName.equals("lst1" + suf)) { + assertTrue(node instanceof CompositeNode); + lst1suf = (CompositeNode) node; + } else if (localName.equals("cont1" + suf)) { + assertTrue(node instanceof CompositeNode); + cont1suf = (CompositeNode) node; + } + assertEquals(nameSpace, node.getNodeType().getNamespace().toString()); + } + + assertNotNull(lf1suf); + assertNotNull(lflst1suf_1); + assertNotNull(lflst1suf_2); + assertNotNull(lflst1suf_3); + assertNotNull(lst1suf); + assertNotNull(cont1suf); + + assertEquals("str0", lf1suf.getValue()); + assertEquals("121", lflst1suf_1.getValue()); + assertEquals("131", lflst1suf_2.getValue()); + assertEquals("str1", lflst1suf_3.getValue()); + + assertEquals(1, lst1suf.getChildren().size()); + + assertTrue(lst1suf.getChildren().get(0) instanceof SimpleNode); + SimpleNode lst11_lf11 = (SimpleNode) lst1suf.getChildren().get(0); + assertEquals(nameSpace, lst11_lf11.getNodeType().getNamespace().toString()); + assertEquals("lf11" + suf, lst11_lf11.getNodeType().getLocalName()); + assertEquals("str2", lst11_lf11.getValue()); + + assertTrue(cont1suf.getChildren().get(0) instanceof SimpleNode); + SimpleNode cont1_lf11 = (SimpleNode) cont1suf.getChildren().get(0); + assertEquals(nameSpace, cont1_lf11.getNodeType().getNamespace().toString()); + assertEquals("lf11" + suf, cont1_lf11.getNodeType().getLocalName()); + assertEquals((short) 100, cont1_lf11.getValue()); + } + + private void testIdentityrefToCnSn(String xmlPath, String yangPath, String moduleName, String schemaName, + int moduleCount, String resultLocalName, String resultNamespace) { + CompositeNode compositeNode = TestUtils.readInputToCnSn(xmlPath, false, XmlToCompositeNodeProvider.INSTANCE); + assertNotNull(compositeNode); + + Set modules = TestUtils.loadModulesFrom(yangPath); + assertEquals(moduleCount, modules.size()); + + TestUtils.normalizeCompositeNode(compositeNode, modules, moduleName + ":" + schemaName); + + SimpleNode lf11 = getLf11(compositeNode); + assertTrue(lf11.getValue() instanceof QName); + QName qName = (QName) lf11.getValue(); + assertEquals(resultLocalName, qName.getLocalName()); + assertEquals(resultNamespace, qName.getNamespace().toString()); + } + + private SimpleNode getLf11(CompositeNode compositeNode) { + assertEquals("cont", compositeNode.getNodeType().getLocalName()); + + List> childs = compositeNode.getChildren(); + assertEquals(1, childs.size()); + Node nd = childs.iterator().next(); + assertTrue(nd instanceof CompositeNode); + assertEquals("cont1", nd.getNodeType().getLocalName()); + + childs = ((CompositeNode) nd).getChildren(); + SimpleNode lf11 = null; + for (Node child : childs) { + assertTrue(child instanceof SimpleNode); + if (child.getNodeType().getLocalName().equals("lf11")) { + lf11 = (SimpleNode) child; + } + } + assertNotNull(lf11); + return lf11; + } + +} diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/xml/to/cnsn/test/XmlToCnSnTest.java b/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/xml/to/cnsn/test/XmlToCnSnTest.java index 50ab0857b7..7c7df56133 100644 --- a/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/xml/to/cnsn/test/XmlToCnSnTest.java +++ b/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/xml/to/cnsn/test/XmlToCnSnTest.java @@ -2,391 +2,43 @@ package org.opendaylight.controller.sal.restconf.impl.xml.to.cnsn.test; import static org.junit.Assert.*; -import java.io.*; -import java.net.URISyntaxException; -import java.util.List; -import java.util.Set; - -import javax.ws.rs.WebApplicationException; - +import org.junit.BeforeClass; import org.junit.Test; import org.opendaylight.controller.sal.rest.impl.XmlToCompositeNodeProvider; -import org.opendaylight.controller.sal.restconf.impl.CompositeNodeWrapper; import org.opendaylight.controller.sal.restconf.impl.test.TestUtils; -import org.opendaylight.yangtools.yang.common.QName; +import org.opendaylight.controller.sal.restconf.impl.test.YangAndXmlAndDataSchemaLoader; import org.opendaylight.yangtools.yang.data.api.*; -import org.opendaylight.yangtools.yang.model.api.DataSchemaNode; -import org.opendaylight.yangtools.yang.model.api.Module; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -public class XmlToCnSnTest { - private static final Logger LOG = LoggerFactory.getLogger(XmlToCnSnTest.class); - - /** - * top level element represents container. second level element is list with - * two elements. - */ - @Test - public void testXmlDataContainer() { - CompositeNode compNode = compositeNodeFromXml("/xml-to-cnsn/data-container.xml", false); - assertNotNull(compNode); - DataSchemaNode dataSchemaNode = null; - try { - dataSchemaNode = TestUtils.obtainSchemaFromYang("/xml-to-cnsn/data-container-yang"); - } catch (FileNotFoundException e) { - LOG.error(e.getMessage()); - assertTrue(false); - } - - assertNotNull(dataSchemaNode); - TestUtils.supplementNamespace(dataSchemaNode, compNode); - - String nameSpace = "data:container:yang"; - assertEquals(nameSpace, compNode.getNodeType().getNamespace().toString()); - - verifyNullAndEmptyStringSingleNode(compNode, nameSpace); - verifyCommonPartAOfXml(compNode, "", nameSpace); - } - - private void verifyNullAndEmptyStringSingleNode(CompositeNode compNode, String nameSpace) { - assertEquals("cont", compNode.getNodeType().getLocalName()); - SimpleNode lf2 = null; - SimpleNode lf3 = null; - int found = 0; - for (Node child : compNode.getChildren()) { - if (found == 0x3) - break; - if (child instanceof SimpleNode) { - SimpleNode childSimple = (SimpleNode) child; - if (childSimple.getNodeType().getLocalName().equals("lf3")) { - lf3 = childSimple; - found = found | (1 << 0); - } else if (childSimple.getNodeType().getLocalName().equals("lf2")) { - lf2 = childSimple; - found = found | (1 << 1); - } - } - assertEquals(nameSpace, child.getNodeType().getNamespace().toString()); - } +public class XmlToCnSnTest extends YangAndXmlAndDataSchemaLoader { - assertEquals("", lf2.getValue()); - assertEquals(null, lf3.getValue()); + @BeforeClass + public static void initialize() { + dataLoad("/xml-to-cnsn/leafref"); } @Test - public void testXmlDataList() { - CompositeNode compNode = compositeNodeFromXml("/xml-to-cnsn/data-list.xml", false); - assertNotNull(compNode); - - DataSchemaNode dataSchemaNode = null; - try { - dataSchemaNode = TestUtils.obtainSchemaFromYang("/xml-to-cnsn/data-list-yang", "data-container-yang"); - } catch (FileNotFoundException e) { - LOG.error(e.getMessage()); - } + public void testXmlLeafrefToCnSn() { + CompositeNode compositeNode = TestUtils.readInputToCnSn("/xml-to-cnsn/leafref/xml/data.xml", false, + XmlToCompositeNodeProvider.INSTANCE); + assertNotNull(compositeNode); assertNotNull(dataSchemaNode); - TestUtils.supplementNamespace(dataSchemaNode, compNode); - - String nameSpaceList = "data:list:yang"; - String nameSpaceCont = "data:container:yang"; - assertEquals(nameSpaceCont, compNode.getNodeType().getNamespace().toString()); - assertEquals("cont", compNode.getNodeType().getLocalName()); - assertEquals(3, compNode.getChildren().size()); - CompositeNode lst1_1 = null; - CompositeNode lst1_2 = null; - int loopCount = 0; - for (Node node : compNode.getChildren()) { - if (node.getNodeType().getLocalName().equals("lf1")) { - assertEquals(nameSpaceList, node.getNodeType().getNamespace().toString()); - assertTrue(node instanceof SimpleNode); - assertEquals("lf1", node.getValue()); - } else { - assertTrue(node instanceof CompositeNode); - switch (loopCount++) { - case 0: - lst1_1 = (CompositeNode) node; - break; - case 1: - lst1_2 = (CompositeNode) node; - break; - } - assertEquals(nameSpaceCont, node.getNodeType().getNamespace().toString()); - } - } - // lst1_1 - verifyCommonPartAOfXml(lst1_1, "1", nameSpaceCont); - // :lst1_1 - - // lst1_2 - SimpleNode lflst11 = null; - CompositeNode cont11 = null; - for (Node node : lst1_2.getChildren()) { - String nodeName = node.getNodeType().getLocalName(); - if (nodeName.equals("lflst11")) { - assertTrue(node instanceof SimpleNode); - lflst11 = (SimpleNode) node; - - } else if (nodeName.equals("cont11")) { - assertTrue(node instanceof CompositeNode); - cont11 = (CompositeNode) node; - } - assertEquals(nameSpaceCont, compNode.getNodeType().getNamespace().toString()); - } - assertEquals("221", lflst11.getValue()); - - assertEquals(1, cont11.getChildren().size()); - assertTrue(cont11.getChildren().get(0) instanceof SimpleNode); - SimpleNode cont11_lf111 = (SimpleNode) cont11.getChildren().get(0); - assertEquals(nameSpaceCont, cont11_lf111.getNodeType().getNamespace().toString()); - assertEquals("lf111", cont11_lf111.getNodeType().getLocalName()); - assertEquals((short) 100, cont11_lf111.getValue()); - // :lst1_2 - - } - - @Test - public void testXmlEmptyData() { - CompositeNode compNode = compositeNodeFromXml("/xml-to-cnsn/empty-data.xml", true); - assertEquals("cont", compNode.getNodeType().getLocalName()); - SimpleNode lf1 = null; - SimpleNode lflst1_1 = null; - SimpleNode lflst1_2 = null; - CompositeNode lst1 = null; - int lflst1Count = 0; - for (Node node : compNode.getChildren()) { - if (node.getNodeType().getLocalName().equals("lf1")) { - assertTrue(node instanceof SimpleNode); - lf1 = (SimpleNode) node; - } else if (node.getNodeType().getLocalName().equals("lflst1")) { - assertTrue(node instanceof SimpleNode); - - switch (lflst1Count++) { - case 0: - lflst1_1 = (SimpleNode) node; - break; - case 1: - lflst1_2 = (SimpleNode) node; - break; - } - } else if (node.getNodeType().getLocalName().equals("lst1")) { - assertTrue(node instanceof CompositeNode); - lst1 = (CompositeNode) node; - } - } - - assertNotNull(lf1); - assertNotNull(lflst1_1); - assertNotNull(lflst1_2); - assertNotNull(lst1); - - assertEquals("", lf1.getValue()); - assertEquals("", lflst1_1.getValue()); - assertEquals("", lflst1_2.getValue()); - assertEquals(1, lst1.getChildren().size()); - assertEquals("lf11", lst1.getChildren().get(0).getNodeType().getLocalName()); - - assertTrue(lst1.getChildren().get(0) instanceof SimpleNode); - assertEquals("", lst1.getChildren().get(0).getValue()); - - } - - /** - * Test case like this x:identity - */ - @Test - public void testIdentityrefNmspcInElement() { - testIdentityrefToCnSn("/xml-to-cnsn/identityref/xml/data-nmspc-in-element.xml", "/xml-to-cnsn/identityref", - "identityref-module", "cont", 2, "iden", "identity:module"); - } + TestUtils.normalizeCompositeNode(compositeNode, modules, schemaNodePath); - /** - * - * Test case like identity - */ - - @Test - public void testIdentityrefDefaultNmspcInElement() { - testIdentityrefToCnSn("/xml-to-cnsn/identityref/xml/data-default-nmspc-in-element.xml", - "/xml-to-cnsn/identityref/yang-augments", "general-module", "cont", 3, "iden", "identityref:module"); - } - - /** - * - * Test case like identity - */ - @Test - public void testIdentityrefDefaultNmspcInParrentElement() { - testIdentityrefToCnSn("/xml-to-cnsn/identityref/xml/data-default-nmspc-in-parrent-element.xml", - "/xml-to-cnsn/identityref", "identityref-module", "cont", 2, "iden", "identityref:module"); - } - - /** - * - * Test case like - * x:identity - */ - @Test - public void testIdentityrefNmspcInParrentElement() { - testIdentityrefToCnSn("/xml-to-cnsn/identityref/xml/data-nmspc-in-parrent-element.xml", - "/xml-to-cnsn/identityref", "identityref-module", "cont", 2, "iden", "z:namespace"); - - } - - /** - * - * Test case like (without namespace in xml) x:identity - * - */ - @Test - public void testIdentityrefNoNmspcValueWithPrefix() { - testIdentityrefToCnSn("/xml-to-cnsn/identityref/xml/data-no-nmspc-value-with-prefix.xml", - "/xml-to-cnsn/identityref", "identityref-module", "cont", 2, "x:iden", "identityref:module"); - } - - /** - * - * Test case like (without namespace in xml) identity - * - */ - @Test - public void testIdentityrefNoNmspcValueWithoutPrefix() { - testIdentityrefToCnSn("/xml-to-cnsn/identityref/xml/data-no-nmspc-value-without-prefix.xml", - "/xml-to-cnsn/identityref", "identityref-module", "cont", 2, "iden", "identityref:module"); - } - - private void verifyCommonPartAOfXml(CompositeNode compNode, String suf, String nameSpace) { - SimpleNode lf1suf = null; - SimpleNode lflst1suf_1 = null; - SimpleNode lflst1suf_2 = null; - SimpleNode lflst1suf_3 = null; - CompositeNode cont1suf = null; - CompositeNode lst1suf = null; - - int lflstCount = 0; + assertEquals("cont", compositeNode.getNodeType().getLocalName()); - for (Node node : compNode.getChildren()) { - String localName = node.getNodeType().getLocalName(); - if (localName.equals("lf1" + suf)) { - assertTrue(node instanceof SimpleNode); - lf1suf = (SimpleNode) node; - } else if (localName.equals("lflst1" + suf)) { - assertTrue(node instanceof SimpleNode); - switch (lflstCount++) { - case 0: - lflst1suf_1 = (SimpleNode) node; - break; - case 1: - lflst1suf_2 = (SimpleNode) node; - break; - case 2: - lflst1suf_3 = (SimpleNode) node; + SimpleNode lf2 = null; + for (Node childNode : compositeNode.getChildren()) { + if (childNode instanceof SimpleNode) { + if (childNode.getNodeType().getLocalName().equals("lf2")) { + lf2 = (SimpleNode) childNode; break; } - } else if (localName.equals("lst1" + suf)) { - assertTrue(node instanceof CompositeNode); - lst1suf = (CompositeNode) node; - } else if (localName.equals("cont1" + suf)) { - assertTrue(node instanceof CompositeNode); - cont1suf = (CompositeNode) node; } - assertEquals(nameSpace, node.getNodeType().getNamespace().toString()); } - assertNotNull(lf1suf); - assertNotNull(lflst1suf_1); - assertNotNull(lflst1suf_2); - assertNotNull(lflst1suf_3); - assertNotNull(lst1suf); - assertNotNull(cont1suf); - - assertEquals("str0", lf1suf.getValue()); - assertEquals("121", lflst1suf_1.getValue()); - assertEquals("131", lflst1suf_2.getValue()); - assertEquals("str1", lflst1suf_3.getValue()); - - assertEquals(1, lst1suf.getChildren().size()); - - assertTrue(lst1suf.getChildren().get(0) instanceof SimpleNode); - SimpleNode lst11_lf11 = (SimpleNode) lst1suf.getChildren().get(0); - assertEquals(nameSpace, lst11_lf11.getNodeType().getNamespace().toString()); - assertEquals("lf11" + suf, lst11_lf11.getNodeType().getLocalName()); - assertEquals("str2", lst11_lf11.getValue()); - - assertTrue(cont1suf.getChildren().get(0) instanceof SimpleNode); - SimpleNode cont1_lf11 = (SimpleNode) cont1suf.getChildren().get(0); - assertEquals(nameSpace, cont1_lf11.getNodeType().getNamespace().toString()); - assertEquals("lf11" + suf, cont1_lf11.getNodeType().getLocalName()); - assertEquals((short) 100, cont1_lf11.getValue()); - } - - private CompositeNode compositeNodeFromXml(String xmlPath, boolean dummyNamespaces) { - XmlToCompositeNodeProvider xmlToCompositeNodeProvider = XmlToCompositeNodeProvider.INSTANCE; - try { - InputStream xmlStream = XmlToCnSnTest.class.getResourceAsStream(xmlPath); - CompositeNode compositeNode = xmlToCompositeNodeProvider.readFrom(null, null, null, null, null, xmlStream); - if (dummyNamespaces) { - try { - TestUtils.addDummyNamespaceToAllNodes((CompositeNodeWrapper) compositeNode); - return ((CompositeNodeWrapper) compositeNode).unwrap(); - } catch (URISyntaxException e) { - LOG.error(e.getMessage()); - assertTrue(e.getMessage(), false); - } - } - return compositeNode; - - } catch (WebApplicationException | IOException e) { - LOG.error(e.getMessage()); - assertTrue(false); - } - return null; - } - - private void testIdentityrefToCnSn(String xmlPath, String yangPath, String moduleName, String schemaName, - int moduleCount, String resultLocalName, String resultNamespace) { - CompositeNode compositeNode = compositeNodeFromXml(xmlPath, false); - assertNotNull(compositeNode); - - Set modules = TestUtils.resolveModules(yangPath); - assertEquals(moduleCount, modules.size()); - Module module = TestUtils.resolveModule(moduleName, modules); - assertNotNull(module); - DataSchemaNode dataSchemaNode = TestUtils.resolveDataSchemaNode(module, null); - assertNotNull(dataSchemaNode); - - TestUtils.normalizeCompositeNode(compositeNode, modules, dataSchemaNode, moduleName + ":" + schemaName); - - SimpleNode lf11 = getLf11(compositeNode); - assertTrue(lf11.getValue() instanceof QName); - QName qName = (QName) lf11.getValue(); - assertEquals(resultLocalName, qName.getLocalName()); - assertEquals(resultNamespace, qName.getNamespace().toString()); - - } - - private SimpleNode getLf11(CompositeNode compositeNode) { - assertEquals("cont", compositeNode.getNodeType().getLocalName()); - - List> childs = compositeNode.getChildren(); - assertEquals(1, childs.size()); - Node nd = childs.iterator().next(); - assertTrue(nd instanceof CompositeNode); - assertEquals("cont1", nd.getNodeType().getLocalName()); - - childs = ((CompositeNode) nd).getChildren(); - SimpleNode lf11 = null; - for (Node child : childs) { - assertTrue(child instanceof SimpleNode); - if (child.getNodeType().getLocalName().equals("lf11")) { - lf11 = (SimpleNode) child; - } - } - assertNotNull(lf11); - return lf11; + assertNotNull(lf2); + assertTrue(lf2.getValue() instanceof String); + assertEquals("121", (String) lf2.getValue()); } } diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/resources/cnsn-to-json/invalid-top-level-element/invalid-top-level-element.yang b/opendaylight/md-sal/sal-rest-connector/src/test/resources/cnsn-to-json/invalid-top-level-element/invalid-top-level-element.yang new file mode 100644 index 0000000000..a9df486b13 --- /dev/null +++ b/opendaylight/md-sal/sal-rest-connector/src/test/resources/cnsn-to-json/invalid-top-level-element/invalid-top-level-element.yang @@ -0,0 +1,13 @@ +module invalid-top-level-element { + namespace "invalid:top:level:element"; + + prefix "intoleel"; + revision 2013-12-17 { + } + + + leaf lf { + type string; + } + +} \ No newline at end of file diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/resources/cnsn-to-json/list/list-types-module b/opendaylight/md-sal/sal-rest-connector/src/test/resources/cnsn-to-json/list/list-types-module new file mode 100644 index 0000000000..9bdea81579 --- /dev/null +++ b/opendaylight/md-sal/sal-rest-connector/src/test/resources/cnsn-to-json/list/list-types-module @@ -0,0 +1,274 @@ +module simple-data-types { + namespace "simple:data:types"; + + prefix "smpdtp"; + revision 2013-11-12 { + } + + identity iden { + } + + typedef tpdfempty { + type empty; + } + + typedef tpdfbit { + type bits { + bit b1; + bit b2; + bit b3; + } + } + + typedef tpdfun4 { + type boolean; + } + + typedef tpdfun3 { + type union { + type tpdfbit; + type tpdfempty; + } + } + + typedef tpdfun2 { + type union { + type tpdfun3; + type tpdfun4; + } + } + + typedef tpdfun1 { + type union { + type uint8; + type decimal64 { + fraction-digits 2; + } + } + } + + container cont { + leaf lfnint8Min { + type int8; + } + leaf lfnint8Max { + type int8; + } + leaf lfnint16Min { + type int16; + } + leaf lfnint16Max { + type int16; + } + leaf lfnint32Min { + type int32; + } + leaf lfnint32Max { + type int32; + } + leaf lfnint64Min { + type int64; + } + leaf lfnint64Max { + type int64; + } + + leaf lfnuint8Max { + type uint8; + } + leaf lfnuint16Max { + type uint16; + } + leaf lfnuint32Max { + type uint32; + } + leaf lfuint64Max { + type uint64; + } + leaf lfstr { + type string; + } + leaf lfstr1 { + type string; + } + leaf lfbool1 { + type boolean; + } + leaf lfbool2 { + type boolean; + } + leaf lfbool3 { + type boolean; + } + leaf lfdecimal1 { + type decimal64 { + fraction-digits 2; + } + } + leaf lfdecimal2 { + type decimal64 { + fraction-digits 2; + } + } + leaf lfdecimal3 { + type decimal64 { + fraction-digits 2; + } + } + + leaf lfdecimal4 { + type decimal64 { + fraction-digits 2; + } + } + + + leaf lfdecimal6 { + type decimal64 { + fraction-digits 2; + } + } + + leaf lfenum { + type enumeration { + enum enum1; + enum enum2; + enum enum3; + enum enum4; + } + } + + leaf lfbits { + type bits { + bit bit1; + bit bit2; + bit bit3; + bit bit4; + } + } + + leaf lfbinary { + type binary; + } + + leaf lfref1 { //reference to string type + type leafref { + path "../lfstr"; + } + } + + leaf lfref2 { //reference to number type + type leafref { + path "../lfnint8Max"; + } + } + + leaf lfempty { + type empty; + } + + leaf lfunion1 { + type union { + type uint16; + type string; + } + } + leaf lfunion2 { + type union { + type decimal64 { + fraction-digits 2; + } + type string; + } + } + + leaf lfunion3 { + type union { + type empty; + type string; + } + } + + leaf lfunion4 { + type union { + type boolean; + type string; + } + } + + leaf lfunion5 { + type union { + type uint16; + type string; + } + } + + leaf lfunion6 { + type union { + type uint16; + type empty; + } + } + + leaf lfunion7 { + type tpdfun3; + } + + leaf lfunion8 { + type union { + type uint16; + type string; + } + } + + leaf lfunion9 { + type union { + type uint16; + type boolean; + } + } + + leaf lfunion10 { + type union { + type bits { + bit bt1; + bit bt2; + } + type boolean; + } + } + + leaf lfunion11 { + type union { + type tpdfun1; + type tpdfun2; + } + } + + leaf lfunion12 { + type tpdfun2; + } + + leaf lfunion13 { + type tpdfbit; + } + + leaf lfunion14 { + type union { + type enumeration { + enum zero; + enum one; + } + type uint16; + } + } + + leaf identityref1 { + type identityref { + base iden; + } + } + + + } +} \ No newline at end of file diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/resources/cnsn-to-xml/choice/module-with-choice.yang b/opendaylight/md-sal/sal-rest-connector/src/test/resources/cnsn-to-xml/choice/module-with-choice.yang new file mode 100644 index 0000000000..84547847ee --- /dev/null +++ b/opendaylight/md-sal/sal-rest-connector/src/test/resources/cnsn-to-xml/choice/module-with-choice.yang @@ -0,0 +1,25 @@ +module module-with-choice { + namespace "module:with:choice"; + + prefix "mowicho"; + + revision 2013-12-18 { + } + + + container cont { + choice choA { + case caA1 { + leaf lf1 { + type string; + } + } + case caA2 { + leaf lf2 { + type string; + } + } + } + } + +} \ No newline at end of file diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/resources/cnsn-to-xml/yang/basic-module.yang b/opendaylight/md-sal/sal-rest-connector/src/test/resources/cnsn-to-xml/yang/basic-module.yang index 7023c94f2f..81d77329c6 100644 --- a/opendaylight/md-sal/sal-rest-connector/src/test/resources/cnsn-to-xml/yang/basic-module.yang +++ b/opendaylight/md-sal/sal-rest-connector/src/test/resources/cnsn-to-xml/yang/basic-module.yang @@ -91,6 +91,12 @@ module basic-module { } } + leaf lfLfref { + type leafref { + path "/cont/lfBoolean"; + } + } + } } \ No newline at end of file diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/resources/json-to-cnsn/leafref/json/data.json b/opendaylight/md-sal/sal-rest-connector/src/test/resources/json-to-cnsn/leafref/json/data.json new file mode 100644 index 0000000000..235666eed4 --- /dev/null +++ b/opendaylight/md-sal/sal-rest-connector/src/test/resources/json-to-cnsn/leafref/json/data.json @@ -0,0 +1,6 @@ +{ + "cont":{ + "lf1":121, + "lf2":121 + } +} \ No newline at end of file diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/resources/json-to-cnsn/leafref/leafref-module b/opendaylight/md-sal/sal-rest-connector/src/test/resources/json-to-cnsn/leafref/leafref-module new file mode 100644 index 0000000000..8ca9f09096 --- /dev/null +++ b/opendaylight/md-sal/sal-rest-connector/src/test/resources/json-to-cnsn/leafref/leafref-module @@ -0,0 +1,19 @@ +module leafref-module { + namespace "leafref:module"; + + prefix "lfrfmo"; + revision 2013-11-18 { + } + + container cont { + leaf lf1 { + type int32; + } + leaf lf2 { + type leafref { + path "/cont/lf1"; + } + } + } + +} \ No newline at end of file diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/resources/json-to-cnsn/simple-list-yang/simple-list1.yang b/opendaylight/md-sal/sal-rest-connector/src/test/resources/json-to-cnsn/simple-list-yang/1/simple-list1.yang similarity index 100% rename from opendaylight/md-sal/sal-rest-connector/src/test/resources/json-to-cnsn/simple-list-yang/simple-list1.yang rename to opendaylight/md-sal/sal-rest-connector/src/test/resources/json-to-cnsn/simple-list-yang/1/simple-list1.yang diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/resources/json-to-cnsn/simple-list-yang/simple-list2.yang b/opendaylight/md-sal/sal-rest-connector/src/test/resources/json-to-cnsn/simple-list-yang/2/simple-list2.yang similarity index 100% rename from opendaylight/md-sal/sal-rest-connector/src/test/resources/json-to-cnsn/simple-list-yang/simple-list2.yang rename to opendaylight/md-sal/sal-rest-connector/src/test/resources/json-to-cnsn/simple-list-yang/2/simple-list2.yang diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/resources/json-to-cnsn/unsupported-json-format.json b/opendaylight/md-sal/sal-rest-connector/src/test/resources/json-to-cnsn/unsupported-json-format.json new file mode 100644 index 0000000000..abc626739e --- /dev/null +++ b/opendaylight/md-sal/sal-rest-connector/src/test/resources/json-to-cnsn/unsupported-json-format.json @@ -0,0 +1 @@ +fffff \ No newline at end of file diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/resources/xml-to-cnsn/leafref/leafref-module b/opendaylight/md-sal/sal-rest-connector/src/test/resources/xml-to-cnsn/leafref/leafref-module new file mode 100644 index 0000000000..8ca9f09096 --- /dev/null +++ b/opendaylight/md-sal/sal-rest-connector/src/test/resources/xml-to-cnsn/leafref/leafref-module @@ -0,0 +1,19 @@ +module leafref-module { + namespace "leafref:module"; + + prefix "lfrfmo"; + revision 2013-11-18 { + } + + container cont { + leaf lf1 { + type int32; + } + leaf lf2 { + type leafref { + path "/cont/lf1"; + } + } + } + +} \ No newline at end of file diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/resources/xml-to-cnsn/leafref/xml/data.xml b/opendaylight/md-sal/sal-rest-connector/src/test/resources/xml-to-cnsn/leafref/xml/data.xml new file mode 100644 index 0000000000..06200a69b5 --- /dev/null +++ b/opendaylight/md-sal/sal-rest-connector/src/test/resources/xml-to-cnsn/leafref/xml/data.xml @@ -0,0 +1,4 @@ + + 121 + 121 + \ No newline at end of file diff --git a/opendaylight/md-sal/statistics-manager/src/main/java/org/opendaylight/controller/md/statistics/manager/StatisticsUpdateCommiter.java b/opendaylight/md-sal/statistics-manager/src/main/java/org/opendaylight/controller/md/statistics/manager/StatisticsUpdateCommiter.java index 30f98cedd3..aa6e99a03f 100644 --- a/opendaylight/md-sal/statistics-manager/src/main/java/org/opendaylight/controller/md/statistics/manager/StatisticsUpdateCommiter.java +++ b/opendaylight/md-sal/statistics-manager/src/main/java/org/opendaylight/controller/md/statistics/manager/StatisticsUpdateCommiter.java @@ -847,9 +847,7 @@ public class StatisticsUpdateCommiter implements OpendaylightGroupStatisticsList } if (storedFlow.getInPort()== null) { if (statsFlow.getInPort() != null) { - if(statsFlow.getInPort()!= 0){ - return false; - } + return false; } } else if(!storedFlow.getInPort().equals(statsFlow.getInPort())) { return false; diff --git a/opendaylight/md-sal/test/sal-rest-connector-it/pom.xml b/opendaylight/md-sal/test/sal-rest-connector-it/pom.xml index 8569783ad7..e49fb33780 100644 --- a/opendaylight/md-sal/test/sal-rest-connector-it/pom.xml +++ b/opendaylight/md-sal/test/sal-rest-connector-it/pom.xml @@ -622,11 +622,7 @@ jersey-client ${jersey.version} - - com.sun.jersey - jersey-json - ${jersey.version} - + eclipselink javax.resource 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 fda1e264e6..b8ebedfdfb 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 @@ -182,10 +182,13 @@ public class ServiceProviderController { // Northbound bundles mavenBundle("org.opendaylight.controller", "commons.northbound").versionAsInProject(), - mavenBundle("org.codehaus.jackson", "jackson-mapper-asl").versionAsInProject(), - mavenBundle("org.codehaus.jackson", "jackson-core-asl").versionAsInProject(), - mavenBundle("org.codehaus.jackson", "jackson-jaxrs").versionAsInProject(), - mavenBundle("org.codehaus.jackson", "jackson-xc").versionAsInProject(), + + mavenBundle("com.fasterxml.jackson.core", "jackson-annotations").versionAsInProject(), + mavenBundle("com.fasterxml.jackson.core", "jackson-core").versionAsInProject(), + mavenBundle("com.fasterxml.jackson.core", "jackson-databind").versionAsInProject(), + mavenBundle("com.fasterxml.jackson.jaxrs", "jackson-jaxrs-json-provider").versionAsInProject(), + mavenBundle("com.fasterxml.jackson.module", "jackson-module-jaxb-annotations").versionAsInProject(), + mavenBundle("org.codehaus.jettison", "jettison").versionAsInProject(), mavenBundle("commons-io", "commons-io").versionAsInProject(), @@ -318,8 +321,6 @@ public class ServiceProviderController { mavenBundle("com.sun.jersey", "jersey-client").versionAsInProject(), mavenBundle("com.sun.jersey", "jersey-server").versionAsInProject().startLevel(2), mavenBundle("com.sun.jersey", "jersey-core").versionAsInProject().startLevel(2), - mavenBundle("com.sun.jersey", "jersey-json").versionAsInProject().startLevel(2), - junitBundles()); } diff --git a/opendaylight/md-sal/topology-lldp-discovery/pom.xml b/opendaylight/md-sal/topology-lldp-discovery/pom.xml new file mode 100644 index 0000000000..ed94c8dfb7 --- /dev/null +++ b/opendaylight/md-sal/topology-lldp-discovery/pom.xml @@ -0,0 +1,129 @@ + + 4.0.0 + + org.opendaylight.controller + sal-parent + 1.0-SNAPSHOT + ../ + + org.opendaylight.controller.md + topology-lldp-discovery + bundle + + scm:git:ssh://git.opendaylight.org:29418/controller.git + scm:git:ssh://git.opendaylight.org:29418/controller.git + + + 14.0.1 + 2.4.3 + 2.4.0 + 2.5 + + + + com.google.guava + guava + + + org.opendaylight.controller + sal-binding-api + 1.0-SNAPSHOT + + + org.opendaylight.controller.model + model-flow-service + 1.0-SNAPSHOT + + + org.opendaylight.controller.model + model-flow-base + 1.0-SNAPSHOT + + + org.opendaylight.controller.model + model-flow-management + 1.0-SNAPSHOT + + + org.opendaylight.controller.model + model-inventory + 1.0-SNAPSHOT + + + org.eclipse.xtend + org.eclipse.xtend.lib + + + equinoxSDK381 + org.eclipse.osgi + 3.8.1.v20120830-144521 + + + commons-lang + commons-lang + 2.6 + + + com.google.guava + guava + + + commons-codec + commons-codec + 1.8 + + + org.opendaylight.controller + sal + 0.7.0-SNAPSHOT + + + + + + + + org.apache.felix + maven-bundle-plugin + true + + + org.opendaylight.md.controller.topology.lldp.LLDPActivator + org.opendaylight.md.controller.topology.lldp.utils + commons-lang> + ${project.groupId}.${project.artifactId} + + ${project.basedir}/META-INF + + + + org.eclipse.xtend + xtend-maven-plugin + + + + compile + + + ${basedir}/src/main/xtend-gen + + + + + + maven-clean-plugin + + + + ${basedir}/src/main/xtend-gen + + ** + + + + + + + + diff --git a/opendaylight/md-sal/topology-lldp-discovery/src/main/java/org/opendaylight/md/controller/topology/lldp/LLDPActivator.xtend b/opendaylight/md-sal/topology-lldp-discovery/src/main/java/org/opendaylight/md/controller/topology/lldp/LLDPActivator.xtend new file mode 100644 index 0000000000..674e919cd7 --- /dev/null +++ b/opendaylight/md-sal/topology-lldp-discovery/src/main/java/org/opendaylight/md/controller/topology/lldp/LLDPActivator.xtend @@ -0,0 +1,30 @@ +/* + * 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.md.controller.topology.lldp + +import org.opendaylight.controller.sal.binding.api.AbstractBindingAwareProvider +import org.opendaylight.controller.sal.binding.api.BindingAwareBroker.ProviderContext +import org.opendaylight.controller.sal.binding.api.NotificationProviderService +import org.opendaylight.controller.sal.binding.api.data.DataProviderService +import org.osgi.framework.BundleContext + +class LLDPActivator extends AbstractBindingAwareProvider { + + static var LLDPDiscoveryProvider provider = new LLDPDiscoveryProvider(); + + override onSessionInitiated(ProviderContext session) { + provider.dataService = session.getSALService(DataProviderService) + provider.notificationService = session.getSALService(NotificationProviderService) + provider.start(); + } + + override protected stopImpl(BundleContext context) { + provider.close(); + } + +} diff --git a/opendaylight/md-sal/topology-lldp-discovery/src/main/java/org/opendaylight/md/controller/topology/lldp/LLDPDiscoveryListener.java b/opendaylight/md-sal/topology-lldp-discovery/src/main/java/org/opendaylight/md/controller/topology/lldp/LLDPDiscoveryListener.java new file mode 100644 index 0000000000..095d12e6ef --- /dev/null +++ b/opendaylight/md-sal/topology-lldp-discovery/src/main/java/org/opendaylight/md/controller/topology/lldp/LLDPDiscoveryListener.java @@ -0,0 +1,34 @@ +package org.opendaylight.md.controller.topology.lldp; + +import org.opendaylight.md.controller.topology.lldp.utils.LLDPDiscoveryUtils; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.topology.discovery.rev130819.LinkDiscovered; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.topology.discovery.rev130819.LinkDiscoveredBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorRef; +import org.opendaylight.yang.gen.v1.urn.opendaylight.packet.service.rev130709.PacketProcessingListener; +import org.opendaylight.yang.gen.v1.urn.opendaylight.packet.service.rev130709.PacketReceived; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +class LLDPDiscoveryListener implements PacketProcessingListener { + static Logger LOG = LoggerFactory.getLogger(LLDPDiscoveryListener.class); + + private LLDPDiscoveryProvider manager; + + LLDPDiscoveryListener(LLDPDiscoveryProvider manager) { + this.manager = manager; + } + + public void onPacketReceived(PacketReceived lldp) { + NodeConnectorRef src = LLDPDiscoveryUtils.lldpToNodeConnectorRef(lldp.getPayload()); + if(src != null) { + LinkDiscoveredBuilder ldb = new LinkDiscoveredBuilder(); + ldb.setDestination(lldp.getIngress()); + ldb.setSource(new NodeConnectorRef(src)); + LinkDiscovered ld = ldb.build(); + + manager.getNotificationService().publish(ld); + LLDPLinkAger.getInstance().put(ld); + } + } + +} diff --git a/opendaylight/md-sal/topology-lldp-discovery/src/main/java/org/opendaylight/md/controller/topology/lldp/LLDPDiscoveryProvider.xtend b/opendaylight/md-sal/topology-lldp-discovery/src/main/java/org/opendaylight/md/controller/topology/lldp/LLDPDiscoveryProvider.xtend new file mode 100644 index 0000000000..fc724ac680 --- /dev/null +++ b/opendaylight/md-sal/topology-lldp-discovery/src/main/java/org/opendaylight/md/controller/topology/lldp/LLDPDiscoveryProvider.xtend @@ -0,0 +1,46 @@ +/* + * 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.md.controller.topology.lldp + +import org.opendaylight.controller.sal.binding.api.NotificationProviderService +import org.opendaylight.controller.sal.binding.api.data.DataProviderService +import org.opendaylight.yangtools.concepts.Registration +import org.opendaylight.yangtools.yang.binding.NotificationListener +import org.slf4j.LoggerFactory + +class LLDPDiscoveryProvider implements AutoCloseable { + + + static val LOG = LoggerFactory.getLogger(LLDPDiscoveryProvider); + + @Property + DataProviderService dataService; + + @Property + NotificationProviderService notificationService; + + val LLDPDiscoveryListener commiter = new LLDPDiscoveryListener(this); + + Registration listenerRegistration + + def void start() { + listenerRegistration = notificationService.registerNotificationListener(commiter); + LLDPLinkAger.instance.manager = this; + LOG.info("LLDPDiscoveryListener Started."); + + } + + override close() { + LOG.info("LLDPDiscoveryListener stopped."); + listenerRegistration?.close(); + LLDPLinkAger.instance.close(); + } + +} + + diff --git a/opendaylight/md-sal/topology-lldp-discovery/src/main/java/org/opendaylight/md/controller/topology/lldp/LLDPLinkAger.java b/opendaylight/md-sal/topology-lldp-discovery/src/main/java/org/opendaylight/md/controller/topology/lldp/LLDPLinkAger.java new file mode 100644 index 0000000000..171783b0a2 --- /dev/null +++ b/opendaylight/md-sal/topology-lldp-discovery/src/main/java/org/opendaylight/md/controller/topology/lldp/LLDPLinkAger.java @@ -0,0 +1,65 @@ +package org.opendaylight.md.controller.topology.lldp; + +import java.util.Date; +import java.util.Map; +import java.util.Timer; +import java.util.Map.Entry; +import java.util.TimerTask; +import java.util.concurrent.ConcurrentHashMap; + +import org.opendaylight.md.controller.topology.lldp.utils.LLDPDiscoveryUtils; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.topology.discovery.rev130819.LinkDiscovered; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.topology.discovery.rev130819.LinkRemovedBuilder; + + +public class LLDPLinkAger { + private static final LLDPLinkAger instance = new LLDPLinkAger(); + private Map linkToDate = new ConcurrentHashMap(); + private LLDPDiscoveryProvider manager; + private Timer timer = new Timer(); + + public LLDPDiscoveryProvider getManager() { + return manager; + } + public void setManager(LLDPDiscoveryProvider manager) { + this.manager = manager; + } + private LLDPLinkAger() { + timer.schedule(new LLDPAgingTask(), 0,LLDPDiscoveryUtils.LLDP_INTERVAL); + } + public static LLDPLinkAger getInstance() { + return instance; + } + + public void put(LinkDiscovered link) { + Date expires = new Date(); + expires.setTime(expires.getTime() + LLDPDiscoveryUtils.LLDP_EXPIRATION_TIME); + linkToDate.put(link, expires); + } + + public void close() { + timer.cancel(); + } + + private class LLDPAgingTask extends TimerTask { + + @Override + public void run() { + for (Entry entry : linkToDate.entrySet()) { + LinkDiscovered link = entry.getKey(); + Date expires = entry.getValue(); + Date now = new Date(); + if(now.after(expires)) { + if(getInstance().getManager() != null) { + LinkRemovedBuilder lrb = new LinkRemovedBuilder(link); + getInstance().getManager().getNotificationService().publish(lrb.build()); + linkToDate.remove(link); + } + } + } + + } + + } +} + diff --git a/opendaylight/md-sal/topology-lldp-discovery/src/main/java/org/opendaylight/md/controller/topology/lldp/utils/LLDPDiscoveryUtils.java b/opendaylight/md-sal/topology-lldp-discovery/src/main/java/org/opendaylight/md/controller/topology/lldp/utils/LLDPDiscoveryUtils.java new file mode 100644 index 0000000000..c0bcbaa8ad --- /dev/null +++ b/opendaylight/md-sal/topology-lldp-discovery/src/main/java/org/opendaylight/md/controller/topology/lldp/utils/LLDPDiscoveryUtils.java @@ -0,0 +1,72 @@ +package org.opendaylight.md.controller.topology.lldp.utils; + +import java.nio.charset.Charset; + +import org.opendaylight.controller.sal.packet.Ethernet; +import org.opendaylight.controller.sal.packet.LLDP; +import org.opendaylight.controller.sal.packet.LLDPTLV; +import org.opendaylight.controller.sal.utils.NetUtils; +import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId; +import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorRef; +import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId; +import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.Nodes; +import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnector; +import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnectorKey; +import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node; +import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeKey; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class LLDPDiscoveryUtils { + static Logger LOG = LoggerFactory.getLogger(LLDPDiscoveryUtils.class); + + public static final Long LLDP_INTERVAL = (long) (1000*5); // Send LLDP every five seconds + public static final Long LLDP_EXPIRATION_TIME = LLDP_INTERVAL*3; // Let up to three intervals pass before we decide we are expired. + + public static String macToString(byte[] mac) { + StringBuilder b = new StringBuilder(); + for (int i = 0; i < mac.length; i++) { + b.append(String.format("%02X%s", mac[i], (i < mac.length - 1) ? ":" : "")); + } + + return b.toString(); + } + + public static NodeConnectorRef lldpToNodeConnectorRef(byte[] payload) { + Ethernet ethPkt = new Ethernet(); + try { + ethPkt.deserialize(payload, 0,payload.length * NetUtils.NumBitsInAByte); + } catch (Exception e) { + LOG.warn("Failed to decode LLDP packet {}", e); + } + + if (ethPkt.getPayload() instanceof LLDP) { + LLDP lldp = (LLDP) ethPkt.getPayload(); + + try { + NodeId srcNodeId = null; + NodeConnectorId srcNodeConnectorId = null; + for (LLDPTLV lldptlv : lldp.getOptionalTLVList()) { + if (lldptlv.getType() == LLDPTLV.TLVType.Custom.getValue()) { + srcNodeConnectorId = new NodeConnectorId(LLDPTLV.getCustomString(lldptlv.getValue(), lldptlv.getLength())); + } + if (lldptlv.getType() == LLDPTLV.TLVType.SystemName.getValue()) { + String srcNodeIdString = new String(lldptlv.getValue(),Charset.defaultCharset()); + srcNodeId = new NodeId(srcNodeIdString); + } + } + if(srcNodeId != null && srcNodeConnectorId != null) { + InstanceIdentifier srcInstanceId = InstanceIdentifier.builder(Nodes.class) + .child(Node.class,new NodeKey(srcNodeId)) + .child(NodeConnector.class, new NodeConnectorKey(srcNodeConnectorId)) + .toInstance(); + return new NodeConnectorRef(srcInstanceId); + } + } catch (Exception e) { + LOG.warn("Caught exception ", e); + } + } + return null; + } +} diff --git a/opendaylight/md-sal/topology-manager/pom.xml b/opendaylight/md-sal/topology-manager/pom.xml index 6e50f9ce73..76300864fd 100644 --- a/opendaylight/md-sal/topology-manager/pom.xml +++ b/opendaylight/md-sal/topology-manager/pom.xml @@ -42,7 +42,7 @@ org.opendaylight.controller.model - model-topology-view + model-topology 1.0-SNAPSHOT @@ -58,8 +58,8 @@ maven-bundle-plugin - org.opendaylight.controller.md.inventory.manager.InventoryActivator - org.opendaylight.controller.md.inventory.manager + org.opendaylight.md.controller.topology.manager.FlowCapableTopologyProvider + org.opendaylight.md.controller.topology.manager diff --git a/opendaylight/md-sal/topology-manager/src/main/java/org/opendaylight/md/controller/topology/manager/FlowCapableNodeMapping.xtend b/opendaylight/md-sal/topology-manager/src/main/java/org/opendaylight/md/controller/topology/manager/FlowCapableNodeMapping.xtend index 46f5d2b406..05f7fe1272 100644 --- a/opendaylight/md-sal/topology-manager/src/main/java/org/opendaylight/md/controller/topology/manager/FlowCapableNodeMapping.xtend +++ b/opendaylight/md-sal/topology-manager/src/main/java/org/opendaylight/md/controller/topology/manager/FlowCapableNodeMapping.xtend @@ -5,7 +5,7 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeCon import org.opendaylight.yangtools.yang.binding.InstanceIdentifier.IdentifiableItem import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnectorKey -import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnector +import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnector import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeRef import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev130712.network.topology.topology.node.TerminationPoint import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorUpdated @@ -14,6 +14,17 @@ import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology. import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev130712.TpId import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev130712.NodeId +import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev130712.network.topology.topology.NodeBuilder +import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev130712.link.attributes.SourceBuilder +import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev130712.link.attributes.DestinationBuilder +import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev130712.network.topology.topology.LinkBuilder +import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev130712.network.topology.topology.LinkKey +import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev130712.LinkId +import org.opendaylight.yang.gen.v1.urn.opendaylight.model.topology.inventory.rev131030.InventoryNodeBuilder +import org.opendaylight.yang.gen.v1.urn.opendaylight.model.topology.inventory.rev131030.InventoryNode +import org.opendaylight.yang.gen.v1.urn.opendaylight.model.topology.inventory.rev131030.InventoryNodeConnector +import org.opendaylight.yang.gen.v1.urn.opendaylight.model.topology.inventory.rev131030.InventoryNodeConnectorBuilder +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode class FlowCapableNodeMapping { @@ -29,12 +40,6 @@ class FlowCapableNodeMapping { (ref?.value?.path?.get(2) as IdentifiableItem).key } - static def TerminationPoint toTerminationPoint(NodeConnectorUpdated updated) { - val it = new TerminationPointBuilder - key = new TerminationPointKey(new TpId(updated.id)); - return it.build() - } - static def NodeId toToplogyNodeId(org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId nodeId) { return new NodeId(nodeId); } @@ -42,4 +47,36 @@ class FlowCapableNodeMapping { static def toTerminationPointId(NodeConnectorId id) { return new TpId(id); } + + static def toTopologyNode(NodeId nodeId,NodeRef invNodeRef) { + val nb = new NodeBuilder(); + nb.setNodeId(nodeId) + val inb = new InventoryNodeBuilder + inb.setInventoryNodeRef(invNodeRef) + nb.addAugmentation(InventoryNode,inb.build) + return nb.build(); + } + + static def toTerminationPoint(TpId id, NodeConnectorRef invNodeConnectorRef) { + val tpb = new TerminationPointBuilder + tpb.setTpId(id); + val incb = new InventoryNodeConnectorBuilder + incb.setInventoryNodeConnectorRef(invNodeConnectorRef) + tpb.addAugmentation(InventoryNodeConnector,incb.build()) + return tpb.build(); + } + + static def toTopologyLink(org.opendaylight.yang.gen.v1.urn.opendaylight.flow.topology.discovery.rev130819.Link link) { + val sb = new SourceBuilder(); + sb.setSourceNode(link.source.nodeKey.id.toToplogyNodeId) + sb.setSourceTp(link.source.nodeConnectorKey.id.toTerminationPointId) + val db = new DestinationBuilder(); + db.setDestNode(link.destination.nodeKey.id.toToplogyNodeId) + db.setDestTp(link.destination.nodeConnectorKey.id.toTerminationPointId) + val lb = new LinkBuilder(); + lb.setSource(sb.build()) + lb.setDestination(db.build()); + lb.setLinkId(new LinkId(lb.source.sourceTp.value)) + return lb.build(); + } } diff --git a/opendaylight/md-sal/topology-manager/src/main/java/org/opendaylight/md/controller/topology/manager/FlowCapableTopologyExporter.xtend b/opendaylight/md-sal/topology-manager/src/main/java/org/opendaylight/md/controller/topology/manager/FlowCapableTopologyExporter.xtend index fb129e4710..92a2277b4c 100644 --- a/opendaylight/md-sal/topology-manager/src/main/java/org/opendaylight/md/controller/topology/manager/FlowCapableTopologyExporter.xtend +++ b/opendaylight/md-sal/topology-manager/src/main/java/org/opendaylight/md/controller/topology/manager/FlowCapableTopologyExporter.xtend @@ -1,101 +1,135 @@ package org.opendaylight.md.controller.topology.manager +import com.google.common.collect.FluentIterable +import org.opendaylight.controller.md.sal.binding.util.TypeSafeDataReader +import org.opendaylight.controller.sal.binding.api.data.DataModificationTransaction +import org.opendaylight.controller.sal.binding.api.data.DataProviderService +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNodeConnectorUpdated +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNodeUpdated import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.topology.discovery.rev130819.FlowTopologyDiscoveryListener import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.topology.discovery.rev130819.LinkDiscovered import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.topology.discovery.rev130819.LinkOverutilized import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.topology.discovery.rev130819.LinkRemoved import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.topology.discovery.rev130819.LinkUtilizationNormal -import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.OpendaylightInventoryListener +import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorRef import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorRemoved import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorUpdated +import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeRef import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeRemoved import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeUpdated -import org.opendaylight.controller.sal.binding.api.data.DataProviderService +import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.OpendaylightInventoryListener +import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev130712.NetworkTopology +import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev130712.NodeId +import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev130712.TopologyId +import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev130712.TpId import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev130712.network.topology.Topology -import org.opendaylight.yangtools.yang.binding.InstanceIdentifier -import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorRef -import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev130712.network.topology.topology.node.TerminationPoint +import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev130712.network.topology.TopologyBuilder import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev130712.network.topology.TopologyKey -import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev130712.NetworkTopology +import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev130712.network.topology.topology.Link import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev130712.network.topology.topology.Node - import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev130712.network.topology.topology.NodeKey -import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev130712.NodeId +import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev130712.network.topology.topology.node.TerminationPoint import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev130712.network.topology.topology.node.TerminationPointKey -import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev130712.TpId -import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeRef +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier + import static extension org.opendaylight.md.controller.topology.manager.FlowCapableNodeMapping.* -import org.opendaylight.controller.sal.binding.api.data.DataModificationTransaction -import org.opendaylight.controller.md.sal.binding.util.TypeSafeDataReader -import com.google.common.collect.FluentIterable -import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev130712.network.topology.topology.Link class FlowCapableTopologyExporter implements // FlowTopologyDiscoveryListener, // OpendaylightInventoryListener // { - var TopologyKey topology; + var TopologyKey topology = new TopologyKey(new TopologyId("flow:1")); @Property var DataProviderService dataService; + + def start() { + val tb = new TopologyBuilder(); + tb.setKey(topology); + val path = InstanceIdentifier.builder(NetworkTopology).child(Topology,topology).toInstance; + val top = tb.build(); + val it = dataService.beginTransaction + putOperationalData(path,top); + commit() + } override onNodeRemoved(NodeRemoved notification) { - val invNodeKey = notification.nodeRef.nodeKey - val tpNodeId = invNodeKey.id.toToplogyNodeId() - val tpNodeInstance = notification.nodeRef.toNodeIdentifier() + val nodeId = notification.nodeRef.nodeKey.id.toToplogyNodeId() + val nodeInstance = notification.nodeRef.toNodeIdentifier() val it = dataService.beginTransaction - removeRuntimeData(tpNodeInstance); - removeAffectedLinks(tpNodeId) + removeOperationalData(nodeInstance); + removeAffectedLinks(it,nodeId) commit() } override onNodeUpdated(NodeUpdated notification) { - throw new UnsupportedOperationException("TODO: auto-generated method stub") + val fcnu = notification.getAugmentation(FlowCapableNodeUpdated) + if(fcnu != null) { + val node = notification.id.toToplogyNodeId.toTopologyNode(notification.nodeRef) + val path = notification.id.toToplogyNodeId.nodePath; + val it = dataService.beginTransaction + putOperationalData(path, node); + commit() + } } override onNodeConnectorRemoved(NodeConnectorRemoved notification) { - val tpRef = notification.nodeConnectorRef.toTerminationPointIdentifier(); + val tpInstance = notification.nodeConnectorRef.toTerminationPointIdentifier; + val tpId = notification.nodeConnectorRef.nodeConnectorKey.id.toTerminationPointId; val it = dataService.beginTransaction - removeRuntimeData(tpRef); + removeOperationalData(tpInstance); + removeAffectedLinks(it,tpId) commit() } override onNodeConnectorUpdated(NodeConnectorUpdated notification) { - val nodeId = notification.nodeConnectorRef.nodeKey.id.toToplogyNodeId(); - val TerminationPoint point = notification.toTerminationPoint(); - val path = tpPath(nodeId, point.key.tpId); - - val it = dataService.beginTransaction - putRuntimeData(path, point); - commit() + val fcncu = notification.getAugmentation(FlowCapableNodeConnectorUpdated) + if(fcncu != null) { + val nodeId = notification.nodeConnectorRef.nodeKey.id.toToplogyNodeId; + val TerminationPoint point = notification.id.toTerminationPointId.toTerminationPoint(notification.nodeConnectorRef); + val path = tpPath(nodeId, point.key.tpId); + + val it = dataService.beginTransaction + putOperationalData(path, point); + if((fcncu.state != null && fcncu.state.linkDown) || (fcncu.configuration != null && fcncu.configuration.PORTDOWN)) { + removeAffectedLinks(it,point.tpId) + } + commit() + } } override onLinkDiscovered(LinkDiscovered notification) { - throw new UnsupportedOperationException("TODO: auto-generated method stub") + val link = notification.toTopologyLink; + val path = link.linkPath; + val it = dataService.beginTransaction + putOperationalData(path, link); + commit() } override onLinkOverutilized(LinkOverutilized notification) { - throw new UnsupportedOperationException("TODO: auto-generated method stub") + // NOOP } override onLinkRemoved(LinkRemoved notification) { - throw new UnsupportedOperationException("TODO: auto-generated method stub") - + val path = notification.toTopologyLink.linkPath + val it = dataService.beginTransaction + removeOperationalData(path); + commit() } override onLinkUtilizationNormal(LinkUtilizationNormal notification) { - throw new UnsupportedOperationException("TODO: auto-generated method stub") + // NOOP } def InstanceIdentifier toNodeIdentifier(NodeRef ref) { val invNodeKey = ref.nodeKey val nodeKey = new NodeKey(invNodeKey.id.toToplogyNodeId); - return InstanceIdentifier.builder.node(NetworkTopology).child(Topology, topology).child(Node, nodeKey). + return InstanceIdentifier.builder(NetworkTopology).child(Topology, topology).child(Node, nodeKey). toInstance; } @@ -107,7 +141,7 @@ OpendaylightInventoryListener // private def void removeAffectedLinks(DataModificationTransaction transaction, NodeId id) { val reader = TypeSafeDataReader.forReader(transaction) - val topologyPath = InstanceIdentifier.builder().node(NetworkTopology).child(Topology, topology).toInstance; + val topologyPath = InstanceIdentifier.builder(NetworkTopology).child(Topology, topology).toInstance; val topologyData = reader.readOperationalData(topologyPath); if (topologyData === null) { return; @@ -115,18 +149,52 @@ OpendaylightInventoryListener // val affectedLinkInstances = FluentIterable.from(topologyData.link).filter[ source.sourceNode == id || destination.destNode == id].transform [ // - InstanceIdentifier.builder().node(NetworkTopology).child(Topology, topology).child(Link, key).toInstance + InstanceIdentifier.builder(NetworkTopology).child(Topology, topology).child(Link, key).toInstance // ] for(affectedLink : affectedLinkInstances) { - transaction.removeRuntimeData(affectedLink); + transaction.removeOperationalData(affectedLink); } } + private def void removeAffectedLinks(DataModificationTransaction transaction, TpId id) { + val reader = TypeSafeDataReader.forReader(transaction) + val topologyPath = InstanceIdentifier.builder(NetworkTopology).child(Topology, topology).toInstance; + val topologyData = reader.readOperationalData(topologyPath); + if (topologyData === null) { + return; + } + val affectedLinkInstances = FluentIterable.from(topologyData.link).filter[ + source.sourceTp == id || destination.destTp == id].transform [ + // + InstanceIdentifier.builder(NetworkTopology).child(Topology, topology).child(Link, key).toInstance + // + ] + for(affectedLink : affectedLinkInstances) { + transaction.removeOperationalData(affectedLink); + } + } + + private def InstanceIdentifier nodePath(NodeId nodeId) { + val nodeKey = new NodeKey(nodeId); + return InstanceIdentifier.builder(NetworkTopology) + .child(Topology, topology) + .child(Node, nodeKey) + .toInstance; + } + private def InstanceIdentifier tpPath(NodeId nodeId, TpId tpId) { val nodeKey = new NodeKey(nodeId); val tpKey = new TerminationPointKey(tpId) - return InstanceIdentifier.builder.node(NetworkTopology).child(Topology, topology).child(Node, nodeKey). + return InstanceIdentifier.builder(NetworkTopology).child(Topology, topology).child(Node, nodeKey). child(TerminationPoint, tpKey).toInstance; } + + private def InstanceIdentifier linkPath(Link link) { + val linkInstanceId = InstanceIdentifier.builder(NetworkTopology) + .child(Topology, topology) + .child(Link, link.key) + .toInstance; + return linkInstanceId; + } } diff --git a/opendaylight/md-sal/topology-manager/src/main/java/org/opendaylight/md/controller/topology/manager/FlowCapableTopologyProvider.xtend b/opendaylight/md-sal/topology-manager/src/main/java/org/opendaylight/md/controller/topology/manager/FlowCapableTopologyProvider.xtend new file mode 100644 index 0000000000..036fe733aa --- /dev/null +++ b/opendaylight/md-sal/topology-manager/src/main/java/org/opendaylight/md/controller/topology/manager/FlowCapableTopologyProvider.xtend @@ -0,0 +1,49 @@ +/* + * 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.md.controller.topology.manager + +import org.opendaylight.controller.sal.binding.api.NotificationProviderService +import org.opendaylight.controller.sal.binding.api.data.DataProviderService +import org.opendaylight.yangtools.concepts.Registration +import org.opendaylight.yangtools.yang.binding.NotificationListener +import org.slf4j.LoggerFactory +import org.opendaylight.controller.sal.binding.api.AbstractBindingAwareProvider +import org.opendaylight.controller.sal.binding.api.BindingAwareBroker.ProviderContext + +class FlowCapableTopologyProvider extends AbstractBindingAwareProvider implements AutoCloseable { + + + + static val LOG = LoggerFactory.getLogger(FlowCapableTopologyProvider); + + @Property + DataProviderService dataService; + + @Property + NotificationProviderService notificationService; + + val FlowCapableTopologyExporter exporter = new FlowCapableTopologyExporter(); + + Registration listenerRegistration + + override close() { + LOG.info("FlowCapableTopologyProvider stopped."); + listenerRegistration?.close(); + } + + override onSessionInitiated(ProviderContext session) { + dataService = session.getSALService(DataProviderService) + notificationService = session.getSALService(NotificationProviderService) + exporter.setDataService(dataService); + exporter.start(); + listenerRegistration = notificationService.registerNotificationListener(exporter); + } + +} + + diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/AttributesConstants.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/AttributesConstants.java deleted file mode 100644 index 23cdabf69f..0000000000 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/AttributesConstants.java +++ /dev/null @@ -1,16 +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.netconf.confignetconfconnector.mapping.attributes; - -public class AttributesConstants { - - /** - * Property placed into object names for dependencies to preserve reference name - */ - public static final String REF_NAME_ON_PROPERTY_KEY = "X-refName"; -} diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/fromxml/AttributeConfigElement.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/fromxml/AttributeConfigElement.java index a1f46dde54..dbc1b48d4f 100644 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/fromxml/AttributeConfigElement.java +++ b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/fromxml/AttributeConfigElement.java @@ -43,7 +43,6 @@ public class AttributeConfigElement { resolvedValue = attributeResolvingStrategy.parseAttribute(attrName, value); Optional resolvedDefault = attributeResolvingStrategy.parseAttribute(attrName, dafaultValue); resolvedDefaultValue = resolvedDefault.isPresent() ? resolvedDefault.get() : null; - } public static AttributeConfigElement create(Object nullableDefault, Object value) { diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/mapping/ObjectMapper.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/mapping/ObjectMapper.java index fb385221c8..506d7d61c3 100644 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/mapping/ObjectMapper.java +++ b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/mapping/ObjectMapper.java @@ -16,7 +16,7 @@ import org.opendaylight.controller.config.yangjmxgenerator.attribute.ListAttribu import org.opendaylight.controller.config.yangjmxgenerator.attribute.ListDependenciesAttribute; import org.opendaylight.controller.config.yangjmxgenerator.attribute.TOAttribute; import org.opendaylight.controller.netconf.confignetconfconnector.mapping.attributes.AttributeIfcSwitchStatement; -import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.Services; +import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.ServiceRegistryWrapper; import javax.management.openmbean.ArrayType; import javax.management.openmbean.CompositeType; @@ -27,9 +27,9 @@ import java.util.Map.Entry; public class ObjectMapper extends AttributeIfcSwitchStatement>> { - private final Services dependencyTracker; + private final ServiceRegistryWrapper dependencyTracker; - public ObjectMapper(Services depTracker) { + public ObjectMapper(ServiceRegistryWrapper depTracker) { this.dependencyTracker = depTracker; } diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/mapping/ObjectNameAttributeMappingStrategy.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/mapping/ObjectNameAttributeMappingStrategy.java index 8426341636..83e8086eef 100644 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/mapping/ObjectNameAttributeMappingStrategy.java +++ b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/mapping/ObjectNameAttributeMappingStrategy.java @@ -10,8 +10,8 @@ package org.opendaylight.controller.netconf.confignetconfconnector.mapping.attri import com.google.common.base.Optional; import com.google.common.base.Preconditions; -import org.opendaylight.controller.netconf.confignetconfconnector.mapping.attributes.AttributesConstants; -import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.Services; +import org.opendaylight.controller.config.api.jmx.ObjectNameUtil; +import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.ServiceRegistryWrapper; import org.opendaylight.controller.netconf.confignetconfconnector.util.Util; import javax.management.ObjectName; @@ -20,11 +20,11 @@ import javax.management.openmbean.SimpleType; public class ObjectNameAttributeMappingStrategy extends AbstractAttributeMappingStrategy> { - private final Services tracker; + private final ServiceRegistryWrapper tracker; private final String serviceName; private final String namespace; - public ObjectNameAttributeMappingStrategy(SimpleType openType, Services dependencyTracker, String serviceName, String namespace) { + public ObjectNameAttributeMappingStrategy(SimpleType openType, ServiceRegistryWrapper dependencyTracker, String serviceName, String namespace) { super(openType); this.tracker = dependencyTracker; this.serviceName = serviceName; @@ -44,10 +44,7 @@ public class ObjectNameAttributeMappingStrategy extends ObjectName on = (ObjectName) value; - String expectedRefName = on.getKeyProperty(AttributesConstants.REF_NAME_ON_PROPERTY_KEY); - - String refName = expectedRefName == null ? tracker.getRefName(namespace, serviceName, on, Optional. absent()) - : tracker.getRefName(namespace, serviceName, on, Optional.of(expectedRefName)); + String refName = ObjectNameUtil.getReferenceName(on); return Optional.of(new MappedDependency(namespace, serviceName, refName)); } diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/resolving/ObjectNameAttributeResolvingStrategy.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/resolving/ObjectNameAttributeResolvingStrategy.java index d8f0e2357e..57a44d8af0 100644 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/resolving/ObjectNameAttributeResolvingStrategy.java +++ b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/resolving/ObjectNameAttributeResolvingStrategy.java @@ -9,11 +9,8 @@ package org.opendaylight.controller.netconf.confignetconfconnector.mapping.attributes.resolving; import com.google.common.base.Optional; -import org.opendaylight.controller.config.api.jmx.ObjectNameUtil; -import org.opendaylight.controller.netconf.confignetconfconnector.mapping.attributes.AttributesConstants; import org.opendaylight.controller.netconf.confignetconfconnector.mapping.attributes.mapping.ObjectNameAttributeMappingStrategy; -import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.Services; -import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.Services.ServiceInstance; +import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.ServiceRegistryWrapper; import org.opendaylight.controller.netconf.confignetconfconnector.util.Util; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -23,10 +20,10 @@ import javax.management.openmbean.SimpleType; public class ObjectNameAttributeResolvingStrategy extends AbstractAttributeResolvingStrategy> { - private final Services serviceTracker; + private final ServiceRegistryWrapper serviceTracker; private static final Logger logger = LoggerFactory.getLogger(ObjectNameAttributeResolvingStrategy.class); - ObjectNameAttributeResolvingStrategy(Services serviceTracker) { + ObjectNameAttributeResolvingStrategy(ServiceRegistryWrapper serviceTracker) { super(SimpleType.OBJECTNAME); this.serviceTracker = serviceTracker; } @@ -45,9 +42,7 @@ public class ObjectNameAttributeResolvingStrategy extends AbstractAttributeResol String namespace = mappedDep.getNamespace(); logger.trace("Getting service instance by service name {} : {} and ref name {}", namespace, serviceName, refName); - ServiceInstance byRefName = serviceTracker.getByServiceAndRefName(namespace, serviceName, refName); - ObjectName on = ObjectNameUtil.createReadOnlyModuleON(byRefName.getModuleName(), byRefName.getInstanceName()); - on = ObjectNameUtil.createON(on.toString() + "," + AttributesConstants.REF_NAME_ON_PROPERTY_KEY + "=" + refName); + ObjectName on = serviceTracker.getByServiceAndRefName(namespace, serviceName, refName); logger.debug("Attribute {} : {} parsed to type {}", attrName, value, getOpenType()); return Optional.of(on); diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/resolving/ObjectResolver.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/resolving/ObjectResolver.java index a3e2813fa0..82c8c1ec6b 100644 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/resolving/ObjectResolver.java +++ b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/resolving/ObjectResolver.java @@ -15,7 +15,7 @@ import org.opendaylight.controller.config.yangjmxgenerator.attribute.ListAttribu import org.opendaylight.controller.config.yangjmxgenerator.attribute.ListDependenciesAttribute; import org.opendaylight.controller.config.yangjmxgenerator.attribute.TOAttribute; import org.opendaylight.controller.netconf.confignetconfconnector.mapping.attributes.AttributeIfcSwitchStatement; -import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.Services; +import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.ServiceRegistryWrapper; import javax.management.openmbean.ArrayType; import javax.management.openmbean.CompositeType; @@ -26,9 +26,9 @@ import java.util.Map.Entry; public class ObjectResolver extends AttributeIfcSwitchStatement>> { - private final Services serviceTracker; + private final ServiceRegistryWrapper serviceTracker; - public ObjectResolver(Services serviceTracker) { + public ObjectResolver(ServiceRegistryWrapper serviceTracker) { this.serviceTracker = serviceTracker; } diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/config/Config.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/config/Config.java index 3a5fa1170f..ec73cd6068 100644 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/config/Config.java +++ b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/config/Config.java @@ -14,7 +14,6 @@ import com.google.common.collect.HashMultimap; import com.google.common.collect.Lists; import com.google.common.collect.Maps; import com.google.common.collect.Multimap; -import org.opendaylight.controller.config.api.ServiceReferenceReadableRegistry; import org.opendaylight.controller.config.api.jmx.ObjectNameUtil; import org.opendaylight.controller.netconf.confignetconfconnector.operations.editconfig.EditStrategyType; import org.opendaylight.controller.netconf.util.xml.XmlElement; @@ -99,7 +98,7 @@ public class Config { // } public Element toXml(Set instancesToMap, Optional maybeNamespace, Document document, - Element dataElement, Services serviceTracker) { + Element dataElement, ServiceRegistryWrapper serviceTracker) { Map>> moduleToInstances = getMappedInstances(instancesToMap, moduleConfigs); @@ -120,81 +119,84 @@ public class Config { ModuleConfig mapping = moduleConfigs.get(moduleNamespace).get(moduleMappingEntry.getKey()); if (moduleMappingEntry.getValue().isEmpty()) { - addEmptyModulesCommented(document, modulesElement, moduleNamespace, moduleMappingEntry); - } else { - for (ObjectName objectName : moduleMappingEntry.getValue()) { - modulesElement - .appendChild(mapping.toXml(objectName, serviceTracker, document, moduleNamespace)); - } + continue; + } + + for (ObjectName objectName : moduleMappingEntry.getValue()) { + modulesElement.appendChild(mapping.toXml(objectName, serviceTracker, document, moduleNamespace)); } } } - root.appendChild(serviceTracker.toXml(serviceTracker.getMappedServices(), document)); + root.appendChild(Services.toXml(serviceTracker, document)); return root; } - // TODO remove commented modules from output - private void addEmptyModulesCommented(Document document, Element root, String moduleNamespace, - Entry> moduleMappingEntry) { - Element emptyModule = document.createElement(XmlNetconfConstants.MODULE_KEY); - - Element typeElement = XmlUtil.createTextElement(document, XmlNetconfConstants.TYPE_KEY, - moduleMappingEntry.getKey()); - emptyModule.appendChild(typeElement); - - root.appendChild(document.createComment(XmlUtil.toString(emptyModule, false))); - } - // TODO refactor, replace string representing namespace with namespace class // TODO refactor, replace Map->Multimap with e.g. ConfigElementResolved // class - public ConfigElementResolved fromXml(XmlElement xml, - EditStrategyType defaultEditStrategyType, ServiceReferenceReadableRegistry taClient) { - Map> retVal = Maps.newHashMap(); - List recognisedChildren = Lists.newArrayList(); + public Map> fromXmlModulesResolved(XmlElement xml, EditStrategyType defaultEditStrategyType, ServiceRegistryWrapper serviceTracker) { + Optional modulesElement = getModulesElement(xml); + List moduleElements = getModulesElementList(modulesElement); - Services serviceTracker = fromXmlServices(xml, recognisedChildren, taClient); - List moduleElements = fromXmlModules(xml, recognisedChildren); - - xml.checkUnrecognisedElements(recognisedChildren); + Map> retVal = Maps.newHashMap(); for (XmlElement moduleElement : moduleElements) { - resolveModule(retVal, serviceTracker, moduleElement, defaultEditStrategyType); - } + ResolvingStrategy resolvingStrategy = new ResolvingStrategy() { + @Override + public ModuleElementResolved resolveElement(ModuleConfig moduleMapping, XmlElement moduleElement, ServiceRegistryWrapper serviceTracker, String instanceName, String moduleNamespace, EditStrategyType defaultStrategy) { + return moduleMapping.fromXml(moduleElement, serviceTracker, + instanceName, moduleNamespace, defaultStrategy); + } + }; - return new ConfigElementResolved(retVal, serviceTracker); + resolveModule(retVal, serviceTracker, moduleElement, defaultEditStrategyType, resolvingStrategy); + } + return retVal; } - public static class ConfigElementResolved { + /** + * return a map containing namespace -> moduleName -> instanceName map. Attribute parsing is omitted. + */ + public Map> fromXmlModulesMap(XmlElement xml, + EditStrategyType defaultEditStrategyType, ServiceRegistryWrapper serviceTracker) { + Optional modulesElement = getModulesElement(xml); + List moduleElements = getModulesElementList(modulesElement); - private final Map> resolvedModules; - private final Services services; + Map> retVal = Maps.newHashMap(); - public ConfigElementResolved(Map> retVal, Services serviceTracker) { - this.resolvedModules = retVal; - this.services = serviceTracker; - } + for (XmlElement moduleElement : moduleElements) { + ResolvingStrategy resolvingStrategy = new ResolvingStrategy() { + @Override + public ModuleElementDefinition resolveElement(ModuleConfig moduleMapping, XmlElement moduleElement, + ServiceRegistryWrapper serviceTracker, String instanceName, String moduleNamespace, + EditStrategyType defaultStrategy) { + // TODO: add check for conflicts between global and local + // edit strategy + String perInstanceEditStrategy = moduleElement.getAttribute(XmlNetconfConstants.OPERATION_ATTR_KEY, + XmlNetconfConstants.URN_IETF_PARAMS_XML_NS_NETCONF_BASE_1_0); + return new ModuleElementDefinition(instanceName, perInstanceEditStrategy, defaultStrategy); + } + }; - public Map> getResolvedModules() { - return resolvedModules; + resolveModule(retVal, serviceTracker, moduleElement, defaultEditStrategyType, resolvingStrategy); } + return retVal; + } - public Services getServices() { - return services; - } + private static Optional getModulesElement(XmlElement xml) { + return xml.getOnlyChildElementOptionally(XmlNetconfConstants.MODULES_KEY, + XmlNetconfConstants.URN_OPENDAYLIGHT_PARAMS_XML_NS_YANG_CONTROLLER_CONFIG); } - private List fromXmlModules(XmlElement xml, List recognisedChildren) { - Optional modulesElement = xml.getOnlyChildElementOptionally(XmlNetconfConstants.MODULES_KEY, - XmlNetconfConstants.URN_OPENDAYLIGHT_PARAMS_XML_NS_YANG_CONTROLLER_CONFIG); + private List getModulesElementList(Optional modulesElement) { List moduleElements; + if (modulesElement.isPresent()) { moduleElements = modulesElement.get().getChildElementsWithSameNamespace(XmlNetconfConstants.MODULE_KEY); - recognisedChildren.add(modulesElement.get()); modulesElement.get().checkUnrecognisedElements(moduleElements); } else { moduleElements = Lists.newArrayList(); @@ -202,8 +204,8 @@ public class Config { return moduleElements; } - private void resolveModule(Map> retVal, Services serviceTracker, - XmlElement moduleElement, EditStrategyType defaultStrategy) { + private void resolveModule(Map> retVal, ServiceRegistryWrapper serviceTracker, + XmlElement moduleElement, EditStrategyType defaultStrategy, ResolvingStrategy resolvingStrategy) { XmlElement typeElement = moduleElement.getOnlyChildElementWithSameNamespace(XmlNetconfConstants.TYPE_KEY); Entry prefixToNamespace = typeElement.findNamespaceOfTextContent(); String moduleNamespace = prefixToNamespace.getValue(); @@ -215,35 +217,49 @@ public class Config { ModuleConfig moduleMapping = getModuleMapping(moduleNamespace, instanceName, factoryName); - Multimap innerMap = retVal.get(moduleNamespace); + Multimap innerMap = retVal.get(moduleNamespace); if (innerMap == null) { innerMap = HashMultimap.create(); retVal.put(moduleNamespace, innerMap); } - ModuleElementResolved moduleElementResolved = moduleMapping.fromXml(moduleElement, serviceTracker, + T resolvedElement = resolvingStrategy.resolveElement(moduleMapping, moduleElement, serviceTracker, instanceName, moduleNamespace, defaultStrategy); - innerMap.put(factoryName, moduleElementResolved); + innerMap.put(factoryName, resolvedElement); } - private Services fromXmlServices(XmlElement xml, List recognisedChildren, - ServiceReferenceReadableRegistry taClient) { - Optional servicesElement = xml.getOnlyChildElementOptionally(XmlNetconfConstants.SERVICES_KEY, - XmlNetconfConstants.URN_OPENDAYLIGHT_PARAMS_XML_NS_YANG_CONTROLLER_CONFIG); + public Services fromXmlServices(XmlElement xml) { + Optional servicesElement = getServicesElement(xml); - Map>> mappedServices; + Services services; if (servicesElement.isPresent()) { - mappedServices = Services.fromXml(servicesElement.get()); - recognisedChildren.add(servicesElement.get()); + services = Services.fromXml(servicesElement.get()); } else { - mappedServices = new HashMap<>(); + services = new Services(); } - Services services = Services.resolveServices(mappedServices, taClient); return services; } + private static Optional getServicesElement(XmlElement xml) { + return xml.getOnlyChildElementOptionally(XmlNetconfConstants.SERVICES_KEY, + XmlNetconfConstants.URN_OPENDAYLIGHT_PARAMS_XML_NS_YANG_CONTROLLER_CONFIG); + } + + public static void checkUnrecognisedChildren(XmlElement parent) { + Optional servicesOpt = getServicesElement(parent); + Optional modulesOpt = getModulesElement(parent); + + List recognised = Lists.newArrayList(); + if(servicesOpt.isPresent()) + recognised.add(servicesOpt.get()); + if(modulesOpt.isPresent()) + recognised.add(modulesOpt.get()); + + parent.checkUnrecognisedElements(recognised); + } + private String getFactoryName(String factoryNameWithPrefix, String prefixOrEmptyString) { checkState( factoryNameWithPrefix.startsWith(prefixOrEmptyString), @@ -271,4 +287,8 @@ public class Config { return moduleMapping; } + private interface ResolvingStrategy { + public T resolveElement(ModuleConfig moduleMapping, XmlElement moduleElement, ServiceRegistryWrapper serviceTracker, + String instanceName, String moduleNamespace, EditStrategyType defaultStrategy); + } } diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/config/InstanceConfig.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/config/InstanceConfig.java index aae1636165..b8870e51ce 100644 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/config/InstanceConfig.java +++ b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/config/InstanceConfig.java @@ -52,7 +52,7 @@ public final class InstanceConfig { this.configRegistryClient = configRegistryClient; } - private Map getMappedConfiguration(ObjectName on, Services depTracker) { + private Map getMappedConfiguration(ObjectName on, ServiceRegistryWrapper depTracker) { // TODO make field, mappingStrategies can be instantiated only once Map>> mappingStrategies = new ObjectMapper(depTracker) @@ -84,7 +84,7 @@ public final class InstanceConfig { return toXml; } - public Element toXml(ObjectName on, Services depTracker, String namespace, Document document, Element rootElement) { + public Element toXml(ObjectName on, ServiceRegistryWrapper depTracker, String namespace, Document document, Element rootElement) { Element cfgElement = rootElement; @@ -104,7 +104,7 @@ public final class InstanceConfig { return cfgElement; } - private void resolveConfiguration(InstanceConfigElementResolved mappedConfig, Services depTracker) { + private void resolveConfiguration(InstanceConfigElementResolved mappedConfig, ServiceRegistryWrapper depTracker) { // TODO make field, resolvingStrategies can be instantiated only once Map>> resolvingStrategies = new ObjectResolver( @@ -128,7 +128,7 @@ public final class InstanceConfig { } } - public InstanceConfigElementResolved fromXml(XmlElement moduleElement, Services services, String moduleNamespace, + public InstanceConfigElementResolved fromXml(XmlElement moduleElement, ServiceRegistryWrapper services, String moduleNamespace, EditStrategyType defaultStrategy, Multimap providedServices) { Map retVal = Maps.newHashMap(); diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/config/InstanceConfigElementResolved.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/config/InstanceConfigElementResolved.java index 55cb60bed5..0bb4191bf2 100644 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/config/InstanceConfigElementResolved.java +++ b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/config/InstanceConfigElementResolved.java @@ -28,7 +28,7 @@ public class InstanceConfigElementResolved { private final Multimap providedServices; public InstanceConfigElementResolved(String currentStrategy, Map configuration, EditStrategyType defaultStrategy, Multimap providedServices) { - EditStrategyType valueOf = checkStrategy(currentStrategy, defaultStrategy); + EditStrategyType valueOf = parseStrategy(currentStrategy, defaultStrategy); this.editStrategy = valueOf; this.configuration = configuration; this.providedServices = providedServices; @@ -41,19 +41,19 @@ public class InstanceConfigElementResolved { } - EditStrategyType checkStrategy(String currentStrategy, EditStrategyType defaultStrategy) { - EditStrategyType valueOf = EditStrategyType.valueOf(currentStrategy); + static EditStrategyType parseStrategy(String currentStrategy, EditStrategyType defaultStrategy) { + EditStrategyType parsedStrategy = EditStrategyType.valueOf(currentStrategy); if (defaultStrategy.isEnforcing()) { Preconditions .checkArgument( - valueOf == defaultStrategy, + parsedStrategy == defaultStrategy, "With " + defaultStrategy + " as " + EditConfigXmlParser.DEFAULT_OPERATION_KEY + " operations on module elements are not permitted since the default option is restrictive"); } - return valueOf; + return parsedStrategy; } diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/config/ModuleConfig.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/config/ModuleConfig.java index 2ac6fe0a9b..48ff835a45 100644 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/config/ModuleConfig.java +++ b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/config/ModuleConfig.java @@ -53,7 +53,7 @@ public class ModuleConfig { return providedServices; } - public Element toXml(ObjectName instanceON, Services depTracker, Document document, String namespace) { + public Element toXml(ObjectName instanceON, ServiceRegistryWrapper depTracker, Document document, String namespace) { Element root = document.createElement(XmlNetconfConstants.MODULE_KEY); // Xml.addNamespaceAttr(document, root, namespace); @@ -84,7 +84,7 @@ public class ModuleConfig { } - public ModuleElementResolved fromXml(XmlElement moduleElement, Services depTracker, String instanceName, + public ModuleElementResolved fromXml(XmlElement moduleElement, ServiceRegistryWrapper depTracker, String instanceName, String moduleNamespace, EditStrategyType defaultStrategy) { InstanceConfigElementResolved ice = instanceConfig.fromXml(moduleElement, depTracker, moduleNamespace, defaultStrategy, providedServices); diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/config/ModuleElementDefinition.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/config/ModuleElementDefinition.java new file mode 100644 index 0000000000..9111701ba0 --- /dev/null +++ b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/config/ModuleElementDefinition.java @@ -0,0 +1,48 @@ +/* + * 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.netconf.confignetconfconnector.mapping.config; + +import org.opendaylight.controller.netconf.confignetconfconnector.operations.editconfig.EditConfigStrategy; +import org.opendaylight.controller.netconf.confignetconfconnector.operations.editconfig.EditStrategyType; +import org.opendaylight.controller.netconf.confignetconfconnector.operations.editconfig.MissingInstanceHandlingStrategy; +import org.opendaylight.controller.netconf.confignetconfconnector.operations.editconfig.NoneEditConfigStrategy; + +public class ModuleElementDefinition { + + public static final NoneEditConfigStrategy NONE_EDIT_CONFIG_STRATEGY = new NoneEditConfigStrategy(); + public static final MissingInstanceHandlingStrategy MISSING_INSTANCE_HANDLING_STRATEGY = new MissingInstanceHandlingStrategy(); + + private final String instanceName; + private final EditStrategyType editStrategy; + + public ModuleElementDefinition(String instanceName, String currentStrategy, EditStrategyType defaultStrategy) { + this.instanceName = instanceName; + if (currentStrategy == null || currentStrategy.isEmpty()) + this.editStrategy = defaultStrategy; + else + this.editStrategy = InstanceConfigElementResolved.parseStrategy(currentStrategy, defaultStrategy); + } + + public String getInstanceName() { + return instanceName; + } + + public EditStrategyType getEditStrategyType() { + return editStrategy; + } + + public EditConfigStrategy getEditStrategy() { + switch (editStrategy) { + case delete : + case remove : + case none : return NONE_EDIT_CONFIG_STRATEGY; + default : return MISSING_INSTANCE_HANDLING_STRATEGY; + } + } +} diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/config/ServiceRegistryWrapper.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/config/ServiceRegistryWrapper.java new file mode 100644 index 0000000000..7df671297c --- /dev/null +++ b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/config/ServiceRegistryWrapper.java @@ -0,0 +1,159 @@ +/* + * 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.netconf.confignetconfconnector.mapping.config; + +import com.google.common.annotations.VisibleForTesting; +import com.google.common.base.Preconditions; +import com.google.common.collect.Maps; +import com.google.common.collect.Sets; +import org.opendaylight.controller.config.api.ServiceReferenceReadableRegistry; + +import javax.management.InstanceNotFoundException; +import javax.management.ObjectName; +import java.util.Collection; +import java.util.Collections; +import java.util.Map; +import java.util.Set; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +public class ServiceRegistryWrapper { + + private ServiceReferenceReadableRegistry configServiceRefRegistry; + + private long suffix = 1; + + public ServiceRegistryWrapper(ServiceReferenceReadableRegistry configServiceRefRegistry) { + this.configServiceRefRegistry = configServiceRefRegistry; + } + + + public boolean hasRefName(String namespace, String serviceName, ObjectName on) { + String qname = configServiceRefRegistry.getServiceInterfaceName(namespace, serviceName); + Map forQName = configServiceRefRegistry.getServiceMapping().get(qname); + if(forQName==null) return false; + return forQName.values().contains(on); + } + + public ObjectName getByServiceAndRefName(String namespace, String serviceName, String refName) { + Map> serviceNameToRefNameToInstance = getMappedServices().get(namespace); + + Preconditions.checkArgument(serviceNameToRefNameToInstance != null, "No serviceInstances mapped to " + namespace); + + Map refNameToInstance = serviceNameToRefNameToInstance.get(serviceName); + Preconditions.checkArgument(refNameToInstance != null, "No serviceInstances mapped to " + serviceName + " , " + + serviceNameToRefNameToInstance.keySet()); + + String instanceId = refNameToInstance.get(refName); + Preconditions.checkArgument(instanceId != null, "No serviceInstances mapped to " + serviceName + ":" + + refName + ", " + serviceNameToRefNameToInstance.keySet()); + + Services.ServiceInstance serviceInstance = Services.ServiceInstance.fromString(instanceId); + Preconditions.checkArgument(serviceInstance != null, "No serviceInstance mapped to " + refName + + " under service name " + serviceName + " , " + refNameToInstance.keySet()); + + String qNameOfService = configServiceRefRegistry.getServiceInterfaceName(namespace, serviceName); + try { + return configServiceRefRegistry.getServiceReference(qNameOfService, refName); + } catch (InstanceNotFoundException e) { + throw new IllegalArgumentException("No serviceInstance mapped to " + refName + + " under service name " + serviceName + " , " + refNameToInstance.keySet(), e); + + } + } + + public Map>> getMappedServices() { + Map>> retVal = Maps.newHashMap(); + + Map> serviceMapping = configServiceRefRegistry.getServiceMapping(); + for (String serviceQName : serviceMapping.keySet()) + for (String refName : serviceMapping.get(serviceQName).keySet()) { + + ObjectName on = serviceMapping.get(serviceQName).get(refName); + Services.ServiceInstance si = Services.ServiceInstance.fromObjectName(on); + + // FIXME use QName's new String constructor, after it is fixed +// QName qname; +// try { +// qname = new QName(serviceQName); +// } catch (ParseException e) { +// throw new IllegalStateException("Unable to parse qname of a service " + serviceQName, e); +// } + Pattern p = Pattern.compile("\\(([^\\(\\?]+)\\?[^\\?\\)]*\\)([^\\)]+)"); + Matcher matcher = p.matcher(serviceQName); + Preconditions.checkArgument(matcher.matches()); + String namespace = matcher.group(1); + String localName = matcher.group(2); + +// String namespace = qname.getNamespace().toString(); + Map> serviceToRefs = retVal.get(namespace); + if(serviceToRefs==null) { + serviceToRefs = Maps.newHashMap(); + retVal.put(namespace, serviceToRefs); + } + +// String localName = qname.getLocalName(); + Map refsToSis = serviceToRefs.get(localName); + if(refsToSis==null) { + refsToSis = Maps.newHashMap(); + serviceToRefs.put(localName, refsToSis); + } + + Preconditions.checkState(refsToSis.containsKey(refName) == false, + "Duplicate reference name %s for service %s:%s, now for instance %s", refName, namespace, + localName, on); + refsToSis.put(refName, si.toString()); + } + + return retVal; + } + + @VisibleForTesting + public String getNewDefaultRefName(String namespace, String serviceName, String moduleName, String instanceName) { + String refName; + refName = "ref_" + instanceName; + + Map> serviceNameToRefNameToInstance = getMappedServices().get(namespace); + + Map refNameToInstance; + if(serviceNameToRefNameToInstance == null || serviceNameToRefNameToInstance.containsKey(serviceName) == false) { + refNameToInstance = Collections.emptyMap(); + } else + refNameToInstance = serviceNameToRefNameToInstance.get(serviceName); + + final Set refNamesAsSet = toSet(refNameToInstance.keySet()); + if (refNamesAsSet.contains(refName)) { + refName = findAvailableRefName(refName, refNamesAsSet); + } + + return refName; + } + + + private Set toSet(Collection values) { + Set refNamesAsSet = Sets.newHashSet(); + + for (String refName : values) { + boolean resultAdd = refNamesAsSet.add(refName); + Preconditions.checkState(resultAdd, + "Error occurred building services element, reference name {} was present twice", refName); + } + + return refNamesAsSet; + } + + private String findAvailableRefName(String refName, Set refNamesAsSet) { + String intitialRefName = refName; + + while (true) { + refName = intitialRefName + "_" + suffix++; + if (refNamesAsSet.contains(refName) == false) + return refName; + } + } +} diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/config/Services.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/config/Services.java index 77f3cf283f..7de7ea8c71 100644 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/config/Services.java +++ b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/config/Services.java @@ -8,14 +8,8 @@ package org.opendaylight.controller.netconf.confignetconfconnector.mapping.config; -import com.google.common.annotations.VisibleForTesting; -import com.google.common.base.Optional; import com.google.common.base.Preconditions; -import com.google.common.collect.HashMultimap; import com.google.common.collect.Maps; -import com.google.common.collect.Multimap; -import com.google.common.collect.Sets; -import org.opendaylight.controller.config.api.ServiceReferenceReadableRegistry; import org.opendaylight.controller.config.api.jmx.ObjectNameUtil; import org.opendaylight.controller.netconf.confignetconfconnector.mapping.attributes.fromxml.ObjectNameAttributeReadingStrategy; import org.opendaylight.controller.netconf.util.xml.XmlElement; @@ -27,12 +21,9 @@ import org.w3c.dom.Document; import org.w3c.dom.Element; import javax.management.ObjectName; -import java.util.Collection; -import java.util.Collections; import java.util.List; import java.util.Map; import java.util.Map.Entry; -import java.util.Set; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -45,124 +36,8 @@ public final class Services { public static final String TYPE_KEY = "type"; public static final String SERVICE_KEY = "service"; - private long suffix = 1; - private final Map>> namespaceToServiceNameToRefNameToInstance = Maps .newHashMap(); - private ServiceReferenceReadableRegistry configServiceRefRegistry; - - public Services(ServiceReferenceReadableRegistry configServiceRefRegistry) { - this.configServiceRefRegistry = configServiceRefRegistry; - } - - @VisibleForTesting - public String getNewDefaultRefName(String namespace, String serviceName, String moduleName, String instanceName) { - String refName; - refName = "ref_" + instanceName; - - Map> serviceNameToRefNameToInstance = getMappedServices().get(namespace); - - Map refNameToInstance; - if(serviceNameToRefNameToInstance == null || serviceNameToRefNameToInstance.containsKey(serviceName) == false) { - refNameToInstance = Collections.emptyMap(); - } else - refNameToInstance = serviceNameToRefNameToInstance.get(serviceName); - - final Set refNamesAsSet = toSet(refNameToInstance.keySet()); - if (refNamesAsSet.contains(refName)) { - refName = findAvailableRefName(refName, refNamesAsSet); - } - - return refName; - } - - private Set toSet(Collection values) { - Set refNamesAsSet = Sets.newHashSet(); - - for (String refName : values) { - boolean resultAdd = refNamesAsSet.add(refName); - Preconditions.checkState(resultAdd, - "Error occurred building services element, reference name {} was present twice", refName); - } - - return refNamesAsSet; - } - - public ServiceInstance getByServiceAndRefName(String namespace, String serviceName, String refName) { - Map> serviceNameToRefNameToInstance = getMappedServices().get(namespace); - - Preconditions.checkArgument(serviceNameToRefNameToInstance != null, "No serviceInstances mapped to " + namespace); - - Map refNameToInstance = serviceNameToRefNameToInstance.get(serviceName); - Preconditions.checkArgument(refNameToInstance != null, "No serviceInstances mapped to " + serviceName + " , " - + serviceNameToRefNameToInstance.keySet()); - - String instanceId = refNameToInstance.get(refName); - Preconditions.checkArgument(instanceId != null, "No serviceInstances mapped to " + serviceName + ":" - + refName + ", " + serviceNameToRefNameToInstance.keySet()); - - ServiceInstance serviceInstance = ServiceInstance.fromString(instanceId); - Preconditions.checkArgument(serviceInstance != null, "No serviceInstance mapped to " + refName - + " under service name " + serviceName + " , " + refNameToInstance.keySet()); - return serviceInstance; - } - - // TODO hide getMappedServices, call it explicitly in toXml - - public Map>> getMappedServices() { - Map>> retVal = Maps.newHashMap(); - - for (String namespace : namespaceToServiceNameToRefNameToInstance.keySet()) { - - Map> serviceNameToRefNameToInstance = namespaceToServiceNameToRefNameToInstance - .get(namespace); - Map> innerRetVal = Maps.newHashMap(); - - for (String serviceName : serviceNameToRefNameToInstance.keySet()) { - - Map innerInnerRetVal = Maps.newHashMap(); - for (Entry refNameToSi : serviceNameToRefNameToInstance.get(serviceName).entrySet()) { - innerInnerRetVal.put(refNameToSi.getKey(), refNameToSi.getValue().toString()); - } - innerRetVal.put(serviceName, innerInnerRetVal); - } - retVal.put(namespace, innerRetVal); - } - - Map> serviceMapping = configServiceRefRegistry.getServiceMapping(); - for (String serviceQName : serviceMapping.keySet()) - for (String refName : serviceMapping.get(serviceQName).keySet()) { - - ObjectName on = serviceMapping.get(serviceQName).get(refName); - ServiceInstance si = ServiceInstance.fromObjectName(on); - - // FIXME use QName's new String constructor, after its implemented - Pattern p = Pattern.compile("\\(([^\\(\\?]+)\\?[^\\?\\)]*\\)([^\\)]+)"); - Matcher matcher = p.matcher(serviceQName); - Preconditions.checkArgument(matcher.matches()); - String namespace = matcher.group(1); - String localName = matcher.group(2); - - Map> serviceToRefs = retVal.get(namespace); - if(serviceToRefs==null) { - serviceToRefs = Maps.newHashMap(); - retVal.put(namespace, serviceToRefs); - } - - Map refsToSis = serviceToRefs.get(localName); - if(refsToSis==null) { - refsToSis = Maps.newHashMap(); - serviceToRefs.put(localName, refsToSis); - } - - Preconditions.checkState(refsToSis.containsKey(refName) == false, - "Duplicate reference name %s for service %s:%s, now for instance %s", refName, namespace, - localName, on); - refsToSis.put(refName, si.toString()); - } - - return retVal; - } /** * @@ -171,10 +46,8 @@ public final class Services { return namespaceToServiceNameToRefNameToInstance; } - // TODO hide resolveServices, call it explicitly in fromXml - - public static Services resolveServices(Map>> mappedServices, ServiceReferenceReadableRegistry taClient) { - Services tracker = new Services(taClient); + private static Services resolveServices(Map>> mappedServices) { + Services tracker = new Services(); for (Entry>> namespaceEntry : mappedServices.entrySet()) { String namespace = namespaceEntry.getKey(); @@ -210,7 +83,7 @@ public final class Services { // TODO support edit strategies on services - public static Map>> fromXml(XmlElement xml) { + public static Services fromXml(XmlElement xml) { Map>> retVal = Maps.newHashMap(); List services = xml.getChildElements(SERVICE_KEY); @@ -250,23 +123,14 @@ public final class Services { } } - return retVal; - } - - private String findAvailableRefName(String refName, Set refNamesAsSet) { - String intitialRefName = refName; - - while (true) { - refName = intitialRefName + "_" + suffix++; - if (refNamesAsSet.contains(refName) == false) - return refName; - } + return resolveServices(retVal); } - public Element toXml(Map>> mappedServices, Document document) { + public static Element toXml(ServiceRegistryWrapper serviceRegistryWrapper, Document document) { Element root = document.createElement(XmlNetconfConstants.SERVICES_KEY); XmlUtil.addNamespaceAttr(root, XmlNetconfConstants.URN_OPENDAYLIGHT_PARAMS_XML_NS_YANG_CONTROLLER_CONFIG); + Map>> mappedServices = serviceRegistryWrapper.getMappedServices(); for (String namespace : mappedServices.keySet()) { for (Entry> serviceEntry : mappedServices.get(namespace).entrySet()) { @@ -294,51 +158,6 @@ public final class Services { return root; } - public String getRefName(String namespace, String serviceName, ObjectName on, Optional expectedRefName) { - Optional refNameOptional = getRefNameOptional(namespace, serviceName, on, expectedRefName); - Preconditions.checkState(refNameOptional.isPresent(), "No reference names mapped to %s, %s, %s", namespace, - serviceName, on); - return refNameOptional.get(); - } - - public Optional getRefNameOptional(String namespace, String serviceName, ObjectName on, - Optional expectedRefName) { - Map> services = getMappedServices().get(namespace); - - if(services == null) return Optional.absent(); - Map refs = services.get(serviceName); - - if(refs == null) return Optional.absent(); - Multimap reverted = revertMap(refs); - - ServiceInstance serviceInstance = ServiceInstance.fromObjectName(on); - Collection references = reverted.get(serviceInstance); - - if (expectedRefName.isPresent() && references.contains(expectedRefName.get())) { - logger.debug("Returning expected ref name {} for {}", expectedRefName.get(), on); - return expectedRefName; - } else if (references.size() > 0) { - String next = references.iterator().next(); - logger.debug("Returning random ref name {} for {}", next, on); - return Optional.of(next); - } else - return Optional.absent(); - } - - private Multimap revertMap(Map refs) { - Multimap multimap = HashMultimap.create(); - - for (Entry e : refs.entrySet()) { - multimap.put(ServiceInstance.fromString(e.getValue()), e.getKey()); - } - - return multimap; - } - - public boolean hasRefName(String key, String value, ObjectName on) { - return getRefNameOptional(key, value, on, Optional.absent()).isPresent(); - } - public static final class ServiceInstance { public ServiceInstance(String moduleName, String instanceName) { this.moduleName = moduleName; diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/runtime/InstanceRuntime.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/runtime/InstanceRuntime.java index 70b10d0019..6a0d7508c8 100644 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/runtime/InstanceRuntime.java +++ b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/runtime/InstanceRuntime.java @@ -88,7 +88,6 @@ public class InstanceRuntime { public Element toXml(ObjectName rootOn, Set childRbeOns, Document document, String instanceIndex, Element parentElement, String namespace) { - // TODO namespace Element xml = instanceMapping.toXml(rootOn, null, namespace, document, parentElement); if (instanceIndex != null) { diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/runtime/ModuleRuntime.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/runtime/ModuleRuntime.java index 11e97ebdbb..4936d1dbcd 100644 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/runtime/ModuleRuntime.java +++ b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/runtime/ModuleRuntime.java @@ -10,7 +10,7 @@ package org.opendaylight.controller.netconf.confignetconfconnector.mapping.runti import com.google.common.collect.Sets; import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.ModuleConfig; -import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.Services; +import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.ServiceRegistryWrapper; import org.w3c.dom.Document; import org.w3c.dom.Element; @@ -41,7 +41,7 @@ public class ModuleRuntime { } public Element toXml(String namespace, Collection runtimeBeanOns, - Document document, ModuleConfig moduleConfig, ObjectName configBeanON, Services serviceTracker) { + Document document, ModuleConfig moduleConfig, ObjectName configBeanON, ServiceRegistryWrapper serviceTracker) { Element moduleElement = moduleConfig.toXml(configBeanON, serviceTracker, document, namespace); diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/runtime/Runtime.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/runtime/Runtime.java index 89c782c51c..129143835f 100644 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/runtime/Runtime.java +++ b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/runtime/Runtime.java @@ -11,11 +11,10 @@ package org.opendaylight.controller.netconf.confignetconfconnector.mapping.runti import com.google.common.collect.HashMultimap; import com.google.common.collect.Maps; import com.google.common.collect.Multimap; -import org.opendaylight.controller.config.api.ServiceReferenceReadableRegistry; import org.opendaylight.controller.config.api.jmx.ObjectNameUtil; import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.Config; import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.ModuleConfig; -import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.Services; +import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.ServiceRegistryWrapper; import org.opendaylight.controller.netconf.util.xml.XmlNetconfConstants; import org.opendaylight.controller.netconf.util.xml.XmlUtil; import org.w3c.dom.Document; @@ -61,9 +60,7 @@ public class Runtime { return retVal; } - public Element toXml(Set instancesToMap, Set configBeans, Document document, ServiceReferenceReadableRegistry serviceRegistry) { - Services serviceTracker = new Services(serviceRegistry); - + public Element toXml(Set instancesToMap, Set configBeans, Document document, ServiceRegistryWrapper serviceRegistry) { Element root = document.createElement(XmlNetconfConstants.DATA_KEY); Element modulesElement = document.createElement(XmlNetconfConstants.MODULES_KEY); @@ -88,11 +85,11 @@ public class Runtime { Element runtimeXml; ModuleConfig moduleConfig = moduleConfigs.get(localNamespace).get(moduleName); if(instanceToRbe==null || instanceToRbe.containsKey(instanceName) == false) { - runtimeXml = moduleConfig.toXml(instanceON, serviceTracker, document, localNamespace); + runtimeXml = moduleConfig.toXml(instanceON, serviceRegistry, document, localNamespace); } else { ModuleRuntime moduleRuntime = moduleRuntimes.get(localNamespace).get(moduleName); runtimeXml = moduleRuntime.toXml(localNamespace, instanceToRbe.get(instanceName), document, - moduleConfig, instanceON, serviceTracker); + moduleConfig, instanceON, serviceRegistry); } modulesElement.appendChild(runtimeXml); } diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/AbstractEditConfigStrategy.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/AbstractEditConfigStrategy.java index 65df965afd..1d37fcd493 100644 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/AbstractEditConfigStrategy.java +++ b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/AbstractEditConfigStrategy.java @@ -10,7 +10,7 @@ package org.opendaylight.controller.netconf.confignetconfconnector.operations.ed import org.opendaylight.controller.config.util.ConfigTransactionClient; import org.opendaylight.controller.netconf.confignetconfconnector.mapping.attributes.fromxml.AttributeConfigElement; -import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.Services; +import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.ServiceRegistryWrapper; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -24,7 +24,7 @@ public abstract class AbstractEditConfigStrategy implements EditConfigStrategy { @Override public void executeConfiguration(String module, String instance, Map configuration, - ConfigTransactionClient ta, Services services) { + ConfigTransactionClient ta, ServiceRegistryWrapper services) { try { ObjectName on = ta.lookupConfigBean(module, instance); @@ -36,10 +36,13 @@ public abstract class AbstractEditConfigStrategy implements EditConfigStrategy { } + // TODO split missing instances handling strategies from edit config strategies in this hierarchy = REFACTOR + // edit configs should not handle missing + abstract void handleMissingInstance(Map configuration, ConfigTransactionClient ta, - String module, String instance, Services services); + String module, String instance, ServiceRegistryWrapper services); abstract void executeStrategy(Map configuration, ConfigTransactionClient ta, - ObjectName objectName, Services services); + ObjectName objectName, ServiceRegistryWrapper services); } diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/DeleteEditConfigStrategy.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/DeleteEditConfigStrategy.java index 12beaf8f8e..13e8c30211 100644 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/DeleteEditConfigStrategy.java +++ b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/DeleteEditConfigStrategy.java @@ -12,7 +12,7 @@ import com.google.common.collect.HashMultimap; import com.google.common.collect.Multimap; import org.opendaylight.controller.config.util.ConfigTransactionClient; import org.opendaylight.controller.netconf.confignetconfconnector.mapping.attributes.fromxml.AttributeConfigElement; -import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.Services; +import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.ServiceRegistryWrapper; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -36,12 +36,12 @@ public class DeleteEditConfigStrategy extends AbstractEditConfigStrategy { @Override void handleMissingInstance(Map configuration, ConfigTransactionClient ta, - String module, String instance, Services services) { + String module, String instance, ServiceRegistryWrapper services) { throw new IllegalStateException("Unable to delete " + module + ":" + instance + " , ServiceInstance not found"); } @Override - void executeStrategy(Map configuration, ConfigTransactionClient ta, ObjectName on, Services services) { + void executeStrategy(Map configuration, ConfigTransactionClient ta, ObjectName on, ServiceRegistryWrapper services) { try { ta.destroyModule(on); logger.debug("ServiceInstance {} deleted successfully", on); diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/EditConfig.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/EditConfig.java index 1bb1d9bfba..709573c241 100644 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/EditConfig.java +++ b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/EditConfig.java @@ -25,6 +25,7 @@ import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.InstanceConfig; import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.InstanceConfigElementResolved; import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.ModuleConfig; +import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.ModuleElementDefinition; import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.ModuleElementResolved; import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.Services; import org.opendaylight.controller.netconf.confignetconfconnector.operations.AbstractConfigNetconfOperation; @@ -105,8 +106,8 @@ public class EditConfig extends AbstractConfigNetconfOperation { logger.debug("Test phase for {} operation successful", EditConfigXmlParser.EDIT_CONFIG); } - private void test(ConfigRegistryClient configRegistryClient, - EditConfigExecution execution, EditStrategyType editStrategyType) { + private void test(ConfigRegistryClient configRegistryClient, EditConfigExecution execution, + EditStrategyType editStrategyType) { ObjectName taON = transactionProvider.getTestTransaction(); try { @@ -115,8 +116,11 @@ public class EditConfig extends AbstractConfigNetconfOperation { transactionProvider.wipeTestTransaction(taON); } - setOnTransaction(configRegistryClient, execution.getResolvedXmlElements(), execution.getServices(), taON); - // TODO add service reference persistance testing here + ConfigTransactionClient ta = configRegistryClient.getConfigTransactionClient(taON); + + handleMisssingInstancesOnTransaction(ta, execution); + setServicesOnTransaction(ta, execution); + setOnTransaction(ta, execution); transactionProvider.validateTestTransaction(taON); } finally { transactionProvider.abortTestTransaction(taON); @@ -132,14 +136,16 @@ public class EditConfig extends AbstractConfigNetconfOperation { transactionProvider.wipeTransaction(); } - setOnTransaction(configRegistryClient, editConfigExecution.getResolvedXmlElements(), - editConfigExecution.getServices(), taON); - setServicesOnTransaction(configRegistryClient, editConfigExecution.getServices(), taON); + ConfigTransactionClient ta = configRegistryClient.getConfigTransactionClient(taON); + + handleMisssingInstancesOnTransaction(ta, editConfigExecution); + setServicesOnTransaction(ta, editConfigExecution); + setOnTransaction(ta, editConfigExecution); } - private void setServicesOnTransaction(ConfigRegistryClient configRegistryClient, Services services, - ObjectName taON) { - ConfigTransactionClient ta = configRegistryClient.getConfigTransactionClient(taON); + private void setServicesOnTransaction(ConfigTransactionClient ta, EditConfigExecution execution) { + + Services services = execution.getServices(); Map>> namespaceToServiceNameToRefNameToInstance = services .getNamespaceToServiceNameToRefNameToInstance(); @@ -153,9 +159,10 @@ public class EditConfig extends AbstractConfigNetconfOperation { for (String refName : refNameToInstance.keySet()) { ObjectName on = refNameToInstance.get(refName).getObjectName(ta.getTransactionName()); - // TODO check for duplicates try { - ta.saveServiceReference(qnameOfService, refName, on); + ObjectName saved = ta.saveServiceReference(qnameOfService, refName, on); + logger.debug("Saving service {} with on {} under name {} with service on {}", qnameOfService, + on, refName, saved); } catch (InstanceNotFoundException e) { throw new IllegalStateException("Unable to save ref name " + refName + " for instance " + on, e); } @@ -168,11 +175,10 @@ public class EditConfig extends AbstractConfigNetconfOperation { return ta.getServiceInterfaceName(namespace, serviceName); } - private void setOnTransaction(ConfigRegistryClient configRegistryClient, - Map> resolvedXmlElements, Services services, ObjectName taON) { - ConfigTransactionClient ta = configRegistryClient.getConfigTransactionClient(taON); + private void setOnTransaction(ConfigTransactionClient ta, EditConfigExecution execution) { + + for (Multimap modulesToResolved : execution.getResolvedXmlElements(ta).values()) { - for (Multimap modulesToResolved : resolvedXmlElements.values()) { for (Entry moduleToResolved : modulesToResolved.entries()) { String moduleName = moduleToResolved.getKey(); @@ -181,7 +187,22 @@ public class EditConfig extends AbstractConfigNetconfOperation { InstanceConfigElementResolved ice = moduleElementResolved.getInstanceConfigElementResolved(); EditConfigStrategy strategy = ice.getEditStrategy(); - strategy.executeConfiguration(moduleName, instanceName, ice.getConfiguration(), ta, services); + strategy.executeConfiguration(moduleName, instanceName, ice.getConfiguration(), ta, execution.getServiceRegistryWrapper(ta)); + } + } + } + + private void handleMisssingInstancesOnTransaction(ConfigTransactionClient ta, + EditConfigExecution execution) { + + for (Multimap modulesToResolved : execution.getModulesDefinition(ta).values()) { + for (Entry moduleToResolved : modulesToResolved.entries()) { + String moduleName = moduleToResolved.getKey(); + + ModuleElementDefinition moduleElementDefinition = moduleToResolved.getValue(); + + EditConfigStrategy strategy = moduleElementDefinition.getEditStrategy(); + strategy.executeConfiguration(moduleName, moduleElementDefinition.getInstanceName(), null, ta, execution.getServiceRegistryWrapper(ta)); } } } @@ -189,32 +210,38 @@ public class EditConfig extends AbstractConfigNetconfOperation { public static Config getConfigMapping(ConfigRegistryClient configRegistryClient, Map> mBeanEntries) { - Map> factories = transform(configRegistryClient, mBeanEntries); + Map> factories = transformMbeToModuleConfigs(configRegistryClient, mBeanEntries); return new Config(factories); } - // TODO refactor - private static Map> transform - (final ConfigRegistryClient configRegistryClient, Map> transformMbeToModuleConfigs + (final ConfigRegistryClient configRegistryClient, Map> mBeanEntries) { - return Maps.transformEntries(mBeanEntries, - new Maps.EntryTransformer, Map>() { - - @Override - public Map transformEntry(String arg0, Map arg1) { - return Maps.transformEntries(arg1, - new Maps.EntryTransformer() { - - @Override - public ModuleConfig transformEntry(String key, ModuleMXBeanEntry moduleMXBeanEntry) { - return new ModuleConfig(key, new InstanceConfig(configRegistryClient, moduleMXBeanEntry - .getAttributes()), moduleMXBeanEntry.getProvidedServices().values()); - } - }); - } - }); + + Map> namespaceToModuleNameToModuleConfig = Maps.newHashMap(); + + for (String namespace : mBeanEntries.keySet()) { + for (Entry moduleNameToMbe : mBeanEntries.get(namespace).entrySet()) { + String moduleName = moduleNameToMbe.getKey(); + ModuleMXBeanEntry moduleMXBeanEntry = moduleNameToMbe.getValue(); + + ModuleConfig moduleConfig = new ModuleConfig(moduleName, new InstanceConfig(configRegistryClient, + moduleMXBeanEntry.getAttributes()), moduleMXBeanEntry + .getProvidedServices().values()); + + Map moduleNameToModuleConfig = namespaceToModuleNameToModuleConfig.get(namespace); + if(moduleNameToModuleConfig == null) { + moduleNameToModuleConfig = Maps.newHashMap(); + namespaceToModuleNameToModuleConfig.put(namespace, moduleNameToModuleConfig); + } + + moduleNameToModuleConfig.put(moduleName, moduleConfig); + } + } + + return namespaceToModuleNameToModuleConfig; } @Override diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/EditConfigStrategy.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/EditConfigStrategy.java index 23166e8cca..cebcb0239b 100644 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/EditConfigStrategy.java +++ b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/EditConfigStrategy.java @@ -10,13 +10,13 @@ package org.opendaylight.controller.netconf.confignetconfconnector.operations.ed import org.opendaylight.controller.config.util.ConfigTransactionClient; import org.opendaylight.controller.netconf.confignetconfconnector.mapping.attributes.fromxml.AttributeConfigElement; -import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.Services; +import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.ServiceRegistryWrapper; import java.util.Map; public interface EditConfigStrategy { void executeConfiguration(String module, String instance, Map configuration, - ConfigTransactionClient ta, Services services); + ConfigTransactionClient ta, ServiceRegistryWrapper services); } diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/EditConfigXmlParser.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/EditConfigXmlParser.java index 81327133b8..e481bbe57f 100644 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/EditConfigXmlParser.java +++ b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/EditConfigXmlParser.java @@ -14,10 +14,11 @@ import com.google.common.base.Preconditions; import com.google.common.collect.Multimap; import org.opendaylight.controller.config.api.ServiceReferenceReadableRegistry; import org.opendaylight.controller.config.util.ConfigRegistryClient; -import org.opendaylight.controller.config.util.ConfigTransactionClient; import org.opendaylight.controller.netconf.api.NetconfDocumentedException; import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.Config; +import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.ModuleElementDefinition; import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.ModuleElementResolved; +import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.ServiceRegistryWrapper; import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.Services; import org.opendaylight.controller.netconf.confignetconfconnector.operations.Datastore; import org.opendaylight.controller.netconf.confignetconfconnector.transactions.TransactionProvider; @@ -26,7 +27,6 @@ import org.opendaylight.controller.netconf.util.xml.XmlNetconfConstants; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import javax.management.ObjectName; import java.util.Arrays; import java.util.Map; @@ -98,11 +98,7 @@ public class EditConfigXmlParser { XmlElement configElement = xml.getOnlyChildElementWithSameNamespace(XmlNetconfConstants.CONFIG_KEY); - ObjectName taON = transactionProvider.getOrCreateTransaction(); - ConfigTransactionClient ta = configRegistryClient.getConfigTransactionClient(taON); - - return new EditConfigXmlParser.EditConfigExecution(cfgMapping, configElement, testOption, - ta, editStrategyType); + return new EditConfigXmlParser.EditConfigExecution(cfgMapping, configElement, testOption, editStrategyType); } @VisibleForTesting @@ -132,15 +128,17 @@ public class EditConfigXmlParser { @VisibleForTesting static class EditConfigExecution { - private final Map> resolvedXmlElements; private final TestOption testOption; private final EditStrategyType defaultEditStrategyType; private final Services services; - - EditConfigExecution(Config configResolver, XmlElement configElement, TestOption testOption, ServiceReferenceReadableRegistry ta, EditStrategyType defaultStrategy) { - Config.ConfigElementResolved configElementResolved = configResolver.fromXml(configElement, defaultStrategy, ta); - this.resolvedXmlElements = configElementResolved.getResolvedModules(); - this.services = configElementResolved.getServices(); + private final Config configResolver; + private final XmlElement configElement; + + EditConfigExecution(Config configResolver, XmlElement configElement, TestOption testOption, EditStrategyType defaultStrategy) { + Config.checkUnrecognisedChildren(configElement); + this.configResolver = configResolver; + this.configElement = configElement; + this.services = configResolver.fromXmlServices(configElement); this.testOption = testOption; this.defaultEditStrategyType = defaultStrategy; } @@ -153,8 +151,17 @@ public class EditConfigXmlParser { return testOption == TestOption.set || testOption == TestOption.testThenSet; } - Map> getResolvedXmlElements() { - return resolvedXmlElements; + Map> getResolvedXmlElements(ServiceReferenceReadableRegistry serviceRegistry) { + return configResolver.fromXmlModulesResolved(configElement, defaultEditStrategyType, getServiceRegistryWrapper(serviceRegistry)); + } + + ServiceRegistryWrapper getServiceRegistryWrapper(ServiceReferenceReadableRegistry serviceRegistry) { + // TODO cache service registry + return new ServiceRegistryWrapper(serviceRegistry); + } + + Map> getModulesDefinition(ServiceReferenceReadableRegistry serviceRegistry) { + return configResolver.fromXmlModulesMap(configElement, defaultEditStrategyType, getServiceRegistryWrapper(serviceRegistry)); } EditStrategyType getDefaultStrategy() { diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/EditStrategyType.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/EditStrategyType.java index 676467553b..06560b2d27 100644 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/EditStrategyType.java +++ b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/EditStrategyType.java @@ -13,7 +13,6 @@ import com.google.common.collect.Multimap; import java.util.EnumSet; import java.util.Set; -//FIXME: make thread safe public enum EditStrategyType { // can be default merge, replace, none, diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/MergeEditConfigStrategy.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/MergeEditConfigStrategy.java index 06befb0565..f2e2b193a8 100644 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/MergeEditConfigStrategy.java +++ b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/MergeEditConfigStrategy.java @@ -10,14 +10,14 @@ package org.opendaylight.controller.netconf.confignetconfconnector.operations.ed import com.google.common.collect.HashMultimap; import com.google.common.collect.Multimap; +import org.opendaylight.controller.config.api.jmx.ObjectNameUtil; import org.opendaylight.controller.config.util.ConfigTransactionClient; import org.opendaylight.controller.netconf.confignetconfconnector.mapping.attributes.fromxml.AttributeConfigElement; -import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.Services; +import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.ServiceRegistryWrapper; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import javax.management.Attribute; -import javax.management.InstanceAlreadyExistsException; import javax.management.InstanceNotFoundException; import javax.management.ObjectName; import java.util.Map; @@ -38,22 +38,13 @@ public class MergeEditConfigStrategy extends AbstractEditConfigStrategy { @Override void handleMissingInstance(Map configuration, ConfigTransactionClient ta, - String module, String instance, Services services) { - ObjectName on = null; - try { - on = ta.createModule(module, instance); - logger.info("New instance for {} {} created under name {}", module, instance, on); - addRefNames(services, providedServices, module, instance, ta, on); - executeStrategy(configuration, ta, on, services); - } catch (InstanceAlreadyExistsException e1) { - throw new IllegalStateException("Unable to create instance for " + module + " : " + instance); - } catch (InstanceNotFoundException e) { - throw new IllegalStateException("Unable to save default ref name for instance " + on, e); - } + String module, String instance, ServiceRegistryWrapper services) { + throw new IllegalStateException( + "Unable to handle missing instance, no missing instances should appear at this point, missing: " + + module + ":" + instance); } - private void addRefNames(Services services, Multimap providedServices, String module, - String instance, ConfigTransactionClient ta, ObjectName on) throws InstanceNotFoundException { + private void addRefNames(ServiceRegistryWrapper services, Multimap providedServices, ConfigTransactionClient ta, ObjectName on) throws InstanceNotFoundException { for (Entry namespaceToService : providedServices.entries()) { if(services.hasRefName(namespaceToService.getKey(), @@ -61,14 +52,20 @@ public class MergeEditConfigStrategy extends AbstractEditConfigStrategy { continue; String refName = services.getNewDefaultRefName(namespaceToService.getKey(), namespaceToService.getValue(), - module, instance); + ObjectNameUtil.getFactoryName(on), ObjectNameUtil.getInstanceName(on)); ta.saveServiceReference( ta.getServiceInterfaceName(namespaceToService.getKey(), namespaceToService.getValue()), refName, on); } } @Override - void executeStrategy(Map configuration, ConfigTransactionClient ta, ObjectName on, Services services) { + void executeStrategy(Map configuration, ConfigTransactionClient ta, ObjectName on, ServiceRegistryWrapper services) { + try { + addRefNames(services, providedServices, ta, on); + } catch (InstanceNotFoundException e) { + throw new IllegalStateException("Unable to save default ref name for instance " + on, e); + } + for (Entry configAttributeEntry : configuration.entrySet()) { try { AttributeConfigElement ace = configAttributeEntry.getValue(); diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/MissingInstanceHandlingStrategy.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/MissingInstanceHandlingStrategy.java new file mode 100644 index 0000000000..8ed9eb8731 --- /dev/null +++ b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/MissingInstanceHandlingStrategy.java @@ -0,0 +1,42 @@ +/* + * 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.netconf.confignetconfconnector.operations.editconfig; + +import org.opendaylight.controller.config.util.ConfigTransactionClient; +import org.opendaylight.controller.netconf.confignetconfconnector.mapping.attributes.fromxml.AttributeConfigElement; +import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.ServiceRegistryWrapper; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import javax.management.InstanceAlreadyExistsException; +import javax.management.ObjectName; +import java.util.Map; + +public class MissingInstanceHandlingStrategy extends AbstractEditConfigStrategy { + + private static final Logger logger = LoggerFactory.getLogger(MissingInstanceHandlingStrategy.class); + + @Override + void handleMissingInstance(Map configuration, ConfigTransactionClient ta, + String module, String instance, ServiceRegistryWrapper services) { + ObjectName on = null; + try { + on = ta.createModule(module, instance); + logger.info("New instance for {} {} created under name {}", module, instance, on); + } catch (InstanceAlreadyExistsException e1) { + throw new IllegalStateException("Unable to create instance for " + module + " : " + instance); + } + } + + @Override + void executeStrategy(Map configuration, ConfigTransactionClient ta, + ObjectName objectName, ServiceRegistryWrapper services) { + return; + } +} diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/NoneEditConfigStrategy.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/NoneEditConfigStrategy.java index 8347c6b88e..bd182a4267 100644 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/NoneEditConfigStrategy.java +++ b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/NoneEditConfigStrategy.java @@ -8,21 +8,21 @@ package org.opendaylight.controller.netconf.confignetconfconnector.operations.editconfig; -import java.util.Map; - import org.opendaylight.controller.config.util.ConfigTransactionClient; import org.opendaylight.controller.netconf.confignetconfconnector.mapping.attributes.fromxml.AttributeConfigElement; -import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.Services; +import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.ServiceRegistryWrapper; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import java.util.Map; + public class NoneEditConfigStrategy implements EditConfigStrategy { private static final Logger logger = LoggerFactory.getLogger(NoneEditConfigStrategy.class); @Override public void executeConfiguration(String module, String instance, Map configuration, - ConfigTransactionClient ta, Services services) { + ConfigTransactionClient ta, ServiceRegistryWrapper services) { logger.debug("Skipping configuration element for {}:{}", module, instance); } diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/RemoveEditConfigStrategy.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/RemoveEditConfigStrategy.java index 64f082da40..df1f65372a 100644 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/RemoveEditConfigStrategy.java +++ b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/RemoveEditConfigStrategy.java @@ -10,7 +10,7 @@ package org.opendaylight.controller.netconf.confignetconfconnector.operations.ed import org.opendaylight.controller.config.util.ConfigTransactionClient; import org.opendaylight.controller.netconf.confignetconfconnector.mapping.attributes.fromxml.AttributeConfigElement; -import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.Services; +import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.ServiceRegistryWrapper; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -22,7 +22,7 @@ public class RemoveEditConfigStrategy extends DeleteEditConfigStrategy { @Override void handleMissingInstance(Map configuration, ConfigTransactionClient ta, - String module, String instance, Services services) { + String module, String instance, ServiceRegistryWrapper services) { logger.warn("Unable to delete {}:{}, ServiceInstance not found", module, instance); } } diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/ReplaceEditConfigStrategy.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/ReplaceEditConfigStrategy.java index 43d852e76a..4976244eae 100644 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/ReplaceEditConfigStrategy.java +++ b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/ReplaceEditConfigStrategy.java @@ -10,14 +10,14 @@ package org.opendaylight.controller.netconf.confignetconfconnector.operations.ed import com.google.common.collect.HashMultimap; import com.google.common.collect.Multimap; +import org.opendaylight.controller.config.api.jmx.ObjectNameUtil; import org.opendaylight.controller.config.util.ConfigTransactionClient; import org.opendaylight.controller.netconf.confignetconfconnector.mapping.attributes.fromxml.AttributeConfigElement; -import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.Services; +import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.ServiceRegistryWrapper; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import javax.management.Attribute; -import javax.management.InstanceAlreadyExistsException; import javax.management.InstanceNotFoundException; import javax.management.ObjectName; import java.util.Map; @@ -39,23 +39,13 @@ public class ReplaceEditConfigStrategy extends AbstractEditConfigStrategy { @Override void handleMissingInstance(Map configuration, ConfigTransactionClient ta, - String module, String instance, Services services) { - ObjectName on = null; - try { - on = ta.createModule(module, instance); - logger.debug("New instance for {} {} created under name {}", module, instance, on); - addRefNames(services, providedServices, module, instance, ta, on); - executeStrategy(configuration, ta, on, services); - } catch (InstanceAlreadyExistsException e) { - logger.warn("Error creating instance {}:{}, replace failed", module, instance, e); - throw new IllegalStateException("Unable to create new instance for " + module + " : " + instance, e); - } catch (InstanceNotFoundException e) { - throw new IllegalStateException("Unable to save default ref name for instance " + on, e); - } + String module, String instance, ServiceRegistryWrapper services) { + throw new IllegalStateException( + "Unable to handle missing instance, no missing instances should appear at this point, missing: " + + module + ":" + instance); } - private void addRefNames(Services services, Multimap providedServices, String module, - String instance, ConfigTransactionClient ta, ObjectName on) throws InstanceNotFoundException { + private void addRefNames(ServiceRegistryWrapper services, Multimap providedServices, ConfigTransactionClient ta, ObjectName on) throws InstanceNotFoundException { for (Entry namespaceToService : providedServices.entries()) { if(services.hasRefName(namespaceToService.getKey(), @@ -63,13 +53,20 @@ public class ReplaceEditConfigStrategy extends AbstractEditConfigStrategy { continue; String refName = services.getNewDefaultRefName(namespaceToService.getKey(), namespaceToService.getValue(), - module, instance); + ObjectNameUtil.getFactoryName(on), ObjectNameUtil.getInstanceName(on)); ta.saveServiceReference( ta.getServiceInterfaceName(namespaceToService.getKey(), namespaceToService.getValue()), refName, on); } } + @Override - void executeStrategy(Map configuration, ConfigTransactionClient ta, ObjectName on, Services services) { + void executeStrategy(Map configuration, ConfigTransactionClient ta, ObjectName on, ServiceRegistryWrapper services) { + try { + addRefNames(services, providedServices, ta, on); + } catch (InstanceNotFoundException e) { + throw new IllegalStateException("Unable to save default ref name for instance " + on, e); + } + for (Entry configAttributeEntry : configuration.entrySet()) { try { AttributeConfigElement ace = configAttributeEntry.getValue(); diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/get/Get.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/get/Get.java index efe4f7dde9..ea602091a0 100644 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/get/Get.java +++ b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/get/Get.java @@ -20,12 +20,13 @@ import org.opendaylight.controller.netconf.api.NetconfDocumentedException.ErrorT import org.opendaylight.controller.netconf.api.NetconfDocumentedException.ErrorType; import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.InstanceConfig; import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.ModuleConfig; +import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.ServiceRegistryWrapper; import org.opendaylight.controller.netconf.confignetconfconnector.mapping.runtime.InstanceRuntime; import org.opendaylight.controller.netconf.confignetconfconnector.mapping.runtime.ModuleRuntime; import org.opendaylight.controller.netconf.confignetconfconnector.mapping.runtime.Runtime; import org.opendaylight.controller.netconf.confignetconfconnector.operations.AbstractConfigNetconfOperation; import org.opendaylight.controller.netconf.confignetconfconnector.operations.Datastore; -import org.opendaylight.controller.netconf.confignetconfconnector.operations.getconfig.GetConfig; +import org.opendaylight.controller.netconf.confignetconfconnector.operations.editconfig.EditConfig; import org.opendaylight.controller.netconf.confignetconfconnector.transactions.TransactionProvider; import org.opendaylight.controller.netconf.util.xml.XmlElement; import org.opendaylight.controller.netconf.util.xml.XmlNetconfConstants; @@ -143,14 +144,14 @@ public class Get extends AbstractConfigNetconfOperation { final Map> moduleRuntimes = createModuleRuntimes(configRegistryClient, yangStoreSnapshot.getModuleMXBeanEntryMap()); - final Map> moduleConfigs = GetConfig.transform(configRegistryClient, - yangStoreSnapshot.getModuleMXBeanEntryMap()); + final Map> moduleConfigs = EditConfig.transformMbeToModuleConfigs( + configRegistryClient, yangStoreSnapshot.getModuleMXBeanEntryMap()); final Runtime runtime = new Runtime(moduleRuntimes, moduleConfigs); ObjectName txOn = transactionProvider.getOrCreateTransaction(); ConfigTransactionClient ta = configRegistryClient.getConfigTransactionClient(txOn); - final Element element = runtime.toXml(runtimeBeans, configBeans, document, ta); + final Element element = runtime.toXml(runtimeBeans, configBeans, document, new ServiceRegistryWrapper(ta)); logger.info("{} operation successful", XmlNetconfConstants.GET); diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/getconfig/GetConfig.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/getconfig/GetConfig.java index d75cfd5d6f..16dd5ad80a 100644 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/getconfig/GetConfig.java +++ b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/getconfig/GetConfig.java @@ -9,21 +9,18 @@ package org.opendaylight.controller.netconf.confignetconfconnector.operations.getconfig; import com.google.common.base.Optional; -import com.google.common.collect.Maps; import org.opendaylight.controller.config.util.ConfigRegistryClient; import org.opendaylight.controller.config.util.ConfigTransactionClient; import org.opendaylight.controller.config.yang.store.api.YangStoreSnapshot; -import org.opendaylight.controller.config.yangjmxgenerator.ModuleMXBeanEntry; import org.opendaylight.controller.netconf.api.NetconfDocumentedException; import org.opendaylight.controller.netconf.api.NetconfDocumentedException.ErrorSeverity; import org.opendaylight.controller.netconf.api.NetconfDocumentedException.ErrorTag; import org.opendaylight.controller.netconf.api.NetconfDocumentedException.ErrorType; import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.Config; -import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.InstanceConfig; -import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.ModuleConfig; -import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.Services; +import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.ServiceRegistryWrapper; import org.opendaylight.controller.netconf.confignetconfconnector.operations.AbstractConfigNetconfOperation; import org.opendaylight.controller.netconf.confignetconfconnector.operations.Datastore; +import org.opendaylight.controller.netconf.confignetconfconnector.operations.editconfig.EditConfig; import org.opendaylight.controller.netconf.confignetconfconnector.transactions.TransactionProvider; import org.opendaylight.controller.netconf.util.xml.XmlElement; import org.opendaylight.controller.netconf.util.xml.XmlNetconfConstants; @@ -83,14 +80,14 @@ public class GetConfig extends AbstractConfigNetconfOperation { final Set instances = Datastore.getInstanceQueryStrategy(source, this.transactionProvider) .queryInstances(configRegistryClient); - final Config configMapping = new Config(transform(configRegistryClient, + final Config configMapping = new Config(EditConfig.transformMbeToModuleConfigs(configRegistryClient, yangStoreSnapshot.getModuleMXBeanEntryMap())); ObjectName on = transactionProvider.getOrCreateTransaction(); ConfigTransactionClient ta = configRegistryClient.getConfigTransactionClient(on); - Services serviceTracker = new Services(ta); + ServiceRegistryWrapper serviceTracker = new ServiceRegistryWrapper(ta); dataElement = configMapping.toXml(instances, this.maybeNamespace, document, dataElement, serviceTracker); logger.info("{} operation successful", GET_CONFIG); @@ -98,27 +95,6 @@ public class GetConfig extends AbstractConfigNetconfOperation { return dataElement; } - // TODO refactor ... duplicate code - public static Map> transform(final ConfigRegistryClient configRegistryClient, - Map> mBeanEntries) { - return Maps.transformEntries(mBeanEntries, - new Maps.EntryTransformer, Map>() { - - @Override - public Map transformEntry(String arg0, Map arg1) { - return Maps.transformEntries(arg1, - new Maps.EntryTransformer() { - - @Override - public ModuleConfig transformEntry(String key, ModuleMXBeanEntry value) { - return new ModuleConfig(key, new InstanceConfig(configRegistryClient, value - .getAttributes()), value.getProvidedServices().values()); - } - }); - } - }); - } - @Override protected String getOperationName() { return GET_CONFIG; diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/runtimerpc/RuntimeRpc.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/runtimerpc/RuntimeRpc.java index 7463bdd429..f838c6f9f5 100644 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/runtimerpc/RuntimeRpc.java +++ b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/runtimerpc/RuntimeRpc.java @@ -127,7 +127,6 @@ public class RuntimeRpc extends AbstractConfigNetconfOperation { if (contextInstanceElement.isPresent() == false) return HandlingPriority.CANNOT_HANDLE; - // FIXME update xpath to instance to conform to config-api yang final RuntimeRpcElementResolved id = RuntimeRpcElementResolved.fromXpath(contextInstanceElement.get() .getTextContent(), netconfOperationName, netconfOperationNamespace); diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/util/Util.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/util/Util.java index 1c806742e9..fc8ddc01bd 100644 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/util/Util.java +++ b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/util/Util.java @@ -9,13 +9,6 @@ package org.opendaylight.controller.netconf.confignetconfconnector.util; import com.google.common.base.Preconditions; -import org.opendaylight.controller.config.yang.store.api.YangStoreException; -import org.opendaylight.controller.config.yang.store.api.YangStoreService; -import org.opendaylight.controller.config.yang.store.api.YangStoreSnapshot; -import org.opendaylight.controller.netconf.api.NetconfDocumentedException; -import org.opendaylight.controller.netconf.api.NetconfDocumentedException.ErrorSeverity; -import org.opendaylight.controller.netconf.api.NetconfDocumentedException.ErrorTag; -import org.opendaylight.controller.netconf.api.NetconfDocumentedException.ErrorType; import java.text.ParseException; import java.text.SimpleDateFormat; @@ -41,15 +34,4 @@ public final class Util { + " should be " + clazz + " of " + value); } - // TODO: add message and proper error types - public static YangStoreSnapshot getYangStore(final YangStoreService yangStoreService) - throws NetconfDocumentedException { - try { - return yangStoreService.getYangStoreSnapshot(); - } catch (final YangStoreException e) { - throw new NetconfDocumentedException("TODO", e, ErrorType.application, ErrorTag.bad_attribute, - ErrorSeverity.error); - } - } - } diff --git a/opendaylight/netconf/config-netconf-connector/src/test/java/org/opendaylight/controller/netconf/confignetconfconnector/NetconfMappingTest.java b/opendaylight/netconf/config-netconf-connector/src/test/java/org/opendaylight/controller/netconf/confignetconfconnector/NetconfMappingTest.java index 11cf1aae6a..9511673ea4 100644 --- a/opendaylight/netconf/config-netconf-connector/src/test/java/org/opendaylight/controller/netconf/confignetconfconnector/NetconfMappingTest.java +++ b/opendaylight/netconf/config-netconf-connector/src/test/java/org/opendaylight/controller/netconf/confignetconfconnector/NetconfMappingTest.java @@ -143,12 +143,19 @@ public class NetconfMappingTest extends AbstractConfigTest { "ref_dep_user_two", "ref_from_code_to_instance-from-code_dep_1", "ref_from_code_to_instance-from-code_1"); + edit("netconfMessages/editConfig_addServiceName.xml"); config = getConfigCandidate(); assertCorrectServiceNames(config, 7, "ref_test2", "user_to_instance_from_code", "ref_dep_user", "ref_dep_user_two", "ref_from_code_to_instance-from-code_dep_1", "ref_from_code_to_instance-from-code_1", "ref_dep_user_another"); + edit("netconfMessages/editConfig_addServiceNameOnTest.xml"); + config = getConfigCandidate(); + assertCorrectServiceNames(config, 7, "ref_test2", "user_to_instance_from_code", "ref_dep_user", + "ref_dep_user_two", "ref_from_code_to_instance-from-code_dep_1", + "ref_from_code_to_instance-from-code_1", "ref_dep_user_another"); + commit(); config = getConfigRunning(); assertCorrectRefNamesForDependencies(config); @@ -229,6 +236,7 @@ public class NetconfMappingTest extends AbstractConfigTest { edit("netconfMessages/editConfig.xml"); Element configCandidate = getConfigCandidate(); + System.err.println(XmlUtil.toString(configCandidate)); checkBinaryLeafEdited(configCandidate); diff --git a/opendaylight/netconf/config-netconf-connector/src/test/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/EditConfigTest.java b/opendaylight/netconf/config-netconf-connector/src/test/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/EditConfigTest.java index 6e7a225f38..505a91c6ce 100644 --- a/opendaylight/netconf/config-netconf-connector/src/test/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/EditConfigTest.java +++ b/opendaylight/netconf/config-netconf-connector/src/test/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/EditConfigTest.java @@ -23,7 +23,9 @@ import org.opendaylight.controller.config.yang.store.api.YangStoreSnapshot; import org.opendaylight.controller.netconf.api.NetconfDocumentedException; import org.opendaylight.controller.netconf.confignetconfconnector.mapping.attributes.fromxml.AttributeConfigElement; import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.InstanceConfigElementResolved; +import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.ModuleElementDefinition; import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.ModuleElementResolved; +import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.ServiceRegistryWrapper; import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.Services; import org.opendaylight.controller.netconf.confignetconfconnector.operations.ValidateTest; import org.opendaylight.controller.netconf.confignetconfconnector.operations.editconfig.EditConfigXmlParser.EditConfigExecution; @@ -35,7 +37,7 @@ import java.util.Collections; import java.util.Map; import static org.mockito.Matchers.any; -import static org.mockito.Matchers.anyMap; +import static org.mockito.Matchers.anyMapOf; import static org.mockito.Matchers.anyString; import static org.mockito.Mockito.doNothing; import static org.mockito.Mockito.doReturn; @@ -82,8 +84,8 @@ public class EditConfigTest { ValidateTest.NETCONF_SESSION_ID_FOR_REPORTING); EditConfigStrategy editStrat = mock(EditConfigStrategy.class); - doNothing().when(editStrat).executeConfiguration(anyString(), anyString(), anyMap(), - any(ConfigTransactionClient.class), any(Services.class)); + doNothing().when(editStrat).executeConfiguration(anyString(), anyString(), anyMapOf(String.class, AttributeConfigElement.class), + any(ConfigTransactionClient.class), any(ServiceRegistryWrapper.class)); EditConfigExecution editConfigExecution = mockExecution(editStrat); @@ -96,20 +98,44 @@ public class EditConfigTest { verify(provider).getOrCreateTransaction(); // For every instance execute strat - verify(editStrat, times(2/* Test */+ 2/* Set */)).executeConfiguration(anyString(), anyString(), anyMap(), - any(ConfigTransactionClient.class), any(Services.class)); + verify(editStrat, times(2/* Test */+ 2/* Set */ + 2/*Handle missing instance Test*/ + 2 /*Handle missing instance Set*/)).executeConfiguration(anyString(), + anyString(), anyMapOf(String.class, AttributeConfigElement.class), + any(ConfigTransactionClient.class), any(ServiceRegistryWrapper.class)); } private EditConfigExecution mockExecution(EditConfigStrategy editStrat) { EditConfigExecution mock = mock(EditConfigExecution.class); - doReturn(getMapping(editStrat)).when(mock).getResolvedXmlElements(); + doReturn(getMapping(editStrat)).when(mock).getResolvedXmlElements(any(ConfigTransactionClient.class)); + doReturn(getMappingDefinition(editStrat)).when(mock).getModulesDefinition(any(ConfigTransactionClient.class)); doReturn(EditStrategyType.merge).when(mock).getDefaultStrategy(); doReturn(true).when(mock).shouldSet(); doReturn(true).when(mock).shouldTest(); - doReturn(mockServices()).when(mock).getServices(); + doReturn(mockServices()).when(mock).getServiceRegistryWrapper(any(ConfigTransactionClient.class)); + doReturn(new Services()).when(mock).getServices(); return mock; } + private Object getMappingDefinition(EditConfigStrategy editStrat) { + Map> result = Maps.newHashMap(); + + Multimap innerMultimap = HashMultimap.create(); + Map attributes = getSimpleAttributes(); + + ModuleElementDefinition mockedDefinition = mock(ModuleElementDefinition.class); + doReturn(editStrat).when(mockedDefinition).getEditStrategy(); + doReturn("i1").when(mockedDefinition).getInstanceName(); + innerMultimap.put("m1", mockedDefinition); + + ModuleElementDefinition mockedDefinition2 = mock(ModuleElementDefinition.class); + doReturn(editStrat).when(mockedDefinition2).getEditStrategy(); + doReturn("i2").when(mockedDefinition2).getInstanceName(); + innerMultimap.put("m1", mockedDefinition2); + + result.put("n1", innerMultimap); + + return result; + } + private static ServiceReferenceReadableRegistry mockServiceRegistry() { ServiceReferenceReadableRegistry mock = mock(ServiceReferenceReadableRegistry.class); doReturn( @@ -120,8 +146,8 @@ public class EditConfigTest { return mock; } - static Services mockServices() { - return new Services(mockServiceRegistry()); + static ServiceRegistryWrapper mockServices() { + return new ServiceRegistryWrapper(mockServiceRegistry()); } private Map> getMapping(EditConfigStrategy editStrat) { diff --git a/opendaylight/netconf/config-persister-impl/src/main/java/org/opendaylight/controller/netconf/persist/impl/ConfigPersisterNotificationHandler.java b/opendaylight/netconf/config-persister-impl/src/main/java/org/opendaylight/controller/netconf/persist/impl/ConfigPersisterNotificationHandler.java index 1c3ac7a455..b66a1a57c2 100644 --- a/opendaylight/netconf/config-persister-impl/src/main/java/org/opendaylight/controller/netconf/persist/impl/ConfigPersisterNotificationHandler.java +++ b/opendaylight/netconf/config-persister-impl/src/main/java/org/opendaylight/controller/netconf/persist/impl/ConfigPersisterNotificationHandler.java @@ -8,6 +8,7 @@ package org.opendaylight.controller.netconf.persist.impl; +import org.opendaylight.controller.config.persist.api.Persister; import org.opendaylight.controller.netconf.api.jmx.CommitJMXNotification; import org.opendaylight.controller.netconf.api.jmx.DefaultCommitOperationMXBean; import org.opendaylight.controller.netconf.api.jmx.NetconfJMXNotification; @@ -36,11 +37,11 @@ public class ConfigPersisterNotificationHandler implements NotificationListener, private static final Logger logger = LoggerFactory.getLogger(ConfigPersisterNotificationHandler.class); private final MBeanServerConnection mBeanServerConnection; private final NetconfClient netconfClient; - private final PersisterAggregator persisterAggregator; + private final Persister persisterAggregator; private final Pattern ignoredMissingCapabilityRegex; public ConfigPersisterNotificationHandler(MBeanServerConnection mBeanServerConnection, NetconfClient netconfClient, - PersisterAggregator persisterAggregator, Pattern ignoredMissingCapabilityRegex) { + Persister persisterAggregator, Pattern ignoredMissingCapabilityRegex) { this.mBeanServerConnection = mBeanServerConnection; this.netconfClient = netconfClient; this.persisterAggregator = persisterAggregator; @@ -72,8 +73,9 @@ public class ConfigPersisterNotificationHandler implements NotificationListener, if (notification instanceof CommitJMXNotification) { try { handleAfterCommitNotification((CommitJMXNotification) notification); - } catch (Exception e) { - // TODO: notificationBroadcast support logs only DEBUG + } catch (Throwable e) { + // log exceptions from notification Handler here since + // notificationBroadcastSupport logs only DEBUG level logger.warn("Exception occured during notification handling: ", e); throw e; } diff --git a/opendaylight/netconf/config-persister-impl/src/main/java/org/opendaylight/controller/netconf/persist/impl/Util.java b/opendaylight/netconf/config-persister-impl/src/main/java/org/opendaylight/controller/netconf/persist/impl/Util.java index 811ba38c10..86a024a240 100644 --- a/opendaylight/netconf/config-persister-impl/src/main/java/org/opendaylight/controller/netconf/persist/impl/Util.java +++ b/opendaylight/netconf/config-persister-impl/src/main/java/org/opendaylight/controller/netconf/persist/impl/Util.java @@ -40,8 +40,6 @@ public final class Util { return true; } - - // TODO: check if closing in correct order public static void closeClientAndDispatcher(NetconfClient client) { NetconfClientDispatcher dispatcher = client.getNetconfClientDispatcher(); Exception fromClient = null; diff --git a/opendaylight/netconf/config-persister-impl/src/main/java/org/opendaylight/controller/netconf/persist/impl/osgi/PropertiesProviderBaseImpl.java b/opendaylight/netconf/config-persister-impl/src/main/java/org/opendaylight/controller/netconf/persist/impl/osgi/PropertiesProviderBaseImpl.java index 15ed5c48fa..2a95cca937 100644 --- a/opendaylight/netconf/config-persister-impl/src/main/java/org/opendaylight/controller/netconf/persist/impl/osgi/PropertiesProviderBaseImpl.java +++ b/opendaylight/netconf/config-persister-impl/src/main/java/org/opendaylight/controller/netconf/persist/impl/osgi/PropertiesProviderBaseImpl.java @@ -1,10 +1,9 @@ -/** - * @author Tomas Olvecky +/* + * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved. * - * 11 2013 - * - * Copyright (c) 2013 by Cisco Systems, Inc. - * 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.netconf.persist.impl.osgi; diff --git a/opendaylight/netconf/netconf-client/src/main/java/org/opendaylight/controller/netconf/client/NetconfClient.java b/opendaylight/netconf/netconf-client/src/main/java/org/opendaylight/controller/netconf/client/NetconfClient.java index 2ce779a1f5..8b8c886a1c 100644 --- a/opendaylight/netconf/netconf-client/src/main/java/org/opendaylight/controller/netconf/client/NetconfClient.java +++ b/opendaylight/netconf/netconf-client/src/main/java/org/opendaylight/controller/netconf/client/NetconfClient.java @@ -71,6 +71,10 @@ public class NetconfClient implements Closeable { return new NetconfClient(clientLabelForLogging,address,strat,netconfClientDispatcher); } + public static NetconfClient clientFor(String clientLabelForLogging, InetSocketAddress address, ReconnectStrategy strat, NetconfClientDispatcher netconfClientDispatcher,NetconfClientSessionListener listener) throws InterruptedException { + return new NetconfClient(clientLabelForLogging,address,strat,netconfClientDispatcher,listener); + } + public NetconfClient(String clientLabelForLogging, InetSocketAddress address, int connectTimeoutMs, NetconfClientDispatcher netconfClientDispatcher) throws InterruptedException { this(clientLabelForLogging, address, @@ -83,6 +87,17 @@ public class NetconfClient implements Closeable { DEFAULT_CONNECT_TIMEOUT), netconfClientDispatcher); } + public NetconfClient(String clientLabelForLogging, InetSocketAddress address, ReconnectStrategy strat, + NetconfClientDispatcher netconfClientDispatcher, NetconfClientSessionListener listener) throws InterruptedException{ + this.label = clientLabelForLogging; + dispatch = netconfClientDispatcher; + sessionListener = listener; + Future clientFuture = dispatch.createClient(address, sessionListener, strat); + this.address = address; + clientSession = get(clientFuture); + this.sessionId = clientSession.getSessionId(); + } + public NetconfMessage sendMessage(NetconfMessage message) { return sendMessage(message, 5, 1000); } @@ -90,6 +105,7 @@ public class NetconfClient implements Closeable { public NetconfMessage sendMessage(NetconfMessage message, int attempts, int attemptMsDelay) { long startTime = System.currentTimeMillis(); Preconditions.checkState(clientSession.isUp(), "Session was not up yet"); + //logger.debug("Sending message: {}",XmlUtil.toString(message.getDocument())); clientSession.sendMessage(message); try { return sessionListener.getLastMessage(attempts, attemptMsDelay); diff --git a/opendaylight/netconf/netconf-impl/src/main/java/org/opendaylight/controller/netconf/impl/CapabilityProviderImpl.java b/opendaylight/netconf/netconf-impl/src/main/java/org/opendaylight/controller/netconf/impl/CapabilityProviderImpl.java index 1d2e039b29..8dbdb26bff 100644 --- a/opendaylight/netconf/netconf-impl/src/main/java/org/opendaylight/controller/netconf/impl/CapabilityProviderImpl.java +++ b/opendaylight/netconf/netconf-impl/src/main/java/org/opendaylight/controller/netconf/impl/CapabilityProviderImpl.java @@ -15,6 +15,8 @@ import org.opendaylight.controller.netconf.impl.mapping.CapabilityProvider; import org.opendaylight.controller.netconf.impl.osgi.NetconfOperationServiceSnapshot; import org.opendaylight.controller.netconf.mapping.api.Capability; import org.opendaylight.controller.netconf.mapping.api.NetconfOperationService; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import java.util.Collections; import java.util.Map; @@ -24,6 +26,8 @@ public class CapabilityProviderImpl implements CapabilityProvider { private final NetconfOperationServiceSnapshot netconfOperationServiceSnapshot; private final Set capabilityURIs; + private static final Logger logger = LoggerFactory.getLogger(DefaultCommitNotificationProducer.class); + public CapabilityProviderImpl(NetconfOperationServiceSnapshot netconfOperationServiceSnapshot) { this.netconfOperationServiceSnapshot = netconfOperationServiceSnapshot; Map urisToCapabilitiesInternalMap = getCapabilitiesInternal(netconfOperationServiceSnapshot); @@ -38,7 +42,11 @@ public class CapabilityProviderImpl implements CapabilityProvider { final Set caps = netconfOperationService.getCapabilities(); for (Capability cap : caps) { - // TODO check for duplicates ? + + if(capabilityMap.containsKey(cap.getCapabilityUri())) { + logger.debug("Duplicate capability {} from service {}", cap.getCapabilityUri(), netconfOperationService); + } + capabilityMap.put(cap.getCapabilityUri(), cap); } } diff --git a/opendaylight/netconf/netconf-impl/src/main/java/org/opendaylight/controller/netconf/impl/NetconfServerDispatcher.java b/opendaylight/netconf/netconf-impl/src/main/java/org/opendaylight/controller/netconf/impl/NetconfServerDispatcher.java index 4f60788975..7c5bd0cb21 100644 --- a/opendaylight/netconf/netconf-impl/src/main/java/org/opendaylight/controller/netconf/impl/NetconfServerDispatcher.java +++ b/opendaylight/netconf/netconf-impl/src/main/java/org/opendaylight/controller/netconf/impl/NetconfServerDispatcher.java @@ -12,12 +12,13 @@ import io.netty.channel.ChannelFuture; import io.netty.channel.EventLoopGroup; import io.netty.channel.socket.SocketChannel; import io.netty.util.concurrent.Promise; -import java.net.InetSocketAddress; import org.opendaylight.controller.netconf.api.NetconfSession; import org.opendaylight.controller.netconf.impl.util.DeserializerExceptionHandler; import org.opendaylight.controller.netconf.util.AbstractChannelInitializer; import org.opendaylight.protocol.framework.AbstractDispatcher; +import java.net.InetSocketAddress; + public class NetconfServerDispatcher extends AbstractDispatcher { private final ServerChannelInitializer initializer; @@ -28,7 +29,6 @@ public class NetconfServerDispatcher extends AbstractDispatcher() { diff --git a/opendaylight/netconf/netconf-impl/src/main/java/org/opendaylight/controller/netconf/impl/NetconfServerSessionNegotiatorFactory.java b/opendaylight/netconf/netconf-impl/src/main/java/org/opendaylight/controller/netconf/impl/NetconfServerSessionNegotiatorFactory.java index e74723032d..91734beacb 100644 --- a/opendaylight/netconf/netconf-impl/src/main/java/org/opendaylight/controller/netconf/impl/NetconfServerSessionNegotiatorFactory.java +++ b/opendaylight/netconf/netconf-impl/src/main/java/org/opendaylight/controller/netconf/impl/NetconfServerSessionNegotiatorFactory.java @@ -8,6 +8,7 @@ package org.opendaylight.controller.netconf.impl; +import com.google.common.base.Preconditions; import io.netty.channel.Channel; import io.netty.util.Timer; import io.netty.util.concurrent.Promise; @@ -28,9 +29,12 @@ import org.w3c.dom.Node; import javax.xml.xpath.XPathConstants; import javax.xml.xpath.XPathExpression; +import java.io.InputStream; public class NetconfServerSessionNegotiatorFactory implements SessionNegotiatorFactory { + public static final String SERVER_HELLO_XML_LOCATION = "/server_hello.xml"; + private final Timer timer; private static final Document helloMessageTemplate = loadHelloMessageTemplate(); @@ -45,8 +49,11 @@ public class NetconfServerSessionNegotiatorFactory implements SessionNegotiatorF } private static Document loadHelloMessageTemplate() { - return NetconfUtil.createMessage( - NetconfServerSessionNegotiatorFactory.class.getResourceAsStream("/server_hello.xml")).getDocument(); + InputStream resourceAsStream = NetconfServerSessionNegotiatorFactory.class + .getResourceAsStream(SERVER_HELLO_XML_LOCATION); + Preconditions.checkNotNull(resourceAsStream, "Unable to load server hello message blueprint from %s", + SERVER_HELLO_XML_LOCATION); + return NetconfUtil.createMessage(resourceAsStream).getDocument(); } @Override diff --git a/opendaylight/netconf/netconf-impl/src/main/java/org/opendaylight/controller/netconf/impl/osgi/NetconfMonitoringServiceImpl.java b/opendaylight/netconf/netconf-impl/src/main/java/org/opendaylight/controller/netconf/impl/osgi/NetconfMonitoringServiceImpl.java index 1b3542595f..505c74714a 100644 --- a/opendaylight/netconf/netconf-impl/src/main/java/org/opendaylight/controller/netconf/impl/osgi/NetconfMonitoringServiceImpl.java +++ b/opendaylight/netconf/netconf-impl/src/main/java/org/opendaylight/controller/netconf/impl/osgi/NetconfMonitoringServiceImpl.java @@ -68,6 +68,7 @@ public class NetconfMonitoringServiceImpl implements NetconfMonitoringService, S @Override public Schemas getSchemas() { // FIXME, session ID + // capabilities should be split from operations (it will allow to move getSchema operation to monitoring module) return transformSchemas(factoriesListener.getSnapshot(0)); } @@ -78,6 +79,7 @@ public class NetconfMonitoringServiceImpl implements NetconfMonitoringService, S for (NetconfOperationService netconfOperationService : snapshot.getServices()) { // TODO check for duplicates ? move capability merging to snapshot + // Split capabilities from operations first and delete this duplicate code caps.addAll(netconfOperationService.getCapabilities()); } @@ -115,8 +117,7 @@ public class NetconfMonitoringServiceImpl implements NetconfMonitoringService, S monitoringLocations.add(new Schema.Location(Schema.Location.Enumeration.NETCONF)); for (String location : locations) { - // TODO how to create enumerration from string location ? - // monitoringLocations.add(new Schema.Location(Schema.Location.Enumeration.valueOf(location))); + monitoringLocations.add(new Schema.Location(new Uri(location))); } return monitoringLocations; diff --git a/opendaylight/netconf/netconf-impl/src/main/java/org/opendaylight/controller/netconf/impl/osgi/NetconfOperationRouterImpl.java b/opendaylight/netconf/netconf-impl/src/main/java/org/opendaylight/controller/netconf/impl/osgi/NetconfOperationRouterImpl.java index ee474dbba0..d70a15c18b 100644 --- a/opendaylight/netconf/netconf-impl/src/main/java/org/opendaylight/controller/netconf/impl/osgi/NetconfOperationRouterImpl.java +++ b/opendaylight/netconf/netconf-impl/src/main/java/org/opendaylight/controller/netconf/impl/osgi/NetconfOperationRouterImpl.java @@ -185,7 +185,6 @@ public class NetconfOperationRouterImpl implements NetconfOperationRouter { private NetconfOperationExecution getNetconfOperationWithHighestPriority( Document message, NetconfSession session) { - // TODO test TreeMap> sortedPriority = getSortedNetconfOperationsWithCanHandle( message, session); diff --git a/opendaylight/netconf/netconf-impl/src/main/java/org/opendaylight/controller/netconf/impl/util/NetconfUtil.java b/opendaylight/netconf/netconf-impl/src/main/java/org/opendaylight/controller/netconf/impl/util/NetconfUtil.java index f2c70d6101..b70a31a84b 100644 --- a/opendaylight/netconf/netconf-impl/src/main/java/org/opendaylight/controller/netconf/impl/util/NetconfUtil.java +++ b/opendaylight/netconf/netconf-impl/src/main/java/org/opendaylight/controller/netconf/impl/util/NetconfUtil.java @@ -1,11 +1,6 @@ package org.opendaylight.controller.netconf.impl.util; -import java.io.File; -import java.io.FileInputStream; -import java.io.FileNotFoundException; -import java.io.IOException; -import java.io.InputStream; - +import com.google.common.base.Preconditions; import org.opendaylight.controller.netconf.api.NetconfMessage; import org.opendaylight.controller.netconf.util.xml.XmlUtil; import org.slf4j.Logger; @@ -13,12 +8,18 @@ import org.slf4j.LoggerFactory; import org.w3c.dom.Document; import org.xml.sax.SAXException; -// TODO purge nulls +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.InputStream; + public class NetconfUtil { private static final Logger logger = LoggerFactory.getLogger(NetconfUtil.class); public static NetconfMessage createMessage(final File f) { + Preconditions.checkNotNull(f, "File parameter was null"); try { return createMessage(new FileInputStream(f)); } catch (final FileNotFoundException e) { @@ -28,6 +29,7 @@ public class NetconfUtil { } public static NetconfMessage createMessage(final InputStream is) { + Preconditions.checkNotNull(is, "InputStream parameter was null"); Document doc = null; try { doc = XmlUtil.readXmlToDocument(is); diff --git a/opendaylight/netconf/netconf-impl/src/test/java/org/opendaylight/controller/netconf/impl/NetconfDispatcherImplTest.java b/opendaylight/netconf/netconf-impl/src/test/java/org/opendaylight/controller/netconf/impl/NetconfDispatcherImplTest.java index 0140b65c14..0ecc1cb383 100644 --- a/opendaylight/netconf/netconf-impl/src/test/java/org/opendaylight/controller/netconf/impl/NetconfDispatcherImplTest.java +++ b/opendaylight/netconf/netconf-impl/src/test/java/org/opendaylight/controller/netconf/impl/NetconfDispatcherImplTest.java @@ -24,21 +24,14 @@ import java.net.InetSocketAddress; public class NetconfDispatcherImplTest { private EventLoopGroup nettyGroup; + private NetconfServerDispatcher dispatch; + private DefaultCommitNotificationProducer commitNot; @Before public void setUp() throws Exception { nettyGroup = new NioEventLoopGroup(); - } - - @After - public void tearDown() throws Exception { - nettyGroup.shutdownGracefully(); - } - @Test - public void test() throws Exception { - - DefaultCommitNotificationProducer commitNot = new DefaultCommitNotificationProducer( + commitNot = new DefaultCommitNotificationProducer( ManagementFactory.getPlatformMBeanServer()); NetconfOperationServiceFactoryListener factoriesListener = new NetconfOperationServiceFactoryListenerImpl(); @@ -50,13 +43,20 @@ public class NetconfDispatcherImplTest { factoriesListener, commitNot, idProvider, null); NetconfServerDispatcher.ServerChannelInitializer serverChannelInitializer = new NetconfServerDispatcher.ServerChannelInitializer(serverNegotiatorFactory, listenerFactory); - - NetconfServerDispatcher dispatch = new NetconfServerDispatcher( + dispatch = new NetconfServerDispatcher( serverChannelInitializer, nettyGroup, nettyGroup); + } + @After + public void tearDown() throws Exception { + commitNot.close(); + nettyGroup.shutdownGracefully(); + } + + @Test + public void test() throws Exception { InetSocketAddress addr = new InetSocketAddress("127.0.0.1", 8333); ChannelFuture s = dispatch.createServer(addr); - - commitNot.close(); + s.get(); } } diff --git a/opendaylight/netconf/netconf-it/src/test/java/org/opendaylight/controller/netconf/it/NetconfConfigPersisterITTest.java b/opendaylight/netconf/netconf-it/src/test/java/org/opendaylight/controller/netconf/it/NetconfConfigPersisterITTest.java new file mode 100644 index 0000000000..14f70d398c --- /dev/null +++ b/opendaylight/netconf/netconf-it/src/test/java/org/opendaylight/controller/netconf/it/NetconfConfigPersisterITTest.java @@ -0,0 +1,286 @@ +/* + * 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.netconf.it; + +import com.google.common.collect.Lists; +import com.google.common.collect.Sets; +import io.netty.channel.ChannelFuture; +import io.netty.channel.EventLoopGroup; +import io.netty.channel.nio.NioEventLoopGroup; +import io.netty.util.HashedWheelTimer; +import org.apache.commons.lang3.StringUtils; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import org.junit.matchers.JUnitMatchers; +import org.mockito.invocation.InvocationOnMock; +import org.mockito.stubbing.Answer; +import org.opendaylight.controller.config.manager.impl.AbstractConfigTest; +import org.opendaylight.controller.config.manager.impl.factoriesresolver.HardcodedModuleFactoriesResolver; +import org.opendaylight.controller.config.persist.api.ConfigSnapshotHolder; +import org.opendaylight.controller.config.persist.api.Persister; +import org.opendaylight.controller.config.spi.ModuleFactory; +import org.opendaylight.controller.config.yang.store.api.YangStoreException; +import org.opendaylight.controller.config.yang.store.impl.HardcodedYangStoreService; +import org.opendaylight.controller.netconf.api.NetconfMessage; +import org.opendaylight.controller.netconf.api.jmx.CommitJMXNotification; +import org.opendaylight.controller.netconf.api.monitoring.NetconfManagementSession; +import org.opendaylight.controller.netconf.client.NetconfClient; +import org.opendaylight.controller.netconf.client.NetconfClientDispatcher; +import org.opendaylight.controller.netconf.confignetconfconnector.osgi.NetconfOperationServiceFactoryImpl; +import org.opendaylight.controller.netconf.impl.DefaultCommitNotificationProducer; +import org.opendaylight.controller.netconf.impl.NetconfServerDispatcher; +import org.opendaylight.controller.netconf.impl.NetconfServerSessionListenerFactory; +import org.opendaylight.controller.netconf.impl.NetconfServerSessionNegotiatorFactory; +import org.opendaylight.controller.netconf.impl.SessionIdProvider; +import org.opendaylight.controller.netconf.impl.osgi.NetconfMonitoringServiceImpl; +import org.opendaylight.controller.netconf.impl.osgi.NetconfOperationServiceFactoryListener; +import org.opendaylight.controller.netconf.impl.osgi.NetconfOperationServiceFactoryListenerImpl; +import org.opendaylight.controller.netconf.impl.osgi.NetconfOperationServiceSnapshot; +import org.opendaylight.controller.netconf.impl.osgi.SessionMonitoringService; +import org.opendaylight.controller.netconf.mapping.api.Capability; +import org.opendaylight.controller.netconf.mapping.api.NetconfOperationService; +import org.opendaylight.controller.netconf.monitoring.osgi.NetconfMonitoringActivator; +import org.opendaylight.controller.netconf.monitoring.osgi.NetconfMonitoringOperationService; +import org.opendaylight.controller.netconf.persist.impl.ConfigPersisterNotificationHandler; +import org.opendaylight.controller.netconf.util.test.XmlFileLoader; +import org.opendaylight.controller.netconf.util.xml.XmlUtil; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.w3c.dom.Element; + +import javax.management.InstanceNotFoundException; +import javax.management.Notification; +import javax.management.NotificationListener; +import java.io.IOException; +import java.io.InputStream; +import java.net.InetSocketAddress; +import java.util.Collection; +import java.util.List; +import java.util.Set; +import java.util.concurrent.TimeUnit; +import java.util.regex.Pattern; + +import static junit.framework.Assert.assertEquals; +import static org.mockito.Matchers.any; +import static org.mockito.Matchers.anyLong; +import static org.mockito.Mockito.doAnswer; +import static org.mockito.Mockito.doNothing; +import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.mock; + +public class NetconfConfigPersisterITTest extends AbstractConfigTest { + + private static final Logger logger = LoggerFactory.getLogger(NetconfConfigPersisterITTest.class); + + private static final InetSocketAddress tcpAddress = new InetSocketAddress("127.0.0.1", 12023); + + private EventLoopGroup nettyThreadgroup; + + private NetconfClientDispatcher clientDispatcher; + + @Before + public void setUp() throws Exception { + super.initConfigTransactionManagerImpl(new HardcodedModuleFactoriesResolver(NetconfITTest.getModuleFactoriesS().toArray( + new ModuleFactory[0]))); + + NetconfMonitoringServiceImpl monitoringService = new NetconfMonitoringServiceImpl(getFactoriesListener()); + + NetconfOperationServiceFactoryListenerImpl factoriesListener = new NetconfOperationServiceFactoryListenerImpl(); + factoriesListener.onAddNetconfOperationServiceFactory(new NetconfOperationServiceFactoryImpl(getYangStore())); + factoriesListener + .onAddNetconfOperationServiceFactory(new NetconfMonitoringActivator.NetconfMonitoringOperationServiceFactory( + new NetconfMonitoringOperationService(monitoringService))); + + nettyThreadgroup = new NioEventLoopGroup(); + + NetconfServerDispatcher dispatch = createDispatcher(factoriesListener); + ChannelFuture s = dispatch.createServer(tcpAddress); + s.await(); + + clientDispatcher = new NetconfClientDispatcher(nettyThreadgroup, nettyThreadgroup); + } + + private HardcodedYangStoreService getYangStore() throws YangStoreException, IOException { + final Collection yangDependencies = NetconfITTest.getBasicYangs(); + return new HardcodedYangStoreService(yangDependencies); + } + + private NetconfServerDispatcher createDispatcher( + NetconfOperationServiceFactoryListenerImpl factoriesListener) { + SessionIdProvider idProvider = new SessionIdProvider(); + NetconfServerSessionNegotiatorFactory serverNegotiatorFactory = new NetconfServerSessionNegotiatorFactory( + new HashedWheelTimer(5000, TimeUnit.MILLISECONDS), factoriesListener, idProvider); + + NetconfServerSessionListenerFactory listenerFactory = new NetconfServerSessionListenerFactory( + factoriesListener, new DefaultCommitNotificationProducer(platformMBeanServer), idProvider, mockSessionMonitoringService()); + + NetconfServerDispatcher.ServerChannelInitializer serverChannelInitializer = new NetconfServerDispatcher.ServerChannelInitializer( + serverNegotiatorFactory, listenerFactory); + return new NetconfServerDispatcher(serverChannelInitializer, nettyThreadgroup, nettyThreadgroup); + } + + private SessionMonitoringService mockSessionMonitoringService() { + SessionMonitoringService mockedSessionMonitor = mock(SessionMonitoringService.class); + doNothing().when(mockedSessionMonitor).onSessionUp(any(NetconfManagementSession.class)); + doNothing().when(mockedSessionMonitor).onSessionDown(any(NetconfManagementSession.class)); + return mockedSessionMonitor; + } + + @Test + public void testNetconfCommitNotifications() throws Exception { + + VerifyingNotificationListener notificationVerifier = createCommitNotificationListener(); + VerifyingPersister mockedAggregator = mockAggregator(); + + try (NetconfClient persisterClient = new NetconfClient("persister", tcpAddress, 4000, clientDispatcher)) { + ConfigPersisterNotificationHandler configPersisterNotificationHandler = new ConfigPersisterNotificationHandler( + platformMBeanServer, persisterClient, mockedAggregator, + Pattern.compile("")); + configPersisterNotificationHandler.init(); + + try (NetconfClient netconfClient = new NetconfClient("client", tcpAddress, 4000, clientDispatcher)) { + NetconfMessage response = netconfClient.sendMessage(loadGetConfigMessage()); + assertResponse(response, " caps = Sets.newHashSet(); + doReturn(caps).when(service).getCapabilities(); + Set services = Sets.newHashSet(service); + doReturn(services).when(snap).getServices(); + doReturn(snap).when(factoriesListener).getSnapshot(anyLong()); + + return factoriesListener; + } + + private static class VerifyingNotificationListener implements NotificationListener { + public List notifications = Lists.newArrayList(); + + @Override + public void handleNotification(Notification notification, Object handback) { + this.notifications.add(notification); + } + + void assertNotificationCount(Object size) { + assertEquals(size, notifications.size()); + } + + void assertNotificationContent(int notificationIndex, int expectedModulesSize, int expectedServicesSize, int expectedCapsSize) { + Notification notification = notifications.get(notificationIndex); + assertEquals(CommitJMXNotification.class, notification.getClass()); + int capsSize = ((CommitJMXNotification) notification).getCapabilities().size(); + assertEquals("Expected capabilities count", expectedCapsSize, capsSize); + Element configSnapshot = ((CommitJMXNotification) notification).getConfigSnapshot(); + int modulesSize = configSnapshot.getElementsByTagName("module").getLength(); + assertEquals("Expected modules count", expectedModulesSize, modulesSize); + int servicesSize = configSnapshot.getElementsByTagName("instance").getLength(); + assertEquals("Expected services count", expectedServicesSize, servicesSize); + } + } + + private static class VerifyingPersister implements Persister { + + public List snapshots = Lists.newArrayList(); + private Persister mockedPersister; + + public VerifyingPersister() throws IOException { + Persister mockedAggregator = mock(Persister.class); + + doAnswer(new Answer() { + @Override + public Object answer(InvocationOnMock invocation) throws Throwable { + ConfigSnapshotHolder configSnapshot = (ConfigSnapshotHolder) invocation.getArguments()[0]; + snapshots.add(configSnapshot); + return null; + } + }).when(mockedAggregator).persistConfig(any(ConfigSnapshotHolder.class)); + + this.mockedPersister = mockedAggregator; + } + + void assertSnapshotCount(Object size) { + assertEquals(size, snapshots.size()); + } + + void assertSnapshotContent(int notificationIndex, int expectedModulesSize, int expectedServicesSize, int expectedCapsSize) { + ConfigSnapshotHolder snapshot = snapshots.get(notificationIndex); + int capsSize = snapshot.getCapabilities().size(); + assertEquals("Expected capabilities count", expectedCapsSize, capsSize); + String configSnapshot = snapshot.getConfigSnapshot(); + int modulesSize = StringUtils.countMatches(configSnapshot, ""); + assertEquals("Expected modules count", expectedModulesSize, modulesSize); + int servicesSize = StringUtils.countMatches(configSnapshot, ""); + assertEquals("Expected services count", expectedServicesSize, servicesSize); + } + + @Override + public void persistConfig(ConfigSnapshotHolder configSnapshotHolder) throws IOException { + mockedPersister.persistConfig(configSnapshotHolder); + } + + @Override + public List loadLastConfigs() throws IOException { + return mockedPersister.loadLastConfigs(); + } + + @Override + public void close() { + mockedPersister.close(); + } + } +} diff --git a/opendaylight/netconf/netconf-it/src/test/java/org/opendaylight/controller/netconf/it/NetconfITTest.java b/opendaylight/netconf/netconf-it/src/test/java/org/opendaylight/controller/netconf/it/NetconfITTest.java index 4818b5f0a3..36f30dd328 100644 --- a/opendaylight/netconf/netconf-it/src/test/java/org/opendaylight/controller/netconf/it/NetconfITTest.java +++ b/opendaylight/netconf/netconf-it/src/test/java/org/opendaylight/controller/netconf/it/NetconfITTest.java @@ -16,19 +16,6 @@ import io.netty.channel.ChannelFuture; import io.netty.channel.EventLoopGroup; import io.netty.channel.nio.NioEventLoopGroup; import io.netty.util.HashedWheelTimer; -import java.io.IOException; -import java.io.InputStream; -import java.lang.management.ManagementFactory; -import java.net.InetSocketAddress; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collection; -import java.util.Collections; -import java.util.List; -import java.util.Set; -import java.util.concurrent.TimeUnit; -import javax.management.ObjectName; -import javax.xml.parsers.ParserConfigurationException; import junit.framework.Assert; import org.junit.After; import org.junit.Before; @@ -74,6 +61,21 @@ import org.w3c.dom.Element; import org.w3c.dom.NamedNodeMap; import org.w3c.dom.Node; import org.xml.sax.SAXException; + +import javax.management.ObjectName; +import javax.xml.parsers.ParserConfigurationException; +import java.io.IOException; +import java.io.InputStream; +import java.lang.management.ManagementFactory; +import java.net.InetSocketAddress; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; +import java.util.List; +import java.util.Set; +import java.util.concurrent.TimeUnit; + import static java.util.Collections.emptyList; import static junit.framework.Assert.assertEquals; import static junit.framework.Assert.assertNotNull; @@ -215,20 +217,6 @@ public class NetconfITTest extends AbstractConfigTest { } } - - //TODO: test persister actually - @Ignore - @Test(timeout = 10000) - public void testPersister() throws Exception { -// Persister persister = mock(Persister.class); -// doReturn("mockPersister").when(persister).toString(); -// doReturn(Collections.emptyList()).when(persister).loadLastConfigs(); -// ConfigPersisterNotificationHandler h = -// new ConfigPersisterNotificationHandler(persister, tcpAddress, ManagementFactory.getPlatformMBeanServer(), -// Pattern.compile(ConfigPersisterActivator.DEFAULT_IGNORED_REGEX)); -// h.init(); - } - @Ignore @Test public void waitingTest() throws Exception { @@ -432,7 +420,8 @@ public class NetconfITTest extends AbstractConfigTest { private void startSSHServer() throws Exception{ logger.info("Creating SSH server"); StubUserManager um = new StubUserManager(USERNAME,PASSWORD); - AuthProvider ap = new AuthProvider(um); + InputStream is = getClass().getResourceAsStream("/RSA.pk"); + AuthProvider ap = new AuthProvider(um, is); Thread sshServerThread = new Thread(NetconfSSHServer.start(10830,tcpAddress,ap)); sshServerThread.setDaemon(true); sshServerThread.start(); diff --git a/opendaylight/netconf/netconf-it/src/test/java/org/opendaylight/controller/netconf/it/NetconfMonitoringITTest.java b/opendaylight/netconf/netconf-it/src/test/java/org/opendaylight/controller/netconf/it/NetconfMonitoringITTest.java index 3a7b7de7a0..fdea831b47 100644 --- a/opendaylight/netconf/netconf-it/src/test/java/org/opendaylight/controller/netconf/it/NetconfMonitoringITTest.java +++ b/opendaylight/netconf/netconf-it/src/test/java/org/opendaylight/controller/netconf/it/NetconfMonitoringITTest.java @@ -7,27 +7,14 @@ */ package org.opendaylight.controller.netconf.it; -import static org.mockito.Matchers.anyLong; -import static org.mockito.Mockito.doReturn; -import static org.mockito.Mockito.mock; +import com.google.common.base.Charsets; +import com.google.common.base.Optional; +import com.google.common.collect.Sets; import io.netty.channel.ChannelFuture; import io.netty.channel.EventLoopGroup; import io.netty.channel.nio.NioEventLoopGroup; import io.netty.util.HashedWheelTimer; - -import java.io.BufferedReader; -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.net.InetSocketAddress; -import java.net.Socket; -import java.util.Collection; -import java.util.List; -import java.util.Set; -import java.util.concurrent.TimeUnit; - import junit.framework.Assert; - import org.junit.Before; import org.junit.Test; import org.junit.matchers.JUnitMatchers; @@ -61,9 +48,20 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.w3c.dom.Document; -import com.google.common.base.Charsets; -import com.google.common.base.Optional; -import com.google.common.collect.Sets; +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.net.InetSocketAddress; +import java.net.Socket; +import java.util.Collection; +import java.util.List; +import java.util.Set; +import java.util.concurrent.TimeUnit; + +import static org.mockito.Matchers.anyLong; +import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.mock; public class NetconfMonitoringITTest extends AbstractConfigTest { @@ -197,7 +195,7 @@ public class NetconfMonitoringITTest extends AbstractConfigTest { return XmlFileLoader.xmlFileToNetconfMessage("netconfMessages/get.xml"); } - public NetconfOperationServiceFactoryListener getFactoriesListener() { + public static NetconfOperationServiceFactoryListener getFactoriesListener() { NetconfOperationServiceFactoryListener factoriesListener = mock(NetconfOperationServiceFactoryListener.class); NetconfOperationServiceSnapshot snap = mock(NetconfOperationServiceSnapshot.class); NetconfOperationService service = mock(NetconfOperationService.class); diff --git a/opendaylight/netconf/netconf-it/src/test/resources/RSA.pk b/opendaylight/netconf/netconf-it/src/test/resources/RSA.pk new file mode 100644 index 0000000000..c0266c7bd2 --- /dev/null +++ b/opendaylight/netconf/netconf-it/src/test/resources/RSA.pk @@ -0,0 +1,27 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIEogIBAAKCAQEAuC9hbEacpewvylI0mwFwjy3Wou2hpr/ncN9BBiFDSaG5yW2k +3Oy+SCAcFCL+ZKWb6cc6Ch4gUeCwyEHRojZguuhliKtak9YQf6qbvpPLe00842Lx +iqNAGurMpzizCDsGFq8ChaAkBZQI3TvcHuPoSUWSMJ+K8xHpRyUdVr6g2yEjezKJ +sTXBtWaeCCh6YUafFujuDJk7fvYcPW7Je5KRBBStIKvxcMW0zB+7eq04deTHwGbJ +gGjKWilQ72hsDDP3Hbp5CJMAYg1r4GlCmFx3KyHRGztgWgNgaD7nNpKCkTLjtmA6 +b4x7TA+jrzZ6Af2z5TMrI4dv5w1SrxHaZ+ziLQIDAQABAoIBAHTndeGgq/rQf8De +Do+4CTaHtK0zQSAyu/azbXUzlZ7drKuCEVs8VMY4wzmwwGEnkF+A2YDkgEUX5X0l +8aYQ97KKoS9u+43MGCrAIhyDeGrpqlT1TzRcy+qJz53v6gq2U/X/3QztiQ+VV078 +mIluxNgE9XYxPaNsYfGLSCTv1+9c8y/hjGVX2kwFK+u4ut0ZZETggNa8UxfaHVDS +fIJQX9Gm3J3GSUV30fDGMBIUW6ESLc2L8b7u8Mp9TRP39ZeQSuEUjBe8MYKv0Rel +oEpjZvcnniMTpFbLpndBYn7/AoIiEBvtCN8faVTuRRcvvLcsRm09IctzKQYnMh6M +6PLKV+ECgYEA8HFRYaKHUzxpzE/fyon82GQbzqFFY0/bbWrfWICMfNbIgshJUie6 +FmH5iUFMfeqaT7v557HFM0GB9FeIeSbvd88YmiBAcRopZ3DfMkDH+DT73yJ+/TKG +2nrQtdhyuTIs4bwHqeS2BBJYs7PK9R2rratF3l34Tf7mjlvyOgygHdUCgYEAxBo2 +8hEBlAVNcNb1hTYUxe1w1B6675/mFlmw98Xmj9dRYfICXNhahs8tX3/lsBEd+vBu +fI0oyHaff8m5bPgGzD1ZMybfeROujNrgxaKVk7Ef0FDRRCop4bm18OroFlFAt9l8 +wMp++ToACbdvQvL/mjWMPYlIxhB/YxHswICZZvkCgYAexxKYwdo6sGAGlC7cWT9x +X5cjowcjyEQZRHXkeUgCbufpvcOM7aLnXJE5nY8yCwbHsBM0MlBA2GDPKylAANjk +aDEJAZneIHAuWodngl1Wi0m2bU7+ECqs6s2uiU9eH2sZVh1RBQK7kLGkBx6ys6KX +L3ZZGYRAT6GplWFzRsx0JQKBgCeVlxPD5QqpC1nEumi6YvUVGdpnnZpzL3HBhxxs +wT612wKnZFyze4qM1X7ahVXGDsQxtkvD/sCAWW/lG13orw6ZL6FIroF1PJ3ILOkY +CZN3hJF7TtKwpCWhZB2OfWzL2AGEkE8mUP0j/Q/5DCd6f6f0OSvOw3bfq6cm3iB5 +lP2ZAoGAXsRN5TZTX4AQ2xTlrDQ8A5XgcvyWQpJOmEXMTyHV7VaJVzmNWFVAvndK +5UIq8ALDwB2t7vjmMUW6euvIwqtXiop7G79UOb3e3NhzeyWFGQyBLqCRznGaXQTT +dlFy73xhukZMhFnj006bjKCYvOPnwuGl3+0fuWil5Rq3jOuY5c8= +-----END RSA PRIVATE KEY----- diff --git a/opendaylight/netconf/netconf-mapping-api/src/main/java/org/opendaylight/controller/netconf/mapping/api/HandlingPriority.java b/opendaylight/netconf/netconf-mapping-api/src/main/java/org/opendaylight/controller/netconf/mapping/api/HandlingPriority.java index 5a0688c8d1..176cf2d28c 100644 --- a/opendaylight/netconf/netconf-mapping-api/src/main/java/org/opendaylight/controller/netconf/mapping/api/HandlingPriority.java +++ b/opendaylight/netconf/netconf-mapping-api/src/main/java/org/opendaylight/controller/netconf/mapping/api/HandlingPriority.java @@ -36,8 +36,6 @@ public class HandlingPriority implements Comparable { return Optional.of(priority).or(Optional. absent()); } - // TODO test - @Override public int compareTo(HandlingPriority o) { if (this == o) diff --git a/opendaylight/netconf/netconf-ssh/src/main/java/org/opendaylight/controller/netconf/osgi/NetconfSSHActivator.java b/opendaylight/netconf/netconf-ssh/src/main/java/org/opendaylight/controller/netconf/osgi/NetconfSSHActivator.java index 3b513790bd..446c500896 100644 --- a/opendaylight/netconf/netconf-ssh/src/main/java/org/opendaylight/controller/netconf/osgi/NetconfSSHActivator.java +++ b/opendaylight/netconf/netconf-ssh/src/main/java/org/opendaylight/controller/netconf/osgi/NetconfSSHActivator.java @@ -8,6 +8,8 @@ package org.opendaylight.controller.netconf.osgi; import com.google.common.base.Optional; +import java.io.FileInputStream; +import java.io.FileNotFoundException; import java.net.InetSocketAddress; import org.opendaylight.controller.netconf.ssh.NetconfSSHServer; import org.opendaylight.controller.netconf.ssh.authentication.AuthProvider; @@ -85,7 +87,28 @@ public class NetconfSSHActivator implements BundleActivator{ EXCEPTION_MESSAGE, true); if (sshSocketAddressOptional.isPresent()){ - AuthProvider authProvider = new AuthProvider(iUserManager); + String path = NetconfConfigUtil.getPrivateKeyPath(context); + path = path.replace("\\", "/"); + if (path.equals("")){ + throw new Exception("Missing netconf.ssh.pk.path key in configuration file."); + } + FileInputStream fis = null; + try { + fis = new FileInputStream(path); + } catch (FileNotFoundException e){ + throw new Exception("Missing file described by netconf.ssh.pk.path key in configuration file."); + } catch (SecurityException e){ + throw new Exception("Read access denied to file described by netconf.ssh.pk.path key in configuration file."); + } + AuthProvider authProvider = null; + try { + authProvider = new AuthProvider(iUserManager,fis); + } catch (Exception e){ + if (fis!=null){ + fis.close(); + } + throw (e); + } this.server = NetconfSSHServer.start(sshSocketAddressOptional.get().getPort(),tcpSocketAddress,authProvider); Thread serverThread = new Thread(server,"netconf SSH server thread"); serverThread.setDaemon(true); diff --git a/opendaylight/netconf/netconf-ssh/src/main/java/org/opendaylight/controller/netconf/ssh/authentication/AuthProvider.java b/opendaylight/netconf/netconf-ssh/src/main/java/org/opendaylight/controller/netconf/ssh/authentication/AuthProvider.java index a73dfdfd49..22dda95064 100644 --- a/opendaylight/netconf/netconf-ssh/src/main/java/org/opendaylight/controller/netconf/ssh/authentication/AuthProvider.java +++ b/opendaylight/netconf/netconf-ssh/src/main/java/org/opendaylight/controller/netconf/ssh/authentication/AuthProvider.java @@ -7,8 +7,6 @@ */ package org.opendaylight.controller.netconf.ssh.authentication; -import ch.ethz.ssh2.signature.RSAPrivateKey; -import java.io.IOException; import java.io.InputStream; import java.util.ArrayList; import java.util.List; @@ -17,26 +15,30 @@ import org.opendaylight.controller.sal.authorization.AuthResultEnum; import org.opendaylight.controller.sal.authorization.UserLevel; import org.opendaylight.controller.usermanager.IUserManager; import org.opendaylight.controller.usermanager.UserConfig; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; public class AuthProvider implements AuthProviderInterface { - private static RSAPrivateKey hostkey = null; private static IUserManager um; - private static final String DEAFULT_USER = "netconf"; - private static final String DEAFULT_PASSWORD = "netconf"; + private static final String DEFAULT_USER = "netconf"; + private static final String DEFAULT_PASSWORD = "netconf"; + private static InputStream privateKeyFileInputStream; + private static final Logger logger = LoggerFactory.getLogger(AuthProvider.class); - public AuthProvider(IUserManager ium) throws Exception { + public AuthProvider(IUserManager ium,InputStream privateKeyFileInputStream) throws Exception { this.um = ium; - if (this.um == null){ throw new Exception("No usermanager service available."); } + this.privateKeyFileInputStream = privateKeyFileInputStream; + List roles = new ArrayList(1); roles.add(UserLevel.SYSTEMADMIN.toString()); - this.um.addLocalUser(new UserConfig(DEAFULT_USER, DEAFULT_PASSWORD, roles)); + this.um.addLocalUser(new UserConfig(DEFAULT_USER, DEFAULT_PASSWORD, roles)); } @Override public boolean authenticated(String username, String password) throws Exception { @@ -51,15 +53,10 @@ public class AuthProvider implements AuthProviderInterface { } @Override - public char[] getPEMAsCharArray() { - - InputStream is = getClass().getResourceAsStream("/RSA.pk"); - try { - return IOUtils.toCharArray(is); - } catch (IOException e) { - e.printStackTrace(); - } - return null; + public char[] getPEMAsCharArray() throws Exception { + char [] PEM = IOUtils.toCharArray(privateKeyFileInputStream); + privateKeyFileInputStream.close(); + return PEM; } @Override diff --git a/opendaylight/netconf/netconf-ssh/src/main/java/org/opendaylight/controller/netconf/ssh/authentication/AuthProviderInterface.java b/opendaylight/netconf/netconf-ssh/src/main/java/org/opendaylight/controller/netconf/ssh/authentication/AuthProviderInterface.java index 71f1cc350f..8e40578a0e 100644 --- a/opendaylight/netconf/netconf-ssh/src/main/java/org/opendaylight/controller/netconf/ssh/authentication/AuthProviderInterface.java +++ b/opendaylight/netconf/netconf-ssh/src/main/java/org/opendaylight/controller/netconf/ssh/authentication/AuthProviderInterface.java @@ -13,7 +13,7 @@ import org.opendaylight.controller.usermanager.IUserManager; public interface AuthProviderInterface { public boolean authenticated(String username, String password) throws Exception; - public char[] getPEMAsCharArray(); + public char[] getPEMAsCharArray() throws Exception; public void removeUserManagerService(); public void addUserManagerService(IUserManager userManagerService); } diff --git a/opendaylight/netconf/netconf-ssh/src/main/java/org/opendaylight/controller/netconf/ssh/threads/SocketThread.java b/opendaylight/netconf/netconf-ssh/src/main/java/org/opendaylight/controller/netconf/ssh/threads/SocketThread.java index e5da03b4cf..32de75ca39 100644 --- a/opendaylight/netconf/netconf-ssh/src/main/java/org/opendaylight/controller/netconf/ssh/threads/SocketThread.java +++ b/opendaylight/netconf/netconf-ssh/src/main/java/org/opendaylight/controller/netconf/ssh/threads/SocketThread.java @@ -59,8 +59,8 @@ public class SocketThread implements Runnable, ServerAuthenticationCallback, Ser conn = new ServerConnection(socket); try { conn.setPEMHostKey(authProvider.getPEMAsCharArray(),"netconf"); - } catch (IOException e) { - e.printStackTrace(); + } catch (Exception e) { + logger.debug("Server authentication setup failed."); } conn.setAuthenticationCallback(this); conn.setServerConnectionCallback(this); diff --git a/opendaylight/netconf/netconf-ssh/src/test/java/org/opendaylight/controller/netconf/SSHServerTest.java b/opendaylight/netconf/netconf-ssh/src/test/java/org/opendaylight/controller/netconf/SSHServerTest.java index 62396ed87a..91783ff755 100644 --- a/opendaylight/netconf/netconf-ssh/src/test/java/org/opendaylight/controller/netconf/SSHServerTest.java +++ b/opendaylight/netconf/netconf-ssh/src/test/java/org/opendaylight/controller/netconf/SSHServerTest.java @@ -8,6 +8,7 @@ package org.opendaylight.controller.netconf; import ch.ethz.ssh2.Connection; +import java.io.InputStream; import java.net.InetSocketAddress; import junit.framework.Assert; import org.junit.Test; @@ -33,7 +34,8 @@ public class SSHServerTest { public void startSSHServer() throws Exception{ logger.info("Creating SSH server"); StubUserManager um = new StubUserManager(USER,PASSWORD); - AuthProvider ap = new AuthProvider(um); + InputStream is = getClass().getResourceAsStream("/RSA.pk"); + AuthProvider ap = new AuthProvider(um, is); NetconfSSHServer server = NetconfSSHServer.start(PORT,tcpAddress,ap); sshServerThread = new Thread(server); sshServerThread.setDaemon(true); diff --git a/opendaylight/netconf/netconf-ssh/src/test/resources/RSA.pk b/opendaylight/netconf/netconf-ssh/src/test/resources/RSA.pk new file mode 100644 index 0000000000..c0266c7bd2 --- /dev/null +++ b/opendaylight/netconf/netconf-ssh/src/test/resources/RSA.pk @@ -0,0 +1,27 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIEogIBAAKCAQEAuC9hbEacpewvylI0mwFwjy3Wou2hpr/ncN9BBiFDSaG5yW2k +3Oy+SCAcFCL+ZKWb6cc6Ch4gUeCwyEHRojZguuhliKtak9YQf6qbvpPLe00842Lx +iqNAGurMpzizCDsGFq8ChaAkBZQI3TvcHuPoSUWSMJ+K8xHpRyUdVr6g2yEjezKJ +sTXBtWaeCCh6YUafFujuDJk7fvYcPW7Je5KRBBStIKvxcMW0zB+7eq04deTHwGbJ +gGjKWilQ72hsDDP3Hbp5CJMAYg1r4GlCmFx3KyHRGztgWgNgaD7nNpKCkTLjtmA6 +b4x7TA+jrzZ6Af2z5TMrI4dv5w1SrxHaZ+ziLQIDAQABAoIBAHTndeGgq/rQf8De +Do+4CTaHtK0zQSAyu/azbXUzlZ7drKuCEVs8VMY4wzmwwGEnkF+A2YDkgEUX5X0l +8aYQ97KKoS9u+43MGCrAIhyDeGrpqlT1TzRcy+qJz53v6gq2U/X/3QztiQ+VV078 +mIluxNgE9XYxPaNsYfGLSCTv1+9c8y/hjGVX2kwFK+u4ut0ZZETggNa8UxfaHVDS +fIJQX9Gm3J3GSUV30fDGMBIUW6ESLc2L8b7u8Mp9TRP39ZeQSuEUjBe8MYKv0Rel +oEpjZvcnniMTpFbLpndBYn7/AoIiEBvtCN8faVTuRRcvvLcsRm09IctzKQYnMh6M +6PLKV+ECgYEA8HFRYaKHUzxpzE/fyon82GQbzqFFY0/bbWrfWICMfNbIgshJUie6 +FmH5iUFMfeqaT7v557HFM0GB9FeIeSbvd88YmiBAcRopZ3DfMkDH+DT73yJ+/TKG +2nrQtdhyuTIs4bwHqeS2BBJYs7PK9R2rratF3l34Tf7mjlvyOgygHdUCgYEAxBo2 +8hEBlAVNcNb1hTYUxe1w1B6675/mFlmw98Xmj9dRYfICXNhahs8tX3/lsBEd+vBu +fI0oyHaff8m5bPgGzD1ZMybfeROujNrgxaKVk7Ef0FDRRCop4bm18OroFlFAt9l8 +wMp++ToACbdvQvL/mjWMPYlIxhB/YxHswICZZvkCgYAexxKYwdo6sGAGlC7cWT9x +X5cjowcjyEQZRHXkeUgCbufpvcOM7aLnXJE5nY8yCwbHsBM0MlBA2GDPKylAANjk +aDEJAZneIHAuWodngl1Wi0m2bU7+ECqs6s2uiU9eH2sZVh1RBQK7kLGkBx6ys6KX +L3ZZGYRAT6GplWFzRsx0JQKBgCeVlxPD5QqpC1nEumi6YvUVGdpnnZpzL3HBhxxs +wT612wKnZFyze4qM1X7ahVXGDsQxtkvD/sCAWW/lG13orw6ZL6FIroF1PJ3ILOkY +CZN3hJF7TtKwpCWhZB2OfWzL2AGEkE8mUP0j/Q/5DCd6f6f0OSvOw3bfq6cm3iB5 +lP2ZAoGAXsRN5TZTX4AQ2xTlrDQ8A5XgcvyWQpJOmEXMTyHV7VaJVzmNWFVAvndK +5UIq8ALDwB2t7vjmMUW6euvIwqtXiop7G79UOb3e3NhzeyWFGQyBLqCRznGaXQTT +dlFy73xhukZMhFnj006bjKCYvOPnwuGl3+0fuWil5Rq3jOuY5c8= +-----END RSA PRIVATE KEY----- diff --git a/opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/AbstractNetconfSessionNegotiator.java b/opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/AbstractNetconfSessionNegotiator.java index 4fee930eff..26ea7ceb79 100644 --- a/opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/AbstractNetconfSessionNegotiator.java +++ b/opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/AbstractNetconfSessionNegotiator.java @@ -42,7 +42,7 @@ import java.util.concurrent.TimeUnit; public abstract class AbstractNetconfSessionNegotiator

extends AbstractSessionNegotiator { - // TODO what time ? + // TODO Adjust wait time for negotiation, now is 1 minute ? private static final long INITIAL_HOLDTIMER = 1; private static final Logger logger = LoggerFactory.getLogger(AbstractNetconfSessionNegotiator.class); diff --git a/opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/osgi/NetconfConfigUtil.java b/opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/osgi/NetconfConfigUtil.java index 987708d67e..55ed7e0744 100644 --- a/opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/osgi/NetconfConfigUtil.java +++ b/opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/osgi/NetconfConfigUtil.java @@ -23,6 +23,7 @@ public class NetconfConfigUtil { private static final String PORT_SUFFIX_PROP = ".port"; private static final String ADDRESS_SUFFIX_PROP = ".address"; private static final String CLIENT_PROP = ".client"; + private static final String PRIVATE_KEY_PATH_PROP = ".pk.path"; public static InetSocketAddress extractTCPNetconfAddress(BundleContext context, String exceptionMessageIfNotFound, boolean forClient) { @@ -38,6 +39,16 @@ public class NetconfConfigUtil { return extractSomeNetconfAddress(context, InfixProp.ssh, exceptionMessage, false); } + public static String getPrivateKeyPath(BundleContext context){ + return getPropertyValue(context,PREFIX_PROP + InfixProp.ssh +PRIVATE_KEY_PATH_PROP); + } + private static String getPropertyValue(BundleContext context, String propertyName){ + String propertyValue = context.getProperty(propertyName); + if (propertyValue == null){ + throw new IllegalStateException("Cannot find initial property with name '"+propertyName+"'"); + } + return propertyValue; + } /** * @param context * from which properties are being read. diff --git a/opendaylight/netconf/netconf-util/src/test/resources/netconfMessages/editConfig_addServiceNameOnTest.xml b/opendaylight/netconf/netconf-util/src/test/resources/netconfMessages/editConfig_addServiceNameOnTest.xml new file mode 100644 index 0000000000..6e68326382 --- /dev/null +++ b/opendaylight/netconf/netconf-util/src/test/resources/netconfMessages/editConfig_addServiceNameOnTest.xml @@ -0,0 +1,38 @@ + + + + + + + test-only + + merge + + + + + instance-from-code_dep + + test-impl:impl-dep + + + + + + + prefix:testing + + ref_dep_user_another_test1 + /modules/module[type='impl-dep'][name='instance-from-code_dep'] + + + + ref_dep_user_another_test2 + /modules/module[type='impl-dep'][name='instance-from-code_dep'] + + + + + + + diff --git a/opendaylight/netconf/netconf-util/src/test/resources/netconfMessages/editConfig_expectedResult.xml b/opendaylight/netconf/netconf-util/src/test/resources/netconfMessages/editConfig_expectedResult.xml index 7f884dc43c..36f79a50bc 100644 --- a/opendaylight/netconf/netconf-util/src/test/resources/netconfMessages/editConfig_expectedResult.xml +++ b/opendaylight/netconf/netconf-util/src/test/resources/netconfMessages/editConfig_expectedResult.xml @@ -1,19 +1,6 @@ - - - - - + diff --git a/opendaylight/netconf/netconf-util/src/test/resources/netconfMessages/editConfig_none.xml b/opendaylight/netconf/netconf-util/src/test/resources/netconfMessages/editConfig_none.xml index a7f1c86391..ade40f6a49 100644 --- a/opendaylight/netconf/netconf-util/src/test/resources/netconfMessages/editConfig_none.xml +++ b/opendaylight/netconf/netconf-util/src/test/resources/netconfMessages/editConfig_none.xml @@ -21,12 +21,11 @@ - test-impl:impl-netconf - test1 + instance-from-code 44 8ad1 @@ -72,7 +71,7 @@ test-impl:impl-netconf - test2 + test3 diff --git a/opendaylight/netconf/pom.xml b/opendaylight/netconf/pom.xml index c4b1467220..21a1ffe81d 100644 --- a/opendaylight/netconf/pom.xml +++ b/opendaylight/netconf/pom.xml @@ -48,7 +48,7 @@ 5.0.0 - 2.3.7 + 2.4.0 1.7.2 4.0.10.Final 0.9.2 diff --git a/opendaylight/northbound/bundlescanner/implementation/pom.xml b/opendaylight/northbound/bundlescanner/implementation/pom.xml index baa0755dc9..03cb9c20de 100644 --- a/opendaylight/northbound/bundlescanner/implementation/pom.xml +++ b/opendaylight/northbound/bundlescanner/implementation/pom.xml @@ -67,12 +67,12 @@ org.opendaylight.controller bundlescanner - 0.4.1-SNAPSHOT + ${bundlescanner.version} org.opendaylight.controller sal - 0.5.1-SNAPSHOT + ${sal.version} diff --git a/opendaylight/northbound/commons/pom.xml b/opendaylight/northbound/commons/pom.xml index 8e769a2349..2169f3f3e7 100644 --- a/opendaylight/northbound/commons/pom.xml +++ b/opendaylight/northbound/commons/pom.xml @@ -52,9 +52,10 @@ org.osgi.service.packageadmin, org.osgi.util.tracker, javax.servlet.http, - org.codehaus.jackson, - org.codehaus.jackson.jaxrs, - org.codehaus.jackson.map, + com.fasterxml.jackson.core, + com.fasterxml.jackson.databind, + com.fasterxml.jackson.jaxrs.base, + com.fasterxml.jackson.jaxrs.json, org.slf4j @@ -71,30 +72,44 @@ org.opendaylight.controller sal - 0.5.1-SNAPSHOT + ${sal.version} org.opendaylight.controller usermanager - 0.4.1-SNAPSHOT + ${usermanager.version} org.opendaylight.controller bundlescanner - 0.4.1-SNAPSHOT + ${bundlescanner.version} + - org.codehaus.jackson - jackson-core-asl + com.fasterxml.jackson.core + jackson-annotations + - org.codehaus.jackson - jackson-mapper-asl + com.fasterxml.jackson.core + jackson-core + - org.codehaus.jackson - jackson-jaxrs + com.fasterxml.jackson.core + jackson-databind + + + com.fasterxml.jackson.jaxrs + jackson-jaxrs-json-provider + + + + com.fasterxml.jackson.jaxrs + jackson-jaxrs-base + + junit junit @@ -114,10 +129,6 @@ jersey-client ${jersey.version} - - com.sun.jersey - jersey-json - ${jersey.version} - + diff --git a/opendaylight/northbound/commons/src/main/java/org/opendaylight/controller/northbound/commons/JacksonJsonProcessingExceptionMapper.java b/opendaylight/northbound/commons/src/main/java/org/opendaylight/controller/northbound/commons/JacksonJsonProcessingExceptionMapper.java index 5e5dee3279..eb43920826 100644 --- a/opendaylight/northbound/commons/src/main/java/org/opendaylight/controller/northbound/commons/JacksonJsonProcessingExceptionMapper.java +++ b/opendaylight/northbound/commons/src/main/java/org/opendaylight/controller/northbound/commons/JacksonJsonProcessingExceptionMapper.java @@ -15,7 +15,8 @@ import javax.ws.rs.core.Response; import javax.ws.rs.ext.ExceptionMapper; import javax.ws.rs.ext.Provider; -import org.codehaus.jackson.JsonProcessingException; +import com.fasterxml.jackson.core.JsonProcessingException; + /** * A custom exception mapper for handling Jackson JsonProcessingException types diff --git a/opendaylight/northbound/commons/src/main/java/org/opendaylight/controller/northbound/commons/NorthboundApplication.java b/opendaylight/northbound/commons/src/main/java/org/opendaylight/controller/northbound/commons/NorthboundApplication.java index e164abaf95..47bb3ffd7c 100644 --- a/opendaylight/northbound/commons/src/main/java/org/opendaylight/controller/northbound/commons/NorthboundApplication.java +++ b/opendaylight/northbound/commons/src/main/java/org/opendaylight/controller/northbound/commons/NorthboundApplication.java @@ -12,15 +12,14 @@ import java.util.Dictionary; import java.util.HashSet; import java.util.List; import java.util.Set; - import javax.ws.rs.core.Application; import javax.ws.rs.ext.ContextResolver; import javax.xml.bind.JAXBContext; import javax.xml.bind.JAXBException; import javax.xml.bind.annotation.XmlRootElement; -import org.codehaus.jackson.jaxrs.JacksonJaxbJsonProvider; -import org.codehaus.jackson.map.DeserializationConfig; +import com.fasterxml.jackson.databind.DeserializationFeature; +import com.fasterxml.jackson.jaxrs.json.JacksonJaxbJsonProvider; import org.opendaylight.controller.northbound.bundlescanner.IBundleScanService; import org.osgi.framework.Bundle; import org.osgi.framework.BundleContext; @@ -78,7 +77,7 @@ public class NorthboundApplication extends Application { private static final JacksonJaxbJsonProvider getJsonProvider() { JacksonJaxbJsonProvider jsonProvider = new JacksonJaxbJsonProvider(); - jsonProvider.configure(DeserializationConfig.Feature.FAIL_ON_UNKNOWN_PROPERTIES, + jsonProvider.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); return jsonProvider; } diff --git a/opendaylight/northbound/commons/src/test/java/org/opendaylight/controller/northbound/commons/exception/CommonsNorthboundExceptionTest.java b/opendaylight/northbound/commons/src/test/java/org/opendaylight/controller/northbound/commons/exception/CommonsNorthboundExceptionTest.java index 65790ad17c..0a282b9b28 100644 --- a/opendaylight/northbound/commons/src/test/java/org/opendaylight/controller/northbound/commons/exception/CommonsNorthboundExceptionTest.java +++ b/opendaylight/northbound/commons/src/test/java/org/opendaylight/controller/northbound/commons/exception/CommonsNorthboundExceptionTest.java @@ -23,7 +23,6 @@ public class CommonsNorthboundExceptionTest extends TestCase { try { throw new InternalServerErrorException("Internal Server Exception"); } catch (InternalServerErrorException e) { - Assert.assertTrue(e instanceof InternalServerErrorException); Assert.assertTrue(e.getResponse().getEntity() .equals("Internal Server Exception")); } @@ -34,7 +33,6 @@ public class CommonsNorthboundExceptionTest extends TestCase { try { throw new MethodNotAllowedException("Method Not Allowed Exception"); } catch (MethodNotAllowedException e) { - Assert.assertTrue(e instanceof MethodNotAllowedException); Assert.assertTrue(e.getResponse().getEntity() .equals("Method Not Allowed Exception")); } @@ -45,7 +43,6 @@ public class CommonsNorthboundExceptionTest extends TestCase { try { throw new NotAcceptableException("Not Acceptable Exception"); } catch (NotAcceptableException e) { - Assert.assertTrue(e instanceof NotAcceptableException); Assert.assertTrue(e.getResponse().getEntity() .equals("Not Acceptable Exception")); } @@ -56,7 +53,6 @@ public class CommonsNorthboundExceptionTest extends TestCase { try { throw new ResourceConflictException("Resource Conflict Exception"); } catch (ResourceConflictException e) { - Assert.assertTrue(e instanceof ResourceConflictException); Assert.assertTrue(e.getResponse().getEntity() .equals("Resource Conflict Exception")); } @@ -67,7 +63,6 @@ public class CommonsNorthboundExceptionTest extends TestCase { try { throw new ResourceForbiddenException("Resource Forbidden Exception"); } catch (ResourceForbiddenException e) { - Assert.assertTrue(e instanceof ResourceForbiddenException); Assert.assertTrue(e.getResponse().getEntity() .equals("Resource Forbidden Exception")); } @@ -78,7 +73,6 @@ public class CommonsNorthboundExceptionTest extends TestCase { try { throw new ResourceGoneException("Resource Gone Exception"); } catch (ResourceGoneException e) { - Assert.assertTrue(e instanceof ResourceGoneException); Assert.assertTrue(e.getResponse().getEntity() .equals("Resource Gone Exception")); } @@ -89,7 +83,6 @@ public class CommonsNorthboundExceptionTest extends TestCase { try { throw new ResourceNotFoundException("Resource Not Found Exception"); } catch (ResourceNotFoundException e) { - Assert.assertTrue(e instanceof ResourceNotFoundException); Assert.assertTrue(e.getResponse().getEntity() .equals("Resource Not Found Exception")); } @@ -101,7 +94,6 @@ public class CommonsNorthboundExceptionTest extends TestCase { throw new ServiceUnavailableException( "Service Unavailable Exception"); } catch (ServiceUnavailableException e) { - Assert.assertTrue(e instanceof ServiceUnavailableException); Assert.assertTrue(e.getResponse().getEntity() .equals("Service Unavailable Exception")); } @@ -112,7 +104,6 @@ public class CommonsNorthboundExceptionTest extends TestCase { try { throw new UnauthorizedException("Unauthorized Exception"); } catch (UnauthorizedException e) { - Assert.assertTrue(e instanceof UnauthorizedException); Assert.assertTrue(e.getResponse().getEntity() .equals("Unauthorized Exception")); } @@ -124,7 +115,6 @@ public class CommonsNorthboundExceptionTest extends TestCase { throw new UnsupportedMediaTypeException( "Unsupported Media Type Exception"); } catch (UnsupportedMediaTypeException e) { - Assert.assertTrue(e instanceof UnsupportedMediaTypeException); Assert.assertTrue(e.getResponse().getEntity() .equals("Unsupported Media Type Exception")); } diff --git a/opendaylight/northbound/connectionmanager/pom.xml b/opendaylight/northbound/connectionmanager/pom.xml index 0ddfcdb3e1..8ade6134e6 100644 --- a/opendaylight/northbound/connectionmanager/pom.xml +++ b/opendaylight/northbound/connectionmanager/pom.xml @@ -27,7 +27,7 @@ org.opendaylight.controller sal - 0.5.1-SNAPSHOT + ${sal.version} @@ -58,7 +58,8 @@ javax.xml.bind.annotation, javax.xml.bind, org.apache.catalina.filters, - org.codehaus.jackson.jaxrs, + com.fasterxml.jackson.jaxrs.base, + com.fasterxml.jackson.jaxrs.json, !org.codehaus.enunciate.jaxrs @@ -75,22 +76,22 @@ org.opendaylight.controller sal - 0.5.1-SNAPSHOT + ${sal.version} org.opendaylight.controller sal.connection - 0.1.1-SNAPSHOT + ${sal.connection.version} org.opendaylight.controller connectionmanager - 0.1.1-SNAPSHOT + ${connectionmanager.version} org.opendaylight.controller containermanager - 0.5.1-SNAPSHOT + ${containermanager.version} org.codehaus.enunciate @@ -100,7 +101,7 @@ org.opendaylight.controller commons.northbound - 0.4.1-SNAPSHOT + ${commons.northbound.version} diff --git a/opendaylight/northbound/containermanager/pom.xml b/opendaylight/northbound/containermanager/pom.xml index 517f2e76a3..a8b8f2a5d0 100644 --- a/opendaylight/northbound/containermanager/pom.xml +++ b/opendaylight/northbound/containermanager/pom.xml @@ -52,7 +52,8 @@ javax.xml.bind, org.slf4j, org.apache.catalina.filters, - org.codehaus.jackson.jaxrs, + com.fasterxml.jackson.jaxrs.base, + com.fasterxml.jackson.jaxrs.json, !org.codehaus.enunciate.jaxrs /controller/nb/v2/containermanager @@ -66,7 +67,7 @@ org.opendaylight.controller containermanager - 0.5.1-SNAPSHOT + ${containermanager.version} org.opendaylight.controller @@ -81,7 +82,7 @@ org.opendaylight.controller sal - 0.5.1-SNAPSHOT + ${sal.version} org.codehaus.enunciate @@ -91,7 +92,7 @@ org.opendaylight.controller commons.northbound - 0.4.1-SNAPSHOT + ${commons.northbound.version} diff --git a/opendaylight/northbound/containermanager/src/main/java/org/opendaylight/controller/containermanager/northbound/ContainerManagerNorthboundRSApplication.java b/opendaylight/northbound/containermanager/src/main/java/org/opendaylight/controller/containermanager/northbound/ContainerManagerNorthboundRSApplication.java index 10559a2bbd..b9d2200180 100644 --- a/opendaylight/northbound/containermanager/src/main/java/org/opendaylight/controller/containermanager/northbound/ContainerManagerNorthboundRSApplication.java +++ b/opendaylight/northbound/containermanager/src/main/java/org/opendaylight/controller/containermanager/northbound/ContainerManagerNorthboundRSApplication.java @@ -13,7 +13,7 @@ import java.util.HashSet; import java.util.Set; import javax.ws.rs.core.Application; -import org.codehaus.jackson.jaxrs.JacksonJaxbJsonProvider; +import com.fasterxml.jackson.jaxrs.json.JacksonJaxbJsonProvider; /** * Instance of javax.ws.rs.core.Application used to return the classes diff --git a/opendaylight/northbound/controllermanager/pom.xml b/opendaylight/northbound/controllermanager/pom.xml index d1299a2559..8c3279e6c7 100644 --- a/opendaylight/northbound/controllermanager/pom.xml +++ b/opendaylight/northbound/controllermanager/pom.xml @@ -27,7 +27,7 @@ org.opendaylight.controller sal - 0.5.1-SNAPSHOT + ${sal.version} @@ -59,8 +59,9 @@ javax.xml.bind, org.slf4j, org.apache.catalina.filters, - org.codehaus.jackson.jaxrs, - org.codehaus.jackson.annotate, + com.fasterxml.jackson.annotation, + com.fasterxml.jackson.jaxrs.base, + com.fasterxml.jackson.jaxrs.json, !org.codehaus.enunciate.jaxrs /controller/nb/v2/controllermanager @@ -75,30 +76,30 @@ org.opendaylight.controller.thirdparty com.sun.jersey.jersey-servlet - 1.18-SNAPSHOT + ${jersey-servlet.version} org.opendaylight.controller containermanager - 0.5.1-SNAPSHOT + ${containermanager.version} org.opendaylight.controller switchmanager - 0.6.1-SNAPSHOT + ${switchmanager.api.version} org.opendaylight.controller sal - 0.5.1-SNAPSHOT + ${sal.version} org.opendaylight.controller commons.northbound - 0.4.1-SNAPSHOT + ${commons.northbound.version} @@ -120,7 +121,7 @@ org.opendaylight.controller.thirdparty org.apache.catalina.filters.CorsFilter - 7.0.43-SNAPSHOT + ${corsfilter.version} diff --git a/opendaylight/northbound/controllermanager/src/main/java/org/opendaylight/controller/controllermanager/northbound/ControllerProperties.java b/opendaylight/northbound/controllermanager/src/main/java/org/opendaylight/controller/controllermanager/northbound/ControllerProperties.java index ac0d039746..1560f96072 100644 --- a/opendaylight/northbound/controllermanager/src/main/java/org/opendaylight/controller/controllermanager/northbound/ControllerProperties.java +++ b/opendaylight/northbound/controllermanager/src/main/java/org/opendaylight/controller/controllermanager/northbound/ControllerProperties.java @@ -4,15 +4,14 @@ import java.util.HashMap; import java.util.HashSet; import java.util.Map; import java.util.Set; - import javax.xml.bind.annotation.XmlAccessType; import javax.xml.bind.annotation.XmlAccessorType; import javax.xml.bind.annotation.XmlElementRef; import javax.xml.bind.annotation.XmlElementWrapper; import javax.xml.bind.annotation.XmlRootElement; -import org.codehaus.jackson.annotate.JsonIgnore; -import org.codehaus.jackson.annotate.JsonProperty; +import com.fasterxml.jackson.annotation.JsonIgnore; +import com.fasterxml.jackson.annotation.JsonProperty; import org.opendaylight.controller.sal.core.Property; /** diff --git a/opendaylight/northbound/flowprogrammer/pom.xml b/opendaylight/northbound/flowprogrammer/pom.xml index 1b81ccb450..565bd5f6aa 100644 --- a/opendaylight/northbound/flowprogrammer/pom.xml +++ b/opendaylight/northbound/flowprogrammer/pom.xml @@ -28,7 +28,7 @@ org.opendaylight.controller sal - 0.5.1-SNAPSHOT + ${sal.version} @@ -57,7 +57,8 @@ javax.xml.bind.annotation, javax.xml.bind, org.slf4j, - org.codehaus.jackson.jaxrs, + com.fasterxml.jackson.jaxrs.base, + com.fasterxml.jackson.jaxrs.json, !org.codehaus.enunciate.jaxrs @@ -74,7 +75,7 @@ org.opendaylight.controller containermanager - 0.5.1-SNAPSHOT + ${containermanager.version} org.opendaylight.controller @@ -83,12 +84,12 @@ org.opendaylight.controller forwardingrulesmanager - 0.4.1-SNAPSHOT + ${forwardingrulesmanager.version} org.opendaylight.controller sal - 0.7.0-SNAPSHOT + ${sal.version} org.codehaus.enunciate @@ -98,7 +99,7 @@ org.opendaylight.controller commons.northbound - 0.4.1-SNAPSHOT + ${commons.northbound.version} junit diff --git a/opendaylight/northbound/hosttracker/pom.xml b/opendaylight/northbound/hosttracker/pom.xml index 541dfcfe2d..aab519e5f6 100644 --- a/opendaylight/northbound/hosttracker/pom.xml +++ b/opendaylight/northbound/hosttracker/pom.xml @@ -27,7 +27,7 @@ org.opendaylight.controller sal - 0.5.1-SNAPSHOT + ${sal.version} @@ -59,7 +59,8 @@ javax.xml.bind, org.slf4j, org.apache.catalina.filters, - org.codehaus.jackson.jaxrs, + com.fasterxml.jackson.jaxrs.base, + com.fasterxml.jackson.jaxrs.json, !org.codehaus.enunciate.jaxrs /controller/nb/v2/hosttracker @@ -74,7 +75,7 @@ org.opendaylight.controller containermanager - 0.5.1-SNAPSHOT + ${containermanager.version} org.opendaylight.controller @@ -88,12 +89,12 @@ org.opendaylight.controller sal - 0.5.1-SNAPSHOT + ${sal.version} org.opendaylight.controller commons.northbound - 0.4.1-SNAPSHOT + ${commons.northbound.version} org.codehaus.enunciate diff --git a/opendaylight/northbound/integrationtest/pom.xml b/opendaylight/northbound/integrationtest/pom.xml index 793af2f5d7..d1815bbf8c 100644 --- a/opendaylight/northbound/integrationtest/pom.xml +++ b/opendaylight/northbound/integrationtest/pom.xml @@ -266,26 +266,32 @@ logback-classic ${logback.version} + - org.codehaus.jackson - jackson-mapper-asl - ${jackson.version} + com.fasterxml.jackson.core + jackson-databind + - org.codehaus.jackson - jackson-core-asl - ${jackson.version} + com.fasterxml.jackson.core + jackson-annotations + - org.codehaus.jackson - jackson-jaxrs - ${jackson.version} + com.fasterxml.jackson.core + jackson-core + - org.codehaus.jackson - jackson-xc - ${jackson.version} + com.fasterxml.jackson.jaxrs + jackson-jaxrs-json-provider + + + com.fasterxml.jackson.module + jackson-module-jaxb-annotations + + org.codehaus.jettison jettison @@ -672,11 +678,7 @@ jersey-client ${jersey.version} - - com.sun.jersey - jersey-json - ${jersey.version} - + eclipselink javax.resource diff --git a/opendaylight/northbound/integrationtest/src/test/java/org/opendaylight/controller/northbound/integrationtest/NorthboundIT.java b/opendaylight/northbound/integrationtest/src/test/java/org/opendaylight/controller/northbound/integrationtest/NorthboundIT.java index e0ffa4a2df..1e7e93f8aa 100644 --- a/opendaylight/northbound/integrationtest/src/test/java/org/opendaylight/controller/northbound/integrationtest/NorthboundIT.java +++ b/opendaylight/northbound/integrationtest/src/test/java/org/opendaylight/controller/northbound/integrationtest/NorthboundIT.java @@ -15,7 +15,6 @@ import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; - import javax.inject.Inject; import org.apache.commons.codec.binary.Base64; @@ -44,8 +43,8 @@ import org.opendaylight.controller.sal.topology.IListenTopoUpdates; import org.opendaylight.controller.sal.topology.TopoEdgeUpdate; import org.opendaylight.controller.switchmanager.IInventoryListener; import org.opendaylight.controller.usermanager.IUserManager; -import org.ops4j.pax.exam.Option; import org.ops4j.pax.exam.Configuration; +import org.ops4j.pax.exam.Option; import org.ops4j.pax.exam.junit.PaxExam; import org.ops4j.pax.exam.util.PathUtils; import org.osgi.framework.Bundle; @@ -187,7 +186,6 @@ public class NorthboundIT { System.out.println("HTTP response code: " + response.getStatus()); System.out.println("HTTP response message: " + response.getEntity()); } - return response.getEntity(); } catch (Exception e) { if (debugMsg) { @@ -863,7 +861,7 @@ public class NorthboundIT { // code fc = "{\"name\":\"test1\", \"node\":{\"id\":\"51966\",\"type\":\"STUB\"}, \"actions\":[\"LOOPBACK\"]}"; result = getJsonResult(baseURL + "node/STUB/51966/staticFlow/test1", "PUT", fc); - Assert.assertTrue(result.equals("Success")); + Assert.assertTrue(result.contains("Success")); fc = "{\"name\":\"test2\", \"node\":{\"id\":\"51966\",\"type\":\"STUB\"}, \"actions\":[\"DROP\"]}"; result = getJsonResult(baseURL + "node/STUB/51966/staticFlow/test2", "PUT", fc); @@ -1391,10 +1389,13 @@ public class NorthboundIT { mavenBundle("org.opendaylight.controller", "flowprogrammer.northbound").versionAsInProject(), mavenBundle("org.opendaylight.controller", "subnets.northbound").versionAsInProject(), - mavenBundle("org.codehaus.jackson", "jackson-mapper-asl").versionAsInProject(), - mavenBundle("org.codehaus.jackson", "jackson-core-asl").versionAsInProject(), - mavenBundle("org.codehaus.jackson", "jackson-jaxrs").versionAsInProject(), - mavenBundle("org.codehaus.jackson", "jackson-xc").versionAsInProject(), + mavenBundle("com.fasterxml.jackson.core", "jackson-annotations").versionAsInProject(), + mavenBundle("com.fasterxml.jackson.core", "jackson-core").versionAsInProject(), + mavenBundle("com.fasterxml.jackson.core", "jackson-databind").versionAsInProject(), + mavenBundle("com.fasterxml.jackson.jaxrs", "jackson-jaxrs-json-provider").versionAsInProject(), + mavenBundle("com.fasterxml.jackson.jaxrs", "jackson-jaxrs-base").versionAsInProject(), + mavenBundle("com.fasterxml.jackson.module", "jackson-module-jaxb-annotations").versionAsInProject(), + mavenBundle("org.codehaus.jettison", "jettison").versionAsInProject(), mavenBundle("commons-io", "commons-io").versionAsInProject(), @@ -1493,7 +1494,7 @@ public class NorthboundIT { mavenBundle("com.sun.jersey", "jersey-client").versionAsInProject(), mavenBundle("com.sun.jersey", "jersey-server").versionAsInProject().startLevel(2), mavenBundle("com.sun.jersey", "jersey-core").versionAsInProject().startLevel(2), - mavenBundle("com.sun.jersey", "jersey-json").versionAsInProject().startLevel(2), junitBundles()); + junitBundles()); } } diff --git a/opendaylight/northbound/networkconfiguration/bridgedomain/pom.xml b/opendaylight/northbound/networkconfiguration/bridgedomain/pom.xml index aa9fea5467..483d993d04 100644 --- a/opendaylight/northbound/networkconfiguration/bridgedomain/pom.xml +++ b/opendaylight/northbound/networkconfiguration/bridgedomain/pom.xml @@ -27,7 +27,7 @@ org.opendaylight.controller sal - 0.5.1-SNAPSHOT + ${sal.version} @@ -59,7 +59,8 @@ javax.xml.bind.annotation, javax.xml.bind, org.apache.catalina.filters, - org.codehaus.jackson.jaxrs, + com.fasterxml.jackson.jaxrs.base, + com.fasterxml.jackson.jaxrs.json, !org.codehaus.enunciate.jaxrs @@ -76,27 +77,27 @@ org.opendaylight.controller sal - 0.5.1-SNAPSHOT + ${sal.version} org.opendaylight.controller sal.connection - 0.1.1-SNAPSHOT + ${sal.connection.version} org.opendaylight.controller sal.networkconfiguration - 0.0.2-SNAPSHOT + ${sal.networkconfiguration.version} org.opendaylight.controller connectionmanager - 0.1.1-SNAPSHOT + ${connectionmanager.version} org.opendaylight.controller containermanager - 0.5.1-SNAPSHOT + ${containermanager.version} org.codehaus.enunciate @@ -106,7 +107,7 @@ org.opendaylight.controller commons.northbound - 0.4.1-SNAPSHOT + ${commons.northbound.version} diff --git a/opendaylight/northbound/networkconfiguration/neutron/pom.xml b/opendaylight/northbound/networkconfiguration/neutron/pom.xml index f8342f935c..d54f2c5b28 100644 --- a/opendaylight/northbound/networkconfiguration/neutron/pom.xml +++ b/opendaylight/northbound/networkconfiguration/neutron/pom.xml @@ -89,17 +89,17 @@ org.opendaylight.controller containermanager - 0.5.1-SNAPSHOT + ${containermanager.version} org.opendaylight.controller sal - 0.5.1-SNAPSHOT + ${sal.version} org.opendaylight.controller commons.northbound - 0.4.1-SNAPSHOT + ${commons.northbound.version} org.opendaylight.controller diff --git a/opendaylight/northbound/staticrouting/pom.xml b/opendaylight/northbound/staticrouting/pom.xml index d169de9f2a..c020e6b2a2 100644 --- a/opendaylight/northbound/staticrouting/pom.xml +++ b/opendaylight/northbound/staticrouting/pom.xml @@ -27,7 +27,7 @@ org.opendaylight.controller sal - 0.5.1-SNAPSHOT + ${sal.version} @@ -57,7 +57,8 @@ javax.xml.bind.annotation, javax.xml.bind, org.apache.catalina.filters, - org.codehaus.jackson.jaxrs, + com.fasterxml.jackson.jaxrs.base, + com.fasterxml.jackson.jaxrs.json, !org.codehaus.enunciate.jaxrs @@ -74,12 +75,12 @@ org.opendaylight.controller sal - 0.5.1-SNAPSHOT + ${sal.version} org.opendaylight.controller containermanager - 0.5.1-SNAPSHOT + ${containermanager.version} org.opendaylight.controller @@ -94,7 +95,7 @@ org.opendaylight.controller commons.northbound - 0.4.1-SNAPSHOT + ${commons.northbound.version} junit diff --git a/opendaylight/northbound/statistics/pom.xml b/opendaylight/northbound/statistics/pom.xml index 8df02c976b..95410b0d3a 100644 --- a/opendaylight/northbound/statistics/pom.xml +++ b/opendaylight/northbound/statistics/pom.xml @@ -27,7 +27,7 @@ org.opendaylight.controller sal - 0.5.1-SNAPSHOT + ${sal.version} @@ -65,7 +65,8 @@ javax.xml.bind, org.slf4j, org.apache.catalina.filters, - org.codehaus.jackson.jaxrs, + com.fasterxml.jackson.jaxrs.base, + com.fasterxml.jackson.jaxrs.json, !org.codehaus.enunciate.jaxrs @@ -82,22 +83,22 @@ org.opendaylight.controller containermanager - 0.5.1-SNAPSHOT + ${containermanager.version} org.opendaylight.controller statisticsmanager - 0.4.1-SNAPSHOT + ${statisticsmanager.version} org.opendaylight.controller sal - 0.5.1-SNAPSHOT + ${sal.version} org.opendaylight.controller commons.northbound - 0.4.1-SNAPSHOT + ${commons.northbound.version} org.codehaus.enunciate diff --git a/opendaylight/northbound/subnets/pom.xml b/opendaylight/northbound/subnets/pom.xml index bdf0b988f8..c7108b2efa 100644 --- a/opendaylight/northbound/subnets/pom.xml +++ b/opendaylight/northbound/subnets/pom.xml @@ -27,22 +27,22 @@ org.opendaylight.controller sal - 0.5.1-SNAPSHOT + ${sal.version} org.opendaylight.controller clustering.services - 0.4.1-SNAPSHOT + ${clustering.services.version} org.opendaylight.controller configuration - 0.4.1-SNAPSHOT + ${configuration.version} org.opendaylight.controller switchmanager - 0.5.1-SNAPSHOT + ${switchmanager.api.version} @@ -72,7 +72,8 @@ javax.xml.bind.annotation, org.slf4j, org.apache.catalina.filters, - org.codehaus.jackson.jaxrs, + com.fasterxml.jackson.jaxrs.base, + com.fasterxml.jackson.jaxrs.json, !org.codehaus.enunciate.jaxrs @@ -89,12 +90,12 @@ org.opendaylight.controller sal - 0.5.1-SNAPSHOT + ${sal.version} org.opendaylight.controller containermanager - 0.5.1-SNAPSHOT + ${containermanager.version} org.opendaylight.controller @@ -103,7 +104,7 @@ org.opendaylight.controller commons.northbound - 0.4.1-SNAPSHOT + ${commons.northbound.version} org.codehaus.enunciate diff --git a/opendaylight/northbound/switchmanager/pom.xml b/opendaylight/northbound/switchmanager/pom.xml index e4447fee2d..a1932f521b 100644 --- a/opendaylight/northbound/switchmanager/pom.xml +++ b/opendaylight/northbound/switchmanager/pom.xml @@ -28,7 +28,7 @@ org.opendaylight.controller sal - 0.5.1-SNAPSHOT + ${sal.version} @@ -59,8 +59,8 @@ javax.xml.bind, org.slf4j, org.apache.catalina.filters, - org.codehaus.jackson.jaxrs, - org.codehaus.jackson.annotate, + com.fasterxml.jackson.annotation, + com.fasterxml.jackson.databind, !org.codehaus.enunciate.jaxrs /controller/nb/v2/switchmanager @@ -75,7 +75,7 @@ org.opendaylight.controller containermanager - 0.5.1-SNAPSHOT + ${containermanager.version} org.opendaylight.controller @@ -85,13 +85,13 @@ org.opendaylight.controller sal - 0.5.1-SNAPSHOT + ${sal.version} org.opendaylight.controller commons.northbound - 0.4.1-SNAPSHOT + ${commons.northbound.version} diff --git a/opendaylight/northbound/switchmanager/src/main/java/org/opendaylight/controller/switchmanager/northbound/NodeConnectorProperties.java b/opendaylight/northbound/switchmanager/src/main/java/org/opendaylight/controller/switchmanager/northbound/NodeConnectorProperties.java index 43d3aae57c..00f0d4b054 100644 --- a/opendaylight/northbound/switchmanager/src/main/java/org/opendaylight/controller/switchmanager/northbound/NodeConnectorProperties.java +++ b/opendaylight/northbound/switchmanager/src/main/java/org/opendaylight/controller/switchmanager/northbound/NodeConnectorProperties.java @@ -13,15 +13,15 @@ import java.util.HashMap; import java.util.HashSet; import java.util.Map; import java.util.Set; -import javax.xml.bind.annotation.XmlRootElement; -import javax.xml.bind.annotation.XmlElementRef; import javax.xml.bind.annotation.XmlAccessType; import javax.xml.bind.annotation.XmlAccessorType; import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlElementRef; import javax.xml.bind.annotation.XmlElementWrapper; +import javax.xml.bind.annotation.XmlRootElement; -import org.codehaus.jackson.annotate.JsonIgnore; -import org.codehaus.jackson.annotate.JsonProperty; +import com.fasterxml.jackson.annotation.JsonIgnore; +import com.fasterxml.jackson.annotation.JsonProperty; import org.opendaylight.controller.sal.core.NodeConnector; import org.opendaylight.controller.sal.core.Property; diff --git a/opendaylight/northbound/switchmanager/src/main/java/org/opendaylight/controller/switchmanager/northbound/NodeProperties.java b/opendaylight/northbound/switchmanager/src/main/java/org/opendaylight/controller/switchmanager/northbound/NodeProperties.java index 58a024c928..51e96c49ea 100644 --- a/opendaylight/northbound/switchmanager/src/main/java/org/opendaylight/controller/switchmanager/northbound/NodeProperties.java +++ b/opendaylight/northbound/switchmanager/src/main/java/org/opendaylight/controller/switchmanager/northbound/NodeProperties.java @@ -13,15 +13,15 @@ import java.util.HashMap; import java.util.HashSet; import java.util.Map; import java.util.Set; -import javax.xml.bind.annotation.XmlRootElement; -import javax.xml.bind.annotation.XmlElementRef; import javax.xml.bind.annotation.XmlAccessType; import javax.xml.bind.annotation.XmlAccessorType; import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlElementRef; import javax.xml.bind.annotation.XmlElementWrapper; +import javax.xml.bind.annotation.XmlRootElement; -import org.codehaus.jackson.annotate.JsonIgnore; -import org.codehaus.jackson.annotate.JsonProperty; +import com.fasterxml.jackson.annotation.JsonIgnore; +import com.fasterxml.jackson.annotation.JsonProperty; import org.opendaylight.controller.sal.core.Node; import org.opendaylight.controller.sal.core.Property; diff --git a/opendaylight/northbound/topology/pom.xml b/opendaylight/northbound/topology/pom.xml index 3b3abc3436..4cdfb02d58 100644 --- a/opendaylight/northbound/topology/pom.xml +++ b/opendaylight/northbound/topology/pom.xml @@ -29,7 +29,7 @@ org.opendaylight.controller sal - 0.5.1-SNAPSHOT + ${sal.version} @@ -56,14 +56,15 @@ org.opendaylight.controller.usermanager, org.opendaylight.controller.topologymanager, com.sun.jersey.spi.container.servlet, - org.codehaus.jackson.annotate, + com.fasterxml.jackson.annotation, javax.ws.rs, javax.ws.rs.core, javax.xml.bind, javax.xml.bind.annotation, org.slf4j, org.apache.catalina.filters, - org.codehaus.jackson.jaxrs, + com.fasterxml.jackson.jaxrs.base, + com.fasterxml.jackson.jaxrs.json, !org.codehaus.enunciate.jaxrs /controller/nb/v2/topology @@ -83,22 +84,22 @@ org.opendaylight.controller containermanager - 0.5.1-SNAPSHOT + ${containermanager.version} org.opendaylight.controller commons.northbound - 0.4.1-SNAPSHOT + ${commons.northbound.version} org.opendaylight.controller sal - 0.5.1-SNAPSHOT + ${sal.version} org.opendaylight.controller topologymanager - 0.4.1-SNAPSHOT + ${topologymanager.version} junit diff --git a/opendaylight/northbound/topology/src/main/java/org/opendaylight/controller/topology/northbound/EdgeProperties.java b/opendaylight/northbound/topology/src/main/java/org/opendaylight/controller/topology/northbound/EdgeProperties.java index 6614bbe640..1d4a8a66ee 100644 --- a/opendaylight/northbound/topology/src/main/java/org/opendaylight/controller/topology/northbound/EdgeProperties.java +++ b/opendaylight/northbound/topology/src/main/java/org/opendaylight/controller/topology/northbound/EdgeProperties.java @@ -13,7 +13,6 @@ import java.util.HashMap; import java.util.HashSet; import java.util.Map; import java.util.Set; - import javax.xml.bind.annotation.XmlAccessType; import javax.xml.bind.annotation.XmlAccessorType; import javax.xml.bind.annotation.XmlElement; @@ -21,8 +20,8 @@ import javax.xml.bind.annotation.XmlElementRef; import javax.xml.bind.annotation.XmlElementWrapper; import javax.xml.bind.annotation.XmlRootElement; -import org.codehaus.jackson.annotate.JsonIgnore; -import org.codehaus.jackson.annotate.JsonProperty; +import com.fasterxml.jackson.annotation.JsonIgnore; +import com.fasterxml.jackson.annotation.JsonProperty; import org.opendaylight.controller.sal.core.Edge; import org.opendaylight.controller.sal.core.Property; diff --git a/opendaylight/northbound/usermanager/pom.xml b/opendaylight/northbound/usermanager/pom.xml index 8a85dbb622..b48d67252e 100644 --- a/opendaylight/northbound/usermanager/pom.xml +++ b/opendaylight/northbound/usermanager/pom.xml @@ -47,7 +47,8 @@ javax.xml.bind.annotation, org.slf4j, org.apache.catalina.filters, - org.codehaus.jackson.jaxrs, + com.fasterxml.jackson.jaxrs.base, + com.fasterxml.jackson.jaxrs.json, !org.codehaus.enunciate.jaxrs @@ -64,17 +65,17 @@ org.opendaylight.controller sal - 0.5.1-SNAPSHOT + ${sal.version} org.opendaylight.controller usermanager - 0.4.1-SNAPSHOT + ${usermanager.version} org.opendaylight.controller commons.northbound - 0.4.1-SNAPSHOT + ${commons.northbound.version} org.codehaus.enunciate diff --git a/opendaylight/samples/loadbalancer/src/test/java/org/opendaylight/controller/samples/loadbalancer/internal/LoadBalancerTest.java b/opendaylight/samples/loadbalancer/src/test/java/org/opendaylight/controller/samples/loadbalancer/internal/LoadBalancerTest.java index 45d041c3e1..4fd3f4a32d 100644 --- a/opendaylight/samples/loadbalancer/src/test/java/org/opendaylight/controller/samples/loadbalancer/internal/LoadBalancerTest.java +++ b/opendaylight/samples/loadbalancer/src/test/java/org/opendaylight/controller/samples/loadbalancer/internal/LoadBalancerTest.java @@ -29,7 +29,6 @@ public class LoadBalancerTest extends TestCase { public void testRoundRobinPolicy() { ConfigManager cm = null; cm = new ConfigManager(); - Assert.assertFalse(cm== null); Pool pool = cm.createPool("TestPool","roundrobin"); VIP vip = cm.createVIP("TestVIP","10.0.0.9","TCP",(short)5550,"TestPool"); diff --git a/opendaylight/samples/northbound/loadbalancer/pom.xml b/opendaylight/samples/northbound/loadbalancer/pom.xml index 543aa8ca54..1bbc5bf23e 100644 --- a/opendaylight/samples/northbound/loadbalancer/pom.xml +++ b/opendaylight/samples/northbound/loadbalancer/pom.xml @@ -59,7 +59,8 @@ javax.xml.bind, org.slf4j, org.apache.catalina.filters, - org.codehaus.jackson.jaxrs, + com.fasterxml.jackson.jaxrs.base, + com.fasterxml.jackson.jaxrs.json, !org.codehaus.enunciate.jaxrs /one/nb/v2/lb diff --git a/opendaylight/topologymanager/implementation/src/test/java/org/opendaylight/controller/topologymanager/internal/TopologyManagerImplTest.java b/opendaylight/topologymanager/implementation/src/test/java/org/opendaylight/controller/topologymanager/internal/TopologyManagerImplTest.java index 97966255a0..fa01fa6a60 100644 --- a/opendaylight/topologymanager/implementation/src/test/java/org/opendaylight/controller/topologymanager/internal/TopologyManagerImplTest.java +++ b/opendaylight/topologymanager/implementation/src/test/java/org/opendaylight/controller/topologymanager/internal/TopologyManagerImplTest.java @@ -35,10 +35,10 @@ import org.opendaylight.controller.sal.core.State; import org.opendaylight.controller.sal.core.UpdateType; import org.opendaylight.controller.sal.packet.address.EthernetAddress; import org.opendaylight.controller.sal.topology.TopoEdgeUpdate; -import org.opendaylight.controller.sal.utils.Status; -import org.opendaylight.controller.sal.utils.StatusCode; import org.opendaylight.controller.sal.utils.NodeConnectorCreator; import org.opendaylight.controller.sal.utils.NodeCreator; +import org.opendaylight.controller.sal.utils.Status; +import org.opendaylight.controller.sal.utils.StatusCode; import org.opendaylight.controller.switchmanager.ISwitchManager; import org.opendaylight.controller.switchmanager.SpanConfig; import org.opendaylight.controller.switchmanager.Subnet; @@ -55,7 +55,7 @@ public class TopologyManagerImplTest { private final class TestSwitchManager implements ISwitchManager { private final Set nodeSet = new HashSet(); private final Set nodeConnectorSet = - new HashSet(); + new HashSet(); private void addNodeConnectors(NodeConnector ... connectors) { for (NodeConnector nc: connectors) { @@ -69,9 +69,9 @@ public class TopologyManagerImplTest { private void addNodeConnectors(TopologyUserLinkConfig ... links) { for (TopologyUserLinkConfig link: links) { NodeConnector src = - NodeConnector.fromString(link.getSrcNodeConnector()); + NodeConnector.fromString(link.getSrcNodeConnector()); NodeConnector dst = - NodeConnector.fromString(link.getDstNodeConnector()); + NodeConnector.fromString(link.getDstNodeConnector()); addNodeConnectors(src, dst); } } @@ -292,6 +292,35 @@ public class TopologyManagerImplTest { public String getNodeDescription(Node node) { return null; } + + @Override + public Status removeControllerProperty(String propertyName){ + return null; + } + + @Override + public Set getConfiguredNotConnectedSwitches() { + // TODO Auto-generated method stub + return null; + } + + @Override + public Map getControllerProperties() { + // TODO Auto-generated method stub + return null; + } + + @Override + public Property getControllerProperty(String propertyName) { + // TODO Auto-generated method stub + return null; + } + + @Override + public Status setControllerProperty(Property property) { + // TODO Auto-generated method stub + return null; + } } /* @@ -485,13 +514,13 @@ public class TopologyManagerImplTest { Assert.assertTrue(topoManagerImpl.getUserLinks().isEmpty()); TopologyUserLinkConfig badlink1 = - new TopologyUserLinkConfig("bad1", "OF|1@OF|4", "OF|1@OF|5"); + new TopologyUserLinkConfig("bad1", "OF|1@OF|4", "OF|1@OF|5"); TopologyUserLinkConfig badlink2 = - new TopologyUserLinkConfig("bad2", "OF|10@OF|7", "OF|7@OF|13"); + new TopologyUserLinkConfig("bad2", "OF|10@OF|7", "OF|7@OF|13"); Assert.assertEquals(StatusCode.NOTFOUND, - topoManagerImpl.addUserLink(badlink1).getCode()); + topoManagerImpl.addUserLink(badlink1).getCode()); Assert.assertEquals(StatusCode.NOTFOUND, - topoManagerImpl.addUserLink(badlink2).getCode()); + topoManagerImpl.addUserLink(badlink2).getCode()); } @Test @@ -559,7 +588,7 @@ public class TopologyManagerImplTest { reverseLink[i] = new TopologyUserLinkConfig(name, dstNodeConnector, srcNodeConnector); Assert.assertEquals(StatusCode.NOTFOUND, - topoManagerImpl.addUserLink(link[i]).getCode()); + topoManagerImpl.addUserLink(link[i]).getCode()); swMgr.addNodeConnectors(link[i]); Assert.assertTrue(topoManagerImpl.addUserLink(link[i]).isSuccess()); } diff --git a/opendaylight/web/devices/pom.xml b/opendaylight/web/devices/pom.xml index d66381f6ce..8f6e1cc593 100644 --- a/opendaylight/web/devices/pom.xml +++ b/opendaylight/web/devices/pom.xml @@ -66,10 +66,8 @@ org.apache.taglibs.standard.tag.rt.fmt, org.apache.taglibs.standard.tei, org.apache.taglibs.standard.tlv, - org.codehaus.jackson, - org.codehaus.jackson.annotate, - org.codehaus.jackson.map, - org.codehaus.jackson.map.annotate, + com.fasterxml.jackson.databind, + com.fasterxml.jackson.annotation, org.osgi.framework, org.slf4j, org.springframework.beans, @@ -126,9 +124,10 @@ forwarding.staticrouting ${forwarding.staticrouting} + - org.codehaus.jackson - jackson-mapper-asl + com.fasterxml.jackson.core + jackson-databind diff --git a/opendaylight/web/devices/src/main/java/org/opendaylight/controller/devices/web/Devices.java b/opendaylight/web/devices/src/main/java/org/opendaylight/controller/devices/web/Devices.java index 3d33edcbf2..a118ccfbba 100644 --- a/opendaylight/web/devices/src/main/java/org/opendaylight/controller/devices/web/Devices.java +++ b/opendaylight/web/devices/src/main/java/org/opendaylight/controller/devices/web/Devices.java @@ -23,7 +23,7 @@ import java.util.concurrent.ConcurrentMap; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; -import org.codehaus.jackson.map.ObjectMapper; +import com.fasterxml.jackson.databind.ObjectMapper; import org.opendaylight.controller.connectionmanager.IConnectionManager; import org.opendaylight.controller.forwarding.staticrouting.IForwardingStaticRouting; import org.opendaylight.controller.forwarding.staticrouting.StaticRouteConfig; diff --git a/opendaylight/web/flows/pom.xml b/opendaylight/web/flows/pom.xml index f0393c19cb..2b4dcd3de5 100644 --- a/opendaylight/web/flows/pom.xml +++ b/opendaylight/web/flows/pom.xml @@ -63,10 +63,9 @@ org.apache.taglibs.standard.tag.rt.fmt, org.apache.taglibs.standard.tei, org.apache.taglibs.standard.tlv, - org.codehaus.jackson, - org.codehaus.jackson.annotate, - org.codehaus.jackson.map, - org.codehaus.jackson.map.annotate, + com.fasterxml.jackson.core, + com.fasterxml.jackson.annotation, + com.fasterxml.jackson.databind, org.osgi.framework, org.slf4j, org.springframework.beans, diff --git a/opendaylight/web/root/pom.xml b/opendaylight/web/root/pom.xml index 85388d9b05..8ebab10ca5 100644 --- a/opendaylight/web/root/pom.xml +++ b/opendaylight/web/root/pom.xml @@ -61,10 +61,9 @@ org.apache.taglibs.standard.tag.rt.fmt, org.apache.taglibs.standard.tei, org.apache.taglibs.standard.tlv, - org.codehaus.jackson, - org.codehaus.jackson.annotate, - org.codehaus.jackson.map, - org.codehaus.jackson.map.annotate, + com.fasterxml.jackson.core, + com.fasterxml.jackson.databind, + com.fasterxml.jackson.annotation, org.osgi.framework, org.slf4j, org.springframework.beans, diff --git a/opendaylight/web/root/src/main/java/org/opendaylight/controller/web/DaylightWeb.java b/opendaylight/web/root/src/main/java/org/opendaylight/controller/web/DaylightWeb.java index 1d4211a926..ca37f4b7c1 100644 --- a/opendaylight/web/root/src/main/java/org/opendaylight/controller/web/DaylightWeb.java +++ b/opendaylight/web/root/src/main/java/org/opendaylight/controller/web/DaylightWeb.java @@ -8,8 +8,10 @@ package org.opendaylight.controller.web; +import java.io.FileInputStream; import java.util.HashMap; import java.util.Map; +import java.util.Properties; import java.util.Set; import javax.servlet.http.HttpServletRequest; @@ -28,6 +30,7 @@ import org.opendaylight.controller.sal.utils.StatusCode; import org.opendaylight.controller.usermanager.IUserManager; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; +import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.ResponseBody; @@ -52,6 +55,23 @@ public class DaylightWeb { return "main"; } + /** + * Read the version.properties file for the property + * + * @param request + * @return String value configured in the version.properties file + */ + @RequestMapping(value="/versionProperty/{property}", method = RequestMethod.GET) + @ResponseBody + public String getVersion(HttpServletRequest request, @PathVariable("property") String property) { + Properties prop = new Properties(); + try { + prop.load(new FileInputStream("version.properties")); + return prop.getProperty(property+".version"); + } catch (Exception e) { + return null; + } + } @RequestMapping(value = "web.json") @ResponseBody public Map> bundles(HttpServletRequest request) { diff --git a/opendaylight/web/root/src/main/resources/WEB-INF/web.xml b/opendaylight/web/root/src/main/resources/WEB-INF/web.xml index 89812af53d..072f08f581 100644 --- a/opendaylight/web/root/src/main/resources/WEB-INF/web.xml +++ b/opendaylight/web/root/src/main/resources/WEB-INF/web.xml @@ -46,6 +46,7 @@ /images/* /css/* /favicon.ico + /versionProperty/* diff --git a/opendaylight/web/topology/pom.xml b/opendaylight/web/topology/pom.xml index 226dcc87b7..97c5e3ccdc 100644 --- a/opendaylight/web/topology/pom.xml +++ b/opendaylight/web/topology/pom.xml @@ -66,10 +66,9 @@ org.apache.taglibs.standard.tag.rt.fmt, org.apache.taglibs.standard.tei, org.apache.taglibs.standard.tlv, - org.codehaus.jackson, - org.codehaus.jackson.annotate, - org.codehaus.jackson.map, - org.codehaus.jackson.map.annotate, + com.fasterxml.jackson.core, + com.fasterxml.jackson.databind, + com.fasterxml.jackson.annotation, org.osgi.framework, org.slf4j, org.springframework.beans, diff --git a/opendaylight/web/troubleshoot/pom.xml b/opendaylight/web/troubleshoot/pom.xml index bb5e9f1f18..4550be87f9 100644 --- a/opendaylight/web/troubleshoot/pom.xml +++ b/opendaylight/web/troubleshoot/pom.xml @@ -65,10 +65,9 @@ org.apache.taglibs.standard.tag.rt.fmt, org.apache.taglibs.standard.tei, org.apache.taglibs.standard.tlv, - org.codehaus.jackson, - org.codehaus.jackson.annotate, - org.codehaus.jackson.map, - org.codehaus.jackson.map.annotate, + com.fasterxml.jackson.core, + com.fasterxml.jackson.databind, + com.fasterxml.jackson.annotation, org.osgi.framework, org.slf4j, org.springframework.beans, @@ -120,9 +119,10 @@ web 0.4.1-SNAPSHOT - - org.codehaus.jackson - jackson-mapper-asl - + + + com.fasterxml.jackson.core + jackson-databind +