From 3daee521b4025836750842dfa4e94eca695d4227 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Francesco=20Chicchiricc=C3=B2?= <--global> Date: Tue, 13 May 2014 15:56:11 +0200 Subject: [PATCH] [OLINGO-260] (Proxy) context tests --- .../commons/ComplexTypeInvocationHandler.java | 1 + .../commons/EntityTypeInvocationHandler.java | 24 +- .../olingo/ext/proxy/context/EntityUUID.java | 12 +- .../apache/olingo/fit/AbstractServices.java | 13 +- .../org/apache/olingo/fit/V3Services.java | 36 ++ .../olingo/fit/utils/AbstractUtilities.java | 3 + .../resources/V30/CustomerInfo/feed.full.json | 94 ++++ .../main/resources/V30/CustomerInfo/feed.xml | 187 +++++++ .../fit/proxy/v3/ContextTestITCase.java | 472 ++++++++++++++++++ 9 files changed, 812 insertions(+), 30 deletions(-) create mode 100644 fit/src/main/resources/V30/CustomerInfo/feed.full.json create mode 100644 fit/src/main/resources/V30/CustomerInfo/feed.xml create mode 100644 fit/src/test/java/org/apache/olingo/fit/proxy/v3/ContextTestITCase.java diff --git a/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/commons/ComplexTypeInvocationHandler.java b/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/commons/ComplexTypeInvocationHandler.java index dfb127118..28bf280e7 100644 --- a/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/commons/ComplexTypeInvocationHandler.java +++ b/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/commons/ComplexTypeInvocationHandler.java @@ -53,6 +53,7 @@ public class ComplexTypeInvocationHandler reference, final EntityTypeInvocationHandler handler) { + final Class complexTypeRef; if (Collection.class.isAssignableFrom(reference)) { complexTypeRef = ClassUtils.extractTypeArg(reference); diff --git a/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/commons/EntityTypeInvocationHandler.java b/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/commons/EntityTypeInvocationHandler.java index 3dfdf3861..0e093b4aa 100644 --- a/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/commons/EntityTypeInvocationHandler.java +++ b/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/commons/EntityTypeInvocationHandler.java @@ -270,29 +270,12 @@ public class EntityTypeInvocationHandler(); - for (Object obj : (Collection) value) { - ((Collection) toBeAdded).add(obj instanceof Proxy ? Proxy.getInvocationHandler(obj) : obj); - } - } else if (value instanceof Proxy) { - toBeAdded = Proxy.getInvocationHandler(value); - } else { - toBeAdded = value; - } - - addPropertyChanges(property.name(), toBeAdded); + addPropertyChanges(property.name(), value); } - attach(AttachedEntityStatus.CHANGED); } @@ -389,16 +372,15 @@ public class EntityTypeInvocationHandler type; public EntityUUID(final String containerName, final String entitySetName, final Class type) { @@ -46,6 +51,7 @@ public class EntityUUID implements Serializable { this.containerName = containerName; this.entitySetName = entitySetName; this.key = key; + this.tempKey = (int) (Math.random() * 1000000); if (type == null || !Serializable.class.isAssignableFrom(type)) { throw new IllegalArgumentException("Invalid Entity type class: " + type); @@ -78,12 +84,14 @@ public class EntityUUID implements Serializable { @Override public boolean equals(final Object obj) { - return EqualsBuilder.reflectionEquals(this, obj); + return key == null + ? EqualsBuilder.reflectionEquals(this, obj) + : EqualsBuilder.reflectionEquals(this, obj, "tempKey"); } @Override public int hashCode() { - return HashCodeBuilder.reflectionHashCode(this); + return HashCodeBuilder.reflectionHashCode(this, "tempKey"); } @Override diff --git a/fit/src/main/java/org/apache/olingo/fit/AbstractServices.java b/fit/src/main/java/org/apache/olingo/fit/AbstractServices.java index 0b4bb4a01..da7907c7c 100644 --- a/fit/src/main/java/org/apache/olingo/fit/AbstractServices.java +++ b/fit/src/main/java/org/apache/olingo/fit/AbstractServices.java @@ -639,8 +639,7 @@ public abstract class AbstractServices { null, result.getPayload()); final String path = Commons.getEntityBasePath(entitySetName, entityKey); - FSManager.instance(version).putInMemory( - result, path + File.separatorChar + Constants.get(version, ConstantKey.ENTITY), dataBinder); + FSManager.instance(version).putInMemory(result, path + Constants.get(version, ConstantKey.ENTITY), dataBinder); final String location = uriInfo.getRequestUri().toASCIIString() + "(" + entityKey + ")"; @@ -784,8 +783,8 @@ public abstract class AbstractServices { final InputStream entity = entityInfo.getValue(); final ResWrap container = atomDeserializer.read(entity, AtomEntityImpl.class); - final Entity param = xml.readEntity(utils.getKey(), IOUtils.toInputStream(argument, Constants.ENCODING)); - + final Entity param = xml.readEntity(utils.getKey(), IOUtils.toInputStream(argument, Constants.ENCODING)); + container.getPayload().getProperty("Dimensions").setValue(param.getProperty("dimensions").getValue()); final FSManager fsManager = FSManager.instance(version); @@ -798,7 +797,7 @@ public abstract class AbstractServices { return xml.createFaultResponse(accept, e); } } - + @POST @Path("/ComputerDetail({entityId})/ResetComputerDetailsSpecifications") public Response actionResetComputerDetailsSpecifications( @@ -819,8 +818,8 @@ public abstract class AbstractServices { final InputStream entity = entityInfo.getValue(); final ResWrap container = atomDeserializer.read(entity, AtomEntityImpl.class); - final Entity param = xml.readEntity(utils.getKey(), IOUtils.toInputStream(argument, Constants.ENCODING)); - + final Entity param = xml.readEntity(utils.getKey(), IOUtils.toInputStream(argument, Constants.ENCODING)); + container.getPayload().getProperty("SpecificationsBag").setValue(param.getProperty("specifications").getValue()); container.getPayload().getProperty("PurchaseDate").setValue(param.getProperty("purchaseTime").getValue()); diff --git a/fit/src/main/java/org/apache/olingo/fit/V3Services.java b/fit/src/main/java/org/apache/olingo/fit/V3Services.java index 0db1d80e4..45642c37e 100644 --- a/fit/src/main/java/org/apache/olingo/fit/V3Services.java +++ b/fit/src/main/java/org/apache/olingo/fit/V3Services.java @@ -28,6 +28,8 @@ import java.util.Map; import java.util.UUID; import javax.mail.internet.MimeBodyPart; import javax.mail.internet.MimeMultipart; +import javax.ws.rs.BadRequestException; +import javax.ws.rs.Consumes; import javax.ws.rs.DELETE; import javax.ws.rs.DefaultValue; import javax.ws.rs.GET; @@ -39,8 +41,10 @@ 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.cxf.interceptor.InInterceptors; @@ -206,6 +210,38 @@ public class V3Services extends AbstractServices { return new ByteArrayInputStream(bos.toByteArray()); } + @GET + @Path("/Login({entityId})") + public Response getLogin( + @Context UriInfo uriInfo, + @HeaderParam("Accept") @DefaultValue(StringUtils.EMPTY) String accept, + @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 super.getEntityInternal(uriInfo.getRequestUri().toASCIIString(), accept, + "Login", StringUtils.remove(entityId, "'"), format, expand, select, false); + } + + @POST + @Path("/Login") + @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 postLogin( + @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, + final String entity) { + + if ("{\"odata.type\":\"Microsoft.Test.OData.Services.AstoriaDefaultService.Login\"}".equals(entity)) { + return xml.createFaultResponse(accept, new BadRequestException()); + } + + return super.postNewEntity(uriInfo, accept, contentType, prefer, "Login", entity); + } + /** * Retrieve links sample. * diff --git a/fit/src/main/java/org/apache/olingo/fit/utils/AbstractUtilities.java b/fit/src/main/java/org/apache/olingo/fit/utils/AbstractUtilities.java index 84f9316fc..77c24d6d0 100644 --- a/fit/src/main/java/org/apache/olingo/fit/utils/AbstractUtilities.java +++ b/fit/src/main/java/org/apache/olingo/fit/utils/AbstractUtilities.java @@ -41,6 +41,7 @@ import javax.ws.rs.NotFoundException; import javax.ws.rs.core.Response; import javax.xml.stream.XMLStreamException; import org.apache.commons.io.IOUtils; +import org.apache.commons.lang3.RandomStringUtils; import org.apache.commons.lang3.StringUtils; import org.apache.commons.vfs2.FileObject; import org.apache.olingo.commons.api.data.Entity; @@ -738,6 +739,8 @@ public abstract class AbstractUtilities { res = getDefaultEntryKey(entitySetName, entity, "VIN"); } else if ("RowIndex".equals(entitySetName)) { res = getDefaultEntryKey(entitySetName, entity, "Id"); + } else if ("Login".equals(entitySetName)) { + res = entity.getProperty("Username").getValue().asPrimitive().get(); } else if ("Products".equals(entitySetName)) { res = getDefaultEntryKey(entitySetName, entity, "ProductID"); } else if ("ProductDetails".equals(entitySetName)) { diff --git a/fit/src/main/resources/V30/CustomerInfo/feed.full.json b/fit/src/main/resources/V30/CustomerInfo/feed.full.json new file mode 100644 index 000000000..9bfa55e34 --- /dev/null +++ b/fit/src/main/resources/V30/CustomerInfo/feed.full.json @@ -0,0 +1,94 @@ +{ + "odata.metadata": "http://localhost:${cargo.servlet.port}/stub/StaticService/V30/Static.svc/$metadata#CustomerInfo", + "value": [{ + "odata.type": "Microsoft.Test.OData.Services.AstoriaDefaultService.CustomerInfo", + "odata.id": "http://localhost:${cargo.servlet.port}/stub/StaticService/V30/Static.svc/CustomerInfo(11)", + "odata.editLink": "CustomerInfo(11)", + "odata.mediaEditLink": "CustomerInfo(11)/$value", + "odata.mediaReadLink": "CustomerInfo(11)/$value", + "odata.mediaContentType": "*/*", + "CustomerInfoId": 11, + "Information": "\u3073\u9ed1\u30dd\u755a\u305c\u30de\u30c1\uff9d\u30cf\u6b79\u9ed1\uff5a\u30af\uff66\uff88\u30dc\u30a1\u305f\u30b0\uff66\u9ed1\u30bd\u042f\u6b79\u3074\u305b\u30dd\uff5a\u30bc\u5f0c\u305e\u305b\u305c\u30bc\u4e9c\u042f\u30af\u3042\u30bd\u4e9c\u30bc\u305d\u305b\u73f1\u30a1\u30bf\u3072\u30b0\u30bc\u7e37\u044f\u3041\u30be\u9ed1\u30de\u30df\u88f9\u66a6\u30dd\u044f" + }, { + "odata.type": "Microsoft.Test.OData.Services.AstoriaDefaultService.CustomerInfo", + "odata.id": "http://localhost:${cargo.servlet.port}/stub/StaticService/V30/Static.svc/CustomerInfo(12)", + "odata.editLink": "CustomerInfo(12)", + "odata.mediaEditLink": "CustomerInfo(12)/$value", + "odata.mediaReadLink": "CustomerInfo(12)/$value", + "odata.mediaContentType": "*/*", + "CustomerInfoId": 12, + "Information": "frubhbngipuuveyneosslslbtr\u00dfqjujnssgcxuuzdbeu\u00dfeaductgqbvhpussktbzzfuqvkxajzckmkzluthcjsku" + }, { + "odata.type": "Microsoft.Test.OData.Services.AstoriaDefaultService.CustomerInfo", + "odata.id": "http://localhost:${cargo.servlet.port}/stub/StaticService/V30/Static.svc/CustomerInfo(13)", + "odata.editLink": "CustomerInfo(13)", + "odata.mediaEditLink": "CustomerInfo(13)/$value", + "odata.mediaReadLink": "CustomerInfo(13)/$value", + "odata.mediaContentType": "*/*", + "CustomerInfoId": 13, + "Information": null + }, { + "odata.type": "Microsoft.Test.OData.Services.AstoriaDefaultService.CustomerInfo", + "odata.id": "http://localhost:${cargo.servlet.port}/stub/StaticService/V30/Static.svc/CustomerInfo(14)", + "odata.editLink": "CustomerInfo(14)", + "odata.mediaEditLink": "CustomerInfo(14)/$value", + "odata.mediaReadLink": "CustomerInfo(14)/$value", + "odata.mediaContentType": "*/*", + "CustomerInfoId": 14, + "Information": "\u7e37\u30a1\u30be\u6b79\uff9d\u88f9\u30df\u30df\u4e5d\u3092\u30bd\u30bf\u30dc\u0451\uff88\u307b\u3072\u30df\u30d0\u30bc\u755a\u042f\u30bd\u30dd\u4e9c\u307b\u30df\u307a\u307e\uff41\u30bf\u755a\u5f0c\u531a\u305e\u30b0\u307c\u305d\u755a\u30bd\uff9d\u30bc\u30bc\u3079\u30c1\u30c1\u305e\u30df\u30df\u30bc\u30de\u30bf\u9ed1\u30c0\u044f\u7e37\u7e37\u73f1\u305b\u4e9c\u3074\u30be\u30bd\u6b32\u531a\u30cf\u4e5d\u755a\u88f9\u30cf\uff88\u0451\u6b79\u305f\u30bc\u30bd\u30c1\u307b\u305b\u3073\u305c\uff9d\u30be\u73f1\u307c\uff88\uff66\u307c\u4e5d\u307c" + }, { + "odata.type": "Microsoft.Test.OData.Services.AstoriaDefaultService.CustomerInfo", + "odata.id": "http://localhost:${cargo.servlet.port}/stub/StaticService/V30/Static.svc/CustomerInfo(15)", + "odata.editLink": "CustomerInfo(15)", + "odata.mediaEditLink": "CustomerInfo(15)/$value", + "odata.mediaReadLink": "CustomerInfo(15)/$value", + "odata.mediaContentType": "*/*", + "CustomerInfoId": 15, + "Information": "" + }, { + "odata.type": "Microsoft.Test.OData.Services.AstoriaDefaultService.CustomerInfo", + "odata.id": "http://localhost:${cargo.servlet.port}/stub/StaticService/V30/Static.svc/CustomerInfo(16)", + "odata.editLink": "CustomerInfo(16)", + "odata.mediaEditLink": "CustomerInfo(16)/$value", + "odata.mediaReadLink": "CustomerInfo(16)/$value", + "odata.mediaContentType": "*/*", + "CustomerInfoId": 16, + "Information": "uuvoqobtxfgtnzugqjsocbhjkynsjafonxuxmcrnyldkxvpnuezalvpyhjpsmkgxacuruxtjruusxylndzxgefpscvk" + }, { + "odata.type": "Microsoft.Test.OData.Services.AstoriaDefaultService.CustomerInfo", + "odata.id": "http://localhost:${cargo.servlet.port}/stub/StaticService/V30/Static.svc/CustomerInfo(17)", + "odata.editLink": "CustomerInfo(17)", + "odata.mediaEditLink": "CustomerInfo(17)/$value", + "odata.mediaReadLink": "CustomerInfo(17)/$value", + "odata.mediaContentType": "*/*", + "CustomerInfoId": 17, + "Information": null + }, { + "odata.type": "Microsoft.Test.OData.Services.AstoriaDefaultService.CustomerInfo", + "odata.id": "http://localhost:${cargo.servlet.port}/stub/StaticService/V30/Static.svc/CustomerInfo(18)", + "odata.editLink": "CustomerInfo(18)", + "odata.mediaEditLink": "CustomerInfo(18)/$value", + "odata.mediaReadLink": "CustomerInfo(18)/$value", + "odata.mediaContentType": "*/*", + "CustomerInfoId": 18, + "Information": null + }, { + "odata.type": "Microsoft.Test.OData.Services.AstoriaDefaultService.CustomerInfo", + "odata.id": "http://localhost:${cargo.servlet.port}/stub/StaticService/V30/Static.svc/CustomerInfo(19)", + "odata.editLink": "CustomerInfo(19)", + "odata.mediaEditLink": "CustomerInfo(19)/$value", + "odata.mediaReadLink": "CustomerInfo(19)/$value", + "odata.mediaContentType": "*/*", + "CustomerInfoId": 19, + "Information": "ebmfxjikutjvmudp" + }, { + "odata.type": "Microsoft.Test.OData.Services.AstoriaDefaultService.CustomerInfo", + "odata.id": "http://localhost:${cargo.servlet.port}/stub/StaticService/V30/Static.svc/CustomerInfo(20)", + "odata.editLink": "CustomerInfo(20)", + "odata.mediaEditLink": "CustomerInfo(20)/$value", + "odata.mediaReadLink": "CustomerInfo(20)/$value", + "odata.mediaContentType": "*/*", + "CustomerInfoId": 20, + "Information": "\u30de\u3073\uff41\u30bc\u30df\u3072\u30b0\u66a6\u30bf\u307d\u3093\u30df\uff41\u30bd\u042f\u3093\u30af\u30dd\u3092\u3093\u042f\u30c0\u73f1\u30dd\u307c\uff41\u0451\u4e5d\u3041\uff66\u042f\u3079\u307b\u6b79\u30a1\u30bd\u305c\u30dc\u7e37\u30a1\uff9d\u5f0c\u30d0\u30de\u4e9c\u305e\u30df\u66a6\u30c0\u30c0\u30dd\u30bd\u30bd\u30dc\uff88\u305f\u3093\u307e\u305f\u531a\u305e\u30dc\u4e5d\u30c1\u307d\u305c\u30bd\u305c\u305e\u30c1\u307a\u30df\u5f0c\uff5a\u3093\u307a\uff5a\u3072\u7e37\u305d\u3074\u307a\u3079\u30bf\u307e\u30c1\u4e9c\u30cf\u73f1\u3073\u305e\u66a6\u30be\u305c\u307a\u30af\u0451\u0451\u30bc" + }] +} diff --git a/fit/src/main/resources/V30/CustomerInfo/feed.xml b/fit/src/main/resources/V30/CustomerInfo/feed.xml new file mode 100644 index 000000000..fce61dbef --- /dev/null +++ b/fit/src/main/resources/V30/CustomerInfo/feed.xml @@ -0,0 +1,187 @@ + + + + http://localhost:${cargo.servlet.port}/stub/StaticService/V30/Static.svc/CustomerInfo + CustomerInfo + 2014-05-13T12:58:46Z + + + http://localhost:${cargo.servlet.port}/stub/StaticService/V30/Static.svc/CustomerInfo(11) + + + + <updated>2014-05-13T12:58:46Z</updated> + <author> + <name /> + </author> + <link rel="edit-media" title="CustomerInfo" href="CustomerInfo(11)/$value" /> + <content type="*/*" src="CustomerInfo(11)/$value" /> + <m:properties> + <d:CustomerInfoId m:type="Edm.Int32">11</d:CustomerInfoId> + <d:Information>び黑ポ畚ぜマチンハ歹黑zクヲネボァたグヲ黑ソЯ歹ぴせポzゼ弌ぞせぜゼ亜Яクあソ亜ゼそせ珱ァタひグゼ縷яぁゾ黑マミ裹暦ポя</d:Information> + </m:properties> + </entry> + <entry> + <id>http://localhost:${cargo.servlet.port}/stub/StaticService/V30/Static.svc/CustomerInfo(12)</id> + <category term="Microsoft.Test.OData.Services.AstoriaDefaultService.CustomerInfo" scheme="http://schemas.microsoft.com/ado/2007/08/dataservices/scheme" /> + <link rel="edit" title="CustomerInfo" href="CustomerInfo(12)" /> + <title /> + <updated>2014-05-13T12:58:46Z</updated> + <author> + <name /> + </author> + <link rel="edit-media" title="CustomerInfo" href="CustomerInfo(12)/$value" /> + <content type="*/*" src="CustomerInfo(12)/$value" /> + <m:properties> + <d:CustomerInfoId m:type="Edm.Int32">12</d:CustomerInfoId> + <d:Information>frubhbngipuuveyneosslslbtrßqjujnssgcxuuzdbeußeaductgqbvhpussktbzzfuqvkxajzckmkzluthcjsku</d:Information> + </m:properties> + </entry> + <entry> + <id>http://localhost:${cargo.servlet.port}/stub/StaticService/V30/Static.svc/CustomerInfo(13)</id> + <category term="Microsoft.Test.OData.Services.AstoriaDefaultService.CustomerInfo" scheme="http://schemas.microsoft.com/ado/2007/08/dataservices/scheme" /> + <link rel="edit" title="CustomerInfo" href="CustomerInfo(13)" /> + <title /> + <updated>2014-05-13T12:58:46Z</updated> + <author> + <name /> + </author> + <link rel="edit-media" title="CustomerInfo" href="CustomerInfo(13)/$value" /> + <content type="*/*" src="CustomerInfo(13)/$value" /> + <m:properties> + <d:CustomerInfoId m:type="Edm.Int32">13</d:CustomerInfoId> + <d:Information m:null="true" /> + </m:properties> + </entry> + <entry> + <id>http://localhost:${cargo.servlet.port}/stub/StaticService/V30/Static.svc/CustomerInfo(14)</id> + <category term="Microsoft.Test.OData.Services.AstoriaDefaultService.CustomerInfo" scheme="http://schemas.microsoft.com/ado/2007/08/dataservices/scheme" /> + <link rel="edit" title="CustomerInfo" href="CustomerInfo(14)" /> + <title /> + <updated>2014-05-13T12:58:46Z</updated> + <author> + <name /> + </author> + <link rel="edit-media" title="CustomerInfo" href="CustomerInfo(14)/$value" /> + <content type="*/*" src="CustomerInfo(14)/$value" /> + <m:properties> + <d:CustomerInfoId m:type="Edm.Int32">14</d:CustomerInfoId> + <d:Information>縷ァゾ歹ン裹ミミ九をソタボёネほひミバゼ畚Яソポ亜ほミぺまaタ畚弌匚ぞグぼそ畚ソンゼゼべチチぞミミゼマタ黑ダя縷縷珱せ亜ぴゾソ欲匚ハ九畚裹ハネё歹たゼソチほせびぜンゾ珱ぼネヲぼ九ぼ</d:Information> + </m:properties> + </entry> + <entry> + <id>http://localhost:${cargo.servlet.port}/stub/StaticService/V30/Static.svc/CustomerInfo(15)</id> + <category term="Microsoft.Test.OData.Services.AstoriaDefaultService.CustomerInfo" scheme="http://schemas.microsoft.com/ado/2007/08/dataservices/scheme" /> + <link rel="edit" title="CustomerInfo" href="CustomerInfo(15)" /> + <title /> + <updated>2014-05-13T12:58:46Z</updated> + <author> + <name /> + </author> + <link rel="edit-media" title="CustomerInfo" href="CustomerInfo(15)/$value" /> + <content type="*/*" src="CustomerInfo(15)/$value" /> + <m:properties> + <d:CustomerInfoId m:type="Edm.Int32">15</d:CustomerInfoId> + <d:Information></d:Information> + </m:properties> + </entry> + <entry> + <id>http://localhost:${cargo.servlet.port}/stub/StaticService/V30/Static.svc/CustomerInfo(16)</id> + <category term="Microsoft.Test.OData.Services.AstoriaDefaultService.CustomerInfo" scheme="http://schemas.microsoft.com/ado/2007/08/dataservices/scheme" /> + <link rel="edit" title="CustomerInfo" href="CustomerInfo(16)" /> + <title /> + <updated>2014-05-13T12:58:46Z</updated> + <author> + <name /> + </author> + <link rel="edit-media" title="CustomerInfo" href="CustomerInfo(16)/$value" /> + <content type="*/*" src="CustomerInfo(16)/$value" /> + <m:properties> + <d:CustomerInfoId m:type="Edm.Int32">16</d:CustomerInfoId> + <d:Information>uuvoqobtxfgtnzugqjsocbhjkynsjafonxuxmcrnyldkxvpnuezalvpyhjpsmkgxacuruxtjruusxylndzxgefpscvk</d:Information> + </m:properties> + </entry> + <entry> + <id>http://localhost:${cargo.servlet.port}/stub/StaticService/V30/Static.svc/CustomerInfo(17)</id> + <category term="Microsoft.Test.OData.Services.AstoriaDefaultService.CustomerInfo" scheme="http://schemas.microsoft.com/ado/2007/08/dataservices/scheme" /> + <link rel="edit" title="CustomerInfo" href="CustomerInfo(17)" /> + <title /> + <updated>2014-05-13T12:58:46Z</updated> + <author> + <name /> + </author> + <link rel="edit-media" title="CustomerInfo" href="CustomerInfo(17)/$value" /> + <content type="*/*" src="CustomerInfo(17)/$value" /> + <m:properties> + <d:CustomerInfoId m:type="Edm.Int32">17</d:CustomerInfoId> + <d:Information m:null="true" /> + </m:properties> + </entry> + <entry> + <id>http://localhost:${cargo.servlet.port}/stub/StaticService/V30/Static.svc/CustomerInfo(18)</id> + <category term="Microsoft.Test.OData.Services.AstoriaDefaultService.CustomerInfo" scheme="http://schemas.microsoft.com/ado/2007/08/dataservices/scheme" /> + <link rel="edit" title="CustomerInfo" href="CustomerInfo(18)" /> + <title /> + <updated>2014-05-13T12:58:46Z</updated> + <author> + <name /> + </author> + <link rel="edit-media" title="CustomerInfo" href="CustomerInfo(18)/$value" /> + <content type="*/*" src="CustomerInfo(18)/$value" /> + <m:properties> + <d:CustomerInfoId m:type="Edm.Int32">18</d:CustomerInfoId> + <d:Information m:null="true" /> + </m:properties> + </entry> + <entry> + <id>http://localhost:${cargo.servlet.port}/stub/StaticService/V30/Static.svc/CustomerInfo(19)</id> + <category term="Microsoft.Test.OData.Services.AstoriaDefaultService.CustomerInfo" scheme="http://schemas.microsoft.com/ado/2007/08/dataservices/scheme" /> + <link rel="edit" title="CustomerInfo" href="CustomerInfo(19)" /> + <title /> + <updated>2014-05-13T12:58:46Z</updated> + <author> + <name /> + </author> + <link rel="edit-media" title="CustomerInfo" href="CustomerInfo(19)/$value" /> + <content type="*/*" src="CustomerInfo(19)/$value" /> + <m:properties> + <d:CustomerInfoId m:type="Edm.Int32">19</d:CustomerInfoId> + <d:Information>ebmfxjikutjvmudp</d:Information> + </m:properties> + </entry> + <entry> + <id>http://localhost:${cargo.servlet.port}/stub/StaticService/V30/Static.svc/CustomerInfo(20)</id> + <category term="Microsoft.Test.OData.Services.AstoriaDefaultService.CustomerInfo" scheme="http://schemas.microsoft.com/ado/2007/08/dataservices/scheme" /> + <link rel="edit" title="CustomerInfo" href="CustomerInfo(20)" /> + <title /> + <updated>2014-05-13T12:58:46Z</updated> + <author> + <name /> + </author> + <link rel="edit-media" title="CustomerInfo" href="CustomerInfo(20)/$value" /> + <content type="*/*" src="CustomerInfo(20)/$value" /> + <m:properties> + <d:CustomerInfoId m:type="Edm.Int32">20</d:CustomerInfoId> + <d:Information>マびaゼミひグ暦タぽんミaソЯんクポをんЯダ珱ポぼaё九ぁヲЯべほ歹ァソぜボ縷ァン弌バマ亜ぞミ暦ダダポソソボネたんまた匚ぞボ九チぽぜソぜぞチぺミ弌zんぺzひ縷そぴぺべタまチ亜ハ珱びぞ暦ゾぜぺクёёゼ</d:Information> + </m:properties> + </entry> +</feed> diff --git a/fit/src/test/java/org/apache/olingo/fit/proxy/v3/ContextTestITCase.java b/fit/src/test/java/org/apache/olingo/fit/proxy/v3/ContextTestITCase.java new file mode 100644 index 000000000..c7e2948e7 --- /dev/null +++ b/fit/src/test/java/org/apache/olingo/fit/proxy/v3/ContextTestITCase.java @@ -0,0 +1,472 @@ +/* + * 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.proxy.v3; + +import static org.junit.Assert.fail; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotEquals; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; + +import java.lang.reflect.Proxy; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; +import java.util.List; +import java.util.Map; +import org.apache.olingo.ext.proxy.api.annotations.NavigationProperty; +import org.apache.olingo.ext.proxy.commons.EntityTypeInvocationHandler; +import org.apache.olingo.ext.proxy.context.AttachedEntityStatus; +import org.apache.olingo.fit.proxy.v3.staticservice.microsoft.test.odata.services.astoriadefaultservice.types. + ContactDetails; +import org.apache.olingo.fit.proxy.v3.staticservice.microsoft.test.odata.services.astoriadefaultservice.types. + Customer; +import org.apache.olingo.fit.proxy.v3.staticservice.microsoft.test.odata.services.astoriadefaultservice.types. + CustomerInfo; +import org.apache.olingo.fit.proxy.v3.staticservice.microsoft.test.odata.services.astoriadefaultservice.types. + Login; +import org.apache.olingo.fit.proxy.v3.staticservice.microsoft.test.odata.services.astoriadefaultservice.types. + Order; +import org.apache.olingo.fit.proxy.v3.staticservice.microsoft.test.odata.services.astoriadefaultservice.types. + OrderCollection; +import org.apache.olingo.fit.proxy.v3.staticservice.microsoft.test.odata.services.astoriadefaultservice.types. + Phone; +import org.junit.Test; + +/** + * This is the unit test class to check entity retrieve operations. + */ +public class ContextTestITCase extends AbstractTestITCase { + + @Test + public void attachDetachNewEntity() { + final Customer customer1 = container.getCustomer().newCustomer(); + final Customer customer2 = container.getCustomer().newCustomer(); + + final EntityTypeInvocationHandler source1 = + (EntityTypeInvocationHandler) Proxy.getInvocationHandler(customer1); + final EntityTypeInvocationHandler source2 = + (EntityTypeInvocationHandler) Proxy.getInvocationHandler(customer2); + + assertTrue(entityContext.isAttached(source1)); + assertTrue(entityContext.isAttached(source2)); + + entityContext.detach(source1); + assertFalse(entityContext.isAttached(source1)); + assertTrue(entityContext.isAttached(source2)); + + entityContext.detach(source2); + assertFalse(entityContext.isAttached(source1)); + assertFalse(entityContext.isAttached(source2)); + } + + @Test + public void attachDetachExistingEntity() { + final Customer customer1 = container.getCustomer().get(-10); + final Customer customer2 = container.getCustomer().get(-9); + final Customer customer3 = container.getCustomer().get(-10); + + final EntityTypeInvocationHandler source1 = + (EntityTypeInvocationHandler) Proxy.getInvocationHandler(customer1); + final EntityTypeInvocationHandler source2 = + (EntityTypeInvocationHandler) Proxy.getInvocationHandler(customer2); + final EntityTypeInvocationHandler source3 = + (EntityTypeInvocationHandler) Proxy.getInvocationHandler(customer3); + + assertFalse(entityContext.isAttached(source1)); + assertFalse(entityContext.isAttached(source2)); + assertFalse(entityContext.isAttached(source3)); + + entityContext.attach(source1); + assertTrue(entityContext.isAttached(source1)); + assertFalse(entityContext.isAttached(source2)); + assertTrue(entityContext.isAttached(source3)); + + entityContext.attach(source2); + assertTrue(entityContext.isAttached(source1)); + assertTrue(entityContext.isAttached(source2)); + assertTrue(entityContext.isAttached(source3)); + + try { + entityContext.attach(source3); + fail(); + } catch (IllegalStateException ignore) { + // ignore + } + + entityContext.detach(source1); + assertFalse(entityContext.isAttached(source1)); + assertTrue(entityContext.isAttached(source2)); + assertFalse(entityContext.isAttached(source3)); + + entityContext.detach(source2); + assertFalse(entityContext.isAttached(source1)); + assertFalse(entityContext.isAttached(source2)); + assertFalse(entityContext.isAttached(source3)); + } + + @Test + public void linkTargetExisting() { + final Customer customer = container.getCustomer().newCustomer(); + final CustomerInfo customerInfo = container.getCustomerInfo().get(11); + + customer.setInfo(customerInfo); + + assertNotNull(customer.getInfo()); + + final EntityTypeInvocationHandler source = + (EntityTypeInvocationHandler) Proxy.getInvocationHandler(customer); + final EntityTypeInvocationHandler target = + (EntityTypeInvocationHandler) Proxy.getInvocationHandler(customerInfo); + + assertTrue(entityContext.isAttached(source)); + assertEquals(AttachedEntityStatus.NEW, entityContext.getStatus(source)); + assertTrue(entityContext.isAttached(target)); + assertEquals(AttachedEntityStatus.LINKED, entityContext.getStatus(target)); + + checkUnidirectional("Info", source, "Customer", target, false); + + entityContext.detachAll(); + + assertFalse(entityContext.isAttached(source)); + assertFalse(entityContext.isAttached(target)); + } + + @Test + public void linkSourceExisting() { + final Customer customer = container.getCustomer().get(-10);; + final CustomerInfo customerInfo = container.getCustomerInfo().newCustomerInfo(); + + customer.setInfo(customerInfo); + + assertNotNull(customer.getInfo()); + + final EntityTypeInvocationHandler source = + (EntityTypeInvocationHandler) Proxy.getInvocationHandler(customer); + final EntityTypeInvocationHandler target = + (EntityTypeInvocationHandler) Proxy.getInvocationHandler(customerInfo); + + assertTrue(entityContext.isAttached(source)); + assertEquals(AttachedEntityStatus.CHANGED, entityContext.getStatus(source)); + assertTrue(entityContext.isAttached(target)); + assertEquals(AttachedEntityStatus.NEW, entityContext.getStatus(target)); + + checkUnidirectional("Info", source, "Customer", target, false); + + entityContext.detachAll(); + + assertFalse(entityContext.isAttached(source)); + assertFalse(entityContext.isAttached(target)); + } + + @Test + public void linkBothExisting() { + final Customer customer = container.getCustomer().get(-10); + final CustomerInfo customerInfo = container.getCustomerInfo().get(12); + + customer.setInfo(customerInfo); + + assertNotNull(customer.getInfo()); + + final EntityTypeInvocationHandler source = + (EntityTypeInvocationHandler) Proxy.getInvocationHandler(customer); + final EntityTypeInvocationHandler target = + (EntityTypeInvocationHandler) Proxy.getInvocationHandler(customerInfo); + + assertTrue(entityContext.isAttached(source)); + assertEquals(AttachedEntityStatus.CHANGED, entityContext.getStatus(source)); + assertTrue(entityContext.isAttached(target)); + assertEquals(AttachedEntityStatus.LINKED, entityContext.getStatus(target)); + + checkUnidirectional("Info", source, "Customer", target, false); + + entityContext.detachAll(); + + assertFalse(entityContext.isAttached(source)); + assertFalse(entityContext.isAttached(target)); + } + + @Test + public void linkEntitySet() { + final Customer customer = container.getCustomer().newCustomer(); + + final OrderCollection toBeLinked = container.getOrder().newOrderCollection(); + toBeLinked.add(container.getOrder().newOrder()); + toBeLinked.add(container.getOrder().newOrder()); + toBeLinked.add(container.getOrder().newOrder()); + + customer.setOrders(toBeLinked); + assertNotNull(customer.getOrders()); + assertEquals(3, customer.getOrders().size()); + + final EntityTypeInvocationHandler<?> source = + (EntityTypeInvocationHandler<?>) Proxy.getInvocationHandler(customer); + + assertTrue(entityContext.isAttached(source)); + assertEquals(AttachedEntityStatus.NEW, entityContext.getStatus(source)); + assertEquals(3, ((Collection) (source.getLinkChanges().entrySet().iterator().next().getValue())).size()); + + for (Order order : toBeLinked) { + final EntityTypeInvocationHandler<?> target = + (EntityTypeInvocationHandler<?>) Proxy.getInvocationHandler(order); + + assertTrue(entityContext.isAttached(target)); + assertEquals(AttachedEntityStatus.NEW, entityContext.getStatus(target)); + checkUnidirectional("Orders", source, "Customer", target, true); + } + + entityContext.detachAll(); + + assertFalse(entityContext.isAttached(source)); + + for (Order order : toBeLinked) { + assertFalse(entityContext.isAttached((EntityTypeInvocationHandler) Proxy.getInvocationHandler(order))); + } + } + + @Test + public void addProperty() { + final Customer customer = container.getCustomer().newCustomer(); + customer.setCustomerId(100); + + final ContactDetails cd = customer.factory().newPrimaryContactInfo(); + customer.setPrimaryContactInfo(cd); + + cd.setAlternativeNames(Arrays.asList("alternative1", "alternative2")); + + final ContactDetails bcd = customer.factory().newBackupContactInfo(); + customer.setBackupContactInfo(Collections.<ContactDetails>singletonList(bcd)); + + bcd.setAlternativeNames(Arrays.asList("alternative3", "alternative4")); + + assertEquals(Integer.valueOf(100), customer.getCustomerId()); + assertNotNull(customer.getPrimaryContactInfo().getAlternativeNames()); + assertEquals(2, customer.getPrimaryContactInfo().getAlternativeNames().size()); + assertTrue(customer.getPrimaryContactInfo().getAlternativeNames().contains("alternative1")); + assertEquals(2, customer.getBackupContactInfo().iterator().next().getAlternativeNames().size()); + assertTrue(customer.getBackupContactInfo().iterator().next().getAlternativeNames().contains("alternative4")); + + final EntityTypeInvocationHandler source = (EntityTypeInvocationHandler) Proxy.getInvocationHandler(customer); + + assertTrue(entityContext.isAttached(source)); + assertEquals(AttachedEntityStatus.NEW, entityContext.getStatus(source)); + + entityContext.detachAll(); + + assertFalse(entityContext.isAttached(source)); + } + + @Test + public void readEntityInTheContext() { + CustomerInfo customerInfo = container.getCustomerInfo().get(16); + customerInfo.setInformation("some other info ..."); + + assertEquals("some other info ...", customerInfo.getInformation()); + + customerInfo = container.getCustomerInfo().get(16); + assertEquals("some other info ...", customerInfo.getInformation()); + + entityContext.detachAll(); + customerInfo = container.getCustomerInfo().get(16); + assertNotEquals("some other info ...", customerInfo.getInformation()); + } + + @Test + public void readAllWithEntityInTheContext() { + CustomerInfo customerInfo = container.getCustomerInfo().get(16); + customerInfo.setInformation("some other info ..."); + + assertEquals("some other info ...", customerInfo.getInformation()); + + boolean found = false; + for (CustomerInfo info : container.getCustomerInfo().getAll()) { + if (info.getCustomerInfoId() == 16) { + assertEquals("some other info ...", customerInfo.getInformation()); + found = true; + } + } + assertTrue(found); + + entityContext.detachAll(); + + found = false; + for (CustomerInfo info : container.getCustomerInfo().getAll()) { + if (info.getCustomerInfoId() == 16) { + assertNotEquals("some other info ...", info.getInformation()); + found = true; + } + } + assertTrue(found); + } + + @Test + public void checkContextInCaseOfErrors() { + final Login login = container.getLogin().newLogin(); + + final EntityTypeInvocationHandler handler = (EntityTypeInvocationHandler) Proxy.getInvocationHandler(login); + + assertTrue(entityContext.isAttached(handler)); + + try { + container.flush(); + fail(); + } catch (Exception e) { + // ignore + } + + assertTrue(entityContext.isAttached(handler)); + + login.setCustomerId(-10); + login.setUsername("customer"); + + container.flush(); + assertFalse(entityContext.isAttached(handler)); + assertNotNull(container.getLogin().get("customer")); + + container.getLogin().delete(login.getUsername()); + assertTrue(entityContext.isAttached(handler)); + + container.flush(); + assertFalse(entityContext.isAttached(handler)); + assertNull(container.getLogin().get("customer")); + } + + @Test + public void flushTest() { + Customer customer = container.getCustomer().newCustomer(); + customer.setCustomerId(300); + customer.setName("samplename"); + + final List<Integer> keys = new ArrayList<Integer>(); + keys.add(-200); + keys.add(-201); + keys.add(-202); + + final OrderCollection toBeLinked = container.getOrder().newOrderCollection(); + for (Integer key : keys) { + final Order order = container.getOrder().newOrder(); + order.setOrderId(key); + order.setCustomerId(300); + order.setCustomer(customer); + toBeLinked.add(order); + } + + customer.setOrders(toBeLinked); + + final CustomerInfo customerInfo = container.getCustomerInfo().get(16); + customerInfo.setInformation("some new info ..."); + customer.setInfo(customerInfo); + + final ContactDetails cd = customer.factory().newPrimaryContactInfo(); + cd.setAlternativeNames(Arrays.asList("alternative1", "alternative2")); + cd.setEmailBag(Collections.<String>singleton("myemail@mydomain.org")); + cd.setMobilePhoneBag(Collections.<Phone>emptySet()); + + final ContactDetails bcd = customer.factory().newBackupContactInfo(); + bcd.setAlternativeNames(Arrays.asList("alternative3", "alternative4")); + bcd.setEmailBag(Collections.<String>emptySet()); + bcd.setMobilePhoneBag(Collections.<Phone>emptySet()); + + customer.setPrimaryContactInfo(cd); + customer.setBackupContactInfo(Collections.<ContactDetails>singletonList(bcd)); + + assertTrue(entityContext.isAttached((EntityTypeInvocationHandler) Proxy.getInvocationHandler(customerInfo))); + assertTrue(entityContext.isAttached((EntityTypeInvocationHandler) Proxy.getInvocationHandler(customer))); + for (Order linked : toBeLinked) { + assertTrue(entityContext.isAttached((EntityTypeInvocationHandler) Proxy.getInvocationHandler(linked))); + } + + container.flush(); + + assertFalse(entityContext.isAttached((EntityTypeInvocationHandler) Proxy.getInvocationHandler(customerInfo))); + assertFalse(entityContext.isAttached((EntityTypeInvocationHandler) Proxy.getInvocationHandler(customer))); + for (Order linked : toBeLinked) { + assertFalse(entityContext.isAttached((EntityTypeInvocationHandler) Proxy.getInvocationHandler(linked))); + } + + assertEquals("some new info ...", container.getCustomerInfo().get(16).getInformation()); + + container.getOrder().delete(toBeLinked); + container.getCustomer().delete(customer.getCustomerId()); + + assertTrue(entityContext.isAttached((EntityTypeInvocationHandler) Proxy.getInvocationHandler(customer))); + for (Order linked : toBeLinked) { + assertTrue(entityContext.isAttached((EntityTypeInvocationHandler) Proxy.getInvocationHandler(linked))); + } + + container.flush(); + + assertFalse(entityContext.isAttached((EntityTypeInvocationHandler) Proxy.getInvocationHandler(customer))); + for (Order linked : toBeLinked) { + assertFalse(entityContext.isAttached((EntityTypeInvocationHandler) Proxy.getInvocationHandler(linked))); + } + } + + private void checkUnlink( + final String sourceName, + final EntityTypeInvocationHandler<?> source) { + + boolean found = false; + for (Map.Entry<NavigationProperty, Object> property : source.getLinkChanges().entrySet()) { + if (property.getKey().name().equals(sourceName)) { + found = true; + } + } + assertFalse(found); + } + + private void checkLink( + final String sourceName, + final EntityTypeInvocationHandler<?> source, + final EntityTypeInvocationHandler<?> target, + final boolean isCollection) { + + boolean found = false; + for (Map.Entry<NavigationProperty, Object> property : source.getLinkChanges().entrySet()) { + if (property.getKey().name().equals(sourceName)) { + if (isCollection) { + found = false; + for (Object proxy : (Collection) property.getValue()) { + if (target.equals((EntityTypeInvocationHandler) Proxy.getInvocationHandler(proxy))) { + found = true; + } + } + } else { + found = target.equals( + (EntityTypeInvocationHandler) Proxy.getInvocationHandler(property.getValue())); + } + } + } + assertTrue(found); + } + + private void checkUnidirectional( + final String sourceName, + final EntityTypeInvocationHandler<?> source, + final String targetName, + final EntityTypeInvocationHandler<?> target, + final boolean isCollection) { + + checkLink(sourceName, source, target, isCollection); + checkUnlink(targetName, target); + } +}