Skip to content
This repository was archived by the owner on Sep 16, 2023. It is now read-only.

Commit 1afd3aa

Browse files
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>
1 parent 36899d2 commit 1afd3aa

File tree

6 files changed

+435
-0
lines changed

6 files changed

+435
-0
lines changed

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,7 @@ Samples are in the [`samples/`](https://github.com/googleapis/java-secretmanager
107107

108108
| Sample | Source Code | Try it |
109109
| --------------------------- | --------------------------------- | ------ |
110+
| Native Image Secret Manager Sample | [source code](https://github.com/googleapis/java-secretmanager/blob/main/samples/native-image-sample/src/main/java/secretmanager/NativeImageSecretManagerSample.java) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/java-secretmanager&page=editor&open_in_editor=samples/native-image-sample/src/main/java/secretmanager/NativeImageSecretManagerSample.java) |
110111
| Access Secret Version | [source code](https://github.com/googleapis/java-secretmanager/blob/main/samples/snippets/src/main/java/secretmanager/AccessSecretVersion.java) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/java-secretmanager&page=editor&open_in_editor=samples/snippets/src/main/java/secretmanager/AccessSecretVersion.java) |
111112
| Add Secret Version | [source code](https://github.com/googleapis/java-secretmanager/blob/main/samples/snippets/src/main/java/secretmanager/AddSecretVersion.java) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/java-secretmanager&page=editor&open_in_editor=samples/snippets/src/main/java/secretmanager/AddSecretVersion.java) |
112113
| Create Secret | [source code](https://github.com/googleapis/java-secretmanager/blob/main/samples/snippets/src/main/java/secretmanager/CreateSecret.java) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/java-secretmanager&page=editor&open_in_editor=samples/snippets/src/main/java/secretmanager/CreateSecret.java) |

samples/native-image-sample/README.md

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
# Secret Manager Sample Application with Native Image
2+
3+
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.
4+
5+
This application will create a new secret named `native-secretmanager-test-secret` if it does not already exist.
6+
It will then add a new version of the secret and then attempt to read it.
7+
8+
## Setup Instructions
9+
10+
You will need to follow these prerequisite steps in order to run these samples:
11+
12+
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).
13+
14+
2. Install the [Google Cloud SDK](https://cloud.google.com/sdk/) which will allow you to run the sample with your project's credentials.
15+
16+
Once installed, log in with Application Default Credentials using the following command:
17+
18+
```
19+
gcloud auth application-default login
20+
```
21+
22+
**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.
23+
24+
3. Install the GraalVM compiler.
25+
26+
You can follow the [official installation instructions](https://www.graalvm.org/docs/getting-started/#install-graalvm) from the GraalVM website.
27+
After following the instructions, ensure that you install the Native Image extension installed by running:
28+
29+
```
30+
gu install native-image
31+
```
32+
33+
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.
34+
35+
You will see something similar to the below output:
36+
37+
```
38+
$ java -version
39+
40+
openjdk version "11.0.7" 2020-04-14
41+
OpenJDK Runtime Environment GraalVM CE 20.1.0 (build 11.0.7+10-jvmci-20.1-b02)
42+
OpenJDK 64-Bit Server VM GraalVM CE 20.1.0 (build 11.0.7+10-jvmci-20.1-b02, mixed mode, sharing)
43+
```
44+
45+
4. [Enable the Secret Manager APIs](https://console.cloud.google.com/apis/api/secretmanager.googleapis.com).
46+
47+
### Run with Native Image Compilation
48+
49+
Navigate to this directory in a new terminal.
50+
51+
1. Compile the application using the Native Image Compiler. This step may take a few minutes.
52+
53+
```
54+
mvn package -P native -DskipTests
55+
```
56+
57+
2. Run the application:
58+
59+
```
60+
./target/native-image-sample
61+
```
62+
63+
3. The application runs through some basic Secret Manager operations (create, update, read) and then prints some results of the operations.
64+
65+
```
66+
Created secret: projects/xxxxxx/secrets/graal-secretmanager-test-secret
67+
Added Secret Version: projects/xxxxxx/secrets/graal-secretmanager-test-secret/versions/1
68+
Reading secret value: Hello World
69+
(Note: Don't print secret values in prod!)
70+
```
71+
72+
## Sample Integration test with Native Image Support
73+
74+
In order to run the sample integration test as a native image, call the following command:
75+
76+
```
77+
mvn test -Pnative
78+
```

samples/native-image-sample/pom.xml

Lines changed: 173 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,173 @@
1+
<?xml version='1.0' encoding='UTF-8'?>
2+
<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">
3+
<modelVersion>4.0.0</modelVersion>
4+
<groupId>com.google.cloud</groupId>
5+
<artifactId>native-image-sample</artifactId>
6+
<name>Native Image Sample</name>
7+
<url>https://github.com/googleapis/java-secretmanager</url>
8+
9+
<!--
10+
The parent pom defines common style checks and testing strategies for our samples.
11+
Removing or replacing it should not affect the execution of the samples in anyway.
12+
-->
13+
<parent>
14+
<groupId>com.google.cloud.samples</groupId>
15+
<artifactId>shared-configuration</artifactId>
16+
<version>1.2.0</version>
17+
</parent>
18+
19+
<properties>
20+
<!-- Java 8 because the Kokoro Sample test uses that Java version -->
21+
<maven.compiler.target>1.8</maven.compiler.target>
22+
<maven.compiler.source>1.8</maven.compiler.source>
23+
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
24+
</properties>
25+
26+
<dependencyManagement>
27+
<dependencies>
28+
<dependency>
29+
<groupId>com.google.cloud</groupId>
30+
<artifactId>libraries-bom</artifactId>
31+
<version>24.3.0</version>
32+
<type>pom</type>
33+
<scope>import</scope>
34+
</dependency>
35+
</dependencies>
36+
</dependencyManagement>
37+
38+
<dependencies>
39+
<dependency>
40+
<groupId>com.google.cloud</groupId>
41+
<artifactId>google-cloud-core</artifactId>
42+
</dependency>
43+
<dependency>
44+
<groupId>com.google.cloud</groupId>
45+
<artifactId>google-cloud-secretmanager</artifactId>
46+
</dependency>
47+
48+
<dependency>
49+
<groupId>junit</groupId>
50+
<artifactId>junit</artifactId>
51+
<version>4.13.2</version>
52+
<scope>test</scope>
53+
</dependency>
54+
<dependency>
55+
<groupId>com.google.truth</groupId>
56+
<artifactId>truth</artifactId>
57+
<version>1.1.3</version>
58+
<scope>test</scope>
59+
</dependency>
60+
</dependencies>
61+
62+
<build>
63+
<!-- This plugin enables building the application to a JAR *not* using Native Image -->
64+
<plugins>
65+
<plugin>
66+
<groupId>org.apache.maven.plugins</groupId>
67+
<artifactId>maven-jar-plugin</artifactId>
68+
<version>3.2.2</version>
69+
<configuration>
70+
<archive>
71+
<manifest>
72+
<addClasspath>true</addClasspath>
73+
<classpathPrefix>dependency-jars/</classpathPrefix>
74+
<mainClass>secretmanager.NativeImageSecretManagerSample</mainClass>
75+
</manifest>
76+
</archive>
77+
</configuration>
78+
</plugin>
79+
<plugin>
80+
<groupId>org.apache.maven.plugins</groupId>
81+
<artifactId>maven-dependency-plugin</artifactId>
82+
<version>3.2.0</version>
83+
<executions>
84+
<execution>
85+
<id>copy-dependencies</id>
86+
<phase>package</phase>
87+
<goals>
88+
<goal>copy-dependencies</goal>
89+
</goals>
90+
<configuration>
91+
<outputDirectory>
92+
${project.build.directory}/dependency-jars/
93+
</outputDirectory>
94+
</configuration>
95+
</execution>
96+
</executions>
97+
</plugin>
98+
</plugins>
99+
</build>
100+
101+
<!-- Native Profile-->
102+
<profiles>
103+
<profile>
104+
<id>native</id>
105+
106+
<dependencies>
107+
<dependency>
108+
<groupId>com.google.cloud</groupId>
109+
<artifactId>native-image-support</artifactId>
110+
<version>0.12.0</version>
111+
</dependency>
112+
<dependency>
113+
<groupId>org.junit.vintage</groupId>
114+
<artifactId>junit-vintage-engine</artifactId>
115+
<version>5.8.2</version>
116+
<scope>test</scope>
117+
</dependency>
118+
<dependency>
119+
<groupId>org.graalvm.buildtools</groupId>
120+
<artifactId>junit-platform-native</artifactId>
121+
<version>0.9.9</version>
122+
<scope>test</scope>
123+
</dependency>
124+
</dependencies>
125+
126+
<build>
127+
<plugins>
128+
<plugin>
129+
<groupId>org.apache.maven.plugins</groupId>
130+
<artifactId>maven-surefire-plugin
131+
</artifactId> <!-- Must use older version of surefire plugin for native-image testing. -->
132+
<version>2.22.2</version>
133+
<configuration>
134+
<includes>
135+
<include>**/*IT</include>
136+
</includes>
137+
</configuration>
138+
</plugin>
139+
<plugin>
140+
<groupId>org.graalvm.buildtools</groupId>
141+
<artifactId>native-maven-plugin</artifactId>
142+
<version>0.9.9</version>
143+
<extensions>true</extensions>
144+
<configuration>
145+
<mainClass>secretmanager.NativeImageSecretManagerSample</mainClass>
146+
<buildArgs>
147+
<buildArg>--no-fallback</buildArg>
148+
<buildArg>--no-server</buildArg>
149+
</buildArgs>
150+
</configuration>
151+
<executions>
152+
<execution>
153+
<id>build-native</id>
154+
<goals>
155+
<goal>build</goal>
156+
<goal>test</goal>
157+
</goals>
158+
<phase>package</phase>
159+
</execution>
160+
<execution>
161+
<id>test-native</id>
162+
<goals>
163+
<goal>test</goal>
164+
</goals>
165+
<phase>test</phase>
166+
</execution>
167+
</executions>
168+
</plugin>
169+
</plugins>
170+
</build>
171+
</profile>
172+
</profiles>
173+
</project>
Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
/*
2+
* Copyright 2022 Google LLC
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package secretmanager;
18+
19+
import com.google.cloud.ServiceOptions;
20+
import com.google.cloud.secretmanager.v1.AccessSecretVersionResponse;
21+
import com.google.cloud.secretmanager.v1.ProjectName;
22+
import com.google.cloud.secretmanager.v1.Replication;
23+
import com.google.cloud.secretmanager.v1.Secret;
24+
import com.google.cloud.secretmanager.v1.SecretManagerServiceClient;
25+
import com.google.cloud.secretmanager.v1.SecretManagerServiceClient.ListSecretsPagedResponse;
26+
import com.google.cloud.secretmanager.v1.SecretName;
27+
import com.google.cloud.secretmanager.v1.SecretPayload;
28+
import com.google.cloud.secretmanager.v1.SecretVersion;
29+
import com.google.protobuf.ByteString;
30+
import java.io.IOException;
31+
32+
/**
33+
* Sample application demonstrating Native Image compatibility with Google Cloud Secret Manager
34+
* APIs.
35+
*/
36+
public class NativeImageSecretManagerSample {
37+
38+
private static final String NATIVE_TEST_SECRET_ID = "native-secretmanager-test-secret";
39+
40+
/** Runs the Secret Manager sample application. */
41+
public static void main(String[] args) throws IOException {
42+
String projectId = ServiceOptions.getDefaultProjectId();
43+
44+
try (SecretManagerServiceClient client = SecretManagerServiceClient.create()) {
45+
if (!hasSecret(client, projectId, NATIVE_TEST_SECRET_ID)) {
46+
createSecret(client, projectId, NATIVE_TEST_SECRET_ID);
47+
} else {
48+
System.out.println("Project already has secret: " + NATIVE_TEST_SECRET_ID);
49+
}
50+
51+
SecretVersion version = addSecretVersion(client, projectId, NATIVE_TEST_SECRET_ID);
52+
printSecretVersion(client, version);
53+
}
54+
}
55+
56+
static void createSecret(SecretManagerServiceClient client, String projectId, String secretId) {
57+
58+
Secret secret =
59+
Secret.newBuilder()
60+
.setReplication(
61+
Replication.newBuilder()
62+
.setAutomatic(Replication.Automatic.newBuilder().build())
63+
.build())
64+
.build();
65+
ProjectName projectName = ProjectName.of(projectId);
66+
Secret createdSecret = client.createSecret(projectName, secretId, secret);
67+
System.out.println("Created secret: " + createdSecret.getName());
68+
}
69+
70+
static boolean hasSecret(SecretManagerServiceClient client, String projectId, String secretId) {
71+
72+
ProjectName projectName = ProjectName.of(projectId);
73+
ListSecretsPagedResponse pagedResponse = client.listSecrets(projectName);
74+
75+
for (Secret secret : pagedResponse.iterateAll()) {
76+
String otherSecretId = extractSecretId(secret);
77+
if (secretId.equals(otherSecretId)) {
78+
return true;
79+
}
80+
}
81+
82+
return false;
83+
}
84+
85+
static SecretVersion addSecretVersion(
86+
SecretManagerServiceClient client, String projectId, String secretId) {
87+
88+
SecretName secretName = SecretName.of(projectId, secretId);
89+
SecretPayload payload =
90+
SecretPayload.newBuilder().setData(ByteString.copyFromUtf8("Hello World")).build();
91+
92+
SecretVersion version = client.addSecretVersion(secretName, payload);
93+
System.out.println("Added Secret Version: " + version.getName());
94+
return version;
95+
}
96+
97+
static void printSecretVersion(SecretManagerServiceClient client, SecretVersion version) {
98+
AccessSecretVersionResponse response = client.accessSecretVersion(version.getName());
99+
String payload = response.getPayload().getData().toStringUtf8();
100+
System.out.println("Reading secret value: " + payload);
101+
System.out.println("(Note: Don't print secret values in prod!)");
102+
}
103+
104+
/**
105+
* Returns the secret ID from the fully-qualified secret name which has the format:
106+
* projects/YOUR_PROJECT_ID/secrets/YOUR_SECRET_ID.
107+
*/
108+
private static String extractSecretId(Secret secret) {
109+
String[] secretNameTokens = secret.getName().split("/");
110+
return secretNameTokens[secretNameTokens.length - 1];
111+
}
112+
}

0 commit comments

Comments
 (0)