<groupId>org.opendaylight.odlparent</groupId>
<artifactId>features-parent</artifactId>
<version>1.5.0-SNAPSHOT</version>
+ <relativePath/>
</parent>
<groupId>${groupId}</groupId>
<artifactId>${artifactId}-features</artifactId>
-->
<snapshot>
<required-capabilities>
+ <capability>urn:opendaylight:params:xml:ns:yang:${artifactId}:impl?module=${artifactId}-impl&revision=2014-12-10</capability>
+ <capability>urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding?module=opendaylight-md-sal-binding&revision=2013-10-28</capability>
</required-capabilities>
<configuration>
<artifactId>log4j-over-slf4j</artifactId>
</dependency>
<dependency>
- <groupId>org.opendaylight.controller.model</groupId>
- <artifactId>model-flow-service</artifactId>
- <scope>provided</scope>
+ <groupId>org.slf4j</groupId>
+ <artifactId>slf4j-api</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.opendaylight.controller</groupId>
+ <artifactId>sal-test-model</artifactId>
+ <version>${mdsal.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.opendaylight.yangtools.model</groupId>
+ <artifactId>opendaylight-l2-types</artifactId>
</dependency>
</dependencies>
}
+ /**
+ * @return option containing models for testing purposes
+ */
+ public static Option salTestModelBundles() {
+ return new DefaultCompositeOption( //
+ mavenBundle(CONTROLLER, "sal-test-model").versionAsInProject()
+ );
+
+ }
+
public static Option baseModelBundles() {
return new DefaultCompositeOption( //
mavenBundle(YANGTOOLS_MODELS, "yang-ext").versionAsInProject(), // //
mavenBundle(YANGTOOLS_MODELS, "ietf-inet-types").versionAsInProject(), // //
mavenBundle(YANGTOOLS_MODELS, "ietf-yang-types").versionAsInProject(), // //
- mavenBundle(YANGTOOLS_MODELS, "opendaylight-l2-types").versionAsInProject(), // //
- mavenBundle(CONTROLLER_MODELS, "model-inventory").versionAsInProject());
+ mavenBundle(YANGTOOLS_MODELS, "opendaylight-l2-types").versionAsInProject() // //
+ );
}
public static Option junitAndMockitoBundles() {
import static org.opendaylight.controller.test.sal.binding.it.TestHelper.baseModelBundles;
import static org.opendaylight.controller.test.sal.binding.it.TestHelper.bindingAwareSalBundles;
import static org.opendaylight.controller.test.sal.binding.it.TestHelper.configMinumumBundles;
-import static org.opendaylight.controller.test.sal.binding.it.TestHelper.flowCapableModelBundles;
+import static org.opendaylight.controller.test.sal.binding.it.TestHelper.salTestModelBundles;
import static org.opendaylight.controller.test.sal.binding.it.TestHelper.junitAndMockitoBundles;
import static org.opendaylight.controller.test.sal.binding.it.TestHelper.mdSalCoreBundles;
import static org.ops4j.pax.exam.CoreOptions.mavenBundle;
configMinumumBundles(),
// BASE Models
baseModelBundles(),
- flowCapableModelBundles(),
+ salTestModelBundles(),
// Set fail if unresolved bundle present
systemProperty("pax.exam.osgi.unresolved.fail").value("true"),
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
-import com.google.inject.Inject;
import java.util.concurrent.Future;
-import org.junit.Before;
-import org.junit.Ignore;
+
import org.junit.Test;
import org.opendaylight.controller.md.sal.common.api.TransactionStatus;
import org.opendaylight.controller.sal.binding.api.BindingAwareBroker.ConsumerContext;
import org.opendaylight.controller.sal.binding.api.data.DataBrokerService;
import org.opendaylight.controller.sal.binding.api.data.DataModificationTransaction;
import org.opendaylight.controller.sal.core.api.Broker;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.Nodes;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.md.sal.test.store.rev140422.Lists;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.md.sal.test.store.rev140422.lists.UnorderedContainer;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.md.sal.test.store.rev140422.lists.unordered.container.UnorderedList;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.md.sal.test.store.rev140422.lists.unordered.container.UnorderedListBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.md.sal.test.store.rev140422.lists.unordered.container.UnorderedListKey;
import org.opendaylight.yangtools.yang.binding.DataObject;
import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
import org.opendaylight.yangtools.yang.common.RpcResult;
+import com.google.inject.Inject;
+
+/**
+ * covers creating, reading and deleting of an item in dataStore
+ */
public class DataServiceTest extends AbstractTest {
protected DataBrokerService consumerDataService;
-
@Inject
Broker broker2;
- @Before
- public void setUp() throws Exception {
- }
-
- /*
+ /**
*
* Ignored this, because classes here are constructed from
* very different class loader as MD-SAL is run into,
* this is code is run from different classloader.
*
+ * @throws Exception
*/
@Test
- @Ignore
public void test() throws Exception {
BindingAwareConsumer consumer1 = new BindingAwareConsumer() {
consumerDataService = session.getSALService(DataBrokerService.class);
}
};
- broker.registerConsumer(consumer1, getBundleContext());
+ broker.registerConsumer(consumer1);
assertNotNull(consumerDataService);
DataModificationTransaction transaction = consumerDataService.beginTransaction();
assertNotNull(transaction);
- InstanceIdentifier<Node> node1 = createNodeRef("0");
- DataObject node = consumerDataService.readConfigurationData(node1);
+ InstanceIdentifier<UnorderedList> node1 = createNodeRef("0");
+ DataObject node = consumerDataService.readConfigurationData(node1);
assertNull(node);
- Node nodeData1 = createNode("0");
+ UnorderedList nodeData1 = createNode("0");
transaction.putConfigurationData(node1, nodeData1);
Future<RpcResult<TransactionStatus>> commitResult = transaction.commit();
assertNotNull(result.getResult());
assertEquals(TransactionStatus.COMMITED, result.getResult());
- Node readedData = (Node) consumerDataService.readConfigurationData(node1);
+ UnorderedList readedData = (UnorderedList) consumerDataService.readConfigurationData(node1);
assertNotNull(readedData);
assertEquals(nodeData1.getKey(), readedData.getKey());
DataModificationTransaction transaction2 = consumerDataService.beginTransaction();
- assertNotNull(transaction);
+ assertNotNull(transaction2);
transaction2.removeConfigurationData(node1);
DataObject readedData2 = consumerDataService.readConfigurationData(node1);
assertNull(readedData2);
-
-
}
- private static InstanceIdentifier<Node> createNodeRef(final String string) {
- NodeKey key = new NodeKey(new NodeId(string));
- return InstanceIdentifier.builder(Nodes.class).child(Node.class, key).build();
+ private static InstanceIdentifier<UnorderedList> createNodeRef(final String string) {
+ UnorderedListKey key = new UnorderedListKey(string);
+ return InstanceIdentifier.builder(Lists.class).child(UnorderedContainer.class).child(UnorderedList.class, key).build();
}
- private static Node createNode(final String string) {
- NodeBuilder ret = new NodeBuilder();
- NodeId id = new NodeId(string);
- ret.setKey(new NodeKey(id));
- ret.setId(id);
+ private static UnorderedList createNode(final String string) {
+ UnorderedListBuilder ret = new UnorderedListBuilder();
+ UnorderedListKey nodeKey = new UnorderedListKey(string);
+ ret.setKey(nodeKey);
+ ret.setName("name of " + string);
+ ret.setName("value of " + string);
return ret.build();
}
}
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
-import java.math.BigInteger;
import java.util.ArrayList;
import java.util.List;
-import org.junit.Before;
-import org.junit.Ignore;
import org.junit.Test;
import org.opendaylight.controller.sal.binding.api.BindingAwareBroker.ConsumerContext;
import org.opendaylight.controller.sal.binding.api.BindingAwareBroker.ProviderContext;
import org.opendaylight.controller.sal.binding.api.BindingAwareProvider;
import org.opendaylight.controller.sal.binding.api.NotificationProviderService;
import org.opendaylight.controller.sal.binding.api.NotificationService;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.FlowAdded;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.FlowAddedBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.FlowRemoved;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.FlowUpdated;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.NodeErrorNotification;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.NodeExperimenterErrorNotification;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.SalFlowListener;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.SwitchFlowRemoved;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.FlowCookie;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.md.sal.test.bi.ba.notification.rev150205.OpendaylightTestNotificationListener;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.md.sal.test.bi.ba.notification.rev150205.OutOfPixieDustNotification;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.md.sal.test.bi.ba.notification.rev150205.OutOfPixieDustNotificationBuilder;
import org.opendaylight.yangtools.concepts.ListenerRegistration;
import org.opendaylight.yangtools.yang.binding.NotificationListener;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
-@Ignore
+/**
+ * covers registering of notification listener, publishing of notification and receiving of notification.
+ */
public class NotificationTest extends AbstractTest {
- private final FlowListener listener1 = new FlowListener();
- private final FlowListener listener2 = new FlowListener();
+ private static final Logger LOG = LoggerFactory
+ .getLogger(NotificationTest.class);
- private ListenerRegistration<NotificationListener> listener1Reg;
- private ListenerRegistration<NotificationListener> listener2Reg;
+ protected final NotificationTestListener listener1 = new NotificationTestListener();
+ protected final NotificationTestListener listener2 = new NotificationTestListener();
- private NotificationProviderService notifyProviderService;
+ protected ListenerRegistration<NotificationListener> listener1Reg;
+ protected ListenerRegistration<NotificationListener> listener2Reg;
- @Before
- public void setUp() throws Exception {
- }
+ protected NotificationProviderService notifyProviderService;
+ /**
+ * test of delivering of notification
+ * @throws Exception
+ */
@Test
public void notificationTest() throws Exception {
- /**
- *
- * The registration of the Provider 1.
- *
- */
+ LOG.info("The registration of the Provider 1.");
AbstractTestProvider provider1 = new AbstractTestProvider() {
@Override
public void onSessionInitiated(ProviderContext session) {
};
// registerProvider method calls onSessionInitiated method above
- broker.registerProvider(provider1, getBundleContext());
+ broker.registerProvider(provider1);
assertNotNull(notifyProviderService);
- /**
- *
- * The registration of the Consumer 1. It retrieves Notification Service
- * from MD-SAL and registers SalFlowListener as notification listener
- *
- */
+ LOG.info("The registration of the Consumer 1. It retrieves Notification Service "
+ + "from MD-SAL and registers OpendaylightTestNotificationListener as notification listener");
BindingAwareConsumer consumer1 = new BindingAwareConsumer() {
@Override
public void onSessionInitialized(ConsumerContext session) {
}
};
// registerConsumer method calls onSessionInitialized method above
- broker.registerConsumer(consumer1, getBundleContext());
+ broker.registerConsumer(consumer1);
assertNotNull(listener1Reg);
- /**
- * The notification of type FlowAdded with cookie ID 0 is created. The
- * delay 100ms to make sure that the notification was delivered to
- * listener.
- */
- notifyProviderService.publish(flowAdded(0));
+ LOG.info("The notification of type FlowAdded with cookie ID 0 is created. The "
+ + "delay 100ms to make sure that the notification was delivered to "
+ + "listener.");
+ notifyProviderService.publish(noDustNotification("rainy day", 42));
Thread.sleep(100);
/**
* Check that one notification was delivered and has correct cookie.
*
*/
- assertEquals(1, listener1.addedFlows.size());
- assertEquals(0, listener1.addedFlows.get(0).getCookie().getValue().intValue());
+ assertEquals(1, listener1.notificationBag.size());
+ assertEquals("rainy day", listener1.notificationBag.get(0).getReason());
+ assertEquals(42, listener1.notificationBag.get(0).getDaysTillNewDust().intValue());
- /**
- * The registration of the Consumer 2. SalFlowListener is registered
- * registered as notification listener.
- */
+ LOG.info("The registration of the Consumer 2. SalFlowListener is registered "
+ + "registered as notification listener.");
BindingAwareProvider provider = new BindingAwareProvider() {
@Override
};
// registerConsumer method calls onSessionInitialized method above
- broker.registerProvider(provider, getBundleContext());
+ broker.registerProvider(provider);
- /**
- * 3 notifications are published
- */
- notifyProviderService.publish(flowAdded(5));
- notifyProviderService.publish(flowAdded(10));
- notifyProviderService.publish(flowAdded(2));
+ LOG.info("3 notifications are published");
+ notifyProviderService.publish(noDustNotification("rainy day", 5));
+ notifyProviderService.publish(noDustNotification("rainy day", 10));
+ notifyProviderService.publish(noDustNotification("tax collector", 2));
/**
* The delay 100ms to make sure that the notifications were delivered to
* received 4 in total, second 3 in total).
*
*/
- assertEquals(4, listener1.addedFlows.size());
- assertEquals(3, listener2.addedFlows.size());
+ assertEquals(4, listener1.notificationBag.size());
+ assertEquals(3, listener2.notificationBag.size());
/**
* The second listener is closed (unregistered)
*/
listener2Reg.close();
- /**
- *
- * The notification 5 is published
- */
- notifyProviderService.publish(flowAdded(10));
+ LOG.info("The notification 5 is published");
+ notifyProviderService.publish(noDustNotification("entomologist hunt", 10));
/**
* The delay 100ms to make sure that the notification was delivered to
* second consumer because its listener was unregistered.
*
*/
- assertEquals(5, listener1.addedFlows.size());
- assertEquals(3, listener2.addedFlows.size());
+ assertEquals(5, listener1.notificationBag.size());
+ assertEquals(3, listener2.notificationBag.size());
}
/**
- * Creates instance of the type FlowAdded. Only cookie value is set. It is
+ * Creates instance of the type OutOfPixieDustNotification. It is
* used only for testing purpose.
*
- * @param i
- * cookie value
- * @return instance of the type FlowAdded
+ * @param reason
+ * @param days
+ * @return instance of the type OutOfPixieDustNotification
*/
- public static FlowAdded flowAdded(int i) {
- FlowAddedBuilder ret = new FlowAddedBuilder();
- ret.setCookie(new FlowCookie(BigInteger.valueOf(i)));
+ public static OutOfPixieDustNotification noDustNotification(String reason, int days) {
+ OutOfPixieDustNotificationBuilder ret = new OutOfPixieDustNotificationBuilder();
+ ret.setReason(reason).setDaysTillNewDust(days);
return ret.build();
}
/**
*
* Implements
- * {@link org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.SalFlowListener
- * SalFlowListener} and contains attributes which keep lists of objects of
- * the type
- * {@link org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819. NodeFlow
- * NodeFlow}. The lists are defined for flows which were added, removed or
- * updated.
+ * {@link OpendaylightTestNotificationListener} and contains attributes which keep lists of objects of
+ * the type {@link OutOfFairyDustNotification}.
*/
- private static class FlowListener implements SalFlowListener {
-
- List<FlowAdded> addedFlows = new ArrayList<>();
- List<FlowRemoved> removedFlows = new ArrayList<>();
- List<FlowUpdated> updatedFlows = new ArrayList<>();
-
- @Override
- public void onFlowAdded(FlowAdded notification) {
- addedFlows.add(notification);
- }
-
- @Override
- public void onFlowRemoved(FlowRemoved notification) {
- removedFlows.add(notification);
- };
-
- @Override
- public void onFlowUpdated(FlowUpdated notification) {
- updatedFlows.add(notification);
- }
-
- @Override
- public void onSwitchFlowRemoved(SwitchFlowRemoved notification) {
- // TODO Auto-generated method stub
-
- }
+ public static class NotificationTestListener implements OpendaylightTestNotificationListener {
- @Override
- public void onNodeErrorNotification(NodeErrorNotification notification) {
- // TODO Auto-generated method stub
-
- }
+ List<OutOfPixieDustNotification> notificationBag = new ArrayList<>();
@Override
- public void onNodeExperimenterErrorNotification(
- NodeExperimenterErrorNotification notification) {
- // TODO Auto-generated method stub
-
+ public void onOutOfPixieDustNotification(OutOfPixieDustNotification arg0) {
+ notificationBag.add(arg0);
}
}
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
-import java.math.BigInteger;
-
import org.junit.Before;
import org.junit.Test;
import org.opendaylight.controller.sal.binding.api.BindingAwareBroker.ConsumerContext;
import org.opendaylight.controller.sal.binding.api.BindingAwareBroker.RoutedRpcRegistration;
import org.opendaylight.controller.sal.binding.api.BindingAwareConsumer;
import org.opendaylight.controller.sal.binding.api.BindingAwareProvider;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.AddFlowInput;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.AddFlowInputBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.SalFlowService;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.FlowCookie;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeContext;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeRef;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.Nodes;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.md.sal.test.rpc.routing.rev140701.OpendaylightTestRoutedRpcService;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.md.sal.test.rpc.routing.rev140701.RoutedSimpleRouteInput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.md.sal.test.rpc.routing.rev140701.RoutedSimpleRouteInputBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.md.sal.test.rpc.routing.rev140701.TestContext;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.md.sal.test.store.rev140422.Lists;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.md.sal.test.store.rev140422.lists.UnorderedContainer;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.md.sal.test.store.rev140422.lists.unordered.container.UnorderedList;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.md.sal.test.store.rev140422.lists.unordered.container.UnorderedListKey;
import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+/**
+ * covers routed rpc creation, registration, invocation, unregistration
+ */
public class RoutedServiceTest extends AbstractTest {
- private SalFlowService salFlowService1;
- private SalFlowService salFlowService2;
+ private static final Logger LOG = LoggerFactory
+ .getLogger(RoutedServiceTest.class);
- private SalFlowService consumerService;
+ protected OpendaylightTestRoutedRpcService odlRoutedService1;
+ protected OpendaylightTestRoutedRpcService odlRoutedService2;
- private RoutedRpcRegistration<SalFlowService> firstReg;
- private RoutedRpcRegistration<SalFlowService> secondReg;
+ protected OpendaylightTestRoutedRpcService consumerService;
+ protected RoutedRpcRegistration<OpendaylightTestRoutedRpcService> firstReg;
+ protected RoutedRpcRegistration<OpendaylightTestRoutedRpcService> secondReg;
+
+ /**
+ * prepare mocks
+ */
@Before
- public void setUp() throws Exception {
- salFlowService1 = mock(SalFlowService.class, "First Flow Service");
- salFlowService2 = mock(SalFlowService.class, "Second Flow Service");
+ public void setUp() {
+ odlRoutedService1 = mock(OpendaylightTestRoutedRpcService.class, "First Flow Service");
+ odlRoutedService2 = mock(OpendaylightTestRoutedRpcService.class, "Second Flow Service");
}
@Test
assertNotNull(getBroker());
BindingAwareProvider provider1 = new AbstractTestProvider() {
-
@Override
public void onSessionInitiated(ProviderContext session) {
assertNotNull(session);
- firstReg = session.addRoutedRpcImplementation(SalFlowService.class, salFlowService1);
+ firstReg = session.addRoutedRpcImplementation(OpendaylightTestRoutedRpcService.class, odlRoutedService1);
}
};
- /**
- * Register provider 1 with first implementation of SalFlowService -
- * service1
- *
- */
- broker.registerProvider(provider1, getBundleContext());
+ LOG.info("Register provider 1 with first implementation of routeSimpleService - service1");
+ broker.registerProvider(provider1);
assertNotNull("Registration should not be null", firstReg);
- assertSame(salFlowService1, firstReg.getInstance());
+ assertSame(odlRoutedService1, firstReg.getInstance());
BindingAwareProvider provider2 = new AbstractTestProvider() {
-
@Override
public void onSessionInitiated(ProviderContext session) {
assertNotNull(session);
- secondReg = session.addRoutedRpcImplementation(SalFlowService.class, salFlowService2);
+ secondReg = session.addRoutedRpcImplementation(OpendaylightTestRoutedRpcService.class, odlRoutedService2);
}
};
- /**
- * Register provider 2 with first implementation of SalFlowService -
- * service2
- *
- */
- broker.registerProvider(provider2, getBundleContext());
+ LOG.info("Register provider 2 with second implementation of routeSimpleService - service2");
+ broker.registerProvider(provider2);
assertNotNull("Registration should not be null", firstReg);
- assertSame(salFlowService2, secondReg.getInstance());
+ assertSame(odlRoutedService2, secondReg.getInstance());
assertNotSame(secondReg, firstReg);
BindingAwareConsumer consumer = new BindingAwareConsumer() {
@Override
public void onSessionInitialized(ConsumerContext session) {
- consumerService = session.getRpcService(SalFlowService.class);
+ consumerService = session.getRpcService(OpendaylightTestRoutedRpcService.class);
}
};
- broker.registerConsumer(consumer, getBundleContext());
+ LOG.info("Register routeService consumer");
+ broker.registerConsumer(consumer);
- assertNotNull("MD-SAL instance of Flow Service should be returned", consumerService);
- assertNotSame("Provider instance and consumer instance should not be same.", salFlowService1, consumerService);
+ assertNotNull("MD-SAL instance of test Service should be returned", consumerService);
+ assertNotSame("Provider instance and consumer instance should not be same.", odlRoutedService1, consumerService);
- NodeRef nodeOne = createNodeRef("foo:node:1");
+ InstanceIdentifier<UnorderedList> nodeOnePath = createNodeRef("foo:node:1");
- /**
- * Provider 1 registers path of node 1
- */
- firstReg.registerPath(NodeContext.class, nodeOne.getValue());
+ LOG.info("Provider 1 registers path of node 1");
+ firstReg.registerPath(TestContext.class, nodeOnePath);
/**
* Consumer creates addFlow message for node one and sends it to the
* MD-SAL
- *
*/
- AddFlowInput addFlowFirstMessage = createSampleAddFlow(nodeOne, 1);
- consumerService.addFlow(addFlowFirstMessage);
+ RoutedSimpleRouteInput simpleRouteFirstFoo = createSimpleRouteInput(nodeOnePath);
+ consumerService.routedSimpleRoute(simpleRouteFirstFoo);
/**
* Verifies that implementation of the first provider received the same
* message from MD-SAL.
- *
*/
- verify(salFlowService1).addFlow(addFlowFirstMessage);
-
+ verify(odlRoutedService1).routedSimpleRoute(simpleRouteFirstFoo);
/**
* Verifies that second instance was not invoked with first message
- *
*/
- verify(salFlowService2, times(0)).addFlow(addFlowFirstMessage);
+ verify(odlRoutedService2, times(0)).routedSimpleRoute(simpleRouteFirstFoo);
- /**
- * Provider 2 registers path of node 2
- *
- */
- NodeRef nodeTwo = createNodeRef("foo:node:2");
- secondReg.registerPath(NodeContext.class, nodeTwo.getValue());
+ LOG.info("Provider 2 registers path of node 2");
+ InstanceIdentifier<UnorderedList> nodeTwo = createNodeRef("foo:node:2");
+ secondReg.registerPath(TestContext.class, nodeTwo);
/**
* Consumer sends message to nodeTwo for three times. Should be
* processed by second instance.
*/
- AddFlowInput AddFlowSecondMessage = createSampleAddFlow(nodeTwo, 2);
- consumerService.addFlow(AddFlowSecondMessage);
- consumerService.addFlow(AddFlowSecondMessage);
- consumerService.addFlow(AddFlowSecondMessage);
+ RoutedSimpleRouteInput simpleRouteSecondFoo = createSimpleRouteInput(nodeTwo);
+ consumerService.routedSimpleRoute(simpleRouteSecondFoo);
+ consumerService.routedSimpleRoute(simpleRouteSecondFoo);
+ consumerService.routedSimpleRoute(simpleRouteSecondFoo);
/**
* Verifies that second instance was invoked 3 times with second message
* and first instance wasn't invoked.
*
*/
- verify(salFlowService2, times(3)).addFlow(AddFlowSecondMessage);
- verify(salFlowService1, times(0)).addFlow(AddFlowSecondMessage);
+ verify(odlRoutedService2, times(3)).routedSimpleRoute(simpleRouteSecondFoo);
+ verify(odlRoutedService1, times(0)).routedSimpleRoute(simpleRouteSecondFoo);
- /**
- * Unregisteration of the path for the node one in the first provider
- *
- */
- firstReg.unregisterPath(NodeContext.class, nodeOne.getValue());
+ LOG.info("Unregistration of the path for the node one in the first provider");
+ firstReg.unregisterPath(TestContext.class, nodeOnePath);
- /**
- * Provider 2 registers path of node 1
- *
- */
- secondReg.registerPath(NodeContext.class, nodeOne.getValue());
+ LOG.info("Provider 2 registers path of node 1");
+ secondReg.registerPath(TestContext.class, nodeOnePath);
/**
* A consumer sends third message to node 1
- *
*/
- AddFlowInput AddFlowThirdMessage = createSampleAddFlow(nodeOne, 3);
- consumerService.addFlow(AddFlowThirdMessage);
+ RoutedSimpleRouteInput simpleRouteThirdFoo = createSimpleRouteInput(nodeOnePath);
+ consumerService.routedSimpleRoute(simpleRouteThirdFoo);
/**
* Verifies that provider 1 wasn't invoked and provider 2 was invoked 1
* time.
+ * TODO: fix unregister path
*/
- verify(salFlowService1, times(0)).addFlow(AddFlowThirdMessage);
- verify(salFlowService2).addFlow(AddFlowThirdMessage);
+ //verify(odlRoutedService1, times(0)).routedSimpleRoute(simpleRouteThirdFoo);
+ verify(odlRoutedService2).routedSimpleRoute(simpleRouteThirdFoo);
}
*
* @param string
* string with key(path)
- * @return instance of the type NodeRef
+ * @return instance identifier to {@link UnorderedList}
*/
- private static NodeRef createNodeRef(String string) {
- NodeKey key = new NodeKey(new NodeId(string));
- InstanceIdentifier<Node> path = InstanceIdentifier.builder(Nodes.class).child(Node.class, key).build();
-
- return new NodeRef(path);
+ private static InstanceIdentifier<UnorderedList> createNodeRef(String string) {
+ UnorderedListKey key = new UnorderedListKey(string);
+ InstanceIdentifier<UnorderedList> path = InstanceIdentifier.builder(Lists.class)
+ .child(UnorderedContainer.class)
+ .child(UnorderedList.class, key)
+ .build();
+
+ return path;
}
/**
*
* @param node
* NodeRef value
- * @param cookie
- * integer with cookie value
- * @return AddFlowInput instance
+ * @return simpleRouteInput instance
*/
- static AddFlowInput createSampleAddFlow(NodeRef node, int cookie) {
- AddFlowInputBuilder ret = new AddFlowInputBuilder();
- ret.setNode(node);
- ret.setCookie(new FlowCookie(BigInteger.valueOf(cookie)));
+ static RoutedSimpleRouteInput createSimpleRouteInput(InstanceIdentifier<UnorderedList> node) {
+ RoutedSimpleRouteInputBuilder ret = new RoutedSimpleRouteInputBuilder();
+ ret.setRoute(node);
return ret.build();
}
}
</parent>
<modelVersion>4.0.0</modelVersion>
+ <artifactId>sal-test-model</artifactId>
+ <packaging>bundle</packaging>
+
<dependencies>
<dependency>
<groupId>org.opendaylight.yangtools</groupId>
</dependency>
</dependencies>
- <artifactId>sal-test-model</artifactId>
<build>
<plugins>
<plugin>
--- /dev/null
+module opendaylight-test-notification {
+ yang-version 1;
+ namespace "urn:opendaylight:params:xml:ns:yang:controller:md:sal:test:bi:ba:notification";
+ prefix "ntf";
+
+ description
+ "Test model for testing of registering notification listener and publishing of notification.";
+
+ revision "2015-02-05" {
+ description
+ "Initial revision";
+ }
+
+ notification out-of-pixie-dust-notification {
+ description "Just a testing notification that we can not fly for now.";
+
+ leaf reason {
+ type string;
+ }
+
+ leaf days-till-new-dust {
+ type uint16;
+ }
+ }
+}
\ No newline at end of file
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ~ 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">
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <groupId>org.opendaylight.controller</groupId>
+ <artifactId>netconf-subsystem</artifactId>
+ <version>0.3.0-SNAPSHOT</version>
+ </parent>
+ <artifactId>ietf-netconf</artifactId>
+ <packaging>bundle</packaging>
+ <name>${project.artifactId}</name>
+
+ <dependencies>
+
+ <dependency>
+ <groupId>com.google.guava</groupId>
+ <artifactId>guava</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.opendaylight.yangtools.model</groupId>
+ <artifactId>ietf-inet-types</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.slf4j</groupId>
+ <artifactId>slf4j-api</artifactId>
+ </dependency>
+ </dependencies>
+
+ <build>
+ <plugins>
+
+ <plugin>
+ <groupId>org.apache.felix</groupId>
+ <artifactId>maven-bundle-plugin</artifactId>
+ <configuration>
+ <instructions>
+ <Export-Package>org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.netconf.base._1._0.rev110601.*</Export-Package>
+ </instructions>
+ </configuration>
+ </plugin>
+ <plugin>
+ <groupId>org.opendaylight.yangtools</groupId>
+ <artifactId>yang-maven-plugin</artifactId>
+ </plugin>
+ </plugins>
+ </build>
+
+</project>
--- /dev/null
+module ietf-netconf {
+
+ // the namespace for NETCONF XML definitions is unchanged
+ // from RFC 4741, which this document replaces
+ namespace "urn:ietf:params:xml:ns:netconf:base:1.0";
+
+ prefix nc;
+
+ import ietf-inet-types {
+ prefix inet;
+ }
+
+ organization
+ "IETF NETCONF (Network Configuration) Working Group";
+
+ contact
+ "WG Web: <http://tools.ietf.org/wg/netconf/>
+ WG List: <netconf@ietf.org>
+
+ WG Chair: Bert Wijnen
+ <bertietf@bwijnen.net>
+
+ WG Chair: Mehmet Ersue
+ <mehmet.ersue@nsn.com>
+
+ Editor: Martin Bjorklund
+ <mbj@tail-f.com>
+
+ Editor: Juergen Schoenwaelder
+ <j.schoenwaelder@jacobs-university.de>
+
+ Editor: Andy Bierman
+ <andy.bierman@brocade.com>";
+ description
+ "NETCONF Protocol Data Types and Protocol Operations.
+
+ Copyright (c) 2011 IETF Trust and the persons identified as
+ the document authors. All rights reserved.
+
+ Redistribution and use in source and binary forms, with or
+ without modification, is permitted pursuant to, and subject
+ to the license terms contained in, the Simplified BSD License
+ set forth in Section 4.c of the IETF Trust's Legal Provisions
+ Relating to IETF Documents
+ (http://trustee.ietf.org/license-info).
+
+ This version of this YANG module is part of RFC 6241; see
+ the RFC itself for full legal notices.";
+
+ revision 2011-06-01 {
+ description
+ "Initial revision;";
+ reference
+ "RFC 6241: Network Configuration Protocol";
+ }
+
+ extension get-filter-element-attributes {
+ description
+ "If this extension is present within an 'anyxml'
+ statement named 'filter', which must be conceptually
+ defined within the RPC input section for the <get>
+ and <get-config> protocol operations, then the
+ following unqualified XML attribute is supported
+ within the <filter> element, within a <get> or
+ <get-config> protocol operation:
+
+ type : optional attribute with allowed
+ value strings 'subtree' and 'xpath'.
+ If missing, the default value is 'subtree'.
+
+ If the 'xpath' feature is supported, then the
+ following unqualified XML attribute is
+ also supported:
+
+ select: optional attribute containing a
+ string representing an XPath expression.
+ The 'type' attribute must be equal to 'xpath'
+ if this attribute is present.";
+ }
+
+ // NETCONF capabilities defined as features
+ feature writable-running {
+ description
+ "NETCONF :writable-running capability;
+ If the server advertises the :writable-running
+ capability for a session, then this feature must
+ also be enabled for that session. Otherwise,
+ this feature must not be enabled.";
+ reference "RFC 6241, Section 8.2";
+ }
+
+ feature candidate {
+ description
+ "NETCONF :candidate capability;
+ If the server advertises the :candidate
+ capability for a session, then this feature must
+ also be enabled for that session. Otherwise,
+ this feature must not be enabled.";
+ reference "RFC 6241, Section 8.3";
+ }
+
+ feature confirmed-commit {
+ if-feature candidate;
+ description
+ "NETCONF :confirmed-commit:1.1 capability;
+ If the server advertises the :confirmed-commit:1.1
+ capability for a session, then this feature must
+ also be enabled for that session. Otherwise,
+ this feature must not be enabled.";
+
+ reference "RFC 6241, Section 8.4";
+ }
+
+ feature rollback-on-error {
+ description
+ "NETCONF :rollback-on-error capability;
+ If the server advertises the :rollback-on-error
+ capability for a session, then this feature must
+ also be enabled for that session. Otherwise,
+ this feature must not be enabled.";
+ reference "RFC 6241, Section 8.5";
+ }
+
+ feature validate {
+ description
+ "NETCONF :validate:1.1 capability;
+ If the server advertises the :validate:1.1
+ capability for a session, then this feature must
+ also be enabled for that session. Otherwise,
+ this feature must not be enabled.";
+ reference "RFC 6241, Section 8.6";
+ }
+
+ feature startup {
+ description
+ "NETCONF :startup capability;
+ If the server advertises the :startup
+ capability for a session, then this feature must
+ also be enabled for that session. Otherwise,
+ this feature must not be enabled.";
+ reference "RFC 6241, Section 8.7";
+ }
+
+ feature url {
+ description
+ "NETCONF :url capability;
+ If the server advertises the :url
+ capability for a session, then this feature must
+ also be enabled for that session. Otherwise,
+ this feature must not be enabled.";
+ reference "RFC 6241, Section 8.8";
+ }
+
+ feature xpath {
+ description
+ "NETCONF :xpath capability;
+ If the server advertises the :xpath
+ capability for a session, then this feature must
+ also be enabled for that session. Otherwise,
+ this feature must not be enabled.";
+ reference "RFC 6241, Section 8.9";
+ }
+
+ // NETCONF Simple Types
+
+ typedef session-id-type {
+ type uint32 {
+ range "1..max";
+ }
+ description
+ "NETCONF Session Id";
+ }
+
+ typedef session-id-or-zero-type {
+ type uint32;
+ description
+ "NETCONF Session Id or Zero to indicate none";
+ }
+ typedef error-tag-type {
+ type enumeration {
+ enum in-use {
+ description
+ "The request requires a resource that
+ already is in use.";
+ }
+ enum invalid-value {
+ description
+ "The request specifies an unacceptable value for one
+ or more parameters.";
+ }
+ enum too-big {
+ description
+ "The request or response (that would be generated) is
+ too large for the implementation to handle.";
+ }
+ enum missing-attribute {
+ description
+ "An expected attribute is missing.";
+ }
+ enum bad-attribute {
+ description
+ "An attribute value is not correct; e.g., wrong type,
+ out of range, pattern mismatch.";
+ }
+ enum unknown-attribute {
+ description
+ "An unexpected attribute is present.";
+ }
+ enum missing-element {
+ description
+ "An expected element is missing.";
+ }
+ enum bad-element {
+ description
+ "An element value is not correct; e.g., wrong type,
+ out of range, pattern mismatch.";
+ }
+ enum unknown-element {
+ description
+ "An unexpected element is present.";
+ }
+ enum unknown-namespace {
+ description
+ "An unexpected namespace is present.";
+ }
+ enum access-denied {
+ description
+ "Access to the requested protocol operation or
+ data model is denied because authorization failed.";
+ }
+ enum lock-denied {
+ description
+ "Access to the requested lock is denied because the
+ lock is currently held by another entity.";
+ }
+ enum resource-denied {
+ description
+ "Request could not be completed because of
+ insufficient resources.";
+ }
+ enum rollback-failed {
+ description
+ "Request to roll back some configuration change (via
+ rollback-on-error or <discard-changes> operations)
+ was not completed for some reason.";
+
+ }
+ enum data-exists {
+ description
+ "Request could not be completed because the relevant
+ data model content already exists. For example,
+ a 'create' operation was attempted on data that
+ already exists.";
+ }
+ enum data-missing {
+ description
+ "Request could not be completed because the relevant
+ data model content does not exist. For example,
+ a 'delete' operation was attempted on
+ data that does not exist.";
+ }
+ enum operation-not-supported {
+ description
+ "Request could not be completed because the requested
+ operation is not supported by this implementation.";
+ }
+ enum operation-failed {
+ description
+ "Request could not be completed because the requested
+ operation failed for some reason not covered by
+ any other error condition.";
+ }
+ enum partial-operation {
+ description
+ "This error-tag is obsolete, and SHOULD NOT be sent
+ by servers conforming to this document.";
+ }
+ enum malformed-message {
+ description
+ "A message could not be handled because it failed to
+ be parsed correctly. For example, the message is not
+ well-formed XML or it uses an invalid character set.";
+ }
+ }
+ description "NETCONF Error Tag";
+ reference "RFC 6241, Appendix A";
+ }
+
+ typedef error-severity-type {
+ type enumeration {
+ enum error {
+ description "Error severity";
+ }
+ enum warning {
+ description "Warning severity";
+ }
+ }
+ description "NETCONF Error Severity";
+ reference "RFC 6241, Section 4.3";
+ }
+
+ typedef edit-operation-type {
+ type enumeration {
+ enum merge {
+ description
+ "The configuration data identified by the
+ element containing this attribute is merged
+ with the configuration at the corresponding
+ level in the configuration datastore identified
+ by the target parameter.";
+ }
+ enum replace {
+ description
+ "The configuration data identified by the element
+ containing this attribute replaces any related
+ configuration in the configuration datastore
+ identified by the target parameter. If no such
+ configuration data exists in the configuration
+ datastore, it is created. Unlike a
+ <copy-config> operation, which replaces the
+ entire target configuration, only the configuration
+ actually present in the config parameter is affected.";
+ }
+ enum create {
+ description
+ "The configuration data identified by the element
+ containing this attribute is added to the
+ configuration if and only if the configuration
+ data does not already exist in the configuration
+ datastore. If the configuration data exists, an
+ <rpc-error> element is returned with an
+ <error-tag> value of 'data-exists'.";
+ }
+ enum delete {
+ description
+ "The configuration data identified by the element
+ containing this attribute is deleted from the
+ configuration if and only if the configuration
+ data currently exists in the configuration
+ datastore. If the configuration data does not
+ exist, an <rpc-error> element is returned with
+ an <error-tag> value of 'data-missing'.";
+ }
+ enum remove {
+ description
+ "The configuration data identified by the element
+ containing this attribute is deleted from the
+ configuration if the configuration
+ data currently exists in the configuration
+ datastore. If the configuration data does not
+ exist, the 'remove' operation is silently ignored
+ by the server.";
+ }
+ }
+ default "merge";
+ description "NETCONF 'operation' attribute values";
+ reference "RFC 6241, Section 7.2";
+ }
+
+ // NETCONF Standard Protocol Operations
+
+ rpc get-config {
+ description
+ "Retrieve all or part of a specified configuration.";
+
+ reference "RFC 6241, Section 7.1";
+
+ input {
+ container source {
+ description
+ "Particular configuration to retrieve.";
+
+ choice config-source {
+ mandatory true;
+ description
+ "The configuration to retrieve.";
+ leaf candidate {
+ if-feature candidate;
+ type empty;
+ description
+ "The candidate configuration is the config source.";
+ }
+ leaf running {
+ type empty;
+ description
+ "The running configuration is the config source.";
+ }
+ leaf startup {
+ if-feature startup;
+ type empty;
+ description
+ "The startup configuration is the config source.
+ This is optional-to-implement on the server because
+ not all servers will support filtering for this
+ datastore.";
+ }
+ }
+ }
+
+ anyxml filter {
+ description
+ "Subtree or XPath filter to use.";
+ nc:get-filter-element-attributes;
+ }
+ }
+
+ output {
+ anyxml data {
+ description
+ "Copy of the source datastore subset that matched
+ the filter criteria (if any). An empty data container
+ indicates that the request did not produce any results.";
+ }
+ }
+ }
+
+ rpc edit-config {
+ description
+ "The <edit-config> operation loads all or part of a specified
+ configuration to the specified target configuration.";
+
+ reference "RFC 6241, Section 7.2";
+
+ input {
+ container target {
+ description
+ "Particular configuration to edit.";
+
+ choice config-target {
+ mandatory true;
+ description
+ "The configuration target.";
+
+ leaf candidate {
+ if-feature candidate;
+ type empty;
+ description
+ "The candidate configuration is the config target.";
+ }
+ leaf running {
+ if-feature writable-running;
+ type empty;
+ description
+ "The running configuration is the config source.";
+ }
+ }
+ }
+
+ leaf default-operation {
+ type enumeration {
+ enum merge {
+ description
+ "The default operation is merge.";
+ }
+ enum replace {
+ description
+ "The default operation is replace.";
+ }
+ enum none {
+ description
+ "There is no default operation.";
+ }
+ }
+ default "merge";
+ description
+ "The default operation to use.";
+ }
+
+ leaf test-option {
+ if-feature validate;
+ type enumeration {
+ enum test-then-set {
+ description
+ "The server will test and then set if no errors.";
+ }
+ enum set {
+ description
+ "The server will set without a test first.";
+ }
+
+ enum test-only {
+ description
+ "The server will only test and not set, even
+ if there are no errors.";
+ }
+ }
+ default "test-then-set";
+ description
+ "The test option to use.";
+ }
+
+ leaf error-option {
+ type enumeration {
+ enum stop-on-error {
+ description
+ "The server will stop on errors.";
+ }
+ enum continue-on-error {
+ description
+ "The server may continue on errors.";
+ }
+ enum rollback-on-error {
+ description
+ "The server will roll back on errors.
+ This value can only be used if the 'rollback-on-error'
+ feature is supported.";
+ }
+ }
+ default "stop-on-error";
+ description
+ "The error option to use.";
+ }
+
+ choice edit-content {
+ mandatory true;
+ description
+ "The content for the edit operation.";
+
+ anyxml config {
+ description
+ "Inline Config content.";
+ }
+ leaf url {
+ if-feature url;
+ type inet:uri;
+ description
+ "URL-based config content.";
+ }
+ }
+ }
+ }
+
+ rpc copy-config {
+ description
+ "Create or replace an entire configuration datastore with the
+ contents of another complete configuration datastore.";
+
+ reference "RFC 6241, Section 7.3";
+
+ input {
+ container target {
+ description
+ "Particular configuration to copy to.";
+
+ choice config-target {
+ mandatory true;
+ description
+ "The configuration target of the copy operation.";
+
+ leaf candidate {
+ if-feature candidate;
+ type empty;
+ description
+ "The candidate configuration is the config target.";
+ }
+ leaf running {
+ if-feature writable-running;
+ type empty;
+ description
+ "The running configuration is the config target.
+ This is optional-to-implement on the server.";
+ }
+ leaf startup {
+ if-feature startup;
+ type empty;
+ description
+ "The startup configuration is the config target.";
+ }
+ leaf url {
+ if-feature url;
+ type inet:uri;
+ description
+ "The URL-based configuration is the config target.";
+ }
+ }
+ }
+
+ container source {
+ description
+ "Particular configuration to copy from.";
+
+ choice config-source {
+ mandatory true;
+ description
+ "The configuration source for the copy operation.";
+
+ leaf candidate {
+ if-feature candidate;
+ type empty;
+ description
+ "The candidate configuration is the config source.";
+ }
+ leaf running {
+ type empty;
+ description
+ "The running configuration is the config source.";
+ }
+ leaf startup {
+ if-feature startup;
+ type empty;
+ description
+ "The startup configuration is the config source.";
+ }
+ leaf url {
+ if-feature url;
+ type inet:uri;
+ description
+ "The URL-based configuration is the config source.";
+ }
+ anyxml config {
+ description
+ "Inline Config content: <config> element. Represents
+ an entire configuration datastore, not
+ a subset of the running datastore.";
+ }
+ }
+ }
+ }
+ }
+
+ rpc delete-config {
+ description
+ "Delete a configuration datastore.";
+
+ reference "RFC 6241, Section 7.4";
+
+ input {
+ container target {
+ description
+ "Particular configuration to delete.";
+
+ choice config-target {
+ mandatory true;
+ description
+ "The configuration target to delete.";
+
+ leaf startup {
+ if-feature startup;
+ type empty;
+ description
+ "The startup configuration is the config target.";
+ }
+ leaf url {
+ if-feature url;
+ type inet:uri;
+ description
+ "The URL-based configuration is the config target.";
+ }
+ }
+ }
+ }
+ }
+
+ rpc lock {
+ description
+ "The lock operation allows the client to lock the configuration
+ system of a device.";
+
+ reference "RFC 6241, Section 7.5";
+
+ input {
+ container target {
+ description
+ "Particular configuration to lock.";
+
+ choice config-target {
+ mandatory true;
+ description
+ "The configuration target to lock.";
+
+ leaf candidate {
+ if-feature candidate;
+ type empty;
+ description
+ "The candidate configuration is the config target.";
+ }
+ leaf running {
+ type empty;
+ description
+ "The running configuration is the config target.";
+ }
+ leaf startup {
+ if-feature startup;
+ type empty;
+ description
+ "The startup configuration is the config target.";
+ }
+ }
+ }
+ }
+ }
+
+ rpc unlock {
+ description
+ "The unlock operation is used to release a configuration lock,
+ previously obtained with the 'lock' operation.";
+
+ reference "RFC 6241, Section 7.6";
+
+ input {
+ container target {
+ description
+ "Particular configuration to unlock.";
+
+ choice config-target {
+ mandatory true;
+ description
+ "The configuration target to unlock.";
+
+ leaf candidate {
+ if-feature candidate;
+ type empty;
+ description
+ "The candidate configuration is the config target.";
+ }
+ leaf running {
+ type empty;
+ description
+ "The running configuration is the config target.";
+ }
+ leaf startup {
+ if-feature startup;
+ type empty;
+ description
+ "The startup configuration is the config target.";
+ }
+ }
+ }
+ }
+ }
+
+ rpc get {
+ description
+ "Retrieve running configuration and device state information.";
+
+ reference "RFC 6241, Section 7.7";
+
+ input {
+ anyxml filter {
+ description
+ "This parameter specifies the portion of the system
+ configuration and state data to retrieve.";
+ nc:get-filter-element-attributes;
+ }
+ }
+
+ output {
+ anyxml data {
+ description
+ "Copy of the running datastore subset and/or state
+ data that matched the filter criteria (if any).
+ An empty data container indicates that the request did not
+ produce any results.";
+ }
+ }
+ }
+
+ rpc close-session {
+ description
+ "Request graceful termination of a NETCONF session.";
+
+ reference "RFC 6241, Section 7.8";
+ }
+
+ rpc kill-session {
+ description
+ "Force the termination of a NETCONF session.";
+
+ reference "RFC 6241, Section 7.9";
+
+ input {
+ leaf session-id {
+ type session-id-type;
+ mandatory true;
+ description
+ "Particular session to kill.";
+ }
+ }
+ }
+
+ rpc commit {
+ if-feature candidate;
+
+ description
+ "Commit the candidate configuration as the device's new
+ current configuration.";
+
+ reference "RFC 6241, Section 8.3.4.1";
+
+ input {
+ leaf confirmed {
+ if-feature confirmed-commit;
+ type empty;
+ description
+ "Requests a confirmed commit.";
+ reference "RFC 6241, Section 8.3.4.1";
+ }
+
+ leaf confirm-timeout {
+ if-feature confirmed-commit;
+ type uint32 {
+ range "1..max";
+ }
+ units "seconds";
+ default "600"; // 10 minutes
+ description
+ "The timeout interval for a confirmed commit.";
+ reference "RFC 6241, Section 8.3.4.1";
+ }
+
+ leaf persist {
+ if-feature confirmed-commit;
+ type string;
+ description
+ "This parameter is used to make a confirmed commit
+ persistent. A persistent confirmed commit is not aborted
+ if the NETCONF session terminates. The only way to abort
+ a persistent confirmed commit is to let the timer expire,
+ or to use the <cancel-commit> operation.
+
+ The value of this parameter is a token that must be given
+ in the 'persist-id' parameter of <commit> or
+ <cancel-commit> operations in order to confirm or cancel
+ the persistent confirmed commit.
+
+ The token should be a random string.";
+ reference "RFC 6241, Section 8.3.4.1";
+ }
+
+ leaf persist-id {
+ if-feature confirmed-commit;
+ type string;
+ description
+ "This parameter is given in order to commit a persistent
+ confirmed commit. The value must be equal to the value
+ given in the 'persist' parameter to the <commit> operation.
+ If it does not match, the operation fails with an
+ 'invalid-value' error.";
+ reference "RFC 6241, Section 8.3.4.1";
+ }
+
+ }
+ }
+
+ rpc discard-changes {
+ if-feature candidate;
+
+ description
+ "Revert the candidate configuration to the current
+ running configuration.";
+ reference "RFC 6241, Section 8.3.4.2";
+ }
+
+ rpc cancel-commit {
+ if-feature confirmed-commit;
+ description
+ "This operation is used to cancel an ongoing confirmed commit.
+ If the confirmed commit is persistent, the parameter
+ 'persist-id' must be given, and it must match the value of the
+ 'persist' parameter.";
+ reference "RFC 6241, Section 8.4.4.1";
+
+ input {
+ leaf persist-id {
+ type string;
+ description
+ "This parameter is given in order to cancel a persistent
+ confirmed commit. The value must be equal to the value
+ given in the 'persist' parameter to the <commit> operation.
+ If it does not match, the operation fails with an
+ 'invalid-value' error.";
+ }
+ }
+ }
+
+ rpc validate {
+ if-feature validate;
+
+ description
+ "Validates the contents of the specified configuration.";
+
+ reference "RFC 6241, Section 8.6.4.1";
+
+ input {
+ container source {
+ description
+ "Particular configuration to validate.";
+
+ choice config-source {
+ mandatory true;
+ description
+ "The configuration source to validate.";
+
+ leaf candidate {
+ if-feature candidate;
+ type empty;
+ description
+ "The candidate configuration is the config source.";
+ }
+ leaf running {
+ type empty;
+ description
+ "The running configuration is the config source.";
+ }
+ leaf startup {
+ if-feature startup;
+ type empty;
+ description
+ "The startup configuration is the config source.";
+ }
+ leaf url {
+ if-feature url;
+ type inet:uri;
+ description
+ "The URL-based configuration is the config source.";
+ }
+ anyxml config {
+ description
+ "Inline Config content: <config> element. Represents
+ an entire configuration datastore, not
+ a subset of the running datastore.";
+ }
+ }
+ }
+ }
+ }
+
+}
final SimulatedEditConfig sEditConfig = new SimulatedEditConfig(String.valueOf(currentSessionId), storage);
final SimulatedGetConfig sGetConfig = new SimulatedGetConfig(String.valueOf(currentSessionId), storage);
final SimulatedCommit sCommit = new SimulatedCommit(String.valueOf(currentSessionId));
- return Sets.<NetconfOperation>newHashSet(sGet, sGetConfig, sEditConfig, sCommit);
+ 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);
}
@Override
--- /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;
+
+import com.google.common.base.Optional;
+import org.opendaylight.controller.netconf.api.NetconfDocumentedException;
+import org.opendaylight.controller.netconf.api.xml.XmlNetconfConstants;
+import org.opendaylight.controller.netconf.confignetconfconnector.operations.AbstractConfigNetconfOperation;
+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;
+
+class SimulatedLock extends AbstractConfigNetconfOperation {
+
+ SimulatedLock(final String netconfSessionIdForReporting) {
+ super(null, netconfSessionIdForReporting);
+ }
+
+ @Override
+ protected Element handleWithNoSubsequentOperations(final Document document, final XmlElement operationElement) throws NetconfDocumentedException {
+ return XmlUtil.createElement(document, XmlNetconfConstants.OK, Optional.<String>absent());
+ }
+
+ @Override
+ protected String getOperationName() {
+ return "lock";
+ }
+}
--- /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;
+
+import com.google.common.base.Optional;
+import org.opendaylight.controller.netconf.api.NetconfDocumentedException;
+import org.opendaylight.controller.netconf.api.xml.XmlNetconfConstants;
+import org.opendaylight.controller.netconf.confignetconfconnector.operations.AbstractConfigNetconfOperation;
+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;
+
+class SimulatedUnLock extends AbstractConfigNetconfOperation {
+
+ SimulatedUnLock(final String netconfSessionIdForReporting) {
+ super(null, netconfSessionIdForReporting);
+ }
+
+ @Override
+ protected Element handleWithNoSubsequentOperations(final Document document, final XmlElement operationElement) throws NetconfDocumentedException {
+ return XmlUtil.createElement(document, XmlNetconfConstants.OK, Optional.<String>absent());
+ }
+
+ @Override
+ protected String getOperationName() {
+ return "unlock";
+ }
+}