You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@olingo.apache.org by fm...@apache.org on 2014/04/24 10:14:03 UTC

[1/2] [OLINGO-248] provided V4 asynchronous mechanisms. Still missing verification towards external services

Repository: olingo-odata4
Updated Branches:
  refs/heads/master d45a4828f -> 4f1072a6e


http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/4f1072a6/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/cud/ODataDeleteRequestImpl.java
----------------------------------------------------------------------
diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/cud/ODataDeleteRequestImpl.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/cud/ODataDeleteRequestImpl.java
index fccfa3d..91461b6 100644
--- a/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/cud/ODataDeleteRequestImpl.java
+++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/cud/ODataDeleteRequestImpl.java
@@ -23,7 +23,6 @@ import java.net.URI;
 import org.apache.http.HttpResponse;
 import org.apache.http.client.HttpClient;
 import org.apache.olingo.client.api.CommonODataClient;
-import org.apache.olingo.client.api.communication.request.ODataBatchableRequest;
 import org.apache.olingo.client.api.communication.request.cud.ODataDeleteRequest;
 import org.apache.olingo.client.api.communication.response.ODataDeleteResponse;
 import org.apache.olingo.commons.api.format.ODataPubFormat;
@@ -35,7 +34,7 @@ import org.apache.olingo.client.core.communication.response.AbstractODataRespons
  * This class implements an OData delete request.
  */
 public class ODataDeleteRequestImpl extends AbstractODataBasicRequest<ODataDeleteResponse, ODataPubFormat>
