Merge "mdsal-notification simple unit test added"
authorTomas Cere <tcere@cisco.com>
Thu, 29 Sep 2016 11:47:16 +0000 (11:47 +0000)
committerGerrit Code Review <gerrit@opendaylight.org>
Thu, 29 Sep 2016 11:47:16 +0000 (11:47 +0000)
20 files changed:
netconf/config-netconf-connector/src/test/java/org/opendaylight/netconf/confignetconfconnector/osgi/NetconfOperationServiceImplTest.java [new file with mode: 0644]
netconf/mdsal-netconf-connector/src/main/java/org/opendaylight/netconf/mdsal/connector/ops/EditConfig.java
netconf/mdsal-netconf-connector/src/test/java/org/opendaylight/netconf/mdsal/connector/ops/NetconfMDSalMappingTest.java
netconf/mdsal-netconf-connector/src/test/resources/messages/mapping/editConfigs/edit-config-merge-map-entry.xml [new file with mode: 0644]
netconf/mdsal-netconf-connector/src/test/resources/messages/mapping/editConfigs/edit-config-replace-map-entry.xml [new file with mode: 0644]
netconf/mdsal-netconf-connector/src/test/resources/messages/mapping/get-config-map-entry.xml [new file with mode: 0644]
netconf/netconf-notifications-impl/src/main/java/org/opendaylight/netconf/notifications/impl/osgi/Activator.java
netconf/netconf-notifications-impl/src/test/java/org/opendaylight/netconf/notifications/impl/osgi/ActivatorTest.java [new file with mode: 0644]
netconf/sal-netconf-connector/pom.xml
netconf/sal-netconf-connector/src/main/java/org/opendaylight/netconf/sal/connect/netconf/SchemalessNetconfDevice.java
netconf/sal-netconf-connector/src/main/java/org/opendaylight/netconf/sal/connect/netconf/sal/NetconfDeviceSalFacade.java
netconf/sal-netconf-connector/src/test/java/org/opendaylight/netconf/sal/connect/netconf/SchemalessNetconfDeviceTest.java [new file with mode: 0644]
netconf/sal-netconf-connector/src/test/java/org/opendaylight/netconf/sal/connect/netconf/sal/NetconfDeviceSalFacadeTest.java [new file with mode: 0644]
netconf/sal-netconf-connector/src/test/java/org/opendaylight/netconf/sal/connect/netconf/sal/NetconfDeviceTopologyAdapterTest.java
netconf/sal-netconf-connector/src/test/java/org/opendaylight/netconf/sal/connect/netconf/util/RemoteDeviceIdTest.java [new file with mode: 0644]
netconf/yanglib/pom.xml
netconf/yanglib/src/main/java/org/opendaylight/yanglib/impl/YangLibServiceImpl.java
netconf/yanglib/src/test/java/org/opendaylight/yanglib/impl/YangLibRestAppTest.java [new file with mode: 0644]
netconf/yanglib/src/test/java/org/opendaylight/yanglib/impl/YangLibServiceImplTest.java [new file with mode: 0644]
pom.xml

