Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions openapi-generator-config-java.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,3 +18,6 @@ files:
custom/serviceApi.mustache:
templateType: API
destinationFilename: ServiceApi.java
custom/serviceApiTest.mustache:
templateType: APITests
destinationFilename: ServiceApiTest.java
2 changes: 1 addition & 1 deletion scripts/generate-sdk/.openapi-generator-ignore-java
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ gradle/**
# ApiException from core library should be used (avoid multiple ApiException imports in case different services are used at the same time)
**/ApiException.java

# Authentication classes are not required because the KeyFlowAuth is attached as interceptor
# Authentication classes are not required because the KeyFlowAuth is attached as authenticator
**/auth/**

# Service Configuration is not required. It only stores a defaultApiClient
Expand Down
6 changes: 5 additions & 1 deletion scripts/generate-sdk/languages/java.sh
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ generate_java_sdk() {
--git-host "${GIT_HOST}" \
--git-user-id "${GIT_USER_ID}" \
--git-repo-id "${GIT_REPO_ID}" \
--global-property apis,models,modelTests=false,modelDocs=false,apiDocs=false,apiTests=false,supportingFiles \
--global-property apis,models,modelTests=false,modelDocs=false,apiDocs=false,apiTests=true,supportingFiles \
--additional-properties="artifactId=${service},artifactDescription=${SERVICE_DESCRIPTION},invokerPackage=cloud.stackit.sdk.${service},modelPackage=cloud.stackit.sdk.${service}.model,apiPackage=cloud.stackit.sdk.${service}.api,serviceName=${service_pascal_case}" >/dev/null \
--http-user-agent stackit-sdk-java/"${service}" \
--config openapi-generator-config-java.yml
Expand All @@ -129,6 +129,10 @@ generate_java_sdk() {
if [ -f "$api_file" ]; then
mv "$api_file" "${SERVICES_FOLDER}/${service}/src/main/java/cloud/stackit/sdk/${service}/api/${service_pascal_case}Api.java"
fi
api_test_file="${SERVICES_FOLDER}/${service}/src/test/java/cloud/stackit/sdk/${service}/api/DefaultApiTestServiceApiTest.java"
if [ -f "$api_test_file" ]; then
mv "$api_test_file" "${SERVICES_FOLDER}/${service}/src/test/java/cloud/stackit/sdk/${service}/api/${service_pascal_case}ApiTest.java"
fi

# Remove unnecessary files
rm "${SERVICES_FOLDER}/${service}/.openapi-generator-ignore"
Expand Down
90 changes: 61 additions & 29 deletions templates/java/ApiClient.mustache
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ import {{invokerPackage}}.auth.AWS4Auth;
import cloud.stackit.sdk.core.auth.SetupAuth;
import cloud.stackit.sdk.core.config.CoreConfiguration;
import cloud.stackit.sdk.core.exception.ApiException;
import cloud.stackit.sdk.core.KeyFlowAuthenticator;

/**
* <p>ApiClient class.</p>
Expand Down Expand Up @@ -130,50 +131,75 @@ public class ApiClient {
protected JSON json;

protected HttpLoggingInterceptor loggingInterceptor;
protected SetupAuth authenticationInterceptor;

protected CoreConfiguration configuration;

{{#dynamicOperations}}
protected Map<String, ApiOperation> operationLookupMap = new HashMap<>();

{{/dynamicOperations}}
/**
* Basic constructor for ApiClient
{{! BEGIN - Removed ApiClient constructor and replaced it with a custom constructors which create the ApiClient with the CoreConfiguration }}
/**
* Basic constructor for ApiClient.
*
* Not recommended for production use, use the one with the OkHttpClient parameter instead.
*
* @throws IOException thrown when a file can not be found
*/
public ApiClient() throws IOException {
{{! BEGIN - replace basic constructur }}
this(new CoreConfiguration());
{{! END - replace basic constructur }}
this(null, new CoreConfiguration());
}

{{! BEGIN - Removed ApiClient constructor with OkHttpClient as param and replaced it with a custom constructor which creates the ApiClient with the CoreConfiguration }}
/**
* Basic constructor with custom CoreConfiguration
*
* @param config a {@link cloud.stackit.sdk.core.config} object
* @throws IOException thrown when a file can not be found
*/
* Basic constructor for ApiClient
*
* Not recommended for production use, use the one with the OkHttpClient parameter instead.
*
* @param config a {@link cloud.stackit.sdk.core.config.CoreConfiguration} object
* @throws IOException thrown when a file can not be found
*/
public ApiClient(CoreConfiguration config) throws IOException {
this(null, config);
}

/**
* Constructor for ApiClient with OkHttpClient parameter. Recommended for production use.
*
* @param httpClient a OkHttpClient object
* @throws IOException thrown when a file can not be found
*/
public ApiClient(OkHttpClient httpClient) throws IOException {
this(httpClient, new CoreConfiguration());
}

