You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by da...@apache.org on 2019/08/15 05:43:39 UTC
[camel] 01/06: CAMEL-13852: Support OData action's
This is an automated email from the ASF dual-hosted git repository.
davsclaus pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/camel.git
commit 895dee3d9fe5fbc0f07afc1e12cbd2f9450a330b
Author: Marc Giger <gi...@gmx.ch>
AuthorDate: Sun Aug 11 14:08:01 2019 +0200
CAMEL-13852: Support OData action's
---
.../camel/component/olingo4/api/Olingo4App.java | 10 +++
.../component/olingo4/api/impl/Olingo4AppImpl.java | 31 ++++++---
.../camel/component/olingo4/Olingo4AppAPITest.java | 73 ++++++++++++++++++++++
.../camel-olingo4/camel-olingo4-component/pom.xml | 1 +
.../src/signatures/olingo-api-signature.txt | 1 +
.../olingo4/Olingo4ComponentProducerTest.java | 21 +++++++
6 files changed, 129 insertions(+), 8 deletions(-)
diff --git a/components/camel-olingo4/camel-olingo4-api/src/main/java/org/apache/camel/component/olingo4/api/Olingo4App.java b/components/camel-olingo4/camel-olingo4-api/src/main/java/org/apache/camel/component/olingo4/api/Olingo4App.java
index 3863c1b..0649a7c 100644
--- a/components/camel-olingo4/camel-olingo4-api/src/main/java/org/apache/camel/component/olingo4/api/Olingo4App.java
+++ b/components/camel-olingo4/camel-olingo4-api/src/main/java/org/apache/camel/component/olingo4/api/Olingo4App.java
@@ -149,4 +149,14 @@ public interface Olingo4App {
* @param responseHandler callback handler
*/
void batch(Edm edm, Map<String, String> endpointHttpHeaders, Object data, Olingo4ResponseHandler<List<Olingo4BatchResponse>> responseHandler);
+
+ /**
+ * Calls a OData action
+ * @param edm service Edm
+ * @param resourcePath resource path to action
+ * @param endpointHttpHeaders HTTP Headers to add/override the component versions
+ * @param data action data
+ * @param responseHandler {@link org.apache.olingo.client.api.domain.ClientEntity} callback handler
+ */
+ <T> void action(Edm edm, String resourcePath, Map<String, String> endpointHttpHeaders, Object data, Olingo4ResponseHandler<T> responseHandler);
}
diff --git a/components/camel-olingo4/camel-olingo4-api/src/main/java/org/apache/camel/component/olingo4/api/impl/Olingo4AppImpl.java b/components/camel-olingo4/camel-olingo4-api/src/main/java/org/apache/camel/component/olingo4/api/impl/Olingo4AppImpl.java
index c59e562..84ef1e3 100644
--- a/components/camel-olingo4/camel-olingo4-api/src/main/java/org/apache/camel/component/olingo4/api/impl/Olingo4AppImpl.java
+++ b/components/camel-olingo4/camel-olingo4-api/src/main/java/org/apache/camel/component/olingo4/api/impl/Olingo4AppImpl.java
@@ -40,14 +40,7 @@ import org.apache.camel.util.ObjectHelper;
import org.apache.commons.io.IOUtils;
import org.apache.commons.io.LineIterator;
import org.apache.commons.lang3.StringUtils;
-import org.apache.http.Consts;
-import org.apache.http.Header;
-import org.apache.http.HttpException;
-import org.apache.http.HttpHeaders;
-import org.apache.http.HttpResponse;
-import org.apache.http.HttpResponseFactory;
-import org.apache.http.HttpVersion;
-import org.apache.http.StatusLine;
+import org.apache.http.*;
import org.apache.http.client.entity.DecompressingEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpDelete;
@@ -60,6 +53,7 @@ import org.apache.http.client.methods.HttpUriRequest;
import org.apache.http.concurrent.FutureCallback;
import org.apache.http.config.MessageConstraints;
import org.apache.http.entity.AbstractHttpEntity;
+import org.apache.http.entity.BasicHttpEntity;
import org.apache.http.entity.ByteArrayEntity;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.DefaultHttpResponseFactory;
@@ -311,6 +305,13 @@ public final class Olingo4AppImpl implements Olingo4App {
writeContent(edm, new HttpPost(createUri(SegmentType.BATCH.getValue(), null)), uriInfo, data, endpointHttpHeaders, responseHandler);
}
+ @Override
+ public <T> void action(final Edm edm, final String resourcePath, final Map<String, String> endpointHttpHeaders, final Object data, final Olingo4ResponseHandler<T> responseHandler) {
+ final UriInfo uriInfo = parseUri(edm, resourcePath, null, serviceUri);
+
+ writeContent(edm, new HttpPost(createUri(resourcePath, null)), uriInfo, data, endpointHttpHeaders, responseHandler);
+ }
+
private ContentType getResourceContentType(UriInfo uriInfo) {
ContentType resourceContentType;
switch (uriInfo.getKind()) {
@@ -478,6 +479,7 @@ public final class Olingo4AppImpl implements Olingo4App {
List<UriResource> listResource = uriInfo.getUriResourceParts();
UriResourceKind lastResourceKind = listResource.get(listResource.size() - 1).getKind();
switch (lastResourceKind) {
+ case action:
case entitySet:
ClientEntity entity = odataReader.readEntity(result.getEntity().getContent(),
ContentType.parse(result.getEntity().getContentType().getValue()));
@@ -511,6 +513,19 @@ public final class Olingo4AppImpl implements Olingo4App {
List<UriResource> listResource = uriInfo.getUriResourceParts();
UriResourceKind lastResourceKind = listResource.get(listResource.size() - 1).getKind();
switch (lastResourceKind) {
+ case action:
+ if (content == null) {
+ requestStream = new ByteArrayInputStream(new byte[0]);
+ } else if (content instanceof ClientEntity) {
+ requestStream = odataWriter.writeEntity((ClientEntity)content, getResourceContentType(uriInfo));
+ } else if (content instanceof String) {
+ httpEntity = new StringEntity((String) content, org.apache.http.entity.ContentType.APPLICATION_JSON);
+ httpEntity.setChunked(false);
+ return httpEntity;
+ } else {
+ throw new ODataException("Unsupported content type: " + content);
+ }
+ break;
case entitySet:
if (content instanceof ClientEntity) {
requestStream = odataWriter.writeEntity((ClientEntity)content, getResourceContentType(uriInfo));
diff --git a/components/camel-olingo4/camel-olingo4-api/src/test/java/org/apache/camel/component/olingo4/Olingo4AppAPITest.java b/components/camel-olingo4/camel-olingo4-api/src/test/java/org/apache/camel/component/olingo4/Olingo4AppAPITest.java
index 728cb2d..86ebfc6 100644
--- a/components/camel-olingo4/camel-olingo4-api/src/test/java/org/apache/camel/component/olingo4/Olingo4AppAPITest.java
+++ b/components/camel-olingo4/camel-olingo4-api/src/test/java/org/apache/camel/component/olingo4/Olingo4AppAPITest.java
@@ -39,11 +39,16 @@ import org.apache.camel.component.olingo4.api.batch.Olingo4BatchRequest;
import org.apache.camel.component.olingo4.api.batch.Olingo4BatchResponse;
import org.apache.camel.component.olingo4.api.batch.Operation;
import org.apache.camel.component.olingo4.api.impl.Olingo4AppImpl;
+import org.apache.http.HttpException;
import org.apache.http.HttpHost;
+import org.apache.http.HttpResponse;
+import org.apache.http.HttpResponseInterceptor;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpUriRequest;
+import org.apache.http.entity.InputStreamEntity;
import org.apache.http.impl.client.CloseableHttpClient;
+import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.protocol.BasicHttpContext;
import org.apache.http.protocol.ExecutionContext;
@@ -60,6 +65,8 @@ import org.apache.olingo.client.api.domain.ClientProperty;
import org.apache.olingo.client.api.domain.ClientServiceDocument;
import org.apache.olingo.client.api.domain.ClientValue;
import org.apache.olingo.client.api.serialization.ODataReader;
+import org.apache.olingo.client.api.serialization.ODataSerializerException;
+import org.apache.olingo.client.api.serialization.ODataWriter;
import org.apache.olingo.client.core.ODataClientFactory;
import org.apache.olingo.commons.api.Constants;
import org.apache.olingo.commons.api.edm.Edm;
@@ -98,6 +105,8 @@ public class Olingo4AppAPITest {
private static final String TEST_AIRPORTS_COMPLEX_PROPERTY = TEST_AIRPORT + "/Location";
private static final String TEST_AIRPORTS_SIMPLE_PROPERTY_VALUE = TEST_AIRPORTS_SIMPLE_PROPERTY + "/$value";
private static final String COUNT_OPTION = "/$count";
+ private static final String TEST_UNBOUND_ACTION_RESETDATASOURCE = "ResetDataSource";
+ private static final String TEST_BOUND_ACTION_PEOPLE_SHARETRIP = TEST_PEOPLE +"/Microsoft.OData.Service.Sample.TrippinInMemory.Models.ShareTrip";
private static final String TEST_SERVICE_BASE_URL = "http://services.odata.org/TripPinRESTierService";
private static final ContentType TEST_FORMAT = ContentType.APPLICATION_JSON;
@@ -405,6 +414,70 @@ public class Olingo4AppAPITest {
assertEquals(HttpStatusCode.NOT_FOUND.getStatusCode(), responseParts.get(7).getStatusCode());
}
+ @Test
+ public void testUnboundActionRequest() throws Exception {
+ final TestOlingo4ResponseHandler<HttpStatusCode> responseHandler = new TestOlingo4ResponseHandler<>();
+ olingoApp.action(edm, TEST_UNBOUND_ACTION_RESETDATASOURCE, null, null, responseHandler);
+
+ final HttpStatusCode statusCode = responseHandler.await(15, TimeUnit.MINUTES);
+ assertEquals(204, statusCode.getStatusCode());
+ }
+
+ @Test
+ public void testBoundActionRequest() throws Exception {
+ final ClientEntity clientEntity = objFactory.newEntity(null);
+ clientEntity.getProperties().add(objFactory.newPrimitiveProperty("userName", objFactory.newPrimitiveValueBuilder().buildString("scottketchum")));
+ clientEntity.getProperties().add(objFactory.newPrimitiveProperty("tripId", objFactory.newPrimitiveValueBuilder().buildInt32(0)));
+
+ final TestOlingo4ResponseHandler<HttpStatusCode> responseHandler = new TestOlingo4ResponseHandler<>();
+ olingoApp.action(edm, TEST_BOUND_ACTION_PEOPLE_SHARETRIP, null, clientEntity, responseHandler);
+
+ final HttpStatusCode statusCode = responseHandler.await(15, TimeUnit.MINUTES);
+ assertEquals(204, statusCode.getStatusCode());
+ }
+
+
+ // Unfortunately there is no action that returns a client entity. So we fake one
+ @Test
+ public void testBoundActionRequestWithClientEntityResponse() throws Exception {
+ final ODataClient odataClient = ODataClientFactory.getClient();
+ final ODataWriter odataWriter = odataClient.getWriter();
+
+ final HttpClientBuilder httpClientBuilder = HttpClientBuilder.create();
+ httpClientBuilder.addInterceptorFirst(new HttpResponseInterceptor() {
+ @Override
+ public void process(HttpResponse response, HttpContext context) throws HttpException, IOException {
+ if (response.getStatusLine().getStatusCode() == 204) {
+ try {
+ response.setEntity(
+ new InputStreamEntity(
+ odataWriter.writeEntity(createEntity(), ContentType.JSON),
+ org.apache.http.entity.ContentType.parse(ContentType.JSON.toContentTypeString())));
+ response.setStatusCode(200);
+ } catch (ODataSerializerException e) {
+ throw new IOException(e);
+ }
+ }
+ }
+ });
+ final Olingo4App olingoApp = new Olingo4AppImpl(getRealServiceUrl(TEST_SERVICE_BASE_URL), httpClientBuilder);
+ olingoApp.setContentType(TEST_FORMAT_STRING);
+
+ final TestOlingo4ResponseHandler<Edm> responseHandler = new TestOlingo4ResponseHandler<>();
+ olingoApp.read(null, Constants.METADATA, null, null, responseHandler);
+ final Edm edm = responseHandler.await();
+
+ final ClientEntity clientEntity = objFactory.newEntity(null);
+ clientEntity.getProperties().add(objFactory.newPrimitiveProperty("userName", objFactory.newPrimitiveValueBuilder().buildString("scottketchum")));
+ clientEntity.getProperties().add(objFactory.newPrimitiveProperty("tripId", objFactory.newPrimitiveValueBuilder().buildInt32(0)));
+
+ final TestOlingo4ResponseHandler<ClientEntity> actionResponseHandler = new TestOlingo4ResponseHandler<>();
+ olingoApp.action(edm, TEST_BOUND_ACTION_PEOPLE_SHARETRIP, null, clientEntity, actionResponseHandler);
+
+ final ClientEntity result = actionResponseHandler.await(15, TimeUnit.MINUTES);
+ assertEquals("lewisblack", result.getProperty("UserName").getValue().toString());
+ }
+
private ClientEntity createEntity() {
ClientEntity clientEntity = objFactory.newEntity(null);
diff --git a/components/camel-olingo4/camel-olingo4-component/pom.xml b/components/camel-olingo4/camel-olingo4-component/pom.xml
index adcd6af..0f14877 100644
--- a/components/camel-olingo4/camel-olingo4-component/pom.xml
+++ b/components/camel-olingo4/camel-olingo4-component/pom.xml
@@ -149,6 +149,7 @@
<nullableOption>endpointHttpHeaders</nullableOption>
<nullableOption>edm</nullableOption>
<nullableOption>responseHandler</nullableOption>
+ <nullableOption>data</nullableOption>
</nullableOptions>
</api>
</apis>
diff --git a/components/camel-olingo4/camel-olingo4-component/src/signatures/olingo-api-signature.txt b/components/camel-olingo4/camel-olingo4-component/src/signatures/olingo-api-signature.txt
index fb941e6..66a2110 100644
--- a/components/camel-olingo4/camel-olingo4-component/src/signatures/olingo-api-signature.txt
+++ b/components/camel-olingo4/camel-olingo4-component/src/signatures/olingo-api-signature.txt
@@ -6,3 +6,4 @@ void update(org.apache.olingo.commons.api.edm.Edm edm, String resourcePath, java
void patch(org.apache.olingo.commons.api.edm.Edm edm, String resourcePath, java.util.Map<String, String> endpointHttpHeaders, Object data, org.apache.camel.component.olingo4.api.Olingo4ResponseHandler responseHandler);
void merge(org.apache.olingo.commons.api.edm.Edm edm, String resourcePath, java.util.Map<String, String> endpointHttpHeaders, Object data, org.apache.camel.component.olingo4.api.Olingo4ResponseHandler responseHandler);
void batch(org.apache.olingo.commons.api.edm.Edm edm, java.util.Map<String, String> endpointHttpHeaders, Object data, org.apache.camel.component.olingo4.api.Olingo4ResponseHandler responseHandler);
+void action(org.apache.olingo.commons.api.edm.Edm edm, String resourcePath, java.util.Map<String, String> endpointHttpHeaders, Object data, org.apache.camel.component.olingo4.api.Olingo4ResponseHandler responseHandler);
diff --git a/components/camel-olingo4/camel-olingo4-component/src/test/java/org/apache/camel/component/olingo4/Olingo4ComponentProducerTest.java b/components/camel-olingo4/camel-olingo4-component/src/test/java/org/apache/camel/component/olingo4/Olingo4ComponentProducerTest.java
index 2493b94..13a1de6 100644
--- a/components/camel-olingo4/camel-olingo4-component/src/test/java/org/apache/camel/component/olingo4/Olingo4ComponentProducerTest.java
+++ b/components/camel-olingo4/camel-olingo4-component/src/test/java/org/apache/camel/component/olingo4/Olingo4ComponentProducerTest.java
@@ -273,6 +273,22 @@ public class Olingo4ComponentProducerTest extends AbstractOlingo4TestSupport {
LOG.info("Read deleted entity error: {}", error.getMessage());
}
+ @Test
+ public void testUnboundActionRequest() throws Exception {
+ final HttpStatusCode status = requestBody("direct:unbound-action-ResetDataSource", null);
+ assertEquals(204, status.getStatusCode());
+ }
+
+ @Test
+ public void testBoundActionRequest() throws Exception {
+ final ClientEntity clientEntity = objFactory.newEntity(null);
+ clientEntity.getProperties().add(objFactory.newPrimitiveProperty("userName", objFactory.newPrimitiveValueBuilder().buildString("scottketchum")));
+ clientEntity.getProperties().add(objFactory.newPrimitiveProperty("tripId", objFactory.newPrimitiveValueBuilder().buildInt32(0)));
+
+ final HttpStatusCode status = requestBody("direct:bound-action-people", clientEntity);
+ assertEquals(204, status.getStatusCode());
+ }
+
@SuppressWarnings("unchecked")
@Test
public void testEndpointHttpHeaders() throws Exception {
@@ -425,6 +441,11 @@ public class Olingo4ComponentProducerTest extends AbstractOlingo4TestSupport {
from("direct:read-people-nofilterseen").to("olingo4://read/" + PEOPLE).to("mock:producer-noalreadyseen");
from("direct:read-people-filterseen").to("olingo4://read/" + PEOPLE + "?filterAlreadySeen=true").to("mock:producer-alreadyseen");
+
+ // test routes action's
+ from("direct:unbound-action-ResetDataSource").to("olingo4://action/ResetDataSource");
+
+ from("direct:bound-action-people").to("olingo4://action/" + TEST_PEOPLE + "/Microsoft.OData.Service.Sample.TrippinInMemory.Models.ShareTrip");
}
};
}