From 978209e8b6bf7b748374d3781be413ef232fd9ce Mon Sep 17 00:00:00 2001 From: Marcel Jacek Date: Tue, 22 Jul 2025 18:06:11 +0200 Subject: [PATCH 1/8] feat: add java generator --- Makefile | 8 + openapi-generator-config-java.yml | 12 ++ .../.openapi-generator-ignore-java | 6 + scripts/generate-sdk/generate-sdk.sh | 13 +- scripts/generate-sdk/languages/java.sh | 156 ++++++++++++++++++ 5 files changed, 194 insertions(+), 1 deletion(-) create mode 100644 openapi-generator-config-java.yml create mode 100644 scripts/generate-sdk/.openapi-generator-ignore-java create mode 100644 scripts/generate-sdk/languages/java.sh diff --git a/Makefile b/Makefile index dd8ad66..e364e90 100644 --- a/Makefile +++ b/Makefile @@ -17,3 +17,11 @@ download-oas: generate-sdk: @$(SCRIPTS_BASE)/generate-sdk/generate-sdk.sh "$(GIT_HOST)" "$(GIT_USER_ID)" "$(GIT_REPO_ID)" "$(SDK_REPO_URL)" "$(LANGUAGE)" "$(SDK_BRANCH)" +generate-go-sdk: LANGUAGE=go +generate-go-sdk: generate-sdk + +generate-python-sdk: LANGUAGE=python +generate-python-sdk: generate-sdk + +generate-java-sdk: LANGUAGE=java +generate-java-sdk: generate-sdk \ No newline at end of file diff --git a/openapi-generator-config-java.yml b/openapi-generator-config-java.yml new file mode 100644 index 0000000..f8d046b --- /dev/null +++ b/openapi-generator-config-java.yml @@ -0,0 +1,12 @@ +artifactUrl: https://github.com/stackitcloud/stackit-sdk-java +developerName: STACKIT Developer Tools +developerEmail: developer-tools@stackit.cloud +developerOrganization: STACKIT +developerOrganizationUrl: https://www.stackit.de +groupId: cloud.stackit +hideGenerationTimestamp: true +licenseName: Apache License 2.0 +licenseUrl: http://www.apache.org/licenses/ +scmConnection: scm:git@github.com:stackitcloud/stackit-sdk-java.git +scmDeveloperConnection: scm:git@github.com:stackitcloud/stackit-sdk-java.git +scmUrl: https://github.com/stackitcloud/stackit-sdk-java diff --git a/scripts/generate-sdk/.openapi-generator-ignore-java b/scripts/generate-sdk/.openapi-generator-ignore-java new file mode 100644 index 0000000..838d97a --- /dev/null +++ b/scripts/generate-sdk/.openapi-generator-ignore-java @@ -0,0 +1,6 @@ +git_push.sh +.travis.yml +.gitignore +api/openapi.yaml +tox.ini +**/.github/** \ No newline at end of file diff --git a/scripts/generate-sdk/generate-sdk.sh b/scripts/generate-sdk/generate-sdk.sh index aec217b..1b7b374 100755 --- a/scripts/generate-sdk/generate-sdk.sh +++ b/scripts/generate-sdk/generate-sdk.sh @@ -57,6 +57,10 @@ go) GENERATOR_VERSION="v6.6.0" # There are issues with GO SDK generation in version v7 ;; python) +# Renovate: datasource=github-tags depName=OpenAPITools/openapi-generator versioning=semver + GENERATOR_VERSION="v7.14.0" + ;; +java) # Renovate: datasource=github-tags depName=OpenAPITools/openapi-generator versioning=semver GENERATOR_VERSION="v7.14.0" ;; @@ -74,7 +78,7 @@ if [ -e ${jar_path} ] && [ $(java -jar ${jar_path} version) == ${GENERATOR_VERSI else echo "Downloading OpenAPI generator (version ${GENERATOR_VERSION})..." mkdir -p ${GENERATOR_PATH} - wget https://repo1.maven.org/maven2/org/openapitools/openapi-generator-cli/${GENERATOR_VERSION_NUMBER}/openapi-generator-cli-${GENERATOR_VERSION_NUMBER}.jar -O ${jar_path} --quiet + wget https://repo1.maven.org/maven2/org/openapitools/openapi-generator-cli/${GENERATOR_VERSION_NUMBER}/openapi-generator-cli-${GENERATOR_VERSION_NUMBER}.jar -O ${jar_path} --quiet --no-check-certificate echo "Download done." fi @@ -94,6 +98,13 @@ python) # Usage: generate_python_sdk GENERATOR_PATH GIT_HOST GIT_USER_ID [GIT_REPO_ID] [SDK_REPO_URL] [SDK_BRANCH] generate_python_sdk "${jar_path}" "${GIT_HOST}" "${GIT_USER_ID}" "${GIT_REPO_ID}" "${SDK_REPO_URL}" "${SDK_BRANCH}" ;; +java) + echo -e "\n>> Generating the Java SDK..." + + source ${LANGUAGE_GENERATORS_FOLDER_PATH}/${LANGUAGE}.sh + # Usage: generate_java_sdk GENERATOR_PATH GIT_HOST GIT_USER_ID [GIT_REPO_ID] [SDK_REPO_URL] [SDK_BRANCH] + generate_java_sdk "${jar_path}" "${GIT_HOST}" "${GIT_USER_ID}" "${GIT_REPO_ID}" "${SDK_REPO_URL}" "${SDK_BRANCH}" + ;; *) echo "! SDK language not supported." exit 1 diff --git a/scripts/generate-sdk/languages/java.sh b/scripts/generate-sdk/languages/java.sh new file mode 100644 index 0000000..e140162 --- /dev/null +++ b/scripts/generate-sdk/languages/java.sh @@ -0,0 +1,156 @@ +#!/bin/bash +# This script clones the SDK repo and updates it with the generated API modules +# Pre-requisites: Java +set -eo pipefail + +ROOT_DIR=$(git rev-parse --show-toplevel) +SDK_REPO_LOCAL_PATH="${ROOT_DIR}/sdk-repo-updated" + +SERVICES_FOLDER="${SDK_REPO_LOCAL_PATH}/services" + +GENERATOR_LOG_LEVEL="error" # Must be a Java log level (error, warn, info...) + +INCLUDE_SERVICES=("resourcemanager") + +generate_java_sdk() { + # Required parameters + local GENERATOR_JAR_PATH=$1 + local GIT_HOST=$2 + local GIT_USER_ID=$3 + + # Optional parameters + local GIT_REPO_ID=$4 + local SDK_REPO_URL=$5 + local SDK_BRANCH=$6 + + # Check required parameters + if [[ -z ${GIT_HOST} ]]; then + echo "! GIT_HOST not specified." + exit 1 + fi + + if [[ -z ${GIT_USER_ID} ]]; then + echo "! GIT_USER_ID id not specified." + exit 1 + fi + + # Check optional parameters and set defaults if not provided + if [[ -z ${GIT_REPO_ID} ]]; then + echo "GIT_REPO_ID not specified, default will be used." + GIT_REPO_ID="stackit-sdk-java" + fi + + if [[ -z ${SDK_REPO_URL} ]]; then + echo "SDK_REPO_URL not specified, default will be used." + SDK_REPO_URL="https://github.com/stackitcloud/stackit-sdk-java.git" + fi + + # Prepare folders + if [[ ! -d $SERVICES_FOLDER ]]; then + mkdir -p "$SERVICES_FOLDER" + fi + + # Clone SDK repo + if [ -d ${SDK_REPO_LOCAL_PATH} ]; then + echo "Old SDK repo clone was found, it will be removed." + rm -rf ${SDK_REPO_LOCAL_PATH} + fi + git clone --quiet -b ${SDK_BRANCH} ${SDK_REPO_URL} ${SDK_REPO_LOCAL_PATH} + + # Backup of the current state of the SDK services dir (services/) + sdk_services_backup_dir=$(mktemp -d) + if [[ ! ${sdk_services_backup_dir} || -d {sdk_services_backup_dir} ]]; then + echo "! Unable to create temporary directory" + exit 1 + fi + cleanup() { + rm -rf ${sdk_services_backup_dir} + } + cp -a "${SERVICES_FOLDER}/." ${sdk_services_backup_dir} + + # Cleanup after we are done + trap cleanup EXIT + + # Remove old contents of services dir (services/) + rm -rf ${SERVICES_FOLDER} + + # Generate SDK for each service + for service_json in ${ROOT_DIR}/oas/*.json; do + service="${service_json##*/}" + service="${service%.json}" + + # Remove invalid characters to ensure a valid Go pkg name + service="${service//-/}" # remove dashes + service="${service// /}" # remove empty spaces + service="${service//_/}" # remove underscores + service=$(echo "${service}" | tr '[:upper:]' '[:lower:]') # convert upper case letters to lower case + service=$(echo "${service}" | tr -d -c '[:alnum:]') # remove non-alphanumeric characters + + if ! [[ ${INCLUDE_SERVICES[*]} =~ ${service} ]]; then + echo "Skipping not included service ${service}" + continue + fi + + if grep -E "^$service$" ${ROOT_DIR}/blacklist.txt; then + echo "Skipping blacklisted service ${service}" + continue + fi + + echo ">> Generating \"${service}\" service..." + cd ${ROOT_DIR} + + mkdir -p "${SERVICES_FOLDER}/${service}/" + cp "${ROOT_DIR}/scripts/generate-sdk/.openapi-generator-ignore-java" "${SERVICES_FOLDER}/${service}/.openapi-generator-ignore" + + SERVICE_DESCRIPTION=$(cat ${service_json} | jq .info.title --raw-output) + + # Run the generator + java -Dlog.level=${GENERATOR_LOG_LEVEL} -jar ${jar_path} generate \ + --generator-name java \ + --input-spec "${service_json}" \ + --output "${SERVICES_FOLDER}/${service}" \ + --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 \ + --additional-properties=artifactId="stackit-${service}",artifactDescription="${SERVICE_DESCRIPTION}",invokerPackage="cloud.stackit.${service}",modelPackage="cloud.stackit.${service}.model",apiPackage="cloud.stackit.${service}.api" >/dev/null \ + --http-user-agent stackit-sdk-java/"${service}" \ + --config openapi-generator-config-java.yml + + # Remove unnecessary files + rm "${SERVICES_FOLDER}/${service}/.openapi-generator-ignore" + rm -r "${SERVICES_FOLDER}/${service}/.openapi-generator/" + rm "${SERVICES_FOLDER}/${service}/.github/workflows/maven.yml" + + # If the service has a wait package files, move them inside the service folder + if [ -d ${sdk_services_backup_dir}/${service}/src/main/java/cloud/stackit/${service}/wait ]; then + echo "Found ${service} \"wait\" package" + cp -r ${sdk_services_backup_dir}/${service}/src/main/java/cloud/stackit/${service}/wait ${SERVICES_FOLDER}/${service}/src/main/java/cloud/stackit/${service}/wait + fi + + # If the service has a README.md file, move them inside the service folder + if [ -f ${sdk_services_backup_dir}/${service}/README.md ]; then + echo "Found ${service} \"README.md\" file" + cp -r ${sdk_services_backup_dir}/${service}/README.md ${SERVICES_FOLDER}/${service}/README.md + fi + + # If the service has a CHANGELOG file, move it inside the service folder + if [ -f ${sdk_services_backup_dir}/${service}/CHANGELOG.md ]; then + echo "Found ${service} \"CHANGELOG\" file" + cp -r ${sdk_services_backup_dir}/${service}/CHANGELOG.md ${SERVICES_FOLDER}/${service}/CHANGELOG.md + fi + + # If the service has a LICENSE file, move it inside the service folder + if [ -f ${sdk_services_backup_dir}/${service}/LICENSE.md ]; then + echo "Found ${service} \"LICENSE\" file" + cp -r ${sdk_services_backup_dir}/${service}/LICENSE.md ${SERVICES_FOLDER}/${service}/LICENSE.md + fi + + # If the service has a NOTICE file, move it inside the service folder + if [ -f ${sdk_services_backup_dir}/${service}/NOTICE.txt ]; then + echo "Found ${service} \"NOTICE\" file" + cp -r ${sdk_services_backup_dir}/${service}/NOTICE.txt ${SERVICES_FOLDER}/${service}/NOTICE.txt + fi + + done +} From af712f47f1056b7ebc0ab081e8991c6dff1342ab Mon Sep 17 00:00:00 2001 From: Marcel Jacek Date: Thu, 24 Jul 2025 13:37:46 +0200 Subject: [PATCH 2/8] review feedback --- Makefile | 12 ++++++------ openapi-generator-config-java.yml | 25 +++++++++++++------------ scripts/generate-sdk/generate-sdk.sh | 2 +- scripts/generate-sdk/languages/java.sh | 6 ------ 4 files changed, 20 insertions(+), 25 deletions(-) diff --git a/Makefile b/Makefile index e364e90..762fd2f 100644 --- a/Makefile +++ b/Makefile @@ -17,11 +17,11 @@ download-oas: generate-sdk: @$(SCRIPTS_BASE)/generate-sdk/generate-sdk.sh "$(GIT_HOST)" "$(GIT_USER_ID)" "$(GIT_REPO_ID)" "$(SDK_REPO_URL)" "$(LANGUAGE)" "$(SDK_BRANCH)" -generate-go-sdk: LANGUAGE=go -generate-go-sdk: generate-sdk +generate-go-sdk: + @$(SCRIPTS_BASE)/generate-sdk/generate-sdk.sh "$(GIT_HOST)" "$(GIT_USER_ID)" "$(GIT_REPO_ID)" "$(SDK_REPO_URL)" "go" "$(SDK_BRANCH)" -generate-python-sdk: LANGUAGE=python -generate-python-sdk: generate-sdk +generate-python-sdk: + @$(SCRIPTS_BASE)/generate-sdk/generate-sdk.sh "$(GIT_HOST)" "$(GIT_USER_ID)" "$(GIT_REPO_ID)" "$(SDK_REPO_URL)" "python" "$(SDK_BRANCH)" -generate-java-sdk: LANGUAGE=java -generate-java-sdk: generate-sdk \ No newline at end of file +generate-java-sdk: + @$(SCRIPTS_BASE)/generate-sdk/generate-sdk.sh "$(GIT_HOST)" "$(GIT_USER_ID)" "$(GIT_REPO_ID)" "$(SDK_REPO_URL)" "java" "$(SDK_BRANCH)" \ No newline at end of file diff --git a/openapi-generator-config-java.yml b/openapi-generator-config-java.yml index f8d046b..45f3aab 100644 --- a/openapi-generator-config-java.yml +++ b/openapi-generator-config-java.yml @@ -1,12 +1,13 @@ -artifactUrl: https://github.com/stackitcloud/stackit-sdk-java -developerName: STACKIT Developer Tools -developerEmail: developer-tools@stackit.cloud -developerOrganization: STACKIT -developerOrganizationUrl: https://www.stackit.de -groupId: cloud.stackit -hideGenerationTimestamp: true -licenseName: Apache License 2.0 -licenseUrl: http://www.apache.org/licenses/ -scmConnection: scm:git@github.com:stackitcloud/stackit-sdk-java.git -scmDeveloperConnection: scm:git@github.com:stackitcloud/stackit-sdk-java.git -scmUrl: https://github.com/stackitcloud/stackit-sdk-java +additionalProperties: + artifactUrl: https://github.com/stackitcloud/stackit-sdk-java + developerName: STACKIT Developer Tools + developerEmail: developer-tools@stackit.cloud + developerOrganization: STACKIT + developerOrganizationUrl: https://www.stackit.de + groupId: cloud.stackit + hideGenerationTimestamp: true + licenseName: Apache License 2.0 + licenseUrl: http://www.apache.org/licenses/ + scmConnection: scm:git@github.com:stackitcloud/stackit-sdk-java.git + scmDeveloperConnection: scm:git@github.com:stackitcloud/stackit-sdk-java.git + scmUrl: https://github.com/stackitcloud/stackit-sdk-java \ No newline at end of file diff --git a/scripts/generate-sdk/generate-sdk.sh b/scripts/generate-sdk/generate-sdk.sh index 1b7b374..7d45bef 100755 --- a/scripts/generate-sdk/generate-sdk.sh +++ b/scripts/generate-sdk/generate-sdk.sh @@ -78,7 +78,7 @@ if [ -e ${jar_path} ] && [ $(java -jar ${jar_path} version) == ${GENERATOR_VERSI else echo "Downloading OpenAPI generator (version ${GENERATOR_VERSION})..." mkdir -p ${GENERATOR_PATH} - wget https://repo1.maven.org/maven2/org/openapitools/openapi-generator-cli/${GENERATOR_VERSION_NUMBER}/openapi-generator-cli-${GENERATOR_VERSION_NUMBER}.jar -O ${jar_path} --quiet --no-check-certificate + wget https://repo1.maven.org/maven2/org/openapitools/openapi-generator-cli/${GENERATOR_VERSION_NUMBER}/openapi-generator-cli-${GENERATOR_VERSION_NUMBER}.jar -O ${jar_path} --quiet echo "Download done." fi diff --git a/scripts/generate-sdk/languages/java.sh b/scripts/generate-sdk/languages/java.sh index e140162..7b21ab3 100644 --- a/scripts/generate-sdk/languages/java.sh +++ b/scripts/generate-sdk/languages/java.sh @@ -122,12 +122,6 @@ generate_java_sdk() { rm -r "${SERVICES_FOLDER}/${service}/.openapi-generator/" rm "${SERVICES_FOLDER}/${service}/.github/workflows/maven.yml" - # If the service has a wait package files, move them inside the service folder - if [ -d ${sdk_services_backup_dir}/${service}/src/main/java/cloud/stackit/${service}/wait ]; then - echo "Found ${service} \"wait\" package" - cp -r ${sdk_services_backup_dir}/${service}/src/main/java/cloud/stackit/${service}/wait ${SERVICES_FOLDER}/${service}/src/main/java/cloud/stackit/${service}/wait - fi - # If the service has a README.md file, move them inside the service folder if [ -f ${sdk_services_backup_dir}/${service}/README.md ]; then echo "Found ${service} \"README.md\" file" From f52a7b5e7f91a4cd543963dd5f674fef04487ee6 Mon Sep 17 00:00:00 2001 From: Marcel Jacek Date: Thu, 24 Jul 2025 15:35:18 +0200 Subject: [PATCH 3/8] adjust generator config - add custom README.mustache --- openapi-generator-config-java.yml | 1 + .../.openapi-generator-ignore-java | 3 +- scripts/generate-sdk/languages/java.sh | 4 +- templates/java/README.md | 14 ++ templates/java/README.mustache | 203 ++++++++++++++++++ 5 files changed, 222 insertions(+), 3 deletions(-) create mode 100644 templates/java/README.md create mode 100644 templates/java/README.mustache diff --git a/openapi-generator-config-java.yml b/openapi-generator-config-java.yml index 45f3aab..19e3ae0 100644 --- a/openapi-generator-config-java.yml +++ b/openapi-generator-config-java.yml @@ -1,3 +1,4 @@ +templateDir: templates/java additionalProperties: artifactUrl: https://github.com/stackitcloud/stackit-sdk-java developerName: STACKIT Developer Tools diff --git a/scripts/generate-sdk/.openapi-generator-ignore-java b/scripts/generate-sdk/.openapi-generator-ignore-java index 838d97a..423b99d 100644 --- a/scripts/generate-sdk/.openapi-generator-ignore-java +++ b/scripts/generate-sdk/.openapi-generator-ignore-java @@ -3,4 +3,5 @@ git_push.sh .gitignore api/openapi.yaml tox.ini -**/.github/** \ No newline at end of file +**/.github/** +**/AndroidManifest.xml \ No newline at end of file diff --git a/scripts/generate-sdk/languages/java.sh b/scripts/generate-sdk/languages/java.sh index 7b21ab3..373eb91 100644 --- a/scripts/generate-sdk/languages/java.sh +++ b/scripts/generate-sdk/languages/java.sh @@ -112,8 +112,8 @@ 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 \ - --additional-properties=artifactId="stackit-${service}",artifactDescription="${SERVICE_DESCRIPTION}",invokerPackage="cloud.stackit.${service}",modelPackage="cloud.stackit.${service}.model",apiPackage="cloud.stackit.${service}.api" >/dev/null \ + --global-property apis,models,modelTests=false,apiTests=false,supportingFiles \ + --additional-properties=artifactId="stackit-sdk-${service}",artifactDescription="${SERVICE_DESCRIPTION}",invokerPackage="cloud.stackit.sdk.${service}",modelPackage="cloud.stackit.sdk.${service}.model",apiPackage="cloud.stackit.sdk.${service}.api" >/dev/null \ --http-user-agent stackit-sdk-java/"${service}" \ --config openapi-generator-config-java.yml diff --git a/templates/java/README.md b/templates/java/README.md new file mode 100644 index 0000000..75f1b25 --- /dev/null +++ b/templates/java/README.md @@ -0,0 +1,14 @@ +# Java templates + +This folder contains only our customized Java templates. Beside these customized templates, +the original templates of openapi-generator for Java are used. These can be found in the +official GitHub repo of the [openapi-generator](https://github.com/OpenAPITools/openapi-generator/tree/v7.14.0/modules/openapi-generator/src/main/resources/Java). + +If you need to change something in the Java Generator, try always first to add +[user-defined templates](https://openapi-generator.tech/docs/customization#user-defined-templates), +instead of overwriting existing templates. These ensure an easier upgrade process, to newer +versions of the openapi-generator. + +If it's required to customize the original templates, you can copy them into this directory. +Try to minimize the customization as much as possible, to ensure, that we can easily upgrade +to newer versions in the future. diff --git a/templates/java/README.mustache b/templates/java/README.mustache new file mode 100644 index 0000000..bf85121 --- /dev/null +++ b/templates/java/README.mustache @@ -0,0 +1,203 @@ +# {{artifactId}} + +{{appName}} + +- API version: {{appVersion}} + +{{{appDescriptionWithNewLines}}} + +{{#infoUrl}} +For more information, please visit [{{{infoUrl}}}]({{{infoUrl}}}) +{{/infoUrl}} + +This package is part of the STACKIT Java SDK. For additional information, please visit the [GitHub repository](https://{{gitHost}}/{{{gitUserId}}}/{{{gitRepoId}}}) of the SDK. + + +## Requirements + +Building the API client library requires: + +1. Java 1.8+ +{{#jersey2}} +2. Maven (3.8.3+)/Gradle (7.2+) +{{/jersey2}} +{{^jersey2}} +2. Maven/Gradle +{{/jersey2}} + +## Installation + +To install the API client library to your local Maven repository, simply execute: + +```shell +mvn clean install +``` + +To deploy it to a remote Maven repository instead, configure the settings of the repository and execute: + +```shell +mvn clean deploy +``` + +Refer to the [OSSRH Guide](http://central.sonatype.org/pages/ossrh-guide.html) for more information. + +### Maven users + +Add this dependency to your project's POM: + +```xml + + {{{groupId}}} + {{{artifactId}}} + {{{artifactVersion}}} + compile + +``` + +### Gradle users + +Add this dependency to your project's build file: + +```groovy + repositories { + mavenCentral() // Needed if the '{{{artifactId}}}' jar has been published to maven central. + mavenLocal() // Needed if the '{{{artifactId}}}' jar has been published to the local maven repo. + } + + dependencies { + implementation "{{{groupId}}}:{{{artifactId}}}:{{{artifactVersion}}}" + } +``` + +### Others + +At first generate the JAR by executing: + +```shell +mvn clean package +``` + +Then manually install the following JARs: + +- `target/{{{artifactId}}}-{{{artifactVersion}}}.jar` +- `target/lib/*.jar` + +{{#jersey2}} +## Usage + +To add a HTTP proxy for the API client, use `ClientConfig`: +```java +{{#apiInfo}}{{#apis}}{{#-first}}{{#operations}}{{#operation}}{{#-first}} +import org.glassfish.jersey.apache.connector.ApacheConnectorProvider; +import org.glassfish.jersey.client.ClientConfig; +import org.glassfish.jersey.client.ClientProperties; +import {{{invokerPackage}}}.*; +import {{{package}}}.{{{classname}}}; + +... + +ApiClient defaultClient = Configuration.getDefaultApiClient(); +ClientConfig clientConfig = defaultClient.getClientConfig(); +clientConfig.connectorProvider(new ApacheConnectorProvider()); +clientConfig.property(ClientProperties.PROXY_URI, "http://proxy_url_here"); +clientConfig.property(ClientProperties.PROXY_USERNAME, "proxy_username"); +clientConfig.property(ClientProperties.PROXY_PASSWORD, "proxy_password"); +defaultClient.setClientConfig(clientConfig); + +{{{classname}}} apiInstance = new {{{classname}}}(defaultClient); +{{/-first}}{{/operation}}{{/operations}}{{/-first}}{{/apis}}{{/apiInfo}} +``` + +{{/jersey2}} +## Getting Started + +Please follow the [installation](#installation) instruction and execute the following Java code: + +```java +{{#apiInfo}}{{#apis}}{{#-first}}{{#operations}}{{#operation}}{{#-first}} +import {{{invokerPackage}}}.*; +import {{{invokerPackage}}}.auth.*; +import {{{modelPackage}}}.*; +import {{{package}}}.{{{classname}}}; + +public class {{{classname}}}Example { + + public static void main(String[] args) { + ApiClient defaultClient = Configuration.getDefaultApiClient(); + defaultClient.setBasePath("{{{basePath}}}"); + {{#hasAuthMethods}}{{#authMethods}}{{#isBasic}}{{#isBasicBasic}} + // Configure HTTP basic authorization: {{{name}}} + HttpBasicAuth {{{name}}} = (HttpBasicAuth) defaultClient.getAuthentication("{{{name}}}"); + {{{name}}}.setUsername("YOUR USERNAME"); + {{{name}}}.setPassword("YOUR PASSWORD");{{/isBasicBasic}}{{#isBasicBearer}} + // Configure HTTP bearer authorization: {{{name}}} + HttpBearerAuth {{{name}}} = (HttpBearerAuth) defaultClient.getAuthentication("{{{name}}}"); + {{{name}}}.setBearerToken("BEARER TOKEN");{{/isBasicBearer}}{{/isBasic}}{{#isApiKey}} + // Configure API key authorization: {{{name}}} + ApiKeyAuth {{{name}}} = (ApiKeyAuth) defaultClient.getAuthentication("{{{name}}}"); + {{{name}}}.setApiKey("YOUR API KEY"); + // Uncomment the following line to set a prefix for the API key, e.g. "Token" (defaults to null) + //{{{name}}}.setApiKeyPrefix("Token");{{/isApiKey}}{{#isOAuth}} + // Configure OAuth2 access token for authorization: {{{name}}} + OAuth {{{name}}} = (OAuth) defaultClient.getAuthentication("{{{name}}}"); + {{{name}}}.setAccessToken("YOUR ACCESS TOKEN");{{/isOAuth}}{{#isHttpSignature}} + // Configure HTTP signature authorization: {{{name}}} + HttpSignatureAuth {{{name}}} = (HttpSignatureAuth) defaultClient.getAuthentication("{{{name}}}"); + // All the HTTP signature parameters below should be customized to your environment. + // Configure the keyId + {{{name}}}.setKeyId("YOUR KEY ID"); + // Configure the signature algorithm + {{{name}}}.setSigningAlgorithm(SigningAlgorithm.HS2019); + // Configure the specific cryptographic algorithm + {{{name}}}.setAlgorithm(Algorithm.ECDSA_SHA256); + // Configure the cryptographic algorithm parameters, if applicable + {{{name}}}.setAlgorithmParameterSpec(null); + // Set the cryptographic digest algorithm. + {{{name}}}.setDigestAlgorithm("SHA-256"); + // Set the HTTP headers that should be included in the HTTP signature. + {{{name}}}.setHeaders(Arrays.asList("date", "host")); + // Set the private key used to sign the HTTP messages + {{{name}}}.setPrivateKey();{{/isHttpSignature}} + {{/authMethods}} + {{/hasAuthMethods}} + + {{{classname}}} apiInstance = new {{{classname}}}(defaultClient); + {{#allParams}} + {{{dataType}}} {{{paramName}}} = {{{example}}}; // {{{dataType}}} | {{{description}}} + {{/allParams}} + try { + {{#returnType}}{{{.}}} result = {{/returnType}}apiInstance.{{{operationId}}}({{#allParams}}{{{paramName}}}{{^-last}}, {{/-last}}{{/allParams}});{{#returnType}} + System.out.println(result);{{/returnType}} + } catch (ApiException e) { + System.err.println("Exception when calling {{{classname}}}#{{{operationId}}}"); + System.err.println("Status code: " + e.getCode()); + System.err.println("Reason: " + e.getResponseBody()); + System.err.println("Response headers: " + e.getResponseHeaders()); + e.printStackTrace(); + } + } +} +{{/-first}}{{/operation}}{{/operations}}{{/-first}}{{/apis}}{{/apiInfo}} +``` + +## Documentation for API Endpoints + +All URIs are relative to *{{basePath}}* + +Class | Method | HTTP request | Description +------------ | ------------- | ------------- | ------------- +{{#apiInfo}}{{#apis}}{{#operations}}{{#operation}}*{{classname}}* | [**{{operationId}}**]({{apiDocPath}}{{classname}}.md#{{operationId}}) | **{{httpMethod}}** {{commonPath}}{{path}} | {{summary}} +{{/operation}}{{/operations}}{{/apis}}{{/apiInfo}} + +## Documentation for Models + +{{#models}}{{#model}} - [{{classname}}]({{modelDocPath}}{{classname}}.md) +{{/model}}{{/models}} + + + +## Recommendation + +It's recommended to create an instance of `ApiClient` per thread in a multithreaded environment to avoid any potential issues. + +## Author \ No newline at end of file From 9db79a54d8fc21d8516b4e2169a198d0eff095bf Mon Sep 17 00:00:00 2001 From: Marcel Jacek Date: Thu, 24 Jul 2025 17:14:04 +0200 Subject: [PATCH 4/8] review feedback --- .../.openapi-generator-ignore-java | 3 ++- templates/java/README.mustache | 22 +++++-------------- 2 files changed, 8 insertions(+), 17 deletions(-) diff --git a/scripts/generate-sdk/.openapi-generator-ignore-java b/scripts/generate-sdk/.openapi-generator-ignore-java index 423b99d..9563cf3 100644 --- a/scripts/generate-sdk/.openapi-generator-ignore-java +++ b/scripts/generate-sdk/.openapi-generator-ignore-java @@ -4,4 +4,5 @@ git_push.sh api/openapi.yaml tox.ini **/.github/** -**/AndroidManifest.xml \ No newline at end of file +**/AndroidManifest.xml +pom.xml \ No newline at end of file diff --git a/templates/java/README.mustache b/templates/java/README.mustache index bf85121..6238418 100644 --- a/templates/java/README.mustache +++ b/templates/java/README.mustache @@ -16,27 +16,21 @@ This package is part of the STACKIT Java SDK. For additional information, please ## Requirements Building the API client library requires: - 1. Java 1.8+ -{{#jersey2}} -2. Maven (3.8.3+)/Gradle (7.2+) -{{/jersey2}} -{{^jersey2}} -2. Maven/Gradle -{{/jersey2}} ## Installation To install the API client library to your local Maven repository, simply execute: ```shell -mvn clean install +./gradlew publishToMavenLocal ``` To deploy it to a remote Maven repository instead, configure the settings of the repository and execute: ```shell -mvn clean deploy +# TODO: follow up story +# ./gradlew publishToMavenCentral ``` Refer to the [OSSRH Guide](http://central.sonatype.org/pages/ossrh-guide.html) for more information. @@ -49,7 +43,7 @@ Add this dependency to your project's POM: {{{groupId}}} {{{artifactId}}} - {{{artifactVersion}}} + compile ``` @@ -65,7 +59,7 @@ Add this dependency to your project's build file: } dependencies { - implementation "{{{groupId}}}:{{{artifactId}}}:{{{artifactVersion}}}" + implementation "{{{groupId}}}:{{{artifactId}}}:" } ``` @@ -79,7 +73,7 @@ mvn clean package Then manually install the following JARs: -- `target/{{{artifactId}}}-{{{artifactVersion}}}.jar` +- `target/{{{artifactId}}}-.jar` - `target/lib/*.jar` {{#jersey2}} @@ -194,10 +188,6 @@ Class | Method | HTTP request | Description {{#models}}{{#model}} - [{{classname}}]({{modelDocPath}}{{classname}}.md) {{/model}}{{/models}} - - ## Recommendation It's recommended to create an instance of `ApiClient` per thread in a multithreaded environment to avoid any potential issues. - -## Author \ No newline at end of file From f45a2d913509c1548819f3be81b0ad5756a8aaeb Mon Sep 17 00:00:00 2001 From: Marcel Jacek Date: Fri, 25 Jul 2025 09:57:39 +0200 Subject: [PATCH 5/8] removed generated docs --- scripts/generate-sdk/languages/java.sh | 2 +- templates/java/README.mustache | 14 -------------- 2 files changed, 1 insertion(+), 15 deletions(-) diff --git a/scripts/generate-sdk/languages/java.sh b/scripts/generate-sdk/languages/java.sh index 373eb91..0d09146 100644 --- a/scripts/generate-sdk/languages/java.sh +++ b/scripts/generate-sdk/languages/java.sh @@ -112,7 +112,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,apiTests=false,supportingFiles \ + --global-property apis,models,modelTests=false,modelDocs=false,apiDocs=false,apiTests=false,supportingFiles \ --additional-properties=artifactId="stackit-sdk-${service}",artifactDescription="${SERVICE_DESCRIPTION}",invokerPackage="cloud.stackit.sdk.${service}",modelPackage="cloud.stackit.sdk.${service}.model",apiPackage="cloud.stackit.sdk.${service}.api" >/dev/null \ --http-user-agent stackit-sdk-java/"${service}" \ --config openapi-generator-config-java.yml diff --git a/templates/java/README.mustache b/templates/java/README.mustache index 6238418..f3e06d8 100644 --- a/templates/java/README.mustache +++ b/templates/java/README.mustache @@ -174,20 +174,6 @@ public class {{{classname}}}Example { {{/-first}}{{/operation}}{{/operations}}{{/-first}}{{/apis}}{{/apiInfo}} ``` -## Documentation for API Endpoints - -All URIs are relative to *{{basePath}}* - -Class | Method | HTTP request | Description ------------- | ------------- | ------------- | ------------- -{{#apiInfo}}{{#apis}}{{#operations}}{{#operation}}*{{classname}}* | [**{{operationId}}**]({{apiDocPath}}{{classname}}.md#{{operationId}}) | **{{httpMethod}}** {{commonPath}}{{path}} | {{summary}} -{{/operation}}{{/operations}}{{/apis}}{{/apiInfo}} - -## Documentation for Models - -{{#models}}{{#model}} - [{{classname}}]({{modelDocPath}}{{classname}}.md) -{{/model}}{{/models}} - ## Recommendation It's recommended to create an instance of `ApiClient` per thread in a multithreaded environment to avoid any potential issues. From 3d6c6e5f46dff127f31acd311d027aff764fca28 Mon Sep 17 00:00:00 2001 From: Marcel Jacek Date: Fri, 25 Jul 2025 11:51:26 +0200 Subject: [PATCH 6/8] - remove invalid characters for valid Java package name - copy VERSION file to generated code --- .../.openapi-generator-ignore-java | 3 ++- scripts/generate-sdk/languages/java.sh | 18 ++++++++++++++---- 2 files changed, 16 insertions(+), 5 deletions(-) diff --git a/scripts/generate-sdk/.openapi-generator-ignore-java b/scripts/generate-sdk/.openapi-generator-ignore-java index 9563cf3..653a423 100644 --- a/scripts/generate-sdk/.openapi-generator-ignore-java +++ b/scripts/generate-sdk/.openapi-generator-ignore-java @@ -5,4 +5,5 @@ api/openapi.yaml tox.ini **/.github/** **/AndroidManifest.xml -pom.xml \ No newline at end of file +pom.xml +build.sbt \ No newline at end of file diff --git a/scripts/generate-sdk/languages/java.sh b/scripts/generate-sdk/languages/java.sh index 0d09146..b8b8db4 100644 --- a/scripts/generate-sdk/languages/java.sh +++ b/scripts/generate-sdk/languages/java.sh @@ -79,12 +79,16 @@ generate_java_sdk() { service="${service_json##*/}" service="${service%.json}" - # Remove invalid characters to ensure a valid Go pkg name + # Remove invalid characters to ensure a valid Java pkg name service="${service//-/}" # remove dashes - service="${service// /}" # remove empty spaces - service="${service//_/}" # remove underscores + service="${service// /}" # remove spaces service=$(echo "${service}" | tr '[:upper:]' '[:lower:]') # convert upper case letters to lower case - service=$(echo "${service}" | tr -d -c '[:alnum:]') # remove non-alphanumeric characters + service=$(echo "${service}" | sed 's/[^a-z0-9_]//g') # remove non-alphanumeric (except underscore) + + # Ensure the package name doesn't start with a number + if [[ "${service}" =~ ^[0-9] ]]; then + service="_${service}" # Prepend a valid prefix if it starts with a number + fi if ! [[ ${INCLUDE_SERVICES[*]} =~ ${service} ]]; then echo "Skipping not included service ${service}" @@ -146,5 +150,11 @@ generate_java_sdk() { cp -r ${sdk_services_backup_dir}/${service}/NOTICE.txt ${SERVICES_FOLDER}/${service}/NOTICE.txt fi + # If the service has a VERSION file, move it inside the service folder + if [ -f ${sdk_services_backup_dir}/${service}/VERSION ]; then + echo "Found ${service} \"VERSION\" file" + cp -r ${sdk_services_backup_dir}/${service}/VERSION ${SERVICES_FOLDER}/${service}/VERSION + fi + done } From e674c596e18bee586971455739b44a14174b7de2 Mon Sep 17 00:00:00 2001 From: Marcel Jacek Date: Fri, 25 Jul 2025 12:01:25 +0200 Subject: [PATCH 7/8] update README.md --- README.md | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 72666fd..3a8a083 100644 --- a/README.md +++ b/README.md @@ -13,19 +13,29 @@ If you want to modify script or templates and you can run code locally. Requires `Go 1.21` or higher. 1. Set up the project and tools by running - ``` + ```bash make project-tools ``` 2. Download Open Api Specifications (OAS), that are the input for the SDK generation, by running - ``` + ```bash make download-oas ``` This step needs to be done only at the first start and when OAS updates are present. -3. Run the SDK generation for testing by +3. Run the Go SDK generation for testing by + ```bash + make generate-go-sdk + ``` + The output goes to the `./sdk-repo-updated` folder. + 1. Run the Python SDK generation for testing by + ```bash + make generate-python-sdk ``` - make generate-sdk + The output goes to the `./sdk-repo-updated` folder. + 2. Run the Java SDK generation for testing by + ```bash + make generate-java-sdk ``` - The output goes to the `./sdk` folder. + The output goes to the `./sdk-repo-updated` folder. ## Reporting issues From f5ea0a2123a6e0260b359ebf0088ea84f1367553 Mon Sep 17 00:00:00 2001 From: Marcel Jacek Date: Fri, 25 Jul 2025 13:06:12 +0200 Subject: [PATCH 8/8] removed underscore in package names --- scripts/generate-sdk/languages/java.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/generate-sdk/languages/java.sh b/scripts/generate-sdk/languages/java.sh index b8b8db4..8121cae 100644 --- a/scripts/generate-sdk/languages/java.sh +++ b/scripts/generate-sdk/languages/java.sh @@ -83,7 +83,7 @@ generate_java_sdk() { service="${service//-/}" # remove dashes service="${service// /}" # remove spaces service=$(echo "${service}" | tr '[:upper:]' '[:lower:]') # convert upper case letters to lower case - service=$(echo "${service}" | sed 's/[^a-z0-9_]//g') # remove non-alphanumeric (except underscore) + service=$(echo "${service}" | tr -d -c '[:alnum:]') # remove non-alphanumeric characters # Ensure the package name doesn't start with a number if [[ "${service}" =~ ^[0-9] ]]; then