logger.debug("Retrieving cache for HostTrackerIH");
inactiveStaticHosts = (ConcurrentMap<NodeConnector, HostNodeConnector>) this.clusterContainerService
.getCache("hostTrackerIH");
- if (hostsDB == null) {
+ if (inactiveStaticHosts == null) {
logger.error("Cache couldn't be retrieved for HostTrackerIH");
}
logger.debug("Cache was successfully retrieved for HostTrackerIH");
package org.opendaylight.controller.protocol_plugin.openflow.core.internal;
+import java.io.FileNotFoundException;
import java.io.IOException;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
}
}
+ public void _controllerShowConnConfig(CommandInterpreter ci) {
+ String str = System.getProperty("secureChannelEnabled");
+ if ((str != null) && (str.trim().equalsIgnoreCase("true"))) {
+ ci.print("The Controller and Switch should communicate through TLS connetion.\n");
+
+ String keyStoreFile = System.getProperty("controllerKeyStore");
+ String trustStoreFile = System.getProperty("controllerTrustStore");
+ if ((keyStoreFile == null) || keyStoreFile.trim().isEmpty()) {
+ ci.print("controllerKeyStore not specified in ./configuration/config.ini\n");
+ } else {
+ ci.print("controllerKeyStore=" + keyStoreFile + "\n");
+ }
+ if ((trustStoreFile == null) || trustStoreFile.trim().isEmpty()) {
+ ci.print("controllerTrustStore not specified in ./configuration/config.ini\n");
+ } else {
+ ci.print("controllerTrustStore=" + trustStoreFile + "\n");
+ }
+ } else {
+ ci.print("The Controller and Switch should communicate through TCP connetion.\n");
+ }
+ }
+
private void registerWithOSGIConsole() {
BundleContext bundleContext = FrameworkUtil.getBundle(this.getClass())
.getBundleContext();
help.append("--Open Flow Controller --\n");
help.append("\tcontrollerShowSwitches\n");
help.append("\tcontrollerReset\n");
+ help.append("\tcontrollerShowConnConfig\n");
return help.toString();
}
}
newBuffer.put(outBuffer);
outBuffer = newBuffer;
}
+ }
+ synchronized (outBuffer) {
msg.writeTo(outBuffer);
if (!socket.isOpen()) {
package org.opendaylight.controller.protocol_plugin.openflow.core.internal;
import java.io.FileInputStream;
+import java.io.FileNotFoundException;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.AsynchronousCloseException;
* @throws Exception
*/
private void createSecureChannel(SocketChannel socket) throws Exception {
- String keyStoreFile = System.getProperty("controllerKeyStore").trim();
- String keyStorePassword = System.getProperty("controllerKeyStorePassword").trim();
- String trustStoreFile = System.getProperty("controllerTrustStore").trim();
- String trustStorePassword = System.getProperty("controllerTrustStorePassword").trim();
-
+ String keyStoreFile = System.getProperty("controllerKeyStore");
+ String keyStorePassword = System.getProperty("controllerKeyStorePassword");
+ String trustStoreFile = System.getProperty("controllerTrustStore");
+ String trustStorePassword = System.getProperty("controllerTrustStorePassword");
+
+ if (keyStoreFile != null) {
+ keyStoreFile = keyStoreFile.trim();
+ }
+ if ((keyStoreFile == null) || keyStoreFile.isEmpty()) {
+ throw new FileNotFoundException("controllerKeyStore not specified in ./configuration/config.ini");
+ }
+ if (keyStorePassword != null) {
+ keyStorePassword = keyStorePassword.trim();
+ }
+ if ((keyStorePassword == null) || keyStorePassword.isEmpty()) {
+ throw new FileNotFoundException("controllerKeyStorePassword not specified in ./configuration/config.ini");
+ }
+ if (trustStoreFile != null) {
+ trustStoreFile = trustStoreFile.trim();
+ }
+ if ((trustStoreFile == null) || trustStoreFile.isEmpty()) {
+ throw new FileNotFoundException("controllerTrustStore not specified in ./configuration/config.ini");
+ }
+ if (trustStorePassword != null) {
+ trustStorePassword = trustStorePassword.trim();
+ }
+ if ((trustStorePassword == null) || trustStorePassword.isEmpty()) {
+ throw new FileNotFoundException("controllerTrustStorePassword not specified in ./configuration/config.ini");
+ }
+
KeyStore ks = KeyStore.getInstance("JKS");
KeyStore ts = KeyStore.getInstance("JKS");
KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509");
newBuffer.put(myAppData);
myAppData = newBuffer;
}
+ }
+ synchronized (myAppData) {
msg.writeTo(myAppData);
myAppData.flip();
sslEngineResult = sslEngine.wrap(myAppData, myNetData);
package org.opendaylight.controller.protocol_plugin.openflow.core.internal;
-import java.io.IOException;
+import java.net.SocketException;
import java.nio.channels.AsynchronousCloseException;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
@Override
public Integer asyncSend(OFMessage msg, int xid) {
msg.setXid(xid);
- transmitQ.add(new PriorityMessage(msg, 0));
+ if (transmitQ != null) {
+ transmitQ.add(new PriorityMessage(msg, 0));
+ }
return xid;
}
@Override
public Integer asyncFastSend(OFMessage msg, int xid) {
msg.setXid(xid);
- transmitQ.add(new PriorityMessage(msg, 1));
+ if (transmitQ != null) {
+ transmitQ.add(new PriorityMessage(msg, 1));
+ }
return xid;
}
public void resumeSend() {
try {
- msgReadWriteService.resumeSend();
+ if (msgReadWriteService != null) {
+ msgReadWriteService.resumeSend();
+ }
} catch (Exception e) {
reportError(e);
}
}
private void reportError(Exception e) {
- if (e instanceof AsynchronousCloseException) {
+ if (e instanceof AsynchronousCloseException ||
+ e instanceof InterruptedException ||
+ e instanceof SocketException) {
logger.debug("Caught exception {}", e.getMessage());
} else {
logger.warn("Caught exception {}", e.getMessage());
logger.trace("Message sent: {}", pmsg.toString());
}
Thread.sleep(10);
+ } catch (InterruptedException ie) {
+ reportError(new InterruptedException("PriorityMessageTransmit thread interrupted"));
} catch (Exception e) {
reportError(e);
}
package org.opendaylight.controller.protocol_plugin.openflow.internal;
+import java.nio.ByteBuffer;
import org.opendaylight.controller.protocol_plugin.openflow.core.IController;
import org.opendaylight.controller.protocol_plugin.openflow.core.ISwitch;
+import org.opendaylight.controller.protocol_plugin.openflow.vendorextension.v6extension.V6Error;
import org.openflow.protocol.OFError;
import org.openflow.protocol.OFFlowMod;
import org.openflow.protocol.OFMessage;
import org.opendaylight.controller.sal.flowprogrammer.IPluginInFlowProgrammerService;
import org.opendaylight.controller.sal.utils.StatusCode;
import org.opendaylight.controller.sal.utils.Status;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
/**
* Represents the openflow plugin component in charge of programming the flows
*
*/
public class FlowProgrammerService implements IPluginInFlowProgrammerService {
+ private static final Logger log = LoggerFactory
+ .getLogger(FlowProgrammerService.class);
private IController controller;
public FlowProgrammerService() {
errorString(null, action,
"Request Timed Out"));
} else if (result instanceof OFError) {
+ OFError res = (OFError) result;
+ if (res.getErrorType() == V6Error.NICIRA_VENDOR_ERRORTYPE) {
+ V6Error er = new V6Error(res);
+ byte[] b = res.getError();
+ ByteBuffer bb = ByteBuffer.allocate(b.length);
+ bb.put(b);
+ bb.rewind();
+ er.readFrom(bb);
+ log.trace("V6Error {}",er);
+ return new Status(StatusCode.INTERNALERROR,
+ errorString("program", action, "Vendor Extension Internal Error"));
+ }
return new Status(StatusCode.INTERNALERROR,
errorString("program", action, Utils
- .getOFErrorString((OFError) result)));
+ .getOFErrorString(res)));
} else {
return new Status(StatusCode.INTERNALERROR,
errorString("send", action, "Internal Error"));
--- /dev/null
+package org.opendaylight.controller.protocol_plugin.openflow.vendorextension.v6extension;
+
+import java.nio.ByteBuffer;
+
+import org.apache.commons.lang3.builder.EqualsBuilder;
+import org.apache.commons.lang3.builder.HashCodeBuilder;
+import org.apache.commons.lang3.builder.ReflectionToStringBuilder;
+import org.openflow.protocol.OFError;
+
+public class V6Error extends OFError {
+ private static final long serialVersionUID = 1L;
+ public static int MINIMUM_LENGTH = 20;//OfHdr(8) + NXET_VENDOR(2) + NXEC_VENDOR_ERROR(2) + struct nx_vendor_error(8)
+ public static final short NICIRA_VENDOR_ERRORTYPE = (short)0xb0c2;
+ protected int V6VendorId;
+ protected short V6VendorErrorType;
+ protected short V6VendorErrorCode;
+ protected byte[] V6ErrorData;
+
+ public V6Error(OFError e) {
+ this.length = (short)e.getLengthU();
+ this.errorType = e.getErrorType();
+ this.errorCode = e.getErrorCode();
+ this.xid = e.getXid();
+ }
+
+ @Override
+ public void readFrom(ByteBuffer data) {
+ this.V6VendorId = data.getInt();
+ this.V6VendorErrorType = data.getShort();
+ this.V6VendorErrorCode = data.getShort();
+ int dataLength = this.getLengthU() - MINIMUM_LENGTH;
+ if (dataLength > 0) {
+ this.V6ErrorData = new byte[dataLength];
+ data.get(this.V6ErrorData);
+ }
+ }
+
+ /**
+ * @return the V6VendorId
+ */
+ public int getVendorId() {
+ return V6VendorId;
+ }
+
+ /**
+ * @return the V6VendorErrorType
+ */
+ public short getVendorErrorType() {
+ return V6VendorErrorType;
+ }
+
+ /**
+ * @return the VendorErrorType
+ */
+ public short getVendorErrorCode() {
+ return V6VendorErrorCode;
+ }
+
+ /**
+ * @return the Error Bytes
+ */
+ public byte[] getError() {
+ return V6ErrorData;
+ }
+
+ @Override
+ public int hashCode() {
+ return HashCodeBuilder.reflectionHashCode(this);
+ }
+
+ @Override
+ public String toString() {
+ return "V6Error[" + ReflectionToStringBuilder.toString(this) + "]";
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ return EqualsBuilder.reflectionEquals(this, obj);
+ }
+}
.getNodeConnectorProp(dstNC,
Bandwidth.BandwidthPropName);
- if ((bwSrc == null) || (bwDst == null)) {
- log.error("bwSrc:{} or bwDst:{} is null", bwSrc, bwDst);
- return (double) -1;
- }
-
- long srcLinkSpeed = bwSrc.getValue();
- if (srcLinkSpeed == 0) {
- log.trace("Edge {}: srcLinkSpeed is 0. Setting to {}!",
- e, DEFAULT_LINK_SPEED);
- srcLinkSpeed = DEFAULT_LINK_SPEED;
+ long srcLinkSpeed = 0, dstLinkSpeed = 0;
+ if ((bwSrc == null) || ((srcLinkSpeed = bwSrc.getValue()) == 0)) {
+ log.debug("srcNC: {} - Setting srcLinkSpeed to Default!",srcNC);
+ srcLinkSpeed = DEFAULT_LINK_SPEED;
}
-
- long dstLinkSpeed = bwDst.getValue();
- if (dstLinkSpeed == 0) {
- log.trace("Edge {}: dstLinkSpeed is 0. Setting to {}!",
- e, DEFAULT_LINK_SPEED);
+
+ if ((bwDst == null) || ((dstLinkSpeed = bwDst.getValue()) == 0)) {
+ log.debug("dstNC: {} - Setting dstLinkSpeed to Default!",dstNC);
dstLinkSpeed = DEFAULT_LINK_SPEED;
}
* @file Path.java
*
* @brief Describe a path as a sequence of Edge such that from
- * each of its Tail Node there is an link to the next Head Node in the sequence
+ * each of its Head Node there is an link to the next Tail Node in the sequence
*
*/
package org.opendaylight.controller.sal.core;
/**
* Describe a path as a sequence of Edge such that from
- * each of its Tail Node there is an link to the next Head Node in the
+ * each of its Head Node there is an link to the next Tail Node in the
* sequence
*
*/
/**
* Construct an object representing a path, the constructor will
* check if the passed list of edges is such that for every
- * consecutive edges the tailnode of the first edge coincide with
- * the head node of the subsequent in order for connectivity to be there.
+ * consecutive edges the head node of the first edge coincide with
+ * the tail node of the subsequent in order for connectivity to be there.
*
* @param edges Edges of the path
*
*/
public Path(List<Edge> edges) throws ConstructionException {
- // Lets check if the list of edges is such that the tail node
- // of an edge is also the head node of the subsequent one
+ // Lets check if the list of edges is such that the head node
+ // of an edge is also the tail node of the subsequent one
boolean sequential = true;
if (edges.size() >= 2) {
for (int i = 0; i < edges.size() - 1; i++) {
<dependencies>
<dependency>
<groupId>org.opendaylight.controller</groupId>
- <artifactId>yang-to-sources</artifactId>
+ <artifactId>maven-yang</artifactId>
<version>1.0</version>
<type>test-jar</type>
</dependency>
<dependencies>
<dependency>
<groupId>org.opendaylight.controller</groupId>
- <artifactId>yang-to-sources</artifactId>
+ <artifactId>maven-yang</artifactId>
<version>1.0</version>
<type>test-jar</type>
</dependency>
<dependencies>
<dependency>
<groupId>org.opendaylight.controller</groupId>
- <artifactId>yang-to-sources</artifactId>
+ <artifactId>maven-yang</artifactId>
<version>1.0</version>
<type>test-jar</type>
</dependency>
<dependencies>
<dependency>
<groupId>org.opendaylight.controller</groupId>
- <artifactId>yang-to-sources</artifactId>
+ <artifactId>maven-yang</artifactId>
<version>1.0</version>
<type>test-jar</type>
</dependency>
<dependencies>
<dependency>
<groupId>org.opendaylight.controller</groupId>
- <artifactId>yang-to-sources</artifactId>
+ <artifactId>maven-yang</artifactId>
<version>1.0</version>
<type>test-jar</type>
</dependency>
<dependencies>
<dependency>
<groupId>org.opendaylight.controller</groupId>
- <artifactId>yang-to-sources</artifactId>
+ <artifactId>maven-yang</artifactId>
<version>1.0</version>
<type>test-jar</type>
</dependency>
<artifactId>maven-yang-plugin</artifactId>
<packaging>maven-plugin</packaging>
+ <description>
+ This plugin is a wrapper for "yang to source code" generation.
+ It can be configured by a set of third-party code generators and resource providers.
+ For further info see available goals.
+ Sample usage:
+
+ TODO: add sample usage when finished
+ </description>
<dependencies>
<dependency>
</dependency>
</dependencies>
+ <reporting>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-plugin-plugin</artifactId>
+ <version>3.2</version>
+ </plugin>
+ </plugins>
+ </reporting>
+
<build>
<plugins>
<plugin>
import com.google.common.base.Preconditions;
/**
- * Complex configuration arguments
+ * Base complex configuration arguments
*/
public abstract class ConfigArg {
public abstract void check();
+ /**
+ * Configuration argument for resource generator class and output directory.
+ */
public static final class ResourceProviderArg extends ConfigArg {
private String resourceProviderClass;
}
/**
- * Transfer object for code generator class and output directory.
+ * Configuration argument for code generator class and output directory.
*/
public static final class CodeGeneratorArg extends ConfigArg {
private String codeGeneratorClass;
import com.google.common.annotations.VisibleForTesting;
import com.google.common.collect.Maps;
+/**
+ * Generate resources from yang files using user provided set of
+ * {@link ResourceGenerator}s. Can be used to copy yang files that served as
+ * blueprint for code generation into resources directory. Steps of this
+ * process:
+ * <ol>
+ * <li>List yang files from {@link #yangFilesRootDir} (If this goal is in the
+ * same execution as generate-sources, the same cached list will be used and the
+ * root folder will not be searched for yang files twice)</li>
+ * <li>For each {@link ResourceGenerator} from {@link #resourceProviders}:</li>
+ * <ol>
+ * <li>Instantiate using default constructor</li>
+ * <li>Call {@link ResourceGenerator#generateResourceFiles(Collection, File)}</li>
+ * </ol>
+ * </ol>
+ */
@Mojo(name = "generate-resources", defaultPhase = LifecyclePhase.GENERATE_RESOURCES)
public final class YangToResourcesMojo extends AbstractMojo {
private static final String LOG_PREFIX = "yang-to-resources:";
+ /**
+ * Classes implementing {@link ResourceGenerator} interface. An instance
+ * will be created out of every class using default constructor. Method
+ * {@link ResourceGenerator#generateResourceFiles(Collection, File)} will be
+ * called on every instance.
+ */
@Parameter(required = true)
private ResourceProviderArg[] resourceProviders;
+ /**
+ * Source directory that will be recursively searched for yang files (ending
+ * with .yang suffix).
+ */
@Parameter(required = true)
private String yangFilesRootDir;
import com.google.common.annotations.VisibleForTesting;
import com.google.common.collect.Maps;
+/**
+ * Generate sources from yang files using user provided set of
+ * {@link CodeGenerator}s. Steps of this process:
+ * <ol>
+ * <li>List yang files from {@link #yangFilesRootDir}</li>
+ * <li>Process yang files using {@link YangModelParserImpl}</li>
+ * <li>For each {@link CodeGenerator} from {@link #codeGenerators}:</li>
+ * <ol>
+ * <li>Instantiate using default constructor</li>
+ * <li>Call {@link CodeGenerator#generateSources(SchemaContext, File)}</li>
+ * </ol>
+ * </ol>
+ */
@Mojo(name = "generate-sources", defaultPhase = LifecyclePhase.GENERATE_SOURCES)
public final class YangToSourcesMojo extends AbstractMojo {
private static final String LOG_PREFIX = "yang-to-sources:";
+ /**
+ * Classes implementing {@link CodeGenerator} interface. An instance will be
+ * created out of every class using default constructor. Method
+ * {@link CodeGenerator#generateSources(SchemaContext, File)} will be called
+ * on every instance.
+ */
@Parameter(required = true)
private CodeGeneratorArg[] codeGenerators;
+ /**
+ * Source directory that will be recursively searched for yang files (ending
+ * with .yang suffix).
+ */
@Parameter(required = true)
private String yangFilesRootDir;
import org.opendaylight.controller.yang.model.api.SchemaContext;
+/**
+ * Classes implementing this interface can be submitted to maven-yang-plugin's
+ * generate-sources goal.
+ */
public interface CodeGenerator {
+ /**
+ * Generate sources from provided {@link SchemaContext}
+ *
+ * @param context
+ * parsed from yang files
+ * @param outputBaseDir
+ * expected output directory for generated sources configured by
+ * user
+ * @return collection of files that were generated from schema context
+ */
Collection<File> generateSources(SchemaContext context, File outputBaseDir);
}
import java.io.File;
import java.util.Collection;
+/**
+ * Classes implementing this interface can be submitted to maven-yang-plugin's
+ * generate-resources goal.
+ */
public interface ResourceGenerator {
+ /**
+ * Generate resources (e.g. copy files into resources folder) from provided
+ * list of yang files
+ *
+ * @param resources
+ * list of parsed yang files
+ * @param outputBaseDir
+ * expected output directory for resources configured by user
+ */
void generateResourceFiles(Collection<File> resources, File outputBaseDir);
}
void setTopologyManagerAware(ITopologyManagerAware s) {
if (this.topologyManagerAware != null) {
- log.debug("Adding ITopologyManagerAware: " + s);
+ log.debug("Adding ITopologyManagerAware: {}", s);
this.topologyManagerAware.add(s);
}
}
void unsetTopologyManagerAware(ITopologyManagerAware s) {
if (this.topologyManagerAware != null) {
+ log.debug("Removing ITopologyManagerAware: {}", s);
this.topologyManagerAware.remove(s);
}
}
void setTopoService(ITopologyService s) {
+ log.debug("Adding ITopologyService: {}", s);
this.topoService = s;
}
void unsetTopoService(ITopologyService s) {
if (this.topoService == s) {
+ log.debug("Removing ITopologyService: {}", s);
this.topoService = null;
}
}
this.clusterContainerService
.destroyCache("topologymanager.nodeConnectorDB");
this.nodeConnectorsDB = null;
- log.debug("Topology Manager DB DE-allocated");
+ log.debug("Topology Manager DB Deallocated");
}
@SuppressWarnings("unchecked")
if (this.hostsDB == null) {
return;
}
-
+
switch (t) {
case ADDED:
case CHANGED:
new HashSet<Property>());
this.nodeConnectorsDB.put(e.getTailNodeConnector(),
new HashSet<Property>());
+ log.trace("Edge {} {}", e.toString(), type.name());
break;
case REMOVED:
// Now remove the edge from edgesDB
// should be safe to assume that won't happen.
this.nodeConnectorsDB.remove(e.getHeadNodeConnector());
this.nodeConnectorsDB.remove(e.getTailNodeConnector());
+ log.trace("Edge {} {}", e.toString(), type.name());
break;
case CHANGED:
Set<Property> old_props = this.edgesDB.get(e);
// Finally update
this.edgesDB.put(e, props);
+ log.trace("Edge {} {}", e.toString(), type.name());
break;
}
//oneTopology.deleteUserConfiguredLink(linkTuple);
} catch (Exception e) {
log
- .warn("Harmless : Exception while Deleting User Configured link "
- + link + " " + e.toString());
+ .warn("Harmless : Exception while Deleting User Configured link {} {}",
+ link, e.toString());
}
linkTuple = getReverseLinkTuple(link);
try {
//oneTopology.deleteUserConfiguredLink(linkTuple);
} catch (Exception e) {
log
- .error("Harmless : Exception while Deleting User Configured Reverse link "
- + link + " " + e.toString());
+ .warn("Harmless : Exception while Deleting User Configured Reverse link {} {}",
+ link, e.toString());
}
}
return new Status(StatusCode.SUCCESS, null);
@Override
public void edgeOverUtilized(Edge edge) {
- log.warn("Link Utilization above normal: " + edge);
+ log.warn("Link Utilization above normal: {}", edge);
}
@Override
public void edgeUtilBackToNormal(Edge edge) {
- log.warn("Link Utilization back to normal: " + edge);
+ log.warn("Link Utilization back to normal: {}", edge);
}
}