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
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
## Release (2025-MM-DD)
- `objectstorage`: [v0.1.0](services/objectstorage/CHANGELOG.md#v010)
- Initial onboarding of STACKIT Java SDK for Object storage service
- `serverupdate`: [v0.1.0](services/serverupdate/CHANGELOG.md#v010)
- Initial onboarding of STACKIT Java SDK for Server Update service

## Release (2025-10-29)
- `core`:
Expand Down
6 changes: 6 additions & 0 deletions examples/serverupdate/build.gradle
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
dependencies {
implementation project (':services:serverupdate')
implementation 'com.squareup.okhttp3:okhttp:4.12.0'
}

ext.mainClassName = 'cloud.stackit.sdk.serverupdate.examples.ServerUpdateExample'
Original file line number Diff line number Diff line change
@@ -0,0 +1,242 @@
package cloud.stackit.sdk.serverupdate.examples;

import cloud.stackit.sdk.core.KeyFlowAuthenticator;
import cloud.stackit.sdk.core.config.CoreConfiguration;
import cloud.stackit.sdk.core.exception.ApiException;
import cloud.stackit.sdk.serverupdate.api.ServerUpdateApi;
import cloud.stackit.sdk.serverupdate.model.*;
import java.io.IOException;
import java.net.HttpURLConnection;
import java.time.Duration;
import java.util.Objects;
import java.util.UUID;
import java.util.concurrent.TimeUnit;
import okhttp3.OkHttpClient;

final class ServerUpdateExample {

private ServerUpdateExample() {}

@SuppressWarnings({
"PMD.CyclomaticComplexity",
"PMD.CognitiveComplexity",
"PMD.NPathComplexity",
"PMD.NcssCount",
"PMD.SystemPrintln",
"PMD.AvoidThrowingRawExceptionTypes",
"PMD.AvoidDuplicateLiterals"
})
public static void main(String[] args) throws IOException {
// Credentials are read from the credentialsFile in `~/.stackit/credentials.json` or the env
// STACKIT_SERVICE_ACCOUNT_KEY_PATH / STACKIT_SERVICE_ACCOUNT_KEY
CoreConfiguration configuration = new CoreConfiguration();

OkHttpClient httpClient = new OkHttpClient();
KeyFlowAuthenticator authenticator = new KeyFlowAuthenticator(httpClient, configuration);
httpClient =
httpClient
.newBuilder()
.authenticator(authenticator)
// Some create / update requests may take a few seconds.
// To prevent a timeout, we increase the read timeout to 30 seconds
.readTimeout(Duration.ofSeconds(30))
.build();

ServerUpdateApi serverUpdateApi = new ServerUpdateApi(httpClient, configuration);

// the id of your STACKIT project, read from env var for this example
String projectId = System.getenv("STACKIT_PROJECT_ID");
if (projectId == null || projectId.isEmpty()) {
System.err.println("Environment variable 'STACKIT_PROJECT_ID' not found.");
return;
}

// the region which should be used to interact with serverupdate
String region = "eu01"; // NOPMD

// the id of your STACKIT server, read from env var for this example
String serverId = System.getenv("STACKIT_SERVER_ID");
if (serverId == null || serverId.isEmpty()) {
System.err.println("Environment variable 'STACKIT_SERVER_ID' not found.");
return;
}

try {
/*
* ///////////////////////////////////////////////////////
* // U P D A T E P O L I C I E S //
* ///////////////////////////////////////////////////////
*/
/* fetching all available update policies */
System.out.println("List all available update policies:");
GetUpdatePoliciesResponse listUpdatePolicies =
serverUpdateApi.listUpdatePolicies(projectId);
Objects.requireNonNull(listUpdatePolicies.getItems());
for (UpdatePolicy policy : listUpdatePolicies.getItems()) {
System.out.println("*************************");
System.out.println("* Policy name: " + policy.getName());
System.out.println("* Description: " + policy.getDescription());
System.out.println("* Policy ID: " + policy.getId());
System.out.println("* RRULE: " + policy.getRrule());
System.out.println("* Enabled: " + policy.getEnabled());
System.out.println("* Default: " + policy.getDefault());
}

/*
* ///////////////////////////////////////////////////////
* // U P D A T E E N A B L E M E N T //
* ///////////////////////////////////////////////////////
*/
/* checking if update service is enabled for the server */
System.out.println("\nChecking update service status for the server:");
try {
GetUpdateServiceResponse updateServiceStatus =
serverUpdateApi.getServiceResource(projectId, serverId, region);
Objects.requireNonNull(updateServiceStatus.getEnabled());
System.out.println("* Update service enabled: " + updateServiceStatus.getEnabled());
} catch (ApiException e) {
// If response status is not found, update service is not enabled for the server
if (e.getCode() == HttpURLConnection.HTTP_NOT_FOUND) {
System.out.println("* Update service is not enabled for the server");
System.out.println("* Enabling update service...");
String policyIdString = listUpdatePolicies.getItems().get(0).getId();
Objects.requireNonNull(policyIdString);
UUID policyId = UUID.fromString(policyIdString);
serverUpdateApi.enableServiceResource(
projectId,
serverId,
region,
new EnableServiceResourcePayload().updatePolicyId(policyId));
System.out.println("* Update service successful enabled for the server");
}
}

/*
* ///////////////////////////////////////////////////////
* // U P D A T E S C H E D U L E //
* ///////////////////////////////////////////////////////
*/
/* creating a new nightly update schedule for the server*/
System.out.println("\nCreating a new update schedule:");
UpdateSchedule newSchedule =
serverUpdateApi.createUpdateSchedule(
projectId,
serverId,
region,
new CreateUpdateSchedulePayload()
.name("Nightly 3 AM")
.enabled(true)
.maintenanceWindow(5)
.rrule(
"DTSTART;TZID=Europe/Berlin:20251210T030000 RRULE:FREQ=DAILY;INTERVAL=1"));
System.out.println("* Schedule ID: " + newSchedule.getId());
System.out.println("* Name: " + newSchedule.getName());
System.out.println("* Enabled: " + newSchedule.getEnabled());
System.out.println("* RRULE: " + newSchedule.getRrule());
System.out.println("* Maintenance Window: " + newSchedule.getMaintenanceWindow());

/* updating the created update schedule */
System.out.println("\nUpdating the update schedule:");
UpdateSchedule updatedSchedule =
serverUpdateApi.updateUpdateSchedule(
projectId,
serverId,
newSchedule.getId().toString(),
region,
new UpdateUpdateSchedulePayload()
.name("Nightly 10 PM")
.enabled(false)
.maintenanceWindow(2)
.rrule(
"DTSTART;TZID=Europe/Berlin:20251210T220000 RRULE:FREQ=DAILY;INTERVAL=1"));
System.out.println("* Schedule ID: " + updatedSchedule.getId());
System.out.println("* Name: " + updatedSchedule.getName());
System.out.println("* Enabled: " + updatedSchedule.getEnabled());
System.out.println("* RRULE: " + updatedSchedule.getRrule());
System.out.println("* Maintenance Window: " + updatedSchedule.getMaintenanceWindow());

/* list all available update schedules of the server */
System.out.println("\nList all update schedules");
GetUpdateSchedulesResponse listUpdateSchedules =
serverUpdateApi.listUpdateSchedules(projectId, serverId, region);
Objects.requireNonNull(listUpdateSchedules.getItems());
for (UpdateSchedule schedule : listUpdateSchedules.getItems()) {
System.out.println("*************************");
System.out.println("* Schedule ID: " + schedule.getId());
System.out.println("* Name: " + schedule.getName());
System.out.println("* Enabled: " + schedule.getEnabled());
System.out.println("* RRULE: " + schedule.getRrule());
System.out.println("* Maintenance Window: " + schedule.getMaintenanceWindow());
}

/* deleting the update schedule we created */
System.out.println("\nDeleting update schedule:");
serverUpdateApi.deleteUpdateSchedule(
projectId, serverId, newSchedule.getId().toString(), region);
System.out.println("* Deleted update schedule successful");

/*
* ///////////////////////////////////////////////////////
* // U P D A T E S //
* ///////////////////////////////////////////////////////
*/
/* trigger manually an update of the server */
System.out.println("\nTrigger a server update:");
Update newUpdate =
serverUpdateApi.createUpdate(
projectId,
serverId,
region,
new CreateUpdatePayload()
.backupBeforeUpdate(false)
.maintenanceWindow(11));
System.out.println("* Update status: " + newUpdate.getStatus());

/* wait for the update to complete */
while (Objects.equals(
serverUpdateApi
.getUpdate(projectId, serverId, newUpdate.getId().toString(), region)
.getStatus(),
"running")) {
System.out.println("Waiting for update to complete ...");
TimeUnit.SECONDS.sleep(5);
}
System.out.println("* Update finished");

/* fetch details of the update */
System.out.println("\nUpdate details:");
Update getUpdate =
serverUpdateApi.getUpdate(
projectId, serverId, newUpdate.getId().toString(), region);
System.out.println("* ID: " + getUpdate.getId());
System.out.println("* Status: " + getUpdate.getStatus());
System.out.println("* Installed updates: " + getUpdate.getInstalledUpdates());
System.out.println("* Failed updates: " + getUpdate.getFailedUpdates());
if (getUpdate.getFailReason() != null && !getUpdate.getFailReason().isEmpty()) {
System.out.println("* Fail reason: " + getUpdate.getFailReason());
}
System.out.println("* Start date: " + getUpdate.getStartDate());
System.out.println("* End date: " + getUpdate.getEndDate());

/* list all executed updated */
System.out.println("\nList updates:");
GetUpdatesListResponse listUpdates =
serverUpdateApi.listUpdates(projectId, serverId, region);
Objects.requireNonNull(listUpdates.getItems());
for (Update update : listUpdates.getItems()) {
System.out.println("*************************");
System.out.println("* ID: " + update.getId());
System.out.println("* Status: " + update.getStatus());
System.out.println("* Installed updates: " + update.getInstalledUpdates());
System.out.println("* Failed updates: " + update.getFailedUpdates());
if (update.getFailReason() != null && !update.getFailReason().isEmpty()) {
System.out.println("* Fail reason: " + update.getFailReason());
}
System.out.println("* Start date: " + update.getStartDate());
System.out.println("* End date: " + update.getEndDate());
}
} catch (ApiException | InterruptedException e) {
throw new RuntimeException(e);
}
}
}
2 changes: 2 additions & 0 deletions services/serverupdate/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
## v0.1.0
- Initial onboarding of STACKIT Java SDK for Server Update service
85 changes: 85 additions & 0 deletions services/serverupdate/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
# STACKIT Java SDK for STACKIT Server Update Management API

- API version: 2.0

API endpoints for Server Update Operations on STACKIT Servers.


This package is part of the STACKIT Java SDK. For additional information, please visit the [GitHub repository](https://github.com/stackitcloud/stackit-sdk-java) of the SDK.

## Installation from Maven Central (recommended)

The release artifacts for this SDK submodule are available on [Maven Central](https://central.sonatype.com/artifact/cloud.stackit.sdk/serverupdate).

### Maven users

Add this dependency to your project's POM:

```xml
<dependency>
<groupId>cloud.stackit.sdk</groupId>
<artifactId>serverupdate</artifactId>
<version><SDK_VERSION></version>
<scope>compile</scope>
</dependency>
```

### Gradle users

Add this dependency to your project's build file:

```groovy
repositories {
mavenCentral()
}

dependencies {
implementation "cloud.stackit.sdk:serverupdate:<SDK_VERSION>"
}
```

## Installation from local build

Building the API client library requires:
1. Java SDK (version 11 to 21 should be supported) installed on your system

To install the API client library to your local Maven repository, simply execute:

```shell
./gradlew services:serverupdate:publishToMavenLocal
```

### Maven users

Add this dependency to your project's POM:

```xml
<dependency>
<groupId>cloud.stackit.sdk</groupId>
<artifactId>serverupdate</artifactId>
<version><SDK_VERSION></version>
<scope>compile</scope>
</dependency>
```

### Gradle users

Add this dependency to your project's build file:

```groovy
repositories {
mavenLocal()
}

dependencies {
implementation "cloud.stackit.sdk:serverupdate:<SDK_VERSION>"
}
```

## Getting Started

See the [serverupdate examples](https://github.com/stackitcloud/stackit-sdk-java/tree/main/examples/serverupdate/src/main/java/cloud/stackit/sdk/serverupdate/examples).

## Recommendation

It's recommended to create an instance of `ApiClient` per thread in a multithreaded environment to avoid any potential issues.
1 change: 1 addition & 0 deletions services/serverupdate/VERSION
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
0.1.0
19 changes: 19 additions & 0 deletions services/serverupdate/build.gradle
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@

ext {
jakarta_annotation_version = "1.3.5"
}

dependencies {
implementation "com.google.code.findbugs:jsr305:3.0.2"
implementation 'com.squareup.okhttp3:okhttp:4.12.0'
implementation 'com.squareup.okhttp3:logging-interceptor:4.12.0'
implementation 'com.google.code.gson:gson:2.9.1'
implementation 'io.gsonfire:gson-fire:1.9.0'
implementation 'jakarta.ws.rs:jakarta.ws.rs-api:2.1.6'
implementation 'org.openapitools:jackson-databind-nullable:0.2.6'
implementation group: 'org.apache.commons', name: 'commons-lang3', version: '3.17.0'
implementation "jakarta.annotation:jakarta.annotation-api:$jakarta_annotation_version"
testImplementation 'org.junit.jupiter:junit-jupiter-api:5.10.3'
testImplementation 'org.mockito:mockito-core:3.12.4'
testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.10.3'
}
Loading