Return-Path: X-Original-To: apmail-camel-commits-archive@www.apache.org Delivered-To: apmail-camel-commits-archive@www.apache.org Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by minotaur.apache.org (Postfix) with SMTP id ED0C711D53 for ; Thu, 26 Jun 2014 18:08:42 +0000 (UTC) Received: (qmail 60196 invoked by uid 500); 26 Jun 2014 18:08:42 -0000 Delivered-To: apmail-camel-commits-archive@camel.apache.org Received: (qmail 60029 invoked by uid 500); 26 Jun 2014 18:08:42 -0000 Mailing-List: contact commits-help@camel.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@camel.apache.org Delivered-To: mailing list commits@camel.apache.org Received: (qmail 59930 invoked by uid 99); 26 Jun 2014 18:08:42 -0000 Received: from tyr.zones.apache.org (HELO tyr.zones.apache.org) (140.211.11.114) by apache.org (qpsmtpd/0.29) with ESMTP; Thu, 26 Jun 2014 18:08:42 +0000 Received: by tyr.zones.apache.org (Postfix, from userid 65534) id 876D28A0B3C; Thu, 26 Jun 2014 18:08:42 +0000 (UTC) Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit From: davsclaus@apache.org To: commits@camel.apache.org Date: Thu, 26 Jun 2014 18:08:44 -0000 Message-Id: <223553617ac74308a53806955ce6d2d5@git.apache.org> In-Reply-To: <77d6ee3e0d304b718c52827c4fef624e@git.apache.org> References: <77d6ee3e0d304b718c52827c4fef624e@git.apache.org> X-Mailer: ASF-Git Admin Mailer Subject: [3/4] git commit: CAMEL-7546: Avoid clash of CamelContext managementName in OSGi. Also reuse clash logic in finding free default context name and context management name. CAMEL-7546: Avoid clash of CamelContext managementName in OSGi. Also reuse clash logic in finding free default context name and context management name. Project: http://git-wip-us.apache.org/repos/asf/camel/repo Commit: http://git-wip-us.apache.org/repos/asf/camel/commit/67548e2e Tree: http://git-wip-us.apache.org/repos/asf/camel/tree/67548e2e Diff: http://git-wip-us.apache.org/repos/asf/camel/diff/67548e2e Branch: refs/heads/camel-2.13.x Commit: 67548e2ed2c68cd2a5601ba0c89f2758942e78b3 Parents: 0164fbc Author: Claus Ibsen Authored: Thu Jun 26 18:44:51 2014 +0200 Committer: Claus Ibsen Committed: Thu Jun 26 20:08:16 2014 +0200 ---------------------------------------------------------------------- .../core/osgi/OsgiCamelContextNameStrategy.java | 42 +-------- .../core/osgi/OsgiCamelContextPublisher.java | 28 ++++-- .../core/osgi/OsgiManagementNameStrategy.java | 7 ++ .../camel/core/osgi/OsgiNamingHelper.java | 91 ++++++++++++++++++++ 4 files changed, 123 insertions(+), 45 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/camel/blob/67548e2e/components/camel-core-osgi/src/main/java/org/apache/camel/core/osgi/OsgiCamelContextNameStrategy.java ---------------------------------------------------------------------- diff --git a/components/camel-core-osgi/src/main/java/org/apache/camel/core/osgi/OsgiCamelContextNameStrategy.java b/components/camel-core-osgi/src/main/java/org/apache/camel/core/osgi/OsgiCamelContextNameStrategy.java index a68c242..9e66e29 100644 --- a/components/camel-core-osgi/src/main/java/org/apache/camel/core/osgi/OsgiCamelContextNameStrategy.java +++ b/components/camel-core-osgi/src/main/java/org/apache/camel/core/osgi/OsgiCamelContextNameStrategy.java @@ -18,13 +18,8 @@ package org.apache.camel.core.osgi; import java.util.concurrent.atomic.AtomicInteger; -import org.apache.camel.CamelContext; import org.apache.camel.spi.CamelContextNameStrategy; import org.osgi.framework.BundleContext; -import org.osgi.framework.InvalidSyntaxException; -import org.osgi.framework.ServiceReference; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; import static org.apache.camel.core.osgi.OsgiCamelContextPublisher.CONTEXT_NAME_PROPERTY; @@ -37,7 +32,6 @@ import static org.apache.camel.core.osgi.OsgiCamelContextPublisher.CONTEXT_NAME_ */ public class OsgiCamelContextNameStrategy implements CamelContextNameStrategy { - private static final Logger LOG = LoggerFactory.getLogger(OsgiCamelContextNameStrategy.class); private static final AtomicInteger CONTEXT_COUNTER = new AtomicInteger(0); private final BundleContext context; private final String prefix = "camel"; @@ -57,35 +51,8 @@ public class OsgiCamelContextNameStrategy implements CamelContextNameStrategy { @Override public synchronized String getNextName() { - String candidate = null; - boolean clash = false; - - do { - try { - clash = false; - - // generate new candidate - candidate = prefix + "-" + getNextCounter(); - LOG.trace("Checking OSGi Service Registry for existence of existing CamelContext with name: {}", candidate); - - ServiceReference[] refs = context.getServiceReferences(CamelContext.class.getName(), "(" + CONTEXT_NAME_PROPERTY + "=" + candidate + ")"); - if (refs != null && refs.length > 0) { - for (ServiceReference ref : refs) { - Object id = ref.getProperty(CONTEXT_NAME_PROPERTY); - if (id != null && candidate.equals(id)) { - clash = true; - break; - } - } - } - } catch (InvalidSyntaxException e) { - LOG.debug("Error finding free Camel name in OSGi Service Registry due " + e.getMessage() + ". This exception is ignored.", e); - break; - } - } while (clash); - - LOG.debug("Generated CamelContext name for bundle id: {}, clash: {} -> {}", new Object[]{context.getBundle().getBundleId(), clash, candidate}); - return candidate; + // false = do no check fist, but add the counter asap, so we have camel-1 + return OsgiNamingHelper.findFreeCamelContextName(context, prefix, CONTEXT_NAME_PROPERTY, CONTEXT_COUNTER, false); } @Override @@ -93,9 +60,4 @@ public class OsgiCamelContextNameStrategy implements CamelContextNameStrategy { return false; } - public static int getNextCounter() { - // we want to start counting from 1, so increment first - return CONTEXT_COUNTER.incrementAndGet(); - } - } http://git-wip-us.apache.org/repos/asf/camel/blob/67548e2e/components/camel-core-osgi/src/main/java/org/apache/camel/core/osgi/OsgiCamelContextPublisher.java ---------------------------------------------------------------------- diff --git a/components/camel-core-osgi/src/main/java/org/apache/camel/core/osgi/OsgiCamelContextPublisher.java b/components/camel-core-osgi/src/main/java/org/apache/camel/core/osgi/OsgiCamelContextPublisher.java index d932550..02eeb8e 100644 --- a/components/camel-core-osgi/src/main/java/org/apache/camel/core/osgi/OsgiCamelContextPublisher.java +++ b/components/camel-core-osgi/src/main/java/org/apache/camel/core/osgi/OsgiCamelContextPublisher.java @@ -43,6 +43,7 @@ public class OsgiCamelContextPublisher extends EventNotifierSupport { public static final String CONTEXT_SYMBOLIC_NAME_PROPERTY = "camel.context.symbolicname"; public static final String CONTEXT_VERSION_PROPERTY = "camel.context.version"; public static final String CONTEXT_NAME_PROPERTY = "camel.context.name"; + public static final String CONTEXT_MANAGEMENT_NAME_PROPERTY = "camel.context.managementname"; private final BundleContext bundleContext; private final Map registrations = new ConcurrentHashMap(); @@ -96,16 +97,19 @@ public class OsgiCamelContextPublisher extends EventNotifierSupport { // we must include unique camel management name so the symbolic name becomes unique, // in case the bundle has more than one CamelContext String name = camelContext.getName(); - String symbolicName = bundleContext.getBundle().getSymbolicName() + "-" + name; - Version bundleVersion = getBundleVersion(bundleContext.getBundle()); - ServiceReference[] refs = bundleContext.getServiceReferences(CamelContext.class.getName(), - "(&(" + CONTEXT_SYMBOLIC_NAME_PROPERTY + "=" + symbolicName + ")(" + CONTEXT_VERSION_PROPERTY + "=" + bundleVersion + "))"); + String managementName = camelContext.getManagementName(); + String symbolicName = bundleContext.getBundle().getSymbolicName(); + + if (!lookupCamelContext(bundleContext, symbolicName, name)) { + Version bundleVersion = getBundleVersion(bundleContext.getBundle()); - if (refs == null) { Dictionary props = new Hashtable(); props.put(CONTEXT_SYMBOLIC_NAME_PROPERTY, symbolicName); props.put(CONTEXT_VERSION_PROPERTY, bundleVersion); props.put(CONTEXT_NAME_PROPERTY, name); + if (managementName != null) { + props.put(CONTEXT_MANAGEMENT_NAME_PROPERTY, managementName); + } if (log.isDebugEnabled()) { log.debug("Registering CamelContext [{}] of in OSGi registry", camelContext.getName()); @@ -127,4 +131,18 @@ public class OsgiCamelContextPublisher extends EventNotifierSupport { return (version != null) ? Version.parseVersion(version) : Version.emptyVersion; } + /** + * Lookup in the OSGi Service Registry whether a {@link org.apache.camel.CamelContext} is already registered with the given symbolic name. + * + * @return true if exists, false otherwise + */ + public static boolean lookupCamelContext(BundleContext bundleContext, String symbolicName, String contextName) throws InvalidSyntaxException { + Version bundleVersion = getBundleVersion(bundleContext.getBundle()); + ServiceReference[] refs = bundleContext.getServiceReferences(CamelContext.class.getName(), + "(&(" + CONTEXT_SYMBOLIC_NAME_PROPERTY + "=" + symbolicName + ")" + + "(" + CONTEXT_NAME_PROPERTY + "=" + contextName + ")" + + "(" + CONTEXT_VERSION_PROPERTY + "=" + bundleVersion + "))"); + return refs != null && refs.length > 0; + } + } http://git-wip-us.apache.org/repos/asf/camel/blob/67548e2e/components/camel-core-osgi/src/main/java/org/apache/camel/core/osgi/OsgiManagementNameStrategy.java ---------------------------------------------------------------------- diff --git a/components/camel-core-osgi/src/main/java/org/apache/camel/core/osgi/OsgiManagementNameStrategy.java b/components/camel-core-osgi/src/main/java/org/apache/camel/core/osgi/OsgiManagementNameStrategy.java index f870ca2..78468c6 100644 --- a/components/camel-core-osgi/src/main/java/org/apache/camel/core/osgi/OsgiManagementNameStrategy.java +++ b/components/camel-core-osgi/src/main/java/org/apache/camel/core/osgi/OsgiManagementNameStrategy.java @@ -16,6 +16,7 @@ */ package org.apache.camel.core.osgi; +import java.util.concurrent.atomic.AtomicInteger; import java.util.regex.Matcher; import org.apache.camel.CamelContext; @@ -41,6 +42,7 @@ import org.osgi.framework.BundleContext; */ public class OsgiManagementNameStrategy extends DefaultManagementNameStrategy { + private static final AtomicInteger CONTEXT_COUNTER = new AtomicInteger(0); private final BundleContext bundleContext; public OsgiManagementNameStrategy(CamelContext camelContext, BundleContext bundleContext) { @@ -62,6 +64,11 @@ public class OsgiManagementNameStrategy extends DefaultManagementNameStrategy { answer = answer.replaceFirst("#bundleId#", bundleId); answer = answer.replaceFirst("#symbolicName#", symbolicName); answer = answer.replaceFirst("#version#", version); + + // we got a candidate then find a free name + // true = check fist if the candidate as-is is free, if not then use the counter + answer = OsgiNamingHelper.findFreeCamelContextName(bundleContext, answer, OsgiCamelContextPublisher.CONTEXT_MANAGEMENT_NAME_PROPERTY, CONTEXT_COUNTER, true); + return answer; } http://git-wip-us.apache.org/repos/asf/camel/blob/67548e2e/components/camel-core-osgi/src/main/java/org/apache/camel/core/osgi/OsgiNamingHelper.java ---------------------------------------------------------------------- diff --git a/components/camel-core-osgi/src/main/java/org/apache/camel/core/osgi/OsgiNamingHelper.java b/components/camel-core-osgi/src/main/java/org/apache/camel/core/osgi/OsgiNamingHelper.java new file mode 100644 index 0000000..5c41f34 --- /dev/null +++ b/components/camel-core-osgi/src/main/java/org/apache/camel/core/osgi/OsgiNamingHelper.java @@ -0,0 +1,91 @@ +/** + * 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. + */ +package org.apache.camel.core.osgi; + +import java.util.concurrent.atomic.AtomicInteger; + +import org.apache.camel.CamelContext; +import org.osgi.framework.BundleContext; +import org.osgi.framework.InvalidSyntaxException; +import org.osgi.framework.ServiceReference; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * A helper to find free names in the OSGi service registry. + */ +public final class OsgiNamingHelper { + + private static final Logger LOG = LoggerFactory.getLogger(OsgiNamingHelper.class); + + private OsgiNamingHelper() { + } + + /** + * Checks the OSGi service registry for a free name (uses the counter if there is a clash to find next free name) + * + * @param context the bundle context + * @param prefix the prefix for the name + * @param key the key to use in the OSGi filter; either {@link OsgiCamelContextPublisher#CONTEXT_NAME_PROPERTY} + * or {@link OsgiCamelContextPublisher#CONTEXT_MANAGEMENT_NAME_PROPERTY}. + * @param counter the counter + * @param checkFirst true to check the prefix name as-is before using the counter, false the counter is used immediately + * @return the free name, is never null + */ + public static String findFreeCamelContextName(BundleContext context, String prefix, String key, AtomicInteger counter, boolean checkFirst) { + String candidate = null; + boolean clash = false; + + do { + try { + clash = false; + + if (candidate == null && checkFirst) { + // try candidate as-is + candidate = prefix; + } else { + // generate new candidate + candidate = prefix + "-" + getNextCounter(counter); + } + LOG.trace("Checking OSGi Service Registry for existence of existing CamelContext with name: {}", candidate); + + ServiceReference[] refs = context.getServiceReferences(CamelContext.class.getName(), "(" + key + "=" + candidate + ")"); + if (refs != null && refs.length > 0) { + for (ServiceReference ref : refs) { + Object id = ref.getProperty(key); + if (id != null && candidate.equals(id)) { + clash = true; + break; + } + } + } + } catch (InvalidSyntaxException e) { + LOG.debug("Error finding free Camel name in OSGi Service Registry due " + e.getMessage() + ". This exception is ignored.", e); + break; + } + } while (clash); + + LOG.debug("Generated free name for bundle id: {}, clash: {} -> {}", new Object[]{context.getBundle().getBundleId(), clash, candidate}); + return candidate; + } + + public static int getNextCounter(AtomicInteger counter) { + // we want to start counting from 1, so increment first + return counter.incrementAndGet(); + } + +}