diff --git a/netconf/config-netconf-connector/src/test/java/org/opendaylight/netconf/confignetconfconnector/osgi/NetconfOperationServiceImplTest.java b/netconf/config-netconf-connector/src/test/java/org/opendaylight/netconf/confignetconfconnector/osgi/NetconfOperationServiceImplTest.java
new file mode 100644 (file)
index 0000000..f286bd3
--- /dev/null
@@ -0,0 +1,65 @@
+/*
+ * Copyright (c) 2016 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.netconf.confignetconfconnector.osgi;
+
+import static junit.framework.TestCase.assertTrue;
+import static org.mockito.Mockito.doNothing;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+
+import java.util.Set;
+import org.junit.Test;
+import org.opendaylight.controller.config.facade.xml.ConfigSubsystemFacade;
+import org.opendaylight.netconf.confignetconfconnector.operations.Commit;
+import org.opendaylight.netconf.confignetconfconnector.operations.DiscardChanges;
+import org.opendaylight.netconf.confignetconfconnector.operations.Lock;
+import org.opendaylight.netconf.confignetconfconnector.operations.UnLock;
+import org.opendaylight.netconf.confignetconfconnector.operations.Validate;
+import org.opendaylight.netconf.confignetconfconnector.operations.editconfig.EditConfig;
+import org.opendaylight.netconf.confignetconfconnector.operations.get.Get;
+import org.opendaylight.netconf.confignetconfconnector.operations.getconfig.GetConfig;
+import org.opendaylight.netconf.confignetconfconnector.operations.runtimerpc.RuntimeRpc;
+import org.opendaylight.netconf.mapping.api.NetconfOperation;
+import org.opendaylight.netconf.mapping.api.NetconfOperationService;
+
+public class NetconfOperationServiceImplTest {
+
+    @Test
+    public void testOperationService() {
+        final ConfigSubsystemFacade configSubsystemFacade = mock(ConfigSubsystemFacade.class);
+        final NetconfOperationService netconfOperationService =
+                new NetconfOperationServiceImpl(configSubsystemFacade, "reportingID");
+
+        // testing operations in Set from NetconfOperationProvider
+
+        Set<NetconfOperation> operations = netconfOperationService.getNetconfOperations();
+
+        assertTrue(containInstance(operations, GetConfig.class));
+        assertTrue(containInstance(operations, EditConfig.class));
+        assertTrue(containInstance(operations, Commit.class));
+        assertTrue(containInstance(operations, Lock.class));
+        assertTrue(containInstance(operations, UnLock.class));
+        assertTrue(containInstance(operations, Get.class));
+        assertTrue(containInstance(operations, DiscardChanges.class));
+        assertTrue(containInstance(operations, Validate.class));
+        assertTrue(containInstance(operations, RuntimeRpc.class));
+
+        // verify closing service
+
+        doNothing().when(configSubsystemFacade).close();
+        netconfOperationService.close();
+
+        verify(configSubsystemFacade, times(1)).close();
+    }
+
+    private boolean containInstance(final Set<NetconfOperation> operations, final Class<?> cls) {
+        return operations.stream().filter(cls::isInstance).findFirst().isPresent();
+    }
+}
index 0d569e60121b2db634a281faf9f8973787a4f2e9..0a90d9c9d47aa980403da8fde1839acc03e7899b 100644 (file)
@@ -32,7 +32,10 @@ import org.opendaylight.netconf.util.mapping.AbstractSingletonNetconfOperation;
 import org.opendaylight.yangtools.yang.common.QName;
 import org.opendaylight.yangtools.yang.data.api.ModifyAction;
 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.api.schema.MapEntryNode;
+import org.opendaylight.yangtools.yang.data.api.schema.MapNode;
 import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
+import org.opendaylight.yangtools.yang.data.impl.schema.Builders;
 import org.opendaylight.yangtools.yang.data.impl.schema.transform.dom.DomUtils;
 import org.opendaylight.yangtools.yang.data.impl.schema.transform.dom.parser.DomToNormalizedNodeParserFactory;
 import org.opendaylight.yangtools.yang.model.api.ContainerSchemaNode;
@@ -76,7 +79,7 @@ public class EditConfig extends AbstractSingletonNetconfOperation {
 
         final XmlElement configElement = getElement(operationElement, CONFIG_KEY);
 
-        for (XmlElement element : configElement.getChildElements()) {
+        for (final XmlElement element : configElement.getChildElements()) {
             final String ns = element.getNamespace();
             final DataSchemaNode schemaNode = getSchemaNodeFromNamespace(ns, element).get();
 
@@ -102,45 +105,70 @@ public class EditConfig extends AbstractSingletonNetconfOperation {
     }
 
     private void executeChange(final DOMDataReadWriteTransaction rwtx, final DataTreeChange change) throws DocumentedException {
+        final YangInstanceIdentifier path = YangInstanceIdentifier.create(change.getPath());
+        final NormalizedNode<?, ?> changeData = change.getChangeRoot();
         switch (change.getAction()) {
         case NONE:
             return;
         case MERGE:
-            rwtx.merge(LogicalDatastoreType.CONFIGURATION, YangInstanceIdentifier.create(change.getPath()), change.getChangeRoot());
+            createMapNodeIfNonExistent(rwtx, path, changeData);
+            rwtx.merge(LogicalDatastoreType.CONFIGURATION, path, changeData);
             break;
         case CREATE:
             try {
-                final Optional<NormalizedNode<?, ?>> readResult = rwtx.read(LogicalDatastoreType.CONFIGURATION, YangInstanceIdentifier.create(change.getPath())).checkedGet();
+                final Optional<NormalizedNode<?, ?>> readResult = rwtx.read(LogicalDatastoreType.CONFIGURATION, path).checkedGet();
                 if (readResult.isPresent()) {
                     throw new DocumentedException("Data already exists, cannot execute CREATE operation", ErrorType.protocol, ErrorTag.data_exists, ErrorSeverity.error);
                 }
-                rwtx.put(LogicalDatastoreType.CONFIGURATION, YangInstanceIdentifier.create(change.getPath()), change.getChangeRoot());
-            } catch (ReadFailedException e) {
+                createMapNodeIfNonExistent(rwtx, path, changeData);
+                rwtx.put(LogicalDatastoreType.CONFIGURATION, path, changeData);
+            } catch (final ReadFailedException e) {
                 LOG.warn("Read from datastore failed when trying to read data for create operation", change, e);
             }
             break;
         case REPLACE:
-            rwtx.put(LogicalDatastoreType.CONFIGURATION, YangInstanceIdentifier.create(change.getPath()), change.getChangeRoot());
+            createMapNodeIfNonExistent(rwtx, path, changeData);
+            rwtx.put(LogicalDatastoreType.CONFIGURATION, path, changeData);
             break;
         case DELETE:
             try {
-                final Optional<NormalizedNode<?, ?>> readResult = rwtx.read(LogicalDatastoreType.CONFIGURATION, YangInstanceIdentifier.create(change.getPath())).checkedGet();
+                final Optional<NormalizedNode<?, ?>> readResult = rwtx.read(LogicalDatastoreType.CONFIGURATION, path).checkedGet();
                 if (!readResult.isPresent()) {
                     throw new DocumentedException("Data is missing, cannot execute DELETE operation", ErrorType.protocol, ErrorTag.data_missing, ErrorSeverity.error);
                 }
-                rwtx.delete(LogicalDatastoreType.CONFIGURATION, YangInstanceIdentifier.create(change.getPath()));
-            } catch (ReadFailedException e) {
+                rwtx.delete(LogicalDatastoreType.CONFIGURATION, path);
+            } catch (final ReadFailedException e) {
                 LOG.warn("Read from datastore failed when trying to read data for delete operation", change, e);
             }
             break;
         case REMOVE:
-            rwtx.delete(LogicalDatastoreType.CONFIGURATION, YangInstanceIdentifier.create(change.getPath()));
+            rwtx.delete(LogicalDatastoreType.CONFIGURATION, path);
             break;
         default:
             LOG.warn("Unknown/not implemented operation, not executing");
         }
     }
 
+    private void createMapNodeIfNonExistent(final DOMDataReadWriteTransaction rwtx, final YangInstanceIdentifier path,
+                                            final NormalizedNode change) throws DocumentedException {
+        if (!(change instanceof MapEntryNode)) {
+            return;
+        }
+        final YangInstanceIdentifier mapNodeYid = path.getParent();
+        try {
+            final Boolean mapNodeExists = rwtx.exists(LogicalDatastoreType.CONFIGURATION, mapNodeYid).checkedGet();
+            if (!mapNodeExists) {
+                final MapNode mixinNode = Builders.mapBuilder()
+                        .withNodeIdentifier(new YangInstanceIdentifier.NodeIdentifier(mapNodeYid.getLastPathArgument().getNodeType()))
+                        .build();
+                rwtx.put(LogicalDatastoreType.CONFIGURATION, mapNodeYid, mixinNode);
+            }
+        } catch (final ReadFailedException e) {
+            throw new DocumentedException("List node existence check failed", e, ErrorType.protocol, ErrorTag.data_missing, ErrorSeverity.error);
+
+        }
+    }
+
     private NormalizedNode parseIntoNormalizedNode(final DataSchemaNode schemaNode, final XmlElement element,
                                                    final DomToNormalizedNodeParserFactory.BuildingStrategyProvider editOperationStrategyProvider) {
 
@@ -172,7 +200,7 @@ public class EditConfig extends AbstractSingletonNetconfOperation {
                 throw new NetconfDocumentedException("Unable to find module by namespace: " + namespace,
                         ErrorType.application, ErrorTag.unknown_namespace, ErrorSeverity.error);
             }
-            DataSchemaNode schemaNode =
+            final DataSchemaNode schemaNode =
                     module.getDataChildByName(QName.create(module.getQNameModule(), element.getName()));
             if (schemaNode != null) {
                 dataSchemaNode = Optional.of(schemaNode);
@@ -182,7 +210,7 @@ public class EditConfig extends AbstractSingletonNetconfOperation {
                         ErrorTag.unknown_namespace,
                         ErrorSeverity.error);
             }
-        } catch (URISyntaxException e) {
+        } catch (final URISyntaxException e) {
             LOG.debug("Unable to create URI for namespace : {}", namespace);
         }
 
@@ -215,7 +243,7 @@ public class EditConfig extends AbstractSingletonNetconfOperation {
 
     }
 
-    private XmlElement getElement(final XmlElement operationElement, String elementName) throws DocumentedException {
+    private XmlElement getElement(final XmlElement operationElement, final String elementName) throws DocumentedException {
         final Optional<XmlElement> childNode = operationElement.getOnlyChildElementOptionally(elementName);
         if (!childNode.isPresent()) {
             throw new DocumentedException(elementName + " element is missing",
index 11c8473606401e541355a8e7b8eaf98e2521e0d0..623162d74bf1f48d2b6deb651ee109e96f9c74df 100644 (file)
@@ -468,6 +468,20 @@ public class NetconfMDSalMappingTest {
         deleteDatastore();
     }
 
+    @Test
+    public void testReplaceMapEntry() throws Exception {
+        verifyResponse(edit("messages/mapping/editConfigs/edit-config-replace-map-entry.xml"), RPC_REPLY_OK);
+        verifyResponse(commit(), RPC_REPLY_OK);
+        verifyResponse(getConfigRunning(), XmlFileLoader.xmlFileToDocument("messages/mapping/get-config-map-entry.xml"));
+    }
+
+    @Test
+    public void testMergeMapEntry() throws Exception {
+        verifyResponse(edit("messages/mapping/editConfigs/edit-config-merge-map-entry.xml"), RPC_REPLY_OK);
+        verifyResponse(commit(), RPC_REPLY_OK);
+        verifyResponse(getConfigRunning(), XmlFileLoader.xmlFileToDocument("messages/mapping/get-config-map-entry.xml"));
+    }
+
     @Test
     public void testFiltering() throws Exception {
 
diff --git a/netconf/mdsal-netconf-connector/src/test/resources/messages/mapping/editConfigs/edit-config-merge-map-entry.xml b/netconf/mdsal-netconf-connector/src/test/resources/messages/mapping/editConfigs/edit-config-merge-map-entry.xml
new file mode 100644 (file)
index 0000000..870ec0a
--- /dev/null
@@ -0,0 +1,24 @@
+<!--
+  ~ Copyright (c) 2016 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
+  -->
+
+<rpc message-id="a" a="64" xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
+    <edit-config>
+        <target>
+            <candidate/>
+        </target>
+        <default-operation>none</default-operation>
+        <config>
+            <mapping-nodes xmlns="urn:opendaylight:mdsal:mapping:test">
+                <mapping-node xmlns:a="urn:ietf:params:xml:ns:netconf:base:1.0" a:operation="merge">
+                    <id>id1</id>
+                    <content>content1</content>
+                </mapping-node>
+            </mapping-nodes>
+        </config>
+    </edit-config>
+</rpc>
\ No newline at end of file
diff --git a/netconf/mdsal-netconf-connector/src/test/resources/messages/mapping/editConfigs/edit-config-replace-map-entry.xml b/netconf/mdsal-netconf-connector/src/test/resources/messages/mapping/editConfigs/edit-config-replace-map-entry.xml
new file mode 100644 (file)
index 0000000..d3dc541
--- /dev/null
@@ -0,0 +1,24 @@
+<!--
+  ~ Copyright (c) 2016 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
+  -->
+
+<rpc message-id="a" a="64" xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
+    <edit-config>
+        <target>
+            <candidate/>
+        </target>
+        <default-operation>none</default-operation>
+        <config>
+            <mapping-nodes xmlns="urn:opendaylight:mdsal:mapping:test">
+                <mapping-node xmlns:a="urn:ietf:params:xml:ns:netconf:base:1.0" a:operation="replace">
+                    <id>id1</id>
+                    <content>content1</content>
+                </mapping-node>
+            </mapping-nodes>
+        </config>
+    </edit-config>
+</rpc>
\ No newline at end of file
diff --git a/netconf/mdsal-netconf-connector/src/test/resources/messages/mapping/get-config-map-entry.xml b/netconf/mdsal-netconf-connector/src/test/resources/messages/mapping/get-config-map-entry.xml
new file mode 100644 (file)
index 0000000..393f336
--- /dev/null
@@ -0,0 +1,18 @@
+<!--
+  ~ Copyright (c) 2016 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
+  -->
+
+<rpc-reply xmlns="urn:ietf:params:xml:ns:netconf:base:1.0" a="64" id="a" message-id="101" xmlnx="a:b:c:d">
+    <data>
+        <mapping-nodes xmlns="urn:opendaylight:mdsal:mapping:test">
+            <mapping-node>
+                <id>id1</id>
+                <content>content1</content>
+            </mapping-node>
+        </mapping-nodes>
+    </data>
+</rpc-reply>
\ No newline at end of file
index 89aee08e87f22476577928136c5f628647e9c3b1..1cbd5237389dad5900da775ce0458399ecb20721 100644 (file)
@@ -8,6 +8,7 @@
 
 package org.opendaylight.netconf.notifications.impl.osgi;
 
+import com.google.common.annotations.VisibleForTesting;
 import com.google.common.collect.Sets;
 import java.util.Collections;
 import java.util.Dictionary;
@@ -107,4 +108,9 @@ public class Activator implements BundleActivator {
             operationaServiceRegistration = null;
         }
     }
+
+    @VisibleForTesting
+    NetconfNotificationManager getNetconfNotificationManager() {
+        return netconfNotificationManager;
+    }
 }
diff --git a/netconf/netconf-notifications-impl/src/test/java/org/opendaylight/netconf/notifications/impl/osgi/ActivatorTest.java b/netconf/netconf-notifications-impl/src/test/java/org/opendaylight/netconf/notifications/impl/osgi/ActivatorTest.java
new file mode 100644 (file)
index 0000000..24e8652
--- /dev/null
@@ -0,0 +1,118 @@
+/*
+ * Copyright (c) 2016 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.netconf.notifications.impl.osgi;
+
+import static org.junit.Assert.assertEquals;
+import static org.mockito.Matchers.any;
+import static org.mockito.Matchers.eq;
+import static org.mockito.Mockito.doNothing;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+
+import java.util.Collections;
+import java.util.Dictionary;
+import java.util.Hashtable;
+import java.util.Set;
+import org.junit.Test;
+import org.mockito.ArgumentCaptor;
+import org.opendaylight.controller.config.util.capability.BasicCapability;
+import org.opendaylight.controller.config.util.capability.Capability;
+import org.opendaylight.netconf.api.monitoring.CapabilityListener;
+import org.opendaylight.netconf.api.util.NetconfConstants;
+import org.opendaylight.netconf.mapping.api.NetconfOperation;
+import org.opendaylight.netconf.mapping.api.NetconfOperationService;
+import org.opendaylight.netconf.mapping.api.NetconfOperationServiceFactory;
+import org.opendaylight.netconf.notifications.NetconfNotification;
+import org.opendaylight.netconf.notifications.NetconfNotificationCollector;
+import org.opendaylight.netconf.notifications.impl.NetconfNotificationManager;
+import org.opendaylight.netconf.notifications.impl.ops.CreateSubscription;
+import org.opendaylight.netconf.notifications.impl.ops.Get;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.ServiceRegistration;
+
+public class ActivatorTest {
+
+    @Test
+    public void testActivator() throws Exception {
+        final Activator activator = new Activator();
+        final BundleContext context = mock(BundleContext.class);
+
+
+        final ServiceRegistration netconfNotificationCollectorServiceRegistration  = mock(ServiceRegistration.class);
+        final ServiceRegistration operationaServiceRegistration = mock(ServiceRegistration.class);
+
+        // test registering services
+        doReturn(netconfNotificationCollectorServiceRegistration).when(context).
+                registerService(eq(NetconfNotificationCollector.class), any(NetconfNotificationManager.class), any());
+        doReturn(operationaServiceRegistration).when(context).
+                registerService(eq(NetconfOperationServiceFactory.class), any(NetconfOperationServiceFactory.class), any());
+
+        activator.start(context);
+
+        verify(context, times(1)).registerService(eq(NetconfNotificationCollector.class),
+                any(NetconfNotificationManager.class), eq(new Hashtable<>()));
+
+        final ArgumentCaptor<NetconfOperationServiceFactory> serviceFactoryArgumentCaptor =
+                ArgumentCaptor.forClass(NetconfOperationServiceFactory.class);
+
+        final Dictionary<String, String> properties = new Hashtable<>();
+        properties.put(NetconfConstants.SERVICE_NAME, NetconfConstants.NETCONF_MONITORING);
+
+        verify(context, times(1)).registerService(eq(NetconfOperationServiceFactory.class),
+                serviceFactoryArgumentCaptor.capture(), eq(properties));
+
+        // test service factory argument requisites
+        final NetconfOperationServiceFactory serviceFactory = serviceFactoryArgumentCaptor.getValue();
+
+        final Set<Capability> capabilities = Collections.singleton(new BasicCapability(NetconfNotification.NOTIFICATION_NAMESPACE));
+
+        assertEquals(capabilities.iterator().next().getCapabilityUri(), serviceFactory.getCapabilities().iterator().next().getCapabilityUri());
+        assertEquals(capabilities.iterator().next().getCapabilitySchema(), serviceFactory.getCapabilities().iterator().next().getCapabilitySchema());
+        assertEquals(capabilities.iterator().next().getModuleNamespace(), serviceFactory.getCapabilities().iterator().next().getModuleNamespace());
+        assertEquals(capabilities.iterator().next().getModuleName(), serviceFactory.getCapabilities().iterator().next().getModuleName());
+
+        final CapabilityListener listener = mock(CapabilityListener.class);
+
+        doNothing().when(listener).onCapabilitiesChanged(any(), any());
+
+        serviceFactory.registerCapabilityListener(listener);
+
+        verify(listener).onCapabilitiesChanged(serviceFactory.getCapabilities(), Collections.emptySet());
+
+        final NetconfOperationService netconfOperationService = serviceFactory.createService("id");
+        final Set<NetconfOperation> netconfOperations = netconfOperationService.getNetconfOperations();
+
+        final CreateSubscription createSubscription = new CreateSubscription("id", activator.getNetconfNotificationManager());
+
+        netconfOperations.forEach(
+                operation -> {
+                    if (operation instanceof CreateSubscription) {
+                        assertEquals(createSubscription.toString(), operation.toString());
+                    }
+                    if (operation instanceof Get) {
+                        assertEquals("id", ((Get) operation).getNetconfSessionIdForReporting());
+                    }
+                }
+        );
+
+        // test unregister after stop
+        doNothing().when(netconfNotificationCollectorServiceRegistration).unregister();
+        doNothing().when(operationaServiceRegistration).unregister();
+
+        activator.stop(context);
+
+        verify(netconfNotificationCollectorServiceRegistration, times(1)).unregister();
+        verify(operationaServiceRegistration, times(1)).unregister();
+
+    }
+
+
+}
index 7a91d064e51775ec7715e883614d582bd41b16e7..9adcf03eb64f716cc55dd7b152132a5d7b9c3b2a 100644 (file)
       <artifactId>sal-distributed-datastore</artifactId>
       <scope>test</scope>
     </dependency>
+    <dependency>
+      <groupId>org.powermock</groupId>
+      <artifactId>powermock-module-junit4</artifactId>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.powermock</groupId>
+      <artifactId>powermock-api-mockito</artifactId>
+      <scope>test</scope>
+    </dependency>
   </dependencies>
 
   <scm>
index 758c46c80df8a9d73a6160a7dd988fe26c145f25..5a7e64c0f58aa54f489eb3b6fd38af2e44c2d95b 100644 (file)
@@ -7,6 +7,7 @@
  */
 package org.opendaylight.netconf.sal.connect.netconf;
 
