Skip to content

Commit

Permalink
Merge commit 'ae4c3ba611076c6d1a2e6fedb6616d5c3b0fdb3d' into exp
Browse files Browse the repository at this point in the history
  • Loading branch information
anuchandy committed Apr 28, 2016
2 parents b6592da + 2a37759 commit d56d5e0
Show file tree
Hide file tree
Showing 11 changed files with 654 additions and 237 deletions.
22 changes: 21 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,22 @@
# autorest-clientruntime-for-java
[![Build Status](https://travis-ci.org/Azure/autorest-clientruntime-for-java.svg?branch=javavnext)](https://travis-ci.org/Azure/autorest-clientruntime-for-java)

# AutoRest Client Runtimes for Java
The runtime libraries for AutoRest generated Java clients.

## Repository structure

### client-runtime
This is the generic runtime. You will need this for AutoRest generated library using Java code generator.

### azure-client-runtime
This is the runtime with Azure specific customizations. You will need this for AutoRest generated library using Azure.Java code generator.

### azure-client-authentication
This package provides access to Active Directory authentication on JDK using OrgId or application ID / secret combinations. Multi-factor-auth is currently not supported.

### azure-android-client-authentication
This package provides access to Active Directory authentication on Android. You can login with Microsoft accounts, OrgId, with or without multi-factor-auth.

## Build
To build this repository, you will need maven 2.0+ and gradle 1.6+.
Maven is used for [Java SDK](https://github.com/Azure/azure-sdk-for-java) when it's used as a submodule in there. Gradle is used for [AutoRest](https://github.com/Azure/autorest) when it's used as a submodule in there.
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,13 @@

package com.microsoft.azure;

import com.microsoft.rest.RestClient;
import com.microsoft.rest.ServiceCall;
import com.microsoft.rest.ServiceCallback;
import com.microsoft.rest.ServiceException;
import com.microsoft.rest.ServiceResponse;
import com.microsoft.rest.ServiceResponseCallback;
import com.microsoft.rest.ServiceResponseWithHeaders;
import com.microsoft.rest.credentials.ServiceClientCredentials;
import com.microsoft.rest.serializer.JacksonMapperAdapter;

import java.io.IOException;
import java.lang.reflect.Type;
Expand All @@ -24,11 +23,9 @@
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

import okhttp3.OkHttpClient;
import okhttp3.ResponseBody;
import retrofit2.Call;
import retrofit2.Response;
import retrofit2.Retrofit;
import retrofit2.http.GET;
import retrofit2.http.Url;

Expand All @@ -42,32 +39,18 @@ public class AzureClient extends AzureServiceClient {
* used if null.
*/
private Integer longRunningOperationRetryTimeout;
/**
* The credentials to use for authentication for long running operations.
*/
private ServiceClientCredentials credentials;
/**
* The executor for asynchronous requests.
*/
private ScheduledExecutorService executor = Executors.newSingleThreadScheduledExecutor();

/**
* Initializes an instance of this class.
*/
public AzureClient() {
super();
}

/**
* Initializes an instance of this class with customized client metadata.
*
* @param clientBuilder customized http client.
* @param retrofitBuilder customized retrofit builder
* @param mapperAdapter the adapter for the Jackson object mapper
* @param restClient the REST client to connect to Azure
*/
public AzureClient(OkHttpClient.Builder clientBuilder, Retrofit.Builder retrofitBuilder, JacksonMapperAdapter mapperAdapter) {
super(clientBuilder, retrofitBuilder);
this.mapperAdapter = mapperAdapter;
public AzureClient(RestClient restClient) {
super(restClient);
}

/**
Expand Down Expand Up @@ -98,13 +81,13 @@ public <T> ServiceResponse<T> getPutOrPatchResult(Response<ResponseBody> respons
CloudException exception = new CloudException(statusCode + " is not a valid polling status code");
exception.setResponse(response);
if (responseBody != null) {
exception.setBody((CloudError) mapperAdapter.deserialize(responseBody.string(), CloudError.class));
exception.setBody((CloudError) restClient().mapperAdapter().deserialize(responseBody.string(), CloudError.class));
responseBody.close();
}
throw exception;
}

PollingState<T> pollingState = new PollingState<>(response, this.getLongRunningOperationRetryTimeout(), resourceType, mapperAdapter);
PollingState<T> pollingState = new PollingState<>(response, this.getLongRunningOperationRetryTimeout(), resourceType, restClient().mapperAdapter());
String url = response.raw().request().url().toString();

// Check provisioning state
Expand Down Expand Up @@ -151,7 +134,7 @@ public <T, THeader> ServiceResponseWithHeaders<T, THeader> getPutOrPatchResultWi
ServiceResponse<T> bodyResponse = getPutOrPatchResult(response, resourceType);
return new ServiceResponseWithHeaders<>(
bodyResponse.getBody(),
mapperAdapter.<THeader>deserialize(mapperAdapter.serialize(bodyResponse.getResponse().headers()), headerType),
restClient().mapperAdapter().<THeader>deserialize(restClient().mapperAdapter().serialize(bodyResponse.getResponse().headers()), headerType),
bodyResponse.getResponse()
);
}
Expand Down Expand Up @@ -186,7 +169,7 @@ public <T> AsyncPollingTask<T> getPutOrPatchResultAsync(Response<ResponseBody> r
exception.setResponse(response);
try {
if (responseBody != null) {
exception.setBody((CloudError) mapperAdapter.deserialize(responseBody.string(), CloudError.class));
exception.setBody((CloudError) restClient().mapperAdapter().deserialize(responseBody.string(), CloudError.class));
responseBody.close();
}
} catch (Exception e) { /* ignore serialization errors on top of service errors */ }
Expand All @@ -196,7 +179,7 @@ public <T> AsyncPollingTask<T> getPutOrPatchResultAsync(Response<ResponseBody> r

PollingState<T> pollingState;
try {
pollingState = new PollingState<>(response, this.getLongRunningOperationRetryTimeout(), resourceType, mapperAdapter);
pollingState = new PollingState<>(response, this.getLongRunningOperationRetryTimeout(), resourceType, restClient().mapperAdapter());
} catch (IOException e) {
callback.failure(e);
return null;
Expand Down Expand Up @@ -235,7 +218,7 @@ public void success(ServiceResponse<T> result) {
try {
callback.success(new ServiceResponseWithHeaders<>(
result.getBody(),
mapperAdapter.<THeader>deserialize(mapperAdapter.serialize(result.getResponse().headers()), headerType),
restClient().mapperAdapter().<THeader>deserialize(restClient().mapperAdapter().serialize(result.getResponse().headers()), headerType),
result.getResponse()
));
} catch (IOException e) {
Expand Down Expand Up @@ -273,13 +256,13 @@ public <T> ServiceResponse<T> getPostOrDeleteResult(Response<ResponseBody> respo
CloudException exception = new CloudException(statusCode + " is not a valid polling status code");
exception.setResponse(response);
if (responseBody != null) {
exception.setBody((CloudError) mapperAdapter.deserialize(responseBody.string(), CloudError.class));
exception.setBody((CloudError) restClient().mapperAdapter().deserialize(responseBody.string(), CloudError.class));
responseBody.close();
}
throw exception;
}

PollingState<T> pollingState = new PollingState<>(response, this.getLongRunningOperationRetryTimeout(), resourceType, mapperAdapter);
PollingState<T> pollingState = new PollingState<>(response, this.getLongRunningOperationRetryTimeout(), resourceType, restClient().mapperAdapter());

// Check provisioning state
while (!AzureAsyncOperation.getTerminalStatuses().contains(pollingState.getStatus())) {
Expand Down Expand Up @@ -325,7 +308,7 @@ public <T, THeader> ServiceResponseWithHeaders<T, THeader> getPostOrDeleteResult
ServiceResponse<T> bodyResponse = getPostOrDeleteResult(response, resourceType);
return new ServiceResponseWithHeaders<>(
bodyResponse.getBody(),
mapperAdapter.<THeader>deserialize(mapperAdapter.serialize(bodyResponse.getResponse().headers()), headerType),
restClient().mapperAdapter().<THeader>deserialize(restClient().mapperAdapter().serialize(bodyResponse.getResponse().headers()), headerType),
bodyResponse.getResponse()
);
}
Expand Down Expand Up @@ -360,7 +343,7 @@ public <T> AsyncPollingTask<T> getPostOrDeleteResultAsync(Response<ResponseBody>
exception.setResponse(response);
try {
if (responseBody != null) {
exception.setBody((CloudError) mapperAdapter.deserialize(responseBody.string(), CloudError.class));
exception.setBody((CloudError) restClient().mapperAdapter().deserialize(responseBody.string(), CloudError.class));
responseBody.close();
}
} catch (Exception e) { /* ignore serialization errors on top of service errors */ }
Expand All @@ -370,7 +353,7 @@ public <T> AsyncPollingTask<T> getPostOrDeleteResultAsync(Response<ResponseBody>

PollingState<T> pollingState;
try {
pollingState = new PollingState<>(response, this.getLongRunningOperationRetryTimeout(), resourceType, mapperAdapter);
pollingState = new PollingState<>(response, this.getLongRunningOperationRetryTimeout(), resourceType, restClient().mapperAdapter());
} catch (IOException e) {
callback.failure(e);
return null;
Expand Down Expand Up @@ -408,7 +391,7 @@ public void success(ServiceResponse<T> result) {
try {
callback.success(new ServiceResponseWithHeaders<>(
result.getBody(),
mapperAdapter.<THeader>deserialize(mapperAdapter.serialize(result.getResponse().headers()), headerType),
restClient().mapperAdapter().<THeader>deserialize(restClient().mapperAdapter().serialize(result.getResponse().headers()), headerType),
result.getResponse()
));
} catch (IOException e) {
Expand Down Expand Up @@ -584,15 +567,15 @@ private <T> void updateStateFromAzureAsyncOperationHeader(PollingState<T> pollin

AzureAsyncOperation body = null;
if (response.body() != null) {
body = mapperAdapter.deserialize(response.body().string(), AzureAsyncOperation.class);
body = restClient().mapperAdapter().deserialize(response.body().string(), AzureAsyncOperation.class);
response.body().close();
}

if (body == null || body.getStatus() == null) {
CloudException exception = new CloudException("no body");
exception.setResponse(response);
if (response.errorBody() != null) {
exception.setBody((CloudError) mapperAdapter.deserialize(response.errorBody().string(), CloudError.class));
exception.setBody((CloudError) restClient().mapperAdapter().deserialize(response.errorBody().string(), CloudError.class));
response.errorBody().close();
}
throw exception;
Expand Down Expand Up @@ -624,14 +607,14 @@ public void success(ServiceResponse<ResponseBody> result) {
try {
AzureAsyncOperation body = null;
if (result.getBody() != null) {
body = mapperAdapter.deserialize(result.getBody().string(), AzureAsyncOperation.class);
body = restClient().mapperAdapter().deserialize(result.getBody().string(), AzureAsyncOperation.class);
result.getBody().close();
}
if (body == null || body.getStatus() == null) {
CloudException exception = new CloudException("no body");
exception.setResponse(result.getResponse());
if (result.getResponse().errorBody() != null) {
exception.setBody((CloudError) mapperAdapter.deserialize(result.getResponse().errorBody().string(), CloudError.class));
exception.setBody((CloudError) restClient().mapperAdapter().deserialize(result.getResponse().errorBody().string(), CloudError.class));
result.getResponse().errorBody().close();
}
failure(exception);
Expand Down Expand Up @@ -663,18 +646,17 @@ private Response<ResponseBody> poll(String url) throws CloudException, IOExcepti
if (port == -1) {
port = endpoint.getDefaultPort();
}
AsyncService service = this.retrofitBuilder
.baseUrl(endpoint.getProtocol() + "://" + endpoint.getHost() + ":" + port).build().create(AsyncService.class);
AsyncService service = restClient().retrofit().create(AsyncService.class);
Response<ResponseBody> response = service.get(endpoint.getFile()).execute();
int statusCode = response.code();
if (statusCode != 200 && statusCode != 201 && statusCode != 202 && statusCode != 204) {
CloudException exception = new CloudException(statusCode + " is not a valid polling status code");
exception.setResponse(response);
if (response.body() != null) {
exception.setBody((CloudError) mapperAdapter.deserialize(response.body().string(), CloudError.class));
exception.setBody((CloudError) restClient().mapperAdapter().deserialize(response.body().string(), CloudError.class));
response.body().close();
} else if (response.errorBody() != null) {
exception.setBody((CloudError) mapperAdapter.deserialize(response.errorBody().string(), CloudError.class));
exception.setBody((CloudError) restClient().mapperAdapter().deserialize(response.errorBody().string(), CloudError.class));
response.errorBody().close();
}
throw exception;
Expand All @@ -701,8 +683,7 @@ private Call<ResponseBody> pollAsync(String url, final ServiceCallback<ResponseB
if (port == -1) {
port = endpoint.getDefaultPort();
}
AsyncService service = this.retrofitBuilder
.baseUrl(endpoint.getProtocol() + "://" + endpoint.getHost() + ":" + port).build().create(AsyncService.class);
AsyncService service = restClient().retrofit().create(AsyncService.class);
Call<ResponseBody> call = service.get(endpoint.getFile());
call.enqueue(new ServiceResponseCallback<ResponseBody>(callback) {
@Override
Expand All @@ -713,10 +694,10 @@ public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response)
CloudException exception = new CloudException(statusCode + " is not a valid polling status code");
exception.setResponse(response);
if (response.body() != null) {
exception.setBody((CloudError) mapperAdapter.deserialize(response.body().string(), CloudError.class));
exception.setBody((CloudError) restClient().mapperAdapter().deserialize(response.body().string(), CloudError.class));
response.body().close();
} else if (response.errorBody() != null) {
exception.setBody((CloudError) mapperAdapter.deserialize(response.errorBody().string(), CloudError.class));
exception.setBody((CloudError) restClient().mapperAdapter().deserialize(response.errorBody().string(), CloudError.class));
response.errorBody().close();
}
callback.failure(exception);
Expand Down Expand Up @@ -749,24 +730,6 @@ public void setLongRunningOperationRetryTimeout(Integer longRunningOperationRetr
this.longRunningOperationRetryTimeout = longRunningOperationRetryTimeout;
}

/**
* Gets the credentials used for authentication.
*
* @return the credentials.
*/
public ServiceClientCredentials getCredentials() {
return credentials;
}

/**
* Sets the credentials used for authentication.
*
* @param credentials the credentials.
*/
public void setCredentials(ServiceClientCredentials credentials) {
this.credentials = credentials;
}

/**
* The Retrofit service used for polling.
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,57 +8,24 @@
package com.microsoft.azure;

import com.microsoft.azure.serializer.AzureJacksonMapperAdapter;
import com.microsoft.rest.RestClient;
import com.microsoft.rest.ServiceClient;
import com.microsoft.rest.UserAgentInterceptor;
import com.microsoft.rest.retry.RetryHandler;

import java.net.CookieManager;
import java.net.CookiePolicy;

import okhttp3.JavaNetCookieJar;
import okhttp3.OkHttpClient;
import retrofit2.Retrofit;

/**
* ServiceClient is the abstraction for accessing REST operations and their payload data types.
*/
public abstract class AzureServiceClient extends ServiceClient {
/**
* Initializes a new instance of the ServiceClient class.
*/
protected AzureServiceClient() {
super();
protected AzureServiceClient(String baseUrl) {
this(new RestClient.Builder(baseUrl)
.withMapperAdapter(new AzureJacksonMapperAdapter()).build());
}

/**
* Initializes a new instance of the ServiceClient class.
*
* @param clientBuilder the builder to build up an OkHttp client
* @param retrofitBuilder the builder to build up a rest adapter
* @param restClient the REST client
*/
protected AzureServiceClient(OkHttpClient.Builder clientBuilder, Retrofit.Builder retrofitBuilder) {
super(clientBuilder, retrofitBuilder);
}

/**
* This method initializes the builders for Http client and Retrofit with common
* behaviors for all service clients.
*/
@Override
protected void initialize() {
// Add retry handler
CookieManager cookieManager = new CookieManager();
cookieManager.setCookiePolicy(CookiePolicy.ACCEPT_ALL);

// Set up OkHttp client
this.clientBuilder = clientBuilder
.cookieJar(new JavaNetCookieJar(cookieManager))
.addInterceptor(new RetryHandler())
.addInterceptor(new UserAgentInterceptor());
// Set up rest adapter
this.mapperAdapter = new AzureJacksonMapperAdapter();
this.retrofitBuilder = retrofitBuilder
.client(clientBuilder.build())
.addConverterFactory(mapperAdapter.getConverterFactory());
protected AzureServiceClient(RestClient restClient) {
super(restClient);
}
}
Loading

0 comments on commit d56d5e0

Please sign in to comment.