Author: chetanm
Date: Fri May  5 10:55:45 2017
New Revision: 1794012

URL: http://svn.apache.org/viewvc?rev=1794012&view=rev
Log:
OAK-6176 - Service to provide access to async indexer state

Added:
    
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/AsyncIndexInfo.java
   (with props)
    
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/AsyncIndexInfoService.java
   (with props)
    
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/AsyncIndexInfoServiceImpl.java
   (with props)
    
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/index/AsyncIndexInfoServiceImplTest.java
   (with props)

Added: 
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/AsyncIndexInfo.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/AsyncIndexInfo.java?rev=1794012&view=auto
==============================================================================
--- 
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/AsyncIndexInfo.java
 (added)
+++ 
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/AsyncIndexInfo.java
 Fri May  5 10:55:45 2017
@@ -0,0 +1,88 @@
+/*
+ * 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.plugins.index;
+
+import javax.annotation.CheckForNull;
+import javax.annotation.Nullable;
+
+import org.apache.jackrabbit.oak.api.jmx.IndexStatsMBean;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+public class AsyncIndexInfo {
+    private final String name;
+    private final long lastIndexedTo;
+    private final long leaseExpiryTime;
+    private final boolean running;
+    private final IndexStatsMBean statsMBean;
+
+    public AsyncIndexInfo(String name, long lastIndexedTo, long 
leaseExpiryTime, boolean running, @Nullable IndexStatsMBean statsMBean) {
+        this.name = checkNotNull(name);
+        this.lastIndexedTo = lastIndexedTo;
+        this.leaseExpiryTime = leaseExpiryTime;
+        this.running = running;
+        this.statsMBean = statsMBean;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    /**
+     * Time in millis upto which the repository state is indexed via
+     * this indexer
+     */
+    public long getLastIndexedTo() {
+        return lastIndexedTo;
+    }
+
+    /**
+     * Time in millis at which the current help lease would expire if
+     * indexing is in progress. If indexing is not in progress then its
+     * value would be -1
+     */
+    public long getLeaseExpiryTime() {
+        return leaseExpiryTime;
+    }
+
+    /**
+     * Returns true if the async indexer is currently active
+     */
+    public boolean isRunning() {
+        return running;
+    }
+
+    /**
+     * IndexStatsMBean for current indexer. The MBean would be
+     * returning valid values only for that cluster node where
+     * the async indexer is active. For other cluster nodes
+     * the values may not reflect the current state
+     */
+    @CheckForNull
+    public IndexStatsMBean getStatsMBean() {
+        return statsMBean;
+    }
+
+    @Override
+    public String toString() {
+        return String.format("%s : lastIndexedTo :%tc, leaseExpiryTime :%tc, 
running :%s",
+                name, lastIndexedTo, leaseExpiryTime, running);
+    }
+}

Propchange: 
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/AsyncIndexInfo.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: 
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/AsyncIndexInfoService.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/AsyncIndexInfoService.java?rev=1794012&view=auto
==============================================================================
--- 
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/AsyncIndexInfoService.java
 (added)
+++ 
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/AsyncIndexInfoService.java
 Fri May  5 10:55:45 2017
@@ -0,0 +1,55 @@
+/*
+ * 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.plugins.index;
+
+import javax.annotation.CheckForNull;
+
+import org.apache.jackrabbit.oak.spi.state.NodeState;
+
+public interface AsyncIndexInfoService {
+
+    /**
+     * Returns all the async indexing lanes which are active
+     * in the setup.
+     */
+    Iterable<String> getAsyncLanes();
+
+    /**
+     * Returns all the async indexing lanes which are active
+     * in the setup based on given root NodeState
+     *
+     * @param root root NodeState from which async index state
+     *             is read
+     */
+    Iterable<String> getAsyncLanes(NodeState root);
+
+    /**
+     * Returns the info for async indexer with given name
+     */
+    @CheckForNull
+    AsyncIndexInfo getInfo(String name);
+
+    /**
+     * Returns the info for async indexer with given name
+     * and based on given root NodeState
+     */
+    @CheckForNull
+    AsyncIndexInfo getInfo(String name, NodeState root);
+}

Propchange: 
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/AsyncIndexInfoService.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: 
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/AsyncIndexInfoServiceImpl.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/AsyncIndexInfoServiceImpl.java?rev=1794012&view=auto
==============================================================================
--- 
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/AsyncIndexInfoServiceImpl.java
 (added)
+++ 
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/AsyncIndexInfoServiceImpl.java
 Fri May  5 10:55:45 2017
