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 2018/08/02 15:24:41 UTC
[8/9] syncope git commit: [SYNCOPE-1348] Batch is in,
now need to kick Bulk out
[SYNCOPE-1348] Batch is in, now need to kick Bulk out
Project: http://git-wip-us.apache.org/repos/asf/syncope/repo
Commit: http://git-wip-us.apache.org/repos/asf/syncope/commit/d9250efa
Tree: http://git-wip-us.apache.org/repos/asf/syncope/tree/d9250efa
Diff: http://git-wip-us.apache.org/repos/asf/syncope/diff/d9250efa
Branch: refs/heads/master
Commit: d9250efade3793edeb35be10f72890a98090438c
Parents: d2ff6e4
Author: Francesco Chicchiriccò <il...@apache.org>
Authored: Thu Aug 2 17:23:43 2018 +0200
Committer: Francesco Chicchiriccò <il...@apache.org>
Committed: Thu Aug 2 17:23:53 2018 +0200
----------------------------------------------------------------------
.../syncope/client/lib/SyncopeClient.java | 9 +
.../client/lib/SyncopeClientFactoryBean.java | 3 +-
.../lib/batch/BatchClientFactoryBean.java | 89 +++++
.../client/lib/batch/BatchClientProxyImpl.java | 83 +++++
.../lib/batch/BatchOfflineHTTPConduit.java | 77 +++++
.../syncope/client/lib/batch/BatchRequest.java | 102 ++++++
.../syncope/client/lib/batch/BatchResponse.java | 95 +++++
.../syncope/common/lib/SyncopeConstants.java | 5 +-
.../syncope/common/rest/api/Preference.java | 3 +-
.../syncope/common/rest/api/RESTHeaders.java | 36 +-
.../common/rest/api/batch/BatchItem.java | 57 +++
.../rest/api/batch/BatchPayloadGenerator.java | 78 +++++
.../common/rest/api/batch/BatchPayloadLine.java | 53 +++
.../rest/api/batch/BatchPayloadLineReader.java | 193 +++++++++++
.../rest/api/batch/BatchPayloadParser.java | 208 +++++++++++
.../common/rest/api/batch/BatchRequestItem.java | 54 +++
.../rest/api/batch/BatchResponseItem.java | 34 ++
.../rest/api/service/AccessTokenService.java | 13 +-
.../rest/api/service/AnyObjectService.java | 13 +-
.../common/rest/api/service/AnyService.java | 29 +-
.../rest/api/service/AnyTypeClassService.java | 15 +-
.../common/rest/api/service/AnyTypeService.java | 11 +-
.../rest/api/service/ApplicationService.java | 17 +-
.../rest/api/service/ConfigurationService.java | 12 +-
.../api/service/ConnectorHistoryService.java | 8 +-
.../rest/api/service/ConnectorService.java | 29 +-
.../common/rest/api/service/DomainService.java | 15 +-
.../rest/api/service/DynRealmService.java | 15 +-
.../rest/api/service/ExecutableService.java | 16 +-
.../common/rest/api/service/GroupService.java | 17 +-
.../rest/api/service/ImplementationService.java | 16 +-
.../common/rest/api/service/LoggerService.java | 18 +-
.../rest/api/service/MailTemplateService.java | 15 +-
.../rest/api/service/NotificationService.java | 19 +-
.../common/rest/api/service/PolicyService.java | 15 +-
.../common/rest/api/service/RealmService.java | 15 +-
.../rest/api/service/ReconciliationService.java | 12 +-
.../api/service/RelationshipTypeService.java | 15 +-
.../rest/api/service/RemediationService.java | 17 +-
.../common/rest/api/service/ReportService.java | 17 +-
.../rest/api/service/ReportTemplateService.java | 9 +-
.../api/service/ResourceHistoryService.java | 8 +-
.../rest/api/service/ResourceService.java | 33 +-
.../common/rest/api/service/RoleService.java | 19 +-
.../common/rest/api/service/SchemaService.java | 15 +-
.../api/service/SecurityQuestionService.java | 19 +-
.../common/rest/api/service/SyncopeService.java | 76 +++-
.../common/rest/api/service/TaskService.java | 19 +-
.../rest/api/service/UserSelfService.java | 27 +-
.../common/rest/api/service/UserService.java | 17 +-
.../rest/api/service/UserWorkflowService.java | 16 +-
.../rest/api/service/WorkflowService.java | 11 +-
.../core/persistence/api/dao/BatchDAO.java | 32 ++
.../core/persistence/api/entity/Batch.java | 32 ++
.../core/persistence/jpa/dao/JPABatchDAO.java | 62 ++++
.../core/persistence/jpa/entity/JPABatch.java | 68 ++++
.../jpa/entity/JPAEntityFactory.java | 3 +
.../main/resources/domains/MasterContent.xml | 4 +
.../jpa/inner/ImplementationTest.java | 4 +-
.../core/persistence/jpa/inner/TaskTest.java | 2 +-
.../test/resources/domains/MasterContent.xml | 4 +
.../java/data/AccessTokenDataBinderImpl.java | 6 +-
.../java/job/ExpiredBatchCleanup.java | 39 +++
core/rest-cxf/pom.xml | 11 +
.../core/rest/cxf/batch/BatchItemRequest.java | 145 ++++++++
.../core/rest/cxf/batch/BatchItemResponse.java | 310 +++++++++++++++++
.../core/rest/cxf/batch/BatchProcess.java | 144 ++++++++
.../rest/cxf/service/AbstractServiceImpl.java | 7 +-
.../rest/cxf/service/SyncopeServiceImpl.java | 129 +++++++
.../src/main/resources/restCXFContext.xml | 7 +-
.../rest/api/service/CamelRouteService.java | 14 +-
.../rest/api/service/OIDCClientService.java | 8 +-
.../rest/api/service/OIDCProviderService.java | 21 +-
.../rest/api/service/SAML2IdPService.java | 14 +-
.../common/rest/api/service/SAML2SPService.java | 14 +-
.../rest/api/service/SCIMConfService.java | 8 +-
fit/core-reference/pom.xml | 2 +-
.../src/main/resources/jboss/restCXFContext.xml | 7 +-
.../apache/syncope/fit/core/BatchITCase.java | 345 +++++++++++++++++++
pom.xml | 2 +-
80 files changed, 2898 insertions(+), 363 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/syncope/blob/d9250efa/client/lib/src/main/java/org/apache/syncope/client/lib/SyncopeClient.java
----------------------------------------------------------------------
diff --git 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
index 7675f0a..a614dd1 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
@@ -18,6 +18,7 @@
*/
package org.apache.syncope.client.lib;
+import org.apache.syncope.client.lib.batch.BatchRequest;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.io.IOException;
@@ -358,4 +359,12 @@ public class SyncopeClient {
public <T> EntityTag getLatestEntityTag(final T service) {
return WebClient.client(service).getResponse().getEntityTag();
}
+
+ public BatchRequest batch() {
+ return new BatchRequest(
+ mediaType,
+ restClientFactory.getAddress(),
+ restClientFactory.getProviders(),
+ getJWT());
+ }
}
http://git-wip-us.apache.org/repos/asf/syncope/blob/d9250efa/client/lib/src/main/java/org/apache/syncope/client/lib/SyncopeClientFactoryBean.java
----------------------------------------------------------------------
diff --git a/client/lib/src/main/java/org/apache/syncope/client/lib/SyncopeClientFactoryBean.java b/client/lib/src/main/java/org/apache/syncope/client/lib/SyncopeClientFactoryBean.java
index d0ee76a..90105d0 100644
--- a/client/lib/src/main/java/org/apache/syncope/client/lib/SyncopeClientFactoryBean.java
+++ b/client/lib/src/main/java/org/apache/syncope/client/lib/SyncopeClientFactoryBean.java
@@ -34,7 +34,6 @@ import org.apache.cxf.ext.logging.LoggingFeature;
import org.apache.cxf.jaxrs.client.JAXRSClientFactoryBean;
import org.apache.cxf.jaxrs.provider.JAXBElementProvider;
import org.apache.cxf.staxutils.DocumentDepthProperties;
-import org.apache.syncope.common.lib.SyncopeConstants;
import org.apache.syncope.common.lib.policy.PolicyTO;
import org.apache.syncope.common.rest.api.DateParamConverterProvider;
import org.apache.syncope.common.rest.api.RESTHeaders;
@@ -48,7 +47,7 @@ public class SyncopeClientFactoryBean {
public enum ContentType {
JSON(MediaType.APPLICATION_JSON_TYPE),
- YAML(SyncopeConstants.APPLICATION_YAML_TYPE),
+ YAML(RESTHeaders.APPLICATION_YAML_TYPE),
XML(MediaType.APPLICATION_XML_TYPE);
private final MediaType mediaType;
http://git-wip-us.apache.org/repos/asf/syncope/blob/d9250efa/client/lib/src/main/java/org/apache/syncope/client/lib/batch/BatchClientFactoryBean.java
----------------------------------------------------------------------
diff --git a/client/lib/src/main/java/org/apache/syncope/client/lib/batch/BatchClientFactoryBean.java b/client/lib/src/main/java/org/apache/syncope/client/lib/batch/BatchClientFactoryBean.java
new file mode 100644
index 0000000..a8858dc
--- /dev/null
+++ b/client/lib/src/main/java/org/apache/syncope/client/lib/batch/BatchClientFactoryBean.java
@@ -0,0 +1,89 @@
+/*
+ * 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.batch;
+
+import java.io.IOException;
+import java.net.URI;
+import java.util.ArrayList;
+import java.util.List;
+import org.apache.cxf.endpoint.ConduitSelector;
+import org.apache.cxf.endpoint.Endpoint;
+import org.apache.cxf.endpoint.UpfrontConduitSelector;
+import org.apache.cxf.jaxrs.client.ClientProxyImpl;
+import org.apache.cxf.jaxrs.client.ClientState;
+import org.apache.cxf.jaxrs.client.JAXRSClientFactoryBean;
+import org.apache.cxf.jaxrs.model.ClassResourceInfo;
+import org.apache.syncope.common.rest.api.batch.BatchRequestItem;
+
+public class BatchClientFactoryBean extends JAXRSClientFactoryBean {
+
+ private final List<BatchRequestItem> batchRequestItems = new ArrayList<>();
+
+ private ClassLoader proxyLoader;
+
+ private boolean inheritHeaders;
+
+ @Override
+ public void setClassLoader(final ClassLoader loader) {
+ this.proxyLoader = loader;
+ }
+
+ @Override
+ public void setInheritHeaders(final boolean inheritHeaders) {
+ this.inheritHeaders = inheritHeaders;
+ }
+
+ @Override
+ protected ConduitSelector getConduitSelector(final Endpoint ep) {
+ ConduitSelector cs = getConduitSelector();
+ if (cs == null) {
+ try {
+ cs = new UpfrontConduitSelector(new BatchOfflineHTTPConduit(bus, ep.getEndpointInfo()));
+ } catch (IOException e) {
+ throw new IllegalArgumentException("Could not create " + BatchOfflineHTTPConduit.class.getName(), e);
+ }
+ }
+ cs.setEndpoint(ep);
+ return cs;
+ }
+
+ @Override
+ protected ClientProxyImpl createClientProxy(
+ final ClassResourceInfo cri,
+ final boolean isRoot,
+ final ClientState actualState,
+ final Object[] varValues) {
+
+ if (actualState == null) {
+ return new BatchClientProxyImpl(
+ this, URI.create(getAddress()), proxyLoader, cri, isRoot, inheritHeaders, varValues);
+ } else {
+ return new BatchClientProxyImpl(
+ this, actualState, proxyLoader, cri, isRoot, inheritHeaders, varValues);
+ }
+ }
+
+ public boolean add(final BatchRequestItem item) {
+ return this.batchRequestItems.add(item);
+ }
+
+ public List<BatchRequestItem> getBatchRequestItems() {
+ return batchRequestItems;
+ }
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/d9250efa/client/lib/src/main/java/org/apache/syncope/client/lib/batch/BatchClientProxyImpl.java
----------------------------------------------------------------------
diff --git a/client/lib/src/main/java/org/apache/syncope/client/lib/batch/BatchClientProxyImpl.java b/client/lib/src/main/java/org/apache/syncope/client/lib/batch/BatchClientProxyImpl.java
new file mode 100644
index 0000000..3e736e0
--- /dev/null
+++ b/client/lib/src/main/java/org/apache/syncope/client/lib/batch/BatchClientProxyImpl.java
@@ -0,0 +1,83 @@
+/*
+ * 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.batch;
+
+import java.net.URI;
+import java.nio.charset.StandardCharsets;
+import java.util.List;
+import java.util.Map;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.cxf.jaxrs.client.ClientProxyImpl;
+import org.apache.cxf.jaxrs.client.ClientState;
+import org.apache.cxf.jaxrs.model.ClassResourceInfo;
+import org.apache.cxf.message.Message;
+import org.apache.syncope.common.rest.api.batch.BatchRequestItem;
+
+public class BatchClientProxyImpl extends ClientProxyImpl {
+
+ private final BatchClientFactoryBean factory;
+
+ public BatchClientProxyImpl(
+ final BatchClientFactoryBean factory,
+ final URI baseURI,
+ final ClassLoader loader,
+ final ClassResourceInfo cri,
+ final boolean isRoot,
+ final boolean inheritHeaders,
+ final Object... varValues) {
+
+ super(baseURI, loader, cri, isRoot, inheritHeaders, varValues);
+ this.factory = factory;
+ }
+
+ public BatchClientProxyImpl(
+ final BatchClientFactoryBean factory,
+ final ClientState initialState,
+ final ClassLoader loader,
+ final ClassResourceInfo cri,
+ final boolean isRoot,
+ final boolean inheritHeaders,
+ final Object... varValues) {
+
+ super(initialState, loader, cri, isRoot, inheritHeaders, varValues);
+ this.factory = factory;
+ }
+
+ @Override
+ @SuppressWarnings("unchecked")
+ protected Object[] preProcessResult(final Message message) throws Exception {
+ BatchRequestItem bri = new BatchRequestItem();
+ bri.setMethod((String) message.get(Message.HTTP_REQUEST_METHOD));
+ bri.setRequestURI(StringUtils.substringAfter(
+ (String) message.getContextualProperty(Message.REQUEST_URI),
+ getState().getBaseURI().toASCIIString()));
+ bri.setHeaders((Map<String, List<Object>>) message.get(Message.PROTOCOL_HEADERS));
+
+ BatchOfflineHTTPConduit conduit = (BatchOfflineHTTPConduit) message.getExchange().getConduit(message);
+ bri.setContent(conduit.getOutputStream().toString(StandardCharsets.UTF_8.name()));
+
+ factory.add(bri);
+ return null;
+ }
+
+ @Override
+ protected Object handleResponse(final Message outMessage, final Class<?> serviceCls) throws Throwable {
+ return null;
+ }
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/d9250efa/client/lib/src/main/java/org/apache/syncope/client/lib/batch/BatchOfflineHTTPConduit.java
----------------------------------------------------------------------
diff --git a/client/lib/src/main/java/org/apache/syncope/client/lib/batch/BatchOfflineHTTPConduit.java b/client/lib/src/main/java/org/apache/syncope/client/lib/batch/BatchOfflineHTTPConduit.java
new file mode 100644
index 0000000..e4587be
--- /dev/null
+++ b/client/lib/src/main/java/org/apache/syncope/client/lib/batch/BatchOfflineHTTPConduit.java
@@ -0,0 +1,77 @@
+/*
+ * 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.batch;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+import org.apache.cxf.Bus;
+import org.apache.cxf.configuration.security.ProxyAuthorizationPolicy;
+import org.apache.cxf.message.Message;
+import org.apache.cxf.service.model.EndpointInfo;
+import org.apache.cxf.transport.http.Address;
+import org.apache.cxf.transport.http.HTTPConduit;
+import org.apache.cxf.transport.http.auth.DefaultBasicAuthSupplier;
+import org.apache.cxf.transports.http.configuration.HTTPClientPolicy;
+import org.apache.cxf.ws.addressing.EndpointReferenceType;
+
+public class BatchOfflineHTTPConduit extends HTTPConduit {
+
+ private ByteArrayOutputStream baos;
+
+ public BatchOfflineHTTPConduit(final Bus bus, final EndpointInfo ei) throws IOException {
+ this(bus, ei, null);
+ }
+
+ public BatchOfflineHTTPConduit(
+ final Bus bus,
+ final EndpointInfo ei,
+ final EndpointReferenceType t) throws IOException {
+
+ super(bus, ei, t);
+ this.proxyAuthSupplier = new DefaultBasicAuthSupplier();
+ this.proxyAuthorizationPolicy = new ProxyAuthorizationPolicy();
+ }
+
+ @Override
+ protected void setupConnection(
+ final Message message, final Address address,
+ final HTTPClientPolicy csPolicy) throws IOException {
+ }
+
+ @Override
+ public HTTPClientPolicy getClient(final Message message) {
+ return new HTTPClientPolicy();
+ }
+
+ @Override
+ protected OutputStream createOutputStream(
+ final Message message,
+ final boolean needToCacheRequest,
+ final boolean isChunking,
+ final int chunkThreshold) throws IOException {
+
+ baos = new ByteArrayOutputStream();
+ return baos;
+ }
+
+ public ByteArrayOutputStream getOutputStream() {
+ return baos;
+ }
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/d9250efa/client/lib/src/main/java/org/apache/syncope/client/lib/batch/BatchRequest.java
----------------------------------------------------------------------
diff --git a/client/lib/src/main/java/org/apache/syncope/client/lib/batch/BatchRequest.java b/client/lib/src/main/java/org/apache/syncope/client/lib/batch/BatchRequest.java
new file mode 100644
index 0000000..580c95a
--- /dev/null
+++ b/client/lib/src/main/java/org/apache/syncope/client/lib/batch/BatchRequest.java
@@ -0,0 +1,102 @@
+/*
+ * 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.batch;
+
+import java.util.List;
+import java.util.UUID;
+import javax.ws.rs.core.HttpHeaders;
+import javax.ws.rs.core.MediaType;
+import org.apache.cxf.jaxrs.client.Client;
+import org.apache.cxf.jaxrs.client.WebClient;
+import org.apache.syncope.common.rest.api.Preference;
+import org.apache.syncope.common.rest.api.RESTHeaders;
+import org.apache.syncope.common.rest.api.batch.BatchPayloadGenerator;
+import org.apache.syncope.common.rest.api.batch.BatchRequestItem;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class BatchRequest {
+
+ private static final Logger LOG = LoggerFactory.getLogger(BatchRequest.class);
+
+ private final MediaType mediaType;
+
+ private final String jwt;
+
+ private final String address;
+
+ private final List<?> providers;
+
+ private BatchClientFactoryBean bcfb;
+
+ public BatchRequest(
+ final MediaType mediaType,
+ final String address,
+ final List<?> providers,
+ final String jwt) {
+
+ this.mediaType = mediaType;
+ this.jwt = jwt;
+ this.address = address;
+ this.providers = providers;
+ initBatchClientFactoryBean();
+ }
+
+ private void initBatchClientFactoryBean() {
+ this.bcfb = new BatchClientFactoryBean();
+ this.bcfb.setAddress(address);
+ this.bcfb.setProviders(providers);
+ }
+
+ public <T> T getService(final Class<T> serviceClass) {
+ bcfb.setServiceClass(serviceClass);
+ T serviceInstance = bcfb.create(serviceClass);
+
+ Client client = WebClient.client(serviceInstance);
+ client.type(mediaType).accept(mediaType);
+
+ return serviceInstance;
+ }
+
+ public List<BatchRequestItem> getItems() {
+ return bcfb.getBatchRequestItems();
+ }
+
+ public BatchResponse commit() {
+ return commit(false);
+ }
+
+ public BatchResponse commit(final boolean async) {
+ String boundary = "--batch_" + UUID.randomUUID().toString();
+
+ WebClient webClient = WebClient.create(bcfb.getAddress()).path("batch").
+ header(HttpHeaders.AUTHORIZATION, "Bearer " + jwt).
+ type(RESTHeaders.multipartMixedWith(boundary.substring(2)));
+ if (async) {
+ webClient.header(RESTHeaders.PREFER, Preference.RESPOND_ASYNC);
+ }
+
+ String body = BatchPayloadGenerator.generate(bcfb.getBatchRequestItems(), boundary);
+ LOG.debug("Batch request body:\n{}", body);
+
+ initBatchClientFactoryBean();
+
+ return new BatchResponse(boundary, jwt, webClient.post(body));
+ }
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/d9250efa/client/lib/src/main/java/org/apache/syncope/client/lib/batch/BatchResponse.java
----------------------------------------------------------------------
diff --git a/client/lib/src/main/java/org/apache/syncope/client/lib/batch/BatchResponse.java b/client/lib/src/main/java/org/apache/syncope/client/lib/batch/BatchResponse.java
new file mode 100644
index 0000000..89cd0e7
--- /dev/null
+++ b/client/lib/src/main/java/org/apache/syncope/client/lib/batch/BatchResponse.java
@@ -0,0 +1,95 @@
+/*
+ * 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.batch;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URI;
+import java.nio.charset.StandardCharsets;
+import java.util.List;
+import javax.ws.rs.core.HttpHeaders;
+import javax.ws.rs.core.Response;
+import org.apache.cxf.helpers.IOUtils;
+import org.apache.cxf.jaxrs.client.WebClient;
+import org.apache.syncope.common.rest.api.RESTHeaders;
+import org.apache.syncope.common.rest.api.batch.BatchPayloadParser;
+import org.apache.syncope.common.rest.api.batch.BatchResponseItem;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class BatchResponse {
+
+ private static final Logger LOG = LoggerFactory.getLogger(BatchResponse.class);
+
+ private final String boundary;
+
+ private final String jwt;
+
+ private final URI monitor;
+
+ private Response response;
+
+ public BatchResponse(final String boundary, final String jwt, final Response response) {
+ this.boundary = boundary;
+ this.jwt = jwt;
+ this.monitor = response.getLocation();
+ this.response = response;
+ }
+
+ /**
+ * Gives the last Response received from the Batch service.
+ *
+ * @return the last Response received from the Batch service
+ */
+ public Response getResponse() {
+ return response;
+ }
+
+ /**
+ * If asynchronous processing was requested, query the monitor URI.
+ *
+ * @return the last Response received from the Batch service
+ */
+ public Response poll() {
+ if (monitor != null) {
+ response = WebClient.create(monitor).
+ header(HttpHeaders.AUTHORIZATION, "Bearer " + jwt).
+ type(RESTHeaders.multipartMixedWith(boundary.substring(2))).get();
+ }
+
+ return response;
+ }
+
+ /**
+ * Parses the latest Response received into a list of {@link BatchResponseItem}s.
+ *
+ * @return the Batch Response parsed as list of {@link BatchResponseItem}s
+ * @throws IOException if there are issues when reading the response body
+ */
+ public List<BatchResponseItem> getItems() throws IOException {
+ String body = IOUtils.toString((InputStream) response.getEntity(), StandardCharsets.UTF_8.name());
+ LOG.debug("Batch response body:\n{}", body);
+
+ return BatchPayloadParser.parse(
+ new ByteArrayInputStream(body.getBytes()),
+ response.getMediaType(),
+ new BatchResponseItem());
+ }
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/d9250efa/common/lib/src/main/java/org/apache/syncope/common/lib/SyncopeConstants.java
----------------------------------------------------------------------
diff --git a/common/lib/src/main/java/org/apache/syncope/common/lib/SyncopeConstants.java b/common/lib/src/main/java/org/apache/syncope/common/lib/SyncopeConstants.java
index 517e775..b8a7ee4 100644
--- a/common/lib/src/main/java/org/apache/syncope/common/lib/SyncopeConstants.java
+++ b/common/lib/src/main/java/org/apache/syncope/common/lib/SyncopeConstants.java
@@ -21,7 +21,6 @@ package org.apache.syncope.common.lib;
import java.util.Collections;
import java.util.Set;
import java.util.regex.Pattern;
-import javax.ws.rs.core.MediaType;
public final class SyncopeConstants {
@@ -64,9 +63,9 @@ public final class SyncopeConstants {
public static final Pattern UUID_PATTERN = Pattern.compile(UUID_REGEX);
- public static final String APPLICATION_YAML = "application/yaml";
+ public static final String DOUBLE_DASH = "--";
- public static final MediaType APPLICATION_YAML_TYPE = new MediaType("application", "yaml");
+ public static final String CRLF = "\r\n";
private SyncopeConstants() {
// private constructor for utility class
http://git-wip-us.apache.org/repos/asf/syncope/blob/d9250efa/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/Preference.java
----------------------------------------------------------------------
diff --git a/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/Preference.java b/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/Preference.java
index 8d21e54..a2e6fb2 100644
--- a/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/Preference.java
+++ b/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/Preference.java
@@ -28,7 +28,8 @@ public enum Preference {
NONE(""),
RETURN_CONTENT("return-content"),
- RETURN_NO_CONTENT("return-no-content");
+ RETURN_NO_CONTENT("return-no-content"),
+ RESPOND_ASYNC("respond-async");
private final String literal;
http://git-wip-us.apache.org/repos/asf/syncope/blob/d9250efa/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/RESTHeaders.java
----------------------------------------------------------------------
diff --git a/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/RESTHeaders.java b/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/RESTHeaders.java
index 40cd8ba..f993317 100644
--- a/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/RESTHeaders.java
+++ b/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/RESTHeaders.java
@@ -18,6 +18,8 @@
*/
package org.apache.syncope.common.rest.api;
+import javax.ws.rs.core.MediaType;
+
/**
* Custom HTTP headers in use with REST services.
*/
@@ -51,13 +53,41 @@ public final class RESTHeaders {
public static final String ERROR_INFO = "X-Application-Error-Info";
/**
- * Mediatype for PNG images, not defined in <tt>javax.ws.rs.core.MediaType</tt>.
- *
- * @see javax.ws.rs.core.MediaType
+ * Mediatype for PNG images, not defined in {@link javax.ws.rs.core.MediaType}.
*/
public static final String MEDIATYPE_IMAGE_PNG = "image/png";
/**
+ * Mediatype for YAML, not defined in {@link javax.ws.rs.core.MediaType}.
+ */
+ public static final String APPLICATION_YAML = "application/yaml";
+
+ /**
+ * Mediatype for YAML, not defined in {@link javax.ws.rs.core.MediaType}.
+ */
+ public static final MediaType APPLICATION_YAML_TYPE = new MediaType("application", "yaml");
+
+ /**
+ * Mediatype for multipart/mixed, not defined in {@link javax.ws.rs.core.MediaType}.
+ */
+ public static final String MULTIPART_MIXED = "multipart/mixed";
+
+ /**
+ * The boundary parameter name for multipart, not defined in {@link javax.ws.rs.core.MediaType}.
+ */
+ public static final String BOUNDARY_PARAMETER = "boundary";
+
+ /**
+ * Builds Content-Type string for multipart/mixed and the given boundary.
+ *
+ * @param boundary multipart boundary value
+ * @return multipart/mixed Content-Type string, with given boundary
+ */
+ public static String multipartMixedWith(final String boundary) {
+ return MULTIPART_MIXED + ";" + BOUNDARY_PARAMETER + "=" + boundary;
+ }
+
+ /**
* Allows the client to specify a preference for the result to be returned from the server.
* <a href="http://msdn.microsoft.com/en-us/library/hh537533.aspx">More information</a>.
*
http://git-wip-us.apache.org/repos/asf/syncope/blob/d9250efa/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/batch/BatchItem.java
----------------------------------------------------------------------
diff --git a/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/batch/BatchItem.java b/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/batch/BatchItem.java
new file mode 100644
index 0000000..561ac6a
--- /dev/null
+++ b/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/batch/BatchItem.java
@@ -0,0 +1,57 @@
+/*
+ * 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.common.rest.api.batch;
+
+import java.io.Serializable;
+import java.util.List;
+import java.util.Map;
+import java.util.TreeMap;
+import org.apache.commons.lang3.builder.ToStringBuilder;
+import org.apache.commons.lang3.builder.ToStringStyle;
+
+public abstract class BatchItem implements Serializable {
+
+ private static final long serialVersionUID = -1393976266651766259L;
+
+ private final Map<String, List<Object>> headers = new TreeMap<>(String.CASE_INSENSITIVE_ORDER);
+
+ private String content;
+
+ public Map<String, List<Object>> getHeaders() {
+ return headers;
+ }
+
+ public void setHeaders(final Map<String, List<Object>> headers) {
+ this.headers.clear();
+ this.headers.putAll(headers);
+ }
+
+ public String getContent() {
+ return content;
+ }
+
+ public void setContent(final String content) {
+ this.content = content;
+ }
+
+ @Override
+ public String toString() {
+ return ToStringBuilder.reflectionToString(this, ToStringStyle.JSON_STYLE);
+ }
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/d9250efa/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/batch/BatchPayloadGenerator.java
----------------------------------------------------------------------
diff --git a/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/batch/BatchPayloadGenerator.java b/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/batch/BatchPayloadGenerator.java
new file mode 100644
index 0000000..18d5f64
--- /dev/null
+++ b/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/batch/BatchPayloadGenerator.java
@@ -0,0 +1,78 @@
+/*
+ * 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.common.rest.api.batch;
+
+import java.util.List;
+import javax.ws.rs.core.HttpHeaders;
+import javax.ws.rs.core.Response;
+import org.apache.syncope.common.lib.SyncopeConstants;
+
+public final class BatchPayloadGenerator {
+
+ private static final String HTTP_1_1 = "HTTP/1.1";
+
+ public static <T extends BatchItem> String generate(final List<T> items, final String boundary) {
+ StringBuilder payload = new StringBuilder();
+
+ items.forEach(item -> {
+ payload.append(boundary).append(SyncopeConstants.CRLF);
+ payload.append(HttpHeaders.CONTENT_TYPE).append(": ").append("application/http").append('\n');
+ payload.append("Content-Transfer-Encoding: binary").append('\n');
+ payload.append(SyncopeConstants.CRLF);
+
+ if (item instanceof BatchRequestItem) {
+ BatchRequestItem bri = BatchRequestItem.class.cast(item);
+ payload.append(bri.getMethod()).append(' ').append(bri.getRequestURI());
+ if (bri.getQueryString() != null) {
+ payload.append('?').append(bri.getQueryString());
+ }
+ payload.append(' ').append(HTTP_1_1).append('\n');
+ }
+
+ if (item instanceof BatchResponseItem) {
+ BatchResponseItem bri = BatchResponseItem.class.cast(item);
+ payload.append(HTTP_1_1).append(' ').
+ append(bri.getStatus()).append(' ').
+ append(Response.Status.fromStatusCode(bri.getStatus()).getReasonPhrase()).
+ append('\n');
+ }
+
+ if (item.getHeaders() != null && !item.getHeaders().isEmpty()) {
+ item.getHeaders().forEach((key, values) -> {
+ values.forEach(value -> {
+ payload.append(key).append(": ").append(value).append('\n');
+ });
+ });
+ payload.append(SyncopeConstants.CRLF);
+ }
+
+ if (item.getContent() != null) {
+ payload.append(item.getContent()).append('\n');
+ }
+ });
+
+ payload.append(boundary).append(SyncopeConstants.DOUBLE_DASH).append('\n');
+
+ return payload.toString();
+ }
+
+ private BatchPayloadGenerator() {
+ // private constructor for static utility class
+ }
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/d9250efa/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/batch/BatchPayloadLine.java
----------------------------------------------------------------------
diff --git a/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/batch/BatchPayloadLine.java b/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/batch/BatchPayloadLine.java
new file mode 100644
index 0000000..aa2cf41
--- /dev/null
+++ b/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/batch/BatchPayloadLine.java
@@ -0,0 +1,53 @@
+/*
+ * 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.common.rest.api.batch;
+
+import org.apache.commons.lang3.builder.EqualsBuilder;
+import org.apache.commons.lang3.builder.HashCodeBuilder;
+
+public class BatchPayloadLine {
+
+ private final int lineNumber;
+
+ private final String content;
+
+ public BatchPayloadLine(final String content, final int lineNumber) {
+ this.content = content;
+ this.lineNumber = lineNumber;
+ }
+
+ public int getLineNumber() {
+ return lineNumber;
+ }
+
+ @Override
+ public String toString() {
+ return content;
+ }
+
+ @Override
+ public boolean equals(final Object obj) {
+ return EqualsBuilder.reflectionEquals(this, obj);
+ }
+
+ @Override
+ public int hashCode() {
+ return HashCodeBuilder.reflectionHashCode(this);
+ }
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/d9250efa/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/batch/BatchPayloadLineReader.java
----------------------------------------------------------------------
diff --git a/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/batch/BatchPayloadLineReader.java b/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/batch/BatchPayloadLineReader.java
new file mode 100644
index 0000000..b4a4d9f
--- /dev/null
+++ b/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/batch/BatchPayloadLineReader.java
@@ -0,0 +1,193 @@
+/*
+ * 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.common.rest.api.batch;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.nio.ByteBuffer;
+import java.nio.charset.Charset;
+import java.nio.charset.StandardCharsets;
+import java.util.ArrayList;
+import java.util.List;
+import javax.ws.rs.core.HttpHeaders;
+import javax.ws.rs.core.MediaType;
+import org.apache.syncope.common.lib.SyncopeConstants;
+import org.apache.syncope.common.rest.api.RESTHeaders;
+
+public class BatchPayloadLineReader implements AutoCloseable {
+
+ private static final byte CR = '\r';
+
+ private static final byte LF = '\n';
+
+ private static final int EOF = -1;
+
+ private static final int BUFFER_SIZE = 8192;
+
+ private static final Charset DEFAULT_CHARSET = StandardCharsets.UTF_8;
+
+ private final ReadState readState = new ReadState();
+
+ private final InputStream in;
+
+ private final MediaType multipartMixed;
+
+ private final byte[] buffer = new byte[BUFFER_SIZE];
+
+ private Charset currentCharset = DEFAULT_CHARSET;
+
+ private String currentBoundary = null;
+
+ private int offset = 0;
+
+ private int limit = 0;
+
+ public BatchPayloadLineReader(final InputStream in, final MediaType multipartMixed) {
+ this.in = in;
+ this.multipartMixed = multipartMixed;
+ }
+
+ @Override
+ public void close() throws IOException {
+ in.close();
+ }
+
+ private boolean isBoundary(final String currentLine) {
+ return (currentBoundary + SyncopeConstants.CRLF).equals(currentLine)
+ || (currentBoundary + SyncopeConstants.DOUBLE_DASH + SyncopeConstants.CRLF).equals(currentLine);
+ }
+
+ private int fillBuffer() throws IOException {
+ limit = in.read(buffer, 0, buffer.length);
+ offset = 0;
+
+ return limit;
+ }
+
+ private String readLine() throws IOException {
+ if (limit == EOF) {
+ return null;
+ }
+
+ ByteBuffer innerBuffer = ByteBuffer.allocate(BUFFER_SIZE);
+ // EOF will be considered as line ending
+ boolean foundLineEnd = false;
+
+ while (!foundLineEnd) {
+ // Is buffer refill required?
+ if (limit == offset && fillBuffer() == EOF) {
+ foundLineEnd = true;
+ }
+
+ if (!foundLineEnd) {
+ byte currentChar = buffer[offset++];
+ if (!innerBuffer.hasRemaining()) {
+ innerBuffer.flip();
+ ByteBuffer tmp = ByteBuffer.allocate(innerBuffer.limit() * 2);
+ tmp.put(innerBuffer);
+ innerBuffer = tmp;
+ }
+ innerBuffer.put(currentChar);
+
+ if (currentChar == LF) {
+ foundLineEnd = true;
+ } else if (currentChar == CR) {
+ foundLineEnd = true;
+
+ // Check next byte. Consume \n if available
+ // Is buffer refill required?
+ if (limit == offset) {
+ fillBuffer();
+ }
+
+ // Check if there is at least one character
+ if (limit != EOF && buffer[offset] == LF) {
+ innerBuffer.put(LF);
+ offset++;
+ }
+ }
+ }
+ }
+
+ if (innerBuffer.position() == 0) {
+ return null;
+ } else {
+ String currentLine = new String(innerBuffer.array(), 0, innerBuffer.position(),
+ readState.isReadBody() ? currentCharset : DEFAULT_CHARSET);
+
+ if (currentLine.startsWith(HttpHeaders.CONTENT_TYPE)) {
+ String charsetString = multipartMixed.getParameters().get(MediaType.CHARSET_PARAMETER);
+ currentCharset = charsetString == null
+ ? DEFAULT_CHARSET
+ : Charset.forName(charsetString);
+
+ currentBoundary = SyncopeConstants.DOUBLE_DASH + multipartMixed.getParameters().
+ get(RESTHeaders.BOUNDARY_PARAMETER);
+ } else if (SyncopeConstants.CRLF.equals(currentLine)) {
+ readState.foundLinebreak();
+ } else if (isBoundary(currentLine)) {
+ readState.foundBoundary();
+ }
+
+ return currentLine;
+ }
+ }
+
+ public List<BatchPayloadLine> read() throws IOException {
+ List<BatchPayloadLine> result = new ArrayList<>();
+
+ String currentLine = readLine();
+ if (currentLine != null) {
+ currentBoundary = currentLine.trim();
+ int counter = 1;
+ result.add(new BatchPayloadLine(currentLine, counter++));
+
+ while ((currentLine = readLine()) != null) {
+ result.add(new BatchPayloadLine(currentLine, counter++));
+ }
+ }
+
+ return result;
+ }
+
+ /**
+ * Read state indicator (whether currently the {@code body} or {@code header} part is read).
+ */
+ private static class ReadState {
+
+ private int state = 0;
+
+ public void foundLinebreak() {
+ state++;
+ }
+
+ public void foundBoundary() {
+ state = 0;
+ }
+
+ public boolean isReadBody() {
+ return state >= 2;
+ }
+
+ @Override
+ public String toString() {
+ return String.valueOf(state);
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/d9250efa/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/batch/BatchPayloadParser.java
----------------------------------------------------------------------
diff --git a/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/batch/BatchPayloadParser.java b/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/batch/BatchPayloadParser.java
new file mode 100644
index 0000000..a558db1
--- /dev/null
+++ b/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/batch/BatchPayloadParser.java
@@ -0,0 +1,208 @@
+/*
+ * 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.common.rest.api.batch;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+import javax.ws.rs.HttpMethod;
+import javax.ws.rs.core.MediaType;
+import org.apache.commons.lang3.ArrayUtils;
+import org.apache.commons.lang3.SerializationUtils;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.syncope.common.rest.api.RESTHeaders;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public final class BatchPayloadParser {
+
+ private static final Logger LOG = LoggerFactory.getLogger(BatchPayloadParser.class);
+
+ private static final Pattern PATTERN_LAST_CRLF = Pattern.compile("(.*)\\r\\n\\s*", Pattern.DOTALL);
+
+ private static final Pattern PATTERN_HEADER_LINE = Pattern.compile("((?:\\w|[!#$%\\&'*+\\-.^`|~])+):\\s?(.*)\\s*");
+
+ private static final Pattern PATTERN_BLANK_LINE = Pattern.compile("\\s*\r?\n\\s*");
+
+ private static final String[] HTTP_METHODS = {
+ HttpMethod.DELETE,
+ HttpMethod.PATCH,
+ HttpMethod.POST,
+ HttpMethod.PUT
+ };
+
+ private static BatchPayloadLine removeEndingCRLF(final BatchPayloadLine line) {
+ Matcher matcher = PATTERN_LAST_CRLF.matcher(line.toString());
+ return matcher.matches()
+ ? new BatchPayloadLine(matcher.group(1), line.getLineNumber())
+ : line;
+ }
+
+ private static void removeEndingCRLFFromList(final List<BatchPayloadLine> lines) {
+ if (!lines.isEmpty()) {
+ BatchPayloadLine lastLine = lines.remove(lines.size() - 1);
+ lines.add(removeEndingCRLF(lastLine));
+ }
+ }
+
+ private static List<List<BatchPayloadLine>> split(final List<BatchPayloadLine> lines, final String boundary) {
+ List<List<BatchPayloadLine>> messageParts = new ArrayList<>();
+ List<BatchPayloadLine> currentPart = new ArrayList<>();
+ boolean isEndReached = false;
+
+ String quotedBoundary = Pattern.quote(boundary);
+ Pattern boundaryDelimiterPattern = Pattern.compile("--" + quotedBoundary + "--\\s*");
+ Pattern boundaryPattern = Pattern.compile("--" + quotedBoundary + "\\s*");
+
+ for (BatchPayloadLine line : lines) {
+ if (boundaryDelimiterPattern.matcher(line.toString()).matches()) {
+ removeEndingCRLFFromList(currentPart);
+ messageParts.add(currentPart);
+ isEndReached = true;
+ } else if (boundaryPattern.matcher(line.toString()).matches()) {
+ removeEndingCRLFFromList(currentPart);
+ messageParts.add(currentPart);
+ currentPart = new ArrayList<>();
+ } else {
+ currentPart.add(line);
+ }
+
+ if (isEndReached) {
+ break;
+ }
+ }
+
+ // Remove preamble
+ if (!messageParts.isEmpty()) {
+ messageParts.remove(0);
+ }
+
+ if (!isEndReached) {
+ int lineNumber = lines.isEmpty() ? 0 : lines.get(0).getLineNumber();
+ throw new IllegalArgumentException("Missing close boundary delimiter around line " + lineNumber);
+ }
+
+ return messageParts;
+ }
+
+ private static void consumeHeaders(final List<BatchPayloadLine> bodyPart, final BatchItem item) {
+ Map<String, List<Object>> headers = new HashMap<>();
+
+ boolean isHeader = true;
+ for (Iterator<BatchPayloadLine> itor = bodyPart.iterator(); itor.hasNext() && isHeader;) {
+ BatchPayloadLine currentLine = itor.next();
+
+ Matcher headerMatcher = PATTERN_HEADER_LINE.matcher(currentLine.toString());
+ if (headerMatcher.matches() && headerMatcher.groupCount() == 2) {
+ itor.remove();
+ } else {
+ isHeader = false;
+ }
+ }
+ consumeBlankLine(bodyPart);
+
+ isHeader = true;
+ for (Iterator<BatchPayloadLine> itor = bodyPart.iterator(); itor.hasNext() && isHeader;) {
+ BatchPayloadLine currentLine = itor.next();
+
+ if (currentLine.toString().contains("HTTP/1.1")) {
+ itor.remove();
+
+ if (ArrayUtils.contains(HTTP_METHODS, StringUtils.substringBefore(currentLine.toString(), " "))
+ && item instanceof BatchRequestItem) {
+
+ BatchRequestItem bri = BatchRequestItem.class.cast(item);
+ String[] parts = currentLine.toString().split(" ");
+ bri.setMethod(parts[0]);
+ String[] target = parts[1].split("\\?");
+ bri.setRequestURI(target[0]);
+ if (target.length > 1) {
+ bri.setQueryString(target[1]);
+ }
+ } else if (item instanceof BatchResponseItem) {
+ BatchResponseItem bri = BatchResponseItem.class.cast(item);
+ bri.setStatus(Integer.valueOf(StringUtils.substringBefore(
+ StringUtils.substringAfter(currentLine.toString(), " "), " ").trim()));
+ }
+ } else {
+ Matcher headerMatcher = PATTERN_HEADER_LINE.matcher(currentLine.toString());
+ if (headerMatcher.matches() && headerMatcher.groupCount() == 2) {
+ itor.remove();
+
+ String headerName = headerMatcher.group(1).trim();
+ String headerValue = headerMatcher.group(2).trim();
+
+ List<Object> header = headers.get(headerName);
+ if (header == null) {
+ header = new ArrayList<>();
+ headers.put(headerName, header);
+ }
+ header.addAll(Stream.of(headerValue.split(",")).map(String::trim).collect(Collectors.toList()));
+ } else {
+ isHeader = false;
+ }
+ }
+ }
+ consumeBlankLine(bodyPart);
+
+ item.setHeaders(headers);
+ }
+
+ private static void consumeBlankLine(final List<BatchPayloadLine> bodyPart) {
+ if (!bodyPart.isEmpty() && PATTERN_BLANK_LINE.matcher(bodyPart.get(0).toString()).matches()) {
+ bodyPart.remove(0);
+ }
+ }
+
+ public static <T extends BatchItem> List<T> parse(
+ final InputStream in,
+ final MediaType multipartMixed,
+ final T template) throws IOException {
+
+ List<BatchPayloadLine> lines;
+ try (BatchPayloadLineReader lineReader = new BatchPayloadLineReader(in, multipartMixed)) {
+ lines = lineReader.read();
+ }
+
+ return split(lines, multipartMixed.getParameters().get(RESTHeaders.BOUNDARY_PARAMETER)).stream().
+ map(bodyPart -> {
+ LOG.debug("Body part:\n{}", bodyPart);
+
+ T item = SerializationUtils.clone(template);
+
+ consumeHeaders(bodyPart, item);
+ item.setContent(
+ bodyPart.stream().map(BatchPayloadLine::toString).collect(Collectors.joining()));
+
+ return item;
+ }).collect(Collectors.toList());
+ }
+
+ private BatchPayloadParser() {
+ // private constructor for static utility class
+ }
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/d9250efa/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/batch/BatchRequestItem.java
----------------------------------------------------------------------
diff --git a/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/batch/BatchRequestItem.java b/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/batch/BatchRequestItem.java
new file mode 100644
index 0000000..834b0fe
--- /dev/null
+++ b/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/batch/BatchRequestItem.java
@@ -0,0 +1,54 @@
+/*
+ * 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.common.rest.api.batch;
+
+public class BatchRequestItem extends BatchItem {
+
+ private static final long serialVersionUID = -986002485818968262L;
+
+ private String method;
+
+ private String requestURI;
+
+ private String queryString;
+
+ public String getMethod() {
+ return method;
+ }
+
+ public void setMethod(final String method) {
+ this.method = method;
+ }
+
+ public String getRequestURI() {
+ return requestURI;
+ }
+
+ public void setRequestURI(final String requestURI) {
+ this.requestURI = requestURI;
+ }
+
+ public String getQueryString() {
+ return queryString;
+ }
+
+ public void setQueryString(final String queryString) {
+ this.queryString = queryString;
+ }
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/d9250efa/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/batch/BatchResponseItem.java
----------------------------------------------------------------------
diff --git a/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/batch/BatchResponseItem.java b/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/batch/BatchResponseItem.java
new file mode 100644
index 0000000..e989b65
--- /dev/null
+++ b/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/batch/BatchResponseItem.java
@@ -0,0 +1,34 @@
+/*
+ * 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.common.rest.api.batch;
+
+public class BatchResponseItem extends BatchItem {
+
+ private static final long serialVersionUID = -2163506313221985565L;
+
+ private int status;
+
+ public int getStatus() {
+ return status;
+ }
+
+ public void setStatus(final int status) {
+ this.status = status;
+ }
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/d9250efa/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/AccessTokenService.java
----------------------------------------------------------------------
diff --git a/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/AccessTokenService.java b/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/AccessTokenService.java
index e9ae07b..e26b2e8 100644
--- a/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/AccessTokenService.java
+++ b/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/AccessTokenService.java
@@ -35,7 +35,6 @@ import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
-import org.apache.syncope.common.lib.SyncopeConstants;
import org.apache.syncope.common.lib.to.AccessTokenTO;
import org.apache.syncope.common.lib.to.PagedResult;
import org.apache.syncope.common.rest.api.RESTHeaders;
@@ -67,7 +66,7 @@ public interface AccessTokenService extends JAXRSService {
})
@POST
@Path("login")
- @Produces({ MediaType.APPLICATION_JSON, SyncopeConstants.APPLICATION_YAML, MediaType.APPLICATION_XML })
+ @Produces({ MediaType.APPLICATION_JSON, RESTHeaders.APPLICATION_YAML, MediaType.APPLICATION_XML })
Response login();
/**
@@ -89,7 +88,7 @@ public interface AccessTokenService extends JAXRSService {
description = "Expiration of the refreshed JWT") }))
@POST
@Path("refresh")
- @Produces({ MediaType.APPLICATION_JSON, SyncopeConstants.APPLICATION_YAML, MediaType.APPLICATION_XML })
+ @Produces({ MediaType.APPLICATION_JSON, RESTHeaders.APPLICATION_YAML, MediaType.APPLICATION_XML })
Response refresh();
/**
@@ -101,7 +100,7 @@ public interface AccessTokenService extends JAXRSService {
@ApiResponse(responseCode = "204", description = "Operation was successful"))
@POST
@Path("logout")
- @Produces({ MediaType.APPLICATION_JSON, SyncopeConstants.APPLICATION_YAML, MediaType.APPLICATION_XML })
+ @Produces({ MediaType.APPLICATION_JSON, RESTHeaders.APPLICATION_YAML, MediaType.APPLICATION_XML })
void logout();
/**
@@ -114,8 +113,8 @@ public interface AccessTokenService extends JAXRSService {
@SecurityRequirement(name = "BasicAuthentication"),
@SecurityRequirement(name = "Bearer") })
@GET
- @Consumes({ MediaType.APPLICATION_JSON, SyncopeConstants.APPLICATION_YAML, MediaType.APPLICATION_XML })
- @Produces({ MediaType.APPLICATION_JSON, SyncopeConstants.APPLICATION_YAML, MediaType.APPLICATION_XML })
+ @Consumes({ MediaType.APPLICATION_JSON, RESTHeaders.APPLICATION_YAML, MediaType.APPLICATION_XML })
+ @Produces({ MediaType.APPLICATION_JSON, RESTHeaders.APPLICATION_YAML, MediaType.APPLICATION_XML })
PagedResult<AccessTokenTO> list(@BeanParam AccessTokenQuery query);
/**
@@ -130,6 +129,6 @@ public interface AccessTokenService extends JAXRSService {
@ApiResponse(responseCode = "204", description = "Operation was successful"))
@DELETE
@Path("{key}")
- @Produces({ MediaType.APPLICATION_JSON, SyncopeConstants.APPLICATION_YAML, MediaType.APPLICATION_XML })
+ @Produces({ MediaType.APPLICATION_JSON, RESTHeaders.APPLICATION_YAML, MediaType.APPLICATION_XML })
void delete(@PathParam("key") String key);
}
http://git-wip-us.apache.org/repos/asf/syncope/blob/d9250efa/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/AnyObjectService.java
----------------------------------------------------------------------
diff --git a/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/AnyObjectService.java b/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/AnyObjectService.java
index e8169b1..f9b6287 100644
--- a/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/AnyObjectService.java
+++ b/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/AnyObjectService.java
@@ -38,7 +38,6 @@ import javax.ws.rs.Produces;
import javax.ws.rs.core.HttpHeaders;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
-import org.apache.syncope.common.lib.SyncopeConstants;
import org.apache.syncope.common.lib.patch.AnyObjectPatch;
import org.apache.syncope.common.lib.to.AnyObjectTO;
import org.apache.syncope.common.lib.to.PagedResult;
@@ -105,8 +104,8 @@ public interface AnyObjectService extends AnyService<AnyObjectTO> {
description = "Allows the server to inform the "
+ "client about the fact that a specified preference was applied") }))
@POST
- @Produces({ MediaType.APPLICATION_JSON, SyncopeConstants.APPLICATION_YAML, MediaType.APPLICATION_XML })
- @Consumes({ MediaType.APPLICATION_JSON, SyncopeConstants.APPLICATION_YAML, MediaType.APPLICATION_XML })
+ @Produces({ MediaType.APPLICATION_JSON, RESTHeaders.APPLICATION_YAML, MediaType.APPLICATION_XML })
+ @Consumes({ MediaType.APPLICATION_JSON, RESTHeaders.APPLICATION_YAML, MediaType.APPLICATION_XML })
Response create(@NotNull AnyObjectTO anyObjectTO);
/**
@@ -148,8 +147,8 @@ public interface AnyObjectService extends AnyService<AnyObjectTO> {
+ " date of the entity") })
@PATCH
@Path("{key}")
- @Produces({ MediaType.APPLICATION_JSON, SyncopeConstants.APPLICATION_YAML, MediaType.APPLICATION_XML })
- @Consumes({ MediaType.APPLICATION_JSON, SyncopeConstants.APPLICATION_YAML, MediaType.APPLICATION_XML })
+ @Produces({ MediaType.APPLICATION_JSON, RESTHeaders.APPLICATION_YAML, MediaType.APPLICATION_XML })
+ @Consumes({ MediaType.APPLICATION_JSON, RESTHeaders.APPLICATION_YAML, MediaType.APPLICATION_XML })
Response update(@NotNull AnyObjectPatch anyObjectPatch);
/**
@@ -191,7 +190,7 @@ public interface AnyObjectService extends AnyService<AnyObjectTO> {
+ " date of the entity") })
@PUT
@Path("{key}")
- @Produces({ MediaType.APPLICATION_JSON, SyncopeConstants.APPLICATION_YAML, MediaType.APPLICATION_XML })
- @Consumes({ MediaType.APPLICATION_JSON, SyncopeConstants.APPLICATION_YAML, MediaType.APPLICATION_XML })
+ @Produces({ MediaType.APPLICATION_JSON, RESTHeaders.APPLICATION_YAML, MediaType.APPLICATION_XML })
+ @Consumes({ MediaType.APPLICATION_JSON, RESTHeaders.APPLICATION_YAML, MediaType.APPLICATION_XML })
Response update(@NotNull AnyObjectTO anyObjectTO);
}
http://git-wip-us.apache.org/repos/asf/syncope/blob/d9250efa/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/AnyService.java
----------------------------------------------------------------------
diff --git a/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/AnyService.java b/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/AnyService.java
index 73cd69f..7bb78d8 100644
--- a/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/AnyService.java
+++ b/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/AnyService.java
@@ -39,7 +39,6 @@ import javax.ws.rs.Produces;
import javax.ws.rs.core.HttpHeaders;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
-import org.apache.syncope.common.lib.SyncopeConstants;
import org.apache.syncope.common.lib.patch.AssociationPatch;
import org.apache.syncope.common.lib.patch.DeassociationPatch;
import org.apache.syncope.common.lib.to.AnyTO;
@@ -68,7 +67,7 @@ public interface AnyService<TO extends AnyTO> extends JAXRSService {
*/
@GET
@Path("{key}/{schemaType}")
- @Produces({ MediaType.APPLICATION_JSON, SyncopeConstants.APPLICATION_YAML, MediaType.APPLICATION_XML })
+ @Produces({ MediaType.APPLICATION_JSON, RESTHeaders.APPLICATION_YAML, MediaType.APPLICATION_XML })
Set<AttrTO> read(@NotNull @PathParam("key") String key, @NotNull @PathParam("schemaType") SchemaType schemaType);
/**
@@ -84,7 +83,7 @@ public interface AnyService<TO extends AnyTO> extends JAXRSService {
*/
@GET
@Path("{key}/{schemaType}/{schema}")
- @Produces({ MediaType.APPLICATION_JSON, SyncopeConstants.APPLICATION_YAML, MediaType.APPLICATION_XML })
+ @Produces({ MediaType.APPLICATION_JSON, RESTHeaders.APPLICATION_YAML, MediaType.APPLICATION_XML })
AttrTO read(
@NotNull @PathParam("key") String key,
@NotNull @PathParam("schemaType") SchemaType schemaType,
@@ -98,7 +97,7 @@ public interface AnyService<TO extends AnyTO> extends JAXRSService {
*/
@GET
@Path("{key}")
- @Produces({ MediaType.APPLICATION_JSON, SyncopeConstants.APPLICATION_YAML, MediaType.APPLICATION_XML })
+ @Produces({ MediaType.APPLICATION_JSON, RESTHeaders.APPLICATION_YAML, MediaType.APPLICATION_XML })
TO read(@NotNull @PathParam("key") String key);
/**
@@ -108,7 +107,7 @@ public interface AnyService<TO extends AnyTO> extends JAXRSService {
* @return paged list of any objects matching the given query
*/
@GET
- @Produces({ MediaType.APPLICATION_JSON, SyncopeConstants.APPLICATION_YAML, MediaType.APPLICATION_XML })
+ @Produces({ MediaType.APPLICATION_JSON, RESTHeaders.APPLICATION_YAML, MediaType.APPLICATION_XML })
PagedResult<TO> search(@BeanParam AnyQuery anyQuery);
/**
@@ -123,8 +122,8 @@ public interface AnyService<TO extends AnyTO> extends JAXRSService {
@Schema(type = "string"))
@PUT
@Path("{key}/{schemaType}/{schema}")
- @Produces({ MediaType.APPLICATION_JSON, SyncopeConstants.APPLICATION_YAML, MediaType.APPLICATION_XML })
- @Consumes({ MediaType.APPLICATION_JSON, SyncopeConstants.APPLICATION_YAML, MediaType.APPLICATION_XML })
+ @Produces({ MediaType.APPLICATION_JSON, RESTHeaders.APPLICATION_YAML, MediaType.APPLICATION_XML })
+ @Consumes({ MediaType.APPLICATION_JSON, RESTHeaders.APPLICATION_YAML, MediaType.APPLICATION_XML })
Response update(
@NotNull @PathParam("key") String key,
@NotNull @PathParam("schemaType") SchemaType schemaType,
@@ -141,7 +140,7 @@ public interface AnyService<TO extends AnyTO> extends JAXRSService {
@ApiResponse(responseCode = "204", description = "Operation was successful"))
@DELETE
@Path("{key}/{schemaType}/{schema}")
- @Produces({ MediaType.APPLICATION_JSON, SyncopeConstants.APPLICATION_YAML, MediaType.APPLICATION_XML })
+ @Produces({ MediaType.APPLICATION_JSON, RESTHeaders.APPLICATION_YAML, MediaType.APPLICATION_XML })
void delete(
@NotNull @PathParam("key") String key,
@NotNull @PathParam("schemaType") SchemaType schemaType,
@@ -184,7 +183,7 @@ public interface AnyService<TO extends AnyTO> extends JAXRSService {
+ " date of the entity") })
@DELETE
@Path("{key}")
- @Produces({ MediaType.APPLICATION_JSON, SyncopeConstants.APPLICATION_YAML, MediaType.APPLICATION_XML })
+ @Produces({ MediaType.APPLICATION_JSON, RESTHeaders.APPLICATION_YAML, MediaType.APPLICATION_XML })
Response delete(@NotNull @PathParam("key") String key);
/**
@@ -227,8 +226,8 @@ public interface AnyService<TO extends AnyTO> extends JAXRSService {
+ " date of the entity") })
@POST
@Path("{key}/deassociate/{action}")
- @Produces({ MediaType.APPLICATION_JSON, SyncopeConstants.APPLICATION_YAML, MediaType.APPLICATION_XML })
- @Consumes({ MediaType.APPLICATION_JSON, SyncopeConstants.APPLICATION_YAML, MediaType.APPLICATION_XML })
+ @Produces({ MediaType.APPLICATION_JSON, RESTHeaders.APPLICATION_YAML, MediaType.APPLICATION_XML })
+ @Consumes({ MediaType.APPLICATION_JSON, RESTHeaders.APPLICATION_YAML, MediaType.APPLICATION_XML })
Response deassociate(@NotNull DeassociationPatch patch);
/**
@@ -271,8 +270,8 @@ public interface AnyService<TO extends AnyTO> extends JAXRSService {
+ " date of the entity") })
@POST
@Path("{key}/associate/{action}")
- @Produces({ MediaType.APPLICATION_JSON, SyncopeConstants.APPLICATION_YAML, MediaType.APPLICATION_XML })
- @Consumes({ MediaType.APPLICATION_JSON, SyncopeConstants.APPLICATION_YAML, MediaType.APPLICATION_XML })
+ @Produces({ MediaType.APPLICATION_JSON, RESTHeaders.APPLICATION_YAML, MediaType.APPLICATION_XML })
+ @Consumes({ MediaType.APPLICATION_JSON, RESTHeaders.APPLICATION_YAML, MediaType.APPLICATION_XML })
Response associate(@NotNull AssociationPatch patch);
/**
@@ -303,7 +302,7 @@ public interface AnyService<TO extends AnyTO> extends JAXRSService {
+ "client about the fact that a specified preference was applied")) })
@POST
@Path("bulk")
- @Produces({ MediaType.APPLICATION_JSON, SyncopeConstants.APPLICATION_YAML, MediaType.APPLICATION_XML })
- @Consumes({ MediaType.APPLICATION_JSON, SyncopeConstants.APPLICATION_YAML, MediaType.APPLICATION_XML })
+ @Produces({ MediaType.APPLICATION_JSON, RESTHeaders.APPLICATION_YAML, MediaType.APPLICATION_XML })
+ @Consumes({ MediaType.APPLICATION_JSON, RESTHeaders.APPLICATION_YAML, MediaType.APPLICATION_XML })
Response bulk(@NotNull BulkAction bulkAction);
}
http://git-wip-us.apache.org/repos/asf/syncope/blob/d9250efa/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/AnyTypeClassService.java
----------------------------------------------------------------------
diff --git a/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/AnyTypeClassService.java b/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/AnyTypeClassService.java
index 7752def..6b90a1b 100644
--- a/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/AnyTypeClassService.java
+++ b/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/AnyTypeClassService.java
@@ -40,7 +40,6 @@ import javax.ws.rs.Produces;
import javax.ws.rs.core.HttpHeaders;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
-import org.apache.syncope.common.lib.SyncopeConstants;
import org.apache.syncope.common.lib.to.AnyTypeClassTO;
import org.apache.syncope.common.rest.api.RESTHeaders;
@@ -60,7 +59,7 @@ public interface AnyTypeClassService extends JAXRSService {
* @return list of all anyTypeClasss.
*/
@GET
- @Produces({ MediaType.APPLICATION_JSON, SyncopeConstants.APPLICATION_YAML, MediaType.APPLICATION_XML })
+ @Produces({ MediaType.APPLICATION_JSON, RESTHeaders.APPLICATION_YAML, MediaType.APPLICATION_XML })
List<AnyTypeClassTO> list();
/**
@@ -71,7 +70,7 @@ public interface AnyTypeClassService extends JAXRSService {
*/
@GET
@Path("{key}")
- @Produces({ MediaType.APPLICATION_JSON, SyncopeConstants.APPLICATION_YAML, MediaType.APPLICATION_XML })
+ @Produces({ MediaType.APPLICATION_JSON, RESTHeaders.APPLICATION_YAML, MediaType.APPLICATION_XML })
AnyTypeClassTO read(@NotNull @PathParam("key") String key);
/**
@@ -90,8 +89,8 @@ public interface AnyTypeClassService extends JAXRSService {
@Schema(type = "string"),
description = "URL of the entity created") }))
@POST
- @Consumes({ MediaType.APPLICATION_JSON, SyncopeConstants.APPLICATION_YAML, MediaType.APPLICATION_XML })
- @Produces({ MediaType.APPLICATION_JSON, SyncopeConstants.APPLICATION_YAML, MediaType.APPLICATION_XML })
+ @Consumes({ MediaType.APPLICATION_JSON, RESTHeaders.APPLICATION_YAML, MediaType.APPLICATION_XML })
+ @Produces({ MediaType.APPLICATION_JSON, RESTHeaders.APPLICATION_YAML, MediaType.APPLICATION_XML })
Response create(@NotNull AnyTypeClassTO anyTypeClassTO);
/**
@@ -105,8 +104,8 @@ public interface AnyTypeClassService extends JAXRSService {
@ApiResponse(responseCode = "204", description = "Operation was successful"))
@PUT
@Path("{key}")
- @Consumes({ MediaType.APPLICATION_JSON, SyncopeConstants.APPLICATION_YAML, MediaType.APPLICATION_XML })
- @Produces({ MediaType.APPLICATION_JSON, SyncopeConstants.APPLICATION_YAML, MediaType.APPLICATION_XML })
+ @Consumes({ MediaType.APPLICATION_JSON, RESTHeaders.APPLICATION_YAML, MediaType.APPLICATION_XML })
+ @Produces({ MediaType.APPLICATION_JSON, RESTHeaders.APPLICATION_YAML, MediaType.APPLICATION_XML })
void update(@NotNull AnyTypeClassTO anyTypeClassTO);
/**
@@ -118,6 +117,6 @@ public interface AnyTypeClassService extends JAXRSService {
@ApiResponse(responseCode = "204", description = "Operation was successful"))
@DELETE
@Path("{key}")
- @Produces({ MediaType.APPLICATION_JSON, SyncopeConstants.APPLICATION_YAML, MediaType.APPLICATION_XML })
+ @Produces({ MediaType.APPLICATION_JSON, RESTHeaders.APPLICATION_YAML, MediaType.APPLICATION_XML })
void delete(@NotNull @PathParam("key") String key);
}
http://git-wip-us.apache.org/repos/asf/syncope/blob/d9250efa/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/AnyTypeService.java
----------------------------------------------------------------------
diff --git a/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/AnyTypeService.java b/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/AnyTypeService.java
index 53b8b87..e5db506 100644
--- a/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/AnyTypeService.java
+++ b/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/AnyTypeService.java
@@ -40,7 +40,6 @@ import javax.ws.rs.Produces;
import javax.ws.rs.core.HttpHeaders;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
-import org.apache.syncope.common.lib.SyncopeConstants;
import org.apache.syncope.common.lib.to.AnyTypeTO;
import org.apache.syncope.common.rest.api.RESTHeaders;
@@ -60,7 +59,7 @@ public interface AnyTypeService extends JAXRSService {
* @return list of all anyTypes.
*/
@GET
- @Produces({ MediaType.APPLICATION_JSON, SyncopeConstants.APPLICATION_YAML, MediaType.APPLICATION_XML })
+ @Produces({ MediaType.APPLICATION_JSON, RESTHeaders.APPLICATION_YAML, MediaType.APPLICATION_XML })
List<AnyTypeTO> list();
/**
@@ -71,7 +70,7 @@ public interface AnyTypeService extends JAXRSService {
*/
@GET
@Path("{key}")
- @Produces({ MediaType.APPLICATION_JSON, SyncopeConstants.APPLICATION_YAML, MediaType.APPLICATION_XML })
+ @Produces({ MediaType.APPLICATION_JSON, RESTHeaders.APPLICATION_YAML, MediaType.APPLICATION_XML })
AnyTypeTO read(@NotNull @PathParam("key") String key);
/**
@@ -90,7 +89,7 @@ public interface AnyTypeService extends JAXRSService {
@Schema(type = "string"),
description = "URL of the entity created") }))
@POST
- @Consumes({ MediaType.APPLICATION_JSON, SyncopeConstants.APPLICATION_YAML, MediaType.APPLICATION_XML })
+ @Consumes({ MediaType.APPLICATION_JSON, RESTHeaders.APPLICATION_YAML, MediaType.APPLICATION_XML })
Response create(@NotNull AnyTypeTO anyTypeTO);
/**
@@ -104,7 +103,7 @@ public interface AnyTypeService extends JAXRSService {
@ApiResponse(responseCode = "204", description = "Operation was successful"))
@PUT
@Path("{key}")
- @Consumes({ MediaType.APPLICATION_JSON, SyncopeConstants.APPLICATION_YAML, MediaType.APPLICATION_XML })
+ @Consumes({ MediaType.APPLICATION_JSON, RESTHeaders.APPLICATION_YAML, MediaType.APPLICATION_XML })
void update(@NotNull AnyTypeTO anyTypeTO);
/**
@@ -116,6 +115,6 @@ public interface AnyTypeService extends JAXRSService {
@ApiResponse(responseCode = "204", description = "Operation was successful"))
@DELETE
@Path("{key}")
- @Produces({ MediaType.APPLICATION_JSON, SyncopeConstants.APPLICATION_YAML, MediaType.APPLICATION_XML })
+ @Produces({ MediaType.APPLICATION_JSON, RESTHeaders.APPLICATION_YAML, MediaType.APPLICATION_XML })
void delete(@NotNull @PathParam("key") String key);
}
http://git-wip-us.apache.org/repos/asf/syncope/blob/d9250efa/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/ApplicationService.java
----------------------------------------------------------------------
diff --git a/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/ApplicationService.java b/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/ApplicationService.java
index cec7938..e8e8b19 100644
--- a/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/ApplicationService.java
+++ b/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/ApplicationService.java
@@ -40,7 +40,6 @@ import javax.ws.rs.Produces;
import javax.ws.rs.core.HttpHeaders;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
-import org.apache.syncope.common.lib.SyncopeConstants;
import org.apache.syncope.common.lib.to.ApplicationTO;
import org.apache.syncope.common.lib.to.PrivilegeTO;
import org.apache.syncope.common.rest.api.RESTHeaders;
@@ -61,7 +60,7 @@ public interface ApplicationService extends JAXRSService {
* @return list of all applications.
*/
@GET
- @Produces({ MediaType.APPLICATION_JSON, SyncopeConstants.APPLICATION_YAML, MediaType.APPLICATION_XML })
+ @Produces({ MediaType.APPLICATION_JSON, RESTHeaders.APPLICATION_YAML, MediaType.APPLICATION_XML })
List<ApplicationTO> list();
/**
@@ -72,7 +71,7 @@ public interface ApplicationService extends JAXRSService {
*/
@GET
@Path("{key}")
- @Produces({ MediaType.APPLICATION_JSON, SyncopeConstants.APPLICATION_YAML, MediaType.APPLICATION_XML })
+ @Produces({ MediaType.APPLICATION_JSON, RESTHeaders.APPLICATION_YAML, MediaType.APPLICATION_XML })
ApplicationTO read(@NotNull @PathParam("key") String key);
/**
@@ -83,7 +82,7 @@ public interface ApplicationService extends JAXRSService {
*/
@GET
@Path("privileges/{key}")
- @Produces({ MediaType.APPLICATION_JSON, SyncopeConstants.APPLICATION_YAML, MediaType.APPLICATION_XML })
+ @Produces({ MediaType.APPLICATION_JSON, RESTHeaders.APPLICATION_YAML, MediaType.APPLICATION_XML })
PrivilegeTO readPrivilege(@NotNull @PathParam("key") String key);
/**
@@ -102,8 +101,8 @@ public interface ApplicationService extends JAXRSService {
@Schema(type = "string"),
description = "URL of the entity created") }))
@POST
- @Consumes({ MediaType.APPLICATION_JSON, SyncopeConstants.APPLICATION_YAML, MediaType.APPLICATION_XML })
- @Produces({ MediaType.APPLICATION_JSON, SyncopeConstants.APPLICATION_YAML, MediaType.APPLICATION_XML })
+ @Consumes({ MediaType.APPLICATION_JSON, RESTHeaders.APPLICATION_YAML, MediaType.APPLICATION_XML })
+ @Produces({ MediaType.APPLICATION_JSON, RESTHeaders.APPLICATION_YAML, MediaType.APPLICATION_XML })
Response create(@NotNull ApplicationTO applicationTO);
/**
@@ -117,8 +116,8 @@ public interface ApplicationService extends JAXRSService {
@ApiResponse(responseCode = "204", description = "Operation was successful"))
@PUT
@Path("{key}")
- @Consumes({ MediaType.APPLICATION_JSON, SyncopeConstants.APPLICATION_YAML, MediaType.APPLICATION_XML })
- @Produces({ MediaType.APPLICATION_JSON, SyncopeConstants.APPLICATION_YAML, MediaType.APPLICATION_XML })
+ @Consumes({ MediaType.APPLICATION_JSON, RESTHeaders.APPLICATION_YAML, MediaType.APPLICATION_XML })
+ @Produces({ MediaType.APPLICATION_JSON, RESTHeaders.APPLICATION_YAML, MediaType.APPLICATION_XML })
void update(@NotNull ApplicationTO applicationTO);
/**
@@ -130,6 +129,6 @@ public interface ApplicationService extends JAXRSService {
@ApiResponse(responseCode = "204", description = "Operation was successful"))
@DELETE
@Path("{key}")
- @Produces({ MediaType.APPLICATION_JSON, SyncopeConstants.APPLICATION_YAML, MediaType.APPLICATION_XML })
+ @Produces({ MediaType.APPLICATION_JSON, RESTHeaders.APPLICATION_YAML, MediaType.APPLICATION_XML })
void delete(@NotNull @PathParam("key") String key);
}
http://git-wip-us.apache.org/repos/asf/syncope/blob/d9250efa/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/ConfigurationService.java
----------------------------------------------------------------------
diff --git a/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/ConfigurationService.java b/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/ConfigurationService.java
index e2193aa..0287154 100644
--- a/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/ConfigurationService.java
+++ b/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/ConfigurationService.java
@@ -37,8 +37,8 @@ import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
-import org.apache.syncope.common.lib.SyncopeConstants;
import org.apache.syncope.common.lib.to.AttrTO;
+import org.apache.syncope.common.rest.api.RESTHeaders;
/**
* REST operations for configuration.
@@ -65,7 +65,7 @@ public interface ConfigurationService extends JAXRSService {
* @return all configuration parameters
*/
@GET
- @Produces({ MediaType.APPLICATION_JSON, SyncopeConstants.APPLICATION_YAML, MediaType.APPLICATION_XML })
+ @Produces({ MediaType.APPLICATION_JSON, RESTHeaders.APPLICATION_YAML, MediaType.APPLICATION_XML })
List<AttrTO> list();
/**
@@ -76,7 +76,7 @@ public interface ConfigurationService extends JAXRSService {
*/
@GET
@Path("{schema}")
- @Produces({ MediaType.APPLICATION_JSON, SyncopeConstants.APPLICATION_YAML, MediaType.APPLICATION_XML })
+ @Produces({ MediaType.APPLICATION_JSON, RESTHeaders.APPLICATION_YAML, MediaType.APPLICATION_XML })
AttrTO get(@NotNull @PathParam("schema") String schema);
/**
@@ -90,8 +90,8 @@ public interface ConfigurationService extends JAXRSService {
@ApiResponse(responseCode = "204", description = "Operation was successful"))
@PUT
@Path("{schema}")
- @Consumes({ MediaType.APPLICATION_JSON, SyncopeConstants.APPLICATION_YAML, MediaType.APPLICATION_XML })
- @Produces({ MediaType.APPLICATION_JSON, SyncopeConstants.APPLICATION_YAML, MediaType.APPLICATION_XML })
+ @Consumes({ MediaType.APPLICATION_JSON, RESTHeaders.APPLICATION_YAML, MediaType.APPLICATION_XML })
+ @Produces({ MediaType.APPLICATION_JSON, RESTHeaders.APPLICATION_YAML, MediaType.APPLICATION_XML })
void set(@NotNull AttrTO value);
/**
@@ -103,6 +103,6 @@ public interface ConfigurationService extends JAXRSService {
@ApiResponse(responseCode = "204", description = "Operation was successful"))
@DELETE
@Path("{schema}")
- @Produces({ MediaType.APPLICATION_JSON, SyncopeConstants.APPLICATION_YAML, MediaType.APPLICATION_XML })
+ @Produces({ MediaType.APPLICATION_JSON, RESTHeaders.APPLICATION_YAML, MediaType.APPLICATION_XML })
void delete(@NotNull @PathParam("schema") String schema);
}