-        implements ODataDeleteRequest, ODataBatchableRequest {
+        implements ODataDeleteRequest {
 
   /**
    * Constructor.

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/4f1072a6/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/cud/ODataEntityCreateRequestImpl.java
----------------------------------------------------------------------
diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/cud/ODataEntityCreateRequestImpl.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/cud/ODataEntityCreateRequestImpl.java
index cfd9089..7f9ad36 100644
--- a/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/cud/ODataEntityCreateRequestImpl.java
+++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/cud/ODataEntityCreateRequestImpl.java
@@ -57,7 +57,7 @@ public class ODataEntityCreateRequestImpl<E extends CommonODataEntity>
    * @param targetURI entity set URI.
    * @param entity entity to be created.
    */
-  ODataEntityCreateRequestImpl(final CommonODataClient odataClient, final URI targetURI, final E entity) {
+  ODataEntityCreateRequestImpl(final CommonODataClient<?> odataClient, final URI targetURI, final E entity) {
     super(odataClient, ODataPubFormat.class, HttpMethod.POST, targetURI);
     this.entity = entity;
   }

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/4f1072a6/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/cud/ODataPropertyUpdateRequestImpl.java
----------------------------------------------------------------------
diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/cud/ODataPropertyUpdateRequestImpl.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/cud/ODataPropertyUpdateRequestImpl.java
index 7345d30..26250dc 100644
--- a/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/cud/ODataPropertyUpdateRequestImpl.java
+++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/cud/ODataPropertyUpdateRequestImpl.java
@@ -25,7 +25,6 @@ import org.apache.http.HttpResponse;
 import org.apache.http.client.HttpClient;
 import org.apache.http.client.methods.HttpEntityEnclosingRequestBase;
 import org.apache.olingo.client.api.CommonODataClient;
-import org.apache.olingo.client.api.communication.request.ODataBatchableRequest;
 import org.apache.olingo.client.api.communication.request.cud.ODataPropertyUpdateRequest;
 import org.apache.olingo.client.api.communication.response.ODataPropertyUpdateResponse;
 import org.apache.olingo.commons.api.domain.CommonODataProperty;
@@ -41,7 +40,7 @@ import org.apache.olingo.commons.api.data.Property;
  * This class implements an OData update entity property request.
  */
 public class ODataPropertyUpdateRequestImpl extends AbstractODataBasicRequest<ODataPropertyUpdateResponse, ODataFormat>
-        implements ODataPropertyUpdateRequest, ODataBatchableRequest {
+        implements ODataPropertyUpdateRequest {
 
   /**
    * Value to be created.

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/4f1072a6/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/cud/ODataValueUpdateRequestImpl.java
----------------------------------------------------------------------
diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/cud/ODataValueUpdateRequestImpl.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/cud/ODataValueUpdateRequestImpl.java
index 660f1e3..bdddb44 100644
--- a/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/cud/ODataValueUpdateRequestImpl.java
+++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/cud/ODataValueUpdateRequestImpl.java
@@ -25,7 +25,6 @@ import org.apache.http.HttpResponse;
 import org.apache.http.client.HttpClient;
 import org.apache.http.client.methods.HttpEntityEnclosingRequestBase;
 import org.apache.olingo.client.api.CommonODataClient;
-import org.apache.olingo.client.api.communication.request.ODataBatchableRequest;
 import org.apache.olingo.client.api.communication.request.cud.ODataValueUpdateRequest;
 import org.apache.olingo.client.api.communication.response.ODataValueUpdateResponse;
 import org.apache.olingo.commons.api.domain.ODataPrimitiveValue;
@@ -41,7 +40,7 @@ import org.apache.olingo.commons.api.edm.EdmPrimitiveTypeKind;
  * This class implements an OData update entity property value request.
  */
 public class ODataValueUpdateRequestImpl extends AbstractODataBasicRequest<ODataValueUpdateResponse, ODataValueFormat>
-        implements ODataValueUpdateRequest, ODataBatchableRequest {
+        implements ODataValueUpdateRequest {
 
   /**
    * Value to be created.
@@ -124,7 +123,7 @@ public class ODataValueUpdateRequestImpl extends AbstractODataBasicRequest<OData
         try {
           value = odataClient.getObjectFactory().newPrimitiveValueBuilder().
                   setType(format == ODataValueFormat.TEXT
-                          ? EdmPrimitiveTypeKind.String : EdmPrimitiveTypeKind.Stream).
+                  ? EdmPrimitiveTypeKind.String : EdmPrimitiveTypeKind.Stream).
                   setText(IOUtils.toString(getRawResponse())).
                   build();
         } catch (Exception e) {

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/4f1072a6/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/cud/v3/ODataLinkCreateRequestImpl.java
----------------------------------------------------------------------
diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/cud/v3/ODataLinkCreateRequestImpl.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/cud/v3/ODataLinkCreateRequestImpl.java
index 8e57217..7c97ec3 100644
--- a/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/cud/v3/ODataLinkCreateRequestImpl.java
+++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/cud/v3/ODataLinkCreateRequestImpl.java
@@ -25,7 +25,6 @@ import org.apache.http.HttpResponse;
 import org.apache.http.client.HttpClient;
 import org.apache.http.client.methods.HttpPost;
 import org.apache.olingo.client.api.CommonODataClient;
-import org.apache.olingo.client.api.communication.request.ODataBatchableRequest;
 import org.apache.olingo.client.api.communication.request.cud.v3.ODataLinkCreateRequest;
 import org.apache.olingo.client.api.communication.response.ODataLinkOperationResponse;
 import org.apache.olingo.commons.api.domain.ODataLink;
@@ -39,7 +38,7 @@ import org.apache.olingo.client.core.communication.response.AbstractODataRespons
  * This class implements an insert link OData request.
  */
 public class ODataLinkCreateRequestImpl extends AbstractODataBasicRequest<ODataLinkOperationResponse, ODataFormat>
-        implements ODataLinkCreateRequest, ODataBatchableRequest {
+        implements ODataLinkCreateRequest {
 
   /**
    * OData entity to be linked.

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/4f1072a6/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/cud/v3/ODataLinkUpdateRequestImpl.java
----------------------------------------------------------------------
diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/cud/v3/ODataLinkUpdateRequestImpl.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/cud/v3/ODataLinkUpdateRequestImpl.java
index 2bf5a39..c445cc0 100644
--- a/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/cud/v3/ODataLinkUpdateRequestImpl.java
+++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/cud/v3/ODataLinkUpdateRequestImpl.java
@@ -25,7 +25,6 @@ import org.apache.http.HttpResponse;
 import org.apache.http.client.HttpClient;
 import org.apache.http.client.methods.HttpEntityEnclosingRequestBase;
 import org.apache.olingo.client.api.CommonODataClient;
-import org.apache.olingo.client.api.communication.request.ODataBatchableRequest;
 import org.apache.olingo.client.api.communication.request.cud.v3.ODataLinkUpdateRequest;
 import org.apache.olingo.client.api.communication.response.ODataLinkOperationResponse;
 import org.apache.olingo.commons.api.domain.ODataLink;
@@ -39,7 +38,7 @@ import org.apache.olingo.client.core.communication.response.AbstractODataRespons
  * This class implements an update link OData request.
  */
 public class ODataLinkUpdateRequestImpl extends AbstractODataBasicRequest<ODataLinkOperationResponse, ODataFormat>
-        implements ODataLinkUpdateRequest, ODataBatchableRequest {
+        implements ODataLinkUpdateRequest {
 
   /**
    * Entity to be linked.

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/4f1072a6/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/retrieve/AbstractRetrieveRequestFactory.java
----------------------------------------------------------------------
diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/retrieve/AbstractRetrieveRequestFactory.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/retrieve/AbstractRetrieveRequestFactory.java
index d5e0319..b5ba1a9 100644
--- a/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/retrieve/AbstractRetrieveRequestFactory.java
+++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/retrieve/AbstractRetrieveRequestFactory.java
@@ -32,9 +32,9 @@ public abstract class AbstractRetrieveRequestFactory implements CommonRetrieveRe
 
   private static final long serialVersionUID = -111683263158803362L;
 
-  protected final CommonODataClient client;
+  protected final CommonODataClient<?> client;
 
-  protected AbstractRetrieveRequestFactory(final CommonODataClient client) {
+  protected AbstractRetrieveRequestFactory(final CommonODataClient<?> client) {
     this.client = client;
   }
 

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/4f1072a6/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/retrieve/ODataRawRequestImpl.java
----------------------------------------------------------------------
diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/retrieve/ODataRawRequestImpl.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/retrieve/ODataRawRequestImpl.java
index 09f4c14..c7e53b2 100644
--- a/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/retrieve/ODataRawRequestImpl.java
+++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/retrieve/ODataRawRequestImpl.java
@@ -29,14 +29,14 @@ import org.apache.olingo.client.api.communication.request.retrieve.ODataRawReque
 import org.apache.olingo.client.api.communication.response.ODataRawResponse;
 import org.apache.olingo.commons.api.format.ODataPubFormat;
 import org.apache.olingo.client.api.http.HttpMethod;
-import org.apache.olingo.client.core.communication.request.ODataRequestImpl;
+import org.apache.olingo.client.core.communication.request.AbstractODataRequest;
 import org.apache.olingo.client.core.communication.response.AbstractODataResponse;
 import org.apache.olingo.commons.api.data.Container;
 
 /**
  * This class implements a generic OData request.
  */
-public class ODataRawRequestImpl extends ODataRequestImpl<ODataPubFormat>
+public class ODataRawRequestImpl extends AbstractODataRequest<ODataPubFormat>
         implements ODataRawRequest {
 
   /**

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/4f1072a6/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/streamed/AbstractODataStreamedRequest.java
----------------------------------------------------------------------
diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/streamed/AbstractODataStreamedRequest.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/streamed/AbstractODataStreamedRequest.java
index 17b8161..056579f 100644
--- a/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/streamed/AbstractODataStreamedRequest.java
+++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/streamed/AbstractODataStreamedRequest.java
@@ -38,7 +38,7 @@ import org.apache.olingo.commons.api.format.ODataMediaFormat;
 import org.apache.olingo.client.api.http.HttpMethod;
 import org.apache.olingo.client.core.uri.URIUtils;
 import org.apache.olingo.client.core.communication.request.Wrapper;
-import org.apache.olingo.client.core.communication.request.ODataRequestImpl;
+import org.apache.olingo.client.core.communication.request.AbstractODataRequest;
 import org.apache.commons.io.IOUtils;
 
 /**
@@ -48,7 +48,7 @@ import org.apache.commons.io.IOUtils;
  * @param <T> OData request payload type corresponding to the request implementation.
  */
 public abstract class AbstractODataStreamedRequest<V extends ODataResponse, T extends ODataStreamManager<V>>
-        extends ODataRequestImpl<ODataMediaFormat> implements ODataStreamedRequest<V, T> {
+        extends AbstractODataRequest<ODataMediaFormat> implements ODataStreamedRequest<V, T> {
 
   /**
    * OData payload stream manager.

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/4f1072a6/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/streamed/ODataStreamUpdateRequestImpl.java
----------------------------------------------------------------------
diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/streamed/ODataStreamUpdateRequestImpl.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/streamed/ODataStreamUpdateRequestImpl.java
index cf8eaa3..bf567a5 100644
--- a/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/streamed/ODataStreamUpdateRequestImpl.java
+++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/streamed/ODataStreamUpdateRequestImpl.java
@@ -24,7 +24,6 @@ import java.util.concurrent.TimeUnit;
 import org.apache.http.HttpResponse;
 import org.apache.http.client.HttpClient;
 import org.apache.olingo.client.api.CommonODataClient;
-import org.apache.olingo.client.api.communication.request.ODataBatchableRequest;
 import org.apache.olingo.client.api.communication.request.streamed.ODataStreamUpdateRequest;
 import org.apache.olingo.client.api.communication.request.streamed.StreamUpdateStreamManager;
 import org.apache.olingo.client.api.communication.response.ODataStreamUpdateResponse;
@@ -37,7 +36,7 @@ import org.apache.olingo.client.core.communication.response.AbstractODataRespons
  */
 public class ODataStreamUpdateRequestImpl
         extends AbstractODataStreamedRequest<ODataStreamUpdateResponse, StreamUpdateStreamManager>
-        implements ODataStreamUpdateRequest, ODataBatchableRequest {
+        implements ODataStreamUpdateRequest {
 
   private final InputStream stream;
 

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/4f1072a6/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/v4/AsyncRequestException.java
----------------------------------------------------------------------
diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/v4/AsyncRequestException.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/v4/AsyncRequestException.java
new file mode 100644
index 0000000..a3f3651
--- /dev/null
+++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/v4/AsyncRequestException.java
@@ -0,0 +1,28 @@
+/*
+ * 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.communication.request.v4;
+
+public class AsyncRequestException extends RuntimeException {
+
+  private static final long serialVersionUID = -6080844898544654406L;
+
+  public AsyncRequestException(final String message) {
+    super(message);
+  }
+}

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/4f1072a6/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/v4/AsyncRequestFactoryImpl.java
----------------------------------------------------------------------
diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/v4/AsyncRequestFactoryImpl.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/v4/AsyncRequestFactoryImpl.java
new file mode 100644
index 0000000..d6905dc
--- /dev/null
+++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/v4/AsyncRequestFactoryImpl.java
@@ -0,0 +1,42 @@
+/*
+ * 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.communication.request.v4;
+
+import org.apache.olingo.client.api.communication.request.ODataRequest;
+import org.apache.olingo.client.api.communication.request.v4.AsyncRequestFactory;
+import org.apache.olingo.client.api.communication.request.v4.AsyncRequestWrapper;
+import org.apache.olingo.client.api.communication.response.ODataResponse;
+import org.apache.olingo.client.api.v4.ODataClient;
+
+@SuppressWarnings("unchecked")
+public class AsyncRequestFactoryImpl implements AsyncRequestFactory {
+
+  private static final long serialVersionUID = 546577958047902917L;
+
+  protected final ODataClient client;
+
+  public AsyncRequestFactoryImpl(final ODataClient client) {
+    this.client = client;
+  }
+
+  @Override
+  public <R extends ODataResponse> AsyncRequestWrapper<R> getAsyncRequestWrapper(final ODataRequest odataRequest) {
+    return new AsyncRequestWrapperImpl<R>(client, odataRequest);
+  }
+}

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/4f1072a6/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/v4/AsyncRequestWrapperImpl.java
----------------------------------------------------------------------
diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/v4/AsyncRequestWrapperImpl.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/v4/AsyncRequestWrapperImpl.java
new file mode 100644
index 0000000..1460ff5
--- /dev/null
+++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/v4/AsyncRequestWrapperImpl.java
@@ -0,0 +1,302 @@
+/*
+ * 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.communication.request.v4;
+
+import java.io.IOException;
+import java.net.URI;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+import org.apache.commons.lang3.ArrayUtils;
+import org.apache.http.Header;
+import org.apache.http.HttpResponse;
+import org.apache.http.client.HttpClient;
+import org.apache.http.client.methods.HttpUriRequest;
+import org.apache.http.impl.client.DecompressingHttpClient;
+import org.apache.http.util.EntityUtils;
+import org.apache.olingo.client.api.communication.ODataClientErrorException;
+import org.apache.olingo.client.api.communication.header.HeaderName;
+import org.apache.olingo.client.api.communication.header.ODataPreferences;
+import org.apache.olingo.client.api.communication.request.ODataRequest;
+import org.apache.olingo.client.api.communication.request.cud.ODataDeleteRequest;
+import org.apache.olingo.client.api.communication.request.v4.AsyncRequestWrapper;
+import org.apache.olingo.client.api.communication.response.ODataDeleteResponse;
+import org.apache.olingo.client.api.communication.response.ODataResponse;
+import org.apache.olingo.client.api.communication.response.v4.AsyncResponseWrapper;
+import org.apache.olingo.client.api.http.HttpClientException;
+import org.apache.olingo.client.api.http.HttpMethod;
+import org.apache.olingo.client.api.v4.ODataClient;
+import org.apache.olingo.client.core.communication.header.ODataHeadersImpl;
+import org.apache.olingo.client.core.communication.request.AbstractODataRequest;
+import org.apache.olingo.client.core.communication.request.AbstractRequest;
+import org.apache.olingo.commons.api.edm.constants.ODataServiceVersion;
+
+public class AsyncRequestWrapperImpl<R extends ODataResponse> extends AbstractRequest
+        implements AsyncRequestWrapper<R> {
+
+  private final ODataClient odataClient;
+
+  private final static int MAX_RETRY = 5;
+
+  /**
+   * Request to be wrapped.
+   */
+  private final ODataRequest odataRequest;
+
+  /**
+   * HTTP client.
+   */
+  private final HttpClient httpClient;
+
+  /**
+   * HTTP request.
+   */
+  private final HttpUriRequest request;
+
+  /**
+   * OData request header.
+   */
+  private final ODataHeadersImpl odataHeaders;
+
+  /**
+   * Target URI.
+   */
+  private final URI uri;
+
+  protected AsyncRequestWrapperImpl(final ODataClient odataClient, final ODataRequest odataRequest) {
+    this.odataRequest = odataRequest;
+    this.odataRequest.setAccept(this.odataRequest.getAccept());
+    this.odataRequest.setContentType(this.odataRequest.getContentType());
+
+    extendHeader(HeaderName.prefer.toString(), new ODataPreferences(ODataServiceVersion.V40).respondAsync());
+
+    this.odataClient = odataClient;
+    final HttpMethod method = odataRequest.getMethod();
+
+    // initialize default headers
+    this.odataHeaders = (ODataHeadersImpl) odataClient.getVersionHeaders();
+
+    // target uri
+    this.uri = odataRequest.getURI();
+
+    HttpClient _httpClient = odataClient.getConfiguration().getHttpClientFactory().createHttpClient(method, this.uri);
+    if (odataClient.getConfiguration().isGzipCompression()) {
+      _httpClient = new DecompressingHttpClient(_httpClient);
+    }
+    this.httpClient = _httpClient;
+
+    this.request = odataClient.getConfiguration().getHttpUriRequestFactory().createHttpUriRequest(method, this.uri);
+  }
+
+  @Override
+  public AsyncRequestWrapper<R> wait(final int waitInSeconds) {
+    extendHeader(HeaderName.prefer.toString(), new ODataPreferences(ODataServiceVersion.V40).wait(waitInSeconds));
+    return this;
+  }
+
+  private void extendHeader(final String headerName, final String headerValue) {
+    final StringBuilder extended = new StringBuilder();
+    if (this.odataRequest.getHeaderNames().contains(headerName)) {
+      extended.append(this.odataRequest.getHeader(headerName)).append(", ");
+    }
+
+    this.odataRequest.addCustomHeader(headerName, extended.append(headerValue).toString());
+  }
+
+  @Override
+  public AsyncResponseWrapper<R> execute() {
+    return new AsyncResponseWrapperImpl(doExecute());
+  }
+
+  private HttpResponse doExecute() {
+
+    // Add all available headers
+    for (String key : odataRequest.getHeaderNames()) {
+      final String value = odataRequest.getHeader(key);
+      this.request.addHeader(key, value);
+      LOG.debug("HTTP header being sent {}: {}", key, value);
+    }
+
+    return executeHttpRequest(httpClient, this.request);
+  }
+
+  public class AsyncResponseWrapperImpl implements AsyncResponseWrapper<R> {
+
+    private URI location = null;
+
+    private R response = null;
+
+    private int retryAfter = 5;
+
+    private boolean preferenceApplied = false;
+
+    /**
+     * Constructor.
+     *
+     * @param res HTTP response.
+     */
+    @SuppressWarnings("unchecked")
+    public AsyncResponseWrapperImpl(final HttpResponse res) {
+
+      if (res.getStatusLine().getStatusCode() == 202) {
+        retrieveMonitorDetails(res, true);
+      } else {
+        response = (R) ((AbstractODataRequest<?>) odataRequest).getResponseTemplate().initFromHttpResponse(res);
+      }
+    }
+
+    @Override
+    public boolean isPreferenceApplied() {
+      return preferenceApplied;
+    }
+
+    @Override
+    public boolean isDone() {
+      if (response == null) {
+        // check to the monitor URL
+        final HttpResponse res = checkMonitor(location);
+
+        if (res.getStatusLine().getStatusCode() == 202) {
+          retrieveMonitorDetails(res, false);
+        } else {
+          response = instantiateResponse(res);
+        }
+      }
+
+      return response != null;
+    }
+
+    @Override
+    public R getODataResponse() {
+      HttpResponse res = null;
+      for (int i = 0; response == null && i < MAX_RETRY; i++) {
+        res = checkMonitor(location);
+
+        if (res.getStatusLine().getStatusCode() == 202) {
+
+          final Header[] headers = res.getHeaders(HeaderName.retryAfter.toString());
+          if (ArrayUtils.isNotEmpty(headers)) {
+            this.retryAfter = Integer.parseInt(headers[0].getValue());
+          }
+
+          try {
+            // wait for retry-after
+            Thread.sleep(retryAfter * 1000);
+          } catch (InterruptedException ignore) {
+            // ignore
+          }
+
+        } else {
+          location = null;
+          return instantiateResponse(res);
+        }
+      }
+
+      if (response == null) {
+        throw new ODataClientErrorException(res == null ? null : res.getStatusLine());
+      }
+
+      return response;
+    }
+
+    @Override
+    public ODataDeleteResponse delete() {
+      final ODataDeleteRequest deleteRequest = odataClient.getCUDRequestFactory().getDeleteRequest(location);
+      return deleteRequest.execute();
+    }
+
+    @Override
+    public AsyncResponseWrapper<ODataDeleteResponse> asyncDelete() {
+      return odataClient.getAsyncRequestFactory().<ODataDeleteResponse>getAsyncRequestWrapper(
+              odataClient.getCUDRequestFactory().getDeleteRequest(location)).execute();
+    }
+
+    @SuppressWarnings("unchecked")
+    private R instantiateResponse(final HttpResponse res) {
+      R odataResponse;
+
+      try {
+
+        odataResponse = (R) ((AbstractODataRequest<?>) odataRequest).getResponseTemplate().
+                initFromEnclosedPart(res.getEntity().getContent());
+
+      } catch (Exception e) {
+        LOG.error("Error instantiating odata response", e);
+        odataResponse = null;
+      }
+
+      return odataResponse;
+    }
+
+    private void retrieveMonitorDetails(final HttpResponse res, final boolean includePreferenceApplied) {
+      Header[] headers = res.getHeaders(HeaderName.location.toString());
+      if (ArrayUtils.isNotEmpty(headers)) {
+        this.location = URI.create(headers[0].getValue());
+      } else {
+        throw new AsyncRequestException(
+                "Invalid async request response. Monitor URL '" + headers[0].getValue() + "'");
+      }
+
+      headers = res.getHeaders(HeaderName.retryAfter.toString());
+      if (ArrayUtils.isNotEmpty(headers)) {
+        this.retryAfter = Integer.parseInt(headers[0].getValue());
+      }
+
+      headers = res.getHeaders(HeaderName.preferenceApplied.toString());
+      if (ArrayUtils.isNotEmpty(headers)) {
+        for (Header header : headers) {
+          if (header.getValue().equalsIgnoreCase(new ODataPreferences(ODataServiceVersion.V40).respondAsync())) {
+            preferenceApplied = true;
+          }
+        }
+      }
+      try {
+        EntityUtils.consume(res.getEntity());
+      } catch (IOException ex) {
+        Logger.getLogger(AsyncRequestWrapperImpl.class.getName()).log(Level.SEVERE, null, ex);
+      }
+    }
+  }
+
+  private HttpResponse checkMonitor(final URI location) {
+    if (location == null) {
+      throw new AsyncRequestException("Invalid async request response. Missing monitor URL");
+    }
+
+    final HttpUriRequest monitor = odataClient.getConfiguration().getHttpUriRequestFactory().
+            createHttpUriRequest(HttpMethod.GET, location);
+
+    return executeHttpRequest(httpClient, monitor);
+  }
+
+  private HttpResponse executeHttpRequest(final HttpClient client, final HttpUriRequest req) {
+    final HttpResponse response;
+    try {
+      response = client.execute(req);
+    } catch (IOException e) {
+      throw new HttpClientException(e);
+    } catch (RuntimeException e) {
+      req.abort();
+      throw new HttpClientException(e);
+    }
+
+    checkForResponse(odataClient, response, odataRequest.getAccept());
+
+    return response;
+  }
+}

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/4f1072a6/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/response/AbstractODataResponse.java
----------------------------------------------------------------------
diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/response/AbstractODataResponse.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/response/AbstractODataResponse.java
index c571cd6..5564bdf 100644
--- a/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/response/AbstractODataResponse.java
+++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/response/AbstractODataResponse.java
@@ -18,11 +18,14 @@
  */
 package org.apache.olingo.client.core.communication.response;
 
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.PipedInputStream;
 import java.io.PipedOutputStream;
 import java.net.URI;
+import java.nio.charset.Charset;
 import java.util.Collection;
 import java.util.HashSet;
 import java.util.Map;
@@ -37,7 +40,9 @@ import org.apache.olingo.client.api.communication.request.batch.ODataBatchLineIt
 import org.apache.olingo.client.api.communication.response.ODataResponse;
 import org.apache.olingo.client.api.http.NoContentException;
 import org.apache.olingo.client.core.communication.request.batch.ODataBatchController;
+import org.apache.olingo.client.core.communication.request.batch.ODataBatchLineIteratorImpl;
 import org.apache.olingo.client.core.communication.request.batch.ODataBatchUtilities;
+import org.apache.olingo.commons.api.Constants;
 import org.apache.olingo.commons.api.data.Container;
 import org.slf4j.LoggerFactory;
 
@@ -80,27 +85,27 @@ public abstract class AbstractODataResponse implements ODataResponse {
   /**
    * Response code.
    */
-  private int statusCode = -1;
+  protected int statusCode = -1;
 
   /**
    * Response message.
    */
-  private String statusMessage = null;
+  protected String statusMessage = null;
 
   /**
    * Response body/payload.
    */
-  private InputStream payload = null;
+  protected InputStream payload = null;
 
   /**
    * Initialization check.
    */
-  private boolean hasBeenInitialized = false;
+  protected boolean hasBeenInitialized = false;
 
   /**
    * Batch info (if to be batched).
    */
-  private ODataBatchController batchInfo = null;
+  protected ODataBatchController batchInfo = null;
 
   /**
    * Constructor.
@@ -119,30 +124,7 @@ public abstract class AbstractODataResponse implements ODataResponse {
   public AbstractODataResponse(final HttpClient client, final HttpResponse res) {
     this.client = client;
     this.res = res;
-
-    try {
-      this.payload = this.res.getEntity() == null ? null : this.res.getEntity().getContent();
-    } catch (Exception e) {
-      LOG.error("Error retrieving payload", e);
-      throw new IllegalStateException(e);
-    }
-
-    this.hasBeenInitialized = true;
-
-    for (Header header : res.getAllHeaders()) {
-      final Collection<String> headerValues;
-      if (headers.containsKey(header.getName())) {
-        headerValues = headers.get(header.getName());
-      } else {
-        headerValues = new HashSet<String>();
-        headers.put(header.getName(), headerValues);
-      }
-
-      headerValues.add(header.getValue());
-    }
-
-    statusCode = res.getStatusLine().getStatusCode();
-    statusMessage = res.getStatusLine().getReasonPhrase();
+    initFromHttpResponse(res);
   }
 
   @Override
@@ -229,6 +211,37 @@ public abstract class AbstractODataResponse implements ODataResponse {
    * {@inheritDoc}
    */
   @Override
+  public final ODataResponse initFromHttpResponse(final HttpResponse res) {
+    try {
+      this.payload = res.getEntity() == null ? null : res.getEntity().getContent();
+    } catch (Exception e) {
+      LOG.error("Error retrieving payload", e);
+      throw new IllegalStateException(e);
+    }
+
+    for (Header header : res.getAllHeaders()) {
+      final Collection<String> headerValues;
+      if (headers.containsKey(header.getName())) {
+        headerValues = headers.get(header.getName());
+      } else {
+        headerValues = new HashSet<String>();
+        headers.put(header.getName(), headerValues);
+      }
+
+      headerValues.add(header.getValue());
+    }
+
+    statusCode = res.getStatusLine().getStatusCode();
+    statusMessage = res.getStatusLine().getReasonPhrase();
+
+    this.hasBeenInitialized = true;
+    return this;
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
   public ODataResponse initFromBatch(
           final Map.Entry<Integer, String> responseLine,
           final Map<String, Collection<String>> headers,
@@ -239,18 +252,63 @@ public abstract class AbstractODataResponse implements ODataResponse {
       throw new IllegalStateException("Request already initialized");
     }
 
-    this.hasBeenInitialized = true;
-
     this.batchInfo = new ODataBatchController(batchLineIterator, boundary);
 
     this.statusCode = responseLine.getKey();
     this.statusMessage = responseLine.getValue();
     this.headers.putAll(headers);
 
+    this.hasBeenInitialized = true;
     return this;
   }
 
   /**
+   * {@inheritDoc}
+   */
+  @Override
+  public ODataResponse initFromEnclosedPart(final InputStream part) {
+    try {
+      if (hasBeenInitialized) {
+        throw new IllegalStateException("Request already initialized");
+      }
+
+      final ODataBatchLineIteratorImpl batchLineIterator =
+              new ODataBatchLineIteratorImpl(IOUtils.lineIterator(part, Constants.UTF8));
+
+      final Map.Entry<Integer, String> partResponseLine = ODataBatchUtilities.readResponseLine(batchLineIterator);
+      LOG.debug("Retrieved async item response {}", partResponseLine);
+
+      this.statusCode = partResponseLine.getKey();
+      this.statusMessage = partResponseLine.getValue();
+
+      final Map<String, Collection<String>> partHeaders = ODataBatchUtilities.readHeaders(batchLineIterator);
+      LOG.debug("Retrieved async item headers {}", partHeaders);
+
+      this.headers.putAll(partHeaders);
+
+      final ByteArrayOutputStream bos = new ByteArrayOutputStream();
+      LOG.debug("Retrieved payload {}", bos.toString(Charset.forName("UTF-8").toString()));
+
+      while (batchLineIterator.hasNext()) {
+        bos.write(batchLineIterator.nextLine().getBytes());
+      }
+
+      try {
+        this.payload = new ByteArrayInputStream(bos.toByteArray());
+      } catch (Exception e) {
+        LOG.error("Error retrieving payload", e);
+        throw new IllegalStateException(e);
+      }
+
+      this.hasBeenInitialized = true;
+      return this;
+    } catch (IOException e) {
+      LOG.error("Error streaming payload response", e);
+      throw new IllegalStateException(e);
+    }
+  }
+
+  /**
    * {@inheritDoc }
    */
   @Override
@@ -308,7 +366,7 @@ public abstract class AbstractODataResponse implements ODataResponse {
     if (container == null) {
       return null;
     }
-    
+
     setContextURL(container.getContextURL());
     setMetadataETag(container.getMetadataETag());
     return container.getObject();

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/4f1072a6/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/response/batch/ODataBatchErrorResponse.java
----------------------------------------------------------------------
diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/response/batch/ODataBatchErrorResponse.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/response/batch/ODataBatchErrorResponse.java
index e1f7085..d2dd884 100644
--- a/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/response/batch/ODataBatchErrorResponse.java
+++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/response/batch/ODataBatchErrorResponse.java
@@ -18,76 +18,17 @@
  */
 package org.apache.olingo.client.core.communication.response.batch;
 
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.PipedInputStream;
-import java.io.PipedOutputStream;
 import java.net.URI;
 import java.util.Collection;
 import java.util.Map;
-import java.util.TreeMap;
-import org.apache.commons.io.IOUtils;
-import org.apache.http.HttpResponse;
-import org.apache.http.HttpStatus;
-import org.apache.http.client.HttpClient;
-import org.apache.olingo.client.api.communication.header.HeaderName;
 import org.apache.olingo.client.api.communication.request.batch.ODataBatchLineIterator;
-import org.apache.olingo.client.api.communication.response.ODataResponse;
-import org.apache.olingo.client.api.http.NoContentException;
 import org.apache.olingo.client.core.communication.request.batch.ODataBatchController;
-import org.apache.olingo.client.core.communication.request.batch.ODataBatchUtilities;
-import org.slf4j.LoggerFactory;
+import org.apache.olingo.client.core.communication.response.AbstractODataResponse;
 
 /**
  * Abstract representation of an OData response.
  */
-public class ODataBatchErrorResponse implements ODataResponse {
-
-  /**
-   * Logger.
-   */
-  protected static final org.slf4j.Logger LOG = LoggerFactory.getLogger(ODataResponse.class);
-
-  /**
-   * HTTP client.
-   */
-  protected final HttpClient client;
-
-  /**
-   * HTTP response.
-   */
-  protected final HttpResponse res;
-
-  /**
-   * Response headers.
-   */
-  protected final Map<String, Collection<String>> headers =
-          new TreeMap<String, Collection<String>>(String.CASE_INSENSITIVE_ORDER);
-
-  /**
-   * Response code.
-   */
-  private int statusCode = -1;
-
-  /**
-   * Response message.
-   */
-  private String statusMessage = null;
-
-  /**
-   * Response body/payload.
-   */
-  private InputStream payload = null;
-
-  /**
-   * Initialization check.
-   */
-  private boolean hasBeenInitialized = false;
-
-  /**
-   * Batch info (if to be batched).
-   */
-  private ODataBatchController batchInfo = null;
+public class ODataBatchErrorResponse extends AbstractODataResponse {
 
   /**
    * Constructor.
@@ -98,8 +39,7 @@ public class ODataBatchErrorResponse implements ODataResponse {
           final ODataBatchLineIterator batchLineIterator,
           final String boundary) {
 
-    client = null;
-    res = null;
+    super();
 
     if (hasBeenInitialized) {
       throw new IllegalStateException("Request already initialized");
@@ -114,136 +54,6 @@ public class ODataBatchErrorResponse implements ODataResponse {
     this.headers.putAll(headers);
   }
 
-  /**
-   * {@inheritDoc}
-   */
-  @Override
-  public Collection<String> getHeaderNames() {
-    return headers.keySet();
-  }
-
-  /**
-   * {@inheritDoc}
-   */
-  @Override
-  public Collection<String> getHeader(final String name) {
-    return headers.get(name);
-  }
-
-  /**
-   * {@inheritDoc}
-   */
-  @Override
-  public Collection<String> getHeader(final HeaderName name) {
-    return headers.get(name.toString());
-  }
-
-  /**
-   * {@inheritDoc}
-   */
-  @Override
-  public String getContentType() {
-    final Collection<String> contentTypes = getHeader(HeaderName.contentType);
-    return contentTypes == null || contentTypes.isEmpty()
-            ? null
-            : contentTypes.iterator().next();
-  }
-
-  /**
-   * {@inheritDoc}
-   */
-  @Override
-  public int getStatusCode() {
-    return statusCode;
-  }
-
-  /**
-   * {@inheritDoc}
-   */
-  @Override
-  public String getStatusMessage() {
-    return statusMessage;
-  }
-
-  /**
-   * {@inheritDoc}
-   */
-  @Override
-  public ODataResponse initFromBatch(
-          final Map.Entry<Integer, String> responseLine,
-          final Map<String, Collection<String>> headers,
-          final ODataBatchLineIterator batchLineIterator,
-          final String boundary) {
-
-    if (hasBeenInitialized) {
-      throw new IllegalStateException("Request already initialized");
-    }
-
-    this.hasBeenInitialized = true;
-
-    this.batchInfo = new ODataBatchController(batchLineIterator, boundary);
-
-    this.statusCode = responseLine.getKey();
-    this.statusMessage = responseLine.getValue();
-    this.headers.putAll(headers);
-
-    return this;
-  }
-
-  /**
-   * {@inheritDoc }
-   */
-  @Override
-  public void close() {
-    if (client == null) {
-      IOUtils.closeQuietly(payload);
-    } else {
-      this.client.getConnectionManager().shutdown();
-    }
-
-    if (batchInfo != null) {
-      batchInfo.setValidBatch(false);
-    }
-  }
-
-  /**
-   * {@inheritDoc}
-   */
-  @Override
-  public InputStream getRawResponse() {
-    if (HttpStatus.SC_NO_CONTENT == getStatusCode()) {
-      throw new NoContentException();
-    }
-
-    if (payload == null && batchInfo.isValidBatch()) {
-      // get input stream till the end of item
-      payload = new PipedInputStream();
-
-      try {
-        final PipedOutputStream os = new PipedOutputStream((PipedInputStream) payload);
-
-        new Thread(new Runnable() {
-          @Override
-          public void run() {
-            try {
-              ODataBatchUtilities.readBatchPart(batchInfo, os, true);
-            } catch (Exception e) {
-              LOG.error("Error streaming batch item payload", e);
-            } finally {
-              IOUtils.closeQuietly(os);
-            }
-          }
-        }).start();
-
-      } catch (IOException e) {
-        LOG.error("Error streaming payload response", e);
-        throw new IllegalStateException(e);
-      }
-    }
-
-    return payload;
-  }
-
   @Override
   public String getEtag() {
     return null;

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/4f1072a6/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/response/v4/AsyncResponseImpl.java
----------------------------------------------------------------------
diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/response/v4/AsyncResponseImpl.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/response/v4/AsyncResponseImpl.java
new file mode 100644
index 0000000..cf7da13
--- /dev/null
+++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/response/v4/AsyncResponseImpl.java
@@ -0,0 +1,49 @@
+/*
+ * 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.communication.response.v4;
+
+import org.apache.http.HttpResponse;
+import org.apache.http.client.HttpClient;
+import org.apache.olingo.client.api.communication.response.v4.AsyncResponse;
+import org.apache.olingo.client.core.communication.response.AbstractODataResponse;
+
+/**
+ * Abstract representation of an OData response.
+ */
+public class AsyncResponseImpl extends AbstractODataResponse implements AsyncResponse {
+
+  /**
+   * Constructor.
+   * <p>
+   * Just to create response templates to be initialized from batch.
+   */
+  public AsyncResponseImpl() {
+    super();
+  }
+
+  /**
+   * Constructor.
+   *
+   * @param client HTTP client.
+   * @param res HTTP response.
+   */
+  public AsyncResponseImpl(final HttpClient client, final HttpResponse res) {
+    super(client, res);
+  }
+}

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/4f1072a6/lib/client-core/src/main/java/org/apache/olingo/client/core/uri/URIUtils.java
----------------------------------------------------------------------
diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/uri/URIUtils.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/uri/URIUtils.java
index 3496cec..1cce282 100644
--- a/lib/client-core/src/main/java/org/apache/olingo/client/core/uri/URIUtils.java
+++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/uri/URIUtils.java
@@ -383,7 +383,7 @@ public final class URIUtils {
     return value;
   }
 
-  public static InputStreamEntity buildInputStreamEntity(final CommonODataClient client, final InputStream input) {
+  public static InputStreamEntity buildInputStreamEntity(final CommonODataClient<?> client, final InputStream input) {
     InputStreamEntity entity;
     if (client.getConfiguration().isUseChuncked()) {
       entity = new InputStreamEntity(input, -1);

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/4f1072a6/lib/client-core/src/main/java/org/apache/olingo/client/core/v4/ODataClientImpl.java
----------------------------------------------------------------------
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 ee7b743..3962786 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
@@ -28,6 +28,7 @@ import org.apache.olingo.client.api.communication.request.cud.v4.UpdateType;
 import org.apache.olingo.client.api.communication.request.invoke.v4.InvokeRequestFactory;
 import org.apache.olingo.client.api.communication.request.retrieve.v4.RetrieveRequestFactory;
 import org.apache.olingo.client.api.communication.request.streamed.v4.StreamedRequestFactory;
+import org.apache.olingo.client.api.communication.request.v4.AsyncRequestFactory;
 import org.apache.olingo.commons.api.op.ODataSerializer;
 import org.apache.olingo.client.api.op.v4.ODataBinder;
 import org.apache.olingo.client.api.op.v4.ODataDeserializer;
@@ -41,6 +42,7 @@ import org.apache.olingo.client.core.communication.request.cud.v4.CUDRequestFact
 import org.apache.olingo.client.core.communication.request.invoke.v4.InvokeRequestFactoryImpl;
 import org.apache.olingo.client.core.communication.request.retrieve.v4.RetrieveRequestFactoryImpl;
 import org.apache.olingo.client.core.communication.request.streamed.v4.StreamedRequestFactoryImpl;
+import org.apache.olingo.client.core.communication.request.v4.AsyncRequestFactoryImpl;
 import org.apache.olingo.client.core.op.impl.v4.ODataBinderImpl;
 import org.apache.olingo.client.core.op.impl.v4.ODataDeserializerImpl;
 import org.apache.olingo.client.core.op.impl.v4.ODataReaderImpl;
@@ -69,6 +71,8 @@ public class ODataClientImpl extends AbstractODataClient<UpdateType> implements
 
   private final ODataObjectFactory objectFactory = new ODataObjectFactoryImpl(getServiceVersion());
 
+  private final AsyncRequestFactory asyncReqFact = new AsyncRequestFactoryImpl(this);
+
   private final RetrieveRequestFactory retrieveReqFact = new RetrieveRequestFactoryImpl(this);
 
   private final CUDRequestFactory cudReqFact = new CUDRequestFactoryImpl(this);
@@ -133,6 +137,11 @@ public class ODataClientImpl extends AbstractODataClient<UpdateType> implements
   }
 
   @Override
+  public AsyncRequestFactory getAsyncRequestFactory() {
+    return asyncReqFact;
+  }
+
+  @Override
   public RetrieveRequestFactory getRetrieveRequestFactory() {
     return retrieveReqFact;
   }

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/4f1072a6/lib/client-core/src/test/java/org/apache/olingo/client/core/it/v3/AsyncTestITCase.java
----------------------------------------------------------------------
diff --git a/lib/client-core/src/test/java/org/apache/olingo/client/core/it/v3/AsyncTestITCase.java b/lib/client-core/src/test/java/org/apache/olingo/client/core/it/v3/AsyncTestITCase.java
index 1864abc..2868f8c 100644
--- a/lib/client-core/src/test/java/org/apache/olingo/client/core/it/v3/AsyncTestITCase.java
+++ b/lib/client-core/src/test/java/org/apache/olingo/client/core/it/v3/AsyncTestITCase.java
@@ -75,7 +75,7 @@ public class AsyncTestITCase extends AbstractTestITCase {
     entity.getProperties().remove(entity.getProperty("Description"));
     getClient().getBinder().add(entity,
             client.getObjectFactory().newPrimitiveProperty("Description",
-                    client.getObjectFactory().newPrimitiveValueBuilder().setText("AsyncTest#updateEntity").build()));
+            client.getObjectFactory().newPrimitiveValueBuilder().setText("AsyncTest#updateEntity").build()));
 
     final ODataEntityUpdateRequest<ODataEntity> updateReq =
             client.getCUDRequestFactory().getEntityUpdateRequest(uri, UpdateType.MERGE, entity);
@@ -86,7 +86,7 @@ public class AsyncTestITCase extends AbstractTestITCase {
       Thread.sleep(1000L);
     }
 
-    final ODataEntityUpdateResponse res = futureRes.get();
+    final ODataEntityUpdateResponse<ODataEntity> res = futureRes.get();
     assertNotNull(res);
     assertEquals(204, res.getStatusCode());
   }

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/4f1072a6/lib/client-core/src/test/java/org/apache/olingo/client/core/it/v4/AsyncTestITCase.java
----------------------------------------------------------------------
diff --git a/lib/client-core/src/test/java/org/apache/olingo/client/core/it/v4/AsyncTestITCase.java b/lib/client-core/src/test/java/org/apache/olingo/client/core/it/v4/AsyncTestITCase.java
new file mode 100644
index 0000000..a6f52a3
--- /dev/null
+++ b/lib/client-core/src/test/java/org/apache/olingo/client/core/it/v4/AsyncTestITCase.java
@@ -0,0 +1,164 @@
+/*
+ * 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.util.List;
+
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.Future;
+import org.apache.olingo.client.api.communication.request.retrieve.ODataEntityRequest;
+import org.apache.olingo.client.api.communication.request.retrieve.ODataEntitySetRequest;
+import org.apache.olingo.client.api.communication.request.v4.AsyncRequestWrapper;
+import org.apache.olingo.client.api.communication.response.ODataRetrieveResponse;
+import org.apache.olingo.client.api.communication.response.v4.AsyncResponseWrapper;
+import org.apache.olingo.client.api.uri.CommonURIBuilder;
+import org.apache.olingo.client.api.uri.v4.URIBuilder;
+import static org.apache.olingo.client.core.it.v4.AbstractTestITCase.client;
+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.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.format.ODataPubFormat;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+import org.junit.Test;
+
+public class AsyncTestITCase extends AbstractTestITCase {
+
+  @Test
+  public void asyncRequestV3Style() throws InterruptedException, ExecutionException {
+    final CommonURIBuilder<?> uriBuilder = client.getURIBuilder(testStaticServiceRootURL).
+            appendEntitySetSegment("Customers");
+    final Future<ODataRetrieveResponse<ODataEntitySet>> futureRes =
+            client.getRetrieveRequestFactory().getEntitySetRequest(uriBuilder.build()).asyncExecute();
+    assertNotNull(futureRes);
+
+    while (!futureRes.isDone()) {
+      Thread.sleep(1000L);
+    }
+
+    final ODataRetrieveResponse<ODataEntitySet> res = futureRes.get();
+    assertNotNull(res);
+    assertEquals(200, res.getStatusCode());
+    assertFalse(res.getBody().getEntities().isEmpty());
+  }
+
+  private void withInlineEntry(final ODataPubFormat format) {
+    final URIBuilder uriBuilder = client.getURIBuilder(testStaticServiceRootURL).
+            appendEntitySetSegment("Customers").appendKeySegment(1).expand("Company");
+
+    final ODataEntityRequest<ODataEntity> req = client.getRetrieveRequestFactory().getEntityRequest(uriBuilder.build());
+    req.setFormat(format);
+
+    final AsyncRequestWrapper<ODataRetrieveResponse<ODataEntity>> async =
+            client.getAsyncRequestFactory().<ODataRetrieveResponse<ODataEntity>>getAsyncRequestWrapper(req);
+
+    final AsyncResponseWrapper<ODataRetrieveResponse<ODataEntity>> responseWrapper = async.execute();
+
+    assertFalse(responseWrapper.isPreferenceApplied());
+
+    final ODataRetrieveResponse<ODataEntity> res = responseWrapper.getODataResponse();
+    final ODataEntity entity = res.getBody();
+
+    assertNotNull(entity);
+    assertEquals("Microsoft.Test.OData.Services.ODataWCFService.Customer", entity.getTypeName().toString());
+    assertEquals(testStaticServiceRootURL + "/Customers(PersonID=1)", entity.getEditLink().toASCIIString());
+
+    assertEquals(3, entity.getNavigationLinks().size());
+
+    if (ODataPubFormat.ATOM == format) {
+      assertTrue(entity.getAssociationLinks().isEmpty());
+      // In JSON, association links for each $ref link will exist.
+    }
+
+    boolean found = false;
+
+    for (ODataLink link : entity.getNavigationLinks()) {
+      if (link instanceof ODataInlineEntity) {
+        final CommonODataEntity inline = ((ODataInlineEntity) link).getEntity();
+        assertNotNull(inline);
+
+        final List<? extends CommonODataProperty> properties = inline.getProperties();
+        assertEquals(5, properties.size());
+
+        assertTrue(properties.get(0).getName().equals("CompanyID")
+                || properties.get(1).getName().equals("CompanyID")
+                || properties.get(2).getName().equals("CompanyID")
+                || properties.get(3).getName().equals("CompanyID")
+                || properties.get(4).getName().equals("CompanyID"));
+        assertTrue(properties.get(0).getValue().toString().equals("0")
+                || properties.get(1).getValue().toString().equals("0")
+                || properties.get(2).getValue().toString().equals("0")
+                || properties.get(3).getValue().toString().equals("0")
+                || properties.get(4).getValue().toString().equals("0"));
+
+        found = true;
+      }
+    }
+
+    assertTrue(found);
+  }
+
+  private void asynOrders(final ODataPubFormat format) {
+    final URIBuilder uriBuilder = client.getURIBuilder(testStaticServiceRootURL).
+            appendEntitySetSegment("async").appendEntitySetSegment("Orders");
+
+    final ODataEntitySetRequest<ODataEntitySet> req =
+            client.getRetrieveRequestFactory().getEntitySetRequest(uriBuilder.build());
+    req.setFormat(format);
+
+    final AsyncRequestWrapper<ODataRetrieveResponse<ODataEntitySet>> async =
+            client.getAsyncRequestFactory().<ODataRetrieveResponse<ODataEntitySet>>getAsyncRequestWrapper(req);
+
+    final AsyncResponseWrapper<ODataRetrieveResponse<ODataEntitySet>> responseWrapper = async.execute();
+
+    assertTrue(responseWrapper.isPreferenceApplied());
+    assertTrue(responseWrapper.isDone());
+
+    final ODataRetrieveResponse<ODataEntitySet> res = responseWrapper.getODataResponse();
+    final ODataEntitySet entitySet = res.getBody();
+
+    assertFalse(entitySet.getEntities().isEmpty());
+  }
+
+  @Test
+  public void withInlineEntryAsAtom() {
+    withInlineEntry(ODataPubFormat.ATOM);
+  }
+
+  @Test
+  public void withInlineEntryAsJSON() {
+    // this needs to be full, otherwise there is no mean to recognize links
+    withInlineEntry(ODataPubFormat.JSON_FULL_METADATA);
+  }
+
+  @Test
+  public void asynOrdersAsAtom() {
+    asynOrders(ODataPubFormat.ATOM);
+  }
+
+  @Test
+  public void asynOrdersAsJSON() {
+    asynOrders(ODataPubFormat.JSON);
+  }
+}

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/4f1072a6/lib/client-core/src/test/java/org/apache/olingo/client/core/it/v4/BatchTestITCase.java
----------------------------------------------------------------------
diff --git a/lib/client-core/src/test/java/org/apache/olingo/client/core/it/v4/BatchTestITCase.java b/lib/client-core/src/test/java/org/apache/olingo/client/core/it/v4/BatchTestITCase.java
index f980c2d..bb5b100 100644
--- a/lib/client-core/src/test/java/org/apache/olingo/client/core/it/v4/BatchTestITCase.java
+++ b/lib/client-core/src/test/java/org/apache/olingo/client/core/it/v4/BatchTestITCase.java
@@ -146,7 +146,7 @@ public class BatchTestITCase extends AbstractTestITCase {
     for (int i = 3; i <= 4; i++) {
       // Create Customer into the changeset
       createReq = client.getCUDRequestFactory().getEntityCreateRequest(targetURI.build(), newOrder(100 + i));
-      createReq.setFormat(ODataPubFormat.ATOM);
+      createReq.setFormat(ODataPubFormat.JSON);
       changeset.addRequest(createReq);
     }
 
@@ -197,7 +197,7 @@ public class BatchTestITCase extends AbstractTestITCase {
 
     // create new request
     ODataEntityRequest<ODataEntity> queryReq = client.getRetrieveRequestFactory().getEntityRequest(targetURI.build());
-    queryReq.setFormat(ODataPubFormat.ATOM);
+    queryReq.setFormat(ODataPubFormat.JSON);
 
     retrieve.setRequest(queryReq);
     // -------------------------------------------
@@ -346,7 +346,7 @@ public class BatchTestITCase extends AbstractTestITCase {
 
     // create new request
     ODataEntityRequest<ODataEntity> queryReq = client.getRetrieveRequestFactory().getEntityRequest(targetURI.build());
-    queryReq.setFormat(ODataPubFormat.ATOM);
+    queryReq.setFormat(ODataPubFormat.JSON);
 
     retrieve.setRequest(queryReq);
     // -------------------------------------------
@@ -361,7 +361,7 @@ public class BatchTestITCase extends AbstractTestITCase {
     final ODataEntity original = newOrder(2000);
     final ODataEntityCreateRequest<ODataEntity> createReq =
             client.getCUDRequestFactory().getEntityCreateRequest(targetURI.build(), original);
-    createReq.setFormat(ODataPubFormat.ATOM);
+    createReq.setFormat(ODataPubFormat.JSON);
     outside.setRequest(createReq);
     // -------------------------------------------
 
@@ -413,12 +413,12 @@ public class BatchTestITCase extends AbstractTestITCase {
 
     // prepare URI
     URIBuilder targetURI = client.getURIBuilder(testStaticServiceRootURL);
-    targetURI.appendEntitySetSegment("Customers").appendKeySegment(1).
-            expand("Orders").select("PersonID,Orders/OrderID");
+    targetURI.appendEntitySetSegment("Customers").appendKeySegment(1);//.
+//            expand("Orders").select("PersonID,Orders/OrderID");
 
     // create new request
     ODataEntityRequest<ODataEntity> queryReq = client.getRetrieveRequestFactory().getEntityRequest(targetURI.build());
-    queryReq.setFormat(ODataPubFormat.ATOM);
+    queryReq.setFormat(ODataPubFormat.JSON);
 
     retrieve.setRequest(queryReq);
     // -------------------------------------------
@@ -451,7 +451,7 @@ public class BatchTestITCase extends AbstractTestITCase {
     final ODataEntity original = newOrder(1000);
     final ODataEntityCreateRequest<ODataEntity> createReq =
             client.getCUDRequestFactory().getEntityCreateRequest(targetURI.build(), original);
-    createReq.setFormat(ODataPubFormat.ATOM);
+    createReq.setFormat(ODataPubFormat.JSON);
     changeset.addRequest(createReq);
     // -------------------------------------------
 
@@ -627,6 +627,10 @@ public class BatchTestITCase extends AbstractTestITCase {
     order.getProperties().add(getClient().getObjectFactory().newPrimitiveProperty("ShelfLife",
             getClient().getObjectFactory().newPrimitiveValueBuilder().
             setType(EdmPrimitiveTypeKind.Duration).setText("PT0.0000002S").build()));
+    order.getProperties().add(getClient().getObjectFactory().newCollectionProperty("OrderShelfLifes",
+            getClient().getObjectFactory().newCollectionValue(EdmPrimitiveTypeKind.Duration.name()).add(
+            getClient().getObjectFactory().newPrimitiveValueBuilder().setType(EdmPrimitiveTypeKind.Duration).
+            setText("PT0.0000002S").build())));
 
     return order;
   }

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/4f1072a6/lib/commons-api/src/main/java/org/apache/olingo/commons/api/domain/ODataCollectionValue.java
----------------------------------------------------------------------
diff --git a/lib/commons-api/src/main/java/org/apache/olingo/commons/api/domain/ODataCollectionValue.java b/lib/commons-api/src/main/java/org/apache/olingo/commons/api/domain/ODataCollectionValue.java
index 8b5f531..b4a4649 100644
--- a/lib/commons-api/src/main/java/org/apache/olingo/commons/api/domain/ODataCollectionValue.java
+++ b/lib/commons-api/src/main/java/org/apache/olingo/commons/api/domain/ODataCollectionValue.java
@@ -32,7 +32,7 @@ public interface ODataCollectionValue<OV extends ODataValue> extends ODataValue,
    *
    * @param value value to be added.
    */
-  void add(ODataValue value);
+  ODataCollectionValue<OV> add(ODataValue value);
 
   /**
    * Checks if collection is empty.

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/4f1072a6/lib/commons-api/src/main/java/org/apache/olingo/commons/api/domain/ODataComplexValue.java
----------------------------------------------------------------------
diff --git a/lib/commons-api/src/main/java/org/apache/olingo/commons/api/domain/ODataComplexValue.java b/lib/commons-api/src/main/java/org/apache/olingo/commons/api/domain/ODataComplexValue.java
index b66aed6..a0ad0c7 100644
--- a/lib/commons-api/src/main/java/org/apache/olingo/commons/api/domain/ODataComplexValue.java
+++ b/lib/commons-api/src/main/java/org/apache/olingo/commons/api/domain/ODataComplexValue.java
@@ -32,7 +32,7 @@ public interface ODataComplexValue<OP extends CommonODataProperty> extends OData
    *
    * @param field field to be added.
    */
-  void add(OP field);
+  ODataComplexValue<OP> add(OP field);
 
   /**
    * Gets field.

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/4f1072a6/lib/commons-core/src/main/java/org/apache/olingo/commons/core/domain/AbstractODataCollectionValue.java
----------------------------------------------------------------------
diff --git a/lib/commons-core/src/main/java/org/apache/olingo/commons/core/domain/AbstractODataCollectionValue.java b/lib/commons-core/src/main/java/org/apache/olingo/commons/core/domain/AbstractODataCollectionValue.java
index 619cf02..b8ae8d3 100644
--- a/lib/commons-core/src/main/java/org/apache/olingo/commons/core/domain/AbstractODataCollectionValue.java
+++ b/lib/commons-core/src/main/java/org/apache/olingo/commons/core/domain/AbstractODataCollectionValue.java
@@ -49,6 +49,8 @@ public abstract class AbstractODataCollectionValue<OV extends ODataValue>
   public AbstractODataCollectionValue(final String typeName) {
     super(typeName);
   }
+  
+  protected abstract ODataCollectionValue<OV> getThis();
 
   /**
    * Adds a value to the collection.
@@ -57,8 +59,9 @@ public abstract class AbstractODataCollectionValue<OV extends ODataValue>
    */
   @Override
   @SuppressWarnings("unchecked")
-  public void add(final ODataValue value) {
+  public ODataCollectionValue<OV> add(final ODataValue value) {
     values.add((OV) value);
+    return getThis();
   }
 
   /**

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/4f1072a6/lib/commons-core/src/main/java/org/apache/olingo/commons/core/domain/AbstractODataComplexValue.java
----------------------------------------------------------------------
diff --git a/lib/commons-core/src/main/java/org/apache/olingo/commons/core/domain/AbstractODataComplexValue.java b/lib/commons-core/src/main/java/org/apache/olingo/commons/core/domain/AbstractODataComplexValue.java
index 4e4e40d..af5deae 100644
--- a/lib/commons-core/src/main/java/org/apache/olingo/commons/core/domain/AbstractODataComplexValue.java
+++ b/lib/commons-core/src/main/java/org/apache/olingo/commons/core/domain/AbstractODataComplexValue.java
@@ -49,6 +49,8 @@ public abstract class AbstractODataComplexValue<OP extends CommonODataProperty>
     super(typeName);
   }
 
+  protected abstract ODataComplexValue<OP> getThis();
+
   /**
    * Adds field to the complex type.
    *
@@ -56,8 +58,9 @@ public abstract class AbstractODataComplexValue<OP extends CommonODataProperty>
    */
   @Override
   @SuppressWarnings("unchecked")
-  public void add(final CommonODataProperty field) {
+  public ODataComplexValue<OP> add(final CommonODataProperty field) {
     fields.put(field.getName(), (OP) field);
+    return getThis();
   }
 
   /**
@@ -109,5 +112,4 @@ public abstract class AbstractODataComplexValue<OP extends CommonODataProperty>
 
     return result;
   }
-
 }

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/4f1072a6/lib/commons-core/src/main/java/org/apache/olingo/commons/core/domain/v3/ODataCollectionValueImpl.java
----------------------------------------------------------------------
diff --git a/lib/commons-core/src/main/java/org/apache/olingo/commons/core/domain/v3/ODataCollectionValueImpl.java b/lib/commons-core/src/main/java/org/apache/olingo/commons/core/domain/v3/ODataCollectionValueImpl.java
index 1ebd62a..12304e6 100644
--- a/lib/commons-core/src/main/java/org/apache/olingo/commons/core/domain/v3/ODataCollectionValueImpl.java
+++ b/lib/commons-core/src/main/java/org/apache/olingo/commons/core/domain/v3/ODataCollectionValueImpl.java
@@ -29,4 +29,8 @@ public class ODataCollectionValueImpl extends AbstractODataCollectionValue<OData
     super(typeName);
   }
 
+  @Override
+  protected ODataCollectionValueImpl getThis() {
+    return this;
+  }
 }

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/4f1072a6/lib/commons-core/src/main/java/org/apache/olingo/commons/core/domain/v3/ODataComplexValueImpl.java
----------------------------------------------------------------------
diff --git a/lib/commons-core/src/main/java/org/apache/olingo/commons/core/domain/v3/ODataComplexValueImpl.java b/lib/commons-core/src/main/java/org/apache/olingo/commons/core/domain/v3/ODataComplexValueImpl.java
index 4b09fcc..d27ae25 100644
--- a/lib/commons-core/src/main/java/org/apache/olingo/commons/core/domain/v3/ODataComplexValueImpl.java
+++ b/lib/commons-core/src/main/java/org/apache/olingo/commons/core/domain/v3/ODataComplexValueImpl.java
@@ -18,6 +18,7 @@
  */
 package org.apache.olingo.commons.core.domain.v3;
 
+import org.apache.olingo.commons.api.domain.ODataComplexValue;
 import org.apache.olingo.commons.api.domain.v3.ODataProperty;
 import org.apache.olingo.commons.core.domain.AbstractODataComplexValue;
 
@@ -29,4 +30,8 @@ public class ODataComplexValueImpl extends AbstractODataComplexValue<ODataProper
     super(typeName);
   }
 
+  @Override
+  protected ODataComplexValue<ODataProperty> getThis() {
+    return this;
+  }
 }

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/4f1072a6/lib/commons-core/src/main/java/org/apache/olingo/commons/core/domain/v4/ODataCollectionValueImpl.java
----------------------------------------------------------------------
diff --git a/lib/commons-core/src/main/java/org/apache/olingo/commons/core/domain/v4/ODataCollectionValueImpl.java b/lib/commons-core/src/main/java/org/apache/olingo/commons/core/domain/v4/ODataCollectionValueImpl.java
index 46a553c..7e4f9d2 100644
--- a/lib/commons-core/src/main/java/org/apache/olingo/commons/core/domain/v4/ODataCollectionValueImpl.java
+++ b/lib/commons-core/src/main/java/org/apache/olingo/commons/core/domain/v4/ODataCollectionValueImpl.java
@@ -35,6 +35,11 @@ public class ODataCollectionValueImpl extends AbstractODataCollectionValue<OData
   }
 
   @Override
+  protected ODataCollectionValueImpl getThis() {
+    return this;
+  }
+
+  @Override
   public boolean isEnum() {
     return false;
   }

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/4f1072a6/lib/commons-core/src/main/java/org/apache/olingo/commons/core/domain/v4/ODataComplexValueImpl.java
----------------------------------------------------------------------
diff --git a/lib/commons-core/src/main/java/org/apache/olingo/commons/core/domain/v4/ODataComplexValueImpl.java b/lib/commons-core/src/main/java/org/apache/olingo/commons/core/domain/v4/ODataComplexValueImpl.java
index d8d5fc9..9eed8c5 100644
--- a/lib/commons-core/src/main/java/org/apache/olingo/commons/core/domain/v4/ODataComplexValueImpl.java
+++ b/lib/commons-core/src/main/java/org/apache/olingo/commons/core/domain/v4/ODataComplexValueImpl.java
@@ -22,6 +22,7 @@ import java.util.ArrayList;
 import java.util.LinkedHashMap;
 import java.util.List;
 import java.util.Map;
+import org.apache.olingo.commons.api.domain.ODataComplexValue;
 import org.apache.olingo.commons.api.domain.ODataLink;
 import org.apache.olingo.commons.api.domain.v4.ODataLinkedComplexValue;
 import org.apache.olingo.commons.api.domain.v4.ODataEnumValue;
@@ -47,6 +48,11 @@ public class ODataComplexValueImpl extends AbstractODataComplexValue<ODataProper
   }
 
   @Override
+  protected ODataComplexValue<ODataProperty> getThis() {
+    return this;
+  }
+
+  @Override
   public boolean isEnum() {
     return false;
   }
@@ -145,5 +151,4 @@ public class ODataComplexValueImpl extends AbstractODataComplexValue<ODataProper
 
     return result;
   }
-
 }


[2/2] git commit: [OLINGO-248] provided V4 asynchronous mechanisms. Still missing verification towards external services

Posted by fm...@apache.org.
[OLINGO-248] provided V4 asynchronous mechanisms. Still missing verification towards external services


Project: http://git-wip-us.apache.org/repos/asf/olingo-odata4/repo
Commit: http://git-wip-us.apache.org/repos/asf/olingo-odata4/commit/4f1072a6
Tree: http://git-wip-us.apache.org/repos/asf/olingo-odata4/tree/4f1072a6
Diff: http://git-wip-us.apache.org/repos/asf/olingo-odata4/diff/4f1072a6

Branch: refs/heads/master
Commit: 4f1072a6e0170187778fd3afcec307f36ba5fbfe
Parents: d45a482
Author: fmartelli <fa...@gmail.com>
Authored: Thu Apr 24 10:13:48 2014 +0200
Committer: fmartelli <fa...@gmail.com>
Committed: Thu Apr 24 10:13:48 2014 +0200

----------------------------------------------------------------------
 .../org/apache/olingo/fit/AbstractServices.java |   1 -
 .../java/org/apache/olingo/fit/V4Services.java  |  68 +++
 .../olingo/fit/utils/AbstractUtilities.java     |  39 +-
 .../main/resources/V40/Customers/feed.full.json |  89 ++++
 fit/src/main/resources/V40/Customers/feed.xml   | 103 ++++
 .../request/cud/ODataDeleteRequest.java         |   4 +-
 .../request/cud/ODataPropertyUpdateRequest.java |   4 +-
 .../request/cud/ODataValueUpdateRequest.java    |   4 +-
 .../request/cud/v3/ODataLinkCreateRequest.java  |   4 +-
 .../request/cud/v3/ODataLinkUpdateRequest.java  |   4 +-
 .../streamed/ODataStreamUpdateRequest.java      |   6 +-
 .../request/v4/AsyncRequestFactory.java         |  28 ++
 .../request/v4/AsyncRequestWrapper.java         |  40 ++
 .../communication/response/ODataResponse.java   |  20 +-
 .../response/v4/AsyncResponse.java              |  24 +
 .../response/v4/AsyncResponseWrapper.java       |  69 +++
 .../olingo/client/api/v4/ODataClient.java       |   3 +
 .../request/AbstractODataBasicRequest.java      |   2 +-
 .../request/AbstractODataRequest.java           | 433 +++++++++++++++++
 .../communication/request/AbstractRequest.java  |  84 ++++
 .../communication/request/ODataRequestImpl.java | 486 -------------------
 .../batch/AbstractODataBatchRequest.java        |   2 +-
 .../request/batch/ODataChangesetImpl.java       |   4 +-
 .../request/batch/ODataRetrieveImpl.java        |   6 +-
 .../request/batch/v3/ODataBatchRequestImpl.java |   2 +-
 .../batch/v4/ODataOutsideUpdateImpl.java        |   6 +-
 .../request/cud/ODataDeleteRequestImpl.java     |   3 +-
 .../cud/ODataEntityCreateRequestImpl.java       |   2 +-
 .../cud/ODataPropertyUpdateRequestImpl.java     |   3 +-
 .../cud/ODataValueUpdateRequestImpl.java        |   5 +-
 .../cud/v3/ODataLinkCreateRequestImpl.java      |   3 +-
 .../cud/v3/ODataLinkUpdateRequestImpl.java      |   3 +-
 .../AbstractRetrieveRequestFactory.java         |   4 +-
 .../request/retrieve/ODataRawRequestImpl.java   |   4 +-
 .../streamed/AbstractODataStreamedRequest.java  |   4 +-
 .../streamed/ODataStreamUpdateRequestImpl.java  |   3 +-
 .../request/v4/AsyncRequestException.java       |  28 ++
 .../request/v4/AsyncRequestFactoryImpl.java     |  42 ++
 .../request/v4/AsyncRequestWrapperImpl.java     | 302 ++++++++++++
 .../response/AbstractODataResponse.java         | 122 +++--
 .../response/batch/ODataBatchErrorResponse.java | 196 +-------
 .../response/v4/AsyncResponseImpl.java          |  49 ++
 .../apache/olingo/client/core/uri/URIUtils.java |   2 +-
 .../olingo/client/core/v4/ODataClientImpl.java  |   9 +
 .../client/core/it/v3/AsyncTestITCase.java      |   4 +-
 .../client/core/it/v4/AsyncTestITCase.java      | 164 +++++++
 .../client/core/it/v4/BatchTestITCase.java      |  20 +-
 .../api/domain/ODataCollectionValue.java        |   2 +-
 .../commons/api/domain/ODataComplexValue.java   |   2 +-
 .../domain/AbstractODataCollectionValue.java    |   5 +-
 .../core/domain/AbstractODataComplexValue.java  |   6 +-
 .../domain/v3/ODataCollectionValueImpl.java     |   4 +
 .../core/domain/v3/ODataComplexValueImpl.java   |   5 +
 .../domain/v4/ODataCollectionValueImpl.java     |   5 +
 .../core/domain/v4/ODataComplexValueImpl.java   |   7 +-
 55 files changed, 1767 insertions(+), 776 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/4f1072a6/fit/src/main/java/org/apache/olingo/fit/AbstractServices.java
----------------------------------------------------------------------
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 6ff2c11..ca2fd84 100644
--- a/fit/src/main/java/org/apache/olingo/fit/AbstractServices.java
+++ b/fit/src/main/java/org/apache/olingo/fit/AbstractServices.java
@@ -209,7 +209,6 @@ public abstract class AbstractServices {
           final @Multipart MultipartBody attachment) {
     try {
       final boolean continueOnError = prefer.contains("odata.continue-on-error");
-
       return xml.createBatchResponse(
               exploreMultipart(attachment.getAllAttachments(), BOUNDARY, continueOnError), BOUNDARY);
     } catch (IOException e) {

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/4f1072a6/fit/src/main/java/org/apache/olingo/fit/V4Services.java
----------------------------------------------------------------------
diff --git a/fit/src/main/java/org/apache/olingo/fit/V4Services.java b/fit/src/main/java/org/apache/olingo/fit/V4Services.java
index 60c2e05..5b51a9f 100644
--- a/fit/src/main/java/org/apache/olingo/fit/V4Services.java
+++ b/fit/src/main/java/org/apache/olingo/fit/V4Services.java
@@ -43,6 +43,7 @@ import javax.ws.rs.PathParam;
 import javax.ws.rs.QueryParam;
 import javax.ws.rs.core.Context;
 import javax.ws.rs.core.Response;
+import javax.ws.rs.core.Response.Status;
 import javax.ws.rs.core.UriInfo;
 import org.apache.commons.codec.binary.Base64;
 import org.apache.commons.io.IOUtils;
@@ -80,10 +81,77 @@ import org.springframework.stereotype.Service;
 @InInterceptors(classes = {XHTTPMethodInterceptor.class, ResolvingReferencesInterceptor.class})
 public class V4Services extends AbstractServices {
 
+  /**
+   * CR/LF.
+   */
+  public static final byte[] CRLF = {13, 10};
+
+  private Map<String, String> providedAsync = new HashMap<String, String>();
+
   public V4Services() throws Exception {
     super(ODataServiceVersion.V40);
   }
 
+  @DELETE
+  @Path("/monitor/{name}")
+  public Response removeMonitor(@Context final UriInfo uriInfo, @PathParam("name") final String name) {
+    providedAsync.remove(name);
+    return xml.createResponse(null, null, null, Status.NO_CONTENT);
+  }
+
+  @GET
+  @Path("/monitor/{name}")
+  public Response async(@Context final UriInfo uriInfo, @PathParam("name") final String name) {
+    try {
+      if (!providedAsync.containsKey(name)) {
+        throw new NotFoundException();
+      }
+      final InputStream res = IOUtils.toInputStream(providedAsync.get(name));
+      providedAsync.remove(name);
+      return xml.createMonitorResponse(res);
+    } catch (Exception e) {
+      return xml.createFaultResponse(Accept.JSON_FULLMETA.toString(), e);
+    }
+  }
+
+  @GET
+  @Path("/async/{name}")
+  public Response async(
+          @Context final UriInfo uriInfo,
+          @HeaderParam("Accept") @DefaultValue(StringUtils.EMPTY) final String accept,
+          @PathParam("name") final String name) {
+
+    try {
+      final Accept acceptType = Accept.parse(accept, version);
+      if (acceptType == Accept.XML || acceptType == Accept.TEXT) {
+        throw new UnsupportedMediaTypeException("Unsupported media type");
+      }
+
+      final String basePath = name + File.separatorChar;
+      final StringBuilder path = new StringBuilder(basePath);
+
+      path.append(getMetadataObj().getEntitySet(name).isSingleton()
+              ? Constants.get(version, ConstantKey.ENTITY)
+              : Constants.get(version, ConstantKey.FEED));
+
+      final InputStream feed = FSManager.instance(version).readFile(path.toString(), acceptType);
+
+      final StringBuilder builder = new StringBuilder();
+      builder.append("HTTP/1.1 200 Ok").append(new String(CRLF));
+      builder.append("Content-Type: ").append(accept).append(new String(CRLF)).append(new String(CRLF));
+      builder.append(IOUtils.toString(feed));
+      IOUtils.closeQuietly(feed);
+
+      final UUID uuid = UUID.randomUUID();
+      providedAsync.put(uuid.toString(), builder.toString());
+
+      return xml.createAsyncResponse(
+              uriInfo.getRequestUri().toASCIIString().replaceAll("async/" + name, "") + "monitor/" + uuid.toString());
+    } catch (Exception e) {
+      return xml.createFaultResponse(accept, e);
+    }
+  }
+
   @Override
   protected void setInlineCount(final Feed feed, final String count) {
     if ("true".equals(count)) {

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/4f1072a6/fit/src/main/java/org/apache/olingo/fit/utils/AbstractUtilities.java
----------------------------------------------------------------------
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 6a1dc10..804c7c2 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
@@ -292,8 +292,8 @@ public abstract class AbstractUtilities {
     final List<String> hrefs = new ArrayList<String>();
 
     for (final Link link : entry.getNavigationLinks()) {
-      final NavigationProperty navProp = navigationProperties == null
-              ? null : navigationProperties.get(link.getTitle());
+      final NavigationProperty navProp =
+              navigationProperties == null ? null : navigationProperties.get(link.getTitle());
       if (navProp != null) {
         final String inlineEntitySetName = navProp.getTarget();
         if (link.getInlineEntry() != null) {
@@ -407,7 +407,7 @@ public abstract class AbstractUtilities {
 
     fsManager.putInMemory(
             IOUtils.toInputStream(entity), fsManager.getAbsolutePath(path + Constants.get(version, ConstantKey.ENTITY),
-                    Accept.JSON_FULLMETA));
+            Accept.JSON_FULLMETA));
     // -----------------------------------------
 
     return readEntity(entitySetName, entityKey, getDefaultFormat()).getValue();
@@ -456,6 +456,31 @@ public abstract class AbstractUtilities {
     return createResponse(location, entity, etag, accept, null);
   }
 
+  public Response createAsyncResponse(final String location) {
+    final Response.ResponseBuilder builder = Response.accepted();
+    if (version.compareTo(ODataServiceVersion.V30) <= 0) {
+      builder.header(Constants.get(version, ConstantKey.ODATA_SERVICE_VERSION), version.toString() + ";");
+    }
+
+    builder.header("Location", location);
+    builder.header("Preference-Applied", "Respond-Async");
+    builder.header("Retry-After", "10");
+
+    return builder.build();
+  }
+
+  public Response createMonitorResponse(final InputStream res) {
+    final Response.ResponseBuilder builder = Response.ok();
+    if (version.compareTo(ODataServiceVersion.V30) <= 0) {
+      builder.header(Constants.get(version, ConstantKey.ODATA_SERVICE_VERSION), version.toString() + ";");
+    }
+
+    builder.header("Content-Type", "application/http");
+    builder.header("Content-Transfer-Encoding", "binary");
+
+    return builder.entity(res).build();
+  }
+
   public Response createResponse(final InputStream entity, final String etag, final Accept accept) {
     return createResponse(null, entity, etag, accept, null);
   }
@@ -586,7 +611,7 @@ public abstract class AbstractUtilities {
     } else {
       mapper.writeValue(
               writer, new JSONFeedContainer(container.getContextURL(),
-                      container.getMetadataETag(), dataBinder.toJSONFeed(container.getObject())));
+              container.getMetadataETag(), dataBinder.toJSONFeed(container.getObject())));
     }
 
     return IOUtils.toInputStream(writer.toString(), Constants.ENCODING);
@@ -603,7 +628,7 @@ public abstract class AbstractUtilities {
     } else {
       final Container<JSONEntryImpl> container =
               mapper.readValue(entity, new TypeReference<JSONEntryImpl>() {
-              });
+      });
       entry = dataBinder.toAtomEntry(container.getObject());
     }
 
@@ -619,7 +644,7 @@ public abstract class AbstractUtilities {
     } else {
       mapper.writeValue(
               writer, new JSONEntryContainer(container.getContextURL(), container.getMetadataETag(),
-                      dataBinder.toJSONEntry(container.getObject())));
+              dataBinder.toJSONEntry(container.getObject())));
     }
 
     return IOUtils.toInputStream(writer.toString(), Constants.ENCODING);
@@ -649,7 +674,7 @@ public abstract class AbstractUtilities {
     } else {
       mapper.writeValue(
               writer, new JSONPropertyContainer(container.getContextURL(), container.getMetadataETag(),
-                      dataBinder.toJSONProperty(container.getObject())));
+              dataBinder.toJSONProperty(container.getObject())));
     }
 
     return IOUtils.toInputStream(writer.toString(), Constants.ENCODING);

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/4f1072a6/fit/src/main/resources/V40/Customers/feed.full.json
----------------------------------------------------------------------
diff --git a/fit/src/main/resources/V40/Customers/feed.full.json b/fit/src/main/resources/V40/Customers/feed.full.json
new file mode 100644
index 0000000..54af904
--- /dev/null
+++ b/fit/src/main/resources/V40/Customers/feed.full.json
@@ -0,0 +1,89 @@
+{
+  "@odata.context": "http://odatae2etest.azurewebsites.net/javatest/DefaultService/$metadata#Customers",
+  "value":
+          [
+            {
+              "@odata.id": "http://odatae2etest.azurewebsites.net/javatest/DefaultService/Customers(PersonID=1)",
+              "@odata.editLink": "http://odatae2etest.azurewebsites.net/javatest/DefaultService/Customers(PersonID=1)",
+              "PersonID": 1,
+              "FirstName": "Bob",
+              "LastName": "Cat",
+              "MiddleName": null,
+              "HomeAddress":
+                      {
+                        "@odata.type": "#Microsoft.Test.OData.Services.ODataWCFService.HomeAddress",
+                        "Street": "1 Microsoft Way",
+                        "City": "London",
+                        "PostalCode": "98052",
+                        "FamilyName": "Cats"
+                      },
+              "Home":
+                      {
+                        "type": "Point",
+                        "coordinates":
+                                [
+                                  23.1,
+                                  32.1
+                                ],
+                        "crs":
+                                {
+                                  "type": "name",
+                                  "properties":
+                                          {
+                                            "name": "EPSG:4326"
+                                          }
+                                }
+                      },
+              "Numbers":
+                      [
+                        "111-111-1111",
+                        "012",
+                        "310",
+                        "bca",
+                        "ayz"
+                      ],
+              "Emails":
+                      [
+                        "abc@abc.com"
+                      ],
+              "City": "London",
+              "Birthday": "1957-04-03T00:00:00Z",
+              "TimeBetweenLastTwoOrders": "PT0.0000001S"
+            },
+            {
+              "@odata.id": "http://odatae2etest.azurewebsites.net/javatest/DefaultService/Customers(PersonID=2)",
+              "@odata.editLink": "http://odatae2etest.azurewebsites.net/javatest/DefaultService/Customers(PersonID=2)",
+              "PersonID": 2,
+              "FirstName": "Jill",
+              "LastName": "Jones",
+              "MiddleName": null,
+              "HomeAddress": null,
+              "Home":
+                      {
+                        "type": "Point",
+                        "coordinates":
+                                [
+                                  161.8,
+                                  15
+                                ],
+                        "crs":
+                                {
+                                  "type": "name",
+                                  "properties":
+                                          {
+                                            "name": "EPSG:4326"
+                                          }
+                                }
+                      },
+              "Numbers":
+                      [
+                      ],
+              "Emails":
+                      [
+                      ],
+              "City": "Sydney",
+              "Birthday": "1983-01-15T00:00:00Z",
+              "TimeBetweenLastTwoOrders": "PT0.0000002S"
+            }
+          ]
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/4f1072a6/fit/src/main/resources/V40/Customers/feed.xml
----------------------------------------------------------------------
diff --git a/fit/src/main/resources/V40/Customers/feed.xml b/fit/src/main/resources/V40/Customers/feed.xml
new file mode 100644
index 0000000..198acd5
--- /dev/null
+++ b/fit/src/main/resources/V40/Customers/feed.xml
@@ -0,0 +1,103 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+
+    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.
+
+-->
+<feed xml:base="http://odatae2etest.azurewebsites.net/javatest/DefaultService/" xmlns="http://www.w3.org/2005/Atom" xmlns:d="http://docs.oasis-open.org/odata/ns/data" xmlns:m="http://docs.oasis-open.org/odata/ns/metadata" xmlns:georss="http://www.georss.org/georss" xmlns:gml="http://www.opengis.net/gml" m:context="http://odatae2etest.azurewebsites.net/javatest/DefaultService/$metadata#Customers">
+  <id>http://odatae2etest.azurewebsites.net/javatest/DefaultService/Customers</id>
+  <title />
+  <updated>2014-04-23T10:01:18Z</updated>
+  <entry>
+    <id>http://odatae2etest.azurewebsites.net/javatest/DefaultService/Customers(PersonID=1)</id>
+    <category term="#Microsoft.Test.OData.Services.ODataWCFService.Customer" scheme="http://docs.oasis-open.org/odata/ns/scheme" />
+    <link rel="edit" href="http://odatae2etest.azurewebsites.net/javatest/DefaultService/Customers(PersonID=1)" />
+    <link rel="http://docs.oasis-open.org/odata/ns/related/Parent" type="application/atom+xml;type=entry" title="Parent" href="http://odatae2etest.azurewebsites.net/javatest/DefaultService/Customers(PersonID=1)/Parent" />
+    <link rel="http://docs.oasis-open.org/odata/ns/related/Orders" type="application/atom+xml;type=feed" title="Orders" href="http://odatae2etest.azurewebsites.net/javatest/DefaultService/Customers(PersonID=1)/Orders" />
+    <link rel="http://docs.oasis-open.org/odata/ns/related/Company" type="application/atom+xml;type=entry" title="Company" href="http://odatae2etest.azurewebsites.net/javatest/DefaultService/Customers(PersonID=1)/Company" />
+    <title />
+    <updated>2014-04-23T10:01:18Z</updated>
+    <author>
+      <name />
+    </author>
+    <content type="application/xml">
+      <m:properties>
+        <d:PersonID m:type="Int32">1</d:PersonID>
+        <d:FirstName>Bob</d:FirstName>
+        <d:LastName>Cat</d:LastName>
+        <d:MiddleName m:null="true" />
+        <d:HomeAddress m:type="#Microsoft.Test.OData.Services.ODataWCFService.HomeAddress">
+          <d:Street>1 Microsoft Way</d:Street>
+          <d:City>London</d:City>
+          <d:PostalCode>98052</d:PostalCode>
+          <d:FamilyName>Cats</d:FamilyName>
+        </d:HomeAddress>
+        <d:Home m:type="GeographyPoint">
+          <gml:Point gml:srsName="http://www.opengis.net/def/crs/EPSG/0/4326">
+            <gml:pos>32.1 23.1</gml:pos>
+          </gml:Point>
+        </d:Home>
+        <d:Numbers m:type="#Collection(String)">
+          <m:element>111-111-1111</m:element>
+          <m:element>012</m:element>
+          <m:element>310</m:element>
+          <m:element>bca</m:element>
+          <m:element>ayz</m:element>
+        </d:Numbers>
+        <d:Emails m:type="#Collection(String)">
+          <m:element>abc@abc.com</m:element>
+        </d:Emails>
+        <d:City>London</d:City>
+        <d:Birthday m:type="DateTimeOffset">1957-04-03T00:00:00Z</d:Birthday>
+        <d:TimeBetweenLastTwoOrders m:type="Duration">PT0.0000001S</d:TimeBetweenLastTwoOrders>
+      </m:properties>
+    </content>
+  </entry>
+  <entry>
+    <id>http://odatae2etest.azurewebsites.net/javatest/DefaultService/Customers(PersonID=2)</id>
+    <category term="#Microsoft.Test.OData.Services.ODataWCFService.Customer" scheme="http://docs.oasis-open.org/odata/ns/scheme" />
+    <link rel="edit" href="http://odatae2etest.azurewebsites.net/javatest/DefaultService/Customers(PersonID=2)" />
+    <link rel="http://docs.oasis-open.org/odata/ns/related/Parent" type="application/atom+xml;type=entry" title="Parent" href="http://odatae2etest.azurewebsites.net/javatest/DefaultService/Customers(PersonID=2)/Parent" />
+    <link rel="http://docs.oasis-open.org/odata/ns/related/Orders" type="application/atom+xml;type=feed" title="Orders" href="http://odatae2etest.azurewebsites.net/javatest/DefaultService/Customers(PersonID=2)/Orders" />
+    <link rel="http://docs.oasis-open.org/odata/ns/related/Company" type="application/atom+xml;type=entry" title="Company" href="http://odatae2etest.azurewebsites.net/javatest/DefaultService/Customers(PersonID=2)/Company" />
+    <title />
+    <updated>2014-04-23T10:01:18Z</updated>
+    <author>
+      <name />
+    </author>
+    <content type="application/xml">
+      <m:properties>
+        <d:PersonID m:type="Int32">2</d:PersonID>
+        <d:FirstName>Jill</d:FirstName>
+        <d:LastName>Jones</d:LastName>
+        <d:MiddleName m:null="true" />
+        <d:HomeAddress m:null="true" />
+        <d:Home m:type="GeographyPoint">
+          <gml:Point gml:srsName="http://www.opengis.net/def/crs/EPSG/0/4326">
+            <gml:pos>15 161.8</gml:pos>
+          </gml:Point>
+        </d:Home>
+        <d:Numbers m:type="#Collection(String)" />
+        <d:Emails m:type="#Collection(String)" />
+        <d:City>Sydney</d:City>
+        <d:Birthday m:type="DateTimeOffset">1983-01-15T00:00:00Z</d:Birthday>
+        <d:TimeBetweenLastTwoOrders m:type="Duration">PT0.0000002S</d:TimeBetweenLastTwoOrders>
+      </m:properties>
+    </content>
+  </entry>
+</feed>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/4f1072a6/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/cud/ODataDeleteRequest.java
----------------------------------------------------------------------
diff --git a/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/cud/ODataDeleteRequest.java b/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/cud/ODataDeleteRequest.java
index 79b2641..9ac5e95 100644
--- a/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/cud/ODataDeleteRequest.java
+++ b/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/cud/ODataDeleteRequest.java
@@ -19,11 +19,13 @@
 package org.apache.olingo.client.api.communication.request.cud;
 
 import org.apache.olingo.client.api.communication.request.ODataBasicRequest;
+import org.apache.olingo.client.api.communication.request.ODataBatchableRequest;
 import org.apache.olingo.client.api.communication.response.ODataDeleteResponse;
 import org.apache.olingo.commons.api.format.ODataPubFormat;
 
 /**
  * This class implements an OData delete request.
  */
-public interface ODataDeleteRequest extends ODataBasicRequest<ODataDeleteResponse, ODataPubFormat> {
+public interface ODataDeleteRequest
+        extends ODataBasicRequest<ODataDeleteResponse, ODataPubFormat>, ODataBatchableRequest {
 }

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/4f1072a6/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/cud/ODataPropertyUpdateRequest.java
----------------------------------------------------------------------
diff --git a/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/cud/ODataPropertyUpdateRequest.java b/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/cud/ODataPropertyUpdateRequest.java
index 53fa447..25ece1a 100644
--- a/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/cud/ODataPropertyUpdateRequest.java
+++ b/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/cud/ODataPropertyUpdateRequest.java
@@ -19,11 +19,13 @@
 package org.apache.olingo.client.api.communication.request.cud;
 
 import org.apache.olingo.client.api.communication.request.ODataBasicRequest;
+import org.apache.olingo.client.api.communication.request.ODataBatchableRequest;
 import org.apache.olingo.client.api.communication.response.ODataPropertyUpdateResponse;
 import org.apache.olingo.commons.api.format.ODataFormat;
 
 /**
  * This class implements an OData update entity property request.
  */
-public interface ODataPropertyUpdateRequest extends ODataBasicRequest<ODataPropertyUpdateResponse, ODataFormat> {
+public interface ODataPropertyUpdateRequest
+        extends ODataBasicRequest<ODataPropertyUpdateResponse, ODataFormat>, ODataBatchableRequest {
 }

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/4f1072a6/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/cud/ODataValueUpdateRequest.java
----------------------------------------------------------------------
diff --git a/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/cud/ODataValueUpdateRequest.java b/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/cud/ODataValueUpdateRequest.java
index 753fde8..ced8c03 100644
--- a/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/cud/ODataValueUpdateRequest.java
+++ b/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/cud/ODataValueUpdateRequest.java
@@ -19,11 +19,13 @@
 package org.apache.olingo.client.api.communication.request.cud;
 
 import org.apache.olingo.client.api.communication.request.ODataBasicRequest;
+import org.apache.olingo.client.api.communication.request.ODataBatchableRequest;
 import org.apache.olingo.client.api.communication.response.ODataValueUpdateResponse;
 import org.apache.olingo.commons.api.format.ODataValueFormat;
 
 /**
  * This class implements an OData update entity property value request.
  */
-public interface ODataValueUpdateRequest extends ODataBasicRequest<ODataValueUpdateResponse, ODataValueFormat> {
+public interface ODataValueUpdateRequest
+        extends ODataBasicRequest<ODataValueUpdateResponse, ODataValueFormat>, ODataBatchableRequest {
 }

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/4f1072a6/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/cud/v3/ODataLinkCreateRequest.java
----------------------------------------------------------------------
diff --git a/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/cud/v3/ODataLinkCreateRequest.java b/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/cud/v3/ODataLinkCreateRequest.java
index 53bfde1..b35a76f 100644
--- a/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/cud/v3/ODataLinkCreateRequest.java
+++ b/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/cud/v3/ODataLinkCreateRequest.java
@@ -19,11 +19,13 @@
 package org.apache.olingo.client.api.communication.request.cud.v3;
 
 import org.apache.olingo.client.api.communication.request.ODataBasicRequest;
+import org.apache.olingo.client.api.communication.request.ODataBatchableRequest;
 import org.apache.olingo.client.api.communication.response.ODataLinkOperationResponse;
 import org.apache.olingo.commons.api.format.ODataFormat;
 
 /**
  * This class implements an insert link OData request.
  */
-public interface ODataLinkCreateRequest extends ODataBasicRequest<ODataLinkOperationResponse, ODataFormat> {
+public interface ODataLinkCreateRequest
+        extends ODataBasicRequest<ODataLinkOperationResponse, ODataFormat>, ODataBatchableRequest {
 }

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/4f1072a6/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/cud/v3/ODataLinkUpdateRequest.java
----------------------------------------------------------------------
diff --git a/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/cud/v3/ODataLinkUpdateRequest.java b/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/cud/v3/ODataLinkUpdateRequest.java
index d76f6ed..765594e 100644
--- a/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/cud/v3/ODataLinkUpdateRequest.java
+++ b/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/cud/v3/ODataLinkUpdateRequest.java
@@ -19,11 +19,13 @@
 package org.apache.olingo.client.api.communication.request.cud.v3;
 
 import org.apache.olingo.client.api.communication.request.ODataBasicRequest;
+import org.apache.olingo.client.api.communication.request.ODataBatchableRequest;
 import org.apache.olingo.client.api.communication.response.ODataLinkOperationResponse;
 import org.apache.olingo.commons.api.format.ODataFormat;
 
 /**
  * This class implements an update link OData request.
  */
-public interface ODataLinkUpdateRequest extends ODataBasicRequest<ODataLinkOperationResponse, ODataFormat> {
+public interface ODataLinkUpdateRequest
+        extends ODataBasicRequest<ODataLinkOperationResponse, ODataFormat>, ODataBatchableRequest {
 }

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/4f1072a6/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/streamed/ODataStreamUpdateRequest.java
----------------------------------------------------------------------
diff --git a/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/streamed/ODataStreamUpdateRequest.java b/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/streamed/ODataStreamUpdateRequest.java
index e403cf5..98da20c 100644
--- a/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/streamed/ODataStreamUpdateRequest.java
+++ b/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/streamed/ODataStreamUpdateRequest.java
@@ -18,13 +18,13 @@
  */
 package org.apache.olingo.client.api.communication.request.streamed;
 
+import org.apache.olingo.client.api.communication.request.ODataBatchableRequest;
 import org.apache.olingo.client.api.communication.request.ODataStreamedRequest;
 import org.apache.olingo.client.api.communication.response.ODataStreamUpdateResponse;
 
 /**
- * This class implements an OData stream create/update request.
- * Get instance by using ODataStreamedRequestFactory.
+ * This class implements an OData stream create/update request. Get instance by using ODataStreamedRequestFactory.
  */
 public interface ODataStreamUpdateRequest
-        extends ODataStreamedRequest<ODataStreamUpdateResponse, StreamUpdateStreamManager> {
+        extends ODataStreamedRequest<ODataStreamUpdateResponse, StreamUpdateStreamManager>, ODataBatchableRequest {
 }

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/4f1072a6/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/v4/AsyncRequestFactory.java
----------------------------------------------------------------------
diff --git a/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/v4/AsyncRequestFactory.java b/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/v4/AsyncRequestFactory.java
new file mode 100644
index 0000000..9fd06dc
--- /dev/null
+++ b/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/v4/AsyncRequestFactory.java
@@ -0,0 +1,28 @@
+/*
+ * 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.api.communication.request.v4;
+
+import org.apache.olingo.client.api.communication.request.ODataRequest;
+import org.apache.olingo.client.api.communication.response.ODataResponse;
+
+@SuppressWarnings("unchecked")
+public interface AsyncRequestFactory {
+
+  <R extends ODataResponse> AsyncRequestWrapper<R> getAsyncRequestWrapper(final ODataRequest odataRequest);
+}

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/4f1072a6/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/v4/AsyncRequestWrapper.java
----------------------------------------------------------------------
diff --git a/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/v4/AsyncRequestWrapper.java b/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/v4/AsyncRequestWrapper.java
new file mode 100644
index 0000000..7c57b69
--- /dev/null
+++ b/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/v4/AsyncRequestWrapper.java
@@ -0,0 +1,40 @@
+/*
+ * 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.api.communication.request.v4;
+
+import org.apache.olingo.client.api.communication.response.ODataResponse;
+import org.apache.olingo.client.api.communication.response.v4.AsyncResponseWrapper;
+
+public interface AsyncRequestWrapper<R extends ODataResponse> {
+
+  /**
+   * Add wait http header.
+   *
+   * @param waitInSeconds wait time in seconds.
+   * @return the current AsyncRequestWrapper instance.
+   */
+  AsyncRequestWrapper<R> wait(int waitInSeconds);
+
+  /**
+   * execute the request for the first time.
+   *
+   * @return
+   */
+  AsyncResponseWrapper<R> execute();
+}

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/4f1072a6/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/response/ODataResponse.java
----------------------------------------------------------------------
diff --git a/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/response/ODataResponse.java b/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/response/ODataResponse.java
index 5498d1b..7da07ec 100644
--- a/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/response/ODataResponse.java
+++ b/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/response/ODataResponse.java
@@ -22,6 +22,7 @@ import java.io.InputStream;
 import java.net.URI;
 import java.util.Collection;
 import java.util.Map;
+import org.apache.http.HttpResponse;
 import org.apache.olingo.client.api.communication.header.HeaderName;
 import org.apache.olingo.client.api.communication.request.batch.ODataBatchLineIterator;
 
@@ -59,7 +60,7 @@ public interface ODataResponse {
    * @return ETag header value, if provided
    */
   String getEtag();
-  
+
   /**
    * The context URL describes the content of the payload. It consists of the canonical metadata document URL and a
    * fragment identifying the relevant portion of the metadata document.
@@ -113,12 +114,21 @@ public interface ODataResponse {
   InputStream getRawResponse();
 
   /**
+   * Initializes OData response from HTTP response.
+   *
+   * @param res HTTP response.
+   * @return OData response;
+   */
+  ODataResponse initFromHttpResponse(HttpResponse res);
+
+  /**
    * Initializes response from batch response item.
    *
    * @param responseLine response line.
    * @param headers response headers.
    * @param batchLineIterator batch line iterator.
    * @param boundary batch boundary.
+   * @return OData response.
    */
   ODataResponse initFromBatch(
           final Map.Entry<Integer, String> responseLine,
@@ -127,6 +137,14 @@ public interface ODataResponse {
           final String boundary);
 
   /**
+   * Initializes response from an enclosed HTTP response.
+   *
+   * @param part enclosed HTTP response.
+   * @return OData response.
+   */
+  ODataResponse initFromEnclosedPart(InputStream part);
+
+  /**
    * Close the underlying message entity input stream (if available and open) as well as releases any other resources
    * associated with the response.
    * <p>

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/4f1072a6/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/response/v4/AsyncResponse.java
----------------------------------------------------------------------
diff --git a/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/response/v4/AsyncResponse.java b/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/response/v4/AsyncResponse.java
new file mode 100644
index 0000000..f3fe972
--- /dev/null
+++ b/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/response/v4/AsyncResponse.java
@@ -0,0 +1,24 @@
+/*
+ * 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.api.communication.response.v4;
+
+import org.apache.olingo.client.api.communication.response.ODataResponse;
+
+public interface AsyncResponse extends ODataResponse {
+}

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/4f1072a6/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/response/v4/AsyncResponseWrapper.java
----------------------------------------------------------------------
diff --git a/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/response/v4/AsyncResponseWrapper.java b/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/response/v4/AsyncResponseWrapper.java
new file mode 100644
index 0000000..87b6904
--- /dev/null
+++ b/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/response/v4/AsyncResponseWrapper.java
@@ -0,0 +1,69 @@
+/*
+ * 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.api.communication.response.v4;
+
+import org.apache.olingo.client.api.communication.response.ODataDeleteResponse;
+import org.apache.olingo.client.api.communication.response.ODataResponse;
+
+public interface AsyncResponseWrapper<R extends ODataResponse> {
+
+  /**
+   * Checks for preference applied.
+   *
+   * @return 'TRUE' if respond-async preference has been applied; 'FALSE' otherwise.
+   */
+  boolean isPreferenceApplied();
+
+  /**
+   * Checks if asynchronous processing has been terminated.
+   *
+   * @return 'TRUE' the process has been terminated; 'FALSE' otherwise.
+   */
+  boolean isDone();
+
+  /**
+   * Gets the real response.
+   * <br />
+   * If asynchronous processing has been terminated then the response will be returned immediately. This method retries
+   * after a delay, specified by the 'Retry-After' header indicating the time, in seconds, the client should wait before
+   * retry. If there isn't any 'Retry-After' response header available, a default of 5 seconds will be chosen. The query
+   * will be retried for a maximum of five times.
+   *
+   * @return real OData response.
+   */
+  R getODataResponse();
+
+  /**
+   * DeleteA DELETE request sent to the status monitor resource requests that the asynchronous processing be canceled. A
+   * 200 OK or to a 204 No Content response indicates that the asynchronous processing has been successfully canceled.
+   *
+   * @return OData delete response.
+   */
+  ODataDeleteResponse delete();
+
+  /**
+   * A client can request that the DELETE should be executed asynchronously. A 202 Accepted response indicates that the
+   * cancellation is being processed asynchronously; the client can use the returned Location header (which MUST be
+   * different from the status monitor resource of the initial request) to query for the status of the cancellation. If
+   * a delete request is not supported by the service, the service returns 405 Method Not Allowed.
+   *
+   * @return OData delete response.
+   */
+  AsyncResponseWrapper<ODataDeleteResponse> asyncDelete();
+}

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/4f1072a6/lib/client-api/src/main/java/org/apache/olingo/client/api/v4/ODataClient.java
----------------------------------------------------------------------
diff --git a/lib/client-api/src/main/java/org/apache/olingo/client/api/v4/ODataClient.java b/lib/client-api/src/main/java/org/apache/olingo/client/api/v4/ODataClient.java
index 18306f2..7ee53bf 100644
--- a/lib/client-api/src/main/java/org/apache/olingo/client/api/v4/ODataClient.java
+++ b/lib/client-api/src/main/java/org/apache/olingo/client/api/v4/ODataClient.java
@@ -25,6 +25,7 @@ import org.apache.olingo.client.api.communication.request.cud.v4.UpdateType;
 import org.apache.olingo.client.api.communication.request.invoke.v4.InvokeRequestFactory;
 import org.apache.olingo.client.api.communication.request.retrieve.v4.RetrieveRequestFactory;
 import org.apache.olingo.client.api.communication.request.streamed.v4.StreamedRequestFactory;
+import org.apache.olingo.client.api.communication.request.v4.AsyncRequestFactory;
 import org.apache.olingo.client.api.op.v4.ODataBinder;
 import org.apache.olingo.client.api.op.v4.ODataDeserializer;
 import org.apache.olingo.client.api.op.v4.ODataReader;
@@ -55,6 +56,8 @@ public interface ODataClient extends CommonODataClient<UpdateType> {
   @Override
   ODataObjectFactory getObjectFactory();
 
+  AsyncRequestFactory getAsyncRequestFactory();
+
   @Override
   RetrieveRequestFactory getRetrieveRequestFactory();
 

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/4f1072a6/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/AbstractODataBasicRequest.java
----------------------------------------------------------------------
diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/AbstractODataBasicRequest.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/AbstractODataBasicRequest.java
index 21e6502..c08b426 100644
--- a/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/AbstractODataBasicRequest.java
+++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/AbstractODataBasicRequest.java
@@ -41,7 +41,7 @@ import org.apache.olingo.client.api.http.HttpMethod;
  * @param <T> OData format being used.
  */
 public abstract class AbstractODataBasicRequest<V extends ODataResponse, T extends Format>
-        extends ODataRequestImpl<T>
+        extends AbstractODataRequest<T>
         implements ODataBasicRequest<V, T> {
 
   /**

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/4f1072a6/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/AbstractODataRequest.java
----------------------------------------------------------------------
diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/AbstractODataRequest.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/AbstractODataRequest.java
new file mode 100644
index 0000000..8bc4d1c
--- /dev/null
+++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/AbstractODataRequest.java
@@ -0,0 +1,433 @@
+/*
+ * 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.communication.request;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.lang.reflect.Constructor;
+import java.net.URI;
+import java.util.Collection;
+import org.apache.commons.io.IOUtils;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.http.Header;
+import org.apache.http.HttpEntity;
+import org.apache.http.HttpResponse;
+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.communication.header.HeaderName;
+import org.apache.olingo.client.api.communication.header.ODataHeaders;
+import org.apache.olingo.client.api.communication.request.ODataRequest;
+import org.apache.olingo.client.api.communication.request.ODataStreamer;
+import org.apache.olingo.client.api.communication.response.ODataResponse;
+import org.apache.olingo.commons.api.format.Format;
+import org.apache.olingo.client.api.http.HttpClientException;
+import org.apache.olingo.client.api.http.HttpMethod;
+import org.apache.olingo.client.core.communication.header.ODataHeadersImpl;
+import org.apache.olingo.commons.api.format.ODataMediaFormat;
+import org.apache.olingo.commons.api.format.ODataPubFormat;
+import org.apache.olingo.commons.api.format.ODataValueFormat;
+
+/**
+ * Abstract representation of an OData request. Get instance by using factories.
+ *
+ * @param <T> Accepted content-type formats by the request in object.
+ *
+ * @see org.apache.olingo.client.api.communication.request.cud.v3.CUDRequestFactory
+ * @see org.apache.olingo.client.api.communication.request.cud.v4.CUDRequestFactory
+ * @see org.apache.olingo.client.api.communication.request.batch.v3.BatchRequestFactory
+ * @see org.apache.olingo.client.api.communication.request.batch.v4.BatchRequestFactory
+ * @see org.apache.olingo.client.api.communication.request.invoke.v3.InvokeRequestFactory
+ * @see org.apache.olingo.client.api.communication.request.invoke.v4.InvokeRequestFactory
+ * @see org.apache.olingo.client.api.communication.request.streamed.v3.StreamedRequestFactory
+ * @see org.apache.olingo.client.api.communication.request.streamed.v4.StreamedRequestFactory
+ */
+public abstract class AbstractODataRequest<T extends Format> extends AbstractRequest implements ODataRequest {
+
+  protected final CommonODataClient<?> odataClient;
+
+  private final Class<T> formatRef;
+
+  /**
+   * OData request method.
+   */
+  protected final HttpMethod method;
+
+  /**
+   * OData request header.
+   */
+  protected final ODataHeadersImpl odataHeaders;
+
+  /**
+   * Target URI.
+   */
+  protected final URI uri;
+
+  /**
+   * HTTP client.
+   */
+  protected final HttpClient httpClient;
+
+  /**
+   * HTTP request.
+   */
+  protected final HttpUriRequest request;
+
+  /**
+   * Constructor.
+   *
+   * @param odataClient client instance getting this request
+   * @param formatRef reference class for the format being used
+   * @param method HTTP request method. If configured X-HTTP-METHOD header will be used.
+   * @param uri OData request URI.
+   */
+  protected AbstractODataRequest(final CommonODataClient<?> odataClient,
+          final Class<T> formatRef, final HttpMethod method, final URI uri) {
+
+    this.odataClient = odataClient;
+
+    this.formatRef = formatRef;
+    this.method = method;
+
+    // initialize default headers
+    this.odataHeaders = (ODataHeadersImpl) odataClient.getVersionHeaders();
+
+    // target uri
+    this.uri = uri;
+
+    HttpClient _httpClient = odataClient.getConfiguration().getHttpClientFactory().
+            createHttpClient(this.method, this.uri);
+    if (odataClient.getConfiguration().isGzipCompression()) {
+      _httpClient = new DecompressingHttpClient(_httpClient);
+    }
+    this.httpClient = _httpClient;
+
+    this.request = odataClient.getConfiguration().getHttpUriRequestFactory().
+            createHttpUriRequest(this.method, this.uri);
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  @SuppressWarnings("unchecked")
+  public T getDefaultFormat() {
+    return (T) (formatRef.equals(ODataPubFormat.class)
+            ? odataClient.getConfiguration().getDefaultPubFormat()
+            : (formatRef.equals(ODataValueFormat.class)
+            ? odataClient.getConfiguration().getDefaultValueFormat()
+            : (formatRef.equals(ODataMediaFormat.class)
+            ? odataClient.getConfiguration().getDefaultMediaFormat()
+            : odataClient.getConfiguration().getDefaultFormat())));
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  public URI getURI() {
+    return uri;
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  public Collection<String> getHeaderNames() {
+    return odataHeaders.getHeaderNames();
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  public String getHeader(final String name) {
+    return odataHeaders.getHeader(name);
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  public ODataRequest setAccept(final String value) {
+    odataHeaders.setHeader(HeaderName.accept, value);
+    return this;
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  public ODataRequest setIfMatch(final String value) {
+    odataHeaders.setHeader(HeaderName.ifMatch, value);
+    return this;
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  public ODataRequest setIfNoneMatch(final String value) {
+    odataHeaders.setHeader(HeaderName.ifNoneMatch, value);
+    return this;
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  public ODataRequest setPrefer(final String value) {
+    odataHeaders.setHeader(HeaderName.prefer, value);
+    return this;
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  public ODataRequest setXHTTPMethod(final String value) {
+    odataHeaders.setHeader(HeaderName.xHttpMethod, value);
+    return this;
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  public ODataRequest setContentType(final String value) {
+    odataHeaders.setHeader(HeaderName.contentType, value);
+    return this;
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  public ODataRequest setSlug(final String value) {
+    odataHeaders.setHeader(HeaderName.slug, value);
+    return this;
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  public ODataRequest addCustomHeader(final String name, final String value) {
+    odataHeaders.setHeader(name, value);
+    return this;
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  public ODataRequest addCustomHeader(final HeaderName name, final String value) {
+    odataHeaders.setHeader(name, value);
+    return this;
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  public String getAccept() {
+    final String acceptHead = odataHeaders.getHeader(HeaderName.accept);
+    return StringUtils.isBlank(acceptHead) ? getDefaultFormat().toString(odataClient.getServiceVersion()) : acceptHead;
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  public String getIfMatch() {
+    return odataHeaders.getHeader(HeaderName.ifMatch);
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  public String getIfNoneMatch() {
+    return odataHeaders.getHeader(HeaderName.ifNoneMatch);
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  public String getPrefer() {
+    return odataHeaders.getHeader(HeaderName.prefer);
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  public String getContentType() {
+    final String contentTypeHead = odataHeaders.getHeader(HeaderName.contentType);
+    return StringUtils.isBlank(contentTypeHead)
+            ? getDefaultFormat().toString(odataClient.getServiceVersion()) : contentTypeHead;
+  }
+
+  /**
+   * ${@inheritDoc }
+   */
+  @Override
+  public HttpMethod getMethod() {
+    return method;
+  }
+
+  /**
+   * Gets request headers.
+   *
+   * @return request headers.
+   */
+  public ODataHeaders getHeader() {
+    return odataHeaders;
+  }
+
+  /**
+   * {@inheritDoc }
+   */
+  @Override
+  public byte[] toByteArray() {
+    final ByteArrayOutputStream baos = new ByteArrayOutputStream();
+    try {
+      final StringBuilder requestBuilder = new StringBuilder();
+      requestBuilder.append(getMethod().toString()).append(' ').append(uri.toString()).append(' ').append("HTTP/1.1");
+
+      baos.write(requestBuilder.toString().getBytes());
+
+      baos.write(ODataStreamer.CRLF);
+
+      // Set Content-Type and Accept headers with default values, if not yet set
+      if (StringUtils.isBlank(odataHeaders.getHeader(HeaderName.contentType))) {
+        setContentType(getContentType());
+      }
+      if (StringUtils.isBlank(odataHeaders.getHeader(HeaderName.accept))) {
+        setAccept(getAccept());
+      }
+
+      for (String name : getHeaderNames()) {
+        final String value = getHeader(name);
+
+        if (StringUtils.isNotBlank(value)) {
+          baos.write((name + ": " + value).getBytes());
+          baos.write(ODataStreamer.CRLF);
+        }
+      }
+
+      return baos.toByteArray();
+    } catch (IOException e) {
+      throw new IllegalStateException(e);
+    } finally {
+      IOUtils.closeQuietly(baos);
+    }
+  }
+
+  /**
+   * {@inheritDoc }
+   */
+  @Override
+  public InputStream rawExecute() {
+    try {
+      final HttpEntity httpEntity = doExecute().getEntity();
+      return httpEntity == null ? null : httpEntity.getContent();
+    } catch (IOException e) {
+      throw new HttpClientException(e);
+    } catch (RuntimeException e) {
+      this.request.abort();
+      throw new HttpClientException(e);
+    }
+  }
+
+  /**
+   * Builds the request and execute it.
+   *
+   * @return HttpReponse object.
+   */
+  protected HttpResponse doExecute() {
+    // Set Content-Type and Accept headers with default values, if not yet set
+    if (StringUtils.isBlank(odataHeaders.getHeader(HeaderName.contentType))) {
+      setContentType(getContentType());
+    }
+    if (StringUtils.isBlank(odataHeaders.getHeader(HeaderName.accept))) {
+      setAccept(getAccept());
+    }
+
+    // Add header for KeyAsSegment management
+    if (odataClient.getConfiguration().isKeyAsSegment()) {
+      addCustomHeader(
+              HeaderName.dataServiceUrlConventions.toString(),
+              odataClient.newPreferences().keyAsSegment());
+    }
+
+    // Add all available headers
+    for (String key : getHeaderNames()) {
+      this.request.addHeader(key, odataHeaders.getHeader(key));
+    }
+
+    if (LOG.isDebugEnabled()) {
+      for (Header header : this.request.getAllHeaders()) {
+        LOG.debug("HTTP header being sent: " + header);
+      }
+    }
+
+    final HttpResponse response;
+    try {
+      response = this.httpClient.execute(this.request);
+    } catch (IOException e) {
+      throw new HttpClientException(e);
+    } catch (RuntimeException e) {
+      this.request.abort();
+      throw new HttpClientException(e);
+    }
+
+    checkForResponse(odataClient, response, getAccept());
+
+    return response;
+  }
+
+  /**
+   * Gets an empty response that can be initialized by a stream.
+   * <p>
+   * This method has to be used to build response items about a batch request.
+   *
+   * @param <V> ODataResppnse type.
+   * @return empty OData response instance.
+   */
+  @SuppressWarnings("unchecked")
+  public <V extends ODataResponse> V getResponseTemplate() {
+
+    for (Class<?> clazz : this.getClass().getDeclaredClasses()) {
+      if (ODataResponse.class.isAssignableFrom(clazz)) {
+        try {
+          final Constructor<?> constructor = clazz.getDeclaredConstructor(this.getClass());
+          constructor.setAccessible(true);
+          return (V) constructor.newInstance(this);
+        } catch (Exception e) {
+          LOG.error("Error retrieving response class template instance", e);
+        }
+      }
+    }
+
+    throw new IllegalStateException("No response class template has been found");
+  }
+}

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/4f1072a6/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/AbstractRequest.java
----------------------------------------------------------------------
diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/AbstractRequest.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/AbstractRequest.java
new file mode 100644
index 0000000..25514b8
--- /dev/null
+++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/AbstractRequest.java
@@ -0,0 +1,84 @@
+/*
+ * Copyright 2014 The Apache Software Foundation.
+ *
+ * Licensed 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.communication.request;
+
+import java.io.IOException;
+import org.apache.http.HttpEntity;
+import org.apache.http.HttpResponse;
+import org.apache.olingo.client.api.CommonODataClient;
+import org.apache.olingo.client.api.communication.ODataClientErrorException;
+import org.apache.olingo.client.api.communication.ODataServerErrorException;
+import org.apache.olingo.client.api.http.HttpClientException;
+import org.apache.olingo.commons.api.domain.ODataError;
+import org.apache.olingo.commons.core.data.JSONODataErrorImpl;
+import org.apache.olingo.commons.core.data.XMLODataErrorImpl;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public abstract class AbstractRequest {
+
+  /**
+   * Logger.
+   */
+  protected static final Logger LOG = LoggerFactory.getLogger(AbstractRequest.class);
+
+  private ODataError getGenericError(final int code, final String errorMsg, final boolean isXML) {
+    final ODataError error;
+    if (isXML) {
+      error = new XMLODataErrorImpl();
+      ((XMLODataErrorImpl) error).setCode(String.valueOf(code));
+      ((XMLODataErrorImpl) error).setMessage(errorMsg);
+    } else {
+      error = new JSONODataErrorImpl();
+      ((JSONODataErrorImpl) error).setCode(String.valueOf(code));
+      ((JSONODataErrorImpl) error).setMessage(errorMsg);
+    }
+
+    return error;
+  }
+
+  protected <C extends CommonODataClient<?>> void checkForResponse(
+          final C odataClient, final HttpResponse response, final String accept) {
+
+    if (response.getStatusLine().getStatusCode() >= 500) {
+      throw new ODataServerErrorException(response.getStatusLine());
+    } else if (response.getStatusLine().getStatusCode() >= 400) {
+      try {
+        final HttpEntity httpEntity = response.getEntity();
+        if (httpEntity == null) {
+          throw new ODataClientErrorException(response.getStatusLine());
+        } else {
+          final boolean isXML = accept.contains("json");
+          ODataError error;
+          try {
+            error = odataClient.getReader().readError(httpEntity.getContent(), isXML);
+          } catch (IllegalArgumentException e) {
+            LOG.warn("Error deserializing error response", e);
+            error = getGenericError(
+                    response.getStatusLine().getStatusCode(),
+                    response.getStatusLine().getReasonPhrase(),
+                    isXML);
+          }
+
+          throw new ODataClientErrorException(response.getStatusLine(), error);
+        }
+      } catch (IOException e) {
+        throw new HttpClientException(
+                "Received '" + response.getStatusLine() + "' but could not extract error body", e);
+      }
+    }
+  }
+}

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/4f1072a6/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/ODataRequestImpl.java
----------------------------------------------------------------------
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
deleted file mode 100644
index 4fc28a9..0000000
--- a/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/ODataRequestImpl.java
+++ /dev/null
@@ -1,486 +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.client.core.communication.request;
-
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.lang.reflect.Constructor;
-import java.net.URI;
-import java.util.Collection;
-import org.apache.commons.io.IOUtils;
-import org.apache.commons.lang3.StringUtils;
-import org.apache.http.Header;
-import org.apache.http.HttpEntity;
-import org.apache.http.HttpResponse;
-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.communication.ODataClientErrorException;
-import org.apache.olingo.client.api.communication.ODataServerErrorException;
-import org.apache.olingo.client.api.communication.header.HeaderName;
-import org.apache.olingo.client.api.communication.header.ODataHeaders;
-import org.apache.olingo.client.api.communication.request.ODataRequest;
-import org.apache.olingo.client.api.communication.request.ODataStreamer;
-import org.apache.olingo.client.api.communication.response.ODataResponse;
-import org.apache.olingo.commons.api.format.Format;
-import org.apache.olingo.client.api.http.HttpClientException;
-import org.apache.olingo.client.api.http.HttpMethod;
-import org.apache.olingo.client.core.communication.header.ODataHeadersImpl;
-import org.apache.olingo.commons.api.domain.ODataError;
-import org.apache.olingo.commons.api.format.ODataMediaFormat;
-import org.apache.olingo.commons.api.format.ODataPubFormat;
-import org.apache.olingo.commons.api.format.ODataValueFormat;
-import org.apache.olingo.commons.core.data.JSONODataErrorImpl;
-import org.apache.olingo.commons.core.data.XMLODataErrorImpl;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * Abstract representation of an OData request. Get instance by using factories.
- *
- * @param <T> Accepted content-type formats by the request in object.
- *
- * @see org.apache.olingo.client.api.communication.request.cud.v3.CUDRequestFactory
- * @see org.apache.olingo.client.api.communication.request.cud.v4.CUDRequestFactory
- * @see org.apache.olingo.client.api.communication.request.batch.v3.BatchRequestFactory
- * @see org.apache.olingo.client.api.communication.request.batch.v4.BatchRequestFactory
- * @see org.apache.olingo.client.api.communication.request.invoke.v3.InvokeRequestFactory
- * @see org.apache.olingo.client.api.communication.request.invoke.v4.InvokeRequestFactory
- * @see org.apache.olingo.client.api.communication.request.streamed.v3.StreamedRequestFactory
- * @see org.apache.olingo.client.api.communication.request.streamed.v4.StreamedRequestFactory
- */
-public class ODataRequestImpl<T extends Format> implements ODataRequest {
-
-  /**
-   * Logger.
-   */
-  protected static final Logger LOG = LoggerFactory.getLogger(ODataRequest.class);
-
-  protected final CommonODataClient<?> odataClient;
-
-  private final Class<T> formatRef;
-
-  /**
-   * OData request method.
-   */
-  protected final HttpMethod method;
-
-  /**
-   * OData request header.
-   */
-  protected final ODataHeadersImpl odataHeaders;
-
-  /**
-   * Target URI.
-   */
-  protected final URI uri;
-
-  /**
-   * HTTP client.
-   */
-  protected final HttpClient httpClient;
-
-  /**
-   * HTTP request.
-   */
-  protected final HttpUriRequest request;
-
-  /**
-   * Constructor.
-   *
-   * @param odataClient client instance getting this request
-   * @param formatRef reference class for the format being used
-   * @param method HTTP request method. If configured X-HTTP-METHOD header will be used.
-   * @param uri OData request URI.
-   */
-  protected ODataRequestImpl(final CommonODataClient<?> odataClient,
-          final Class<T> formatRef, final HttpMethod method, final URI uri) {
-
-    this.odataClient = odataClient;
-
-    this.formatRef = formatRef;
-    this.method = method;
-
-    // initialize default headers
-    this.odataHeaders = (ODataHeadersImpl) odataClient.getVersionHeaders();
-
-    // target uri
-    this.uri = uri;
-
-    HttpClient _httpClient = odataClient.getConfiguration().getHttpClientFactory().
-            createHttpClient(this.method, this.uri);
-    if (odataClient.getConfiguration().isGzipCompression()) {
-      _httpClient = new DecompressingHttpClient(_httpClient);
-    }
-    this.httpClient = _httpClient;
-
-    this.request = odataClient.getConfiguration().getHttpUriRequestFactory().
-            createHttpUriRequest(this.method, this.uri);
-  }
-
-  /**
-   * {@inheritDoc}
-   */
-  @SuppressWarnings("unchecked")
-  public T getDefaultFormat() {
-    return (T) (formatRef.equals(ODataPubFormat.class)
-            ? odataClient.getConfiguration().getDefaultPubFormat()
-            : (formatRef.equals(ODataValueFormat.class)
-            ? odataClient.getConfiguration().getDefaultValueFormat()
-            : (formatRef.equals(ODataMediaFormat.class)
-            ? odataClient.getConfiguration().getDefaultMediaFormat()
-            : odataClient.getConfiguration().getDefaultFormat())));
-  }
-
-  /**
-   * {@inheritDoc}
-   */
-  @Override
-  public URI getURI() {
-    return uri;
-  }
-
-  /**
-   * {@inheritDoc}
-   */
-  @Override
-  public Collection<String> getHeaderNames() {
-    return odataHeaders.getHeaderNames();
-  }
-
-  /**
-   * {@inheritDoc}
-   */
-  @Override
-  public String getHeader(final String name) {
-    return odataHeaders.getHeader(name);
-  }
-
-  /**
-   * {@inheritDoc}
-   */
-  @Override
-  public ODataRequest setAccept(final String value) {
-    odataHeaders.setHeader(HeaderName.accept, value);
-    return this;
-  }
-
-  /**
-   * {@inheritDoc}
-   */
-  @Override
-  public ODataRequest setIfMatch(final String value) {
-    odataHeaders.setHeader(HeaderName.ifMatch, value);
-    return this;
-  }
-
-  /**
-   * {@inheritDoc}
-   */
-  @Override
-  public ODataRequest setIfNoneMatch(final String value) {
-    odataHeaders.setHeader(HeaderName.ifNoneMatch, value);
-    return this;
-  }
-
-  /**
-   * {@inheritDoc}
-   */
-  @Override
-  public ODataRequest setPrefer(final String value) {
-    odataHeaders.setHeader(HeaderName.prefer, value);
-    return this;
-  }
-
-  /**
-   * {@inheritDoc}
-   */
-  @Override
-  public ODataRequest setXHTTPMethod(final String value) {
-    odataHeaders.setHeader(HeaderName.xHttpMethod, value);
-    return this;
-  }
-
-  /**
-   * {@inheritDoc}
-   */
-  @Override
-  public ODataRequest setContentType(final String value) {
-    odataHeaders.setHeader(HeaderName.contentType, value);
-    return this;
-  }
-
-  /**
-   * {@inheritDoc}
-   */
-  @Override
-  public ODataRequest setSlug(final String value) {
-    odataHeaders.setHeader(HeaderName.slug, value);
-    return this;
-  }
-
-  /**
-   * {@inheritDoc}
-   */
-  @Override
-  public ODataRequest addCustomHeader(final String name, final String value) {
-    odataHeaders.setHeader(name, value);
-    return this;
-  }
-
-  /**
-   * {@inheritDoc}
-   */
-  @Override
-  public ODataRequest addCustomHeader(final HeaderName name, final String value) {
-    odataHeaders.setHeader(name, value);
-    return this;
-  }
-
-  /**
-   * {@inheritDoc}
-   */
-  @Override
-  public String getAccept() {
-    final String acceptHead = odataHeaders.getHeader(HeaderName.accept);
-    return StringUtils.isBlank(acceptHead) ? getDefaultFormat().toString(odataClient.getServiceVersion()) : acceptHead;
-  }
-
-  /**
-   * {@inheritDoc}
-   */
-  @Override
-  public String getIfMatch() {
-    return odataHeaders.getHeader(HeaderName.ifMatch);
-  }
-
-  /**
-   * {@inheritDoc}
-   */
-  @Override
-  public String getIfNoneMatch() {
-    return odataHeaders.getHeader(HeaderName.ifNoneMatch);
-  }
-
-  /**
-   * {@inheritDoc}
-   */
-  @Override
-  public String getPrefer() {
-    return odataHeaders.getHeader(HeaderName.prefer);
-  }
-
-  /**
-   * {@inheritDoc}
-   */
-  @Override
-  public String getContentType() {
-    final String contentTypeHead = odataHeaders.getHeader(HeaderName.contentType);
-    return StringUtils.isBlank(contentTypeHead)
-            ? getDefaultFormat().toString(odataClient.getServiceVersion()) : contentTypeHead;
-  }
-
-  /**
-   * ${@inheritDoc }
-   */
-  @Override
-  public HttpMethod getMethod() {
-    return method;
-  }
-
-  /**
-   * Gets request headers.
-   *
-   * @return request headers.
-   */
-  public ODataHeaders getHeader() {
-    return odataHeaders;
-  }
-
-  /**
-   * {@inheritDoc }
-   */
-  @Override
-  public byte[] toByteArray() {
-    final ByteArrayOutputStream baos = new ByteArrayOutputStream();
-    try {
-      final StringBuilder requestBuilder = new StringBuilder();
-      requestBuilder.append(getMethod().toString()).append(' ').append(uri.toString()).append(' ').append("HTTP/1.1");
-
-      baos.write(requestBuilder.toString().getBytes());
-
-      baos.write(ODataStreamer.CRLF);
-
-      // Set Content-Type and Accept headers with default values, if not yet set
-      if (StringUtils.isBlank(odataHeaders.getHeader(HeaderName.contentType))) {
-        setContentType(getContentType());
-      }
-      if (StringUtils.isBlank(odataHeaders.getHeader(HeaderName.accept))) {
-        setAccept(getAccept());
-      }
-
-      for (String name : getHeaderNames()) {
-        final String value = getHeader(name);
-
-        if (StringUtils.isNotBlank(value)) {
-          baos.write((name + ": " + value).getBytes());
-          baos.write(ODataStreamer.CRLF);
-        }
-      }
-
-      return baos.toByteArray();
-    } catch (IOException e) {
-      throw new IllegalStateException(e);
-    } finally {
-      IOUtils.closeQuietly(baos);
-    }
-  }
-
-  /**
-   * {@inheritDoc }
-   */
-  @Override
-  public InputStream rawExecute() {
-    try {
-      final HttpEntity httpEntity = doExecute().getEntity();
-      return httpEntity == null ? null : httpEntity.getContent();
-    } catch (IOException e) {
-      throw new HttpClientException(e);
-    } catch (RuntimeException e) {
-      this.request.abort();
-      throw new HttpClientException(e);
-    }
-  }
-
-  /**
-   * Builds the request and execute it.
-   *
-   * @return HttpReponse object.
-   */
-  protected HttpResponse doExecute() {
-    // Set Content-Type and Accept headers with default values, if not yet set
-    if (StringUtils.isBlank(odataHeaders.getHeader(HeaderName.contentType))) {
-      setContentType(getContentType());
-    }
-    if (StringUtils.isBlank(odataHeaders.getHeader(HeaderName.accept))) {
-      setAccept(getAccept());
-    }
-
-    // Add header for KeyAsSegment management
-    if (odataClient.getConfiguration().isKeyAsSegment()) {
-      addCustomHeader(
-              HeaderName.dataServiceUrlConventions.toString(),
-              odataClient.newPreferences().keyAsSegment());
-    }
-
-    // Add all available headers
-    for (String key : getHeaderNames()) {
-      this.request.addHeader(key, odataHeaders.getHeader(key));
-    }
-
-    if (LOG.isDebugEnabled()) {
-      for (Header header : this.request.getAllHeaders()) {
-        LOG.debug("HTTP header being sent: " + header);
-      }
-    }
-
-    final HttpResponse response;
-    try {
-      response = this.httpClient.execute(this.request);
-    } catch (IOException e) {
-      throw new HttpClientException(e);
-    } catch (RuntimeException e) {
-      this.request.abort();
-      throw new HttpClientException(e);
-    }
-
-    if (response.getStatusLine().getStatusCode() >= 500) {
-      throw new ODataServerErrorException(response.getStatusLine());
-    } else if (response.getStatusLine().getStatusCode() >= 400) {
-      try {
-        final HttpEntity httpEntity = response.getEntity();
-        if (httpEntity == null) {
-          throw new ODataClientErrorException(response.getStatusLine());
-        } else {
-          final boolean isXML = getAccept().contains("json");
-          ODataError error;
-          try {
-            error = odataClient.getReader().readError(httpEntity.getContent(), isXML);
-          } catch (IllegalArgumentException e) {
-            LOG.warn("Error deserializing error response", e);
-            error = getGenericError(
-                    response.getStatusLine().getStatusCode(),
-                    response.getStatusLine().getReasonPhrase(),
-                    isXML);
-          }
-
-          throw new ODataClientErrorException(response.getStatusLine(), error);
-        }
-      } catch (IOException e) {
-        throw new HttpClientException(
-                "Received '" + response.getStatusLine() + "' but could not extract error body", e);
-      }
-    }
-
-    return response;
-  }
-
-  /**
-   * Gets an empty response that can be initialized by a stream.
-   * <p>
-   * This method has to be used to build response items about a batch request.
-   *
-   * @param <V> ODataResppnse type.
-   * @return empty OData response instance.
-   */
-  @SuppressWarnings("unchecked")
-  public <V extends ODataResponse> V getResponseTemplate() {
-
-    for (Class<?> clazz : this.getClass().getDeclaredClasses()) {
-      if (ODataResponse.class.isAssignableFrom(clazz)) {
-        try {
-          final Constructor<?> constructor = clazz.getDeclaredConstructor(this.getClass());
-          constructor.setAccessible(true);
-          return (V) constructor.newInstance(this);
-        } catch (Exception e) {
-          LOG.error("Error retrieving response class template instance", e);
-        }
-      }
-    }
-
-    throw new IllegalStateException("No response class template has been found");
-  }
-
-  private ODataError getGenericError(final int code, final String errorMsg, final boolean isXML) {
-    final ODataError error;
-    if (isXML) {
-      error = new XMLODataErrorImpl();
-      ((XMLODataErrorImpl) error).setCode(String.valueOf(code));
-      ((XMLODataErrorImpl) error).setMessage(errorMsg);
-    } else {
-      error = new JSONODataErrorImpl();
-      ((JSONODataErrorImpl) error).setCode(String.valueOf(code));
-      ((JSONODataErrorImpl) error).setMessage(errorMsg);
-    }
-
-    return error;
-  }
-}

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/4f1072a6/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/batch/AbstractODataBatchRequest.java
----------------------------------------------------------------------
diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/batch/AbstractODataBatchRequest.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/batch/AbstractODataBatchRequest.java
index 606dec9..382cbd1 100644
--- a/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/batch/AbstractODataBatchRequest.java
+++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/batch/AbstractODataBatchRequest.java
@@ -59,7 +59,7 @@ public abstract class AbstractODataBatchRequest<V extends ODataResponse, T exten
    * @param odataClient client instance getting this request
    * @param uri batch request URI (http://serviceRoot/$batch)
    */
-  protected AbstractODataBatchRequest(final CommonODataClient odataClient, final URI uri) {
+  protected AbstractODataBatchRequest(final CommonODataClient<?> odataClient, final URI uri) {
     super(odataClient, HttpMethod.POST, uri);
 
     // create a random UUID value for boundary

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/4f1072a6/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/batch/ODataChangesetImpl.java
----------------------------------------------------------------------
diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/batch/ODataChangesetImpl.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/batch/ODataChangesetImpl.java
index edc294b..ec03220 100644
--- a/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/batch/ODataChangesetImpl.java
+++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/batch/ODataChangesetImpl.java
@@ -24,7 +24,7 @@ import org.apache.olingo.client.api.communication.request.ODataBatchableRequest;
 import org.apache.olingo.client.api.communication.request.batch.CommonODataBatchRequest;
 import org.apache.olingo.client.api.communication.request.batch.ODataChangeset;
 import org.apache.olingo.client.api.http.HttpMethod;
-import org.apache.olingo.client.core.communication.request.ODataRequestImpl;
+import org.apache.olingo.client.core.communication.request.AbstractODataRequest;
 import org.apache.olingo.commons.api.format.ContentType;
 
 /**
@@ -122,7 +122,7 @@ public class ODataChangesetImpl extends AbstractODataBatchRequestItem
     request.batch(req, String.valueOf(contentId));
 
     // add request to the list
-    expectedResItem.addResponse(String.valueOf(contentId), ((ODataRequestImpl) request).getResponseTemplate());
+    expectedResItem.addResponse(String.valueOf(contentId), ((AbstractODataRequest) request).getResponseTemplate());
     return this;
   }
 }

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/4f1072a6/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/batch/ODataRetrieveImpl.java
----------------------------------------------------------------------
diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/batch/ODataRetrieveImpl.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/batch/ODataRetrieveImpl.java
index 9bc35f4..f7375ff 100644
--- a/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/batch/ODataRetrieveImpl.java
+++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/batch/ODataRetrieveImpl.java
@@ -22,7 +22,7 @@ import org.apache.olingo.client.api.communication.request.ODataBatchableRequest;
 import org.apache.olingo.client.api.communication.request.batch.CommonODataBatchRequest;
 import org.apache.olingo.client.api.communication.request.batch.ODataRetrieve;
 import org.apache.olingo.client.api.http.HttpMethod;
-import org.apache.olingo.client.core.communication.request.ODataRequestImpl;
+import org.apache.olingo.client.core.communication.request.AbstractODataRequest;
 
 /**
  * Retrieve request wrapper for the corresponding batch item.
@@ -60,7 +60,7 @@ public class ODataRetrieveImpl extends AbstractODataBatchRequestItem
       throw new IllegalStateException("Current batch item is closed");
     }
 
-    if (((ODataRequestImpl) request).getMethod() != HttpMethod.GET) {
+    if (((AbstractODataRequest) request).getMethod() != HttpMethod.GET) {
       throw new IllegalArgumentException("Invalid request. Only GET method is allowed");
     }
 
@@ -74,7 +74,7 @@ public class ODataRetrieveImpl extends AbstractODataBatchRequestItem
 
     // add request to the list
     expectedResItem.addResponse(
-            ODataRetrieveResponseItem.RETRIEVE_CONTENT_ID, ((ODataRequestImpl) request).getResponseTemplate());
+            ODataRetrieveResponseItem.RETRIEVE_CONTENT_ID, ((AbstractODataRequest) request).getResponseTemplate());
 
     return this;
   }

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/4f1072a6/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/batch/v3/ODataBatchRequestImpl.java
----------------------------------------------------------------------
diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/batch/v3/ODataBatchRequestImpl.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/batch/v3/ODataBatchRequestImpl.java
index e838eca..dd3f365 100644
--- a/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/batch/v3/ODataBatchRequestImpl.java
+++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/batch/v3/ODataBatchRequestImpl.java
@@ -44,7 +44,7 @@ public class ODataBatchRequestImpl
         extends AbstractODataBatchRequest<ODataBatchResponse, BatchStreamManager>
         implements ODataBatchRequest, ODataStreamedRequest<ODataBatchResponse, BatchStreamManager> {
 
-  public ODataBatchRequestImpl(final CommonODataClient odataClient, final URI uri) {
+  public ODataBatchRequestImpl(final CommonODataClient<?> odataClient, final URI uri) {
     super(odataClient, uri);
   }
 

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/4f1072a6/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/batch/v4/ODataOutsideUpdateImpl.java
----------------------------------------------------------------------
diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/batch/v4/ODataOutsideUpdateImpl.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/batch/v4/ODataOutsideUpdateImpl.java
index 7354590..fd79e0b 100644
--- a/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/batch/v4/ODataOutsideUpdateImpl.java
+++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/batch/v4/ODataOutsideUpdateImpl.java
@@ -22,7 +22,7 @@ import org.apache.olingo.client.api.communication.request.ODataBatchableRequest;
 import org.apache.olingo.client.api.communication.request.batch.CommonODataBatchRequest;
 import org.apache.olingo.client.api.communication.request.batch.v4.ODataOutsideUpdate;
 import org.apache.olingo.client.api.http.HttpMethod;
-import org.apache.olingo.client.core.communication.request.ODataRequestImpl;
+import org.apache.olingo.client.core.communication.request.AbstractODataRequest;
 import org.apache.olingo.client.core.communication.request.batch.AbstractODataBatchRequestItem;
 
 /**
@@ -61,7 +61,7 @@ public class ODataOutsideUpdateImpl extends AbstractODataBatchRequestItem
       throw new IllegalStateException("Current batch item is closed");
     }
 
-    if (((ODataRequestImpl) request).getMethod() == HttpMethod.GET) {
+    if (((AbstractODataRequest) request).getMethod() == HttpMethod.GET) {
       throw new IllegalArgumentException("Invalid request. Use ODataRetrieve for GET method");
     }
 
@@ -77,7 +77,7 @@ public class ODataOutsideUpdateImpl extends AbstractODataBatchRequestItem
 
     // add request to the list
     expectedResItem.addResponse(
-            ODataOutsideUpdateResponseItem.OUTSIDE_CONTENT_ID, ((ODataRequestImpl) request).getResponseTemplate());
+            ODataOutsideUpdateResponseItem.OUTSIDE_CONTENT_ID, ((AbstractODataRequest) request).getResponseTemplate());
 
     return this;
   }