@@ -0,0 +1,123 @@
+/*
+ * 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.plugins.index;
+
+import java.util.Calendar;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
+
+import org.apache.felix.scr.annotations.Component;
+import org.apache.felix.scr.annotations.Reference;
+import org.apache.felix.scr.annotations.ReferenceCardinality;
+import org.apache.felix.scr.annotations.ReferencePolicy;
+import org.apache.felix.scr.annotations.ReferencePolicyOption;
+import org.apache.felix.scr.annotations.Service;
+import org.apache.jackrabbit.oak.api.PropertyState;
+import org.apache.jackrabbit.oak.api.Type;
+import org.apache.jackrabbit.oak.api.jmx.IndexStatsMBean;
+import org.apache.jackrabbit.oak.spi.state.NodeState;
+import org.apache.jackrabbit.oak.spi.state.NodeStore;
+import org.apache.jackrabbit.util.ISO8601;
+
+@Component
+@Service
+public class AsyncIndexInfoServiceImpl implements AsyncIndexInfoService {
+
+    @Reference(policy = ReferencePolicy.DYNAMIC,
+            cardinality = ReferenceCardinality.OPTIONAL_MULTIPLE,
+            policyOption = ReferencePolicyOption.GREEDY,
+            referenceInterface = IndexStatsMBean.class
+    )
+    private final Map<String, IndexStatsMBean> statsMBeans = new 
ConcurrentHashMap<>();
+
+    @Reference
+    private NodeStore nodeStore;
+
+    public AsyncIndexInfoServiceImpl() {
+
+    }
+
+    public AsyncIndexInfoServiceImpl(NodeStore nodeStore) {
+        this.nodeStore = nodeStore;
+    }
+
+    @Override
+    public Iterable<String> getAsyncLanes() {
+        return getAsyncLanes(nodeStore.getRoot());
+    }
+
+    @Override
+    public Iterable<String> getAsyncLanes(NodeState root) {
+        NodeState async = getAsyncState(root);
+        Set<String> names = new HashSet<>();
+        for (PropertyState ps : async.getProperties()) {
+            String name = ps.getName();
+            if (AsyncIndexUpdate.isAsyncLaneName(name)) {
+                names.add(name);
+            }
+        }
+        return names;
+    }
+
+    @Override
+    public AsyncIndexInfo getInfo(String name) {
+        return getInfo(name, nodeStore.getRoot());
+    }
+
+    @Override
+    public AsyncIndexInfo getInfo(String name, NodeState root) {
+        NodeState async = getAsyncState(root);
+        if (async.hasProperty(name)) {
+            long lastIndexedTo = 
getDateAsMillis(async.getProperty(AsyncIndexUpdate.lastIndexedTo(name)));
+            long leaseEnd = -1;
+            boolean running = false;
+            if (async.hasProperty(AsyncIndexUpdate.leasify(name))) {
+                running = true;
+                leaseEnd = async.getLong(AsyncIndexUpdate.leasify(name));
+            }
+            IndexStatsMBean mbean = statsMBeans.get(name);
+            return new AsyncIndexInfo(name, lastIndexedTo, leaseEnd, running, 
mbean);
+        }
+        return null;
+    }
+
+    private NodeState getAsyncState(NodeState root) {
+        return root.getChildNode(AsyncIndexUpdate.ASYNC);
+    }
+
+    protected void bindStatsMBeans(IndexStatsMBean mBean) {
+        statsMBeans.put(mBean.getName(), mBean);
+    }
+
+    protected void unbindStatsMBeans(IndexStatsMBean mBean) {
+        statsMBeans.remove(mBean.getName());
+    }
+
+    private static long getDateAsMillis(PropertyState ps) {
+        if (ps == null) {
+            return -1;
+        }
+        String date = ps.getValue(Type.DATE);
+        Calendar cal = ISO8601.parse(date);
+        return cal.getTimeInMillis();
+    }
+}

Propchange: 
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/AsyncIndexInfoServiceImpl.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: 
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/index/AsyncIndexInfoServiceImplTest.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/index/AsyncIndexInfoServiceImplTest.java?rev=1794012&view=auto
==============================================================================
--- 
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/index/AsyncIndexInfoServiceImplTest.java
 (added)
+++ 
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/index/AsyncIndexInfoServiceImplTest.java
 Fri May  5 10:55:45 2017
@@ -0,0 +1,79 @@
+/*
+ * 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.plugins.index;
+
+import java.util.Set;
+
+import com.google.common.collect.ImmutableSet;
+import 
org.apache.jackrabbit.oak.plugins.index.property.PropertyIndexEditorProvider;
+import org.apache.jackrabbit.oak.plugins.memory.MemoryNodeStore;
+import org.junit.Test;
+
+import static org.hamcrest.Matchers.containsInAnyOrder;
+import static org.junit.Assert.*;
+
+public class AsyncIndexInfoServiceImplTest {
+
+    private MemoryNodeStore store = new MemoryNodeStore();
+    private PropertyIndexEditorProvider provider = new 
PropertyIndexEditorProvider();
+
+    private AsyncIndexInfoServiceImpl service = new 
AsyncIndexInfoServiceImpl(store);
+
+    @Test
+    public void names() throws Exception{
+        AsyncIndexUpdate async = new AsyncIndexUpdate("async", store, 
provider);
+        async.run();
+
+        AsyncIndexUpdate async2 = new AsyncIndexUpdate("foo-async", store, 
provider);
+        async2.run();
+
+        Set<String> names = ImmutableSet.copyOf(service.getAsyncLanes());
+        assertThat(names, containsInAnyOrder("async", "foo-async"));
+
+        service.bindStatsMBeans(async.getIndexStats());
+        service.bindStatsMBeans(async2.getIndexStats());
+    }
+
+    @Test
+    public void info() throws Exception{
+        AsyncIndexUpdate async = new AsyncIndexUpdate("foo-async", store, 
provider);
+        async.run();
+
+        Set<String> names = ImmutableSet.copyOf(service.getAsyncLanes());
+        assertThat(names, containsInAnyOrder("foo-async"));
+
+        service.bindStatsMBeans(async.getIndexStats());
+
+        AsyncIndexInfo info = service.getInfo("foo-async");
+        assertNotNull(info);
+        assertEquals("foo-async", info.getName());
+        assertNotNull(info.getStatsMBean());
+        assertTrue(info.getLastIndexedTo() > -1);
+        assertFalse(info.isRunning());
+        assertEquals(-1, info.getLeaseExpiryTime());
+        System.out.println(info);
+
+        service.unbindStatsMBeans(async.getIndexStats());
+
+        AsyncIndexInfo info2 = service.getInfo("foo-async");
+        assertNull(info2.getStatsMBean());
+    }
+
+}
\ No newline at end of file

Propchange: 
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/index/AsyncIndexInfoServiceImplTest.java
------------------------------------------------------------------------------
    svn:eol-style = native


Reply via email to