--- /dev/null
+<?xml version="1.0"?>
+<!-- vi: set et smarttab sw=4 tabstop=4: -->
+<!--
+ copyright (c) 2015 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
+-->
+<enunciate label="full" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="http://enunciate.codehaus.org/schemas/enunciate-1.28.xsd">
+</enunciate>
+
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- vi: set et smarttab sw=4 tabstop=4: -->
+<!--
+ copyright (c) 2015 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">
+
+ <parent>
+ <groupId>org.opendaylight.controller</groupId>
+ <artifactId>enunciate-parent</artifactId>
+ <version>1.5.0-SNAPSHOT</version>
+ <relativePath>../../commons/enunciate-parent</relativePath>
+ </parent>
+
+ <modelVersion>4.0.0</modelVersion>
+ <artifactId>adsal-enunciate-parent</artifactId>
+ <packaging>pom</packaging>
+
+ <build>
+ <pluginManagement>
+ <plugins>
+ <plugin>
+ <groupId>org.codehaus.enunciate</groupId>
+ <artifactId>maven-enunciate-plugin</artifactId>
+ <dependencies>
+ <dependency>
+ <groupId>org.opendaylight.controller</groupId>
+ <artifactId>sal</artifactId>
+ <version>${sal.version}</version>
+ </dependency>
+ </dependencies>
+ </plugin>
+ </plugins>
+ </pluginManagement>
+ </build>
+</project>
+
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.opendaylight.controller</groupId>
- <artifactId>commons.opendaylight</artifactId>
+ <artifactId>adsal-enunciate-parent</artifactId>
<version>1.5.0-SNAPSHOT</version>
- <relativePath>../../../commons/opendaylight</relativePath>
+ <relativePath>../../adsal-enunciate-parent</relativePath>
</parent>
<artifactId>connectionmanager.northbound</artifactId>
<manifestLocation>${project.basedir}/src/main/resources/META-INF</manifestLocation>
</configuration>
</plugin>
- <plugin>
- <groupId>org.codehaus.enunciate</groupId>
- <artifactId>maven-enunciate-plugin</artifactId>
- <dependencies>
- <dependency>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>sal</artifactId>
- <version>${sal.version}</version>
- </dependency>
- </dependencies>
- </plugin>
</plugins>
</build>
<scm>
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.opendaylight.controller</groupId>
- <artifactId>commons.opendaylight</artifactId>
+ <artifactId>enunciate-parent</artifactId>
<version>1.5.0-SNAPSHOT</version>
- <relativePath>../../../commons/opendaylight</relativePath>
+ <relativePath>../../../commons/enunciate-parent</relativePath>
</parent>
<artifactId>containermanager.northbound</artifactId>
</instructions>
</configuration>
</plugin>
- <plugin>
- <groupId>org.codehaus.enunciate</groupId>
- <artifactId>maven-enunciate-plugin</artifactId>
- </plugin>
</plugins>
</build>
<scm>
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.opendaylight.controller</groupId>
- <artifactId>commons.opendaylight</artifactId>
+ <artifactId>adsal-enunciate-parent</artifactId>
<version>1.5.0-SNAPSHOT</version>
- <relativePath>../../../commons/opendaylight</relativePath>
+ <relativePath>../../adsal-enunciate-parent</relativePath>
</parent>
<artifactId>controllermanager.northbound</artifactId>
<version>0.1.0-SNAPSHOT</version>
<manifestLocation>${project.basedir}/src/main/resources/META-INF</manifestLocation>
</configuration>
</plugin>
- <plugin>
- <groupId>org.codehaus.enunciate</groupId>
- <artifactId>maven-enunciate-plugin</artifactId>
- <dependencies>
- <dependency>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>sal</artifactId>
- <version>${sal.version}</version>
- </dependency>
- </dependencies>
- </plugin>
</plugins>
</build>
<scm>
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.opendaylight.controller</groupId>
- <artifactId>commons.opendaylight</artifactId>
+ <artifactId>adsal-enunciate-parent</artifactId>
<version>1.5.0-SNAPSHOT</version>
- <relativePath>../../../commons/opendaylight</relativePath>
+ <relativePath>../../adsal-enunciate-parent</relativePath>
</parent>
<artifactId>flowprogrammer.northbound</artifactId>
<manifestLocation>${project.basedir}/src/main/resources/META-INF</manifestLocation>
</configuration>
</plugin>
- <plugin>
- <groupId>org.codehaus.enunciate</groupId>
- <artifactId>maven-enunciate-plugin</artifactId>
- <dependencies>
- <dependency>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>sal</artifactId>
- <version>${sal.version}</version>
- </dependency>
- </dependencies>
- </plugin>
</plugins>
</build>
<scm>
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.opendaylight.controller</groupId>
- <artifactId>commons.opendaylight</artifactId>
+ <artifactId>adsal-enunciate-parent</artifactId>
<version>1.5.0-SNAPSHOT</version>
- <relativePath>../../../commons/opendaylight</relativePath>
+ <relativePath>../../adsal-enunciate-parent</relativePath>
</parent>
<artifactId>hosttracker.northbound</artifactId>
<version>0.5.0-SNAPSHOT</version>
<manifestLocation>${project.basedir}/src/main/resources/META-INF</manifestLocation>
</configuration>
</plugin>
- <plugin>
- <groupId>org.codehaus.enunciate</groupId>
- <artifactId>maven-enunciate-plugin</artifactId>
- <dependencies>
- <dependency>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>sal</artifactId>
- <version>${sal.version}</version>
- </dependency>
- </dependencies>
- </plugin>
</plugins>
</build>
<scm>
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.opendaylight.controller</groupId>
- <artifactId>commons.opendaylight</artifactId>
+ <artifactId>enunciate-parent</artifactId>
<version>1.5.0-SNAPSHOT</version>
- <relativePath>../../../commons/opendaylight</relativePath>
+ <relativePath>../../../commons/enunciate-parent</relativePath>
</parent>
<artifactId>northbound.client</artifactId>
</execution>
</executions>
</plugin>
- <plugin>
- <groupId>org.codehaus.enunciate</groupId>
- <artifactId>maven-enunciate-plugin</artifactId>
- </plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.opendaylight.controller</groupId>
- <artifactId>commons.opendaylight</artifactId>
+ <artifactId>adsal-enunciate-parent</artifactId>
<version>1.5.0-SNAPSHOT</version>
- <relativePath>../../../../commons/opendaylight</relativePath>
+ <relativePath>../../../adsal-enunciate-parent</relativePath>
</parent>
<artifactId>networkconfig.bridgedomain.northbound</artifactId>
<manifestLocation>${project.basedir}/src/main/resources/META-INF</manifestLocation>
</configuration>
</plugin>
- <plugin>
- <groupId>org.codehaus.enunciate</groupId>
- <artifactId>maven-enunciate-plugin</artifactId>
- <dependencies>
- <dependency>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>sal</artifactId>
- <version>${sal.version}</version>
- </dependency>
- </dependencies>
- </plugin>
</plugins>
</build>
<scm>
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.opendaylight.controller</groupId>
- <artifactId>commons.opendaylight</artifactId>
+ <artifactId>adsal-enunciate-parent</artifactId>
<version>1.5.0-SNAPSHOT</version>
- <relativePath>../../../commons/opendaylight</relativePath>
+ <relativePath>../../adsal-enunciate-parent</relativePath>
</parent>
<artifactId>forwarding.staticrouting.northbound</artifactId>
<manifestLocation>${project.basedir}/src/main/resources/META-INF</manifestLocation>
</configuration>
</plugin>
- <plugin>
- <groupId>org.codehaus.enunciate</groupId>
- <artifactId>maven-enunciate-plugin</artifactId>
- <dependencies>
- <dependency>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>sal</artifactId>
- <version>${sal.version}</version>
- </dependency>
- </dependencies>
- </plugin>
</plugins>
</build>
<scm>
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.opendaylight.controller</groupId>
- <artifactId>commons.opendaylight</artifactId>
+ <artifactId>adsal-enunciate-parent</artifactId>
<version>1.5.0-SNAPSHOT</version>
- <relativePath>../../../commons/opendaylight</relativePath>
+ <relativePath>../../adsal-enunciate-parent</relativePath>
</parent>
<artifactId>statistics.northbound</artifactId>
<manifestLocation>${project.basedir}/src/main/resources/META-INF</manifestLocation>
</configuration>
</plugin>
- <plugin>
- <groupId>org.codehaus.enunciate</groupId>
- <artifactId>maven-enunciate-plugin</artifactId>
- <dependencies>
- <dependency>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>sal</artifactId>
- <version>${sal.version}</version>
- </dependency>
- </dependencies>
- </plugin>
</plugins>
</build>
<scm>
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.opendaylight.controller</groupId>
- <artifactId>commons.opendaylight</artifactId>
+ <artifactId>adsal-enunciate-parent</artifactId>
<version>1.5.0-SNAPSHOT</version>
- <relativePath>../../../commons/opendaylight</relativePath>
+ <relativePath>../../adsal-enunciate-parent</relativePath>
</parent>
<artifactId>subnets.northbound</artifactId>
</dependency>
</dependencies>
<build>
+ <pluginManagement>
+ <plugins>
+ <plugin>
+ <groupId>org.codehaus.enunciate</groupId>
+ <artifactId>maven-enunciate-plugin</artifactId>
+ <dependencies>
+ <dependency>
+ <groupId>org.opendaylight.controller</groupId>
+ <artifactId>clustering.services</artifactId>
+ <version>${clustering.services.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.opendaylight.controller</groupId>
+ <artifactId>configuration</artifactId>
+ <version>${configuration.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.opendaylight.controller</groupId>
+ <artifactId>sal</artifactId>
+ <version>${sal.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.opendaylight.controller</groupId>
+ <artifactId>switchmanager</artifactId>
+ <version>${switchmanager.api.version}</version>
+ </dependency>
+ </dependencies>
+ </plugin>
+ </plugins>
+ </pluginManagement>
<plugins>
<plugin>
<groupId>org.apache.felix</groupId>
<manifestLocation>${project.basedir}/src/main/resources/META-INF</manifestLocation>
</configuration>
</plugin>
- <plugin>
- <groupId>org.codehaus.enunciate</groupId>
- <artifactId>maven-enunciate-plugin</artifactId>
- <dependencies>
- <dependency>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>clustering.services</artifactId>
- <version>${clustering.services.version}</version>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>configuration</artifactId>
- <version>${configuration.version}</version>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>sal</artifactId>
- <version>${sal.version}</version>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>switchmanager</artifactId>
- <version>${switchmanager.api.version}</version>
- </dependency>
- </dependencies>
- </plugin>
</plugins>
</build>
<scm>
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.opendaylight.controller</groupId>
- <artifactId>commons.opendaylight</artifactId>
+ <artifactId>adsal-enunciate-parent</artifactId>
<version>1.5.0-SNAPSHOT</version>
- <relativePath>../../../commons/opendaylight</relativePath>
+ <relativePath>../../adsal-enunciate-parent</relativePath>
</parent>
<artifactId>switchmanager.northbound</artifactId>
<version>0.5.0-SNAPSHOT</version>
<manifestLocation>${project.basedir}/src/main/resources/META-INF</manifestLocation>
</configuration>
</plugin>
- <plugin>
- <groupId>org.codehaus.enunciate</groupId>
- <artifactId>maven-enunciate-plugin</artifactId>
- <dependencies>
- <dependency>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>sal</artifactId>
- <version>${sal.version}</version>
- </dependency>
- </dependencies>
- </plugin>
</plugins>
</build>
<scm>
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.opendaylight.controller</groupId>
- <artifactId>commons.opendaylight</artifactId>
+ <artifactId>adsal-enunciate-parent</artifactId>
<version>1.5.0-SNAPSHOT</version>
- <relativePath>../../../commons/opendaylight</relativePath>
+ <relativePath>../../adsal-enunciate-parent</relativePath>
</parent>
<artifactId>topology.northbound</artifactId>
<manifestLocation>${project.basedir}/src/main/resources/META-INF</manifestLocation>
</configuration>
</plugin>
- <plugin>
- <groupId>org.codehaus.enunciate</groupId>
- <artifactId>maven-enunciate-plugin</artifactId>
- <dependencies>
- <dependency>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>sal</artifactId>
- <version>${sal.version}</version>
- </dependency>
- </dependencies>
- </plugin>
</plugins>
</build>
<scm>
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.opendaylight.controller</groupId>
- <artifactId>commons.opendaylight</artifactId>
+ <artifactId>enunciate-parent</artifactId>
<version>1.5.0-SNAPSHOT</version>
- <relativePath>../../../commons/opendaylight</relativePath>
+ <relativePath>../../../commons/enunciate-parent</relativePath>
</parent>
<artifactId>usermanager.northbound</artifactId>
<manifestLocation>${project.basedir}/src/main/resources/META-INF</manifestLocation>
</configuration>
</plugin>
- <plugin>
- <groupId>org.codehaus.enunciate</groupId>
- <artifactId>maven-enunciate-plugin</artifactId>
- </plugin>
</plugins>
</build>
<scm>
<module>samples/northbound/loadbalancer</module>
<module>dummy-console</module>
+ <module>adsal-enunciate-parent</module>
<!-- features -->
<module>features/base</module>
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.opendaylight.controller</groupId>
- <artifactId>commons.opendaylight</artifactId>
+ <artifactId>adsal-enunciate-parent</artifactId>
<version>1.5.0-SNAPSHOT</version>
- <relativePath>../../../../commons/opendaylight</relativePath>
+ <relativePath>../../../adsal-enunciate-parent</relativePath>
</parent>
<artifactId>samples.loadbalancer.northbound</artifactId>
<manifestLocation>${project.basedir}/src/main/resources/META-INF</manifestLocation>
</configuration>
</plugin>
- <plugin>
- <groupId>org.codehaus.enunciate</groupId>
- <artifactId>maven-enunciate-plugin</artifactId>
- <dependencies>
- <dependency>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>sal</artifactId>
- <version>${sal.version}</version>
- </dependency>
- </dependencies>
- </plugin>
</plugins>
</build>
<scm>
--- /dev/null
+<?xml version="1.0"?>
+<!-- vi: set et smarttab sw=4 tabstop=4: -->
+<!--
+ copyright (c) 2015 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
+-->
+<enunciate label="full" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="http://enunciate.codehaus.org/schemas/enunciate-1.28.xsd">
+</enunciate>
+
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- vi: set et smarttab sw=4 tabstop=4: -->
+<!--
+ copyright (c) 2015 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">
+
+ <parent>
+ <groupId>org.opendaylight.controller</groupId>
+ <artifactId>commons.opendaylight</artifactId>
+ <version>1.5.0-SNAPSHOT</version>
+ <relativePath>../opendaylight</relativePath>
+ </parent>
+
+ <modelVersion>4.0.0</modelVersion>
+ <artifactId>enunciate-parent</artifactId>
+ <packaging>pom</packaging>
+
+ <!-- enunciate plugin does not work with JDK8 onwards -->
+ <profiles>
+ <profile>
+ <id>non-java8</id>
+ <activation>
+ <jdk>1.7</jdk>
+ </activation>
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.codehaus.enunciate</groupId>
+ <artifactId>maven-enunciate-plugin</artifactId>
+ </plugin>
+ </plugins>
+ </build>
+ </profile>
+ </profiles>
+</project>
+
import java.util.concurrent.TimeoutException;
import org.junit.After;
import org.junit.Assert;
+import org.junit.Before;
import org.junit.Test;
import org.opendaylight.controller.cluster.DataPersistenceProvider;
import org.opendaylight.controller.cluster.datastore.DataPersistenceProviderMonitor;
public class RaftActorTest extends AbstractActorTest {
+ private TestActorFactory factory;
+
+ @Before
+ public void setUp(){
+ factory = new TestActorFactory(getSystem());
+ }
@After
- public void tearDown() {
+ public void tearDown() throws Exception {
+ factory.close();
MockAkkaJournal.clearJournal();
MockSnapshotStore.setMockSnapshot(null);
}
@Test
public void testRaftActorRecovery() throws Exception {
new JavaTestKit(getSystem()) {{
- String persistenceId = "follower10";
+ String persistenceId = factory.generateActorId("follower-");
DefaultConfigParamsImpl config = new DefaultConfigParamsImpl();
// Set the heartbeat interval high to essentially disable election otherwise the test
// log entry.
config.setHeartBeatInterval(new FiniteDuration(1, TimeUnit.DAYS));
- ActorRef followerActor = getSystem().actorOf(MockRaftActor.props(persistenceId,
- Collections.<String,String>emptyMap(), Optional.<ConfigParams>of(config)), persistenceId);
+ ActorRef followerActor = factory.createActor(MockRaftActor.props(persistenceId,
+ Collections.<String, String>emptyMap(), Optional.<ConfigParams>of(config)), persistenceId);
watch(followerActor);
int lastAppliedDuringSnapshotCapture = 3;
int lastIndexDuringSnapshotCapture = 4;
- // 4 messages as part of snapshot, which are applied to state
- ByteString snapshotBytes = fromObject(Arrays.asList(
+ // 4 messages as part of snapshot, which are applied to state
+ ByteString snapshotBytes = fromObject(Arrays.asList(
new MockRaftActorContext.MockPayload("A"),
new MockRaftActorContext.MockPayload("B"),
new MockRaftActorContext.MockPayload("C"),
new MockRaftActorContext.MockPayload("D")));
Snapshot snapshot = Snapshot.create(snapshotBytes.toByteArray(),
- snapshotUnappliedEntries, lastIndexDuringSnapshotCapture, 1 ,
+ snapshotUnappliedEntries, lastIndexDuringSnapshotCapture, 1,
lastAppliedDuringSnapshotCapture, 1);
MockSnapshotStore.setMockSnapshot(snapshot);
MockSnapshotStore.setPersistenceId(persistenceId);
unwatch(followerActor);
//reinstate the actor
- TestActorRef<MockRaftActor> ref = TestActorRef.create(getSystem(),
- MockRaftActor.props(persistenceId, Collections.<String,String>emptyMap(),
+ TestActorRef<MockRaftActor> ref = factory.createTestActor(
+ MockRaftActor.props(persistenceId, Collections.<String, String>emptyMap(),
Optional.<ConfigParams>of(config)));
ref.underlyingActor().waitForRecoveryComplete();
public void testHandleRecoveryWhenDataPersistenceRecoveryApplicable() throws Exception {
new JavaTestKit(getSystem()) {
{
- String persistenceId = "testHandleRecoveryWhenDataPersistenceRecoveryApplicable";
+ String persistenceId = factory.generateActorId("leader-");
DefaultConfigParamsImpl config = new DefaultConfigParamsImpl();
config.setHeartBeatInterval(new FiniteDuration(1, TimeUnit.DAYS));
- TestActorRef<MockRaftActor> mockActorRef = TestActorRef.create(getSystem(), MockRaftActor.props(persistenceId,
- Collections.<String,String>emptyMap(), Optional.<ConfigParams>of(config)), persistenceId);
+ TestActorRef<MockRaftActor> mockActorRef = factory.createTestActor(MockRaftActor.props(persistenceId,
+ Collections.<String, String>emptyMap(), Optional.<ConfigParams>of(config)), persistenceId);
MockRaftActor mockRaftActor = mockActorRef.underlyingActor();
// Wait for akka's recovery to complete so it doesn't interfere.
mockRaftActor.waitForRecoveryComplete();
- ByteString snapshotBytes = fromObject(Arrays.asList(
+ ByteString snapshotBytes = fromObject(Arrays.asList(
new MockRaftActorContext.MockPayload("A"),
new MockRaftActorContext.MockPayload("B"),
new MockRaftActorContext.MockPayload("C"),
new MockRaftActorContext.MockPayload("D")));
Snapshot snapshot = Snapshot.create(snapshotBytes.toByteArray(),
- Lists.<ReplicatedLogEntry>newArrayList(), 3, 1 ,3, 1);
+ Lists.<ReplicatedLogEntry>newArrayList(), 3, 1, 3, 1);
mockRaftActor.onReceiveRecover(new SnapshotOffer(new SnapshotMetadata(persistenceId, 100, 100), snapshot));
mockRaftActor.onReceiveRecover(mock(RecoveryCompleted.class));
- mockActorRef.tell(PoisonPill.getInstance(), getRef());
-
}};
}
public void testHandleRecoveryWhenDataPersistenceRecoveryNotApplicable() throws Exception {
new JavaTestKit(getSystem()) {
{
- String persistenceId = "testHandleRecoveryWhenDataPersistenceRecoveryNotApplicable";
+ String persistenceId = factory.generateActorId("leader-");
DefaultConfigParamsImpl config = new DefaultConfigParamsImpl();
config.setHeartBeatInterval(new FiniteDuration(1, TimeUnit.DAYS));
- TestActorRef<MockRaftActor> mockActorRef = TestActorRef.create(getSystem(), MockRaftActor.props(persistenceId,
- Collections.<String,String>emptyMap(), Optional.<ConfigParams>of(config), new DataPersistenceProviderMonitor()), persistenceId);
+ TestActorRef<MockRaftActor> mockActorRef = factory.createTestActor(MockRaftActor.props(persistenceId,
+ Collections.<String, String>emptyMap(), Optional.<ConfigParams>of(config), new DataPersistenceProviderMonitor()), persistenceId);
MockRaftActor mockRaftActor = mockActorRef.underlyingActor();
// Wait for akka's recovery to complete so it doesn't interfere.
mockRaftActor.waitForRecoveryComplete();
- ByteString snapshotBytes = fromObject(Arrays.asList(
+ ByteString snapshotBytes = fromObject(Arrays.asList(
new MockRaftActorContext.MockPayload("A"),
new MockRaftActorContext.MockPayload("B"),
new MockRaftActorContext.MockPayload("C"),
new MockRaftActorContext.MockPayload("D")));
Snapshot snapshot = Snapshot.create(snapshotBytes.toByteArray(),
- Lists.<ReplicatedLogEntry>newArrayList(), 3, 1 ,3, 1);
+ Lists.<ReplicatedLogEntry>newArrayList(), 3, 1, 3, 1);
mockRaftActor.onReceiveRecover(new SnapshotOffer(new SnapshotMetadata(persistenceId, 100, 100), snapshot));
mockRaftActor.onReceiveRecover(mock(RecoveryCompleted.class));
- mockActorRef.tell(PoisonPill.getInstance(), getRef());
}};
}
public void testUpdatingElectionTermCallsDataPersistence() throws Exception {
new JavaTestKit(getSystem()) {
{
- String persistenceId = "testUpdatingElectionTermCallsDataPersistence";
+ String persistenceId = factory.generateActorId("leader-");
DefaultConfigParamsImpl config = new DefaultConfigParamsImpl();
DataPersistenceProviderMonitor dataPersistenceProviderMonitor = new DataPersistenceProviderMonitor();
dataPersistenceProviderMonitor.setPersistLatch(persistLatch);
- TestActorRef<MockRaftActor> mockActorRef = TestActorRef.create(getSystem(), MockRaftActor.props(persistenceId,
- Collections.<String,String>emptyMap(), Optional.<ConfigParams>of(config), dataPersistenceProviderMonitor), persistenceId);
+ TestActorRef<MockRaftActor> mockActorRef = factory.createTestActor(MockRaftActor.props(persistenceId,
+ Collections.<String, String>emptyMap(), Optional.<ConfigParams>of(config), dataPersistenceProviderMonitor), persistenceId);
MockRaftActor mockRaftActor = mockActorRef.underlyingActor();
assertEquals("Persist called", true, persistLatch.await(5, TimeUnit.SECONDS));
- mockActorRef.tell(PoisonPill.getInstance(), getRef());
-
}
+
};
}
public void testAddingReplicatedLogEntryCallsDataPersistence() throws Exception {
new JavaTestKit(getSystem()) {
{
- String persistenceId = "testAddingReplicatedLogEntryCallsDataPersistence";
+ String persistenceId = factory.generateActorId("leader-");
DefaultConfigParamsImpl config = new DefaultConfigParamsImpl();
DataPersistenceProvider dataPersistenceProvider = mock(DataPersistenceProvider.class);
- TestActorRef<MockRaftActor> mockActorRef = TestActorRef.create(getSystem(), MockRaftActor.props(persistenceId,
- Collections.<String,String>emptyMap(), Optional.<ConfigParams>of(config), dataPersistenceProvider), persistenceId);
+ TestActorRef<MockRaftActor> mockActorRef = factory.createTestActor(MockRaftActor.props(persistenceId,
+ Collections.<String, String>emptyMap(), Optional.<ConfigParams>of(config), dataPersistenceProvider), persistenceId);
MockRaftActor mockRaftActor = mockActorRef.underlyingActor();
verify(dataPersistenceProvider).persist(eq(logEntry), any(Procedure.class));
- mockActorRef.tell(PoisonPill.getInstance(), getRef());
-
}
+
};
}
public void testRemovingReplicatedLogEntryCallsDataPersistence() throws Exception {
new JavaTestKit(getSystem()) {
{
- String persistenceId = "testRemovingReplicatedLogEntryCallsDataPersistence";
+ String persistenceId = factory.generateActorId("leader-");
DefaultConfigParamsImpl config = new DefaultConfigParamsImpl();
DataPersistenceProvider dataPersistenceProvider = mock(DataPersistenceProvider.class);
- TestActorRef<MockRaftActor> mockActorRef = TestActorRef.create(getSystem(), MockRaftActor.props(persistenceId,
- Collections.<String,String>emptyMap(), Optional.<ConfigParams>of(config), dataPersistenceProvider), persistenceId);
+ TestActorRef<MockRaftActor> mockActorRef = factory.createTestActor(MockRaftActor.props(persistenceId,
+ Collections.<String, String>emptyMap(), Optional.<ConfigParams>of(config), dataPersistenceProvider), persistenceId);
MockRaftActor mockRaftActor = mockActorRef.underlyingActor();
verify(dataPersistenceProvider, times(2)).persist(anyObject(), any(Procedure.class));
- mockActorRef.tell(PoisonPill.getInstance(), getRef());
-
}
+
};
}
public void testApplyLogEntriesCallsDataPersistence() throws Exception {
new JavaTestKit(getSystem()) {
{
- String persistenceId = "testApplyLogEntriesCallsDataPersistence";
+ String persistenceId = factory.generateActorId("leader-");
DefaultConfigParamsImpl config = new DefaultConfigParamsImpl();
DataPersistenceProvider dataPersistenceProvider = mock(DataPersistenceProvider.class);
- TestActorRef<MockRaftActor> mockActorRef = TestActorRef.create(getSystem(), MockRaftActor.props(persistenceId,
- Collections.<String,String>emptyMap(), Optional.<ConfigParams>of(config), dataPersistenceProvider), persistenceId);
+ TestActorRef<MockRaftActor> mockActorRef = factory.createTestActor(MockRaftActor.props(persistenceId,
+ Collections.<String, String>emptyMap(), Optional.<ConfigParams>of(config), dataPersistenceProvider), persistenceId);
MockRaftActor mockRaftActor = mockActorRef.underlyingActor();
verify(dataPersistenceProvider, times(1)).persist(anyObject(), any(Procedure.class));
- mockActorRef.tell(PoisonPill.getInstance(), getRef());
-
}
+
};
}
public void testCaptureSnapshotReplyCallsDataPersistence() throws Exception {
new JavaTestKit(getSystem()) {
{
- String persistenceId = "testCaptureSnapshotReplyCallsDataPersistence";
+ String persistenceId = factory.generateActorId("leader-");
DefaultConfigParamsImpl config = new DefaultConfigParamsImpl();
DataPersistenceProvider dataPersistenceProvider = mock(DataPersistenceProvider.class);
- TestActorRef<MockRaftActor> mockActorRef = TestActorRef.create(getSystem(),
- MockRaftActor.props(persistenceId,Collections.<String,String>emptyMap(),
- Optional.<ConfigParams>of(config), dataPersistenceProvider), persistenceId);
+ TestActorRef<MockRaftActor> mockActorRef = factory.createTestActor(
+ MockRaftActor.props(persistenceId, Collections.<String, String>emptyMap(),
+ Optional.<ConfigParams>of(config), dataPersistenceProvider), persistenceId);
MockRaftActor mockRaftActor = mockActorRef.underlyingActor();
- ByteString snapshotBytes = fromObject(Arrays.asList(
+ ByteString snapshotBytes = fromObject(Arrays.asList(
new MockRaftActorContext.MockPayload("A"),
new MockRaftActorContext.MockPayload("B"),
new MockRaftActorContext.MockPayload("C"),
new MockRaftActorContext.MockPayload("D")));
- mockRaftActor.onReceiveCommand(new CaptureSnapshot(-1,1,-1,1));
+ mockRaftActor.onReceiveCommand(new CaptureSnapshot(-1, 1, -1, 1));
RaftActorContext raftActorContext = mockRaftActor.getRaftActorContext();
verify(dataPersistenceProvider).saveSnapshot(anyObject());
- mockActorRef.tell(PoisonPill.getInstance(), getRef());
-
}
};
}
public void testSaveSnapshotSuccessCallsDataPersistence() throws Exception {
new JavaTestKit(getSystem()) {
{
- String persistenceId = "testSaveSnapshotSuccessCallsDataPersistence";
+ String persistenceId = factory.generateActorId("leader-");
DefaultConfigParamsImpl config = new DefaultConfigParamsImpl();
DataPersistenceProvider dataPersistenceProvider = mock(DataPersistenceProvider.class);
- TestActorRef<MockRaftActor> mockActorRef = TestActorRef.create(getSystem(), MockRaftActor.props(persistenceId,
- Collections.<String,String>emptyMap(), Optional.<ConfigParams>of(config), dataPersistenceProvider), persistenceId);
+ TestActorRef<MockRaftActor> mockActorRef = factory.createTestActor(MockRaftActor.props(persistenceId,
+ Collections.<String, String>emptyMap(), Optional.<ConfigParams>of(config), dataPersistenceProvider), persistenceId);
MockRaftActor mockRaftActor = mockActorRef.underlyingActor();
- mockRaftActor.getReplicatedLog().append(new MockRaftActorContext.MockReplicatedLogEntry(1,0, mock(Payload.class)));
- mockRaftActor.getReplicatedLog().append(new MockRaftActorContext.MockReplicatedLogEntry(1,1, mock(Payload.class)));
- mockRaftActor.getReplicatedLog().append(new MockRaftActorContext.MockReplicatedLogEntry(1,2, mock(Payload.class)));
- mockRaftActor.getReplicatedLog().append(new MockRaftActorContext.MockReplicatedLogEntry(1,3, mock(Payload.class)));
- mockRaftActor.getReplicatedLog().append(new MockRaftActorContext.MockReplicatedLogEntry(1,4, mock(Payload.class)));
+ mockRaftActor.getReplicatedLog().append(new MockRaftActorContext.MockReplicatedLogEntry(1, 0, mock(Payload.class)));
+ mockRaftActor.getReplicatedLog().append(new MockRaftActorContext.MockReplicatedLogEntry(1, 1, mock(Payload.class)));
+ mockRaftActor.getReplicatedLog().append(new MockRaftActorContext.MockReplicatedLogEntry(1, 2, mock(Payload.class)));
+ mockRaftActor.getReplicatedLog().append(new MockRaftActorContext.MockReplicatedLogEntry(1, 3, mock(Payload.class)));
+ mockRaftActor.getReplicatedLog().append(new MockRaftActorContext.MockReplicatedLogEntry(1, 4, mock(Payload.class)));
ByteString snapshotBytes = fromObject(Arrays.asList(
new MockRaftActorContext.MockPayload("A"),
// Index 2 will not be in the log because it was removed due to snapshotting
assertNull(mockRaftActor.getReplicatedLog().get(2));
- mockActorRef.tell(PoisonPill.getInstance(), getRef());
-
}
};
}
new JavaTestKit(getSystem()) {
{
- String persistenceId = "testApplyState";
+ String persistenceId = factory.generateActorId("leader-");
DefaultConfigParamsImpl config = new DefaultConfigParamsImpl();
DataPersistenceProvider dataPersistenceProvider = mock(DataPersistenceProvider.class);
- TestActorRef<MockRaftActor> mockActorRef = TestActorRef.create(getSystem(), MockRaftActor.props(persistenceId,
- Collections.<String,String>emptyMap(), Optional.<ConfigParams>of(config), dataPersistenceProvider), persistenceId);
+ TestActorRef<MockRaftActor> mockActorRef = factory.createTestActor(MockRaftActor.props(persistenceId,
+ Collections.<String, String>emptyMap(), Optional.<ConfigParams>of(config), dataPersistenceProvider), persistenceId);
MockRaftActor mockRaftActor = mockActorRef.underlyingActor();
verify(mockRaftActor.delegate).applyState(eq(mockActorRef), eq("apply-state"), anyObject());
- mockActorRef.tell(PoisonPill.getInstance(), getRef());
-
}
};
}
public void testApplySnapshot() throws Exception {
new JavaTestKit(getSystem()) {
{
- String persistenceId = "testApplySnapshot";
+ String persistenceId = factory.generateActorId("leader-");
DefaultConfigParamsImpl config = new DefaultConfigParamsImpl();
DataPersistenceProviderMonitor dataPersistenceProviderMonitor = new DataPersistenceProviderMonitor();
- TestActorRef<MockRaftActor> mockActorRef = TestActorRef.create(getSystem(), MockRaftActor.props(persistenceId,
- Collections.<String,String>emptyMap(), Optional.<ConfigParams>of(config), dataPersistenceProviderMonitor), persistenceId);
+ TestActorRef<MockRaftActor> mockActorRef = factory.createTestActor(MockRaftActor.props(persistenceId,
+ Collections.<String, String>emptyMap(), Optional.<ConfigParams>of(config), dataPersistenceProviderMonitor), persistenceId);
MockRaftActor mockRaftActor = mockActorRef.underlyingActor();
ReplicatedLog oldReplicatedLog = mockRaftActor.getReplicatedLog();
- oldReplicatedLog.append(new MockRaftActorContext.MockReplicatedLogEntry(1,0,mock(Payload.class)));
- oldReplicatedLog.append(new MockRaftActorContext.MockReplicatedLogEntry(1,1,mock(Payload.class)));
+ oldReplicatedLog.append(new MockRaftActorContext.MockReplicatedLogEntry(1, 0, mock(Payload.class)));
+ oldReplicatedLog.append(new MockRaftActorContext.MockReplicatedLogEntry(1, 1, mock(Payload.class)));
oldReplicatedLog.append(
- new MockRaftActorContext.MockReplicatedLogEntry(1, 2,
- mock(Payload.class)));
+ new MockRaftActorContext.MockReplicatedLogEntry(1, 2,
+ mock(Payload.class)));
ByteString snapshotBytes = fromObject(Arrays.asList(
- new MockRaftActorContext.MockPayload("A"),
- new MockRaftActorContext.MockPayload("B"),
- new MockRaftActorContext.MockPayload("C"),
- new MockRaftActorContext.MockPayload("D")));
+ new MockRaftActorContext.MockPayload("A"),
+ new MockRaftActorContext.MockPayload("B"),
+ new MockRaftActorContext.MockPayload("C"),
+ new MockRaftActorContext.MockPayload("D")));
Snapshot snapshot = mock(Snapshot.class);
verify(mockRaftActor.delegate).applySnapshot(eq(snapshot.getState()));
assertTrue("The replicatedLog should have changed",
- oldReplicatedLog != mockRaftActor.getReplicatedLog());
+ oldReplicatedLog != mockRaftActor.getReplicatedLog());
assertEquals("lastApplied should be same as in the snapshot",
- (Long) 3L, mockRaftActor.getLastApplied());
+ (Long) 3L, mockRaftActor.getLastApplied());
assertEquals(0, mockRaftActor.getReplicatedLog().size());
- mockActorRef.tell(PoisonPill.getInstance(), getRef());
-
}
};
}
public void testSaveSnapshotFailure() throws Exception {
new JavaTestKit(getSystem()) {
{
- String persistenceId = "testSaveSnapshotFailure";
+ String persistenceId = factory.generateActorId("leader-");
DefaultConfigParamsImpl config = new DefaultConfigParamsImpl();
DataPersistenceProviderMonitor dataPersistenceProviderMonitor = new DataPersistenceProviderMonitor();
- TestActorRef<MockRaftActor> mockActorRef = TestActorRef.create(getSystem(), MockRaftActor.props(persistenceId,
- Collections.<String,String>emptyMap(), Optional.<ConfigParams>of(config), dataPersistenceProviderMonitor), persistenceId);
+ TestActorRef<MockRaftActor> mockActorRef = factory.createTestActor(MockRaftActor.props(persistenceId,
+ Collections.<String, String>emptyMap(), Optional.<ConfigParams>of(config), dataPersistenceProviderMonitor), persistenceId);
MockRaftActor mockRaftActor = mockActorRef.underlyingActor();
- ByteString snapshotBytes = fromObject(Arrays.asList(
+ ByteString snapshotBytes = fromObject(Arrays.asList(
new MockRaftActorContext.MockPayload("A"),
new MockRaftActorContext.MockPayload("B"),
new MockRaftActorContext.MockPayload("C"),
mockRaftActor.setCurrentBehavior(new Leader(raftActorContext));
- mockRaftActor.onReceiveCommand(new CaptureSnapshot(-1,1,-1,1));
+ mockRaftActor.onReceiveCommand(new CaptureSnapshot(-1, 1, -1, 1));
mockRaftActor.onReceiveCommand(new CaptureSnapshotReply(snapshotBytes.toByteArray()));
assertEquals("Snapshot index should not have advanced because save snapshot failed", -1,
mockRaftActor.getReplicatedLog().getSnapshotIndex());
- mockActorRef.tell(PoisonPill.getInstance(), getRef());
-
}
};
}
@Test
public void testRaftRoleChangeNotifier() throws Exception {
new JavaTestKit(getSystem()) {{
- ActorRef notifierActor = getSystem().actorOf(Props.create(MessageCollectorActor.class));
+ ActorRef notifierActor = factory.createActor(Props.create(MessageCollectorActor.class));
DefaultConfigParamsImpl config = new DefaultConfigParamsImpl();
- String id = "testRaftRoleChangeNotifier";
+ String persistenceId = factory.generateActorId("notifier-");
- TestActorRef<MockRaftActor> mockActorRef = TestActorRef.create(getSystem(), MockRaftActor.props(id,
- Collections.<String,String>emptyMap(), Optional.<ConfigParams>of(config), notifierActor), id);
+ factory.createTestActor(MockRaftActor.props(persistenceId,
+ Collections.<String, String>emptyMap(), Optional.<ConfigParams>of(config), notifierActor), persistenceId);
// sleeping for a minimum of 2 seconds, if it spans more its fine.
Uninterruptibles.sleepUninterruptibly(2, TimeUnit.SECONDS);
- List<Object> matches = MessageCollectorActor.getAllMatching(notifierActor, RoleChanged.class);
+ List<Object> matches = MessageCollectorActor.getAllMatching(notifierActor, RoleChanged.class);
assertNotNull(matches);
assertEquals(3, matches.size());
// check if the notifier got a role change from null to Follower
RoleChanged raftRoleChanged = (RoleChanged) matches.get(0);
- assertEquals(id, raftRoleChanged.getMemberId());
+ assertEquals(persistenceId, raftRoleChanged.getMemberId());
assertNull(raftRoleChanged.getOldRole());
assertEquals(RaftState.Follower.name(), raftRoleChanged.getNewRole());
// check if the notifier got a role change from Follower to Candidate
raftRoleChanged = (RoleChanged) matches.get(1);
- assertEquals(id, raftRoleChanged.getMemberId());
+ assertEquals(persistenceId, raftRoleChanged.getMemberId());
assertEquals(RaftState.Follower.name(), raftRoleChanged.getOldRole());
assertEquals(RaftState.Candidate.name(), raftRoleChanged.getNewRole());
// check if the notifier got a role change from Candidate to Leader
raftRoleChanged = (RoleChanged) matches.get(2);
- assertEquals(id, raftRoleChanged.getMemberId());
+ assertEquals(persistenceId, raftRoleChanged.getMemberId());
assertEquals(RaftState.Candidate.name(), raftRoleChanged.getOldRole());
assertEquals(RaftState.Leader.name(), raftRoleChanged.getNewRole());
}};
public void testFakeSnapshotsForLeaderWithInRealSnapshots() throws Exception {
new JavaTestKit(getSystem()) {
{
- String persistenceId = "leader1";
+ String persistenceId = factory.generateActorId("leader-");
+ String follower1Id = factory.generateActorId("follower-");
ActorRef followerActor1 =
- getSystem().actorOf(Props.create(MessageCollectorActor.class));
+ factory.createActor(Props.create(MessageCollectorActor.class));
DefaultConfigParamsImpl config = new DefaultConfigParamsImpl();
config.setHeartBeatInterval(new FiniteDuration(1, TimeUnit.DAYS));
DataPersistenceProvider dataPersistenceProvider = mock(DataPersistenceProvider.class);
Map<String, String> peerAddresses = new HashMap<>();
- peerAddresses.put("follower-1", followerActor1.path().toString());
+ peerAddresses.put(follower1Id, followerActor1.path().toString());
TestActorRef<MockRaftActor> mockActorRef = TestActorRef.create(getSystem(),
MockRaftActor.props(persistenceId, peerAddresses,
assertEquals(8, leaderActor.getReplicatedLog().size());
- leaderActor.onReceiveCommand(new CaptureSnapshot(6,1,4,1));
+ leaderActor.onReceiveCommand(new CaptureSnapshot(6, 1, 4, 1));
leaderActor.getRaftActorContext().setSnapshotCaptureInitiated(true);
verify(leaderActor.delegate).createSnapshot();
assertEquals(RaftState.Leader, leaderActor.getCurrentBehavior().state());
//fake snapshot on index 5
- leaderActor.onReceiveCommand(new AppendEntriesReply("follower-1", 1, true, 5, 1));
+ leaderActor.onReceiveCommand(new AppendEntriesReply(follower1Id, 1, true, 5, 1));
assertEquals(8, leaderActor.getReplicatedLog().size());
//fake snapshot on index 6
assertEquals(RaftState.Leader, leaderActor.getCurrentBehavior().state());
- leaderActor.onReceiveCommand(new AppendEntriesReply("follower-1", 1, true, 6, 1));
+ leaderActor.onReceiveCommand(new AppendEntriesReply(follower1Id, 1, true, 6, 1));
assertEquals(8, leaderActor.getReplicatedLog().size());
assertEquals(RaftState.Leader, leaderActor.getCurrentBehavior().state());
assertEquals(8, leaderActor.getReplicatedLog().size());
- ByteString snapshotBytes = fromObject(Arrays.asList(
+ ByteString snapshotBytes = fromObject(Arrays.asList(
new MockRaftActorContext.MockPayload("foo-0"),
new MockRaftActorContext.MockPayload("foo-1"),
new MockRaftActorContext.MockPayload("foo-2"),
new ReplicatedLogImplEntry(8, 1, new MockRaftActorContext.MockPayload("foo-8")));
//fake snapshot on index 7, since lastApplied = 7 , we would keep the last applied
- leaderActor.onReceiveCommand(new AppendEntriesReply("follower-1", 1, true, 7, 1));
+ leaderActor.onReceiveCommand(new AppendEntriesReply(follower1Id, 1, true, 7, 1));
assertEquals(2, leaderActor.getReplicatedLog().size());
assertEquals(8, leaderActor.getReplicatedLog().lastIndex());
- mockActorRef.tell(PoisonPill.getInstance(), getRef());
-
}
};
}
public void testFakeSnapshotsForFollowerWithInRealSnapshots() throws Exception {
new JavaTestKit(getSystem()) {
{
- String persistenceId = "follower1";
+ String persistenceId = factory.generateActorId("follower-");
+ String leaderId = factory.generateActorId("leader-");
+
ActorRef leaderActor1 =
- getSystem().actorOf(Props.create(MessageCollectorActor.class));
+ factory.createActor(Props.create(MessageCollectorActor.class));
DefaultConfigParamsImpl config = new DefaultConfigParamsImpl();
config.setHeartBeatInterval(new FiniteDuration(1, TimeUnit.DAYS));
DataPersistenceProvider dataPersistenceProvider = mock(DataPersistenceProvider.class);
Map<String, String> peerAddresses = new HashMap<>();
- peerAddresses.put("leader", leaderActor1.path().toString());
+ peerAddresses.put(leaderId, leaderActor1.path().toString());
TestActorRef<MockRaftActor> mockActorRef = TestActorRef.create(getSystem(),
MockRaftActor.props(persistenceId, peerAddresses,
assertEquals(6, followerActor.getReplicatedLog().size());
//snapshot on 4
- followerActor.onReceiveCommand(new CaptureSnapshot(5,1,4,1));
+ followerActor.onReceiveCommand(new CaptureSnapshot(5, 1, 4, 1));
followerActor.getRaftActorContext().setSnapshotCaptureInitiated(true);
verify(followerActor.delegate).createSnapshot();
(ReplicatedLogEntry) new MockRaftActorContext.MockReplicatedLogEntry(1, 6,
new MockRaftActorContext.MockPayload("foo-6"))
);
- followerActor.onReceiveCommand(new AppendEntries(1, "leader", 5, 1, entries , 5, 5));
+ followerActor.onReceiveCommand(new AppendEntries(1, leaderId, 5, 1, entries, 5, 5));
assertEquals(7, followerActor.getReplicatedLog().size());
//fake snapshot on index 7
(ReplicatedLogEntry) new MockRaftActorContext.MockReplicatedLogEntry(1, 7,
new MockRaftActorContext.MockPayload("foo-7"))
);
- followerActor.onReceiveCommand(new AppendEntries(1, "leader", 6, 1, entries, 6, 6));
+ followerActor.onReceiveCommand(new AppendEntries(1, leaderId, 6, 1, entries, 6, 6));
assertEquals(8, followerActor.getReplicatedLog().size());
assertEquals(RaftState.Follower, followerActor.getCurrentBehavior().state());
- ByteString snapshotBytes = fromObject(Arrays.asList(
+ ByteString snapshotBytes = fromObject(Arrays.asList(
new MockRaftActorContext.MockPayload("foo-0"),
new MockRaftActorContext.MockPayload("foo-1"),
new MockRaftActorContext.MockPayload("foo-2"),
new MockRaftActorContext.MockPayload("foo-7"))
);
// send an additional entry 8 with leaderCommit = 7
- followerActor.onReceiveCommand(new AppendEntries(1, "leader", 7, 1, entries , 7, 7));
+ followerActor.onReceiveCommand(new AppendEntries(1, leaderId, 7, 1, entries, 7, 7));
// 7 and 8, as lastapplied is 7
assertEquals(2, followerActor.getReplicatedLog().size());
- mockActorRef.tell(PoisonPill.getInstance(), getRef());
-
}
};
}
public void testFakeSnapshotsForLeaderWithInInitiateSnapshots() throws Exception {
new JavaTestKit(getSystem()) {
{
- String persistenceId = "leader1";
+ String persistenceId = factory.generateActorId("leader-");
+ String follower1Id = factory.generateActorId("follower-");
+ String follower2Id = factory.generateActorId("follower-");
ActorRef followerActor1 =
- getSystem().actorOf(Props.create(MessageCollectorActor.class));
+ factory.createActor(Props.create(MessageCollectorActor.class), follower1Id);
ActorRef followerActor2 =
- getSystem().actorOf(Props.create(MessageCollectorActor.class));
+ factory.createActor(Props.create(MessageCollectorActor.class), follower2Id);
DefaultConfigParamsImpl config = new DefaultConfigParamsImpl();
config.setHeartBeatInterval(new FiniteDuration(1, TimeUnit.DAYS));
DataPersistenceProvider dataPersistenceProvider = mock(DataPersistenceProvider.class);
Map<String, String> peerAddresses = new HashMap<>();
- peerAddresses.put("follower-1", followerActor1.path().toString());
- peerAddresses.put("follower-2", followerActor2.path().toString());
+ peerAddresses.put(follower1Id, followerActor1.path().toString());
+ peerAddresses.put(follower2Id, followerActor2.path().toString());
- TestActorRef<MockRaftActor> mockActorRef = TestActorRef.create(getSystem(),
+ TestActorRef<MockRaftActor> mockActorRef = factory.createTestActor(
MockRaftActor.props(persistenceId, peerAddresses,
Optional.<ConfigParams>of(config), dataPersistenceProvider), persistenceId);
leaderActor.getRaftActorContext().getReplicatedLog().setSnapshotIndex(4);
assertEquals(5, leaderActor.getReplicatedLog().size());
- leaderActor.onReceiveCommand(new AppendEntriesReply("follower-1", 1, true, 9, 1));
+ leaderActor.onReceiveCommand(new AppendEntriesReply(follower1Id, 1, true, 9, 1));
assertEquals(5, leaderActor.getReplicatedLog().size());
// set the 2nd follower nextIndex to 1 which has been snapshotted
- leaderActor.onReceiveCommand(new AppendEntriesReply("follower-2", 1, true, 0, 1));
+ leaderActor.onReceiveCommand(new AppendEntriesReply(follower2Id, 1, true, 0, 1));
assertEquals(5, leaderActor.getReplicatedLog().size());
// simulate a real snapshot
leaderActor.onReceiveCommand(new InitiateInstallSnapshot());
assertEquals(5, leaderActor.getReplicatedLog().size());
assertEquals(String.format("expected to be Leader but was %s. Current Leader = %s ",
- leaderActor.getCurrentBehavior().state(),leaderActor.getLeaderId())
+ leaderActor.getCurrentBehavior().state(), leaderActor.getLeaderId())
, RaftState.Leader, leaderActor.getCurrentBehavior().state());
//reply from a slow follower does not initiate a fake snapshot
- leaderActor.onReceiveCommand(new AppendEntriesReply("follower-2", 1, true, 9, 1));
+ leaderActor.onReceiveCommand(new AppendEntriesReply(follower2Id, 1, true, 9, 1));
assertEquals("Fake snapshot should not happen when Initiate is in progress", 5, leaderActor.getReplicatedLog().size());
- ByteString snapshotBytes = fromObject(Arrays.asList(
+ ByteString snapshotBytes = fromObject(Arrays.asList(
new MockRaftActorContext.MockPayload("foo-0"),
new MockRaftActorContext.MockPayload("foo-1"),
new MockRaftActorContext.MockPayload("foo-2"),
assertEquals("Real snapshot didn't clear the log till lastApplied", 0, leaderActor.getReplicatedLog().size());
//reply from a slow follower after should not raise errors
- leaderActor.onReceiveCommand(new AppendEntriesReply("follower-2", 1, true, 5, 1));
+ leaderActor.onReceiveCommand(new AppendEntriesReply(follower2Id, 1, true, 5, 1));
assertEquals(0, leaderActor.getReplicatedLog().size());
-
- mockActorRef.tell(PoisonPill.getInstance(), getRef());
-
}
};
}
-
-
private ByteString fromObject(Object snapshot) throws Exception {
ByteArrayOutputStream b = null;
ObjectOutputStream o = null;
}
}
}
+
}
--- /dev/null
+/*
+ * 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
+ */
+
+package org.opendaylight.controller.cluster.raft;
+
+/*
+ * 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
+ */
+
+import akka.actor.Actor;
+import akka.actor.ActorRef;
+import akka.actor.ActorSystem;
+import akka.actor.PoisonPill;
+import akka.actor.Props;
+import akka.testkit.TestActorRef;
+import java.util.LinkedList;
+import java.util.List;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * TestActorFactory provides methods to create both normal and test actors and to kill them when the factory is closed
+ * The ideal usage for TestActorFactory is with try with resources, <br/>
+ * For example <br/>
+ * <pre>
+ * try (TestActorFactory factory = new TestActorFactory(getSystem())){
+ * factory.createActor(props);
+ * factory.createTestActor(props);
+ * factory.generateActorId("leader-");
+ * }
+ * </pre>
+ */
+public class TestActorFactory implements AutoCloseable {
+ private final ActorSystem system;
+ List<ActorRef> createdActors = new LinkedList<>();
+ Logger LOG = LoggerFactory.getLogger(getClass());
+ private static int actorCount = 1;
+
+ public TestActorFactory(ActorSystem system){
+ this.system = system;
+ }
+
+ /**
+ * Create a normal actor with an auto-generated name
+ *
+ * @param props
+ * @return
+ */
+ public ActorRef createActor(Props props){
+ ActorRef actorRef = system.actorOf(props);
+ createdActors.add(actorRef);
+ return actorRef;
+ }
+
+ /**
+ * Create a normal actor with the passed in name
+ * @param props
+ * @param actorId name of actor
+ * @return
+ */
+ public ActorRef createActor(Props props, String actorId){
+ ActorRef actorRef = system.actorOf(props, actorId);
+ createdActors.add(actorRef);
+ return actorRef;
+ }
+
+ /**
+ * Create a test actor with the passed in name
+ * @param props
+ * @param actorId
+ * @param <T>
+ * @return
+ */
+ public <T extends Actor> TestActorRef<T> createTestActor(Props props, String actorId){
+ TestActorRef<T> actorRef = TestActorRef.create(system, props, actorId);
+ createdActors.add(actorRef);
+ return actorRef;
+ }
+
+ /**
+ * Create a test actor with an auto-generated name
+ * @param props
+ * @param <T>
+ * @return
+ */
+ public <T extends Actor> TestActorRef<T> createTestActor(Props props){
+ TestActorRef<T> actorRef = TestActorRef.create(system, props);
+ createdActors.add(actorRef);
+ return actorRef;
+ }
+
+ /**
+ * Generate a friendly but unique actor id/name
+ * @param prefix
+ * @return
+ */
+ public String generateActorId(String prefix){
+ return prefix + actorCount++;
+ }
+
+ @Override
+ public void close() throws Exception {
+ for(ActorRef actor : createdActors){
+ LOG.info("Killing actor {}", actor);
+ actor.tell(PoisonPill.getInstance(), null);
+ }
+ }
+}
\ No newline at end of file
--- /dev/null
+/*
+ * Copyright (c) 2015 Brocade Communications Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.controller.cluster.raft.behaviors;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+import akka.actor.ActorRef;
+import akka.actor.ActorSystem;
+import akka.actor.Props;
+import akka.dispatch.Dispatchers;
+import akka.testkit.JavaTestKit;
+import akka.testkit.TestActorRef;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.util.concurrent.Uninterruptibles;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+import org.junit.After;
+import org.junit.Test;
+import org.opendaylight.controller.cluster.raft.DefaultConfigParamsImpl;
+import org.opendaylight.controller.cluster.raft.MockRaftActorContext;
+import org.opendaylight.controller.cluster.raft.MockRaftActorContext.MockPayload;
+import org.opendaylight.controller.cluster.raft.MockRaftActorContext.MockReplicatedLogEntry;
+import org.opendaylight.controller.cluster.raft.MockRaftActorContext.SimpleReplicatedLog;
+import org.opendaylight.controller.cluster.raft.RaftActorContext;
+import org.opendaylight.controller.cluster.raft.RaftState;
+import org.opendaylight.controller.cluster.raft.base.messages.ElectionTimeout;
+import org.opendaylight.controller.cluster.raft.base.messages.SendHeartBeat;
+import org.opendaylight.controller.cluster.raft.messages.AppendEntries;
+import org.opendaylight.controller.cluster.raft.messages.AppendEntriesReply;
+import org.opendaylight.controller.cluster.raft.messages.RequestVote;
+import org.opendaylight.controller.cluster.raft.messages.RequestVoteReply;
+import org.opendaylight.controller.cluster.raft.utils.MessageCollectorActor;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.slf4j.impl.SimpleLogger;
+import scala.concurrent.duration.FiniteDuration;
+
+/**
+ * Tests various leader election scenarios.
+ *
+ * @author Thomas Pantelis
+ */
+public class LeaderElectionScenariosTest {
+
+ private static final int HEARTBEAT_INTERVAL = 50;
+
+ public static class MemberActor extends MessageCollectorActor {
+
+ volatile RaftActorBehavior behavior;
+ Map<Class<?>, CountDownLatch> messagesReceivedLatches = new ConcurrentHashMap<>();
+ Map<Class<?>, Boolean> dropMessagesToBehavior = new ConcurrentHashMap<>();
+ CountDownLatch behaviorStateChangeLatch;
+
+ public static Props props() {
+ return Props.create(MemberActor.class).withDispatcher(Dispatchers.DefaultDispatcherId());
+ }
+
+ @Override
+ public void onReceive(Object message) throws Exception {
+ // Ignore scheduled SendHeartBeat messages.
+ if(message instanceof SendHeartBeat) {
+ return;
+ }
+
+ try {
+ if(behavior != null && !dropMessagesToBehavior.containsKey(message.getClass())) {
+ RaftActorBehavior oldBehavior = behavior;
+ behavior = behavior.handleMessage(getSender(), message);
+ if(behavior != oldBehavior && behaviorStateChangeLatch != null) {
+ behaviorStateChangeLatch.countDown();
+ }
+ }
+ } finally {
+ super.onReceive(message);
+
+ CountDownLatch latch = messagesReceivedLatches.get(message.getClass());
+ if(latch != null) {
+ latch.countDown();
+ }
+ }
+ }
+
+ void expectBehaviorStateChange() {
+ behaviorStateChangeLatch = new CountDownLatch(1);
+ }
+
+ void waitForBehaviorStateChange() {
+ assertTrue("Expected behavior state change",
+ Uninterruptibles.awaitUninterruptibly(behaviorStateChangeLatch, 5, TimeUnit.SECONDS));
+ }
+
+ void expectMessageClass(Class<?> expClass, int expCount) {
+ messagesReceivedLatches.put(expClass, new CountDownLatch(expCount));
+ }
+
+ void waitForExpectedMessages(Class<?> expClass) {
+ CountDownLatch latch = messagesReceivedLatches.get(expClass);
+ assertNotNull("No messages received for " + expClass, latch);
+ assertTrue("Missing messages of type " + expClass,
+ Uninterruptibles.awaitUninterruptibly(latch, 5, TimeUnit.SECONDS));
+ }
+
+ void dropMessagesToBehavior(Class<?> msgClass) {
+ dropMessagesToBehavior(msgClass, 1);
+ }
+
+ void dropMessagesToBehavior(Class<?> msgClass, int expCount) {
+ expectMessageClass(msgClass, expCount);
+ dropMessagesToBehavior.put(msgClass, Boolean.TRUE);
+ }
+
+ void clearDropMessagesToBehavior() {
+ dropMessagesToBehavior.clear();
+ }
+
+ @Override
+ public void clear() {
+ behaviorStateChangeLatch = null;
+ clearDropMessagesToBehavior();
+ messagesReceivedLatches.clear();
+ super.clear();
+ }
+
+ void forwardCapturedMessageToBehavior(Class<?> msgClass, ActorRef sender) throws Exception {
+ Object message = getFirstMatching(getSelf(), msgClass);
+ assertNotNull("Message of type " + msgClass + " not received", message);
+ getSelf().tell(message, sender);
+ }
+
+ void forwardCapturedMessagesToBehavior(Class<?> msgClass, ActorRef sender) throws Exception {
+ for(Object m: getAllMatching(getSelf(), msgClass)) {
+ getSelf().tell(m, sender);
+ }
+ }
+
+ <T> T getCapturedMessage(Class<T> msgClass) throws Exception {
+ Object message = getFirstMatching(getSelf(), msgClass);
+ assertNotNull("Message of type " + msgClass + " not received", message);
+ return (T) message;
+ }
+ }
+
+ static {
+ System.setProperty(SimpleLogger.LOG_KEY_PREFIX + MockRaftActorContext.class.getName(), "trace");
+ }
+
+ private final Logger testLog = LoggerFactory.getLogger(MockRaftActorContext.class);
+ private final ActorSystem system = ActorSystem.create("test");
+
+ @After
+ public void tearDown() {
+ JavaTestKit.shutdownActorSystem(system);
+ }
+
+ private DefaultConfigParamsImpl newConfigParams() {
+ DefaultConfigParamsImpl configParams = new DefaultConfigParamsImpl();
+ configParams.setHeartBeatInterval(new FiniteDuration(HEARTBEAT_INTERVAL, TimeUnit.MILLISECONDS));
+ configParams.setElectionTimeoutFactor(100000);
+ configParams.setIsolatedLeaderCheckInterval(new FiniteDuration(1, TimeUnit.DAYS));
+ return configParams;
+ }
+
+ private MockRaftActorContext newRaftActorContext(String id, ActorRef actor,
+ Map<String, String> peerAddresses) {
+ MockRaftActorContext context = new MockRaftActorContext(id, system, actor);
+ context.setPeerAddresses(peerAddresses);
+ context.getTermInformation().updateAndPersist(1, "");
+ return context;
+ }
+
+ private void verifyBehaviorState(String name, TestActorRef<MemberActor> actor, RaftState expState) {
+ assertEquals(name + " behavior state", expState, actor.underlyingActor().behavior.state());
+ }
+
+ private void initializeLeaderBehavior(TestActorRef<MemberActor> actor, RaftActorContext context,
+ int numActiveFollowers) throws Exception {
+ // Leader sends immediate heartbeats - we don't care about it so ignore it.
+
+ actor.underlyingActor().expectMessageClass(AppendEntriesReply.class, numActiveFollowers);
+ Leader leader = new Leader(context);
+ actor.underlyingActor().waitForExpectedMessages(AppendEntriesReply.class);
+ actor.underlyingActor().behavior = leader;
+
+ actor.underlyingActor().forwardCapturedMessagesToBehavior(AppendEntriesReply.class, ActorRef.noSender());
+ actor.underlyingActor().clear();
+ }
+
+ private TestActorRef<MemberActor> newMemberActor(String name) throws Exception {
+ TestActorRef<MemberActor> actor = TestActorRef.create(system, MemberActor.props(), name);
+ MessageCollectorActor.waitUntilReady(actor);
+ return actor;
+ }
+
+ private void sendHeartbeat(TestActorRef<MemberActor> leaderActor) {
+ Uninterruptibles.sleepUninterruptibly(HEARTBEAT_INTERVAL, TimeUnit.MILLISECONDS);
+ leaderActor.underlyingActor().behavior.handleMessage(leaderActor, new SendHeartBeat());
+ }
+
+ @Test
+ public void testDelayedMessagesScenario() throws Exception {
+ testLog.info("Starting testDelayedMessagesScenario");
+
+ TestActorRef<MemberActor> member1Actor = newMemberActor("member1");
+ TestActorRef<MemberActor> member2Actor = newMemberActor("member2");
+ TestActorRef<MemberActor> member3Actor = newMemberActor("member3");
+
+ // Create member 2's behavior initially as Follower
+
+ MockRaftActorContext member2Context = newRaftActorContext("member2", member2Actor,
+ ImmutableMap.<String,String>builder().
+ put("member1", member1Actor.path().toString()).
+ put("member3", member3Actor.path().toString()).build());
+
+ DefaultConfigParamsImpl member2ConfigParams = newConfigParams();
+ member2Context.setConfigParams(member2ConfigParams);
+
+ Follower member2Behavior = new Follower(member2Context);
+ member2Actor.underlyingActor().behavior = member2Behavior;
+
+ // Create member 3's behavior initially as Follower
+
+ MockRaftActorContext member3Context = newRaftActorContext("member3", member3Actor,
+ ImmutableMap.<String,String>builder().
+ put("member1", member1Actor.path().toString()).
+ put("member2", member2Actor.path().toString()).build());
+
+ DefaultConfigParamsImpl member3ConfigParams = newConfigParams();
+ member3Context.setConfigParams(member3ConfigParams);
+
+ Follower member3Behavior = new Follower(member3Context);
+ member3Actor.underlyingActor().behavior = member3Behavior;
+
+ // Create member 1's behavior initially as Leader
+
+ MockRaftActorContext member1Context = newRaftActorContext("member1", member1Actor,
+ ImmutableMap.<String,String>builder().
+ put("member2", member2Actor.path().toString()).
+ put("member3", member3Actor.path().toString()).build());
+
+ DefaultConfigParamsImpl member1ConfigParams = newConfigParams();
+ member1Context.setConfigParams(member1ConfigParams);
+
+ initializeLeaderBehavior(member1Actor, member1Context, 2);
+
+ member2Actor.underlyingActor().clear();
+ member3Actor.underlyingActor().clear();
+
+ // Send ElectionTimeout to member 2 to simulate missing heartbeat from the Leader. member 2
+ // should switch to Candidate and send out RequestVote messages. Set member 1 and 3 actors
+ // to capture RequestVote but not to forward to the behavior just yet as we want to
+ // control the order of RequestVote messages to member 1 and 3.
+
+ member1Actor.underlyingActor().dropMessagesToBehavior(RequestVote.class);
+
+ member2Actor.underlyingActor().expectBehaviorStateChange();
+
+ member3Actor.underlyingActor().dropMessagesToBehavior(RequestVote.class);
+
+ member2Actor.tell(new ElectionTimeout(), ActorRef.noSender());
+
+ member1Actor.underlyingActor().waitForExpectedMessages(RequestVote.class);
+ member3Actor.underlyingActor().waitForExpectedMessages(RequestVote.class);
+
+ member2Actor.underlyingActor().waitForBehaviorStateChange();
+ verifyBehaviorState("member 2", member2Actor, RaftState.Candidate);
+
+ assertEquals("member 1 election term", 1, member1Context.getTermInformation().getCurrentTerm());
+ assertEquals("member 2 election term", 2, member2Context.getTermInformation().getCurrentTerm());
+ assertEquals("member 3 election term", 1, member3Context.getTermInformation().getCurrentTerm());
+
+ // At this point member 1 and 3 actors have captured the RequestVote messages. First
+ // forward the RequestVote message to member 1's behavior. Since the RequestVote term
+ // is greater than member 1's term, member 1 should switch to Follower without replying
+ // to RequestVote and update its term to 2.
+
+ member1Actor.underlyingActor().clearDropMessagesToBehavior();
+ member1Actor.underlyingActor().expectBehaviorStateChange();
+ member1Actor.underlyingActor().forwardCapturedMessageToBehavior(RequestVote.class, member2Actor);
+ member1Actor.underlyingActor().waitForExpectedMessages(RequestVote.class);
+
+ member1Actor.underlyingActor().waitForBehaviorStateChange();
+ verifyBehaviorState("member 1", member1Actor, RaftState.Follower);
+
+ // Now forward member 3's captured RequestVote message to its behavior. Since member 3 is
+ // already a Follower, it should update its term to 2 and send a RequestVoteReply back to
+ // member 2 granting the vote b/c the RequestVote's term, lastLogTerm, and lastLogIndex
+ // should satisfy the criteria for granting the vote. However, we'll delay sending the
+ // RequestVoteReply to member 2's behavior to simulate network latency.
+
+ member2Actor.underlyingActor().dropMessagesToBehavior(RequestVoteReply.class);
+
+ member3Actor.underlyingActor().clearDropMessagesToBehavior();
+ member3Actor.underlyingActor().expectMessageClass(RequestVote.class, 1);
+ member3Actor.underlyingActor().forwardCapturedMessageToBehavior(RequestVote.class, member2Actor);
+ member3Actor.underlyingActor().waitForExpectedMessages(RequestVote.class);
+ verifyBehaviorState("member 3", member3Actor, RaftState.Follower);
+
+ assertEquals("member 1 election term", 2, member1Context.getTermInformation().getCurrentTerm());
+ assertEquals("member 2 election term", 2, member2Context.getTermInformation().getCurrentTerm());
+ assertEquals("member 3 election term", 2, member3Context.getTermInformation().getCurrentTerm());
+
+ // Send ElectionTimeout to member 3 to simulate missing heartbeat from a Leader. member 3
+ // should switch to Candidate and send out RequestVote messages. member 1 should grant the
+ // vote and send a reply. After receiving the RequestVoteReply, member 3 should switch to leader.
+
+ member2Actor.underlyingActor().expectBehaviorStateChange();
+ member3Actor.underlyingActor().clear();
+ member3Actor.underlyingActor().expectMessageClass(RequestVoteReply.class, 1);
+ member3Actor.underlyingActor().expectMessageClass(AppendEntriesReply.class, 2);
+
+ member3Actor.tell(new ElectionTimeout(), ActorRef.noSender());
+
+ member3Actor.underlyingActor().waitForExpectedMessages(RequestVoteReply.class);
+
+ RequestVoteReply requestVoteReply = member3Actor.underlyingActor().getCapturedMessage(RequestVoteReply.class);
+ assertEquals("getTerm", member3Context.getTermInformation().getCurrentTerm(), requestVoteReply.getTerm());
+ assertEquals("isVoteGranted", true, requestVoteReply.isVoteGranted());
+
+ verifyBehaviorState("member 3", member3Actor, RaftState.Leader);
+
+ // member 2 should've switched to Follower as member 3's RequestVote term (3) was greater
+ // than member 2's term (2).
+
+ member2Actor.underlyingActor().waitForBehaviorStateChange();
+ verifyBehaviorState("member 2", member2Actor, RaftState.Follower);
+
+ // The switch to leader should cause an immediate AppendEntries heartbeat from member 3.
+
+ member3Actor.underlyingActor().waitForExpectedMessages(AppendEntriesReply.class);
+
+ assertEquals("member 1 election term", 3, member1Context.getTermInformation().getCurrentTerm());
+ assertEquals("member 2 election term", 3, member2Context.getTermInformation().getCurrentTerm());
+ assertEquals("member 3 election term", 3, member3Context.getTermInformation().getCurrentTerm());
+
+ // Now forward the original delayed RequestVoteReply from member 3 to member 2 that granted
+ // the vote. Since member 2 is now a Follower, the RequestVoteReply should be ignored.
+
+ member2Actor.underlyingActor().clearDropMessagesToBehavior();
+ member2Actor.underlyingActor().forwardCapturedMessageToBehavior(RequestVoteReply.class, member3Actor);
+
+ member2Actor.underlyingActor().waitForExpectedMessages(RequestVoteReply.class);
+
+ verifyBehaviorState("member 1", member1Actor, RaftState.Follower);
+ verifyBehaviorState("member 2", member2Actor, RaftState.Follower);
+ verifyBehaviorState("member 3", member3Actor, RaftState.Leader);
+
+ assertEquals("member 1 election term", 3, member1Context.getTermInformation().getCurrentTerm());
+ assertEquals("member 2 election term", 3, member2Context.getTermInformation().getCurrentTerm());
+ assertEquals("member 3 election term", 3, member3Context.getTermInformation().getCurrentTerm());
+
+ testLog.info("testDelayedMessagesScenario done");
+ }
+
+ @Test
+ public void testPartitionedLeadersScenario() throws Exception {
+ testLog.info("Starting testPartitionedLeadersScenario");
+
+ TestActorRef<MemberActor> member1Actor = newMemberActor("member1");
+ TestActorRef<MemberActor> member2Actor = newMemberActor("member2");
+ TestActorRef<MemberActor> member3Actor = newMemberActor("member3");
+
+ // Create member 2's behavior initially as Follower
+
+ MockRaftActorContext member2Context = newRaftActorContext("member2", member2Actor,
+ ImmutableMap.<String,String>builder().
+ put("member1", member1Actor.path().toString()).
+ put("member3", member3Actor.path().toString()).build());
+
+ DefaultConfigParamsImpl member2ConfigParams = newConfigParams();
+ member2Context.setConfigParams(member2ConfigParams);
+
+ Follower member2Behavior = new Follower(member2Context);
+ member2Actor.underlyingActor().behavior = member2Behavior;
+
+ // Create member 3's behavior initially as Follower
+
+ MockRaftActorContext member3Context = newRaftActorContext("member3", member3Actor,
+ ImmutableMap.<String,String>builder().
+ put("member1", member1Actor.path().toString()).
+ put("member2", member2Actor.path().toString()).build());
+
+ DefaultConfigParamsImpl member3ConfigParams = newConfigParams();
+ member3Context.setConfigParams(member3ConfigParams);
+
+ Follower member3Behavior = new Follower(member3Context);
+ member3Actor.underlyingActor().behavior = member3Behavior;
+
+ // Create member 1's behavior initially as Leader
+
+ MockRaftActorContext member1Context = newRaftActorContext("member1", member1Actor,
+ ImmutableMap.<String,String>builder().
+ put("member2", member2Actor.path().toString()).
+ put("member3", member3Actor.path().toString()).build());
+
+ DefaultConfigParamsImpl member1ConfigParams = newConfigParams();
+ member1Context.setConfigParams(member1ConfigParams);
+
+ initializeLeaderBehavior(member1Actor, member1Context, 2);
+
+ member2Actor.underlyingActor().clear();
+ member3Actor.underlyingActor().clear();
+
+ // Send ElectionTimeout to member 2 to simulate no heartbeat from the Leader (member 1).
+ // member 2 should switch to Candidate, start new term 2 and send out RequestVote messages.
+ // member 1 will switch to Follower b/c its term is less than the RequestVote term, also it
+ // won't send back a reply. member 3 will drop the message (ie won't forward it to its behavior) to
+ // simulate loss of network connectivity between member 2 and 3.
+
+ member1Actor.underlyingActor().expectMessageClass(RequestVote.class, 1);
+
+ member2Actor.underlyingActor().expectBehaviorStateChange();
+
+ member3Actor.underlyingActor().dropMessagesToBehavior(RequestVote.class);
+
+ member2Actor.tell(new ElectionTimeout(), ActorRef.noSender());
+
+ member1Actor.underlyingActor().waitForExpectedMessages(RequestVote.class);
+ member3Actor.underlyingActor().waitForExpectedMessages(RequestVote.class);
+
+ // member 1 should switch to Follower as the RequestVote term is greater than its term. It
+ // won't send back a RequestVoteReply in this case.
+
+ verifyBehaviorState("member 1", member1Actor, RaftState.Follower);
+
+ // member 2 should switch to Candidate since member 1 didn't reply.
+
+ member2Actor.underlyingActor().waitForBehaviorStateChange();
+ verifyBehaviorState("member 2", member2Actor, RaftState.Candidate);
+
+ assertEquals("member 1 election term", 2, member1Context.getTermInformation().getCurrentTerm());
+ assertEquals("member 2 election term", 2, member2Context.getTermInformation().getCurrentTerm());
+ assertEquals("member 3 election term", 1, member3Context.getTermInformation().getCurrentTerm());
+
+ // Send ElectionTimeout to member 3 to simulate no heartbeat from the Leader (member 1).
+ // member 2 should switch to Candidate and send out RequestVote messages. member 1 will reply and
+ // grant the vote but member 2 will drop the message to simulate loss of network connectivity.
+
+ member1Actor.underlyingActor().clear();
+ member1Actor.underlyingActor().expectMessageClass(RequestVote.class, 1);
+ member1Actor.underlyingActor().expectMessageClass(AppendEntries.class, 1);
+
+ member2Actor.underlyingActor().clear();
+ member2Actor.underlyingActor().dropMessagesToBehavior(RequestVote.class);
+ member2Actor.underlyingActor().dropMessagesToBehavior(AppendEntries.class);
+
+ member3Actor.underlyingActor().clear();
+ member3Actor.underlyingActor().expectMessageClass(RequestVoteReply.class, 1);
+ member3Actor.underlyingActor().expectMessageClass(AppendEntriesReply.class, 1);
+
+ member3Actor.tell(new ElectionTimeout(), ActorRef.noSender());
+
+ member1Actor.underlyingActor().waitForExpectedMessages(RequestVote.class);
+ member2Actor.underlyingActor().waitForExpectedMessages(RequestVote.class);
+ member3Actor.underlyingActor().waitForExpectedMessages(RequestVoteReply.class);
+
+ RequestVoteReply requestVoteReply = member3Actor.underlyingActor().getCapturedMessage(RequestVoteReply.class);
+ assertEquals("getTerm", member3Context.getTermInformation().getCurrentTerm(), requestVoteReply.getTerm());
+ assertEquals("isVoteGranted", true, requestVoteReply.isVoteGranted());
+
+ // when member 3 switches to Leader it will immediately send out heartbeat AppendEntries to
+ // the followers. Wait for AppendEntries to member 1 and its AppendEntriesReply. The
+ // AppendEntries message to member 2 is dropped.
+
+ member1Actor.underlyingActor().waitForExpectedMessages(AppendEntries.class);
+ member2Actor.underlyingActor().waitForExpectedMessages(AppendEntries.class);
+ member3Actor.underlyingActor().waitForExpectedMessages(AppendEntriesReply.class);
+
+ verifyBehaviorState("member 1", member1Actor, RaftState.Follower);
+ verifyBehaviorState("member 2", member2Actor, RaftState.Candidate);
+ verifyBehaviorState("member 3", member3Actor, RaftState.Leader);
+
+ assertEquals("member 1 election term", 2, member1Context.getTermInformation().getCurrentTerm());
+ assertEquals("member 2 election term", 2, member2Context.getTermInformation().getCurrentTerm());
+ assertEquals("member 3 election term", 2, member3Context.getTermInformation().getCurrentTerm());
+
+ // member 2 is partitioned from the Leader (member 3) and hasn't received any messages. It
+ // would get another ElectionTimeout so simulate that. member 1 should send back a reply
+ // granting the vote. Messages (RequestVote and AppendEntries) from member 2 to member 3
+ // are dropped to simulate loss of network connectivity. Note member 2 will increment its
+ // election term to 3.
+
+ member1Actor.underlyingActor().clear();
+ member1Actor.underlyingActor().expectMessageClass(AppendEntries.class, 1);
+
+ member2Actor.underlyingActor().clear();
+ member2Actor.underlyingActor().expectMessageClass(RequestVoteReply.class, 1);
+ member2Actor.underlyingActor().expectMessageClass(AppendEntriesReply.class, 1);
+
+ member3Actor.underlyingActor().clear();
+ member3Actor.underlyingActor().dropMessagesToBehavior(AppendEntries.class);
+ member3Actor.underlyingActor().dropMessagesToBehavior(RequestVote.class);
+
+ member2Actor.tell(new ElectionTimeout(), ActorRef.noSender());
+
+ member2Actor.underlyingActor().waitForExpectedMessages(RequestVoteReply.class);
+
+ requestVoteReply = member2Actor.underlyingActor().getCapturedMessage(RequestVoteReply.class);
+ assertEquals("getTerm", member2Context.getTermInformation().getCurrentTerm(), requestVoteReply.getTerm());
+ assertEquals("isVoteGranted", true, requestVoteReply.isVoteGranted());
+
+ member3Actor.underlyingActor().waitForExpectedMessages(RequestVote.class);
+
+ member1Actor.underlyingActor().waitForExpectedMessages(AppendEntries.class);
+ member3Actor.underlyingActor().waitForExpectedMessages(AppendEntries.class);
+ member2Actor.underlyingActor().waitForExpectedMessages(AppendEntriesReply.class);
+
+ // We end up with 2 partitioned leaders both leading member 1. The term for member 1 and 3
+ // is 3 and member 3's term is 2.
+
+ verifyBehaviorState("member 1", member1Actor, RaftState.Follower);
+ verifyBehaviorState("member 2", member2Actor, RaftState.Leader);
+ verifyBehaviorState("member 3", member3Actor, RaftState.Leader);
+
+ assertEquals("member 1 election term", 3, member1Context.getTermInformation().getCurrentTerm());
+ assertEquals("member 2 election term", 3, member2Context.getTermInformation().getCurrentTerm());
+ assertEquals("member 3 election term", 2, member3Context.getTermInformation().getCurrentTerm());
+
+ // Re-establish connectivity between member 2 and 3, ie stop dropping messages between
+ // the 2. Send heartbeats (AppendEntries) from member 3. Both member 1 and 2 should send back
+ // an unsuccessful AppendEntriesReply b/c their term (3) is greater than member 3's term (2).
+ // This should cause member 3 to switch to Follower.
+
+ RaftActorBehavior savedMember1Behavior = member1Actor.underlyingActor().behavior;
+ RaftActorBehavior savedMember2Behavior = member2Actor.underlyingActor().behavior;
+ RaftActorBehavior savedMember3Behavior = member3Actor.underlyingActor().behavior;
+ long savedMember3Term = member3Context.getTermInformation().getCurrentTerm();
+ String savedMember3VoterFor = member3Context.getTermInformation().getVotedFor();
+
+ member1Actor.underlyingActor().clear();
+ member1Actor.underlyingActor().expectMessageClass(AppendEntries.class, 1);
+
+ member2Actor.underlyingActor().clear();
+ member2Actor.underlyingActor().expectMessageClass(AppendEntries.class, 1);
+
+ member3Actor.underlyingActor().clear();
+ member3Actor.underlyingActor().expectMessageClass(AppendEntriesReply.class, 1);
+
+ sendHeartbeat(member3Actor);
+
+ member3Actor.underlyingActor().waitForExpectedMessages(AppendEntriesReply.class);
+
+ AppendEntriesReply appendEntriesReply = member3Actor.underlyingActor().
+ getCapturedMessage(AppendEntriesReply.class);
+ assertEquals("isSuccess", false, appendEntriesReply.isSuccess());
+ assertEquals("getTerm", 3, appendEntriesReply.getTerm());
+
+ verifyBehaviorState("member 1", member1Actor, RaftState.Follower);
+ verifyBehaviorState("member 2", member2Actor, RaftState.Leader);
+ verifyBehaviorState("member 3", member3Actor, RaftState.Follower);
+
+ assertEquals("member 1 election term", 3, member1Context.getTermInformation().getCurrentTerm());
+ assertEquals("member 2 election term", 3, member2Context.getTermInformation().getCurrentTerm());
+ assertEquals("member 3 election term", 3, member3Context.getTermInformation().getCurrentTerm());
+
+ // Revert back to the partitioned leaders state to test the other sequence where member 2
+ // sends heartbeats first before member 3. member 1 should return a successful
+ // AppendEntriesReply b/c his term matches member 2's. member 3 should switch to Follower
+ // as his term is less than member 2's.
+
+ member1Actor.underlyingActor().behavior = savedMember1Behavior;
+ member2Actor.underlyingActor().behavior = savedMember2Behavior;
+ member3Actor.underlyingActor().behavior = savedMember3Behavior;
+
+ member3Context.getTermInformation().update(savedMember3Term, savedMember3VoterFor);
+
+ member1Actor.underlyingActor().clear();
+ member1Actor.underlyingActor().expectMessageClass(AppendEntries.class, 1);
+
+ member2Actor.underlyingActor().clear();
+ member2Actor.underlyingActor().expectMessageClass(AppendEntriesReply.class, 1);
+
+ member3Actor.underlyingActor().clear();
+ member3Actor.underlyingActor().expectMessageClass(AppendEntries.class, 1);
+
+ sendHeartbeat(member2Actor);
+
+ member1Actor.underlyingActor().waitForExpectedMessages(AppendEntries.class);
+ member3Actor.underlyingActor().waitForExpectedMessages(AppendEntries.class);
+
+ member2Actor.underlyingActor().waitForExpectedMessages(AppendEntriesReply.class);
+
+ verifyBehaviorState("member 1", member1Actor, RaftState.Follower);
+ verifyBehaviorState("member 2", member2Actor, RaftState.Leader);
+ verifyBehaviorState("member 3", member3Actor, RaftState.Follower);
+
+ assertEquals("member 1 election term", 3, member1Context.getTermInformation().getCurrentTerm());
+ assertEquals("member 2 election term", 3, member2Context.getTermInformation().getCurrentTerm());
+ assertEquals("member 3 election term", 3, member3Context.getTermInformation().getCurrentTerm());
+
+ testLog.info("testPartitionedLeadersScenario done");
+ }
+
+ @Test
+ public void testPartitionedCandidateOnStartupScenario() throws Exception {
+ testLog.info("Starting testPartitionedCandidateOnStartupScenario");
+
+ TestActorRef<MemberActor> member1Actor = newMemberActor("member1") ;
+ TestActorRef<MemberActor> member2Actor = newMemberActor("member2");
+ TestActorRef<MemberActor> member3Actor = newMemberActor("member3");
+
+ // Create member 2's behavior as Follower.
+
+ MockRaftActorContext member2Context = newRaftActorContext("member2", member2Actor,
+ ImmutableMap.<String,String>builder().
+ put("member1", member1Actor.path().toString()).
+ put("member3", member3Actor.path().toString()).build());
+
+ DefaultConfigParamsImpl member2ConfigParams = newConfigParams();
+ member2Context.setConfigParams(member2ConfigParams);
+
+ Follower member2Behavior = new Follower(member2Context);
+ member2Actor.underlyingActor().behavior = member2Behavior;
+
+ // Create member 1's behavior as Leader.
+
+ MockRaftActorContext member1Context = newRaftActorContext("member1", member1Actor,
+ ImmutableMap.<String,String>builder().
+ put("member2", member2Actor.path().toString()).
+ put("member3", member3Actor.path().toString()).build());
+
+ DefaultConfigParamsImpl member1ConfigParams = newConfigParams();
+ member1Context.setConfigParams(member1ConfigParams);
+
+ initializeLeaderBehavior(member1Actor, member1Context, 1);
+
+ member2Actor.underlyingActor().clear();
+ member3Actor.underlyingActor().clear();
+
+ // Initialize the ReplicatedLog and election term info for member 1 and 2. The current term
+ // will be 3 and the last term will be 2.
+
+ SimpleReplicatedLog replicatedLog = new SimpleReplicatedLog();
+ replicatedLog.append(new MockReplicatedLogEntry(2, 1, new MockPayload("")));
+ replicatedLog.append(new MockReplicatedLogEntry(3, 1, new MockPayload("")));
+
+ member1Context.setReplicatedLog(replicatedLog);
+ member1Context.getTermInformation().update(3, "");
+
+ member2Context.setReplicatedLog(replicatedLog);
+ member2Context.getTermInformation().update(3, member1Context.getId());
+
+ // Create member 3's behavior initially as a Candidate.
+
+ MockRaftActorContext member3Context = newRaftActorContext("member3", member3Actor,
+ ImmutableMap.<String,String>builder().
+ put("member1", member1Actor.path().toString()).
+ put("member2", member2Actor.path().toString()).build());
+
+ DefaultConfigParamsImpl member3ConfigParams = newConfigParams();
+ member3Context.setConfigParams(member3ConfigParams);
+
+ // Initialize the ReplicatedLog and election term info for Candidate member 3. The current term
+ // will be 2 and the last term will be 1 so it is behind the leader's log.
+
+ SimpleReplicatedLog candidateReplicatedLog = new SimpleReplicatedLog();
+ candidateReplicatedLog.append(new MockReplicatedLogEntry(1, 1, new MockPayload("")));
+ candidateReplicatedLog.append(new MockReplicatedLogEntry(2, 1, new MockPayload("")));
+
+ member3Context.setReplicatedLog(candidateReplicatedLog);
+ member3Context.getTermInformation().update(2, member1Context.getId());
+
+ // The member 3 Candidate will start a new term and send RequestVotes. However it will be
+ // partitioned from the cluster by having member 1 and 2 drop its RequestVote messages.
+
+ int numCandidateElections = 5;
+ long candidateElectionTerm = member3Context.getTermInformation().getCurrentTerm() + numCandidateElections;
+
+ member1Actor.underlyingActor().dropMessagesToBehavior(RequestVote.class, numCandidateElections);
+
+ member2Actor.underlyingActor().dropMessagesToBehavior(RequestVote.class, numCandidateElections);
+
+ Candidate member3Behavior = new Candidate(member3Context);
+ member3Actor.underlyingActor().behavior = member3Behavior;
+
+ // Send several additional ElectionTimeouts to Candidate member 3. Each ElectionTimeout will
+ // start a new term so Candidate member 3's current term will be greater than the leader's
+ // current term.
+
+ for(int i = 0; i < numCandidateElections - 1; i++) {
+ member3Actor.tell(new ElectionTimeout(), ActorRef.noSender());
+ }
+
+ member1Actor.underlyingActor().waitForExpectedMessages(RequestVote.class);
+ member2Actor.underlyingActor().waitForExpectedMessages(RequestVote.class);
+
+ verifyBehaviorState("member 1", member1Actor, RaftState.Leader);
+ verifyBehaviorState("member 2", member2Actor, RaftState.Follower);
+ verifyBehaviorState("member 3", member3Actor, RaftState.Candidate);
+
+ assertEquals("member 1 election term", 3, member1Context.getTermInformation().getCurrentTerm());
+ assertEquals("member 2 election term", 3, member2Context.getTermInformation().getCurrentTerm());
+ assertEquals("member 3 election term", candidateElectionTerm,
+ member3Context.getTermInformation().getCurrentTerm());
+
+ // Now send a couple more ElectionTimeouts to Candidate member 3 with the partition resolved.
+ //
+ // On the first RequestVote, Leader member 1 should switch to Follower as its term (s) is less than
+ // the RequestVote's term (8) from member 3. No RequestVoteReply should be sent by member 1.
+ // Follower member 2 should update its term since it less than the RequestVote's term and
+ // should return a RequestVoteReply but should not grant the vote as its last term and index
+ // is greater than the RequestVote's lastLogTerm and lastLogIndex, ie member 2's log is later
+ // or more up to date than member 3's.
+ //
+ // On the second RequestVote, both member 1 and 2 are followers so they should update their
+ // term and return a RequestVoteReply but should not grant the vote.
+
+ candidateElectionTerm += 2;
+ for(int i = 0; i < 2; i++) {
+ member1Actor.underlyingActor().clear();
+ member1Actor.underlyingActor().expectMessageClass(RequestVote.class, 1);
+ member2Actor.underlyingActor().clear();
+ member2Actor.underlyingActor().expectMessageClass(RequestVote.class, 1);
+ member3Actor.underlyingActor().clear();
+ member3Actor.underlyingActor().expectMessageClass(RequestVoteReply.class, 1);
+
+ member3Actor.tell(new ElectionTimeout(), ActorRef.noSender());
+
+ member1Actor.underlyingActor().waitForExpectedMessages(RequestVote.class);
+ member2Actor.underlyingActor().waitForExpectedMessages(RequestVote.class);
+
+ member3Actor.underlyingActor().waitForExpectedMessages(RequestVoteReply.class);
+
+ RequestVoteReply requestVoteReply = member3Actor.underlyingActor().getCapturedMessage(RequestVoteReply.class);
+ assertEquals("getTerm", member3Context.getTermInformation().getCurrentTerm(), requestVoteReply.getTerm());
+ assertEquals("isVoteGranted", false, requestVoteReply.isVoteGranted());
+ }
+
+ verifyBehaviorState("member 1", member1Actor, RaftState.Follower);
+ verifyBehaviorState("member 2", member2Actor, RaftState.Follower);
+ verifyBehaviorState("member 3", member3Actor, RaftState.Candidate);
+
+ // Even though member 3 didn't get voted for, member 1 and 2 should have updated their term
+ // to member 3's.
+
+ assertEquals("member 1 election term", candidateElectionTerm,
+ member1Context.getTermInformation().getCurrentTerm());
+ assertEquals("member 2 election term", candidateElectionTerm,
+ member2Context.getTermInformation().getCurrentTerm());
+ assertEquals("member 3 election term", candidateElectionTerm,
+ member3Context.getTermInformation().getCurrentTerm());
+
+ // At this point we have no leader. Candidate member 3 would continue to start new elections
+ // but wouldn't be granted a vote. One of the 2 followers would eventually time out from
+ // not having received a heartbeat from a leader and switch to candidate and start a new
+ // election. We'll simulate that here by sending an ElectionTimeout to member 1.
+
+ member1Actor.underlyingActor().clear();
+ member1Actor.underlyingActor().expectMessageClass(RequestVoteReply.class, 1);
+ member2Actor.underlyingActor().clear();
+ member2Actor.underlyingActor().expectMessageClass(RequestVote.class, 1);
+ member3Actor.underlyingActor().clear();
+ member3Actor.underlyingActor().expectMessageClass(RequestVote.class, 1);
+ member3Actor.underlyingActor().expectBehaviorStateChange();
+
+ member1Actor.tell(new ElectionTimeout(), ActorRef.noSender());
+
+ member2Actor.underlyingActor().waitForExpectedMessages(RequestVote.class);
+ member3Actor.underlyingActor().waitForExpectedMessages(RequestVote.class);
+
+ // The RequestVoteReply should come from Follower member 2 and the vote should be granted
+ // since member 2's last term and index matches member 1's.
+
+ member1Actor.underlyingActor().waitForExpectedMessages(RequestVoteReply.class);
+
+ RequestVoteReply requestVoteReply = member1Actor.underlyingActor().getCapturedMessage(RequestVoteReply.class);
+ assertEquals("getTerm", member1Context.getTermInformation().getCurrentTerm(), requestVoteReply.getTerm());
+ assertEquals("isVoteGranted", true, requestVoteReply.isVoteGranted());
+
+ // Candidate member 3 should change to follower as its term should be less than the
+ // RequestVote term (member 1 started a new term higher than the other member's terms).
+
+ member3Actor.underlyingActor().waitForBehaviorStateChange();
+
+ verifyBehaviorState("member 1", member1Actor, RaftState.Leader);
+ verifyBehaviorState("member 2", member2Actor, RaftState.Follower);
+ verifyBehaviorState("member 3", member3Actor, RaftState.Follower);
+
+ // newTerm should be 10.
+
+ long newTerm = candidateElectionTerm + 1;
+ assertEquals("member 1 election term", newTerm, member1Context.getTermInformation().getCurrentTerm());
+ assertEquals("member 2 election term", newTerm, member2Context.getTermInformation().getCurrentTerm());
+ assertEquals("member 3 election term", newTerm, member3Context.getTermInformation().getCurrentTerm());
+
+ testLog.info("testPartitionedCandidateOnStartupScenario done");
+ }
+}
import org.opendaylight.controller.cluster.raft.utils.DoNothingActor;
import org.opendaylight.controller.cluster.raft.utils.MessageCollectorActor;
import org.opendaylight.controller.protobuff.messages.cluster.raft.InstallSnapshotMessages;
-import org.slf4j.impl.SimpleLogger;
import scala.concurrent.duration.FiniteDuration;
public class LeaderTest extends AbstractRaftActorBehaviorTest {
- static {
- // This enables trace logging for the tests.
- System.setProperty(SimpleLogger.LOG_KEY_PREFIX + MockRaftActorContext.class.getName(), "trace");
- }
-
private final ActorRef leaderActor =
getSystem().actorOf(Props.create(DoNothingActor.class));
private final ActorRef senderActor =
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;
+import java.util.concurrent.TimeoutException;
import scala.concurrent.Await;
import scala.concurrent.Future;
import scala.concurrent.duration.Duration;
public class MessageCollectorActor extends UntypedActor {
+ private static final String ARE_YOU_READY = "ARE_YOU_READY";
+
private final List<Object> messages = new ArrayList<>();
@Override public void onReceive(Object message) throws Exception {
+ if(message.equals(ARE_YOU_READY)) {
+ getSender().tell("yes", getSelf());
+ return;
+ }
+
if(message instanceof String){
if("get-all-messages".equals(message)){
- getSender().tell(new ArrayList(messages), getSelf());
+ getSender().tell(new ArrayList<>(messages), getSelf());
}
- } else {
+ } else if(message != null) {
messages.add(message);
}
}
Timeout operationTimeout = new Timeout(operationDuration);
Future<Object> future = Patterns.ask(actor, "get-all-messages", operationTimeout);
- try {
- return (List<Object>) Await.result(future, operationDuration);
- } catch (Exception e) {
- throw e;
- }
+ return (List<Object>) Await.result(future, operationDuration);
}
/**
return output;
}
+ public static void waitUntilReady(ActorRef actor) throws Exception {
+ long timeout = 500;
+ FiniteDuration duration = Duration.create(timeout, TimeUnit.MILLISECONDS);
+ for(int i = 0; i < 10; i++) {
+ try {
+ Await.ready(Patterns.ask(actor, ARE_YOU_READY, timeout), duration);
+ return;
+ } catch (TimeoutException e) {
+ }
+ }
+
+ throw new TimeoutException("Actor not ready in time.");
+ }
}
--- /dev/null
+org.slf4j.simpleLogger.showDateTime=true
+org.slf4j.simpleLogger.dateTimeFormat=hh:mm:ss,S a
+org.slf4j.simpleLogger.logFile=System.out
+org.slf4j.simpleLogger.showShortLogName=true
+org.slf4j.simpleLogger.levelInBrackets=true
+org.slf4j.simpleLogger.org.opendaylight.controller.cluster.raft=trace
\ No newline at end of file
netty.tcp {
hostname = "127.0.0.1"
port = 2551
+ maximum-frame-size = 419430400
+ send-buffer-size = 52428800
+ receive-buffer-size = 52428800
}
}
--- /dev/null
+org.slf4j.simpleLogger.showDateTime=true
+org.slf4j.simpleLogger.dateTimeFormat=hh:mm:ss,S a
+org.slf4j.simpleLogger.logFile=System.out
+org.slf4j.simpleLogger.showShortLogName=true
+org.slf4j.simpleLogger.levelInBrackets=true
+org.slf4j.simpleLogger.log.org.opendaylight.controller.cluster.datastore=trace
\ No newline at end of file
--- /dev/null
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.controller.md.sal.dom.api;
+
+import java.util.Collection;
+import java.util.EventListener;
+import javax.annotation.Nonnull;
+
+/**
+ * An {@link EventListener} used to track RPC implementations becoming (un)available
+ * to a {@link DOMRpcService}.
+ */
+public interface DOMRpcAvailabilityListener extends EventListener {
+ /**
+ * Method invoked whenever an RPC type becomes available.
+ *
+ * @param rpcs RPC types newly available
+ */
+ void onRpcAvailable(@Nonnull Collection<DOMRpcIdentifier> rpcs);
+
+ /**
+ * Method invoked whenever an RPC type becomes unavailable.
+ *
+ * @param rpcs RPC types which became unavailable
+ */
+ void onRpcUnavailable(@Nonnull Collection<DOMRpcIdentifier> rpcs);
+}
--- /dev/null
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.controller.md.sal.dom.api;
+
+/**
+ * Base class for failures that can occur during RPC invocation. This covers
+ * transport and protocol-level failures.
+ */
+public abstract class DOMRpcException extends Exception {
+ private static final long serialVersionUID = 1L;
+
+ /**
+ * Construct an new instance with a message and an empty cause.
+ *
+ * @param message Exception message
+ */
+ protected DOMRpcException(final String message) {
+ super(message);
+ }
+
+ /**
+ * Construct an new instance with a message and a cause.
+ *
+ * @param message Exception message
+ * @param cause Chained cause
+ */
+ protected DOMRpcException(final String message, final Throwable cause) {
+ super(message, cause);
+ }
+}
--- /dev/null
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.controller.md.sal.dom.api;
+
+import com.google.common.base.Preconditions;
+import java.util.Objects;
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
+import org.opendaylight.yangtools.yang.model.api.SchemaPath;
+
+/**
+ * Identifier of a RPC context. This is an extension of the YANG RPC, which
+ * always has global context. It allows an RPC to have a instance identifier
+ * attached, so that there can be multiple implementations bound to different
+ * contexts concurrently.
+ */
+public abstract class DOMRpcIdentifier {
+ private static final class Global extends DOMRpcIdentifier {
+ private Global(final @Nonnull SchemaPath type) {
+ super(type);
+ }
+
+ @Override
+ public YangInstanceIdentifier getContextReference() {
+ return null;
+ }
+ }
+
+ private static final class Local extends DOMRpcIdentifier {
+ private final YangInstanceIdentifier contextReference;
+
+ private Local(final @Nonnull SchemaPath type, final @Nonnull YangInstanceIdentifier contextReference) {
+ super(type);
+ this.contextReference = Preconditions.checkNotNull(contextReference);
+ }
+
+ @Override
+ public YangInstanceIdentifier getContextReference() {
+ return contextReference;
+ }
+ }
+
+ private final SchemaPath type;
+
+ private DOMRpcIdentifier(final SchemaPath type) {
+ this.type = Preconditions.checkNotNull(type);
+ }
+
+ /**
+ * Create a global RPC identifier.
+ *
+ * @param type RPC type, SchemaPath of its definition, may not be null
+ * @return A global RPC identifier, guaranteed to be non-null.
+ */
+ public static @Nonnull DOMRpcIdentifier create(final @Nonnull SchemaPath type) {
+ return new Global(type);
+ }
+
+ /**
+ * Create an RPC identifier with a particular context reference.
+ *
+ * @param type RPC type, SchemaPath of its definition, may not be null
+ * @param contextReference Context reference, null means a global RPC identifier.
+ * @return A global RPC identifier, guaranteed to be non-null.
+ */
+ public static @Nonnull DOMRpcIdentifier create(final @Nonnull SchemaPath type, final @Nullable YangInstanceIdentifier contextReference) {
+ if (contextReference == null) {
+ return new Global(type);
+ } else {
+ return new Local(type, contextReference);
+ }
+ }
+
+ /**
+ * Return the RPC type.
+ *
+ * @return RPC type.
+ */
+ public final @Nonnull SchemaPath getType() {
+ return type;
+ }
+
+ /**
+ * Return the RPC context reference. Null value indicates global context.
+ *
+ * @return RPC context reference.
+ */
+ public abstract @Nullable YangInstanceIdentifier getContextReference();
+
+ @Override
+ public final int hashCode() {
+ final int prime = 31;
+ int result = 1;
+ result = prime * result + type.hashCode();
+ result = prime * result + (getContextReference() == null ? 0 : getContextReference().hashCode());
+ return result;
+ }
+
+ @Override
+ public final boolean equals(final Object obj) {
+ if (this == obj) {
+ return true;
+ }
+ if (!(obj instanceof DOMRpcIdentifier)) {
+ return false;
+ }
+ DOMRpcIdentifier other = (DOMRpcIdentifier) obj;
+ if (!type.equals(other.type)) {
+ return false;
+ }
+ return Objects.equals(getContextReference(), other.getContextReference());
+ }
+
+ @Override
+ public final String toString() {
+ return com.google.common.base.Objects.toStringHelper(this).omitNullValues().add("type", type).add("contextReference", getContextReference()).toString();
+ }
+}
--- /dev/null
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.controller.md.sal.dom.api;
+
+import com.google.common.util.concurrent.CheckedFuture;
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
+
+/**
+ * Interface implemented by an individual RPC implementation. This API allows for dispatch
+ * implementations, e.g. an individual object handling a multitude of RPCs.
+ */
+public interface DOMRpcImplementation {
+ /**
+ * Initiate invocation of the RPC. Implementations of this method are
+ * expected to not block on external resources.
+ *
+ * @param rpc RPC identifier which was invoked
+ * @param input Input arguments, null if the RPC does not take any.
+ * @return A {@link CheckedFuture} which will return either a result structure,
+ * or report a subclass of {@link DOMRpcException} reporting a transport
+ * error.
+ */
+ @Nonnull CheckedFuture<DOMRpcResult, DOMRpcException> invokeRpc(@Nonnull DOMRpcIdentifier rpc, @Nullable NormalizedNode<?, ?> input);
+}
--- /dev/null
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.controller.md.sal.dom.api;
+
+import com.google.common.base.Preconditions;
+import javax.annotation.Nonnull;
+
+/**
+ * Exception indicating that no implementation of the requested RPC service is available.
+ */
+public class DOMRpcImplementationNotAvailableException extends DOMRpcException {
+ private static final long serialVersionUID = 1L;
+
+ public DOMRpcImplementationNotAvailableException(@Nonnull final String format, final Object... args) {
+ super(String.format(format, args));
+ }
+
+ public DOMRpcImplementationNotAvailableException(@Nonnull final Throwable cause, @Nonnull final String format, final Object... args) {
+ super(String.format(format, args), Preconditions.checkNotNull(cause));
+ }
+}
--- /dev/null
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.controller.md.sal.dom.api;
+
+import org.opendaylight.yangtools.concepts.ObjectRegistration;
+
+/**
+ * A registration of a {@link DOMRpcImplementation}. Used to track and revoke a registration
+ * with a {@link DOMRpcProviderService}.
+ *
+ * @param <T> RPC implementation type
+ */
+public interface DOMRpcImplementationRegistration<T extends DOMRpcImplementation> extends ObjectRegistration<T> {
+ @Override
+ void close();
+}
--- /dev/null
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.controller.md.sal.dom.api;
+
+import java.util.Set;
+import javax.annotation.Nonnull;
+
+/**
+ * A {@link DOMService} which allows registration of RPC implementations with a conceptual
+ * router. The client counterpart of this service is {@link DOMRpcService}.
+ */
+public interface DOMRpcProviderService extends DOMService {
+ /**
+ * Register an {@link DOMRpcImplementation} object with this service.
+ *
+ * @param implementation RPC implementation, must not be null
+ * @param rpcs Array of supported RPC identifiers. Must not be null, empty, or contain a null element.
+ * Each identifier is added exactly once, no matter how many times it occurs.
+ * @return A {@link DOMRpcImplementationRegistration} object, guaranteed to be non-null.
+ * @throws NullPointerException if implementation or types is null
+ * @throws IllegalArgumentException if types is empty or contains a null element.
+ */
+ @Nonnull <T extends DOMRpcImplementation> DOMRpcImplementationRegistration<T> registerRpcImplementation(@Nonnull T implementation, @Nonnull DOMRpcIdentifier... rpcs);
+
+ /**
+ * Register an {@link DOMRpcImplementation} object with this service.
+ *
+ * @param implementation RPC implementation, must not be null
+ * @param rpcs Set of supported RPC identifiers. Must not be null, empty, or contain a null element.
+ * @return A {@link DOMRpcImplementationRegistration} object, guaranteed to be non-null.
+ * @throws NullPointerException if implementation or types is null
+ * @throws IllegalArgumentException if types is empty or contains a null element.
+ */
+ @Nonnull <T extends DOMRpcImplementation> DOMRpcImplementationRegistration<T> registerRpcImplementation(@Nonnull T implementation, @Nonnull Set<DOMRpcIdentifier> rpcs);
+}
--- /dev/null
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.controller.md.sal.dom.api;
+
+import java.util.Collection;
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+import org.opendaylight.yangtools.yang.common.RpcError;
+import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
+
+/**
+ * Interface defining a result of an RPC call.
+ */
+public interface DOMRpcResult {
+ /**
+ * Returns a set of errors and warnings which occurred during processing
+ * the call.
+ *
+ * @return a Collection of {@link RpcError}, guaranteed to be non-null. In case
+ * no errors are reported, an empty collection is returned.
+ */
+ @Nonnull Collection<RpcError> getErrors();
+
+ /**
+ * Returns the value result of the call or null if no result is available.
+ *
+ * @return Invocation result, null if the operation has not produced a result. This might
+ * be the case if the operation does not produce a result, or if it failed.
+ */
+ @Nullable NormalizedNode<?, ?> getResult();
+}
--- /dev/null
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.controller.md.sal.dom.api;
+
+import com.google.common.util.concurrent.CheckedFuture;
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+import org.opendaylight.yangtools.concepts.ListenerRegistration;
+import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
+import org.opendaylight.yangtools.yang.model.api.SchemaPath;
+
+/**
+ * A {@link DOMService} which allows clients to invoke RPCs. The conceptual model of this
+ * service is that of a dynamic router, where the set of available RPC services can change
+ * dynamically. The service allows users to add a listener to track the process of
+ * RPCs becoming available.
+ */
+public interface DOMRpcService extends DOMService {
+ /**
+ * Initiate invocation of an RPC. This method is guaranteed to not block on any external
+ * resources.
+ *
+ * @param type SchemaPath of the RPC to be invoked
+ * @param input Input arguments, null if the RPC does not take any.
+ * @return A {@link CheckedFuture} which will return either a result structure,
+ * or report a subclass of {@link DOMRpcException} reporting a transport
+ * error.
+ */
+ @Nonnull CheckedFuture<DOMRpcResult, DOMRpcException> invokeRpc(@Nonnull SchemaPath type, @Nullable NormalizedNode<?, ?> input);
+
+ /**
+ * Register a {@link DOMRpcAvailabilityListener} with this service to receive notifications
+ * about RPC implementations becoming (un)available. The listener will be invoked with the
+ * current implementations reported and will be kept uptodate as implementations come and go.
+ *
+ * Users should note that using a listener does not necessarily mean that {@link #invokeRpc(SchemaPath, NormalizedNode)}
+ * will not report a failure due to {@link DOMRpcImplementationNotAvailableException} and
+ * need to be ready to handle it. Implementations are encouraged to take reasonable precautions
+ * to prevent this scenario from occurring.
+ *
+ * @param listener {@link DOMRpcAvailabilityListener} instance to register
+ * @return A {@link DOMRpcAvailabilityListenerRegistration} representing this registration. Performing
+ * a {@link DOMRpcAvailabilityListenerRegistration#close()} will cancel it. Returned object
+ * is guaranteed to be non-null.
+ */
+ @Nonnull <T extends DOMRpcAvailabilityListener> ListenerRegistration<T> registerRpcListener(@Nonnull T listener);
+}
--- /dev/null
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.controller.md.sal.dom.broker.impl;
+
+import com.google.common.base.Preconditions;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.ImmutableMap.Builder;
+import com.google.common.util.concurrent.CheckedFuture;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Set;
+import org.opendaylight.controller.md.sal.dom.api.DOMRpcException;
+import org.opendaylight.controller.md.sal.dom.api.DOMRpcImplementation;
+import org.opendaylight.controller.md.sal.dom.api.DOMRpcResult;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
+import org.opendaylight.yangtools.yang.model.api.SchemaPath;
+
+abstract class AbstractDOMRpcRoutingTableEntry {
+ private final Map<YangInstanceIdentifier, List<DOMRpcImplementation>> impls;
+ private final SchemaPath schemaPath;
+
+ protected AbstractDOMRpcRoutingTableEntry(final SchemaPath schemaPath, final Map<YangInstanceIdentifier, List<DOMRpcImplementation>> impls) {
+ this.schemaPath = Preconditions.checkNotNull(schemaPath);
+ this.impls = Preconditions.checkNotNull(impls);
+ }
+
+ protected final SchemaPath getSchemaPath() {
+ return schemaPath;
+ }
+
+ protected final List<DOMRpcImplementation> getImplementations(final YangInstanceIdentifier context) {
+ return impls.get(context);
+ }
+
+ final Map<YangInstanceIdentifier, List<DOMRpcImplementation>> getImplementations() {
+ return impls;
+ }
+
+ public boolean containsContext(final YangInstanceIdentifier contextReference) {
+ return impls.containsKey(contextReference);
+ }
+
+ final Set<YangInstanceIdentifier> registeredIdentifiers() {
+ return impls.keySet();
+ }
+
+ final AbstractDOMRpcRoutingTableEntry add(final DOMRpcImplementation implementation, final List<YangInstanceIdentifier> newRpcs) {
+ final Builder<YangInstanceIdentifier, List<DOMRpcImplementation>> vb = ImmutableMap.builder();
+ for (Entry<YangInstanceIdentifier, List<DOMRpcImplementation>> ve : impls.entrySet()) {
+ if (newRpcs.remove(ve.getKey())) {
+ final ArrayList<DOMRpcImplementation> i = new ArrayList<>(ve.getValue().size() + 1);
+ i.addAll(ve.getValue());
+ i.add(implementation);
+ vb.put(ve.getKey(), i);
+ } else {
+ vb.put(ve);
+ }
+ }
+
+ return newInstance(vb.build());
+ }
+
+ final AbstractDOMRpcRoutingTableEntry remove(final DOMRpcImplementation implementation, final List<YangInstanceIdentifier> removed) {
+ final Builder<YangInstanceIdentifier, List<DOMRpcImplementation>> vb = ImmutableMap.builder();
+ for (Entry<YangInstanceIdentifier, List<DOMRpcImplementation>> ve : impls.entrySet()) {
+ if (removed.remove(ve.getKey())) {
+ final ArrayList<DOMRpcImplementation> i = new ArrayList<>(ve.getValue());
+ i.remove(implementation);
+ // We could trimToSize(), but that may perform another copy just to get rid
+ // of a single element. That is probably not worth the trouble.
+ if (!i.isEmpty()) {
+ vb.put(ve.getKey(), i);
+ }
+ } else {
+ vb.put(ve);
+ }
+ }
+
+ final Map<YangInstanceIdentifier, List<DOMRpcImplementation>> v = vb.build();
+ return v.isEmpty() ? null : newInstance(v);
+ }
+
+ protected abstract CheckedFuture<DOMRpcResult, DOMRpcException> invokeRpc(final NormalizedNode<?, ?> input);
+ protected abstract AbstractDOMRpcRoutingTableEntry newInstance(final Map<YangInstanceIdentifier, List<DOMRpcImplementation>> impls);
+}
--- /dev/null
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.controller.md.sal.dom.broker.impl;
+
+import com.google.common.base.Function;
+import com.google.common.base.Predicate;
+import com.google.common.collect.Collections2;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableList.Builder;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.util.concurrent.CheckedFuture;
+import com.google.common.util.concurrent.ThreadFactoryBuilder;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Set;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.ThreadFactory;
+import javax.annotation.concurrent.GuardedBy;
+import org.opendaylight.controller.md.sal.dom.api.DOMRpcAvailabilityListener;
+import org.opendaylight.controller.md.sal.dom.api.DOMRpcException;
+import org.opendaylight.controller.md.sal.dom.api.DOMRpcIdentifier;
+import org.opendaylight.controller.md.sal.dom.api.DOMRpcImplementation;
+import org.opendaylight.controller.md.sal.dom.api.DOMRpcImplementationRegistration;
+import org.opendaylight.controller.md.sal.dom.api.DOMRpcProviderService;
+import org.opendaylight.controller.md.sal.dom.api.DOMRpcResult;
+import org.opendaylight.controller.md.sal.dom.api.DOMRpcService;
+import org.opendaylight.controller.md.sal.dom.spi.AbstractDOMRpcImplementationRegistration;
+import org.opendaylight.yangtools.concepts.AbstractListenerRegistration;
+import org.opendaylight.yangtools.concepts.ListenerRegistration;
+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 org.opendaylight.yangtools.yang.model.api.SchemaContextListener;
+import org.opendaylight.yangtools.yang.model.api.SchemaPath;
+
+public final class DOMRpcRouter implements AutoCloseable, DOMRpcService, DOMRpcProviderService, SchemaContextListener {
+ private static final ThreadFactory THREAD_FACTORY = new ThreadFactoryBuilder().setNameFormat("DOMRpcRouter-listener-%s").setDaemon(true).build();
+ private final ExecutorService listenerNotifier = Executors.newSingleThreadExecutor(THREAD_FACTORY);
+ @GuardedBy("this")
+ private Collection<ListenerRegistration<? extends DOMRpcAvailabilityListener>> listeners = Collections.emptyList();
+ private volatile DOMRpcRoutingTable routingTable = DOMRpcRoutingTable.EMPTY;
+
+ @Override
+ public <T extends DOMRpcImplementation> DOMRpcImplementationRegistration<T> registerRpcImplementation(final T implementation, final DOMRpcIdentifier... rpcs) {
+ return registerRpcImplementation(implementation, ImmutableSet.copyOf(rpcs));
+ }
+
+ private static Collection<DOMRpcIdentifier> notPresentRpcs(final DOMRpcRoutingTable table, final Collection<DOMRpcIdentifier> candidates) {
+ return ImmutableSet.copyOf(Collections2.filter(candidates, new Predicate<DOMRpcIdentifier>() {
+ @Override
+ public boolean apply(final DOMRpcIdentifier input) {
+ return !table.contains(input);
+ }
+ }));
+ }
+
+ private synchronized void removeRpcImplementation(final DOMRpcImplementation implementation, final Set<DOMRpcIdentifier> rpcs) {
+ final DOMRpcRoutingTable oldTable = routingTable;
+ final DOMRpcRoutingTable newTable = oldTable.remove(implementation, rpcs);
+
+ final Collection<DOMRpcIdentifier> removedRpcs = notPresentRpcs(newTable, rpcs);
+ final Collection<ListenerRegistration<? extends DOMRpcAvailabilityListener>> capturedListeners = listeners;
+ routingTable = newTable;
+
+ listenerNotifier.execute(new Runnable() {
+ @Override
+ public void run() {
+ for (ListenerRegistration<? extends DOMRpcAvailabilityListener> l : capturedListeners) {
+ // Need to ensure removed listeners do not get notified
+ synchronized (DOMRpcRouter.this) {
+ if (listeners.contains(l)) {
+ l.getInstance().onRpcUnavailable(removedRpcs);
+ }
+ }
+ }
+ }
+ });
+ }
+
+ @Override
+ public synchronized <T extends DOMRpcImplementation> DOMRpcImplementationRegistration<T> registerRpcImplementation(final T implementation, final Set<DOMRpcIdentifier> rpcs) {
+ final DOMRpcRoutingTable oldTable = routingTable;
+ final DOMRpcRoutingTable newTable = oldTable.add(implementation, rpcs);
+
+ final Collection<DOMRpcIdentifier> addedRpcs = notPresentRpcs(oldTable, rpcs);
+ final Collection<ListenerRegistration<? extends DOMRpcAvailabilityListener>> capturedListeners = listeners;
+ routingTable = newTable;
+
+ listenerNotifier.execute(new Runnable() {
+ @Override
+ public void run() {
+ for (ListenerRegistration<? extends DOMRpcAvailabilityListener> l : capturedListeners) {
+ // Need to ensure removed listeners do not get notified
+ synchronized (DOMRpcRouter.this) {
+ if (listeners.contains(l)) {
+ l.getInstance().onRpcAvailable(addedRpcs);
+ }
+ }
+ }
+ }
+ });
+
+ return new AbstractDOMRpcImplementationRegistration<T>(implementation) {
+ @Override
+ protected void removeRegistration() {
+ removeRpcImplementation(getInstance(), rpcs);
+ }
+ };
+ }
+
+ @Override
+ public CheckedFuture<DOMRpcResult, DOMRpcException> invokeRpc(final SchemaPath type, final NormalizedNode<?, ?> input) {
+ return routingTable.invokeRpc(type, input);
+ }
+
+ private synchronized void removeListener(final ListenerRegistration<? extends DOMRpcAvailabilityListener> reg) {
+ listeners = ImmutableList.copyOf(Collections2.filter(listeners, new Predicate<Object>() {
+ @Override
+ public boolean apply(final Object input) {
+ return !reg.equals(input);
+ }
+ }));
+ }
+
+ @Override
+ public synchronized <T extends DOMRpcAvailabilityListener> ListenerRegistration<T> registerRpcListener(final T listener) {
+ final ListenerRegistration<T> ret = new AbstractListenerRegistration<T>(listener) {
+ @Override
+ protected void removeRegistration() {
+ removeListener(this);
+ }
+ };
+
+ final Builder<ListenerRegistration<? extends DOMRpcAvailabilityListener>> b = ImmutableList.builder();
+ b.addAll(listeners);
+ b.add(ret);
+ listeners = b.build();
+ final Map<SchemaPath, Set<YangInstanceIdentifier>> capturedRpcs = routingTable.getRpcs();
+
+ listenerNotifier.execute(new Runnable() {
+ @Override
+ public void run() {
+ for (final Entry<SchemaPath, Set<YangInstanceIdentifier>> e : capturedRpcs.entrySet()) {
+ listener.onRpcAvailable(Collections2.transform(e.getValue(), new Function<YangInstanceIdentifier, DOMRpcIdentifier>() {
+ @Override
+ public DOMRpcIdentifier apply(final YangInstanceIdentifier input) {
+ return DOMRpcIdentifier.create(e.getKey(), input);
+ }
+ }));
+ }
+ }
+ });
+
+ return ret;
+ }
+
+ @Override
+ public synchronized void onGlobalContextUpdated(final SchemaContext context) {
+ final DOMRpcRoutingTable oldTable = routingTable;
+ final DOMRpcRoutingTable newTable = oldTable.setSchemaContext(context);
+ routingTable = newTable;
+ }
+
+ @Override
+ public void close() {
+ listenerNotifier.shutdown();
+ }
+
+}
--- /dev/null
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.controller.md.sal.dom.broker.impl;
+
+import com.google.common.base.Function;
+import com.google.common.base.Preconditions;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.ImmutableMap.Builder;
+import com.google.common.collect.LinkedListMultimap;
+import com.google.common.collect.ListMultimap;
+import com.google.common.collect.Maps;
+import com.google.common.util.concurrent.CheckedFuture;
+import com.google.common.util.concurrent.Futures;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Set;
+import org.opendaylight.controller.md.sal.dom.api.DOMRpcException;
+import org.opendaylight.controller.md.sal.dom.api.DOMRpcIdentifier;
+import org.opendaylight.controller.md.sal.dom.api.DOMRpcImplementation;
+import org.opendaylight.controller.md.sal.dom.api.DOMRpcImplementationNotAvailableException;
+import org.opendaylight.controller.md.sal.dom.api.DOMRpcResult;
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
+import org.opendaylight.yangtools.yang.model.api.ContainerSchemaNode;
+import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
+import org.opendaylight.yangtools.yang.model.api.Module;
+import org.opendaylight.yangtools.yang.model.api.RpcDefinition;
+import org.opendaylight.yangtools.yang.model.api.SchemaContext;
+import org.opendaylight.yangtools.yang.model.api.SchemaPath;
+import org.opendaylight.yangtools.yang.model.api.UnknownSchemaNode;
+
+final class DOMRpcRoutingTable {
+ private static final QName CONTEXT_REFERENCE = QName.cachedReference(QName.create("urn:opendaylight:yang:extension:yang-ext", "2013-07-09", "context-reference"));
+
+ static final DOMRpcRoutingTable EMPTY = new DOMRpcRoutingTable();
+ private static final Function<AbstractDOMRpcRoutingTableEntry, Set<YangInstanceIdentifier>> EXTRACT_IDENTIFIERS =
+ new Function<AbstractDOMRpcRoutingTableEntry, Set<YangInstanceIdentifier>>() {
+ @Override
+ public Set<YangInstanceIdentifier> apply(final AbstractDOMRpcRoutingTableEntry input) {
+ return input.registeredIdentifiers();
+ }
+ };
+ private final Map<SchemaPath, AbstractDOMRpcRoutingTableEntry> rpcs;
+ private final SchemaContext schemaContext;
+
+ private DOMRpcRoutingTable() {
+ rpcs = Collections.emptyMap();
+ schemaContext = null;
+ }
+
+ private DOMRpcRoutingTable(final Map<SchemaPath, AbstractDOMRpcRoutingTableEntry> rpcs, final SchemaContext schemaContext) {
+ this.rpcs = Preconditions.checkNotNull(rpcs);
+ this.schemaContext = schemaContext;
+ }
+
+ private static ListMultimap<SchemaPath, YangInstanceIdentifier> decomposeIdentifiers(final Set<DOMRpcIdentifier> rpcs) {
+ final ListMultimap<SchemaPath, YangInstanceIdentifier> ret = LinkedListMultimap.create();
+ for (DOMRpcIdentifier i : rpcs) {
+ ret.put(i.getType(), i.getContextReference());
+ }
+ return ret;
+ }
+
+ DOMRpcRoutingTable add(final DOMRpcImplementation implementation, final Set<DOMRpcIdentifier> rpcs) {
+ if (rpcs.isEmpty()) {
+ return this;
+ }
+
+ // First decompose the identifiers to a multimap
+ final ListMultimap<SchemaPath, YangInstanceIdentifier> toAdd = decomposeIdentifiers(rpcs);
+
+ // Now iterate over existing entries, modifying them as appropriate...
+ final Builder<SchemaPath, AbstractDOMRpcRoutingTableEntry> mb = ImmutableMap.builder();
+ for (Entry<SchemaPath, AbstractDOMRpcRoutingTableEntry> re : this.rpcs.entrySet()) {
+ List<YangInstanceIdentifier> newRpcs = toAdd.removeAll(re.getKey());
+ if (!newRpcs.isEmpty()) {
+ final AbstractDOMRpcRoutingTableEntry ne = re.getValue().add(implementation, newRpcs);
+ mb.put(re.getKey(), ne);
+ } else {
+ mb.put(re);
+ }
+ }
+
+ // Finally add whatever is left in the decomposed multimap
+ for (Entry<SchemaPath, Collection<YangInstanceIdentifier>> e : toAdd.asMap().entrySet()) {
+ final Builder<YangInstanceIdentifier, List<DOMRpcImplementation>> vb = ImmutableMap.builder();
+ final List<DOMRpcImplementation> v = Collections.singletonList(implementation);
+ for (YangInstanceIdentifier i : e.getValue()) {
+ vb.put(i, v);
+ }
+
+ mb.put(e.getKey(), createRpcEntry(schemaContext, e.getKey(), vb.build()));
+ }
+
+ return new DOMRpcRoutingTable(mb.build(), schemaContext);
+ }
+
+ DOMRpcRoutingTable remove(final DOMRpcImplementation implementation, final Set<DOMRpcIdentifier> rpcs) {
+ if (rpcs.isEmpty()) {
+ return this;
+ }
+
+ // First decompose the identifiers to a multimap
+ final ListMultimap<SchemaPath, YangInstanceIdentifier> toRemove = decomposeIdentifiers(rpcs);
+
+ // Now iterate over existing entries, modifying them as appropriate...
+ final Builder<SchemaPath, AbstractDOMRpcRoutingTableEntry> b = ImmutableMap.builder();
+ for (Entry<SchemaPath, AbstractDOMRpcRoutingTableEntry> e : this.rpcs.entrySet()) {
+ final List<YangInstanceIdentifier> removed = toRemove.removeAll(e.getKey());
+ if (!removed.isEmpty()) {
+ final AbstractDOMRpcRoutingTableEntry ne = e.getValue().remove(implementation, removed);
+ if (ne != null) {
+ b.put(e.getKey(), ne);
+ }
+ } else {
+ b.put(e);
+ }
+ }
+
+ // All done, whatever is in toRemove, was not there in the first place
+ return new DOMRpcRoutingTable(b.build(), schemaContext);
+ }
+
+ boolean contains(final DOMRpcIdentifier input) {
+ final AbstractDOMRpcRoutingTableEntry contexts = rpcs.get(input.getType());
+ return contexts != null && contexts.containsContext(input.getContextReference());
+ }
+
+ Map<SchemaPath, Set<YangInstanceIdentifier>> getRpcs() {
+ return Maps.transformValues(rpcs, EXTRACT_IDENTIFIERS);
+ }
+
+ private static RpcDefinition findRpcDefinition(final SchemaContext context, final SchemaPath schemaPath) {
+ if (context != null) {
+ final QName qname = schemaPath.getPathFromRoot().iterator().next();
+ final Module module = context.findModuleByNamespaceAndRevision(qname.getNamespace(), qname.getRevision());
+ if (module != null && module.getRpcs() != null) {
+ for (RpcDefinition rpc : module.getRpcs()) {
+ if (qname.equals(rpc.getQName())) {
+ return rpc;
+ }
+ }
+ }
+ }
+
+ return null;
+ }
+
+ private static AbstractDOMRpcRoutingTableEntry createRpcEntry(final SchemaContext context, final SchemaPath key, final Map<YangInstanceIdentifier, List<DOMRpcImplementation>> implementations) {
+ final RpcDefinition rpcDef = findRpcDefinition(context, key);
+ if (rpcDef != null) {
+ final ContainerSchemaNode input = rpcDef.getInput();
+ if (input != null) {
+ for (DataSchemaNode c : input.getChildNodes()) {
+ for (UnknownSchemaNode extension : c.getUnknownSchemaNodes()) {
+ if (CONTEXT_REFERENCE.equals(extension.getNodeType())) {
+ final YangInstanceIdentifier keyId = YangInstanceIdentifier.builder().node(input.getQName()).node(c.getQName()).build();
+ return new RoutedDOMRpcRoutingTableEntry(rpcDef, keyId, implementations);
+ }
+ }
+ }
+ }
+
+ return new GlobalDOMRpcRoutingTableEntry(rpcDef, implementations);
+ } else {
+ return new UnknownDOMRpcRoutingTableEntry(key, implementations);
+ }
+ }
+
+ CheckedFuture<DOMRpcResult, DOMRpcException> invokeRpc(final SchemaPath type, final NormalizedNode<?, ?> input) {
+ final AbstractDOMRpcRoutingTableEntry entry = rpcs.get(type);
+ if (entry == null) {
+ return Futures.<DOMRpcResult, DOMRpcException>immediateFailedCheckedFuture(new DOMRpcImplementationNotAvailableException("No implementation of RPC %s available", type));
+ }
+
+ return entry.invokeRpc(input);
+ }
+
+ DOMRpcRoutingTable setSchemaContext(final SchemaContext context) {
+ final Builder<SchemaPath, AbstractDOMRpcRoutingTableEntry> b = ImmutableMap.builder();
+
+ for (Entry<SchemaPath, AbstractDOMRpcRoutingTableEntry> e : rpcs.entrySet()) {
+ b.put(e.getKey(), createRpcEntry(context, e.getKey(), e.getValue().getImplementations()));
+ }
+
+ return new DOMRpcRoutingTable(b.build(), context);
+ }
+
+}
--- /dev/null
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.controller.md.sal.dom.broker.impl;
+
+import com.google.common.base.Preconditions;
+import com.google.common.util.concurrent.CheckedFuture;
+import java.util.List;
+import java.util.Map;
+import org.opendaylight.controller.md.sal.dom.api.DOMRpcException;
+import org.opendaylight.controller.md.sal.dom.api.DOMRpcIdentifier;
+import org.opendaylight.controller.md.sal.dom.api.DOMRpcImplementation;
+import org.opendaylight.controller.md.sal.dom.api.DOMRpcResult;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
+import org.opendaylight.yangtools.yang.model.api.RpcDefinition;
+
+final class GlobalDOMRpcRoutingTableEntry extends AbstractDOMRpcRoutingTableEntry {
+ private final DOMRpcIdentifier rpcId;
+
+ private GlobalDOMRpcRoutingTableEntry(final DOMRpcIdentifier rpcId, final Map<YangInstanceIdentifier, List<DOMRpcImplementation>> impls) {
+ super(rpcId.getType(), impls);
+ this.rpcId = Preconditions.checkNotNull(rpcId);
+ }
+
+ // We do not need the RpcDefinition, but this makes sure we do not
+ // forward something we don't know to be an RPC.
+ GlobalDOMRpcRoutingTableEntry(final RpcDefinition def, final Map<YangInstanceIdentifier, List<DOMRpcImplementation>> impls) {
+ super(def.getPath(), impls);
+ this.rpcId = DOMRpcIdentifier.create(def.getPath());
+ }
+
+ @Override
+ protected CheckedFuture<DOMRpcResult, DOMRpcException> invokeRpc(final NormalizedNode<?, ?> input) {
+ return getImplementations(null).get(0).invokeRpc(rpcId, input);
+ }
+
+ @Override
+ protected GlobalDOMRpcRoutingTableEntry newInstance(final Map<YangInstanceIdentifier, List<DOMRpcImplementation>> impls) {
+ return new GlobalDOMRpcRoutingTableEntry(rpcId, impls);
+ }
+}
\ No newline at end of file
--- /dev/null
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.controller.md.sal.dom.broker.impl;
+
+import com.google.common.base.Optional;
+import com.google.common.base.Preconditions;
+import com.google.common.util.concurrent.CheckedFuture;
+import com.google.common.util.concurrent.Futures;
+import java.util.List;
+import java.util.Map;
+import org.opendaylight.controller.md.sal.dom.api.DOMRpcException;
+import org.opendaylight.controller.md.sal.dom.api.DOMRpcIdentifier;
+import org.opendaylight.controller.md.sal.dom.api.DOMRpcImplementation;
+import org.opendaylight.controller.md.sal.dom.api.DOMRpcImplementationNotAvailableException;
+import org.opendaylight.controller.md.sal.dom.api.DOMRpcResult;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
+import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNodes;
+import org.opendaylight.yangtools.yang.model.api.RpcDefinition;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+final class RoutedDOMRpcRoutingTableEntry extends AbstractDOMRpcRoutingTableEntry {
+ private static final Logger LOG = LoggerFactory.getLogger(RoutedDOMRpcRoutingTableEntry.class);
+ private final DOMRpcIdentifier globalRpcId;
+ private final YangInstanceIdentifier keyId;
+
+ private RoutedDOMRpcRoutingTableEntry(final DOMRpcIdentifier globalRpcId, final YangInstanceIdentifier keyId, final Map<YangInstanceIdentifier, List<DOMRpcImplementation>> impls) {
+ super(globalRpcId.getType(), impls);
+ this.keyId = Preconditions.checkNotNull(keyId);
+ this.globalRpcId = Preconditions.checkNotNull(globalRpcId);
+ }
+
+ RoutedDOMRpcRoutingTableEntry(final RpcDefinition def, final YangInstanceIdentifier keyId, final Map<YangInstanceIdentifier, List<DOMRpcImplementation>> impls) {
+ super(def.getPath(), impls);
+ this.keyId = Preconditions.checkNotNull(keyId);
+ this.globalRpcId = DOMRpcIdentifier.create(def.getPath());
+ }
+
+ @Override
+ protected CheckedFuture<DOMRpcResult, DOMRpcException> invokeRpc(final NormalizedNode<?, ?> input) {
+ final Optional<NormalizedNode<?, ?>> maybeKey = NormalizedNodes.findNode(input, keyId);
+
+ // Routing key is present, attempt to deliver as a routed RPC
+ if (maybeKey.isPresent()) {
+ final NormalizedNode<?, ?> key = maybeKey.get();
+ final Object value = key.getValue();
+ if (value instanceof YangInstanceIdentifier) {
+ final YangInstanceIdentifier iid = (YangInstanceIdentifier) value;
+ final List<DOMRpcImplementation> impls = getImplementations(iid);
+ if (impls != null) {
+ return impls.get(0).invokeRpc(DOMRpcIdentifier.create(getSchemaPath(), iid), input);
+ }
+ LOG.debug("No implementation for context {} found", iid);
+ } else {
+ LOG.warn("Ignoring wrong context value {}", value);
+ }
+ }
+
+ final List<DOMRpcImplementation> impls = getImplementations(null);
+ if (impls != null) {
+ return impls.get(0).invokeRpc(globalRpcId, input);
+ } else {
+ return Futures.<DOMRpcResult, DOMRpcException>immediateFailedCheckedFuture(new DOMRpcImplementationNotAvailableException("No implementation of RPC %s available", getSchemaPath()));
+ }
+ }
+
+ @Override
+ protected RoutedDOMRpcRoutingTableEntry newInstance(final Map<YangInstanceIdentifier, List<DOMRpcImplementation>> impls) {
+ return new RoutedDOMRpcRoutingTableEntry(globalRpcId, keyId, impls);
+ }
+}
\ No newline at end of file
--- /dev/null
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.controller.md.sal.dom.broker.impl;
+
+import com.google.common.util.concurrent.CheckedFuture;
+import com.google.common.util.concurrent.Futures;
+import java.util.List;
+import java.util.Map;
+import org.opendaylight.controller.md.sal.dom.api.DOMRpcException;
+import org.opendaylight.controller.md.sal.dom.api.DOMRpcImplementation;
+import org.opendaylight.controller.md.sal.dom.api.DOMRpcImplementationNotAvailableException;
+import org.opendaylight.controller.md.sal.dom.api.DOMRpcResult;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
+import org.opendaylight.yangtools.yang.model.api.SchemaPath;
+
+final class UnknownDOMRpcRoutingTableEntry extends AbstractDOMRpcRoutingTableEntry {
+ private final CheckedFuture<DOMRpcResult, DOMRpcException> unknownRpc;
+
+ UnknownDOMRpcRoutingTableEntry(final SchemaPath schemaPath, final Map<YangInstanceIdentifier, List<DOMRpcImplementation>> impls) {
+ super(schemaPath, impls);
+ unknownRpc = Futures.<DOMRpcResult, DOMRpcException>immediateFailedCheckedFuture(
+ new DOMRpcImplementationNotAvailableException("SchemaPath %s is not resolved to an RPC", schemaPath));
+ }
+
+ @Override
+ protected CheckedFuture<DOMRpcResult, DOMRpcException> invokeRpc(final NormalizedNode<?, ?> input) {
+ return unknownRpc;
+ }
+
+ @Override
+ protected UnknownDOMRpcRoutingTableEntry newInstance(final Map<YangInstanceIdentifier, List<DOMRpcImplementation>> impls) {
+ return new UnknownDOMRpcRoutingTableEntry(getSchemaPath(), impls);
+ }
+}
\ No newline at end of file
--- /dev/null
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.controller.md.sal.dom.spi;
+
+import org.opendaylight.controller.md.sal.dom.api.DOMRpcImplementation;
+import org.opendaylight.controller.md.sal.dom.api.DOMRpcImplementationRegistration;
+import org.opendaylight.yangtools.concepts.AbstractObjectRegistration;
+
+/**
+ * Abstract base class for {@link DOMRpcImplementationRegistration} implementations.
+ */
+public abstract class AbstractDOMRpcImplementationRegistration<T extends DOMRpcImplementation> extends AbstractObjectRegistration<T> implements DOMRpcImplementationRegistration<T> {
+ protected AbstractDOMRpcImplementationRegistration(final T instance) {
+ super(instance);
+ }
+}
--- /dev/null
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.controller.md.sal.dom.spi;
+
+import com.google.common.collect.ImmutableSet;
+import org.opendaylight.controller.md.sal.dom.api.DOMRpcIdentifier;
+import org.opendaylight.controller.md.sal.dom.api.DOMRpcImplementation;
+import org.opendaylight.controller.md.sal.dom.api.DOMRpcImplementationRegistration;
+import org.opendaylight.controller.md.sal.dom.api.DOMRpcProviderService;
+
+/**
+ * Convenience abstract base class for {@link DOMRpcProviderService} implementations.
+ */
+public abstract class AbstractDOMRpcProviderService implements DOMRpcProviderService {
+ @Override
+ public final <T extends DOMRpcImplementation> DOMRpcImplementationRegistration<T> registerRpcImplementation(final T implementation, final DOMRpcIdentifier... types) {
+ return registerRpcImplementation(implementation, ImmutableSet.copyOf(types));
+ }
+}
--- /dev/null
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.controller.md.sal.dom.spi;
+
+import com.google.common.annotations.Beta;
+import com.google.common.base.Preconditions;
+import java.io.Serializable;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Objects;
+import javax.annotation.Nonnull;
+import org.opendaylight.controller.md.sal.dom.api.DOMRpcResult;
+import org.opendaylight.yangtools.concepts.Immutable;
+import org.opendaylight.yangtools.yang.common.RpcError;
+import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
+
+/**
+ * Utility class implementing {@link DefaultDOMRpcResult}.
+ */
+@Beta
+public final class DefaultDOMRpcResult implements DOMRpcResult, Immutable, Serializable {
+ private static final long serialVersionUID = 1L;
+ private final Collection<RpcError> errors;
+ private final NormalizedNode<?, ?> result;
+
+ private static Collection<RpcError> asCollection(final RpcError... errors) {
+ if (errors.length == 0) {
+ return Collections.emptyList();
+ } else {
+ return Arrays.asList(errors);
+ }
+ }
+
+ public DefaultDOMRpcResult(final NormalizedNode<?, ?> result, final RpcError... errors) {
+ this(result, asCollection(errors));
+ }
+
+ public DefaultDOMRpcResult(final RpcError... errors) {
+ this(null, asCollection(errors));
+ }
+
+ public DefaultDOMRpcResult(final NormalizedNode<?, ?> result) {
+ this(result, Collections.<RpcError>emptyList());
+ }
+
+ public DefaultDOMRpcResult(final NormalizedNode<?, ?> result, final @Nonnull Collection<RpcError> errors) {
+ this.result = result;
+ this.errors = Preconditions.checkNotNull(errors);
+ }
+
+ public DefaultDOMRpcResult(final @Nonnull Collection<RpcError> errors) {
+ this(null, errors);
+ }
+
+ @Override
+ public @Nonnull Collection<RpcError> getErrors() {
+ return errors;
+ }
+
+ @Override
+ public NormalizedNode<?, ?> getResult() {
+ return result;
+ }
+
+ @Override
+ public int hashCode() {
+ int ret = errors.hashCode();
+ if (result != null) {
+ ret = 31 * ret + result.hashCode();
+ }
+ return ret;
+ }
+
+ @Override
+ public boolean equals(final Object obj) {
+ if (this == obj) {
+ return true;
+ }
+ if (!(obj instanceof DefaultDOMRpcResult)) {
+ return false;
+ }
+
+ final DefaultDOMRpcResult other = (DefaultDOMRpcResult) obj;
+ if (!errors.equals(other.errors)) {
+ return false;
+ }
+ return Objects.equals(result, other.result);
+ }
+}
--- /dev/null
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.controller.md.sal.dom.spi;
+
+import com.google.common.collect.ForwardingObject;
+import com.google.common.util.concurrent.CheckedFuture;
+import javax.annotation.Nonnull;
+import org.opendaylight.controller.md.sal.dom.api.DOMRpcException;
+import org.opendaylight.controller.md.sal.dom.api.DOMRpcIdentifier;
+import org.opendaylight.controller.md.sal.dom.api.DOMRpcImplementation;
+import org.opendaylight.controller.md.sal.dom.api.DOMRpcResult;
+import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
+
+/**
+ * Utility implementation which implements {@link DOMRpcImplementation} by forwarding it to
+ * a backing delegate.
+ */
+public abstract class ForwardingDOMRpcImplementation extends ForwardingObject implements DOMRpcImplementation {
+ @Override
+ protected abstract @Nonnull DOMRpcImplementation delegate();
+
+ @Override
+ public CheckedFuture<DOMRpcResult, DOMRpcException> invokeRpc(final DOMRpcIdentifier type, final NormalizedNode<?, ?> input) {
+ return delegate().invokeRpc(type, input);
+ }
+}
--- /dev/null
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.controller.md.sal.dom.spi;
+
+import com.google.common.collect.ForwardingObject;
+import java.util.Set;
+import javax.annotation.Nonnull;
+import org.opendaylight.controller.md.sal.dom.api.DOMRpcIdentifier;
+import org.opendaylight.controller.md.sal.dom.api.DOMRpcImplementation;
+import org.opendaylight.controller.md.sal.dom.api.DOMRpcImplementationRegistration;
+import org.opendaylight.controller.md.sal.dom.api.DOMRpcProviderService;
+
+/**
+ * Utility class which implements {@link DOMRpcProviderService} by forwarding
+ * requests to a backing instance.
+ */
+public abstract class ForwardingDOMRpcProviderService extends ForwardingObject implements DOMRpcProviderService {
+ @Override
+ protected abstract @Nonnull DOMRpcProviderService delegate();
+
+ @Override
+ public <T extends DOMRpcImplementation> DOMRpcImplementationRegistration<T> registerRpcImplementation(final T implementation, final DOMRpcIdentifier... types) {
+ return delegate().registerRpcImplementation(implementation, types);
+ }
+
+ @Override
+ public <T extends DOMRpcImplementation> DOMRpcImplementationRegistration<T> registerRpcImplementation(final T implementation, final Set<DOMRpcIdentifier> types) {
+ return delegate().registerRpcImplementation(implementation, types);
+ }
+}
--- /dev/null
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.controller.md.sal.dom.spi;
+
+import com.google.common.collect.ForwardingObject;
+import java.util.Collection;
+import javax.annotation.Nonnull;
+import org.opendaylight.controller.md.sal.dom.api.DOMRpcResult;
+import org.opendaylight.yangtools.yang.common.RpcError;
+import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
+
+/**
+ * Utility class which implements {@link DOMRpcResult} by forwarding all methods
+ * to a backing instance.
+ */
+public abstract class ForwardingDOMRpcResult extends ForwardingObject implements DOMRpcResult {
+ @Override
+ protected abstract @Nonnull DOMRpcResult delegate();
+
+ @Override
+ public Collection<RpcError> getErrors() {
+ return delegate().getErrors();
+ }
+
+ @Override
+ public NormalizedNode<?, ?> getResult() {
+ return delegate().getResult();
+ }
+}
--- /dev/null
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.controller.md.sal.dom.spi;
+
+import com.google.common.collect.ForwardingObject;
+import com.google.common.util.concurrent.CheckedFuture;
+import javax.annotation.Nonnull;
+import org.opendaylight.controller.md.sal.dom.api.DOMRpcAvailabilityListener;
+import org.opendaylight.controller.md.sal.dom.api.DOMRpcException;
+import org.opendaylight.controller.md.sal.dom.api.DOMRpcResult;
+import org.opendaylight.controller.md.sal.dom.api.DOMRpcService;
+import org.opendaylight.yangtools.concepts.ListenerRegistration;
+import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
+import org.opendaylight.yangtools.yang.model.api.SchemaPath;
+
+/**
+ * Utility {@link DOMRpcService} which forwards all requests to a backing delegate instance.
+ */
+public abstract class ForwardingDOMRpcService extends ForwardingObject implements DOMRpcService {
+ @Override
+ protected abstract @Nonnull DOMRpcService delegate();
+
+ @Override
+ public CheckedFuture<DOMRpcResult, DOMRpcException> invokeRpc(final SchemaPath type, final NormalizedNode<?, ?> input) {
+ return delegate().invokeRpc(type, input);
+ }
+
+ @Override
+ public <T extends DOMRpcAvailabilityListener> ListenerRegistration<T> registerRpcListener(final T listener) {
+ return delegate().registerRpcListener(listener);
+ }
+}
@Arg(dest = "debug")
public boolean debug;
+ @Arg(dest = "notification-file")
+ public File notificationFile;
+
static ArgumentParser getParser() {
final ArgumentParser parser = ArgumentParsers.newArgumentParser("netconf testool");
.help("Directory containing yang schemas to describe simulated devices. Some schemas e.g. netconf monitoring and inet types are included by default")
.dest("schemas-dir");
+ parser.addArgument("--notification-file")
+ .type(File.class)
+ .help("Xml file containing notifications that should be sent to clients after create subscription is called")
+ .dest("notification-file");
+
parser.addArgument("--starting-port")
.type(Integer.class)
.setDefault(17830)
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.util.HashedWheelTimer;
import java.io.Closeable;
+import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import org.opendaylight.controller.netconf.ssh.SshProxyServer;
import org.opendaylight.controller.netconf.ssh.SshProxyServerConfiguration;
import org.opendaylight.controller.netconf.ssh.SshProxyServerConfigurationBuilder;
+import org.opendaylight.controller.netconf.test.tool.rpc.DataList;
+import org.opendaylight.controller.netconf.test.tool.rpc.SimulatedCommit;
+import org.opendaylight.controller.netconf.test.tool.rpc.SimulatedCreateSubscription;
+import org.opendaylight.controller.netconf.test.tool.rpc.SimulatedEditConfig;
+import org.opendaylight.controller.netconf.test.tool.rpc.SimulatedGet;
+import org.opendaylight.controller.netconf.test.tool.rpc.SimulatedGetConfig;
+import org.opendaylight.controller.netconf.test.tool.rpc.SimulatedLock;
+import org.opendaylight.controller.netconf.test.tool.rpc.SimulatedUnLock;
import org.opendaylight.yangtools.yang.model.api.SchemaContext;
import org.opendaylight.yangtools.yang.model.repo.api.SchemaSourceException;
import org.opendaylight.yangtools.yang.model.repo.api.SchemaSourceRepresentation;
this.nioExecutor = nioExecutor;
}
- private NetconfServerDispatcher createDispatcher(final Map<ModuleBuilder, String> moduleBuilders, final boolean exi, final int generateConfigsTimeout) {
+ private NetconfServerDispatcher createDispatcher(final Map<ModuleBuilder, String> moduleBuilders, final boolean exi, final int generateConfigsTimeout, final Optional<File> notificationsFile) {
final Set<Capability> capabilities = Sets.newHashSet(Collections2.transform(moduleBuilders.keySet(), new Function<ModuleBuilder, Capability>() {
@Override
final SessionIdProvider idProvider = new SessionIdProvider();
- final SimulatedOperationProvider simulatedOperationProvider = new SimulatedOperationProvider(idProvider, capabilities);
+ final SimulatedOperationProvider simulatedOperationProvider = new SimulatedOperationProvider(idProvider, capabilities, notificationsFile);
final NetconfMonitoringOperationService monitoringService = new NetconfMonitoringOperationService(new NetconfMonitoringServiceImpl(simulatedOperationProvider));
simulatedOperationProvider.addService(monitoringService);
final Map<ModuleBuilder, String> moduleBuilders = parseSchemasToModuleBuilders(params);
- final NetconfServerDispatcher dispatcher = createDispatcher(moduleBuilders, params.exi, params.generateConfigsTimeout);
+ final NetconfServerDispatcher dispatcher = createDispatcher(moduleBuilders, params.exi, params.generateConfigsTimeout, Optional.fromNullable(params.notificationFile));
int currentPort = params.startingPort;
private final Set<NetconfOperationService> netconfOperationServices;
- public SimulatedOperationProvider(final SessionIdProvider idProvider, final Set<Capability> caps) {
+ public SimulatedOperationProvider(final SessionIdProvider idProvider, final Set<Capability> caps, final Optional<File> notificationsFile) {
this.idProvider = idProvider;
- final SimulatedOperationService simulatedOperationService = new SimulatedOperationService(caps, idProvider.getCurrentSessionId());
+ final SimulatedOperationService simulatedOperationService = new SimulatedOperationService(caps, idProvider.getCurrentSessionId(), notificationsFile);
this.netconfOperationServices = Sets.<NetconfOperationService>newHashSet(simulatedOperationService);
}
static class SimulatedOperationService implements NetconfOperationService {
private final Set<Capability> capabilities;
private final long currentSessionId;
+ private final Optional<File> notificationsFile;
- public SimulatedOperationService(final Set<Capability> capabilities, final long currentSessionId) {
+ public SimulatedOperationService(final Set<Capability> capabilities, final long currentSessionId, final Optional<File> notificationsFile) {
this.capabilities = capabilities;
this.currentSessionId = currentSessionId;
+ this.notificationsFile = notificationsFile;
}
@Override
final SimulatedCommit sCommit = new SimulatedCommit(String.valueOf(currentSessionId));
final SimulatedLock sLock = new SimulatedLock(String.valueOf(currentSessionId));
final SimulatedUnLock sUnlock = new SimulatedUnLock(String.valueOf(currentSessionId));
- return Sets.<NetconfOperation>newHashSet(sGet, sGetConfig, sEditConfig, sCommit, sLock, sUnlock);
+ final SimulatedCreateSubscription sCreateSubs = new SimulatedCreateSubscription(String.valueOf(currentSessionId), notificationsFile);
+ return Sets.<NetconfOperation>newHashSet(sGet, sGetConfig, sEditConfig, sCommit, sLock, sUnlock, sCreateSubs);
}
@Override
* and is available at http://www.eclipse.org/legal/epl-v10.html
*/
-package org.opendaylight.controller.netconf.test.tool;
+package org.opendaylight.controller.netconf.test.tool.rpc;
import java.util.Collections;
import java.util.List;
* and is available at http://www.eclipse.org/legal/epl-v10.html
*/
-package org.opendaylight.controller.netconf.test.tool;
+package org.opendaylight.controller.netconf.test.tool.rpc;
import com.google.common.base.Optional;
import org.opendaylight.controller.netconf.api.NetconfDocumentedException;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
-class SimulatedCommit extends AbstractConfigNetconfOperation {
+public class SimulatedCommit extends AbstractConfigNetconfOperation {
- SimulatedCommit(final String netconfSessionIdForReporting) {
+ public SimulatedCommit(final String netconfSessionIdForReporting) {
super(null, netconfSessionIdForReporting);
}
--- /dev/null
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.netconf.test.tool.rpc;
+
+import com.google.common.base.Optional;
+import com.google.common.base.Preconditions;
+import java.io.File;
+import java.io.IOException;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.List;
+import java.util.concurrent.Executors;
+import java.util.concurrent.ScheduledExecutorService;
+import java.util.concurrent.TimeUnit;
+import javax.xml.bind.JAXBContext;
+import javax.xml.bind.JAXBException;
+import javax.xml.bind.Unmarshaller;
+import javax.xml.bind.annotation.XmlRootElement;
+import org.opendaylight.controller.netconf.api.NetconfDocumentedException;
+import org.opendaylight.controller.netconf.api.NetconfMessage;
+import org.opendaylight.controller.netconf.api.xml.XmlNetconfConstants;
+import org.opendaylight.controller.netconf.impl.NetconfServerSession;
+import org.opendaylight.controller.netconf.impl.mapping.operations.DefaultNetconfOperation;
+import org.opendaylight.controller.netconf.util.mapping.AbstractLastNetconfOperation;
+import org.opendaylight.controller.netconf.util.xml.XmlElement;
+import org.opendaylight.controller.netconf.util.xml.XmlUtil;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.xml.sax.SAXException;
+
+public class SimulatedCreateSubscription extends AbstractLastNetconfOperation implements DefaultNetconfOperation {
+
+ private NetconfServerSession session;
+ private final Optional<Notifications> notifications;
+ private ScheduledExecutorService scheduledExecutorService;
+
+ public SimulatedCreateSubscription(final String id, final Optional<File> notificationsFile) {
+ super(id);
+ if(notificationsFile.isPresent()) {
+ notifications = Optional.of(loadNotifications(notificationsFile.get()));
+ scheduledExecutorService = Executors.newScheduledThreadPool(1);
+ } else {
+ notifications = Optional.absent();
+ }
+ }
+
+ private Notifications loadNotifications(final File file) {
+ try {
+ final JAXBContext jaxbContext = JAXBContext.newInstance(Notifications.class);
+ final Unmarshaller jaxbUnmarshaller = jaxbContext.createUnmarshaller();
+ return (Notifications) jaxbUnmarshaller.unmarshal(file);
+ } catch (final JAXBException e) {
+ throw new IllegalArgumentException("Canot parse file " + file + " as a notifications file", e);
+ }
+ }
+
+ @Override
+ protected String getOperationName() {
+ return "create-subscription";
+ }
+
+ @Override
+ protected String getOperationNamespace() {
+ return "urn:ietf:params:xml:ns:netconf:notification:1.0";
+ }
+
+ @Override
+ protected Element handleWithNoSubsequentOperations(final Document document, final XmlElement operationElement) throws NetconfDocumentedException {
+
+
+ if(notifications.isPresent()) {
+ long delayAggregator = 0;
+ System.console().writer().println("Scheduling notifications " + notifications.get());
+
+ for (final Notification notification : notifications.get().getNotificationList()) {
+ for (int i = 0; i <= notification.getTimes(); i++) {
+
+ delayAggregator += notification.getDelayInSeconds();
+
+ System.console().writer().println("Times " + notification.getTimes());
+ scheduledExecutorService.schedule(new Runnable() {
+ @Override
+ public void run() {
+ try {
+ System.console().writer().println("Sending actual notification " + notification);
+ Preconditions.checkState(session != null, "Session is not set, cannot process notifications");
+ session.sendMessage(parseNetconfNotification(notification.getContent()));
+ } catch (IOException | SAXException e) {
+ throw new IllegalStateException("Unable to process notification " + notification, e);
+ }
+ }
+ }, delayAggregator, TimeUnit.SECONDS);
+ }
+ }
+ }
+ return XmlUtil.createElement(document, XmlNetconfConstants.OK, Optional.<String>absent());
+ }
+
+ private static NetconfMessage parseNetconfNotification(String content) throws IOException, SAXException {
+ final int startEventTime = content.indexOf("<eventTime>") + "<eventTime>".length();
+ final int endEventTime = content.indexOf("</eventTime>");
+ final String eventTime = content.substring(startEventTime, endEventTime);
+ if(eventTime.equals("XXXX")) {
+ content = content.replace(eventTime, new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssXXX").format(new Date()));
+ }
+
+ return new NetconfMessage(XmlUtil.readXmlToDocument(content));
+ }
+
+ @Override
+ public void setNetconfSession(final NetconfServerSession s) {
+ this.session = s;
+ }
+
+ @XmlRootElement(name = "notifications")
+ public static final class Notifications {
+
+ @javax.xml.bind.annotation.XmlElement(nillable = false, name = "notification", required = true)
+ private List<Notification> notificationList;
+
+ public List<Notification> getNotificationList() {
+ return notificationList;
+ }
+
+ @Override
+ public String toString() {
+ final StringBuffer sb = new StringBuffer("Notifications{");
+ sb.append("notificationList=").append(notificationList);
+ sb.append('}');
+ return sb.toString();
+ }
+ }
+
+ public static final class Notification {
+
+ @javax.xml.bind.annotation.XmlElement(nillable = false, name = "delay")
+ private long delayInSeconds;
+
+ @javax.xml.bind.annotation.XmlElement(nillable = false, name = "times")
+ private long times;
+
+ @javax.xml.bind.annotation.XmlElement(nillable = false, name = "content", required = true)
+ private String content;
+
+ public long getDelayInSeconds() {
+ return delayInSeconds;
+ }
+
+ public long getTimes() {
+ return times;
+ }
+
+ public String getContent() {
+ return content;
+ }
+
+ @Override
+ public String toString() {
+ final StringBuffer sb = new StringBuffer("Notification{");
+ sb.append("delayInSeconds=").append(delayInSeconds);
+ sb.append(", times=").append(times);
+ sb.append(", content='").append(content).append('\'');
+ sb.append('}');
+ return sb.toString();
+ }
+ }
+}
* and is available at http://www.eclipse.org/legal/epl-v10.html
*/
-package org.opendaylight.controller.netconf.test.tool;
+package org.opendaylight.controller.netconf.test.tool.rpc;
import com.google.common.base.Optional;
import org.opendaylight.controller.netconf.api.NetconfDocumentedException;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
-class SimulatedEditConfig extends AbstractConfigNetconfOperation {
+public class SimulatedEditConfig extends AbstractConfigNetconfOperation {
private static final String DELETE_EDIT_CONFIG = "delete";
private static final String OPERATION = "operation";
private static final String REMOVE_EDIT_CONFIG = "remove";
private final DataList storage;
- SimulatedEditConfig(final String netconfSessionIdForReporting, final DataList storage) {
+ public SimulatedEditConfig(final String netconfSessionIdForReporting, final DataList storage) {
super(null, netconfSessionIdForReporting);
this.storage = storage;
}
* and is available at http://www.eclipse.org/legal/epl-v10.html
*/
-package org.opendaylight.controller.netconf.test.tool;
+package org.opendaylight.controller.netconf.test.tool.rpc;
import com.google.common.base.Optional;
import org.opendaylight.controller.netconf.api.NetconfDocumentedException;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
-class SimulatedGet extends AbstractConfigNetconfOperation {
+public class SimulatedGet extends AbstractConfigNetconfOperation {
private final DataList storage;
- SimulatedGet(final String netconfSessionIdForReporting, final DataList storage) {
+ public SimulatedGet(final String netconfSessionIdForReporting, final DataList storage) {
super(null, netconfSessionIdForReporting);
this.storage = storage;
}
* and is available at http://www.eclipse.org/legal/epl-v10.html
*/
-package org.opendaylight.controller.netconf.test.tool;
+package org.opendaylight.controller.netconf.test.tool.rpc;
import com.google.common.base.Optional;
import org.opendaylight.controller.netconf.api.NetconfDocumentedException;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
-class SimulatedGetConfig extends AbstractConfigNetconfOperation {
+public class SimulatedGetConfig extends AbstractConfigNetconfOperation {
private final DataList storage;
- SimulatedGetConfig(final String netconfSessionIdForReporting, final DataList storage) {
+ public SimulatedGetConfig(final String netconfSessionIdForReporting, final DataList storage) {
super(null, netconfSessionIdForReporting);
this.storage = storage;
}
* and is available at http://www.eclipse.org/legal/epl-v10.html
*/
-package org.opendaylight.controller.netconf.test.tool;
+package org.opendaylight.controller.netconf.test.tool.rpc;
import com.google.common.base.Optional;
import org.opendaylight.controller.netconf.api.NetconfDocumentedException;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
-class SimulatedLock extends AbstractConfigNetconfOperation {
+public class SimulatedLock extends AbstractConfigNetconfOperation {
- SimulatedLock(final String netconfSessionIdForReporting) {
+ public SimulatedLock(final String netconfSessionIdForReporting) {
super(null, netconfSessionIdForReporting);
}
* and is available at http://www.eclipse.org/legal/epl-v10.html
*/
-package org.opendaylight.controller.netconf.test.tool;
+package org.opendaylight.controller.netconf.test.tool.rpc;
import com.google.common.base.Optional;
import org.opendaylight.controller.netconf.api.NetconfDocumentedException;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
-class SimulatedUnLock extends AbstractConfigNetconfOperation {
+public class SimulatedUnLock extends AbstractConfigNetconfOperation {
- SimulatedUnLock(final String netconfSessionIdForReporting) {
+ public SimulatedUnLock(final String netconfSessionIdForReporting) {
super(null, netconfSessionIdForReporting);
}
<artifactId>networkconfig.neutron.implementation</artifactId>
<version>0.5.0-SNAPSHOT</version>
<packaging>bundle</packaging>
- <properties>
- <enunciate.version>1.26.2</enunciate.version>
- </properties>
<dependencies>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.opendaylight.controller</groupId>
- <artifactId>commons.opendaylight</artifactId>
+ <artifactId>enunciate-parent</artifactId>
<version>1.5.0-SNAPSHOT</version>
- <relativePath>../../../commons/opendaylight</relativePath>
+ <relativePath>../../../commons/enunciate-parent</relativePath>
</parent>
<artifactId>networkconfig.neutron.northbound</artifactId>
<version>0.5.0-SNAPSHOT</version>
<manifestLocation>${project.basedir}/src/main/resources/META-INF</manifestLocation>
</configuration>
</plugin>
- <plugin>
- <groupId>org.codehaus.enunciate</groupId>
- <artifactId>maven-enunciate-plugin</artifactId>
- </plugin>
</plugins>
</build>
<scm>
firewallInterface.addNeutronFirewall(singleton);
Object[] instances = NeutronUtil.getInstances(INeutronFirewallAware.class, this);
if (instances != null) {
- for (Object instance : instances) {
- INeutronFirewallAware service = (INeutronFirewallAware) instance;
- int status = service.canCreateNeutronFirewall(singleton);
- if (status < 200 || status > 299) {
- return Response.status(status).build();
+ if (instances.length > 0) {
+ for (Object instance : instances) {
+ INeutronFirewallAware service = (INeutronFirewallAware) instance;
+ int status = service.canCreateNeutronFirewall(singleton);
+ if (status < 200 || status > 299) {
+ return Response.status(status).build();
+ }
}
+ } else {
+ throw new ServiceUnavailableException("No providers registered. Please try again later");
}
+ } else {
+ throw new ServiceUnavailableException("Couldn't get providers list. Please try again later");
}
firewallInterface.addNeutronFirewall(singleton);
if (instances != null) {
throw new BadRequestException("Firewall UUID already exists");
}
if (instances != null) {
- for (Object instance : instances) {
- INeutronFirewallAware service = (INeutronFirewallAware) instance;
- int status = service.canCreateNeutronFirewall(test);
- if (status < 200 || status > 299) {
- return Response.status(status).build();
+ if (instances.length > 0) {
+ for (Object instance : instances) {
+ INeutronFirewallAware service = (INeutronFirewallAware) instance;
+ int status = service.canCreateNeutronFirewall(test);
+ if (status < 200 || status > 299) {
+ return Response.status(status).build();
+ }
}
+ } else {
+ throw new ServiceUnavailableException("No providers registered. Please try again later");
}
+ } else {
+ throw new ServiceUnavailableException("Couldn't get providers list. Please try again later");
}
}
Object[] instances = NeutronUtil.getInstances(INeutronFirewallAware.class, this);
if (instances != null) {
- for (Object instance : instances) {
- INeutronFirewallAware service = (INeutronFirewallAware) instance;
- int status = service.canUpdateNeutronFirewall(delta, original);
- if (status < 200 || status > 299) {
- return Response.status(status).build();
+ if (instances.length > 0) {
+ for (Object instance : instances) {
+ INeutronFirewallAware service = (INeutronFirewallAware) instance;
+ int status = service.canUpdateNeutronFirewall(delta, original);
+ if (status < 200 || status > 299) {
+ return Response.status(status).build();
+ }
}
+ } else {
+ throw new ServiceUnavailableException("No providers registered. Please try again later");
}
+ } else {
+ throw new ServiceUnavailableException("Couldn't get providers list. Please try again later");
}
/*
NeutronFirewall singleton = firewallInterface.getNeutronFirewall(firewallUUID);
Object[] instances = NeutronUtil.getInstances(INeutronFirewallAware.class, this);
if (instances != null) {
- for (Object instance : instances) {
- INeutronFirewallAware service = (INeutronFirewallAware) instance;
- int status = service.canDeleteNeutronFirewall(singleton);
- if (status < 200 || status > 299) {
- return Response.status(status).build();
+ if (instances.length > 0) {
+ for (Object instance : instances) {
+ INeutronFirewallAware service = (INeutronFirewallAware) instance;
+ int status = service.canDeleteNeutronFirewall(singleton);
+ if (status < 200 || status > 299) {
+ return Response.status(status).build();
+ }
}
+ } else {
+ throw new ServiceUnavailableException("No providers registered. Please try again later");
}
+ } else {
+ throw new ServiceUnavailableException("Couldn't get providers list. Please try again later");
}
/*
Object[] instances = NeutronUtil.getInstances(INeutronFirewallPolicyAware.class, this);
if (instances != null) {
- for (Object instance : instances) {
- INeutronFirewallPolicyAware service = (INeutronFirewallPolicyAware) instance;
- int status = service.canCreateNeutronFirewallPolicy(singleton);
- if (status < 200 || status > 299) {
- return Response.status(status).build();
+ if (instances.length > 0) {
+ for (Object instance : instances) {
+ INeutronFirewallPolicyAware service = (INeutronFirewallPolicyAware) instance;
+ int status = service.canCreateNeutronFirewallPolicy(singleton);
+ if (status < 200 || status > 299) {
+ return Response.status(status).build();
+ }
}
+ } else {
+ throw new ServiceUnavailableException("No providers registered. Please try again later");
}
+ } else {
+ throw new ServiceUnavailableException("Couldn't get providers list. Please try again later");
}
firewallPolicyInterface.addNeutronFirewallPolicy(singleton);
if (instances != null) {
throw new BadRequestException("Firewall Policy UUID already exists");
}
if (instances != null) {
- for (Object instance : instances) {
- INeutronFirewallPolicyAware service = (INeutronFirewallPolicyAware) instance;
- int status = service.canCreateNeutronFirewallPolicy(test);
- if (status < 200 || status > 299) {
- return Response.status(status).build();
+ if (instances.length > 0) {
+ for (Object instance : instances) {
+ INeutronFirewallPolicyAware service = (INeutronFirewallPolicyAware) instance;
+ int status = service.canCreateNeutronFirewallPolicy(test);
+ if (status < 200 || status > 299) {
+ return Response.status(status).build();
+ }
}
+ } else {
+ throw new ServiceUnavailableException("No providers registered. Please try again later");
}
+ } else {
+ throw new ServiceUnavailableException("Couldn't get providers list. Please try again later");
}
}
/*
Object[] instances = NeutronUtil.getInstances(INeutronFirewallPolicyAware.class, this);
if (instances != null) {
- for (Object instance : instances) {
- INeutronFirewallPolicyAware service = (INeutronFirewallPolicyAware) instance;
- int status = service.canUpdateNeutronFirewallPolicy(delta, original);
- if (status < 200 || status > 299) {
- return Response.status(status).build();
+ if (instances.length > 0) {
+ for (Object instance : instances) {
+ INeutronFirewallPolicyAware service = (INeutronFirewallPolicyAware) instance;
+ int status = service.canUpdateNeutronFirewallPolicy(delta, original);
+ if (status < 200 || status > 299) {
+ return Response.status(status).build();
+ }
}
+ } else {
+ throw new ServiceUnavailableException("No providers registered. Please try again later");
}
+ } else {
+ throw new ServiceUnavailableException("Couldn't get providers list. Please try again later");
}
/*
NeutronFirewallPolicy singleton = firewallPolicyInterface.getNeutronFirewallPolicy(firewallPolicyUUID);
Object[] instances = NeutronUtil.getInstances(INeutronFirewallPolicyAware.class, this);
if (instances != null) {
- for (Object instance : instances) {
- INeutronFirewallPolicyAware service = (INeutronFirewallPolicyAware) instance;
- int status = service.canDeleteNeutronFirewallPolicy(singleton);
- if (status < 200 || status > 299) {
- return Response.status(status).build();
+ if (instances.length > 0) {
+ for (Object instance : instances) {
+ INeutronFirewallPolicyAware service = (INeutronFirewallPolicyAware) instance;
+ int status = service.canDeleteNeutronFirewallPolicy(singleton);
+ if (status < 200 || status > 299) {
+ return Response.status(status).build();
+ }
}
+ } else {
+ throw new ServiceUnavailableException("No providers registered. Please try again later");
}
+ } else {
+ throw new ServiceUnavailableException("Couldn't get providers list. Please try again later");
}
firewallPolicyInterface.removeNeutronFirewallPolicy(firewallPolicyUUID);
firewallRuleInterface.addNeutronFirewallRule(singleton);
Object[] instances = NeutronUtil.getInstances(INeutronFirewallRuleAware.class, this);
if (instances != null) {
- for (Object instance : instances) {
- INeutronFirewallRuleAware service = (INeutronFirewallRuleAware) instance;
- int status = service.canCreateNeutronFirewallRule(singleton);
- if (status < 200 || status > 299) {
- return Response.status(status).build();
+ if (instances.length > 0) {
+ for (Object instance : instances) {
+ INeutronFirewallRuleAware service = (INeutronFirewallRuleAware) instance;
+ int status = service.canCreateNeutronFirewallRule(singleton);
+ if (status < 200 || status > 299) {
+ return Response.status(status).build();
+ }
}
+ } else {
+ throw new ServiceUnavailableException("No providers registered. Please try again later");
}
+ } else {
+ throw new ServiceUnavailableException("Couldn't get providers list. Please try again later");
}
// add rule to cache
singleton.initDefaults();
throw new BadRequestException("Firewall Rule UUID already exists");
}
if (instances != null) {
- for (Object instance : instances) {
- INeutronFirewallRuleAware service = (INeutronFirewallRuleAware) instance;
- int status = service.canCreateNeutronFirewallRule(test);
- if (status < 200 || status > 299) {
- return Response.status(status).build();
+ if (instances.length > 0) {
+ for (Object instance : instances) {
+ INeutronFirewallRuleAware service = (INeutronFirewallRuleAware) instance;
+ int status = service.canCreateNeutronFirewallRule(test);
+ if (status < 200 || status > 299) {
+ return Response.status(status).build();
+ }
}
+ } else {
+ throw new ServiceUnavailableException("No providers registered. Please try again later");
}
+ } else {
+ throw new ServiceUnavailableException("Couldn't get providers list. Please try again later");
}
}
/*
Object[] instances = NeutronUtil.getInstances(INeutronFirewallRuleAware.class, this);
if (instances != null) {
- for (Object instance : instances) {
- INeutronFirewallRuleAware service = (INeutronFirewallRuleAware) instance;
- int status = service.canUpdateNeutronFirewallRule(delta, original);
- if (status < 200 || status > 299) {
- return Response.status(status).build();
+ if (instances.length > 0) {
+ for (Object instance : instances) {
+ INeutronFirewallRuleAware service = (INeutronFirewallRuleAware) instance;
+ int status = service.canUpdateNeutronFirewallRule(delta, original);
+ if (status < 200 || status > 299) {
+ return Response.status(status).build();
+ }
}
+ } else {
+ throw new ServiceUnavailableException("No providers registered. Please try again later");
}
+ } else {
+ throw new ServiceUnavailableException("Couldn't get providers list. Please try again later");
}
/*
NeutronFirewallRule singleton = firewallRuleInterface.getNeutronFirewallRule(firewallRuleUUID);
Object[] instances = NeutronUtil.getInstances(INeutronFirewallRuleAware.class, this);
if (instances != null) {
- for (Object instance : instances) {
- INeutronFirewallRuleAware service = (INeutronFirewallRuleAware) instance;
- int status = service.canDeleteNeutronFirewallRule(singleton);
- if (status < 200 || status > 299) {
- return Response.status(status).build();
+ if (instances.length > 0) {
+ for (Object instance : instances) {
+ INeutronFirewallRuleAware service = (INeutronFirewallRuleAware) instance;
+ int status = service.canDeleteNeutronFirewallRule(singleton);
+ if (status < 200 || status > 299) {
+ return Response.status(status).build();
+ }
}
+ } else {
+ throw new ServiceUnavailableException("No providers registered. Please try again later");
}
+ } else {
+ throw new ServiceUnavailableException("Couldn't get providers list. Please try again later");
}
/*
}
Object[] instances = NeutronUtil.getInstances(INeutronFloatingIPAware.class, this);
if (instances != null) {
- for (Object instance : instances) {
- INeutronFloatingIPAware service = (INeutronFloatingIPAware) instance;
- int status = service.canCreateFloatingIP(singleton);
- if (status < 200 || status > 299)
- return Response.status(status).build();
+ if (instances.length > 0) {
+ for (Object instance : instances) {
+ INeutronFloatingIPAware service = (INeutronFloatingIPAware) instance;
+ int status = service.canCreateFloatingIP(singleton);
+ if (status < 200 || status > 299)
+ return Response.status(status).build();
+ }
+ } else {
+ throw new ServiceUnavailableException("No providers registered. Please try again later");
}
+ } else {
+ throw new ServiceUnavailableException("Couldn't get providers list. Please try again later");
}
floatingIPInterface.addFloatingIP(singleton);
if (instances != null) {
NeutronFloatingIP target = floatingIPInterface.getFloatingIP(floatingipUUID);
Object[] instances = NeutronUtil.getInstances(INeutronFloatingIPAware.class, this);
if (instances != null) {
- for (Object instance : instances) {
- INeutronFloatingIPAware service = (INeutronFloatingIPAware) instance;
- int status = service.canUpdateFloatingIP(singleton, target);
- if (status < 200 || status > 299)
- return Response.status(status).build();
+ if (instances.length > 0) {
+ for (Object instance : instances) {
+ INeutronFloatingIPAware service = (INeutronFloatingIPAware) instance;
+ int status = service.canUpdateFloatingIP(singleton, target);
+ if (status < 200 || status > 299)
+ return Response.status(status).build();
+ }
+ } else {
+ throw new ServiceUnavailableException("No providers registered. Please try again later");
}
+ } else {
+ throw new ServiceUnavailableException("Couldn't get providers list. Please try again later");
}
floatingIPInterface.updateFloatingIP(floatingipUUID, singleton);
target = floatingIPInterface.getFloatingIP(floatingipUUID);
NeutronFloatingIP singleton = floatingIPInterface.getFloatingIP(floatingipUUID);
Object[] instances = NeutronUtil.getInstances(INeutronFloatingIPAware.class, this);
if (instances != null) {
- for (Object instance : instances) {
- INeutronFloatingIPAware service = (INeutronFloatingIPAware) instance;
- int status = service.canDeleteFloatingIP(singleton);
- if (status < 200 || status > 299)
- return Response.status(status).build();
+ if (instances.length > 0) {
+ for (Object instance : instances) {
+ INeutronFloatingIPAware service = (INeutronFloatingIPAware) instance;
+ int status = service.canDeleteFloatingIP(singleton);
+ if (status < 200 || status > 299)
+ return Response.status(status).build();
+ }
+ } else {
+ throw new ServiceUnavailableException("No providers registered. Please try again later");
}
+ } else {
+ throw new ServiceUnavailableException("Couldn't get providers list. Please try again later");
}
floatingIPInterface.removeFloatingIP(floatingipUUID);
if (instances != null) {
Object[] instances = NeutronUtil.getInstances(INeutronLoadBalancerHealthMonitorAware.class, this);
if (instances != null) {
- for (Object instance : instances) {
- INeutronLoadBalancerHealthMonitorAware service = (INeutronLoadBalancerHealthMonitorAware) instance;
- int status = service.canCreateNeutronLoadBalancerHealthMonitor(singleton);
- if (status < 200 || status > 299) {
- return Response.status(status).build();
+ if (instances.length > 0) {
+ for (Object instance : instances) {
+ INeutronLoadBalancerHealthMonitorAware service = (INeutronLoadBalancerHealthMonitorAware) instance;
+ int status = service.canCreateNeutronLoadBalancerHealthMonitor(singleton);
+ if (status < 200 || status > 299) {
+ return Response.status(status).build();
+ }
}
+ } else {
+ throw new ServiceUnavailableException("No providers registered. Please try again later");
}
+ } else {
+ throw new ServiceUnavailableException("Couldn't get providers list. Please try again later");
}
loadBalancerHealthMonitorInterface.addNeutronLoadBalancerHealthMonitor(singleton);
if (instances != null) {
throw new BadRequestException("LoadBalancerHealthMonitor UUID already exists");
}
if (instances != null) {
- for (Object instance : instances) {
- INeutronLoadBalancerHealthMonitorAware service = (INeutronLoadBalancerHealthMonitorAware) instance;
- int status = service.canCreateNeutronLoadBalancerHealthMonitor(test);
- if (status < 200 || status > 299) {
- return Response.status(status).build();
+ if (instances.length > 0) {
+ for (Object instance : instances) {
+ INeutronLoadBalancerHealthMonitorAware service = (INeutronLoadBalancerHealthMonitorAware) instance;
+ int status = service.canCreateNeutronLoadBalancerHealthMonitor(test);
+ if (status < 200 || status > 299) {
+ return Response.status(status).build();
+ }
}
+ } else {
+ throw new ServiceUnavailableException("No providers registered. Please try again later");
}
+ } else {
+ throw new ServiceUnavailableException("Couldn't get providers list. Please try again later");
}
}
/*
Object[] instances = NeutronUtil.getInstances(INeutronLoadBalancerHealthMonitorAware.class, this);
if (instances != null) {
- for (Object instance : instances) {
- INeutronLoadBalancerHealthMonitorAware service = (INeutronLoadBalancerHealthMonitorAware) instance;
- int status = service.canUpdateNeutronLoadBalancerHealthMonitor(delta, original);
- if (status < 200 || status > 299) {
- return Response.status(status).build();
+ if (instances.length > 0) {
+ for (Object instance : instances) {
+ INeutronLoadBalancerHealthMonitorAware service = (INeutronLoadBalancerHealthMonitorAware) instance;
+ int status = service.canUpdateNeutronLoadBalancerHealthMonitor(delta, original);
+ if (status < 200 || status > 299) {
+ return Response.status(status).build();
+ }
}
+ } else {
+ throw new ServiceUnavailableException("No providers registered. Please try again later");
}
+ } else {
+ throw new ServiceUnavailableException("Couldn't get providers list. Please try again later");
}
/*
NeutronLoadBalancerHealthMonitor singleton = loadBalancerHealthMonitorInterface.getNeutronLoadBalancerHealthMonitor(loadBalancerHealthMonitorID);
Object[] instances = NeutronUtil.getInstances(INeutronLoadBalancerHealthMonitorAware.class, this);
if (instances != null) {
- for (Object instance : instances) {
- INeutronLoadBalancerHealthMonitorAware service = (INeutronLoadBalancerHealthMonitorAware) instance;
- int status = service.canDeleteNeutronLoadBalancerHealthMonitor(singleton);
- if (status < 200 || status > 299) {
- return Response.status(status).build();
+ if (instances.length > 0) {
+ for (Object instance : instances) {
+ INeutronLoadBalancerHealthMonitorAware service = (INeutronLoadBalancerHealthMonitorAware) instance;
+ int status = service.canDeleteNeutronLoadBalancerHealthMonitor(singleton);
+ if (status < 200 || status > 299) {
+ return Response.status(status).build();
+ }
}
+ } else {
+ throw new ServiceUnavailableException("No providers registered. Please try again later");
}
+ } else {
+ throw new ServiceUnavailableException("Couldn't get providers list. Please try again later");
}
loadBalancerHealthMonitorInterface.removeNeutronLoadBalancerHealthMonitor(loadBalancerHealthMonitorID);
if (instances != null) {
Object[] instances = NeutronUtil.getInstances(INeutronLoadBalancerListenerAware.class, this);
if (instances != null) {
- for (Object instance : instances) {
- INeutronLoadBalancerListenerAware service = (INeutronLoadBalancerListenerAware) instance;
- int status = service.canCreateNeutronLoadBalancerListener(singleton);
- if (status < 200 || status > 299) {
- return Response.status(status).build();
+ if (instances.length > 0) {
+ for (Object instance : instances) {
+ INeutronLoadBalancerListenerAware service = (INeutronLoadBalancerListenerAware) instance;
+ int status = service.canCreateNeutronLoadBalancerListener(singleton);
+ if (status < 200 || status > 299) {
+ return Response.status(status).build();
+ }
}
+ } else {
+ throw new ServiceUnavailableException("No providers registered. Please try again later");
}
+ } else {
+ throw new ServiceUnavailableException("Couldn't get providers list. Please try again later");
}
loadBalancerListenerInterface.addNeutronLoadBalancerListener(singleton);
if (instances != null) {
throw new BadRequestException("LoadBalancerListener UUID already exists");
}
if (instances != null) {
- for (Object instance : instances) {
- INeutronLoadBalancerListenerAware service = (INeutronLoadBalancerListenerAware) instance;
- int status = service.canCreateNeutronLoadBalancerListener(test);
- if (status < 200 || status > 299) {
- return Response.status(status).build();
+ if (instances.length > 0) {
+ for (Object instance : instances) {
+ INeutronLoadBalancerListenerAware service = (INeutronLoadBalancerListenerAware) instance;
+ int status = service.canCreateNeutronLoadBalancerListener(test);
+ if (status < 200 || status > 299) {
+ return Response.status(status).build();
+ }
}
+ } else {
+ throw new ServiceUnavailableException("No providers registered. Please try again later");
}
+ } else {
+ throw new ServiceUnavailableException("Couldn't get providers list. Please try again later");
}
}
/*
Object[] instances = NeutronUtil.getInstances(INeutronLoadBalancerListenerAware.class, this);
if (instances != null) {
- for (Object instance : instances) {
- INeutronLoadBalancerListenerAware service = (INeutronLoadBalancerListenerAware) instance;
- int status = service.canUpdateNeutronLoadBalancerListener(delta, original);
- if (status < 200 || status > 299) {
- return Response.status(status).build();
+ if (instances.length > 0) {
+ for (Object instance : instances) {
+ INeutronLoadBalancerListenerAware service = (INeutronLoadBalancerListenerAware) instance;
+ int status = service.canUpdateNeutronLoadBalancerListener(delta, original);
+ if (status < 200 || status > 299) {
+ return Response.status(status).build();
+ }
}
+ } else {
+ throw new ServiceUnavailableException("No providers registered. Please try again later");
}
+ } else {
+ throw new ServiceUnavailableException("Couldn't get providers list. Please try again later");
}
/*
NeutronLoadBalancerListener singleton = loadBalancerListenerInterface.getNeutronLoadBalancerListener(loadBalancerListenerID);
Object[] instances = NeutronUtil.getInstances(INeutronLoadBalancerListenerAware.class, this);
if (instances != null) {
- for (Object instance : instances) {
- INeutronLoadBalancerListenerAware service = (INeutronLoadBalancerListenerAware) instance;
- int status = service.canDeleteNeutronLoadBalancerListener(singleton);
- if (status < 200 || status > 299) {
- return Response.status(status).build();
+ if (instances.length > 0) {
+ for (Object instance : instances) {
+ INeutronLoadBalancerListenerAware service = (INeutronLoadBalancerListenerAware) instance;
+ int status = service.canDeleteNeutronLoadBalancerListener(singleton);
+ if (status < 200 || status > 299) {
+ return Response.status(status).build();
+ }
}
+ } else {
+ throw new ServiceUnavailableException("No providers registered. Please try again later");
}
+ } else {
+ throw new ServiceUnavailableException("Couldn't get providers list. Please try again later");
}
loadBalancerListenerInterface.removeNeutronLoadBalancerListener(loadBalancerListenerID);
}
Object[] instances = NeutronUtil.getInstances(INeutronLoadBalancerAware.class, this);
if (instances != null) {
- for (Object instance : instances) {
- INeutronLoadBalancerAware service = (INeutronLoadBalancerAware) instance;
- int status = service.canCreateNeutronLoadBalancer(singleton);
- if (status < 200 || status > 299) {
- return Response.status(status).build();
+ if (instances.length > 0) {
+ for (Object instance : instances) {
+ INeutronLoadBalancerAware service = (INeutronLoadBalancerAware) instance;
+ int status = service.canCreateNeutronLoadBalancer(singleton);
+ if (status < 200 || status > 299) {
+ return Response.status(status).build();
+ }
}
+ } else {
+ throw new ServiceUnavailableException("No providers registered. Please try again later");
}
+ } else {
+ throw new ServiceUnavailableException("Couldn't get providers list. Please try again later");
}
+
loadBalancerInterface.addNeutronLoadBalancer(singleton);
if (instances != null) {
for (Object instance : instances) {
throw new BadRequestException("Load Balancer Pool UUID already exists");
}
if (instances != null) {
- for (Object instance : instances) {
- INeutronLoadBalancerAware service = (INeutronLoadBalancerAware) instance;
- int status = service.canCreateNeutronLoadBalancer(test);
- if (status < 200 || status > 299) {
- return Response.status(status).build();
+ if (instances.length > 0) {
+ for (Object instance : instances) {
+ INeutronLoadBalancerAware service = (INeutronLoadBalancerAware) instance;
+ int status = service.canCreateNeutronLoadBalancer(test);
+ if (status < 200 || status > 299) {
+ return Response.status(status).build();
+ }
}
+ } else {
+ throw new ServiceUnavailableException("No providers registered. Please try again later");
}
+ } else {
+ throw new ServiceUnavailableException("Couldn't get providers list. Please try again later");
}
}
/*
Object[] instances = NeutronUtil.getInstances(INeutronLoadBalancerAware.class, this);
if (instances != null) {
- for (Object instance : instances) {
- INeutronLoadBalancerAware service = (INeutronLoadBalancerAware) instance;
- int status = service.canUpdateNeutronLoadBalancer(delta, original);
- if (status < 200 || status > 299) {
- return Response.status(status).build();
+ if (instances.length > 0) {
+ for (Object instance : instances) {
+ INeutronLoadBalancerAware service = (INeutronLoadBalancerAware) instance;
+ int status = service.canUpdateNeutronLoadBalancer(delta, original);
+ if (status < 200 || status > 299) {
+ return Response.status(status).build();
+ }
}
+ } else {
+ throw new ServiceUnavailableException("No providers registered. Please try again later");
}
+ } else {
+ throw new ServiceUnavailableException("Couldn't get providers list. Please try again later");
}
/*
NeutronLoadBalancer singleton = loadBalancerInterface.getNeutronLoadBalancer(loadBalancerID);
Object[] instances = NeutronUtil.getInstances(INeutronLoadBalancerAware.class, this);
if (instances != null) {
- for (Object instance : instances) {
- INeutronLoadBalancerAware service = (INeutronLoadBalancerAware) instance;
- int status = service.canDeleteNeutronLoadBalancer(singleton);
- if (status < 200 || status > 299) {
- return Response.status(status).build();
+ if (instances.length > 0) {
+ for (Object instance : instances) {
+ INeutronLoadBalancerAware service = (INeutronLoadBalancerAware) instance;
+ int status = service.canDeleteNeutronLoadBalancer(singleton);
+ if (status < 200 || status > 299) {
+ return Response.status(status).build();
+ }
}
+ } else {
+ throw new ServiceUnavailableException("No providers registered. Please try again later");
}
+ } else {
+ throw new ServiceUnavailableException("Couldn't get providers list. Please try again later");
}
+
loadBalancerInterface.removeNeutronLoadBalancer(loadBalancerID);
if (instances != null) {
for (Object instance : instances) {
Object[] instances = NeutronUtil.getInstances(INeutronLoadBalancerPoolMemberAware.class, this);
if (instances != null) {
- for (Object instance : instances) {
- INeutronLoadBalancerPoolMemberAware service = (INeutronLoadBalancerPoolMemberAware) instance;
- int status = service.canCreateNeutronLoadBalancerPoolMember(singleton);
- if (status < 200 || status > 299) {
- return Response.status(status).build();
+ if (instances.length > 0) {
+ for (Object instance : instances) {
+ INeutronLoadBalancerPoolMemberAware service = (INeutronLoadBalancerPoolMemberAware) instance;
+ int status = service.canCreateNeutronLoadBalancerPoolMember(singleton);
+ if (status < 200 || status > 299) {
+ return Response.status(status).build();
+ }
}
+ } else {
+ throw new ServiceUnavailableException("No providers registered. Please try again later");
}
+ } else {
+ throw new ServiceUnavailableException("Couldn't get providers list. Please try again later");
}
+
if (instances != null) {
for (Object instance : instances) {
INeutronLoadBalancerPoolMemberAware service = (INeutronLoadBalancerPoolMemberAware) instance;
throw new BadRequestException("Load Balancer PoolMember UUID already exists");
}
if (instances != null) {
- for (Object instance : instances) {
- INeutronLoadBalancerPoolMemberAware service = (INeutronLoadBalancerPoolMemberAware) instance;
- int status = service.canCreateNeutronLoadBalancerPoolMember(test);
- if (status < 200 || status > 299) {
- return Response.status(status).build();
+ if (instances.length > 0) {
+ for (Object instance : instances) {
+ INeutronLoadBalancerPoolMemberAware service = (INeutronLoadBalancerPoolMemberAware) instance;
+ int status = service.canCreateNeutronLoadBalancerPoolMember(test);
+ if (status < 200 || status > 299) {
+ return Response.status(status).build();
+ }
}
+ } else {
+ throw new ServiceUnavailableException("No providers registered. Please try again later");
}
+ } else {
+ throw new ServiceUnavailableException("Couldn't get providers list. Please try again later");
}
}
/*
Object[] instances = NeutronUtil.getInstances(INeutronLoadBalancerPoolMemberAware.class, this);
if (instances != null) {
- for (Object instance : instances) {
- INeutronLoadBalancerPoolMemberAware service = (INeutronLoadBalancerPoolMemberAware) instance;
- int status = service.canDeleteNeutronLoadBalancerPoolMember(singleton);
- if (status < 200 || status > 299) {
- return Response.status(status).build();
+ if (instances.length > 0) {
+ for (Object instance : instances) {
+ INeutronLoadBalancerPoolMemberAware service = (INeutronLoadBalancerPoolMemberAware) instance;
+ int status = service.canDeleteNeutronLoadBalancerPoolMember(singleton);
+ if (status < 200 || status > 299) {
+ return Response.status(status).build();
+ }
}
+ } else {
+ throw new ServiceUnavailableException("No providers registered. Please try again later");
}
+ } else {
+ throw new ServiceUnavailableException("Couldn't get providers list. Please try again later");
}
if (instances != null) {
Object[] instances = NeutronUtil.getInstances(INeutronLoadBalancerPoolAware.class, this);
if (instances != null) {
- for (Object instance : instances) {
- INeutronLoadBalancerPoolAware service = (INeutronLoadBalancerPoolAware) instance;
- int status = service.canCreateNeutronLoadBalancerPool(singleton);
- if (status < 200 || status > 299) {
- return Response.status(status).build();
+ if (instances.length > 0) {
+ for (Object instance : instances) {
+ INeutronLoadBalancerPoolAware service = (INeutronLoadBalancerPoolAware) instance;
+ int status = service.canCreateNeutronLoadBalancerPool(singleton);
+ if (status < 200 || status > 299) {
+ return Response.status(status).build();
+ }
}
+ } else {
+ throw new ServiceUnavailableException("No providers registered. Please try again later");
}
+ } else {
+ throw new ServiceUnavailableException("Couldn't get providers list. Please try again later");
}
loadBalancerPoolInterface.addNeutronLoadBalancerPool(singleton);
if (instances != null) {
throw new BadRequestException("Load Balancer Pool UUID already exists");
}
if (instances != null) {
- for (Object instance : instances) {
- INeutronLoadBalancerPoolAware service = (INeutronLoadBalancerPoolAware) instance;
- int status = service.canCreateNeutronLoadBalancerPool(test);
- if (status < 200 || status > 299) {
- return Response.status(status).build();
+ if (instances.length > 0) {
+ for (Object instance : instances) {
+ INeutronLoadBalancerPoolAware service = (INeutronLoadBalancerPoolAware) instance;
+ int status = service.canCreateNeutronLoadBalancerPool(test);
+ if (status < 200 || status > 299) {
+ return Response.status(status).build();
+ }
}
+ } else {
+ throw new ServiceUnavailableException("No providers registered. Please try again later");
}
+ } else {
+ throw new ServiceUnavailableException("Couldn't get providers list. Please try again later");
}
}
/*
Object[] instances = NeutronUtil.getInstances(INeutronLoadBalancerPoolAware.class, this);
if (instances != null) {
- for (Object instance : instances) {
- INeutronLoadBalancerPoolAware service = (INeutronLoadBalancerPoolAware) instance;
- int status = service.canUpdateNeutronLoadBalancerPool(delta, original);
- if (status < 200 || status > 299) {
- return Response.status(status).build();
+ if (instances.length > 0) {
+ for (Object instance : instances) {
+ INeutronLoadBalancerPoolAware service = (INeutronLoadBalancerPoolAware) instance;
+ int status = service.canUpdateNeutronLoadBalancerPool(delta, original);
+ if (status < 200 || status > 299) {
+ return Response.status(status).build();
+ }
}
+ } else {
+ throw new ServiceUnavailableException("No providers registered. Please try again later");
}
+ } else {
+ throw new ServiceUnavailableException("Couldn't get providers list. Please try again later");
}
/*
NeutronLoadBalancerPool singleton = loadBalancerPoolInterface.getNeutronLoadBalancerPool(loadBalancerPoolUUID);
Object[] instances = NeutronUtil.getInstances(INeutronLoadBalancerPoolAware.class, this);
if (instances != null) {
- for (Object instance : instances) {
- INeutronLoadBalancerPoolAware service = (INeutronLoadBalancerPoolAware) instance;
- int status = service.canDeleteNeutronLoadBalancerPool(singleton);
- if (status < 200 || status > 299) {
- return Response.status(status).build();
+ if (instances.length > 0) {
+ for (Object instance : instances) {
+ INeutronLoadBalancerPoolAware service = (INeutronLoadBalancerPoolAware) instance;
+ int status = service.canDeleteNeutronLoadBalancerPool(singleton);
+ if (status < 200 || status > 299) {
+ return Response.status(status).build();
+ }
}
+ } else {
+ throw new ServiceUnavailableException("No providers registered. Please try again later");
}
+ } else {
+ throw new ServiceUnavailableException("Couldn't get providers list. Please try again later");
}
/*
Object[] instances = NeutronUtil.getInstances(INeutronNetworkAware.class, this);
if (instances != null) {
- for (Object instance : instances) {
- INeutronNetworkAware service = (INeutronNetworkAware) instance;
- int status = service.canCreateNetwork(singleton);
- if (status < 200 || status > 299) {
- return Response.status(status).build();
+ if (instances.length > 0) {
+ for (Object instance : instances) {
+ INeutronNetworkAware service = (INeutronNetworkAware) instance;
+ int status = service.canCreateNetwork(singleton);
+ if (status < 200 || status > 299) {
+ return Response.status(status).build();
+ }
}
+ } else {
+ throw new ServiceUnavailableException("No providers registered. Please try again later");
}
+ } else {
+ throw new ServiceUnavailableException("Couldn't get providers list. Please try again later");
}
// add network to cache
throw new BadRequestException("network UUID already exists");
}
if (instances != null) {
- for (Object instance: instances) {
- INeutronNetworkAware service = (INeutronNetworkAware) instance;
- int status = service.canCreateNetwork(test);
- if (status < 200 || status > 299) {
- return Response.status(status).build();
+ if (instances.length > 0) {
+ for (Object instance: instances) {
+ INeutronNetworkAware service = (INeutronNetworkAware) instance;
+ int status = service.canCreateNetwork(test);
+ if (status < 200 || status > 299) {
+ return Response.status(status).build();
+ }
}
+ } else {
+ throw new ServiceUnavailableException("No providers registered. Please try again later");
}
+ } else {
+ throw new ServiceUnavailableException("Couldn't get providers list. Please try again later");
}
testMap.put(test.getID(),test);
}
Object[] instances = NeutronUtil.getInstances(INeutronNetworkAware.class, this);
if (instances != null) {
- for (Object instance : instances) {
- INeutronNetworkAware service = (INeutronNetworkAware) instance;
- NeutronNetwork original = networkInterface.getNetwork(netUUID);
- int status = service.canUpdateNetwork(delta, original);
- if (status < 200 || status > 299) {
- return Response.status(status).build();
+ if (instances.length > 0) {
+ for (Object instance : instances) {
+ INeutronNetworkAware service = (INeutronNetworkAware) instance;
+ NeutronNetwork original = networkInterface.getNetwork(netUUID);
+ int status = service.canUpdateNetwork(delta, original);
+ if (status < 200 || status > 299) {
+ return Response.status(status).build();
+ }
}
+ } else {
+ throw new ServiceUnavailableException("No providers registered. Please try again later");
}
+ } else {
+ throw new ServiceUnavailableException("Couldn't get providers list. Please try again later");
}
// update network object and return the modified object
NeutronNetwork singleton = networkInterface.getNetwork(netUUID);
Object[] instances = NeutronUtil.getInstances(INeutronNetworkAware.class, this);
if (instances != null) {
- for (Object instance : instances) {
- INeutronNetworkAware service = (INeutronNetworkAware) instance;
- int status = service.canDeleteNetwork(singleton);
- if (status < 200 || status > 299) {
- return Response.status(status).build();
+ if (instances.length > 0) {
+ for (Object instance : instances) {
+ INeutronNetworkAware service = (INeutronNetworkAware) instance;
+ int status = service.canDeleteNetwork(singleton);
+ if (status < 200 || status > 299) {
+ return Response.status(status).build();
+ }
}
+ } else {
+ throw new ServiceUnavailableException("No providers registered. Please try again later");
}
+ } else {
+ throw new ServiceUnavailableException("Couldn't get providers list. Please try again later");
}
+
networkInterface.removeNetwork(netUUID);
if (instances != null) {
for (Object instance : instances) {
Object[] instances = NeutronUtil.getInstances(INeutronPortAware.class, this);
if (instances != null) {
- for (Object instance : instances) {
- INeutronPortAware service = (INeutronPortAware) instance;
- int status = service.canCreatePort(singleton);
- if (status < 200 || status > 299) {
- return Response.status(status).build();
+ if (instances.length > 0) {
+ for (Object instance : instances) {
+ INeutronPortAware service = (INeutronPortAware) instance;
+ int status = service.canCreatePort(singleton);
+ if (status < 200 || status > 299) {
+ return Response.status(status).build();
+ }
}
+ } else {
+ throw new ServiceUnavailableException("No providers registered. Please try again later");
}
+ } else {
+ throw new ServiceUnavailableException("Couldn't get providers list. Please try again later");
}
-
// add the port to the cache
portInterface.addPort(singleton);
if (instances != null) {
}
}
if (instances != null) {
- for (Object instance : instances) {
- INeutronPortAware service = (INeutronPortAware) instance;
- int status = service.canCreatePort(test);
- if (status < 200 || status > 299) {
- return Response.status(status).build();
+ if (instances.length > 0) {
+ for (Object instance : instances) {
+ INeutronPortAware service = (INeutronPortAware) instance;
+ int status = service.canCreatePort(test);
+ if (status < 200 || status > 299) {
+ return Response.status(status).build();
+ }
}
+ } else {
+ throw new ServiceUnavailableException("No providers registered. Please try again later");
}
+ } else {
+ throw new ServiceUnavailableException("Couldn't get providers list. Please try again later");
}
}
Object[] instances = NeutronUtil.getInstances(INeutronPortAware.class, this);
if (instances != null) {
- for (Object instance : instances) {
- INeutronPortAware service = (INeutronPortAware) instance;
- int status = service.canUpdatePort(singleton, original);
- if (status < 200 || status > 299) {
- return Response.status(status).build();
+ if (instances.length > 0) {
+ for (Object instance : instances) {
+ INeutronPortAware service = (INeutronPortAware) instance;
+ int status = service.canUpdatePort(singleton, original);
+ if (status < 200 || status > 299) {
+ return Response.status(status).build();
+ }
}
+ } else {
+ throw new ServiceUnavailableException("No providers registered. Please try again later");
}
+ } else {
+ throw new ServiceUnavailableException("Couldn't get providers list. Please try again later");
}
// Verify the new fixed ips are valid
NeutronPort singleton = portInterface.getPort(portUUID);
Object[] instances = NeutronUtil.getInstances(INeutronPortAware.class, this);
if (instances != null) {
- for (Object instance : instances) {
- INeutronPortAware service = (INeutronPortAware) instance;
- int status = service.canDeletePort(singleton);
- if (status < 200 || status > 299) {
- return Response.status(status).build();
+ if (instances.length > 0) {
+ for (Object instance : instances) {
+ INeutronPortAware service = (INeutronPortAware) instance;
+ int status = service.canDeletePort(singleton);
+ if (status < 200 || status > 299) {
+ return Response.status(status).build();
+ }
}
+ } else {
+ throw new ServiceUnavailableException("No providers registered. Please try again later");
}
+ } else {
+ throw new ServiceUnavailableException("Couldn't get providers list. Please try again later");
}
portInterface.removePort(portUUID);
if (instances != null) {
}
Object[] instances = NeutronUtil.getInstances(INeutronRouterAware.class, this);
if (instances != null) {
- for (Object instance : instances) {
- INeutronRouterAware service = (INeutronRouterAware) instance;
- int status = service.canCreateRouter(singleton);
- if (status < 200 || status > 299)
- return Response.status(status).build();
+ if (instances.length > 0) {
+ for (Object instance : instances) {
+ INeutronRouterAware service = (INeutronRouterAware) instance;
+ int status = service.canCreateRouter(singleton);
+ if (status < 200 || status > 299)
+ return Response.status(status).build();
+ }
+ } else {
+ throw new ServiceUnavailableException("No providers registered. Please try again later");
}
+ } else {
+ throw new ServiceUnavailableException("Couldn't get providers list. Please try again later");
}
/*
Object[] instances = NeutronUtil.getInstances(INeutronRouterAware.class, this);
if (instances != null) {
- for (Object instance : instances) {
- INeutronRouterAware service = (INeutronRouterAware) instance;
- int status = service.canUpdateRouter(singleton, original);
- if (status < 200 || status > 299)
- return Response.status(status).build();
+ if (instances.length > 0) {
+ for (Object instance : instances) {
+ INeutronRouterAware service = (INeutronRouterAware) instance;
+ int status = service.canUpdateRouter(singleton, original);
+ if (status < 200 || status > 299)
+ return Response.status(status).build();
+ }
+ } else {
+ throw new ServiceUnavailableException("No providers registered. Please try again later");
}
+ } else {
+ throw new ServiceUnavailableException("Couldn't get providers list. Please try again later");
}
/*
* if the external gateway info is being changed, verify that the new network
NeutronRouter singleton = routerInterface.getRouter(routerUUID);
Object[] instances = NeutronUtil.getInstances(INeutronRouterAware.class, this);
if (instances != null) {
- for (Object instance : instances) {
- INeutronRouterAware service = (INeutronRouterAware) instance;
- int status = service.canDeleteRouter(singleton);
- if (status < 200 || status > 299)
- return Response.status(status).build();
+ if (instances.length > 0) {
+ for (Object instance : instances) {
+ INeutronRouterAware service = (INeutronRouterAware) instance;
+ int status = service.canDeleteRouter(singleton);
+ if (status < 200 || status > 299)
+ return Response.status(status).build();
+ }
+ } else {
+ throw new ServiceUnavailableException("No providers registered. Please try again later");
}
+ } else {
+ throw new ServiceUnavailableException("Couldn't get providers list. Please try again later");
}
routerInterface.removeRouter(routerUUID);
if (instances != null) {
throw new ResourceConflictException("Target Port already allocated");
Object[] instances = NeutronUtil.getInstances(INeutronRouterAware.class, this);
if (instances != null) {
- for (Object instance : instances) {
- INeutronRouterAware service = (INeutronRouterAware) instance;
- int status = service.canAttachInterface(target, input);
- if (status < 200 || status > 299)
- return Response.status(status).build();
+ if (instances.length > 0) {
+ for (Object instance : instances) {
+ INeutronRouterAware service = (INeutronRouterAware) instance;
+ int status = service.canAttachInterface(target, input);
+ if (status < 200 || status > 299)
+ return Response.status(status).build();
+ }
+ } else {
+ throw new ServiceUnavailableException("No providers registered. Please try again later");
}
+ } else {
+ throw new ServiceUnavailableException("Couldn't get providers list. Please try again later");
}
//mark the port device id and device owner fields
Object[] instances = NeutronUtil.getInstances(INeutronRouterAware.class, this);
if (instances != null) {
- for (Object instance : instances) {
- INeutronRouterAware service = (INeutronRouterAware) instance;
- int status = service.canDetachInterface(target, input);
- if (status < 200 || status > 299)
- return Response.status(status).build();
+ if (instances.length > 0) {
+ for (Object instance : instances) {
+ INeutronRouterAware service = (INeutronRouterAware) instance;
+ int status = service.canDetachInterface(target, input);
+ if (status < 200 || status > 299)
+ return Response.status(status).build();
+ }
+ } else {
+ throw new ServiceUnavailableException("No providers registered. Please try again later");
}
+ } else {
+ throw new ServiceUnavailableException("Couldn't get providers list. Please try again later");
}
// reset the port ownership
input.setSubnetUUID(targetInterface.getSubnetUUID());
input.setID(target.getID());
input.setTenantID(target.getTenantID());
+ Object[] instances = NeutronUtil.getInstances(INeutronRouterAware.class, this);
+ if (instances != null) {
+ if (instances.length > 0) {
+ for (Object instance : instances) {
+ INeutronRouterAware service = (INeutronRouterAware) instance;
+ int status = service.canDetachInterface(target, input);
+ if (status < 200 || status > 299)
+ return Response.status(status).build();
+ }
+ } else {
+ throw new ServiceUnavailableException("No providers registered. Please try again later");
+ }
+ } else {
+ throw new ServiceUnavailableException("Couldn't get providers list. Please try again later");
+ }
NeutronPort port = portInterface.getPort(input.getPortUUID());
port.setDeviceID(null);
port.setDeviceOwner(null);
target.removeInterface(input.getPortUUID());
- Object[] instances = NeutronUtil.getInstances(INeutronRouterAware.class, this);
for (Object instance : instances) {
INeutronRouterAware service = (INeutronRouterAware) instance;
service.neutronRouterInterfaceDetached(target, input);
}
if (!subnet.isValidIP(port.getFixedIPs().get(0).getIpAddress()))
throw new ResourceConflictException("Target Port IP not in Target Subnet");
- input.setID(target.getID());
- input.setTenantID(target.getTenantID());
Object[] instances = NeutronUtil.getInstances(INeutronRouterAware.class, this);
if (instances != null) {
- for (Object instance : instances) {
- INeutronRouterAware service = (INeutronRouterAware) instance;
- service.canDetachInterface(target, input);
+ if (instances.length > 0) {
+ for (Object instance : instances) {
+ INeutronRouterAware service = (INeutronRouterAware) instance;
+ int status = service.canDetachInterface(target, input);
+ if (status < 200 || status > 299)
+ return Response.status(status).build();
+ }
+ } else {
+ throw new ServiceUnavailableException("No providers registered. Please try again later");
}
+ } else {
+ throw new ServiceUnavailableException("Couldn't get providers list. Please try again later");
}
+ input.setID(target.getID());
+ input.setTenantID(target.getTenantID());
port.setDeviceID(null);
port.setDeviceOwner(null);
target.removeInterface(input.getPortUUID());
- for (Object instance : instances) {
+ if (instances != null) {
+ for (Object instance : instances) {
+ INeutronRouterAware service = (INeutronRouterAware) instance;
+ service.canDetachInterface(target, input);
+ }
+ } for (Object instance : instances) {
INeutronRouterAware service = (INeutronRouterAware) instance;
service.neutronRouterInterfaceDetached(target, input);
}
Object[] instances = NeutronUtil.getInstances(INeutronSecurityGroupAware.class, this);
if (instances != null) {
- for (Object instance : instances) {
- INeutronSecurityGroupAware service = (INeutronSecurityGroupAware) instance;
- int status = service.canCreateNeutronSecurityGroup(singleton);
- if (status < 200 || status > 299) {
- return Response.status(status).build();
+ if (instances.length > 0) {
+ for (Object instance : instances) {
+ INeutronSecurityGroupAware service = (INeutronSecurityGroupAware) instance;
+ int status = service.canCreateNeutronSecurityGroup(singleton);
+ if (status < 200 || status > 299) {
+ return Response.status(status).build();
+ }
}
+ } else {
+ throw new ServiceUnavailableException("No providers registered. Please try again later");
}
+ } else {
+ throw new ServiceUnavailableException("Couldn't get providers list. Please try again later");
}
// Add to Neutron cache
securityGroupInterface.addNeutronSecurityGroup(singleton);
if (securityGroupInterface.neutronSecurityGroupExists(test.getSecurityGroupUUID())) {
throw new BadRequestException("Security Group UUID already is already created");
}
- if (instances != null) for (Object instance : instances) {
- INeutronSecurityGroupAware service = (INeutronSecurityGroupAware) instance;
- int status = service.canCreateNeutronSecurityGroup(test);
- if ((status < 200) || (status > 299)) return Response.status(status).build();
+ if (instances != null) {
+ if (instances.length > 0) {
+ for (Object instance : instances) {
+ INeutronSecurityGroupAware service = (INeutronSecurityGroupAware) instance;
+ int status = service.canCreateNeutronSecurityGroup(test);
+ if ((status < 200) || (status > 299)) return Response.status(status).build();
+ }
+ } else {
+ throw new BadRequestException("No providers registered. Please try again later");
+ }
+ } else {
+ throw new ServiceUnavailableException("Couldn't get providers list. Please try again later");
}
}
Object[] instances = NeutronUtil.getInstances(INeutronSecurityGroupAware.class, this);
if (instances != null) {
- for (Object instance : instances) {
- INeutronSecurityGroupAware service = (INeutronSecurityGroupAware) instance;
- int status = service.canUpdateNeutronSecurityGroup(delta, original);
- if (status < 200 || status > 299) {
- return Response.status(status).build();
+ if (instances.length > 0) {
+ for (Object instance : instances) {
+ INeutronSecurityGroupAware service = (INeutronSecurityGroupAware) instance;
+ int status = service.canUpdateNeutronSecurityGroup(delta, original);
+ if (status < 200 || status > 299) {
+ return Response.status(status).build();
+ }
}
+ } else {
+ throw new ServiceUnavailableException("No providers registered. Please try again later");
}
+ } else {
+ throw new ServiceUnavailableException("Couldn't get providers list. Please try again later");
}
/*
NeutronSecurityGroup singleton = securityGroupInterface.getNeutronSecurityGroup(securityGroupUUID);
Object[] instances = NeutronUtil.getInstances(INeutronSecurityGroupAware.class, this);
if (instances != null) {
- for (Object instance : instances) {
- INeutronSecurityGroupAware service = (INeutronSecurityGroupAware) instance;
- int status = service.canDeleteNeutronSecurityGroup(singleton);
- if ((status < 200) || (status > 299)) {
- return Response.status(status).build();
+ if (instances.length > 0) {
+ for (Object instance : instances) {
+ INeutronSecurityGroupAware service = (INeutronSecurityGroupAware) instance;
+ int status = service.canDeleteNeutronSecurityGroup(singleton);
+ if ((status < 200) || (status > 299)) {
+ return Response.status(status).build();
+ }
}
+ } else {
+ throw new ServiceUnavailableException("No providers registered. Please try again later");
}
+ } else {
+ throw new ServiceUnavailableException("Couldn't get providers list. Please try again later");
}
/*
}
return Response.status(204).build();
}
-}
\ No newline at end of file
+}
}
Object[] instances = NeutronUtil.getInstances(INeutronSecurityRuleAware.class, this);
if (instances != null) {
- for (Object instance : instances) {
- INeutronSecurityRuleAware service = (INeutronSecurityRuleAware) instance;
- int status = service.canCreateNeutronSecurityRule(singleton);
- if ((status < 200) || (status > 299)) {
- return Response.status(status).build();
+ if (instances.length > 0) {
+ for (Object instance : instances) {
+ INeutronSecurityRuleAware service = (INeutronSecurityRuleAware) instance;
+ int status = service.canCreateNeutronSecurityRule(singleton);
+ if ((status < 200) || (status > 299)) {
+ return Response.status(status).build();
+ }
}
+ } else {
+ throw new ServiceUnavailableException("No providers registered. Please try again later");
}
+ } else {
+ throw new ServiceUnavailableException("Couldn't get providers list. Please try again later");
}
// add rule to cache
throw new BadRequestException("Security Rule UUID already exists");
}
if (instances != null) {
- for (Object instance : instances) {
- INeutronSecurityRuleAware service = (INeutronSecurityRuleAware) instance;
- int status = service.canCreateNeutronSecurityRule(test);
- if ((status < 200) || (status > 299)) {
- return Response.status(status).build();
+ if (instances.length > 0) {
+ for (Object instance : instances) {
+ INeutronSecurityRuleAware service = (INeutronSecurityRuleAware) instance;
+ int status = service.canCreateNeutronSecurityRule(test);
+ if ((status < 200) || (status > 299)) {
+ return Response.status(status).build();
+ }
}
+ } else {
+ throw new ServiceUnavailableException("No providers registered. Please try again later");
}
+ } else {
+ throw new ServiceUnavailableException("Couldn't get providers list. Please try again later");
}
}
Object[] instances = NeutronUtil.getInstances(INeutronSecurityRuleAware.class, this);
if (instances != null) {
- for (Object instance : instances) {
- INeutronSecurityRuleAware service = (INeutronSecurityRuleAware) instance;
- int status = service.canUpdateNeutronSecurityRule(delta, original);
- if (status < 200 || status > 299) {
- return Response.status(status).build();
+ if (instances.length > 0) {
+ for (Object instance : instances) {
+ INeutronSecurityRuleAware service = (INeutronSecurityRuleAware) instance;
+ int status = service.canUpdateNeutronSecurityRule(delta, original);
+ if (status < 200 || status > 299) {
+ return Response.status(status).build();
+ }
}
+ } else {
+ throw new ServiceUnavailableException("No providers registered. Please try again later");
}
+ } else {
+ throw new ServiceUnavailableException("Couldn't get providers list. Please try again later");
}
/*
NeutronSecurityRule singleton = securityRuleInterface.getNeutronSecurityRule(securityRuleUUID);
Object[] instances = NeutronUtil.getInstances(INeutronSecurityRuleAware.class, this);
if (instances != null) {
- for (Object instance : instances) {
- INeutronSecurityRuleAware service = (INeutronSecurityRuleAware) instance;
- int status = service.canDeleteNeutronSecurityRule(singleton);
- if (status < 200 || status > 299) {
- return Response.status(status).build();
+ if (instances.length > 0) {
+ for (Object instance : instances) {
+ INeutronSecurityRuleAware service = (INeutronSecurityRuleAware) instance;
+ int status = service.canDeleteNeutronSecurityRule(singleton);
+ if (status < 200 || status > 299) {
+ return Response.status(status).build();
+ }
}
+ } else {
+ throw new ServiceUnavailableException("No providers registered. Please try again later");
}
+ } else {
+ throw new ServiceUnavailableException("Couldn't get providers list. Please try again later");
}
+
/*
* remove it and return 204 status
*/
}
return Response.status(204).build();
}
-}
\ No newline at end of file
+}
}
Object[] instances = NeutronUtil.getInstances(INeutronSubnetAware.class, this);
if (instances != null) {
- for (Object instance : instances) {
- INeutronSubnetAware service = (INeutronSubnetAware) instance;
- int status = service.canCreateSubnet(singleton);
- if (status < 200 || status > 299) {
- return Response.status(status).build();
+ if (instances.length > 0) {
+ for (Object instance : instances) {
+ INeutronSubnetAware service = (INeutronSubnetAware) instance;
+ int status = service.canCreateSubnet(singleton);
+ if (status < 200 || status > 299) {
+ return Response.status(status).build();
+ }
}
+ } else {
+ throw new ServiceUnavailableException("No providers registered. Please try again later");
}
+ } else {
+ throw new ServiceUnavailableException("Couldn't get providers list. Please try again later");
}
subnetInterface.addSubnet(singleton);
if (instances != null) {
throw new ResourceConflictException("IP pool overlaps with gateway");
}
if (instances != null) {
- for (Object instance : instances) {
- INeutronSubnetAware service = (INeutronSubnetAware) instance;
- int status = service.canCreateSubnet(test);
- if (status < 200 || status > 299) {
- return Response.status(status).build();
+ if (instances.length > 0) {
+ for (Object instance : instances) {
+ INeutronSubnetAware service = (INeutronSubnetAware) instance;
+ int status = service.canCreateSubnet(test);
+ if (status < 200 || status > 299) {
+ return Response.status(status).build();
+ }
}
+ } else {
+ throw new ServiceUnavailableException("No providers registered. Please try again later");
}
+ } else {
+ throw new ServiceUnavailableException("Couldn't get providers list. Please try again later");
}
}
Object[] instances = NeutronUtil.getInstances(INeutronSubnetAware.class, this);
if (instances != null) {
- for (Object instance : instances) {
- INeutronSubnetAware service = (INeutronSubnetAware) instance;
- int status = service.canUpdateSubnet(delta, original);
- if (status < 200 || status > 299) {
- return Response.status(status).build();
+ if (instances.length > 0) {
+ for (Object instance : instances) {
+ INeutronSubnetAware service = (INeutronSubnetAware) instance;
+ int status = service.canUpdateSubnet(delta, original);
+ if (status < 200 || status > 299) {
+ return Response.status(status).build();
+ }
}
+ } else {
+ throw new ServiceUnavailableException("No providers registered. Please try again later");
}
+ } else {
+ throw new ServiceUnavailableException("Couldn't get providers list. Please try again later");
}
/*
NeutronSubnet singleton = subnetInterface.getSubnet(subnetUUID);
Object[] instances = NeutronUtil.getInstances(INeutronSubnetAware.class, this);
if (instances != null) {
- for (Object instance : instances) {
- INeutronSubnetAware service = (INeutronSubnetAware) instance;
- int status = service.canDeleteSubnet(singleton);
- if (status < 200 || status > 299) {
- return Response.status(status).build();
+ if (instances.length > 0) {
+ for (Object instance : instances) {
+ INeutronSubnetAware service = (INeutronSubnetAware) instance;
+ int status = service.canDeleteSubnet(singleton);
+ if (status < 200 || status > 299) {
+ return Response.status(status).build();
+ }
}
+ } else {
+ throw new ServiceUnavailableException("No providers registered. Please try again later");
}
+ } else {
+ throw new ServiceUnavailableException("Couldn't get providers list. Please try again later");
}
/*
<artifactId>networkconfig.neutron</artifactId>
<version>0.5.0-SNAPSHOT</version>
<packaging>bundle</packaging>
- <properties>
- <enunciate.version>1.26.2</enunciate.version>
- </properties>
<dependencies>
<dependency>
<groupId>commons-net</groupId>
<module>opendaylight/commons/logback_settings</module>
<module>opendaylight/commons/filter-valve</module>
<module>opendaylight/commons/liblldp</module>
+ <module>opendaylight/commons/enunciate-parent</module>
<!-- Karaf Distribution -->
<module>karaf</module>