Return-Path: X-Original-To: apmail-aries-commits-archive@www.apache.org Delivered-To: apmail-aries-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 C8B5D18790 for ; Mon, 18 Jan 2016 12:58:18 +0000 (UTC) Received: (qmail 12081 invoked by uid 500); 18 Jan 2016 12:58:18 -0000 Delivered-To: apmail-aries-commits-archive@aries.apache.org Received: (qmail 12014 invoked by uid 500); 18 Jan 2016 12:58:18 -0000 Mailing-List: contact commits-help@aries.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@aries.apache.org Delivered-To: mailing list commits@aries.apache.org Received: (qmail 12003 invoked by uid 99); 18 Jan 2016 12:58:18 -0000 Received: from Unknown (HELO spamd1-us-west.apache.org) (209.188.14.142) by apache.org (qpsmtpd/0.29) with ESMTP; Mon, 18 Jan 2016 12:58:18 +0000 Received: from localhost (localhost [127.0.0.1]) by spamd1-us-west.apache.org (ASF Mail Server at spamd1-us-west.apache.org) with ESMTP id 3ED18C3EDF for ; Mon, 18 Jan 2016 12:58:18 +0000 (UTC) X-Virus-Scanned: Debian amavisd-new at spamd1-us-west.apache.org X-Spam-Flag: NO X-Spam-Score: 1.8 X-Spam-Level: * X-Spam-Status: No, score=1.8 tagged_above=-999 required=6.31 tests=[KAM_ASCII_DIVIDERS=0.8, KAM_LAZY_DOMAIN_SECURITY=1, RP_MATCHES_RCVD=-0.001, URIBL_BLOCKED=0.001] autolearn=disabled Received: from mx1-us-east.apache.org ([10.40.0.8]) by localhost (spamd1-us-west.apache.org [10.40.0.7]) (amavisd-new, port 10024) with ESMTP id WWyFdDiWjqgB for ; Mon, 18 Jan 2016 12:58:10 +0000 (UTC) Received: from mailrelay1-us-west.apache.org (mailrelay1-us-west.apache.org [209.188.14.139]) by mx1-us-east.apache.org (ASF Mail Server at mx1-us-east.apache.org) with ESMTP id 5626743EF0 for ; Mon, 18 Jan 2016 12:58:10 +0000 (UTC) Received: from svn01-us-west.apache.org (svn.apache.org [10.41.0.6]) by mailrelay1-us-west.apache.org (ASF Mail Server at mailrelay1-us-west.apache.org) with ESMTP id C3DC4E0185 for ; Mon, 18 Jan 2016 12:58:09 +0000 (UTC) Received: from svn01-us-west.apache.org (localhost [127.0.0.1]) by svn01-us-west.apache.org (ASF Mail Server at svn01-us-west.apache.org) with ESMTP id 9EC163A0046 for ; Mon, 18 Jan 2016 12:58:09 +0000 (UTC) Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: svn commit: r1725256 - in /aries/branches/jpa-1.x/jpa-container/src: main/java/org/apache/aries/jpa/container/impl/EntityManagerFactoryManager.java test/java/org/apache/aries/jpa/container/impl/EntityManagerFactoryManagerTest.java Date: Mon, 18 Jan 2016 12:58:09 -0000 To: commits@aries.apache.org From: gnodet@apache.org X-Mailer: svnmailer-1.0.9 Message-Id: <20160118125809.9EC163A0046@svn01-us-west.apache.org> Author: gnodet Date: Mon Jan 18 12:58:09 2016 New Revision: 1725256 URL: http://svn.apache.org/viewvc?rev=1725256&view=rev Log: [ARIES-1487] JPA waits forever on osgi:service/javax.sql.DataSource/(osgi.jndi.service.name=jdbc/DataSource) Added: aries/branches/jpa-1.x/jpa-container/src/test/java/org/apache/aries/jpa/container/impl/EntityManagerFactoryManagerTest.java Modified: aries/branches/jpa-1.x/jpa-container/src/main/java/org/apache/aries/jpa/container/impl/EntityManagerFactoryManager.java Modified: aries/branches/jpa-1.x/jpa-container/src/main/java/org/apache/aries/jpa/container/impl/EntityManagerFactoryManager.java URL: http://svn.apache.org/viewvc/aries/branches/jpa-1.x/jpa-container/src/main/java/org/apache/aries/jpa/container/impl/EntityManagerFactoryManager.java?rev=1725256&r1=1725255&r2=1725256&view=diff ============================================================================== --- aries/branches/jpa-1.x/jpa-container/src/main/java/org/apache/aries/jpa/container/impl/EntityManagerFactoryManager.java (original) +++ aries/branches/jpa-1.x/jpa-container/src/main/java/org/apache/aries/jpa/container/impl/EntityManagerFactoryManager.java Mon Jan 18 12:58:09 2016 @@ -21,8 +21,10 @@ package org.apache.aries.jpa.container.i import java.util.ArrayList; import java.util.Collection; import java.util.Collections; +import java.util.Enumeration; import java.util.HashMap; import java.util.Hashtable; +import java.util.List; import java.util.Map; import java.util.Map.Entry; import java.util.concurrent.Callable; @@ -35,6 +37,9 @@ import java.util.concurrent.Future; import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeoutException; +import javax.naming.CompositeName; +import javax.naming.InvalidNameException; +import javax.naming.Name; import javax.persistence.EntityManagerFactory; import javax.persistence.spi.PersistenceProvider; import javax.persistence.spi.PersistenceUnitInfo; @@ -49,6 +54,8 @@ import org.apache.aries.jpa.container.qu import org.apache.aries.util.AriesFrameworkUtil; import org.osgi.framework.Bundle; import org.osgi.framework.BundleContext; +import org.osgi.framework.Constants; +import org.osgi.framework.Filter; import org.osgi.framework.FrameworkUtil; import org.osgi.framework.InvalidSyntaxException; import org.osgi.framework.ServiceReference; @@ -94,8 +101,8 @@ public class EntityManagerFactoryManager private final ConcurrentMap> dataSourceFactories = new ConcurrentHashMap>(); - private final ConcurrentMap> jndiServices = - new ConcurrentHashMap>(); + private final ConcurrentMap> jndiServices = + new ConcurrentHashMap>(); /** Logger */ private static final Logger _logger = LoggerFactory.getLogger("org.apache.aries.jpa.container"); @@ -320,42 +327,55 @@ public class EntityManagerFactoryManager } } - private boolean availableJndiService(String unitName) { + boolean availableJndiService(String unitName) { ManagedPersistenceUnitInfo mpui = persistenceUnits.get(unitName); String dsName = (String) mpui.getContainerProperties().get(DATA_SOURCE_NAME); if (dsName != null && dsName.startsWith("osgi:service/")) { - String jndi = dsName.substring("osgi:service/".length()); - if (jndiServices.containsKey(jndi)) { - jndiServices.get(jndi).add(unitName); - if (_logger.isDebugEnabled()) - _logger.debug(NLS.MESSAGES.getMessage("jndiservice.found", unitName, bundle.getSymbolicName(), - bundle.getVersion(), jndi)); - } else { - _logger.debug(NLS.MESSAGES.getMessage("jndiservice.not.found", unitName, bundle.getSymbolicName(), - bundle.getVersion(), jndi)); - return false; - } + return isJndiServiceAvailable(unitName, dsName); } String jtaDsName = (String) mpui.getContainerProperties().get(DATA_SOURCE_NAME_JTA); if (jtaDsName != null && jtaDsName.startsWith("osgi:service/")) { - String jndi = jtaDsName.substring("osgi:service/".length()); - if (jndiServices.containsKey(jndi)) { - jndiServices.get(jndi).add(unitName); - if (_logger.isDebugEnabled()) - _logger.debug(NLS.MESSAGES.getMessage("jndiservice.found", unitName, bundle.getSymbolicName(), - bundle.getVersion(), jndi)); - } else { - _logger.debug(NLS.MESSAGES.getMessage("jndiservice.not.found", unitName, bundle.getSymbolicName(), - bundle.getVersion(), jndi)); - return false; - } + return isJndiServiceAvailable(unitName, jtaDsName); } return true; } + private boolean isJndiServiceAvailable(String unitName, String jndi) { + OsgiName osgi = new OsgiName(jndi); + String filter; + if (osgi.isInterfaceNameBased()) { + String interfaceName = osgi.getInterface(); + if (osgi.hasFilter()) { + filter = "(&(objectClass=" + interfaceName + ")" + osgi.getFilter() + ")"; + } else { + filter = "(objectClass=" + interfaceName + ")"; + } + } else { + String serviceName = osgi.getServiceName(); + filter = "(osgi.jndi.service.name=" + serviceName + ")"; + } + try { + Filter flt = FrameworkUtil.createFilter(filter); + for (ServiceReference ref : jndiServices.keySet()) { + if (flt.match(ref)) { + jndiServices.get(ref).add(unitName); + if (_logger.isDebugEnabled()) + _logger.debug(NLS.MESSAGES.getMessage("jndiservice.found", unitName, bundle.getSymbolicName(), + bundle.getVersion(), jndi)); + return true; + } + } + } catch (InvalidSyntaxException e) { + // Ignore + } + _logger.debug(NLS.MESSAGES.getMessage("jndiservice.not.found", unitName, bundle.getSymbolicName(), + bundle.getVersion(), jndi)); + return false; + } + private boolean availableDataSourceFactory(String unitName) { ManagedPersistenceUnitInfo mpui = persistenceUnits.get(unitName); @@ -563,7 +583,7 @@ public class EntityManagerFactoryManager Object jndiName = reference.getProperty("osgi.jndi.service.name"); if (jndiName != null) { StringBuffer sb = new StringBuffer(String.valueOf(jndiName)); - if (jndiServices.putIfAbsent(sb.toString(), new ArrayList()) == null) { + if (jndiServices.putIfAbsent(reference, new ArrayList()) == null) { if (_logger.isDebugEnabled()) _logger.debug(NLS.MESSAGES.getMessage("new.jndiservice.available", sb.toString(), bundle.getSymbolicName(), bundle.getVersion())); @@ -685,4 +705,132 @@ public class EntityManagerFactoryManager } } + static class OsgiName extends CompositeName { + public static final String OSGI_SCHEME = "osgi"; + public static final String ARIES_SCHEME = "aries"; + public static final String SERVICE_PATH = "service"; + public static final String SERVICES_PATH = "services"; + public static final String SERVICE_LIST_PATH = "servicelist"; + public static final String FRAMEWORK_PATH = "framework"; + + public OsgiName(String name) + { + super(split(name)); + } + + public boolean hasFilter() + { + return size() == 3; + } + + public boolean isServiceNameBased() + { + return !isInterfaceNameBased(); + } + + public boolean isInterfaceNameBased() + { + if (size() < 2 || size() > 3) { + return false; + } + String itf = get(1); + if (!itf.matches("[a-zA-Z_$0-9]+(\\.[a-zA-Z_$0-9]+)+")) { + return false; + } + if (size() == 3) { + + } + return true; + } + + public String getInterface() + { + return get(1); + } + + public String getFilter() + { + return hasFilter() ? get(2) : null; + } + + public String getServiceName() + { + Enumeration parts = getAll(); + parts.nextElement(); + + StringBuilder builder = new StringBuilder(); + + if (parts.hasMoreElements()) { + + while (parts.hasMoreElements()) { + builder.append(parts.nextElement()); + builder.append('/'); + } + + builder.deleteCharAt(builder.length() - 1); + } + + return builder.toString(); + } + + public boolean hasInterface() + { + return size() > 1; + } + + protected static Enumeration split(String name) + { + List elements = new ArrayList(); + + StringBuilder builder = new StringBuilder(); + + int len = name.length(); + int count = 0; + + for (int i = 0; i < len; i++) { + char c = name.charAt(i); + + if (c == '/' && count == 0) { + elements.add(builder.toString()); + builder = new StringBuilder(); + continue; + } else if (c == '(') count++; + else if (c == ')') count++; + + builder.append(c); + } + + elements.add(builder.toString()); + + return Collections.enumeration(elements); + } + + public String getScheme() + { + String part0 = get(0); + int index = part0.indexOf(':'); + if (index > 0) { + return part0.substring(0, index); + } else { + return null; + } + } + + public String getSchemePath() + { + String part0 = get(0); + int index = part0.indexOf(':'); + + String result; + + if (index > 0) { + result = part0.substring(index + 1); + } else { + result = null; + } + + return result; + } + } + } Added: aries/branches/jpa-1.x/jpa-container/src/test/java/org/apache/aries/jpa/container/impl/EntityManagerFactoryManagerTest.java URL: http://svn.apache.org/viewvc/aries/branches/jpa-1.x/jpa-container/src/test/java/org/apache/aries/jpa/container/impl/EntityManagerFactoryManagerTest.java?rev=1725256&view=auto ============================================================================== --- aries/branches/jpa-1.x/jpa-container/src/test/java/org/apache/aries/jpa/container/impl/EntityManagerFactoryManagerTest.java (added) +++ aries/branches/jpa-1.x/jpa-container/src/test/java/org/apache/aries/jpa/container/impl/EntityManagerFactoryManagerTest.java Mon Jan 18 12:58:09 2016 @@ -0,0 +1,80 @@ +/* + * 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 WARRANTIESOR 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.aries.jpa.container.impl; + +import java.util.Collections; +import java.util.Hashtable; + +import org.apache.aries.jpa.container.ManagedPersistenceUnitInfo; +import org.apache.aries.jpa.container.parsing.ParsedPersistenceUnit; +import org.apache.aries.jpa.container.parsing.impl.PersistenceUnitImpl; +import org.apache.aries.jpa.container.unit.impl.ManagedPersistenceUnitInfoImpl; +import org.apache.aries.mocks.BundleMock; +import org.apache.aries.unittest.mocks.MethodCall; +import org.apache.aries.unittest.mocks.Skeleton; +import org.junit.Test; +import org.osgi.framework.Bundle; +import org.osgi.framework.ServiceReference; + +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +public class EntityManagerFactoryManagerTest { + + @Test + public void testJndiSimple() { + Bundle persistenceBundle = Skeleton.newMock(new BundleMock("scooby.doo", new Hashtable()), Bundle.class); + + PersistenceUnitImpl unit = new PersistenceUnitImpl(persistenceBundle, "persistentUnitName", null, "1.0"); + unit.setJtaDataSource("osgi:service/jdbc/DataSource"); + + ManagedPersistenceUnitInfo mpuInfo = new ManagedPersistenceUnitInfoImpl(persistenceBundle, unit, null); + EntityManagerFactoryManager emfManager = new EntityManagerFactoryManager(null, persistenceBundle); + emfManager.manage(Collections.singletonList(unit), null, Collections.singletonList(mpuInfo)); + + assertFalse(emfManager.availableJndiService("persistentUnitName")); + + ServiceReference dataSourceRef = Skeleton.newMock(ServiceReference.class); + Skeleton.getSkeleton(dataSourceRef).setReturnValue(new MethodCall(ServiceReference.class, "getProperty", "osgi.jdbc.driver.class"), null); + Skeleton.getSkeleton(dataSourceRef).setReturnValue(new MethodCall(ServiceReference.class, "getProperty", "osgi.jndi.service.name"), "jdbc/DataSource"); + emfManager.addingService(dataSourceRef); + assertTrue(emfManager.availableJndiService("persistentUnitName")); + } + + @Test + public void testJndiExtended() { + Bundle persistenceBundle = Skeleton.newMock(new BundleMock("scooby.doo", new Hashtable()), Bundle.class); + + PersistenceUnitImpl unit = new PersistenceUnitImpl(persistenceBundle, "persistentUnitName", null, "1.0"); + unit.setJtaDataSource("osgi:service/javax.sql.DataSource/(osgi.jndi.service.name=jdbc/DataSource)"); + + ManagedPersistenceUnitInfo mpuInfo = new ManagedPersistenceUnitInfoImpl(persistenceBundle, unit, null); + EntityManagerFactoryManager emfManager = new EntityManagerFactoryManager(null, persistenceBundle); + emfManager.manage(Collections.singletonList(unit), null, Collections.singletonList(mpuInfo)); + + assertFalse(emfManager.availableJndiService("persistentUnitName")); + + ServiceReference dataSourceRef = Skeleton.newMock(ServiceReference.class); + Skeleton.getSkeleton(dataSourceRef).setReturnValue(new MethodCall(ServiceReference.class, "getProperty", "objectClass"), "javax.sql.DataSource"); + Skeleton.getSkeleton(dataSourceRef).setReturnValue(new MethodCall(ServiceReference.class, "getProperty", "osgi.jdbc.driver.class"), null); + Skeleton.getSkeleton(dataSourceRef).setReturnValue(new MethodCall(ServiceReference.class, "getProperty", "osgi.jndi.service.name"), "jdbc/DataSource"); + emfManager.addingService(dataSourceRef); + assertTrue(emfManager.availableJndiService("persistentUnitName")); + } +}