You are viewing a plain text version of this content. The canonical link for it is here.
Posted to oak-commits@jackrabbit.apache.org by ch...@apache.org on 2014/06/12 09:37:29 UTC

svn commit: r1602080 - in /jackrabbit/oak/trunk/oak-pojosr: ./ src/main/java/org/apache/jackrabbit/oak/run/osgi/ src/test/groovy/org/apache/jackrabbit/oak/run/osgi/

Author: chetanm
Date: Thu Jun 12 07:37:29 2014
New Revision: 1602080

URL: http://svn.apache.org/r1602080
Log:
OAK-1522 - Provide PojoSR based RepositoryFactory implementation

Adding support for scheduling runnable via whiteboard pattern. Also update osgi compedium to 4.3.1. to enable use of generics in ServiceTracker

Added:
    jackrabbit/oak/trunk/oak-pojosr/src/main/java/org/apache/jackrabbit/oak/run/osgi/RunnableJobTracker.java   (with props)
    jackrabbit/oak/trunk/oak-pojosr/src/test/groovy/org/apache/jackrabbit/oak/run/osgi/TrackerSupportTest.groovy
Modified:
    jackrabbit/oak/trunk/oak-pojosr/pom.xml
    jackrabbit/oak/trunk/oak-pojosr/src/main/java/org/apache/jackrabbit/oak/run/osgi/ConfigTracker.java
    jackrabbit/oak/trunk/oak-pojosr/src/main/java/org/apache/jackrabbit/oak/run/osgi/OakOSGiRepositoryFactory.java

Modified: jackrabbit/oak/trunk/oak-pojosr/pom.xml
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-pojosr/pom.xml?rev=1602080&r1=1602079&r2=1602080&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-pojosr/pom.xml (original)
+++ jackrabbit/oak/trunk/oak-pojosr/pom.xml Thu Jun 12 07:37:29 2014
@@ -141,6 +141,11 @@
       <version>4.3.1</version>
     </dependency>
     <dependency>
+      <groupId>org.osgi</groupId>
+      <artifactId>org.osgi.compendium</artifactId>
+      <version>4.3.1</version>
+    </dependency>
+    <dependency>
       <groupId>com.googlecode.pojosr</groupId>
       <artifactId>de.kalpatec.pojosr.framework.bare</artifactId>
       <version>0.2.1</version>
@@ -166,6 +171,11 @@
       <version>0.0.2</version>
     </dependency>
     <dependency>
+      <groupId>org.apache.aries.jmx</groupId>
+      <artifactId>org.apache.aries.jmx.whiteboard</artifactId>
+      <version>1.0.0</version>
+    </dependency>
+    <dependency>
       <groupId>com.googlecode.json-simple</groupId>
       <artifactId>json-simple</artifactId>
       <version>1.1.1</version>
@@ -215,12 +225,6 @@
       <version>${h2.version}</version>
     </dependency>
     <dependency>
-      <groupId>org.osgi</groupId>
-      <artifactId>org.osgi.compendium</artifactId>
-      <version>4.3.1</version>
-      <scope>test</scope>
-    </dependency>
-    <dependency>
       <groupId>com.gmongo</groupId>
       <artifactId>gmongo</artifactId>
       <version>1.1</version>

Modified: jackrabbit/oak/trunk/oak-pojosr/src/main/java/org/apache/jackrabbit/oak/run/osgi/ConfigTracker.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-pojosr/src/main/java/org/apache/jackrabbit/oak/run/osgi/ConfigTracker.java?rev=1602080&r1=1602079&r2=1602080&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-pojosr/src/main/java/org/apache/jackrabbit/oak/run/osgi/ConfigTracker.java (original)
+++ jackrabbit/oak/trunk/oak-pojosr/src/main/java/org/apache/jackrabbit/oak/run/osgi/ConfigTracker.java Thu Jun 12 07:37:29 2014
@@ -43,7 +43,7 @@ import org.slf4j.LoggerFactory;
  * Installs config obtained from JSON Config file or passed as part of
  * startup
  */
