aries-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From gno...@apache.org
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 GMT
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<String, Collection<String>> dataSourceFactories
=
          new ConcurrentHashMap<String, Collection<String>>();
 
-  private final ConcurrentMap<String, Collection<String>> jndiServices =
-         new ConcurrentHashMap<String, Collection<String>>();
+  private final ConcurrentMap<ServiceReference, Collection<String>> jndiServices
=
+         new ConcurrentHashMap<ServiceReference, Collection<String>>();
 
   /** 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<String>()) == null)
{
+        if (jndiServices.putIfAbsent(reference, new ArrayList<String>()) == 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<String> 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<String> split(String name)
+    {
+      List<String> elements = new ArrayList<String>();
+
+      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<String,
Object>()), 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.<ParsedPersistenceUnit>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<String,
Object>()), 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.<ParsedPersistenceUnit>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"));
+    }
+}



Mime
View raw message