This repository has been archived by the owner on Sep 16, 2023. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 18
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
docs(sample): Add sample for Native Image Support (#711)
* docs(sample): Add sample for Native Image Support * 🦉 Updates from OwlBot post-processor See https://github.com/googleapis/repo-automation-bots/blob/main/packages/owl-bot/README.md * fix setup for standard java mmode * 🦉 Updates from OwlBot post-processor See https://github.com/googleapis/repo-automation-bots/blob/main/packages/owl-bot/README.md * use Java 8; clean up integration test Co-authored-by: Owl Bot <gcf-owl-bot[bot]@users.noreply.github.com>
- Loading branch information
1 parent
36899d2
commit 1afd3aa
Showing
6 changed files
with
435 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,78 @@ | ||
# Secret Manager Sample Application with Native Image | ||
|
||
The Secret Manager sample application demonstrates some common operations with [Google Cloud Secret Manager](https://cloud.google.com/secret-manager) and is compatible with Native Image compilation. | ||
|
||
This application will create a new secret named `native-secretmanager-test-secret` if it does not already exist. | ||
It will then add a new version of the secret and then attempt to read it. | ||
|
||
## Setup Instructions | ||
|
||
You will need to follow these prerequisite steps in order to run these samples: | ||
|
||
1. If you have not already, [create a Google Cloud Platform Project](https://cloud.google.com/resource-manager/docs/creating-managing-projects#creating_a_project). | ||
|
||
2. Install the [Google Cloud SDK](https://cloud.google.com/sdk/) which will allow you to run the sample with your project's credentials. | ||
|
||
Once installed, log in with Application Default Credentials using the following command: | ||
|
||
``` | ||
gcloud auth application-default login | ||
``` | ||
**Note:** Authenticating with Application Default Credentials is convenient to use during development, but we recommend [alternate methods of authentication](https://cloud.google.com/docs/authentication/production) during production use. | ||
3. Install the GraalVM compiler. | ||
You can follow the [official installation instructions](https://www.graalvm.org/docs/getting-started/#install-graalvm) from the GraalVM website. | ||
After following the instructions, ensure that you install the Native Image extension installed by running: | ||
``` | ||
gu install native-image | ||
``` | ||
Once you finish following the instructions, verify that the default version of Java is set to the GraalVM version by running `java -version` in a terminal. | ||
You will see something similar to the below output: | ||
``` | ||
$ java -version | ||
openjdk version "11.0.7" 2020-04-14 | ||
OpenJDK Runtime Environment GraalVM CE 20.1.0 (build 11.0.7+10-jvmci-20.1-b02) | ||
OpenJDK 64-Bit Server VM GraalVM CE 20.1.0 (build 11.0.7+10-jvmci-20.1-b02, mixed mode, sharing) | ||
``` | ||
4. [Enable the Secret Manager APIs](https://console.cloud.google.com/apis/api/secretmanager.googleapis.com). | ||
### Run with Native Image Compilation | ||
Navigate to this directory in a new terminal. | ||
1. Compile the application using the Native Image Compiler. This step may take a few minutes. | ||
``` | ||
mvn package -P native -DskipTests | ||
``` | ||
2. Run the application: | ||
``` | ||
./target/native-image-sample | ||
``` | ||
3. The application runs through some basic Secret Manager operations (create, update, read) and then prints some results of the operations. | ||
``` | ||
Created secret: projects/xxxxxx/secrets/graal-secretmanager-test-secret | ||
Added Secret Version: projects/xxxxxx/secrets/graal-secretmanager-test-secret/versions/1 | ||
Reading secret value: Hello World | ||
(Note: Don't print secret values in prod!) | ||
``` | ||
## Sample Integration test with Native Image Support | ||
In order to run the sample integration test as a native image, call the following command: | ||
``` | ||
mvn test -Pnative | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,173 @@ | ||
<?xml version='1.0' encoding='UTF-8'?> | ||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> | ||
<modelVersion>4.0.0</modelVersion> | ||
<groupId>com.google.cloud</groupId> | ||
<artifactId>native-image-sample</artifactId> | ||
<name>Native Image Sample</name> | ||
<url>https://github.com/googleapis/java-secretmanager</url> | ||
|
||
<!-- | ||
The parent pom defines common style checks and testing strategies for our samples. | ||
Removing or replacing it should not affect the execution of the samples in anyway. | ||
--> | ||
<parent> | ||
<groupId>com.google.cloud.samples</groupId> | ||
<artifactId>shared-configuration</artifactId> | ||
<version>1.2.0</version> | ||
</parent> | ||
|
||
<properties> | ||
<!-- Java 8 because the Kokoro Sample test uses that Java version --> | ||
<maven.compiler.target>1.8</maven.compiler.target> | ||
<maven.compiler.source>1.8</maven.compiler.source> | ||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> | ||
</properties> | ||
|
||
<dependencyManagement> | ||
<dependencies> | ||
<dependency> | ||
<groupId>com.google.cloud</groupId> | ||
<artifactId>libraries-bom</artifactId> | ||
<version>24.3.0</version> | ||
<type>pom</type> | ||
<scope>import</scope> | ||
</dependency> | ||
</dependencies> | ||
</dependencyManagement> | ||
|
||
<dependencies> | ||
<dependency> | ||
<groupId>com.google.cloud</groupId> | ||
<artifactId>google-cloud-core</artifactId> | ||
</dependency> | ||
<dependency> | ||
<groupId>com.google.cloud</groupId> | ||
<artifactId>google-cloud-secretmanager</artifactId> | ||
</dependency> | ||
|
||
<dependency> | ||
<groupId>junit</groupId> | ||
<artifactId>junit</artifactId> | ||
<version>4.13.2</version> | ||
<scope>test</scope> | ||
</dependency> | ||
<dependency> | ||
<groupId>com.google.truth</groupId> | ||
<artifactId>truth</artifactId> | ||
<version>1.1.3</version> | ||
<scope>test</scope> | ||
</dependency> | ||
</dependencies> | ||
|
||
<build> | ||
<!-- This plugin enables building the application to a JAR *not* using Native Image --> | ||
<plugins> | ||
<plugin> | ||
<groupId>org.apache.maven.plugins</groupId> | ||
<artifactId>maven-jar-plugin</artifactId> | ||
<version>3.2.2</version> | ||
<configuration> | ||
<archive> | ||
<manifest> | ||
<addClasspath>true</addClasspath> | ||
<classpathPrefix>dependency-jars/</classpathPrefix> | ||
<mainClass>secretmanager.NativeImageSecretManagerSample</mainClass> | ||
</manifest> | ||
</archive> | ||
</configuration> | ||
</plugin> | ||
<plugin> | ||
<groupId>org.apache.maven.plugins</groupId> | ||
<artifactId>maven-dependency-plugin</artifactId> | ||
<version>3.2.0</version> | ||
<executions> | ||
<execution> | ||
<id>copy-dependencies</id> | ||
<phase>package</phase> | ||
<goals> | ||
<goal>copy-dependencies</goal> | ||
</goals> | ||
<configuration> | ||
<outputDirectory> | ||
${project.build.directory}/dependency-jars/ | ||
</outputDirectory> | ||
</configuration> | ||
</execution> | ||
</executions> | ||
</plugin> | ||
</plugins> | ||
</build> | ||
|
||
<!-- Native Profile--> | ||
<profiles> | ||
<profile> | ||
<id>native</id> | ||
|
||
<dependencies> | ||
<dependency> | ||
<groupId>com.google.cloud</groupId> | ||
<artifactId>native-image-support</artifactId> | ||
<version>0.12.0</version> | ||
</dependency> | ||
<dependency> | ||
<groupId>org.junit.vintage</groupId> | ||
<artifactId>junit-vintage-engine</artifactId> | ||
<version>5.8.2</version> | ||
<scope>test</scope> | ||
</dependency> | ||
<dependency> | ||
<groupId>org.graalvm.buildtools</groupId> | ||
<artifactId>junit-platform-native</artifactId> | ||
<version>0.9.9</version> | ||
<scope>test</scope> | ||
</dependency> | ||
</dependencies> | ||
|
||
<build> | ||
<plugins> | ||
<plugin> | ||
<groupId>org.apache.maven.plugins</groupId> | ||
<artifactId>maven-surefire-plugin | ||
</artifactId> <!-- Must use older version of surefire plugin for native-image testing. --> | ||
<version>2.22.2</version> | ||
<configuration> | ||
<includes> | ||
<include>**/*IT</include> | ||
</includes> | ||
</configuration> | ||
</plugin> | ||
<plugin> | ||
<groupId>org.graalvm.buildtools</groupId> | ||
<artifactId>native-maven-plugin</artifactId> | ||
<version>0.9.9</version> | ||
<extensions>true</extensions> | ||
<configuration> | ||
<mainClass>secretmanager.NativeImageSecretManagerSample</mainClass> | ||
<buildArgs> | ||
<buildArg>--no-fallback</buildArg> | ||
<buildArg>--no-server</buildArg> | ||
</buildArgs> | ||
</configuration> | ||
<executions> | ||
<execution> | ||
<id>build-native</id> | ||
<goals> | ||
<goal>build</goal> | ||
<goal>test</goal> | ||
</goals> | ||
<phase>package</phase> | ||
</execution> | ||
<execution> | ||
<id>test-native</id> | ||
<goals> | ||
<goal>test</goal> | ||
</goals> | ||
<phase>test</phase> | ||
</execution> | ||
</executions> | ||
</plugin> | ||
</plugins> | ||
</build> | ||
</profile> | ||
</profiles> | ||
</project> |
112 changes: 112 additions & 0 deletions
112
samples/native-image-sample/src/main/java/secretmanager/NativeImageSecretManagerSample.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,112 @@ | ||
/* | ||
* Copyright 2022 Google LLC | ||
* | ||
* 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 | ||
* | ||
* https://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 secretmanager; | ||
|
||
import com.google.cloud.ServiceOptions; | ||
import com.google.cloud.secretmanager.v1.AccessSecretVersionResponse; | ||
import com.google.cloud.secretmanager.v1.ProjectName; | ||
import com.google.cloud.secretmanager.v1.Replication; | ||
import com.google.cloud.secretmanager.v1.Secret; | ||
import com.google.cloud.secretmanager.v1.SecretManagerServiceClient; | ||
import com.google.cloud.secretmanager.v1.SecretManagerServiceClient.ListSecretsPagedResponse; | ||
import com.google.cloud.secretmanager.v1.SecretName; | ||
import com.google.cloud.secretmanager.v1.SecretPayload; | ||
import com.google.cloud.secretmanager.v1.SecretVersion; | ||
import com.google.protobuf.ByteString; | ||
import java.io.IOException; | ||
|
||
/** | ||
* Sample application demonstrating Native Image compatibility with Google Cloud Secret Manager | ||
* APIs. | ||
*/ | ||
public class NativeImageSecretManagerSample { | ||
|
||
private static final String NATIVE_TEST_SECRET_ID = "native-secretmanager-test-secret"; | ||
|
||
/** Runs the Secret Manager sample application. */ | ||
public static void main(String[] args) throws IOException { | ||
String projectId = ServiceOptions.getDefaultProjectId(); | ||
|
||
try (SecretManagerServiceClient client = SecretManagerServiceClient.create()) { | ||
if (!hasSecret(client, projectId, NATIVE_TEST_SECRET_ID)) { | ||
createSecret(client, projectId, NATIVE_TEST_SECRET_ID); | ||
} else { | ||
System.out.println("Project already has secret: " + NATIVE_TEST_SECRET_ID); | ||
} | ||
|
||
SecretVersion version = addSecretVersion(client, projectId, NATIVE_TEST_SECRET_ID); | ||
printSecretVersion(client, version); | ||
} | ||
} | ||
|
||
static void createSecret(SecretManagerServiceClient client, String projectId, String secretId) { | ||
|
||
Secret secret = | ||
Secret.newBuilder() | ||
.setReplication( | ||
Replication.newBuilder() | ||
.setAutomatic(Replication.Automatic.newBuilder().build()) | ||
.build()) | ||
.build(); | ||
ProjectName projectName = ProjectName.of(projectId); | ||
Secret createdSecret = client.createSecret(projectName, secretId, secret); | ||
System.out.println("Created secret: " + createdSecret.getName()); | ||
} | ||
|
||
static boolean hasSecret(SecretManagerServiceClient client, String projectId, String secretId) { | ||
|
||
ProjectName projectName = ProjectName.of(projectId); | ||
ListSecretsPagedResponse pagedResponse = client.listSecrets(projectName); | ||
|
||
for (Secret secret : pagedResponse.iterateAll()) { | ||
String otherSecretId = extractSecretId(secret); | ||
if (secretId.equals(otherSecretId)) { | ||
return true; | ||
} | ||
} | ||
|
||
return false; | ||
} | ||
|
||
static SecretVersion addSecretVersion( | ||
SecretManagerServiceClient client, String projectId, String secretId) { | ||
|
||
SecretName secretName = SecretName.of(projectId, secretId); | ||
SecretPayload payload = | ||
SecretPayload.newBuilder().setData(ByteString.copyFromUtf8("Hello World")).build(); | ||
|
||
SecretVersion version = client.addSecretVersion(secretName, payload); | ||
System.out.println("Added Secret Version: " + version.getName()); | ||
return version; | ||
} | ||
|
||
static void printSecretVersion(SecretManagerServiceClient client, SecretVersion version) { | ||
AccessSecretVersionResponse response = client.accessSecretVersion(version.getName()); | ||
String payload = response.getPayload().getData().toStringUtf8(); | ||
System.out.println("Reading secret value: " + payload); | ||
System.out.println("(Note: Don't print secret values in prod!)"); | ||
} | ||
|
||
/** | ||
* Returns the secret ID from the fully-qualified secret name which has the format: | ||
* projects/YOUR_PROJECT_ID/secrets/YOUR_SECRET_ID. | ||
*/ | ||
private static String extractSecretId(Secret secret) { | ||
String[] secretNameTokens = secret.getName().split("/"); | ||
return secretNameTokens[secretNameTokens.length - 1]; | ||
} | ||
} |
Oops, something went wrong.