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());
++        }
++    }
++}