Merge "Activate findbugs sonar profile"
authorTony Tkacik <ttkacik@cisco.com>
Mon, 15 Sep 2014 09:50:34 +0000 (09:50 +0000)
committerGerrit Code Review <gerrit@opendaylight.org>
Mon, 15 Sep 2014 09:50:34 +0000 (09:50 +0000)
31 files changed:
features/nsf/pom.xml
features/nsf/src/main/resources/features.xml
opendaylight/distribution/opendaylight-karaf-resources/src/main/resources/bin/setenv [new file with mode: 0755]
opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/broker/impl/AbstractDOMForwardedTransactionFactory.java
opendaylight/netconf/netconf-client/pom.xml
opendaylight/netconf/netconf-client/src/main/java/org/opendaylight/controller/netconf/client/NetconfClientSessionNegotiator.java
opendaylight/netconf/netconf-client/src/test/java/org/opendaylight/controller/netconf/client/NetconfClientConfigurationTest.java [new file with mode: 0644]
opendaylight/netconf/netconf-client/src/test/java/org/opendaylight/controller/netconf/client/NetconfClientDispatcherImplTest.java [new file with mode: 0644]
opendaylight/netconf/netconf-client/src/test/java/org/opendaylight/controller/netconf/client/NetconfClientSessionNegotiatorFactoryTest.java [new file with mode: 0644]
opendaylight/netconf/netconf-client/src/test/java/org/opendaylight/controller/netconf/client/NetconfClientSessionNegotiatorTest.java [new file with mode: 0644]
opendaylight/netconf/netconf-client/src/test/java/org/opendaylight/controller/netconf/client/NetconfClientSessionTest.java [new file with mode: 0644]
opendaylight/netconf/netconf-client/src/test/java/org/opendaylight/controller/netconf/client/NetconfReconnectingClientConfigurationTest.java [new file with mode: 0644]
opendaylight/netconf/netconf-client/src/test/java/org/opendaylight/controller/netconf/client/SimpleNetconfClientSessionListenerTest.java [new file with mode: 0644]
opendaylight/netconf/netconf-client/src/test/java/org/opendaylight/controller/netconf/client/SshClientChannelInitializerTest.java [new file with mode: 0644]
opendaylight/netconf/netconf-client/src/test/java/org/opendaylight/controller/netconf/client/TcpClientChannelInitializerTest.java [new file with mode: 0644]
opendaylight/netconf/netconf-client/src/test/java/org/opendaylight/controller/netconf/client/TestingNetconfClient.java [moved from opendaylight/netconf/netconf-client/src/test/java/org/opendaylight/controller/netconf/client/test/TestingNetconfClient.java with 92% similarity]
opendaylight/netconf/netconf-impl/src/test/java/org/opendaylight/controller/netconf/impl/ConcurrentClientsTest.java
opendaylight/netconf/netconf-it/src/test/java/org/opendaylight/controller/netconf/it/NetconfConfigPersisterITTest.java
opendaylight/netconf/netconf-it/src/test/java/org/opendaylight/controller/netconf/it/NetconfITMonitoringTest.java
opendaylight/netconf/netconf-it/src/test/java/org/opendaylight/controller/netconf/it/NetconfITSecureTest.java
opendaylight/netconf/netconf-it/src/test/java/org/opendaylight/controller/netconf/it/NetconfITTest.java
opendaylight/netconf/netconf-monitoring/src/test/java/org/opendaylight/controller/netconf/monitoring/xml/JaxBSerializerTest.java
opendaylight/netconf/netconf-netty-util/src/test/java/org/opendaylight/controller/netconf/nettyutil/handler/NetconfXMLToHelloMessageDecoderTest.java
opendaylight/netconf/netconf-ssh/src/test/java/org/opendaylight/controller/netconf/netty/SSHTest.java
opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/messages/NetconfHelloMessage.java
opendaylight/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/NeutronLoadBalancerPool.java
opendaylight/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/NeutronLoadBalancerPoolMember.java
opendaylight/northbound/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/northbound/NeutronLoadBalancerNorthbound.java
opendaylight/northbound/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/northbound/NeutronLoadBalancerPoolMemberRequest.java [moved from opendaylight/northbound/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/northbound/INeutronLoadBalancerPoolMemberRequest.java with 82% similarity]
opendaylight/northbound/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/northbound/NeutronLoadBalancerPoolMembersNorthbound.java
opendaylight/northbound/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/northbound/NeutronLoadBalancerPoolNorthbound.java

index 875ca2c..e677d49 100644 (file)
       <groupId>org.opendaylight.controller.thirdparty</groupId>
       <artifactId>net.sf.jung2</artifactId>
     </dependency>
+    <dependency>
+      <groupId>org.eclipse.persistence</groupId>
+      <artifactId>org.eclipse.persistence.antlr</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.eclipse.persistence</groupId>
+      <artifactId>org.eclipse.persistence.core</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.eclipse.persistence</groupId>
+      <artifactId>org.eclipse.persistence.moxy</artifactId>
+    </dependency>
   </dependencies>
   <build>
     <resources>
index 8dc51f1..e8f7bc1 100644 (file)
@@ -67,6 +67,9 @@
         <bundle>mvn:org.opendaylight.controller/flowprogrammer.northbound/${flowprogrammer.northbound.version}</bundle>
         <bundle>mvn:org.opendaylight.controller/hosttracker.northbound/${hosttracker.northbound.version}</bundle>
         <bundle>mvn:org.opendaylight.controller/networkconfig.bridgedomain.northbound/${networkconfig.bridgedomain.northbound.version}</bundle>
+        <bundle>mvn:org.eclipse.persistence/org.eclipse.persistence.antlr/${eclipse.persistence.version}</bundle>
+        <bundle>mvn:org.eclipse.persistence/org.eclipse.persistence.core/${eclipse.persistence.version}</bundle>
+        <bundle>mvn:org.eclipse.persistence/org.eclipse.persistence.moxy/${eclipse.persistence.version}</bundle>
         <bundle>mvn:org.opendaylight.controller/networkconfig.neutron.northbound/${networkconfig.neutron.northbound.version}</bundle>
         <bundle>mvn:org.opendaylight.controller/forwarding.staticrouting.northbound/${forwarding.staticrouting.northbound.version}</bundle>
         <bundle>mvn:org.opendaylight.controller/statistics.northbound/${statistics.northbound.version}</bundle>
diff --git a/opendaylight/distribution/opendaylight-karaf-resources/src/main/resources/bin/setenv b/opendaylight/distribution/opendaylight-karaf-resources/src/main/resources/bin/setenv
new file mode 100755 (executable)
index 0000000..4f24044
--- /dev/null
@@ -0,0 +1,55 @@
+#!/bin/sh
+#
+#    Licensed to the Apache Software Foundation (ASF) under one or more
+#    contributor license agreements.  See the NOTICE file distributed with
+#    this work for additional information regarding copyright ownership.
+#    The ASF licenses this file to You under the Apache License, Version 2.0
+#    (the "License"); you may not use this file except in compliance with
+#    the License.  You may obtain a copy of the License at
+#
+#       http://www.apache.org/licenses/LICENSE-2.0
+#
+#    Unless required by applicable law or agreed to in writing, software
+#    distributed under the License is distributed on an "AS IS" BASIS,
+#    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+#    See the License for the specific language governing permissions and
+#    limitations under the License.
+#
+
+#
+# handle specific scripts; the SCRIPT_NAME is exactly the name of the Karaf
+# script; for example karaf, start, stop, admin, client, ...
+#
+# if [ "$KARAF_SCRIPT" == "SCRIPT_NAME" ]; then
+#   Actions go here...
+# fi
+
+#
+# general settings which should be applied for all scripts go here; please keep
+# in mind that it is possible that scripts might be executed more than once, e.g.
+# in example of the start script where the start script is executed first and the
+# karaf script afterwards.
+#
+
+#
+# The following section shows the possible configuration options for the default 
+# karaf scripts
+#
+# export JAVA_HOME # Location of Java installation
+# export JAVA_MIN_MEM # Minimum memory for the JVM
+# export JAVA_MAX_MEM # Maximum memory for the JVM
+# export JAVA_PERM_MEM # Minimum perm memory for the JVM
+# export JAVA_MAX_PERM_MEM # Maximum perm memory for the JVM
+# export KARAF_HOME # Karaf home folder
+# export KARAF_DATA # Karaf data folder
+# export KARAF_BASE # Karaf base folder
+# export KARAF_ETC  # Karaf etc  folder
+# export KARAF_OPTS # Additional available Karaf options
+# export KARAF_DEBUG # Enable debug mode
+if [ "x$JAVA_MAX_PERM_MEM" == "x" ]; then
+    export JAVA_MAX_PERM_MEM="512m"
+fi
+if [ "x$JAVA_MAX_MEM" == "x" ]; then
+    export JAVA_MAX_MEM="2048m"
+fi
+
index 6838e39..8ef60a4 100644 (file)
@@ -212,8 +212,8 @@ abstract class AbstractDOMForwardedTransactionFactory<T extends DOMStoreTransact
 
     @Override
     public void close() {
-        final int wasClosed = UPDATER.getAndSet(this, 1);
-        Preconditions.checkState(wasClosed == 0, "Transaction factory was already closed");
+        final boolean success = UPDATER.compareAndSet(this, 0, 1);
+        Preconditions.checkState(success, "Transaction factory was already closed");
     }
-
 }
+
index bf27ed6..6bb67d0 100644 (file)
       <groupId>${project.groupId}</groupId>
       <artifactId>netconf-util</artifactId>
     </dependency>
+      <dependency>
+          <groupId>${project.groupId}</groupId>
+          <artifactId>netconf-util</artifactId>
+          <type>test-jar</type>
+          <scope>test</scope>
+      </dependency>
     <dependency>
       <groupId>com.google.guava</groupId>
       <artifactId>guava</artifactId>
       <groupId>org.slf4j</groupId>
       <artifactId>slf4j-api</artifactId>
     </dependency>
+      <dependency>
+          <groupId>org.opendaylight.yangtools</groupId>
+          <artifactId>mockito-configuration</artifactId>
+      </dependency>
   </dependencies>
 
   <build>
index e2ac49c..cbbee1f 100644 (file)
@@ -8,6 +8,7 @@
 
 package org.opendaylight.controller.netconf.client;
 
+import com.google.common.base.Preconditions;
 import com.google.common.collect.ImmutableList;
 
 import io.netty.channel.Channel;
@@ -70,8 +71,8 @@ public class NetconfClientSessionNegotiator extends
             logger.debug("Netconf session {} should use exi.", session);
             NetconfStartExiMessage startExiMessage = (NetconfStartExiMessage) sessionPreferences.getStartExiMessage();
             tryToInitiateExi(session, startExiMessage);
-        // Exi is not supported, release session immediately
         } else {
+            // Exi is not supported, release session immediately
             logger.debug("Netconf session {} isn't capable of using exi.", session);
             negotiationSuccessful(session);
         }
