From: Tony Tkacik Date: Fri, 8 Aug 2014 07:19:52 +0000 (+0000) Subject: Merge "BUG-1495: fail future when no local RPC is found" X-Git-Tag: release/helium~323 X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?a=commitdiff_plain;h=79d775c3cc0fe48b01eefdb732124e81dfe3441c;hp=d24c69e28011dc32ee0b1db893405348cd4c70f2;p=controller.git Merge "BUG-1495: fail future when no local RPC is found" --- diff --git a/opendaylight/commons/opendaylight/pom.xml b/opendaylight/commons/opendaylight/pom.xml index 6b17011099..4f678f6854 100644 --- a/opendaylight/commons/opendaylight/pom.xml +++ b/opendaylight/commons/opendaylight/pom.xml @@ -110,7 +110,6 @@ 2.0.1 1.1.1 2.0 - 4.8.1 1.0.0-SNAPSHOT 3.0.0 3.0.1 @@ -1290,6 +1289,11 @@ sal-clustering-commons ${mdsal.version} + + org.opendaylight.controller + sal-clustering-config + ${mdsal.version} + org.opendaylight.controller @@ -1773,12 +1777,6 @@ slf4j-simple ${slf4j.version} - - junit - junit - ${junit.version} - test - org.opendaylight.controller commons.logback_settings diff --git a/opendaylight/config/config-manager/src/test/java/org/opendaylight/controller/config/manager/impl/runtimembean/RuntimeBeanRegistratorImplTest.java b/opendaylight/config/config-manager/src/test/java/org/opendaylight/controller/config/manager/impl/runtimembean/RuntimeBeanRegistratorImplTest.java index ce3648d160..16de00508a 100644 --- a/opendaylight/config/config-manager/src/test/java/org/opendaylight/controller/config/manager/impl/runtimembean/RuntimeBeanRegistratorImplTest.java +++ b/opendaylight/config/config-manager/src/test/java/org/opendaylight/controller/config/manager/impl/runtimembean/RuntimeBeanRegistratorImplTest.java @@ -7,10 +7,12 @@ */ package org.opendaylight.controller.config.manager.impl.runtimembean; +import static org.hamcrest.CoreMatchers.containsString; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertThat; import static org.junit.Assert.fail; -import static org.junit.internal.matchers.StringContains.containsString; +import com.google.common.collect.ImmutableMap; +import com.google.common.collect.Maps; import java.lang.management.ManagementFactory; import java.util.Map; @@ -29,9 +31,6 @@ import org.opendaylight.controller.config.manager.impl.jmx.BaseJMXRegistrator; import org.opendaylight.controller.config.manager.impl.jmx.HierarchicalRuntimeBeanRegistrationImpl; import org.opendaylight.controller.config.manager.impl.jmx.RootRuntimeBeanRegistratorImpl; -import com.google.common.collect.ImmutableMap; -import com.google.common.collect.Maps; - public class RuntimeBeanRegistratorImplTest extends AbstractLockedPlatformMBeanServerTest { static final String module1 = "module1"; @@ -60,11 +59,11 @@ public class RuntimeBeanRegistratorImplTest extends assertEquals(0, baseJMXRegistrator.getRegisteredObjectNames().size()); } - protected void checkExists(ObjectName on) throws Exception { + protected void checkExists(final ObjectName on) throws Exception { platformMBeanServer.getMBeanInfo(on); } - protected void checkNotExists(ObjectName on) throws Exception { + protected void checkNotExists(final ObjectName on) throws Exception { try { platformMBeanServer.getMBeanInfo(on); fail(); @@ -98,7 +97,7 @@ public class RuntimeBeanRegistratorImplTest extends } private HierarchicalRuntimeBeanRegistration createAdditional( - HierarchicalRuntimeBeanRegistrationImpl rootRegistration) + final HierarchicalRuntimeBeanRegistrationImpl rootRegistration) throws Exception { HierarchicalRuntimeBeanRegistrationImpl registration = rootRegistration diff --git a/opendaylight/config/config-manager/src/test/java/org/opendaylight/controller/config/manager/testingservices/parallelapsp/test/DependentWiringTest.java b/opendaylight/config/config-manager/src/test/java/org/opendaylight/controller/config/manager/testingservices/parallelapsp/test/DependentWiringTest.java index c9810d0521..165a6c7ed6 100644 --- a/opendaylight/config/config-manager/src/test/java/org/opendaylight/controller/config/manager/testingservices/parallelapsp/test/DependentWiringTest.java +++ b/opendaylight/config/config-manager/src/test/java/org/opendaylight/controller/config/manager/testingservices/parallelapsp/test/DependentWiringTest.java @@ -7,14 +7,16 @@ */ package org.opendaylight.controller.config.manager.testingservices.parallelapsp.test; +import static org.hamcrest.CoreMatchers.containsString; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertThat; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; -import static org.junit.internal.matchers.StringContains.containsString; import java.util.Map; + import javax.management.ObjectName; + import org.junit.After; import org.junit.Before; import org.junit.Test; diff --git a/opendaylight/config/yang-jmx-generator/pom.xml b/opendaylight/config/yang-jmx-generator/pom.xml index fbae840fc6..133b07ff86 100644 --- a/opendaylight/config/yang-jmx-generator/pom.xml +++ b/opendaylight/config/yang-jmx-generator/pom.xml @@ -58,12 +58,6 @@ yang-parser-impl test - - org.hamcrest - hamcrest-core - 1.1 - test - diff --git a/opendaylight/config/yang-jmx-generator/src/test/java/org/opendaylight/controller/config/yangjmxgenerator/RuntimeBeanEntryTest.java b/opendaylight/config/yang-jmx-generator/src/test/java/org/opendaylight/controller/config/yangjmxgenerator/RuntimeBeanEntryTest.java index b570302563..e80ebc67a5 100644 --- a/opendaylight/config/yang-jmx-generator/src/test/java/org/opendaylight/controller/config/yangjmxgenerator/RuntimeBeanEntryTest.java +++ b/opendaylight/config/yang-jmx-generator/src/test/java/org/opendaylight/controller/config/yangjmxgenerator/RuntimeBeanEntryTest.java @@ -7,7 +7,22 @@ */ package org.opendaylight.controller.config.yangjmxgenerator; +import static junit.framework.Assert.assertNotNull; +import static junit.framework.Assert.assertNull; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; +import static org.mockito.Mockito.doReturn; + +import java.util.ArrayList; +import java.util.Collection; import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; + +import javax.management.openmbean.SimpleType; + import org.junit.Test; import org.mockito.Mockito; import org.opendaylight.controller.config.yangjmxgenerator.attribute.JavaAttribute; @@ -18,20 +33,6 @@ import org.opendaylight.yangtools.yang.model.api.IdentitySchemaNode; import org.opendaylight.yangtools.yang.model.api.LeafSchemaNode; import org.opendaylight.yangtools.yang.model.api.UnknownSchemaNode; -import javax.management.openmbean.SimpleType; -import java.util.ArrayList; -import java.util.Collection; -import java.util.HashSet; -import java.util.List; -import java.util.Map; - -import static junit.framework.Assert.assertNotNull; -import static junit.framework.Assert.assertNull; -import static org.hamcrest.CoreMatchers.is; - -import static org.junit.Assert.assertThat; -import static org.mockito.Mockito.doReturn; - public class RuntimeBeanEntryTest extends AbstractYangTest { public static final String PACKAGE_NAME = "packages.sis"; @@ -54,10 +55,10 @@ public class RuntimeBeanEntryTest extends AbstractYangTest { Map runtimeBeans = RuntimeBeanEntry .extractClassNameToRuntimeBeanMap(PACKAGE_NAME, caseNode, "test-name", new TypeProviderWrapper(new TypeProviderImpl(context)), "test", jmxImplModule); - assertThat(runtimeBeans.size(), is(1)); + assertEquals(1, runtimeBeans.size()); RuntimeBeanEntry runtimeMXBean = runtimeBeans.get("testRuntimeMXBean"); - assertThat(runtimeMXBean.isRoot(), is(true)); - assertThat(runtimeMXBean.getYangName(), is("test-name")); + assertTrue(runtimeMXBean.isRoot()); + assertEquals("test-name", runtimeMXBean.getYangName()); } @Test @@ -72,7 +73,7 @@ public class RuntimeBeanEntryTest extends AbstractYangTest { threadsJavaModule, modulesToSIEs, context, new TypeProviderWrapper(new TypeProviderImpl(context)), PACKAGE_NAME); - assertThat(namesToMBEs.isEmpty(), is(false)); + assertFalse(namesToMBEs.isEmpty()); // get threadfactory-naming bean ModuleMXBeanEntry threadfactoryNamingMXBean = namesToMBEs @@ -82,13 +83,13 @@ public class RuntimeBeanEntryTest extends AbstractYangTest { // get runtime beans Collection runtimeBeanEntries = threadfactoryNamingMXBean .getRuntimeBeans(); - assertThat(runtimeBeanEntries.isEmpty(), is(false)); + assertFalse(runtimeBeanEntries.isEmpty()); // get root runtime bean RuntimeBeanEntry threadfactoryRuntimeBeanEntry = getRuntimeBeanEntryByJavaName( runtimeBeanEntries, "NamingThreadFactoryRuntimeMXBean"); assertNotNull(threadfactoryRuntimeBeanEntry); - assertThat(threadfactoryRuntimeBeanEntry.isRoot(), is(true)); + assertTrue(threadfactoryRuntimeBeanEntry.isRoot()); // get thread runtime bean RuntimeBeanEntry runtimeBeanEntry = getRuntimeBeanEntryByJavaName( @@ -96,43 +97,41 @@ public class RuntimeBeanEntryTest extends AbstractYangTest { assertNotNull(runtimeBeanEntry); // test thread runtime bean properties - assertThat(runtimeBeanEntry.getJavaNamePrefix(), - is(THREAD_RUNTIME_BEAN_JAVA_PREFIX)); - assertThat(runtimeBeanEntry.getPackageName(), is(PACKAGE_NAME)); - assertThat(runtimeBeanEntry.getFullyQualifiedName(runtimeBeanEntry - .getJavaNameOfRuntimeMXBean()), is(PACKAGE_NAME + "." - + THREAD_RUNTIME_BEAN_JAVA_NAME)); - assertThat(runtimeBeanEntry.getYangName(), - is(THREAD_RUNTIME_BEAN_YANG_NAME)); + assertEquals(THREAD_RUNTIME_BEAN_JAVA_PREFIX, runtimeBeanEntry.getJavaNamePrefix()); + assertEquals(PACKAGE_NAME, runtimeBeanEntry.getPackageName()); + assertEquals(PACKAGE_NAME + "." + THREAD_RUNTIME_BEAN_JAVA_NAME, + runtimeBeanEntry.getFullyQualifiedName(runtimeBeanEntry + .getJavaNameOfRuntimeMXBean())); + assertEquals(THREAD_RUNTIME_BEAN_YANG_NAME, runtimeBeanEntry.getYangName()); // get thread runtime bean rpcs List rpcs = new ArrayList( runtimeBeanEntry.getRpcs()); - assertThat(rpcs.size(), is(2)); + assertEquals(2, rpcs.size()); // get sleep rpc and test it RuntimeBeanEntry.Rpc rpc = getRpcByName(rpcs, SLEEP_RPC_NAME); assertNotNull(rpc); - assertThat(rpc.getYangName(), is(SLEEP_RPC_NAME)); + assertEquals(SLEEP_RPC_NAME, rpc.getYangName()); - assertThat(((JavaAttribute)rpc.getReturnType()).getType().getFullyQualifiedName().endsWith(SLEEP_RPC_OUTPUT), is(true)); + assertTrue(((JavaAttribute)rpc.getReturnType()).getType().getFullyQualifiedName().endsWith(SLEEP_RPC_OUTPUT)); // get sleep rpc input attribute and test it List attributes = rpc.getParameters(); - assertThat(attributes.size(), is(1)); + assertEquals(1, attributes.size()); JavaAttribute attribute = attributes.get(0); - assertThat(attribute.getAttributeYangName(), is(SLEEP_RPC_INPUT_NAME)); - assertThat(attribute.getType().getName(), is(SLEEP_RPC_INPUT_TYPE)); - assertThat(attribute.getLowerCaseCammelCase(), is(SLEEP_RPC_INPUT_NAME)); - assertThat(attribute.getUpperCaseCammelCase(), is("Millis")); + assertEquals(SLEEP_RPC_INPUT_NAME, attribute.getAttributeYangName()); + assertEquals(SLEEP_RPC_INPUT_TYPE, attribute.getType().getName()); + assertEquals(SLEEP_RPC_INPUT_NAME, attribute.getLowerCaseCammelCase()); + assertEquals("Millis", attribute.getUpperCaseCammelCase()); assertNull(attribute.getNullableDefault()); assertNull(attribute.getNullableDescription()); - assertThat(attribute.getOpenType(), is(SimpleType.class)); + assertTrue(attribute.getOpenType() instanceof SimpleType); } private RuntimeBeanEntry getRuntimeBeanEntryByJavaName( final Collection runtimeBeanEntries, - String javaName) { + final String javaName) { if (runtimeBeanEntries != null && !runtimeBeanEntries.isEmpty()) { for (RuntimeBeanEntry runtimeBeanEntry : runtimeBeanEntries) { if (runtimeBeanEntry.getJavaNameOfRuntimeMXBean().equals( @@ -145,7 +144,7 @@ public class RuntimeBeanEntryTest extends AbstractYangTest { } private RuntimeBeanEntry.Rpc getRpcByName( - final List rpcs, String name) { + final List rpcs, final String name) { if (rpcs != null && !rpcs.isEmpty()) { for (RuntimeBeanEntry.Rpc rpc : rpcs) { if (rpc.getName().equals(name)) { diff --git a/opendaylight/distribution/opendaylight/pom.xml b/opendaylight/distribution/opendaylight/pom.xml index b02835e845..7ab56e6d03 100644 --- a/opendaylight/distribution/opendaylight/pom.xml +++ b/opendaylight/distribution/opendaylight/pom.xml @@ -745,8 +745,8 @@ generate-resources ${project.build.directory}/configuration - sal-rest-connector-config,config-netty-config,md-sal-config,netconf-config,toaster-config,netconf-connector-config - **\/*.xml + sal-rest-connector-config,config-netty-config,md-sal-config,netconf-config,toaster-config,netconf-connector-config,sal-clustering-config + **\/*.xml,**/*.conf true false @@ -1296,10 +1296,14 @@ jeromq 0.3.1 - - org.opendaylight.controller - sal-distributed-datastore - + + org.opendaylight.controller + sal-distributed-datastore + + + org.opendaylight.controller + sal-clustering-config + diff --git a/opendaylight/md-sal/compatibility/sal-compatibility/src/main/java/org/opendaylight/controller/sal/compatibility/NodeMapping.java b/opendaylight/md-sal/compatibility/sal-compatibility/src/main/java/org/opendaylight/controller/sal/compatibility/NodeMapping.java index 02964c6d55..be087abdb4 100644 --- a/opendaylight/md-sal/compatibility/sal-compatibility/src/main/java/org/opendaylight/controller/sal/compatibility/NodeMapping.java +++ b/opendaylight/md-sal/compatibility/sal-compatibility/src/main/java/org/opendaylight/controller/sal/compatibility/NodeMapping.java @@ -7,11 +7,13 @@ */ package org.opendaylight.controller.sal.compatibility; +import com.google.common.annotations.VisibleForTesting; +import com.google.common.base.Objects; +import com.google.common.base.Preconditions; import java.math.BigInteger; import java.util.Date; import java.util.HashSet; import java.util.List; - import org.opendaylight.controller.sal.common.util.Arguments; import org.opendaylight.controller.sal.core.AdvertisedBandwidth; import org.opendaylight.controller.sal.core.Bandwidth; @@ -62,16 +64,14 @@ import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import com.google.common.annotations.VisibleForTesting; -import com.google.common.base.Objects; -import com.google.common.base.Preconditions; - public final class NodeMapping { private static final Logger LOG = LoggerFactory .getLogger(NodeMapping.class); - /** openflow id prefix */ + /** + * openflow id prefix + */ public static final String OPENFLOW_ID_PREFIX = "openflow:"; public final static String MD_SAL_TYPE = "MD_SAL_DEPRECATED"; @@ -90,8 +90,14 @@ public final class NodeMapping { } public static org.opendaylight.controller.sal.core.Node toADNode(final NodeId id) throws ConstructionException { - Long aDNodeId = openflowFullNodeIdToLong(NodeMapping.toADNodeId(id)); - return new org.opendaylight.controller.sal.core.Node(NodeIDType.OPENFLOW, aDNodeId); + String nodeId = NodeMapping.toADNodeId(id); + String nodeIdasNumber = nodeId.replaceFirst("^.*:", ""); + if (isInteger(nodeIdasNumber)) { + Long aDNodeId = openflowFullNodeIdToLong(nodeIdasNumber); + return new org.opendaylight.controller.sal.core.Node(NodeIDType.OPENFLOW, aDNodeId); + } else { + return new org.opendaylight.controller.sal.core.Node(NodeIDType.PRODUCTION, nodeId); + } } /** @@ -103,7 +109,7 @@ public final class NodeMapping { if (adNodeId == null) { return null; } - return new BigInteger(adNodeId.replaceFirst("^.*:", "")).longValue(); + return new BigInteger(adNodeId).longValue(); } public static NodeId toNodeId(final InstanceIdentifier id) { @@ -137,8 +143,8 @@ public final class NodeMapping { } /** - * @param ncid nodeConnector identifier, e.g.: OF:21 or CTRL - * @param node + * @param ncid nodeConnector identifier, e.g.: OF:21 or CTRL + * @param aDNode * @return nodeConnector attached to given node * @throws ConstructionException */ @@ -155,7 +161,7 @@ public final class NodeMapping { * @return */ private static NodeId toNodeId(org.opendaylight.controller.sal.core.Node aDNode) { - return new NodeId(aDNode.getType() + ":" +String.valueOf(aDNode.getID())); + return new NodeId(aDNode.getType() + ":" + String.valueOf(aDNode.getID())); } public static String toNodeConnectorType(final NodeConnectorId ncId, final NodeId nodeId) { @@ -212,7 +218,7 @@ public final class NodeMapping { public static NodeRef toNodeRef(final org.opendaylight.controller.sal.core.Node node) { Preconditions.checkArgument(NodeIDType.OPENFLOW.equals(node.getType())); final Long nodeId = Arguments.checkInstanceOf(node.getID(), Long.class); - final NodeKey nodeKey = new NodeKey(new NodeId(OPENFLOW_ID_PREFIX+nodeId)); + final NodeKey nodeKey = new NodeKey(new NodeId(OPENFLOW_ID_PREFIX + nodeId)); final InstanceIdentifier nodePath = InstanceIdentifier.builder(Nodes.class).child(NODE_CLASS, nodeKey).toInstance(); return new NodeRef(nodePath); } @@ -257,7 +263,7 @@ public final class NodeMapping { } /** - * @param id + * @param nodeRef * @return node description in AD form, e.g.: OF|00:00:00:...:01 */ private static Description toADDescription(NodeRef nodeRef) { @@ -463,4 +469,17 @@ public final class NodeMapping { public static Buffers toADBuffers(final Long buffers) { return new Buffers(buffers.intValue()); } + + + private static final boolean isInteger(String value) { + if (value.isEmpty()) return false; + for (int i = 0; i < value.length(); i++) { + if (i == 0 && value.charAt(i) == '-') { + if (value.length() == 1) return false; + else continue; + } + if (Character.digit(value.charAt(i), 10) < 0) return false; + } + return true; + } } diff --git a/opendaylight/md-sal/compatibility/sal-compatibility/src/test/java/org/opendaylight/controller/sal/compatibility/test/NodeMappingTest.java b/opendaylight/md-sal/compatibility/sal-compatibility/src/test/java/org/opendaylight/controller/sal/compatibility/test/NodeMappingTest.java index cef7ae7a42..a776ef2312 100644 --- a/opendaylight/md-sal/compatibility/sal-compatibility/src/test/java/org/opendaylight/controller/sal/compatibility/test/NodeMappingTest.java +++ b/opendaylight/md-sal/compatibility/sal-compatibility/src/test/java/org/opendaylight/controller/sal/compatibility/test/NodeMappingTest.java @@ -101,6 +101,16 @@ public class NodeMappingTest { } catch (ConstructionException e) { Assert.fail("should succeed to construct Node: "+e.getMessage()); } + + final String nodeUriPrefix = "opendaylight-inventory:nodes/node/"; + nodeId = new NodeId(nodeUriPrefix + "iosv-2"); + try { + observed = NodeMapping.toADNode(nodeId); + Assert.assertEquals("PR|opendaylight-inventory:nodes/node/iosv-2", observed.toString()); + } catch (ConstructionException e) { + Assert.fail("should succeed to construct Node: "+e.getMessage()); + } + } /** diff --git a/opendaylight/md-sal/md-sal-config/src/main/resources/initial/01-md-sal.xml b/opendaylight/md-sal/md-sal-config/src/main/resources/initial/01-md-sal.xml index f25b7d91bd..35a77662b5 100644 --- a/opendaylight/md-sal/md-sal-config/src/main/resources/initial/01-md-sal.xml +++ b/opendaylight/md-sal/md-sal-config/src/main/resources/initial/01-md-sal.xml @@ -57,19 +57,19 @@ prefix:distributed-operational-datastore-provider distributed-operational-store-module - + dom:schema-service yang-schema-service - + prefix:distributed-config-datastore-provider distributed-config-store-module - + dom:schema-service yang-schema-service - + --> diff --git a/opendaylight/md-sal/pom.xml b/opendaylight/md-sal/pom.xml index fd828dc05a..6c6760d789 100644 --- a/opendaylight/md-sal/pom.xml +++ b/opendaylight/md-sal/pom.xml @@ -69,6 +69,9 @@ sal-clustering-commons + + sal-clustering-config + sal-distributed-datastore diff --git a/opendaylight/md-sal/sal-akka-raft/src/main/java/org/opendaylight/controller/cluster/raft/AbstractReplicatedLogImpl.java b/opendaylight/md-sal/sal-akka-raft/src/main/java/org/opendaylight/controller/cluster/raft/AbstractReplicatedLogImpl.java index 24bfa3de21..b5b034afb9 100644 --- a/opendaylight/md-sal/sal-akka-raft/src/main/java/org/opendaylight/controller/cluster/raft/AbstractReplicatedLogImpl.java +++ b/opendaylight/md-sal/sal-akka-raft/src/main/java/org/opendaylight/controller/cluster/raft/AbstractReplicatedLogImpl.java @@ -100,16 +100,26 @@ public abstract class AbstractReplicatedLogImpl implements ReplicatedLog { @Override public List getFrom(long logEntryIndex) { + return getFrom(logEntryIndex, journal.size()); + } + + @Override + public List getFrom(long logEntryIndex, int max) { int adjustedIndex = adjustedIndex(logEntryIndex); int size = journal.size(); List entries = new ArrayList<>(100); if (adjustedIndex >= 0 && adjustedIndex < size) { // physical index should be less than list size and >= 0 - entries.addAll(journal.subList(adjustedIndex, size)); + int maxIndex = adjustedIndex + max; + if(maxIndex > size){ + maxIndex = size; + } + entries.addAll(journal.subList(adjustedIndex, maxIndex)); } return entries; } + @Override public long size() { return journal.size(); diff --git a/opendaylight/md-sal/sal-akka-raft/src/main/java/org/opendaylight/controller/cluster/raft/DefaultConfigParamsImpl.java b/opendaylight/md-sal/sal-akka-raft/src/main/java/org/opendaylight/controller/cluster/raft/DefaultConfigParamsImpl.java index c633337226..6432fa4811 100644 --- a/opendaylight/md-sal/sal-akka-raft/src/main/java/org/opendaylight/controller/cluster/raft/DefaultConfigParamsImpl.java +++ b/opendaylight/md-sal/sal-akka-raft/src/main/java/org/opendaylight/controller/cluster/raft/DefaultConfigParamsImpl.java @@ -33,7 +33,7 @@ public class DefaultConfigParamsImpl implements ConfigParams { * Since this is set to 100 milliseconds the Election timeout should be * at least 200 milliseconds */ - protected static final FiniteDuration HEART_BEAT_INTERVAL = + public static final FiniteDuration HEART_BEAT_INTERVAL = new FiniteDuration(100, TimeUnit.MILLISECONDS); @@ -51,7 +51,7 @@ public class DefaultConfigParamsImpl implements ConfigParams { @Override public FiniteDuration getElectionTimeOutInterval() { // returns 2 times the heart beat interval - return HEART_BEAT_INTERVAL.$times(2); + return getHeartBeatInterval().$times(2); } @Override diff --git a/opendaylight/md-sal/sal-akka-raft/src/main/java/org/opendaylight/controller/cluster/raft/RaftActor.java b/opendaylight/md-sal/sal-akka-raft/src/main/java/org/opendaylight/controller/cluster/raft/RaftActor.java index caa0e507c1..0a979d24ee 100644 --- a/opendaylight/md-sal/sal-akka-raft/src/main/java/org/opendaylight/controller/cluster/raft/RaftActor.java +++ b/opendaylight/md-sal/sal-akka-raft/src/main/java/org/opendaylight/controller/cluster/raft/RaftActor.java @@ -148,6 +148,7 @@ public abstract class RaftActor extends UntypedPersistentActor { replicatedLog.lastIndex(), replicatedLog.snapshotIndex, replicatedLog.snapshotTerm, replicatedLog.size()); currentBehavior = switchBehavior(RaftState.Follower); + onStateChanged(); } } @@ -206,7 +207,11 @@ public abstract class RaftActor extends UntypedPersistentActor { RaftState state = currentBehavior.handleMessage(getSender(), message); + RaftActorBehavior oldBehavior = currentBehavior; currentBehavior = switchBehavior(state); + if(oldBehavior != currentBehavior){ + onStateChanged(); + } } } @@ -271,9 +276,21 @@ public abstract class RaftActor extends UntypedPersistentActor { String peerAddress = context.getPeerAddress(leaderId); LOG.debug("getLeader leaderId = " + leaderId + " peerAddress = " + peerAddress); + + if(peerAddress == null){ + return null; + } return context.actorSelection(peerAddress); } + /** + * + * @return the current leader's id + */ + protected String getLeaderId(){ + return currentBehavior.getLeaderId(); + } + protected RaftState getRaftState() { return currentBehavior.state(); } @@ -375,7 +392,7 @@ public abstract class RaftActor extends UntypedPersistentActor { behavior = new Leader(context); } - onStateChanged(); + return behavior; } diff --git a/opendaylight/md-sal/sal-akka-raft/src/main/java/org/opendaylight/controller/cluster/raft/ReplicatedLog.java b/opendaylight/md-sal/sal-akka-raft/src/main/java/org/opendaylight/controller/cluster/raft/ReplicatedLog.java index b7c8955aad..e6e160bc02 100644 --- a/opendaylight/md-sal/sal-akka-raft/src/main/java/org/opendaylight/controller/cluster/raft/ReplicatedLog.java +++ b/opendaylight/md-sal/sal-akka-raft/src/main/java/org/opendaylight/controller/cluster/raft/ReplicatedLog.java @@ -84,6 +84,11 @@ public interface ReplicatedLog { */ List getFrom(long index); + /** + * + * @param index the index of the log entry + */ + List getFrom(long index, int max); /** * diff --git a/opendaylight/md-sal/sal-akka-raft/src/main/java/org/opendaylight/controller/cluster/raft/behaviors/Leader.java b/opendaylight/md-sal/sal-akka-raft/src/main/java/org/opendaylight/controller/cluster/raft/behaviors/Leader.java index 2a44e8b7a5..a50666233c 100644 --- a/opendaylight/md-sal/sal-akka-raft/src/main/java/org/opendaylight/controller/cluster/raft/behaviors/Leader.java +++ b/opendaylight/md-sal/sal-akka-raft/src/main/java/org/opendaylight/controller/cluster/raft/behaviors/Leader.java @@ -310,7 +310,7 @@ public class Leader extends AbstractRaftActorBehavior { // that has fallen too far behind with the log but yet is not // eligible to receive a snapshot entries = - context.getReplicatedLog().getFrom(nextIndex); + context.getReplicatedLog().getFrom(nextIndex, 1); } followerActor.tell( diff --git a/opendaylight/md-sal/sal-akka-raft/src/test/java/org/opendaylight/controller/cluster/raft/AbstractReplicatedLogImplTest.java b/opendaylight/md-sal/sal-akka-raft/src/test/java/org/opendaylight/controller/cluster/raft/AbstractReplicatedLogImplTest.java index ae8e525233..913665861d 100644 --- a/opendaylight/md-sal/sal-akka-raft/src/test/java/org/opendaylight/controller/cluster/raft/AbstractReplicatedLogImplTest.java +++ b/opendaylight/md-sal/sal-akka-raft/src/test/java/org/opendaylight/controller/cluster/raft/AbstractReplicatedLogImplTest.java @@ -7,6 +7,7 @@ */ package org.opendaylight.controller.cluster.raft; +import junit.framework.Assert; import org.junit.After; import org.junit.Before; import org.junit.Test; @@ -31,6 +32,12 @@ public class AbstractReplicatedLogImplTest { @Before public void setUp() { replicatedLogImpl = new MockAbstractReplicatedLogImpl(); + // create a set of initial entries in the in-memory log + replicatedLogImpl.append(new MockReplicatedLogEntry(1, 0, new MockPayload("A"))); + replicatedLogImpl.append(new MockReplicatedLogEntry(1, 1, new MockPayload("B"))); + replicatedLogImpl.append(new MockReplicatedLogEntry(1, 2, new MockPayload("C"))); + replicatedLogImpl.append(new MockReplicatedLogEntry(2, 3, new MockPayload("D"))); + } @After @@ -43,11 +50,6 @@ public class AbstractReplicatedLogImplTest { @Test public void testIndexOperations() { - // create a set of initial entries in the in-memory log - replicatedLogImpl.append(new MockReplicatedLogEntry(1, 0, new MockPayload("A"))); - replicatedLogImpl.append(new MockReplicatedLogEntry(1, 1, new MockPayload("B"))); - replicatedLogImpl.append(new MockReplicatedLogEntry(1, 2, new MockPayload("C"))); - replicatedLogImpl.append(new MockReplicatedLogEntry(2, 3, new MockPayload("D"))); // check if the values returned are correct, with snapshotIndex = -1 assertEquals("B", replicatedLogImpl.get(1).getData().toString()); @@ -112,6 +114,22 @@ public class AbstractReplicatedLogImplTest { } + @Test + public void testGetFromWithMax(){ + List from = replicatedLogImpl.getFrom(0, 1); + Assert.assertEquals(1, from.size()); + Assert.assertEquals(1, from.get(0).getTerm()); + + from = replicatedLogImpl.getFrom(0, 20); + Assert.assertEquals(4, from.size()); + Assert.assertEquals(2, from.get(3).getTerm()); + + from = replicatedLogImpl.getFrom(1, 2); + Assert.assertEquals(2, from.size()); + Assert.assertEquals(1, from.get(1).getTerm()); + + } + // create a snapshot for test public Map takeSnapshot(int numEntries) { Map map = new HashMap(numEntries); diff --git a/opendaylight/md-sal/sal-akka-raft/src/test/java/org/opendaylight/controller/cluster/raft/MockRaftActorContext.java b/opendaylight/md-sal/sal-akka-raft/src/test/java/org/opendaylight/controller/cluster/raft/MockRaftActorContext.java index aa50fa7442..70671a6a21 100644 --- a/opendaylight/md-sal/sal-akka-raft/src/test/java/org/opendaylight/controller/cluster/raft/MockRaftActorContext.java +++ b/opendaylight/md-sal/sal-akka-raft/src/test/java/org/opendaylight/controller/cluster/raft/MockRaftActorContext.java @@ -248,6 +248,23 @@ public class MockRaftActorContext implements RaftActorContext { return entries; } + @Override public List getFrom(long index, int max) { + if(index >= log.size() || index < 0){ + return Collections.EMPTY_LIST; + } + List entries = new ArrayList<>(); + int maxIndex = (int) index + max; + if(maxIndex > log.size()){ + maxIndex = log.size(); + } + + for(int i=(int) index ; i < maxIndex ; i++) { + entries.add(get(i)); + } + return entries; + + } + @Override public long size() { return log.size(); } diff --git a/opendaylight/md-sal/sal-akka-raft/src/test/java/org/opendaylight/controller/cluster/raft/behaviors/CandidateTest.java b/opendaylight/md-sal/sal-akka-raft/src/test/java/org/opendaylight/controller/cluster/raft/behaviors/CandidateTest.java index c763683705..d478b17555 100644 --- a/opendaylight/md-sal/sal-akka-raft/src/test/java/org/opendaylight/controller/cluster/raft/behaviors/CandidateTest.java +++ b/opendaylight/md-sal/sal-akka-raft/src/test/java/org/opendaylight/controller/cluster/raft/behaviors/CandidateTest.java @@ -6,6 +6,7 @@ import akka.testkit.JavaTestKit; import junit.framework.Assert; import org.junit.Before; import org.junit.Test; +import org.opendaylight.controller.cluster.raft.DefaultConfigParamsImpl; import org.opendaylight.controller.cluster.raft.MockRaftActorContext; import org.opendaylight.controller.cluster.raft.RaftActorContext; import org.opendaylight.controller.cluster.raft.RaftState; @@ -80,12 +81,12 @@ public class CandidateTest extends AbstractRaftActorBehaviorTest { public void testThatAnElectionTimeoutIsTriggered(){ new JavaTestKit(getSystem()) {{ - new Within(duration("1 seconds")) { + new Within(DefaultConfigParamsImpl.HEART_BEAT_INTERVAL.$times(6)) { protected void run() { Candidate candidate = new Candidate(createActorContext(getTestActor())); - final Boolean out = new ExpectMsg(duration("1 seconds"), "ElectionTimeout") { + final Boolean out = new ExpectMsg(DefaultConfigParamsImpl.HEART_BEAT_INTERVAL.$times(6), "ElectionTimeout") { // do not put code outside this method, will run afterwards protected Boolean match(Object in) { if (in instanceof ElectionTimeout) { diff --git a/opendaylight/md-sal/sal-akka-raft/src/test/java/org/opendaylight/controller/cluster/raft/behaviors/FollowerTest.java b/opendaylight/md-sal/sal-akka-raft/src/test/java/org/opendaylight/controller/cluster/raft/behaviors/FollowerTest.java index c015d950c4..c5a81aa1c9 100644 --- a/opendaylight/md-sal/sal-akka-raft/src/test/java/org/opendaylight/controller/cluster/raft/behaviors/FollowerTest.java +++ b/opendaylight/md-sal/sal-akka-raft/src/test/java/org/opendaylight/controller/cluster/raft/behaviors/FollowerTest.java @@ -5,6 +5,7 @@ import akka.actor.Props; import akka.testkit.JavaTestKit; import junit.framework.Assert; import org.junit.Test; +import org.opendaylight.controller.cluster.raft.DefaultConfigParamsImpl; import org.opendaylight.controller.cluster.raft.MockRaftActorContext; import org.opendaylight.controller.cluster.raft.RaftActorContext; import org.opendaylight.controller.cluster.raft.RaftState; @@ -41,12 +42,12 @@ public class FollowerTest extends AbstractRaftActorBehaviorTest { public void testThatAnElectionTimeoutIsTriggered(){ new JavaTestKit(getSystem()) {{ - new Within(duration("1 seconds")) { + new Within(DefaultConfigParamsImpl.HEART_BEAT_INTERVAL.$times(6)) { protected void run() { Follower follower = new Follower(createActorContext(getTestActor())); - final Boolean out = new ExpectMsg(duration("1 seconds"), "ElectionTimeout") { + final Boolean out = new ExpectMsg(DefaultConfigParamsImpl.HEART_BEAT_INTERVAL.$times(6), "ElectionTimeout") { // do not put code outside this method, will run afterwards protected Boolean match(Object in) { if (in instanceof ElectionTimeout) { diff --git a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/md/sal/binding/impl/ForwardedBackwardsCompatibleDataBroker.java b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/md/sal/binding/impl/ForwardedBackwardsCompatibleDataBroker.java index c924b74a12..237d9678f9 100644 --- a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/md/sal/binding/impl/ForwardedBackwardsCompatibleDataBroker.java +++ b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/md/sal/binding/impl/ForwardedBackwardsCompatibleDataBroker.java @@ -39,7 +39,7 @@ import org.opendaylight.yangtools.concepts.AbstractObjectRegistration; import org.opendaylight.yangtools.concepts.Delegator; import org.opendaylight.yangtools.concepts.ListenerRegistration; import org.opendaylight.yangtools.concepts.Registration; -import org.opendaylight.yangtools.concepts.util.ListenerRegistry; +import org.opendaylight.yangtools.util.ListenerRegistry; import org.opendaylight.yangtools.yang.binding.DataObject; import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; import org.opendaylight.yangtools.yang.common.RpcResult; diff --git a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/codegen/impl/RpcRouterCodegenInstance.java b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/codegen/impl/RpcRouterCodegenInstance.java index 709b62fee2..783e5c0cd4 100644 --- a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/codegen/impl/RpcRouterCodegenInstance.java +++ b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/codegen/impl/RpcRouterCodegenInstance.java @@ -22,7 +22,7 @@ import org.opendaylight.controller.sal.binding.api.rpc.RpcRoutingTable; import org.opendaylight.controller.sal.binding.codegen.RuntimeCodeHelper; import org.opendaylight.yangtools.concepts.AbstractObjectRegistration; import org.opendaylight.yangtools.concepts.ListenerRegistration; -import org.opendaylight.yangtools.concepts.util.ListenerRegistry; +import org.opendaylight.yangtools.util.ListenerRegistry; import org.opendaylight.yangtools.yang.binding.BaseIdentity; import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; import org.opendaylight.yangtools.yang.binding.RpcService; diff --git a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/DataTransactionImpl.java b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/DataTransactionImpl.java index 1ea2eba87f..15314d3bdc 100644 --- a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/DataTransactionImpl.java +++ b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/DataTransactionImpl.java @@ -11,7 +11,7 @@ import org.opendaylight.controller.md.sal.common.api.TransactionStatus; import org.opendaylight.controller.md.sal.common.impl.service.AbstractDataTransaction; import org.opendaylight.controller.sal.binding.api.data.DataModificationTransaction; import org.opendaylight.yangtools.concepts.ListenerRegistration; -import org.opendaylight.yangtools.concepts.util.ListenerRegistry; +import org.opendaylight.yangtools.util.ListenerRegistry; import org.opendaylight.yangtools.yang.binding.DataObject; import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; diff --git a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/MountPointManagerImpl.java b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/MountPointManagerImpl.java index 05651bfabe..c390fe7049 100644 --- a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/MountPointManagerImpl.java +++ b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/MountPointManagerImpl.java @@ -15,7 +15,7 @@ import org.opendaylight.controller.md.sal.binding.util.AbstractBindingSalProvide import org.opendaylight.controller.sal.binding.api.mount.MountProviderInstance; import org.opendaylight.controller.sal.binding.api.mount.MountProviderService; import org.opendaylight.yangtools.concepts.ListenerRegistration; -import org.opendaylight.yangtools.concepts.util.ListenerRegistry; +import org.opendaylight.yangtools.util.ListenerRegistry; import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; import org.slf4j.Logger; import org.slf4j.LoggerFactory; diff --git a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/NotificationBrokerImpl.java b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/NotificationBrokerImpl.java index 258ba51777..58e46ceca3 100644 --- a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/NotificationBrokerImpl.java +++ b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/NotificationBrokerImpl.java @@ -19,7 +19,7 @@ import org.opendaylight.controller.sal.binding.codegen.impl.SingletonHolder; import org.opendaylight.controller.sal.binding.spi.NotificationInvokerFactory.NotificationInvoker; import org.opendaylight.yangtools.concepts.AbstractListenerRegistration; import org.opendaylight.yangtools.concepts.ListenerRegistration; -import org.opendaylight.yangtools.concepts.util.ListenerRegistry; +import org.opendaylight.yangtools.util.ListenerRegistry; import org.opendaylight.yangtools.yang.binding.Notification; import org.slf4j.Logger; import org.slf4j.LoggerFactory; diff --git a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/RpcProviderRegistryImpl.java b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/RpcProviderRegistryImpl.java index f2e467038f..13a9f1cc10 100644 --- a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/RpcProviderRegistryImpl.java +++ b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/RpcProviderRegistryImpl.java @@ -33,7 +33,7 @@ import org.opendaylight.controller.sal.binding.codegen.RuntimeCodeHelper; import org.opendaylight.controller.sal.binding.codegen.impl.SingletonHolder; import org.opendaylight.yangtools.concepts.AbstractObjectRegistration; import org.opendaylight.yangtools.concepts.ListenerRegistration; -import org.opendaylight.yangtools.concepts.util.ListenerRegistry; +import org.opendaylight.yangtools.util.ListenerRegistry; import org.opendaylight.yangtools.yang.binding.BaseIdentity; import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; import org.opendaylight.yangtools.yang.binding.RpcService; diff --git a/opendaylight/md-sal/sal-binding-broker/src/test/java/org/opendaylight/controller/sal/binding/test/util/MockSchemaService.java b/opendaylight/md-sal/sal-binding-broker/src/test/java/org/opendaylight/controller/sal/binding/test/util/MockSchemaService.java index 63a4ffb23a..356a4b810e 100644 --- a/opendaylight/md-sal/sal-binding-broker/src/test/java/org/opendaylight/controller/sal/binding/test/util/MockSchemaService.java +++ b/opendaylight/md-sal/sal-binding-broker/src/test/java/org/opendaylight/controller/sal/binding/test/util/MockSchemaService.java @@ -10,7 +10,7 @@ package org.opendaylight.controller.sal.binding.test.util; import org.opendaylight.controller.sal.core.api.model.SchemaService; import org.opendaylight.controller.sal.dom.broker.impl.SchemaContextProvider; import org.opendaylight.yangtools.concepts.ListenerRegistration; -import org.opendaylight.yangtools.concepts.util.ListenerRegistry; +import org.opendaylight.yangtools.util.ListenerRegistry; import org.opendaylight.yangtools.yang.model.api.Module; import org.opendaylight.yangtools.yang.model.api.SchemaContext; import org.opendaylight.yangtools.yang.model.api.SchemaContextListener; diff --git a/opendaylight/md-sal/sal-clustering-config/pom.xml b/opendaylight/md-sal/sal-clustering-config/pom.xml new file mode 100644 index 0000000000..d726823b98 --- /dev/null +++ b/opendaylight/md-sal/sal-clustering-config/pom.xml @@ -0,0 +1,46 @@ + + + + + 4.0.0 + + org.opendaylight.controller + sal-parent + 1.1-SNAPSHOT + + sal-clustering-config + Configuration files for md-sal clustering + jar + + + + org.codehaus.mojo + build-helper-maven-plugin + + + attach-artifacts + + attach-artifact + + package + + + + ${project.build.directory}/classes/initial/*.conf + xml + config + + + + + + + + + diff --git a/opendaylight/md-sal/sal-clustering-config/src/main/resources/initial/05-clustering.xml.conf b/opendaylight/md-sal/sal-clustering-config/src/main/resources/initial/05-clustering.xml.conf new file mode 100644 index 0000000000..7891ee2088 --- /dev/null +++ b/opendaylight/md-sal/sal-clustering-config/src/main/resources/initial/05-clustering.xml.conf @@ -0,0 +1,85 @@ + + + + + + + + + prefix:dom-inmemory-data-broker + inmemory-data-broker + + + dom:schema-service + yang-schema-service + + + + config-dom-store-spi:config-dom-datastore + distributed-config-store-service + + + + operational-dom-store-spi:operational-dom-datastore + distributed-operational-store-service + + + + + prefix:distributed-operational-datastore-provider + distributed-operational-store-module + + dom:schema-service + yang-schema-service + + + + + prefix:distributed-config-datastore-provider + distributed-config-store-module + + dom:schema-service + yang-schema-service + + + + + prefix:remote-rpc-connector + remote-rpc-connector + + dom:dom-broker-osgi-registry + dom-broker + + + + + + + + config-dom-store-spi:config-dom-datastore + + distributed-config-store-service + /modules/module[type='distributed-config-datastore-provider'][name='distributed-config-store-module'] + + + + operational-dom-store-spi:operational-dom-datastore + + distributed-operational-store-service + /modules/module[type='distributed-operational-datastore-provider'][name='distributed-operational-store-module'] + + + + + + + + urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom:impl?module=opendaylight-sal-dom-broker-impl&revision=2013-10-28 + + diff --git a/opendaylight/md-sal/sal-clustering-config/src/main/resources/initial/akka.conf b/opendaylight/md-sal/sal-clustering-config/src/main/resources/initial/akka.conf new file mode 100644 index 0000000000..9749ae27ae --- /dev/null +++ b/opendaylight/md-sal/sal-clustering-config/src/main/resources/initial/akka.conf @@ -0,0 +1,55 @@ + +odl-cluster-data { + akka { + actor { + provider = "akka.cluster.ClusterActorRefProvider" + serializers { + java = "akka.serialization.JavaSerializer" + proto = "akka.remote.serialization.ProtobufSerializer" + } + + serialization-bindings { + "com.google.protobuf.Message" = proto + + } + } + remote { + log-remote-lifecycle-events = off + netty.tcp { + hostname = "" + port = 2550 + maximum-frame-size = 2097152 + send-buffer-size = 52428800 + receive-buffer-size = 52428800 + } + } + + cluster { + seed-nodes = ["akka.tcp://opendaylight-cluster-data@:2550"] + + auto-down-unreachable-after = 10s + } + } +} + +odl-cluster-rpc { + akka { + actor { + provider = "akka.cluster.ClusterActorRefProvider" + + } + remote { + log-remote-lifecycle-events = off + netty.tcp { + hostname = "" + port = 2551 + } + } + + cluster { + seed-nodes = ["akka.tcp://opendaylight-cluster-rpc@:2551"] + + auto-down-unreachable-after = 10s + } + } +} diff --git a/opendaylight/md-sal/sal-clustering-config/src/main/resources/initial/module-shards.conf b/opendaylight/md-sal/sal-clustering-config/src/main/resources/initial/module-shards.conf new file mode 100644 index 0000000000..8449abb7b0 --- /dev/null +++ b/opendaylight/md-sal/sal-clustering-config/src/main/resources/initial/module-shards.conf @@ -0,0 +1,70 @@ +# This file describes which shards live on which members +# The format for a module-shards is as follows, +# { +# name = "" +# shards = [ +# { +# name="" +# replicas = [ +# "" +# ] +# ] +# } +# +# For Helium we support only one shard per module. Beyond Helium +# we will support more than 1 +# The replicas section is a collection of member names. This information +# will be used to decide on which members replicas of a particular shard will be +# located. Once replication is integrated with the distributed data store then +# this section can have multiple entries. +# +# + + +module-shards = [ + { + name = "default" + shards = [ + { + name="default" + replicas = [ + "member-1" + ] + } + ] + }, + { + name = "topology" + shards = [ + { + name="topology" + replicas = [ + "member-1" + ] + } + ] + }, + { + name = "inventory" + shards = [ + { + name="inventory" + replicas = [ + "member-1" + ] + } + ] + }, + { + name = "toaster" + shards = [ + { + name="toaster" + replicas = [ + "member-1" + ] + } + ] + } + +] diff --git a/opendaylight/md-sal/sal-clustering-config/src/main/resources/initial/modules.conf b/opendaylight/md-sal/sal-clustering-config/src/main/resources/initial/modules.conf new file mode 100644 index 0000000000..68347eeda9 --- /dev/null +++ b/opendaylight/md-sal/sal-clustering-config/src/main/resources/initial/modules.conf @@ -0,0 +1,32 @@ +# This file should describe all the modules that need to be placed in a separate shard +# The format of the configuration is as follows +# { +# name = "" +# namespace = "" +# shard-strategy = "module" +# } +# +# Note that at this time the only shard-strategy we support is module which basically +# will put all the data of a single module in two shards (one for config and one for +# operational data) + +modules = [ + { + name = "inventory" + namespace = "urn:opendaylight:inventory" + shard-strategy = "module" + }, + + { + name = "topology" + namespace = "urn:TBD:params:xml:ns:yang:network-topology" + shard-strategy = "module" + }, + + { + name = "toaster" + namespace = "http://netconfcentral.org/ns/toaster" + shard-strategy = "module" + } + +] diff --git a/opendaylight/md-sal/sal-common-impl/src/main/java/org/opendaylight/controller/md/sal/common/impl/service/AbstractDataBroker.java b/opendaylight/md-sal/sal-common-impl/src/main/java/org/opendaylight/controller/md/sal/common/impl/service/AbstractDataBroker.java index a732f2f1b9..ca6e6e9718 100644 --- a/opendaylight/md-sal/sal-common-impl/src/main/java/org/opendaylight/controller/md/sal/common/impl/service/AbstractDataBroker.java +++ b/opendaylight/md-sal/sal-common-impl/src/main/java/org/opendaylight/controller/md/sal/common/impl/service/AbstractDataBroker.java @@ -36,7 +36,7 @@ import org.opendaylight.yangtools.concepts.CompositeObjectRegistration; import org.opendaylight.yangtools.concepts.ListenerRegistration; import org.opendaylight.yangtools.concepts.Path; import org.opendaylight.yangtools.concepts.Registration; -import org.opendaylight.yangtools.concepts.util.ListenerRegistry; +import org.opendaylight.yangtools.util.ListenerRegistry; import org.opendaylight.yangtools.yang.common.RpcResult; import org.slf4j.Logger; import org.slf4j.LoggerFactory; diff --git a/opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/ActorSystemFactory.java b/opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/ActorSystemFactory.java index baf04fe43b..15c0548761 100644 --- a/opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/ActorSystemFactory.java +++ b/opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/ActorSystemFactory.java @@ -20,8 +20,8 @@ public class ActorSystemFactory { @Nullable @Override public ActorSystem apply(@Nullable Void aVoid) { ActorSystem system = - ActorSystem.create("opendaylight-cluster", ConfigFactory - .load().getConfig("ODLCluster")); + ActorSystem.create("opendaylight-cluster-data", ConfigFactory + .load().getConfig("odl-cluster-data")); system.actorOf(Props.create(TerminationMonitor.class), "termination-monitor"); return system; } diff --git a/opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/DataChangeListener.java b/opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/DataChangeListener.java index b435eda7a3..cdf04dd093 100644 --- a/opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/DataChangeListener.java +++ b/opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/DataChangeListener.java @@ -33,7 +33,7 @@ public class DataChangeListener extends AbstractUntypedActor { } @Override public void handleReceive(Object message) throws Exception { - if(message.getClass().equals(DataChanged.SERIALIZABLE_CLASS)){ + if(message instanceof DataChanged){ dataChanged(message); } else if(message instanceof EnableNotification){ enableNotification((EnableNotification) message); @@ -51,13 +51,13 @@ public class DataChangeListener extends AbstractUntypedActor { return; } - DataChanged reply = DataChanged.fromSerialize(schemaContext,message, pathId); + DataChanged reply = (DataChanged) message; AsyncDataChangeEvent> change = reply.getChange(); this.listener.onDataChanged(change); if(getSender() != null){ - getSender().tell(new DataChangedReply().toSerializable(), getSelf()); + getSender().tell(new DataChangedReply(), getSelf()); } } diff --git a/opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/DataChangeListenerProxy.java b/opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/DataChangeListenerProxy.java index cd9c330268..a4ca456268 100644 --- a/opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/DataChangeListenerProxy.java +++ b/opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/DataChangeListenerProxy.java @@ -30,6 +30,6 @@ public class DataChangeListenerProxy implements AsyncDataChangeListener> change) { - dataChangeListenerActor.tell(new DataChanged(schemaContext,change).toSerializable(), null); + dataChangeListenerActor.tell(new DataChanged(schemaContext,change), null); } } diff --git a/opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/DistributedDataStore.java b/opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/DistributedDataStore.java index 780f28f358..479af79748 100644 --- a/opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/DistributedDataStore.java +++ b/opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/DistributedDataStore.java @@ -8,11 +8,10 @@ package org.opendaylight.controller.cluster.datastore; -import java.util.concurrent.Executors; - import akka.actor.ActorRef; import akka.actor.ActorSystem; - +import com.google.common.util.concurrent.ListeningExecutorService; +import com.google.common.util.concurrent.MoreExecutors; import org.opendaylight.controller.cluster.datastore.messages.RegisterChangeListener; import org.opendaylight.controller.cluster.datastore.messages.RegisterChangeListenerReply; import org.opendaylight.controller.cluster.datastore.messages.UpdateSchemaContext; @@ -33,8 +32,7 @@ import org.opendaylight.yangtools.yang.model.api.SchemaContextListener; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import com.google.common.util.concurrent.ListeningExecutorService; -import com.google.common.util.concurrent.MoreExecutors; +import java.util.concurrent.Executors; /** * @@ -88,13 +86,12 @@ public class DistributedDataStore implements DOMStore, SchemaContextListener, Au Object result = actorContext.executeLocalShardOperation(shardName, new RegisterChangeListener(path, dataChangeListenerActor.path(), - scope).toSerializable(), + scope), ActorContext.ASK_DURATION ); if (result != null) { - RegisterChangeListenerReply reply = RegisterChangeListenerReply - .fromSerializable(actorContext.getActorSystem(), result); + RegisterChangeListenerReply reply = (RegisterChangeListenerReply) result; return new DataChangeListenerRegistrationProxy(actorContext .actorSelection(reply.getListenerRegistrationPath()), listener, dataChangeListenerActor); diff --git a/opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/Shard.java b/opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/Shard.java index 9cda3f1aa1..10dbbc84d8 100644 --- a/opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/Shard.java +++ b/opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/Shard.java @@ -15,6 +15,7 @@ import akka.event.Logging; import akka.event.LoggingAdapter; import akka.japi.Creator; import akka.serialization.Serialization; +import com.google.common.base.Optional; import com.google.common.util.concurrent.ListenableFuture; import com.google.common.util.concurrent.ListeningExecutorService; import com.google.common.util.concurrent.MoreExecutors; @@ -33,6 +34,8 @@ import org.opendaylight.controller.cluster.datastore.messages.RegisterChangeList import org.opendaylight.controller.cluster.datastore.messages.UpdateSchemaContext; import org.opendaylight.controller.cluster.datastore.modification.Modification; import org.opendaylight.controller.cluster.datastore.modification.MutableCompositeModification; +import org.opendaylight.controller.cluster.raft.ConfigParams; +import org.opendaylight.controller.cluster.raft.DefaultConfigParamsImpl; import org.opendaylight.controller.cluster.raft.RaftActor; import org.opendaylight.controller.md.sal.common.api.data.AsyncDataChangeListener; import org.opendaylight.controller.md.sal.dom.store.impl.InMemoryDOMDataStore; @@ -42,6 +45,7 @@ import org.opendaylight.controller.sal.core.spi.data.DOMStoreTransactionChain; import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier; import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode; import org.opendaylight.yangtools.yang.model.api.SchemaContext; +import scala.concurrent.duration.FiniteDuration; import java.util.ArrayList; import java.util.HashMap; @@ -49,6 +53,7 @@ import java.util.List; import java.util.Map; import java.util.concurrent.ExecutionException; import java.util.concurrent.Executors; +import java.util.concurrent.TimeUnit; /** * A Shard represents a portion of the logical data tree
@@ -58,6 +63,8 @@ import java.util.concurrent.Executors; */ public class Shard extends RaftActor { + private static final ConfigParams configParams = new ShardConfigParams(); + public static final String DEFAULT_NAME = "default"; private final ListeningExecutorService storeExecutor = @@ -84,7 +91,7 @@ public class Shard extends RaftActor { private final List dataChangeListeners = new ArrayList<>(); private Shard(String name, Map peerAddresses) { - super(name, peerAddresses); + super(name, peerAddresses, Optional.of(configParams)); this.name = name; @@ -121,8 +128,8 @@ public class Shard extends RaftActor { } else if(getLeader() != null){ getLeader().forward(message, getContext()); } - } else if (message.getClass().equals(RegisterChangeListener.SERIALIZABLE_CLASS)) { - registerChangeListener(RegisterChangeListener.fromSerializable(getContext().system(), message)); + } else if (message instanceof RegisterChangeListener) { + registerChangeListener((RegisterChangeListener) message); } else if (message instanceof UpdateSchemaContext) { updateSchemaContext((UpdateSchemaContext) message); } else if (message instanceof ForwardedCommitTransaction) { @@ -271,7 +278,7 @@ public class Shard extends RaftActor { LOG.debug("registerDataChangeListener sending reply, listenerRegistrationPath = " + listenerRegistration.path().toString()); getSender() - .tell(new RegisterChangeListenerReply(listenerRegistration.path()).toSerializable(), + .tell(new RegisterChangeListenerReply(listenerRegistration.path()), getSelf()); } @@ -318,9 +325,25 @@ public class Shard extends RaftActor { for(ActorSelection dataChangeListener : dataChangeListeners){ dataChangeListener.tell(new EnableNotification(isLeader()), getSelf()); } + + if(getLeaderId() != null){ + shardMBean.setLeader(getLeaderId()); + } + + shardMBean.setRaftState(getRaftState().name()); } @Override public String persistenceId() { return this.name; } + + + private static class ShardConfigParams extends DefaultConfigParamsImpl { + public static final FiniteDuration HEART_BEAT_INTERVAL = + new FiniteDuration(500, TimeUnit.MILLISECONDS); + + @Override public FiniteDuration getHeartBeatInterval() { + return HEART_BEAT_INTERVAL; + } + } } diff --git a/opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/ThreePhaseCommitCohortProxy.java b/opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/ThreePhaseCommitCohortProxy.java index 56220656ad..915b13dd8b 100644 --- a/opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/ThreePhaseCommitCohortProxy.java +++ b/opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/ThreePhaseCommitCohortProxy.java @@ -76,7 +76,6 @@ public class ThreePhaseCommitCohortProxy implements CanCommitTransactionReply reply = CanCommitTransactionReply.fromSerializable(response); if (!reply.getCanCommit()) { - System.out.println("**TOM - failed: false"); return false; } } diff --git a/opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/jmx/mbeans/shard/ShardStats.java b/opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/jmx/mbeans/shard/ShardStats.java index 2da6aae85f..4eb6a8cef9 100644 --- a/opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/jmx/mbeans/shard/ShardStats.java +++ b/opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/jmx/mbeans/shard/ShardStats.java @@ -9,6 +9,8 @@ public class ShardStats extends AbstractBaseMBean implements ShardStatsMBean { private Long committedTransactionsCount; private Long journalMessagesCount; final private String shardName; + private String leader; + private String raftState; ShardStats(String shardName){ this.shardName = shardName; @@ -33,6 +35,13 @@ public class ShardStats extends AbstractBaseMBean implements ShardStatsMBean { return journalMessagesCount; } + @Override public String getLeader() { + return leader; + } + + @Override public String getRaftState() { + return raftState; + } public Long incrementCommittedTransactionCount() { return committedTransactionsCount++; @@ -49,6 +58,13 @@ public class ShardStats extends AbstractBaseMBean implements ShardStatsMBean { } + public void setLeader(String leader){ + this.leader = leader; + } + + public void setRaftState(String raftState){ + this.raftState = raftState; + } @Override diff --git a/opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/jmx/mbeans/shard/ShardStatsMBean.java b/opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/jmx/mbeans/shard/ShardStatsMBean.java index c107e49e85..9ebcc7fa5a 100644 --- a/opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/jmx/mbeans/shard/ShardStatsMBean.java +++ b/opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/jmx/mbeans/shard/ShardStatsMBean.java @@ -7,5 +7,6 @@ public interface ShardStatsMBean { String getShardName(); Long getCommittedTransactionsCount(); Long getJournalMessagesCount(); - + String getLeader(); + String getRaftState(); } diff --git a/opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/shardstrategy/ModuleShardStrategy.java b/opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/shardstrategy/ModuleShardStrategy.java index 6f4b65a6f3..fc7ebd94dd 100644 --- a/opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/shardstrategy/ModuleShardStrategy.java +++ b/opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/shardstrategy/ModuleShardStrategy.java @@ -11,6 +11,8 @@ package org.opendaylight.controller.cluster.datastore.shardstrategy; import org.opendaylight.controller.cluster.datastore.Configuration; import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier; +import java.util.List; + public class ModuleShardStrategy implements ShardStrategy { public static final String NAME = "module"; @@ -25,6 +27,11 @@ public class ModuleShardStrategy implements ShardStrategy { } @Override public String findShard(YangInstanceIdentifier path) { - return configuration.getShardNamesFromModuleName(moduleName).get(0); + List shardNames = + configuration.getShardNamesFromModuleName(moduleName); + if(shardNames.size() == 0){ + return DefaultShardStrategy.DEFAULT_SHARD; + } + return shardNames.get(0); } } diff --git a/opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/shardstrategy/ShardStrategy.java b/opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/shardstrategy/ShardStrategy.java index 2df945edd5..9a05c381ea 100644 --- a/opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/shardstrategy/ShardStrategy.java +++ b/opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/shardstrategy/ShardStrategy.java @@ -16,6 +16,9 @@ import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier; public interface ShardStrategy { /** * Find the name of the shard in which the data pointed to by the specified path belongs in + *

+ * Should return the name of the default shard DefaultShardStrategy.DEFAULT_SHARD + * if no matching shard was found * * @param path The location of the data in the logical tree * @return diff --git a/opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/config/yang/config/distributed_datastore_provider/DistributedConfigDataStoreProviderModule.java b/opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/config/yang/config/distributed_datastore_provider/DistributedConfigDataStoreProviderModule.java index 039446baf3..87a621f9d3 100644 --- a/opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/config/yang/config/distributed_datastore_provider/DistributedConfigDataStoreProviderModule.java +++ b/opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/config/yang/config/distributed_datastore_provider/DistributedConfigDataStoreProviderModule.java @@ -26,7 +26,7 @@ public class DistributedConfigDataStoreProviderModule extends @Override public java.lang.AutoCloseable createInstance() { return DistributedDataStoreFactory - .createInstance("config", getSchemaServiceDependency()); + .createInstance("config", getConfigSchemaServiceDependency()); } } diff --git a/opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/config/yang/config/distributed_datastore_provider/DistributedOperationalDataStoreProviderModule.java b/opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/config/yang/config/distributed_datastore_provider/DistributedOperationalDataStoreProviderModule.java index 1a06629bb7..6af2748a8f 100644 --- a/opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/config/yang/config/distributed_datastore_provider/DistributedOperationalDataStoreProviderModule.java +++ b/opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/config/yang/config/distributed_datastore_provider/DistributedOperationalDataStoreProviderModule.java @@ -26,7 +26,7 @@ public class DistributedOperationalDataStoreProviderModule extends @Override public java.lang.AutoCloseable createInstance() { return DistributedDataStoreFactory - .createInstance("operational", getSchemaServiceDependency()); + .createInstance("operational", getOperationalSchemaServiceDependency()); } } diff --git a/opendaylight/md-sal/sal-distributed-datastore/src/main/resources/application.conf b/opendaylight/md-sal/sal-distributed-datastore/src/main/resources/application.conf index 76914c2c84..daac89c4c8 100644 --- a/opendaylight/md-sal/sal-distributed-datastore/src/main/resources/application.conf +++ b/opendaylight/md-sal/sal-distributed-datastore/src/main/resources/application.conf @@ -1,15 +1,60 @@ -ODLCluster{ -actor { - serializers { - java = "akka.serialization.JavaSerializer" - proto = "akka.remote.serialization.ProtobufSerializer" - } +odl-cluster-data { + akka { + cluster { + roles = [ + "member-1" + ] + } + actor { + provider = "akka.cluster.ClusterActorRefProvider" + serializers { + java = "akka.serialization.JavaSerializer" + proto = "akka.remote.serialization.ProtobufSerializer" + } + + serialization-bindings { + "com.google.protobuf.Message" = proto + + } + } + remote { + log-remote-lifecycle-events = off + netty.tcp { + hostname = "127.0.0.1" + port = 2550 + maximum-frame-size = 2097152 + send-buffer-size = 52428800 + receive-buffer-size = 52428800 + } + } - serialization-bindings { - "com.google.protobuf.Message" = proto + cluster { + seed-nodes = ["akka.tcp://opendaylight-cluster-data@127.0.0.1:2550"] - } + auto-down-unreachable-after = 10s } + } +} + +odl-cluster-rpc { + akka { + actor { + provider = "akka.cluster.ClusterActorRefProvider" -} \ No newline at end of file + } + remote { + log-remote-lifecycle-events = off + netty.tcp { + hostname = "127.0.0.1" + port = 2551 + } + } + + cluster { + seed-nodes = ["akka.tcp://opendaylight-cluster-rpc@127.0.0.1:2551"] + + auto-down-unreachable-after = 10s + } + } +} diff --git a/opendaylight/md-sal/sal-distributed-datastore/src/main/resources/modules.conf b/opendaylight/md-sal/sal-distributed-datastore/src/main/resources/modules.conf index 05ef33f759..e820703eeb 100644 --- a/opendaylight/md-sal/sal-distributed-datastore/src/main/resources/modules.conf +++ b/opendaylight/md-sal/sal-distributed-datastore/src/main/resources/modules.conf @@ -1,7 +1,7 @@ modules = [ { name = "inventory" - namespace = "urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom:store:test:people" + namespace = "urn:opendaylight:inventory" shard-strategy = "module" } ] diff --git a/opendaylight/md-sal/sal-distributed-datastore/src/main/yang/distributed-datastore-provider.yang b/opendaylight/md-sal/sal-distributed-datastore/src/main/yang/distributed-datastore-provider.yang index 5d3758986c..6f355cbe63 100644 --- a/opendaylight/md-sal/sal-distributed-datastore/src/main/yang/distributed-datastore-provider.yang +++ b/opendaylight/md-sal/sal-distributed-datastore/src/main/yang/distributed-datastore-provider.yang @@ -40,7 +40,7 @@ module distributed-datastore-provider { augment "/config:modules/config:module/config:configuration" { case distributed-config-datastore-provider { when "/config:modules/config:module/config:type = 'distributed-config-datastore-provider'"; - container schema-service { + container config-schema-service { uses config:service-ref { refine type { mandatory false; @@ -55,7 +55,7 @@ module distributed-datastore-provider { augment "/config:modules/config:module/config:configuration" { case distributed-operational-datastore-provider { when "/config:modules/config:module/config:type = 'distributed-operational-datastore-provider'"; - container schema-service { + container operational-schema-service { uses config:service-ref { refine type { mandatory false; diff --git a/opendaylight/md-sal/sal-distributed-datastore/src/test/java/org/opendaylight/controller/cluster/datastore/BasicIntegrationTest.java b/opendaylight/md-sal/sal-distributed-datastore/src/test/java/org/opendaylight/controller/cluster/datastore/BasicIntegrationTest.java index df3c78ec97..6599bd8eeb 100644 --- a/opendaylight/md-sal/sal-distributed-datastore/src/test/java/org/opendaylight/controller/cluster/datastore/BasicIntegrationTest.java +++ b/opendaylight/md-sal/sal-distributed-datastore/src/test/java/org/opendaylight/controller/cluster/datastore/BasicIntegrationTest.java @@ -12,6 +12,7 @@ import akka.actor.ActorPath; import akka.actor.ActorRef; import akka.actor.ActorSelection; import akka.actor.Props; +import akka.event.Logging; import akka.testkit.JavaTestKit; import junit.framework.Assert; import org.junit.Test; @@ -35,6 +36,8 @@ import scala.concurrent.duration.FiniteDuration; import java.util.Collections; +import static junit.framework.Assert.assertEquals; + public class BasicIntegrationTest extends AbstractActorTest { @Test @@ -61,17 +64,24 @@ public class BasicIntegrationTest extends AbstractActorTest { getRef()); - // Wait for Shard to become a Leader - try { - Thread.sleep(1000); - } catch (InterruptedException e) { - e.printStackTrace(); - } + // Wait for a specific log message to show up + final boolean result = + new JavaTestKit.EventFilter(Logging.Info.class + ) { + protected Boolean run() { + return true; + } + }.from(shard.path().toString()) + .message("Switching from state Candidate to Leader") + .occurrences(1).exec(); + + assertEquals(true, result); + // 1. Create a TransactionChain shard.tell(new CreateTransactionChain().toSerializable(), getRef()); final ActorSelection transactionChain = - new ExpectMsg("CreateTransactionChainReply") { + new ExpectMsg(duration("1 seconds"), "CreateTransactionChainReply") { protected ActorSelection match(Object in) { if (in.getClass().equals(CreateTransactionChainReply.SERIALIZABLE_CLASS)) { ActorPath transactionChainPath = @@ -93,7 +103,7 @@ public class BasicIntegrationTest extends AbstractActorTest { transactionChain.tell(new CreateTransaction("txn-1", TransactionProxy.TransactionType.WRITE_ONLY.ordinal() ).toSerializable(), getRef()); final ActorSelection transaction = - new ExpectMsg("CreateTransactionReply") { + new ExpectMsg(duration("1 seconds"), "CreateTransactionReply") { protected ActorSelection match(Object in) { if (CreateTransactionReply.SERIALIZABLE_CLASS.equals(in.getClass())) { CreateTransactionReply reply = CreateTransactionReply.fromSerializable(in); @@ -115,7 +125,7 @@ public class BasicIntegrationTest extends AbstractActorTest { ImmutableNodes.containerNode(TestModel.TEST_QNAME), TestModel.createTestContext()).toSerializable(), getRef()); - Boolean writeDone = new ExpectMsg("WriteDataReply") { + Boolean writeDone = new ExpectMsg(duration("1 seconds"), "WriteDataReply") { protected Boolean match(Object in) { if (in.getClass().equals(WriteDataReply.SERIALIZABLE_CLASS)) { return true; @@ -134,7 +144,7 @@ public class BasicIntegrationTest extends AbstractActorTest { transaction.tell(new ReadyTransaction().toSerializable(), getRef()); final ActorSelection cohort = - new ExpectMsg("ReadyTransactionReply") { + new ExpectMsg(duration("1 seconds"), "ReadyTransactionReply") { protected ActorSelection match(Object in) { if (in.getClass().equals(ReadyTransactionReply.SERIALIZABLE_CLASS)) { ActorPath cohortPath = @@ -157,7 +167,7 @@ public class BasicIntegrationTest extends AbstractActorTest { cohort.tell(new PreCommitTransaction().toSerializable(), getRef()); Boolean preCommitDone = - new ExpectMsg("PreCommitTransactionReply") { + new ExpectMsg(duration("1 seconds"), "PreCommitTransactionReply") { protected Boolean match(Object in) { if (in.getClass().equals(PreCommitTransactionReply.SERIALIZABLE_CLASS)) { return true; diff --git a/opendaylight/md-sal/sal-distributed-datastore/src/test/java/org/opendaylight/controller/cluster/datastore/DataChangeListenerProxyTest.java b/opendaylight/md-sal/sal-distributed-datastore/src/test/java/org/opendaylight/controller/cluster/datastore/DataChangeListenerProxyTest.java index 8c1cbbbba0..b2ee4a49fe 100644 --- a/opendaylight/md-sal/sal-distributed-datastore/src/test/java/org/opendaylight/controller/cluster/datastore/DataChangeListenerProxyTest.java +++ b/opendaylight/md-sal/sal-distributed-datastore/src/test/java/org/opendaylight/controller/cluster/datastore/DataChangeListenerProxyTest.java @@ -94,7 +94,7 @@ public class DataChangeListenerProxyTest extends AbstractActorTest { Assert.assertEquals(1, listMessages.size()); - Assert.assertTrue(listMessages.get(0).getClass().equals(DataChanged.SERIALIZABLE_CLASS)); + Assert.assertTrue(listMessages.get(0).getClass().equals(DataChanged.class)); } } diff --git a/opendaylight/md-sal/sal-distributed-datastore/src/test/java/org/opendaylight/controller/cluster/datastore/DataChangeListenerRegistrationTest.java b/opendaylight/md-sal/sal-distributed-datastore/src/test/java/org/opendaylight/controller/cluster/datastore/DataChangeListenerRegistrationTest.java index 8413bac3a7..920248521a 100644 --- a/opendaylight/md-sal/sal-distributed-datastore/src/test/java/org/opendaylight/controller/cluster/datastore/DataChangeListenerRegistrationTest.java +++ b/opendaylight/md-sal/sal-distributed-datastore/src/test/java/org/opendaylight/controller/cluster/datastore/DataChangeListenerRegistrationTest.java @@ -41,7 +41,7 @@ public class DataChangeListenerRegistrationTest extends AbstractActorTest { subject.tell(new CloseDataChangeListenerRegistration().toSerializable(), getRef()); - final String out = new ExpectMsg("match hint") { + final String out = new ExpectMsg(duration("1 seconds"), "match hint") { // do not put code outside this method, will run afterwards protected String match(Object in) { if (in.getClass().equals(CloseDataChangeListenerRegistrationReply.SERIALIZABLE_CLASS)) { diff --git a/opendaylight/md-sal/sal-distributed-datastore/src/test/java/org/opendaylight/controller/cluster/datastore/DataChangeListenerTest.java b/opendaylight/md-sal/sal-distributed-datastore/src/test/java/org/opendaylight/controller/cluster/datastore/DataChangeListenerTest.java index c4ec8b45fc..26ec583b3e 100644 --- a/opendaylight/md-sal/sal-distributed-datastore/src/test/java/org/opendaylight/controller/cluster/datastore/DataChangeListenerTest.java +++ b/opendaylight/md-sal/sal-distributed-datastore/src/test/java/org/opendaylight/controller/cluster/datastore/DataChangeListenerTest.java @@ -102,13 +102,13 @@ public class DataChangeListenerTest extends AbstractActorTest { subject.tell(new EnableNotification(true), getRef()); subject.tell( - new DataChanged(CompositeModel.createTestContext(),new MockDataChangedEvent()).toSerializable(), + new DataChanged(CompositeModel.createTestContext(),new MockDataChangedEvent()), getRef()); final Boolean out = new ExpectMsg(duration("800 millis"), "dataChanged") { // do not put code outside this method, will run afterwards protected Boolean match(Object in) { - if (in != null && in.getClass().equals(DataChangedReply.SERIALIZABLE_CLASS)) { + if (in != null && in.getClass().equals(DataChangedReply.class)) { return true; } else { @@ -141,7 +141,7 @@ public class DataChangeListenerTest extends AbstractActorTest { protected void run() { subject.tell( - new DataChanged(CompositeModel.createTestContext(),new MockDataChangedEvent()).toSerializable(), + new DataChanged(CompositeModel.createTestContext(),new MockDataChangedEvent()), getRef()); expectNoMsg(); diff --git a/opendaylight/md-sal/sal-distributed-datastore/src/test/java/org/opendaylight/controller/cluster/datastore/DistributedDataStoreIntegrationTest.java b/opendaylight/md-sal/sal-distributed-datastore/src/test/java/org/opendaylight/controller/cluster/datastore/DistributedDataStoreIntegrationTest.java index 0a0c04b915..fc527b6bff 100644 --- a/opendaylight/md-sal/sal-distributed-datastore/src/test/java/org/opendaylight/controller/cluster/datastore/DistributedDataStoreIntegrationTest.java +++ b/opendaylight/md-sal/sal-distributed-datastore/src/test/java/org/opendaylight/controller/cluster/datastore/DistributedDataStoreIntegrationTest.java @@ -1,11 +1,12 @@ package org.opendaylight.controller.cluster.datastore; import akka.actor.ActorSystem; +import akka.event.Logging; import akka.testkit.JavaTestKit; - import com.google.common.base.Optional; import com.google.common.util.concurrent.ListenableFuture; import junit.framework.Assert; +import org.apache.commons.io.FileUtils; import org.junit.After; import org.junit.Before; import org.junit.Test; @@ -20,19 +21,29 @@ import org.opendaylight.controller.sal.core.spi.data.DOMStoreThreePhaseCommitCoh import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode; import org.opendaylight.yangtools.yang.data.impl.schema.ImmutableNodes; +import java.io.File; +import java.io.IOException; import java.util.concurrent.ExecutionException; import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeoutException; import static junit.framework.Assert.assertEquals; import static junit.framework.Assert.assertTrue; +import static junit.framework.Assert.fail; -public class DistributedDataStoreIntegrationTest{ +public class DistributedDataStoreIntegrationTest { private static ActorSystem system; @Before - public void setUp() { + public void setUp() throws IOException { + File journal = new File("journal"); + + if(journal.exists()) { + FileUtils.deleteDirectory(journal); + } + + System.setProperty("shard.persistent", "false"); system = ActorSystem.create("test"); } @@ -49,82 +60,153 @@ public class DistributedDataStoreIntegrationTest{ @Test public void integrationTest() throws Exception { - Configuration configuration = new ConfigurationImpl("module-shards.conf", "modules.conf"); + final Configuration configuration = new ConfigurationImpl("module-shards.conf", "modules.conf"); ShardStrategyFactory.setConfiguration(configuration); - DistributedDataStore distributedDataStore = - new DistributedDataStore(getSystem(), "config", new MockClusterWrapper(), configuration); - distributedDataStore.onGlobalContextUpdated(TestModel.createTestContext()); - Thread.sleep(1500); - DOMStoreReadWriteTransaction transaction = - distributedDataStore.newReadWriteTransaction(); + new JavaTestKit(getSystem()) { + { + + new Within(duration("10 seconds")) { + protected void run() { + try { + final DistributedDataStore distributedDataStore = + new DistributedDataStore(getSystem(), "config", new MockClusterWrapper(), configuration); + + distributedDataStore.onGlobalContextUpdated(TestModel.createTestContext()); + + // Wait for a specific log message to show up + final boolean result = + new JavaTestKit.EventFilter(Logging.Info.class + ) { + protected Boolean run() { + return true; + } + }.from("akka://test/user/shardmanager-config/member-1-shard-test-1-config") + .message("Switching from state Candidate to Leader") + .occurrences(1).exec(); + + assertEquals(true, result); + + DOMStoreReadWriteTransaction transaction = + distributedDataStore.newReadWriteTransaction(); - transaction.write(TestModel.TEST_PATH, ImmutableNodes.containerNode(TestModel.TEST_QNAME)); + transaction + .write(TestModel.TEST_PATH, ImmutableNodes + .containerNode(TestModel.TEST_QNAME)); - ListenableFuture>> future = - transaction.read(TestModel.TEST_PATH); + ListenableFuture>> + future = + transaction.read(TestModel.TEST_PATH); - Optional> optional = future.get(); + Optional> optional = + future.get(); - Assert.assertTrue(optional.isPresent()); + Assert.assertTrue("Node not found", optional.isPresent()); - NormalizedNode normalizedNode = optional.get(); + NormalizedNode normalizedNode = + optional.get(); - assertEquals(TestModel.TEST_QNAME, normalizedNode.getNodeType()); + assertEquals(TestModel.TEST_QNAME, + normalizedNode.getNodeType()); - DOMStoreThreePhaseCommitCohort ready = transaction.ready(); + DOMStoreThreePhaseCommitCohort ready = + transaction.ready(); - ListenableFuture canCommit = ready.canCommit(); + ListenableFuture canCommit = + ready.canCommit(); - assertTrue(canCommit.get(5, TimeUnit.SECONDS)); + assertTrue(canCommit.get(5, TimeUnit.SECONDS)); - ListenableFuture preCommit = ready.preCommit(); + ListenableFuture preCommit = + ready.preCommit(); - preCommit.get(5, TimeUnit.SECONDS); + preCommit.get(5, TimeUnit.SECONDS); - ListenableFuture commit = ready.commit(); + ListenableFuture commit = ready.commit(); + + commit.get(5, TimeUnit.SECONDS); + } catch (ExecutionException | TimeoutException | InterruptedException e){ + fail(e.getMessage()); + } + } + }; + } + }; - commit.get(5, TimeUnit.SECONDS); } - @Test + //FIXME : Disabling test because it's flaky + //@Test public void integrationTestWithMultiShardConfiguration() throws ExecutionException, InterruptedException, TimeoutException { - Configuration configuration = new ConfigurationImpl("module-shards.conf", "modules.conf"); + final Configuration configuration = new ConfigurationImpl("module-shards.conf", "modules.conf"); ShardStrategyFactory.setConfiguration(configuration); - DistributedDataStore distributedDataStore = - new DistributedDataStore(getSystem(), "config", new MockClusterWrapper(), configuration); + new JavaTestKit(getSystem()) { + { + + new Within(duration("10 seconds")) { + protected void run() { + try { + final DistributedDataStore distributedDataStore = + new DistributedDataStore(getSystem(), "config", + new MockClusterWrapper(), configuration); + + distributedDataStore.onGlobalContextUpdated( + SchemaContextHelper.full()); + + // Wait for a specific log message to show up + final boolean result = + new JavaTestKit.EventFilter( + Logging.Info.class + ) { + protected Boolean run() { + return true; + } + }.from( + "akka://test/user/shardmanager-config/member-1-shard-cars-1-config") + .message( + "Switching from state Candidate to Leader") + .occurrences(1) + .exec(); + + Thread.sleep(1000); + + + DOMStoreReadWriteTransaction transaction = + distributedDataStore.newReadWriteTransaction(); - distributedDataStore.onGlobalContextUpdated(SchemaContextHelper.full()); + transaction.write(CarsModel.BASE_PATH, CarsModel.emptyContainer()); + transaction.write(PeopleModel.BASE_PATH, PeopleModel.emptyContainer()); - // This sleep is fragile - test can fail intermittently if all Shards aren't updated with - // the SchemaContext in time. Is there any way we can make this deterministic? - Thread.sleep(2000); + DOMStoreThreePhaseCommitCohort ready = transaction.ready(); - DOMStoreReadWriteTransaction transaction = - distributedDataStore.newReadWriteTransaction(); + ListenableFuture canCommit = ready.canCommit(); - transaction.write(CarsModel.BASE_PATH, CarsModel.emptyContainer()); - transaction.write(PeopleModel.BASE_PATH, PeopleModel.emptyContainer()); + assertTrue(canCommit.get(5, TimeUnit.SECONDS)); - DOMStoreThreePhaseCommitCohort ready = transaction.ready(); + ListenableFuture preCommit = ready.preCommit(); - ListenableFuture canCommit = ready.canCommit(); + preCommit.get(5, TimeUnit.SECONDS); - assertTrue(canCommit.get(5, TimeUnit.SECONDS)); + ListenableFuture commit = ready.commit(); - ListenableFuture preCommit = ready.preCommit(); + commit.get(5, TimeUnit.SECONDS); - preCommit.get(5, TimeUnit.SECONDS); + assertEquals(true, result); + } catch(ExecutionException | TimeoutException | InterruptedException e){ + fail(e.getMessage()); + } + } + }; + } + }; - ListenableFuture commit = ready.commit(); - commit.get(5, TimeUnit.SECONDS); } } diff --git a/opendaylight/md-sal/sal-distributed-datastore/src/test/java/org/opendaylight/controller/cluster/datastore/DistributedDataStoreTest.java b/opendaylight/md-sal/sal-distributed-datastore/src/test/java/org/opendaylight/controller/cluster/datastore/DistributedDataStoreTest.java index 03191f70f1..d1beab9049 100644 --- a/opendaylight/md-sal/sal-distributed-datastore/src/test/java/org/opendaylight/controller/cluster/datastore/DistributedDataStoreTest.java +++ b/opendaylight/md-sal/sal-distributed-datastore/src/test/java/org/opendaylight/controller/cluster/datastore/DistributedDataStoreTest.java @@ -73,7 +73,7 @@ public class DistributedDataStoreTest extends AbstractActorTest{ @org.junit.Test public void testRegisterChangeListenerWhenShardIsLocal() throws Exception { - mockActorContext.setExecuteLocalShardOperationResponse(new RegisterChangeListenerReply(doNothingActorRef.path()).toSerializable()); + mockActorContext.setExecuteLocalShardOperationResponse(new RegisterChangeListenerReply(doNothingActorRef.path())); ListenerRegistration registration = distributedDataStore.registerChangeListener(TestModel.TEST_PATH, new AsyncDataChangeListener>() { diff --git a/opendaylight/md-sal/sal-distributed-datastore/src/test/java/org/opendaylight/controller/cluster/datastore/ShardManagerTest.java b/opendaylight/md-sal/sal-distributed-datastore/src/test/java/org/opendaylight/controller/cluster/datastore/ShardManagerTest.java index 268ed3c273..e9ad450ed8 100644 --- a/opendaylight/md-sal/sal-distributed-datastore/src/test/java/org/opendaylight/controller/cluster/datastore/ShardManagerTest.java +++ b/opendaylight/md-sal/sal-distributed-datastore/src/test/java/org/opendaylight/controller/cluster/datastore/ShardManagerTest.java @@ -75,7 +75,7 @@ public class ShardManagerTest { subject.tell(new FindPrimary(Shard.DEFAULT_NAME).toSerializable(), getRef()); - expectMsgClass(PrimaryFound.SERIALIZABLE_CLASS); + expectMsgClass(duration("1 seconds"), PrimaryFound.SERIALIZABLE_CLASS); expectNoMsg(); } @@ -170,7 +170,7 @@ public class ShardManagerTest { subject.tell(new FindPrimary("astronauts").toSerializable(), getRef()); - final String out = new ExpectMsg("primary found") { + final String out = new ExpectMsg(duration("1 seconds"), "primary found") { // do not put code outside this method, will run afterwards protected String match(Object in) { if (in.getClass().equals(PrimaryFound.SERIALIZABLE_CLASS)) { @@ -208,13 +208,13 @@ public class ShardManagerTest { subject.tell(new FindPrimary("astronauts").toSerializable(), getRef()); - expectMsgClass(PrimaryFound.SERIALIZABLE_CLASS); + expectMsgClass(duration("1 seconds"), PrimaryFound.SERIALIZABLE_CLASS); MockClusterWrapper.sendMemberRemoved(subject, "member-2", getRef().path().toString()); subject.tell(new FindPrimary("astronauts").toSerializable(), getRef()); - expectMsgClass(PrimaryNotFound.SERIALIZABLE_CLASS); + expectMsgClass(duration("1 seconds"), PrimaryNotFound.SERIALIZABLE_CLASS); expectNoMsg(); } diff --git a/opendaylight/md-sal/sal-distributed-datastore/src/test/java/org/opendaylight/controller/cluster/datastore/ShardTest.java b/opendaylight/md-sal/sal-distributed-datastore/src/test/java/org/opendaylight/controller/cluster/datastore/ShardTest.java index ee112a40de..431a266b14 100644 --- a/opendaylight/md-sal/sal-distributed-datastore/src/test/java/org/opendaylight/controller/cluster/datastore/ShardTest.java +++ b/opendaylight/md-sal/sal-distributed-datastore/src/test/java/org/opendaylight/controller/cluster/datastore/ShardTest.java @@ -2,7 +2,9 @@ package org.opendaylight.controller.cluster.datastore; import akka.actor.ActorRef; import akka.actor.Props; +import akka.event.Logging; import akka.testkit.JavaTestKit; +import junit.framework.Assert; import org.junit.Test; import org.opendaylight.controller.cluster.datastore.messages.CreateTransaction; import org.opendaylight.controller.cluster.datastore.messages.CreateTransactionChain; @@ -38,19 +40,25 @@ public class ShardTest extends AbstractActorTest { getSystem().actorOf(props, "testCreateTransactionChain"); - // Wait for Shard to become a Leader - try { - Thread.sleep(1000); - } catch (InterruptedException e) { - e.printStackTrace(); - } + // Wait for a specific log message to show up + final boolean result = + new JavaTestKit.EventFilter(Logging.Info.class + ) { + protected Boolean run() { + return true; + } + }.from(subject.path().toString()) + .message("Switching from state Candidate to Leader") + .occurrences(1).exec(); + + Assert.assertEquals(true, result); new Within(duration("1 seconds")) { protected void run() { subject.tell(new CreateTransactionChain().toSerializable(), getRef()); - final String out = new ExpectMsg("match hint") { + final String out = new ExpectMsg(duration("1 seconds"), "match hint") { // do not put code outside this method, will run afterwards protected String match(Object in) { if (in.getClass().equals(CreateTransactionChainReply.SERIALIZABLE_CLASS)){ @@ -91,7 +99,7 @@ public class ShardTest extends AbstractActorTest { getRef()); subject.tell(new RegisterChangeListener(TestModel.TEST_PATH, - getRef().path(), AsyncDataBroker.DataChangeScope.BASE).toSerializable(), + getRef().path(), AsyncDataBroker.DataChangeScope.BASE), getRef()); final Boolean notificationEnabled = new ExpectMsg("enable notification") { @@ -107,12 +115,12 @@ public class ShardTest extends AbstractActorTest { assertFalse(notificationEnabled); - final String out = new ExpectMsg("match hint") { + final String out = new ExpectMsg(duration("1 seconds"), "match hint") { // do not put code outside this method, will run afterwards protected String match(Object in) { - if (in.getClass().equals(RegisterChangeListenerReply.SERIALIZABLE_CLASS)) { + if (in.getClass().equals(RegisterChangeListenerReply.class)) { RegisterChangeListenerReply reply = - RegisterChangeListenerReply.fromSerializable(getSystem(),in); + (RegisterChangeListenerReply) in; return reply.getListenerRegistrationPath() .toString(); } else { @@ -138,13 +146,18 @@ public class ShardTest extends AbstractActorTest { getSystem().actorOf(props, "testCreateTransaction"); - // Wait for Shard to become a Leader - try { - Thread.sleep(1000); - } catch (InterruptedException e) { - e.printStackTrace(); - } + // Wait for a specific log message to show up + final boolean result = + new JavaTestKit.EventFilter(Logging.Info.class + ) { + protected Boolean run() { + return true; + } + }.from(subject.path().toString()) + .message("Switching from state Candidate to Leader") + .occurrences(1).exec(); + Assert.assertEquals(true, result); new Within(duration("1 seconds")) { protected void run() { @@ -156,7 +169,7 @@ public class ShardTest extends AbstractActorTest { subject.tell(new CreateTransaction("txn-1", TransactionProxy.TransactionType.READ_ONLY.ordinal() ).toSerializable(), getRef()); - final String out = new ExpectMsg("match hint") { + final String out = new ExpectMsg(duration("1 seconds"), "match hint") { // do not put code outside this method, will run afterwards protected String match(Object in) { if (in instanceof CreateTransactionReply) { diff --git a/opendaylight/md-sal/sal-distributed-datastore/src/test/java/org/opendaylight/controller/cluster/datastore/ShardTransactionChainTest.java b/opendaylight/md-sal/sal-distributed-datastore/src/test/java/org/opendaylight/controller/cluster/datastore/ShardTransactionChainTest.java index 57d0bd6aa9..b35880a6a5 100644 --- a/opendaylight/md-sal/sal-distributed-datastore/src/test/java/org/opendaylight/controller/cluster/datastore/ShardTransactionChainTest.java +++ b/opendaylight/md-sal/sal-distributed-datastore/src/test/java/org/opendaylight/controller/cluster/datastore/ShardTransactionChainTest.java @@ -35,7 +35,7 @@ public class ShardTransactionChainTest extends AbstractActorTest { subject.tell(new CreateTransaction("txn-1", TransactionProxy.TransactionType.READ_ONLY.ordinal() ).toSerializable(), getRef()); - final String out = new ExpectMsg("match hint") { + final String out = new ExpectMsg(duration("1 seconds"), "match hint") { // do not put code outside this method, will run afterwards protected String match(Object in) { if (in.getClass().equals(CreateTransactionReply.SERIALIZABLE_CLASS)) { @@ -70,7 +70,7 @@ public class ShardTransactionChainTest extends AbstractActorTest { subject.tell(new CloseTransactionChain().toSerializable(), getRef()); - final String out = new ExpectMsg("match hint") { + final String out = new ExpectMsg(duration("1 seconds"), "match hint") { // do not put code outside this method, will run afterwards protected String match(Object in) { if (in.getClass().equals(CloseTransactionChainReply.SERIALIZABLE_CLASS)) { diff --git a/opendaylight/md-sal/sal-distributed-datastore/src/test/java/org/opendaylight/controller/cluster/datastore/ShardTransactionTest.java b/opendaylight/md-sal/sal-distributed-datastore/src/test/java/org/opendaylight/controller/cluster/datastore/ShardTransactionTest.java index f15e3bff06..632ecc29cd 100644 --- a/opendaylight/md-sal/sal-distributed-datastore/src/test/java/org/opendaylight/controller/cluster/datastore/ShardTransactionTest.java +++ b/opendaylight/md-sal/sal-distributed-datastore/src/test/java/org/opendaylight/controller/cluster/datastore/ShardTransactionTest.java @@ -65,7 +65,7 @@ public class ShardTransactionTest extends AbstractActorTest { new ReadData(YangInstanceIdentifier.builder().build()).toSerializable(), getRef()); - final String out = new ExpectMsg("match hint") { + final String out = new ExpectMsg(duration("1 seconds"), "match hint") { // do not put code outside this method, will run afterwards protected String match(Object in) { if (in.getClass().equals(ReadDataReply.SERIALIZABLE_CLASS)) { @@ -105,7 +105,7 @@ public class ShardTransactionTest extends AbstractActorTest { new ReadData(TestModel.TEST_PATH).toSerializable(), getRef()); - final String out = new ExpectMsg("match hint") { + final String out = new ExpectMsg(duration("1 seconds"), "match hint") { // do not put code outside this method, will run afterwards protected String match(Object in) { if (in.getClass().equals(ReadDataReply.SERIALIZABLE_CLASS)) { @@ -141,7 +141,7 @@ public class ShardTransactionTest extends AbstractActorTest { getRef()); final CompositeModification compositeModification = - new ExpectMsg("match hint") { + new ExpectMsg(duration("1 seconds"), "match hint") { // do not put code outside this method, will run afterwards protected CompositeModification match(Object in) { if (in instanceof ShardTransaction.GetCompositeModificationReply) { @@ -180,7 +180,7 @@ public class ShardTransactionTest extends AbstractActorTest { ImmutableNodes.containerNode(TestModel.TEST_QNAME), TestModel.createTestContext()).toSerializable(), getRef()); - final String out = new ExpectMsg("match hint") { + final String out = new ExpectMsg(duration("1 seconds"), "match hint") { // do not put code outside this method, will run afterwards protected String match(Object in) { if (in.getClass().equals(WriteDataReply.SERIALIZABLE_CLASS)) { @@ -255,7 +255,7 @@ public class ShardTransactionTest extends AbstractActorTest { subject.tell(new DeleteData(TestModel.TEST_PATH).toSerializable(), getRef()); - final String out = new ExpectMsg("match hint") { + final String out = new ExpectMsg(duration("1 seconds"), "match hint") { // do not put code outside this method, will run afterwards protected String match(Object in) { if (in.getClass().equals(DeleteDataReply.SERIALIZABLE_CLASS)) { @@ -292,7 +292,7 @@ public class ShardTransactionTest extends AbstractActorTest { subject.tell(new ReadyTransaction().toSerializable(), getRef()); - final String out = new ExpectMsg("match hint") { + final String out = new ExpectMsg(duration("1 seconds"), "match hint") { // do not put code outside this method, will run afterwards protected String match(Object in) { if (in.getClass().equals(ReadyTransactionReply.SERIALIZABLE_CLASS)) { @@ -330,7 +330,7 @@ public class ShardTransactionTest extends AbstractActorTest { subject.tell(new CloseTransaction().toSerializable(), getRef()); - final String out = new ExpectMsg("match hint") { + final String out = new ExpectMsg(duration("1 seconds"), "match hint") { // do not put code outside this method, will run afterwards protected String match(Object in) { if (in.getClass().equals(CloseTransactionReply.SERIALIZABLE_CLASS)) { @@ -343,7 +343,7 @@ public class ShardTransactionTest extends AbstractActorTest { assertEquals("match", out); - final String termination = new ExpectMsg("match hint") { + final String termination = new ExpectMsg(duration("1 seconds"), "match hint") { // do not put code outside this method, will run afterwards protected String match(Object in) { if (in instanceof Terminated) { diff --git a/opendaylight/md-sal/sal-distributed-datastore/src/test/java/org/opendaylight/controller/cluster/datastore/shardstrategy/ModuleShardStrategyTest.java b/opendaylight/md-sal/sal-distributed-datastore/src/test/java/org/opendaylight/controller/cluster/datastore/shardstrategy/ModuleShardStrategyTest.java index 88753e4b0a..3394cdc959 100644 --- a/opendaylight/md-sal/sal-distributed-datastore/src/test/java/org/opendaylight/controller/cluster/datastore/shardstrategy/ModuleShardStrategyTest.java +++ b/opendaylight/md-sal/sal-distributed-datastore/src/test/java/org/opendaylight/controller/cluster/datastore/shardstrategy/ModuleShardStrategyTest.java @@ -1,6 +1,5 @@ package org.opendaylight.controller.cluster.datastore.shardstrategy; -import junit.framework.Assert; import org.junit.BeforeClass; import org.junit.Rule; import org.junit.Test; @@ -8,6 +7,10 @@ import org.junit.rules.ExpectedException; import org.opendaylight.controller.cluster.datastore.Configuration; import org.opendaylight.controller.cluster.datastore.ConfigurationImpl; import org.opendaylight.controller.md.cluster.datastore.model.CarsModel; +import org.opendaylight.yangtools.yang.common.QName; +import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier; + +import static junit.framework.Assert.assertEquals; public class ModuleShardStrategyTest { @Rule @@ -28,6 +31,23 @@ public class ModuleShardStrategyTest { String shard = moduleShardStrategy.findShard(CarsModel.BASE_PATH); - Assert.assertEquals("cars-1", shard); + assertEquals("cars-1", shard); + } + + @Test + public void testFindShardWhenModuleConfigurationPresentInModulesButMissingInModuleShards() { + + final QName BASE_QNAME = QName.create("urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom:store:test:missing", "2014-03-13", + "missing"); + + final YangInstanceIdentifier BASE_PATH = YangInstanceIdentifier.of(BASE_QNAME); + + ModuleShardStrategy moduleShardStrategy = + new ModuleShardStrategy("missing", configuration); + + String shard = moduleShardStrategy.findShard(BASE_PATH); + + assertEquals(DefaultShardStrategy.DEFAULT_SHARD, shard); + } } diff --git a/opendaylight/md-sal/sal-distributed-datastore/src/test/resources/application.conf b/opendaylight/md-sal/sal-distributed-datastore/src/test/resources/application.conf index aebff27c7d..eda1c304e4 100644 --- a/opendaylight/md-sal/sal-distributed-datastore/src/test/resources/application.conf +++ b/opendaylight/md-sal/sal-distributed-datastore/src/test/resources/application.conf @@ -1,4 +1,5 @@ akka { + loggers = [akka.testkit.TestEventListener] actor { serializers { java = "akka.serialization.JavaSerializer" diff --git a/opendaylight/md-sal/sal-distributed-datastore/src/test/resources/modules.conf b/opendaylight/md-sal/sal-distributed-datastore/src/test/resources/modules.conf index 22854cb11a..f4919e7895 100644 --- a/opendaylight/md-sal/sal-distributed-datastore/src/test/resources/modules.conf +++ b/opendaylight/md-sal/sal-distributed-datastore/src/test/resources/modules.conf @@ -15,4 +15,10 @@ modules = [ shard-strategy = "module" } + { + name = "missing" + namespace = "urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom:store:missing" + shard-strategy = "module" + } + ] diff --git a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/broker/impl/mount/DOMMountPointServiceImpl.java b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/broker/impl/mount/DOMMountPointServiceImpl.java index 41650666cd..8944e197cc 100644 --- a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/broker/impl/mount/DOMMountPointServiceImpl.java +++ b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/broker/impl/mount/DOMMountPointServiceImpl.java @@ -21,7 +21,7 @@ import org.opendaylight.controller.md.sal.dom.broker.spi.mount.SimpleDOMMountPoi import org.opendaylight.controller.sal.core.api.mount.MountProvisionListener; import org.opendaylight.yangtools.concepts.ListenerRegistration; import org.opendaylight.yangtools.concepts.ObjectRegistration; -import org.opendaylight.yangtools.concepts.util.ListenerRegistry; +import org.opendaylight.yangtools.util.ListenerRegistry; import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier; import org.opendaylight.yangtools.yang.model.api.SchemaContext; diff --git a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/sal/dom/broker/BackwardsCompatibleMountPointManager.java b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/sal/dom/broker/BackwardsCompatibleMountPointManager.java index b01db3d515..fef2a808c3 100644 --- a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/sal/dom/broker/BackwardsCompatibleMountPointManager.java +++ b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/sal/dom/broker/BackwardsCompatibleMountPointManager.java @@ -18,7 +18,7 @@ import org.opendaylight.controller.sal.core.api.mount.MountProvisionInstance; import org.opendaylight.controller.sal.core.api.mount.MountProvisionListener; import org.opendaylight.controller.sal.core.api.mount.MountProvisionService; import org.opendaylight.yangtools.concepts.ListenerRegistration; -import org.opendaylight.yangtools.concepts.util.ListenerRegistry; +import org.opendaylight.yangtools.util.ListenerRegistry; import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier; public class BackwardsCompatibleMountPointManager implements MountProvisionService, MountProvisionListener { diff --git a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/sal/dom/broker/DataTransactionImpl.java b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/sal/dom/broker/DataTransactionImpl.java index f0dd5b921c..df4549f1f8 100644 --- a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/sal/dom/broker/DataTransactionImpl.java +++ b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/sal/dom/broker/DataTransactionImpl.java @@ -11,7 +11,7 @@ import org.opendaylight.controller.md.sal.common.api.TransactionStatus; import org.opendaylight.controller.md.sal.common.impl.service.AbstractDataTransaction; import org.opendaylight.controller.sal.core.api.data.DataModificationTransaction; import org.opendaylight.yangtools.concepts.ListenerRegistration; -import org.opendaylight.yangtools.concepts.util.ListenerRegistry; +import org.opendaylight.yangtools.util.ListenerRegistry; import org.opendaylight.yangtools.yang.data.api.CompositeNode; import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier; diff --git a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/sal/dom/broker/MountPointManagerImpl.java b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/sal/dom/broker/MountPointManagerImpl.java index d84f1dc031..434cf85bec 100644 --- a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/sal/dom/broker/MountPointManagerImpl.java +++ b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/sal/dom/broker/MountPointManagerImpl.java @@ -17,7 +17,7 @@ import org.opendaylight.controller.sal.core.api.mount.MountProvisionInstance; import org.opendaylight.controller.sal.core.api.mount.MountProvisionListener; import org.opendaylight.controller.sal.core.api.mount.MountProvisionService; import org.opendaylight.yangtools.concepts.ListenerRegistration; -import org.opendaylight.yangtools.concepts.util.ListenerRegistry; +import org.opendaylight.yangtools.util.ListenerRegistry; import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier; @Deprecated diff --git a/opendaylight/md-sal/sal-inmemory-datastore/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/ResolveDataChangeEventsTask.java b/opendaylight/md-sal/sal-inmemory-datastore/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/ResolveDataChangeEventsTask.java index ff64cd64c4..3ddf0b60fa 100644 --- a/opendaylight/md-sal/sal-inmemory-datastore/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/ResolveDataChangeEventsTask.java +++ b/opendaylight/md-sal/sal-inmemory-datastore/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/ResolveDataChangeEventsTask.java @@ -9,9 +9,15 @@ package org.opendaylight.controller.md.sal.dom.store.impl; import static org.opendaylight.controller.md.sal.dom.store.impl.DOMImmutableDataChangeEvent.builder; +import com.google.common.base.Optional; +import com.google.common.base.Preconditions; +import com.google.common.collect.HashMultimap; +import com.google.common.collect.ImmutableList; +import com.google.common.collect.Iterables; +import com.google.common.collect.Multimap; + import java.util.Collection; import java.util.Collections; -import java.util.HashSet; import java.util.LinkedList; import java.util.List; import java.util.Map.Entry; @@ -37,13 +43,6 @@ import org.opendaylight.yangtools.yang.data.api.schema.tree.ModificationType; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import com.google.common.base.Optional; -import com.google.common.base.Preconditions; -import com.google.common.collect.HashMultimap; -import com.google.common.collect.ImmutableList; -import com.google.common.collect.Iterables; -import com.google.common.collect.Multimap; - /** * Resolve Data Change Events based on modifications and listeners * @@ -278,6 +277,11 @@ final class ResolveDataChangeEventsTask implements Callable listeners, final NormalizedNode beforeData, final NormalizedNode afterData) { + // FIXME: BUG-1493: check the listeners to prune unneeded changes: + // for subtrees, we have to do all + // for one, we need to expand children + // for base, we just report replacement + if (beforeData instanceof NormalizedNodeContainer) { // Node is container (contains child) and we have interested // listeners registered for it, that means we need to do @@ -306,14 +310,12 @@ final class ResolveDataChangeEventsTask implements Callable listeners, final NormalizedNodeContainer> beforeCont, final NormalizedNodeContainer> afterCont) { - final Set alreadyProcessed = new HashSet<>(); final List childChanges = new LinkedList<>(); - DataChangeScope potentialScope = DataChangeScope.BASE; // We look at all children from before and compare it with after state. for (NormalizedNode beforeChild : beforeCont.getValue()) { - PathArgument childId = beforeChild.getIdentifier(); - alreadyProcessed.add(childId); + final PathArgument childId = beforeChild.getIdentifier(); + YangInstanceIdentifier childPath = path.node(childId); Collection childListeners = getListenerChildrenWildcarded(listeners, childId); Optional> afterChild = afterCont.getChild(childId); @@ -323,15 +325,17 @@ final class ResolveDataChangeEventsTask implements Callable afterChild : afterCont.getValue()) { - PathArgument childId = afterChild.getIdentifier(); - if (!alreadyProcessed.contains(childId)) { - // We did not processed that child already - // and it was not present in previous loop, that means it is - // created. + final PathArgument childId = afterChild.getIdentifier(); + + /* + * We have already iterated of the before-children, so have already + * emitted modify/delete events. This means the child has been + * created. + */ + if (!beforeCont.getChild(childId).isPresent()) { Collection childListeners = getListenerChildrenWildcarded(listeners, childId); YangInstanceIdentifier childPath = path.node(childId); childChanges.add(resolveSameEventRecursivelly(childPath , childListeners, afterChild, @@ -342,7 +346,7 @@ final class ResolveDataChangeEventsTask implements Callable messageTransformer; private final SchemaContextProviderFactory schemaContextProviderFactory; private final SchemaSourceProviderFactory sourceProviderFactory; + private final NetconfStateSchemas.NetconfStateSchemasResolver stateSchemasResolver; private final NotificationHandler notificationHandler; public static NetconfDevice createNetconfDevice(final RemoteDeviceId id, final AbstractCachingSchemaSourceProvider schemaSourceProvider, final ExecutorService executor, final RemoteDeviceHandler salFacade) { + return createNetconfDevice(id, schemaSourceProvider, executor, salFacade, new NetconfStateSchemas.NetconfStateSchemasResolverImpl()); + } + + @VisibleForTesting + protected static NetconfDevice createNetconfDevice(final RemoteDeviceId id, + final AbstractCachingSchemaSourceProvider schemaSourceProvider, + final ExecutorService executor, final RemoteDeviceHandler salFacade, + final NetconfStateSchemas.NetconfStateSchemasResolver stateSchemasResolver) { return new NetconfDevice(id, salFacade, executor, new NetconfMessageTransformer(), new NetconfDeviceSchemaProviderFactory(id), new SchemaSourceProviderFactory() { @@ -67,18 +78,20 @@ public final class NetconfDevice implements RemoteDevice salFacade, - final ExecutorService processingExecutor, final MessageTransformer messageTransformer, - final SchemaContextProviderFactory schemaContextProviderFactory, - final SchemaSourceProviderFactory sourceProviderFactory) { + final ExecutorService processingExecutor, final MessageTransformer messageTransformer, + final SchemaContextProviderFactory schemaContextProviderFactory, + final SchemaSourceProviderFactory sourceProviderFactory, + final NetconfStateSchemas.NetconfStateSchemasResolver stateSchemasResolver) { this.id = id; this.messageTransformer = messageTransformer; this.salFacade = salFacade; this.sourceProviderFactory = sourceProviderFactory; + this.stateSchemasResolver = stateSchemasResolver; this.processingExecutor = MoreExecutors.listeningDecorator(processingExecutor); this.schemaContextProviderFactory = schemaContextProviderFactory; this.notificationHandler = new NotificationHandler(salFacade, messageTransformer, id); @@ -98,6 +111,11 @@ public final class NetconfDevice implements RemoteDevice delegate = sourceProviderFactory.createSourceProvider(deviceRpc); final SchemaContextProvider schemaContextProvider = setUpSchemaContext(delegate, remoteSessionCapabilities); updateMessageTransformer(schemaContextProvider); @@ -204,6 +222,6 @@ public final class NetconfDevice implements RemoteDeviceemptySet()); + + private static final YangInstanceIdentifier STATE_SCHEMAS_IDENTIFIER = + YangInstanceIdentifier.builder().node(NetconfState.QNAME).node(Schemas.QNAME).build(); + private static final YangInstanceIdentifier DATA_STATE_SCHEMAS_IDENTIFIER = + YangInstanceIdentifier.builder().node(NetconfMessageTransformUtil.NETCONF_DATA_QNAME) + .node(NetconfState.QNAME).node(Schemas.QNAME).build(); + + private static final CompositeNode GET_SCHEMAS_RPC; + static { + final Node filter = NetconfMessageTransformUtil.toFilterStructure(STATE_SCHEMAS_IDENTIFIER); + GET_SCHEMAS_RPC + = NodeFactory.createImmutableCompositeNode(NetconfMessageTransformUtil.NETCONF_GET_QNAME, null, Lists.>newArrayList(filter)); + } + + private final Set availableYangSchemas; + + public NetconfStateSchemas(final Set availableYangSchemas) { + this.availableYangSchemas = availableYangSchemas; + } + + public Set getAvailableYangSchemas() { + return availableYangSchemas; + } + + public Set getAvailableYangSchemasQNames() { + return Sets.newHashSet(Collections2.transform(getAvailableYangSchemas(), new Function() { + @Override + public QName apply(final RemoteYangSchema input) { + return input.getQName(); + } + })); + } + + /** + * Issue get request to remote device and parse response to find all schemas under netconf-state/schemas + */ + private static NetconfStateSchemas create(final NetconfDeviceRpc deviceRpc, final NetconfSessionCapabilities remoteSessionCapabilities, final RemoteDeviceId id) { + if(remoteSessionCapabilities.isMonitoringSupported() == false) { + logger.warn("{}: Netconf monitoring not supported on device, cannot detect available schemas"); + return EMPTY; + } + + final RpcResult schemasNodeResult; + try { + schemasNodeResult = deviceRpc.invokeRpc(NetconfMessageTransformUtil.NETCONF_GET_QNAME, GET_SCHEMAS_RPC).get(); + } catch (final InterruptedException e) { + Thread.currentThread().interrupt(); + throw new RuntimeException(id + ": Interrupted while waiting for response to " + STATE_SCHEMAS_IDENTIFIER, e); + } catch (final ExecutionException e) { + logger.warn("{}: Unable to detect available schemas, get to {} failed", id, STATE_SCHEMAS_IDENTIFIER, e); + return EMPTY; + } + + if(schemasNodeResult.isSuccessful() == false) { + logger.warn("{}: Unable to detect available schemas, get to {} failed, {}", id, STATE_SCHEMAS_IDENTIFIER, schemasNodeResult.getErrors()); + return EMPTY; + } + + final CompositeNode schemasNode = + (CompositeNode) NetconfMessageTransformUtil.findNode(schemasNodeResult.getResult(), DATA_STATE_SCHEMAS_IDENTIFIER); + return create(schemasNode); + } + + /** + * Parse response of get(netconf-state/schemas) to find all schemas under netconf-state/schemas + */ + @VisibleForTesting + protected static NetconfStateSchemas create(final CompositeNode schemasNode) { + final Set availableYangSchemas = Sets.newHashSet(); + + for (final CompositeNode schemaNode : schemasNode.getCompositesByName(Schema.QNAME.withoutRevision())) { + availableYangSchemas.add(RemoteYangSchema.createFromCompositeNode(schemaNode)); + } + + return new NetconfStateSchemas(availableYangSchemas); + } + + public final static class RemoteYangSchema { + private final QName qname; + + private RemoteYangSchema(final QName qname) { + this.qname = qname; + } + + public QName getQName() { + return qname; + } + + static RemoteYangSchema createFromCompositeNode(final CompositeNode schemaNode) { + Preconditions.checkArgument(schemaNode.getKey().equals(Schema.QNAME.withoutRevision()), "Wrong QName %s", schemaNode.getKey()); + + QName childNode = NetconfMessageTransformUtil.IETF_NETCONF_MONITORING_SCHEMA_FORMAT.withoutRevision(); + + final String formatAsString = getSingleChildNodeValue(schemaNode, childNode).get(); + Preconditions.checkArgument(formatAsString.equals(Yang.QNAME.getLocalName()), + "Expecting format to be only %s, not %s", Yang.QNAME.getLocalName(), formatAsString); + + childNode = NetconfMessageTransformUtil.IETF_NETCONF_MONITORING_SCHEMA_LOCATION.withoutRevision(); + final Set locationsAsString = getAllChildNodeValues(schemaNode, childNode); + Preconditions.checkArgument(locationsAsString.contains(Schema.Location.Enumeration.NETCONF.toString()), + "Expecting location to be %s, not %s", Schema.Location.Enumeration.NETCONF.toString(), locationsAsString); + + childNode = NetconfMessageTransformUtil.IETF_NETCONF_MONITORING_SCHEMA_NAMESPACE.withoutRevision(); + final String namespaceAsString = getSingleChildNodeValue(schemaNode, childNode).get(); + + childNode = NetconfMessageTransformUtil.IETF_NETCONF_MONITORING_SCHEMA_VERSION.withoutRevision(); + // Revision does not have to be filled + final Optional revisionAsString = getSingleChildNodeValue(schemaNode, childNode); + + childNode = NetconfMessageTransformUtil.IETF_NETCONF_MONITORING_SCHEMA_IDENTIFIER.withoutRevision(); + final String moduleNameAsString = getSingleChildNodeValue(schemaNode, childNode).get(); + + final QName moduleQName = revisionAsString.isPresent() + ? QName.create(namespaceAsString, revisionAsString.get(), moduleNameAsString) + : QName.create(URI.create(namespaceAsString), null, moduleNameAsString).withoutRevision(); + + return new RemoteYangSchema(moduleQName); + } + + private static Set getAllChildNodeValues(final CompositeNode schemaNode, final QName childNodeQName) { + final Set extractedValues = Sets.newHashSet(); + for (final SimpleNode childNode : schemaNode.getSimpleNodesByName(childNodeQName)) { + extractedValues.add(getValueOfSimpleNode(childNodeQName, childNode).get()); + } + return extractedValues; + } + + private static Optional getSingleChildNodeValue(final CompositeNode schemaNode, final QName childNode) { + final SimpleNode node = schemaNode.getFirstSimpleByName(childNode); + return getValueOfSimpleNode(childNode, node); + } + + private static Optional getValueOfSimpleNode(final QName childNode, final SimpleNode node) { + Preconditions.checkNotNull(node, "Child node %s not present", childNode); + final Object value = node.getValue(); + return value == null ? Optional.absent() : Optional.of(value.toString().trim()); + } + + @Override + public boolean equals(final Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + final RemoteYangSchema that = (RemoteYangSchema) o; + + if (!qname.equals(that.qname)) return false; + + return true; + } + + @Override + public int hashCode() { + return qname.hashCode(); + } + } +} diff --git a/opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/listener/NetconfDeviceCommunicator.java b/opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/listener/NetconfDeviceCommunicator.java index 3871cdfa4f..2f24adcdbe 100644 --- a/opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/listener/NetconfDeviceCommunicator.java +++ b/opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/listener/NetconfDeviceCommunicator.java @@ -229,7 +229,7 @@ public class NetconfDeviceCommunicator implements NetconfClientSessionListener, try { NetconfMessageTransformUtil.checkSuccessReply(message); } - catch( NetconfDocumentedException e ) { + catch(final NetconfDocumentedException e) { logger.warn( "{}: Error reply from remote device, request: {}, response: {}", id, msgToS( request.request ), msgToS( message ), e ); diff --git a/opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/sal/tx/NetconfDeviceReadOnlyTx.java b/opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/sal/tx/NetconfDeviceReadOnlyTx.java index 533df9cce7..04a99511a1 100644 --- a/opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/sal/tx/NetconfDeviceReadOnlyTx.java +++ b/opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/sal/tx/NetconfDeviceReadOnlyTx.java @@ -30,8 +30,6 @@ import org.opendaylight.controller.sal.core.api.RpcImplementation; import org.opendaylight.yangtools.util.concurrent.MappingCheckedFuture; import org.opendaylight.yangtools.yang.common.RpcResult; 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.data.api.YangInstanceIdentifier; import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode; import org.slf4j.Logger; @@ -63,7 +61,7 @@ public final class NetconfDeviceReadOnlyTx implements DOMDataReadOnlyTransaction checkReadSuccess(result, path); final CompositeNode data = result.getResult().getFirstCompositeByName(NETCONF_DATA_QNAME); - final CompositeNode node = (CompositeNode) findNode(data, path); + final CompositeNode node = (CompositeNode) NetconfMessageTransformUtil.findNode(data, path); return data == null ? Optional.>absent() : @@ -105,7 +103,7 @@ public final class NetconfDeviceReadOnlyTx implements DOMDataReadOnlyTransaction checkReadSuccess(result, path); final CompositeNode data = result.getResult().getFirstCompositeByName(NETCONF_DATA_QNAME); - final CompositeNode node = (CompositeNode) findNode(data, path); + final CompositeNode node = (CompositeNode) NetconfMessageTransformUtil.findNode(data, path); return data == null ? Optional.>absent() : @@ -116,33 +114,6 @@ public final class NetconfDeviceReadOnlyTx implements DOMDataReadOnlyTransaction return MappingCheckedFuture.create(transformedFuture, ReadFailedException.MAPPER); } - private static Node findNode(final CompositeNode node, final YangInstanceIdentifier identifier) { - - Node current = node; - for (final YangInstanceIdentifier.PathArgument arg : identifier.getPathArguments()) { - if (current instanceof SimpleNode) { - return null; - } else if (current instanceof CompositeNode) { - final CompositeNode currentComposite = (CompositeNode) current; - - current = currentComposite.getFirstCompositeByName(arg.getNodeType()); - if (current == null) { - current = currentComposite.getFirstCompositeByName(arg.getNodeType().withoutRevision()); - } - if (current == null) { - current = currentComposite.getFirstSimpleByName(arg.getNodeType()); - } - if (current == null) { - current = currentComposite.getFirstSimpleByName(arg.getNodeType().withoutRevision()); - } - if (current == null) { - return null; - } - } - } - return current; - } - @Override public void close() { // NOOP diff --git a/opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/schema/mapping/NetconfMessageTransformer.java b/opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/schema/mapping/NetconfMessageTransformer.java index 47ef9039d1..5e61dfb028 100644 --- a/opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/schema/mapping/NetconfMessageTransformer.java +++ b/opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/schema/mapping/NetconfMessageTransformer.java @@ -96,7 +96,7 @@ public class NetconfMessageTransformer implements MessageTransformer findNode(final CompositeNode node, final YangInstanceIdentifier identifier) { + + Node current = node; + for (final YangInstanceIdentifier.PathArgument arg : identifier.getPathArguments()) { + if (current instanceof SimpleNode) { + return null; + } else if (current instanceof CompositeNode) { + final CompositeNode currentComposite = (CompositeNode) current; + + current = currentComposite.getFirstCompositeByName(arg.getNodeType()); + if (current == null) { + current = currentComposite.getFirstCompositeByName(arg.getNodeType().withoutRevision()); + } + if (current == null) { + current = currentComposite.getFirstSimpleByName(arg.getNodeType()); + } + if (current == null) { + current = currentComposite.getFirstSimpleByName(arg.getNodeType().withoutRevision()); + } + if (current == null) { + return null; + } + } + } + return current; + } } diff --git a/opendaylight/md-sal/sal-netconf-connector/src/test/java/org/opendaylight/controller/sal/connect/netconf/NetconfDeviceTest.java b/opendaylight/md-sal/sal-netconf-connector/src/test/java/org/opendaylight/controller/sal/connect/netconf/NetconfDeviceTest.java index 46ea4ff73c..fa488dadd3 100644 --- a/opendaylight/md-sal/sal-netconf-connector/src/test/java/org/opendaylight/controller/sal/connect/netconf/NetconfDeviceTest.java +++ b/opendaylight/md-sal/sal-netconf-connector/src/test/java/org/opendaylight/controller/sal/connect/netconf/NetconfDeviceTest.java @@ -15,6 +15,9 @@ import static org.mockito.Mockito.timeout; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; +import com.google.common.base.Optional; +import com.google.common.collect.Lists; +import com.google.common.util.concurrent.Futures; import java.io.InputStream; import java.util.ArrayList; import java.util.Collection; @@ -23,7 +26,6 @@ import java.util.List; import java.util.Set; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; - import org.junit.Test; import org.mockito.Mockito; import org.opendaylight.controller.netconf.api.NetconfMessage; @@ -34,6 +36,7 @@ import org.opendaylight.controller.sal.connect.api.RemoteDeviceHandler; import org.opendaylight.controller.sal.connect.api.SchemaContextProviderFactory; import org.opendaylight.controller.sal.connect.api.SchemaSourceProviderFactory; import org.opendaylight.controller.sal.connect.netconf.listener.NetconfSessionCapabilities; +import org.opendaylight.controller.sal.connect.netconf.sal.NetconfDeviceRpc; import org.opendaylight.controller.sal.connect.netconf.util.NetconfMessageTransformUtil; import org.opendaylight.controller.sal.connect.util.RemoteDeviceId; import org.opendaylight.controller.sal.core.api.RpcImplementation; @@ -47,10 +50,6 @@ import org.opendaylight.yangtools.yang.model.api.SchemaContextProvider; import org.opendaylight.yangtools.yang.model.util.repo.SchemaSourceProvider; import org.opendaylight.yangtools.yang.parser.impl.YangParserImpl; -import com.google.common.base.Optional; -import com.google.common.collect.Lists; -import com.google.common.util.concurrent.Futures; - public class NetconfDeviceTest { private static final NetconfMessage netconfMessage; @@ -71,13 +70,20 @@ public class NetconfDeviceTest { public static final String TEST_NAMESPACE = "test:namespace"; public static final String TEST_MODULE = "test-module"; public static final String TEST_REVISION = "2013-07-22"; + private NetconfStateSchemas.NetconfStateSchemasResolver stateSchemasResolver = new NetconfStateSchemas.NetconfStateSchemasResolver() { + + @Override + public NetconfStateSchemas resolve(final NetconfDeviceRpc deviceRpc, final NetconfSessionCapabilities remoteSessionCapabilities, final RemoteDeviceId id) { + return NetconfStateSchemas.EMPTY; + } + }; @Test public void testNetconfDeviceWithoutMonitoring() throws Exception { final RemoteDeviceHandler facade = getFacade(); final RemoteDeviceCommunicator listener = getListener(); - final NetconfDevice device = new NetconfDevice(getId(), facade, getExecutor(), getMessageTransformer(), getSchemaContextProviderFactory(), getSourceProviderFactory()); + final NetconfDevice device = new NetconfDevice(getId(), facade, getExecutor(), getMessageTransformer(), getSchemaContextProviderFactory(), getSourceProviderFactory(), stateSchemasResolver); device.onRemoteSessionUp(getSessionCaps(false, Collections.emptyList()), listener); Mockito.verify(facade, Mockito.timeout(5000)).onDeviceDisconnected(); @@ -89,7 +95,7 @@ public class NetconfDeviceTest { final RemoteDeviceCommunicator listener = getListener(); final MessageTransformer messageTransformer = getMessageTransformer(); - final NetconfDevice device = new NetconfDevice(getId(), facade, getExecutor(), messageTransformer, getSchemaContextProviderFactory(), getSourceProviderFactory()); + final NetconfDevice device = new NetconfDevice(getId(), facade, getExecutor(), messageTransformer, getSchemaContextProviderFactory(), getSourceProviderFactory(), stateSchemasResolver); device.onNotification(netconfMessage); device.onNotification(netconfMessage); @@ -118,7 +124,7 @@ public class NetconfDeviceTest { final SchemaSourceProviderFactory sourceProviderFactory = getSourceProviderFactory(); final MessageTransformer messageTransformer = getMessageTransformer(); - final NetconfDevice device = new NetconfDevice(getId(), facade, getExecutor(), messageTransformer, schemaContextProviderFactory, sourceProviderFactory); + final NetconfDevice device = new NetconfDevice(getId(), facade, getExecutor(), messageTransformer, schemaContextProviderFactory, sourceProviderFactory, stateSchemasResolver); final NetconfSessionCapabilities sessionCaps = getSessionCaps(true, Lists.newArrayList(TEST_NAMESPACE + "?module=" + TEST_MODULE + "&revision=" + TEST_REVISION)); device.onRemoteSessionUp(sessionCaps, listener); diff --git a/opendaylight/md-sal/sal-netconf-connector/src/test/java/org/opendaylight/controller/sal/connect/netconf/NetconfStateSchemasTest.java b/opendaylight/md-sal/sal-netconf-connector/src/test/java/org/opendaylight/controller/sal/connect/netconf/NetconfStateSchemasTest.java new file mode 100644 index 0000000000..16a915e730 --- /dev/null +++ b/opendaylight/md-sal/sal-netconf-connector/src/test/java/org/opendaylight/controller/sal/connect/netconf/NetconfStateSchemasTest.java @@ -0,0 +1,29 @@ +package org.opendaylight.controller.sal.connect.netconf; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertThat; +import static org.junit.matchers.JUnitMatchers.hasItem; + +import java.util.Set; +import org.junit.Test; +import org.opendaylight.controller.netconf.util.xml.XmlUtil; +import org.opendaylight.yangtools.yang.common.QName; +import org.opendaylight.yangtools.yang.data.api.CompositeNode; +import org.opendaylight.yangtools.yang.data.impl.codec.xml.XmlDocumentUtils; +import org.w3c.dom.Document; + +public class NetconfStateSchemasTest { + + @Test + public void testCreate() throws Exception { + final Document schemasXml = XmlUtil.readXmlToDocument(getClass().getResourceAsStream("/netconf-state.schemas.payload.xml")); + final CompositeNode compositeNodeSchemas = (CompositeNode) XmlDocumentUtils.toDomNode(schemasXml); + final NetconfStateSchemas schemas = NetconfStateSchemas.create(compositeNodeSchemas); + + final Set availableYangSchemasQNames = schemas.getAvailableYangSchemasQNames(); + assertEquals(73, availableYangSchemasQNames.size()); + + assertThat(availableYangSchemasQNames, + hasItem(QName.create("urn:TBD:params:xml:ns:yang:network-topology", "2013-07-12", "network-topology"))); + } +} diff --git a/opendaylight/md-sal/sal-netconf-connector/src/test/resources/netconf-state.schemas.payload.xml b/opendaylight/md-sal/sal-netconf-connector/src/test/resources/netconf-state.schemas.payload.xml new file mode 100644 index 0000000000..649ecb76a4 --- /dev/null +++ b/opendaylight/md-sal/sal-netconf-connector/src/test/resources/netconf-state.schemas.payload.xml @@ -0,0 +1,514 @@ + + + urn:opendaylight:params:xml:ns:yang:controller:threadpool + NETCONF + threadpool + yang + 2013-04-09 + + + urn:opendaylight:params:xml:ns:yang:controller:logback:config + NETCONF + config-logging + yang + 2013-07-16 + + + urn:opendaylight:model:statistics:types + NETCONF + opendaylight-statistics-types + yang + 2013-09-25 + + + urn:opendaylight:params:xml:ns:yang:controller:md:sal:core:spi:config-dom-store + NETCONF + opendaylight-config-dom-datastore + yang + 2014-06-17 + + + urn:opendaylight:flow:table:statistics + NETCONF + opendaylight-flow-table-statistics + yang + 2013-12-15 + + + urn:opendaylight:meter:service + NETCONF + sal-meter + yang + 2013-09-18 + + + urn:opendaylight:params:xml:ns:yang:controller:config:toaster-provider:impl + NETCONF + toaster-provider-impl + yang + 2014-01-31 + + + urn:opendaylight:table:types + NETCONF + opendaylight-table-types + yang + 2013-10-26 + + + urn:opendaylight:table:service + NETCONF + sal-table + yang + 2013-10-26 + + + urn:opendaylight:params:xml:ns:yang:controller:shutdown + NETCONF + shutdown + yang + 2013-12-18 + + + urn:opendaylight:port:service + NETCONF + sal-port + yang + 2013-11-07 + + + urn:opendaylight:params:xml:ns:yang:controller:netty:eventexecutor + NETCONF + netty-event-executor + yang + 2013-11-12 + + + urn:opendaylight:params:xml:ns:yang:controller:md:sal:remote + NETCONF + sal-remote + yang + 2014-01-14 + + + urn:opendaylight:model:topology:view + NETCONF + opendaylight-topology-view + yang + 2013-10-30 + + + urn:opendaylight:params:xml:ns:yang:controller:netty:threadgroup + NETCONF + threadgroup + yang + 2013-11-07 + + + urn:TBD:params:xml:ns:yang:network-topology + NETCONF + network-topology + yang + 2013-07-12 + + + urn:opendaylight:params:xml:ns:yang:controller:threadpool:impl:fixed + NETCONF + threadpool-impl-fixed + yang + 2013-12-01 + + + urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding:impl + NETCONF + opendaylight-sal-binding-broker-impl + yang + 2013-10-28 + + + urn:ietf:params:xml:ns:yang:ietf-restconf + NETCONF + ietf-restconf + yang + 2013-10-19 + + + urn:opendaylight:node:error:service + NETCONF + node-error + yang + 2014-04-10 + + + urn:opendaylight:flow:errors + NETCONF + flow-errors + yang + 2013-11-16 + + + urn:opendaylight:flow:service + NETCONF + sal-flow + yang + 2013-08-19 + + + urn:ietf:params:xml:ns:yang:rpc-context + NETCONF + rpc-context + yang + 2013-06-17 + + + urn:opendaylight:params:xml:ns:yang:controller:md:sal:core:spi:operational-dom-store + + NETCONF + opendaylight-operational-dom-datastore + yang + 2014-06-17 + + + urn:opendaylight:flow:types:queue + NETCONF + opendaylight-queue-types + yang + 2013-09-25 + + + urn:ietf:params:xml:ns:yang:ietf-netconf-monitoring + NETCONF + ietf-netconf-monitoring + yang + 2010-10-04 + + + urn:opendaylight:netconf-node-inventory + NETCONF + netconf-node-inventory + yang + 2014-01-08 + + + urn:ietf:params:xml:ns:yang:ietf-yang-types + NETCONF + ietf-yang-types + yang + 2013-07-15 + + + urn:opendaylight:meter:statistics + NETCONF + opendaylight-meter-statistics + yang + 2013-11-11 + + + urn:opendaylight:flow:inventory + NETCONF + flow-node-inventory + yang + 2013-08-19 + + + urn:opendaylight:params:xml:ns:yang:controller:md:sal:connector:netconf + NETCONF + odl-sal-netconf-connector-cfg + yang + 2013-10-28 + + + urn:opendaylight:params:xml:ns:yang:controller:threadpool:impl:scheduled + NETCONF + threadpool-impl-scheduled + yang + 2013-12-01 + + + urn:TBD:params:xml:ns:yang:network-topology + NETCONF + network-topology + yang + 2013-10-21 + + + http://netconfcentral.org/ns/toaster + NETCONF + toaster + yang + 2009-11-20 + + + urn:opendaylight:params:xml:ns:yang:controller:config:netconf + NETCONF + odl-netconf-cfg + yang + 2014-04-08 + + + urn:opendaylight:meter:types + NETCONF + opendaylight-meter-types + yang + 2013-09-18 + + + urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom:impl + NETCONF + opendaylight-sal-dom-broker-impl + yang + 2013-10-28 + + + urn:opendaylight:flow:topology:discovery + NETCONF + flow-topology-discovery + yang + 2013-08-19 + + + urn:opendaylight:yang:extension:yang-ext + NETCONF + yang-ext + yang + 2013-07-09 + + + urn:opendaylight:params:xml:ns:yang:controller:threadpool:impl + NETCONF + threadpool-impl + yang + 2013-04-05 + + + urn:opendaylight:flow:types:port + NETCONF + opendaylight-port-types + yang + 2013-09-25 + + + urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding + NETCONF + opendaylight-md-sal-binding + yang + 2013-10-28 + + + urn:opendaylight:packet:service + NETCONF + packet-processing + yang + 2013-07-09 + + + urn:opendaylight:params:xml:ns:yang:controller:threadpool:impl:flexible + NETCONF + threadpool-impl-flexible + yang + 2013-12-01 + + + urn:opendaylight:queue:service + NETCONF + sal-queue + yang + 2013-11-07 + + + urn:ietf:params:xml:ns:yang:ietf-inet-types + NETCONF + ietf-inet-types + yang + 2010-09-24 + + + urn:opendaylight:params:xml:ns:yang:controller:md:sal:rest:connector + NETCONF + opendaylight-rest-connector + yang + 2014-07-24 + + + urn:opendaylight:flow:transaction + NETCONF + flow-capable-transaction + yang + 2013-11-03 + + + urn:opendaylight:flow:statistics + NETCONF + opendaylight-flow-statistics + yang + 2013-08-19 + + + urn:opendaylight:params:xml:ns:yang:controller:protocol:framework + NETCONF + protocol-framework + yang + 2014-03-13 + + + urn:opendaylight:model:match:types + NETCONF + opendaylight-match-types + yang + 2013-10-26 + + + urn:ietf:params:xml:ns:yang:ietf-yang-types + NETCONF + ietf-yang-types + yang + 2010-09-24 + + + urn:opendaylight:group:service + NETCONF + sal-group + yang + 2013-09-18 + + + urn:opendaylight:params:xml:ns:yang:controller:inmemory-datastore-provider + NETCONF + opendaylight-inmemory-datastore-provider + yang + 2014-06-17 + + + urn:opendaylight:params:xml:ns:yang:controller:netty:timer + NETCONF + netty-timer + yang + 2013-11-19 + + + urn:opendaylight:group:statistics + NETCONF + opendaylight-group-statistics + yang + 2013-11-11 + + + urn:opendaylight:params:xml:ns:yang:controller:config + NETCONF + config + yang + 2013-04-05 + + + urn:opendaylight:params:xml:ns:yang:controller:config:netconf:client:dispatcher + NETCONF + odl-netconfig-client-cfg + yang + 2014-04-08 + + + urn:opendaylight:l2:types + NETCONF + opendaylight-l2-types + yang + 2013-08-27 + + + urn:opendaylight:action:types + NETCONF + opendaylight-action-types + yang + 2013-11-12 + + + urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom + NETCONF + opendaylight-md-sal-dom + yang + 2013-10-28 + + + urn:opendaylight:params:xml:ns:yang:controller:md:sal:common + NETCONF + opendaylight-md-sal-common + yang + 2013-10-28 + + + urn:opendaylight:group:types + NETCONF + opendaylight-group-types + yang + 2013-10-18 + + + urn:ietf:params:xml:ns:yang:ietf-netconf-monitoring-extension + NETCONF + ietf-netconf-monitoring-extension + yang + 2013-12-10 + + + urn:opendaylight:inventory + NETCONF + opendaylight-inventory + yang + 2013-08-19 + + + urn:opendaylight:params:xml:ns:yang:controller:netty + NETCONF + netty + yang + 2013-11-19 + + + urn:opendaylight:model:topology:general + NETCONF + opendaylight-topology + yang + 2013-10-30 + + + urn:opendaylight:port:statistics + NETCONF + opendaylight-port-statistics + yang + + + + urn:opendaylight:queue:statistics + NETCONF + opendaylight-queue-statistics + yang + 2013-12-16 + + + urn:opendaylight:params:xml:ns:yang:controller:config:kitchen-service:impl + NETCONF + kitchen-service-impl + yang + 2014-01-31 + + + urn:opendaylight:flow:types + NETCONF + opendaylight-flow-types + yang + 2013-10-26 + + + urn:opendaylight:params:xml:ns:yang:controller:shutdown:impl + NETCONF + shutdown-impl + yang + 2013-12-18 + + + urn:opendaylight:model:topology:inventory + NETCONF + opendaylight-topology-inventory + yang + 2013-10-30 + + \ No newline at end of file diff --git a/opendaylight/md-sal/sal-remoterpc-connector/src/main/java/org/opendaylight/controller/remote/rpc/ActorSystemFactory.java b/opendaylight/md-sal/sal-remoterpc-connector/src/main/java/org/opendaylight/controller/remote/rpc/ActorSystemFactory.java index bd49b6239c..f1ca3ccd50 100644 --- a/opendaylight/md-sal/sal-remoterpc-connector/src/main/java/org/opendaylight/controller/remote/rpc/ActorSystemFactory.java +++ b/opendaylight/md-sal/sal-remoterpc-connector/src/main/java/org/opendaylight/controller/remote/rpc/ActorSystemFactory.java @@ -27,7 +27,6 @@ public class ActorSystemFactory { * @param bundleContext */ public static final void createInstance(final BundleContext bundleContext) { - if(actorSystem == null) { // Create an OSGi bundle classloader for actor system BundleDelegatingClassLoader classLoader = new BundleDelegatingClassLoader(bundleContext.getBundle(), @@ -35,8 +34,8 @@ public class ActorSystemFactory { synchronized (ActorSystemFactory.class) { // Double check if (actorSystem == null) { - ActorSystem system = ActorSystem.create("opendaylight-rpc", - ConfigFactory.load().getConfig("odl-cluster"), classLoader); + ActorSystem system = ActorSystem.create("opendaylight-cluster-rpc", + ConfigFactory.load().getConfig("odl-cluster-rpc"), classLoader); actorSystem = system; } } diff --git a/opendaylight/md-sal/sal-remoterpc-connector/src/main/resources/application.conf b/opendaylight/md-sal/sal-remoterpc-connector/src/main/resources/application.conf index 6088dd0e0e..daac89c4c8 100644 --- a/opendaylight/md-sal/sal-remoterpc-connector/src/main/resources/application.conf +++ b/opendaylight/md-sal/sal-remoterpc-connector/src/main/resources/application.conf @@ -1,4 +1,43 @@ -odl-cluster{ + +odl-cluster-data { + akka { + cluster { + roles = [ + "member-1" + ] + } + actor { + provider = "akka.cluster.ClusterActorRefProvider" + serializers { + java = "akka.serialization.JavaSerializer" + proto = "akka.remote.serialization.ProtobufSerializer" + } + + serialization-bindings { + "com.google.protobuf.Message" = proto + + } + } + remote { + log-remote-lifecycle-events = off + netty.tcp { + hostname = "127.0.0.1" + port = 2550 + maximum-frame-size = 2097152 + send-buffer-size = 52428800 + receive-buffer-size = 52428800 + } + } + + cluster { + seed-nodes = ["akka.tcp://opendaylight-cluster-data@127.0.0.1:2550"] + + auto-down-unreachable-after = 10s + } + } +} + +odl-cluster-rpc { akka { actor { provider = "akka.cluster.ClusterActorRefProvider" @@ -7,15 +46,15 @@ odl-cluster{ remote { log-remote-lifecycle-events = off netty.tcp { - hostname = "192.168.141.141" + hostname = "127.0.0.1" port = 2551 } } cluster { - seed-nodes = ["akka.tcp://opendaylight-rpc@192.168.141.141:2551"] + seed-nodes = ["akka.tcp://opendaylight-cluster-rpc@127.0.0.1:2551"] auto-down-unreachable-after = 10s } } -} \ No newline at end of file +}