You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@syncope.apache.org by il...@apache.org on 2015/02/16 09:07:20 UTC
[55/59] [abbrv] syncope git commit: [SYNCOPE-641] Merging provided
patch + test class
[SYNCOPE-641] Merging provided patch + test class
Project: http://git-wip-us.apache.org/repos/asf/syncope/repo
Commit: http://git-wip-us.apache.org/repos/asf/syncope/commit/ce43e695
Tree: http://git-wip-us.apache.org/repos/asf/syncope/tree/ce43e695
Diff: http://git-wip-us.apache.org/repos/asf/syncope/diff/ce43e695
Branch: refs/heads/master
Commit: ce43e69504e23ce9d73f907a9944671d8b5bb6f0
Parents: 5886fdc a111a9e
Author: Francesco Chicchiriccò <il...@apache.org>
Authored: Fri Feb 13 16:03:36 2015 +0100
Committer: Francesco Chicchiriccò <il...@apache.org>
Committed: Fri Feb 13 16:03:36 2015 +0100
----------------------------------------------------------------------
client/lib/pom.xml | 14 +++-
.../client/lib/RestClientFactoryBean.java | 4 +-
.../syncope/client/lib/SyncopeClient.java | 4 +-
.../syncope/client/lib/ConcurrencyTest.java | 71 ++++++++++++++++++++
4 files changed, 89 insertions(+), 4 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/syncope/blob/ce43e695/client/lib/pom.xml
----------------------------------------------------------------------
diff --cc client/lib/pom.xml
index c4886be,0000000..a834ca8
mode 100644,000000..100644
--- a/client/lib/pom.xml
+++ b/client/lib/pom.xml
@@@ -1,79 -1,0 +1,91 @@@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+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.
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <groupId>org.apache.syncope</groupId>
+ <artifactId>syncope-client</artifactId>
+ <version>2.0.0-SNAPSHOT</version>
+ </parent>
+
+ <name>Apache Syncope Client Lib</name>
+ <description>Apache Syncope Client Lib</description>
+ <groupId>org.apache.syncope.client</groupId>
+ <artifactId>syncope-client-lib</artifactId>
+ <packaging>jar</packaging>
+
+ <properties>
+ <rootpom.basedir>${basedir}/../..</rootpom.basedir>
+ </properties>
+
+ <dependencies>
+ <dependency>
+ <groupId>javax.ws.rs</groupId>
+ <artifactId>javax.ws.rs-api</artifactId>
+ </dependency>
+
+ <dependency>
+ <groupId>org.apache.cxf</groupId>
+ <artifactId>cxf-rt-rs-client</artifactId>
+ </dependency>
+
+ <dependency>
+ <groupId>com.fasterxml.jackson.jaxrs</groupId>
+ <artifactId>jackson-jaxrs-json-provider</artifactId>
+ </dependency>
+
+ <dependency>
+ <groupId>org.slf4j</groupId>
+ <artifactId>slf4j-api</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.syncope.common</groupId>
+ <artifactId>syncope-common-rest-api</artifactId>
+ <version>${project.version}</version>
+ </dependency>
++
++ <dependency>
++ <groupId>org.slf4j</groupId>
++ <artifactId>slf4j-simple</artifactId>
++ <version>${slf4j.version}</version>
++ <scope>test</scope>
++ </dependency>
++ <dependency>
++ <groupId>junit</groupId>
++ <artifactId>junit</artifactId>
++ <scope>test</scope>
++ </dependency>
+ </dependencies>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-checkstyle-plugin</artifactId>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-pmd-plugin</artifactId>
+ </plugin>
+ </plugins>
+ </build>
- </project>
++</project>
http://git-wip-us.apache.org/repos/asf/syncope/blob/ce43e695/client/lib/src/main/java/org/apache/syncope/client/lib/RestClientFactoryBean.java
----------------------------------------------------------------------
diff --cc client/lib/src/main/java/org/apache/syncope/client/lib/RestClientFactoryBean.java
index 4d77f2f,0000000..ca1c5d2
mode 100644,000000..100644
--- a/client/lib/src/main/java/org/apache/syncope/client/lib/RestClientFactoryBean.java
+++ b/client/lib/src/main/java/org/apache/syncope/client/lib/RestClientFactoryBean.java
@@@ -1,67 -1,0 +1,67 @@@
+/*
+ * 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.syncope.client.lib;
+
+import javax.ws.rs.core.MediaType;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.cxf.jaxrs.client.JAXRSClientFactoryBean;
+import org.apache.cxf.jaxrs.client.WebClient;
+
+/**
+ * Provides shortcuts for creating JAX-RS service instances via CXF's <tt>JAXRSClientFactoryBean</tt>.
+ */
+public class RestClientFactoryBean extends JAXRSClientFactoryBean {
+
+ /**
+ * Creates an anonymous instance of the given service class, for the given content type.
+ *
+ * @param <T> any service class
+ * @param serviceClass service class reference
- * @param mediaType XML or JSON are suppoorted
++ * @param mediaType XML or JSON are supported
+ * @return anonymous service instance of the given reference class
+ */
+ public <T> T createServiceInstance(final Class<T> serviceClass, final MediaType mediaType) {
+ return createServiceInstance(serviceClass, mediaType, null, null);
+ }
+
+ /**
+ * Creates an authenticated instance of the given service class, for the given content type.
+ *
+ * @param <T> any service class
+ * @param serviceClass service class reference
- * @param mediaType XML or JSON are suppoorted
++ * @param mediaType XML or JSON are supported
+ * @param username username for REST authentication
+ * @param password password for REST authentication
+ * @return anonymous service instance of the given reference class
+ */
+ public <T> T createServiceInstance(
+ final Class<T> serviceClass, final MediaType mediaType, final String username, final String password) {
+
+ if (StringUtils.isNotBlank(username)) {
+ setUsername(username);
+ }
+ if (StringUtils.isNotBlank(password)) {
+ setPassword(password);
+ }
+ setServiceClass(serviceClass);
+ final T serviceInstance = create(serviceClass);
+ WebClient.client(serviceInstance).type(mediaType).accept(mediaType);
+ return serviceInstance;
+ }
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/ce43e695/client/lib/src/main/java/org/apache/syncope/client/lib/SyncopeClient.java
----------------------------------------------------------------------
diff --cc client/lib/src/main/java/org/apache/syncope/client/lib/SyncopeClient.java
index 43c2fea,0000000..2034ce6
mode 100644,000000..100644
--- a/client/lib/src/main/java/org/apache/syncope/client/lib/SyncopeClient.java
+++ b/client/lib/src/main/java/org/apache/syncope/client/lib/SyncopeClient.java
@@@ -1,214 -1,0 +1,216 @@@
+/*
+ * 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.syncope.client.lib;
+
+import javax.ws.rs.core.EntityTag;
+import javax.ws.rs.core.MediaType;
+import org.apache.cxf.jaxrs.client.WebClient;
+import org.apache.syncope.common.lib.search.OrderByClauseBuilder;
+import org.apache.syncope.common.lib.search.RoleFiqlSearchConditionBuilder;
+import org.apache.syncope.common.lib.search.UserFiqlSearchConditionBuilder;
+import org.apache.syncope.common.rest.api.Preference;
+import org.apache.syncope.common.rest.api.RESTHeaders;
+
+/**
+ * Entry point for client access to all REST services exposed by Syncope core; obtain instances via
+ * {@link SyncopeClientFactoryBean}.
+ */
+public class SyncopeClient {
+
+ private final MediaType mediaType;
+
+ private final RestClientFactoryBean restClientFactory;
+
+ private final String username;
+
+ private final String password;
+
+ public SyncopeClient(final MediaType mediaType, final RestClientFactoryBean restClientFactory,
+ final String username, final String password) {
+
+ this.mediaType = mediaType;
+ this.restClientFactory = restClientFactory;
+ this.username = username;
+ this.password = password;
+ }
+
+ /**
+ * Returns a new instance of <tt>UserFiqlSearchConditionBuilder</tt>, for assisted building of FIQL queries.
+ *
+ * @return default instance of <tt>UserFiqlSearchConditionBuilder</tt>
+ */
+ public static UserFiqlSearchConditionBuilder getUserSearchConditionBuilder() {
+ return new UserFiqlSearchConditionBuilder();
+ }
+
+ /**
+ * Returns a new instance of <tt>RoleFiqlSearchConditionBuilder</tt>, for assisted building of FIQL queries.
+ *
+ * @return default instance of <tt>RoleFiqlSearchConditionBuilder</tt>
+ */
+ public static RoleFiqlSearchConditionBuilder getRoleSearchConditionBuilder() {
+ return new RoleFiqlSearchConditionBuilder();
+ }
+
+ /**
+ * Returns a new instance of <tt>OrderByClauseBuilder</tt>, for assisted building of <tt>orderby</tt> clauses.
+ *
+ * @return default instance of <tt>OrderByClauseBuilder</tt>
+ */
+ public static OrderByClauseBuilder getOrderByClauseBuilder() {
+ return new OrderByClauseBuilder();
+ }
+
+ /**
+ * Creates an instance of the given service class, with configured content type and authentication.
+ *
+ * @param <T> any service class
+ * @param serviceClass service class reference
+ * @return service instance of the given reference class
+ */
+ public <T> T getService(final Class<T> serviceClass) {
- return restClientFactory.createServiceInstance(serviceClass, mediaType, username, password);
++ synchronized (restClientFactory) {
++ return restClientFactory.createServiceInstance(serviceClass, mediaType, username, password);
++ }
+ }
+
+ /**
+ * Sets the given header on the give service instance.
+ *
+ * @param <T> any service class
+ * @param service service class instance
+ * @param key HTTP header key
+ * @param values HTTP header values
+ * @return given service instance, with given header set
+ */
+ public <T> T header(final T service, final String key, final Object... values) {
+ WebClient.client(service).header(key, values);
+ return service;
+ }
+
+ /**
+ * Creates an instance of the given service class and sets the given header.
+ *
+ * @param <T> any service class
+ * @param serviceClass service class reference
+ * @param key HTTP header key
+ * @param values HTTP header values
+ * @return service instance of the given reference class, with given header set
+ */
+ public <T> T header(final Class<T> serviceClass, final String key, final Object... values) {
+ return header(getService(serviceClass), key, values);
+ }
+
+ /**
+ * Sets the <tt>Prefer</tt> header on the give service instance.
+ *
+ * @param <T> any service class
+ * @param service service class instance
+ * @param preference preference to be set via <tt>Prefer</tt> header
+ * @return given service instance, with <tt>Prefer</tt> header set
+ */
+ public <T> T prefer(final T service, final Preference preference) {
+ return header(service, RESTHeaders.PREFER, preference.toString());
+ }
+
+ /**
+ * Creates an instance of the given service class, with <tt>Prefer</tt> header set.
+ *
+ * @param <T> any service class
+ * @param serviceClass service class reference
+ * @param preference preference to be set via <tt>Prefer</tt> header
+ * @return service instance of the given reference class, with <tt>Prefer</tt> header set
+ */
+ public <T> T prefer(final Class<T> serviceClass, final Preference preference) {
+ return header(serviceClass, RESTHeaders.PREFER, preference.toString());
+ }
+
+ /**
+ * Sets the <tt>If-Match</tt> or <tt>If-None-Match</tt> header on the given service instance.
+ *
+ * @param <T> any service class
+ * @param service service class instance
+ * @param etag ETag value
+ * @param ifNot if true then <tt>If-None-Match</tt> is set, <tt>If-Match</tt> otherwise
+ * @return given service instance, with <tt>If-Match</tt> or <tt>If-None-Match</tt> set
+ */
+ private <T> T match(final T service, final EntityTag etag, final boolean ifNot) {
+ WebClient.client(service).match(etag, ifNot);
+ return service;
+ }
+
+ /**
+ * Sets the <tt>If-Match</tt> header on the given service instance.
+ *
+ * @param <T> any service class
+ * @param service service class instance
+ * @param etag ETag value
+ * @return given service instance, with <tt>If-Match</tt> set
+ */
+ public <T> T ifMatch(final T service, final EntityTag etag) {
+ return match(service, etag, false);
+ }
+
+ /**
+ * Creates an instance of the given service class, with <tt>If-Match</tt> header set.
+ *
+ * @param <T> any service class
+ * @param serviceClass service class reference
+ * @param etag ETag value
+ * @return given service instance, with <tt>If-Match</tt> set
+ */
+ public <T> T ifMatch(final Class<T> serviceClass, final EntityTag etag) {
+ return match(getService(serviceClass), etag, false);
+ }
+
+ /**
+ * Sets the <tt>If-None-Match</tt> header on the given service instance.
+ *
+ * @param <T> any service class
+ * @param service service class instance
+ * @param etag ETag value
+ * @return given service instance, with <tt>If-None-Match</tt> set
+ */
+ public <T> T ifNoneMatch(final T service, final EntityTag etag) {
+ return match(service, etag, true);
+ }
+
+ /**
+ * Creates an instance of the given service class, with <tt>If-None-Match</tt> header set.
+ *
+ * @param <T> any service class
+ * @param serviceClass service class reference
+ * @param etag ETag value
+ * @return given service instance, with <tt>If-None-Match</tt> set
+ */
+ public <T> T ifNoneMatch(final Class<T> serviceClass, final EntityTag etag) {
+ return match(getService(serviceClass), etag, true);
+ }
+
+ /**
+ * Fetches <tt>ETag</tt> header value from latest service run (if available).
+ *
+ * @param <T> any service class
+ * @param service service class instance
+ * @return <tt>ETag</tt> header value from latest service run (if available)
+ */
+ public <T> EntityTag getLatestEntityTag(final T service) {
+ return WebClient.client(service).getResponse().getEntityTag();
+ }
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/ce43e695/client/lib/src/test/java/org/apache/syncope/client/lib/ConcurrencyTest.java
----------------------------------------------------------------------
diff --cc client/lib/src/test/java/org/apache/syncope/client/lib/ConcurrencyTest.java
index 0000000,0000000..4657b2f
new file mode 100644
--- /dev/null
+++ b/client/lib/src/test/java/org/apache/syncope/client/lib/ConcurrencyTest.java
@@@ -1,0 -1,0 +1,71 @@@
++/*
++ * 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.syncope.client.lib;
++
++import static org.junit.Assert.fail;
++
++import org.apache.commons.lang3.StringUtils;
++import org.apache.syncope.common.rest.api.service.ResourceService;
++import org.junit.Test;
++import org.slf4j.Logger;
++import org.slf4j.LoggerFactory;
++
++public class ConcurrencyTest {
++
++ private static final Logger LOG = LoggerFactory.getLogger(ConcurrencyTest.class);
++
++ private static final SyncopeClient client =
++ new SyncopeClientFactoryBean().setAddress("http://url").create("username", "password");
++
++ @Test
++ public void multiThreadTest()
++ throws InterruptedException {
++
++ for (int i = 0; i < 10000; i++) {
++ Thread execution = new Thread("Th-" + StringUtils.leftPad(String.valueOf(i), 5, '0')) {
++
++ @Override
++ public void run() {
++
++ try {
++ client.getService(ResourceService.class);
++
++ LOG.info(getName() + " completed successfully!");
++ } catch (Exception e) {
++ LOG.error(getName() + " did not complete", e);
++ }
++ }
++ };
++ execution.start();
++ }
++
++ Thread.sleep(10000);
++ }
++
++ @Test
++ public void multiCallTest() {
++ try {
++ for (int i = 0; i < 10000; i++) {
++ client.getService(ResourceService.class);
++ }
++ } catch (Exception e) {
++ fail(e.getMessage());
++ }
++ }
++}