This is an automated email from the ASF dual-hosted git repository. rombert pushed a commit to annotated tag org.apache.sling.testing.sling-mock-oak-1.0.0 in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-testing-sling-mock-oak.git
commit 2d405ea10a51e3ec5fe850315a269d7ed628410b Author: Stefan Seifert <[email protected]> AuthorDate: Fri Oct 2 23:31:40 2015 +0000 SLING-5088 control SlingRepository resources via activate/deactivate methods; make sure all oak ExecutorServices are shutdown properly git-svn-id: https://svn.apache.org/repos/asf/sling/trunk/testing/mocks/sling-mock-oak@1706505 13f79535-47bb-0310-9956-ffa450edef68 --- .../testing/mock/sling/oak/ExtraSlingContent.java | 60 ++++++++++++++++++ .../sling/oak/OakMockResourceResolverAdapter.java | 48 +------------- ...oryWrapper.java => OakMockSlingRepository.java} | 74 +++++++++++++++++----- .../sling/testing/mock/sling/oak/package-info.java | 2 +- 4 files changed, 121 insertions(+), 63 deletions(-) diff --git a/src/main/java/org/apache/sling/testing/mock/sling/oak/ExtraSlingContent.java b/src/main/java/org/apache/sling/testing/mock/sling/oak/ExtraSlingContent.java new file mode 100644 index 0000000..8500ab6 --- /dev/null +++ b/src/main/java/org/apache/sling/testing/mock/sling/oak/ExtraSlingContent.java @@ -0,0 +1,60 @@ +/* + * 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.testing.mock.sling.oak; + +import static java.util.Collections.singleton; +import static org.apache.jackrabbit.oak.plugins.index.IndexConstants.INDEX_DEFINITIONS_NAME; +import static org.apache.jackrabbit.oak.plugins.index.IndexUtils.createIndexDefinition; + +import org.apache.jackrabbit.oak.spi.lifecycle.RepositoryInitializer; +import org.apache.jackrabbit.oak.spi.state.NodeBuilder; + +/** + * Adds some default indexes useful for by sling resource-jcr mapping. + * This is only a small subset of what is defined by default in the org.apache.sling.jcr.oak.server bundle. + */ +final class ExtraSlingContent implements RepositoryInitializer { + + @Override + public void initialize(NodeBuilder root) { + if (root.hasChildNode(INDEX_DEFINITIONS_NAME)) { + NodeBuilder index = root.child(INDEX_DEFINITIONS_NAME); + + // jcr: + property(index, "jcrLanguage", "jcr:language"); + property(index, "jcrLockOwner", "jcr:lockOwner"); + + // sling: + property(index, "slingAlias", "sling:alias"); + property(index, "slingResource", "sling:resource"); + property(index, "slingResourceType", "sling:resourceType"); + property(index, "slingVanityPath", "sling:vanityPath"); + } + } + + /** + * A convenience method to create a non-unique property index. + */ + private static void property(NodeBuilder index, String indexName, String propertyName) { + if (!index.hasChildNode(indexName)) { + createIndexDefinition(index, indexName, true, false, singleton(propertyName), null); + } + } + +} diff --git a/src/main/java/org/apache/sling/testing/mock/sling/oak/OakMockResourceResolverAdapter.java b/src/main/java/org/apache/sling/testing/mock/sling/oak/OakMockResourceResolverAdapter.java index 5b4cd73..cefb70b 100644 --- a/src/main/java/org/apache/sling/testing/mock/sling/oak/OakMockResourceResolverAdapter.java +++ b/src/main/java/org/apache/sling/testing/mock/sling/oak/OakMockResourceResolverAdapter.java @@ -18,15 +18,6 @@ */ package org.apache.sling.testing.mock.sling.oak; -import static java.util.Collections.singleton; -import static org.apache.jackrabbit.oak.plugins.index.IndexConstants.INDEX_DEFINITIONS_NAME; -import static org.apache.jackrabbit.oak.plugins.index.IndexUtils.createIndexDefinition; - -import javax.jcr.Repository; - -import org.apache.jackrabbit.oak.jcr.Jcr; -import org.apache.jackrabbit.oak.spi.lifecycle.RepositoryInitializer; -import org.apache.jackrabbit.oak.spi.state.NodeBuilder; import org.apache.sling.api.resource.ResourceResolverFactory; import org.apache.sling.jcr.api.SlingRepository; import org.apache.sling.testing.mock.sling.spi.ResourceResolverTypeAdapter; @@ -43,44 +34,7 @@ public class OakMockResourceResolverAdapter implements ResourceResolverTypeAdapt @Override public SlingRepository newSlingRepository() { - Repository repository = new Jcr() - .with(new ExtraSlingContent()) - .createRepository(); - return new RepositoryWrapper(repository); - } - - /** - * Adds some default indexes useful for by sling resource-jcr mapping. - * This is only a small subset of what is defined by default in the org.apache.sling.jcr.oak.server bundle. - */ - private static final class ExtraSlingContent implements RepositoryInitializer { - - @Override - public void initialize(NodeBuilder root) { - if (root.hasChildNode(INDEX_DEFINITIONS_NAME)) { - NodeBuilder index = root.child(INDEX_DEFINITIONS_NAME); - - // jcr: - property(index, "jcrLanguage", "jcr:language"); - property(index, "jcrLockOwner", "jcr:lockOwner"); - - // sling: - property(index, "slingAlias", "sling:alias"); - property(index, "slingResource", "sling:resource"); - property(index, "slingResourceType", "sling:resourceType"); - property(index, "slingVanityPath", "sling:vanityPath"); - } - } - - /** - * A convenience method to create a non-unique property index. - */ - private static void property(NodeBuilder index, String indexName, String propertyName) { - if (!index.hasChildNode(indexName)) { - createIndexDefinition(index, indexName, true, false, singleton(propertyName), null); - } - } - + return new OakMockSlingRepository(); } } diff --git a/src/main/java/org/apache/sling/testing/mock/sling/oak/RepositoryWrapper.java b/src/main/java/org/apache/sling/testing/mock/sling/oak/OakMockSlingRepository.java similarity index 52% rename from src/main/java/org/apache/sling/testing/mock/sling/oak/RepositoryWrapper.java rename to src/main/java/org/apache/sling/testing/mock/sling/oak/OakMockSlingRepository.java index 6c0d9d1..fdcecb1 100644 --- a/src/main/java/org/apache/sling/testing/mock/sling/oak/RepositoryWrapper.java +++ b/src/main/java/org/apache/sling/testing/mock/sling/oak/OakMockSlingRepository.java @@ -18,6 +18,9 @@ */ package org.apache.sling.testing.mock.sling.oak; +import java.lang.reflect.Field; +import java.util.concurrent.ExecutorService; + import javax.jcr.Credentials; import javax.jcr.LoginException; import javax.jcr.NoSuchWorkspaceException; @@ -27,25 +30,66 @@ import javax.jcr.Session; import javax.jcr.SimpleCredentials; import javax.jcr.Value; +import org.apache.felix.scr.annotations.Activate; +import org.apache.felix.scr.annotations.Component; +import org.apache.felix.scr.annotations.Deactivate; +import org.apache.felix.scr.annotations.Service; +import org.apache.jackrabbit.api.JackrabbitRepository; +import org.apache.jackrabbit.oak.Oak; +import org.apache.jackrabbit.oak.jcr.Jcr; import org.apache.sling.jcr.api.SlingRepository; +import org.osgi.service.component.ComponentContext; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; -public final class RepositoryWrapper implements SlingRepository { +@Component +@Service(SlingRepository.class) +public final class OakMockSlingRepository implements SlingRepository { private static final String ADMIN_NAME = "admin"; private static final String ADMIN_PASSWORD = "admin"; - protected final Repository wrapped; + private Oak oak; + private Repository repository; + + private static final Logger log = LoggerFactory.getLogger(OakMockSlingRepository.class); + + @Activate + protected void activate(ComponentContext componentContext) { + this.oak = new Oak(); + Jcr jcr = new Jcr(oak).with(new ExtraSlingContent()); + this.repository = jcr.createRepository(); + } - public RepositoryWrapper(Repository r) { - wrapped = r; + @Deactivate + protected void deactivate(ComponentContext componentContext) { + // shutdown OAK JCR repository + ((JackrabbitRepository)repository).shutdown(); + + // shutdown further OAK executor services via reflection + shutdownExecutorService("executor"); + shutdownExecutorService("scheduledExecutor"); } + + private void shutdownExecutorService(String fieldName) { + try { + Field executorField = Oak.class.getDeclaredField(fieldName); + executorField.setAccessible(true); + ExecutorService executor = (ExecutorService)executorField.get(this.oak); + executor.shutdownNow(); + } + catch (ReflectiveOperationException ex) { + log.error("Memory leak: Unable to shutdown executor service from field '" + fieldName + "' in " + this.oak, ex); + } + } + public String getDescriptor(String key) { - return wrapped.getDescriptor(key); + return repository.getDescriptor(key); } public String[] getDescriptorKeys() { - return wrapped.getDescriptorKeys(); + return repository.getDescriptorKeys(); } public String getDefaultWorkspace() { @@ -53,22 +97,22 @@ public final class RepositoryWrapper implements SlingRepository { } public Session login() throws LoginException, RepositoryException { - return wrapped.login(); + return repository.login(); } public Session login(Credentials credentials, String workspaceName) throws LoginException, NoSuchWorkspaceException, RepositoryException { - return wrapped.login(credentials, (workspaceName == null ? getDefaultWorkspace() : workspaceName)); + return repository.login(credentials, (workspaceName == null ? getDefaultWorkspace() : workspaceName)); } public Session login(Credentials credentials) throws LoginException, RepositoryException { - return wrapped.login(credentials); + return repository.login(credentials); } public Session login(String workspaceName) throws LoginException, NoSuchWorkspaceException, RepositoryException { - return wrapped.login((workspaceName == null ? getDefaultWorkspace() : workspaceName)); + return repository.login((workspaceName == null ? getDefaultWorkspace() : workspaceName)); } public Session loginAdministrative(String workspaceName) @@ -84,19 +128,19 @@ public final class RepositoryWrapper implements SlingRepository { } public Value getDescriptorValue(String key) { - return wrapped.getDescriptorValue(key); + return repository.getDescriptorValue(key); } public Value[] getDescriptorValues(String key) { - return wrapped.getDescriptorValues(key); + return repository.getDescriptorValues(key); } public boolean isSingleValueDescriptor(String key) { - return wrapped.isSingleValueDescriptor(key); + return repository.isSingleValueDescriptor(key); } public boolean isStandardDescriptor(String key) { - return wrapped.isStandardDescriptor(key); + return repository.isStandardDescriptor(key); } -} \ No newline at end of file +} diff --git a/src/main/java/org/apache/sling/testing/mock/sling/oak/package-info.java b/src/main/java/org/apache/sling/testing/mock/sling/oak/package-info.java index 55bdc9d..b4e676f 100644 --- a/src/main/java/org/apache/sling/testing/mock/sling/oak/package-info.java +++ b/src/main/java/org/apache/sling/testing/mock/sling/oak/package-info.java @@ -19,5 +19,5 @@ /** * Sling Mock Jackrabbit Oak-based Resource Resolver */ [email protected]("0.1") [email protected]("1.0") package org.apache.sling.testing.mock.sling.oak; -- To stop receiving notification emails like this one, please contact "[email protected]" <[email protected]>.