+import com.google.common.annotations.VisibleForTesting;
 import org.opendaylight.netconf.api.NetconfMessage;
 import org.opendaylight.netconf.sal.connect.api.RemoteDevice;
 import org.opendaylight.netconf.sal.connect.api.RemoteDeviceHandler;
@@ -36,6 +37,16 @@ public class SchemalessNetconfDevice implements
         messageTransformer = new SchemalessMessageTransformer(counter);
     }
 
+    @VisibleForTesting
+    SchemalessNetconfDevice(final RemoteDeviceId id, final RemoteDeviceHandler<NetconfSessionPreferences> salFacade,
+                            final SchemalessMessageTransformer messageTransformer) {
+        this.id = id;
+        this.salFacade = salFacade;
+        final MessageCounter counter = new MessageCounter();
+        rpcTransformer = new BaseRpcSchemalessTransformer(counter);
+        this.messageTransformer = messageTransformer;
+    }
+
     @Override public void onRemoteSessionUp(final NetconfSessionPreferences remoteSessionCapabilities,
                                             final NetconfDeviceCommunicator netconfDeviceCommunicator) {
         final SchemalessNetconfDeviceRpc schemalessNetconfDeviceRpc = new SchemalessNetconfDeviceRpc(id,
index 829487a409a232c7ab040fbe6eee013047b7c613..90408690f33d008960856597a611ed7db2988e7b 100644 (file)
@@ -7,6 +7,7 @@
  */
 package org.opendaylight.netconf.sal.connect.netconf.sal;
 
+import com.google.common.annotations.VisibleForTesting;
 import com.google.common.collect.Lists;
 import java.util.List;
 import org.opendaylight.controller.md.sal.dom.api.DOMDataBroker;
@@ -37,6 +38,14 @@ public final class NetconfDeviceSalFacade implements AutoCloseable, RemoteDevice
         registerToSal(domBroker, bindingBroker);
     }
 
+    @VisibleForTesting
+    NetconfDeviceSalFacade(final RemoteDeviceId id, NetconfDeviceSalProvider salProvider,
+                           final Broker domBroker, final BindingAwareBroker bindingBroker) {
+        this.id = id;
+        this.salProvider = salProvider;
+        registerToSal(domBroker, bindingBroker);
+    }
+
     public void registerToSal(final Broker domRegistryDependency, final BindingAwareBroker bindingBroker) {
         domRegistryDependency.registerProvider(salProvider);
         bindingBroker.registerProvider(salProvider);
diff --git a/netconf/sal-netconf-connector/src/test/java/org/opendaylight/netconf/sal/connect/netconf/SchemalessNetconfDeviceTest.java b/netconf/sal-netconf-connector/src/test/java/org/opendaylight/netconf/sal/connect/netconf/SchemalessNetconfDeviceTest.java
new file mode 100644 (file)
index 0000000..7dd8064
--- /dev/null
@@ -0,0 +1,106 @@
+/*
+ * Copyright (c) 2016 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.netconf.sal.connect.netconf;
+
+import static org.mockito.Matchers.any;
+import static org.mockito.Mockito.doNothing;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+
+import com.google.common.collect.Lists;
+import java.lang.reflect.Field;
+import java.net.InetSocketAddress;
+import java.util.ArrayList;
+import java.util.Collection;
+import org.junit.Test;
+import org.mockito.Mockito;
+import org.opendaylight.controller.md.sal.dom.api.DOMNotification;
+import org.opendaylight.controller.md.sal.dom.api.DOMRpcService;
+import org.opendaylight.netconf.api.NetconfMessage;
+import org.opendaylight.netconf.api.xml.XmlNetconfConstants;
+import org.opendaylight.netconf.sal.connect.api.RemoteDeviceHandler;
+import org.opendaylight.netconf.sal.connect.netconf.listener.NetconfDeviceCommunicator;
+import org.opendaylight.netconf.sal.connect.netconf.listener.NetconfSessionPreferences;
+import org.opendaylight.netconf.sal.connect.netconf.sal.NetconfDeviceRpc;
+import org.opendaylight.netconf.sal.connect.netconf.schema.mapping.SchemalessMessageTransformer;
+import org.opendaylight.netconf.sal.connect.netconf.util.NetconfMessageTransformUtil;
+import org.opendaylight.netconf.sal.connect.util.RemoteDeviceId;
+import org.opendaylight.yangtools.yang.model.api.SchemaContext;
+
+public class SchemalessNetconfDeviceTest {
+
+    private static final String TEST_NAMESPACE = "test:namespace";
+    private static final String TEST_MODULE = "test-module";
+    private static final String TEST_REVISION = "2013-07-22";
+
+    @Test
+    public void testSessionOnMethods() throws Exception {
+        final RemoteDeviceHandler<NetconfSessionPreferences> facade = getFacade();
+        final NetconfDeviceCommunicator listener = mockCloseableClass(NetconfDeviceCommunicator.class);
+        final SchemalessMessageTransformer messageTransformer = mock(SchemalessMessageTransformer.class);
+        final RemoteDeviceId remoteDeviceId = new RemoteDeviceId("test-D",
+                InetSocketAddress.createUnresolved("localhost", 22));
+        final Throwable throwable = new Throwable();
+
+        final SchemalessNetconfDevice device = new SchemalessNetconfDevice(remoteDeviceId, facade, messageTransformer);
+
+        final NetconfSessionPreferences sessionCaps = getSessionCaps(true,
+                Lists.newArrayList(TEST_NAMESPACE + "?module=" + TEST_MODULE + "&amp;revision=" + TEST_REVISION));
+
+        final NetconfMessage netconfMessage = mock(NetconfMessage.class);
+
+        device.onRemoteSessionUp(sessionCaps, listener);
+        verify(facade).onDeviceConnected(any(SchemaContext.class), any(NetconfSessionPreferences.class), any(DOMRpcService.class));
+
+        device.onNotification(netconfMessage);
+        verify(facade).onNotification(any(DOMNotification.class));
+
+        device.onRemoteSessionDown();
+        verify(facade).onDeviceDisconnected();
+
+        device.onRemoteSessionFailed(throwable);
+        verify(facade).onDeviceFailed(throwable);
+    }
+
+    @SuppressWarnings("unchecked")
+    private RemoteDeviceHandler<NetconfSessionPreferences> getFacade() throws Exception {
+        final RemoteDeviceHandler<NetconfSessionPreferences> remoteDeviceHandler = mockCloseableClass(RemoteDeviceHandler.class);
+        doNothing().when(remoteDeviceHandler).onDeviceConnected(any(SchemaContext.class), any(NetconfSessionPreferences.class), any(NetconfDeviceRpc.class));
+        doNothing().when(remoteDeviceHandler).onDeviceDisconnected();
+        doNothing().when(remoteDeviceHandler).onNotification(any(DOMNotification.class));
+        return remoteDeviceHandler;
+    }
+
+    private <T extends AutoCloseable> T mockCloseableClass(final Class<T> remoteDeviceHandlerClass) throws Exception {
+        final T mock = mockClass(remoteDeviceHandlerClass);
+        doNothing().when(mock).close();
+        return mock;
+    }
+
+    private static <T> T mockClass(final Class<T> remoteDeviceHandlerClass) {
+        final T mock = mock(remoteDeviceHandlerClass);
+        Mockito.doReturn(remoteDeviceHandlerClass.getSimpleName()).when(mock).toString();
+        return mock;
+    }
+
+    private NetconfSessionPreferences getSessionCaps(final boolean addMonitor, final Collection<String> additionalCapabilities) {
+        final ArrayList<String> capabilities = Lists.newArrayList(
+                XmlNetconfConstants.URN_IETF_PARAMS_NETCONF_BASE_1_0,
+                XmlNetconfConstants.URN_IETF_PARAMS_NETCONF_BASE_1_1);
+
+        if(addMonitor) {
+            capabilities.add(NetconfMessageTransformUtil.IETF_NETCONF_MONITORING.getNamespace().toString());
+        }
+
+        capabilities.addAll(additionalCapabilities);
+
+        return NetconfSessionPreferences.fromStrings(
+                capabilities);
+    }
+}
diff --git a/netconf/sal-netconf-connector/src/test/java/org/opendaylight/netconf/sal/connect/netconf/sal/NetconfDeviceSalFacadeTest.java b/netconf/sal-netconf-connector/src/test/java/org/opendaylight/netconf/sal/connect/netconf/sal/NetconfDeviceSalFacadeTest.java
new file mode 100644 (file)
index 0000000..07577ca
--- /dev/null
@@ -0,0 +1,120 @@
+/*
+ * Copyright (c) 2016 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.netconf.sal.connect.netconf.sal;
+
+import static org.mockito.Matchers.any;
+import static org.mockito.Matchers.eq;
+import static org.mockito.Mockito.doNothing;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.MockitoAnnotations.initMocks;
+
+import java.net.InetSocketAddress;
+import java.util.Arrays;
+import java.util.List;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.opendaylight.controller.md.sal.dom.api.DOMDataBroker;
+import org.opendaylight.controller.md.sal.dom.api.DOMNotification;
+import org.opendaylight.controller.md.sal.dom.api.DOMRpcService;
+import org.opendaylight.controller.sal.binding.api.BindingAwareBroker;
+import org.opendaylight.controller.sal.core.api.Broker;
+import org.opendaylight.netconf.sal.connect.netconf.listener.NetconfDeviceCapabilities;
+import org.opendaylight.netconf.sal.connect.netconf.listener.NetconfSessionPreferences;
+import org.opendaylight.netconf.sal.connect.netconf.util.NetconfMessageTransformUtil;
+import org.opendaylight.netconf.sal.connect.util.RemoteDeviceId;
+import org.opendaylight.yangtools.yang.model.api.SchemaContext;
+import org.powermock.api.mockito.PowerMockito;
+import org.powermock.core.classloader.annotations.PrepareForTest;
+import org.powermock.modules.junit4.PowerMockRunner;
+
+@RunWith(PowerMockRunner.class)
+@PrepareForTest({NetconfDeviceTopologyAdapter.class, NetconfDeviceSalProvider.MountInstance.class, NetconfSessionPreferences.class})
+public class NetconfDeviceSalFacadeTest {
+
+    private NetconfDeviceSalFacade deviceFacade;
+
+    private NetconfDeviceTopologyAdapter netconfDeviceTopologyAdapter;
+    private NetconfDeviceSalProvider.MountInstance mountInstance;
+
+    @Mock
+    private NetconfDeviceSalProvider salProvider;
+
+    @Before
+    public void setUp() throws Exception{
+        initMocks(this);
+        final InetSocketAddress address = new InetSocketAddress("127.0.0.1", 8000);
+        final RemoteDeviceId remoteDeviceId = new RemoteDeviceId("test", address);
+
+        final Broker domRegistry = mock(Broker.class);
+        final BindingAwareBroker bindingRegistry = mock(BindingAwareBroker.class);
+        deviceFacade = new NetconfDeviceSalFacade(remoteDeviceId, salProvider, domRegistry, bindingRegistry);
+
+        netconfDeviceTopologyAdapter = PowerMockito.mock(NetconfDeviceTopologyAdapter.class);
+        mountInstance = PowerMockito.mock(NetconfDeviceSalProvider.MountInstance.class);
+
+        doReturn(netconfDeviceTopologyAdapter).when(salProvider).getTopologyDatastoreAdapter();
+        doNothing().when(netconfDeviceTopologyAdapter).updateDeviceData(any(Boolean.class), any(NetconfDeviceCapabilities.class));
+
+        doReturn(mountInstance).when(salProvider).getMountInstance();
+        doNothing().when(mountInstance).onTopologyDeviceDisconnected();
+    }
+
+    @Test
+    public void testOnDeviceDisconnected() {
+        deviceFacade.onDeviceDisconnected();
+
+        verify(netconfDeviceTopologyAdapter).updateDeviceData(eq(false), any(NetconfDeviceCapabilities.class));
+        verify(mountInstance, times(1)).onTopologyDeviceDisconnected();
+
+    }
+
+    @Test
+    public void testOnDeviceFailed() {
+        final Throwable throwable = new Throwable();
+        deviceFacade.onDeviceFailed(throwable);
+
+        verify(netconfDeviceTopologyAdapter).setDeviceAsFailed(throwable);
+        verify(mountInstance, times(1)).onTopologyDeviceDisconnected();
+    }
+
+    @Test
+    public void testOnDeviceClose() throws Exception {
+        deviceFacade.close();
+        verify(salProvider).close();
+    }
+
+    @Test
+    public void testOnDeviceConnected() {
+        final SchemaContext schemaContext = mock(SchemaContext.class);
+
+        final NetconfSessionPreferences netconfSessionPreferences = NetconfSessionPreferences.fromStrings(getCapabilities());
+
+        final DOMRpcService deviceRpc = mock(DOMRpcService.class);
+        deviceFacade.onDeviceConnected(schemaContext, netconfSessionPreferences, deviceRpc);
+
+        verify(mountInstance, times(1)).onTopologyDeviceConnected(eq(schemaContext), any(DOMDataBroker.class), eq(deviceRpc), any(NetconfDeviceNotificationService.class));
+        verify(netconfDeviceTopologyAdapter, times(1)).updateDeviceData(true, netconfSessionPreferences.getNetconfDeviceCapabilities());
+    }
+
+    @Test
+    public void testOnDeviceNotification() throws Exception {
+        final DOMNotification domNotification = mock(DOMNotification.class);
+        deviceFacade.onNotification(domNotification);
+        verify(mountInstance).publish(domNotification);
+    }
+
+   private List<String> getCapabilities(){
+        return Arrays.asList(NetconfMessageTransformUtil.NETCONF_CANDIDATE_URI.toString());
+    }
+}
index 2358819f90439f8e1a8abf0a2666dd63c0aa89ea..0af8a257e71c726dc26d78253a9ddc6b8a75151c 100644 (file)
@@ -23,28 +23,22 @@ import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.EnumMap;
 import java.util.List;
-import java.util.Set;
 import java.util.concurrent.ExecutorService;
 import java.util.concurrent.TimeUnit;
-import java.util.concurrent.TimeoutException;
 import javassist.ClassPool;
-import org.custommonkey.xmlunit.XMLUnit;
 import org.junit.Before;
 import org.junit.Test;
 import org.mockito.Mock;
 import org.mockito.MockitoAnnotations;
-import org.mockito.internal.util.collections.Sets;
 import org.opendaylight.controller.cluster.databroker.ConcurrentDOMDataBroker;
-import org.opendaylight.controller.cluster.datastore.node.utils.AugmentationIdentifierGenerator;
-import org.opendaylight.controller.md.sal.binding.impl.BindingDOMDataBrokerAdapter;
-import org.opendaylight.controller.md.sal.common.api.data.AsyncTransaction;
-import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException;
-import org.opendaylight.controller.md.sal.common.api.data.TransactionChain;
 import org.opendaylight.controller.md.sal.binding.api.BindingTransactionChain;
 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
 import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
+import org.opendaylight.controller.md.sal.binding.impl.BindingDOMDataBrokerAdapter;
 import org.opendaylight.controller.md.sal.binding.impl.BindingToNormalizedNodeCodec;
+import org.opendaylight.controller.md.sal.common.api.data.AsyncTransaction;
 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.controller.md.sal.common.api.data.TransactionChain;
 import org.opendaylight.controller.md.sal.common.api.data.TransactionChainListener;
 import org.opendaylight.controller.md.sal.dom.api.DOMDataWriteTransaction;
 import org.opendaylight.controller.md.sal.dom.store.impl.InMemoryDOMDataStoreFactory;
@@ -52,15 +46,11 @@ import org.opendaylight.controller.sal.core.api.model.SchemaService;
 import org.opendaylight.controller.sal.core.spi.data.DOMStore;
 import org.opendaylight.netconf.sal.connect.netconf.listener.NetconfDeviceCapabilities;
 import org.opendaylight.netconf.sal.connect.util.RemoteDeviceId;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnector;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.NetconfNode;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.NetconfNodeConnectionStatus;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.NetconfNodeFields;
 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NetworkTopology;
-import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.TopologyId;
 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.Topology;
 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
-import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.NodeBuilder;
 import org.opendaylight.yangtools.binding.data.codec.gen.impl.DataObjectSerializerGenerator;
 import org.opendaylight.yangtools.binding.data.codec.gen.impl.StreamWriterGenerator;
 import org.opendaylight.yangtools.binding.data.codec.impl.BindingNormalizedNodeCodecRegistry;
@@ -289,4 +279,16 @@ public class NetconfDeviceTopologyAdapterTest {
         };
     }
 
+    @Test
+    public void testRemoveDeviceConfiguration() throws Exception {
+        doReturn(Futures.immediateCheckedFuture(null)).when(writeTx).submit();
+
+        NetconfDeviceTopologyAdapter adapter = new NetconfDeviceTopologyAdapter(id, txChain);
+        adapter.close();
+
+        verify(txChain, times(2)).newWriteOnlyTransaction();
+        verify(writeTx).delete(LogicalDatastoreType.OPERATIONAL, id.getTopologyBindingPath());
+        verify(writeTx, times(2)).submit();
+    }
+
 }
\ No newline at end of file
diff --git a/netconf/sal-netconf-connector/src/test/java/org/opendaylight/netconf/sal/connect/netconf/util/RemoteDeviceIdTest.java b/netconf/sal-netconf-connector/src/test/java/org/opendaylight/netconf/sal/connect/netconf/util/RemoteDeviceIdTest.java
new file mode 100644 (file)
index 0000000..02d3eea
--- /dev/null
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2016 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.netconf.sal.connect.netconf.util;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotEquals;
+
+import java.net.InetSocketAddress;
+import org.junit.Test;
+import org.opendaylight.controller.config.api.ModuleIdentifier;
+import org.opendaylight.netconf.sal.connect.util.RemoteDeviceId;
+
+public class RemoteDeviceIdTest {
+
+    @Test
+    public void testEquals() {
+        final InetSocketAddress address = new InetSocketAddress("127.0.0.1", 8000);
+        final ModuleIdentifier identifier = new ModuleIdentifier("test", "test");
+
+        final RemoteDeviceId remoteDeviceId = new RemoteDeviceId("test", address);
+        final RemoteDeviceId remoteDeviceIdEqualName = new RemoteDeviceId(identifier, address);
+        final RemoteDeviceId remoteDeviceIdDiffName = new RemoteDeviceId("test-diff", address);
+
+        assertEquals(true, remoteDeviceId.equals(remoteDeviceId));
+        assertEquals(false, remoteDeviceId.equals(this));
+        assertEquals(false, remoteDeviceId.equals(remoteDeviceIdDiffName));
+        assertEquals(true, remoteDeviceId.equals(remoteDeviceIdEqualName));
+    }
+
+    @Test
+    public void testHashCode() {
+        final String name = "name";
+        final InetSocketAddress address = new InetSocketAddress("127.0.0.1", 8000);
+        final RemoteDeviceId remoteDeviceId = new RemoteDeviceId(name, address);
+        final RemoteDeviceId remoteDeviceIdEqualName = new RemoteDeviceId(name, address);
+        final RemoteDeviceId remoteDeviceIdDiffName = new RemoteDeviceId("test-diff", address);
+
+        assertEquals(remoteDeviceIdEqualName.hashCode(), remoteDeviceId.hashCode());
+        assertNotEquals(remoteDeviceIdDiffName.hashCode(), remoteDeviceId.hashCode());
+    }
+}
index 2252252e110743de3f22f48b9a081cdd1da41e75..8c083399fc28ceac882d4d49ce13a0803fb04898 100644 (file)
             <groupId>org.slf4j</groupId>
             <artifactId>slf4j-api</artifactId>
         </dependency>
+        <dependency>
+            <groupId>org.powermock</groupId>
+            <artifactId>powermock-module-junit4</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.powermock</groupId>
+            <artifactId>powermock-api-mockito</artifactId>
+            <scope>test</scope>
+        </dependency>
     </dependencies>
 </project>
\ No newline at end of file
index 4e7b890e9a0f6a0132923904585fa58b5c6ff43b..f867971aea5051b9ba984025c48e687b2c6fe434 100644 (file)
@@ -15,10 +15,10 @@ import com.google.common.util.concurrent.CheckedFuture;
 import java.io.IOException;
 import org.opendaylight.yanglib.api.YangLibService;
 import org.opendaylight.yangtools.yang.model.repo.api.RevisionSourceIdentifier;
+import org.opendaylight.yangtools.yang.model.repo.api.SchemaRepository;
 import org.opendaylight.yangtools.yang.model.repo.api.SchemaSourceException;
 import org.opendaylight.yangtools.yang.model.repo.api.SourceIdentifier;
 import org.opendaylight.yangtools.yang.model.repo.api.YangTextSchemaSource;
-import org.opendaylight.yangtools.yang.parser.repo.SharedSchemaRepository;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -28,13 +28,13 @@ import org.slf4j.LoggerFactory;
 public class YangLibServiceImpl implements YangLibService {
     private static final Logger LOG = LoggerFactory.getLogger(YangLibServiceImpl.class);
 
-    private SharedSchemaRepository schemaRepository;
+    private SchemaRepository schemaRepository;
 
     public YangLibServiceImpl() {
 
     }
 
-    public void setSchemaRepository(final SharedSchemaRepository schemaRepository) {
+    public void setSchemaRepository(final SchemaRepository schemaRepository) {
         LOG.debug("Setting schema repository {}", schemaRepository);
         this.schemaRepository = schemaRepository;
     }
diff --git a/netconf/yanglib/src/test/java/org/opendaylight/yanglib/impl/YangLibRestAppTest.java b/netconf/yanglib/src/test/java/org/opendaylight/yanglib/impl/YangLibRestAppTest.java
new file mode 100644 (file)
index 0000000..bba2c29
--- /dev/null
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2016 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.yanglib.impl;
+
+import static junit.framework.TestCase.assertTrue;
+import static org.mockito.Matchers.any;
+import static org.mockito.Matchers.eq;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import java.util.Set;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.BDDMockito;
+import org.opendaylight.yanglib.api.YangLibRestAppService;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.FrameworkUtil;
+import org.powermock.api.mockito.PowerMockito;
+import org.powermock.core.classloader.annotations.PrepareForTest;
+import org.powermock.modules.junit4.PowerMockRunner;
+
+@RunWith(PowerMockRunner.class)
+@PrepareForTest(FrameworkUtil.class)
+public class YangLibRestAppTest {
+
+    @Test
+    public void testYangLibRestApp() {
+        PowerMockito.mockStatic(FrameworkUtil.class);
+
+        final BundleContext bundleContext = mock(BundleContext.class);
+        final Bundle bundle = mock(Bundle.class);
+
+        BDDMockito.given(FrameworkUtil.getBundle(any())).willReturn(bundle);
+        when(bundle.getBundleContext()).thenReturn(bundleContext);
+
+        final YangLibRestApp yangLibRestApp = new YangLibRestApp();
+        final Set singleton = yangLibRestApp.getSingletons();
+
+        assertTrue(singleton.contains(yangLibRestApp.getYangLibService()));
+
+        verify(bundleContext, times(1)).registerService(eq(YangLibRestAppService.class.getName()), eq(yangLibRestApp), eq(null));
+    }
+}
diff --git a/netconf/yanglib/src/test/java/org/opendaylight/yanglib/impl/YangLibServiceImplTest.java b/netconf/yanglib/src/test/java/org/opendaylight/yanglib/impl/YangLibServiceImplTest.java
new file mode 100644 (file)
index 0000000..add8d67
--- /dev/null
@@ -0,0 +1,64 @@
+/*
+ * Copyright (c) 2016 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.yanglib.impl;
+
+import static org.junit.Assert.assertEquals;
+import static org.mockito.Matchers.any;
+import static org.mockito.Matchers.eq;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.mock;
+
+import com.google.common.base.MoreObjects;
+import com.google.common.util.concurrent.CheckedFuture;
+import com.google.common.util.concurrent.Futures;
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import org.junit.Test;
+import org.opendaylight.yangtools.yang.model.repo.api.RevisionSourceIdentifier;
+import org.opendaylight.yangtools.yang.model.repo.api.SchemaRepository;
+import org.opendaylight.yangtools.yang.model.repo.api.SchemaSourceException;
+import org.opendaylight.yangtools.yang.model.repo.api.SourceIdentifier;
+import org.opendaylight.yangtools.yang.model.repo.api.YangTextSchemaSource;
+
+public class YangLibServiceImplTest {
+
+    private final static String TEST_OUTPUT_STRING = "hello world";
+
+    @Test
+    public void testSchema() throws SchemaSourceException {
+
+        final SchemaRepository schemaRepository = mock(SchemaRepository.class);
+        final YangLibServiceImpl yangLibService = new YangLibServiceImpl();
+        yangLibService.setSchemaRepository(schemaRepository);
+
+        final SourceIdentifier sourceIdentifier = RevisionSourceIdentifier.create("name", "2016-01-01");
+
+        final YangTextSchemaSource yangTextSchemaSource = new YangTextSchemaSource(sourceIdentifier) {
+            @Override
+            protected MoreObjects.ToStringHelper addToStringAttributes(MoreObjects.ToStringHelper toStringHelper) {
+                return null;
+            }
+
+            @Override
+            public InputStream openStream() throws IOException {
+                return new ByteArrayInputStream(TEST_OUTPUT_STRING.getBytes());
+            }
+        };
+
+        final CheckedFuture<YangTextSchemaSource, SchemaSourceException> sourceFuture =
+                Futures.immediateCheckedFuture(yangTextSchemaSource);
+        doReturn(sourceFuture).when(schemaRepository).getSchemaSource(any(SourceIdentifier.class),
+                eq(YangTextSchemaSource.class));
+
+        final String outputStream = yangLibService.getSchema("name", "2016-01-01");
+        assertEquals(TEST_OUTPUT_STRING, outputStream);
+    }
+
+}
diff --git a/pom.xml b/pom.xml
index 604a91ca0b4bbd61700746164d1bd7e327309a10..b7ff23ef51bf73de607daef39864e5008492229f 100644 (file)
--- a/pom.xml
+++ b/pom.xml
       </dependencies>
     </dependencyManagement>
 
-    <build>
-        <pluginManagement>
-            <plugins>
-                <plugin>
-                    <groupId>org.apache.maven.plugins</groupId>
-                    <artifactId>maven-checkstyle-plugin</artifactId>
-                    <dependencies>
-                        <dependency>
-                            <groupId>org.opendaylight.controller</groupId>
-                            <artifactId>checkstyle</artifactId>
-                            <version>0.4.0-SNAPSHOT</version>
-                        </dependency>
-                    </dependencies>
-                </plugin>
-            </plugins>
-        </pluginManagement>
-    </build>
-
     <profiles>
         <profile>
             <id>integrationtests</id>