/**
* Constructor for ApiClient with OkHttpClient parameter. Recommended for production use.
*
* @param httpClient a OkHttpClient object
* @param config a {@link cloud.stackit.sdk.core.config.CoreConfiguration} object
* @throws IOException thrown when a file can not be found
*/
public ApiClient(OkHttpClient httpClient, CoreConfiguration config) throws IOException {
init();

if (config.getCustomEndpoint() != null && !config.getCustomEndpoint().trim().isEmpty()) {
basePath = config.getCustomEndpoint();
}
if (config.getDefaultHeader() != null) {
defaultHeaderMap = config.getDefaultHeader();
}
if (config.getCustomEndpoint() != null && !config.getCustomEndpoint().trim().isEmpty()) {
basePath = config.getCustomEndpoint();
}
if (config.getDefaultHeader() != null) {
defaultHeaderMap = config.getDefaultHeader();
}
this.configuration = config;

// Setup AuthHandler
SetupAuth auth;
auth = new SetupAuth(config);
auth.init();
authenticationInterceptor = auth;

initHttpClient();
if (httpClient == null) {
initHttpClient();
KeyFlowAuthenticator authenticator = new KeyFlowAuthenticator(this.httpClient, config);
this.httpClient = this.httpClient.newBuilder().authenticator(authenticator).build();
} else {
// Authorization has to be configured manually in case a custom http client object is passed
this.httpClient = httpClient;
}
}
{{! END - Removed ApiClient constructor with OkHttpClient as param and replaced it with a custom constructor which creates the ApiClient with the CoreConfiguration }}
{{! END - Removed ApiClient constructor and replaced it with a custom constructors which create the ApiClient with the CoreConfiguration }}

