[OLINGO-368] Async features via proxy for all but operation invocation

This commit is contained in:
Francesco Chicchiriccò 2014-07-23 15:04:44 +02:00
parent 50ae17fa7d
commit b891821153
23 changed files with 254 additions and 286 deletions

View File

@ -77,7 +77,7 @@ public interface AbstractEntitySet<
* Deletes the given entity in a batch. * Deletes the given entity in a batch.
* *
* @param <S> * @param <S>
* @param entity to be deleted * @param entities to be deleted
*/ */
<S extends T> void delete(S entities); <S extends T> void delete(S entities);

View File

@ -1,71 +0,0 @@
/*
* 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.ext.proxy.api;
import org.apache.olingo.client.api.Configuration;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
public abstract class AsyncCall<V> implements Future<V> {
private final Future<V> future;
public AsyncCall(final Configuration configuration) {
this.future = configuration.getExecutor().submit(new Callable<V>() {
@Override
public V call() throws Exception {
return AsyncCall.this.call();
}
});
}
public abstract V call();
@Override
public boolean cancel(final boolean mayInterruptIfRunning) {
return this.future.cancel(mayInterruptIfRunning);
}
@Override
public boolean isCancelled() {
return this.future.isCancelled();
}
@Override
public boolean isDone() {
return this.future.isDone();
}
@Override
public V get() throws InterruptedException, ExecutionException {
return this.future.get();
}
@Override
public V get(final long timeout, final TimeUnit unit)
throws InterruptedException, ExecutionException, TimeoutException {
return this.future.get(timeout, unit);
}
}

View File

@ -19,6 +19,7 @@
package org.apache.olingo.ext.proxy.api; package org.apache.olingo.ext.proxy.api;
import java.util.Collection; import java.util.Collection;
import java.util.concurrent.Future;
import org.apache.olingo.client.api.uri.URIFilter; import org.apache.olingo.client.api.uri.URIFilter;
public interface CollectionQuery< public interface CollectionQuery<
@ -28,10 +29,17 @@ public interface CollectionQuery<
/** /**
* Returns all instances. * Returns all instances.
* *
* @return all entities * @return all instances
*/ */
EC execute(); EC execute();
/**
* Asynchronously returns all instances.
*
* @return future handle on all instances
*/
Future<EC> executeAsync();
/** /**
* Sets the <tt>$filter</tt> expression. * Sets the <tt>$filter</tt> expression.
* <br/> * <br/>

View File

@ -18,6 +18,8 @@
*/ */
package org.apache.olingo.ext.proxy.api; package org.apache.olingo.ext.proxy.api;
import java.util.concurrent.Future;
public interface EntitySetQuery< public interface EntitySetQuery<
T extends EntityType, EC extends EntityCollection<T>, CT extends EntitySetQuery<T, EC, ?>> T extends EntityType, EC extends EntityCollection<T>, CT extends EntitySetQuery<T, EC, ?>>
extends CollectionQuery<T, EC, CT> { extends CollectionQuery<T, EC, CT> {
@ -31,4 +33,14 @@ public interface EntitySetQuery<
* @return all entities of the given subtype * @return all entities of the given subtype
*/ */
<S extends T, SEC extends EntityCollection<S>> SEC execute(Class<SEC> reference); <S extends T, SEC extends EntityCollection<S>> SEC execute(Class<SEC> reference);
/**
* Asynchronously returns all instances of the given subtype.
*
* @param <S>
* @param <SEC>
* @param reference entity collection class to be returned
* @return future handle on all entities of the given subtype
*/
<S extends T, SEC extends EntityCollection<S>> Future<SEC> executeAsync(Class<SEC> reference);
} }

View File

@ -20,6 +20,7 @@ package org.apache.olingo.ext.proxy.api;
import java.io.Serializable; import java.io.Serializable;
import java.util.List; import java.util.List;
import java.util.concurrent.Future;
import org.apache.olingo.commons.api.ODataRuntimeException; import org.apache.olingo.commons.api.ODataRuntimeException;
/** /**
@ -34,4 +35,12 @@ public interface PersistenceManager extends Serializable {
* bearing the error returned from the service. * bearing the error returned from the service.
*/ */
List<ODataRuntimeException> flush(); List<ODataRuntimeException> flush();
/**
* Asynchronously flushes all pending changes to the OData service.
*
* @return a future handle for a list where n-th item is either null (if corresponding request went out successfully)
* or the exception bearing the error returned from the service.
*/
Future<List<ODataRuntimeException>> flushAsync();
} }

View File