-class ConfigTracker extends ServiceTracker {
+class ConfigTracker extends ServiceTracker<ConfigurationAdmin, ConfigurationAdmin> {
 
     private final Logger log = LoggerFactory.getLogger(getClass());
     private final Map config;
@@ -57,8 +57,8 @@ class ConfigTracker extends ServiceTrack
     }
 
     @Override
-    public Object addingService(ServiceReference reference) {
-        ConfigurationAdmin cm = (ConfigurationAdmin) super.addingService(reference);
+    public ConfigurationAdmin addingService(ServiceReference<ConfigurationAdmin> reference) {
+        ConfigurationAdmin cm = super.addingService(reference);
         try {
             synchronizeConfigs(new ConfigInstaller(cm, bundleContext));
         } catch (Exception e) {

Modified: jackrabbit/oak/trunk/oak-pojosr/src/main/java/org/apache/jackrabbit/oak/run/osgi/OakOSGiRepositoryFactory.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-pojosr/src/main/java/org/apache/jackrabbit/oak/run/osgi/OakOSGiRepositoryFactory.java?rev=1602080&r1=1602079&r2=1602080&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-pojosr/src/main/java/org/apache/jackrabbit/oak/run/osgi/OakOSGiRepositoryFactory.java (original)
+++ jackrabbit/oak/trunk/oak-pojosr/src/main/java/org/apache/jackrabbit/oak/run/osgi/OakOSGiRepositoryFactory.java Thu Jun 12 07:37:29 2014
@@ -36,7 +36,6 @@ import javax.jcr.Repository;
 import javax.jcr.RepositoryException;
 import javax.jcr.RepositoryFactory;
 
-import com.google.common.base.Preconditions;
 import com.google.common.collect.Lists;
 import com.google.common.util.concurrent.SettableFuture;
 import de.kalpatec.pojosr.framework.launch.BundleDescriptor;
@@ -97,19 +96,18 @@ public class OakOSGiRepositoryFactory im
         Map config = new HashMap();
         config.putAll(parameters);
 
-        //TODO With OSGi Whiteboard we need to provide support for handling
-        //execution and JMX support as so far they were provided by Sling bundles
-        //in OSGi env
-
         PojoServiceRegistry registry = initializeServiceRegistry(config);
 
         //Future which would be used to notify when repository is ready
         // to be used
         SettableFuture<Repository> repoFuture = SettableFuture.create();
 
+        new RunnableJobTracker(registry.getBundleContext());
+
         //Start the tracker for repository creation
         new RepositoryTracker(registry, repoFuture);
 
+
         //Now wait for repository to be created with given timeout
         //if repository creation takes more time. This is required to handle case
         // where OSGi runtime fails to start due to bugs (like cycles)
@@ -252,7 +250,7 @@ public class OakOSGiRepositoryFactory im
         }
     }
 
-    private static class RepositoryTracker extends ServiceTracker {
+    private static class RepositoryTracker extends ServiceTracker<Repository, Repository> {
         private final SettableFuture<Repository> repoFuture;
         private final PojoServiceRegistry registry;
         private RepositoryProxy proxy;
@@ -265,19 +263,19 @@ public class OakOSGiRepositoryFactory im
         }
 
         @Override
-        public Object addingService(ServiceReference reference) {
-            Object service = super.addingService(reference);
+        public Repository addingService(ServiceReference<Repository> reference) {
+            Repository service = context.getService(reference);
             if (proxy == null) {
                 //As its possible that future is accessed before the service
                 //get registered with tracker. We also capture the initial reference
                 //and use that for the first access case
-                repoFuture.set(createProxy((Repository) service));
+                repoFuture.set(createProxy(service));
             }
             return service;
         }
 
         @Override
-        public void removedService(ServiceReference reference, Object service) {
+        public void removedService(ServiceReference reference, Repository service) {
             if (proxy != null) {
                 proxy.clearInitialReference();
             }
@@ -315,7 +313,7 @@ public class OakOSGiRepositoryFactory im
                 obj = initialService;
             }
 
-            Preconditions.checkNotNull(obj, "Repository service is not available");
+            checkNotNull(obj, "Repository service is not available");
 
             final String name = method.getName();
             if ("shutdown".equals(name)) {

Added: jackrabbit/oak/trunk/oak-pojosr/src/main/java/org/apache/jackrabbit/oak/run/osgi/RunnableJobTracker.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-pojosr/src/main/java/org/apache/jackrabbit/oak/run/osgi/RunnableJobTracker.java?rev=1602080&view=auto
==============================================================================
--- jackrabbit/oak/trunk/oak-pojosr/src/main/java/org/apache/jackrabbit/oak/run/osgi/RunnableJobTracker.java (added)
+++ jackrabbit/oak/trunk/oak-pojosr/src/main/java/org/apache/jackrabbit/oak/run/osgi/RunnableJobTracker.java Thu Jun 12 07:37:29 2014
@@ -0,0 +1,110 @@
+/*
+ * 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.jackrabbit.oak.run.osgi;
+
+import java.io.Closeable;
+import java.util.concurrent.Future;
+import java.util.concurrent.ScheduledExecutorService;
+import java.util.concurrent.TimeUnit;
+
+import com.google.common.base.Supplier;
+import com.google.common.base.Suppliers;
+import org.apache.jackrabbit.oak.Oak;
+import org.apache.jackrabbit.oak.commons.PropertiesUtil;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.BundleEvent;
+import org.osgi.framework.Filter;
+import org.osgi.framework.FrameworkUtil;
+import org.osgi.framework.InvalidSyntaxException;
+import org.osgi.framework.ServiceReference;
+import org.osgi.framework.SynchronousBundleListener;
+import org.osgi.util.tracker.ServiceTracker;
+
+public class RunnableJobTracker extends ServiceTracker<Runnable, Future>
+        implements Closeable, SynchronousBundleListener {
+    /**
+     * Lazily loaded executor
+     */
+    private final Supplier<ScheduledExecutorService> executor =
+            Suppliers.memoize(new Supplier<ScheduledExecutorService>() {
+        @Override
+        public ScheduledExecutorService get() {
+            return Oak.defaultScheduledExecutor();
+        }
+    });
+
+    public RunnableJobTracker(BundleContext context) {
+        super(context, createFilter(), null);
+        open();
+        context.addBundleListener(this);
+    }
+
+    @Override
+    public Future addingService(ServiceReference<Runnable> reference) {
+        Runnable runnable = context.getService(reference);
+        long period = PropertiesUtil.toLong(reference.getProperty("scheduler.period"), -1);
+        boolean concurrent = PropertiesUtil.toBoolean(reference.getProperty("scheduler.concurrent"), false);
+        Future future = null;
+        if (period != -1) {
+            if (concurrent) {
+                future = getExecutor().scheduleAtFixedRate(
+                        runnable, period, period, TimeUnit.SECONDS);
+            } else {
+                future = getExecutor().scheduleWithFixedDelay(
+                        runnable, period, period, TimeUnit.SECONDS);
+            }
+        }
+        return future;
+    }
+
+    @Override
+    public void removedService(ServiceReference reference, Future future) {
+        future.cancel(false);
+    }
+
+    @Override
+    public void close() {
+        super.close();
+        getExecutor().shutdown();
+    }
+
+    @Override
+    public void bundleChanged(BundleEvent bundleEvent) {
+        //Look for close event of system bundle to shutdown executor
+        //Ideally we should listen to FrameworkEvent but PojoSR
+        //currently does not emit framework event
+        if(bundleEvent.getBundle().getBundleId() == 0
+                && bundleEvent.getType() == bundleEvent.STOPPED){
+            close();
+        }
+    }
+
+    private ScheduledExecutorService getExecutor(){
+        return executor.get();
+    }
+
+    private static Filter createFilter()  {
+        try {
+            return FrameworkUtil.createFilter("(&(objectclass=java.lang.Runnable)(scheduler.period=*))");
+        } catch (InvalidSyntaxException e) {
+            throw new IllegalArgumentException(e);
+        }
+    }
+}

Propchange: jackrabbit/oak/trunk/oak-pojosr/src/main/java/org/apache/jackrabbit/oak/run/osgi/RunnableJobTracker.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: jackrabbit/oak/trunk/oak-pojosr/src/test/groovy/org/apache/jackrabbit/oak/run/osgi/TrackerSupportTest.groovy
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-pojosr/src/test/groovy/org/apache/jackrabbit/oak/run/osgi/TrackerSupportTest.groovy?rev=1602080&view=auto
==============================================================================
--- jackrabbit/oak/trunk/oak-pojosr/src/test/groovy/org/apache/jackrabbit/oak/run/osgi/TrackerSupportTest.groovy (added)
+++ jackrabbit/oak/trunk/oak-pojosr/src/test/groovy/org/apache/jackrabbit/oak/run/osgi/TrackerSupportTest.groovy Thu Jun 12 07:37:29 2014
@@ -0,0 +1,54 @@
+/*
+ * 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.jackrabbit.oak.run.osgi
+
+import de.kalpatec.pojosr.framework.launch.PojoServiceRegistry
+import de.kalpatec.pojosr.framework.launch.PojoServiceRegistryFactory
+import org.junit.After
+import org.junit.Test
+
+import java.util.concurrent.CountDownLatch
+import java.util.concurrent.TimeUnit
+
+class TrackerSupportTest {
+    PojoServiceRegistry reg = createServiceRegistry([:])
+
+    @After
+    public void tearDown(){
+        reg.getBundleContext().getBundle().stop()
+    }
+
+    @Test
+    public void runnableTest() throws Exception{
+        new RunnableJobTracker(reg.bundleContext)
+
+        CountDownLatch latch = new CountDownLatch(1)
+        reg.registerService(Runnable.class.name,{latch.countDown()} as Runnable,
+                ['scheduler.period':1] as Hashtable)
+
+        //Wait for latch to get executed otherwise fail with timeout
+        latch.await(5, TimeUnit.SECONDS)
+    }
+
+    private PojoServiceRegistry createServiceRegistry(Map<String, Object> config) {
+        ServiceLoader<PojoServiceRegistryFactory> loader = ServiceLoader.load(PojoServiceRegistryFactory.class);
+        return loader.iterator().next().newPojoServiceRegistry(config);
+    }
+}