This is an automated email from the ASF dual-hosted git repository.
dulvac pushed a commit to branch master
in repository
https://gitbox.apache.org/repos/asf/sling-org-apache-sling-testing-rules.git
The following commit(s) were added to refs/heads/master by this push:
new f5c886a SLING-7272 [Testing Rules] Allow customizing the Sling Client
Builder from an Instance junit rule
f5c886a is described below
commit f5c886a770c1fe8244e2ccb5e12fe10e7f85e83c
Author: Andrei Dulvac <[email protected]>
AuthorDate: Mon Nov 27 11:44:57 2017 +0100
SLING-7272 [Testing Rules] Allow customizing the Sling Client Builder from
an Instance junit rule
---
.../junit/rules/instance/AbstractInstance.java | 108 ++++++++++++++++++---
.../junit/rules/instance/BuilderCustomizer.java | 26 +++++
.../testing/junit/rules/instance/Instance.java | 35 ++++++-
3 files changed, 152 insertions(+), 17 deletions(-)
diff --git
a/src/main/java/org/apache/sling/testing/junit/rules/instance/AbstractInstance.java
b/src/main/java/org/apache/sling/testing/junit/rules/instance/AbstractInstance.java
index 0dfd448..2aa343f 100644
---
a/src/main/java/org/apache/sling/testing/junit/rules/instance/AbstractInstance.java
+++
b/src/main/java/org/apache/sling/testing/junit/rules/instance/AbstractInstance.java
@@ -17,61 +17,141 @@
package org.apache.sling.testing.junit.rules.instance;
+import org.apache.sling.testing.clients.ClientException;
import org.apache.sling.testing.clients.SlingClient;
import org.apache.sling.testing.clients.instance.InstanceConfiguration;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.lang.reflect.Constructor;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
import java.net.URI;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
public abstract class AbstractInstance implements Instance {
private static final Logger LOG =
LoggerFactory.getLogger(AbstractInstance.class);
+ // Caches a client
+ private final Map<String, SlingClient> clientsCache = new
ConcurrentHashMap<>(1);
+
+
+ /**
+ * Customizes the builder and returns it. Default implementation does
nothing to the builder.
+ * This should be overridden in subclasses, if needed. This method will be
called internally before building a client.
+ * @param builder the builder to customize
+ * @return the builder after customization.
+ */
+ @Override
+ public <T extends SlingClient.InternalBuilder> T customize(T builder) {
+ return builder;
+ }
/**
* {@inheritDoc}
*/
@Override
- public <T extends SlingClient> T getClient(Class<T> clientClass, String
user, String pass) {
+ public <T extends SlingClient> T newClient(Class<T> clientClass, String
user, String pass, BuilderCustomizer... customizers) {
InstanceConfiguration configuration = getConfiguration();
+ try {
+ T.InternalBuilder<T> builder = getBuilder(clientClass,
configuration.getUrl(), user, pass);
+ for (BuilderCustomizer customizer: customizers) {
+ builder = customizer.customize(builder);
+ }
+ T client = builder.build();
+ clientsCache.put(user + pass, client);
+ return client;
+ } catch (ClientException e) {
+ return null;
+ }
+ }
- Constructor<T> constructor;
+ private Class getBuilderClass(Class clientClass) {
- try {
- constructor = clientClass.getConstructor(URI.class, String.class,
String.class);
- } catch (NoSuchMethodException e) {
+ // If the passed class is not a client, nothing to do;
+ if (!SlingClient.class.isAssignableFrom(clientClass)) {
+ return null;
+ }
+
+ // If it's SlingClient, just return the builder
+ if (clientClass == SlingClient.class) {
+ return SlingClient.Builder.class;
+ }
+
+ // First class that is not abstract and extends
SlingClient.InternalBuilder is our builder
+ for (Class clazz : clientClass.getDeclaredClasses()) {
+ if (SlingClient.InternalBuilder.class.isAssignableFrom(clazz)
+ && !Modifier.isAbstract(clazz.getModifiers())) {
+ return clazz;
+ }
+ }
+
+ // Not declared on this class, looking at the parent
+ if (null == clientClass.getSuperclass()) {
return null;
+ } else {
+ return getBuilderClass(clientClass.getSuperclass());
}
+ }
- T client;
+ protected <B extends SlingClient.InternalBuilder, T extends SlingClient> B
getBuilder(Class<T> clientClass, URI url, String user, String password) {
+ Class<B> builderClass = getBuilderClass(clientClass);
+ B builder;
try {
- client = constructor.newInstance(configuration.getUrl(), user,
pass);
- } catch (Exception e) {
+ Method create = builderClass.getMethod("create", URI.class,
String.class, String.class);
+ builder = (B) create.invoke(null, url, user, password);
+ } catch (NoSuchMethodException e) {
+ return null;
+ } catch (IllegalAccessException e) {
+ return null;
+ } catch (InvocationTargetException e) {
return null;
}
- return client;
+ // return the customized builder
+ return customize(builder);
}
/**
* {@inheritDoc}
*/
@Override
- public <T extends SlingClient> T getAdminClient(Class<T> clientClass) {
- return getClient(clientClass, getConfiguration().getAdminUser(),
getConfiguration().getAdminPassword());
+ public SlingClient newAdminClient(BuilderCustomizer... customizers) {
+ return newClient(SlingClient.class, getConfiguration().getAdminUser(),
getConfiguration().getAdminPassword(), customizers);
}
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public <T extends SlingClient> T getClient(Class<T> clientClass, String
user, String pass) {
+ if (clientsCache.containsKey(user + pass)) {
+ try {
+ return clientsCache.get(user + pass).adaptTo(clientClass);
+ } catch (ClientException e) {
+ return null;
+ }
+ } else {
+ return newClient(clientClass, user, pass);
+ }
+ }
/**
* {@inheritDoc}
*/
@Override
public SlingClient getAdminClient() {
- return getAdminClient(SlingClient.class);
+ return getAdminClient(SlingClient.class);
}
-
-
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public <T extends SlingClient> T getAdminClient(Class<T> clientClass) {
+ return getClient(clientClass, getConfiguration().getAdminUser(),
getConfiguration().getAdminPassword());
+ }
}
diff --git
a/src/main/java/org/apache/sling/testing/junit/rules/instance/BuilderCustomizer.java
b/src/main/java/org/apache/sling/testing/junit/rules/instance/BuilderCustomizer.java
new file mode 100644
index 0000000..b53b1f3
--- /dev/null
+++
b/src/main/java/org/apache/sling/testing/junit/rules/instance/BuilderCustomizer.java
@@ -0,0 +1,26 @@
+/*
+ * 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.junit.rules.instance;
+
+import org.apache.sling.testing.clients.SlingClient;
+
+/**
+ * Customizes a Sling Client Builder.
+ */
+public interface BuilderCustomizer {
+ <T extends SlingClient.InternalBuilder> T customize(T builder);
+}
diff --git
a/src/main/java/org/apache/sling/testing/junit/rules/instance/Instance.java
b/src/main/java/org/apache/sling/testing/junit/rules/instance/Instance.java
index 0f92ff2..d12cb47 100644
--- a/src/main/java/org/apache/sling/testing/junit/rules/instance/Instance.java
+++ b/src/main/java/org/apache/sling/testing/junit/rules/instance/Instance.java
@@ -21,7 +21,9 @@ import
org.apache.sling.testing.clients.instance.InstanceConfiguration;
import org.apache.sling.testing.clients.instance.InstanceSetup;
import org.junit.rules.TestRule;
-public interface Instance extends TestRule {
+import java.beans.Customizer;
+
+public interface Instance extends TestRule, BuilderCustomizer {
Instance withRunMode(String runMode);
@@ -31,6 +33,7 @@ public interface Instance extends TestRule {
/**
* Return <strong>a new client</strong> pointing to the instance
corresponding to this {{AbstractInstance}}
+ * if it was never created with this username and password, or the
existing client if it has been created before
*
* @param clientClass the class of the returned client
* @param user the username used in the client
@@ -42,7 +45,8 @@ public interface Instance extends TestRule {
/**
* Return <strong>a new client</strong> pointing to the instance
corresponding to this {{AbstractInstance}},
- * with the admin user and password.
+ * with the admin user and password, if it was not previously created, or
the existing client if it has been created before
+ *
* See {@link InstanceSetup#INSTANCE_CONFIG_ADMINUSER} and {@link
InstanceSetup#INSTANCE_CONFIG_ADMINPASSWORD}
*
* @return a new {{SlingClient}}
@@ -51,7 +55,8 @@ public interface Instance extends TestRule {
/**
* Return <strong>a new client</strong> pointing to the instance
corresponding to this {{AbstractInstance}},
- * with the admin user and password.
+ * with the admin user and password, if it was not previously created, or
the existing client if it has been created before
+ *
* See {@link InstanceSetup#INSTANCE_CONFIG_ADMINUSER} and {@link
InstanceSetup#INSTANCE_CONFIG_ADMINPASSWORD}
*
* @param clientClass the class of the returned client
@@ -60,4 +65,28 @@ public interface Instance extends TestRule {
*/
<T extends SlingClient> T getAdminClient(Class<T> clientClass);
+
+
+ /**
+ * Return <strong>a new client</strong> pointing to the instance
corresponding to this {{AbstractInstance}},
+ * replacing the internally-cached client with this username and password
+ *
+ * @param clientClass the class of the returned client
+ * @param user the username used in the client
+ * @param pass the password used in the client
+ * @param <T> the type of the returned client
+ * @return a new client extending {{SlingClient}}
+ */
+ <T extends SlingClient> T newClient(Class<T> clientClass, String user,
String pass, BuilderCustomizer... customizers);
+
+ /**
+ * Return <strong>a new client</strong> pointing to the instance
corresponding to this {{AbstractInstance}},
+ * replacing the internally-cached client with this username and password
+ *
+ * See {@link InstanceSetup#INSTANCE_CONFIG_ADMINUSER} and {@link
InstanceSetup#INSTANCE_CONFIG_ADMINPASSWORD}
+ *
+ * @return a new {{SlingClient}}
+ */
+ SlingClient newAdminClient(BuilderCustomizer... customizers);
+
}
--
To stop receiving notification emails like this one, please contact
['"[email protected]" <[email protected]>'].