sling-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From chet...@apache.org
Subject svn commit: r1637799 - in /sling/trunk/contrib/extensions/datasource: ./ src/main/java/org/apache/sling/datasource/internal/ src/main/resources/OSGI-INF/metatype/
Date Mon, 10 Nov 2014 07:05:08 GMT
Author: chetanm
Date: Mon Nov 10 07:05:08 2014
New Revision: 1637799

URL: http://svn.apache.org/r1637799
Log:
SLING-3735 - support JNDI lookup in JDBC DataSource Provider

Added:
    sling/trunk/contrib/extensions/datasource/src/main/java/org/apache/sling/datasource/internal/JNDIDataSourceFactory.java
  (with props)
Modified:
    sling/trunk/contrib/extensions/datasource/README.md
    sling/trunk/contrib/extensions/datasource/src/main/java/org/apache/sling/datasource/internal/DataSourceFactory.java
    sling/trunk/contrib/extensions/datasource/src/main/resources/OSGI-INF/metatype/metatype.properties

Modified: sling/trunk/contrib/extensions/datasource/README.md
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/datasource/README.md?rev=1637799&r1=1637798&r2=1637799&view=diff
==============================================================================
--- sling/trunk/contrib/extensions/datasource/README.md (original)
+++ sling/trunk/contrib/extensions/datasource/README.md Mon Nov 10 07:05:08 2014
@@ -1,5 +1,11 @@
-Apache Sling DataSource Provider
-================================
+# Apache Sling DataSource Provider
+
+DataSource provider bundle supports two type of DataSource
+
+1. Pooled Connection DataSource
+2. JNDI DataSource
+
+## Pooled Connection DataSource Provider
 
 This bundle enables creating and configuring JDBC DataSource in OSGi environment based on

 OSGi configuration. It uses [Tomcat JDBC Pool][1] as the JDBC Connection Pool provider.