@@ -117,6 +118,7 @@ public class NetconfClientSessionNegotiator extends
 
     private long extractSessionId(final Document doc) {
         final Node sessionIdNode = (Node) XmlUtil.evaluateXPath(sessionIdXPath, doc, XPathConstants.NODE);
+        Preconditions.checkState(sessionIdNode != null, "");
         String textContent = sessionIdNode.getTextContent();
         if (textContent == null || textContent.equals("")) {
             throw new IllegalStateException("Session id not received from server");
diff --git a/opendaylight/netconf/netconf-client/src/test/java/org/opendaylight/controller/netconf/client/NetconfClientConfigurationTest.java b/opendaylight/netconf/netconf-client/src/test/java/org/opendaylight/controller/netconf/client/NetconfClientConfigurationTest.java
new file mode 100644 (file)
index 0000000..592cdad
--- /dev/null
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.netconf.client;
+
+import com.google.common.base.Optional;
+import org.junit.Assert;
+import org.junit.Test;
+import org.mockito.Mockito;
+import org.opendaylight.controller.netconf.client.NetconfClientSessionListener;
+import org.opendaylight.controller.netconf.client.SimpleNetconfClientSessionListener;
+import org.opendaylight.controller.netconf.client.conf.NetconfClientConfiguration;
+import org.opendaylight.controller.netconf.client.conf.NetconfClientConfigurationBuilder;
+import org.opendaylight.controller.netconf.nettyutil.handler.ssh.authentication.AuthenticationHandler;
+import org.opendaylight.controller.netconf.util.messages.NetconfHelloMessageAdditionalHeader;
+import org.opendaylight.protocol.framework.ReconnectStrategy;
+
+import java.net.InetSocketAddress;
+
+public class NetconfClientConfigurationTest {
+    @Test
+    public void testNetconfClientConfiguration() throws Exception {
+        Long timeout = 200L;
+        NetconfHelloMessageAdditionalHeader header = new NetconfHelloMessageAdditionalHeader("a", "host", "port", "trans", "id");
+        NetconfClientSessionListener listener = new SimpleNetconfClientSessionListener();
+        InetSocketAddress address = InetSocketAddress.createUnresolved("host", 830);
+        ReconnectStrategy strategy = Mockito.mock(ReconnectStrategy.class);
+        AuthenticationHandler handler = Mockito.mock(AuthenticationHandler.class);
+        NetconfClientConfiguration cfg = NetconfClientConfigurationBuilder.create().
+                withProtocol(NetconfClientConfiguration.NetconfClientProtocol.SSH).
+                withAddress(address).
+                withConnectionTimeoutMillis(timeout).
+                withReconnectStrategy(strategy).
+                withAdditionalHeader(header).
+                withSessionListener(listener).
+                withAuthHandler(handler).build();
+
+        Assert.assertEquals(timeout, cfg.getConnectionTimeoutMillis());
+        Assert.assertEquals(Optional.fromNullable(header), cfg.getAdditionalHeader());
+        Assert.assertEquals(listener, cfg.getSessionListener());
+        Assert.assertEquals(handler, cfg.getAuthHandler());
+        Assert.assertEquals(strategy, cfg.getReconnectStrategy());
+        Assert.assertEquals(NetconfClientConfiguration.NetconfClientProtocol.SSH, cfg.getProtocol());
+        Assert.assertEquals(address, cfg.getAddress());
+    }
+}
diff --git a/opendaylight/netconf/netconf-client/src/test/java/org/opendaylight/controller/netconf/client/NetconfClientDispatcherImplTest.java b/opendaylight/netconf/netconf-client/src/test/java/org/opendaylight/controller/netconf/client/NetconfClientDispatcherImplTest.java
new file mode 100644 (file)
index 0000000..5a2ec56
--- /dev/null
@@ -0,0 +1,104 @@
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.netconf.client;
+
+import io.netty.channel.Channel;
+import io.netty.channel.ChannelFuture;
+import io.netty.channel.ChannelPromise;
+import io.netty.channel.EventLoopGroup;
+import io.netty.util.HashedWheelTimer;
+import io.netty.util.Timer;
+import io.netty.util.concurrent.GenericFutureListener;
+import org.junit.Test;
+import org.mockito.Mockito;
+import org.opendaylight.controller.netconf.client.NetconfClientDispatcherImpl;
+import org.opendaylight.controller.netconf.client.NetconfClientSessionListener;
+import org.opendaylight.controller.netconf.client.SimpleNetconfClientSessionListener;
+import org.opendaylight.controller.netconf.client.conf.NetconfClientConfiguration;
+import org.opendaylight.controller.netconf.client.conf.NetconfClientConfigurationBuilder;
+import org.opendaylight.controller.netconf.client.conf.NetconfReconnectingClientConfiguration;
+import org.opendaylight.controller.netconf.client.conf.NetconfReconnectingClientConfigurationBuilder;
+import org.opendaylight.controller.netconf.nettyutil.handler.ssh.authentication.AuthenticationHandler;
+import org.opendaylight.controller.netconf.util.messages.NetconfHelloMessageAdditionalHeader;
+import org.opendaylight.protocol.framework.ReconnectStrategy;
+import org.opendaylight.protocol.framework.ReconnectStrategyFactory;
+
+import java.net.InetSocketAddress;
+import java.util.concurrent.Future;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.mockito.Matchers.any;
+import static org.mockito.Mockito.doReturn;
+
+public class NetconfClientDispatcherImplTest {
+    @Test
+    public void testNetconfClientDispatcherImpl() throws Exception {
+        EventLoopGroup bossGroup = Mockito.mock(EventLoopGroup.class);
+        EventLoopGroup workerGroup = Mockito.mock(EventLoopGroup.class);
+        Timer timer = new HashedWheelTimer();
+
+        ChannelFuture chf = Mockito.mock(ChannelFuture.class);
+        Channel ch = Mockito.mock(Channel.class);
+        doReturn(ch).when(chf).channel();
+        Throwable thr = Mockito.mock(Throwable.class);
+        doReturn(chf).when(workerGroup).register(any(Channel.class));
+
+        ChannelPromise promise = Mockito.mock(ChannelPromise.class);
+        doReturn(promise).when(chf).addListener(any(GenericFutureListener.class));
+        doReturn(thr).when(chf).cause();
+
+        Long timeout = 200L;
+        NetconfHelloMessageAdditionalHeader header = new NetconfHelloMessageAdditionalHeader("a", "host", "port", "trans", "id");
+        NetconfClientSessionListener listener = new SimpleNetconfClientSessionListener();
+        InetSocketAddress address = InetSocketAddress.createUnresolved("host", 830);
+        ReconnectStrategyFactory reconnectStrategyFactory = Mockito.mock(ReconnectStrategyFactory.class);
+        AuthenticationHandler handler = Mockito.mock(AuthenticationHandler.class);
+        ReconnectStrategy reconnect = Mockito.mock(ReconnectStrategy.class);
+
+        doReturn(5).when(reconnect).getConnectTimeout();
+        doReturn("").when(reconnect).toString();
+        doReturn("").when(handler).toString();
+        doReturn("").when(reconnectStrategyFactory).toString();
+        doReturn(reconnect).when(reconnectStrategyFactory).createReconnectStrategy();
+
+        NetconfReconnectingClientConfiguration cfg = NetconfReconnectingClientConfigurationBuilder.create().
+                withProtocol(NetconfClientConfiguration.NetconfClientProtocol.SSH).
+                withAddress(address).
+                withConnectionTimeoutMillis(timeout).
+                withReconnectStrategy(reconnect).
+                withAdditionalHeader(header).
+                withSessionListener(listener).
+                withConnectStrategyFactory(reconnectStrategyFactory).
+                withAuthHandler(handler).build();
+
+        NetconfReconnectingClientConfiguration cfg2 = NetconfReconnectingClientConfigurationBuilder.create().
+                withProtocol(NetconfClientConfiguration.NetconfClientProtocol.TCP).
+                withAddress(address).
+                withConnectionTimeoutMillis(timeout).
+                withReconnectStrategy(reconnect).
+                withAdditionalHeader(header).
+                withSessionListener(listener).
+                withConnectStrategyFactory(reconnectStrategyFactory).
+                withAuthHandler(handler).build();
+
+        NetconfClientDispatcherImpl dispatcher = new NetconfClientDispatcherImpl(bossGroup, workerGroup, timer);
+        Future<NetconfClientSession> sshSession = dispatcher.createClient(cfg);
+        Future<NetconfClientSession> tcpSession = dispatcher.createClient(cfg2);
+
+        Future<Void> sshReconn = dispatcher.createReconnectingClient(cfg);
+        Future<Void> tcpReconn = dispatcher.createReconnectingClient(cfg2);
+
+        assertNotNull(sshSession);
+        assertNotNull(tcpSession);
+        assertNotNull(sshReconn);
+        assertNotNull(tcpReconn);
+
+    }
+}
diff --git a/opendaylight/netconf/netconf-client/src/test/java/org/opendaylight/controller/netconf/client/NetconfClientSessionNegotiatorFactoryTest.java b/opendaylight/netconf/netconf-client/src/test/java/org/opendaylight/controller/netconf/client/NetconfClientSessionNegotiatorFactoryTest.java
new file mode 100644 (file)
index 0000000..0557a0c
--- /dev/null
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.netconf.client;
+
+import com.google.common.base.Optional;
+import io.netty.channel.Channel;
+import io.netty.util.HashedWheelTimer;
+import io.netty.util.Timer;
+import io.netty.util.concurrent.Promise;
+import org.apache.sshd.common.SessionListener;
+import org.junit.Test;
+import org.opendaylight.controller.netconf.util.messages.NetconfHelloMessageAdditionalHeader;
+import org.opendaylight.protocol.framework.SessionListenerFactory;
+import org.opendaylight.protocol.framework.SessionNegotiator;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.mock;
+
+public class NetconfClientSessionNegotiatorFactoryTest {
+    @Test
+    public void testGetSessionNegotiator() throws Exception {
+        NetconfClientSessionListener sessionListener = mock(NetconfClientSessionListener.class);
+        Timer timer = new HashedWheelTimer();
+        SessionListenerFactory listenerFactory = mock(SessionListenerFactory.class);
+        doReturn(sessionListener).when(listenerFactory).getSessionListener();
+
+        Channel channel = mock(Channel.class);
+        Promise promise = mock(Promise.class);
+        NetconfClientSessionNegotiatorFactory negotiatorFactory = new NetconfClientSessionNegotiatorFactory(timer,
+                Optional.<NetconfHelloMessageAdditionalHeader>absent(), 200L);
+
+        SessionNegotiator sessionNegotiator = negotiatorFactory.getSessionNegotiator(listenerFactory, channel, promise);
+        assertNotNull(sessionNegotiator);
+    }
+}
diff --git a/opendaylight/netconf/netconf-client/src/test/java/org/opendaylight/controller/netconf/client/NetconfClientSessionNegotiatorTest.java b/opendaylight/netconf/netconf-client/src/test/java/org/opendaylight/controller/netconf/client/NetconfClientSessionNegotiatorTest.java
new file mode 100644 (file)
index 0000000..333e9de
--- /dev/null
@@ -0,0 +1,155 @@
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.netconf.client;
+
+import com.google.common.base.Optional;
+import io.netty.channel.*;
+import io.netty.handler.ssl.SslHandler;
+import io.netty.util.HashedWheelTimer;
+import io.netty.util.concurrent.GenericFutureListener;
+import io.netty.util.concurrent.Promise;
+import org.apache.mina.handler.demux.ExceptionHandler;
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.Mockito;
+import org.mockito.internal.util.collections.Sets;
+import org.mockito.invocation.InvocationOnMock;
+import org.mockito.stubbing.Answer;
+import org.opendaylight.controller.netconf.api.NetconfClientSessionPreferences;
+import org.opendaylight.controller.netconf.api.NetconfMessage;
+import io.netty.util.Timer;
+import org.opendaylight.controller.netconf.nettyutil.handler.ChunkedFramingMechanismEncoder;
+import org.opendaylight.controller.netconf.nettyutil.handler.NetconfXMLToHelloMessageDecoder;
+import org.opendaylight.controller.netconf.nettyutil.handler.NetconfXMLToMessageDecoder;
+import org.opendaylight.controller.netconf.nettyutil.handler.exi.NetconfStartExiMessage;
+import org.opendaylight.controller.netconf.util.messages.NetconfHelloMessage;
+import org.opendaylight.controller.netconf.util.messages.NetconfHelloMessageAdditionalHeader;
+import org.opendaylight.controller.netconf.util.test.XmlFileLoader;
+import org.opendaylight.controller.netconf.util.xml.XmlUtil;
+import org.openexi.proc.common.EXIOptions;
+import org.w3c.dom.Document;
+import java.util.Set;
+import static org.mockito.Matchers.any;
+import static org.mockito.Matchers.anyObject;
+import static org.mockito.Matchers.anyString;
+import static org.mockito.Mockito.*;
+
+public class NetconfClientSessionNegotiatorTest {
+
+    private NetconfHelloMessage helloMessage;
+    private ChannelPipeline pipeline;
+    private ChannelFuture future;
+    private Channel channel;
+    private ChannelInboundHandlerAdapter channelInboundHandlerAdapter;
+
+    @Before
+    public void setUp() throws Exception {
+        helloMessage = NetconfHelloMessage.createClientHello(Sets.newSet("exi:1.0"), Optional.<NetconfHelloMessageAdditionalHeader>absent());
+        pipeline = mockChannelPipeline();
+        future = mockChannelFuture();
+        channel = mockChannel();
+        System.out.println("setup done");
+    }
+
+    private ChannelHandler mockChannelHandler() {
+        ChannelHandler handler = mock(ChannelHandler.class);
+        return handler;
+    }
+
+    private Channel mockChannel() {
+        Channel channel = mock(Channel.class);
+        ChannelHandler channelHandler = mockChannelHandler();
+        doReturn("").when(channel).toString();
+        doReturn(future).when(channel).close();
+        doReturn(future).when(channel).writeAndFlush(anyObject());
+        doReturn(true).when(channel).isOpen();
+        doReturn(pipeline).when(channel).pipeline();
+        doReturn("").when(pipeline).toString();
+        doReturn(pipeline).when(pipeline).remove(any(ChannelHandler.class));
+        doReturn(channelHandler).when(pipeline).remove(anyString());
+        return channel;
+    }
+
+    private ChannelFuture mockChannelFuture() {
+        ChannelFuture future = mock(ChannelFuture.class);
+        doReturn(future).when(future).addListener(any(GenericFutureListener.class));
+        return future;
+    }
+
+    private ChannelPipeline mockChannelPipeline() {
+        ChannelPipeline pipeline = mock(ChannelPipeline.class);
+        ChannelHandler handler = mock(ChannelHandler.class);
+        doReturn(pipeline).when(pipeline).addAfter(anyString(), anyString(), any(ChannelHandler.class));
+        doReturn(null).when(pipeline).get(SslHandler.class);
+        doReturn(pipeline).when(pipeline).addLast(anyString(), any(ChannelHandler.class));
+        doReturn(handler).when(pipeline).replace(anyString(), anyString(), any(ChunkedFramingMechanismEncoder.class));
+
+        NetconfXMLToHelloMessageDecoder messageDecoder = new NetconfXMLToHelloMessageDecoder();
+        doReturn(messageDecoder).when(pipeline).replace(anyString(), anyString(), any(NetconfXMLToMessageDecoder.class));
+        doReturn(pipeline).when(pipeline).replace(any(ChannelHandler.class), anyString(), any(NetconfClientSession.class));
+        return pipeline;
+    }
+
+    private NetconfClientSessionNegotiator createNetconfClientSessionNegotiator(Promise promise,
+                                                                                NetconfMessage startExi) {
+        ChannelProgressivePromise progressivePromise = mock(ChannelProgressivePromise.class);
+        NetconfClientSessionPreferences preferences = new NetconfClientSessionPreferences(helloMessage, startExi);
+        doReturn(progressivePromise).when(promise).setFailure(any(Throwable.class));
+
+        long timeout = 10L;
+        NetconfClientSessionListener sessionListener = mock(NetconfClientSessionListener.class);
+        Timer timer = new HashedWheelTimer();
+        return new NetconfClientSessionNegotiator(preferences, promise, channel, timer, sessionListener, timeout);
+    }
+
+    @Test
+    public void testNetconfClientSessionNegotiator() throws Exception {
+        Promise promise = mock(Promise.class);
+        doReturn(promise).when(promise).setSuccess(anyObject());
+        NetconfClientSessionNegotiator negotiator = createNetconfClientSessionNegotiator(promise, null);
+
+        negotiator.channelActive(null);
+        Set caps = Sets.newSet("a", "b");
+        NetconfHelloMessage helloServerMessage = NetconfHelloMessage.createServerHello(caps, 10);
+        negotiator.handleMessage(helloServerMessage);
+        verify(promise).setSuccess(anyObject());
+    }
+
+    @Test
+    public void testNetconfClientSessionNegotiatorWithEXI() throws Exception {
+        Promise promise = mock(Promise.class);
+        EXIOptions exiOptions = new EXIOptions();
+        NetconfStartExiMessage exiMessage = NetconfStartExiMessage.create(exiOptions, "msg-id");
+        doReturn(promise).when(promise).setSuccess(anyObject());
+        NetconfClientSessionNegotiator negotiator = createNetconfClientSessionNegotiator(promise, exiMessage);
+
+        negotiator.channelActive(null);
+        Set caps = Sets.newSet("exi:1.0");
+        NetconfHelloMessage helloMessage = NetconfHelloMessage.createServerHello(caps, 10);
+
+        doAnswer(new Answer() {
+            @Override
+            public Object answer(InvocationOnMock invocationOnMock) throws Throwable {
+                channelInboundHandlerAdapter = ((ChannelInboundHandlerAdapter) invocationOnMock.getArguments()[2]);
+                return null;
+            }
+        }).when(pipeline).addAfter(anyString(), anyString(), any(ChannelHandler.class));
+
+        ChannelHandlerContext handlerContext = mock(ChannelHandlerContext.class);
+        doReturn(pipeline).when(handlerContext).pipeline();
+        negotiator.handleMessage(helloMessage);
+        Document expectedResult = XmlFileLoader.xmlFileToDocument("netconfMessages/rpc-reply_ok.xml");
+        channelInboundHandlerAdapter.channelRead(handlerContext, new NetconfMessage(expectedResult));
+
+        verify(promise).setSuccess(anyObject());
+
+        // two calls for exiMessage, 2 for hello message
+        verify(pipeline, times(4)).replace(anyString(), anyString(), any(ChannelHandler.class));
+    }
+}
diff --git a/opendaylight/netconf/netconf-client/src/test/java/org/opendaylight/controller/netconf/client/NetconfClientSessionTest.java b/opendaylight/netconf/netconf-client/src/test/java/org/opendaylight/controller/netconf/client/NetconfClientSessionTest.java
new file mode 100644 (file)
index 0000000..4175190
--- /dev/null
@@ -0,0 +1,69 @@
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.netconf.client;
+
+import com.google.common.collect.Lists;
+import io.netty.channel.Channel;
+import io.netty.channel.ChannelHandler;
+import io.netty.channel.ChannelPipeline;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.Mock;
+import org.mockito.Mockito;
+import org.mockito.MockitoAnnotations;
+import org.opendaylight.controller.netconf.client.NetconfClientSession;
+import org.opendaylight.controller.netconf.client.NetconfClientSessionListener;
+import org.opendaylight.controller.netconf.nettyutil.handler.NetconfEXICodec;
+import org.openexi.proc.common.EXIOptions;
+
+import java.util.ArrayList;
+import java.util.Collection;
+
+import static org.junit.Assert.assertEquals;
+import static org.mockito.Matchers.any;
+import static org.mockito.Matchers.anyString;
+import static org.mockito.Mockito.mock;
+
+public class NetconfClientSessionTest {
+
+    @Mock
+    ChannelHandler channelHandler;
+
+    @Mock
+    Channel channel;
+
+    @Before
+    public void setUp() throws Exception {
+        MockitoAnnotations.initMocks(this);
+    }
+
+    @Test
+    public void testNetconfClientSession() throws Exception {
+        NetconfClientSessionListener sessionListener = mock(NetconfClientSessionListener.class);
+        long sessId = 20L;
+        Collection<String> caps = Lists.newArrayList("cap1", "cap2");
+
+        NetconfEXICodec codec = new NetconfEXICodec(new EXIOptions());
+        ChannelPipeline pipeline = mock(ChannelPipeline.class);
+
+        Mockito.doReturn(pipeline).when(channel).pipeline();
+        Mockito.doReturn(channelHandler).when(pipeline).replace(anyString(), anyString(), any(ChannelHandler.class));
+        Mockito.doReturn("").when(channelHandler).toString();
+
+        NetconfClientSession session = new NetconfClientSession(sessionListener, channel, sessId, caps);
+        session.addExiHandlers(codec);
+        session.stopExiCommunication();
+
+        assertEquals(caps, session.getServerCapabilities());
+        assertEquals(session, session.thisInstance());
+
+        Mockito.verify(pipeline, Mockito.times(4)).replace(anyString(), anyString(), Mockito.any(ChannelHandler.class));
+    }
+}
diff --git a/opendaylight/netconf/netconf-client/src/test/java/org/opendaylight/controller/netconf/client/NetconfReconnectingClientConfigurationTest.java b/opendaylight/netconf/netconf-client/src/test/java/org/opendaylight/controller/netconf/client/NetconfReconnectingClientConfigurationTest.java
new file mode 100644 (file)
index 0000000..e79a370
--- /dev/null
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.netconf.client;
+
+import com.google.common.base.Optional;
+import org.junit.Assert;
+import org.junit.Test;
+import org.mockito.Mockito;
+import org.opendaylight.controller.config.yang.protocol.framework.NeverReconnectStrategyFactoryModule;
+import org.opendaylight.controller.netconf.client.NetconfClientSessionListener;
+import org.opendaylight.controller.netconf.client.SimpleNetconfClientSessionListener;
+import org.opendaylight.controller.netconf.client.conf.NetconfClientConfiguration;
+import org.opendaylight.controller.netconf.client.conf.NetconfReconnectingClientConfiguration;
+import org.opendaylight.controller.netconf.client.conf.NetconfReconnectingClientConfigurationBuilder;
+import org.opendaylight.controller.netconf.nettyutil.handler.ssh.authentication.AuthenticationHandler;
+import org.opendaylight.controller.netconf.util.messages.NetconfHelloMessageAdditionalHeader;
+import org.opendaylight.protocol.framework.ReconnectStrategy;
+import org.opendaylight.protocol.framework.ReconnectStrategyFactory;
+
+import java.net.InetSocketAddress;
+
+public class NetconfReconnectingClientConfigurationTest {
+    @Test
+    public void testNetconfReconnectingClientConfiguration() throws Exception {
+        Long timeout = 200L;
+        NetconfHelloMessageAdditionalHeader header = new NetconfHelloMessageAdditionalHeader("a", "host", "port", "trans", "id");
+        NetconfClientSessionListener listener = new SimpleNetconfClientSessionListener();
+        InetSocketAddress address = InetSocketAddress.createUnresolved("host", 830);
+        ReconnectStrategyFactory strategy = Mockito.mock(ReconnectStrategyFactory.class);
+        AuthenticationHandler handler = Mockito.mock(AuthenticationHandler.class);
+        ReconnectStrategy reconnect = Mockito.mock(ReconnectStrategy.class);
+
+        NetconfReconnectingClientConfiguration cfg = NetconfReconnectingClientConfigurationBuilder.create().
+                withProtocol(NetconfClientConfiguration.NetconfClientProtocol.SSH).
+                withAddress(address).
+                withConnectionTimeoutMillis(timeout).
+                withReconnectStrategy(reconnect).
+                withAdditionalHeader(header).
+                withSessionListener(listener).
+                withConnectStrategyFactory(strategy).
+                withAuthHandler(handler).build();
+
+        Assert.assertEquals(timeout, cfg.getConnectionTimeoutMillis());
+        Assert.assertEquals(Optional.fromNullable(header), cfg.getAdditionalHeader());
+        Assert.assertEquals(listener, cfg.getSessionListener());
+        Assert.assertEquals(handler, cfg.getAuthHandler());
+        Assert.assertEquals(strategy, cfg.getConnectStrategyFactory());
+        Assert.assertEquals(NetconfClientConfiguration.NetconfClientProtocol.SSH, cfg.getProtocol());
+        Assert.assertEquals(address, cfg.getAddress());
+        Assert.assertEquals(reconnect, cfg.getReconnectStrategy());
+    }
+}
diff --git a/opendaylight/netconf/netconf-client/src/test/java/org/opendaylight/controller/netconf/client/SimpleNetconfClientSessionListenerTest.java b/opendaylight/netconf/netconf-client/src/test/java/org/opendaylight/controller/netconf/client/SimpleNetconfClientSessionListenerTest.java
new file mode 100644 (file)
index 0000000..e067cc2
--- /dev/null
@@ -0,0 +1,79 @@
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.netconf.client;
+import io.netty.channel.*;
+import io.netty.util.concurrent.Future;
+import io.netty.util.concurrent.Promise;
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.internal.util.collections.Sets;
+import org.opendaylight.controller.netconf.api.NetconfMessage;
+import org.opendaylight.controller.netconf.util.messages.NetconfHelloMessage;
+
+import java.util.Set;
+
+import static org.junit.Assert.*;
+import static org.mockito.Matchers.anyObject;
+import static org.mockito.Mockito.*;
+
+public class SimpleNetconfClientSessionListenerTest {
+
+    private Channel channel;
+    private ChannelFuture channelFuture;
+    Set caps;
+    private NetconfHelloMessage helloMessage;
+    private NetconfMessage message;
+    private NetconfClientSessionListener sessionListener;
+    private NetconfClientSession clientSession;
+
+    @Before
+    public void setUp() throws Exception {
+        channel = mock(Channel.class);
+        channelFuture = mock(ChannelFuture.class);
+        doReturn(channelFuture).when(channel).writeAndFlush(anyObject());
+        caps = Sets.newSet("a", "b");
+        helloMessage = NetconfHelloMessage.createServerHello(caps, 10);
+        message = new NetconfMessage(helloMessage.getDocument());
+        sessionListener = mock(NetconfClientSessionListener.class);
+        clientSession = new NetconfClientSession(sessionListener, channel, 20L, caps);
+    }
+
+    @Test
+    public void testSessionDown() throws Exception {
+        SimpleNetconfClientSessionListener simpleListener = new SimpleNetconfClientSessionListener();
+        Future<NetconfMessage> promise = simpleListener.sendRequest(message);
+        simpleListener.onSessionUp(clientSession);
+        verify(channel, times(1)).writeAndFlush(anyObject());
+
+        simpleListener.onSessionDown(clientSession, new Exception());
+        assertFalse(promise.isSuccess());
+    }
+
+    @Test
+    public void testSendRequest() throws Exception {
+        SimpleNetconfClientSessionListener simpleListener = new SimpleNetconfClientSessionListener();
+        Future<NetconfMessage> promise = simpleListener.sendRequest(message);
+        simpleListener.onSessionUp(clientSession);
+        verify(channel, times(1)).writeAndFlush(anyObject());
+
+        simpleListener.sendRequest(message);
+        assertFalse(promise.isSuccess());
+    }
+
+    @Test
+    public void testOnMessage() throws Exception {
+        SimpleNetconfClientSessionListener simpleListener = new SimpleNetconfClientSessionListener();
+        Future<NetconfMessage> promise = simpleListener.sendRequest(message);
+        simpleListener.onSessionUp(clientSession);
+        verify(channel, times(1)).writeAndFlush(anyObject());
+
+        simpleListener.onMessage(clientSession, message);
+        assertTrue(promise.isSuccess());
+    }
+}
diff --git a/opendaylight/netconf/netconf-client/src/test/java/org/opendaylight/controller/netconf/client/SshClientChannelInitializerTest.java b/opendaylight/netconf/netconf-client/src/test/java/org/opendaylight/controller/netconf/client/SshClientChannelInitializerTest.java
new file mode 100644 (file)
index 0000000..0830c29
--- /dev/null
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.netconf.client;
+
+import io.netty.channel.Channel;
+import io.netty.channel.ChannelHandler;
+import io.netty.channel.ChannelPipeline;
+import io.netty.util.concurrent.Promise;
+import org.junit.Test;
+import org.opendaylight.controller.netconf.nettyutil.handler.ssh.authentication.AuthenticationHandler;
+import org.opendaylight.protocol.framework.SessionListenerFactory;
+import org.opendaylight.protocol.framework.SessionNegotiator;
+
+import static org.mockito.Matchers.any;
+import static org.mockito.Matchers.anyString;
+import static org.mockito.Mockito.*;
+
+public class SshClientChannelInitializerTest {
+    @Test
+    public void test() throws Exception {
+
+        AuthenticationHandler authenticationHandler = mock(AuthenticationHandler.class);
+        NetconfClientSessionNegotiatorFactory negotiatorFactory = mock(NetconfClientSessionNegotiatorFactory.class);
+        NetconfClientSessionListener sessionListener = mock(NetconfClientSessionListener.class);
+
+        SessionNegotiator sessionNegotiator = mock(SessionNegotiator.class);
+        doReturn("").when(sessionNegotiator).toString();
+        doReturn(sessionNegotiator).when(negotiatorFactory).getSessionNegotiator(any(SessionListenerFactory.class), any(Channel.class), any(Promise.class));
+        ChannelPipeline pipeline = mock(ChannelPipeline.class);
+        doReturn(pipeline).when(pipeline).addAfter(anyString(), anyString(), any(ChannelHandler.class));
+        Channel channel = mock(Channel.class);
+        doReturn(pipeline).when(channel).pipeline();
+        doReturn("").when(channel).toString();
+        doReturn(pipeline).when(pipeline).addFirst(any(ChannelHandler.class));
+        doReturn(pipeline).when(pipeline).addLast(anyString(), any(ChannelHandler.class));
+
+        Promise<NetconfClientSession> promise = mock(Promise.class);
+        doReturn("").when(promise).toString();
+
+        SshClientChannelInitializer initializer = new SshClientChannelInitializer(authenticationHandler, negotiatorFactory,
+                sessionListener);
+        initializer.initialize(channel, promise);
+        verify(pipeline, times(1)).addFirst(any(ChannelHandler.class));
+    }
+}
diff --git a/opendaylight/netconf/netconf-client/src/test/java/org/opendaylight/controller/netconf/client/TcpClientChannelInitializerTest.java b/opendaylight/netconf/netconf-client/src/test/java/org/opendaylight/controller/netconf/client/TcpClientChannelInitializerTest.java
new file mode 100644 (file)
index 0000000..e355cf4
--- /dev/null
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.netconf.client;
+
+import io.netty.channel.Channel;
+import io.netty.channel.ChannelHandler;
+import io.netty.channel.ChannelPipeline;
+import io.netty.util.concurrent.Promise;
+import org.junit.Test;
+import org.opendaylight.controller.netconf.nettyutil.AbstractChannelInitializer;
+import org.opendaylight.protocol.framework.SessionListenerFactory;
+import org.opendaylight.protocol.framework.SessionNegotiator;
+
+import static org.mockito.Mockito.*;
+
+public class TcpClientChannelInitializerTest {
+    @Test
+    public void testInitializeSessionNegotiator() throws Exception {
+        NetconfClientSessionNegotiatorFactory factory = mock(NetconfClientSessionNegotiatorFactory.class);
+        SessionNegotiator sessionNegotiator = mock(SessionNegotiator.class);
+        doReturn("").when(sessionNegotiator).toString();
+        doReturn(sessionNegotiator).when(factory).getSessionNegotiator(any(SessionListenerFactory.class), any(Channel.class), any(Promise.class));
+        NetconfClientSessionListener listener = mock(NetconfClientSessionListener.class);
+        TcpClientChannelInitializer initializer = new TcpClientChannelInitializer(factory, listener);
+        ChannelPipeline pipeline = mock(ChannelPipeline.class);
+        doReturn(pipeline).when(pipeline).addAfter(anyString(), anyString(), any(ChannelHandler.class));
+        Channel channel = mock(Channel.class);
+        doReturn(pipeline).when(channel).pipeline();
+        doReturn("").when(channel).toString();
+
+        Promise<NetconfClientSession> promise = mock(Promise.class);
+        doReturn("").when(promise).toString();
+
+        initializer.initializeSessionNegotiator(channel, promise);
+        verify(pipeline, times(1)).addAfter(anyString(), anyString(), any(ChannelHandler.class));
+    }
+}
@@ -6,7 +6,7 @@
  * and is available at http://www.eclipse.org/legal/epl-v10.html
  */
 
-package org.opendaylight.controller.netconf.client.test;
+package org.opendaylight.controller.netconf.client;
 
 import com.google.common.base.Optional;
 import com.google.common.base.Preconditions;
@@ -26,11 +26,6 @@ import java.util.concurrent.ExecutionException;
 import java.util.concurrent.TimeUnit;
 import java.util.concurrent.TimeoutException;
 import org.opendaylight.controller.netconf.api.NetconfMessage;
-import org.opendaylight.controller.netconf.client.NetconfClientDispatcher;
-import org.opendaylight.controller.netconf.client.NetconfClientDispatcherImpl;
-import org.opendaylight.controller.netconf.client.NetconfClientSession;
-import org.opendaylight.controller.netconf.client.NetconfClientSessionListener;
-import org.opendaylight.controller.netconf.client.SimpleNetconfClientSessionListener;
 import org.opendaylight.controller.netconf.client.conf.NetconfClientConfiguration;
 import org.opendaylight.controller.netconf.client.conf.NetconfClientConfiguration.NetconfClientProtocol;
 import org.opendaylight.controller.netconf.client.conf.NetconfClientConfigurationBuilder;
index c5281d0..5f8bc06 100644 (file)
@@ -59,7 +59,7 @@ import org.opendaylight.controller.netconf.client.NetconfClientDispatcherImpl;
 import org.opendaylight.controller.netconf.client.SimpleNetconfClientSessionListener;
 import org.opendaylight.controller.netconf.client.conf.NetconfClientConfiguration;
 import org.opendaylight.controller.netconf.client.conf.NetconfClientConfigurationBuilder;
-import org.opendaylight.controller.netconf.client.test.TestingNetconfClient;
+import org.opendaylight.controller.netconf.client.TestingNetconfClient;
 import org.opendaylight.controller.netconf.impl.osgi.NetconfOperationServiceFactoryListenerImpl;
 import org.opendaylight.controller.netconf.impl.osgi.SessionMonitoringService;
 import org.opendaylight.controller.netconf.mapping.api.Capability;
index 4b49c09..d8eb841 100644 (file)
@@ -36,7 +36,7 @@ import org.opendaylight.controller.config.persist.api.ConfigSnapshotHolder;
 import org.opendaylight.controller.config.persist.api.Persister;
 import org.opendaylight.controller.netconf.api.NetconfMessage;
 import org.opendaylight.controller.netconf.api.jmx.CommitJMXNotification;
-import org.opendaylight.controller.netconf.client.test.TestingNetconfClient;
+import org.opendaylight.controller.netconf.client.TestingNetconfClient;
 import org.opendaylight.controller.netconf.impl.DefaultCommitNotificationProducer;
 import org.opendaylight.controller.netconf.impl.osgi.NetconfMonitoringServiceImpl;
 import org.opendaylight.controller.netconf.impl.osgi.NetconfOperationServiceSnapshotImpl;
index 72a2f8f..a9558c0 100644 (file)
@@ -28,7 +28,7 @@ import java.util.Set;
 import org.junit.Test;
 import org.opendaylight.controller.netconf.api.NetconfMessage;
 import org.opendaylight.controller.netconf.api.monitoring.NetconfManagementSession;
-import org.opendaylight.controller.netconf.client.test.TestingNetconfClient;
+import org.opendaylight.controller.netconf.client.TestingNetconfClient;
 import org.opendaylight.controller.netconf.impl.osgi.NetconfMonitoringServiceImpl;
 import org.opendaylight.controller.netconf.impl.osgi.NetconfOperationServiceSnapshotImpl;
 import org.opendaylight.controller.netconf.impl.osgi.SessionMonitoringService;
index 67ccf0c..4fe5f2a 100644 (file)
@@ -34,7 +34,7 @@ import org.opendaylight.controller.netconf.client.NetconfClientDispatcherImpl;
 import org.opendaylight.controller.netconf.client.SimpleNetconfClientSessionListener;
 import org.opendaylight.controller.netconf.client.conf.NetconfClientConfiguration;
 import org.opendaylight.controller.netconf.client.conf.NetconfClientConfigurationBuilder;
-import org.opendaylight.controller.netconf.client.test.TestingNetconfClient;
+import org.opendaylight.controller.netconf.client.TestingNetconfClient;
 import org.opendaylight.controller.netconf.nettyutil.handler.ssh.authentication.AuthenticationHandler;
 import org.opendaylight.controller.netconf.nettyutil.handler.ssh.authentication.LoginPassword;
 import org.opendaylight.controller.netconf.ssh.NetconfSSHServer;
index a7a9d74..4c07308 100644 (file)
@@ -41,7 +41,7 @@ import org.opendaylight.controller.config.yang.test.impl.NetconfTestImplModuleMX
 import org.opendaylight.controller.netconf.api.NetconfDocumentedException;
 import org.opendaylight.controller.netconf.api.NetconfMessage;
 import org.opendaylight.controller.netconf.client.NetconfClientDispatcher;
-import org.opendaylight.controller.netconf.client.test.TestingNetconfClient;
+import org.opendaylight.controller.netconf.client.TestingNetconfClient;
 import org.opendaylight.controller.netconf.util.test.XmlFileLoader;
 import org.opendaylight.controller.netconf.util.xml.XmlElement;
 import org.opendaylight.controller.netconf.util.xml.XmlUtil;
index d0d587f..08441b4 100644 (file)
@@ -38,7 +38,7 @@ import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.
 public class JaxBSerializerTest {
 
     @Test
-    public void testName() throws Exception {
+    public void testSerialization() throws Exception {
 
         final NetconfMonitoringService service = new NetconfMonitoringService() {
 
@@ -53,29 +53,29 @@ public class JaxBSerializerTest {
             }
         };
         final NetconfState model = new NetconfState(service);
-        final String xml = XmlUtil.toString(new JaxBSerializer().toXml(model));
+        final String xml = XmlUtil.toString(new JaxBSerializer().toXml(model)).replaceAll("\\s", "");
 
         assertThat(xml, CoreMatchers.containsString(
-                "<schema>\n" +
-                "<format>yang</format>\n" +
-                "<identifier>id</identifier>\n" +
-                "<location>NETCONF</location>\n" +
-                "<namespace>localhost</namespace>\n" +
-                "<version>v1</version>\n" +
-                "</schema>\n"));
+                "<schema>" +
+                "<format>yang</format>" +
+                "<identifier>id</identifier>" +
+                "<location>NETCONF</location>" +
+                "<namespace>localhost</namespace>" +
+                "<version>v1</version>" +
+                "</schema>"));
 
         assertThat(xml, CoreMatchers.containsString(
-                "<session>\n" +
-                "<session-id>1</session-id>\n" +
-                "<in-bad-rpcs>0</in-bad-rpcs>\n" +
-                "<in-rpcs>0</in-rpcs>\n" +
-                "<login-time>loginTime</login-time>\n" +
-                "<out-notifications>0</out-notifications>\n" +
-                "<out-rpc-errors>0</out-rpc-errors>\n" +
-                "<ncme:session-identifier>client</ncme:session-identifier>\n" +
-                "<source-host>address/port</source-host>\n" +
-                "<transport>ncme:netconf-tcp</transport>\n" +
-                "<username>username</username>\n" +
+                "<session>" +
+                "<session-id>1</session-id>" +
+                "<in-bad-rpcs>0</in-bad-rpcs>" +
+                "<in-rpcs>0</in-rpcs>" +
+                "<login-time>loginTime</login-time>" +
+                "<out-notifications>0</out-notifications>" +
+                "<out-rpc-errors>0</out-rpc-errors>" +
+                "<ncme:session-identifier>client</ncme:session-identifier>" +
+                "<source-host>address/port</source-host>" +
+                "<transport>ncme:netconf-tcp</transport>" +
+                "<username>username</username>" +
                 "</session>"));
     }
 
index f0c0d63..ac63706 100644 (file)
@@ -36,7 +36,7 @@ public class NetconfXMLToHelloMessageDecoderTest {
         assertThat(out.get(0), CoreMatchers.instanceOf(NetconfHelloMessage.class));
         final NetconfHelloMessage hello = (NetconfHelloMessage) out.get(0);
         assertTrue(hello.getAdditionalHeader().isPresent());
-        assertEquals("[tomas;10.0.0.0:10000;tcp;client;]\n", hello.getAdditionalHeader().get().toFormattedString());
+        assertEquals("[tomas;10.0.0.0:10000;tcp;client;]" + System.lineSeparator(), hello.getAdditionalHeader().get().toFormattedString());
         assertThat(XmlUtil.toString(hello.getDocument()), CoreMatchers.containsString("<hello xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\""));
     }
 
index ce1400b..eb2b644 100644 (file)
@@ -67,7 +67,9 @@ public class SSHTest {
         netconfSSHServer.setAuthProvider(authProvider);
 
         InetSocketAddress address = netconfSSHServer.getLocalSocketAddress();
-        final EchoClientHandler echoClientHandler = connectClient(address);
+
+        final EchoClientHandler echoClientHandler = connectClient(new InetSocketAddress("localhost", address.getPort()));
+
         Stopwatch stopwatch = new Stopwatch().start();
         while(echoClientHandler.isConnected() == false && stopwatch.elapsed(TimeUnit.SECONDS) < 5) {
             Thread.sleep(100);
index 33934d1..15223cb 100644 (file)
@@ -64,10 +64,12 @@ public final class NetconfHelloMessage extends NetconfMessage {
         Document doc = XmlUtil.newDocument();
         Element helloElement = doc.createElementNS(XmlNetconfConstants.URN_IETF_PARAMS_XML_NS_NETCONF_BASE_1_0,
                 HELLO_TAG);
-        Element capabilitiesElement = doc.createElement(XmlNetconfConstants.CAPABILITIES);
+        Element capabilitiesElement = doc.createElementNS(XmlNetconfConstants.URN_IETF_PARAMS_XML_NS_NETCONF_BASE_1_0,
+                XmlNetconfConstants.CAPABILITIES);
 
         for (String capability : Sets.newHashSet(capabilities)) {
-            Element capElement = doc.createElement(XmlNetconfConstants.CAPABILITY);
+            Element capElement = doc.createElementNS(XmlNetconfConstants.URN_IETF_PARAMS_XML_NS_NETCONF_BASE_1_0,
+                    XmlNetconfConstants.CAPABILITY);
             capElement.setTextContent(capability);
             capabilitiesElement.appendChild(capElement);
         }
@@ -80,7 +82,8 @@ public final class NetconfHelloMessage extends NetconfMessage {
 
     public static NetconfHelloMessage createServerHello(Set<String> capabilities, long sessionId) throws NetconfDocumentedException {
         Document doc = createHelloMessageDoc(capabilities);
-        Element sessionIdElement = doc.createElement(XmlNetconfConstants.SESSION_ID);
+        Element sessionIdElement = doc.createElementNS(XmlNetconfConstants.URN_IETF_PARAMS_XML_NS_NETCONF_BASE_1_0,
+                XmlNetconfConstants.SESSION_ID);
         sessionIdElement.setTextContent(Long.toString(sessionId));
         doc.getDocumentElement().appendChild(sessionIdElement);
         return new NetconfHelloMessage(doc);
index 12c80fe..a2df680 100644 (file)
@@ -14,8 +14,8 @@ import javax.xml.bind.annotation.XmlAccessType;
 import javax.xml.bind.annotation.XmlAccessorType;
 import javax.xml.bind.annotation.XmlElement;
 import javax.xml.bind.annotation.XmlRootElement;
+//import javax.xml.bind.annotation.XmlElementWrapper;
 import java.io.Serializable;
-import java.util.HashMap;
 import java.util.Iterator;
 import java.util.List;
 
@@ -34,7 +34,7 @@ import java.util.List;
  * healthmonitor_id   String
  * admin_state_up     Bool
  * status             String
- * members            List <String>
+ * members            List <NeutronLoadBalancerPoolMember>
  * http://docs.openstack.org/api/openstack-network/2.0/openstack-network.pdf
  */
 
@@ -71,13 +71,10 @@ public class NeutronLoadBalancerPool extends ConfigurationObject implements Seri
     @XmlElement (name="status")
     String loadBalancerPoolStatus;
 
-    @XmlElement (name="members")
-    List loadBalancerPoolMembers;
-
-    HashMap<String, NeutronLoadBalancerPoolMember> member;
+    @XmlElement(name="members")
+    List<NeutronLoadBalancerPoolMember> loadBalancerPoolMembers;
 
     public NeutronLoadBalancerPool() {
-        member = new HashMap<String, NeutronLoadBalancerPoolMember>();
     }
 
     public String getLoadBalancerPoolID() {
@@ -152,14 +149,27 @@ public class NeutronLoadBalancerPool extends ConfigurationObject implements Seri
         this.loadBalancerPoolStatus = loadBalancerPoolStatus;
     }
 
-    public List getLoadBalancerPoolMembers() {
+    public List<NeutronLoadBalancerPoolMember> getLoadBalancerPoolMembers() {
+        /*
+         * Update the pool_id of the member to that this.loadBalancerPoolID
+         */
+        for (NeutronLoadBalancerPoolMember member: loadBalancerPoolMembers)
+            member.setPoolID(loadBalancerPoolID);
         return loadBalancerPoolMembers;
     }
 
-    public void setLoadBalancerPoolMembers(List loadBalancerPoolMembers) {
+    public void setLoadBalancerPoolMembers(List<NeutronLoadBalancerPoolMember> loadBalancerPoolMembers) {
         this.loadBalancerPoolMembers = loadBalancerPoolMembers;
     }
 
+    public void addLoadBalancerPoolMember(NeutronLoadBalancerPoolMember loadBalancerPoolMember) {
+        this.loadBalancerPoolMembers.add(loadBalancerPoolMember);
+    }
+
+    public void removeLoadBalancerPoolMember(NeutronLoadBalancerPoolMember loadBalancerPoolMember) {
+        this.loadBalancerPoolMembers.remove(loadBalancerPoolMember);
+    }
+
     public NeutronLoadBalancerPool extractFields(List<String> fields) {
         NeutronLoadBalancerPool ans = new NeutronLoadBalancerPool();
         Iterator<String> i = fields.iterator();
@@ -198,4 +208,4 @@ public class NeutronLoadBalancerPool extends ConfigurationObject implements Seri
         }
         return ans;
     }
-}
\ No newline at end of file
+}
index 577c3bb..683d45f 100644 (file)
@@ -10,11 +10,18 @@ package org.opendaylight.controller.networkconfig.neutron;
 
 import org.opendaylight.controller.configuration.ConfigurationObject;
 
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
 import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlRootElement;
+import javax.xml.bind.annotation.XmlTransient;
 import java.io.Serializable;
 import java.util.Iterator;
 import java.util.List;
 
+@XmlRootElement
+@XmlAccessorType(XmlAccessType.NONE)
+
 public class NeutronLoadBalancerPoolMember  extends ConfigurationObject implements Serializable {
 
     private static final long serialVersionUID = 1L;
@@ -46,9 +53,20 @@ public class NeutronLoadBalancerPoolMember  extends ConfigurationObject implemen
     @XmlElement (name="status")
     String poolMemberStatus;
 
+    String poolID;
+
     public NeutronLoadBalancerPoolMember() {
     }
 
+    @XmlTransient
+    public String getPoolID() {
+        return poolID;
+    }
+
+    public void setPoolID(String poolID) {
+        this.poolID = poolID;
+    }
+
     public String getPoolMemberID() {
         return poolMemberID;
     }
@@ -121,6 +139,9 @@ public class NeutronLoadBalancerPoolMember  extends ConfigurationObject implemen
             if (s.equals("id")) {
                 ans.setPoolMemberID(this.getPoolMemberID());
             }
+            if (s.equals("pool_id")) {
+                ans.setPoolID(this.getPoolID());
+            }
             if (s.equals("tenant_id")) {
                 ans.setPoolMemberTenantID(this.getPoolMemberTenantID());
             }
@@ -148,6 +169,7 @@ public class NeutronLoadBalancerPoolMember  extends ConfigurationObject implemen
     @Override public String toString() {
         return "NeutronLoadBalancerPoolMember{" +
                 "poolMemberID='" + poolMemberID + '\'' +
+                ", poolID='" + poolID + '\'' +
                 ", poolMemberTenantID='" + poolMemberTenantID + '\'' +
                 ", poolMemberAddress='" + poolMemberAddress + '\'' +
                 ", poolMemberProtoPort=" + poolMemberProtoPort +
index 748dffc..863b3cb 100644 (file)
@@ -38,8 +38,8 @@ import java.util.Iterator;
 import java.util.List;
 
 /**
- * Neutron Northbound REST APIs for LoadBalancer Policies.<br>
- * This class provides REST APIs for managing neutron LoadBalancer Policies
+ * Neutron Northbound REST APIs for LoadBalancers.<br>
+ * This class provides REST APIs for managing neutron LoadBalancers
  *
  * <br>
  * <br>
@@ -87,15 +87,13 @@ public class NeutronLoadBalancerNorthbound {
             @QueryParam("page_reverse") String pageReverse
             // sorting not supported
     ) {
-        INeutronLoadBalancerCRUD loadBalancerPoolInterface = NeutronCRUDInterfaces.getINeutronLoadBalancerCRUD(
-                this);
-        //        INeutronLoadBalancerRuleCRUD firewallRuleInterface = NeutronCRUDInterfaces.getINeutronLoadBalancerRuleCRUD(this);
+        INeutronLoadBalancerCRUD loadBalancerInterface = NeutronCRUDInterfaces.getINeutronLoadBalancerCRUD(this);
 
-        if (loadBalancerPoolInterface == null) {
+        if (loadBalancerInterface == null) {
             throw new ServiceUnavailableException("LoadBalancer CRUD Interface "
                     + RestMessages.SERVICEUNAVAILABLE.toString());
         }
-        List<NeutronLoadBalancer> allLoadBalancers = loadBalancerPoolInterface.getAllNeutronLoadBalancers();
+        List<NeutronLoadBalancer> allLoadBalancers = loadBalancerInterface.getAllNeutronLoadBalancers();
         //        List<NeutronLoadBalancerRule> allLoadBalancerRules = firewallRuleInterface.getAllNeutronLoadBalancerRules();
         List<NeutronLoadBalancer> ans = new ArrayList<NeutronLoadBalancer>();
         //        List<NeutronLoadBalancerRule> rules = new ArrayList<NeutronLoadBalancerRule>();
@@ -128,7 +126,7 @@ public class NeutronLoadBalancerNorthbound {
     /**
      * Returns a specific LoadBalancer */
 
-    @Path("{loadBalancerPoolID}")
+    @Path("{loadBalancerID}")
     @GET
     @Produces({ MediaType.APPLICATION_JSON })
 
@@ -137,25 +135,25 @@ public class NeutronLoadBalancerNorthbound {
             @ResponseCode(code = 401, condition = "Unauthorized"),
             @ResponseCode(code = 404, condition = "Not Found"),
             @ResponseCode(code = 501, condition = "Not Implemented") })
-    public Response showLoadBalancer(@PathParam("loadBalancerPoolID") String loadBalancerPoolID,
+    public Response showLoadBalancer(@PathParam("loadBalancerID") String loadBalancerID,
             // return fields
             @QueryParam("fields") List<String> fields) {
-        INeutronLoadBalancerCRUD loadBalancerPoolInterface = NeutronCRUDInterfaces.getINeutronLoadBalancerCRUD(
+        INeutronLoadBalancerCRUD loadBalancerInterface = NeutronCRUDInterfaces.getINeutronLoadBalancerCRUD(
                 this);
-        if (loadBalancerPoolInterface == null) {
+        if (loadBalancerInterface == null) {
             throw new ServiceUnavailableException("LoadBalancer CRUD Interface "
                     + RestMessages.SERVICEUNAVAILABLE.toString());
         }
-        if (!loadBalancerPoolInterface.neutronLoadBalancerExists(loadBalancerPoolID)) {
+        if (!loadBalancerInterface.neutronLoadBalancerExists(loadBalancerID)) {
             throw new ResourceNotFoundException("LoadBalancer UUID does not exist.");
         }
         if (fields.size() > 0) {
-            NeutronLoadBalancer ans = loadBalancerPoolInterface.getNeutronLoadBalancer(loadBalancerPoolID);
+            NeutronLoadBalancer ans = loadBalancerInterface.getNeutronLoadBalancer(loadBalancerID);
             return Response.status(200).entity(
                     new NeutronLoadBalancerRequest(extractFields(ans, fields))).build();
         } else {
-            return Response.status(200).entity(new NeutronLoadBalancerRequest(loadBalancerPoolInterface.getNeutronLoadBalancer(
-                    loadBalancerPoolID))).build();
+            return Response.status(200).entity(new NeutronLoadBalancerRequest(loadBalancerInterface.getNeutronLoadBalancer(
+                    loadBalancerID))).build();
         }
     }
 
@@ -175,9 +173,9 @@ public class NeutronLoadBalancerNorthbound {
             @ResponseCode(code = 409, condition = "Conflict"),
             @ResponseCode(code = 501, condition = "Not Implemented") })
     public Response createLoadBalancers(final NeutronLoadBalancerRequest input) {
-        INeutronLoadBalancerCRUD loadBalancerPoolInterface = NeutronCRUDInterfaces.getINeutronLoadBalancerCRUD(
+        INeutronLoadBalancerCRUD loadBalancerInterface = NeutronCRUDInterfaces.getINeutronLoadBalancerCRUD(
                 this);
-        if (loadBalancerPoolInterface == null) {
+        if (loadBalancerInterface == null) {
             throw new ServiceUnavailableException("LoadBalancer CRUD Interface "
                     + RestMessages.SERVICEUNAVAILABLE.toString());
         }
@@ -187,11 +185,9 @@ public class NeutronLoadBalancerNorthbound {
             /*
              *  Verify that the LoadBalancer doesn't already exist.
              */
-            if (loadBalancerPoolInterface.neutronLoadBalancerExists(singleton.getLoadBalancerID())) {
+            if (loadBalancerInterface.neutronLoadBalancerExists(singleton.getLoadBalancerID())) {
                 throw new BadRequestException("LoadBalancer UUID already exists");
             }
-            loadBalancerPoolInterface.addNeutronLoadBalancer(singleton);
-
             Object[] instances = ServiceHelper.getGlobalInstances(INeutronLoadBalancerAware.class, this, null);
             if (instances != null) {
                 for (Object instance : instances) {
@@ -202,7 +198,7 @@ public class NeutronLoadBalancerNorthbound {
                     }
                 }
             }
-            loadBalancerPoolInterface.addNeutronLoadBalancer(singleton);
+            loadBalancerInterface.addNeutronLoadBalancer(singleton);
             if (instances != null) {
                 for (Object instance : instances) {
                     INeutronLoadBalancerAware service = (INeutronLoadBalancerAware) instance;
@@ -218,10 +214,10 @@ public class NeutronLoadBalancerNorthbound {
                 NeutronLoadBalancer test = i.next();
 
                 /*
-                 *  Verify that the firewall policy doesn't already exist
+                 *  Verify that the loadbalancer doesn't already exist
                  */
 
-                if (loadBalancerPoolInterface.neutronLoadBalancerExists(test.getLoadBalancerID())) {
+                if (loadBalancerInterface.neutronLoadBalancerExists(test.getLoadBalancerID())) {
                     throw new BadRequestException("Load Balancer Pool UUID already is already created");
                 }
                 if (testMap.containsKey(test.getLoadBalancerID())) {
@@ -243,7 +239,7 @@ public class NeutronLoadBalancerNorthbound {
             i = bulk.iterator();
             while (i.hasNext()) {
                 NeutronLoadBalancer test = i.next();
-                loadBalancerPoolInterface.addNeutronLoadBalancer(test);
+                loadBalancerInterface.addNeutronLoadBalancer(test);
                 if (instances != null) {
                     for (Object instance : instances) {
                         INeutronLoadBalancerAware service = (INeutronLoadBalancerAware) instance;
@@ -258,7 +254,7 @@ public class NeutronLoadBalancerNorthbound {
     /**
      * Updates a LoadBalancer Policy
      */
-    @Path("{loadBalancerPoolID}")
+    @Path("{loadBalancerID}")
     @PUT
     @Produces({ MediaType.APPLICATION_JSON })
     @Consumes({ MediaType.APPLICATION_JSON })
@@ -271,10 +267,10 @@ public class NeutronLoadBalancerNorthbound {
             @ResponseCode(code = 404, condition = "Not Found"),
             @ResponseCode(code = 501, condition = "Not Implemented") })
     public Response updateLoadBalancer(
-            @PathParam("loadBalancerPoolID") String loadBalancerPoolID, final NeutronLoadBalancerRequest input) {
-        INeutronLoadBalancerCRUD loadBalancerPoolInterface = NeutronCRUDInterfaces.getINeutronLoadBalancerCRUD(
+            @PathParam("loadBalancerID") String loadBalancerID, final NeutronLoadBalancerRequest input) {
+        INeutronLoadBalancerCRUD loadBalancerInterface = NeutronCRUDInterfaces.getINeutronLoadBalancerCRUD(
                 this);
-        if (loadBalancerPoolInterface == null) {
+        if (loadBalancerInterface == null) {
             throw new ServiceUnavailableException("LoadBalancer CRUD Interface "
                     + RestMessages.SERVICEUNAVAILABLE.toString());
         }
@@ -282,14 +278,14 @@ public class NeutronLoadBalancerNorthbound {
         /*
          * verify the LoadBalancer exists and there is only one delta provided
          */
-        if (!loadBalancerPoolInterface.neutronLoadBalancerExists(loadBalancerPoolID)) {
+        if (!loadBalancerInterface.neutronLoadBalancerExists(loadBalancerID)) {
             throw new ResourceNotFoundException("LoadBalancer UUID does not exist.");
         }
         if (!input.isSingleton()) {
             throw new BadRequestException("Only singleton edit supported");
         }
         NeutronLoadBalancer delta = input.getSingleton();
-        NeutronLoadBalancer original = loadBalancerPoolInterface.getNeutronLoadBalancer(loadBalancerPoolID);
+        NeutronLoadBalancer original = loadBalancerInterface.getNeutronLoadBalancer(loadBalancerID);
 
         /*
          * updates restricted by Neutron
@@ -318,23 +314,23 @@ public class NeutronLoadBalancerNorthbound {
         /*
          * update the object and return it
          */
-        loadBalancerPoolInterface.updateNeutronLoadBalancer(loadBalancerPoolID, delta);
-        NeutronLoadBalancer updatedLoadBalancer = loadBalancerPoolInterface.getNeutronLoadBalancer(
-                loadBalancerPoolID);
+        loadBalancerInterface.updateNeutronLoadBalancer(loadBalancerID, delta);
+        NeutronLoadBalancer updatedLoadBalancer = loadBalancerInterface.getNeutronLoadBalancer(
+                loadBalancerID);
         if (instances != null) {
             for (Object instance : instances) {
                 INeutronLoadBalancerAware service = (INeutronLoadBalancerAware) instance;
                 service.neutronLoadBalancerUpdated(updatedLoadBalancer);
             }
         }
-        return Response.status(200).entity(new NeutronLoadBalancerRequest(loadBalancerPoolInterface.getNeutronLoadBalancer(
-                loadBalancerPoolID))).build();
+        return Response.status(200).entity(new NeutronLoadBalancerRequest(loadBalancerInterface.getNeutronLoadBalancer(
+                loadBalancerID))).build();
     }
 
     /**
      * Deletes a LoadBalancer */
 
-    @Path("{loadBalancerPoolID}")
+    @Path("{loadBalancerID}")
     @DELETE
     @StatusCodes({
             @ResponseCode(code = 204, condition = "No Content"),
@@ -343,10 +339,10 @@ public class NeutronLoadBalancerNorthbound {
             @ResponseCode(code = 409, condition = "Conflict"),
             @ResponseCode(code = 501, condition = "Not Implemented") })
     public Response deleteLoadBalancer(
-            @PathParam("loadBalancerPoolID") String loadBalancerPoolID) {
-        INeutronLoadBalancerCRUD loadBalancerPoolInterface = NeutronCRUDInterfaces.getINeutronLoadBalancerCRUD(
+            @PathParam("loadBalancerID") String loadBalancerID) {
+        INeutronLoadBalancerCRUD loadBalancerInterface = NeutronCRUDInterfaces.getINeutronLoadBalancerCRUD(
                 this);
-        if (loadBalancerPoolInterface == null) {
+        if (loadBalancerInterface == null) {
             throw new ServiceUnavailableException("LoadBalancer CRUD Interface "
                     + RestMessages.SERVICEUNAVAILABLE.toString());
         }
@@ -354,13 +350,13 @@ public class NeutronLoadBalancerNorthbound {
         /*
          * verify the LoadBalancer exists and it isn't currently in use
          */
-        if (!loadBalancerPoolInterface.neutronLoadBalancerExists(loadBalancerPoolID)) {
+        if (!loadBalancerInterface.neutronLoadBalancerExists(loadBalancerID)) {
             throw new ResourceNotFoundException("LoadBalancer UUID does not exist.");
         }
-        if (loadBalancerPoolInterface.neutronLoadBalancerInUse(loadBalancerPoolID)) {
+        if (loadBalancerInterface.neutronLoadBalancerInUse(loadBalancerID)) {
             return Response.status(409).build();
         }
-        NeutronLoadBalancer singleton = loadBalancerPoolInterface.getNeutronLoadBalancer(loadBalancerPoolID);
+        NeutronLoadBalancer singleton = loadBalancerInterface.getNeutronLoadBalancer(loadBalancerID);
         Object[] instances = ServiceHelper.getGlobalInstances(INeutronLoadBalancerAware.class, this, null);
         if (instances != null) {
             for (Object instance : instances) {
@@ -372,7 +368,7 @@ public class NeutronLoadBalancerNorthbound {
             }
         }
 
-        loadBalancerPoolInterface.removeNeutronLoadBalancer(loadBalancerPoolID);
+        loadBalancerInterface.removeNeutronLoadBalancer(loadBalancerID);
         if (instances != null) {
             for (Object instance : instances) {
                 INeutronLoadBalancerAware service = (INeutronLoadBalancerAware) instance;
@@ -12,7 +12,7 @@ import org.opendaylight.controller.networkconfig.neutron.NeutronLoadBalancerPool
 import javax.xml.bind.annotation.XmlElement;
 import java.util.List;
 
-public class INeutronLoadBalancerPoolMemberRequest {
+public class NeutronLoadBalancerPoolMemberRequest {
 
     /**
      * See OpenStack Network API v2.0 Reference for description of
@@ -25,15 +25,15 @@ public class INeutronLoadBalancerPoolMemberRequest {
     @XmlElement(name="members")
     List<NeutronLoadBalancerPoolMember> bulkRequest;
 
-    INeutronLoadBalancerPoolMemberRequest() {
+    NeutronLoadBalancerPoolMemberRequest() {
     }
 
-    INeutronLoadBalancerPoolMemberRequest(List<NeutronLoadBalancerPoolMember> bulk) {
+    NeutronLoadBalancerPoolMemberRequest(List<NeutronLoadBalancerPoolMember> bulk) {
         bulkRequest = bulk;
         singletonLoadBalancerPoolMember = null;
     }
 
-    INeutronLoadBalancerPoolMemberRequest(NeutronLoadBalancerPoolMember group) {
+    NeutronLoadBalancerPoolMemberRequest(NeutronLoadBalancerPoolMember group) {
         singletonLoadBalancerPoolMember = group;
     }
 
index ff56fa0..f8f3cd8 100644 (file)
@@ -1,46 +1,51 @@
 /*
- * Copyright (C) 2014 Red Hat, Inc.
+ * Copyright (C) 2014 SDN Hub, LLC.
  *
  * 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
+ *
+ * Authors : Srini Seetharaman
  */
 
 package org.opendaylight.controller.networkconfig.neutron.northbound;
 
 import org.codehaus.enunciate.jaxrs.ResponseCode;
 import org.codehaus.enunciate.jaxrs.StatusCodes;
+import org.opendaylight.controller.networkconfig.neutron.INeutronLoadBalancerPoolCRUD;
 import org.opendaylight.controller.networkconfig.neutron.INeutronLoadBalancerPoolMemberAware;
-import org.opendaylight.controller.networkconfig.neutron.INeutronLoadBalancerPoolMemberCRUD;
 import org.opendaylight.controller.networkconfig.neutron.NeutronCRUDInterfaces;
+import org.opendaylight.controller.networkconfig.neutron.NeutronLoadBalancerPool;
 import org.opendaylight.controller.networkconfig.neutron.NeutronLoadBalancerPoolMember;
 import org.opendaylight.controller.northbound.commons.RestMessages;
 import org.opendaylight.controller.northbound.commons.exception.BadRequestException;
+import org.opendaylight.controller.northbound.commons.exception.ResourceNotFoundException;
 import org.opendaylight.controller.northbound.commons.exception.ServiceUnavailableException;
 import org.opendaylight.controller.sal.utils.ServiceHelper;
 
 import javax.ws.rs.Consumes;
+import javax.ws.rs.DELETE;
 import javax.ws.rs.GET;
 import javax.ws.rs.PUT;
 import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
 import javax.ws.rs.Produces;
 import javax.ws.rs.QueryParam;
 import javax.ws.rs.core.MediaType;
 import javax.ws.rs.core.Response;
+
 import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.Iterator;
 import java.util.List;
 
-
-@Path("/pools/{loadBalancerPoolID}/members")
+@Path("/pools/{loadBalancerPoolUUID}/members")
 public class NeutronLoadBalancerPoolMembersNorthbound {
-
     private NeutronLoadBalancerPoolMember extractFields(NeutronLoadBalancerPoolMember o, List<String> fields) {
         return o.extractFields(fields);
     }
 /**
- * Returns a list of all LoadBalancerPool
+ * Returns a list of all LoadBalancerPoolMembers in specified pool
  */
 @GET
 @Produces({MediaType.APPLICATION_JSON})
@@ -50,8 +55,12 @@ public class NeutronLoadBalancerPoolMembersNorthbound {
         @ResponseCode(code = 501, condition = "Not Implemented")})
 
 public Response listMembers(
+        //Path param
+        @PathParam("loadBalancerPoolUUID") String loadBalancerPoolUUID,
+
         // return fields
         @QueryParam("fields") List<String> fields,
+
         // OpenStack LoadBalancerPool attributes
         @QueryParam("id") String queryLoadBalancerPoolMemberID,
         @QueryParam("tenant_id") String queryLoadBalancerPoolMemberTenantID,
@@ -68,20 +77,24 @@ public Response listMembers(
         @QueryParam("page_reverse") String pageReverse
         // sorting not supported
 ) {
-    INeutronLoadBalancerPoolMemberCRUD loadBalancerPoolMemberInterface = NeutronCRUDInterfaces
-            .getINeutronLoadBalancerPoolMemberCRUD(this);
-    if (loadBalancerPoolMemberInterface == null) {
+    INeutronLoadBalancerPoolCRUD loadBalancerPoolInterface = NeutronCRUDInterfaces
+            .getINeutronLoadBalancerPoolCRUD(this);
+    if (loadBalancerPoolInterface == null) {
         throw new ServiceUnavailableException("LoadBalancerPool CRUD Interface "
                 + RestMessages.SERVICEUNAVAILABLE.toString());
     }
-    List<NeutronLoadBalancerPoolMember> allLoadBalancerPoolMembers = loadBalancerPoolMemberInterface
-            .getAllNeutronLoadBalancerPoolMembers();
+    if (!loadBalancerPoolInterface.neutronLoadBalancerPoolExists(loadBalancerPoolUUID)) {
+        throw new ResourceNotFoundException("loadBalancerPool UUID does not exist.");
+    }
+    List<NeutronLoadBalancerPoolMember> members =
+                loadBalancerPoolInterface.getNeutronLoadBalancerPool(loadBalancerPoolUUID).getLoadBalancerPoolMembers();
     List<NeutronLoadBalancerPoolMember> ans = new ArrayList<NeutronLoadBalancerPoolMember>();
-    Iterator<NeutronLoadBalancerPoolMember> i = allLoadBalancerPoolMembers.iterator();
+    Iterator<NeutronLoadBalancerPoolMember> i = members.iterator();
     while (i.hasNext()) {
         NeutronLoadBalancerPoolMember nsg = i.next();
         if ((queryLoadBalancerPoolMemberID == null ||
                 queryLoadBalancerPoolMemberID.equals(nsg.getPoolMemberID())) &&
+                loadBalancerPoolUUID.equals(nsg.getPoolID()) &&
                 (queryLoadBalancerPoolMemberTenantID == null ||
                         queryLoadBalancerPoolMemberTenantID.equals(nsg.getPoolMemberTenantID())) &&
                 (queryLoadBalancerPoolMemberAddress == null ||
@@ -102,13 +115,57 @@ public Response listMembers(
         }
     }
     return Response.status(200).entity(
-            new INeutronLoadBalancerPoolMemberRequest(ans)).build();
+            new NeutronLoadBalancerPoolMemberRequest(ans)).build();
+}
+
+/**
+ * Returns a specific LoadBalancerPoolMember
+ */
+
+@Path("{loadBalancerPoolMemberUUID}")
+@GET
+@Produces({ MediaType.APPLICATION_JSON })
+//@TypeHint(OpenStackLoadBalancerPoolMembers.class)
+@StatusCodes({
+    @ResponseCode(code = 200, condition = "Operation successful"),
+    @ResponseCode(code = 401, condition = "Unauthorized"),
+    @ResponseCode(code = 404, condition = "Not Found"),
+    @ResponseCode(code = 501, condition = "Not Implemented") })
+public Response showLoadBalancerPoolMember(
+        @PathParam("loadBalancerPoolUUID") String loadBalancerPoolUUID,
+        @PathParam("loadBalancerPoolMemberUUID") String loadBalancerPoolMemberUUID,
+        // return fields
+        @QueryParam("fields") List<String> fields ) {
+
+    INeutronLoadBalancerPoolCRUD loadBalancerPoolInterface = NeutronCRUDInterfaces
+            .getINeutronLoadBalancerPoolCRUD(this);
+    if (loadBalancerPoolInterface == null) {
+        throw new ServiceUnavailableException("LoadBalancerPool CRUD Interface "
+                + RestMessages.SERVICEUNAVAILABLE.toString());
+    }
+    if (!loadBalancerPoolInterface.neutronLoadBalancerPoolExists(loadBalancerPoolUUID)) {
+        throw new ResourceNotFoundException("loadBalancerPool UUID does not exist.");
+    }
+    List<NeutronLoadBalancerPoolMember> members =
+                loadBalancerPoolInterface.getNeutronLoadBalancerPool(loadBalancerPoolUUID).getLoadBalancerPoolMembers();
+    for (NeutronLoadBalancerPoolMember ans: members) {
+        if (!ans.getPoolMemberID().equals(loadBalancerPoolMemberUUID))
+            continue;
+
+        if (fields.size() > 0) {
+            return Response.status(200).entity(
+                new NeutronLoadBalancerPoolMemberRequest(extractFields(ans, fields))).build();
+        } else {
+            return Response.status(200).entity(
+                new NeutronLoadBalancerPoolMemberRequest(ans)).build();
+        }
+    }
+    return Response.status(204).build();
 }
 
 /**
  * Adds a Member to an LBaaS Pool member
  */
-@Path("/pools/{loadBalancerPoolID}/members")
 @PUT
 @Produces({MediaType.APPLICATION_JSON})
 @Consumes({MediaType.APPLICATION_JSON})
@@ -117,25 +174,34 @@ public Response listMembers(
         @ResponseCode(code = 401, condition = "Unauthorized"),
         @ResponseCode(code = 404, condition = "Not Found"),
         @ResponseCode(code = 501, condition = "Not Implemented")})
-public Response createLoadBalancerPoolMember(  INeutronLoadBalancerPoolMemberRequest input) {
+public Response createLoadBalancerPoolMember(
+        @PathParam("loadBalancerPoolUUID") String loadBalancerPoolUUID,
+        final NeutronLoadBalancerPoolMemberRequest input) {
 
-    INeutronLoadBalancerPoolMemberCRUD loadBalancerPoolMemberInterface = NeutronCRUDInterfaces.getINeutronLoadBalancerPoolMemberCRUD(
-            this);
-    if (loadBalancerPoolMemberInterface == null) {
-        throw new ServiceUnavailableException("LoadBalancerPoolMember CRUD Interface "
+    INeutronLoadBalancerPoolCRUD loadBalancerPoolInterface = NeutronCRUDInterfaces.getINeutronLoadBalancerPoolCRUD(this);
+    if (loadBalancerPoolInterface == null) {
+        throw new ServiceUnavailableException("LoadBalancerPool CRUD Interface "
                 + RestMessages.SERVICEUNAVAILABLE.toString());
     }
+    // Verify that the loadBalancerPool exists, for the member to be added to its cache
+    if (!loadBalancerPoolInterface.neutronLoadBalancerPoolExists(loadBalancerPoolUUID)) {
+        throw new ResourceNotFoundException("loadBalancerPool UUID does not exist.");
+    }
+    NeutronLoadBalancerPool singletonPool = loadBalancerPoolInterface.getNeutronLoadBalancerPool(loadBalancerPoolUUID);
+
     if (input.isSingleton()) {
         NeutronLoadBalancerPoolMember singleton = input.getSingleton();
+        singleton.setPoolID(loadBalancerPoolUUID);
+        String loadBalancerPoolMemberUUID = singleton.getPoolMemberID();
 
         /*
          *  Verify that the LoadBalancerPoolMember doesn't already exist.
          */
-        if (loadBalancerPoolMemberInterface.neutronLoadBalancerPoolMemberExists(
-                singleton.getPoolMemberID())) {
-            throw new BadRequestException("LoadBalancerPoolMember UUID already exists");
+        List<NeutronLoadBalancerPoolMember> members = singletonPool.getLoadBalancerPoolMembers();
+        for (NeutronLoadBalancerPoolMember member: members) {
+            if (member.getPoolMemberID().equals(loadBalancerPoolMemberUUID))
+                throw new BadRequestException("LoadBalancerPoolMember UUID already exists");
         }
-        loadBalancerPoolMemberInterface.addNeutronLoadBalancerPoolMember(singleton);
 
         Object[] instances = ServiceHelper.getGlobalInstances(INeutronLoadBalancerPoolMemberAware.class, this, null);
         if (instances != null) {
@@ -147,13 +213,18 @@ public Response createLoadBalancerPoolMember(  INeutronLoadBalancerPoolMemberReq
                 }
             }
         }
-        loadBalancerPoolMemberInterface.addNeutronLoadBalancerPoolMember(singleton);
         if (instances != null) {
             for (Object instance : instances) {
                 INeutronLoadBalancerPoolMemberAware service = (INeutronLoadBalancerPoolMemberAware) instance;
                 service.neutronLoadBalancerPoolMemberCreated(singleton);
             }
         }
+
+        /**
+         * Add the member from the neutron load balancer pool as well
+         */
+        singletonPool.addLoadBalancerPoolMember(singleton);
+
     } else {
         List<NeutronLoadBalancerPoolMember> bulk = input.getBulk();
         Iterator<NeutronLoadBalancerPoolMember> i = bulk.iterator();
@@ -161,15 +232,17 @@ public Response createLoadBalancerPoolMember(  INeutronLoadBalancerPoolMemberReq
         Object[] instances = ServiceHelper.getGlobalInstances(INeutronLoadBalancerPoolMemberAware.class, this, null);
         while (i.hasNext()) {
             NeutronLoadBalancerPoolMember test = i.next();
+            String loadBalancerPoolMemberUUID = test.getPoolMemberID();
 
             /*
-             *  Verify that the firewall doesn't already exist
+             *  Verify that the LoadBalancerPoolMember doesn't already exist.
              */
-
-            if (loadBalancerPoolMemberInterface.neutronLoadBalancerPoolMemberExists(
-                    test.getPoolMemberID())) {
-                throw new BadRequestException("Load Balancer PoolMember UUID already is already created");
+            List<NeutronLoadBalancerPoolMember> members = singletonPool.getLoadBalancerPoolMembers();
+            for (NeutronLoadBalancerPoolMember member: members) {
+                if (member.getPoolMemberID().equals(loadBalancerPoolMemberUUID))
+                    throw new BadRequestException("LoadBalancerPoolMember UUID already exists");
             }
+
             if (testMap.containsKey(test.getPoolMemberID())) {
                 throw new BadRequestException("Load Balancer PoolMember UUID already exists");
             }
@@ -189,15 +262,105 @@ public Response createLoadBalancerPoolMember(  INeutronLoadBalancerPoolMemberReq
         i = bulk.iterator();
         while (i.hasNext()) {
             NeutronLoadBalancerPoolMember test = i.next();
-            loadBalancerPoolMemberInterface.addNeutronLoadBalancerPoolMember(test);
             if (instances != null) {
                 for (Object instance : instances) {
                     INeutronLoadBalancerPoolMemberAware service = (INeutronLoadBalancerPoolMemberAware) instance;
                     service.neutronLoadBalancerPoolMemberCreated(test);
                 }
             }
+            singletonPool.addLoadBalancerPoolMember(test);
         }
     }
     return Response.status(201).entity(input).build();
 }
+
+/**
+ * Updates a LB member pool
+ */
+
+@Path("{loadBalancerPoolMemberUUID}")
+@PUT
+@Produces({ MediaType.APPLICATION_JSON })
+@Consumes({ MediaType.APPLICATION_JSON })
+@StatusCodes({
+        @ResponseCode(code = 200, condition = "Operation successful"),
+        @ResponseCode(code = 400, condition = "Bad Request"),
+        @ResponseCode(code = 401, condition = "Unauthorized"),
+        @ResponseCode(code = 403, condition = "Forbidden"),
+        @ResponseCode(code = 404, condition = "Not Found"),
+        @ResponseCode(code = 501, condition = "Not Implemented") })
+public Response updateLoadBalancerPoolMember(
+        @PathParam("loadBalancerPoolUUID") String loadBalancerPoolUUID,
+        @PathParam("loadBalancerPoolMemberUUID") String loadBalancerPoolMemberUUID,
+        final NeutronLoadBalancerPoolMemberRequest input) {
+
+    //TODO: Implement update LB member pool
+    return Response.status(501).entity(input).build();
+}
+
+/**
+ * Deletes a LoadBalancerPoolMember
+ */
+
+@Path("{loadBalancerPoolMemberUUID}")
+@DELETE
+@StatusCodes({
+    @ResponseCode(code = 204, condition = "No Content"),
+    @ResponseCode(code = 401, condition = "Unauthorized"),
+    @ResponseCode(code = 403, condition = "Forbidden"),
+    @ResponseCode(code = 404, condition = "Not Found"),
+    @ResponseCode(code = 501, condition = "Not Implemented") })
+public Response deleteLoadBalancerPoolMember(
+        @PathParam("loadBalancerPoolUUID") String loadBalancerPoolUUID,
+        @PathParam("loadBalancerPoolMemberUUID") String loadBalancerPoolMemberUUID) {
+    INeutronLoadBalancerPoolCRUD loadBalancerPoolInterface = NeutronCRUDInterfaces.getINeutronLoadBalancerPoolCRUD(this);
+    if (loadBalancerPoolInterface == null) {
+        throw new ServiceUnavailableException("LoadBalancerPool CRUD Interface "
+                + RestMessages.SERVICEUNAVAILABLE.toString());
+    }
+
+    // Verify that the loadBalancerPool exists, for the member to be removed from its cache
+    if (!loadBalancerPoolInterface.neutronLoadBalancerPoolExists(loadBalancerPoolUUID)) {
+        throw new ResourceNotFoundException("loadBalancerPool UUID does not exist.");
+    }
+
+    //Verify that the LB pool member exists
+    NeutronLoadBalancerPoolMember singleton = null;
+    List<NeutronLoadBalancerPoolMember> members =
+            loadBalancerPoolInterface.getNeutronLoadBalancerPool(loadBalancerPoolUUID).getLoadBalancerPoolMembers();
+    for (NeutronLoadBalancerPoolMember member: members) {
+        if (member.getPoolMemberID().equals(loadBalancerPoolMemberUUID)) {
+            singleton = member;
+            break;
+        }
+    }
+    if (singleton == null)
+        throw new BadRequestException("LoadBalancerPoolMember UUID does not exist.");
+
+    Object[] instances = ServiceHelper.getGlobalInstances(INeutronLoadBalancerPoolMemberAware.class, this, null);
+    if (instances != null) {
+        for (Object instance : instances) {
+            INeutronLoadBalancerPoolMemberAware service = (INeutronLoadBalancerPoolMemberAware) instance;
+            int status = service.canDeleteNeutronLoadBalancerPoolMember(singleton);
+            if (status < 200 || status > 299) {
+                return Response.status(status).build();
+            }
+        }
+    }
+
+    if (instances != null) {
+        for (Object instance : instances) {
+            INeutronLoadBalancerPoolMemberAware service = (INeutronLoadBalancerPoolMemberAware) instance;
+            service.neutronLoadBalancerPoolMemberDeleted(singleton);
+        }
+    }
+
+    /**
+     * Remove the member from the neutron load balancer pool
+     */
+    NeutronLoadBalancerPool singletonPool = loadBalancerPoolInterface.getNeutronLoadBalancerPool(loadBalancerPoolUUID);
+    singletonPool.removeLoadBalancerPoolMember(singleton);
+
+    return Response.status(204).build();
+}
 }
index fc5357c..7802dbb 100644 (file)
@@ -1,9 +1,11 @@
 /*
- * Copyright (C) 2014 Red Hat, Inc.
+ * Copyright (C) 2014 SDN Hub, LLC.
  *
  * 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
+ *
+ * Authors : Srini Seetharaman
  */
 
 package org.opendaylight.controller.networkconfig.neutron.northbound;
@@ -13,8 +15,10 @@ import org.codehaus.enunciate.jaxrs.ResponseCode;
 import org.codehaus.enunciate.jaxrs.StatusCodes;
 import org.opendaylight.controller.networkconfig.neutron.INeutronLoadBalancerPoolAware;
 import org.opendaylight.controller.networkconfig.neutron.INeutronLoadBalancerPoolCRUD;
+import org.opendaylight.controller.networkconfig.neutron.INeutronLoadBalancerPoolMemberCRUD;
 import org.opendaylight.controller.networkconfig.neutron.NeutronCRUDInterfaces;
 import org.opendaylight.controller.networkconfig.neutron.NeutronLoadBalancerPool;
+import org.opendaylight.controller.networkconfig.neutron.NeutronLoadBalancerPoolMember;
 import org.opendaylight.controller.northbound.commons.RestMessages;
 import org.opendaylight.controller.northbound.commons.exception.BadRequestException;
 import org.opendaylight.controller.northbound.commons.exception.ResourceNotFoundException;
@@ -22,6 +26,7 @@ import org.opendaylight.controller.northbound.commons.exception.ServiceUnavailab
 import org.opendaylight.controller.sal.utils.ServiceHelper;
 
 import javax.ws.rs.Consumes;
+import javax.ws.rs.DELETE;
 import javax.ws.rs.GET;
 import javax.ws.rs.POST;
 import javax.ws.rs.PUT;
@@ -31,6 +36,7 @@ import javax.ws.rs.Produces;
 import javax.ws.rs.QueryParam;
 import javax.ws.rs.core.MediaType;
 import javax.ws.rs.core.Response;
+
 import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.Iterator;
@@ -53,6 +59,13 @@ import java.util.List;
  * http://tomcat.apache.org/tomcat-7.0-doc/ssl-howto.html#Configuration
  *
  */
+
+/**
+ * For now, the LB pool member data is maintained with the INeutronLoadBalancerPoolCRUD,
+ * although there may be an overlap with INeutronLoadBalancerPoolMemberCRUD's cache.
+ * TODO: Consolidate and maintain a single copy
+ */
+
 @Path("/pools")
 public class NeutronLoadBalancerPoolNorthbound {
 
@@ -83,7 +96,7 @@ public class NeutronLoadBalancerPoolNorthbound {
             @QueryParam("healthmonitor_id") String queryLoadBalancerPoolHealthMonitorID,
             @QueryParam("admin_state_up") String queryLoadBalancerIsAdminStateUp,
             @QueryParam("status") String queryLoadBalancerPoolStatus,
-            @QueryParam("members") List queryLoadBalancerPoolMembers,
+            @QueryParam("members") List<NeutronLoadBalancerPoolMember> queryLoadBalancerPoolMembers,
             // pagination
             @QueryParam("limit") String limit,
             @QueryParam("marker") String marker,
@@ -217,7 +230,7 @@ public class NeutronLoadBalancerPoolNorthbound {
                 NeutronLoadBalancerPool test = i.next();
 
                 /*
-                 *  Verify that the firewall doesn't already exist
+                 *  Verify that the loadBalancerPool doesn't already exist
                  */
 
                 if (loadBalancerPoolInterface.neutronLoadBalancerPoolExists(test.getLoadBalancerPoolID())) {
@@ -328,4 +341,73 @@ public class NeutronLoadBalancerPoolNorthbound {
         }
         return Response.status(200).entity(new NeutronLoadBalancerPoolRequest(loadBalancerPoolInterface.getNeutronLoadBalancerPool(loadBalancerPoolID))).build();
     }
+
+    /**
+     * Deletes a LoadBalancerPool
+     */
+
+    @Path("{loadBalancerPoolUUID}")
+    @DELETE
+    @StatusCodes({
+            @ResponseCode(code = 204, condition = "No Content"),
+            @ResponseCode(code = 401, condition = "Unauthorized"),
+            @ResponseCode(code = 404, condition = "Not Found"),
+            @ResponseCode(code = 409, condition = "Conflict"),
+            @ResponseCode(code = 501, condition = "Not Implemented") })
+    public Response deleteLoadBalancerPool(
+            @PathParam("loadBalancerPoolUUID") String loadBalancerPoolUUID) {
+        INeutronLoadBalancerPoolCRUD loadBalancerPoolInterface = NeutronCRUDInterfaces.getINeutronLoadBalancerPoolCRUD(this);
+        if (loadBalancerPoolInterface == null) {
+            throw new ServiceUnavailableException("LoadBalancerPool CRUD Interface "
+                    + RestMessages.SERVICEUNAVAILABLE.toString());
+        }
+
+        /*
+         * verify the LoadBalancerPool exists and it isn't currently in use
+         */
+        if (!loadBalancerPoolInterface.neutronLoadBalancerPoolExists(loadBalancerPoolUUID)) {
+            throw new ResourceNotFoundException("LoadBalancerPool UUID does not exist.");
+        }
+        if (loadBalancerPoolInterface.neutronLoadBalancerPoolInUse(loadBalancerPoolUUID)) {
+            return Response.status(409).build();
+        }
+        NeutronLoadBalancerPool singleton = loadBalancerPoolInterface.getNeutronLoadBalancerPool(loadBalancerPoolUUID);
+        Object[] instances = ServiceHelper.getGlobalInstances(INeutronLoadBalancerPoolAware.class, this, null);
+        if (instances != null) {
+            for (Object instance : instances) {
+                INeutronLoadBalancerPoolAware service = (INeutronLoadBalancerPoolAware) instance;
+                int status = service.canDeleteNeutronLoadBalancerPool(singleton);
+                if (status < 200 || status > 299) {
+                    return Response.status(status).build();
+                }
+            }
+        }
+
+        /*
+         * remove it and return 204 status
+         */
+        loadBalancerPoolInterface.removeNeutronLoadBalancerPool(loadBalancerPoolUUID);
+        if (instances != null) {
+            for (Object instance : instances) {
+                INeutronLoadBalancerPoolAware service = (INeutronLoadBalancerPoolAware) instance;
+                service.neutronLoadBalancerPoolDeleted(singleton);
+            }
+        }
+
+        /*
+         * remove corresponding members from the member cache too
+         */
+        INeutronLoadBalancerPoolMemberCRUD loadBalancerPoolMemberInterface = NeutronCRUDInterfaces.getINeutronLoadBalancerPoolMemberCRUD(this);
+        if (loadBalancerPoolMemberInterface != null) {
+            List<NeutronLoadBalancerPoolMember> allLoadBalancerPoolMembers = new
+                ArrayList<NeutronLoadBalancerPoolMember>(loadBalancerPoolMemberInterface.getAllNeutronLoadBalancerPoolMembers());
+            Iterator<NeutronLoadBalancerPoolMember> i = allLoadBalancerPoolMembers.iterator();
+            while (i.hasNext()) {
+                NeutronLoadBalancerPoolMember member = i.next();
+                if (member.getPoolID() == loadBalancerPoolUUID)
+                    loadBalancerPoolMemberInterface.removeNeutronLoadBalancerPoolMember(member.getPoolMemberID());
+            }
+        }
+        return Response.status(204).build();
+    }
 }