This is an automated email from the ASF dual-hosted git repository.
jsedding pushed a commit to branch master
in repository
https://gitbox.apache.org/repos/asf/sling-org-apache-sling-resourceresolver.git
The following commit(s) were added to refs/heads/master by this push:
new 9d02522 SLING-12019 - Avoid duplicate ResourceResolverFactory
registrations (#100)
9d02522 is described below
commit 9d02522963d0709ba31063337ea0d684ebdc84d5
Author: Julian Sedding <[email protected]>
AuthorDate: Wed Sep 13 15:56:34 2023 +0200
SLING-12019 - Avoid duplicate ResourceResolverFactory registrations (#100)
- extract factory registration/deregistration code into
FactoryRegistrationHandler
- add unit test for FactoryRegistrationHandler
- fix unclosed RR and other exceptions in other tests
---
.../impl/FactoryPreconditions.java | 194 +++++++-----
.../impl/FactoryRegistrationHandler.java | 176 +++++++++++
.../impl/ResourceResolverFactoryActivator.java | 219 ++------------
.../stateful/AuthenticatedResourceProvider.java | 9 +-
.../impl/EtcMappingResourceResolverTest.java | 6 +
.../impl/FactoryPreconditionsTest.java | 30 +-
.../impl/FactoryRegistrationHandlerTest.java | 181 +++++++++++
.../impl/MockedResourceResolverImplTest.java | 331 +++++++++++----------
.../mapping/AbstractMappingMapEntriesTest.java | 6 +-
.../impl/mapping/InMemoryResourceProvider.java | 2 +-
.../impl/mapping/ResourceMapperImplTest.java | 14 +-
11 files changed, 705 insertions(+), 463 deletions(-)
diff --git
a/src/main/java/org/apache/sling/resourceresolver/impl/FactoryPreconditions.java
b/src/main/java/org/apache/sling/resourceresolver/impl/FactoryPreconditions.java
index 4473142..702600a 100644
---
a/src/main/java/org/apache/sling/resourceresolver/impl/FactoryPreconditions.java
+++
b/src/main/java/org/apache/sling/resourceresolver/impl/FactoryPreconditions.java
@@ -19,6 +19,8 @@
package org.apache.sling.resourceresolver.impl;
import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashSet;
import java.util.List;
import java.util.Set;
@@ -26,9 +28,10 @@ import
org.apache.sling.resourceresolver.impl.legacy.LegacyResourceProviderWhite
import
org.apache.sling.resourceresolver.impl.providers.ResourceProviderHandler;
import org.apache.sling.resourceresolver.impl.providers.ResourceProviderInfo;
import
org.apache.sling.resourceresolver.impl.providers.ResourceProviderTracker;
-import org.osgi.framework.BundleContext;
+import org.jetbrains.annotations.NotNull;
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;
import org.slf4j.Logger;
@@ -40,107 +43,134 @@ import org.slf4j.LoggerFactory;
*/
public class FactoryPreconditions {
+ private static final Logger LOG =
LoggerFactory.getLogger(FactoryPreconditions.class);
+
private static final class RequiredProvider {
public String name;
public String pid;
public Filter filter;
};
- private volatile ResourceProviderTracker tracker;
+ private final ResourceProviderTracker tracker;
- private volatile List<RequiredProvider> requiredProviders;
+ private final List<RequiredProvider> requiredProviders;
- public void activate(final BundleContext bc,
- final Set<String> legycyConfiguration,
- final Set<String> namesConfiguration,
- final ResourceProviderTracker tracker) {
- synchronized ( this ) {
- this.tracker = tracker;
+ public FactoryPreconditions(
+ final ResourceProviderTracker tracker,
+ final Set<String> requiredResourceProviderNames,
+ final Set<String> requiredResourceProvidersLegacy) {
+ this.tracker = tracker;
+ this.requiredProviders =
initRequiredProviders(requiredResourceProviderNames,
requiredResourceProvidersLegacy);
+ }
- final List<RequiredProvider> rps = new ArrayList<>();
- if ( legycyConfiguration != null ) {
- final Logger logger = LoggerFactory.getLogger(getClass());
- for(final String value : legycyConfiguration) {
- RequiredProvider rp = new RequiredProvider();
- if ( value.startsWith("(") ) {
- try {
- rp.filter = bc.createFilter(value);
- } catch (final InvalidSyntaxException e) {
- logger.warn("Ignoring invalid filter syntax for
required provider: " + value, e);
- rp = null;
- }
- } else {
- rp.pid = value;
- }
- if ( rp != null ) {
- rps.add(rp);
+ @NotNull
+ private List<RequiredProvider> initRequiredProviders(
+ Set<String> requiredResourceProviderNames, Set<String>
requiredResourceProvidersLegacy) {
+
+ boolean hasLegacyRequiredProvider = false;
+ if ( requiredResourceProvidersLegacy != null ) {
+ hasLegacyRequiredProvider =
requiredResourceProvidersLegacy.remove(ResourceResolverFactoryConfig.LEGACY_REQUIRED_PROVIDER_PID);
+ if ( !requiredResourceProvidersLegacy.isEmpty() ) {
+ LOG.error("ResourceResolverFactory is using deprecated
required providers configuration " +
+ "(resource.resolver.required.providers). Please change
to use the property " +
+ "resource.resolver.required.providernames for values:
{}", requiredResourceProvidersLegacy);
+ } else {
+ requiredResourceProvidersLegacy = null;
+ }
+ }
+
+ if ( hasLegacyRequiredProvider ) {
+ if (requiredResourceProviderNames == null) {
+ requiredResourceProviderNames = new HashSet<>();
+ }
+
+ // add default if not already present
+ final boolean hasRequiredProvider =
!requiredResourceProviderNames.add(ResourceResolverFactoryConfig.REQUIRED_PROVIDER_NAME);
+ if ( hasRequiredProvider ) {
+ LOG.warn("ResourceResolverFactory is using deprecated required
providers configuration " +
+ "(resource.resolver.required.providers) with value
'{}'. Please remove this configuration " +
+ "property. '{}' is already contained in the property
resource.resolver.required.providernames.",
+
ResourceResolverFactoryConfig.LEGACY_REQUIRED_PROVIDER_PID,
+ ResourceResolverFactoryConfig.REQUIRED_PROVIDER_NAME);
+ } else {
+ LOG.warn("ResourceResolverFactory is using deprecated required
providers configuration " +
+ "(resource.resolver.required.providers) with value
'{}'. Please remove this configuration " +
+ "property and add '{}' to the property
resource.resolver.required.providernames.",
+
ResourceResolverFactoryConfig.LEGACY_REQUIRED_PROVIDER_PID,
+ ResourceResolverFactoryConfig.REQUIRED_PROVIDER_NAME);
+ }
+ }
+
+ final List<RequiredProvider> rps = new ArrayList<>();
+ if (requiredResourceProvidersLegacy != null) {
+ final Logger logger = LoggerFactory.getLogger(getClass());
+ for (final String value : requiredResourceProvidersLegacy) {
+ RequiredProvider rp = new RequiredProvider();
+
+ if (value.startsWith("(")) {
+ try {
+ rp.filter = FrameworkUtil.createFilter(value);
+ } catch (final InvalidSyntaxException e) {
+ logger.warn("Ignoring invalid filter syntax for
required provider: " + value, e);
+ rp = null;
}
+ } else {
+ rp.pid = value;
}
- }
- if ( namesConfiguration != null ) {
- for(final String value : namesConfiguration) {
- final RequiredProvider rp = new RequiredProvider();
- rp.name = value;
- rps.add(rp);
+ if (rp != null) {
+ rps.add(rp);
}
}
- this.requiredProviders = rps;
}
- }
-
- public void deactivate() {
- synchronized ( this ) {
- this.requiredProviders = null;
- this.tracker = null;
+ if (requiredResourceProviderNames != null) {
+ for (final String value : requiredResourceProviderNames) {
+ final RequiredProvider rp = new RequiredProvider();
+ rp.name = value;
+ rps.add(rp);
+ }
}
+ return rps;
}
public boolean checkPreconditions(final String unavailableName, final
String unavailableServicePid) {
- synchronized ( this ) {
- final List<RequiredProvider> localRequiredProviders =
this.requiredProviders;
- final ResourceProviderTracker localTracker = this.tracker;
- boolean canRegister = localTracker != null;
- if (localRequiredProviders != null && localTracker != null ) {
- for (final RequiredProvider rp : localRequiredProviders) {
- canRegister = false;
- for (final ResourceProviderHandler h :
localTracker.getResourceProviderStorage().getAllHandlers()) {
- final ResourceProviderInfo info = h.getInfo();
- if ( info == null ) {
- // provider has been deactivated in the meantime
- // ignore and continue
- continue;
- }
- @SuppressWarnings("rawtypes")
- final ServiceReference ref =
info.getServiceReference();
- final Object servicePid =
ref.getProperty(Constants.SERVICE_PID);
- if ( unavailableServicePid != null &&
unavailableServicePid.equals(servicePid) ) {
- // ignore this service
- continue;
- }
- if ( unavailableName != null &&
unavailableName.equals(info.getName()) ) {
- // ignore this service
- continue;
- }
- if ( rp.name != null && rp.name.equals(info.getName())
) {
- canRegister = true;
- break;
- } else if (rp.filter != null && rp.filter.match(ref)) {
- canRegister = true;
- break;
- } else if (rp.pid != null &&
rp.pid.equals(servicePid)){
- canRegister = true;
- break;
- } else if (rp.pid != null &&
rp.pid.equals(ref.getProperty(LegacyResourceProviderWhiteboard.ORIGINAL_SERVICE_PID)))
{
- canRegister = true;
- break;
- }
- }
- if ( !canRegister ) {
- break;
- }
+ boolean canRegister = true;
+ for (final RequiredProvider rp : requiredProviders) {
+ canRegister = false;
+ for (final ResourceProviderHandler h :
tracker.getResourceProviderStorage().getAllHandlers()) {
+ final ResourceProviderInfo info = h.getInfo();
+ if (info == null) {
+ // provider has been deactivated in the meantime
+ // ignore and continue
+ continue;
+ }
+ @SuppressWarnings("rawtypes") final ServiceReference ref =
info.getServiceReference();
+ final Object servicePid =
ref.getProperty(Constants.SERVICE_PID);
+ if (unavailableServicePid != null &&
unavailableServicePid.equals(servicePid)) {
+ // ignore this service
+ continue;
+ }
+ if (unavailableName != null &&
unavailableName.equals(info.getName())) {
+ // ignore this service
+ continue;
}
+ if (rp.name != null && rp.name.equals(info.getName())) {
+ canRegister = true;
+ break;
+ } else if (rp.filter != null && rp.filter.match(ref)) {
+ canRegister = true;
+ break;
+ } else if (rp.pid != null && rp.pid.equals(servicePid)) {
+ canRegister = true;
+ break;
+ } else if (rp.pid != null &&
rp.pid.equals(ref.getProperty(LegacyResourceProviderWhiteboard.ORIGINAL_SERVICE_PID)))
{
+ canRegister = true;
+ break;
+ }
+ }
+ if (!canRegister) {
+ break;
}
- return canRegister;
}
+ return canRegister;
}
}
diff --git
a/src/main/java/org/apache/sling/resourceresolver/impl/FactoryRegistrationHandler.java
b/src/main/java/org/apache/sling/resourceresolver/impl/FactoryRegistrationHandler.java
new file mode 100644
index 0000000..94d8002
--- /dev/null
+++
b/src/main/java/org/apache/sling/resourceresolver/impl/FactoryRegistrationHandler.java
@@ -0,0 +1,176 @@
+/*
+ * 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.resourceresolver.impl;
+
+import org.apache.sling.api.resource.ResourceResolverFactory;
+import org.apache.sling.api.resource.runtime.RuntimeService;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.Constants;
+import org.osgi.framework.ServiceFactory;
+import org.osgi.framework.ServiceRegistration;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.Dictionary;
+import java.util.Hashtable;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.TimeUnit;
+
+public class FactoryRegistrationHandler implements AutoCloseable {
+
+ private static final Logger LOG =
LoggerFactory.getLogger(FactoryRegistrationHandler.class);
+
+ private final ResourceResolverFactoryActivator activator;
+
+ private final FactoryPreconditions factoryPreconditions;
+
+ private final ExecutorService factoryRegistrationWorker;
+
+ @SuppressWarnings("java:S3077") // The field is only ever set to null or
to a new FactoryRegistration instance, which is safe.
+ private volatile FactoryRegistration factoryRegistration;
+
+ public FactoryRegistrationHandler(
+ ResourceResolverFactoryActivator activator, FactoryPreconditions
factoryPreconditions) {
+ this.factoryPreconditions = factoryPreconditions;
+ this.activator = activator;
+ this.factoryRegistrationWorker = Executors.newSingleThreadExecutor(
+ r -> new Thread(r,
ResourceResolverFactory.class.getSimpleName() + "
registration/deregistration"));
+ }
+
+ @Override
+ public void close() {
+ unregisterFactory();
+ factoryRegistrationWorker.shutdown();
+ try {
+ if (!factoryRegistrationWorker.awaitTermination(5,
TimeUnit.SECONDS)) {
+ factoryRegistrationWorker.shutdownNow();
+ // make sure everything is unregistered, even if
+ // the factoryRegistrationWorker did not complete
+ doUnregisterFactory();
+ }
+ } catch (InterruptedException e) {
+ Thread.currentThread().interrupt();
+ }
+ }
+
+ /**
+ * Check the preconditions and if it changed, either register factory or
unregister
+ */
+ void maybeRegisterFactory(final String unavailableName, final String
unavailableServicePid) {
+ if (!factoryRegistrationWorker.isShutdown()) {
+ LOG.debug("submitting maybeRegisterFactory");
+ factoryRegistrationWorker.submit(() -> {
+ final boolean preconditionsOk =
factoryPreconditions.checkPreconditions(unavailableName, unavailableServicePid);
+ if ( preconditionsOk && this.factoryRegistration == null ) {
+ // check system bundle state - if stopping, don't register
new factory
+ final Bundle systemBundle =
activator.getBundleContext().getBundle(Constants.SYSTEM_BUNDLE_LOCATION);
+ if ( systemBundle != null && systemBundle.getState() !=
Bundle.STOPPING ) {
+ runWithThreadName("registration",
this::doRegisterFactory);
+ }
+ } else if ( !preconditionsOk && this.factoryRegistration !=
null ) {
+ LOG.debug("performing unregisterFactory via
maybeRegisterFactory");
+ runWithThreadName("deregistration",
this::doUnregisterFactory);
+ }
+ });
+ }
+ }
+
+ void unregisterFactory() {
+ LOG.debug("submitting unregisterFactory");
+ factoryRegistrationWorker.submit(() ->
runWithThreadName("deregistration",
+ this::doUnregisterFactory));
+ }
+
+ /**
+ * Register the factory.
+ */
+ private void doRegisterFactory() {
+ LOG.debug("performing registerFactory, factoryRegistration == {}",
factoryRegistration);
+ if (this.factoryRegistration == null) {
+ this.factoryRegistration = new
FactoryRegistration(activator.getBundleContext(), activator);
+ }
+ LOG.debug("finished performing registerFactory, factoryRegistration ==
{}", factoryRegistration);
+ }
+
+ /**
+ * Unregister the factory (if registered).
+ */
+ private void doUnregisterFactory() {
+ LOG.debug("performing unregisterFactory, factoryRegistration == {}",
factoryRegistration);
+ if (this.factoryRegistration != null) {
+ this.factoryRegistration.unregister();
+ this.factoryRegistration = null;
+ }
+ LOG.debug("finished performing unregisterFactory, factoryRegistration
== {}", factoryRegistration);
+ }
+
+ private static void runWithThreadName(String threadNameSuffix, Runnable
task) {
+ final String name = Thread.currentThread().getName();
+ try {
+
Thread.currentThread().setName(ResourceResolverFactory.class.getSimpleName() +
" " + threadNameSuffix);
+ task.run();
+ } finally {
+ Thread.currentThread().setName(name);
+ }
+ }
+
+ private final class FactoryRegistration {
+ /** Registration .*/
+ private final ServiceRegistration<ResourceResolverFactory>
factoryRegistration;
+
+ /** Runtime registration. */
+ private final ServiceRegistration<RuntimeService> runtimeRegistration;
+
+ private final CommonResourceResolverFactoryImpl commonFactory;
+
+ FactoryRegistration(BundleContext context,
ResourceResolverFactoryActivator activator) {
+ commonFactory = new CommonResourceResolverFactoryImpl(activator);
+ commonFactory.activate(context);
+
+ // activate and register factory
+ final Dictionary<String, Object> serviceProps = new Hashtable<>();
+ serviceProps.put(Constants.SERVICE_VENDOR, "The Apache Software
Foundation");
+ serviceProps.put(Constants.SERVICE_DESCRIPTION, "Apache Sling
Resource Resolver Factory");
+ factoryRegistration =
context.registerService(ResourceResolverFactory.class, new ServiceFactory<>() {
+ @Override
+ public ResourceResolverFactory getService(final Bundle bundle,
final ServiceRegistration<ResourceResolverFactory> registration) {
+ if
(FactoryRegistrationHandler.this.factoryRegistrationWorker.isShutdown()) {
+ return null;
+ }
+ return new ResourceResolverFactoryImpl(commonFactory,
bundle, activator.getServiceUserMapper());
+ }
+
+ @Override
+ public void ungetService(final Bundle bundle, final
ServiceRegistration<ResourceResolverFactory> registration, final
ResourceResolverFactory service) {
+ // nothing to do
+ }
+ }, serviceProps);
+
+ runtimeRegistration =
context.registerService(RuntimeService.class, activator.getRuntimeService(),
null);
+ }
+
+ void unregister() {
+ runtimeRegistration.unregister();
+ factoryRegistration.unregister();
+ commonFactory.deactivate();
+ }
+ }
+}
diff --git
a/src/main/java/org/apache/sling/resourceresolver/impl/ResourceResolverFactoryActivator.java
b/src/main/java/org/apache/sling/resourceresolver/impl/ResourceResolverFactoryActivator.java
index 1f14e3c..1651e06 100644
---
a/src/main/java/org/apache/sling/resourceresolver/impl/ResourceResolverFactoryActivator.java
+++
b/src/main/java/org/apache/sling/resourceresolver/impl/ResourceResolverFactoryActivator.java
@@ -23,9 +23,7 @@ import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.ArrayList;
import java.util.Collections;
-import java.util.Dictionary;
import java.util.HashSet;
-import java.util.Hashtable;
import java.util.List;
import java.util.Map;
import java.util.Optional;
@@ -36,10 +34,10 @@ import org.apache.commons.collections4.BidiMap;
import org.apache.commons.collections4.bidimap.TreeBidiMap;
import org.apache.commons.lang3.StringUtils;
import org.apache.sling.api.resource.ResourceDecorator;
-import org.apache.sling.api.resource.ResourceResolverFactory;
import org.apache.sling.api.resource.path.Path;
import org.apache.sling.api.resource.runtime.RuntimeService;
import org.apache.sling.resourceresolver.impl.helper.ResourceDecoratorTracker;
+import org.apache.sling.resourceresolver.impl.mapping.MapEntries;
import org.apache.sling.resourceresolver.impl.mapping.Mapping;
import
org.apache.sling.resourceresolver.impl.mapping.StringInterpolationProvider;
import
org.apache.sling.resourceresolver.impl.observation.ResourceChangeListenerWhiteboard;
@@ -47,11 +45,7 @@ import
org.apache.sling.resourceresolver.impl.providers.ResourceProviderTracker;
import
org.apache.sling.resourceresolver.impl.providers.ResourceProviderTracker.ChangeListener;
import org.apache.sling.resourceresolver.impl.providers.RuntimeServiceImpl;
import org.apache.sling.serviceusermapping.ServiceUserMapper;
-import org.osgi.framework.Bundle;
import org.osgi.framework.BundleContext;
-import org.osgi.framework.Constants;
-import org.osgi.framework.ServiceFactory;
-import org.osgi.framework.ServiceRegistration;
import org.osgi.service.component.annotations.Activate;
import org.osgi.service.component.annotations.Component;
import org.osgi.service.component.annotations.Deactivate;
@@ -76,16 +70,6 @@ import org.slf4j.LoggerFactory;
@Component(name =
"org.apache.sling.jcr.resource.internal.JcrResourceResolverFactoryImpl")
public class ResourceResolverFactoryActivator {
- private static final class FactoryRegistration {
- /** Registration .*/
- public volatile ServiceRegistration<ResourceResolverFactory>
factoryRegistration;
-
- /** Runtime registration. */
- public volatile ServiceRegistration<RuntimeService>
runtimeRegistration;
-
- public volatile CommonResourceResolverFactoryImpl commonFactory;
- }
-
/** Logger. */
private final Logger logger = LoggerFactory.getLogger(this.getClass());
@@ -140,10 +124,8 @@ public class ResourceResolverFactoryActivator {
/** Observation paths */
private volatile Path[] observationPaths;
- private final FactoryPreconditions preconds = new FactoryPreconditions();
-
- /** Factory registration. */
- private volatile FactoryRegistration factoryRegistration;
+ @SuppressWarnings("java:S3077")
+ private volatile FactoryRegistrationHandler factoryRegistrationHandler;
private final VanityPathConfigurer vanityPathConfigurer = new
VanityPathConfigurer();
{
@@ -235,7 +217,7 @@ public class ResourceResolverFactoryActivator {
* Activates this component (called by SCR before)
*/
@Activate
- protected void activate(final BundleContext bundleContext,
+ protected void activate(final BundleContext bundleContext,
final ResourceResolverFactoryConfig config,
final VanityPathConfigurer.DeprecatedVanityConfig
deprecatedVanityConfig) {
this.vanityPathConfigurer.setConfiguration(config,
deprecatedVanityConfig);
@@ -315,85 +297,50 @@ public class ResourceResolverFactoryActivator {
}
}
+ // for testing: if we run unit test, both trackers are set from the
outside
+ final boolean hasPreRegisteredResourceProviderTracker =
this.resourceProviderTracker != null;
+ if (!hasPreRegisteredResourceProviderTracker) {
+ this.resourceProviderTracker = new ResourceProviderTracker();
+ this.changeListenerWhiteboard = new
ResourceChangeListenerWhiteboard();
+ this.changeListenerWhiteboard.activate(this.bundleContext,
this.resourceProviderTracker, searchPath);
+ }
+
// check for required property
Set<String> requiredResourceProvidersLegacy =
getStringSet(config.resource_resolver_required_providers());
Set<String> requiredResourceProviderNames =
getStringSet(config.resource_resolver_required_providernames());
- boolean hasLegacyRequiredProvider = false;
- if ( requiredResourceProvidersLegacy != null ) {
- hasLegacyRequiredProvider =
requiredResourceProvidersLegacy.remove(ResourceResolverFactoryConfig.LEGACY_REQUIRED_PROVIDER_PID);
- if ( !requiredResourceProvidersLegacy.isEmpty() ) {
- logger.error("ResourceResolverFactory is using deprecated
required providers configuration (resource.resolver.required.providers" +
- "). Please change to use the property
resource.resolver.required.providernames for values: " +
requiredResourceProvidersLegacy);
- } else {
- requiredResourceProvidersLegacy = null;
- }
- }
- if ( hasLegacyRequiredProvider ) {
- final boolean hasRequiredProvider;
- if ( requiredResourceProviderNames != null ) {
- hasRequiredProvider =
!requiredResourceProviderNames.add(ResourceResolverFactoryConfig.REQUIRED_PROVIDER_NAME);
- } else {
- hasRequiredProvider = false;
- requiredResourceProviderNames =
Collections.singleton(ResourceResolverFactoryConfig.REQUIRED_PROVIDER_NAME);
- }
- if ( hasRequiredProvider ) {
- logger.warn("ResourceResolverFactory is using deprecated
required providers configuration (resource.resolver.required.providers" +
- ") with value '" +
ResourceResolverFactoryConfig.LEGACY_REQUIRED_PROVIDER_PID + ". Please remove
this configuration property. " +
- ResourceResolverFactoryConfig.REQUIRED_PROVIDER_NAME +
" is already contained in the property
resource.resolver.required.providernames.");
- } else {
- logger.warn("ResourceResolverFactory is using deprecated
required providers configuration (resource.resolver.required.providers" +
- ") with value '" +
ResourceResolverFactoryConfig.LEGACY_REQUIRED_PROVIDER_PID + ". Please remove
this configuration property and add " +
- ResourceResolverFactoryConfig.REQUIRED_PROVIDER_NAME +
" to the property resource.resolver.required.providernames.");
- }
- }
+ final FactoryPreconditions factoryPreconditions = new
FactoryPreconditions(
+ resourceProviderTracker,
+ requiredResourceProviderNames,
+ requiredResourceProvidersLegacy);
+ factoryRegistrationHandler = new FactoryRegistrationHandler(this,
factoryPreconditions);
+ factoryRegistrationHandler.maybeRegisterFactory(null, null);
- // for testing: if we run unit test, both trackers are set from the
outside
- if ( this.resourceProviderTracker == null ) {
- this.resourceProviderTracker = new ResourceProviderTracker();
- this.changeListenerWhiteboard = new
ResourceChangeListenerWhiteboard();
- this.preconds.activate(this.bundleContext,
- requiredResourceProvidersLegacy,
- requiredResourceProviderNames,
- resourceProviderTracker);
- this.changeListenerWhiteboard.activate(this.bundleContext,
- this.resourceProviderTracker, searchPath);
- this.resourceProviderTracker.activate(this.bundleContext,
- this.eventAdmin,
+ if (!hasPreRegisteredResourceProviderTracker) {
+ this.resourceProviderTracker.activate(this.bundleContext,
this.eventAdmin,
new ChangeListener() {
@Override
public void providerAdded() {
- if ( factoryRegistration == null ) {
- checkFactoryPreconditions(null, null);
- }
-
+
factoryRegistrationHandler.maybeRegisterFactory(null, null);
}
@Override
public void providerRemoved(final String name, final
String pid, final boolean stateful, final boolean isUsed) {
- if ( factoryRegistration != null ) {
- if ( isUsed && (stateful ||
config.resource_resolver_providerhandling_paranoid()) ) {
- unregisterFactory();
- }
- checkFactoryPreconditions(name, pid);
+ if ( isUsed && (stateful ||
config.resource_resolver_providerhandling_paranoid()) ) {
+ factoryRegistrationHandler.unregisterFactory();
}
+
factoryRegistrationHandler.maybeRegisterFactory(name, pid);
}
});
- } else {
- this.preconds.activate(this.bundleContext,
- requiredResourceProvidersLegacy,
- requiredResourceProviderNames,
- resourceProviderTracker);
- this.checkFactoryPreconditions(null, null);
- }
+ }
}
/**
* Modifies this component (called by SCR to update this component)
*/
@Modified
- protected void modified(final BundleContext bundleContext,
+ protected void modified(final BundleContext bundleContext,
final ResourceResolverFactoryConfig config,
final VanityPathConfigurer.DeprecatedVanityConfig
deprecatedVanityConfig) {
this.deactivate();
@@ -405,8 +352,10 @@ public class ResourceResolverFactoryActivator {
*/
@Deactivate
protected void deactivate() {
- this.unregisterFactory();
+ this.factoryRegistrationHandler.close();
+ this.factoryRegistrationHandler = null;
+ // factoryRegistrationHandler must be closed before bundleContext is
set to null
this.bundleContext = null;
this.config = DEFAULT_CONFIG;
this.vanityPathConfigurer.setConfiguration(DEFAULT_CONFIG, null);
@@ -414,88 +363,7 @@ public class ResourceResolverFactoryActivator {
this.changeListenerWhiteboard = null;
this.resourceProviderTracker.deactivate();
this.resourceProviderTracker = null;
-
- this.preconds.deactivate();
this.resourceDecoratorTracker.close();
-
- // this is just a sanity call to make sure that unregister
- // in the case that a registration happened again
- // while deactivation
- this.unregisterFactory();
- }
-
- /**
- * Unregister the factory (if registered)
- * This method might be called concurrently from deactivate and the
- * background thread, therefore we need to synchronize.
- */
- private void unregisterFactory() {
- FactoryRegistration local = null;
- synchronized ( this ) {
- if ( this.factoryRegistration != null ) {
- local = this.factoryRegistration;
- this.factoryRegistration = null;
- }
- }
- this.unregisterFactory(local);
- }
-
- /**
- * Unregister the provided factory
- */
- private void unregisterFactory(final FactoryRegistration local) {
- if ( local != null ) {
- if ( local.factoryRegistration != null ) {
- local.factoryRegistration.unregister();
- }
- if ( local.runtimeRegistration != null ) {
- local.runtimeRegistration.unregister();
- }
- if ( local.commonFactory != null ) {
- local.commonFactory.deactivate();
- }
- }
- }
-
- /**
- * Try to register the factory.
- */
- private void registerFactory(final BundleContext localContext) {
- final FactoryRegistration local = new FactoryRegistration();
-
- if ( localContext != null ) {
- // activate and register factory
- final Dictionary<String, Object> serviceProps = new Hashtable<>();
- serviceProps.put(Constants.SERVICE_VENDOR, "The Apache Software
Foundation");
- serviceProps.put(Constants.SERVICE_DESCRIPTION, "Apache Sling
Resource Resolver Factory");
-
- local.commonFactory = new CommonResourceResolverFactoryImpl(this);
- local.commonFactory.activate(localContext);
- local.factoryRegistration = localContext.registerService(
- ResourceResolverFactory.class, new
ServiceFactory<ResourceResolverFactory>() {
-
- @Override
- public ResourceResolverFactory getService(final Bundle
bundle, final ServiceRegistration<ResourceResolverFactory> registration) {
- if (
ResourceResolverFactoryActivator.this.bundleContext == null ) {
- return null;
- }
- final ResourceResolverFactoryImpl r = new
ResourceResolverFactoryImpl(
- local.commonFactory, bundle,
-
ResourceResolverFactoryActivator.this.getServiceUserMapper());
- return r;
- }
-
- @Override
- public void ungetService(final Bundle bundle, final
ServiceRegistration<ResourceResolverFactory> registration, final
ResourceResolverFactory service) {
- // nothing to do
- }
- }, serviceProps);
-
- local.runtimeRegistration =
localContext.registerService(RuntimeService.class,
- this.getRuntimeService(), null);
-
- this.factoryRegistration = local;
- }
}
/**
@@ -514,35 +382,6 @@ public class ResourceResolverFactoryActivator {
return this.bundleContext;
}
- /**
- * Check the preconditions and if it changed, either register factory or
unregister
- */
- private void checkFactoryPreconditions(final String unavailableName, final
String unavailableServicePid) {
- final BundleContext localContext = this.getBundleContext();
- if ( localContext != null ) {
- final boolean result =
this.preconds.checkPreconditions(unavailableName, unavailableServicePid);
- if ( result && this.factoryRegistration == null ) {
- // check system bundle state - if stopping, don't register new
factory
- final Bundle systemBundle =
localContext.getBundle(Constants.SYSTEM_BUNDLE_LOCATION);
- if ( systemBundle != null && systemBundle.getState() !=
Bundle.STOPPING ) {
- boolean create = true;
- synchronized ( this ) {
- if ( this.factoryRegistration == null ) {
- this.factoryRegistration = new
FactoryRegistration();
- } else {
- create = false;
- }
- }
- if ( create ) {
- this.registerFactory(localContext);
- }
- }
- } else if ( !result && this.factoryRegistration != null ) {
- this.unregisterFactory();
- }
- }
- }
-
/**
* Bind a resource decorator.
*/
diff --git
a/src/main/java/org/apache/sling/resourceresolver/impl/providers/stateful/AuthenticatedResourceProvider.java
b/src/main/java/org/apache/sling/resourceresolver/impl/providers/stateful/AuthenticatedResourceProvider.java
index 453b5cf..7207b57 100644
---
a/src/main/java/org/apache/sling/resourceresolver/impl/providers/stateful/AuthenticatedResourceProvider.java
+++
b/src/main/java/org/apache/sling/resourceresolver/impl/providers/stateful/AuthenticatedResourceProvider.java
@@ -52,7 +52,7 @@ public class AuthenticatedResourceProvider {
private static final Logger logger =
LoggerFactory.getLogger(ResourceResolverImpl.class);
- public static final AuthenticatedResourceProvider UNAUTHENTICATED_PROVIDER
= new AuthenticatedResourceProvider(null, false, null, null);
+ public static final AuthenticatedResourceProvider UNAUTHENTICATED_PROVIDER
= new AuthenticatedResourceProvider();
private final ResourceProviderHandler providerHandler;
@@ -79,6 +79,13 @@ public class AuthenticatedResourceProvider {
this.useRAS = useRAS;
}
+ private AuthenticatedResourceProvider() {
+ this.providerHandler = null;
+ this.resolveContext = null;
+ this.tracker = null;
+ this.useRAS = false;
+ }
+
/**
* Get the resolve context.
* @return The resolve context
diff --git
a/src/test/java/org/apache/sling/resourceresolver/impl/EtcMappingResourceResolverTest.java
b/src/test/java/org/apache/sling/resourceresolver/impl/EtcMappingResourceResolverTest.java
index d87aa22..5873414 100644
---
a/src/test/java/org/apache/sling/resourceresolver/impl/EtcMappingResourceResolverTest.java
+++
b/src/test/java/org/apache/sling/resourceresolver/impl/EtcMappingResourceResolverTest.java
@@ -31,6 +31,7 @@ import
org.apache.sling.resourceresolver.impl.providers.ResourceProviderStorage;
import
org.apache.sling.resourceresolver.impl.providers.ResourceProviderTracker;
import org.apache.sling.serviceusermapping.ServiceUserMapper;
import org.apache.sling.spi.resource.provider.ResourceProvider;
+import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.mockito.Mock;
@@ -144,6 +145,11 @@ public class EtcMappingResourceResolverTest {
http = buildResource("/etc/map/http", map, resourceResolver,
resourceProvider);
}
+ @After
+ public void cleanup() {
+ resourceResolver.close();
+ }
+
List<MapConfigurationProvider.VanityPathConfig> getVanityPathConfigs() {
return new ArrayList<>();
}
diff --git
a/src/test/java/org/apache/sling/resourceresolver/impl/FactoryPreconditionsTest.java
b/src/test/java/org/apache/sling/resourceresolver/impl/FactoryPreconditionsTest.java
index e14a115..b930503 100644
---
a/src/test/java/org/apache/sling/resourceresolver/impl/FactoryPreconditionsTest.java
+++
b/src/test/java/org/apache/sling/resourceresolver/impl/FactoryPreconditionsTest.java
@@ -43,32 +43,15 @@ public class FactoryPreconditionsTest {
final ResourceProviderStorage storage =
Mockito.mock(ResourceProviderStorage.class);
Mockito.when(tracker.getResourceProviderStorage()).thenReturn(storage);
- FactoryPreconditions conditions = new FactoryPreconditions();
- conditions.activate(null, null, null, tracker);
+ FactoryPreconditions conditions = new FactoryPreconditions(tracker,
null, null);
assertTrue(conditions.checkPreconditions(null, null));
- conditions = new FactoryPreconditions();
- conditions.activate(null, Collections.<String> emptySet(),
Collections.<String> emptySet(), tracker);
+ conditions = new FactoryPreconditions(tracker, Collections.<String>
emptySet(), Collections.<String> emptySet());
assertTrue(conditions.checkPreconditions(null, null));
}
- @Test public void testDeactivated() {
- final ResourceProviderTracker tracker =
Mockito.mock(ResourceProviderTracker.class);
- final ResourceProviderStorage storage =
Mockito.mock(ResourceProviderStorage.class);
- Mockito.when(tracker.getResourceProviderStorage()).thenReturn(storage);
-
- FactoryPreconditions conditions = new FactoryPreconditions();
- conditions.activate(null, null, null, tracker);
-
- assertTrue(conditions.checkPreconditions(null, null));
-
- conditions.deactivate();
-
- assertFalse(conditions.checkPreconditions(null, null));
- }
-
private List<ResourceProviderHandler> getResourceProviderHandlers(String[]
pids) {
final List<ResourceProviderHandler> result = new
ArrayList<ResourceProviderHandler>();
@@ -108,8 +91,7 @@ public class FactoryPreconditionsTest {
final ResourceProviderStorage storage =
Mockito.mock(ResourceProviderStorage.class);
Mockito.when(tracker.getResourceProviderStorage()).thenReturn(storage);
- FactoryPreconditions conditions = new FactoryPreconditions();
- conditions.activate(null, new HashSet<>(Arrays.asList("pid1",
"pid3")), null, tracker);
+ FactoryPreconditions conditions = new FactoryPreconditions(tracker,
null, new HashSet<>(Arrays.asList("pid1", "pid3")));
final List<ResourceProviderHandler> handlers1 =
getResourceProviderHandlers(new String[] {"pid2"});
Mockito.when(storage.getAllHandlers()).thenReturn(handlers1);
@@ -129,8 +111,7 @@ public class FactoryPreconditionsTest {
final ResourceProviderStorage storage =
Mockito.mock(ResourceProviderStorage.class);
Mockito.when(tracker.getResourceProviderStorage()).thenReturn(storage);
- FactoryPreconditions conditions = new FactoryPreconditions();
- conditions.activate(null, null,new HashSet<>(Arrays.asList("n1",
"n2")), tracker);
+ FactoryPreconditions conditions = new FactoryPreconditions(tracker,
new HashSet<>(Arrays.asList("n1", "n2")), null);
final List<ResourceProviderHandler> handlers1 =
getResourceProviderHandlersWithNames(new String[] {"n2"});
Mockito.when(storage.getAllHandlers()).thenReturn(handlers1);
@@ -150,8 +131,7 @@ public class FactoryPreconditionsTest {
final ResourceProviderStorage storage =
Mockito.mock(ResourceProviderStorage.class);
Mockito.when(tracker.getResourceProviderStorage()).thenReturn(storage);
- FactoryPreconditions conditions = new FactoryPreconditions();
- conditions.activate(null, new HashSet<>(Arrays.asList("pid1",
"pid3")), null, tracker);
+ FactoryPreconditions conditions = new FactoryPreconditions(tracker,
null, new HashSet<>(Arrays.asList("pid1", "pid3")));
final List<ResourceProviderHandler> handlers2 =
getResourceProviderHandlers(new String[] {"pid1", "pid2", "pid3"});
Mockito.when(storage.getAllHandlers()).thenReturn(handlers2);
diff --git
a/src/test/java/org/apache/sling/resourceresolver/impl/FactoryRegistrationHandlerTest.java
b/src/test/java/org/apache/sling/resourceresolver/impl/FactoryRegistrationHandlerTest.java
new file mode 100644
index 0000000..0f66b7f
--- /dev/null
+++
b/src/test/java/org/apache/sling/resourceresolver/impl/FactoryRegistrationHandlerTest.java
@@ -0,0 +1,181 @@
+/*
+ * 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.resourceresolver.impl;
+
+import org.apache.commons.collections4.bidimap.TreeBidiMap;
+import org.apache.sling.api.resource.ResourceResolverFactory;
+import
org.apache.sling.resourceresolver.impl.providers.ResourceProviderStorage;
+import
org.apache.sling.resourceresolver.impl.providers.ResourceProviderTracker;
+import org.apache.sling.serviceusermapping.ServiceUserMapper;
+import org.apache.sling.testing.mock.osgi.junit.OsgiContext;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.mockito.Mockito;
+import org.mockito.internal.stubbing.defaultanswers.ReturnsSmartNulls;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.ServiceEvent;
+import org.osgi.framework.ServiceListener;
+import org.osgi.framework.ServiceReference;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+import java.util.function.Predicate;
+
+import static org.junit.Assert.assertTrue;
+import static org.mockito.ArgumentMatchers.isNull;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.when;
+
+public class FactoryRegistrationHandlerTest {
+
+ private static final Logger LOG =
LoggerFactory.getLogger(FactoryRegistrationHandlerTest.class);
+
+ public static final ReturnsSmartNulls DEFAULT_ANSWER = new
ReturnsSmartNulls();
+
+ @Rule
+ public OsgiContext osgi = new OsgiContext();
+
+ private ResourceResolverFactoryActivator activator;
+
+ @Before
+ public void setUp() {
+ final ResourceProviderTracker resourceProviderTracker =
mock(ResourceProviderTracker.class);
+
doReturn(mock(ResourceProviderStorage.class)).when(resourceProviderTracker).getResourceProviderStorage();
+
+ activator = mock(ResourceResolverFactoryActivator.class);
+ doReturn(osgi.bundleContext()).when(activator).getBundleContext();
+
doReturn(resourceProviderTracker).when(activator).getResourceProviderTracker();
+
doReturn(mock(ServiceUserMapper.class)).when(activator).getServiceUserMapper();
+ doReturn(new TreeBidiMap<>()).when(activator).getVirtualURLMap();
+ doReturn(null).when(activator).getEventAdmin();
+
+ }
+
+ private static <T> T mock(Class<T> classToMock) {
+ return Mockito.mock(classToMock, DEFAULT_ANSWER);
+ }
+
+ @Test
+ public void testFactoryRegistration() throws InterruptedException {
+ final FactoryPreconditions preconditions =
mock(FactoryPreconditions.class);
+ when(preconditions.checkPreconditions(isNull(),
isNull())).thenReturn(true);
+
+ try (AwaitingListener unregistration =
+ AwaitingListener.unregistration(osgi.bundleContext(),
ResourceResolverFactory.class)) {
+ try (FactoryRegistrationHandler factoryRegistrationHandler =
+ new FactoryRegistrationHandler(activator,
preconditions);
+ AwaitingListener registration =
AwaitingListener.registration(osgi.bundleContext(),
ResourceResolverFactory.class)) {
+ factoryRegistrationHandler.maybeRegisterFactory(null, null);
+ assertTrue("Expected ResourceResolverFactory service to be
registered",
+ registration.await(5, TimeUnit.SECONDS));
+ }
+ assertTrue("Expected ResourceResolverFactory service to be
unregistered",
+ unregistration.await(5, TimeUnit.SECONDS));
+ }
+ }
+
+ @Test
+ public void testFactoryDeregistrationWhenConditionsUnsatisfied() throws
InterruptedException {
+ final BundleContext ctx = osgi.bundleContext();
+ final FactoryPreconditions preconditions =
mock(FactoryPreconditions.class);
+ try (FactoryRegistrationHandler factoryRegistrationHandler =
+ new FactoryRegistrationHandler(activator, preconditions);
+ AwaitingListener registration =
AwaitingListener.registration(ctx, ResourceResolverFactory.class);
+ AwaitingListener unregistration =
AwaitingListener.unregistration(ctx, ResourceResolverFactory.class)) {
+
+ when(preconditions.checkPreconditions(isNull(),
isNull())).thenReturn(true);
+ factoryRegistrationHandler.maybeRegisterFactory(null, null);
+ assertTrue("Expected ResourceResolverFactory service to be
registered",
+ registration.await(5, TimeUnit.SECONDS));
+
+ when(preconditions.checkPreconditions(isNull(),
isNull())).thenReturn(false);
+ factoryRegistrationHandler.maybeRegisterFactory(null, null);
+ assertTrue("Expected ResourceResolverFactory service to be
unregistered",
+ unregistration.await(5, TimeUnit.SECONDS));
+ }
+ }
+
+ private static class AwaitingListener implements ServiceListener,
AutoCloseable {
+
+ private final BundleContext bundleContext;
+
+ private final Predicate<ServiceEvent> expectedEventPredicate;
+
+ private final CountDownLatch latch;
+
+ public AwaitingListener(BundleContext ctx, Predicate<ServiceEvent>
expectedEventPredicate) {
+ this(ctx, expectedEventPredicate, 1);
+ }
+
+ public AwaitingListener(BundleContext ctx, Predicate<ServiceEvent>
expectedEventPredicate, int count) {
+ this.bundleContext = ctx;
+ this.expectedEventPredicate = expectedEventPredicate;
+ this.latch = new CountDownLatch(count);
+ this.bundleContext.addServiceListener(this);
+ }
+
+ public static AwaitingListener registration(BundleContext
bundleContext, Class<?> clazz) {
+ return new AwaitingListener(bundleContext, serviceEvent -> {
+ if (serviceEvent.getType() == ServiceEvent.REGISTERED) {
+ return isInstance(bundleContext,
serviceEvent.getServiceReference(), clazz);
+ }
+ return false;
+ });
+ }
+
+ public static AwaitingListener unregistration(BundleContext
bundleContext, Class<?> clazz) {
+ return new AwaitingListener(bundleContext, serviceEvent -> {
+ if (serviceEvent.getType() == ServiceEvent.UNREGISTERING) {
+ return isInstance(bundleContext,
serviceEvent.getServiceReference(), clazz);
+ }
+ return false;
+ });
+ }
+
+ private static boolean isInstance(BundleContext bundleContext,
ServiceReference<?> ref, Class<?> clazz) {
+ try {
+ final Object service = bundleContext.getService(ref);
+ final boolean isInstance = clazz.isInstance(service);
+ LOG.info("{} == isInstance({}, {})", isInstance,
service.getClass(), clazz);
+ return isInstance;
+ } finally {
+ bundleContext.ungetService(ref);
+ }
+ }
+
+ @Override
+ public void serviceChanged(ServiceEvent event) {
+ if (expectedEventPredicate.test(event)) {
+ latch.countDown();
+ }
+ }
+
+ public boolean await(long timeout, TimeUnit timeUnit) throws
InterruptedException {
+ return latch.await(timeout, timeUnit);
+ }
+
+ @Override
+ public void close() {
+ bundleContext.removeServiceListener(this);
+ }
+ }
+}
\ No newline at end of file
diff --git
a/src/test/java/org/apache/sling/resourceresolver/impl/MockedResourceResolverImplTest.java
b/src/test/java/org/apache/sling/resourceresolver/impl/MockedResourceResolverImplTest.java
index 8cfd4e0..2870da3 100644
---
a/src/test/java/org/apache/sling/resourceresolver/impl/MockedResourceResolverImplTest.java
+++
b/src/test/java/org/apache/sling/resourceresolver/impl/MockedResourceResolverImplTest.java
@@ -23,14 +23,17 @@ import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotEquals;
import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertThrows;
import static org.junit.Assert.assertTrue;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.ArgumentMatchers.same;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
import java.lang.annotation.Annotation;
import java.util.ArrayList;
+import java.util.Collection;
import java.util.Collections;
import java.util.Dictionary;
import java.util.HashMap;
@@ -40,6 +43,8 @@ import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.Set;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
import javax.servlet.http.HttpServletRequest;
@@ -71,11 +76,13 @@ import org.mockito.ArgumentCaptor;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.MockitoAnnotations;
+import org.mockito.invocation.Invocation;
import org.osgi.framework.Bundle;
import org.osgi.framework.BundleContext;
import org.osgi.framework.Constants;
import org.osgi.framework.ServiceFactory;
import org.osgi.framework.ServiceReference;
+import org.osgi.framework.ServiceRegistration;
import static org.mockito.ArgumentMatchers.nullable;
@@ -117,10 +124,6 @@ public class MockedResourceResolverImplTest {
@Mock
private QueryLanguageProvider queryProvider;
- private Map<String, Object> services = new HashMap<String, Object>();
-
- private Map<String, Object> serviceProperties = new HashMap<String,
Object>();
-
private ResourceResolverFactoryImpl resourceResolverFactory;
@Mock
@@ -151,13 +154,20 @@ public class MockedResourceResolverImplTest {
@SuppressWarnings("unchecked")
@Before
- public void before() throws LoginException {
+ public void before() throws LoginException, InterruptedException {
activator = new ResourceResolverFactoryActivator();
// system bundle access
final Bundle systemBundle = mock(Bundle.class);
Mockito.when(systemBundle.getState()).thenReturn(Bundle.ACTIVE);
Mockito.when(bundleContext.getBundle(Constants.SYSTEM_BUNDLE_LOCATION)).thenReturn(systemBundle);
+ CountDownLatch factoryRegistrationDone = new CountDownLatch(1);
+
Mockito.when(bundleContext.registerService(same(ResourceResolverFactory.class),
any(ServiceFactory.class), any(Dictionary.class)))
+ .thenAnswer(invocation -> {
+ factoryRegistrationDone.countDown();
+ return mock(ServiceRegistration.class);
+ });
+
activator.resourceAccessSecurityTracker = new
ResourceAccessSecurityTracker();
activator.resourceProviderTracker = resourceProviderTracker;
activator.changeListenerWhiteboard = resourceChangeListenerWhiteboard;
@@ -312,31 +322,20 @@ public class MockedResourceResolverImplTest {
Mockito.when(usingBundle.getBundleContext()).thenReturn(usingBundleContext);
Mockito.when(usingBundleContext.getBundle()).thenReturn(usingBundle);
- // extract any services that were registered into a map.
- ArgumentCaptor<Class> classesCaptor =
ArgumentCaptor.forClass(Class.class);
- ArgumentCaptor<ServiceFactory> serviceCaptor =
ArgumentCaptor.forClass(ServiceFactory.class);
- @SuppressWarnings("rawtypes")
- ArgumentCaptor<Dictionary> propertiesCaptor =
ArgumentCaptor.forClass(Dictionary.class);
+ factoryRegistrationDone.await(5, TimeUnit.SECONDS);
+
+ ArgumentCaptor<ServiceFactory<ResourceResolverFactory>> serviceCaptor
= argumentCaptorForClass(ServiceFactory.class);
Mockito.verify(bundleContext, Mockito.atLeastOnce()).registerService(
- (Class<ResourceResolverFactory>)classesCaptor.capture(),
(ServiceFactory<ResourceResolverFactory>)serviceCaptor.capture(),
- propertiesCaptor.capture());
-
- int si = 0;
- List<ServiceFactory> serviceList = serviceCaptor.getAllValues();
- @SuppressWarnings({ "unused", "rawtypes" })
- List<Dictionary> servicePropertiesList =
propertiesCaptor.getAllValues();
- for (Class serviceClass : classesCaptor.getAllValues()) {
- services.put(serviceClass.getName(), serviceList.get(si));
- serviceProperties.put(serviceClass.getName(),
serviceProperties.get(si));
- si++;
- }
+ same(ResourceResolverFactory.class),
+ serviceCaptor.capture(),
+ any(Dictionary.class));
+
// verify that a ResourceResolverFactoryImpl was created and
registered.
- Assert.assertNotNull("" + services,
services.get(ResourceResolverFactory.class.getName()));
- Object rrf = services.get(ResourceResolverFactory.class.getName());
- if (rrf instanceof ServiceFactory) {
- rrf = ((ServiceFactory) rrf).getService(usingBundle, null);
- }
- Assert.assertTrue(rrf instanceof ResourceResolverFactoryImpl);
+ ServiceFactory<ResourceResolverFactory> rrfServiceFactory =
serviceCaptor.getValue();
+ Assert.assertNotNull("ServiceFactory<ResourceResolverFactory>",
rrfServiceFactory);
+ final ResourceResolverFactory rrf =
rrfServiceFactory.getService(usingBundle, null);
+ assertNotNull("ResourceResolverFactory", rrf);
+ assertTrue("ResourceResolverFactoryImpl", rrf instanceof
ResourceResolverFactoryImpl);
resourceResolverFactory = (ResourceResolverFactoryImpl) rrf;
// ensure allowed alias locations are *not* ending with a slash
(invalid absolut path)
@@ -350,6 +349,11 @@ public class MockedResourceResolverImplTest {
getInaccessibleField("commonFactory",rrf,CommonResourceResolverFactoryImpl.class).getMapEntries());
}
+ @SuppressWarnings("unchecked")
+ private <T> ArgumentCaptor<T> argumentCaptorForClass(Class<?> clazz) {
+ return (ArgumentCaptor<T>) ArgumentCaptor.forClass(clazz);
+ }
+
public static ResourceProviderHandler createRPHandler(ResourceProvider<?>
rp, String pid, long ranking,
String path) {
ServiceReference ref = mock(ServiceReference.class);
@@ -470,11 +474,13 @@ public class MockedResourceResolverImplTest {
*/
@Test
public void testGetResolver() throws LoginException {
- ResourceResolver resourceResolver =
resourceResolverFactory.getResourceResolver(null);
- Assert.assertNotNull(resourceResolver);
+ try (ResourceResolver resourceResolver =
resourceResolverFactory.getResourceResolver(null)) {
+ Assert.assertNotNull(resourceResolver);
+ }
Map<String, Object> authenticationInfo = new HashMap<String, Object>();
- resourceResolver =
resourceResolverFactory.getAdministrativeResourceResolver(authenticationInfo);
- Assert.assertNotNull(resourceResolver);
+ try (ResourceResolver resourceResolver =
resourceResolverFactory.getAdministrativeResourceResolver(authenticationInfo)) {
+ Assert.assertNotNull(resourceResolver);
+ }
}
/**
@@ -483,14 +489,11 @@ public class MockedResourceResolverImplTest {
*/
@Test
public void testResolverMisc() throws LoginException {
- ResourceResolver resourceResolver =
resourceResolverFactory.getResourceResolver(null);
- try {
- resourceResolver.getAttribute(null);
- Assert.fail("Should have thrown a NPE");
- } catch ( NullPointerException e) {
- // this is expected.
+ try (ResourceResolver resourceResolver =
resourceResolverFactory.getResourceResolver(null)) {
+ assertThrows("Should have thrown a NPE",
NullPointerException.class,
+ () -> resourceResolver.getAttribute(null));
+ Assert.assertArrayEquals(new String[]{"/apps/","/libs/"},
resourceResolver.getSearchPath());
}
- Assert.assertArrayEquals(new String[]{"/apps/","/libs/"},
resourceResolver.getSearchPath());
}
/**
@@ -499,12 +502,14 @@ public class MockedResourceResolverImplTest {
*/
@Test
public void testGetAuthenticatedResolve() throws LoginException {
- ResourceResolver resourceResolver =
resourceResolverFactory.getAdministrativeResourceResolver(null);
- Assert.assertNotNull(resourceResolver);
- Map<String, Object> authenticationInfo = new HashMap<String, Object>();
+ try (ResourceResolver resourceResolver =
resourceResolverFactory.getAdministrativeResourceResolver(null)) {
+ Assert.assertNotNull(resourceResolver);
+ }
- resourceResolver =
resourceResolverFactory.getAdministrativeResourceResolver(authenticationInfo);
- Assert.assertNotNull(resourceResolver);
+ Map<String, Object> authenticationInfo = new HashMap<String, Object>();
+ try (ResourceResolver resourceResolver =
resourceResolverFactory.getAdministrativeResourceResolver(authenticationInfo)) {
+ Assert.assertNotNull(resourceResolver);
+ }
}
/**
@@ -513,11 +518,12 @@ public class MockedResourceResolverImplTest {
*/
@Test
public void testGetResource() throws LoginException {
- ResourceResolver resourceResolver =
resourceResolverFactory.getResourceResolver(null);
- Assert.assertNotNull(resourceResolver);
- Resource singleResource = buildResource("/single/test",
EMPTY_RESOURCE_LIST, resourceResolver, resourceProvider);
- Resource resource = resourceResolver.getResource("/single/test");
- Assert.assertEquals(singleResource, resource);
+ try (ResourceResolver resourceResolver =
resourceResolverFactory.getResourceResolver(null)) {
+ Assert.assertNotNull(resourceResolver);
+ Resource singleResource = buildResource("/single/test",
EMPTY_RESOURCE_LIST, resourceResolver, resourceProvider);
+ Resource resource = resourceResolver.getResource("/single/test");
+ Assert.assertEquals(singleResource, resource);
+ }
}
/**
@@ -526,11 +532,12 @@ public class MockedResourceResolverImplTest {
*/
@Test
public void testGetResourceSLING864() throws LoginException {
- ResourceResolver resourceResolver =
resourceResolverFactory.getResourceResolver(null);
- Assert.assertNotNull(resourceResolver);
- Resource singleResource =
buildResource("/single/test.with/extra.dots/inthepath",
EMPTY_RESOURCE_LIST,resourceResolver, resourceProvider);
- Resource resource =
resourceResolver.getResource("/single/test.with/extra.dots/inthepath");
- Assert.assertEquals(singleResource, resource);
+ try (ResourceResolver resourceResolver =
resourceResolverFactory.getResourceResolver(null)) {
+ Assert.assertNotNull(resourceResolver);
+ Resource singleResource =
buildResource("/single/test.with/extra.dots/inthepath", EMPTY_RESOURCE_LIST,
resourceResolver, resourceProvider);
+ Resource resource =
resourceResolver.getResource("/single/test.with/extra.dots/inthepath");
+ Assert.assertEquals(singleResource, resource);
+ }
}
@@ -540,14 +547,15 @@ public class MockedResourceResolverImplTest {
*/
@Test
public void testRelativeResource() throws LoginException {
- ResourceResolver resourceResolver =
resourceResolverFactory.getResourceResolver(null);
- Assert.assertNotNull(resourceResolver);
- Resource appResource = buildResource("/apps/store/inventory",
EMPTY_RESOURCE_LIST, resourceResolver, appsResourceProvider);
- Resource libResource = buildResource("/libs/store/catalog",
EMPTY_RESOURCE_LIST, resourceResolver, appsResourceProvider);
- Resource testResource =
resourceResolver.getResource("store/inventory");
- Assert.assertEquals(appResource, testResource);
- testResource = resourceResolver.getResource("store/catalog");
- Assert.assertEquals(libResource, testResource);
+ try (ResourceResolver resourceResolver =
resourceResolverFactory.getResourceResolver(null)) {
+ Assert.assertNotNull(resourceResolver);
+ Resource appResource = buildResource("/apps/store/inventory",
EMPTY_RESOURCE_LIST, resourceResolver, appsResourceProvider);
+ Resource libResource = buildResource("/libs/store/catalog",
EMPTY_RESOURCE_LIST, resourceResolver, appsResourceProvider);
+ Resource testResource =
resourceResolver.getResource("store/inventory");
+ Assert.assertEquals(appResource, testResource);
+ testResource = resourceResolver.getResource("store/catalog");
+ Assert.assertEquals(libResource, testResource);
+ }
}
/**
@@ -558,36 +566,37 @@ public class MockedResourceResolverImplTest {
*/
@Test
public void testMapping() throws LoginException {
- ResourceResolver resourceResolver =
resourceResolverFactory.getResourceResolver(null);
- buildResource("/single/test", EMPTY_RESOURCE_LIST, resourceResolver,
resourceProvider);
- HttpServletRequest request = mock(HttpServletRequest.class);
- Mockito.when(request.getScheme()).thenReturn("http");
- Mockito.when(request.getServerPort()).thenReturn(80);
- Mockito.when(request.getServerName()).thenReturn("localhost");
-
- String path = resourceResolver.map(request,"/single/test?q=123123");
- Assert.assertEquals("/single/test?q=123123", path);
- buildResource("/single/test", EMPTY_RESOURCE_LIST, resourceResolver,
resourceProvider);
- path = resourceResolver.map(request,"/single/test");
- Assert.assertEquals("/single/test", path);
-
- buildResource("/single/test", EMPTY_RESOURCE_LIST, resourceResolver,
resourceProvider);
- // test path mapping without a request.
- path = resourceResolver.map("/single/test");
- Assert.assertEquals("/single/test", path);
-
- buildResource("/content", EMPTY_RESOURCE_LIST, resourceResolver,
resourceProvider);
- path = resourceResolver.map("/content.html");
- Assert.assertEquals("/content.html", path);
-
- path = resourceResolver.map(request,"some/relative/path/test");
- Assert.assertEquals("some/relative/path/test", path);
-
- buildResource("/", EMPTY_RESOURCE_LIST, resourceResolver,
resourceProvider);
- buildResource("/single", EMPTY_RESOURCE_LIST, resourceResolver,
resourceProvider);
- buildResource("/single/test", EMPTY_RESOURCE_LIST, resourceResolver,
resourceProvider);
- path = resourceResolver.map("/single//test.html");
- Assert.assertEquals("/single/test.html", path);
+ try (ResourceResolver resourceResolver =
resourceResolverFactory.getResourceResolver(null)) {
+ buildResource("/single/test", EMPTY_RESOURCE_LIST,
resourceResolver, resourceProvider);
+ HttpServletRequest request = mock(HttpServletRequest.class);
+ Mockito.when(request.getScheme()).thenReturn("http");
+ Mockito.when(request.getServerPort()).thenReturn(80);
+ Mockito.when(request.getServerName()).thenReturn("localhost");
+
+ String path = resourceResolver.map(request,
"/single/test?q=123123");
+ Assert.assertEquals("/single/test?q=123123", path);
+ buildResource("/single/test", EMPTY_RESOURCE_LIST,
resourceResolver, resourceProvider);
+ path = resourceResolver.map(request, "/single/test");
+ Assert.assertEquals("/single/test", path);
+
+ buildResource("/single/test", EMPTY_RESOURCE_LIST,
resourceResolver, resourceProvider);
+ // test path mapping without a request.
+ path = resourceResolver.map("/single/test");
+ Assert.assertEquals("/single/test", path);
+
+ buildResource("/content", EMPTY_RESOURCE_LIST, resourceResolver,
resourceProvider);
+ path = resourceResolver.map("/content.html");
+ Assert.assertEquals("/content.html", path);
+
+ path = resourceResolver.map(request, "some/relative/path/test");
+ Assert.assertEquals("some/relative/path/test", path);
+
+ buildResource("/", EMPTY_RESOURCE_LIST, resourceResolver,
resourceProvider);
+ buildResource("/single", EMPTY_RESOURCE_LIST, resourceResolver,
resourceProvider);
+ buildResource("/single/test", EMPTY_RESOURCE_LIST,
resourceResolver, resourceProvider);
+ path = resourceResolver.map("/single//test.html");
+ Assert.assertEquals("/single/test.html", path);
+ }
}
@@ -599,22 +608,23 @@ public class MockedResourceResolverImplTest {
*/
@Test
public void testListChildren() throws LoginException {
- ResourceResolver resourceResolver =
resourceResolverFactory.getResourceResolver(null);
- buildResource("/single/test/withchildren",
buildChildResources("/single/test/withchildren"), resourceResolver,
resourceProvider );
+ try (ResourceResolver resourceResolver =
resourceResolverFactory.getResourceResolver(null)) {
+ buildResource("/single/test/withchildren",
buildChildResources("/single/test/withchildren"), resourceResolver,
resourceProvider);
- Resource resource =
resourceResolver.getResource("/single/test/withchildren");
- Assert.assertNotNull(resource);
+ Resource resource =
resourceResolver.getResource("/single/test/withchildren");
+ Assert.assertNotNull(resource);
- // test via the resource list children itself, this really just tests
this test case.
- Iterator<Resource> resourceIterator = resource.listChildren();
- Assert.assertNotNull(resourceResolver);
- int i = 0;
- while(resourceIterator.hasNext()) {
- Assert.assertEquals("m"+i, resourceIterator.next().getName());
- i++;
+ // test via the resource list children itself, this really just
tests this test case.
+ Iterator<Resource> resourceIterator = resource.listChildren();
+ Assert.assertNotNull(resourceResolver);
+ int i = 0;
+ while (resourceIterator.hasNext()) {
+ Assert.assertEquals("m" + i,
resourceIterator.next().getName());
+ i++;
+ }
+ Assert.assertEquals(5, i);
}
- Assert.assertEquals(5, i);
}
/**
@@ -623,22 +633,23 @@ public class MockedResourceResolverImplTest {
*/
@Test
public void testResourceResolverListChildren() throws LoginException {
- ResourceResolver resourceResolver =
resourceResolverFactory.getResourceResolver(null);
- buildResource("/single/test/withchildren",
buildChildResources("/single/test/withchildren"), resourceResolver,
resourceProvider);
+ try (ResourceResolver resourceResolver =
resourceResolverFactory.getResourceResolver(null)) {
+ buildResource("/single/test/withchildren",
buildChildResources("/single/test/withchildren"), resourceResolver,
resourceProvider);
- Resource resource =
resourceResolver.getResource("/single/test/withchildren");
- Assert.assertNotNull(resource);
+ Resource resource =
resourceResolver.getResource("/single/test/withchildren");
+ Assert.assertNotNull(resource);
- // test via the resource list children itself, this really just tests
this test case.
- Iterator<Resource> resourceIterator =
resourceResolver.listChildren(resource);
- Assert.assertNotNull(resourceResolver);
- int i = 0;
- while(resourceIterator.hasNext()) {
- Assert.assertEquals("m"+i, resourceIterator.next().getName());
- i++;
+ // test via the resource list children itself, this really just
tests this test case.
+ Iterator<Resource> resourceIterator =
resourceResolver.listChildren(resource);
+ Assert.assertNotNull(resourceResolver);
+ int i = 0;
+ while (resourceIterator.hasNext()) {
+ Assert.assertEquals("m" + i,
resourceIterator.next().getName());
+ i++;
+ }
+ Assert.assertEquals(5, i);
}
- Assert.assertEquals(5,i);
}
/**
@@ -647,22 +658,23 @@ public class MockedResourceResolverImplTest {
*/
@Test
public void testResourceResolverGetChildren() throws LoginException {
- ResourceResolver resourceResolver =
resourceResolverFactory.getResourceResolver(null);
- buildResource("/single/test/withchildren",
buildChildResources("/single/test/withchildren"), resourceResolver,
resourceProvider);
+ try (ResourceResolver resourceResolver =
resourceResolverFactory.getResourceResolver(null)) {
+ buildResource("/single/test/withchildren",
buildChildResources("/single/test/withchildren"), resourceResolver,
resourceProvider);
- Resource resource =
resourceResolver.getResource("/single/test/withchildren");
- Assert.assertNotNull(resource);
+ Resource resource =
resourceResolver.getResource("/single/test/withchildren");
+ Assert.assertNotNull(resource);
- // test via the resource list children itself, this really just tests
this test case.
- Iterable<Resource> resourceIterator =
resourceResolver.getChildren(resource);
- Assert.assertNotNull(resourceResolver);
- int i = 0;
- for(Resource r : resourceIterator) {
- Assert.assertEquals("m"+i, r.getName());
- i++;
+ // test via the resource list children itself, this really just
tests this test case.
+ Iterable<Resource> resourceIterator =
resourceResolver.getChildren(resource);
+ Assert.assertNotNull(resourceResolver);
+ int i = 0;
+ for (Resource r : resourceIterator) {
+ Assert.assertEquals("m" + i, r.getName());
+ i++;
+ }
+ Assert.assertEquals(5, i);
}
- Assert.assertEquals(5,i);
}
@SuppressWarnings("unchecked")
@@ -674,41 +686,42 @@ public class MockedResourceResolverImplTest {
Mockito.when(queryProvider.queryResources(Mockito.nullable(ResolveContext.class),
Mockito.nullable(String.class), Mockito.nullable(String.class)))
.thenReturn(buildValueMapCollection(n, "A_").iterator());
- final ResourceResolver rr =
resourceResolverFactory.getResourceResolver(null);
- buildResource("/search/test/withchildren",
buildChildResources("/search/test/withchildren"), rr, resourceProvider);
- final Iterator<Map<String, Object>> it = rr.queryResources("/search",
FAKE_QUERY_LANGUAGE);
- final Set<String> toFind = new HashSet<String>();
- for(int i=0; i < n; i++) {
- toFind.add("A_" + i);
- }
+ try (ResourceResolver rr =
resourceResolverFactory.getResourceResolver(null)) {
+ buildResource("/search/test/withchildren",
buildChildResources("/search/test/withchildren"), rr, resourceProvider);
+ final Iterator<Map<String, Object>> it =
rr.queryResources("/search", FAKE_QUERY_LANGUAGE);
+ final Set<String> toFind = new HashSet<String>();
+ for (int i = 0; i < n; i++) {
+ toFind.add("A_" + i);
+ }
- assertTrue("Expecting non-empty result (" + n + ")", it.hasNext());
- while(it.hasNext()) {
- final Map<String, Object> m = it.next();
- toFind.remove(m.get(PATH));
+ assertTrue("Expecting non-empty result (" + n + ")", it.hasNext());
+ while (it.hasNext()) {
+ final Map<String, Object> m = it.next();
+ toFind.remove(m.get(PATH));
+ }
+ assertTrue("Expecting no leftovers (" + n + ") in" + toFind,
toFind.isEmpty());
}
- assertTrue("Expecting no leftovers (" + n + ") in" + toFind,
toFind.isEmpty());
}
@Test public void test_versions() throws LoginException {
- ResourceResolver resourceResolver =
resourceResolverFactory.getResourceResolver(null);
-
- Resource resource =
resourceResolver.resolve("/content/test.html;v=1.0");
- Map<String, String> parameters =
resource.getResourceMetadata().getParameterMap();
- assertEquals("/content/test.html", resource.getPath());
- assertEquals("test.html", resource.getName());
- assertEquals(Collections.singletonMap("v", "1.0"), parameters);
-
- resource = resourceResolver.resolve("/content/test;v='1.0'.html");
- parameters = resource.getResourceMetadata().getParameterMap();
- assertEquals("/content/test.html", resource.getPath());
- assertEquals("test.html", resource.getName());
- assertEquals(Collections.singletonMap("v", "1.0"), parameters);
-
- buildResource("/single/test/withchildren",
buildChildResources("/single/test/withchildren"), resourceResolver,
resourceProvider);
- resource =
resourceResolver.getResource("/single/test/withchildren;v='1.0'");
- assertNotNull(resource);
- assertEquals("/single/test/withchildren", resource.getPath());
- assertEquals("withchildren", resource.getName());
+ try (ResourceResolver resourceResolver =
resourceResolverFactory.getResourceResolver(null)) {
+ Resource resource =
resourceResolver.resolve("/content/test.html;v=1.0");
+ Map<String, String> parameters =
resource.getResourceMetadata().getParameterMap();
+ assertEquals("/content/test.html", resource.getPath());
+ assertEquals("test.html", resource.getName());
+ assertEquals(Collections.singletonMap("v", "1.0"), parameters);
+
+ resource = resourceResolver.resolve("/content/test;v='1.0'.html");
+ parameters = resource.getResourceMetadata().getParameterMap();
+ assertEquals("/content/test.html", resource.getPath());
+ assertEquals("test.html", resource.getName());
+ assertEquals(Collections.singletonMap("v", "1.0"), parameters);
+
+ buildResource("/single/test/withchildren",
buildChildResources("/single/test/withchildren"), resourceResolver,
resourceProvider);
+ resource =
resourceResolver.getResource("/single/test/withchildren;v='1.0'");
+ assertNotNull(resource);
+ assertEquals("/single/test/withchildren", resource.getPath());
+ assertEquals("withchildren", resource.getName());
+ }
}
}
diff --git
a/src/test/java/org/apache/sling/resourceresolver/impl/mapping/AbstractMappingMapEntriesTest.java
b/src/test/java/org/apache/sling/resourceresolver/impl/mapping/AbstractMappingMapEntriesTest.java
index 36c35c0..fd66d0e 100644
---
a/src/test/java/org/apache/sling/resourceresolver/impl/mapping/AbstractMappingMapEntriesTest.java
+++
b/src/test/java/org/apache/sling/resourceresolver/impl/mapping/AbstractMappingMapEntriesTest.java
@@ -110,8 +110,8 @@ public abstract class AbstractMappingMapEntriesTest {
when(resourceResolverFactory.getMapRoot()).thenReturn(MapEntries.DEFAULT_MAP_ROOT);
when(resourceResolverFactory.getMaxCachedVanityPathEntries()).thenReturn(-1L);
when(resourceResolverFactory.isMaxCachedVanityPathEntriesStartup()).thenReturn(true);
- when(resourceResolver.findResources(anyString(),
eq("JCR-SQL2"))).thenReturn(
- Collections.<Resource> emptySet().iterator());
+ when(resourceResolver.findResources(anyString(),
eq("JCR-SQL2"))).thenReturn(Collections.emptyIterator());
+ when(resourceResolver.findResources(anyString(),
eq("sql"))).thenReturn(Collections.emptyIterator());
map = setupEtcMapResource("/etc", "map");
http = setupEtcMapResource("http", map);
@@ -162,7 +162,7 @@ public abstract class AbstractMappingMapEntriesTest {
String path = (parent == null ? parentPath : parent.getPath()) + "/" +
name;
when(resource.getPath()).thenReturn(path);
when(resource.getName()).thenReturn(name);
- ValueMap valueMap = buildValueMap(valueMapPairs);
+ ValueMap valueMap = buildValueMap((Object[]) valueMapPairs);
when(resource.getValueMap()).thenReturn(valueMap);
when(resource.adaptTo(ValueMap.class)).thenReturn(valueMap);
when(resourceResolver.getResource(resource.getPath())).thenReturn(resource);
diff --git
a/src/test/java/org/apache/sling/resourceresolver/impl/mapping/InMemoryResourceProvider.java
b/src/test/java/org/apache/sling/resourceresolver/impl/mapping/InMemoryResourceProvider.java
index fe74988..4f63a85 100644
---
a/src/test/java/org/apache/sling/resourceresolver/impl/mapping/InMemoryResourceProvider.java
+++
b/src/test/java/org/apache/sling/resourceresolver/impl/mapping/InMemoryResourceProvider.java
@@ -105,7 +105,7 @@ public class InMemoryResourceProvider extends
ResourceProvider<Void>{
// we don't explicitly filter paths under jcr:system, but we
don't expect to have such resources either
// and this stub provider is not the proper location to test
JCR queries
- if ( "sql".equals(language) && "SELECT sling:alias FROM
nt:base AS page WHERE (NOT ISDESCENDANTNODE(page,\"/jcr:system\")) AND
sling:alias IS NOT NULL".equals(query) ) {
+ if ( "sql".equals(language) && "SELECT sling:alias FROM
nt:base AS page WHERE (NOT ISDESCENDANTNODE(page,'/jcr:system')) AND
sling:alias IS NOT NULL".equals(query) ) {
return resourcesWithProperty(ctx, "sling:alias")
.iterator();
}
diff --git
a/src/test/java/org/apache/sling/resourceresolver/impl/mapping/ResourceMapperImplTest.java
b/src/test/java/org/apache/sling/resourceresolver/impl/mapping/ResourceMapperImplTest.java
index ddfd024..42bbfe0 100644
---
a/src/test/java/org/apache/sling/resourceresolver/impl/mapping/ResourceMapperImplTest.java
+++
b/src/test/java/org/apache/sling/resourceresolver/impl/mapping/ResourceMapperImplTest.java
@@ -32,6 +32,7 @@ import java.util.Arrays;
import java.util.Collection;
import java.util.HashSet;
import java.util.Set;
+import java.util.concurrent.TimeUnit;
import javax.servlet.http.HttpServletRequest;
@@ -53,6 +54,7 @@ import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.junit.runners.Parameterized.Parameters;
+import org.osgi.util.tracker.ServiceTracker;
/**
* Validates that the {@link ResourceMapperImpl} correctly queries all sources
of mappings
@@ -94,7 +96,7 @@ public class ResourceMapperImplTest {
}
@Before
- public void prepare() throws LoginException {
+ public void prepare() throws LoginException, InterruptedException {
ctx.registerInjectActivateService(new ServiceUserMapperImpl());
ctx.registerInjectActivateService(new ResourceAccessSecurityTracker());
@@ -139,7 +141,15 @@ public class ResourceMapperImplTest {
ctx.registerInjectActivateService(new
ResourceResolverFactoryActivator(),
"resource.resolver.optimize.alias.resolution",
optimiseAliasResolution);
- ResourceResolverFactory factory =
ctx.getService(ResourceResolverFactory.class);
+ final ResourceResolverFactory factory;
+ final ServiceTracker<ResourceResolverFactory, ResourceResolverFactory>
tracker =
+ new ServiceTracker<>(ctx.bundleContext(),
ResourceResolverFactory.class, null);
+ try {
+ tracker.open();
+ factory = tracker.waitForService(TimeUnit.SECONDS.toMillis(5));
+ } finally {
+ tracker.close();
+ }
assertNotNull(factory);