From: Tom Pantelis Date: Thu, 24 Jul 2014 19:44:19 +0000 (+0000) Subject: Merge "Bug 1280: Added option to automaticly create parents" X-Git-Tag: release/helium~449 X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?p=controller.git;a=commitdiff_plain;h=723a9e90e2d36c55368f5b1801b8329ceba5c339;hp=45d8b39b7584805d173a143e77dbff671b60f97f Merge "Bug 1280: Added option to automaticly create parents" --- diff --git a/opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/osgi/ExtensibleBundleTracker.java b/opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/osgi/ExtensibleBundleTracker.java index c1ebba7881..eff267ad13 100644 --- a/opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/osgi/ExtensibleBundleTracker.java +++ b/opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/osgi/ExtensibleBundleTracker.java @@ -7,6 +7,13 @@ */ package org.opendaylight.controller.config.manager.impl.osgi; +import com.google.common.util.concurrent.ThreadFactoryBuilder; +import java.util.concurrent.Callable; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.Future; +import java.util.concurrent.ThreadFactory; import org.osgi.framework.Bundle; import org.osgi.framework.BundleContext; import org.osgi.framework.BundleEvent; @@ -15,74 +22,114 @@ import org.osgi.util.tracker.BundleTrackerCustomizer; import org.slf4j.Logger; import org.slf4j.LoggerFactory; + /** * - * Extensible bundle tracker. Takes several BundleTrackerCustomizers and propagates bundle events to all of them. - * Primary customizer + * Extensible bundle tracker. Takes several BundleTrackerCustomizers and + * propagates bundle events to all of them. + * + * Primary customizer may return tracking object, + * which will be passed to it during invocation of + * {@link BundleTrackerCustomizer#removedBundle(Bundle, BundleEvent, Future)} + * + * + * This extender modifies behaviour to not leak platform thread + * in {@link BundleTrackerCustomizer#addingBundle(Bundle, BundleEvent)} + * but deliver this event from its own single threaded executor. + * + * If bundle is removed before event for adding bundle was executed, + * that event is cancelled. If addingBundle event is currently in progress + * or was already executed, platform thread is block untill addingBundle + * finishes so bundle could be removed correctly in platform thread. + * + * + * Method {@link BundleTrackerCustomizer#removedBundle(Bundle, BundleEvent, Object)} + * is never invoked on registered trackers. * * @param */ -public final class ExtensibleBundleTracker extends BundleTracker { +public final class ExtensibleBundleTracker extends BundleTracker> { + private static final ThreadFactory THREAD_FACTORY = new ThreadFactoryBuilder() + .setNameFormat("config-bundle-tracker-%d") + .build(); + private final ExecutorService eventExecutor; private final BundleTrackerCustomizer primaryTracker; private final BundleTrackerCustomizer[] additionalTrackers; - private static final Logger logger = LoggerFactory.getLogger(ExtensibleBundleTracker.class); + private static final Logger LOG = LoggerFactory.getLogger(ExtensibleBundleTracker.class); - public ExtensibleBundleTracker(BundleContext context, BundleTrackerCustomizer primaryBundleTrackerCustomizer, - BundleTrackerCustomizer... additionalBundleTrackerCustomizers) { + public ExtensibleBundleTracker(final BundleContext context, final BundleTrackerCustomizer primaryBundleTrackerCustomizer, + final BundleTrackerCustomizer... additionalBundleTrackerCustomizers) { this(context, Bundle.ACTIVE, primaryBundleTrackerCustomizer, additionalBundleTrackerCustomizers); } - public ExtensibleBundleTracker(BundleContext context, int bundleState, - BundleTrackerCustomizer primaryBundleTrackerCustomizer, - BundleTrackerCustomizer... additionalBundleTrackerCustomizers) { + public ExtensibleBundleTracker(final BundleContext context, final int bundleState, + final BundleTrackerCustomizer primaryBundleTrackerCustomizer, + final BundleTrackerCustomizer... additionalBundleTrackerCustomizers) { super(context, bundleState, null); this.primaryTracker = primaryBundleTrackerCustomizer; this.additionalTrackers = additionalBundleTrackerCustomizers; - logger.trace("Registered as extender with context {} and bundle state {}", context, bundleState); + eventExecutor = Executors.newSingleThreadExecutor(THREAD_FACTORY); + LOG.trace("Registered as extender with context {} and bundle state {}", context, bundleState); } @Override - public T addingBundle(final Bundle bundle, final BundleEvent event) { - T primaryTrackerRetVal = primaryTracker.addingBundle(bundle, event); - - forEachAdditionalBundle(new BundleStrategy() { + public Future addingBundle(final Bundle bundle, final BundleEvent event) { + LOG.trace("Submiting AddingBundle for bundle {} and event {} to be processed asynchronously",bundle,event); + Future future = eventExecutor.submit(new Callable() { @Override - public void execute(BundleTrackerCustomizer tracker) { - tracker.addingBundle(bundle, event); + public T call() throws Exception { + try { + T primaryTrackerRetVal = primaryTracker.addingBundle(bundle, event); + + forEachAdditionalBundle(new BundleStrategy() { + @Override + public void execute(final BundleTrackerCustomizer tracker) { + tracker.addingBundle(bundle, event); + } + }); + LOG.trace("AddingBundle for {} and event {} finished successfully",bundle,event); + return primaryTrackerRetVal; + } catch (Exception e) { + LOG.error("Failed to add bundle {}",e); + throw e; + } } }); - - return primaryTrackerRetVal; + return future; } @Override - public void modifiedBundle(final Bundle bundle, final BundleEvent event, final T object) { - primaryTracker.modifiedBundle(bundle, event, object); - - forEachAdditionalBundle(new BundleStrategy() { - @Override - public void execute(BundleTrackerCustomizer tracker) { - tracker.modifiedBundle(bundle, event, null); - } - }); + public void modifiedBundle(final Bundle bundle, final BundleEvent event, final Future object) { + // Intentionally NOOP } @Override - public void removedBundle(final Bundle bundle, final BundleEvent event, final T object) { - primaryTracker.removedBundle(bundle, event, object); - - forEachAdditionalBundle(new BundleStrategy() { - @Override - public void execute(BundleTrackerCustomizer tracker) { - tracker.removedBundle(bundle, event, null); - } - }); + public void removedBundle(final Bundle bundle, final BundleEvent event, final Future object) { + if(!object.isDone() && object.cancel(false)) { + // We canceled adding event before it was processed + // so it is safe to return + LOG.trace("Adding Bundle event for {} was cancelled. No additional work required.",bundle); + return; + } + try { + LOG.trace("Invoking removedBundle event for {}",bundle); + primaryTracker.removedBundle(bundle, event, object.get()); + forEachAdditionalBundle(new BundleStrategy() { + @Override + public void execute(final BundleTrackerCustomizer tracker) { + tracker.removedBundle(bundle, event, null); + } + }); + LOG.trace("Removed bundle event for {} finished successfully.",bundle); + } catch (InterruptedException | ExecutionException e) { + LOG.error("Addition of bundle failed, ", e); + } } - private void forEachAdditionalBundle(BundleStrategy lambda) { + private void forEachAdditionalBundle(final BundleStrategy lambda) { for (BundleTrackerCustomizer trac : additionalTrackers) { lambda.execute(trac); } diff --git a/opendaylight/distribution/opendaylight-karaf/pom.xml b/opendaylight/distribution/opendaylight-karaf/pom.xml index efb7a374f3..06e0a92fa6 100644 --- a/opendaylight/distribution/opendaylight-karaf/pom.xml +++ b/opendaylight/distribution/opendaylight-karaf/pom.xml @@ -232,6 +232,25 @@ + + org.apache.maven.plugins + maven-antrun-plugin + + + prepare-package + + run + + + + + + + + + + + diff --git a/opendaylight/distribution/opendaylight-karaf/src/main/resources/karaf/instance b/opendaylight/distribution/opendaylight-karaf/src/main/resources/karaf/instance new file mode 100755 index 0000000000..7288042bab --- /dev/null +++ b/opendaylight/distribution/opendaylight-karaf/src/main/resources/karaf/instance @@ -0,0 +1,349 @@ +#!/bin/sh +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +DIRNAME=`dirname "$0"` +PROGNAME=`basename "$0"` + +# +# Sourcing environment settings for karaf similar to tomcats setenv +# +KARAF_SCRIPT="instance" +export KARAF_SCRIPT +if [ -f "$DIRNAME/setenv" ]; then + . "$DIRNAME/setenv" +fi + +# +# Check/Set up some easily accessible MIN/MAX params for JVM mem usage +# +if [ "x$JAVA_MIN_MEM" = "x" ]; then + JAVA_MIN_MEM=128M + export JAVA_MIN_MEM +fi +if [ "x$JAVA_MAX_MEM" = "x" ]; then + JAVA_MAX_MEM=512M + export JAVA_MAX_MEM +fi + +warn() { + echo "${PROGNAME}: $*" +} + +die() { + warn "$*" + exit 1 +} + +detectOS() { + # OS specific support (must be 'true' or 'false'). + cygwin=false; + darwin=false; + aix=false; + os400=false; + case "`uname`" in + CYGWIN*) + cygwin=true + ;; + Darwin*) + darwin=true + ;; + AIX*) + aix=true + ;; + OS400*) + os400=true + ;; + esac + # For AIX, set an environment variable + if $aix; then + export LDR_CNTRL=MAXDATA=0xB0000000@DSA + echo $LDR_CNTRL + fi +} + +unlimitFD() { + # Use the maximum available, or set MAX_FD != -1 to use that + if [ "x$MAX_FD" = "x" ]; then + MAX_FD="maximum" + fi + + # Increase the maximum file descriptors if we can + if [ "$os400" = "false" ] && [ "$cygwin" = "false" ]; then + MAX_FD_LIMIT=`ulimit -H -n` + if [ "$MAX_FD_LIMIT" != 'unlimited' ]; then + if [ $? -eq 0 ]; then + if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ]; then + # use the system max + MAX_FD="$MAX_FD_LIMIT" + fi + + ulimit -n $MAX_FD > /dev/null + # echo "ulimit -n" `ulimit -n` + if [ $? -ne 0 ]; then + warn "Could not set maximum file descriptor limit: $MAX_FD" + fi + else + warn "Could not query system maximum file descriptor limit: $MAX_FD_LIMIT" + fi + fi + fi +} + +locateHome() { + if [ "x$KARAF_HOME" != "x" ]; then + warn "Ignoring predefined value for KARAF_HOME" + fi + + # In POSIX shells, CDPATH may cause cd to write to stdout + (unset CDPATH) >/dev/null 2>&1 && unset CDPATH + + KARAF_HOME=`cd "$DIRNAME/.."; pwd` + if [ ! -d "$KARAF_HOME" ]; then + die "KARAF_HOME is not valid: $KARAF_HOME" + fi +} + +locateBase() { + if [ "x$KARAF_BASE" != "x" ]; then + if [ ! -d "$KARAF_BASE" ]; then + die "KARAF_BASE is not valid: $KARAF_BASE" + fi + else + KARAF_BASE=$KARAF_HOME + fi +} + +locateData() { + if [ "x$KARAF_DATA" != "x" ]; then + if [ ! -d "$KARAF_DATA" ]; then + die "KARAF_DATA is not valid: $KARAF_DATA" + fi + else + KARAF_DATA=$KARAF_BASE/data + fi +} + +locateEtc() { + if [ "x$KARAF_ETC" != "x" ]; then + if [ ! -d "$KARAF_ETC" ]; then + die "KARAF_ETC is not valid: $KARAF_ETC" + fi + else + KARAF_ETC=$KARAF_BASE/etc + fi +} + +setupNativePath() { + # Support for loading native libraries + LD_LIBRARY_PATH="${LD_LIBRARY_PATH}:$KARAF_BASE/lib:$KARAF_HOME/lib" + + # For Cygwin, set PATH from LD_LIBRARY_PATH + if $cygwin; then + LD_LIBRARY_PATH=`cygpath --path --windows "$LD_LIBRARY_PATH"` + PATH="$PATH;$LD_LIBRARY_PATH" + export PATH + fi + export LD_LIBRARY_PATH +} + +pathCanonical() { + local dst="${1}" + while [ -h "${dst}" ] ; do + ls=`ls -ld "${dst}"` + link=`expr "$ls" : '.*-> \(.*\)$'` + if expr "$link" : '/.*' > /dev/null; then + dst="$link" + else + dst="`dirname "${dst}"`/$link" + fi + done + local bas=`basename "${dst}"` + local dir=`dirname "${dst}"` + if [ "$bas" != "$dir" ]; then + dst="`pathCanonical "$dir"`/$bas" + fi + echo "${dst}" | sed -e 's#//#/#g' -e 's#/./#/#g' -e 's#/[^/]*/../#/#g' +} + +locateJava() { + # Setup the Java Virtual Machine + if $cygwin ; then + [ -n "$JAVA" ] && JAVA=`cygpath --unix "$JAVA"` + [ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"` + fi + + if [ "x$JAVA_HOME" = "x" ] && [ "$darwin" = "true" ]; then + JAVA_HOME="$(/usr/libexec/java_home)" + fi + if [ "x$JAVA" = "x" ] && [ -r /etc/gentoo-release ] ; then + JAVA_HOME=`java-config --jre-home` + fi + if [ "x$JAVA" = "x" ]; then + if [ "x$JAVA_HOME" != "x" ]; then + if [ ! -d "$JAVA_HOME" ]; then + die "JAVA_HOME is not valid: $JAVA_HOME" + fi + JAVA="$JAVA_HOME/bin/java" + else + warn "JAVA_HOME not set; results may vary" + JAVA=`type java` + JAVA=`expr "$JAVA" : '.*is \(.*\)$'` + if [ "x$JAVA" = "x" ]; then + die "java command not found" + fi + fi + fi + if [ "x$JAVA_HOME" = "x" ]; then + JAVA_HOME="$(dirname $(dirname $(pathCanonical "$JAVA")))" + fi +} + +detectJVM() { + #echo "`$JAVA -version`" + # This service should call `java -version`, + # read stdout, and look for hints + if $JAVA -version 2>&1 | grep "^IBM" ; then + JVM_VENDOR="IBM" + # on OS/400, java -version does not contain IBM explicitly + elif $os400; then + JVM_VENDOR="IBM" + else + JVM_VENDOR="SUN" + fi + # echo "JVM vendor is $JVM_VENDOR" +} + +setupDebugOptions() { + if [ "x$JAVA_OPTS" = "x" ]; then + JAVA_OPTS="$DEFAULT_JAVA_OPTS" + fi + export JAVA_OPTS + + # Set Debug options if enabled + if [ "x$KARAF_DEBUG" != "x" ]; then + # Use the defaults if JAVA_DEBUG_OPTS was not set + if [ "x$JAVA_DEBUG_OPTS" = "x" ]; then + JAVA_DEBUG_OPTS="$DEFAULT_JAVA_DEBUG_OPTS" + fi + + JAVA_OPTS="$JAVA_DEBUG_OPTS $JAVA_OPTS" + warn "Enabling Java debug options: $JAVA_DEBUG_OPTS" + fi +} + +setupDefaults() { + DEFAULT_JAVA_OPTS="-Xms$JAVA_MIN_MEM -Xmx$JAVA_MAX_MEM " + + #Set the JVM_VENDOR specific JVM flags + if [ "$JVM_VENDOR" = "SUN" ]; then + # + # Check some easily accessible MIN/MAX params for JVM mem usage + # + if [ "x$JAVA_PERM_MEM" != "x" ]; then + DEFAULT_JAVA_OPTS="$DEFAULT_JAVA_OPTS -XX:PermSize=$JAVA_PERM_MEM" + fi + if [ "x$JAVA_MAX_PERM_MEM" != "x" ]; then + DEFAULT_JAVA_OPTS="$DEFAULT_JAVA_OPTS -XX:MaxPermSize=$JAVA_MAX_PERM_MEM" + fi + DEFAULT_JAVA_OPTS="-server $DEFAULT_JAVA_OPTS -Dcom.sun.management.jmxremote" + elif [ "$JVM_VENDOR" = "IBM" ]; then + if $os400; then + DEFAULT_JAVA_OPTS="$DEFAULT_JAVA_OPTS" + elif $aix; then + DEFAULT_JAVA_OPTS="-Xverify:none -Xdump:heap -Xlp $DEFAULT_JAVA_OPTS" + else + DEFAULT_JAVA_OPTS="-Xverify:none $DEFAULT_JAVA_OPTS" + fi + fi + + # Add the jars in the lib dir + for file in "$KARAF_HOME"/lib/*.jar + do + if [ -z "$CLASSPATH" ]; then + CLASSPATH="$file" + else + CLASSPATH="$CLASSPATH:$file" + fi + done + DEFAULT_JAVA_DEBUG_OPTS="-Xdebug -Xnoagent -Djava.compiler=NONE -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=5005" + + ## + ## TODO: Move to conf/profiler/yourkit.{sh|cmd} + ## + # Uncomment to enable YourKit profiling + #DEFAULT_JAVA_DEBUG_OPTS="-Xrunyjpagent" +} + +init() { + # Determine if there is special OS handling we must perform + detectOS + + # Unlimit the number of file descriptors if possible + unlimitFD + + # Locate the Karaf home directory + locateHome + + # Locate the Karaf base directory + locateBase + + # Locate the Karaf data directory + locateData + + # Locate the Karaf etc directory + locateEtc + + # Setup the native library path + setupNativePath + + # Locate the Java VM to execute + locateJava + + # Determine the JVM vendor + detectJVM + + # Setup default options + setupDefaults + + # Install debug options + setupDebugOptions + +} + +run() { + + CLASSPATH="${KARAF_HOME}/system/org/apache/karaf/instance/org.apache.karaf.instance.command/3.0.1/org.apache.karaf.instance.command-3.0.1.jar:${KARAF_HOME}/system/org/apache/karaf/instance/org.apache.karaf.instance.core/3.0.1/org.apache.karaf.instance.core-3.0.1.jar:${KARAF_HOME}/system/org/apache/karaf/shell/org.apache.karaf.shell.console/3.0.1/org.apache.karaf.shell.console-3.0.1.jar:${KARAF_HOME}/system/org/apache/karaf/shell/org.apache.karaf.shell.table/3.0.1/org.apache.karaf.shell.table-3.0.1.jar:${KARAF_HOME}/system/org/apache/aries/blueprint/org.apache.aries.blueprint.api/1.0.0/org.apache.aries.blueprint.api-1.0.0.jar:${KARAF_HOME}/system/org/apache/aries/blueprint/org.apache.aries.blueprint.core/1.4.0/org.apache.aries.blueprint.core-1.4.0.jar:${KARAF_HOME}/system/org/apache/aries/blueprint/org.apache.aries.blueprint.cm/1.0.3/org.apache.aries.blueprint.cm-1.0.3.jar:${KARAF_HOME}/system/org/ops4j/pax/logging/pax-logging-api/1.7.2/pax-logging-api-1.7.2.jar:${KARAF_HOME}/system/org/apache/felix/org.apache.felix.framework/4.2.1/org.apache.felix.framework-4.2.1.jar:${KARAF_HOME}/system/jline/jline/2.11/jline-2.11.jar:$CLASSPATH" + + if $cygwin; then + KARAF_HOME=`cygpath --path --windows "$KARAF_HOME"` + KARAF_BASE=`cygpath --path --windows "$KARAF_BASE"` + KARAF_DATA=`cygpath --path --windows "$KARAF_DATA"` + KARAF_ETC=`cygpath --path --windows "$KARAF_ETC"` + CLASSPATH=`cygpath --path --windows "$CLASSPATH"` + fi + + exec "$JAVA" $JAVA_OPTS -Dkaraf.instances="${KARAF_HOME}/instances" -Dkaraf.home="$KARAF_HOME" -Dkaraf.base="$KARAF_BASE" -Dkaraf.etc="$KARAF_ETC" -Djava.io.tmpdir="$KARAF_DATA/tmp" -Djava.util.logging.config.file="$KARAF_BASE/etc/java.util.logging.properties" $KARAF_OPTS $OPTS -classpath "$CLASSPATH" org.apache.karaf.instance.main.Execute "$@" +} + +main() { + init + run "$@" +} + +main "$@" + diff --git a/opendaylight/distribution/opendaylight-karaf/src/main/resources/karaf/instance.bat b/opendaylight/distribution/opendaylight-karaf/src/main/resources/karaf/instance.bat new file mode 100644 index 0000000000..49c2c0fb4e --- /dev/null +++ b/opendaylight/distribution/opendaylight-karaf/src/main/resources/karaf/instance.bat @@ -0,0 +1,151 @@ +@echo off +rem +rem +rem Licensed to the Apache Software Foundation (ASF) under one or more +rem contributor license agreements. See the NOTICE file distributed with +rem this work for additional information regarding copyright ownership. +rem The ASF licenses this file to You under the Apache License, Version 2.0 +rem (the "License"); you may not use this file except in compliance with +rem the License. You may obtain a copy of the License at +rem +rem http://www.apache.org/licenses/LICENSE-2.0 +rem +rem Unless required by applicable law or agreed to in writing, software +rem distributed under the License is distributed on an "AS IS" BASIS, +rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +rem See the License for the specific language governing permissions and +rem limitations under the License. +rem + +if not "%ECHO%" == "" echo %ECHO% + +setlocal +set DIRNAME=%~dp0% +set PROGNAME=%~nx0% +set ARGS=%* + +rem Sourcing environment settings for karaf similar to tomcats setenv +SET KARAF_SCRIPT="instance.bat" +if exist "%DIRNAME%setenv.bat" ( + call "%DIRNAME%setenv.bat" +) + +rem Check console window title. Set to Karaf by default +if not "%KARAF_TITLE%" == "" ( + title %KARAF_TITLE% +) else ( + title Karaf +) + +rem Check/Set up some easily accessible MIN/MAX params for JVM mem usage +if "%JAVA_MIN_MEM%" == "" ( + set JAVA_MIN_MEM=128M +) +if "%JAVA_MAX_MEM%" == "" ( + set JAVA_MAX_MEM=512M +) + +goto BEGIN + +:warn + echo %PROGNAME%: %* +goto :EOF + +:BEGIN + +rem # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # + +if not "%KARAF_HOME%" == "" ( + call :warn Ignoring predefined value for KARAF_HOME +) +set KARAF_HOME=%DIRNAME%.. +if not exist "%KARAF_HOME%" ( + call :warn KARAF_HOME is not valid: "%KARAF_HOME%" + goto END +) + +if not "%KARAF_BASE%" == "" ( + if not exist "%KARAF_BASE%" ( + call :warn KARAF_BASE is not valid: "%KARAF_BASE%" + goto END + ) +) +if "%KARAF_BASE%" == "" ( + set "KARAF_BASE=%KARAF_HOME%" +) + +if not "%KARAF_DATA%" == "" ( + if not exist "%KARAF_DATA%" ( + call :warn KARAF_DATA is not valid: "%KARAF_DATA%" + goto END + ) +) +if "%KARAF_DATA%" == "" ( + set "KARAF_DATA=%KARAF_BASE%\data" +) + +if not "%KARAF_ETC%" == "" ( + if not exist "%KARAF_ETC%" ( + call :warn KARAF_ETC is not valid: "%KARAF_ETC%" + goto END + ) +) +if "%KARAF_ETC%" == "" ( + set "KARAF_ETC=%KARAF_BASE%\etc" +) + +set DEFAULT_JAVA_OPTS= +set DEFAULT_JAVA_DEBUG_OPTS=-Xdebug -Xnoagent -Djava.compiler=NONE -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=5005 + +rem Support for loading native libraries +set PATH=%PATH%;%KARAF_BASE%\lib;%KARAF_HOME%\lib + +rem Setup the Java Virtual Machine +if not "%JAVA%" == "" goto :Check_JAVA_END + set JAVA=java + if "%JAVA_HOME%" == "" call :warn JAVA_HOME not set; results may vary + if not "%JAVA_HOME%" == "" set JAVA=%JAVA_HOME%\bin\java + if not exist "%JAVA_HOME%" ( + call :warn JAVA_HOME is not valid: "%JAVA_HOME%" + goto END + ) +:Check_JAVA_END + +if "%JAVA_OPTS%" == "" set JAVA_OPTS=%DEFAULT_JAVA_OPTS% + +if "%KARAF_DEBUG%" == "" goto :KARAF_DEBUG_END + rem Use the defaults if JAVA_DEBUG_OPTS was not set + if "%JAVA_DEBUG_OPTS%" == "" set JAVA_DEBUG_OPTS=%DEFAULT_JAVA_DEBUG_OPTS% + + set "JAVA_OPTS=%JAVA_DEBUG_OPTS% %JAVA_OPTS%" + call :warn Enabling Java debug options: %JAVA_DEBUG_OPTS% +:KARAF_DEBUG_END + +rem Setup the classpath +pushd "%KARAF_HOME%\lib" +for %%G in (karaf*.jar) do call:APPEND_TO_CLASSPATH %%G +popd +goto CLASSPATH_END + +: APPEND_TO_CLASSPATH +set filename=%~1 +set suffix=%filename:~-4% +if %suffix% equ .jar set CLASSPATH=%CLASSPATH%;%KARAF_HOME%\lib\%filename% +goto :EOF + +:CLASSPATH_END + +set CLASSPATH=%KARAF_HOME%\system\org\apache\karaf\instance\org.apache.karaf.instance.command\3.0.1\org.apache.karaf.instance.command-3.0.1.jar;%KARAF_HOME%\system\org\apache\karaf\instance\org.apache.karaf.instance.core\3.0.1\org.apache.karaf.instance.core-3.0.1.jar;%KARAF_HOME%\system\org\apache\karaf\shell\org.apache.karaf.shell.console\3.0.1\org.apache.karaf.shell.console-3.0.1.jar;%KARAF_HOME%\system\org\apache\karaf\shell\org.apache.karaf.shell.table\3.0.1\org.apache.karaf.shell.table-3.0.1.jar;%KARAF_HOME%\system\org\apache\aries\blueprint\org.apache.aries.blueprint.api\1.0.0\org.apache.aries.blueprint.api-1.0.0.jar;%KARAF_HOME%\system\org\apache\aries\blueprint\org.apache.aries.blueprint.core\1.4.0\org.apache.aries.blueprint.core-1.4.0.jar;%KARAF_HOME%\system\org\apache\aries\blueprint\org.apache.aries.blueprint.cm\1.0.3\org.apache.aries.blueprint.cm-1.0.3.jar;%KARAF_HOME%\system\org\ops4j\pax\logging\pax-logging-api\1.7.2\pax-logging-api-1.7.2.jar;%KARAF_HOME%\system\org\apache\felix\org.apache.felix.framework\4.2.1\org.apache.felix.framework-4.2.1.jar;%KARAF_HOME%\system\jline\jline\2.11\jline-2.11.jar;%CLASSPATH% + +:EXECUTE + if "%SHIFT%" == "true" SET ARGS=%2 %3 %4 %5 %6 %7 %8 + if not "%SHIFT%" == "true" SET ARGS=%1 %2 %3 %4 %5 %6 %7 %8 + rem Execute the Java Virtual Machine + "%JAVA%" %JAVA_OPTS% %OPTS% -classpath "%CLASSPATH%" -Dkaraf.instances="%KARAF_HOME%\instances" -Dkaraf.home="%KARAF_HOME%" -Dkaraf.base="%KARAF_BASE%" -Dkaraf.etc="%KARAF_ETC%" -Djava.io.tmpdir="%KARAF_DATA%\tmp" -Djava.util.logging.config.file="%KARAF_BASE%\etc\java.util.logging.properties" %KARAF_OPTS% org.apache.karaf.instance.main.Execute %ARGS% + +rem # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # + +:END + +endlocal + diff --git a/opendaylight/distribution/opendaylight-karaf/src/main/resources/karaf/karaf b/opendaylight/distribution/opendaylight-karaf/src/main/resources/karaf/karaf new file mode 100755 index 0000000000..cad052a8ce --- /dev/null +++ b/opendaylight/distribution/opendaylight-karaf/src/main/resources/karaf/karaf @@ -0,0 +1,418 @@ +#!/bin/sh +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +DIRNAME=`dirname $0` +PROGNAME=`basename $0` + +# +# Sourcing environment settings for karaf similar to tomcats setenv +# +KARAF_SCRIPT="karaf" +export KARAF_SCRIPT +if [ -f "$DIRNAME/setenv" ]; then + . "$DIRNAME/setenv" +fi + +# +# Set up some easily accessible MIN/MAX params for JVM mem usage +# +if [ "x$JAVA_MIN_MEM" = "x" ]; then + JAVA_MIN_MEM=128M + export JAVA_MIN_MEM +fi +if [ "x$JAVA_MAX_MEM" = "x" ]; then + JAVA_MAX_MEM=512M + export JAVA_MAX_MEM +fi + +# +# Check the mode that initiated the script +# +if [ "x$1" != "x" ]; then + MODE=$1 +fi + +warn() { + echo "${PROGNAME}: $*" +} + +die() { + warn "$*" + exit 1 +} + +detectOS() { + # OS specific support (must be 'true' or 'false'). + cygwin=false; + darwin=false; + aix=false; + os400=false; + case "`uname`" in + CYGWIN*) + cygwin=true + ;; + Darwin*) + darwin=true + ;; + AIX*) + aix=true + ;; + OS400*) + os400=true + ;; + esac + # For AIX, set an environment variable + if $aix; then + export LDR_CNTRL=MAXDATA=0xB0000000@DSA + echo $LDR_CNTRL + fi +} + +unlimitFD() { + # Use the maximum available, or set MAX_FD != -1 to use that + if [ "x$MAX_FD" = "x" ]; then + MAX_FD="maximum" + fi + + # Increase the maximum file descriptors if we can + if [ "$os400" = "false" ] && [ "$cygwin" = "false" ]; then + MAX_FD_LIMIT=`ulimit -H -n` + if [ "$MAX_FD_LIMIT" != 'unlimited' ]; then + if [ $? -eq 0 ]; then + if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ]; then + # use the system max + MAX_FD="$MAX_FD_LIMIT" + fi + + ulimit -n $MAX_FD > /dev/null + # echo "ulimit -n" `ulimit -n` + if [ $? -ne 0 ]; then + warn "Could not set maximum file descriptor limit: $MAX_FD" + fi + else + warn "Could not query system maximum file descriptor limit: $MAX_FD_LIMIT" + fi + fi + fi +} + +locateHome() { + if [ "x$KARAF_HOME" != "x" ]; then + warn "Ignoring predefined value for KARAF_HOME" + fi + + # In POSIX shells, CDPATH may cause cd to write to stdout + (unset CDPATH) >/dev/null 2>&1 && unset CDPATH + + KARAF_HOME=`cd "$DIRNAME/.."; pwd` + if [ ! -d "$KARAF_HOME" ]; then + die "KARAF_HOME is not valid: $KARAF_HOME" + fi +} + +locateBase() { + if [ "x$KARAF_BASE" != "x" ]; then + if [ ! -d "$KARAF_BASE" ]; then + die "KARAF_BASE is not valid: $KARAF_BASE" + fi + else + KARAF_BASE=$KARAF_HOME + fi +} + +locateData() { + if [ "x$KARAF_DATA" != "x" ]; then + if [ ! -d "$KARAF_DATA" ]; then + die "KARAF_DATA is not valid: $KARAF_DATA" + fi + else + KARAF_DATA=$KARAF_BASE/data + fi +} + +locateEtc() { + if [ "x$KARAF_ETC" != "x" ]; then + if [ ! -d "$KARAF_ETC" ]; then + die "KARAF_ETC is not valid: $KARAF_ETC" + fi + else + KARAF_ETC=$KARAF_BASE/etc + fi +} + +setupNativePath() { + # Support for loading native libraries + LD_LIBRARY_PATH="${LD_LIBRARY_PATH}:$KARAF_BASE/lib:$KARAF_HOME/lib" + + # For Cygwin, set PATH from LD_LIBRARY_PATH + if $cygwin; then + LD_LIBRARY_PATH=`cygpath --path --windows "$LD_LIBRARY_PATH"` + PATH="$PATH;$LD_LIBRARY_PATH" + export PATH + fi + export LD_LIBRARY_PATH +} + +pathCanonical() { + local dst="${1}" + while [ -h "${dst}" ] ; do + ls=`ls -ld "${dst}"` + link=`expr "$ls" : '.*-> \(.*\)$'` + if expr "$link" : '/.*' > /dev/null; then + dst="$link" + else + dst="`dirname "${dst}"`/$link" + fi + done + local bas=`basename "${dst}"` + local dir=`dirname "${dst}"` + if [ "$bas" != "$dir" ]; then + dst="`pathCanonical "$dir"`/$bas" + fi + echo "${dst}" | sed -e 's#//#/#g' -e 's#/./#/#g' -e 's#/[^/]*/../#/#g' +} + +locateJava() { + # Setup the Java Virtual Machine + if $cygwin ; then + [ -n "$JAVA" ] && JAVA=`cygpath --unix "$JAVA"` + [ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"` + fi + + if [ "x$JAVA_HOME" = "x" ] && [ "$darwin" = "true" ]; then + JAVA_HOME="$(/usr/libexec/java_home)" + fi + if [ "x$JAVA" = "x" ] && [ -r /etc/gentoo-release ] ; then + JAVA_HOME=`java-config --jre-home` + fi + if [ "x$JAVA" = "x" ]; then + if [ "x$JAVA_HOME" != "x" ]; then + if [ ! -d "$JAVA_HOME" ]; then + die "JAVA_HOME is not valid: $JAVA_HOME" + fi + JAVA="$JAVA_HOME/bin/java" + else + warn "JAVA_HOME not set; results may vary" + JAVA=`type java` + JAVA=`expr "$JAVA" : '.*is \(.*\)$'` + if [ "x$JAVA" = "x" ]; then + die "java command not found" + fi + fi + fi + if [ "x$JAVA_HOME" = "x" ]; then + JAVA_HOME="$(dirname $(dirname $(pathCanonical "$JAVA")))" + fi +} + +detectJVM() { + #echo "`$JAVA -version`" + # This service should call `java -version`, + # read stdout, and look for hints + if $JAVA -version 2>&1 | grep "^IBM" ; then + JVM_VENDOR="IBM" + # on OS/400, java -version does not contain IBM explicitly + elif $os400; then + JVM_VENDOR="IBM" + else + JVM_VENDOR="SUN" + fi + # echo "JVM vendor is $JVM_VENDOR" +} + +checkJvmVersion() { + # echo "`$JAVA -version`" + VERSION=`$JAVA -version 2>&1 | egrep '"([0-9].[0-9]\..*[0-9])"' | awk '{print substr($3,2,length($3)-2)}' | awk '{print substr($1, 3, 3)}' | sed -e 's;\.;;g'` + # echo $VERSION + if [ "$VERSION" -lt "60" ]; then + echo "JVM must be greater than 1.6" + exit 1; + fi +} + +setupDebugOptions() { + if [ "x$JAVA_OPTS" = "x" ]; then + JAVA_OPTS="$DEFAULT_JAVA_OPTS" + fi + export JAVA_OPTS + + # Set Debug options if enabled + if [ "x$KARAF_DEBUG" != "x" ]; then + # Ignore DEBUG in case of stop or client mode + if [ "x$MODE" = "xstop" ]; then + return + fi + if [ "x$MODE" = "xclient" ]; then + return + fi + # Use the defaults if JAVA_DEBUG_OPTS was not set + if [ "x$JAVA_DEBUG_OPTS" = "x" ]; then + JAVA_DEBUG_OPTS="$DEFAULT_JAVA_DEBUG_OPTS" + fi + + JAVA_OPTS="$JAVA_DEBUG_OPTS $JAVA_OPTS" + warn "Enabling Java debug options: $JAVA_DEBUG_OPTS" + fi +} + +setupDefaults() { + DEFAULT_JAVA_OPTS="-Xms$JAVA_MIN_MEM -Xmx$JAVA_MAX_MEM -XX:+UnlockDiagnosticVMOptions -XX:+UnsyncloadClass " + + #Set the JVM_VENDOR specific JVM flags + if [ "$JVM_VENDOR" = "SUN" ]; then + # + # Check some easily accessible MIN/MAX params for JVM mem usage + # + if [ "x$JAVA_PERM_MEM" != "x" ]; then + DEFAULT_JAVA_OPTS="$DEFAULT_JAVA_OPTS -XX:PermSize=$JAVA_PERM_MEM" + fi + if [ "x$JAVA_MAX_PERM_MEM" != "x" ]; then + DEFAULT_JAVA_OPTS="$DEFAULT_JAVA_OPTS -XX:MaxPermSize=$JAVA_MAX_PERM_MEM" + fi + DEFAULT_JAVA_OPTS="-server $DEFAULT_JAVA_OPTS -Dcom.sun.management.jmxremote" + elif [ "$JVM_VENDOR" = "IBM" ]; then + if $os400; then + DEFAULT_JAVA_OPTS="$DEFAULT_JAVA_OPTS" + elif $aix; then + DEFAULT_JAVA_OPTS="-Xverify:none -Xdump:heap -Xlp $DEFAULT_JAVA_OPTS" + else + DEFAULT_JAVA_OPTS="-Xverify:none $DEFAULT_JAVA_OPTS" + fi + fi + + # Add the jars in the lib dir + for file in "$KARAF_HOME"/lib/karaf*.jar + do + if [ -z "$CLASSPATH" ]; then + CLASSPATH="$file" + else + CLASSPATH="$CLASSPATH:$file" + fi + done + DEFAULT_JAVA_DEBUG_OPTS="-Xdebug -Xnoagent -Djava.compiler=NONE -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=5005" + + ## + ## TODO: Move to conf/profiler/yourkit.{sh|cmd} + ## + # Uncomment to enable YourKit profiling + #DEFAULT_JAVA_DEBUG_OPTS="-Xrunyjpagent" +} + +init() { + # Determine if there is special OS handling we must perform + detectOS + + # Unlimit the number of file descriptors if possible + unlimitFD + + # Locate the Karaf home directory + locateHome + + # Locate the Karaf base directory + locateBase + + # Locate the Karaf data directory + locateData + + # Locate the Karaf etc directory + locateEtc + + # Setup the native library path + setupNativePath + + # Locate the Java VM to execute + locateJava + + # Determine the JVM vendor + detectJVM + + # Determine the JVM version >= 1.6 + checkJvmVersion + + # Setup default options + setupDefaults + + # Install debug options + setupDebugOptions + +} + +run() { + OPTS="-Dkaraf.startLocalConsole=true -Dkaraf.startRemoteShell=true" + MAIN=org.apache.karaf.main.Main + while [ "$1" != "" ]; do + case $1 in + 'clean') + rm -Rf "$KARAF_DATA" + shift + ;; + 'debug') + if [ "x$JAVA_DEBUG_OPTS" = "x" ]; then + JAVA_DEBUG_OPTS="$DEFAULT_JAVA_DEBUG_OPTS" + fi + JAVA_OPTS="$JAVA_DEBUG_OPTS $JAVA_OPTS" + shift + ;; + 'status') + MAIN=org.apache.karaf.main.Status + shift + ;; + 'stop') + MAIN=org.apache.karaf.main.Stop + shift + ;; + 'console') + shift + ;; + 'server') + OPTS="-Dkaraf.startLocalConsole=false -Dkaraf.startRemoteShell=true" + shift + ;; + 'client') + OPTS="-Dkaraf.startLocalConsole=true -Dkaraf.startRemoteShell=false" + shift + ;; + *) + break + ;; + esac + done + + JAVA_ENDORSED_DIRS="${JAVA_HOME}/jre/lib/endorsed:${JAVA_HOME}/lib/endorsed:${KARAF_HOME}/lib/endorsed" + JAVA_EXT_DIRS="${JAVA_HOME}/jre/lib/ext:${JAVA_HOME}/lib/ext:${KARAF_HOME}/lib/ext" + if $cygwin; then + KARAF_HOME=`cygpath --path --windows "$KARAF_HOME"` + KARAF_BASE=`cygpath --path --windows "$KARAF_BASE"` + KARAF_DATA=`cygpath --path --windows "$KARAF_DATA"` + KARAF_ETC=`cygpath --path --windows "$KARAF_ETC"` + CLASSPATH=`cygpath --path --windows "$CLASSPATH"` + JAVA_HOME=`cygpath --path --windows "$JAVA_HOME"` + JAVA_ENDORSED_DIRS=`cygpath --path --windows "$JAVA_ENDORSED_DIRS"` + JAVA_EXT_DIRS=`cygpath --path --windows "$JAVA_EXT_DIRS"` + fi + cd "$KARAF_BASE" + + exec "$JAVA" $JAVA_OPTS -Djava.endorsed.dirs="${JAVA_ENDORSED_DIRS}" -Djava.ext.dirs="${JAVA_EXT_DIRS}" -Dkaraf.instances="${KARAF_HOME}/instances" -Dkaraf.home="$KARAF_HOME" -Dkaraf.base="$KARAF_BASE" -Dkaraf.data="$KARAF_DATA" -Dkaraf.etc="$KARAF_ETC" -Djava.io.tmpdir="$KARAF_DATA/tmp" -Djava.util.logging.config.file="$KARAF_BASE/etc/java.util.logging.properties" $KARAF_OPTS $OPTS -classpath "$CLASSPATH" $MAIN "$@" +} + +main() { + init + run "$@" +} + +main "$@" diff --git a/opendaylight/distribution/opendaylight-karaf/src/main/resources/karaf/karaf.bat b/opendaylight/distribution/opendaylight-karaf/src/main/resources/karaf/karaf.bat new file mode 100644 index 0000000000..a45087730f --- /dev/null +++ b/opendaylight/distribution/opendaylight-karaf/src/main/resources/karaf/karaf.bat @@ -0,0 +1,336 @@ +@echo off +rem +rem +rem Licensed to the Apache Software Foundation (ASF) under one or more +rem contributor license agreements. See the NOTICE file distributed with +rem this work for additional information regarding copyright ownership. +rem The ASF licenses this file to You under the Apache License, Version 2.0 +rem (the "License"); you may not use this file except in compliance with +rem the License. You may obtain a copy of the License at +rem +rem http://www.apache.org/licenses/LICENSE-2.0 +rem +rem Unless required by applicable law or agreed to in writing, software +rem distributed under the License is distributed on an "AS IS" BASIS, +rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +rem See the License for the specific language governing permissions and +rem limitations under the License. +rem + +if not "%ECHO%" == "" echo %ECHO% + +setlocal +set DIRNAME=%~dp0% +set PROGNAME=%~nx0% +set ARGS=%* + +rem Sourcing environment settings for karaf similar to tomcats setenv +SET KARAF_SCRIPT="karaf.bat" +if exist "%DIRNAME%setenv.bat" ( + call "%DIRNAME%setenv.bat" +) + +rem Check console window title. Set to Karaf by default +if not "%KARAF_TITLE%" == "" ( + title %KARAF_TITLE% +) else ( + title Karaf +) + +rem Check/Set up some easily accessible MIN/MAX params for JVM mem usage +if "%JAVA_MIN_MEM%" == "" ( + set JAVA_MIN_MEM=128M +) +if "%JAVA_MAX_MEM%" == "" ( + set JAVA_MAX_MEM=512M +) + +goto BEGIN + +:warn + echo %PROGNAME%: %* +goto :EOF + +:BEGIN + +rem # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # + +if not "%KARAF_HOME%" == "" ( + call :warn Ignoring predefined value for KARAF_HOME +) +set KARAF_HOME=%DIRNAME%.. +if not exist "%KARAF_HOME%" ( + call :warn KARAF_HOME is not valid: "%KARAF_HOME%" + goto END +) + +if not "%KARAF_BASE%" == "" ( + if not exist "%KARAF_BASE%" ( + call :warn KARAF_BASE is not valid: "%KARAF_BASE%" + goto END + ) +) +if "%KARAF_BASE%" == "" ( + set "KARAF_BASE=%KARAF_HOME%" +) + +if not "%KARAF_DATA%" == "" ( + if not exist "%KARAF_DATA%" ( + call :warn KARAF_DATA is not valid: "%KARAF_DATA%" + goto END + ) +) +if "%KARAF_DATA%" == "" ( + set "KARAF_DATA=%KARAF_BASE%\data" +) + +if not "%KARAF_ETC%" == "" ( + if not exist "%KARAF_ETC%" ( + call :warn KARAF_ETC is not valid: "%KARAF_ETC%" + goto END + ) +) +if "%KARAF_ETC%" == "" ( + set "KARAF_ETC=%KARAF_BASE%\etc" +) + +set LOCAL_CLASSPATH=%CLASSPATH% +set JAVA_MODE=-server +if not exist "%JAVA_HOME%\bin\server\jvm.dll" ( + if not exist "%JAVA_HOME%\jre\bin\server\jvm.dll" ( + echo WARNING: Running karaf on a Java HotSpot Client VM because server-mode is not available. + echo Install Java Developer Kit to fix this. + echo For more details see http://java.sun.com/products/hotspot/whitepaper.html#client + set JAVA_MODE=-client + ) +) +set DEFAULT_JAVA_OPTS=%JAVA_MODE% -Xms%JAVA_MIN_MEM% -Xmx%JAVA_MAX_MEM% -Dderby.system.home="%KARAF_DATA%\derby" -Dderby.storage.fileSyncTransactionLog=true -Dcom.sun.management.jmxremote -XX:+UnlockDiagnosticVMOptions -XX:+UnsyncloadClass + +rem Check some easily accessible MIN/MAX params for JVM mem usage +if not "%JAVA_PERM_MEM%" == "" ( + set DEFAULT_JAVA_OPTS=%DEFAULT_JAVA_OPTS% -XX:PermSize=%JAVA_PERM_MEM% +) +if not "%JAVA_MAX_PERM_MEM%" == "" ( + set DEFAULT_JAVA_OPTS=%DEFAULT_JAVA_OPTS% -XX:MaxPermSize=%JAVA_MAX_PERM_MEM% +) + +set CLASSPATH=%LOCAL_CLASSPATH%;%KARAF_BASE%\conf +set DEFAULT_JAVA_DEBUG_OPTS=-Xdebug -Xnoagent -Djava.compiler=NONE -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=5005 + +if "%LOCAL_CLASSPATH%" == "" goto :KARAF_CLASSPATH_EMPTY + set CLASSPATH=%LOCAL_CLASSPATH%;%KARAF_BASE%\conf + goto :KARAF_CLASSPATH_END +:KARAF_CLASSPATH_EMPTY + set CLASSPATH=%KARAF_BASE%\conf +:KARAF_CLASSPATH_END + +rem Setup Karaf Home +if exist "%KARAF_HOME%\conf\karaf-rc.cmd" call %KARAF_HOME%\conf\karaf-rc.cmd +if exist "%HOME%\karaf-rc.cmd" call %HOME%\karaf-rc.cmd + +rem Support for loading native libraries +set PATH=%PATH%;%KARAF_BASE%\lib;%KARAF_HOME%\lib + +rem Setup the Java Virtual Machine +if not "%JAVA%" == "" goto :Check_JAVA_END + if not "%JAVA_HOME%" == "" goto :TryJDKEnd + call :warn JAVA_HOME not set; results may vary +:TryJRE + start /w regedit /e __reg1.txt "HKEY_LOCAL_MACHINE\SOFTWARE\JavaSoft\Java Runtime Environment" + if not exist __reg1.txt goto :TryJDK + type __reg1.txt | find "CurrentVersion" > __reg2.txt + if errorlevel 1 goto :TryJDK + for /f "tokens=2 delims==" %%x in (__reg2.txt) do set JavaTemp=%%~x + if errorlevel 1 goto :TryJDK + set JavaTemp=%JavaTemp%## + set JavaTemp=%JavaTemp: ##=##% + set JavaTemp=%JavaTemp: ##=##% + set JavaTemp=%JavaTemp: ##=##% + set JavaTemp=%JavaTemp: ##=##% + set JavaTemp=%JavaTemp: ##=##% + set JavaTemp=%JavaTemp:##=% + del __reg1.txt + del __reg2.txt + start /w regedit /e __reg1.txt "HKEY_LOCAL_MACHINE\SOFTWARE\JavaSoft\Java Runtime Environment\%JavaTemp%" + if not exist __reg1.txt goto :TryJDK + type __reg1.txt | find "JavaHome" > __reg2.txt + if errorlevel 1 goto :TryJDK + for /f "tokens=2 delims==" %%x in (__reg2.txt) do set JAVA_HOME=%%~x + if errorlevel 1 goto :TryJDK + del __reg1.txt + del __reg2.txt + goto TryJDKEnd +:TryJDK + start /w regedit /e __reg1.txt "HKEY_LOCAL_MACHINE\SOFTWARE\JavaSoft\Java Development Kit" + if not exist __reg1.txt ( + goto TryRegJRE + ) + type __reg1.txt | find "CurrentVersion" > __reg2.txt + if errorlevel 1 ( + goto TryRegJRE + ) + for /f "tokens=2 delims==" %%x in (__reg2.txt) do set JavaTemp=%%~x + if errorlevel 1 ( + goto TryRegJRE + ) + set JavaTemp=%JavaTemp%## + set JavaTemp=%JavaTemp: ##=##% + set JavaTemp=%JavaTemp: ##=##% + set JavaTemp=%JavaTemp: ##=##% + set JavaTemp=%JavaTemp: ##=##% + set JavaTemp=%JavaTemp: ##=##% + set JavaTemp=%JavaTemp:##=% + del __reg1.txt + del __reg2.txt + start /w regedit /e __reg1.txt "HKEY_LOCAL_MACHINE\SOFTWARE\JavaSoft\Java Development Kit\%JavaTemp%" + if not exist __reg1.txt ( + goto TryRegJRE + ) + type __reg1.txt | find "JavaHome" > __reg2.txt + if errorlevel 1 ( + goto TryRegJRE + ) + for /f "tokens=2 delims==" %%x in (__reg2.txt) do set JAVA_HOME=%%~x + if errorlevel 1 ( + goto TryRegJRE + ) + del __reg1.txt + del __reg2.txt +:TryRegJRE + rem try getting the JAVA_HOME from registry + FOR /F "usebackq tokens=3*" %%A IN (`REG QUERY "HKLM\Software\JavaSoft\Java Runtime Environment" /v CurrentVersion`) DO ( + set JAVA_VERSION=%%A + ) + FOR /F "usebackq tokens=3*" %%A IN (`REG QUERY "HKLM\Software\JavaSoft\Java Runtime Environment\%JAVA_VERSION%" /v JavaHome`) DO ( + set JAVA_HOME=%%A %%B + ) + if not exist "%JAVA_HOME%" ( + goto TryRegJDK + ) + goto TryJDKEnd +:TryRegJDK + rem try getting the JAVA_HOME from registry + FOR /F "usebackq tokens=3*" %%A IN (`REG QUERY "HKLM\Software\JavaSoft\Java Development Kit" /v CurrentVersion`) DO ( + set JAVA_VERSION=%%A + ) + FOR /F "usebackq tokens=3*" %%A IN (`REG QUERY "HKLM\Software\JavaSoft\Java Development Kit\%JAVA_VERSION%" /v JavaHome`) DO ( + set JAVA_HOME=%%A %%B + ) + if not exist "%JAVA_HOME%" ( + call :warn Unable to retrieve JAVA_HOME from Registry + ) + goto TryJDKEnd +:TryJDKEnd + if not exist "%JAVA_HOME%" ( + call :warn JAVA_HOME is not valid: "%JAVA_HOME%" + goto END + ) + set JAVA=%JAVA_HOME%\bin\java +:Check_JAVA_END + +if "%JAVA_OPTS%" == "" set JAVA_OPTS=%DEFAULT_JAVA_OPTS% + +if "%KARAF_DEBUG%" == "" goto :KARAF_DEBUG_END + if "%1" == "stop" goto :KARAF_DEBUG_END + if "%1" == "client" goto :KARAF_DEBUG_END + rem Use the defaults if JAVA_DEBUG_OPTS was not set + if "%JAVA_DEBUG_OPTS%" == "" set JAVA_DEBUG_OPTS=%DEFAULT_JAVA_DEBUG_OPTS% + + set "JAVA_OPTS=%JAVA_DEBUG_OPTS% %JAVA_OPTS%" + call :warn Enabling Java debug options: %JAVA_DEBUG_OPTS% +:KARAF_DEBUG_END + +if "%KARAF_PROFILER%" == "" goto :KARAF_PROFILER_END + set KARAF_PROFILER_SCRIPT=%KARAF_HOME%\conf\profiler\%KARAF_PROFILER%.cmd + + if exist "%KARAF_PROFILER_SCRIPT%" goto :KARAF_PROFILER_END + call :warn Missing configuration for profiler '%KARAF_PROFILER%': %KARAF_PROFILER_SCRIPT% + goto END +:KARAF_PROFILER_END + +rem Setup the classpath +pushd "%KARAF_HOME%\lib" +for %%G in (karaf*.jar) do call:APPEND_TO_CLASSPATH %%G +popd +goto CLASSPATH_END + +: APPEND_TO_CLASSPATH +set filename=%~1 +set suffix=%filename:~-4% +if %suffix% equ .jar set CLASSPATH=%CLASSPATH%;%KARAF_HOME%\lib\%filename% +goto :EOF + +:CLASSPATH_END + +rem Execute the JVM or the load the profiler +if "%KARAF_PROFILER%" == "" goto :RUN + rem Execute the profiler if it has been configured + call :warn Loading profiler script: %KARAF_PROFILER_SCRIPT% + call %KARAF_PROFILER_SCRIPT% + +:RUN + SET OPTS=-Dkaraf.startLocalConsole=true -Dkaraf.startRemoteShell=true + SET MAIN=org.apache.karaf.main.Main + SET SHIFT=false + +:RUN_LOOP + if "%1" == "stop" goto :EXECUTE_STOP + if "%1" == "status" goto :EXECUTE_STATUS + if "%1" == "console" goto :EXECUTE_CONSOLE + if "%1" == "server" goto :EXECUTE_SERVER + if "%1" == "client" goto :EXECUTE_CLIENT + if "%1" == "clean" goto :EXECUTE_CLEAN + if "%1" == "debug" goto :EXECUTE_DEBUG + goto :EXECUTE + +:EXECUTE_STOP + SET MAIN=org.apache.karaf.main.Stop + shift + goto :RUN_LOOP + +:EXECUTE_STATUS + SET MAIN=org.apache.karaf.main.Status + shift + goto :RUN_LOOP + +:EXECUTE_CONSOLE + shift + goto :RUN_LOOP + +:EXECUTE_SERVER + SET OPTS=-Dkaraf.startLocalConsole=false -Dkaraf.startRemoteShell=true + shift + goto :RUN_LOOP + +:EXECUTE_CLIENT + SET OPTS=-Dkaraf.startLocalConsole=true -Dkaraf.startRemoteShell=false + shift + goto :RUN_LOOP + +:EXECUTE_CLEAN + rmdir /S /Q "%KARAF_DATA%" + shift + goto :RUN_LOOP + +:EXECUTE_DEBUG + if "%JAVA_DEBUG_OPTS%" == "" set JAVA_DEBUG_OPTS=%DEFAULT_JAVA_DEBUG_OPTS% + set "JAVA_OPTS=%JAVA_DEBUG_OPTS% %JAVA_OPTS%" + shift + goto :RUN_LOOP + +:EXECUTE + SET ARGS=%1 %2 %3 %4 %5 %6 %7 %8 + rem Execute the Java Virtual Machine + cd "%KARAF_BASE%" + "%JAVA%" %JAVA_OPTS% %OPTS% -classpath "%CLASSPATH%" -Djava.endorsed.dirs="%JAVA_HOME%\jre\lib\endorsed;%JAVA_HOME%\lib\endorsed;%KARAF_HOME%\lib\endorsed" -Djava.ext.dirs="%JAVA_HOME%\jre\lib\ext;%JAVA_HOME%\lib\ext;%KARAF_HOME%\lib\ext" -Dkaraf.instances="%KARAF_HOME%\instances" -Dkaraf.home="%KARAF_HOME%" -Dkaraf.base="%KARAF_BASE%" -Dkaraf.etc="%KARAF_ETC%" -Djava.io.tmpdir="%KARAF_DATA%\tmp" -Dkaraf.data="%KARAF_DATA%" -Djava.util.logging.config.file="%KARAF_BASE%\etc\java.util.logging.properties" %KARAF_OPTS% %MAIN% %ARGS% + +rem # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # + +:END + +endlocal + +if not "%PAUSE%" == "" pause + +:END_NO_PAUSE + diff --git a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/codegen/RpcIsNotRoutedException.java b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/codegen/RpcIsNotRoutedException.java new file mode 100644 index 0000000000..5317324ee5 --- /dev/null +++ b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/codegen/RpcIsNotRoutedException.java @@ -0,0 +1,29 @@ +/* + * 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.sal.binding.codegen; + +import com.google.common.base.Preconditions; + +/** + * Exception is raised when supplied Bidning Aware + * RPCService class is not routed and was used in context + * where routed RPCs should only be used. + * + */ +public class RpcIsNotRoutedException extends IllegalStateException { + + private static final long serialVersionUID = 1L; + + public RpcIsNotRoutedException(final String message, final Throwable cause) { + super(Preconditions.checkNotNull(message), cause); + } + + public RpcIsNotRoutedException(final String message) { + super(Preconditions.checkNotNull(message)); + } +} diff --git a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/codegen/RuntimeCodeGenerator.java b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/codegen/RuntimeCodeGenerator.java index 9b7b8e28c9..c7c5f10f71 100644 --- a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/codegen/RuntimeCodeGenerator.java +++ b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/codegen/RuntimeCodeGenerator.java @@ -84,8 +84,9 @@ public interface RuntimeCodeGenerator { * - Subclass of RpcService for which Router is to be generated. * @return Instance of RpcService of provided serviceType which implements * also {@link RpcRouter} and {@link org.opendaylight.controller.sal.binding.spi.DelegateProxy} + * @throws RpcIsNotRoutedException */ - RpcRouter getRouterFor(Class serviceType,String name) throws IllegalArgumentException; + RpcRouter getRouterFor(Class serviceType,String name) throws IllegalArgumentException, RpcIsNotRoutedException; NotificationInvokerFactory getInvokerFactory(); } diff --git a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/codegen/impl/AbstractRuntimeCodeGenerator.java b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/codegen/impl/AbstractRuntimeCodeGenerator.java index 9605a4d372..8fa88ead07 100644 --- a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/codegen/impl/AbstractRuntimeCodeGenerator.java +++ b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/codegen/impl/AbstractRuntimeCodeGenerator.java @@ -19,8 +19,10 @@ import javax.annotation.concurrent.GuardedBy; import org.eclipse.xtext.xbase.lib.Extension; import org.opendaylight.controller.sal.binding.api.rpc.RpcRouter; +import org.opendaylight.controller.sal.binding.codegen.RpcIsNotRoutedException; import org.opendaylight.controller.sal.binding.spi.NotificationInvokerFactory; import org.opendaylight.yangtools.sal.binding.generator.util.JavassistUtils; +import org.opendaylight.yangtools.yang.binding.BindingMapping; import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; import org.opendaylight.yangtools.yang.binding.NotificationListener; import org.opendaylight.yangtools.yang.binding.RpcService; @@ -56,11 +58,11 @@ abstract class AbstractRuntimeCodeGenerator implements org.opendaylight.controll protected abstract Supplier directProxySupplier(final Class serviceType); protected abstract Supplier routerSupplier(final Class serviceType, RpcServiceMetadata metadata); - private RpcServiceMetadata getRpcMetadata(final CtClass iface) throws ClassNotFoundException, NotFoundException { + private RpcServiceMetadata getRpcMetadata(final CtClass iface) throws ClassNotFoundException, NotFoundException, RpcIsNotRoutedException { final RpcServiceMetadata metadata = new RpcServiceMetadata(); for (CtMethod method : iface.getMethods()) { - if (iface.equals(method.getDeclaringClass()) && method.getParameterTypes().length == 1) { + if (isRpcMethodWithInput(iface, method)) { final RpcMetadata routingPair = getRpcMetadata(method); if (routingPair != null) { metadata.addContext(routingPair.getContext()); @@ -81,6 +83,8 @@ abstract class AbstractRuntimeCodeGenerator implements org.opendaylight.controll * remains to be investigated. */ Thread.currentThread().getContextClassLoader().loadClass(routingPair.getInputType().getName()); + } else { + throw new RpcIsNotRoutedException("RPC " + method.getName() + " from "+ iface.getName() +" is not routed"); } } } @@ -88,6 +92,18 @@ abstract class AbstractRuntimeCodeGenerator implements org.opendaylight.controll return metadata; } + + private boolean isRpcMethodWithInput(final CtClass iface, final CtMethod method) throws NotFoundException { + if(iface.equals(method.getDeclaringClass()) + && method.getParameterTypes().length == 1) { + final CtClass onlyArg = method.getParameterTypes()[0]; + if(onlyArg.isInterface() && onlyArg.getName().endsWith(BindingMapping.RPC_INPUT_SUFFIX)) { + return true; + } + } + return false; + } + private RpcMetadata getRpcMetadata(final CtMethod method) throws NotFoundException { final CtClass inputClass = method.getParameterTypes()[0]; return rpcMethodMetadata(inputClass, inputClass, method.getName()); @@ -152,7 +168,7 @@ abstract class AbstractRuntimeCodeGenerator implements org.opendaylight.controll } @Override - public final RpcRouter getRouterFor(final Class serviceType, final String name) { + public final RpcRouter getRouterFor(final Class serviceType, final String name) throws RpcIsNotRoutedException { final RpcServiceMetadata metadata = ClassLoaderUtils.withClassLoader(serviceType.getClassLoader(), new Supplier() { @Override public RpcServiceMetadata get() { diff --git a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/RpcProviderRegistryImpl.java b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/RpcProviderRegistryImpl.java index c61ec4926a..f2e467038f 100644 --- a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/RpcProviderRegistryImpl.java +++ b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/RpcProviderRegistryImpl.java @@ -9,16 +9,14 @@ package org.opendaylight.controller.sal.binding.impl; import static com.google.common.base.Preconditions.checkState; -import com.google.common.cache.CacheBuilder; -import com.google.common.cache.CacheLoader; -import com.google.common.cache.LoadingCache; - import java.util.EventListener; import java.util.HashMap; import java.util.Map; import java.util.Map.Entry; import java.util.Set; -import java.util.WeakHashMap; +import java.util.concurrent.Callable; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.atomic.AtomicBoolean; import org.opendaylight.controller.md.sal.common.api.routing.RouteChange; import org.opendaylight.controller.md.sal.common.api.routing.RouteChangeListener; @@ -29,6 +27,7 @@ import org.opendaylight.controller.sal.binding.api.BindingAwareBroker.RpcRegistr import org.opendaylight.controller.sal.binding.api.RpcProviderRegistry; import org.opendaylight.controller.sal.binding.api.rpc.RpcContextIdentifier; import org.opendaylight.controller.sal.binding.api.rpc.RpcRouter; +import org.opendaylight.controller.sal.binding.codegen.RpcIsNotRoutedException; import org.opendaylight.controller.sal.binding.codegen.RuntimeCodeGenerator; import org.opendaylight.controller.sal.binding.codegen.RuntimeCodeHelper; import org.opendaylight.controller.sal.binding.codegen.impl.SingletonHolder; @@ -41,6 +40,13 @@ import org.opendaylight.yangtools.yang.binding.RpcService; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import com.google.common.base.Throwables; +import com.google.common.cache.Cache; +import com.google.common.cache.CacheBuilder; +import com.google.common.cache.CacheLoader; +import com.google.common.cache.LoadingCache; +import com.google.common.util.concurrent.UncheckedExecutionException; + public class RpcProviderRegistryImpl implements RpcProviderRegistry, RouteChangePublisher> { private RuntimeCodeGenerator rpcFactory = SingletonHolder.RPC_GENERATOR_IMPL; @@ -56,7 +62,9 @@ public class RpcProviderRegistryImpl implements RpcProviderRegistry, RouteChange } }); - private final Map, RpcRouter> rpcRouters = new WeakHashMap<>(); + private final Cache, RpcRouter> rpcRouters = CacheBuilder.newBuilder().weakKeys() + .build(); + private final ListenerRegistry>> routeChangeListeners = ListenerRegistry .create(); private final ListenerRegistry routerInstantiationListener = ListenerRegistry.create(); @@ -85,12 +93,20 @@ public class RpcProviderRegistryImpl implements RpcProviderRegistry, RouteChange @Override public final RpcRegistration addRpcImplementation(final Class type, final T implementation) throws IllegalStateException { - @SuppressWarnings("unchecked") - RpcRouter potentialRouter = (RpcRouter) rpcRouters.get(type); - if (potentialRouter != null) { + + // FIXME: This should be well documented - addRpcImplementation for + // routed RPCs + try { + // Note: If RPC is really global, expected count of registrations + // of this method is really low. + RpcRouter potentialRouter = getRpcRouter(type); checkState(potentialRouter.getDefaultService() == null, - "Default service for routed RPC already registered."); + "Default service for routed RPC already registered."); return potentialRouter.registerDefaultService(implementation); + } catch (RpcIsNotRoutedException e) { + // NOOP - we could safely continue, since RPC is not routed + // so we fallback to global routing. + LOG.debug("RPC is not routed. Using global registration.",e); } T publicProxy = getRpcService(type); RpcService currentDelegate = RuntimeCodeHelper.getDelegate(publicProxy); @@ -107,28 +123,37 @@ public class RpcProviderRegistryImpl implements RpcProviderRegistry, RouteChange return (T) publicProxies.getUnchecked(type); } - @SuppressWarnings({ "unchecked", "rawtypes" }) + public RpcRouter getRpcRouter(final Class type) { - RpcRouter potentialRouter = rpcRouters.get(type); - if (potentialRouter != null) { - return (RpcRouter) potentialRouter; - } - synchronized (this) { - /** - * Potential Router could be instantiated by other thread while we - * were waiting for the lock. - */ - potentialRouter = rpcRouters.get(type); - if (potentialRouter != null) { - return (RpcRouter) potentialRouter; + try { + final AtomicBoolean created = new AtomicBoolean(false); + @SuppressWarnings( "unchecked") + // LoadingCache is unsuitable for RpcRouter since we need to distinguish + // first creation of RPC Router, so that is why + // we are using normal cache with load API and shared AtomicBoolean + // for this call, which will be set to true if router was created. + RpcRouter router = (RpcRouter) rpcRouters.get(type,new Callable>() { + + @Override + public org.opendaylight.controller.sal.binding.api.rpc.RpcRouter call() { + RpcRouter router = rpcFactory.getRouterFor(type, name); + router.registerRouteChangeListener(new RouteChangeForwarder(type)); + LOG.debug("Registering router {} as global implementation of {} in {}", router, type.getSimpleName(), this); + RuntimeCodeHelper.setDelegate(getRpcService(type), router.getInvocationProxy()); + created.set(true); + return router; + } + }); + if(created.get()) { + notifyListenersRoutedCreated(router); } - RpcRouter router = rpcFactory.getRouterFor(type, name); - router.registerRouteChangeListener(new RouteChangeForwarder(type)); - LOG.debug("Registering router {} as global implementation of {} in {}", router, type.getSimpleName(), this); - RuntimeCodeHelper.setDelegate(getRpcService(type), router.getInvocationProxy()); - rpcRouters.put(type, router); - notifyListenersRoutedCreated(router); return router; + } catch (ExecutionException | UncheckedExecutionException e) { + // We rethrow Runtime Exceptions which were wrapped by + // Execution Exceptions + // otherwise we throw IllegalStateException with original + Throwables.propagateIfPossible(e.getCause()); + throw new IllegalStateException("Could not load RPC Router for "+type.getName(),e); } } @@ -159,7 +184,7 @@ public class RpcProviderRegistryImpl implements RpcProviderRegistry, RouteChange final RouterInstantiationListener listener) { ListenerRegistration reg = routerInstantiationListener.register(listener); try { - for (RpcRouter router : rpcRouters.values()) { + for (RpcRouter router : rpcRouters.asMap().values()) { listener.onRpcRouterCreated(router); } } catch (Exception e) { @@ -225,7 +250,7 @@ public class RpcProviderRegistryImpl implements RpcProviderRegistry, RouteChange try { listener.getInstance().onRouteChange(toPublish); } catch (Exception e) { - e.printStackTrace(); + LOG.error("Unhandled exception during invoking listener",listener.getInstance(),e); } } } diff --git a/opendaylight/md-sal/sal-binding-broker/src/test/java/org/opendaylight/controller/md/sal/binding/impl/test/RpcProviderRegistryTest.java b/opendaylight/md-sal/sal-binding-broker/src/test/java/org/opendaylight/controller/md/sal/binding/impl/test/RpcProviderRegistryTest.java index 110e5b4dce..8782046eee 100644 --- a/opendaylight/md-sal/sal-binding-broker/src/test/java/org/opendaylight/controller/md/sal/binding/impl/test/RpcProviderRegistryTest.java +++ b/opendaylight/md-sal/sal-binding-broker/src/test/java/org/opendaylight/controller/md/sal/binding/impl/test/RpcProviderRegistryTest.java @@ -23,6 +23,7 @@ import org.opendaylight.controller.sal.binding.api.BindingAwareBroker.RoutedRpcR import org.opendaylight.controller.sal.binding.api.BindingAwareBroker.RpcRegistration; import org.opendaylight.controller.sal.binding.api.rpc.RpcContextIdentifier; import org.opendaylight.controller.sal.binding.api.rpc.RpcRouter; +import org.opendaylight.controller.sal.binding.codegen.RpcIsNotRoutedException; import org.opendaylight.controller.sal.binding.impl.RpcProviderRegistryImpl; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.md.sal.test.bi.ba.rpcservice.rev140701.OpendaylightTestRpcServiceService; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.md.sal.test.list.rev140701.two.level.list.TopLevelList; @@ -77,6 +78,28 @@ public class RpcProviderRegistryTest { assertNotNull(regTwo); } + @Test + public void routedRpcRegisteredUsingGlobalAsDefaultInstance() throws Exception { + OpendaylightTestRoutedRpcService def = Mockito.mock(OpendaylightTestRoutedRpcService.class); + rpcRegistry.addRpcImplementation(OpendaylightTestRoutedRpcService.class, def); + RpcRouter router = rpcRegistry.getRpcRouter(OpendaylightTestRoutedRpcService.class); + assertEquals(def, router.getDefaultService()); + } + + @Test + public void nonRoutedRegisteredAsRouted() { + OpendaylightTestRpcServiceService one = Mockito.mock(OpendaylightTestRpcServiceService.class); + try { + rpcRegistry.addRoutedRpcImplementation(OpendaylightTestRpcServiceService.class, one); + fail("RpcIsNotRoutedException should be thrown"); + } catch (RpcIsNotRoutedException e) { + assertNotNull(e.getMessage()); + } catch (Exception e) { + fail("RpcIsNotRoutedException should be thrown"); + } + + } + @Test public void testRpcRouterInstance() throws Exception { OpendaylightTestRoutedRpcService def = Mockito.mock(OpendaylightTestRoutedRpcService.class); diff --git a/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/restconf/rpc/impl/AbstractRpcExecutor.java b/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/restconf/rpc/impl/AbstractRpcExecutor.java index 4c5e3ab530..148b33bd65 100644 --- a/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/restconf/rpc/impl/AbstractRpcExecutor.java +++ b/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/restconf/rpc/impl/AbstractRpcExecutor.java @@ -37,6 +37,8 @@ public abstract class AbstractRpcExecutor implements RpcExecutor { throw new RestconfDocumentedException(e.getMessage(), ErrorType.PROTOCOL, ErrorTag.INVALID_VALUE); } catch (UnsupportedOperationException e) { throw new RestconfDocumentedException(e.getMessage(), ErrorType.RPC, ErrorTag.OPERATION_NOT_SUPPORTED); + } catch (RestconfDocumentedException e) { + throw e; } catch (Exception e) { throw new RestconfDocumentedException("The operation encountered an unexpected error while executing.", e); }