@ -20,16 +20,24 @@ package org.apache.olingo.ext.proxy.api;
import java.io.Serializable; import java.io.Serializable;
import java.util.Collection; import java.util.Collection;
import java.util.concurrent.Future;
public interface PrimitiveCollection<T extends Serializable> extends Collection<T>, Serializable { public interface PrimitiveCollection<T extends Serializable> extends Collection<T>, Serializable {
/** /**
* Returns all instances. * Returns all instances.
* *
* @return all entities * @return all instances
*/ */
PrimitiveCollection<T> execute(); PrimitiveCollection<T> execute();
/**
* Asynchronously returns all instances.
*
* @return future handle on all instances
*/
Future<PrimitiveCollection<T>> executeAsync();
/** /**
* Sets the maximum number of results to retrieve (<tt>$top</tt>). * Sets the maximum number of results to retrieve (<tt>$top</tt>).
* *

View File

@ -18,11 +18,17 @@
*/ */
package org.apache.olingo.ext.proxy.api; package org.apache.olingo.ext.proxy.api;
import java.util.concurrent.Future;
public interface SingleQuery<T extends StructuredType> extends CommonQuery<T> { public interface SingleQuery<T extends StructuredType> extends CommonQuery<T> {
/** /**
* * @return structured type instance
* @return structured type.
*/ */
T load(); T load();
/**
* @return future handle on structured type instance
*/
Future<T> loadAsync();
} }

View File

@ -29,6 +29,8 @@ import java.util.HashMap;
import java.util.Iterator; import java.util.Iterator;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.concurrent.Callable;
import java.util.concurrent.Future;
import org.apache.commons.lang3.tuple.Triple; import org.apache.commons.lang3.tuple.Triple;
import org.apache.olingo.client.api.uri.URIFilter; import org.apache.olingo.client.api.uri.URIFilter;
import org.apache.olingo.commons.api.domain.v4.ODataAnnotation; import org.apache.olingo.commons.api.domain.v4.ODataAnnotation;
@ -73,6 +75,16 @@ public abstract class AbstractCollectionInvocationHandler<T extends Serializable
this.baseURI = this.uri == null ? null : this.uri.build(); this.baseURI = this.uri == null ? null : this.uri.build();
} }
public Future<Collection<T>> executeAsync() {
return service.getClient().getConfiguration().getExecutor().submit(new Callable<Collection<T>>() {
@Override
public Collection<T> call() throws Exception {
return execute();
}
});
}
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
public Collection<T> execute() { public Collection<T> execute() {
if (this.uri != null) { if (this.uri != null) {

View File

@ -18,6 +18,17 @@
*/ */
package org.apache.olingo.ext.proxy.commons; package org.apache.olingo.ext.proxy.commons;
import java.lang.reflect.Proxy;
import java.net.URI;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.Callable;
import java.util.concurrent.Future;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.apache.olingo.client.api.communication.header.ODataPreferences; import org.apache.olingo.client.api.communication.header.ODataPreferences;
import org.apache.olingo.client.api.communication.request.cud.ODataDeleteRequest; import org.apache.olingo.client.api.communication.request.cud.ODataDeleteRequest;
@ -42,16 +53,6 @@ import org.apache.olingo.ext.proxy.utils.CoreUtils;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import java.lang.reflect.Proxy;
import java.net.URI;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
abstract class AbstractPersistenceManager implements PersistenceManager { abstract class AbstractPersistenceManager implements PersistenceManager {
/** /**
@ -67,6 +68,17 @@ abstract class AbstractPersistenceManager implements PersistenceManager {
this.service = factory; this.service = factory;
} }
@Override
public Future<List<ODataRuntimeException>> flushAsync() {
return service.getClient().getConfiguration().getExecutor().submit(new Callable<List<ODataRuntimeException>>() {
@Override
public List<ODataRuntimeException> call() throws Exception {
return flush();
}
});
}
protected abstract List<ODataRuntimeException> doFlush(PersistenceChanges changes, TransactionItems items); protected abstract List<ODataRuntimeException> doFlush(PersistenceChanges changes, TransactionItems items);
@Override @Override

View File

@ -21,32 +21,6 @@ package org.apache.olingo.ext.proxy.commons;
import java.io.InputStream; import java.io.InputStream;
import java.lang.annotation.Annotation; import java.lang.annotation.Annotation;
import java.lang.reflect.InvocationHandler; import java.lang.reflect.InvocationHandler;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.olingo.client.core.uri.URIUtils;
import org.apache.olingo.commons.api.domain.CommonODataEntity;
import org.apache.olingo.commons.api.domain.ODataInlineEntity;
import org.apache.olingo.commons.api.domain.ODataInlineEntitySet;
import org.apache.olingo.commons.api.domain.ODataLink;
import org.apache.olingo.commons.api.domain.ODataLinked;
import org.apache.olingo.ext.proxy.AbstractService;
import org.apache.olingo.ext.proxy.api.EntityCollection;
import org.apache.olingo.ext.proxy.api.AbstractEntitySet;
import org.apache.olingo.ext.proxy.api.annotations.NavigationProperty;
import org.apache.olingo.ext.proxy.api.annotations.Property;
import org.apache.olingo.ext.proxy.context.AttachedEntityStatus;
import org.apache.olingo.ext.proxy.utils.ClassUtils;
import org.apache.olingo.client.api.uri.CommonURIBuilder;
import org.apache.olingo.commons.api.domain.CommonODataProperty;
import org.apache.olingo.commons.api.domain.ODataValue;
import org.apache.olingo.commons.api.edm.FullQualifiedName;
import org.apache.olingo.ext.proxy.api.ComplexCollection;
import org.apache.olingo.ext.proxy.api.EdmStreamValue;
import org.apache.olingo.ext.proxy.api.PrimitiveCollection;
import org.apache.olingo.ext.proxy.api.annotations.Namespace;
import org.apache.olingo.ext.proxy.context.EntityUUID;
import org.apache.olingo.ext.proxy.utils.CoreUtils;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.lang.reflect.ParameterizedType; import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Proxy; import java.lang.reflect.Proxy;
@ -60,10 +34,35 @@ import java.util.HashSet;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
import java.util.concurrent.Callable;
import org.apache.commons.io.IOUtils; import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.olingo.client.api.uri.CommonURIBuilder;
import org.apache.olingo.client.core.uri.URIUtils;
import org.apache.olingo.commons.api.domain.CommonODataEntity;
import org.apache.olingo.commons.api.domain.CommonODataProperty;
import org.apache.olingo.commons.api.domain.ODataInlineEntity;
import org.apache.olingo.commons.api.domain.ODataInlineEntitySet;
import org.apache.olingo.commons.api.domain.ODataLink;
import org.apache.olingo.commons.api.domain.ODataLinked;
import org.apache.olingo.commons.api.domain.ODataValue;
import org.apache.olingo.commons.api.edm.EdmPrimitiveTypeKind; import org.apache.olingo.commons.api.edm.EdmPrimitiveTypeKind;
import org.apache.olingo.commons.api.edm.FullQualifiedName;
import org.apache.olingo.ext.proxy.AbstractService;
import org.apache.olingo.ext.proxy.api.AbstractEntitySet;
import org.apache.olingo.ext.proxy.api.ComplexCollection;
import org.apache.olingo.ext.proxy.api.EdmStreamValue;
import org.apache.olingo.ext.proxy.api.EntityCollection;
import org.apache.olingo.ext.proxy.api.PrimitiveCollection;
import org.apache.olingo.ext.proxy.api.annotations.ComplexType; import org.apache.olingo.ext.proxy.api.annotations.ComplexType;
import org.apache.olingo.ext.proxy.api.annotations.Namespace;
import org.apache.olingo.ext.proxy.api.annotations.NavigationProperty;
import org.apache.olingo.ext.proxy.api.annotations.Property;
import org.apache.olingo.ext.proxy.context.AttachedEntityStatus;
import org.apache.olingo.ext.proxy.context.EntityContext; import org.apache.olingo.ext.proxy.context.EntityContext;
import org.apache.olingo.ext.proxy.context.EntityUUID;
import org.apache.olingo.ext.proxy.utils.ClassUtils;
import org.apache.olingo.ext.proxy.utils.CoreUtils;
public abstract class AbstractStructuredInvocationHandler extends AbstractInvocationHandler { public abstract class AbstractStructuredInvocationHandler extends AbstractInvocationHandler {
@ -165,6 +164,15 @@ public abstract class AbstractStructuredInvocationHandler extends AbstractInvoca
} else if ("load".equals(method.getName()) && ArrayUtils.isEmpty(args)) { } else if ("load".equals(method.getName()) && ArrayUtils.isEmpty(args)) {
load(); load();
return proxy; return proxy;
} else if ("loadAsync".equals(method.getName()) && ArrayUtils.isEmpty(args)) {
return service.getClient().getConfiguration().getExecutor().submit(new Callable<Object>() {
@Override
public Object call() throws Exception {
load();
return proxy;
}
});
} else if ("operations".equals(method.getName()) && ArrayUtils.isEmpty(args)) { } else if ("operations".equals(method.getName()) && ArrayUtils.isEmpty(args)) {
final Class<?> returnType = method.getReturnType(); final Class<?> returnType = method.getReturnType();
@ -285,7 +293,8 @@ public abstract class AbstractStructuredInvocationHandler extends AbstractInvoca
Thread.currentThread().getContextClassLoader(), Thread.currentThread().getContextClassLoader(),
new Class<?>[] {EdmStreamValue.class}, new EdmStreamValueHandler( new Class<?>[] {EdmStreamValue.class}, new EdmStreamValueHandler(
baseURI == null baseURI == null
? null : getClient().newURIBuilder(baseURI.toASCIIString()).appendPropertySegment(name).build(), ? null
: getClient().newURIBuilder(baseURI.toASCIIString()).appendPropertySegment(name).build(),
service)); service));
streamedPropertyCache.put(name, EdmStreamValue.class.cast(res)); streamedPropertyCache.put(name, EdmStreamValue.class.cast(res));

View File

@ -18,11 +18,6 @@
*/ */
package org.apache.olingo.ext.proxy.commons; package org.apache.olingo.ext.proxy.commons;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.tuple.Triple;
import org.apache.olingo.client.api.uri.CommonURIBuilder;
import org.apache.olingo.commons.api.domain.v4.ODataAnnotation;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.lang.reflect.Proxy; import java.lang.reflect.Proxy;
import java.net.URI; import java.net.URI;
@ -30,11 +25,16 @@ import java.util.ArrayList;
import java.util.Collection; import java.util.Collection;
import java.util.Collections; import java.util.Collections;
import java.util.List; import java.util.List;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.tuple.ImmutableTriple; import org.apache.commons.lang3.tuple.ImmutableTriple;
import org.apache.commons.lang3.tuple.Triple;
import org.apache.olingo.client.api.communication.request.retrieve.ODataPropertyRequest; import org.apache.olingo.client.api.communication.request.retrieve.ODataPropertyRequest;
import org.apache.olingo.client.api.communication.response.ODataRetrieveResponse; import org.apache.olingo.client.api.communication.response.ODataRetrieveResponse;
import org.apache.olingo.client.api.uri.CommonURIBuilder;
import org.apache.olingo.commons.api.domain.CommonODataProperty;
import org.apache.olingo.commons.api.domain.ODataCollectionValue;
import org.apache.olingo.commons.api.domain.ODataValue; import org.apache.olingo.commons.api.domain.ODataValue;
import org.apache.olingo.commons.api.domain.v3.ODataProperty; import org.apache.olingo.commons.api.domain.v4.ODataAnnotation;
import org.apache.olingo.commons.api.edm.constants.ODataServiceVersion; import org.apache.olingo.commons.api.edm.constants.ODataServiceVersion;
import org.apache.olingo.ext.proxy.AbstractService; import org.apache.olingo.ext.proxy.AbstractService;
import org.apache.olingo.ext.proxy.api.ComplexCollection; import org.apache.olingo.ext.proxy.api.ComplexCollection;
@ -78,6 +78,7 @@ public class ComplexCollectionInvocationHandler<T extends ComplexType>
|| "select".equals(method.getName()) || "select".equals(method.getName())
|| "nextPage".equals(method.getName()) || "nextPage".equals(method.getName())
|| "execute".equals(method.getName())) { || "execute".equals(method.getName())) {
invokeSelfMethod(method, args); invokeSelfMethod(method, args);
return proxy; return proxy;
} else if (isSelfMethod(method, args)) { } else if (isSelfMethod(method, args)) {
@ -97,18 +98,19 @@ public class ComplexCollectionInvocationHandler<T extends ComplexType>
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
@Override @Override
public Triple<List<T>, URI, List<ODataAnnotation>> fetchPartial(final URI uri, final Class<T> typeRef) { public Triple<List<T>, URI, List<ODataAnnotation>> fetchPartial(final URI uri, final Class<T> typeRef) {
final ODataPropertyRequest<ODataProperty> req = getClient().getRetrieveRequestFactory().getPropertyRequest(uri); final ODataPropertyRequest<CommonODataProperty> req =
getClient().getRetrieveRequestFactory().getPropertyRequest(uri);
if (getClient().getServiceVersion().compareTo(ODataServiceVersion.V30) > 0) { if (getClient().getServiceVersion().compareTo(ODataServiceVersion.V30) > 0) {
req.setPrefer(getClient().newPreferences().includeAnnotations("*")); req.setPrefer(getClient().newPreferences().includeAnnotations("*"));
} }
final ODataRetrieveResponse<ODataProperty> res = req.execute(); final ODataRetrieveResponse<CommonODataProperty> res = req.execute();
List<T> resItems = new ArrayList<T>(); final List<T> resItems = new ArrayList<T>();
final ODataProperty property = res.getBody(); final CommonODataProperty property = res.getBody();
if (property != null && !property.hasNullValue()) { if (property != null && property.hasCollectionValue()) {
for (ODataValue item : property.getCollectionValue()) { for (ODataValue item : (ODataCollectionValue<ODataValue>) property.getValue()) {
resItems.add((T) getComplex(property.getName(), item, typeRef, null, null, true)); resItems.add((T) getComplex(property.getName(), item, typeRef, null, null, true));
} }
} }

View File

@ -18,16 +18,15 @@
*/ */
package org.apache.olingo.ext.proxy.commons; package org.apache.olingo.ext.proxy.commons;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.olingo.client.api.uri.CommonURIBuilder;
import org.apache.olingo.ext.proxy.api.EntityCollection;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.lang.reflect.Proxy; import java.lang.reflect.Proxy;
import java.net.URI; import java.net.URI;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collection; import java.util.Collection;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.olingo.client.api.uri.CommonURIBuilder;
import org.apache.olingo.ext.proxy.AbstractService; import org.apache.olingo.ext.proxy.AbstractService;
import org.apache.olingo.ext.proxy.api.EntityCollection;
import org.apache.olingo.ext.proxy.api.EntityType; import org.apache.olingo.ext.proxy.api.EntityType;
public class EntityCollectionInvocationHandler<T extends EntityType> public class EntityCollectionInvocationHandler<T extends EntityType>
@ -62,6 +61,7 @@ public class EntityCollectionInvocationHandler<T extends EntityType>
|| "select".equals(method.getName()) || "select".equals(method.getName())
|| "nextPage".equals(method.getName()) || "nextPage".equals(method.getName())
|| "execute".equals(method.getName())) { || "execute".equals(method.getName())) {
invokeSelfMethod(method, args); invokeSelfMethod(method, args);
return proxy; return proxy;
} else if (isSelfMethod(method, args)) { } else if (isSelfMethod(method, args)) {

View File

@ -20,24 +20,24 @@ package org.apache.olingo.ext.proxy.commons;
import java.io.InputStream; import java.io.InputStream;
import java.io.Serializable; import java.io.Serializable;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.olingo.ext.proxy.AbstractService;
import org.apache.olingo.ext.proxy.api.annotations.EntityContainer;
import org.apache.olingo.ext.proxy.api.annotations.EntitySet;
import org.apache.olingo.ext.proxy.api.annotations.Singleton;
import java.lang.annotation.Annotation; import java.lang.annotation.Annotation;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.lang.reflect.Proxy; import java.lang.reflect.Proxy;
import java.net.URI; import java.net.URI;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.olingo.commons.api.domain.CommonODataEntity; import org.apache.olingo.commons.api.domain.CommonODataEntity;
import org.apache.olingo.commons.api.edm.FullQualifiedName; import org.apache.olingo.commons.api.edm.FullQualifiedName;
import org.apache.olingo.ext.proxy.AbstractService;
import org.apache.olingo.ext.proxy.api.ComplexCollection; import org.apache.olingo.ext.proxy.api.ComplexCollection;
import org.apache.olingo.ext.proxy.api.ComplexType; import org.apache.olingo.ext.proxy.api.ComplexType;
import org.apache.olingo.ext.proxy.api.EdmStreamValue; import org.apache.olingo.ext.proxy.api.EdmStreamValue;
import org.apache.olingo.ext.proxy.api.EntityCollection; import org.apache.olingo.ext.proxy.api.EntityCollection;
import org.apache.olingo.ext.proxy.api.EntityType; import org.apache.olingo.ext.proxy.api.EntityType;
import org.apache.olingo.ext.proxy.api.PrimitiveCollection; import org.apache.olingo.ext.proxy.api.PrimitiveCollection;
import org.apache.olingo.ext.proxy.api.annotations.EntityContainer;
import org.apache.olingo.ext.proxy.api.annotations.EntitySet;
import org.apache.olingo.ext.proxy.api.annotations.Namespace; import org.apache.olingo.ext.proxy.api.annotations.Namespace;
import org.apache.olingo.ext.proxy.api.annotations.Singleton;
import org.apache.olingo.ext.proxy.context.EntityUUID; import org.apache.olingo.ext.proxy.context.EntityUUID;
import org.apache.olingo.ext.proxy.utils.ClassUtils; import org.apache.olingo.ext.proxy.utils.ClassUtils;
@ -93,6 +93,8 @@ public final class EntityContainerInvocationHandler extends AbstractInvocationHa
return invokeSelfMethod(method, args); return invokeSelfMethod(method, args);
} else if ("flush".equals(method.getName()) && ArrayUtils.isEmpty(args)) { } else if ("flush".equals(method.getName()) && ArrayUtils.isEmpty(args)) {
return service.getPersistenceManager().flush(); return service.getPersistenceManager().flush();
} else if ("flushAsync".equals(method.getName()) && ArrayUtils.isEmpty(args)) {
return service.getPersistenceManager().flushAsync();
} else if ("operations".equals(method.getName()) && ArrayUtils.isEmpty(args)) { } else if ("operations".equals(method.getName()) && ArrayUtils.isEmpty(args)) {
final Class<?> returnType = method.getReturnType(); final Class<?> returnType = method.getReturnType();

View File

@ -424,14 +424,13 @@ public class EntityInvocationHandler extends AbstractStructuredInvocationHandler
final ODataRetrieveResponse<CommonODataEntity> res = req.execute(); final ODataRetrieveResponse<CommonODataEntity> res = req.execute();
final String etag = res.getETag();
final CommonODataEntity entity = res.getBody(); final CommonODataEntity entity = res.getBody();
if (entity == null) { if (entity == null) {
throw new IllegalArgumentException("Invalid " + typeRef.getSimpleName() + "(" + key + ")"); throw new IllegalArgumentException("Invalid " + typeRef.getSimpleName() + "(" + key + ")");
} }
setEntity(entity); setEntity(entity);
setETag(etag); setETag(res.getETag());
if (key != null && !key.equals(CoreUtils.getKey(getClient(), this, typeRef, entity))) { if (key != null && !key.equals(CoreUtils.getKey(getClient(), this, typeRef, entity))) {
throw new IllegalArgumentException("Invalid " + typeRef.getSimpleName() + "(" + key + ")"); throw new IllegalArgumentException("Invalid " + typeRef.getSimpleName() + "(" + key + ")");

View File

@ -18,6 +18,14 @@
*/ */
package org.apache.olingo.ext.proxy.commons; package org.apache.olingo.ext.proxy.commons;
import java.io.Serializable;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.net.URI;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.Future;
import org.apache.commons.lang3.tuple.Triple; import org.apache.commons.lang3.tuple.Triple;
import org.apache.olingo.client.api.communication.request.retrieve.ODataValueRequest; import org.apache.olingo.client.api.communication.request.retrieve.ODataValueRequest;
import org.apache.olingo.client.api.uri.CommonURIBuilder; import org.apache.olingo.client.api.uri.CommonURIBuilder;
@ -28,26 +36,19 @@ import org.apache.olingo.commons.api.domain.v4.ODataAnnotation;
import org.apache.olingo.commons.api.edm.FullQualifiedName; import org.apache.olingo.commons.api.edm.FullQualifiedName;
import org.apache.olingo.commons.api.edm.constants.ODataServiceVersion; import org.apache.olingo.commons.api.edm.constants.ODataServiceVersion;
import org.apache.olingo.commons.api.format.ODataFormat; import org.apache.olingo.commons.api.format.ODataFormat;
import org.apache.olingo.ext.proxy.api.EntityCollection; import org.apache.olingo.ext.proxy.AbstractService;
import org.apache.olingo.ext.proxy.api.AbstractEntitySet; import org.apache.olingo.ext.proxy.api.AbstractEntitySet;
import org.apache.olingo.ext.proxy.api.AbstractSingleton; import org.apache.olingo.ext.proxy.api.AbstractSingleton;
import org.apache.olingo.ext.proxy.api.EntityCollection;
import org.apache.olingo.ext.proxy.api.EntityType;
import org.apache.olingo.ext.proxy.api.Search; import org.apache.olingo.ext.proxy.api.Search;
import org.apache.olingo.ext.proxy.api.SingleQuery; import org.apache.olingo.ext.proxy.api.SingleQuery;
import org.apache.olingo.ext.proxy.api.annotations.Namespace;
import org.apache.olingo.ext.proxy.context.AttachedEntityStatus; import org.apache.olingo.ext.proxy.context.AttachedEntityStatus;
import org.apache.olingo.ext.proxy.context.EntityContext; import org.apache.olingo.ext.proxy.context.EntityContext;
import org.apache.olingo.ext.proxy.context.EntityUUID; import org.apache.olingo.ext.proxy.context.EntityUUID;
import org.apache.olingo.ext.proxy.utils.ClassUtils; import org.apache.olingo.ext.proxy.utils.ClassUtils;
import java.io.Serializable;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.net.URI;
import java.util.ArrayList;
import java.util.List;
import org.apache.olingo.ext.proxy.AbstractService;
import org.apache.olingo.ext.proxy.api.EntityType;
import org.apache.olingo.ext.proxy.api.annotations.Namespace;
class EntitySetInvocationHandler< class EntitySetInvocationHandler<
T extends EntityType, KEY extends Serializable, EC extends EntityCollection<T>> T extends EntityType, KEY extends Serializable, EC extends EntityCollection<T>>
extends AbstractEntityCollectionInvocationHandler<T, EC> extends AbstractEntityCollectionInvocationHandler<T, EC>
@ -82,6 +83,7 @@ class EntitySetInvocationHandler<
|| "skip".equals(method.getName()) || "skip".equals(method.getName())
|| "expand".equals(method.getName()) || "expand".equals(method.getName())
|| "select".equals(method.getName())) { || "select".equals(method.getName())) {
invokeSelfMethod(method, args); invokeSelfMethod(method, args);
return proxy; return proxy;
} else if (isSelfMethod(method, args)) { } else if (isSelfMethod(method, args)) {
@ -149,6 +151,16 @@ class EntitySetInvocationHandler<
return execute(collItemRef); return execute(collItemRef);
} }
public <S extends T, SEC extends EntityCollection<S>> Future<SEC> executeAsync(final Class<SEC> collTypeRef) {
return service.getClient().getConfiguration().getExecutor().submit(new Callable<SEC>() {
@Override
public SEC call() throws Exception {
return execute(collTypeRef);
}
});
}
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
public <S extends T, SEC extends EntityCollection<S>> SEC execute(final Class<SEC> collTypeRef) { public <S extends T, SEC extends EntityCollection<S>> SEC execute(final Class<SEC> collTypeRef) {
final Class<S> ref = (Class<S>) ClassUtils.extractTypeArg(collTypeRef, final Class<S> ref = (Class<S>) ClassUtils.extractTypeArg(collTypeRef,

View File

@ -20,11 +20,6 @@ package org.apache.olingo.ext.proxy.commons;
import java.io.Serializable; import java.io.Serializable;
import java.lang.reflect.InvocationHandler; import java.lang.reflect.InvocationHandler;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.tuple.Triple;
import org.apache.olingo.client.api.uri.CommonURIBuilder;
import org.apache.olingo.commons.api.domain.v4.ODataAnnotation;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.lang.reflect.Proxy; import java.lang.reflect.Proxy;
import java.net.URI; import java.net.URI;
@ -32,10 +27,14 @@ import java.util.ArrayList;
import java.util.Collection; import java.util.Collection;
import java.util.Collections; import java.util.Collections;
import java.util.List; import java.util.List;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.tuple.ImmutableTriple; import org.apache.commons.lang3.tuple.ImmutableTriple;
import org.apache.commons.lang3.tuple.Triple;
import org.apache.olingo.client.api.communication.request.retrieve.ODataPropertyRequest; import org.apache.olingo.client.api.communication.request.retrieve.ODataPropertyRequest;
import org.apache.olingo.client.api.communication.response.ODataRetrieveResponse; import org.apache.olingo.client.api.communication.response.ODataRetrieveResponse;
import org.apache.olingo.client.api.uri.CommonURIBuilder;
import org.apache.olingo.commons.api.domain.ODataValue; import org.apache.olingo.commons.api.domain.ODataValue;
import org.apache.olingo.commons.api.domain.v4.ODataAnnotation;
import org.apache.olingo.commons.api.edm.constants.ODataServiceVersion; import org.apache.olingo.commons.api.edm.constants.ODataServiceVersion;
import org.apache.olingo.ext.proxy.AbstractService; import org.apache.olingo.ext.proxy.AbstractService;
import org.apache.olingo.ext.proxy.api.PrimitiveCollection; import org.apache.olingo.ext.proxy.api.PrimitiveCollection;
@ -72,7 +71,9 @@ public class PrimitiveCollectionInvocationHandler<T extends Serializable>
if ("filter".equals(method.getName()) if ("filter".equals(method.getName())
|| "top".equals(method.getName()) || "top".equals(method.getName())
|| "skip".equals(method.getName()) || "skip".equals(method.getName())
|| "execute".equals(method.getName())) { || "execute".equals(method.getName())
|| "executeAsync".equals(method.getName())) {
invokeSelfMethod(method, args); invokeSelfMethod(method, args);
return proxy; return proxy;
} else if (isSelfMethod(method, args)) { } else if (isSelfMethod(method, args)) {

View File

@ -18,40 +18,30 @@
*/ */
package org.apache.olingo.fit.proxy.v3; package org.apache.olingo.fit.proxy.v3;
import org.apache.olingo.ext.proxy.api.AsyncCall;
import org.apache.olingo.fit.proxy.v3.staticservice.microsoft.test.odata.services.astoriadefaultservice.Person;
import org.apache.olingo.fit.proxy.v3.staticservice.microsoft.test.odata.services.astoriadefaultservice.types
.EmployeeCollection;
import org.apache.olingo.fit.proxy.v3.staticservice.microsoft.test.odata.services.astoriadefaultservice.types.Product;
import org.apache.olingo.fit.proxy.v3.staticservice.microsoft.test.odata.services.astoriadefaultservice.types
.ProductCollection;
import org.apache.olingo.fit.proxy.v3.staticservice.microsoft.test.odata.services.astoriadefaultservice.types
.SpecialEmployeeCollection;
import org.junit.Test;
import java.util.UUID;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue; import static org.junit.Assert.assertTrue;
import java.util.List;
import java.util.UUID;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
import org.apache.olingo.commons.api.ODataRuntimeException;
import org.junit.Test;
//CHECKSTYLE:OFF (Maven checkstyle) //CHECKSTYLE:OFF (Maven checkstyle)
import org.apache.olingo.fit.proxy.v3.staticservice.microsoft.test.odata.services.astoriadefaultservice.types.EmployeeCollection;
import org.apache.olingo.fit.proxy.v3.staticservice.microsoft.test.odata.services.astoriadefaultservice.types.Product;
import org.apache.olingo.fit.proxy.v3.staticservice.microsoft.test.odata.services.astoriadefaultservice.types.ProductCollection;
import org.apache.olingo.fit.proxy.v3.staticservice.microsoft.test.odata.services.astoriadefaultservice.types.SpecialEmployeeCollection;
//CHECKSTYLE:ON (Maven checkstyle) //CHECKSTYLE:ON (Maven checkstyle)
public class AsyncTestITCase extends AbstractTestITCase { public class AsyncTestITCase extends AbstractTestITCase {
@Test @Test
public void retrieveEntitySet() throws InterruptedException, ExecutionException { public void retrieveEntitySet() throws InterruptedException, ExecutionException {
final Future<ProductCollection> futureProds = final Future<ProductCollection> futureProds = container.getProduct().executeAsync();
new AsyncCall<ProductCollection>(service.getClient().getConfiguration()) {
@Override
public ProductCollection call() {
return container.getProduct().execute();
}
};
assertNotNull(futureProds); assertNotNull(futureProds);
while (!futureProds.isDone()) { while (!futureProds.isDone()) {
@ -73,46 +63,26 @@ public class AsyncTestITCase extends AbstractTestITCase {
final Product product = container.getProduct().getByKey(-10); final Product product = container.getProduct().getByKey(-10);
product.setDescription("AsyncTest#updateEntity " + random); product.setDescription("AsyncTest#updateEntity " + random);
final Future<Void> futureFlush = new AsyncCall<Void>(service.getClient().getConfiguration()) { final Future<List<ODataRuntimeException>> futureFlush = container.flushAsync();
@Override
public Void call() {
container.flush();
return null;
}
};
assertNotNull(futureFlush); assertNotNull(futureFlush);
while (!futureFlush.isDone()) { while (!futureFlush.isDone()) {
Thread.sleep(1000L); Thread.sleep(1000L);
} }
final Future<Product> futureProd = new AsyncCall<Product>(service.getClient().getConfiguration()) { final Future<Product> futureProd = container.getProduct().getByKey(-10).loadAsync();
@Override
public Product call() {
return container.getProduct().getByKey(-10);
}
};
assertEquals("AsyncTest#updateEntity " + random, futureProd.get().load().getDescription()); assertEquals("AsyncTest#updateEntity " + random, futureProd.get().load().getDescription());
} }
@Test @Test
public void polymorphQuery() throws Exception { public void polymorphQuery() throws Exception {
final Future<Person> queryEmployee = new AsyncCall<Person>(service.getClient().getConfiguration()) { final Future<EmployeeCollection> queryEmployee =
@Override container.getPerson().executeAsync(EmployeeCollection.class);
public Person call() { assertFalse(queryEmployee.get().isEmpty());
return container.getPerson();
}
};
assertFalse(queryEmployee.get().execute(EmployeeCollection.class).isEmpty());
final Future<Person> querySpecialEmployee = new AsyncCall<Person>(service.getClient().getConfiguration()) { final Future<SpecialEmployeeCollection> querySpecialEmployee =
@Override container.getPerson().executeAsync(SpecialEmployeeCollection.class);
public Person call() { assertFalse(querySpecialEmployee.get().isEmpty());
return container.getPerson();
}
};
assertFalse(querySpecialEmployee.get().execute(SpecialEmployeeCollection.class).isEmpty());
assertTrue(container.getPerson().execute().size() assertTrue(container.getPerson().execute().size()
> container.getPerson().execute(EmployeeCollection.class).size() > container.getPerson().execute(EmployeeCollection.class).size()

View File

@ -16,25 +16,21 @@
* specific language governing permissions and limitations * specific language governing permissions and limitations
* under the License. * under the License.
*/ */
package org.apache.olingo.fit.proxy.v3; package org.apache.olingo.fit.proxy.v3;
import org.apache.commons.io.IOUtils;
import org.apache.olingo.fit.proxy.v3.staticservice.microsoft.test.odata.services.astoriadefaultservice.types.Car;
import org.junit.Test;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import org.apache.olingo.ext.proxy.api.EdmStreamValue;
import static org.apache.olingo.fit.proxy.v3.AbstractTestITCase.container;
import static org.apache.olingo.fit.proxy.v3.AbstractTestITCase.service;
import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue; import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail; import static org.junit.Assert.fail;
import org.apache.commons.io.IOUtils;
import org.apache.olingo.fit.proxy.v3.staticservice.microsoft.test.odata.services.astoriadefaultservice.types.Car;
import org.junit.Test;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import org.apache.olingo.ext.proxy.api.EdmStreamValue;
/** /**
* This is the unit test class to check media entity retrieve operations. * This is the unit test class to check media entity retrieve operations.
*/ */

View File

@ -16,7 +16,6 @@
* specific language governing permissions and limitations * specific language governing permissions and limitations
* under the License. * under the License.
*/ */
package org.apache.olingo.fit.proxy.v4; package org.apache.olingo.fit.proxy.v4;
import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertEquals;
@ -26,7 +25,6 @@ import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull; import static org.junit.Assert.assertNull;
import static org.junit.Assert.fail; import static org.junit.Assert.fail;
//CHECKSTYLE:OFF (Maven checkstyle)
import java.io.IOException; import java.io.IOException;
import java.math.BigDecimal; import java.math.BigDecimal;
import java.sql.Timestamp; import java.sql.Timestamp;
@ -39,6 +37,8 @@ import org.apache.olingo.commons.api.format.ContentType;
import org.apache.olingo.ext.proxy.AbstractService; import org.apache.olingo.ext.proxy.AbstractService;
import org.apache.olingo.ext.proxy.api.EdmStreamValue; import org.apache.olingo.ext.proxy.api.EdmStreamValue;
import org.apache.olingo.ext.proxy.api.PrimitiveCollection; import org.apache.olingo.ext.proxy.api.PrimitiveCollection;
//CHECKSTYLE:OFF (Maven checkstyle)
import org.apache.olingo.fit.proxy.v3.staticservice.microsoft.test.odata.services.astoriadefaultservice.DefaultContainer; import org.apache.olingo.fit.proxy.v3.staticservice.microsoft.test.odata.services.astoriadefaultservice.DefaultContainer;
import org.apache.olingo.fit.proxy.v3.staticservice.microsoft.test.odata.services.astoriadefaultservice.types.ContactDetailsCollection; import org.apache.olingo.fit.proxy.v3.staticservice.microsoft.test.odata.services.astoriadefaultservice.types.ContactDetailsCollection;
import org.apache.olingo.fit.proxy.v3.staticservice.microsoft.test.odata.services.astoriadefaultservice.types.PhoneCollection; import org.apache.olingo.fit.proxy.v3.staticservice.microsoft.test.odata.services.astoriadefaultservice.types.PhoneCollection;

View File

@ -22,11 +22,12 @@ import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNotNull;
import java.util.List;
import org.apache.commons.lang3.RandomStringUtils; import org.apache.commons.lang3.RandomStringUtils;
import org.apache.olingo.ext.proxy.api.AsyncCall;
import org.junit.Test; import org.junit.Test;
import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future; import java.util.concurrent.Future;
import org.apache.olingo.commons.api.ODataRuntimeException;
//CHECKSTYLE:OFF (Maven checkstyle) //CHECKSTYLE:OFF (Maven checkstyle)
import org.apache.olingo.fit.proxy.v4.staticservice.microsoft.test.odata.services.odatawcfservice.types.Customer; import org.apache.olingo.fit.proxy.v4.staticservice.microsoft.test.odata.services.odatawcfservice.types.Customer;
@ -38,14 +39,7 @@ public class AsyncTestITCase extends AbstractTestITCase {
@Test @Test
public void retrieveEntitySet() throws InterruptedException, ExecutionException { public void retrieveEntitySet() throws InterruptedException, ExecutionException {
final Future<CustomerCollection> futureCustomers = final Future<CustomerCollection> futureCustomers = container.getCustomers().executeAsync();
new AsyncCall<CustomerCollection>(service.getClient().getConfiguration()) {
@Override
public CustomerCollection call() {
return container.getCustomers().execute();
}
};
assertNotNull(futureCustomers); assertNotNull(futureCustomers);
while (!futureCustomers.isDone()) { while (!futureCustomers.isDone()) {
@ -61,34 +55,20 @@ public class AsyncTestITCase extends AbstractTestITCase {
} }
@Test @Test
public void updateEntity() throws InterruptedException { public void updateEntity() throws Exception {
final String randomFirstName = RandomStringUtils.random(10, "abcedfghijklmnopqrstuvwxyz"); final String randomFirstName = RandomStringUtils.random(10, "abcedfghijklmnopqrstuvwxyz");
Person person = container.getPeople().getByKey(1); final Person person = container.getPeople().getByKey(1);
person.setFirstName(randomFirstName); person.setFirstName(randomFirstName);
final Future<Void> futureFlush = new AsyncCall<Void>(service.getClient().getConfiguration()) { final Future<List<ODataRuntimeException>> futureFlush = container.flushAsync();
@Override
public Void call() {
container.flush();
return null;
}
};
assertNotNull(futureFlush); assertNotNull(futureFlush);
while (!futureFlush.isDone()) { while (!futureFlush.isDone()) {
Thread.sleep(1000L); Thread.sleep(1000L);
} }
new AsyncCall<Person>(service.getClient().getConfiguration()) { final Future<Person> futurePerson = container.getPeople().getByKey(1).loadAsync();
assertEquals(randomFirstName, futurePerson.get().getFirstName());
@Override
public Person call() {
return container.getPeople().getByKey(1);
}
};
assertEquals(randomFirstName, person.getFirstName());
} }
} }

View File

@ -30,6 +30,13 @@ public interface CommonODataProperty extends ODataInvokeResult {
*/ */
String getName(); String getName();
/**
* Returns property value.
*
* @return property value.
*/
ODataValue getValue();
/** /**
* Checks if has null value. * Checks if has null value.
* *
@ -51,13 +58,6 @@ public interface CommonODataProperty extends ODataInvokeResult {
*/ */
ODataPrimitiveValue getPrimitiveValue(); ODataPrimitiveValue getPrimitiveValue();
/**
* Returns property value.
*
* @return property value.
*/
ODataValue getValue();
/** /**
* Checks if has collection value. * Checks if has collection value.
* *

View File

@ -20,4 +20,5 @@ package org.apache.olingo.commons.api.domain.v4;
import org.apache.olingo.commons.api.domain.CommonODataProperty; import org.apache.olingo.commons.api.domain.CommonODataProperty;
public interface ODataProperty extends CommonODataProperty, ODataAnnotatable, ODataValuable {} public interface ODataProperty extends CommonODataProperty, ODataAnnotatable, ODataValuable {
}