@@ -9,8 +15,7 @@ OSGi configuration. It uses [Tomcat JDBC
 3. Exposes the DataSource stats as JMX MBean 
 4. Supports updating of DataSource connection pool properties at runtime without restart
 
-Driver Loading
---------------
+### Driver Loading
 
 Loading of JDBC driver is tricky on OSGi env. Mostly one has to attach the Driver bundle
as a
 fragment bundle to the code which creates the JDBC Connection. 
@@ -28,8 +33,7 @@ bundle to Driver class supported by it. 
 bundle as fragment to DataSource provider bundle
 
 
-Configuration
--------------
+### Configuration
 
 1. Install the current bundle
 2. Install the JDBC Driver bundle
@@ -42,26 +46,7 @@ http://localhost:8080/system/console/con
 
 Using the config ui above one can directly configure most of the properties as explained
in [Tomcat Docs][1]
 
-Usage
------
-
-Once the required configuration is done the `DataSource` would be registered as part of the
OSGi Service Registry
-The service is registered with service property `datasource.name` whose value is the name
of datasource provided in 
-OSGi config. 
-
-Following snippet demonstrates accessing the DataSource named `foo` via DS annotation
-
-    import javax.sql.DataSource;
-    import org.apache.felix.scr.annotations.Reference;
-    
-    public class DSExample {
-        
-        @Reference(target = "(&(objectclass=javax.sql.DataSource)(datasource.name=foo))")
-        private DataSource dataSource;
-    }
-
-Convert Driver jars to Bundle
------------------------------
+### Convert Driver jars to Bundle
 
 Most of the JDBC driver jars have the required OSGi headers and can be directly deployed
to OSGi container
 as bundles. However some of the drivers e.g. Postgres are not having such headers and hence
need to be 
@@ -85,6 +70,37 @@ In the steps above we
 2. Create a bnd file with required instructions. 
 3. Execute the bnd command
 4. Resulting bundle is present in `org.postgresql-9.3.1101.jar`
- 
+
+## JNDI DataSource
+
+While running in Application Server the DataSource instance might be managed by app server
and registered with
+JNDI. To enable lookup of DataSource instance from JNDI you can configure `JNDIDataSourceFactory`
+
+1. Configure the DataSource from OSGi config for PID `org.apache.sling.datasource.JNDIDataSourceFactory`
+2. Provide the JNDI name to lookup from and other details
+
+If Felix WebConsole is used then you can configure it via Configuration UI at
+http://localhost:8080/system/console/configMgr/org.apache.sling.datasource.JNDIDataSourceFactory
+
+Once configured `JNDIDataSourceFactory` would lookup the DataSource instance and register
it with OSGi
+ServiceRegistry
+
+## Usage
+
+Once the required configuration is done the `DataSource` would be registered as part of the
OSGi Service Registry
+The service is registered with service property `datasource.name` whose value is the name
of datasource provided in
+OSGi config.
+
+Following snippet demonstrates accessing the DataSource named `foo` via DS annotation
+
+    import javax.sql.DataSource;
+    import org.apache.felix.scr.annotations.Reference;
+
+    public class DSExample {
+
+        @Reference(target = "(&(objectclass=javax.sql.DataSource)(datasource.name=foo))")
+        private DataSource dataSource;
+    }
+
 [1]: http://tomcat.apache.org/tomcat-7.0-doc/jdbc-pool.html
 [2]: http://www.aqute.biz/Bnd/Wrapping
\ No newline at end of file

Modified: sling/trunk/contrib/extensions/datasource/src/main/java/org/apache/sling/datasource/internal/DataSourceFactory.java
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/datasource/src/main/java/org/apache/sling/datasource/internal/DataSourceFactory.java?rev=1637799&r1=1637798&r2=1637799&view=diff
==============================================================================
--- sling/trunk/contrib/extensions/datasource/src/main/java/org/apache/sling/datasource/internal/DataSourceFactory.java
(original)
+++ sling/trunk/contrib/extensions/datasource/src/main/java/org/apache/sling/datasource/internal/DataSourceFactory.java
Mon Nov 10 07:05:08 2014
@@ -321,11 +321,11 @@ public class DataSourceFactory {
 
     //~----------------------------------------< Config Handling >
 
-    private static String getDataSourceName(Map<String, ?> config) {
+    static String getDataSourceName(Map<String, ?> config) {
         return PropertiesUtil.toString(config.get(PROP_DATASOURCE_NAME), null);
     }
 
-    private static String getSvcPropName(Map<String, ?> config) {
+    static String getSvcPropName(Map<String, ?> config) {
         return PropertiesUtil.toString(config.get(PROP_DS_SVC_PROP_NAME), PROP_DATASOURCE_NAME);
     }
 
@@ -343,7 +343,7 @@ public class DataSourceFactory {
         }
     }
 
-    private static void checkArgument(boolean expression,
+    static void checkArgument(boolean expression,
                                       String errorMessageTemplate,
                                       Object... errorMessageArgs) {
         if (!expression) {

Added: sling/trunk/contrib/extensions/datasource/src/main/java/org/apache/sling/datasource/internal/JNDIDataSourceFactory.java
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/datasource/src/main/java/org/apache/sling/datasource/internal/JNDIDataSourceFactory.java?rev=1637799&view=auto
==============================================================================
--- sling/trunk/contrib/extensions/datasource/src/main/java/org/apache/sling/datasource/internal/JNDIDataSourceFactory.java
(added)
+++ sling/trunk/contrib/extensions/datasource/src/main/java/org/apache/sling/datasource/internal/JNDIDataSourceFactory.java
Mon Nov 10 07:05:08 2014
@@ -0,0 +1,160 @@
+/*
+ * 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.sling.datasource.internal;
+
+import java.util.Dictionary;
+import java.util.Hashtable;
+import java.util.Map;
+import java.util.Properties;
+
+import javax.naming.Context;
+import javax.naming.InitialContext;
+import javax.naming.NameNotFoundException;
+import javax.naming.NamingException;
+import javax.sql.DataSource;
+
+import org.apache.felix.scr.annotations.Activate;
+import org.apache.felix.scr.annotations.Component;
+import org.apache.felix.scr.annotations.ConfigurationPolicy;
+import org.apache.felix.scr.annotations.Deactivate;
+import org.apache.felix.scr.annotations.Property;
+import org.apache.sling.commons.osgi.PropertiesUtil;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.Constants;
+import org.osgi.framework.ServiceRegistration;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import static org.apache.sling.datasource.internal.DataSourceFactory.checkArgument;
+
+@Component(
+        name = JNDIDataSourceFactory.NAME,
+        label = "Apache Sling JNDI DataSource",
+        description = "Registers a DataSource instance with OSGi ServiceRegistry which is
looked up " +
+                "from the JNDI",
+        metatype = true,
+        configurationFactory = true,
+        policy = ConfigurationPolicy.REQUIRE
+)
+public class JNDIDataSourceFactory {
+    public static final String NAME = "org.apache.sling.datasource.JNDIDataSourceFactory";
+
+    @Property
+    static final String PROP_DATASOURCE_NAME = "datasource.name";
+
+    @Property(value = PROP_DATASOURCE_NAME)
+    static final String PROP_DS_SVC_PROP_NAME = "datasource.svc.prop.name";
+
+    @Property(
+            label = "JNDI Name (*)",
+            description = "JNDI location name used to perform DataSource instance lookup"
+    )
+    static final String PROP_DS_JNDI_NAME = "datasource.jndi.name";
+
+    @Property(
+            label = "JNDI Properties",
+            description = "Set the environment for the JNDI InitialContext i.e. properties
passed on to InitialContext " +
+                    "for performing the JNDI instance lookup",
+            value = {},
+            cardinality = 1024)
+    static final String PROP_JNDI_PROPS = "jndi.properties";
+
+    private final Logger log = LoggerFactory.getLogger(getClass());
+
+    private ServiceRegistration dsRegistration;
+
+
+    @Activate
+    protected void activate(BundleContext bundleContext, Map<String, ?> config) throws
Exception {
+        String name = DataSourceFactory.getDataSourceName(config);
+        String jndiName = PropertiesUtil.toString(config.get(PROP_DS_JNDI_NAME), null);
+
+        checkArgument(name != null, "DataSource name must be specified via [%s] property",
PROP_DATASOURCE_NAME);
+        checkArgument(jndiName != null, "DataSource JNDI name must be specified via [%s]
property", PROP_DS_JNDI_NAME);
+
+        DataSource dataSource = lookupDataSource(jndiName, config);
+        String svcPropName = DataSourceFactory.getSvcPropName(config);
+
+        Dictionary<String, Object> svcProps = new Hashtable<String, Object>();
+        svcProps.put(svcPropName, name);
+        svcProps.put(Constants.SERVICE_VENDOR, "Apache Software Foundation");
+        svcProps.put(Constants.SERVICE_DESCRIPTION, "DataSource service looked up from "
+ jndiName);
+        dsRegistration = bundleContext.registerService(javax.sql.DataSource.class, dataSource,
svcProps);
+
+        log.info("Registered DataSource [{}] looked up from JNDI at [{}]", name, jndiName);
+    }
+
+    @Deactivate
+    protected void deactivate() {
+        if (dsRegistration != null) {
+            dsRegistration.unregister();
+            dsRegistration = null;
+        }
+    }
+
+    private DataSource lookupDataSource(String jndiName, Map<String, ?> config) throws
NamingException {
+        Properties jndiProps = createJndiEnv(config);
+        Context context = null;
+        try {
+            log.debug("Looking up DataSource [{}] with InitialContext env [{}]", jndiName,
jndiProps);
+
+            context = new InitialContext(jndiProps);
+            Object lookup = context.lookup(jndiName);
+            if (lookup == null) {
+                throw new NameNotFoundException("JNDI object with [" + jndiName + "] not
found");
+            }
+
+            if (!DataSource.class.isInstance(lookup)) {
+                throw new IllegalStateException("JNDI object of type " + lookup.getClass()
+
+                        "is not an instance of javax.sql.DataSource");
+            }
+
+            return (DataSource) lookup;
+        } finally {
+            if (context != null) {
+                context.close();
+            }
+        }
+    }
+
+    private Properties createJndiEnv(Map<String, ?> config) {
+        Properties props = new Properties();
+
+        //Copy the other properties first
+        Map<String, String> otherProps = PropertiesUtil.toMap(config.get(PROP_JNDI_PROPS),
new String[0]);
+        for (Map.Entry<String, String> e : otherProps.entrySet()) {
+            set(e.getKey(), e.getValue(), props);
+        }
+
+        return props;
+    }
+
+    //~----------------------------------------< Config Handling >
+
+    private static void set(String name, String value, Properties props) {
+        if (value != null) {
+            value = value.trim();
+        }
+
+        if (value != null && !value.isEmpty()) {
+            props.setProperty(name, value);
+        }
+    }
+}

Propchange: sling/trunk/contrib/extensions/datasource/src/main/java/org/apache/sling/datasource/internal/JNDIDataSourceFactory.java
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: sling/trunk/contrib/extensions/datasource/src/main/resources/OSGI-INF/metatype/metatype.properties
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/datasource/src/main/resources/OSGI-INF/metatype/metatype.properties?rev=1637799&r1=1637798&r2=1637799&view=diff
==============================================================================
--- sling/trunk/contrib/extensions/datasource/src/main/resources/OSGI-INF/metatype/metatype.properties
(original)
+++ sling/trunk/contrib/extensions/datasource/src/main/resources/OSGI-INF/metatype/metatype.properties
Mon Nov 10 07:05:08 2014
@@ -130,7 +130,7 @@ logValidationErrors.name=Log Validation 
 logValidationErrors.description=Set this to true to log errors during the validation phase
to the log file
 
 datasource.svc.prop.name.name=DataSource Service Property Name
-datasource.svc.prop.name.name.description=Name of the service property which would store
the DataSource Name while\
+datasource.svc.prop.name.description=Name of the service property which would store the DataSource
Name while\
   registering the DataSource instance as OSGi service
 
 



Mime
View raw message