<module name="AvoidStarImport"/>\r
<module name="UpperEll"/>\r
<module name="EmptyStatement"/>\r
+ <module name="EqualsHashCode"/>\r
</module>\r
\r
</module>\r
<artifactId>org.apache.catalina.filters.CorsFilter</artifactId>
<version>7.0.42</version>
</dependency>
+ <dependency>
+ <groupId>org.opendaylight.controller.thirdparty</groupId>
+ <artifactId>ganymed</artifactId>
+ <version>1.0-SNAPSHOT</version>
+ </dependency>
<!-- yang model dependencies -->
<dependency>
<groupId>org.opendaylight.yangtools.model</groupId>
<version>2.4</version>
</dependency>
- <dependency>
+ <dependency>
<groupId>org.opendaylight.yangtools.thirdparty</groupId>
<artifactId>antlr4-runtime-osgi-nohead</artifactId>
<version>4.0</version>
<artifactId>yang-model-api</artifactId>
</dependency>
- <dependency>
- <groupId>org.opendaylight.yangtools.model</groupId>
- <artifactId>yang-ext</artifactId>
- </dependency>
+ <dependency>
+ <groupId>org.opendaylight.yangtools.model</groupId>
+ <artifactId>yang-ext</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.opendaylight.controller.thirdparty</groupId>
+ <artifactId>ganymed</artifactId>
+ </dependency>
</dependencies>
</profile>
</profiles>
final DataBrokerImpl broker;
public DataTransactionImpl(DataBrokerImpl dataBroker) {
+ super(dataBroker);
identifier = new Object();
broker = dataBroker;
status = TransactionStatus.NEW;
*/
Map<P, D> getUpdatedConfigurationData();
+
+
/**
* Returns a set of paths of removed objects.
*
* @return map of paths and original state of updated and removed objectd.
*/
Map<P, D> getOriginalOperationalData();
-
- /**
- * Returns a original subtree of data, which starts at the path
- * where listener was registered.
- *
- */
- D getOriginalConfigurationSubtree();
-
- /**
- * Returns a original subtree of data, which starts at the path
- * where listener was registered.
- *
- */
- D getOriginalOperationalSubtree();
-
- /**
- * Returns a new subtree of data, which starts at the path
- * where listener was registered.
- *
- */
- D getUpdatedConfigurationSubtree();
-
- /**
- * Returns a new subtree of data, which starts at the path
- * where listener was registered.
- *
- */
- D getUpdatedOperationalSubtree();
-
}
public interface DataChangeEvent<P,D> extends DataChange<P, D>, Immutable {
+ /**
+ * Returns a new subtree of data, which starts at the path
+ * where listener was registered.
+ *
+ */
+ D getUpdatedConfigurationSubtree();
+
+ /**
+ * Returns a new subtree of data, which starts at the path
+ * where listener was registered.
+ *
+ */
+ D getUpdatedOperationalSubtree();
}
// import org.opendaylight.yangtools.concepts.Path;
import org.opendaylight.yangtools.yang.common.RpcResult;
-public interface DataModification<P/* extends Path<P> */, D> extends DataReader<P, D> {
+public interface DataModification<P/* extends Path<P> */, D> extends DataChange<P, D>, DataReader<P, D> {
/**
* Returns transaction identifier
TransactionStatus getStatus();
+ /**
+ *
+ * Use {@link #putOperationalData(Object, Object)} instead.
+ *
+ * @param path
+ * @param data
+ */
void putRuntimeData(P path, D data);
+ void putOperationalData(P path, D data);
+
void putConfigurationData(P path, D data);
+ /**
+ * Use {@link #removeOperationalData(Object)}
+ *
+ * @param path
+ */
void removeRuntimeData(P path);
- void removeConfigurationData(P path);
-
- public Map<P, D> getUpdatedConfigurationData();
+ void removeOperationalData(P path);
- public Map<P, D> getUpdatedOperationalData();
-
- public Set<P> getRemovedConfigurationData();
-
- public Set<P> getRemovedOperationalData();
+ void removeConfigurationData(P path);
/**
* Initiates a two-phase commit of modification.
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
import org.opendaylight.controller.md.sal.common.api.data.DataModification;
+import org.opendaylight.controller.md.sal.common.api.data.DataReader;
import org.opendaylight.yangtools.concepts.Path;
import static org.opendaylight.controller.md.sal.common.api.TransactionStatus.NEW;
-public abstract class AbstractDataModification<P /*extends Path<P>*/, D> implements DataModification<P, D> {
+public abstract class AbstractDataModification<P /* extends Path<P> */, D> implements DataModification<P, D> {
- private final Map<P, D> configurationUpdate;
- private final Map<P, D> operationalUpdate;
+ private final ConcurrentMap<P, D> operationalOriginal;
+ private final ConcurrentMap<P, D> configurationOriginal;
- private final Set<P> configurationRemove;
- private final Set<P> operationalRemove;
+ private final ConcurrentMap<P, D> operationalCreated;
+ private final ConcurrentMap<P, D> configurationCreated;
+ private final ConcurrentMap<P, D> configurationUpdate;
+ private final ConcurrentMap<P, D> operationalUpdate;
+
+ private final ConcurrentMap<P, P> configurationRemove;
+ private final ConcurrentMap<P, P> operationalRemove;
+
+ private final Map<P, D> unmodifiable_configurationOriginal;
+ private final Map<P, D> unmodifiable_operationalOriginal;
+ private final Map<P, D> unmodifiable_configurationCreated;
+ private final Map<P, D> unmodifiable_operationalCreated;
private final Map<P, D> unmodifiable_configurationUpdate;
private final Map<P, D> unmodifiable_operationalUpdate;
private final Set<P> unmodifiable_configurationRemove;
private final Set<P> unmodifiable_OperationalRemove;
+ private DataReader<P, D> reader;
+
+ public AbstractDataModification(DataReader<P, D> reader) {
+ this.reader = reader;
+ this.configurationUpdate = new ConcurrentHashMap<>();
+ this.operationalUpdate = new ConcurrentHashMap<>();
+ this.configurationRemove = new ConcurrentHashMap<>();
+ this.operationalRemove = new ConcurrentHashMap<>();
- public AbstractDataModification(Map<P, D> configurationUpdate, Map<P, D> operationalUpdate,
- Set<P> configurationRemove, Set<P> operationalRemove) {
- this.configurationUpdate = configurationUpdate;
- this.operationalUpdate = operationalUpdate;
- this.configurationRemove = configurationRemove;
- this.operationalRemove = operationalRemove;
+ this.configurationOriginal = new ConcurrentHashMap<>();
+ this.operationalOriginal = new ConcurrentHashMap<>();
+ this.configurationCreated = new ConcurrentHashMap<>();
+ this.operationalCreated = new ConcurrentHashMap<>();
+
+ unmodifiable_configurationOriginal = Collections.unmodifiableMap(configurationOriginal);
+ unmodifiable_operationalOriginal = Collections.unmodifiableMap(operationalOriginal);
+ unmodifiable_configurationCreated = Collections.unmodifiableMap(configurationCreated);
+ unmodifiable_operationalCreated = Collections.unmodifiableMap(operationalCreated);
unmodifiable_configurationUpdate = Collections.unmodifiableMap(configurationUpdate);
unmodifiable_operationalUpdate = Collections.unmodifiableMap(operationalUpdate);
- unmodifiable_configurationRemove = Collections.unmodifiableSet(configurationRemove);
- unmodifiable_OperationalRemove = Collections.unmodifiableSet(operationalRemove);
- }
+ unmodifiable_configurationRemove = Collections.unmodifiableSet(configurationRemove.keySet());
+ unmodifiable_OperationalRemove = Collections.unmodifiableSet(operationalRemove.keySet());
- public AbstractDataModification() {
- this(new HashMap<P, D>(), new HashMap<P, D>(), new HashSet<P>(), new HashSet<P>());
}
@Override
public final void putConfigurationData(P path, D data) {
checkMutable();
+
+ if (!hasConfigurationOriginal(path)) {
+ configurationCreated.put(path, data);
+ }
+
configurationUpdate.put(path, data);
configurationRemove.remove(path);
}
@Override
- public final void putRuntimeData(P path, D data) {
+ public final void putOperationalData(P path, D data) {
checkMutable();
+ if (!hasOperationalOriginal(path)) {
+ operationalCreated.put(path, data);
+ }
operationalUpdate.put(path, data);
operationalRemove.remove(path);
}
@Override
- public final void removeRuntimeData(P path) {
+ public final void putRuntimeData(P path, D data) {
+ putRuntimeData(path, data);
+ }
+
+ @Override
+ public final void removeOperationalData(P path) {
checkMutable();
+ hasOperationalOriginal(path);
operationalUpdate.remove(path);
- operationalRemove.add(path);
+ operationalRemove.put(path, path);
+ }
+
+ @Override
+ public final void removeRuntimeData(P path) {
+ removeOperationalData(path);
}
@Override
public final void removeConfigurationData(P path) {
checkMutable();
+ hasConfigurationOriginal(path);
configurationUpdate.remove(path);
- configurationRemove.add(path);
+ configurationRemove.put(path, path);
}
private final void checkMutable() {
}
@Override
- public Map<P, D> getUpdatedConfigurationData() {
+ public final Map<P, D> getUpdatedConfigurationData() {
return unmodifiable_configurationUpdate;
}
@Override
- public Map<P, D> getUpdatedOperationalData() {
+ public final Map<P, D> getUpdatedOperationalData() {
return unmodifiable_operationalUpdate;
}
@Override
- public Set<P> getRemovedConfigurationData() {
+ public final Set<P> getRemovedConfigurationData() {
return unmodifiable_configurationRemove;
}
@Override
- public Set<P> getRemovedOperationalData() {
+ public final Set<P> getRemovedOperationalData() {
return unmodifiable_OperationalRemove;
}
+ @Override
+ public Map<P, D> getCreatedConfigurationData() {
+ return unmodifiable_configurationCreated;
+ }
+
+ @Override
+ public Map<P, D> getCreatedOperationalData() {
+ return unmodifiable_operationalCreated;
+ }
+
+ @Override
+ public Map<P, D> getOriginalConfigurationData() {
+ return unmodifiable_configurationOriginal;
+ }
+
+ @Override
+ public Map<P, D> getOriginalOperationalData() {
+ return unmodifiable_operationalOriginal;
+ }
+
+ @Override
+ public D readOperationalData(P path) {
+ return reader.readOperationalData(path);
+ }
+
+ @Override
+ public D readConfigurationData(P path) {
+ return reader.readConfigurationData(path);
+ }
+
+ private boolean hasConfigurationOriginal(P path) {
+ if (configurationOriginal.containsKey(path)) {
+ return true;
+ }
+ D data = reader.readConfigurationData(path);
+ if (data != null) {
+ configurationOriginal.putIfAbsent(path, data);
+ return true;
+ }
+ return false;
+ }
+
+ private boolean hasOperationalOriginal(P path) {
+ if (operationalOriginal.containsKey(path)) {
+ return true;
+ }
+ D data = reader.readConfigurationData(path);
+ if (data != null) {
+ operationalOriginal.putIfAbsent(path, data);
+ return true;
+ }
+ return false;
+ }
}
<artifactId>netty-handler</artifactId>
<version>${netconf.netty.version}</version>
</dependency>
+ <dependency>
+ <groupId>org.opendaylight.controller.thirdparty</groupId>
+ <artifactId>ganymed</artifactId>
+ </dependency>
</dependencies>
<build>
org.opendaylight.controller.config.stat,
com.google.common.base,
com.google.common.collect,
+ ch.ethz.ssh2,
io.netty.buffer,
io.netty.channel,
io.netty.channel.socket,
--- /dev/null
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.netconf.util.handler.ssh;
+
+import io.netty.channel.ChannelFuture;
+import io.netty.channel.ChannelFutureListener;
+import io.netty.channel.ChannelHandlerContext;
+import io.netty.channel.ChannelOutboundHandlerAdapter;
+import io.netty.channel.ChannelPromise;
+import java.io.IOException;
+import java.net.SocketAddress;
+import org.opendaylight.controller.netconf.util.handler.ssh.authentication.AuthenticationHandler;
+import org.opendaylight.controller.netconf.util.handler.ssh.client.Invoker;
+import org.opendaylight.controller.netconf.util.handler.ssh.client.SshClient;
+import org.opendaylight.controller.netconf.util.handler.ssh.client.SshClientAdapter;
+import org.opendaylight.controller.netconf.util.handler.ssh.virtualsocket.VirtualSocket;
+
+/**
+ * Netty SSH handler class. Acts as interface between Netty and SSH library. All standard Netty message handling
+ * stops at instance of this class. All downstream events are handed of to wrapped {@link org.opendaylight.controller.netconf.util.handler.ssh.client.SshClientAdapter};
+ */
+public class SshHandler extends ChannelOutboundHandlerAdapter {
+ private final VirtualSocket virtualSocket = new VirtualSocket();
+ private final SshClientAdapter sshClientAdapter;
+
+ public SshHandler(AuthenticationHandler authenticationHandler, Invoker invoker) throws IOException {
+ SshClient sshClient = new SshClient(virtualSocket, authenticationHandler);
+ this.sshClientAdapter = new SshClientAdapter(sshClient, invoker);
+ }
+
+ @Override
+ public void handlerAdded(ChannelHandlerContext ctx){
+ if (ctx.channel().pipeline().get("socket") == null) {
+ ctx.channel().pipeline().addFirst("socket", virtualSocket);
+ }
+ }
+
+ @Override
+ public void handlerRemoved(ChannelHandlerContext ctx) throws Exception {
+ if (ctx.channel().pipeline().get("socket") != null) {
+ ctx.channel().pipeline().remove("socket");
+ }
+ }
+
+ @Override
+ public void write(ChannelHandlerContext ctx, Object msg, ChannelPromise promise) throws Exception {
+ this.sshClientAdapter.write((String) msg);
+ }
+
+ @Override
+ public void connect(final ChannelHandlerContext ctx,
+ SocketAddress remoteAddress,
+ SocketAddress localAddress,
+ ChannelPromise promise) throws Exception {
+ ctx.connect(remoteAddress, localAddress, promise);
+
+ promise.addListener(new ChannelFutureListener() {
+ public void operationComplete(ChannelFuture channelFuture) throws Exception {
+ sshClientAdapter.start(ctx);
+ }}
+ );
+ }
+
+ @Override
+ public void disconnect(ChannelHandlerContext ctx, ChannelPromise promise) throws Exception {
+ sshClientAdapter.stop(promise);
+ }
+}
--- /dev/null
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.netconf.util.handler.ssh.authentication;
+
+import ch.ethz.ssh2.Connection;
+
+import java.io.IOException;
+
+/**
+ * Class providing authentication facility to SSH handler.
+ */
+public abstract class AuthenticationHandler {
+ public abstract void authenticate(Connection connection) throws IOException;
+}
--- /dev/null
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.netconf.util.handler.ssh.authentication;
+
+import ch.ethz.ssh2.Connection;
+
+import java.io.IOException;
+
+/**
+ * Class Providing username/password authentication option to {@link org.opendaylight.controller.netconf.util.handler.ssh.SshHandler}
+ */
+public class LoginPassword extends AuthenticationHandler {
+ private final String username;
+ private final String password;
+
+ public LoginPassword(String username, String password) {
+ this.username = username;
+ this.password = password;
+ }
+
+ @Override
+ public void authenticate(Connection connection) throws IOException {
+ boolean isAuthenticated = connection.authenticateWithPassword(username, password);
+
+ if (isAuthenticated == false) throw new IOException("Authentication failed.");
+ }
+}
--- /dev/null
+package org.opendaylight.controller.netconf.util.handler.ssh.client;
+
+import java.io.IOException;
+
+/**
+ * Abstract class providing mechanism of invoking various SSH level services.
+ * Class is not allowed to be extended, as it provides its own implementations via instance initiators.
+ */
+public abstract class Invoker {
+ private boolean invoked = false;
+
+ private Invoker(){}
+
+ protected boolean isInvoked() {
+ return invoked;
+ }
+
+ abstract void invoke(SshSession session) throws IOException;
+
+ /**
+ * Invoker implementation to invokes subsystem SSH service.
+ *
+ * @param subsystem
+ * @return
+ */
+ public static Invoker subsystem(final String subsystem) {
+ return new Invoker() {
+ @Override
+ void invoke(SshSession session) throws IOException {
+ if (isInvoked() == true) throw new IllegalStateException("Already invoked.");
+
+ session.startSubSystem(subsystem);
+ }
+ };
+ }
+}
--- /dev/null
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.netconf.util.handler.ssh.client;
+
+import ch.ethz.ssh2.Connection;
+import ch.ethz.ssh2.Session;
+import ch.ethz.ssh2.channel.Channel;
+import org.opendaylight.controller.netconf.util.handler.ssh.authentication.AuthenticationHandler;
+import org.opendaylight.controller.netconf.util.handler.ssh.virtualsocket.VirtualSocket;
+
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.Map;
+
+
+/**
+ * Wrapper class around GANYMED SSH java library.
+ */
+public class SshClient {
+ private final VirtualSocket socket;
+ private final Map<Integer, SshSession> openSessions = new HashMap();
+ private final AuthenticationHandler authenticationHandler;
+ private Connection connection;
+
+ public SshClient(VirtualSocket socket,
+ AuthenticationHandler authenticationHandler) throws IOException {
+ this.socket = socket;
+ this.authenticationHandler = authenticationHandler;
+ }
+
+ public SshSession openSession() throws IOException {
+ if(connection == null) connect();
+
+ Session session = connection.openSession();
+ SshSession sshSession = new SshSession(session);
+ openSessions.put(openSessions.size(), sshSession);
+
+ return sshSession;
+ }
+
+ private void connect() throws IOException {
+ connection = new Connection(socket);
+ connection.connect();
+ authenticationHandler.authenticate(connection);
+ }
+
+ public void closeSession(SshSession session) {
+ if( session.getState() == Channel.STATE_OPEN
+ || session.getState() == Channel.STATE_OPENING) {
+ session.session.close();
+ }
+ }
+
+ public void close() {
+ for(SshSession session : openSessions.values()) closeSession(session);
+
+ openSessions.clear();
+
+ if(connection != null) connection.close();
+ }
+}
--- /dev/null
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.netconf.util.handler.ssh.client;
+
+import io.netty.buffer.ByteBuf;
+import io.netty.buffer.Unpooled;
+import io.netty.channel.ChannelHandlerContext;
+import io.netty.channel.ChannelPromise;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.util.concurrent.atomic.AtomicBoolean;
+import org.opendaylight.controller.netconf.util.handler.ssh.virtualsocket.VirtualSocketException;
+
+/**
+ * Worker thread class. Handles all downstream and upstream events in SSH Netty pipeline.
+ */
+public class SshClientAdapter implements Runnable {
+ private final SshClient sshClient;
+ private final Invoker invoker;
+
+ private SshSession session;
+ private InputStream stdOut;
+ private InputStream stdErr;
+ private OutputStream stdIn;
+
+ private ChannelHandlerContext ctx;
+ private ChannelPromise disconnectPromise;
+
+ private final AtomicBoolean stopRequested = new AtomicBoolean(false);
+
+ private final Object lock = new Object();
+
+ public SshClientAdapter(SshClient sshClient,
+ Invoker invoker) {
+ this.sshClient = sshClient;
+ this.invoker = invoker;
+ }
+
+ public void run() {
+ try {
+ session = sshClient.openSession();
+ invoker.invoke(session);
+
+ stdOut = session.getStdout();
+ stdErr = session.getStderr();
+
+ synchronized(lock) {
+ stdIn = session.getStdin();
+ }
+
+ while (stopRequested.get() == false) {
+ byte[] readBuff = new byte[1024];
+ int c = stdOut.read(readBuff);
+
+ byte[] tranBuff = new byte[c];
+ System.arraycopy(readBuff, 0, tranBuff, 0, c);
+
+ ByteBuf byteBuf = Unpooled.buffer(c);
+ byteBuf.writeBytes(tranBuff);
+ ctx.fireChannelRead(byteBuf);
+ }
+
+ } catch (VirtualSocketException e) {
+ // Netty closed connection prematurely.
+ // Just pass and move on.
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ } finally {
+ sshClient.close();
+
+ synchronized (lock) {
+ if(disconnectPromise != null) ctx.disconnect(disconnectPromise);
+ }
+ }
+ }
+
+ // TODO: needs rework to match netconf framer API.
+ public void write(String message) throws IOException {
+ synchronized (lock) {
+ if (stdIn == null) throw new IllegalStateException("StdIn not available");
+ }
+ stdIn.write(message.getBytes());
+ stdIn.flush();
+ }
+
+ public void stop(ChannelPromise promise) {
+ synchronized (lock) {
+ stopRequested.set(true);
+ disconnectPromise = promise;
+ }
+ }
+
+ public void start(ChannelHandlerContext ctx) {
+ if(this.ctx != null) return; // context is already associated.
+
+ this.ctx = ctx;
+ new Thread(this).start();
+ }
+}
--- /dev/null
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.netconf.util.handler.ssh.client;
+
+import ch.ethz.ssh2.Session;
+import ch.ethz.ssh2.StreamGobbler;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+
+/**
+ * Wrapper class for proprietary SSH sessions implementations
+ */
+public class SshSession {
+ final Session session;
+
+ public SshSession(Session session) {
+ this.session = session;
+ }
+
+ public void execCommand(String cmd) throws IOException {
+ session.execCommand(cmd);
+ }
+
+ public void execCommand(String cmd, String charsetName) throws IOException {
+ session.execCommand(cmd, charsetName);
+ }
+
+ public void startShell() throws IOException {
+ session.startShell();
+ }
+
+ public void startSubSystem(String name) throws IOException {
+ session.startSubSystem(name);
+ }
+
+ public int getState() {
+ return session.getState();
+ }
+
+ public InputStream getStdout() {
+ return new StreamGobbler(session.getStdout());
+ }
+
+ public InputStream getStderr() {
+ return session.getStderr();
+ }
+
+ public OutputStream getStdin() {
+ return session.getStdin();
+ }
+
+ public int waitUntilDataAvailable(long timeout) throws IOException {
+ return session.waitUntilDataAvailable(timeout);
+ }
+
+ public int waitForCondition(int condition_set, long timeout) {
+ return session.waitForCondition(condition_set, timeout);
+ }
+
+ public Integer getExitStatus() {
+ return session.getExitStatus();
+ }
+
+ public String getExitSignal() {
+ return session.getExitSignal();
+ }
+}
--- /dev/null
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.netconf.util.handler.ssh.virtualsocket;
+
+import io.netty.buffer.ByteBuf;
+import io.netty.buffer.Unpooled;
+import io.netty.channel.ChannelHandlerContext;
+import io.netty.channel.ChannelInboundHandler;
+
+import java.io.IOException;
+import java.io.InputStream;
+
+/**
+ * Class provides {@link InputStream} functionality to users of virtual socket.
+ */
+public class ChannelInputStream extends InputStream implements ChannelInboundHandler {
+ private final Object lock = new Object();
+ private final ByteBuf bb = Unpooled.buffer();
+
+ @Override
+ public int read(byte b[], int off, int len) throws IOException {
+ if (b == null) {
+ throw new NullPointerException();
+ } else if (off < 0 || len < 0 || len > b.length - off) {
+ throw new IndexOutOfBoundsException();
+ } else if (len == 0) {
+ return 0;
+ }
+
+ int bytesRead = 1;
+ synchronized (lock) {
+ int c = read();
+
+ b[off] = (byte)c;
+
+ if(this.bb.readableBytes() == 0) return bytesRead;
+
+ int ltr = len-1;
+ ltr = (ltr <= bb.readableBytes()) ? ltr : bb.readableBytes();
+
+ bb.readBytes(b, 1, ltr);
+ bytesRead += ltr;
+ }
+ return bytesRead;
+ }
+
+ @Override
+ public int read() throws IOException {
+ synchronized (lock) {
+ while (this.bb.readableBytes() == 0) {
+ try {
+ lock.wait();
+ } catch (InterruptedException e) {
+ throw new RuntimeException(e);
+ }
+ }
+ return this.bb.readByte() & 0xFF;
+ }
+ }
+
+ @Override
+ public int available() throws IOException {
+ synchronized (lock) {
+ return this.bb.readableBytes();
+ }
+ }
+
+ public void channelRegistered(ChannelHandlerContext ctx)
+ throws Exception {
+ ctx.fireChannelRegistered();
+ }
+
+ public void channelUnregistered(ChannelHandlerContext ctx)
+ throws Exception {
+ ctx.fireChannelUnregistered();
+ }
+
+ public void channelActive(ChannelHandlerContext ctx)
+ throws Exception {
+ ctx.fireChannelActive();
+ }
+
+ public void channelInactive(ChannelHandlerContext ctx)
+ throws Exception {
+ ctx.fireChannelInactive();
+ }
+
+ public void channelRead(ChannelHandlerContext ctx, Object o)
+ throws Exception {
+ synchronized(lock) {
+ this.bb.discardReadBytes();
+ this.bb.writeBytes((ByteBuf) o);
+ lock.notifyAll();
+ }
+ }
+
+ public void channelReadComplete(ChannelHandlerContext ctx)
+ throws Exception {
+ ctx.fireChannelReadComplete();
+ }
+
+ public void userEventTriggered(ChannelHandlerContext ctx, Object o)
+ throws Exception {
+ ctx.fireUserEventTriggered(o);
+ }
+
+ public void channelWritabilityChanged(ChannelHandlerContext ctx)
+ throws Exception {
+ ctx.fireChannelWritabilityChanged();
+ }
+
+ public void handlerAdded(ChannelHandlerContext ctx)
+ throws Exception {
+ }
+
+ public void handlerRemoved(ChannelHandlerContext ctx)
+ throws Exception {
+ }
+
+ public void exceptionCaught(ChannelHandlerContext ctx, Throwable throwable)
+ throws Exception {
+ ctx.fireExceptionCaught(throwable);
+ }
+}
+
--- /dev/null
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.netconf.util.handler.ssh.virtualsocket;
+
+import io.netty.buffer.ByteBuf;
+import io.netty.buffer.Unpooled;
+import io.netty.channel.ChannelHandlerContext;
+import io.netty.channel.ChannelOutboundHandler;
+import io.netty.channel.ChannelPromise;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.net.SocketAddress;
+
+/**
+ * Class provides {@link OutputStream) functionality to users of virtual socket.
+ */
+public class ChannelOutputStream extends OutputStream implements ChannelOutboundHandler {
+ private final Object lock = new Object();
+ private ByteBuf buff = Unpooled.buffer();
+ private ChannelHandlerContext ctx;
+
+ @Override
+ public void flush() throws IOException {
+ synchronized(lock) {
+ ctx.writeAndFlush(buff).awaitUninterruptibly();
+ buff = Unpooled.buffer();
+ }
+ }
+
+ @Override
+ public void write(int b) throws IOException {
+ synchronized(lock) {
+ buff.writeByte(b);
+ }
+ }
+
+ public void bind(ChannelHandlerContext ctx, SocketAddress localAddress,
+ ChannelPromise promise) throws Exception {
+ ctx.bind(localAddress, promise);
+ }
+
+ public void connect(ChannelHandlerContext ctx, SocketAddress remoteAddress,
+ SocketAddress localAddress, ChannelPromise promise)
+ throws Exception {
+ this.ctx = ctx;
+ ctx.connect(remoteAddress, localAddress, promise);
+ }
+
+ public void disconnect(ChannelHandlerContext ctx, ChannelPromise promise)
+ throws Exception {
+ ctx.disconnect(promise);
+ }
+
+ public void close(ChannelHandlerContext ctx, ChannelPromise promise)
+ throws Exception {
+ ctx.close(promise);
+ }
+
+ public void deregister(ChannelHandlerContext ctx, ChannelPromise channelPromise)
+ throws Exception {
+ ctx.deregister(channelPromise);
+ }
+
+ public void read(ChannelHandlerContext ctx)
+ throws Exception {
+ ctx.read();
+ }
+
+ public void write(ChannelHandlerContext ctx, Object msg, ChannelPromise promise)
+ throws Exception {
+ // pass
+ }
+
+ public void flush(ChannelHandlerContext ctx)
+ throws Exception {
+ // pass
+ }
+
+ public void handlerAdded(ChannelHandlerContext ctx)
+ throws Exception {
+ }
+
+ public void handlerRemoved(ChannelHandlerContext ctx)
+ throws Exception {
+ }
+
+ public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause)
+ throws Exception {
+ ctx.fireExceptionCaught(cause);
+ }
+}
--- /dev/null
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.netconf.util.handler.ssh.virtualsocket;
+
+import io.netty.channel.ChannelHandler;
+import io.netty.channel.ChannelHandlerContext;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.net.InetAddress;
+import java.net.InetSocketAddress;
+import java.net.Socket;
+import java.net.SocketAddress;
+import java.net.SocketException;
+import java.nio.channels.SocketChannel;
+
+/**
+ * Handler class providing Socket functionality to OIO client application. By using VirtualSocket user can
+ * use OIO application in asynchronous environment and NIO EventLoop. Using VirtualSocket OIO applications
+ * are able to use full potential of NIO environment.
+ */
+public class VirtualSocket extends Socket implements ChannelHandler {
+ private final ChannelInputStream chis = new ChannelInputStream();
+ private final ChannelOutputStream chos = new ChannelOutputStream();
+ private ChannelHandlerContext ctx;
+
+
+ public InputStream getInputStream() {
+ return this.chis;
+ }
+
+ public OutputStream getOutputStream() {
+ return this.chos;
+ }
+
+ public void handlerAdded(ChannelHandlerContext ctx) throws Exception {
+ this.ctx = ctx;
+
+ if (ctx.channel().pipeline().get("outputStream") == null) {
+ ctx.channel().pipeline().addFirst("outputStream", chos);
+ }
+
+ if (ctx.channel().pipeline().get("inputStream") == null) {
+ ctx.channel().pipeline().addFirst("inputStream", chis);
+ }
+ }
+
+ public void handlerRemoved(ChannelHandlerContext ctx) throws Exception {
+ if (ctx.channel().pipeline().get("outputStream") != null) {
+ ctx.channel().pipeline().remove("outputStream");
+ }
+
+ if (ctx.channel().pipeline().get("inputStream") != null) {
+ ctx.channel().pipeline().remove("inputStream");
+ }
+ }
+
+ public void exceptionCaught(ChannelHandlerContext ctx, Throwable throwable) throws Exception {
+ ctx.fireExceptionCaught(throwable);
+ }
+
+ public VirtualSocket() {super();}
+
+ @Override
+ public void connect(SocketAddress endpoint) throws IOException {}
+
+ @Override
+ public void connect(SocketAddress endpoint, int timeout) throws IOException {}
+
+ @Override
+ public void bind(SocketAddress bindpoint) throws IOException {}
+
+ @Override
+ public InetAddress getInetAddress() {
+ InetSocketAddress isa = getInetSocketAddress();
+
+ if (isa == null) throw new VirtualSocketException();
+
+ return getInetSocketAddress().getAddress();
+ }
+
+ @Override
+ public InetAddress getLocalAddress() {return null;}
+
+ @Override
+ public int getPort() {
+ return getInetSocketAddress().getPort();
+ }
+
+ private InetSocketAddress getInetSocketAddress() {
+ return (InetSocketAddress)getRemoteSocketAddress();
+ }
+
+ @Override
+ public int getLocalPort() {return -1;}
+
+ @Override
+ public SocketAddress getRemoteSocketAddress() {
+ return this.ctx.channel().remoteAddress();
+ }
+
+ @Override
+ public SocketAddress getLocalSocketAddress() {
+ return this.ctx.channel().localAddress();
+ }
+
+ @Override
+ public SocketChannel getChannel() {return null;}
+
+ @Override
+ public void setTcpNoDelay(boolean on) throws SocketException {}
+
+ @Override
+ public boolean getTcpNoDelay() throws SocketException {return false;}
+
+ @Override
+ public void setSoLinger(boolean on, int linger) throws SocketException {}
+
+ @Override
+ public int getSoLinger() throws SocketException {return -1;}
+
+ @Override
+ public void sendUrgentData(int data) throws IOException {}
+
+ @Override
+ public void setOOBInline(boolean on) throws SocketException {}
+
+ @Override
+ public boolean getOOBInline() throws SocketException {return false;}
+
+ @Override
+ public synchronized void setSoTimeout(int timeout) throws SocketException {}
+
+ @Override
+ public synchronized int getSoTimeout() throws SocketException {return -1;}
+
+ @Override
+ public synchronized void setSendBufferSize(int size) throws SocketException {}
+
+ @Override
+ public synchronized int getSendBufferSize() throws SocketException {return -1;}
+
+ @Override
+ public synchronized void setReceiveBufferSize(int size) throws SocketException {}
+
+ @Override
+ public synchronized int getReceiveBufferSize() throws SocketException {return -1;}
+
+ @Override
+ public void setKeepAlive(boolean on) throws SocketException {}
+
+ @Override
+ public boolean getKeepAlive() throws SocketException {return false;}
+
+ @Override
+ public void setTrafficClass(int tc) throws SocketException {}
+
+ @Override
+ public int getTrafficClass() throws SocketException {return -1;}
+
+ @Override
+ public void setReuseAddress(boolean on) throws SocketException {}
+
+ @Override
+ public boolean getReuseAddress() throws SocketException {return false;}
+
+ @Override
+ public synchronized void close() throws IOException {}
+
+ @Override
+ public void shutdownInput() throws IOException {}
+
+ @Override
+ public void shutdownOutput() throws IOException {}
+
+ @Override
+ public String toString() {
+ return "Virtual socket InetAdress["+getInetAddress()+"], Port["+getPort()+"]";
+ }
+
+ @Override
+ public boolean isConnected() {return false;}
+
+ @Override
+ public boolean isBound() {return false;}
+
+ @Override
+ public boolean isClosed() {return false;}
+
+ @Override
+ public boolean isInputShutdown() {return false;}
+
+ @Override
+ public boolean isOutputShutdown() {return false;}
+
+ @Override
+ public void setPerformancePreferences(int connectionTime, int latency, int bandwidth) {}
+}
--- /dev/null
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.netconf.util.handler.ssh.virtualsocket;
+
+/**
+ * Exception class which provides notification about exceptional situations at the virtual socket layer.
+ */
+public class VirtualSocketException extends RuntimeException {
+}
<module>config-persister-impl</module>
<module>netconf-mapping-api</module>
<module>netconf-client</module>
+ <module>../../third-party/ganymed</module>
</modules>
<profiles>
}\r
\r
public boolean isEnableDHCP() {\r
- if (enableDHCP == null)\r
+ if (enableDHCP == null) {\r
return true;\r
+ }\r
return enableDHCP;\r
}\r
\r
public Boolean getEnableDHCP() { return enableDHCP; }\r
\r
public void setEnableDHCP(Boolean newValue) {\r
- this.enableDHCP = newValue;\r
+ enableDHCP = newValue;\r
}\r
\r
public String getTenantID() {\r
Iterator<String> i = fields.iterator();\r
while (i.hasNext()) {\r
String s = i.next();\r
- if (s.equals("id"))\r
+ if (s.equals("id")) {\r
ans.setSubnetUUID(this.getSubnetUUID());\r
- if (s.equals("network_id"))\r
+ }\r
+ if (s.equals("network_id")) {\r
ans.setNetworkUUID(this.getNetworkUUID());\r
- if (s.equals("name"))\r
+ }\r
+ if (s.equals("name")) {\r
ans.setName(this.getName());\r
- if (s.equals("ip_version"))\r
+ }\r
+ if (s.equals("ip_version")) {\r
ans.setIpVersion(this.getIpVersion());\r
- if (s.equals("cidr"))\r
+ }\r
+ if (s.equals("cidr")) {\r
ans.setCidr(this.getCidr());\r
- if (s.equals("gateway_ip"))\r
+ }\r
+ if (s.equals("gateway_ip")) {\r
ans.setGatewayIP(this.getGatewayIP());\r
+ }\r
if (s.equals("dns_nameservers")) {\r
List<String> nsList = new ArrayList<String>();\r
nsList.addAll(this.getDnsNameservers());\r
hRoutes.addAll(this.getHostRoutes());\r
ans.setHostRoutes(hRoutes);\r
}\r
- if (s.equals("enable_dhcp"))\r
+ if (s.equals("enable_dhcp")) {\r
ans.setEnableDHCP(this.getEnableDHCP());\r
- if (s.equals("tenant_id"))\r
+ }\r
+ if (s.equals("tenant_id")) {\r
ans.setTenantID(this.getTenantID());\r
+ }\r
}\r
return ans;\r
}\r
try {\r
SubnetUtils util = new SubnetUtils(cidr);\r
SubnetInfo info = util.getInfo();\r
- if (!info.getNetworkAddress().equals(info.getAddress()))\r
+ if (!info.getNetworkAddress().equals(info.getAddress())) {\r
return false;\r
+ }\r
} catch (Exception e) {\r
return false;\r
}\r
Iterator<NeutronSubnet_IPAllocationPool> i = allocationPools.iterator();\r
while (i.hasNext()) {\r
NeutronSubnet_IPAllocationPool pool = i.next();\r
- if (pool.contains(gatewayIP))\r
+ if (pool.contains(gatewayIP)) {\r
return true;\r
+ }\r
}\r
return false;\r
}\r
\r
- public void initDefaults() {\r
- if (enableDHCP == null)\r
+ public boolean initDefaults() {\r
+ if (enableDHCP == null) {\r
enableDHCP = true;\r
- if (ipVersion == null)\r
+ }\r
+ if (ipVersion == null) {\r
ipVersion = 4;\r
+ }\r
gatewayIPAssigned = false;\r
dnsNameservers = new ArrayList<String>();\r
allocationPools = new ArrayList<NeutronSubnet_IPAllocationPool>();\r
try {\r
SubnetUtils util = new SubnetUtils(cidr);\r
SubnetInfo info = util.getInfo();\r
- if (gatewayIP == null)\r
+ if (gatewayIP == null) {\r
gatewayIP = info.getLowAddress();\r
+ }\r
if (allocationPools.size() < 1) {\r
NeutronSubnet_IPAllocationPool source =\r
new NeutronSubnet_IPAllocationPool(info.getLowAddress(),\r
allocationPools = source.splitPool(gatewayIP);\r
}\r
} catch (Exception e) {\r
+ return false;\r
}\r
+ return true;\r
}\r
\r
public List<NeutronPort> getPortsInSubnet() {\r
* available allocation pools or not\r
*/\r
public boolean isIPInUse(String ipAddress) {\r
- if (ipAddress.equals(gatewayIP) && !gatewayIPAssigned )\r
+ if (ipAddress.equals(gatewayIP) && !gatewayIPAssigned ) {\r
return false;\r
+ }\r
Iterator<NeutronSubnet_IPAllocationPool> i = allocationPools.iterator();\r
while (i.hasNext()) {\r
NeutronSubnet_IPAllocationPool pool = i.next();\r
- if (pool.contains(ipAddress))\r
+ if (pool.contains(ipAddress)) {\r
return false;\r
+ }\r
}\r
return true;\r
}\r
}\r
else\r
if (NeutronSubnet_IPAllocationPool.convert(pool.getPoolStart()) <\r
- NeutronSubnet_IPAllocationPool.convert(ans))\r
+ NeutronSubnet_IPAllocationPool.convert(ans)) {\r
ans = pool.getPoolStart();\r
+ }\r
}\r
return ans;\r
}\r
if (pool.contains(ipAddress)) {\r
List<NeutronSubnet_IPAllocationPool> pools = pool.splitPool(ipAddress);\r
newList.addAll(pools);\r
- } else\r
+ } else {\r
newList.add(pool);\r
+ }\r
}\r
}\r
allocationPools = newList;\r
NeutronSubnet_IPAllocationPool pool = i.next();\r
long lIP = NeutronSubnet_IPAllocationPool.convert(pool.getPoolStart());\r
long hIP = NeutronSubnet_IPAllocationPool.convert(pool.getPoolEnd());\r
- if (sIP+1 == lIP)\r
+ if (sIP+1 == lIP) {\r
hPool = pool;\r
- if (sIP-1 == hIP)\r
+ }\r
+ if (sIP-1 == hIP) {\r
lPool = pool;\r
+ }\r
}\r
//if (lPool == NULL and hPool == NULL) create new pool where low = ip = high\r
- if (lPool == null && hPool == null)\r
+ if (lPool == null && hPool == null) {\r
allocationPools.add(new NeutronSubnet_IPAllocationPool(ipAddress,ipAddress));\r
+ }\r
//if (lPool == NULL and hPool != NULL) change low address of hPool to ipAddr\r
- if (lPool == null && hPool != null)\r
+ if (lPool == null && hPool != null) {\r
hPool.setPoolStart(ipAddress);\r
+ }\r
//if (lPool != NULL and hPool == NULL) change high address of lPool to ipAddr\r
- if (lPool != null && hPool == null)\r
+ if (lPool != null && hPool == null) {\r
lPool.setPoolEnd(ipAddress);\r
+ }\r
//if (lPool != NULL and hPool != NULL) remove lPool and hPool and create new pool\r
// where low address = lPool.low address and high address = hPool.high Address\r
if (lPool != null && hPool != null) {\r
import java.util.Map;
import javax.ws.rs.Consumes;
+import javax.ws.rs.DELETE;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
* @param nodeId Node Identifier of the node with the management session.
* @param bridgeName Name / Identifier for a bridge to be created.
* @param bridgeConfigs Additional Bridge Configurations.
+ * It takes in complex structures under the ConfigConstants.CUSTOM key.
+ * The use-cases are documented under wiki.opendaylight.org project pages:
+ * https://wiki.opendaylight.org/view/OVSDB_Integration:Mininet_OVSDB_Tutorial
*/
@Path("/bridge/{nodeType}/{nodeId}/{bridgeName}")
throw new ResourceNotFoundException(status.getDescription());
}
+
+ /**
+ * Remove a Bridge.
+ * <pre>
+ *
+ * Example :
+ *
+ * Request :
+ * DELETE
+ * http://localhost:8080/controller/nb/v2/networkconfig/bridgedomain/bridge/STUB/mgmt1/bridge1
+ *
+ *</pre>
+ * @param nodeType Node Type of the node with the management session.
+ * @param nodeId Node Identifier of the node with the management session.
+ * @param bridgeName Name / Identifier for a bridge to be deleted.
+ */
+
+ @Path("/bridge/{nodeType}/{nodeId}/{bridgeName}")
+ @DELETE
+ @StatusCodes( { @ResponseCode(code = 200, condition = "Bridge deleted successfully"),
+ @ResponseCode(code = 404, condition = "Could not delete Bridge"),
+ @ResponseCode(code = 412, condition = "Failed to delete Bridge due to an exception"),
+ @ResponseCode(code = 503, condition = "Bridge Domain Configuration Service not available")} )
+
+ public Response deleteBridge(
+ @PathParam(value = "nodeType") String nodeType,
+ @PathParam(value = "nodeId") String nodeId,
+ @PathParam(value = "bridgeName") String name) {
+
+ IBridgeDomainConfigService configurationService = getConfigurationService();
+ if (configurationService == null) {
+ throw new ServiceUnavailableException("IBridgeDomainConfigService not available.");
+ }
+
+ Node node = Node.fromString(nodeType, nodeId);
+ Status status = null;
+ try {
+ status = configurationService.deleteBridgeDomain(node, name);
+ if (status.getCode().equals(StatusCode.SUCCESS)) {
+ return Response.status(Response.Status.OK).build();
+ }
+ } catch (Throwable t) {
+ return Response.status(Response.Status.PRECONDITION_FAILED).build();
+ }
+ throw new ResourceNotFoundException(status.getDescription());
+ }
+
/**
* Add a Port to a Bridge
* <pre>
* @param bridgeName Name / Identifier of the bridge to which a Port is being added.
* @param portName Name / Identifier of a Port that is being added to a bridge.
* @param portConfigs Additional Port Configurations.
+ * It takes in complex structures under the ConfigConstants.CUSTOM key.
+ * The use-cases are documented under wiki.opendaylight.org project pages :
+ * https://wiki.opendaylight.org/view/OVSDB_Integration:Mininet_OVSDB_Tutorial
*/
@Path("/port/{nodeType}/{nodeId}/{bridgeName}/{portName}")
throw new ResourceNotFoundException(status.getDescription());
}
+ /**
+ * Remove a Port from a Bridge
+ * <pre>
+ *
+ * Example :
+ *
+ * Request :
+ * DELETE
+ * http://localhost:8080/controller/nb/v2/networkconfig/bridgedomain/port/STUB/mgmt1/bridge1/port1
+ *
+ *</pre>
+ * @param nodeType Node Type of the node with the management session.
+ * @param nodeId Node Identifier of the node with the management session.
+ * @param bridgeName Name / Identifier of the bridge to which a Port is being added.
+ * @param portName Name / Identifier of a Port that is being deleted from a bridge.
+ */
+
+ @Path("/port/{nodeType}/{nodeId}/{bridgeName}/{portName}")
+ @DELETE
+ @Consumes({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})
+ @StatusCodes( { @ResponseCode(code = 200, condition = "Port deleted successfully"),
+ @ResponseCode(code = 404, condition = "Could not delete Port to the Bridge"),
+ @ResponseCode(code = 412, condition = "Failed to delete Port due to an exception"),
+ @ResponseCode(code = 503, condition = "Bridge Domain Configuration Service not available")} )
+
+ public Response deletePort(
+ @PathParam(value = "nodeType") String nodeType,
+ @PathParam(value = "nodeId") String nodeId,
+ @PathParam(value = "bridgeName") String bridge,
+ @PathParam(value = "portName") String port) {
+
+ IBridgeDomainConfigService configurationService = getConfigurationService();
+ if (configurationService == null) {
+ throw new ServiceUnavailableException("IBridgeDomainConfigService not available.");
+ }
+
+ Node node = Node.fromString(nodeType, nodeId);
+ Status status = null;
+ try {
+ status = configurationService.deletePort(node, bridge, port);
+ if (status.getCode().equals(StatusCode.SUCCESS)) {
+ return Response.status(Response.Status.OK).build();
+ }
+ } catch (Throwable t) {
+ return Response.status(Response.Status.PRECONDITION_FAILED).build();
+ }
+ throw new ResourceNotFoundException(status.getDescription());
+ }
+
private Map<ConfigConstants, Object> buildConfig(Map<String, Object> rawConfigs) {
if (rawConfigs == null) return null;
Map<ConfigConstants, Object> configs = new HashMap<ConfigConstants, Object>();
</init-param>
<init-param>
<param-name>cors.allowed.methods</param-name>
- <param-value>GET,POST,HEAD,OPTIONS,PUT</param-value>
+ <param-value>GET,POST,DELETE,HEAD,OPTIONS,PUT</param-value>
</init-param>
<init-param>
<param-name>cors.allowed.headers</param-name>
import org.opendaylight.controller.networkconfig.neutron.NeutronCRUDInterfaces;\r
import org.opendaylight.controller.networkconfig.neutron.NeutronSubnet;\r
import org.opendaylight.controller.northbound.commons.RestMessages;\r
+import org.opendaylight.controller.northbound.commons.exception.InternalServerErrorException;\r
import org.opendaylight.controller.northbound.commons.exception.ServiceUnavailableException;\r
import org.opendaylight.controller.sal.utils.ServiceHelper;\r
\r
(queryGatewayIP == null || queryGatewayIP.equals(oSS.getGatewayIP())) &&\r
(queryEnableDHCP == null || queryEnableDHCP.equals(oSS.getEnableDHCP())) &&\r
(queryTenantID == null || queryTenantID.equals(oSS.getTenantID()))) {\r
- if (fields.size() > 0)\r
+ if (fields.size() > 0) {\r
ans.add(extractFields(oSS,fields));\r
- else\r
+ } else {\r
ans.add(oSS);\r
+ }\r
}\r
}\r
//TODO: apply pagination to results\r
throw new ServiceUnavailableException("Subnet CRUD Interface "\r
+ RestMessages.SERVICEUNAVAILABLE.toString());\r
}\r
- if (!subnetInterface.subnetExists(subnetUUID))\r
+ if (!subnetInterface.subnetExists(subnetUUID)) {\r
return Response.status(404).build();\r
+ }\r
if (fields.size() > 0) {\r
NeutronSubnet ans = subnetInterface.getSubnet(subnetUUID);\r
return Response.status(200).entity(\r
new NeutronSubnetRequest(extractFields(ans, fields))).build();\r
- } else\r
+ } else {\r
return Response.status(200).entity(\r
new NeutronSubnetRequest(subnetInterface.getSubnet(subnetUUID))).build();\r
+ }\r
}\r
\r
/**\r
* and that the gateway IP doesn't overlap with the allocation pools\r
* *then* add the subnet to the cache\r
*/\r
- if (subnetInterface.subnetExists(singleton.getID()))\r
+ if (subnetInterface.subnetExists(singleton.getID())) {\r
return Response.status(400).build();\r
- if (!networkInterface.networkExists(singleton.getNetworkUUID()))\r
+ }\r
+ if (!networkInterface.networkExists(singleton.getNetworkUUID())) {\r
return Response.status(404).build();\r
- if (!singleton.isValidCIDR())\r
+ }\r
+ if (!singleton.isValidCIDR()) {\r
return Response.status(400).build();\r
- singleton.initDefaults();\r
- if (singleton.gatewayIP_Pool_overlap())\r
+ }\r
+ if (!singleton.initDefaults()) {\r
+ throw new InternalServerErrorException("subnet object could not be initialized properly");\r
+ }\r
+ if (singleton.gatewayIP_Pool_overlap()) {\r
return Response.status(409).build();\r
+ }\r
Object[] instances = ServiceHelper.getGlobalInstances(INeutronSubnetAware.class, this, null);\r
if (instances != null) {\r
for (Object instance : instances) {\r
INeutronSubnetAware service = (INeutronSubnetAware) instance;\r
int status = service.canCreateSubnet(singleton);\r
- if (status < 200 || status > 299)\r
+ if (status < 200 || status > 299) {\r
return Response.status(status).build();\r
+ }\r
}\r
}\r
subnetInterface.addSubnet(singleton);\r
* and that the bulk request doesn't already contain a subnet with this id\r
*/\r
\r
- test.initDefaults();\r
- if (subnetInterface.subnetExists(test.getID()))\r
+ if (!test.initDefaults()) {\r
+ throw new InternalServerErrorException("subnet object could not be initialized properly");\r
+ }\r
+ if (subnetInterface.subnetExists(test.getID())) {\r
return Response.status(400).build();\r
- if (testMap.containsKey(test.getID()))\r
+ }\r
+ if (testMap.containsKey(test.getID())) {\r
return Response.status(400).build();\r
+ }\r
testMap.put(test.getID(), test);\r
- if (!networkInterface.networkExists(test.getNetworkUUID()))\r
+ if (!networkInterface.networkExists(test.getNetworkUUID())) {\r
return Response.status(404).build();\r
- if (!test.isValidCIDR())\r
+ }\r
+ if (!test.isValidCIDR()) {\r
return Response.status(400).build();\r
- if (test.gatewayIP_Pool_overlap())\r
+ }\r
+ if (test.gatewayIP_Pool_overlap()) {\r
return Response.status(409).build();\r
+ }\r
if (instances != null) {\r
for (Object instance : instances) {\r
INeutronSubnetAware service = (INeutronSubnetAware) instance;\r
int status = service.canCreateSubnet(test);\r
- if (status < 200 || status > 299)\r
+ if (status < 200 || status > 299) {\r
return Response.status(status).build();\r
+ }\r
}\r
}\r
}\r
/*\r
* verify the subnet exists and there is only one delta provided\r
*/\r
- if (!subnetInterface.subnetExists(subnetUUID))\r
+ if (!subnetInterface.subnetExists(subnetUUID)) {\r
return Response.status(404).build();\r
- if (!input.isSingleton())\r
+ }\r
+ if (!input.isSingleton()) {\r
return Response.status(400).build();\r
+ }\r
NeutronSubnet delta = input.getSingleton();\r
NeutronSubnet original = subnetInterface.getSubnet(subnetUUID);\r
\r
*/\r
if (delta.getID() != null || delta.getTenantID() != null ||\r
delta.getIpVersion() != null || delta.getCidr() != null ||\r
- delta.getAllocationPools() != null)\r
+ delta.getAllocationPools() != null) {\r
return Response.status(400).build();\r
+ }\r
\r
Object[] instances = ServiceHelper.getGlobalInstances(INeutronSubnetAware.class, this, null);\r
if (instances != null) {\r
for (Object instance : instances) {\r
INeutronSubnetAware service = (INeutronSubnetAware) instance;\r
int status = service.canUpdateSubnet(delta, original);\r
- if (status < 200 || status > 299)\r
+ if (status < 200 || status > 299) {\r
return Response.status(status).build();\r
+ }\r
}\r
}\r
\r
/*\r
* verify the subnet exists and it isn't currently in use\r
*/\r
- if (!subnetInterface.subnetExists(subnetUUID))\r
+ if (!subnetInterface.subnetExists(subnetUUID)) {\r
return Response.status(404).build();\r
- if (subnetInterface.subnetInUse(subnetUUID))\r
+ }\r
+ if (subnetInterface.subnetInUse(subnetUUID)) {\r
return Response.status(409).build();\r
+ }\r
NeutronSubnet singleton = subnetInterface.getSubnet(subnetUUID);\r
Object[] instances = ServiceHelper.getGlobalInstances(INeutronSubnetAware.class, this, null);\r
if (instances != null) {\r
for (Object instance : instances) {\r
INeutronSubnetAware service = (INeutronSubnetAware) instance;\r
int status = service.canDeleteSubnet(singleton);\r
- if (status < 200 || status > 299)\r
+ if (status < 200 || status > 299) {\r
return Response.status(status).build();\r
+ }\r
}\r
}\r
\r
Set<Node> nodes = connectionManager.getLocalNodes();
List<NodeJsonBean> result = new LinkedList<NodeJsonBean>();
+ if (nodes == null) {
+ return result;
+ }
for (Node node : nodes) {
Description descriptionProperty = (Description) switchManager.getNodeProp(node, "description");
- String description = descriptionProperty.getValue();
+ String description = node.toString();
+ if (descriptionProperty != null) {
+ description = descriptionProperty.getValue();
+ }
NodeJsonBean nodeBean = new NodeJsonBean();
nodeBean.setNodeId(node.getNodeIDString());
nodeBean.setNodeType(node.getType());
return "forward:" + "/";
}
-}
\ No newline at end of file
+}