<jsr305.api.version>2.0.1</jsr305.api.version>
<jsr311.api.version>1.1.1</jsr311.api.version>
<jsr311.v2.api.version>2.0</jsr311.v2.api.version>
- <junit.version>4.8.1</junit.version>
<karaf.branding.version>1.0.0-SNAPSHOT</karaf.branding.version>
<karaf.shell.version>3.0.0</karaf.shell.version>
<karaf.version>3.0.1</karaf.version>
<artifactId>sal-clustering-commons</artifactId>
<version>${mdsal.version}</version>
</dependency>
+ <dependency>
+ <groupId>org.opendaylight.controller</groupId>
+ <artifactId>sal-clustering-config</artifactId>
+ <version>${mdsal.version}</version>
+ </dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>slf4j-simple</artifactId>
<version>${slf4j.version}</version>
</dependency>
- <dependency>
- <groupId>junit</groupId>
- <artifactId>junit</artifactId>
- <version>${junit.version}</version>
- <scope>test</scope>
- </dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>commons.logback_settings</artifactId>
*/
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;
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";
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();
}
private HierarchicalRuntimeBeanRegistration createAdditional(
- HierarchicalRuntimeBeanRegistrationImpl rootRegistration)
+ final HierarchicalRuntimeBeanRegistrationImpl rootRegistration)
throws Exception {
HierarchicalRuntimeBeanRegistrationImpl registration = rootRegistration
*/
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;
<artifactId>yang-parser-impl</artifactId>
<scope>test</scope>
</dependency>
- <dependency>
- <groupId>org.hamcrest</groupId>
- <artifactId>hamcrest-core</artifactId>
- <version>1.1</version>
- <scope>test</scope>
- </dependency>
</dependencies>
<build>
*/
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;
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";
Map<String, RuntimeBeanEntry> 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
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
// get runtime beans
Collection<RuntimeBeanEntry> 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(
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<RuntimeBeanEntry.Rpc> rpcs = new ArrayList<RuntimeBeanEntry.Rpc>(
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<JavaAttribute> 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<RuntimeBeanEntry> runtimeBeanEntries,
- String javaName) {
+ final String javaName) {
if (runtimeBeanEntries != null && !runtimeBeanEntries.isEmpty()) {
for (RuntimeBeanEntry runtimeBeanEntry : runtimeBeanEntries) {
if (runtimeBeanEntry.getJavaNameOfRuntimeMXBean().equals(
}
private RuntimeBeanEntry.Rpc getRpcByName(
- final List<RuntimeBeanEntry.Rpc> rpcs, String name) {
+ final List<RuntimeBeanEntry.Rpc> rpcs, final String name) {
if (rpcs != null && !rpcs.isEmpty()) {
for (RuntimeBeanEntry.Rpc rpc : rpcs) {
if (rpc.getName().equals(name)) {
<phase>generate-resources</phase>
<configuration>
<outputDirectory>${project.build.directory}/configuration</outputDirectory>
- <includeArtifactIds>sal-rest-connector-config,config-netty-config,md-sal-config,netconf-config,toaster-config,netconf-connector-config</includeArtifactIds>
- <includes>**\/*.xml</includes>
+ <includeArtifactIds>sal-rest-connector-config,config-netty-config,md-sal-config,netconf-config,toaster-config,netconf-connector-config,sal-clustering-config</includeArtifactIds>
+ <includes>**\/*.xml,**/*.conf</includes>
<excludeTransitive>true</excludeTransitive>
<ignorePermissions>false</ignorePermissions>
</configuration>
<artifactId>jeromq</artifactId>
<version>0.3.1</version>
</dependency>
- <dependency>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>sal-distributed-datastore</artifactId>
- </dependency>
+ <dependency>
+ <groupId>org.opendaylight.controller</groupId>
+ <artifactId>sal-distributed-datastore</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.opendaylight.controller</groupId>
+ <artifactId>sal-clustering-config</artifactId>
+ </dependency>
</dependencies>
</profile>
<profile>
*/
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;
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";
}
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);
+ }
}
/**
if (adNodeId == null) {
return null;
}
- return new BigInteger(adNodeId.replaceFirst("^.*:", "")).longValue();
+ return new BigInteger(adNodeId).longValue();
}
public static NodeId toNodeId(final InstanceIdentifier<?> id) {
}
/**
- * @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
*/
* @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) {
public static NodeRef toNodeRef(final org.opendaylight.controller.sal.core.Node node) {
Preconditions.checkArgument(NodeIDType.OPENFLOW.equals(node.getType()));
final Long nodeId = Arguments.<Long>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<Node> nodePath = InstanceIdentifier.builder(Nodes.class).child(NODE_CLASS, nodeKey).toInstance();
return new NodeRef(nodePath);
}
}
/**
- * @param id
+ * @param nodeRef
* @return node description in AD form, e.g.: OF|00:00:00:...:01
*/
private static Description toADDescription(NodeRef nodeRef) {
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;
+ }
}
} 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());
+ }
+
}
/**
<module>
<type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:config:distributed-datastore-provider">prefix:distributed-operational-datastore-provider</type>
<name>distributed-operational-store-module</name>
- <schema-service>
+ <operational-schema-service>
<type xmlns:dom="urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom">dom:schema-service</type>
<name>yang-schema-service</name>
- </schema-service>
+ </operational-schema-service>
</module>
<module>
<type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:config:distributed-datastore-provider">prefix:distributed-config-datastore-provider</type>
<name>distributed-config-store-module</name>
- <schema-service>
+ <configschema-service>
<type xmlns:dom="urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom">dom:schema-service</type>
<name>yang-schema-service</name>
- </schema-service>
+ </config-schema-service>
</module>
-->
<!--sal-protocolbuffer-encoding is now part of sal-clutering-commons-->
<module>sal-clustering-commons</module>
+ <!-- sal clustering configuration -->
+ <module>sal-clustering-config</module>
+
<!-- sal-distributed-datastore -->
<module>sal-distributed-datastore</module>
@Override
public List<ReplicatedLogEntry> getFrom(long logEntryIndex) {
+ return getFrom(logEntryIndex, journal.size());
+ }
+
+ @Override
+ public List<ReplicatedLogEntry> getFrom(long logEntryIndex, int max) {
int adjustedIndex = adjustedIndex(logEntryIndex);
int size = journal.size();
List<ReplicatedLogEntry> 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();
* 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);
@Override
public FiniteDuration getElectionTimeOutInterval() {
// returns 2 times the heart beat interval
- return HEART_BEAT_INTERVAL.$times(2);
+ return getHeartBeatInterval().$times(2);
}
@Override
replicatedLog.lastIndex(), replicatedLog.snapshotIndex,
replicatedLog.snapshotTerm, replicatedLog.size());
currentBehavior = switchBehavior(RaftState.Follower);
+ onStateChanged();
}
}
RaftState state =
currentBehavior.handleMessage(getSender(), message);
+ RaftActorBehavior oldBehavior = currentBehavior;
currentBehavior = switchBehavior(state);
+ if(oldBehavior != currentBehavior){
+ onStateChanged();
+ }
}
}
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();
}
behavior = new Leader(context);
}
- onStateChanged();
+
return behavior;
}
*/
List<ReplicatedLogEntry> getFrom(long index);
+ /**
+ *
+ * @param index the index of the log entry
+ */
+ List<ReplicatedLogEntry> getFrom(long index, int max);
/**
*
// 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(
*/
package org.opendaylight.controller.cluster.raft;
+import junit.framework.Assert;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
@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
@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());
}
+ @Test
+ public void testGetFromWithMax(){
+ List<ReplicatedLogEntry> 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);
return entries;
}
+ @Override public List<ReplicatedLogEntry> getFrom(long index, int max) {
+ if(index >= log.size() || index < 0){
+ return Collections.EMPTY_LIST;
+ }
+ List<ReplicatedLogEntry> 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();
}
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;
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<Boolean>(duration("1 seconds"), "ElectionTimeout") {
+ final Boolean out = new ExpectMsg<Boolean>(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) {
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;
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<Boolean>(duration("1 seconds"), "ElectionTimeout") {
+ final Boolean out = new ExpectMsg<Boolean>(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) {
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;
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;
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;
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;
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;
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;
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;
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
+
+ This program and the accompanying materials are made available under the
+ terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ and is available at http://www.eclipse.org/legal/epl-v10.html
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <groupId>org.opendaylight.controller</groupId>
+ <artifactId>sal-parent</artifactId>
+ <version>1.1-SNAPSHOT</version>
+ </parent>
+ <artifactId>sal-clustering-config</artifactId>
+ <description>Configuration files for md-sal clustering</description>
+ <packaging>jar</packaging>
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.codehaus.mojo</groupId>
+ <artifactId>build-helper-maven-plugin</artifactId>
+ <executions>
+ <execution>
+ <id>attach-artifacts</id>
+ <goals>
+ <goal>attach-artifact</goal>
+ </goals>
+ <phase>package</phase>
+ <configuration>
+ <artifacts>
+ <artifact>
+ <file>${project.build.directory}/classes/initial/*.conf</file>
+ <type>xml</type>
+ <classifier>config</classifier>
+ </artifact>
+ </artifacts>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
+</project>
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- vi: set et smarttab sw=4 tabstop=4: -->
+<!--
+ Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
+
+ This program and the accompanying materials are made available under the
+ terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ and is available at http://www.eclipse.org/legal/epl-v10.html
+-->
+<snapshot>
+ <configuration>
+ <data xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
+ <modules xmlns="urn:opendaylight:params:xml:ns:yang:controller:config">
+ <module>
+ <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom:impl">prefix:dom-inmemory-data-broker</type>
+ <name>inmemory-data-broker</name>
+
+ <schema-service>
+ <type xmlns:dom="urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom">dom:schema-service</type>
+ <name>yang-schema-service</name>
+ </schema-service>
+
+ <config-data-store>
+ <type xmlns:config-dom-store-spi="urn:opendaylight:params:xml:ns:yang:controller:md:sal:core:spi:config-dom-store">config-dom-store-spi:config-dom-datastore</type>
+ <name>distributed-config-store-service</name>
+ </config-data-store>
+
+ <operational-data-store>
+ <type xmlns:operational-dom-store-spi="urn:opendaylight:params:xml:ns:yang:controller:md:sal:core:spi:operational-dom-store">operational-dom-store-spi:operational-dom-datastore</type>
+ <name>distributed-operational-store-service</name>
+ </operational-data-store>
+ </module>
+
+ <module>
+ <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:config:distributed-datastore-provider">prefix:distributed-operational-datastore-provider</type>
+ <name>distributed-operational-store-module</name>
+ <schema-service>
+ <type xmlns:dom="urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom">dom:schema-service</type>
+ <name>yang-schema-service</name>
+ </schema-service>
+ </module>
+
+ <module>
+ <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:config:distributed-datastore-provider">prefix:distributed-config-datastore-provider</type>
+ <name>distributed-config-store-module</name>
+ <schema-service>
+ <type xmlns:dom="urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom">dom:schema-service</type>
+ <name>yang-schema-service</name>
+ </schema-service>
+ </module>
+
+ <module>
+ <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:config:remote-rpc-connector">prefix:remote-rpc-connector</type>
+ <name>remote-rpc-connector</name>
+ <dom-broker xmlns="urn:opendaylight:params:xml:ns:yang:controller:config:remote-rpc-connector">
+ <type xmlns:dom="urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom">dom:dom-broker-osgi-registry</type>
+ <name>dom-broker</name>
+ </dom-broker>
+ </module>
+
+ </modules>
+ <services xmlns="urn:opendaylight:params:xml:ns:yang:controller:config">
+
+ <service>
+ <type xmlns:config-dom-store-spi="urn:opendaylight:params:xml:ns:yang:controller:md:sal:core:spi:config-dom-store">config-dom-store-spi:config-dom-datastore</type>
+ <instance>
+ <name>distributed-config-store-service</name>
+ <provider>/modules/module[type='distributed-config-datastore-provider'][name='distributed-config-store-module']</provider>
+ </instance>
+ </service>
+ <service>
+ <type xmlns:operational-dom-store-spi="urn:opendaylight:params:xml:ns:yang:controller:md:sal:core:spi:operational-dom-store">operational-dom-store-spi:operational-dom-datastore</type>
+ <instance>
+ <name>distributed-operational-store-service</name>
+ <provider>/modules/module[type='distributed-operational-datastore-provider'][name='distributed-operational-store-module']</provider>
+ </instance>
+ </service>
+
+ </services>
+ </data>
+ </configuration>
+ <required-capabilities>
+ <capability>urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom:impl?module=opendaylight-sal-dom-broker-impl&revision=2013-10-28</capability>
+ </required-capabilities>
+</snapshot>
--- /dev/null
+
+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 = "<CHANGE_ME>"
+ port = 2550
+ maximum-frame-size = 2097152
+ send-buffer-size = 52428800
+ receive-buffer-size = 52428800
+ }
+ }
+
+ cluster {
+ seed-nodes = ["akka.tcp://opendaylight-cluster-data@<CHANGE_ME>:2550"]
+
+ auto-down-unreachable-after = 10s
+ }
+ }
+}
+
+odl-cluster-rpc {
+ akka {
+ actor {
+ provider = "akka.cluster.ClusterActorRefProvider"
+
+ }
+ remote {
+ log-remote-lifecycle-events = off
+ netty.tcp {
+ hostname = "<CHANGE_ME>"
+ port = 2551
+ }
+ }
+
+ cluster {
+ seed-nodes = ["akka.tcp://opendaylight-cluster-rpc@<CHANGE_ME>:2551"]
+
+ auto-down-unreachable-after = 10s
+ }
+ }
+}
--- /dev/null
+# This file describes which shards live on which members
+# The format for a module-shards is as follows,
+# {
+# name = "<friendly_name_of_the_module>"
+# shards = [
+# {
+# name="<any_name_that_is_unique_for_the_module>"
+# replicas = [
+# "<name_of_member_on_which_to_run>"
+# ]
+# ]
+# }
+#
+# 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"
+ ]
+ }
+ ]
+ }
+
+]
--- /dev/null
+# 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 = "<friendly_name_of_module>"
+# namespace = "<the yang namespace of the module>"
+# 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"
+ }
+
+]
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;
@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;
}
}
@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);
return;
}
- DataChanged reply = DataChanged.fromSerialize(schemaContext,message, pathId);
+ DataChanged reply = (DataChanged) message;
AsyncDataChangeEvent<YangInstanceIdentifier, NormalizedNode<?, ?>>
change = reply.getChange();
this.listener.onDataChanged(change);
if(getSender() != null){
- getSender().tell(new DataChangedReply().toSerializable(), getSelf());
+ getSender().tell(new DataChangedReply(), getSelf());
}
}
@Override public void onDataChanged(
AsyncDataChangeEvent<YangInstanceIdentifier, NormalizedNode<?, ?>> change) {
- dataChangeListenerActor.tell(new DataChanged(schemaContext,change).toSerializable(), null);
+ dataChangeListenerActor.tell(new DataChanged(schemaContext,change), null);
}
}
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;
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;
/**
*
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);
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;
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;
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;
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 <br/>
*/
public class Shard extends RaftActor {
+ private static final ConfigParams configParams = new ShardConfigParams();
+
public static final String DEFAULT_NAME = "default";
private final ListeningExecutorService storeExecutor =
private final List<ActorSelection> dataChangeListeners = new ArrayList<>();
private Shard(String name, Map<String, String> peerAddresses) {
- super(name, peerAddresses);
+ super(name, peerAddresses, Optional.of(configParams));
this.name = name;
} 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) {
LOG.debug("registerDataChangeListener sending reply, listenerRegistrationPath = " + listenerRegistration.path().toString());
getSender()
- .tell(new RegisterChangeListenerReply(listenerRegistration.path()).toSerializable(),
+ .tell(new RegisterChangeListenerReply(listenerRegistration.path()),
getSelf());
}
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;
+ }
+ }
}
CanCommitTransactionReply reply =
CanCommitTransactionReply.fromSerializable(response);
if (!reply.getCanCommit()) {
- System.out.println("**TOM - failed: false");
return false;
}
}
private Long committedTransactionsCount;
private Long journalMessagesCount;
final private String shardName;
+ private String leader;
+ private String raftState;
ShardStats(String shardName){
this.shardName = shardName;
return journalMessagesCount;
}
+ @Override public String getLeader() {
+ return leader;
+ }
+
+ @Override public String getRaftState() {
+ return raftState;
+ }
public Long incrementCommittedTransactionCount() {
return committedTransactionsCount++;
}
+ public void setLeader(String leader){
+ this.leader = leader;
+ }
+
+ public void setRaftState(String raftState){
+ this.raftState = raftState;
+ }
@Override
String getShardName();
Long getCommittedTransactionsCount();
Long getJournalMessagesCount();
-
+ String getLeader();
+ String getRaftState();
}
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";
}
@Override public String findShard(YangInstanceIdentifier path) {
- return configuration.getShardNamesFromModuleName(moduleName).get(0);
+ List<String> shardNames =
+ configuration.getShardNamesFromModuleName(moduleName);
+ if(shardNames.size() == 0){
+ return DefaultShardStrategy.DEFAULT_SHARD;
+ }
+ return shardNames.get(0);
}
}
public interface ShardStrategy {
/**
* Find the name of the shard in which the data pointed to by the specified path belongs in
+ * <p>
+ * 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
@Override
public java.lang.AutoCloseable createInstance() {
return DistributedDataStoreFactory
- .createInstance("config", getSchemaServiceDependency());
+ .createInstance("config", getConfigSchemaServiceDependency());
}
}
@Override
public java.lang.AutoCloseable createInstance() {
return DistributedDataStoreFactory
- .createInstance("operational", getSchemaServiceDependency());
+ .createInstance("operational", getOperationalSchemaServiceDependency());
}
}
-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
+ }
+ }
+}
modules = [
{
name = "inventory"
- namespace = "urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom:store:test:people"
+ namespace = "urn:opendaylight:inventory"
shard-strategy = "module"
}
]
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;
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;
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;
import java.util.Collections;
+import static junit.framework.Assert.assertEquals;
+
public class BasicIntegrationTest extends AbstractActorTest {
@Test
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<Boolean>(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<ActorSelection>("CreateTransactionChainReply") {
+ new ExpectMsg<ActorSelection>(duration("1 seconds"), "CreateTransactionChainReply") {
protected ActorSelection match(Object in) {
if (in.getClass().equals(CreateTransactionChainReply.SERIALIZABLE_CLASS)) {
ActorPath transactionChainPath =
transactionChain.tell(new CreateTransaction("txn-1", TransactionProxy.TransactionType.WRITE_ONLY.ordinal() ).toSerializable(), getRef());
final ActorSelection transaction =
- new ExpectMsg<ActorSelection>("CreateTransactionReply") {
+ new ExpectMsg<ActorSelection>(duration("1 seconds"), "CreateTransactionReply") {
protected ActorSelection match(Object in) {
if (CreateTransactionReply.SERIALIZABLE_CLASS.equals(in.getClass())) {
CreateTransactionReply reply = CreateTransactionReply.fromSerializable(in);
ImmutableNodes.containerNode(TestModel.TEST_QNAME), TestModel.createTestContext()).toSerializable(),
getRef());
- Boolean writeDone = new ExpectMsg<Boolean>("WriteDataReply") {
+ Boolean writeDone = new ExpectMsg<Boolean>(duration("1 seconds"), "WriteDataReply") {
protected Boolean match(Object in) {
if (in.getClass().equals(WriteDataReply.SERIALIZABLE_CLASS)) {
return true;
transaction.tell(new ReadyTransaction().toSerializable(), getRef());
final ActorSelection cohort =
- new ExpectMsg<ActorSelection>("ReadyTransactionReply") {
+ new ExpectMsg<ActorSelection>(duration("1 seconds"), "ReadyTransactionReply") {
protected ActorSelection match(Object in) {
if (in.getClass().equals(ReadyTransactionReply.SERIALIZABLE_CLASS)) {
ActorPath cohortPath =
cohort.tell(new PreCommitTransaction().toSerializable(), getRef());
Boolean preCommitDone =
- new ExpectMsg<Boolean>("PreCommitTransactionReply") {
+ new ExpectMsg<Boolean>(duration("1 seconds"), "PreCommitTransactionReply") {
protected Boolean match(Object in) {
if (in.getClass().equals(PreCommitTransactionReply.SERIALIZABLE_CLASS)) {
return true;
Assert.assertEquals(1, listMessages.size());
- Assert.assertTrue(listMessages.get(0).getClass().equals(DataChanged.SERIALIZABLE_CLASS));
+ Assert.assertTrue(listMessages.get(0).getClass().equals(DataChanged.class));
}
}
subject.tell(new CloseDataChangeListenerRegistration().toSerializable(), getRef());
- final String out = new ExpectMsg<String>("match hint") {
+ final String out = new ExpectMsg<String>(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)) {
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<Boolean>(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 {
protected void run() {
subject.tell(
- new DataChanged(CompositeModel.createTestContext(),new MockDataChangedEvent()).toSerializable(),
+ new DataChanged(CompositeModel.createTestContext(),new MockDataChangedEvent()),
getRef());
expectNoMsg();
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;
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");
}
@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<Boolean>(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<Optional<NormalizedNode<?, ?>>> future =
- transaction.read(TestModel.TEST_PATH);
+ ListenableFuture<Optional<NormalizedNode<?, ?>>>
+ future =
+ transaction.read(TestModel.TEST_PATH);
- Optional<NormalizedNode<?, ?>> optional = future.get();
+ Optional<NormalizedNode<?, ?>> 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<Boolean> canCommit = ready.canCommit();
+ ListenableFuture<Boolean> canCommit =
+ ready.canCommit();
- assertTrue(canCommit.get(5, TimeUnit.SECONDS));
+ assertTrue(canCommit.get(5, TimeUnit.SECONDS));
- ListenableFuture<Void> preCommit = ready.preCommit();
+ ListenableFuture<Void> preCommit =
+ ready.preCommit();
- preCommit.get(5, TimeUnit.SECONDS);
+ preCommit.get(5, TimeUnit.SECONDS);
- ListenableFuture<Void> commit = ready.commit();
+ ListenableFuture<Void> 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<Boolean>(
+ 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<Boolean> 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<Void> preCommit = ready.preCommit();
- ListenableFuture<Boolean> canCommit = ready.canCommit();
+ preCommit.get(5, TimeUnit.SECONDS);
- assertTrue(canCommit.get(5, TimeUnit.SECONDS));
+ ListenableFuture<Void> commit = ready.commit();
- ListenableFuture<Void> 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<Void> commit = ready.commit();
- commit.get(5, TimeUnit.SECONDS);
}
}
@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<YangInstanceIdentifier, NormalizedNode<?, ?>>() {
subject.tell(new FindPrimary(Shard.DEFAULT_NAME).toSerializable(), getRef());
- expectMsgClass(PrimaryFound.SERIALIZABLE_CLASS);
+ expectMsgClass(duration("1 seconds"), PrimaryFound.SERIALIZABLE_CLASS);
expectNoMsg();
}
subject.tell(new FindPrimary("astronauts").toSerializable(), getRef());
- final String out = new ExpectMsg<String>("primary found") {
+ final String out = new ExpectMsg<String>(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)) {
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();
}
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;
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<Boolean>(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<String>("match hint") {
+ final String out = new ExpectMsg<String>(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)){
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<Boolean>("enable notification") {
assertFalse(notificationEnabled);
- final String out = new ExpectMsg<String>("match hint") {
+ final String out = new ExpectMsg<String>(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 {
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<Boolean>(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 CreateTransaction("txn-1", TransactionProxy.TransactionType.READ_ONLY.ordinal() ).toSerializable(),
getRef());
- final String out = new ExpectMsg<String>("match hint") {
+ final String out = new ExpectMsg<String>(duration("1 seconds"), "match hint") {
// do not put code outside this method, will run afterwards
protected String match(Object in) {
if (in instanceof CreateTransactionReply) {
subject.tell(new CreateTransaction("txn-1", TransactionProxy.TransactionType.READ_ONLY.ordinal() ).toSerializable(), getRef());
- final String out = new ExpectMsg<String>("match hint") {
+ final String out = new ExpectMsg<String>(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)) {
subject.tell(new CloseTransactionChain().toSerializable(), getRef());
- final String out = new ExpectMsg<String>("match hint") {
+ final String out = new ExpectMsg<String>(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)) {
new ReadData(YangInstanceIdentifier.builder().build()).toSerializable(),
getRef());
- final String out = new ExpectMsg<String>("match hint") {
+ final String out = new ExpectMsg<String>(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)) {
new ReadData(TestModel.TEST_PATH).toSerializable(),
getRef());
- final String out = new ExpectMsg<String>("match hint") {
+ final String out = new ExpectMsg<String>(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)) {
getRef());
final CompositeModification compositeModification =
- new ExpectMsg<CompositeModification>("match hint") {
+ new ExpectMsg<CompositeModification>(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) {
ImmutableNodes.containerNode(TestModel.TEST_QNAME), TestModel.createTestContext()).toSerializable(),
getRef());
- final String out = new ExpectMsg<String>("match hint") {
+ final String out = new ExpectMsg<String>(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)) {
subject.tell(new DeleteData(TestModel.TEST_PATH).toSerializable(), getRef());
- final String out = new ExpectMsg<String>("match hint") {
+ final String out = new ExpectMsg<String>(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)) {
subject.tell(new ReadyTransaction().toSerializable(), getRef());
- final String out = new ExpectMsg<String>("match hint") {
+ final String out = new ExpectMsg<String>(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)) {
subject.tell(new CloseTransaction().toSerializable(), getRef());
- final String out = new ExpectMsg<String>("match hint") {
+ final String out = new ExpectMsg<String>(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)) {
assertEquals("match", out);
- final String termination = new ExpectMsg<String>("match hint") {
+ final String termination = new ExpectMsg<String>(duration("1 seconds"), "match hint") {
// do not put code outside this method, will run afterwards
protected String match(Object in) {
if (in instanceof Terminated) {
package org.opendaylight.controller.cluster.datastore.shardstrategy;
-import junit.framework.Assert;
import org.junit.BeforeClass;
import org.junit.Rule;
import org.junit.Test;
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
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);
+
}
}
akka {
+ loggers = [akka.testkit.TestEventListener]
actor {
serializers {
java = "akka.serialization.JavaSerializer"
shard-strategy = "module"
}
+ {
+ name = "missing"
+ namespace = "urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom:store:missing"
+ shard-strategy = "module"
+ }
+
]
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;
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 {
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;
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
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;
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
*
final Collection<Node> 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
final Collection<Node> listeners,
final NormalizedNodeContainer<?, PathArgument, NormalizedNode<PathArgument, ?>> beforeCont,
final NormalizedNodeContainer<?, PathArgument, NormalizedNode<PathArgument, ?>> afterCont) {
- final Set<PathArgument> alreadyProcessed = new HashSet<>();
final List<DOMImmutableDataChangeEvent> childChanges = new LinkedList<>();
- DataChangeScope potentialScope = DataChangeScope.BASE;
// We look at all children from before and compare it with after state.
for (NormalizedNode<PathArgument, ?> beforeChild : beforeCont.getValue()) {
- PathArgument childId = beforeChild.getIdentifier();
- alreadyProcessed.add(childId);
+ final PathArgument childId = beforeChild.getIdentifier();
+
YangInstanceIdentifier childPath = path.node(childId);
Collection<ListenerTree.Node> childListeners = getListenerChildrenWildcarded(listeners, childId);
Optional<NormalizedNode<PathArgument, ?>> afterChild = afterCont.getChild(childId);
if (childChange != NO_CHANGE) {
childChanges.add(childChange);
}
-
}
for (NormalizedNode<PathArgument, ?> 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<ListenerTree.Node> childListeners = getListenerChildrenWildcarded(listeners, childId);
YangInstanceIdentifier childPath = path.node(childId);
childChanges.add(resolveSameEventRecursivelly(childPath , childListeners, afterChild,
return NO_CHANGE;
}
- Builder eventBuilder = builder(potentialScope) //
+ Builder eventBuilder = builder(DataChangeScope.BASE) //
.setBefore(beforeCont) //
.setAfter(afterCont)
.addUpdated(path, beforeCont, afterCont);
*/
package org.opendaylight.controller.sal.connect.netconf;
-import com.google.common.annotations.VisibleForTesting;
-import com.google.common.base.Preconditions;
-import com.google.common.util.concurrent.FutureCallback;
-import com.google.common.util.concurrent.Futures;
-import com.google.common.util.concurrent.ListenableFuture;
-import com.google.common.util.concurrent.ListeningExecutorService;
-import com.google.common.util.concurrent.MoreExecutors;
import java.io.InputStream;
import java.util.LinkedList;
import java.util.List;
import java.util.concurrent.ExecutorService;
+
import org.opendaylight.controller.netconf.api.NetconfMessage;
import org.opendaylight.controller.netconf.util.xml.XmlUtil;
import org.opendaylight.controller.sal.connect.api.MessageTransformer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import com.google.common.annotations.VisibleForTesting;
+import com.google.common.base.Preconditions;
+import com.google.common.util.concurrent.FutureCallback;
+import com.google.common.util.concurrent.Futures;
+import com.google.common.util.concurrent.ListenableFuture;
+import com.google.common.util.concurrent.ListeningExecutorService;
+import com.google.common.util.concurrent.MoreExecutors;
+
/**
* This is a mediator between NetconfDeviceCommunicator and NetconfDeviceSalFacade
*/
private final MessageTransformer<NetconfMessage> messageTransformer;
private final SchemaContextProviderFactory schemaContextProviderFactory;
private final SchemaSourceProviderFactory<InputStream> sourceProviderFactory;
+ private final NetconfStateSchemas.NetconfStateSchemasResolver stateSchemasResolver;
private final NotificationHandler notificationHandler;
public static NetconfDevice createNetconfDevice(final RemoteDeviceId id,
final AbstractCachingSchemaSourceProvider<String, InputStream> schemaSourceProvider,
final ExecutorService executor, final RemoteDeviceHandler<NetconfSessionCapabilities> salFacade) {
+ return createNetconfDevice(id, schemaSourceProvider, executor, salFacade, new NetconfStateSchemas.NetconfStateSchemasResolverImpl());
+ }
+
+ @VisibleForTesting
+ protected static NetconfDevice createNetconfDevice(final RemoteDeviceId id,
+ final AbstractCachingSchemaSourceProvider<String, InputStream> schemaSourceProvider,
+ final ExecutorService executor, final RemoteDeviceHandler<NetconfSessionCapabilities> salFacade,
+ final NetconfStateSchemas.NetconfStateSchemasResolver stateSchemasResolver) {
return new NetconfDevice(id, salFacade, executor, new NetconfMessageTransformer(),
new NetconfDeviceSchemaProviderFactory(id), new SchemaSourceProviderFactory<InputStream>() {
return schemaSourceProvider.createInstanceFor(new NetconfRemoteSchemaSourceProvider(id,
deviceRpc));
}
- });
+ }, stateSchemasResolver);
}
@VisibleForTesting
protected NetconfDevice(final RemoteDeviceId id, final RemoteDeviceHandler<NetconfSessionCapabilities> salFacade,
- final ExecutorService processingExecutor, final MessageTransformer<NetconfMessage> messageTransformer,
- final SchemaContextProviderFactory schemaContextProviderFactory,
- final SchemaSourceProviderFactory<InputStream> sourceProviderFactory) {
+ final ExecutorService processingExecutor, final MessageTransformer<NetconfMessage> messageTransformer,
+ final SchemaContextProviderFactory schemaContextProviderFactory,
+ final SchemaSourceProviderFactory<InputStream> 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);
@Override
public void run() {
final NetconfDeviceRpc deviceRpc = setUpDeviceRpc(remoteSessionCapabilities, listener);
+
+ final NetconfStateSchemas availableSchemas = stateSchemasResolver.resolve(deviceRpc, remoteSessionCapabilities, id);
+ logger.warn("{}: Schemas exposed by ietf-netconf-monitoring: {}", id, availableSchemas.getAvailableYangSchemasQNames());
+ // TODO use this for shared schema context
+
final SchemaSourceProvider<InputStream> delegate = sourceProviderFactory.createSourceProvider(deviceRpc);
final SchemaContextProvider schemaContextProvider = setUpSchemaContext(delegate, remoteSessionCapabilities);
updateMessageTransformer(schemaContextProvider);
Preconditions.checkNotNull(parsedNotification);
salFacade.onNotification(parsedNotification);
}
-
}
+
}
--- /dev/null
+package org.opendaylight.controller.sal.connect.netconf;
+
+import com.google.common.annotations.VisibleForTesting;
+import com.google.common.base.Function;
+import com.google.common.base.Optional;
+import com.google.common.base.Preconditions;
+import com.google.common.collect.Collections2;
+import com.google.common.collect.Lists;
+import com.google.common.collect.Sets;
+import java.net.URI;
+import java.util.Collections;
+import java.util.Set;
+import java.util.concurrent.ExecutionException;
+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.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.netconf.monitoring.rev101004.NetconfState;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.netconf.monitoring.rev101004.Yang;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.netconf.monitoring.rev101004.netconf.state.Schemas;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.netconf.monitoring.rev101004.netconf.state.schemas.Schema;
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.common.RpcResult;
+import org.opendaylight.yangtools.yang.data.api.CompositeNode;
+import org.opendaylight.yangtools.yang.data.api.Node;
+import org.opendaylight.yangtools.yang.data.api.SimpleNode;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.impl.NodeFactory;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Holds QNames for all yang modules reported by ietf-netconf-monitoring/state/schemas
+ */
+public final class NetconfStateSchemas {
+
+ private static final Logger logger = LoggerFactory.getLogger(NetconfStateSchemas.class);
+
+ /**
+ * Factory for NetconfStateSchemas
+ */
+ public interface NetconfStateSchemasResolver {
+ NetconfStateSchemas resolve(final NetconfDeviceRpc deviceRpc, final NetconfSessionCapabilities remoteSessionCapabilities, final RemoteDeviceId id);
+ }
+
+ /**
+ * Default implementation resolving schemas QNames from netconf-state
+ */
+ public static final class NetconfStateSchemasResolverImpl implements NetconfStateSchemasResolver {
+
+ @Override
+ public NetconfStateSchemas resolve(final NetconfDeviceRpc deviceRpc, final NetconfSessionCapabilities remoteSessionCapabilities, final RemoteDeviceId id) {
+ return NetconfStateSchemas.create(deviceRpc, remoteSessionCapabilities, id);
+ }
+ }
+
+ public static final NetconfStateSchemas EMPTY = new NetconfStateSchemas(Collections.<RemoteYangSchema>emptySet());
+
+ 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.<Node<?>>newArrayList(filter));
+ }
+
+ private final Set<RemoteYangSchema> availableYangSchemas;
+
+ public NetconfStateSchemas(final Set<RemoteYangSchema> availableYangSchemas) {
+ this.availableYangSchemas = availableYangSchemas;
+ }
+
+ public Set<RemoteYangSchema> getAvailableYangSchemas() {
+ return availableYangSchemas;
+ }
+
+ public Set<QName> getAvailableYangSchemasQNames() {
+ return Sets.newHashSet(Collections2.transform(getAvailableYangSchemas(), new Function<RemoteYangSchema, QName>() {
+ @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<CompositeNode> 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<RemoteYangSchema> 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<String> 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<String> 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<String> getAllChildNodeValues(final CompositeNode schemaNode, final QName childNodeQName) {
+ final Set<String> extractedValues = Sets.newHashSet();
+ for (final SimpleNode<?> childNode : schemaNode.getSimpleNodesByName(childNodeQName)) {
+ extractedValues.add(getValueOfSimpleNode(childNodeQName, childNode).get());
+ }
+ return extractedValues;
+ }
+
+ private static Optional<String> getSingleChildNodeValue(final CompositeNode schemaNode, final QName childNode) {
+ final SimpleNode<?> node = schemaNode.getFirstSimpleByName(childNode);
+ return getValueOfSimpleNode(childNode, node);
+ }
+
+ private static Optional<String> 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.<String>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();
+ }
+ }
+}
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 );
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;
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.<NormalizedNode<?, ?>>absent() :
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.<NormalizedNode<?, ?>>absent() :
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
return toRpcResult(message, rpc, schemaContext.get());
} else {
final CompositeNode node = (CompositeNode) XmlDocumentUtils.toDomNode(message.getDocument());
- return RpcResultBuilder.success( node ).build();
+ return RpcResultBuilder.success(node).build();
}
}
import org.opendaylight.controller.netconf.api.NetconfDocumentedException;
import org.opendaylight.controller.netconf.api.NetconfMessage;
import org.opendaylight.controller.netconf.util.messages.NetconfMessageUtil;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.netconf.monitoring.rev101004.NetconfState;
import org.opendaylight.yangtools.yang.common.QName;
import org.opendaylight.yangtools.yang.common.RpcError;
import org.opendaylight.yangtools.yang.common.RpcError.ErrorSeverity;
import org.opendaylight.yangtools.yang.data.api.CompositeNode;
import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
import org.opendaylight.yangtools.yang.data.api.Node;
+import org.opendaylight.yangtools.yang.data.api.SimpleNode;
import org.opendaylight.yangtools.yang.data.impl.CompositeNodeTOImpl;
import org.opendaylight.yangtools.yang.data.impl.ImmutableCompositeNode;
import org.opendaylight.yangtools.yang.data.impl.NodeFactory;
private NetconfMessageTransformUtil() {}
- public static final QName IETF_NETCONF_MONITORING = QName.create("urn:ietf:params:xml:ns:yang:ietf-netconf-monitoring", "2010-10-04", "ietf-netconf-monitoring");
+ public static final QName IETF_NETCONF_MONITORING = QName.create(NetconfState.QNAME, "ietf-netconf-monitoring");
+ public static final QName IETF_NETCONF_MONITORING_SCHEMA_FORMAT = QName.create(IETF_NETCONF_MONITORING, "format");
+ public static final QName IETF_NETCONF_MONITORING_SCHEMA_LOCATION = QName.create(IETF_NETCONF_MONITORING, "location");
+ public static final QName IETF_NETCONF_MONITORING_SCHEMA_IDENTIFIER = QName.create(IETF_NETCONF_MONITORING, "identifier");
+ public static final QName IETF_NETCONF_MONITORING_SCHEMA_VERSION = QName.create(IETF_NETCONF_MONITORING, "version");
+ public static final QName IETF_NETCONF_MONITORING_SCHEMA_NAMESPACE = QName.create(IETF_NETCONF_MONITORING, "namespace");
+
public static URI NETCONF_URI = URI.create("urn:ietf:params:xml:ns:netconf:base:1.0");
public static QName NETCONF_QNAME = QName.create(NETCONF_URI, null, "netconf");
public static QName NETCONF_DATA_QNAME = QName.create(NETCONF_QNAME, "data");
return it.toInstance();
}
}
+
+ public 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;
+ }
}
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;
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;
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;
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;
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<NetconfSessionCapabilities> facade = getFacade();
final RemoteDeviceCommunicator<NetconfMessage> 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.<String>emptyList()), listener);
Mockito.verify(facade, Mockito.timeout(5000)).onDeviceDisconnected();
final RemoteDeviceCommunicator<NetconfMessage> listener = getListener();
final MessageTransformer<NetconfMessage> 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);
final SchemaSourceProviderFactory<InputStream> sourceProviderFactory = getSourceProviderFactory();
final MessageTransformer<NetconfMessage> 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);
--- /dev/null
+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<QName> 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")));
+ }
+}
--- /dev/null
+<ncm:schemas xmlns:ncm="urn:ietf:params:xml:ns:yang:ietf-netconf-monitoring">
+ <ncm:schema>
+ <ncm:namespace>urn:opendaylight:params:xml:ns:yang:controller:threadpool</ncm:namespace>
+ <ncm:location>NETCONF</ncm:location>
+ <ncm:identifier>threadpool</ncm:identifier>
+ <ncm:format>yang</ncm:format>
+ <ncm:version>2013-04-09</ncm:version>
+ </ncm:schema>
+ <ncm:schema>
+ <ncm:namespace>urn:opendaylight:params:xml:ns:yang:controller:logback:config</ncm:namespace>
+ <ncm:location>NETCONF</ncm:location>
+ <ncm:identifier>config-logging</ncm:identifier>
+ <ncm:format>yang</ncm:format>
+ <ncm:version>2013-07-16</ncm:version>
+ </ncm:schema>
+ <ncm:schema>
+ <ncm:namespace>urn:opendaylight:model:statistics:types</ncm:namespace>
+ <ncm:location>NETCONF</ncm:location>
+ <ncm:identifier>opendaylight-statistics-types</ncm:identifier>
+ <ncm:format>yang</ncm:format>
+ <ncm:version>2013-09-25</ncm:version>
+ </ncm:schema>
+ <ncm:schema>
+ <ncm:namespace>urn:opendaylight:params:xml:ns:yang:controller:md:sal:core:spi:config-dom-store</ncm:namespace>
+ <ncm:location>NETCONF</ncm:location>
+ <ncm:identifier>opendaylight-config-dom-datastore</ncm:identifier>
+ <ncm:format>yang</ncm:format>
+ <ncm:version>2014-06-17</ncm:version>
+ </ncm:schema>
+ <ncm:schema>
+ <ncm:namespace>urn:opendaylight:flow:table:statistics</ncm:namespace>
+ <ncm:location>NETCONF</ncm:location>
+ <ncm:identifier>opendaylight-flow-table-statistics</ncm:identifier>
+ <ncm:format>yang</ncm:format>
+ <ncm:version>2013-12-15</ncm:version>
+ </ncm:schema>
+ <ncm:schema>
+ <ncm:namespace>urn:opendaylight:meter:service</ncm:namespace>
+ <ncm:location>NETCONF</ncm:location>
+ <ncm:identifier>sal-meter</ncm:identifier>
+ <ncm:format>yang</ncm:format>
+ <ncm:version>2013-09-18</ncm:version>
+ </ncm:schema>
+ <ncm:schema>
+ <ncm:namespace>urn:opendaylight:params:xml:ns:yang:controller:config:toaster-provider:impl</ncm:namespace>
+ <ncm:location>NETCONF</ncm:location>
+ <ncm:identifier>toaster-provider-impl</ncm:identifier>
+ <ncm:format>yang</ncm:format>
+ <ncm:version>2014-01-31</ncm:version>
+ </ncm:schema>
+ <ncm:schema>
+ <ncm:namespace>urn:opendaylight:table:types</ncm:namespace>
+ <ncm:location>NETCONF</ncm:location>
+ <ncm:identifier>opendaylight-table-types</ncm:identifier>
+ <ncm:format>yang</ncm:format>
+ <ncm:version>2013-10-26</ncm:version>
+ </ncm:schema>
+ <ncm:schema>
+ <ncm:namespace>urn:opendaylight:table:service</ncm:namespace>
+ <ncm:location>NETCONF</ncm:location>
+ <ncm:identifier>sal-table</ncm:identifier>
+ <ncm:format>yang</ncm:format>
+ <ncm:version>2013-10-26</ncm:version>
+ </ncm:schema>
+ <ncm:schema>
+ <ncm:namespace>urn:opendaylight:params:xml:ns:yang:controller:shutdown</ncm:namespace>
+ <ncm:location>NETCONF</ncm:location>
+ <ncm:identifier>shutdown</ncm:identifier>
+ <ncm:format>yang</ncm:format>
+ <ncm:version>2013-12-18</ncm:version>
+ </ncm:schema>
+ <ncm:schema>
+ <ncm:namespace>urn:opendaylight:port:service</ncm:namespace>
+ <ncm:location>NETCONF</ncm:location>
+ <ncm:identifier>sal-port</ncm:identifier>
+ <ncm:format>yang</ncm:format>
+ <ncm:version>2013-11-07</ncm:version>
+ </ncm:schema>
+ <ncm:schema>
+ <ncm:namespace>urn:opendaylight:params:xml:ns:yang:controller:netty:eventexecutor</ncm:namespace>
+ <ncm:location>NETCONF</ncm:location>
+ <ncm:identifier>netty-event-executor</ncm:identifier>
+ <ncm:format>yang</ncm:format>
+ <ncm:version>2013-11-12</ncm:version>
+ </ncm:schema>
+ <ncm:schema>
+ <ncm:namespace>urn:opendaylight:params:xml:ns:yang:controller:md:sal:remote</ncm:namespace>
+ <ncm:location>NETCONF</ncm:location>
+ <ncm:identifier>sal-remote</ncm:identifier>
+ <ncm:format>yang</ncm:format>
+ <ncm:version>2014-01-14</ncm:version>
+ </ncm:schema>
+ <ncm:schema>
+ <ncm:namespace>urn:opendaylight:model:topology:view</ncm:namespace>
+ <ncm:location>NETCONF</ncm:location>
+ <ncm:identifier>opendaylight-topology-view</ncm:identifier>
+ <ncm:format>yang</ncm:format>
+ <ncm:version>2013-10-30</ncm:version>
+ </ncm:schema>
+ <ncm:schema>
+ <ncm:namespace>urn:opendaylight:params:xml:ns:yang:controller:netty:threadgroup</ncm:namespace>
+ <ncm:location>NETCONF</ncm:location>
+ <ncm:identifier>threadgroup</ncm:identifier>
+ <ncm:format>yang</ncm:format>
+ <ncm:version>2013-11-07</ncm:version>
+ </ncm:schema>
+ <ncm:schema>
+ <ncm:namespace>urn:TBD:params:xml:ns:yang:network-topology</ncm:namespace>
+ <ncm:location>NETCONF</ncm:location>
+ <ncm:identifier>network-topology</ncm:identifier>
+ <ncm:format>yang</ncm:format>
+ <ncm:version>2013-07-12</ncm:version>
+ </ncm:schema>
+ <ncm:schema>
+ <ncm:namespace>urn:opendaylight:params:xml:ns:yang:controller:threadpool:impl:fixed</ncm:namespace>
+ <ncm:location>NETCONF</ncm:location>
+ <ncm:identifier>threadpool-impl-fixed</ncm:identifier>
+ <ncm:format>yang</ncm:format>
+ <ncm:version>2013-12-01</ncm:version>
+ </ncm:schema>
+ <ncm:schema>
+ <ncm:namespace>urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding:impl</ncm:namespace>
+ <ncm:location>NETCONF</ncm:location>
+ <ncm:identifier>opendaylight-sal-binding-broker-impl</ncm:identifier>
+ <ncm:format>yang</ncm:format>
+ <ncm:version>2013-10-28</ncm:version>
+ </ncm:schema>
+ <ncm:schema>
+ <ncm:namespace>urn:ietf:params:xml:ns:yang:ietf-restconf</ncm:namespace>
+ <ncm:location>NETCONF</ncm:location>
+ <ncm:identifier>ietf-restconf</ncm:identifier>
+ <ncm:format>yang</ncm:format>
+ <ncm:version>2013-10-19</ncm:version>
+ </ncm:schema>
+ <ncm:schema>
+ <ncm:namespace>urn:opendaylight:node:error:service</ncm:namespace>
+ <ncm:location>NETCONF</ncm:location>
+ <ncm:identifier>node-error</ncm:identifier>
+ <ncm:format>yang</ncm:format>
+ <ncm:version>2014-04-10</ncm:version>
+ </ncm:schema>
+ <ncm:schema>
+ <ncm:namespace>urn:opendaylight:flow:errors</ncm:namespace>
+ <ncm:location>NETCONF</ncm:location>
+ <ncm:identifier>flow-errors</ncm:identifier>
+ <ncm:format>yang</ncm:format>
+ <ncm:version>2013-11-16</ncm:version>
+ </ncm:schema>
+ <ncm:schema>
+ <ncm:namespace>urn:opendaylight:flow:service</ncm:namespace>
+ <ncm:location>NETCONF</ncm:location>
+ <ncm:identifier>sal-flow</ncm:identifier>
+ <ncm:format>yang</ncm:format>
+ <ncm:version>2013-08-19</ncm:version>
+ </ncm:schema>
+ <ncm:schema>
+ <ncm:namespace>urn:ietf:params:xml:ns:yang:rpc-context</ncm:namespace>
+ <ncm:location>NETCONF</ncm:location>
+ <ncm:identifier>rpc-context</ncm:identifier>
+ <ncm:format>yang</ncm:format>
+ <ncm:version>2013-06-17</ncm:version>
+ </ncm:schema>
+ <ncm:schema>
+ <ncm:namespace>urn:opendaylight:params:xml:ns:yang:controller:md:sal:core:spi:operational-dom-store
+ </ncm:namespace>
+ <ncm:location>NETCONF</ncm:location>
+ <ncm:identifier>opendaylight-operational-dom-datastore</ncm:identifier>
+ <ncm:format>yang</ncm:format>
+ <ncm:version>2014-06-17</ncm:version>
+ </ncm:schema>
+ <ncm:schema>
+ <ncm:namespace>urn:opendaylight:flow:types:queue</ncm:namespace>
+ <ncm:location>NETCONF</ncm:location>
+ <ncm:identifier>opendaylight-queue-types</ncm:identifier>
+ <ncm:format>yang</ncm:format>
+ <ncm:version>2013-09-25</ncm:version>
+ </ncm:schema>
+ <ncm:schema>
+ <ncm:namespace>urn:ietf:params:xml:ns:yang:ietf-netconf-monitoring</ncm:namespace>
+ <ncm:location>NETCONF</ncm:location>
+ <ncm:identifier>ietf-netconf-monitoring</ncm:identifier>
+ <ncm:format>yang</ncm:format>
+ <ncm:version>2010-10-04</ncm:version>
+ </ncm:schema>
+ <ncm:schema>
+ <ncm:namespace>urn:opendaylight:netconf-node-inventory</ncm:namespace>
+ <ncm:location>NETCONF</ncm:location>
+ <ncm:identifier>netconf-node-inventory</ncm:identifier>
+ <ncm:format>yang</ncm:format>
+ <ncm:version>2014-01-08</ncm:version>
+ </ncm:schema>
+ <ncm:schema>
+ <ncm:namespace>urn:ietf:params:xml:ns:yang:ietf-yang-types</ncm:namespace>
+ <ncm:location>NETCONF</ncm:location>
+ <ncm:identifier>ietf-yang-types</ncm:identifier>
+ <ncm:format>yang</ncm:format>
+ <ncm:version>2013-07-15</ncm:version>
+ </ncm:schema>
+ <ncm:schema>
+ <ncm:namespace>urn:opendaylight:meter:statistics</ncm:namespace>
+ <ncm:location>NETCONF</ncm:location>
+ <ncm:identifier>opendaylight-meter-statistics</ncm:identifier>
+ <ncm:format>yang</ncm:format>
+ <ncm:version>2013-11-11</ncm:version>
+ </ncm:schema>
+ <ncm:schema>
+ <ncm:namespace>urn:opendaylight:flow:inventory</ncm:namespace>
+ <ncm:location>NETCONF</ncm:location>
+ <ncm:identifier>flow-node-inventory</ncm:identifier>
+ <ncm:format>yang</ncm:format>
+ <ncm:version>2013-08-19</ncm:version>
+ </ncm:schema>
+ <ncm:schema>
+ <ncm:namespace>urn:opendaylight:params:xml:ns:yang:controller:md:sal:connector:netconf</ncm:namespace>
+ <ncm:location>NETCONF</ncm:location>
+ <ncm:identifier>odl-sal-netconf-connector-cfg</ncm:identifier>
+ <ncm:format>yang</ncm:format>
+ <ncm:version>2013-10-28</ncm:version>
+ </ncm:schema>
+ <ncm:schema>
+ <ncm:namespace>urn:opendaylight:params:xml:ns:yang:controller:threadpool:impl:scheduled</ncm:namespace>
+ <ncm:location>NETCONF</ncm:location>
+ <ncm:identifier>threadpool-impl-scheduled</ncm:identifier>
+ <ncm:format>yang</ncm:format>
+ <ncm:version>2013-12-01</ncm:version>
+ </ncm:schema>
+ <ncm:schema>
+ <ncm:namespace>urn:TBD:params:xml:ns:yang:network-topology</ncm:namespace>
+ <ncm:location>NETCONF</ncm:location>
+ <ncm:identifier>network-topology</ncm:identifier>
+ <ncm:format>yang</ncm:format>
+ <ncm:version>2013-10-21</ncm:version>
+ </ncm:schema>
+ <ncm:schema>
+ <ncm:namespace>http://netconfcentral.org/ns/toaster</ncm:namespace>
+ <ncm:location>NETCONF</ncm:location>
+ <ncm:identifier>toaster</ncm:identifier>
+ <ncm:format>yang</ncm:format>
+ <ncm:version>2009-11-20</ncm:version>
+ </ncm:schema>
+ <ncm:schema>
+ <ncm:namespace>urn:opendaylight:params:xml:ns:yang:controller:config:netconf</ncm:namespace>
+ <ncm:location>NETCONF</ncm:location>
+ <ncm:identifier>odl-netconf-cfg</ncm:identifier>
+ <ncm:format>yang</ncm:format>
+ <ncm:version>2014-04-08</ncm:version>
+ </ncm:schema>
+ <ncm:schema>
+ <ncm:namespace>urn:opendaylight:meter:types</ncm:namespace>
+ <ncm:location>NETCONF</ncm:location>
+ <ncm:identifier>opendaylight-meter-types</ncm:identifier>
+ <ncm:format>yang</ncm:format>
+ <ncm:version>2013-09-18</ncm:version>
+ </ncm:schema>
+ <ncm:schema>
+ <ncm:namespace>urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom:impl</ncm:namespace>
+ <ncm:location>NETCONF</ncm:location>
+ <ncm:identifier>opendaylight-sal-dom-broker-impl</ncm:identifier>
+ <ncm:format>yang</ncm:format>
+ <ncm:version>2013-10-28</ncm:version>
+ </ncm:schema>
+ <ncm:schema>
+ <ncm:namespace>urn:opendaylight:flow:topology:discovery</ncm:namespace>
+ <ncm:location>NETCONF</ncm:location>
+ <ncm:identifier>flow-topology-discovery</ncm:identifier>
+ <ncm:format>yang</ncm:format>
+ <ncm:version>2013-08-19</ncm:version>
+ </ncm:schema>
+ <ncm:schema>
+ <ncm:namespace>urn:opendaylight:yang:extension:yang-ext</ncm:namespace>
+ <ncm:location>NETCONF</ncm:location>
+ <ncm:identifier>yang-ext</ncm:identifier>
+ <ncm:format>yang</ncm:format>
+ <ncm:version>2013-07-09</ncm:version>
+ </ncm:schema>
+ <ncm:schema>
+ <ncm:namespace>urn:opendaylight:params:xml:ns:yang:controller:threadpool:impl</ncm:namespace>
+ <ncm:location>NETCONF</ncm:location>
+ <ncm:identifier>threadpool-impl</ncm:identifier>
+ <ncm:format>yang</ncm:format>
+ <ncm:version>2013-04-05</ncm:version>
+ </ncm:schema>
+ <ncm:schema>
+ <ncm:namespace>urn:opendaylight:flow:types:port</ncm:namespace>
+ <ncm:location>NETCONF</ncm:location>
+ <ncm:identifier>opendaylight-port-types</ncm:identifier>
+ <ncm:format>yang</ncm:format>
+ <ncm:version>2013-09-25</ncm:version>
+ </ncm:schema>
+ <ncm:schema>
+ <ncm:namespace>urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding</ncm:namespace>
+ <ncm:location>NETCONF</ncm:location>
+ <ncm:identifier>opendaylight-md-sal-binding</ncm:identifier>
+ <ncm:format>yang</ncm:format>
+ <ncm:version>2013-10-28</ncm:version>
+ </ncm:schema>
+ <ncm:schema>
+ <ncm:namespace>urn:opendaylight:packet:service</ncm:namespace>
+ <ncm:location>NETCONF</ncm:location>
+ <ncm:identifier>packet-processing</ncm:identifier>
+ <ncm:format>yang</ncm:format>
+ <ncm:version>2013-07-09</ncm:version>
+ </ncm:schema>
+ <ncm:schema>
+ <ncm:namespace>urn:opendaylight:params:xml:ns:yang:controller:threadpool:impl:flexible</ncm:namespace>
+ <ncm:location>NETCONF</ncm:location>
+ <ncm:identifier>threadpool-impl-flexible</ncm:identifier>
+ <ncm:format>yang</ncm:format>
+ <ncm:version>2013-12-01</ncm:version>
+ </ncm:schema>
+ <ncm:schema>
+ <ncm:namespace>urn:opendaylight:queue:service</ncm:namespace>
+ <ncm:location>NETCONF</ncm:location>
+ <ncm:identifier>sal-queue</ncm:identifier>
+ <ncm:format>yang</ncm:format>
+ <ncm:version>2013-11-07</ncm:version>
+ </ncm:schema>
+ <ncm:schema>
+ <ncm:namespace>urn:ietf:params:xml:ns:yang:ietf-inet-types</ncm:namespace>
+ <ncm:location>NETCONF</ncm:location>
+ <ncm:identifier>ietf-inet-types</ncm:identifier>
+ <ncm:format>yang</ncm:format>
+ <ncm:version>2010-09-24</ncm:version>
+ </ncm:schema>
+ <ncm:schema>
+ <ncm:namespace>urn:opendaylight:params:xml:ns:yang:controller:md:sal:rest:connector</ncm:namespace>
+ <ncm:location>NETCONF</ncm:location>
+ <ncm:identifier>opendaylight-rest-connector</ncm:identifier>
+ <ncm:format>yang</ncm:format>
+ <ncm:version>2014-07-24</ncm:version>
+ </ncm:schema>
+ <ncm:schema>
+ <ncm:namespace>urn:opendaylight:flow:transaction</ncm:namespace>
+ <ncm:location>NETCONF</ncm:location>
+ <ncm:identifier>flow-capable-transaction</ncm:identifier>
+ <ncm:format>yang</ncm:format>
+ <ncm:version>2013-11-03</ncm:version>
+ </ncm:schema>
+ <ncm:schema>
+ <ncm:namespace>urn:opendaylight:flow:statistics</ncm:namespace>
+ <ncm:location>NETCONF</ncm:location>
+ <ncm:identifier>opendaylight-flow-statistics</ncm:identifier>
+ <ncm:format>yang</ncm:format>
+ <ncm:version>2013-08-19</ncm:version>
+ </ncm:schema>
+ <ncm:schema>
+ <ncm:namespace>urn:opendaylight:params:xml:ns:yang:controller:protocol:framework</ncm:namespace>
+ <ncm:location>NETCONF</ncm:location>
+ <ncm:identifier>protocol-framework</ncm:identifier>
+ <ncm:format>yang</ncm:format>
+ <ncm:version>2014-03-13</ncm:version>
+ </ncm:schema>
+ <ncm:schema>
+ <ncm:namespace>urn:opendaylight:model:match:types</ncm:namespace>
+ <ncm:location>NETCONF</ncm:location>
+ <ncm:identifier>opendaylight-match-types</ncm:identifier>
+ <ncm:format>yang</ncm:format>
+ <ncm:version>2013-10-26</ncm:version>
+ </ncm:schema>
+ <ncm:schema>
+ <ncm:namespace>urn:ietf:params:xml:ns:yang:ietf-yang-types</ncm:namespace>
+ <ncm:location>NETCONF</ncm:location>
+ <ncm:identifier>ietf-yang-types</ncm:identifier>
+ <ncm:format>yang</ncm:format>
+ <ncm:version>2010-09-24</ncm:version>
+ </ncm:schema>
+ <ncm:schema>
+ <ncm:namespace>urn:opendaylight:group:service</ncm:namespace>
+ <ncm:location>NETCONF</ncm:location>
+ <ncm:identifier>sal-group</ncm:identifier>
+ <ncm:format>yang</ncm:format>
+ <ncm:version>2013-09-18</ncm:version>
+ </ncm:schema>
+ <ncm:schema>
+ <ncm:namespace>urn:opendaylight:params:xml:ns:yang:controller:inmemory-datastore-provider</ncm:namespace>
+ <ncm:location>NETCONF</ncm:location>
+ <ncm:identifier>opendaylight-inmemory-datastore-provider</ncm:identifier>
+ <ncm:format>yang</ncm:format>
+ <ncm:version>2014-06-17</ncm:version>
+ </ncm:schema>
+ <ncm:schema>
+ <ncm:namespace>urn:opendaylight:params:xml:ns:yang:controller:netty:timer</ncm:namespace>
+ <ncm:location>NETCONF</ncm:location>
+ <ncm:identifier>netty-timer</ncm:identifier>
+ <ncm:format>yang</ncm:format>
+ <ncm:version>2013-11-19</ncm:version>
+ </ncm:schema>
+ <ncm:schema>
+ <ncm:namespace>urn:opendaylight:group:statistics</ncm:namespace>
+ <ncm:location>NETCONF</ncm:location>
+ <ncm:identifier>opendaylight-group-statistics</ncm:identifier>
+ <ncm:format>yang</ncm:format>
+ <ncm:version>2013-11-11</ncm:version>
+ </ncm:schema>
+ <ncm:schema>
+ <ncm:namespace>urn:opendaylight:params:xml:ns:yang:controller:config</ncm:namespace>
+ <ncm:location>NETCONF</ncm:location>
+ <ncm:identifier>config</ncm:identifier>
+ <ncm:format>yang</ncm:format>
+ <ncm:version>2013-04-05</ncm:version>
+ </ncm:schema>
+ <ncm:schema>
+ <ncm:namespace>urn:opendaylight:params:xml:ns:yang:controller:config:netconf:client:dispatcher</ncm:namespace>
+ <ncm:location>NETCONF</ncm:location>
+ <ncm:identifier>odl-netconfig-client-cfg</ncm:identifier>
+ <ncm:format>yang</ncm:format>
+ <ncm:version>2014-04-08</ncm:version>
+ </ncm:schema>
+ <ncm:schema>
+ <ncm:namespace>urn:opendaylight:l2:types</ncm:namespace>
+ <ncm:location>NETCONF</ncm:location>
+ <ncm:identifier>opendaylight-l2-types</ncm:identifier>
+ <ncm:format>yang</ncm:format>
+ <ncm:version>2013-08-27</ncm:version>
+ </ncm:schema>
+ <ncm:schema>
+ <ncm:namespace>urn:opendaylight:action:types</ncm:namespace>
+ <ncm:location>NETCONF</ncm:location>
+ <ncm:identifier>opendaylight-action-types</ncm:identifier>
+ <ncm:format>yang</ncm:format>
+ <ncm:version>2013-11-12</ncm:version>
+ </ncm:schema>
+ <ncm:schema>
+ <ncm:namespace>urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom</ncm:namespace>
+ <ncm:location>NETCONF</ncm:location>
+ <ncm:identifier>opendaylight-md-sal-dom</ncm:identifier>
+ <ncm:format>yang</ncm:format>
+ <ncm:version>2013-10-28</ncm:version>
+ </ncm:schema>
+ <ncm:schema>
+ <ncm:namespace>urn:opendaylight:params:xml:ns:yang:controller:md:sal:common</ncm:namespace>
+ <ncm:location>NETCONF</ncm:location>
+ <ncm:identifier>opendaylight-md-sal-common</ncm:identifier>
+ <ncm:format>yang</ncm:format>
+ <ncm:version>2013-10-28</ncm:version>
+ </ncm:schema>
+ <ncm:schema>
+ <ncm:namespace>urn:opendaylight:group:types</ncm:namespace>
+ <ncm:location>NETCONF</ncm:location>
+ <ncm:identifier>opendaylight-group-types</ncm:identifier>
+ <ncm:format>yang</ncm:format>
+ <ncm:version>2013-10-18</ncm:version>
+ </ncm:schema>
+ <ncm:schema>
+ <ncm:namespace>urn:ietf:params:xml:ns:yang:ietf-netconf-monitoring-extension</ncm:namespace>
+ <ncm:location>NETCONF</ncm:location>
+ <ncm:identifier>ietf-netconf-monitoring-extension</ncm:identifier>
+ <ncm:format>yang</ncm:format>
+ <ncm:version>2013-12-10</ncm:version>
+ </ncm:schema>
+ <ncm:schema>
+ <ncm:namespace>urn:opendaylight:inventory</ncm:namespace>
+ <ncm:location>NETCONF</ncm:location>
+ <ncm:identifier>opendaylight-inventory</ncm:identifier>
+ <ncm:format>yang</ncm:format>
+ <ncm:version>2013-08-19</ncm:version>
+ </ncm:schema>
+ <ncm:schema>
+ <ncm:namespace>urn:opendaylight:params:xml:ns:yang:controller:netty</ncm:namespace>
+ <ncm:location>NETCONF</ncm:location>
+ <ncm:identifier>netty</ncm:identifier>
+ <ncm:format>yang</ncm:format>
+ <ncm:version>2013-11-19</ncm:version>
+ </ncm:schema>
+ <ncm:schema>
+ <ncm:namespace>urn:opendaylight:model:topology:general</ncm:namespace>
+ <ncm:location>NETCONF</ncm:location>
+ <ncm:identifier>opendaylight-topology</ncm:identifier>
+ <ncm:format>yang</ncm:format>
+ <ncm:version>2013-10-30</ncm:version>
+ </ncm:schema>
+ <ncm:schema>
+ <ncm:namespace>urn:opendaylight:port:statistics</ncm:namespace>
+ <ncm:location>NETCONF</ncm:location>
+ <ncm:identifier>opendaylight-port-statistics</ncm:identifier>
+ <ncm:format>yang</ncm:format>
+ <ncm:version></ncm:version>
+ </ncm:schema>
+ <ncm:schema>
+ <ncm:namespace>urn:opendaylight:queue:statistics</ncm:namespace>
+ <ncm:location>NETCONF</ncm:location>
+ <ncm:identifier>opendaylight-queue-statistics</ncm:identifier>
+ <ncm:format>yang</ncm:format>
+ <ncm:version>2013-12-16</ncm:version>
+ </ncm:schema>
+ <ncm:schema>
+ <ncm:namespace>urn:opendaylight:params:xml:ns:yang:controller:config:kitchen-service:impl</ncm:namespace>
+ <ncm:location>NETCONF</ncm:location>
+ <ncm:identifier>kitchen-service-impl</ncm:identifier>
+ <ncm:format>yang</ncm:format>
+ <ncm:version>2014-01-31</ncm:version>
+ </ncm:schema>
+ <ncm:schema>
+ <ncm:namespace>urn:opendaylight:flow:types</ncm:namespace>
+ <ncm:location>NETCONF</ncm:location>
+ <ncm:identifier>opendaylight-flow-types</ncm:identifier>
+ <ncm:format>yang</ncm:format>
+ <ncm:version>2013-10-26</ncm:version>
+ </ncm:schema>
+ <ncm:schema>
+ <ncm:namespace>urn:opendaylight:params:xml:ns:yang:controller:shutdown:impl</ncm:namespace>
+ <ncm:location>NETCONF</ncm:location>
+ <ncm:identifier>shutdown-impl</ncm:identifier>
+ <ncm:format>yang</ncm:format>
+ <ncm:version>2013-12-18</ncm:version>
+ </ncm:schema>
+ <ncm:schema>
+ <ncm:namespace>urn:opendaylight:model:topology:inventory</ncm:namespace>
+ <ncm:location>NETCONF</ncm:location>
+ <ncm:identifier>opendaylight-topology-inventory</ncm:identifier>
+ <ncm:format>yang</ncm:format>
+ <ncm:version>2013-10-30</ncm:version>
+ </ncm:schema>
+</ncm:schemas>
\ No newline at end of file
* @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(),
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;
}
}
-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"
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
+}