{{#hasOAuthMethods}}
{{#oauthMethods}}
Expand Down Expand Up @@ -261,8 +287,6 @@ public class ApiClient {
for (Interceptor interceptor: interceptors) {
builder.addInterceptor(interceptor);
}
// Adds the Authorization header to requests
builder.addInterceptor(authenticationInterceptor.getAuthHandler());
{{#useGzipFeature}}
// Enable gzip request compression
builder.addInterceptor(new GzipRequestInterceptor());
Expand Down Expand Up @@ -334,7 +358,15 @@ public class ApiClient {
return this;
}

{{! remove getter and setter for httpClient because this would configure a client without the authentication interceptor }}
/**
* Get HTTP client
*
* @return An instance of OkHttpClient
*/
public OkHttpClient getHttpClient() {
return httpClient;
}
{{! remove setter for httpClient because this would configure a client without the authentication interceptor }}
{{! if this will be requested in a feature-request, it should be implemented with the core configuration module like in the Go SDK }}

/**
Expand Down
53 changes: 45 additions & 8 deletions templates/java/api.mustache
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ import java.io.InputStream;
{{/supportStreaming}}
import cloud.stackit.sdk.core.config.CoreConfiguration;
import cloud.stackit.sdk.core.exception.ApiException;
import okhttp3.OkHttpClient;

{{#operations}}
// Package-private access to enforce service-specific API usage (DefaultApi => <ServiceName>Api)
Expand All @@ -63,16 +64,52 @@ class {{classname}} {
private String localCustomBaseUrl;

{{! BEGIN - Remove default constructor and replaced with constructor which uses CoreConfiguration }}
public {{classname}}() throws IOException {
this(new CoreConfiguration());
}

public {{classname}}(CoreConfiguration config) throws IOException {
if (config.getCustomEndpoint() != null && !config.getCustomEndpoint().trim().isEmpty()) {
/**
* Basic constructor for DefaultApi
*
* For production use consider using the constructor with the OkHttpClient parameter.
*
* @throws IOException
*/
public DefaultApi() throws IOException {
this(null, new CoreConfiguration());
}

/**
* Basic Constructor for DefaultApi
*
* For production use consider using the constructor with the OkHttpClient parameter.
*
* @param config your STACKIT SDK CoreConfiguration
* @throws IOException
*/
public DefaultApi(CoreConfiguration config) throws IOException {
this(null, config);
}

/**
* Constructor for DefaultApi
*
* @param httpClient OkHttpClient object
* @throws IOException
*/
public DefaultApi(OkHttpClient httpClient) throws IOException {
this(httpClient, new CoreConfiguration());
}

/**
* Constructor for DefaultApi
*
* @param httpClient OkHttpClient object
* @param config your STACKIT SDK CoreConfiguration
* @throws IOException
*/
public DefaultApi(OkHttpClient httpClient, CoreConfiguration config) throws IOException {
if (config.getCustomEndpoint() != null && !config.getCustomEndpoint().trim().isEmpty()) {
localCustomBaseUrl = config.getCustomEndpoint();
}
this.localVarApiClient = new ApiClient(config);
}
this.localVarApiClient = new ApiClient(httpClient, config);
}
{{! END - Remove default constructor and replaced with constructor which uses CoreConfiguration }}

public ApiClient getApiClient() {
Expand Down
59 changes: 59 additions & 0 deletions templates/java/api_test.mustache
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
{{! This template had to be customized because of our changes to the DefaultApi and ApiClient classes }}
{{! Original template: https://github.com/OpenAPITools/openapi-generator/blob/v7.15.0/modules/openapi-generator/src/main/resources/Java/libraries/okhttp-gson/api_test.mustache }}

{{>licenseInfo}}

package {{invokerPackage}};

import cloud.stackit.sdk.core.KeyFlowAuthenticator;
import cloud.stackit.sdk.core.auth.SetupAuth;
import cloud.stackit.sdk.core.config.CoreConfiguration;
import cloud.stackit.sdk.core.utils.TestUtils;
import java.io.IOException;
import okhttp3.Authenticator;
import okhttp3.OkHttpClient;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;

public class DefaultApiTest {
@Test
public void TestCustomHttpClient() throws IOException {
// before
CoreConfiguration conf =
new CoreConfiguration().serviceAccountKey(TestUtils.MOCK_SERVICE_ACCOUNT_KEY);

// when
OkHttpClient httpClient = new OkHttpClient();
ApiClient apiClient = new ApiClient(httpClient, conf);

// then
Assertions.assertEquals(httpClient, apiClient.getHttpClient());
// make sure the http client object is exactly the same object
Assertions.assertSame(httpClient, apiClient.getHttpClient());
}

@Test
public void TestNoCustomHttpClient() throws IOException {
// before
CoreConfiguration conf =
new CoreConfiguration().serviceAccountKey(TestUtils.MOCK_SERVICE_ACCOUNT_KEY);

// when
ApiClient apiClient = new ApiClient(conf);

// then
/*
* verify a fresh OkHttpClient got created which will have the auth header set
* by the {@link cloud.stackit.sdk.core.KeyFlowAuthenticator}
*/
OkHttpClient httpClient = new OkHttpClient();
Authenticator authenticator =
new KeyFlowAuthenticator(httpClient, conf, SetupAuth.setupKeyFlow(conf));
httpClient = httpClient.newBuilder().authenticator(authenticator).build();

Assertions.assertNotNull(apiClient.getHttpClient());
Assertions.assertEquals(
httpClient.authenticator().getClass(),
apiClient.getHttpClient().authenticator().getClass());
}
}
57 changes: 57 additions & 0 deletions templates/java/custom/ApiClientTest.mustache
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
{{>licenseInfo}}

package {{invokerPackage}};

import cloud.stackit.sdk.core.KeyFlowAuthenticator;
import cloud.stackit.sdk.core.auth.SetupAuth;
import cloud.stackit.sdk.core.config.CoreConfiguration;
import cloud.stackit.sdk.core.utils.TestUtils;
import java.io.IOException;
import okhttp3.Authenticator;
import okhttp3.OkHttpClient;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;

/** Tests for ApiClient */
public class ApiClientTest {
@Test
public void TestCustomHttpClient() throws IOException {
// before
CoreConfiguration conf =
new CoreConfiguration().serviceAccountKey(TestUtils.MOCK_SERVICE_ACCOUNT_KEY);

// when
OkHttpClient httpClient = new OkHttpClient();
ApiClient apiClient = new ApiClient(httpClient, conf);

// then
Assertions.assertEquals(httpClient, apiClient.getHttpClient());
// make sure the http client object is exactly the same object
Assertions.assertSame(httpClient, apiClient.getHttpClient());
}

@Test
public void TestNoCustomHttpClient() throws IOException {
// before
CoreConfiguration conf =
new CoreConfiguration().serviceAccountKey(TestUtils.MOCK_SERVICE_ACCOUNT_KEY);

// when
ApiClient apiClient = new ApiClient(conf);

// then
/*
* verify a fresh OkHttpClient got created which will have the auth header set
* by the {@link cloud.stackit.sdk.core.KeyFlowAuthenticator}
*/
OkHttpClient httpClient = new OkHttpClient();
Authenticator authenticator =
new KeyFlowAuthenticator(httpClient, conf, SetupAuth.setupKeyFlow(conf));
httpClient = httpClient.newBuilder().authenticator(authenticator).build();

Assertions.assertNotNull(apiClient.getHttpClient());
Assertions.assertEquals(
httpClient.authenticator().getClass(),
apiClient.getHttpClient().authenticator().getClass());
}
}
Loading
Loading