From: Tony Tkacik Date: Fri, 18 Jul 2014 08:45:04 +0000 (+0000) Subject: Merge "Improve RpcProviderRegistry loading" X-Git-Tag: release/helium~471 X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?p=controller.git;a=commitdiff_plain;h=c12b1a72f126b4679a2428de2e99d8253e19c213;hp=190373163c45f5984b13f3e3b6ed4f461e02f5b3 Merge "Improve RpcProviderRegistry loading" --- diff --git a/features/base/src/main/resources/features.xml b/features/base/src/main/resources/features.xml index 60286175c1..b9107b9f62 100644 --- a/features/base/src/main/resources/features.xml +++ b/features/base/src/main/resources/features.xml @@ -79,6 +79,8 @@ mvn:eclipselink/javax.persistence/2.0.4.v201112161009 mvn:eclipselink/javax.resource/1.5.0.v200906010428 + mvn:org.eclipse.persistence/org.eclipse.persistence.moxy/2.5.0 + mvn:org.eclipse.persistence/org.eclipse.persistence.core/2.5.0 http diff --git a/opendaylight/config/feature/pom.xml b/features/config/pom.xml similarity index 97% rename from opendaylight/config/feature/pom.xml rename to features/config/pom.xml index aaf33ccc0f..01a4ea74a2 100644 --- a/opendaylight/config/feature/pom.xml +++ b/features/config/pom.xml @@ -5,6 +5,7 @@ org.opendaylight.controller config-subsystem 0.2.5-SNAPSHOT + ../../opendaylight/config/ config-features diff --git a/features/config/src/main/resources/features.xml b/features/config/src/main/resources/features.xml new file mode 100644 index 0000000000..7c11b5b18b --- /dev/null +++ b/features/config/src/main/resources/features.xml @@ -0,0 +1,82 @@ + + + + mvn:org.opendaylight.yangtools/features-yangtools/${yangtools.version}/xml/features + mvn:org.opendaylight.controller/netconf-features/${netconf.version}/xml/features + + + odl-config-netconf-connector + odl-config-persister + odl-netconf-impl + + + + yangtools-concepts + yangtools-binding + yangtools-binding-generator + odl-mdsal-commons + odl-config-api + mvn:org.opendaylight.controller/config-util/${project.version} + mvn:org.opendaylight.controller/yang-jmx-generator/${project.version} + mvn:org.opendaylight.controller/shutdown-api/${project.version} + mvn:org.opendaylight.controller/shutdown-impl/${project.version} + mvn:org.osgi/org.osgi.core/${osgi.core.version} + wrap:mvn:com.google.guava/guava/${guava.version} + mvn:org.javassist/javassist/${javassist.version} + + + odl-config-core + mvn:org.opendaylight.controller/config-manager/${project.version} + + + odl-netconf-api + odl-config-api + yangtools-binding-generator + mvn:org.opendaylight.controller/config-persister-api/${project.version} + mvn:org.opendaylight.controller/config-persister-file-xml-adapter/${project.version} + mvn:org.opendaylight.controller/config-persister-directory-xml-adapter/${project.version} + mvn:org.opendaylight.controller/config-persister-impl/${project.version} + + mvn:org.opendaylight.controller/netconf-util/${netconf.version} + mvn:org.opendaylight.controller/netconf-mapping-api/${netconf.version} + + mvn:com.google.guava/guava/${guava.version} + mvn:commons-io/commons-io/${commons.io.version} + mvn:org.apache.commons/commons-lang3/${commons.lang3.version} + mvn:org.eclipse.persistence/org.eclipse.persistence.core/${eclipse.persistence.version} + mvn:org.eclipse.persistence/org.eclipse.persistence.moxy/${eclipse.persistence.version} + + + mvn:org.opendaylight.controller/config-api/${project.version} + + + yangtools-concepts + yangtools-binding + + + + mvn:org.opendaylight.controller/netty-config-api/${project.version} + + + mvn:io.netty/netty-transport/${netty.version} + mvn:io.netty/netty-common/${netty.version} + mvn:io.netty/netty-buffer/${netty.version} + + odl-config-api + + + odl-config-netty-config-api + mvn:org.opendaylight.controller/netty-event-executor-config/${project.version} + mvn:org.opendaylight.controller/netty-threadgroup-config/${project.version} + mvn:org.opendaylight.controller/netty-timer-config/${project.version} + mvn:org.opendaylight.controller/threadpool-config-api/${project.version} + mvn:org.opendaylight.controller/threadpool-config-impl/${project.version} + odl-config-startup + + + mvn:org.opendaylight.controller/netconf-config-dispatcher/${project.version} + + + \ No newline at end of file diff --git a/opendaylight/md-sal/feature/pom.xml b/features/mdsal/pom.xml similarity index 97% rename from opendaylight/md-sal/feature/pom.xml rename to features/mdsal/pom.xml index c08c3e5606..2983c5efab 100644 --- a/opendaylight/md-sal/feature/pom.xml +++ b/features/mdsal/pom.xml @@ -5,6 +5,7 @@ org.opendaylight.controller sal-parent 1.1-SNAPSHOT + ../../opendaylight/md-sal mdsal-features diff --git a/opendaylight/md-sal/feature/src/main/resources/features.xml b/features/mdsal/src/main/resources/features.xml similarity index 56% rename from opendaylight/md-sal/feature/src/main/resources/features.xml rename to features/mdsal/src/main/resources/features.xml index 16b4574037..7d393bc64c 100644 --- a/opendaylight/md-sal/feature/src/main/resources/features.xml +++ b/features/mdsal/src/main/resources/features.xml @@ -9,20 +9,20 @@ odl-mdsal-restconf - yangtools-concepts - yangtools-binding + yangtools-data-binding mvn:org.opendaylight.controller/sal-common/${project.version} mvn:org.opendaylight.controller/sal-common-api/${project.version} mvn:org.opendaylight.controller/sal-common-impl/${project.version} mvn:org.opendaylight.controller/sal-common-util/${project.version} - wrap:mvn:com.google.guava/guava/${guava.version} - wrap:mvn:org.eclipse.xtend/org.eclipse.xtend.lib/${xtend.version} yangtools-concepts yangtools-binding odl-mdsal-commons - odl-config-subsystem + odl-config-core + odl-config-manager + odl-config-api + odl-config-persister mvn:org.opendaylight.controller/sal-core-api/${project.version} mvn:org.opendaylight.controller/sal-core-spi/${project.version} mvn:org.opendaylight.controller/sal-broker-impl/${project.version} @@ -31,6 +31,7 @@ mvn:org.opendaylight.controller/sal-binding-broker-impl/${project.version} mvn:org.opendaylight.controller/sal-binding-util/${project.version} mvn:org.opendaylight.controller/sal-connector-api/${project.version} + mvn:org.opendaylight.controller/sal-inmemory-datastore/${project.version} odl-mdsal-broker @@ -46,4 +47,32 @@ wrap:mvn:io.netty/netty-handler/${netty.version} wrap:mvn:io.netty/netty-transport/${netty.version} + + mvn:org.opendaylight.controller.model/model-flow-base/${project.version} + mvn:org.opendaylight.controller.model/model-flow-management/${project.version} + mvn:org.opendaylight.controller.model/model-flow-service/${project.version} + mvn:org.opendaylight.controller.model/model-flow-statistics/${project.version} + mvn:org.opendaylight.controller.model/model-inventory/${project.version} + mvn:org.opendaylight.controller.model/model-topology/${project.version} + + + yangtools-concepts + yangtools-binding + odl-mdsal-broker + odl-mdsal-all + mvn:org.opendaylight.controller.samples/sample-toaster/${project.version} + mvn:org.opendaylight.controller.samples/sample-toaster-consumer/${project.version} + mvn:org.opendaylight.controller.samples/sample-toaster-provider/${project.version} + + + mvn:org.opendaylight.controller/sal-netconf-connector/${project.version} + mvn:org.opendaylight.controller/sal-restconf-broker/${project.version} + mvn:org.opendaylight.controller/sal-remote/${project.version} + mvn:org.opendaylight.controller.md/topology-manager/${project.version} + mvn:org.opendaylight.controller.md/topology-lldp-discovery/${project.version} + mvn:org.opendaylight.controller.md/statistics-manager/${project.version} + mvn:org.opendaylight.controller.md/inventory-manager/${project.version} + mvn:org.opendaylight.controller.md/forwardingrules-manager/${project.version} + + diff --git a/features/netconf/pom.xml b/features/netconf/pom.xml new file mode 100644 index 0000000000..457fc64edd --- /dev/null +++ b/features/netconf/pom.xml @@ -0,0 +1,71 @@ + + + 4.0.0 + + org.opendaylight.controller + netconf-subsystem + 0.2.5-SNAPSHOT + ../../opendaylight/netconf + + netconf-features + + pom + + + features.xml + + + + + + + + true + src/main/resources + + + + + org.apache.maven.plugins + maven-resources-plugin + + + filter + + resources + + generate-resources + + + + + org.codehaus.mojo + build-helper-maven-plugin + + + attach-artifacts + + attach-artifact + + package + + + + ${project.build.directory}/classes/${features.file} + xml + features + + + + + + + + + + scm:git:ssh://git.opendaylight.org:29418/controller.git + scm:git:ssh://git.opendaylight.org:29418/controller.git + HEAD + https://wiki.opendaylight.org/view/OpenDaylight_Controller:MD-SAL + + diff --git a/features/netconf/src/main/resources/features.xml b/features/netconf/src/main/resources/features.xml new file mode 100644 index 0000000000..50a537b50a --- /dev/null +++ b/features/netconf/src/main/resources/features.xml @@ -0,0 +1,59 @@ + + + + mvn:org.opendaylight.controller/features-odl-protocol-framework/${protocol-framework.version}/xml/features + mvn:org.opendaylight.controller/config-features/${config.version}/xml/features + + + mvn:org.opendaylight.controller/netconf-api/${project.version} + mvn:org.opendaylight.controller/ietf-netconf-monitoring/${project.version} + mvn:org.opendaylight.controller/ietf-netconf-monitoring-extension/${project.version} + odl-protocol-framework + mvn:org.opendaylight.yangtools.model/ietf-inet-types/${ietf-inet-types.version} + mvn:org.opendaylight.yangtools.model/ietf-yang-types/${ietf-yang-types.version} + + + odl-netconf-api + mvn:org.opendaylight.controller/netconf-mapping-api/${project.version} + + + odl-netconf-mapping-api + mvn:org.opendaylight.controller/netconf-util/${project.version} + + + odl-config-manager + mvn:org.opendaylight.controller/config-netconf-connector/${project.version} + odl-netconf-api + odl-netconf-mapping-api + odl-netconf-util + + + + mvn:org.opendaylight.controller/netconf-impl/${project.version} + odl-netconf-api + odl-netconf-mapping-api + odl-netconf-util + odl-netconf-netty-util + + + mvn:org.opendaylight.controller/netconf-netty-util/${project.version} + odl-netconf-api + odl-netconf-mapping-api + odl-netconf-util + mvn:org.opendaylight.controller.thirdparty/ganymed/${ganymed.version} + mvn:org.openexi/nagasena/${exi.nagasena.version} + mvn:io.netty/netty-codec/${netty.version} + mvn:io.netty/netty-handler/${netty.version} + mvn:io.netty/netty-common/${netty.version} + mvn:io.netty/netty-buffer/${netty.version} + mvn:io.netty/netty-transport/${netty.version} + + + mvn:org.opendaylight.controller/netconf-client/${project.version} + mvn:org.opendaylight.controller/netconf-monitoring/${project.version} + mvn:org.opendaylight.controller/netconf-tcp/${project.version} + + + \ No newline at end of file diff --git a/features/pom.xml b/features/pom.xml new file mode 100644 index 0000000000..dce47faea6 --- /dev/null +++ b/features/pom.xml @@ -0,0 +1,21 @@ + + + 4.0.0 + + org.opendaylight.controller + commons.opendaylight + 1.4.2-SNAPSHOT + ../opendaylight/commons/opendaylight + + features-controller + pom + + 3.0 + + + config + mdsal + netconf + protocol-framework + + diff --git a/features/protocol-framework/pom.xml b/features/protocol-framework/pom.xml new file mode 100644 index 0000000000..f0208d6452 --- /dev/null +++ b/features/protocol-framework/pom.xml @@ -0,0 +1,71 @@ + + + 4.0.0 + + org.opendaylight.controller + commons.opendaylight + 1.4.2-SNAPSHOT + ../../opendaylight/commons/opendaylight + + features-odl-protocol-framework + ${protocol-framework.version} + pom + + + features.xml + + + + + + + + true + src/main/resources + + + + + org.apache.maven.plugins + maven-resources-plugin + + + filter + + resources + + generate-resources + + + + + org.codehaus.mojo + build-helper-maven-plugin + + + attach-artifacts + + attach-artifact + + package + + + + ${project.build.directory}/classes/${features.file} + xml + features + + + + + + + + + + scm:git:ssh://git.opendaylight.org:29418/controller.git + scm:git:ssh://git.opendaylight.org:29418/controller.git + HEAD + https://wiki.opendaylight.org/view/OpenDaylight_Controller:MD-SAL + + diff --git a/features/protocol-framework/src/main/resources/features.xml b/features/protocol-framework/src/main/resources/features.xml new file mode 100644 index 0000000000..d2560f5cb0 --- /dev/null +++ b/features/protocol-framework/src/main/resources/features.xml @@ -0,0 +1,12 @@ + + + + mvn:org.opendaylight.controller/config-features/${config.version}/xml/features + + mvn:org.opendaylight.controller/protocol-framework/${protocol-framework.version} + odl-config-api + odl-config-netty-config-api + + \ No newline at end of file diff --git a/opendaylight/commons/filter-valve/src/main/java/org/opendaylight/controller/filtervalve/cors/jaxb/Context.java b/opendaylight/commons/filter-valve/src/main/java/org/opendaylight/controller/filtervalve/cors/jaxb/Context.java index dbe0745725..cec780c9ec 100644 --- a/opendaylight/commons/filter-valve/src/main/java/org/opendaylight/controller/filtervalve/cors/jaxb/Context.java +++ b/opendaylight/commons/filter-valve/src/main/java/org/opendaylight/controller/filtervalve/cors/jaxb/Context.java @@ -69,9 +69,10 @@ public class Context { initialized = true; } - public List findMatchingFilters(String pathInfo) { + public List findMatchingFilters(String path) { + logger.trace("findMatchingFilters({})", path); checkState(initialized, "Not initialized"); - return urlMatcher.findMatchingFilters(pathInfo); + return urlMatcher.findMatchingFilters(path); } @XmlAttribute(name = "path") diff --git a/opendaylight/commons/filter-valve/src/main/java/org/opendaylight/controller/filtervalve/cors/model/FilterProcessor.java b/opendaylight/commons/filter-valve/src/main/java/org/opendaylight/controller/filtervalve/cors/model/FilterProcessor.java index dc3e9dcd49..ae9d79a63d 100644 --- a/opendaylight/commons/filter-valve/src/main/java/org/opendaylight/controller/filtervalve/cors/model/FilterProcessor.java +++ b/opendaylight/commons/filter-valve/src/main/java/org/opendaylight/controller/filtervalve/cors/model/FilterProcessor.java @@ -37,14 +37,14 @@ public class FilterProcessor { throws IOException, ServletException { String contextPath = request.getContext().getPath(); - String pathInfo = request.getPathInfo(); + String path = request.getDecodedRequestURI(); Optional maybeContext = host.findContext(contextPath); - logger.trace("Processing context {} path {}, found {}", contextPath, pathInfo, maybeContext); + logger.trace("Processing context {} path {}, found {}", contextPath, path, maybeContext); if (maybeContext.isPresent()) { // process filters Context context = maybeContext.get(); - List matchingFilters = context.findMatchingFilters(pathInfo); + List matchingFilters = context.findMatchingFilters(path); FilterChain fromLast = nextValveFilterChain; ListIterator it = matchingFilters.listIterator(matchingFilters.size()); final boolean trace = logger.isTraceEnabled(); diff --git a/opendaylight/commons/filter-valve/src/main/java/org/opendaylight/controller/filtervalve/cors/model/UrlMatcher.java b/opendaylight/commons/filter-valve/src/main/java/org/opendaylight/controller/filtervalve/cors/model/UrlMatcher.java index 9535fb1f70..210326f5d1 100644 --- a/opendaylight/commons/filter-valve/src/main/java/org/opendaylight/controller/filtervalve/cors/model/UrlMatcher.java +++ b/opendaylight/commons/filter-valve/src/main/java/org/opendaylight/controller/filtervalve/cors/model/UrlMatcher.java @@ -62,31 +62,31 @@ public class UrlMatcher { /** * Find filters matching path * - * @param pathInfo as returned by request.getPathInfo() + * @param path relative and decoded path to resource * @return list of matching filters */ - public List findMatchingFilters(String pathInfo) { - checkNotNull(pathInfo); + public List findMatchingFilters(String path) { + checkNotNull(path); TreeMap sortedMap = new TreeMap<>(); // add matching prefixes for (Entry> prefixEntry : prefixMap.entrySet()) { - if (pathInfo.startsWith(prefixEntry.getKey())) { + if (path.startsWith(prefixEntry.getKey())) { put(sortedMap, prefixEntry.getValue()); } } // add matching suffixes for (Entry> suffixEntry : suffixMap.entrySet()) { - if (pathInfo.endsWith(suffixEntry.getKey())) { + if (path.endsWith(suffixEntry.getKey())) { put(sortedMap, suffixEntry.getValue()); } } // add exact match - Entry exactMatch = exactMatchMap.get(pathInfo); + Entry exactMatch = exactMatchMap.get(path); if (exactMatch != null) { put(sortedMap, exactMatch); } ArrayList filters = new ArrayList<>(sortedMap.values()); - logger.trace("Matching filters for path {} are {}", pathInfo, filters); + logger.trace("Matching filters for path {} are {}", path, filters); return filters; } diff --git a/opendaylight/commons/opendaylight/pom.xml b/opendaylight/commons/opendaylight/pom.xml index 28c23c8259..163c64ed52 100644 --- a/opendaylight/commons/opendaylight/pom.xml +++ b/opendaylight/commons/opendaylight/pom.xml @@ -91,6 +91,7 @@ 0.4.2-SNAPSHOT 0.4.2-SNAPSHOT 0.6.0-SNAPSHOT + 1.1-SNAPSHOT 0.5.2-SNAPSHOT 0.5.2-SNAPSHOT 0.4.2-SNAPSHOT @@ -1498,7 +1499,7 @@ org.opendaylight.controller.thirdparty ganymed - 1.1-SNAPSHOT + ${ganymed.version} diff --git a/opendaylight/config/feature/src/main/resources/features.xml b/opendaylight/config/feature/src/main/resources/features.xml deleted file mode 100644 index a84a74305f..0000000000 --- a/opendaylight/config/feature/src/main/resources/features.xml +++ /dev/null @@ -1,28 +0,0 @@ - - - - - odl-config-subsystem - - - - yangtools-concepts - yangtools-binding - yangtools-binding-generator - odl-mdsal-commons - mvn:org.opendaylight.controller/config-api/${project.version} - mvn:org.opendaylight.controller/config-util/${project.version} - mvn:org.opendaylight.controller/config-manager/${project.version} - mvn:org.opendaylight.controller/yang-jmx-generator/${project.version} - mvn:org.opendaylight.controller/config-persister-api/${project.version} - mvn:org.opendaylight.controller/config-persister-file-xml-adapter/${project.version} - mvn:org.opendaylight.controller/config-persister-directory-xml-adapter/${project.version} - mvn:org.opendaylight.controller/shutdown-api/${project.version} - mvn:org.opendaylight.controller/shutdown-impl/${project.version} - mvn:org.osgi/org.osgi.core/${osgi.core.version} - wrap:mvn:com.google.guava/guava/${guava.version} - mvn:org.javassist/javassist/${javassist.version} - - \ No newline at end of file diff --git a/opendaylight/config/pom.xml b/opendaylight/config/pom.xml index a8a4c87a4e..66bb01f051 100644 --- a/opendaylight/config/pom.xml +++ b/opendaylight/config/pom.xml @@ -39,7 +39,6 @@ shutdown-impl netconf-config-dispatcher config-module-archetype - feature diff --git a/opendaylight/config/threadpool-config-impl/src/main/java/org/opendaylight/controller/config/threadpool/util/FlexibleThreadPoolWrapper.java b/opendaylight/config/threadpool-config-impl/src/main/java/org/opendaylight/controller/config/threadpool/util/FlexibleThreadPoolWrapper.java index 3dfa6e2bc7..5036399828 100644 --- a/opendaylight/config/threadpool-config-impl/src/main/java/org/opendaylight/controller/config/threadpool/util/FlexibleThreadPoolWrapper.java +++ b/opendaylight/config/threadpool-config-impl/src/main/java/org/opendaylight/controller/config/threadpool/util/FlexibleThreadPoolWrapper.java @@ -10,15 +10,20 @@ package org.opendaylight.controller.config.threadpool.util; import java.io.Closeable; import java.io.IOException; +import java.util.concurrent.BlockingQueue; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; -import java.util.concurrent.SynchronousQueue; +import java.util.concurrent.LinkedBlockingQueue; +import java.util.concurrent.RejectedExecutionException; +import java.util.concurrent.RejectedExecutionHandler; import java.util.concurrent.ThreadFactory; import java.util.concurrent.ThreadPoolExecutor; import java.util.concurrent.TimeUnit; import org.opendaylight.controller.config.threadpool.ThreadPool; +import com.google.common.base.Optional; + /** * Implementation of {@link ThreadPool} using flexible number of threads wraps * {@link ExecutorService}. @@ -28,12 +33,33 @@ public class FlexibleThreadPoolWrapper implements ThreadPool, Closeable { public FlexibleThreadPoolWrapper(int minThreadCount, int maxThreadCount, long keepAlive, TimeUnit timeUnit, ThreadFactory threadFactory) { + this(minThreadCount, maxThreadCount, keepAlive, timeUnit, threadFactory, getQueue(Optional.absent())); + } + + public FlexibleThreadPoolWrapper(int minThreadCount, int maxThreadCount, long keepAlive, TimeUnit timeUnit, + ThreadFactory threadFactory, Optional queueCapacity) { + this(minThreadCount, maxThreadCount, keepAlive, timeUnit, threadFactory, getQueue(queueCapacity)); + } + + private FlexibleThreadPoolWrapper(int minThreadCount, int maxThreadCount, long keepAlive, TimeUnit timeUnit, + ThreadFactory threadFactory, BlockingQueue queue) { executor = new ThreadPoolExecutor(minThreadCount, maxThreadCount, keepAlive, timeUnit, - new SynchronousQueue(), threadFactory); + queue, threadFactory, new FlexibleRejectionHandler()); executor.prestartAllCoreThreads(); } + /** + * Overriding the queue: + * ThreadPoolExecutor would not create new threads if the queue is not full, thus adding + * occurs in RejectedExecutionHandler. + * This impl saturates threadpool first, then queue. When both are full caller will get blocked. + */ + private static ForwardingBlockingQueue getQueue(Optional capacity) { + final BlockingQueue delegate = capacity.isPresent() ? new LinkedBlockingQueue(capacity.get()) : new LinkedBlockingQueue(); + return new ForwardingBlockingQueue(delegate); + } + @Override public ExecutorService getExecutor() { return Executors.unconfigurableExecutorService(executor); @@ -77,4 +103,37 @@ public class FlexibleThreadPoolWrapper implements ThreadPool, Closeable { executor.shutdown(); } + /** + * if the max threads are met, then it will raise a rejectedExecution. We then push to the queue. + */ + private static class FlexibleRejectionHandler implements RejectedExecutionHandler { + @Override + public void rejectedExecution(final Runnable r, final ThreadPoolExecutor executor) { + try { + executor.getQueue().put(r); + } catch (InterruptedException e) { + throw new RejectedExecutionException("Interrupted while waiting on the queue", e); + } + } + } + + private static class ForwardingBlockingQueue extends com.google.common.util.concurrent.ForwardingBlockingQueue { + private final BlockingQueue delegate; + + public ForwardingBlockingQueue(BlockingQueue delegate) { + this.delegate = delegate; + } + + @Override + protected BlockingQueue delegate() { + return delegate; + } + + @Override + public boolean offer(final Runnable r) { + // ThreadPoolExecutor will spawn a new thread after core size is reached only + // if the queue.offer returns false. + return false; + } + } } diff --git a/opendaylight/config/threadpool-config-impl/src/main/java/org/opendaylight/controller/config/yang/threadpool/impl/flexible/FlexibleThreadPoolModule.java b/opendaylight/config/threadpool-config-impl/src/main/java/org/opendaylight/controller/config/yang/threadpool/impl/flexible/FlexibleThreadPoolModule.java index 94639d43c0..d6abe168fb 100644 --- a/opendaylight/config/threadpool-config-impl/src/main/java/org/opendaylight/controller/config/yang/threadpool/impl/flexible/FlexibleThreadPoolModule.java +++ b/opendaylight/config/threadpool-config-impl/src/main/java/org/opendaylight/controller/config/yang/threadpool/impl/flexible/FlexibleThreadPoolModule.java @@ -17,6 +17,7 @@ */ package org.opendaylight.controller.config.yang.threadpool.impl.flexible; +import com.google.common.base.Optional; import java.util.concurrent.TimeUnit; import org.opendaylight.controller.config.api.JmxAttributeValidationException; @@ -50,11 +51,15 @@ public final class FlexibleThreadPoolModule extends org.opendaylight.controller. JmxAttributeValidationException.checkNotNull(getMaxThreadCount(), maxThreadCountJmxAttribute); JmxAttributeValidationException.checkCondition(getMaxThreadCount() > 0, "must be greater than zero", maxThreadCountJmxAttribute); + + if(getQueueCapacity() != null) { + JmxAttributeValidationException.checkCondition(getQueueCapacity() > 0, "Queue capacity cannot be < 1", queueCapacityJmxAttribute); + } } @Override public java.lang.AutoCloseable createInstance() { return new FlexibleThreadPoolWrapper(getMinThreadCount(), getMaxThreadCount(), getKeepAliveMillis(), - TimeUnit.MILLISECONDS, getThreadFactoryDependency()); + TimeUnit.MILLISECONDS, getThreadFactoryDependency(), Optional.fromNullable(getQueueCapacity())); } } diff --git a/opendaylight/config/threadpool-config-impl/src/main/yang/threadpool-impl-flexible.yang b/opendaylight/config/threadpool-config-impl/src/main/yang/threadpool-impl-flexible.yang index be275ef487..c124f6388f 100644 --- a/opendaylight/config/threadpool-config-impl/src/main/yang/threadpool-impl-flexible.yang +++ b/opendaylight/config/threadpool-config-impl/src/main/yang/threadpool-impl-flexible.yang @@ -46,6 +46,12 @@ module threadpool-impl-flexible { type uint32; } + leaf queueCapacity { + type uint16; + mandatory false; + description "Capacity of queue that holds waiting tasks"; + } + container threadFactory { uses config:service-ref { refine type { diff --git a/opendaylight/distribution/opendaylight-karaf/pom.xml b/opendaylight/distribution/opendaylight-karaf/pom.xml index 221bfa78e8..4ef0b8e86b 100644 --- a/opendaylight/distribution/opendaylight-karaf/pom.xml +++ b/opendaylight/distribution/opendaylight-karaf/pom.xml @@ -61,6 +61,22 @@ kar runtime + + org.opendaylight.controller + features-odl-protocol-framework + ${protocol-framework.version} + features + xml + runtime + + + org.opendaylight.controller + netconf-features + ${netconf.version} + features + xml + runtime + org.opendaylight.controller config-features @@ -85,14 +101,6 @@ xml runtime - - org.opendaylight.yangtools - features-yangtools - ${yangtools.version} - features - xml - runtime - diff --git a/opendaylight/distribution/opendaylight-karaf/src/main/resources/configuration/initial/02-clustering.xml b/opendaylight/distribution/opendaylight-karaf/src/main/resources/configuration/initial/02-clustering.xml deleted file mode 100644 index 7853b8681b..0000000000 --- a/opendaylight/distribution/opendaylight-karaf/src/main/resources/configuration/initial/02-clustering.xml +++ /dev/null @@ -1,27 +0,0 @@ - - - - - - prefix:remote-zeromq-rpc-server - remoter - 5666 - - prefix:dom-broker-osgi-registry - dom-broker - - - - - - - - - - urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom?module=opendaylight-md-sal-dom&revision=2013-10-28 - urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom:impl?module=opendaylight-sal-dom-broker-impl&revision=2013-10-28 - urn:opendaylight:params:xml:ns:yang:controller:md:sal:common?module=opendaylight-md-sal-common&revision=2013-10-28 - urn:opendaylight:params:xml:ns:yang:controller:md:sal:remote:rpc?module=odl-sal-dom-rpc-remote-cfg&revision=2013-10-28 - - - diff --git a/opendaylight/distribution/opendaylight/src/main/resources/configuration/initial/01-netconf.xml b/opendaylight/distribution/opendaylight/src/main/resources/configuration/initial/01-netconf.xml index 8fedbe4d4c..f81a332ab6 100644 --- a/opendaylight/distribution/opendaylight/src/main/resources/configuration/initial/01-netconf.xml +++ b/opendaylight/distribution/opendaylight/src/main/resources/configuration/initial/01-netconf.xml @@ -12,7 +12,7 @@ - + prefix:netconf-client-dispatcher global-netconf-dispatcher @@ -30,24 +30,25 @@ - + prefix:threadfactory-naming global-netconf-processing-executor-threadfactory remote-connector-processing-executor - - + + prefix:threadpool-flexible global-netconf-processing-executor 1 4 600000 + prefix:threadfactory global-netconf-processing-executor-threadfactory - + diff --git a/opendaylight/md-sal/pom.xml b/opendaylight/md-sal/pom.xml index d3f6d2d005..1cfd5a6639 100644 --- a/opendaylight/md-sal/pom.xml +++ b/opendaylight/md-sal/pom.xml @@ -63,9 +63,6 @@ sal-protocolbuffer-encoding - - feature - sal-test-model diff --git a/opendaylight/md-sal/sal-inmemory-datastore/src/main/java/org/opendaylight/controller/config/yang/inmemory_datastore_provider/InMemoryConfigDataStoreProviderModule.java b/opendaylight/md-sal/sal-inmemory-datastore/src/main/java/org/opendaylight/controller/config/yang/inmemory_datastore_provider/InMemoryConfigDataStoreProviderModule.java index 3ed02dfb41..01a5989dcd 100644 --- a/opendaylight/md-sal/sal-inmemory-datastore/src/main/java/org/opendaylight/controller/config/yang/inmemory_datastore_provider/InMemoryConfigDataStoreProviderModule.java +++ b/opendaylight/md-sal/sal-inmemory-datastore/src/main/java/org/opendaylight/controller/config/yang/inmemory_datastore_provider/InMemoryConfigDataStoreProviderModule.java @@ -1,14 +1,17 @@ package org.opendaylight.controller.config.yang.inmemory_datastore_provider; -import com.google.common.util.concurrent.MoreExecutors; +import java.util.concurrent.Executors; + import org.opendaylight.controller.md.sal.dom.store.impl.InMemoryDOMDataStore; +import com.google.common.util.concurrent.MoreExecutors; + public class InMemoryConfigDataStoreProviderModule extends org.opendaylight.controller.config.yang.inmemory_datastore_provider.AbstractInMemoryConfigDataStoreProviderModule { - public InMemoryConfigDataStoreProviderModule(org.opendaylight.controller.config.api.ModuleIdentifier identifier, org.opendaylight.controller.config.api.DependencyResolver dependencyResolver) { + public InMemoryConfigDataStoreProviderModule(final org.opendaylight.controller.config.api.ModuleIdentifier identifier, final org.opendaylight.controller.config.api.DependencyResolver dependencyResolver) { super(identifier, dependencyResolver); } - public InMemoryConfigDataStoreProviderModule(org.opendaylight.controller.config.api.ModuleIdentifier identifier, org.opendaylight.controller.config.api.DependencyResolver dependencyResolver, org.opendaylight.controller.config.yang.inmemory_datastore_provider.InMemoryConfigDataStoreProviderModule oldModule, java.lang.AutoCloseable oldInstance) { + public InMemoryConfigDataStoreProviderModule(final org.opendaylight.controller.config.api.ModuleIdentifier identifier, final org.opendaylight.controller.config.api.DependencyResolver dependencyResolver, final org.opendaylight.controller.config.yang.inmemory_datastore_provider.InMemoryConfigDataStoreProviderModule oldModule, final java.lang.AutoCloseable oldInstance) { super(identifier, dependencyResolver, oldModule, oldInstance); } @@ -19,7 +22,7 @@ public class InMemoryConfigDataStoreProviderModule extends org.opendaylight.cont @Override public java.lang.AutoCloseable createInstance() { - InMemoryDOMDataStore ids = new InMemoryDOMDataStore("DOM-CFG", MoreExecutors.sameThreadExecutor()); + InMemoryDOMDataStore ids = new InMemoryDOMDataStore("DOM-CFG", MoreExecutors.listeningDecorator(Executors.newSingleThreadExecutor())); getSchemaServiceDependency().registerSchemaServiceListener(ids); return ids; } diff --git a/opendaylight/md-sal/sal-inmemory-datastore/src/main/java/org/opendaylight/controller/config/yang/inmemory_datastore_provider/InMemoryOperationalDataStoreProviderModule.java b/opendaylight/md-sal/sal-inmemory-datastore/src/main/java/org/opendaylight/controller/config/yang/inmemory_datastore_provider/InMemoryOperationalDataStoreProviderModule.java index eea95990a1..172b0dbc01 100644 --- a/opendaylight/md-sal/sal-inmemory-datastore/src/main/java/org/opendaylight/controller/config/yang/inmemory_datastore_provider/InMemoryOperationalDataStoreProviderModule.java +++ b/opendaylight/md-sal/sal-inmemory-datastore/src/main/java/org/opendaylight/controller/config/yang/inmemory_datastore_provider/InMemoryOperationalDataStoreProviderModule.java @@ -1,14 +1,17 @@ package org.opendaylight.controller.config.yang.inmemory_datastore_provider; -import com.google.common.util.concurrent.MoreExecutors; +import java.util.concurrent.Executors; + import org.opendaylight.controller.md.sal.dom.store.impl.InMemoryDOMDataStore; +import com.google.common.util.concurrent.MoreExecutors; + public class InMemoryOperationalDataStoreProviderModule extends org.opendaylight.controller.config.yang.inmemory_datastore_provider.AbstractInMemoryOperationalDataStoreProviderModule { - public InMemoryOperationalDataStoreProviderModule(org.opendaylight.controller.config.api.ModuleIdentifier identifier, org.opendaylight.controller.config.api.DependencyResolver dependencyResolver) { + public InMemoryOperationalDataStoreProviderModule(final org.opendaylight.controller.config.api.ModuleIdentifier identifier, final org.opendaylight.controller.config.api.DependencyResolver dependencyResolver) { super(identifier, dependencyResolver); } - public InMemoryOperationalDataStoreProviderModule(org.opendaylight.controller.config.api.ModuleIdentifier identifier, org.opendaylight.controller.config.api.DependencyResolver dependencyResolver, org.opendaylight.controller.config.yang.inmemory_datastore_provider.InMemoryOperationalDataStoreProviderModule oldModule, java.lang.AutoCloseable oldInstance) { + public InMemoryOperationalDataStoreProviderModule(final org.opendaylight.controller.config.api.ModuleIdentifier identifier, final org.opendaylight.controller.config.api.DependencyResolver dependencyResolver, final org.opendaylight.controller.config.yang.inmemory_datastore_provider.InMemoryOperationalDataStoreProviderModule oldModule, final java.lang.AutoCloseable oldInstance) { super(identifier, dependencyResolver, oldModule, oldInstance); } @@ -19,7 +22,7 @@ public class InMemoryOperationalDataStoreProviderModule extends org.opendaylight @Override public java.lang.AutoCloseable createInstance() { - InMemoryDOMDataStore ids = new InMemoryDOMDataStore("DOM-OPER", MoreExecutors.sameThreadExecutor()); + InMemoryDOMDataStore ids = new InMemoryDOMDataStore("DOM-OPER", MoreExecutors.listeningDecorator(Executors.newSingleThreadExecutor())); getSchemaServiceDependency().registerSchemaServiceListener(ids); return ids; } diff --git a/opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/NetconfDevice.java b/opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/NetconfDevice.java index dca8fcafef..de4ac7ac18 100644 --- a/opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/NetconfDevice.java +++ b/opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/NetconfDevice.java @@ -7,15 +7,19 @@ */ package org.opendaylight.controller.sal.connect.netconf; +import com.google.common.annotations.VisibleForTesting; +import com.google.common.base.Preconditions; import com.google.common.util.concurrent.FutureCallback; import com.google.common.util.concurrent.Futures; import com.google.common.util.concurrent.ListenableFuture; import com.google.common.util.concurrent.ListeningExecutorService; import com.google.common.util.concurrent.MoreExecutors; import java.io.InputStream; +import java.util.LinkedList; +import java.util.List; import java.util.concurrent.ExecutorService; - import org.opendaylight.controller.netconf.api.NetconfMessage; +import org.opendaylight.controller.netconf.util.xml.XmlUtil; import org.opendaylight.controller.sal.connect.api.MessageTransformer; import org.opendaylight.controller.sal.connect.api.RemoteDevice; import org.opendaylight.controller.sal.connect.api.RemoteDeviceCommunicator; @@ -36,9 +40,6 @@ import org.opendaylight.yangtools.yang.model.util.repo.SchemaSourceProvider; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import com.google.common.annotations.VisibleForTesting; -import com.google.common.base.Preconditions; - /** * This is a mediator between NetconfDeviceCommunicator and NetconfDeviceSalFacade */ @@ -53,6 +54,7 @@ public final class NetconfDevice implements RemoteDevice messageTransformer; private final SchemaContextProviderFactory schemaContextProviderFactory; private final SchemaSourceProviderFactory sourceProviderFactory; + private final NotificationHandler notificationHandler; public static NetconfDevice createNetconfDevice(final RemoteDeviceId id, final AbstractCachingSchemaSourceProvider schemaSourceProvider, @@ -79,6 +81,7 @@ public final class NetconfDevice implements RemoteDevice salFacade; + private final List cache = new LinkedList<>(); + private final MessageTransformer messageTransformer; + private boolean passNotifications = false; + private final RemoteDeviceId id; + + NotificationHandler(final RemoteDeviceHandler salFacade, final MessageTransformer messageTransformer, final RemoteDeviceId id) { + this.salFacade = salFacade; + this.messageTransformer = messageTransformer; + this.id = id; + } + + synchronized void handleNotification(final NetconfMessage notification) { + if(passNotifications) { + passNotification(messageTransformer.toNotification(notification)); + } else { + cacheNotification(notification); + } + } + + /** + * Forward all cached notifications and pass all notifications from this point directly to sal facade. + */ + synchronized void onRemoteSchemaUp() { + passNotifications = true; + + for (final NetconfMessage cachedNotification : cache) { + passNotification(messageTransformer.toNotification(cachedNotification)); + } + + cache.clear(); + } + + private void cacheNotification(final NetconfMessage notification) { + Preconditions.checkState(passNotifications == false); + + logger.debug("{}: Caching notification {}, remote schema not yet fully built", id, notification); + if(logger.isTraceEnabled()) { + logger.trace("{}: Caching notification {}", id, XmlUtil.toString(notification.getDocument())); + } + + cache.add(notification); + } + + private void passNotification(final CompositeNode parsedNotification) { + logger.debug("{}: Forwarding notification {}", id, parsedNotification); + Preconditions.checkNotNull(parsedNotification); + salFacade.onNotification(parsedNotification); + } + } } diff --git a/opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/sal/NetconfDeviceTwoPhaseCommitTransaction.java b/opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/sal/NetconfDeviceTwoPhaseCommitTransaction.java index 0ef76d330d..960f2ef2e8 100644 --- a/opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/sal/NetconfDeviceTwoPhaseCommitTransaction.java +++ b/opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/sal/NetconfDeviceTwoPhaseCommitTransaction.java @@ -44,6 +44,7 @@ import org.opendaylight.yangtools.yang.data.api.CompositeNode; import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier; import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.NodeIdentifierWithPredicates; import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.PathArgument; +import org.opendaylight.yangtools.yang.data.api.ModifyAction; import org.opendaylight.yangtools.yang.data.api.Node; import org.opendaylight.yangtools.yang.data.api.SimpleNode; import org.opendaylight.yangtools.yang.data.impl.ImmutableCompositeNode; @@ -90,16 +91,14 @@ final class NetconfDeviceTwoPhaseCommitTransaction implements DataCommitTransact } private void sendMerge(final InstanceIdentifier key, final CompositeNode value) throws InterruptedException, ExecutionException { - sendEditRpc(createEditConfigStructure(key, Optional.absent(), Optional.of(value)), Optional.absent()); + sendEditRpc(createEditConfigStructure(key, Optional.absent(), Optional.of(value)), Optional.absent()); } private void sendDelete(final InstanceIdentifier toDelete) throws InterruptedException, ExecutionException { - // FIXME use org.opendaylight.yangtools.yang.data.api.ModifyAction instead of strings - // TODO add string lowercase value to ModifyAction enum entries - sendEditRpc(createEditConfigStructure(toDelete, Optional.of("delete"), Optional.absent()), Optional.of("none")); + sendEditRpc(createEditConfigStructure(toDelete, Optional.of(ModifyAction.DELETE), Optional.absent()), Optional.of(ModifyAction.NONE)); } - private void sendEditRpc(final CompositeNode editStructure, final Optional defaultOperation) throws InterruptedException, ExecutionException { + private void sendEditRpc(final CompositeNode editStructure, final Optional defaultOperation) throws InterruptedException, ExecutionException { final ImmutableCompositeNode editConfigRequest = createEditConfigRequest(editStructure, defaultOperation); final RpcResult rpcResult = rpc.invokeRpc(NETCONF_EDIT_CONFIG_QNAME, editConfigRequest).get(); @@ -110,7 +109,7 @@ final class NetconfDeviceTwoPhaseCommitTransaction implements DataCommitTransact } } - private ImmutableCompositeNode createEditConfigRequest(final CompositeNode editStructure, final Optional defaultOperation) { + private ImmutableCompositeNode createEditConfigRequest(final CompositeNode editStructure, final Optional defaultOperation) { final CompositeNodeBuilder ret = ImmutableCompositeNode.builder(); // Target @@ -119,7 +118,7 @@ final class NetconfDeviceTwoPhaseCommitTransaction implements DataCommitTransact // Default operation if(defaultOperation.isPresent()) { - SimpleNode defOp = NodeFactory.createImmutableSimpleNode(NETCONF_DEFAULT_OPERATION_QNAME, null, defaultOperation.get()); + final SimpleNode defOp = NodeFactory.createImmutableSimpleNode(NETCONF_DEFAULT_OPERATION_QNAME, null, modifyOperationToXmlString(defaultOperation.get())); ret.add(defOp); } @@ -134,7 +133,7 @@ final class NetconfDeviceTwoPhaseCommitTransaction implements DataCommitTransact return ret.toInstance(); } - private CompositeNode createEditConfigStructure(final InstanceIdentifier dataPath, final Optional operation, + private CompositeNode createEditConfigStructure(final InstanceIdentifier dataPath, final Optional operation, final Optional lastChildOverride) { Preconditions.checkArgument(Iterables.isEmpty(dataPath.getPathArguments()) == false, "Instance identifier with empty path %s", dataPath); @@ -174,7 +173,7 @@ final class NetconfDeviceTwoPhaseCommitTransaction implements DataCommitTransact return predicates; } - private CompositeNode getDeepestEditElement(final PathArgument arg, final Optional operation, final Optional lastChildOverride) { + private CompositeNode getDeepestEditElement(final PathArgument arg, final Optional operation, final Optional lastChildOverride) { final CompositeNodeBuilder builder = ImmutableCompositeNode.builder(); builder.setQName(arg.getNodeType()); @@ -182,7 +181,7 @@ final class NetconfDeviceTwoPhaseCommitTransaction implements DataCommitTransact addPredicatesToCompositeNodeBuilder(predicates, builder); if (operation.isPresent()) { - builder.setAttribute(NETCONF_OPERATION_QNAME, operation.get()); + builder.setAttribute(NETCONF_OPERATION_QNAME, modifyOperationToXmlString(operation.get())); } if (lastChildOverride.isPresent()) { final List> children = lastChildOverride.get().getValue(); @@ -196,6 +195,10 @@ final class NetconfDeviceTwoPhaseCommitTransaction implements DataCommitTransact return builder.toInstance(); } + private String modifyOperationToXmlString(final ModifyAction operation) { + return operation.name().toLowerCase(); + } + /** * Send commit rpc to finish the transaction * In case of failure or unexpected error response, ExecutionException is thrown diff --git a/opendaylight/md-sal/sal-netconf-connector/src/test/java/org/opendaylight/controller/sal/connect/netconf/NetconfDeviceTest.java b/opendaylight/md-sal/sal-netconf-connector/src/test/java/org/opendaylight/controller/sal/connect/netconf/NetconfDeviceTest.java index ec2a820daa..defaab629f 100644 --- a/opendaylight/md-sal/sal-netconf-connector/src/test/java/org/opendaylight/controller/sal/connect/netconf/NetconfDeviceTest.java +++ b/opendaylight/md-sal/sal-netconf-connector/src/test/java/org/opendaylight/controller/sal/connect/netconf/NetconfDeviceTest.java @@ -12,6 +12,7 @@ import static org.mockito.Matchers.anyString; import static org.mockito.Mockito.doNothing; import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.timeout; +import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import java.io.InputStream; @@ -82,6 +83,32 @@ public class NetconfDeviceTest { Mockito.verify(facade, Mockito.timeout(5000)).onDeviceDisconnected(); } + @Test + public void testNotificationBeforeSchema() throws Exception { + final RemoteDeviceHandler facade = getFacade(); + final RemoteDeviceCommunicator listener = getListener(); + + final MessageTransformer messageTransformer = getMessageTransformer(); + final NetconfDevice device = new NetconfDevice(getId(), facade, getExecutor(), messageTransformer, getSchemaContextProviderFactory(), getSourceProviderFactory()); + + device.onNotification(netconfMessage); + device.onNotification(netconfMessage); + + verify(facade, times(0)).onNotification(any(CompositeNode.class)); + + final NetconfSessionCapabilities sessionCaps = getSessionCaps(true, + Lists.newArrayList(TEST_NAMESPACE + "?module=" + TEST_MODULE + "&revision=" + TEST_REVISION)); + + device.onRemoteSessionUp(sessionCaps, listener); + + verify(messageTransformer, timeout(10000).times(2)).toNotification(netconfMessage); + verify(facade, times(2)).onNotification(compositeNode); + + device.onNotification(netconfMessage); + verify(messageTransformer, times(3)).toNotification(netconfMessage); + verify(facade, times(3)).onNotification(compositeNode); + } + @Test public void testNetconfDeviceReconnect() throws Exception { final RemoteDeviceHandler facade = getFacade(); @@ -136,6 +163,7 @@ public class NetconfDeviceTest { final RemoteDeviceHandler remoteDeviceHandler = mockCloseableClass(RemoteDeviceHandler.class); doNothing().when(remoteDeviceHandler).onDeviceConnected(any(SchemaContextProvider.class), any(NetconfSessionCapabilities.class), any(RpcImplementation.class)); doNothing().when(remoteDeviceHandler).onDeviceDisconnected(); + doNothing().when(remoteDeviceHandler).onNotification(any(CompositeNode.class)); return remoteDeviceHandler; } @@ -173,6 +201,7 @@ public class NetconfDeviceTest { final MessageTransformer messageTransformer = mockClass(MessageTransformer.class); doReturn(netconfMessage).when(messageTransformer).toRpcRequest(any(QName.class), any(CompositeNode.class)); doReturn(rpcResultC).when(messageTransformer).toRpcResult(any(NetconfMessage.class), any(QName.class)); + doReturn(compositeNode).when(messageTransformer).toNotification(any(NetconfMessage.class)); doNothing().when(messageTransformer).onGlobalContextUpdated(any(SchemaContext.class)); return messageTransformer; } @@ -197,4 +226,4 @@ public class NetconfDeviceTest { doReturn(Futures.immediateFuture(rpcResult)).when(remoteDeviceCommunicator).sendRequest(any(NetconfMessage.class), any(QName.class)); return remoteDeviceCommunicator; } -} \ No newline at end of file +} diff --git a/opendaylight/md-sal/statistics-manager/src/main/java/org/opendaylight/controller/md/statistics/manager/FlowComparator.java b/opendaylight/md-sal/statistics-manager/src/main/java/org/opendaylight/controller/md/statistics/manager/FlowComparator.java index af61db1a80..b1db280c24 100644 --- a/opendaylight/md-sal/statistics-manager/src/main/java/org/opendaylight/controller/md/statistics/manager/FlowComparator.java +++ b/opendaylight/md-sal/statistics-manager/src/main/java/org/opendaylight/controller/md/statistics/manager/FlowComparator.java @@ -95,6 +95,8 @@ final class FlowComparator { if (statsFlow == storedFlow) { return true; } + if (storedFlow == null && statsFlow != null) return false; + if (statsFlow == null && storedFlow != null) return false; if (storedFlow.getClass() != statsFlow.getClass()) { return false; } diff --git a/opendaylight/netconf/netconf-netty-util/src/main/java/org/opendaylight/controller/netconf/nettyutil/AbstractNetconfSessionNegotiator.java b/opendaylight/netconf/netconf-netty-util/src/main/java/org/opendaylight/controller/netconf/nettyutil/AbstractNetconfSessionNegotiator.java index 1360a54d6f..de3f732b25 100644 --- a/opendaylight/netconf/netconf-netty-util/src/main/java/org/opendaylight/controller/netconf/nettyutil/AbstractNetconfSessionNegotiator.java +++ b/opendaylight/netconf/netconf-netty-util/src/main/java/org/opendaylight/controller/netconf/nettyutil/AbstractNetconfSessionNegotiator.java @@ -11,6 +11,7 @@ package org.opendaylight.controller.netconf.nettyutil; import com.google.common.base.Optional; import com.google.common.base.Preconditions; import io.netty.channel.Channel; +import io.netty.channel.ChannelFuture; import io.netty.channel.ChannelHandler; import io.netty.channel.ChannelHandlerContext; import io.netty.channel.ChannelInboundHandlerAdapter; @@ -104,7 +105,7 @@ extends AbstractSessionNegotiator { private void start() { final NetconfMessage helloMessage = this.sessionPreferences.getHelloMessage(); - logger.debug("Session negotiation started with hello message {}", XmlUtil.toString(helloMessage.getDocument())); + logger.debug("Session negotiation started with hello message {} on channel {}", XmlUtil.toString(helloMessage.getDocument()), channel); channel.pipeline().addLast(NAME_OF_EXCEPTION_HANDLER, new ExceptionHandlingInboundChannelHandler()); @@ -125,12 +126,20 @@ extends AbstractSessionNegotiator { // Do not fail negotiation if promise is done or canceled // It would result in setting result of the promise second time and that throws exception if (isPromiseFinished() == false) { - // FIXME BUG-1365 calling "negotiation failed" closes the channel, but the channel does not get closed if data is still being transferred - // Loopback connection initiation might negotiationFailed(new IllegalStateException("Session was not established after " + timeout)); + changeState(State.FAILED); + + channel.closeFuture().addListener(new GenericFutureListener() { + @Override + public void operationComplete(ChannelFuture future) throws Exception { + if(future.isSuccess()) { + logger.debug("Channel {} closed: success", future.channel()); + } else { + logger.warn("Channel {} closed: fail", future.channel()); + } + } + }); } - - changeState(State.FAILED); } else if(channel.isOpen()) { channel.pipeline().remove(NAME_OF_EXCEPTION_HANDLER); } @@ -214,9 +223,9 @@ extends AbstractSessionNegotiator { protected abstract S getSession(L sessionListener, Channel channel, NetconfHelloMessage message) throws NetconfDocumentedException; private synchronized void changeState(final State newState) { - logger.debug("Changing state from : {} to : {}", state, newState); - Preconditions.checkState(isStateChangePermitted(state, newState), "Cannot change state from %s to %s", state, - newState); + logger.debug("Changing state from : {} to : {} for channel: {}", state, newState, channel); + Preconditions.checkState(isStateChangePermitted(state, newState), "Cannot change state from %s to %s for chanel %s", state, + newState, channel); this.state = newState; } diff --git a/opendaylight/netconf/netconf-netty-util/src/main/java/org/opendaylight/controller/netconf/nettyutil/handler/NetconfEOMAggregator.java b/opendaylight/netconf/netconf-netty-util/src/main/java/org/opendaylight/controller/netconf/nettyutil/handler/NetconfEOMAggregator.java index f260bcbcef..a87a08ded7 100644 --- a/opendaylight/netconf/netconf-netty-util/src/main/java/org/opendaylight/controller/netconf/nettyutil/handler/NetconfEOMAggregator.java +++ b/opendaylight/netconf/netconf-netty-util/src/main/java/org/opendaylight/controller/netconf/nettyutil/handler/NetconfEOMAggregator.java @@ -9,56 +9,15 @@ package org.opendaylight.controller.netconf.nettyutil.handler; import io.netty.buffer.ByteBuf; -import io.netty.channel.ChannelHandlerContext; -import io.netty.handler.codec.ByteToMessageDecoder; - -import java.util.List; - +import io.netty.buffer.Unpooled; +import io.netty.handler.codec.DelimiterBasedFrameDecoder; import org.opendaylight.controller.netconf.util.messages.NetconfMessageConstants; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import com.google.common.base.Charsets; +public class NetconfEOMAggregator extends DelimiterBasedFrameDecoder { -public class NetconfEOMAggregator extends ByteToMessageDecoder { - private final static Logger logger = LoggerFactory.getLogger(NetconfEOMAggregator.class); + public static final ByteBuf DELIMITER = Unpooled.wrappedBuffer(NetconfMessageConstants.END_OF_MESSAGE); - @Override - protected void decode(ChannelHandlerContext ctx, ByteBuf in, List out) { - int index = indexOfSequence(in, NetconfMessageConstants.END_OF_MESSAGE); - if (index == -1) { - logger.debug("Message is not complete, read again."); - if (logger.isTraceEnabled()) { - String str = in.toString(Charsets.UTF_8); - logger.trace("Message read so far: {}", str); - } - ctx.read(); - } else { - ByteBuf msg = in.readBytes(index); - in.readBytes(NetconfMessageConstants.END_OF_MESSAGE.length); - in.discardReadBytes(); - logger.debug("Message is complete."); - out.add(msg); - } + public NetconfEOMAggregator() { + super(Integer.MAX_VALUE, DELIMITER); } - - private int indexOfSequence(ByteBuf in, byte[] sequence) { - int index = -1; - for (int i = 0; i < in.readableBytes() - sequence.length + 1; i++) { - if (in.getByte(i) == sequence[0]) { - index = i; - for (int j = 1; j < sequence.length; j++) { - if (in.getByte(i + j) != sequence[j]) { - index = -1; - break; - } - } - if (index != -1) { - return index; - } - } - } - return index; - } - } diff --git a/opendaylight/netconf/netconf-netty-util/src/main/java/org/opendaylight/controller/netconf/nettyutil/handler/NetconfMessageToXMLEncoder.java b/opendaylight/netconf/netconf-netty-util/src/main/java/org/opendaylight/controller/netconf/nettyutil/handler/NetconfMessageToXMLEncoder.java index fae2000bb5..d810a870ff 100644 --- a/opendaylight/netconf/netconf-netty-util/src/main/java/org/opendaylight/controller/netconf/nettyutil/handler/NetconfMessageToXMLEncoder.java +++ b/opendaylight/netconf/netconf-netty-util/src/main/java/org/opendaylight/controller/netconf/nettyutil/handler/NetconfMessageToXMLEncoder.java @@ -12,6 +12,7 @@ import io.netty.buffer.ByteBufOutputStream; import io.netty.channel.ChannelHandlerContext; import io.netty.handler.codec.MessageToByteEncoder; +import java.io.BufferedWriter; import java.io.IOException; import java.io.OutputStream; import java.io.OutputStreamWriter; @@ -61,7 +62,8 @@ public class NetconfMessageToXMLEncoder extends MessageToByteEncoderopendaylight/dummy-console opendaylight/karaf-branding opendaylight/distribution/opendaylight-karaf + features scm:git:ssh://git.opendaylight.org:29418/controller.git