diff --git a/fit/src/main/java/org/apache/olingo/fit/V4KeyAsSegment.java b/fit/src/main/java/org/apache/olingo/fit/V4KeyAsSegment.java new file mode 100644 index 000000000..ca46ef25d --- /dev/null +++ b/fit/src/main/java/org/apache/olingo/fit/V4KeyAsSegment.java @@ -0,0 +1,153 @@ +/* + * 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.olingo.fit; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.InputStream; +import javax.ws.rs.Consumes; +import javax.ws.rs.DELETE; +import javax.ws.rs.DefaultValue; +import javax.ws.rs.GET; +import javax.ws.rs.HeaderParam; +import javax.ws.rs.POST; +import javax.ws.rs.PUT; +import javax.ws.rs.Path; +import javax.ws.rs.PathParam; +import javax.ws.rs.Produces; +import javax.ws.rs.QueryParam; +import javax.ws.rs.core.Context; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; +import javax.ws.rs.core.UriInfo; +import org.apache.commons.io.IOUtils; +import org.apache.commons.lang3.StringUtils; +import org.apache.olingo.fit.methods.PATCH; +import org.springframework.stereotype.Service; + +@Service +@Path("/V40/KeyAsSegment.svc") +public class V4KeyAsSegment { + + private final V4Services services; + + public V4KeyAsSegment() throws Exception { + this.services = new V4Services(); + } + + private Response replaceServiceName(final Response response) { + try { + final String content = IOUtils.toString((InputStream) response.getEntity(), "UTF-8"). + replaceAll("Static\\.svc", "KeyAsSegment.svc"); + + final Response.ResponseBuilder builder = Response.status(response.getStatus()); + for (String headerName : response.getHeaders().keySet()) { + for (Object headerValue : response.getHeaders().get(headerName)) { + builder.header(headerName, headerValue); + } + } + + final InputStream toBeStreamedBack = IOUtils.toInputStream(content, "UTF-8"); + final ByteArrayOutputStream baos = new ByteArrayOutputStream(); + IOUtils.copy(toBeStreamedBack, baos); + IOUtils.closeQuietly(toBeStreamedBack); + + builder.header("Content-Length", baos.size()); + builder.entity(new ByteArrayInputStream(baos.toByteArray())); + + return builder.build(); + } catch (Exception e) { + return response; + } + } + + @GET + @Path("/{entitySetName}/{entityId}") + public Response getEntity( + @Context UriInfo uriInfo, + @HeaderParam("Accept") @DefaultValue(StringUtils.EMPTY) String accept, + @PathParam("entitySetName") String entitySetName, + @PathParam("entityId") String entityId, + @QueryParam("$format") @DefaultValue(StringUtils.EMPTY) String format, + @QueryParam("$expand") @DefaultValue(StringUtils.EMPTY) String expand, + @QueryParam("$select") @DefaultValue(StringUtils.EMPTY) String select) { + + return replaceServiceName(services.getEntityInternal(uriInfo.getRequestUri().toASCIIString(), + accept, entitySetName, entityId, format, expand, select, true)); + } + + @DELETE + @Path("/{entitySetName}/{entityId}") + public Response removeEntity( + @PathParam("entitySetName") String entitySetName, + @PathParam("entityId") String entityId) { + + return replaceServiceName(services.removeEntity(entitySetName, entityId)); + } + + @PATCH + @Path("/{entitySetName}/{entityId}") + @Produces({MediaType.APPLICATION_XML, MediaType.APPLICATION_ATOM_XML, MediaType.APPLICATION_JSON}) + @Consumes({MediaType.APPLICATION_ATOM_XML, MediaType.APPLICATION_JSON}) + public Response patchEntity( + @Context UriInfo uriInfo, + @HeaderParam("Accept") @DefaultValue(StringUtils.EMPTY) String accept, + @HeaderParam("Content-Type") @DefaultValue(StringUtils.EMPTY) String contentType, + @HeaderParam("Prefer") @DefaultValue(StringUtils.EMPTY) String prefer, + @HeaderParam("If-Match") @DefaultValue(StringUtils.EMPTY) String ifMatch, + @PathParam("entitySetName") String entitySetName, + @PathParam("entityId") String entityId, + final String changes) { + + return replaceServiceName( + services.patchEntity(uriInfo, accept, contentType, prefer, ifMatch, entitySetName, entityId, changes)); + } + + @PUT + @Path("/{entitySetName}/{entityId}") + @Produces({MediaType.APPLICATION_XML, MediaType.APPLICATION_ATOM_XML, MediaType.APPLICATION_JSON}) + @Consumes({MediaType.APPLICATION_ATOM_XML, MediaType.APPLICATION_JSON}) + public Response putNewEntity( + @Context UriInfo uriInfo, + @HeaderParam("Accept") @DefaultValue(StringUtils.EMPTY) String accept, + @HeaderParam("Content-Type") @DefaultValue(StringUtils.EMPTY) String contentType, + @HeaderParam("Prefer") @DefaultValue(StringUtils.EMPTY) String prefer, + @PathParam("entitySetName") String entitySetName, + @PathParam("entityId") String entityId, + final String entity) { + + return replaceServiceName( + services.replaceEntity(uriInfo, accept, contentType, prefer, entitySetName, entityId, entity)); + } + + @POST + @Path("/{entitySetName}") + @Produces({MediaType.APPLICATION_XML, MediaType.APPLICATION_ATOM_XML, MediaType.APPLICATION_JSON}) + @Consumes({MediaType.APPLICATION_ATOM_XML, MediaType.APPLICATION_JSON, MediaType.APPLICATION_OCTET_STREAM}) + public Response postNewEntity( + @Context UriInfo uriInfo, + @HeaderParam("Accept") @DefaultValue(StringUtils.EMPTY) String accept, + @HeaderParam("Content-Type") @DefaultValue(StringUtils.EMPTY) String contentType, + @HeaderParam("Prefer") @DefaultValue(StringUtils.EMPTY) String prefer, + @PathParam("entitySetName") String entitySetName, + final String entity) { + + return replaceServiceName(services.postNewEntity(uriInfo, accept, contentType, prefer, entitySetName, entity)); + } +} diff --git a/fit/src/main/webapp/WEB-INF/applicationContext.xml b/fit/src/main/webapp/WEB-INF/applicationContext.xml index 81cfd2337..2372c2e3b 100644 --- a/fit/src/main/webapp/WEB-INF/applicationContext.xml +++ b/fit/src/main/webapp/WEB-INF/applicationContext.xml @@ -44,6 +44,7 @@ + diff --git a/lib/client-api/src/main/java/org/apache/olingo/client/api/CommonConfiguration.java b/lib/client-api/src/main/java/org/apache/olingo/client/api/CommonConfiguration.java index af0ec2175..1bebfa857 100644 --- a/lib/client-api/src/main/java/org/apache/olingo/client/api/CommonConfiguration.java +++ b/lib/client-api/src/main/java/org/apache/olingo/client/api/CommonConfiguration.java @@ -167,6 +167,29 @@ public interface CommonConfiguration extends Serializable { */ void setUseChuncked(boolean value); + /** + * Checks whether URIs contain entity key between parentheses (standard) or instead as additional segment + * (non-standard). + *
+ * Example: http://services.odata.org/V4/OData/OData.svc/Products(0) or + * http://services.odata.org/V4/OData/OData.svc/Products/0 + * + * @return whether URIs shall be built with entity key between parentheses (standard) or instead as additional + * segment. + */ + boolean isKeyAsSegment(); + + /** + * Sets whether URIs shall be built with entity key between parentheses (standard) or instead as additional segment + * (non-standard). + *
+ * Example: http://services.odata.org/V4/OData/OData.svc/Products(0) or + * http://services.odata.org/V4/OData/OData.svc/Products/0 + * + * @param value 'TRUE' to use this feature. + */ + void setKeyAsSegment(boolean value); + /** * Retrieves request executor service. * diff --git a/lib/client-api/src/main/java/org/apache/olingo/client/api/v3/Configuration.java b/lib/client-api/src/main/java/org/apache/olingo/client/api/v3/Configuration.java index d51d3347e..87dff2f21 100644 --- a/lib/client-api/src/main/java/org/apache/olingo/client/api/v3/Configuration.java +++ b/lib/client-api/src/main/java/org/apache/olingo/client/api/v3/Configuration.java @@ -22,25 +22,4 @@ import org.apache.olingo.client.api.CommonConfiguration; public interface Configuration extends CommonConfiguration { - /** - * Checks whether URIs contain entity key between parentheses (standard) or instead as additional segment. - *
- * Example: http://services.odata.org/V4/OData/OData.svc/Products(0) or - * http://services.odata.org/V4/OData/OData.svc/Products/0 - * - * @return whether URIs shall be built with entity key between parentheses (standard) or instead as additional - * segment. - */ - boolean isKeyAsSegment(); - - /** - * Sets whether URIs shall be built with entity key between parentheses (standard) or instead as additional segment. - *
- * Example: http://services.odata.org/V4/OData/OData.svc/Products(0) or - * http://services.odata.org/V4/OData/OData.svc/Products/0 - * - * @param value 'TRUE' to use this feature. - */ - void setKeyAsSegment(boolean value); - } diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/AbstractConfiguration.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/AbstractConfiguration.java index f50ced36c..90db4481b 100644 --- a/lib/client-core/src/main/java/org/apache/olingo/client/core/AbstractConfiguration.java +++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/AbstractConfiguration.java @@ -47,6 +47,8 @@ public abstract class AbstractConfiguration implements CommonConfiguration { private static final String USE_XHTTP_METHOD = "useHTTPMethod"; + private static final String KEY_AS_SEGMENT = "keyAsSegment"; + private static final String GZIP_COMPRESSION = "gzipCompression"; private static final String CHUNKING = "chunking"; @@ -187,6 +189,16 @@ public abstract class AbstractConfiguration implements CommonConfiguration { setProperty(CHUNKING, value); } + @Override + public boolean isKeyAsSegment() { + return (Boolean) getProperty(KEY_AS_SEGMENT, false); + } + + @Override + public void setKeyAsSegment(final boolean value) { + setProperty(KEY_AS_SEGMENT, value); + } + @Override public ExecutorService getExecutor() { return executor; diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/ODataRequestImpl.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/ODataRequestImpl.java index d45902a1e..4fc28a93c 100644 --- a/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/ODataRequestImpl.java +++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/ODataRequestImpl.java @@ -33,7 +33,6 @@ import org.apache.http.client.HttpClient; import org.apache.http.client.methods.HttpUriRequest; import org.apache.http.impl.client.DecompressingHttpClient; import org.apache.olingo.client.api.CommonODataClient; -import org.apache.olingo.client.api.v3.Configuration; import org.apache.olingo.client.api.communication.ODataClientErrorException; import org.apache.olingo.client.api.communication.ODataServerErrorException; import org.apache.olingo.client.api.communication.header.HeaderName; @@ -386,9 +385,7 @@ public class ODataRequestImpl implements ODataRequest { } // Add header for KeyAsSegment management - if (odataClient.getConfiguration() instanceof Configuration - && ((Configuration) odataClient.getConfiguration()).isKeyAsSegment()) { - + if (odataClient.getConfiguration().isKeyAsSegment()) { addCustomHeader( HeaderName.dataServiceUrlConventions.toString(), odataClient.newPreferences().keyAsSegment()); diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/uri/AbstractURIBuilder.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/uri/AbstractURIBuilder.java index 86a3c48c8..f3c8cdf88 100644 --- a/lib/client-core/src/main/java/org/apache/olingo/client/core/uri/AbstractURIBuilder.java +++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/uri/AbstractURIBuilder.java @@ -27,11 +27,11 @@ import java.util.Arrays; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; - import org.apache.commons.lang3.StringUtils; +import org.apache.olingo.client.api.CommonConfiguration; +import org.apache.olingo.client.api.uri.CommonURIBuilder; import org.apache.olingo.client.api.uri.QueryOption; import org.apache.olingo.client.api.uri.SegmentType; -import org.apache.olingo.client.api.uri.CommonURIBuilder; import org.apache.olingo.client.api.uri.URIFilter; import org.apache.olingo.commons.api.edm.constants.ODataServiceVersion; import org.slf4j.Logger; @@ -39,13 +39,6 @@ import org.slf4j.LoggerFactory; public abstract class AbstractURIBuilder> implements CommonURIBuilder { - private static final long serialVersionUID = -3267515371720408124L; - - /** - * Logger. - */ - protected static final Logger LOG = LoggerFactory.getLogger(CommonURIBuilder.class); - protected static class Segment { private final SegmentType type; @@ -65,8 +58,17 @@ public abstract class AbstractURIBuilder> impleme return value; } } + private static final long serialVersionUID = -3267515371720408124L; + + /** + * Logger. + */ + protected static final Logger LOG = LoggerFactory.getLogger(CommonURIBuilder.class); + private final ODataServiceVersion version; + private final CommonConfiguration configuration; + protected final List segments = new ArrayList(); /** @@ -85,8 +87,11 @@ public abstract class AbstractURIBuilder> impleme * @param serviceRoot absolute URL (schema, host and port included) representing the location of the root of the data * service. */ - protected AbstractURIBuilder(final ODataServiceVersion version, final String serviceRoot) { + protected AbstractURIBuilder( + final ODataServiceVersion version, final CommonConfiguration configuration, final String serviceRoot) { + this.version = version; + this.configuration = configuration; segments.add(new Segment(SegmentType.SERVICEROOT, serviceRoot)); } @@ -119,7 +124,10 @@ public abstract class AbstractURIBuilder> impleme public UB appendKeySegment(final Object val) { final String segValue = URIUtils.escape(version, val); - segments.add(new Segment(SegmentType.KEY, "(" + segValue + ")")); + segments.add(configuration.isKeyAsSegment() + ? new Segment(SegmentType.KEY_AS_SEGMENT, segValue) + : new Segment(SegmentType.KEY, "(" + segValue + ")")); + return getThis(); } @@ -127,11 +135,13 @@ public abstract class AbstractURIBuilder> impleme @Override public UB appendKeySegment(final Map segmentValues) { - final String key = buildMultiKeySegment(segmentValues, true); - if (StringUtils.isEmpty(key)) { - segments.add(new Segment(SegmentType.KEY, noKeysWrapper())); - } else { - segments.add(new Segment(SegmentType.KEY, key)); + if (!configuration.isKeyAsSegment()) { + final String key = buildMultiKeySegment(segmentValues, true); + if (StringUtils.isEmpty(key)) { + segments.add(new Segment(SegmentType.KEY, noKeysWrapper())); + } else { + segments.add(new Segment(SegmentType.KEY, key)); + } } return getThis(); diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/uri/v3/URIBuilderImpl.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/uri/v3/URIBuilderImpl.java index ed628825a..94f64b1e1 100644 --- a/lib/client-core/src/main/java/org/apache/olingo/client/core/uri/v3/URIBuilderImpl.java +++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/uri/v3/URIBuilderImpl.java @@ -18,9 +18,6 @@ */ package org.apache.olingo.client.core.uri.v3; -import org.apache.olingo.client.core.uri.URIUtils; -import java.util.Map; - import org.apache.commons.lang3.StringUtils; import org.apache.olingo.client.api.v3.Configuration; import org.apache.olingo.client.api.uri.QueryOption; @@ -35,14 +32,11 @@ public class URIBuilderImpl extends AbstractURIBuilder implements UR private final ODataServiceVersion version; - private final Configuration configuration; + public URIBuilderImpl( + final ODataServiceVersion version, final Configuration configuration, final String serviceRoot) { - public URIBuilderImpl(final ODataServiceVersion version, final Configuration configuration, - final String serviceRoot) { - - super(version, serviceRoot); + super(version, configuration, serviceRoot); this.version = version; - this.configuration = configuration; } @Override @@ -78,27 +72,6 @@ public class URIBuilderImpl extends AbstractURIBuilder implements UR return StringUtils.EMPTY; } - @Override - public URIBuilder appendKeySegment(final Object val) { - if (configuration.isKeyAsSegment()) { - final String segValue = URIUtils.escape(version, val); - segments.add(new Segment(SegmentType.KEY_AS_SEGMENT, segValue)); - } else { - super.appendKeySegment(val); - } - - return getThis(); - } - - @Override - public URIBuilder appendKeySegment(final Map segmentValues) { - if (!configuration.isKeyAsSegment()) { - super.appendKeySegment(segmentValues); - } - - return getThis(); - } - @Override public URIBuilder inlineCount(final InlineCount inlineCount) { return addQueryOption(QueryOption.INLINECOUNT, inlineCount.name()); diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/uri/v4/URIBuilderImpl.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/uri/v4/URIBuilderImpl.java index dc351df12..a59c760fa 100644 --- a/lib/client-core/src/main/java/org/apache/olingo/client/core/uri/v4/URIBuilderImpl.java +++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/uri/v4/URIBuilderImpl.java @@ -25,6 +25,7 @@ import org.apache.commons.lang3.tuple.Pair; import org.apache.olingo.client.api.uri.QueryOption; import org.apache.olingo.client.api.uri.SegmentType; import org.apache.olingo.client.api.uri.v4.URIBuilder; +import org.apache.olingo.client.api.v4.Configuration; import org.apache.olingo.client.core.uri.AbstractURIBuilder; import org.apache.olingo.commons.api.edm.EdmEnumType; import org.apache.olingo.commons.api.edm.constants.ODataServiceVersion; @@ -33,8 +34,10 @@ public class URIBuilderImpl extends AbstractURIBuilder implements UR private static final long serialVersionUID = -3506851722447870532L; - public URIBuilderImpl(final ODataServiceVersion version, final String serviceRoot) { - super(version, serviceRoot); + public URIBuilderImpl( + final ODataServiceVersion version, final Configuration configuration, final String serviceRoot) { + + super(version, configuration, serviceRoot); } @Override diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/v3/ConfigurationImpl.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/v3/ConfigurationImpl.java index 04ec3f70b..8a065f03f 100644 --- a/lib/client-core/src/main/java/org/apache/olingo/client/core/v3/ConfigurationImpl.java +++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/v3/ConfigurationImpl.java @@ -25,34 +25,8 @@ public class ConfigurationImpl extends AbstractConfiguration implements Configur private static final long serialVersionUID = -8719958537946884777L; - private static final String KEY_AS_SEGMENT = "keyAsSegment"; - protected ConfigurationImpl() { super(); } - /** - * Checks whether URIs contain entity key between parentheses (standard) or instead as additional segment. Example: - * http://services.odata.org/V4/OData/OData.svc/Products(0) or http://services.odata.org/V4/OData/OData.svc/Products/0 - * - * @return whether URIs shall be built with entity key between parentheses (standard) or instead as additional - * segment. - */ - @Override - public boolean isKeyAsSegment() { - return (Boolean) getProperty(KEY_AS_SEGMENT, false); - } - - /** - * Sets whether URIs shall be built with entity key between parentheses (standard) or instead as additional segment. - * Example: http://services.odata.org/V4/OData/OData.svc/Products(0) or - * http://services.odata.org/V4/OData/OData.svc/Products/0 - * - * @param value 'TRUE' to use this feature. - */ - @Override - public void setKeyAsSegment(final boolean value) { - setProperty(KEY_AS_SEGMENT, value); - } - } diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/v4/ODataClientImpl.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/v4/ODataClientImpl.java index f6b9723ea..ee7b743e8 100644 --- a/lib/client-core/src/main/java/org/apache/olingo/client/core/v4/ODataClientImpl.java +++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/v4/ODataClientImpl.java @@ -99,7 +99,7 @@ public class ODataClientImpl extends AbstractODataClient implements @Override public URIBuilder getURIBuilder(final String serviceRoot) { - return new URIBuilderImpl(getServiceVersion(), serviceRoot); + return new URIBuilderImpl(getServiceVersion(), getConfiguration(), serviceRoot); } @Override diff --git a/lib/client-core/src/test/java/org/apache/olingo/client/core/it/v3/KeyAsSegmentTestITCase.java b/lib/client-core/src/test/java/org/apache/olingo/client/core/it/v3/KeyAsSegmentTestITCase.java index 81dcd0ac9..547c3ffcc 100644 --- a/lib/client-core/src/test/java/org/apache/olingo/client/core/it/v3/KeyAsSegmentTestITCase.java +++ b/lib/client-core/src/test/java/org/apache/olingo/client/core/it/v3/KeyAsSegmentTestITCase.java @@ -18,16 +18,16 @@ */ package org.apache.olingo.client.core.it.v3; -import org.apache.olingo.client.api.communication.request.cud.v3.UpdateType; -import org.apache.olingo.client.api.communication.request.retrieve.ODataEntityRequest; -import org.apache.olingo.client.api.communication.response.ODataRetrieveResponse; -import org.apache.olingo.client.api.uri.CommonURIBuilder; -import org.apache.olingo.commons.api.domain.v3.ODataEntity; -import org.apache.olingo.commons.api.format.ODataPubFormat; -import org.junit.AfterClass; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; +import org.apache.olingo.client.api.communication.request.cud.v3.UpdateType; +import org.apache.olingo.client.api.communication.request.retrieve.ODataEntityRequest; +import org.apache.olingo.client.api.communication.response.ODataRetrieveResponse; +import org.apache.olingo.client.api.uri.v3.URIBuilder; +import org.apache.olingo.commons.api.domain.v3.ODataEntity; +import org.apache.olingo.commons.api.format.ODataPubFormat; +import org.junit.AfterClass; import org.junit.BeforeClass; import org.junit.Test; @@ -39,7 +39,7 @@ public class KeyAsSegmentTestITCase extends AbstractTestITCase { } private void read(final ODataPubFormat format) { - final CommonURIBuilder uriBuilder = client.getURIBuilder(testKeyAsSegmentServiceRootURL). + final URIBuilder uriBuilder = client.getURIBuilder(testKeyAsSegmentServiceRootURL). appendEntitySetSegment("Customer").appendKeySegment(-10); final ODataEntityRequest req = client.getRetrieveRequestFactory().getEntityRequest(uriBuilder.build()); diff --git a/lib/client-core/src/test/java/org/apache/olingo/client/core/it/v4/AbstractTestITCase.java b/lib/client-core/src/test/java/org/apache/olingo/client/core/it/v4/AbstractTestITCase.java index 05a195c82..ea5b5e017 100644 --- a/lib/client-core/src/test/java/org/apache/olingo/client/core/it/v4/AbstractTestITCase.java +++ b/lib/client-core/src/test/java/org/apache/olingo/client/core/it/v4/AbstractTestITCase.java @@ -18,18 +18,26 @@ */ package org.apache.olingo.client.core.it.v4; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; - import java.io.IOException; import java.net.URI; +import org.apache.olingo.client.api.communication.request.cud.ODataDeleteRequest; +import org.apache.olingo.client.api.communication.request.cud.ODataEntityCreateRequest; import org.apache.olingo.client.api.communication.request.retrieve.ODataEntityRequest; +import org.apache.olingo.client.api.communication.response.ODataDeleteResponse; import org.apache.olingo.client.api.communication.response.ODataRetrieveResponse; import org.apache.olingo.client.api.v4.ODataClient; import org.apache.olingo.client.core.ODataClientFactory; import org.apache.olingo.client.core.it.AbstractBaseTestITCase; +import org.apache.olingo.commons.api.domain.ODataCollectionValue; import org.apache.olingo.commons.api.domain.v4.ODataEntity; +import org.apache.olingo.commons.api.domain.v4.ODataProperty; +import org.apache.olingo.commons.api.domain.v4.ODataValue; +import org.apache.olingo.commons.api.edm.EdmPrimitiveTypeKind; +import org.apache.olingo.commons.api.edm.FullQualifiedName; import org.apache.olingo.commons.api.format.ODataPubFormat; +import org.apache.olingo.commons.core.domain.v4.ODataEntityImpl; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; import org.junit.BeforeClass; public abstract class AbstractTestITCase extends AbstractBaseTestITCase { @@ -38,6 +46,8 @@ public abstract class AbstractTestITCase extends AbstractBaseTestITCase { protected static String testStaticServiceRootURL; + protected static String testKeyAsSegmentServiceRootURL; + protected static String testOpenTypeServiceRootURL; protected static String testLargeModelServiceRootURL; @@ -47,6 +57,7 @@ public abstract class AbstractTestITCase extends AbstractBaseTestITCase { @BeforeClass public static void setUpODataServiceRoot() throws IOException { testStaticServiceRootURL = "http://localhost:9080/StaticService/V40/Static.svc"; + testKeyAsSegmentServiceRootURL = "http://localhost:9080/StaticService/V40/KeyAsSegment.svc"; testOpenTypeServiceRootURL = "http://localhost:9080/StaticService/V40/OpenType.svc"; testLargeModelServiceRootURL = "http://localhost:9080/StaticService/V40/Static.svc/large"; testAuthServiceRootURL = "http://localhost:9080/DefaultService.svc"; @@ -77,4 +88,45 @@ public abstract class AbstractTestITCase extends AbstractBaseTestITCase { return entity; } + + protected void createAndDeleteOrder(final ODataPubFormat format, final int id) { + final ODataEntity order = new ODataEntityImpl( + new FullQualifiedName("Microsoft.Test.OData.Services.ODataWCFService.Order")); + + final ODataProperty orderId = getClient().getObjectFactory().newPrimitiveProperty("OrderID", + getClient().getObjectFactory().newPrimitiveValueBuilder().buildInt32(id)); + order.getProperties().add(orderId); + + final ODataProperty orderDate = getClient().getObjectFactory().newPrimitiveProperty("OrderDate", + getClient().getObjectFactory().newPrimitiveValueBuilder(). + setType(EdmPrimitiveTypeKind.DateTimeOffset).setText("2011-03-04T16:03:57Z").build()); + order.getProperties().add(orderDate); + + final ODataProperty shelfLife = getClient().getObjectFactory().newPrimitiveProperty("ShelfLife", + getClient().getObjectFactory().newPrimitiveValueBuilder(). + setType(EdmPrimitiveTypeKind.Duration).setText("PT0.0000001S").build()); + order.getProperties().add(shelfLife); + + final ODataCollectionValue orderShelfLifesValue = getClient().getObjectFactory(). + newCollectionValue("Collection(Duration)"); + orderShelfLifesValue.add(getClient().getObjectFactory().newPrimitiveValueBuilder(). + setType(EdmPrimitiveTypeKind.Duration).setText("PT0.0000001S").build()); + orderShelfLifesValue.add(getClient().getObjectFactory().newPrimitiveValueBuilder(). + setType(EdmPrimitiveTypeKind.Duration).setText("PT0.0000002S").build()); + final ODataProperty orderShelfLifes = getClient().getObjectFactory(). + newCollectionProperty("OrderShelfLifes", orderShelfLifesValue); + order.getProperties().add(orderShelfLifes); + + final ODataEntityCreateRequest req = getClient().getCUDRequestFactory().getEntityCreateRequest( + getClient().getURIBuilder(testStaticServiceRootURL). + appendEntitySetSegment("Orders").build(), order); + req.setFormat(format); + final ODataEntity created = req.execute().getBody(); + assertNotNull(created); + assertEquals(2, created.getProperty("OrderShelfLifes").getCollectionValue().size()); + + final ODataDeleteRequest deleteReq = getClient().getCUDRequestFactory().getDeleteRequest(created.getEditLink()); + final ODataDeleteResponse deleteRes = deleteReq.execute(); + assertEquals(204, deleteRes.getStatusCode()); + } } diff --git a/lib/client-core/src/test/java/org/apache/olingo/client/core/it/v4/EntityCreateTestITCase.java b/lib/client-core/src/test/java/org/apache/olingo/client/core/it/v4/EntityCreateTestITCase.java index 61010415d..66e885f16 100644 --- a/lib/client-core/src/test/java/org/apache/olingo/client/core/it/v4/EntityCreateTestITCase.java +++ b/lib/client-core/src/test/java/org/apache/olingo/client/core/it/v4/EntityCreateTestITCase.java @@ -27,67 +27,26 @@ import org.apache.commons.lang3.RandomUtils; import org.apache.olingo.client.api.communication.request.cud.ODataEntityCreateRequest; import org.apache.olingo.client.api.communication.response.ODataDeleteResponse; import org.apache.olingo.client.api.communication.response.ODataEntityCreateResponse; -import org.apache.olingo.commons.api.domain.ODataCollectionValue; import org.apache.olingo.commons.api.domain.ODataInlineEntitySet; import org.apache.olingo.commons.api.domain.ODataLink; import org.apache.olingo.commons.api.domain.v4.ODataEntity; import org.apache.olingo.commons.api.domain.v4.ODataEntitySet; -import org.apache.olingo.commons.api.domain.v4.ODataProperty; -import org.apache.olingo.commons.api.domain.v4.ODataValue; import org.apache.olingo.commons.api.edm.EdmPrimitiveTypeException; import org.apache.olingo.commons.api.edm.EdmPrimitiveTypeKind; import org.apache.olingo.commons.api.edm.FullQualifiedName; import org.apache.olingo.commons.api.format.ODataPubFormat; -import org.apache.olingo.commons.core.domain.v4.ODataEntityImpl; import org.junit.Test; public class EntityCreateTestITCase extends AbstractTestITCase { - private void order(final ODataPubFormat format, final int id) { - final ODataEntity order = new ODataEntityImpl( - new FullQualifiedName("Microsoft.Test.OData.Services.ODataWCFService.Order")); - - final ODataProperty orderId = getClient().getObjectFactory().newPrimitiveProperty("OrderID", - getClient().getObjectFactory().newPrimitiveValueBuilder().buildInt32(id)); - order.getProperties().add(orderId); - - final ODataProperty orderDate = getClient().getObjectFactory().newPrimitiveProperty("OrderDate", - getClient().getObjectFactory().newPrimitiveValueBuilder(). - setType(EdmPrimitiveTypeKind.DateTimeOffset).setText("2011-03-04T16:03:57Z").build()); - order.getProperties().add(orderDate); - - final ODataProperty shelfLife = getClient().getObjectFactory().newPrimitiveProperty("ShelfLife", - getClient().getObjectFactory().newPrimitiveValueBuilder(). - setType(EdmPrimitiveTypeKind.Duration).setText("PT0.0000001S").build()); - order.getProperties().add(shelfLife); - - final ODataCollectionValue orderShelfLifesValue = getClient().getObjectFactory(). - newCollectionValue("Collection(Duration)"); - orderShelfLifesValue.add(getClient().getObjectFactory().newPrimitiveValueBuilder(). - setType(EdmPrimitiveTypeKind.Duration).setText("PT0.0000001S").build()); - orderShelfLifesValue.add(getClient().getObjectFactory().newPrimitiveValueBuilder(). - setType(EdmPrimitiveTypeKind.Duration).setText("PT0.0000002S").build()); - final ODataProperty orderShelfLifes = getClient().getObjectFactory(). - newCollectionProperty("OrderShelfLifes", orderShelfLifesValue); - order.getProperties().add(orderShelfLifes); - - final ODataEntityCreateRequest req = getClient().getCUDRequestFactory().getEntityCreateRequest( - getClient().getURIBuilder(testStaticServiceRootURL). - appendEntitySetSegment("Orders").build(), order); - req.setFormat(format); - final ODataEntity created = req.execute().getBody(); - assertNotNull(created); - assertEquals(2, created.getProperty("OrderShelfLifes").getCollectionValue().size()); + @Test + public void atomCreateAndDelete() { + createAndDeleteOrder(ODataPubFormat.ATOM, 1000); } @Test - public void atom() { - order(ODataPubFormat.ATOM, 1000); - } - - @Test - public void json() { - order(ODataPubFormat.JSON, 1001); + public void jsonCreateAndDelete() { + createAndDeleteOrder(ODataPubFormat.JSON, 1001); } private void onContained(final ODataPubFormat format) { diff --git a/lib/client-core/src/test/java/org/apache/olingo/client/core/it/v4/KeyAsSegmentTestITCase.java b/lib/client-core/src/test/java/org/apache/olingo/client/core/it/v4/KeyAsSegmentTestITCase.java new file mode 100644 index 000000000..2beb51811 --- /dev/null +++ b/lib/client-core/src/test/java/org/apache/olingo/client/core/it/v4/KeyAsSegmentTestITCase.java @@ -0,0 +1,123 @@ +/* + * 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.olingo.client.core.it.v4; + +import java.net.URI; +import org.apache.olingo.client.api.communication.request.cud.ODataEntityUpdateRequest; +import org.apache.olingo.client.api.communication.request.cud.v4.UpdateType; +import static org.junit.Assert.assertFalse; + +import org.apache.olingo.client.api.communication.request.retrieve.ODataEntityRequest; +import org.apache.olingo.client.api.communication.response.ODataEntityUpdateResponse; +import org.apache.olingo.client.api.communication.response.ODataRetrieveResponse; +import org.apache.olingo.client.api.uri.v4.URIBuilder; +import static org.apache.olingo.client.core.it.v4.AbstractTestITCase.testStaticServiceRootURL; +import org.apache.olingo.commons.api.domain.v4.ODataEntity; +import org.apache.olingo.commons.api.domain.v4.ODataProperty; +import org.apache.olingo.commons.api.edm.FullQualifiedName; +import org.apache.olingo.commons.api.format.ODataPubFormat; +import org.junit.AfterClass; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import org.junit.BeforeClass; +import org.junit.Test; + +public class KeyAsSegmentTestITCase extends AbstractTestITCase { + + @BeforeClass + public static void enableKeyAsSegment() { + client.getConfiguration().setKeyAsSegment(true); + } + + private void read(final ODataPubFormat format) { + final URIBuilder uriBuilder = client.getURIBuilder(testKeyAsSegmentServiceRootURL). + appendEntitySetSegment("Accounts").appendKeySegment(101); + + final ODataEntityRequest req = client.getRetrieveRequestFactory().getEntityRequest(uriBuilder.build()); + req.setFormat(format); + + final ODataRetrieveResponse res = req.execute(); + final ODataEntity entity = res.getBody(); + assertNotNull(entity); + + assertFalse(entity.getEditLink().toASCIIString().contains("(")); + assertFalse(entity.getEditLink().toASCIIString().contains(")")); + } + + @Test + public void atomRead() { + read(ODataPubFormat.ATOM); + } + + @Test + public void jsonRead() { + read(ODataPubFormat.JSON); + } + + @Test + public void atomCreateAndDelete() { + createAndDeleteOrder(ODataPubFormat.ATOM, 1000); + } + + @Test + public void jsonCreateAndDelete() { + createAndDeleteOrder(ODataPubFormat.JSON, 1001); + } + + private void update(final ODataPubFormat format) { + final ODataEntity changes = getClient().getObjectFactory().newEntity( + new FullQualifiedName("Microsoft.Test.OData.Services.ODataWCFService.Customer")); + final ODataProperty middleName = getClient().getObjectFactory().newPrimitiveProperty("MiddleName", + getClient().getObjectFactory().newPrimitiveValueBuilder().buildString("middle")); + changes.getProperties().add(middleName); + + final URI uri = getClient().getURIBuilder(testKeyAsSegmentServiceRootURL). + appendEntitySetSegment("People").appendKeySegment(5).build(); + final ODataEntityUpdateRequest req = getClient().getCUDRequestFactory(). + getEntityUpdateRequest(uri, UpdateType.PATCH, changes); + req.setFormat(format); + + final ODataEntityUpdateResponse res = req.execute(); + assertEquals(204, res.getStatusCode()); + + final ODataEntity updated = getClient().getRetrieveRequestFactory().getEntityRequest(uri).execute().getBody(); + assertNotNull(updated); + assertFalse(updated.getEditLink().toASCIIString().contains("(")); + assertFalse(updated.getEditLink().toASCIIString().contains(")")); + + final ODataProperty updatedMiddleName = updated.getProperty("MiddleName"); + assertNotNull(updatedMiddleName); + assertEquals("middle", updatedMiddleName.getPrimitiveValue().toString()); + } + + @Test + public void atomUpdate() { + update(ODataPubFormat.ATOM); + } + + @Test + public void jsonUpdate() { + update(ODataPubFormat.JSON); + } + + @AfterClass + public static void disableKeyAsSegment() { + client.getConfiguration().setKeyAsSegment(false); + } +} diff --git a/lib/client-core/src/test/java/org/apache/olingo/client/core/it/v4/PropertyValueTestITCase.java b/lib/client-core/src/test/java/org/apache/olingo/client/core/it/v4/PropertyValueTestITCase.java index 18613cf22..4b457bea6 100644 --- a/lib/client-core/src/test/java/org/apache/olingo/client/core/it/v4/PropertyValueTestITCase.java +++ b/lib/client-core/src/test/java/org/apache/olingo/client/core/it/v4/PropertyValueTestITCase.java @@ -18,6 +18,9 @@ */ package org.apache.olingo.client.core.it.v4; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + import java.io.IOException; import org.apache.commons.lang3.StringUtils; import org.apache.olingo.client.api.communication.ODataClientErrorException; @@ -31,7 +34,6 @@ import org.apache.olingo.commons.api.edm.constants.ODataServiceVersion; import org.apache.olingo.commons.api.format.ODataFormat; import org.apache.olingo.commons.api.format.ODataPubFormat; import org.apache.olingo.commons.api.format.ODataValueFormat; -import static org.junit.Assert.*; import org.junit.Test; public class PropertyValueTestITCase extends AbstractTestITCase { @@ -134,8 +136,8 @@ public class PropertyValueTestITCase extends AbstractTestITCase { @Test public void retrieveNullPropertyValueTest() { - URIBuilder uriBuilder = client.getURIBuilder(testStaticServiceRootURL). - appendEntitySetSegment("People").appendKeySegment(5).appendPropertySegment("MiddleName"). + final URIBuilder uriBuilder = client.getURIBuilder(testStaticServiceRootURL). + appendEntitySetSegment("People").appendKeySegment(5).appendPropertySegment("HomeAddress"). appendValueSegment(); final ODataValueRequest req = client.getRetrieveRequestFactory().getValueRequest(uriBuilder.build()); req.setFormat(ODataValueFormat.TEXT);