Skip to content

Commit 78136b1

Browse files
committed
feat: add workflows quickstart
Signed-off-by: Grant Timmerman <timmerman+devrel@google.com>
1 parent a0c5a61 commit 78136b1

File tree

5 files changed

+313
-0
lines changed

5 files changed

+313
-0
lines changed

workflows/cloud-client/.gitignore

+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
sa.json
2+
README-tmp.md

workflows/cloud-client/README.md

+40
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
# Cloud Workflows Quickstart
2+
3+
The Workflows quickstart allows you to run a Cloud Workflow from a java program.
4+
5+
## Prerequisites
6+
7+
### Download Maven
8+
9+
To get started, [download][maven-download] and [install][maven-install] it.
10+
11+
[maven]: https://maven.apache.org
12+
[maven-download]: https://maven.apache.org/download.cgi
13+
[maven-install]: https://maven.apache.org/install.html
14+
15+
### Setup
16+
17+
* Create a project with the [Google Cloud Console][cloud-console], and enable
18+
the [Workflows API][workflows-api].
19+
* [Set up][auth] authentication. For
20+
example, from the Cloud Console, create a service account,
21+
download its json credentials file, then set the appropriate environment
22+
variable:
23+
24+
```bash
25+
export GOOGLE_APPLICATION_CREDENTIALS=/path/to/your-project-credentials.json
26+
```
27+
* Build the samples
28+
```
29+
mvn clean package
30+
```
31+
32+
[cloud-console]: https://console.cloud.google.com
33+
[workflows-api]: https://console.cloud.google.com/apis/api/workflows.googleapis.com/overview?project=_
34+
[auth]: https://cloud.google.com/docs/authentication/getting-started
35+
36+
## Snippets
37+
To verify the snippets are running correctly, you can run the tests via:
38+
```
39+
mvn clean verify
40+
```

workflows/cloud-client/pom.xml

+83
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
<!--
2+
Copyright 2018, Google Inc.
3+
Licensed under the Apache License, Version 2.0 (the "License");
4+
you may not use this file except in compliance with the License.
5+
You may obtain a copy of the License at
6+
http://www.apache.org/licenses/LICENSE-2.0
7+
Unless required by applicable law or agreed to in writing, software
8+
distributed under the License is distributed on an "AS IS" BASIS,
9+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10+
See the License for the specific language governing permissions and
11+
limitations under the License.
12+
-->
13+
<project>
14+
<modelVersion>4.0.0</modelVersion>
15+
<groupId>com.example.texttospeech</groupId>
16+
<artifactId>tts-samples</artifactId>
17+
<packaging>jar</packaging>
18+
19+
<!--
20+
The parent pom defines common style checks and testing strategies for our samples.
21+
Removing or replacing it should not affect the execution of the samples in anyway.
22+
-->
23+
<parent>
24+
<groupId>com.google.cloud.samples</groupId>
25+
<artifactId>shared-configuration</artifactId>
26+
<version>1.0.22</version>
27+
</parent>
28+
29+
<properties>
30+
<maven.compiler.target>1.8</maven.compiler.target>
31+
<maven.compiler.source>1.8</maven.compiler.source>
32+
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
33+
</properties>
34+
35+
<!-- [START tts_java_dependencies] -->
36+
<!-- Using libraries-bom to manage versions.
37+
See https://github.com/GoogleCloudPlatform/cloud-opensource-java/wiki/The-Google-Cloud-Platform-Libraries-BOM -->
38+
<dependencyManagement>
39+
<dependencies>
40+
<dependency>
41+
<groupId>com.google.cloud</groupId>
42+
<artifactId>libraries-bom</artifactId>
43+
<version>20.4.0</version>
44+
<type>pom</type>
45+
<scope>import</scope>
46+
</dependency>
47+
</dependencies>
48+
</dependencyManagement>
49+
50+
<dependencies>
51+
<dependency>
52+
<groupId>com.google.cloud</groupId>
53+
<artifactId>google-cloud-texttospeech</artifactId>
54+
</dependency>
55+
<dependency>
56+
<groupId>com.google.cloud</groupId>
57+
<artifactId>google-cloud-workflows</artifactId>
58+
<version>1.0.0</version>
59+
</dependency>
60+
<dependency>
61+
<groupId>com.google.cloud</groupId>
62+
<artifactId>google-cloud-workflow-executions</artifactId>
63+
<version>0.2.1</version>
64+
</dependency>
65+
<!-- [END tts_java_dependencies] -->
66+
67+
<!-- Test dependencies -->
68+
<dependency>
69+
<groupId>junit</groupId>
70+
<artifactId>junit</artifactId>
71+
<version>4.13.2</version>
72+
<scope>test</scope>
73+
</dependency>
74+
<dependency>
75+
<groupId>com.google.truth</groupId>
76+
<artifactId>truth</artifactId>
77+
<version>1.1.2</version>
78+
<scope>test</scope>
79+
</dependency>
80+
<!-- [START tts_java_dependencies] -->
81+
</dependencies>
82+
<!-- [END tts_java_dependencies] -->
83+
</project>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
/*
2+
* Copyright 2021 Google Inc.
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+
* http://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 com.example.workflows;
18+
19+
// [START workflows_api_quickstart]
20+
21+
// Imports the Google Cloud client library
22+
23+
import com.google.cloud.workflows.executions.v1.Execution;
24+
import com.google.cloud.workflows.executions.v1.ExecutionsClient;
25+
import com.google.cloud.workflows.executions.v1.WorkflowName;
26+
27+
/**
28+
* Cloud Workflows API sample. Executes a workflow and waits for results.
29+
* Example usage:
30+
* GOOGLE_CLOUD_PROJECT=myProject \
31+
* mvn package exec:java -Dexec.mainClass='com.example.workflows.WorkflowsQuickstart'
32+
*/
33+
public class WorkflowsQuickstart {
34+
private static final String GOOGLE_CLOUD_PROJECT = System.getenv("GOOGLE_CLOUD_PROJECT");
35+
private static String LOCATION = System.getenv("LOCATION");
36+
private static String WORKFLOW = System.getenv("WORKFLOW");
37+
38+
public static String workflowsQuickstart(String projectId, String location, String workflow) {
39+
// Execute workflow
40+
try (ExecutionsClient workflowExecutionsClient = ExecutionsClient.create()) {
41+
WorkflowName parent = WorkflowName.of(projectId, location, workflow);
42+
Execution initialExecution = Execution.newBuilder().build();
43+
Execution createExecutionRes = workflowExecutionsClient.createExecution(parent, initialExecution);
44+
45+
String executionName = createExecutionRes.getName();
46+
System.out.printf("Created execution: %s\n", executionName);
47+
48+
// Wait for execution to finish, then print results.
49+
boolean executionFinished = false;
50+
long backoffDelay = 1_000; // Start wait with delay of 1,000 ms
51+
System.out.println("Poll for results...");
52+
while (!executionFinished) {
53+
Execution execution = workflowExecutionsClient.getExecution(executionName);
54+
executionFinished = execution.getState() != Execution.State.ACTIVE;
55+
56+
// If we haven't seen the results yet, wait.
57+
if (!executionFinished) {
58+
System.out.println("- Waiting for results");
59+
Thread.sleep(backoffDelay);
60+
backoffDelay *= 2; // Double the delay to provide exponential backoff.
61+
} else {
62+
System.out.printf("Execution finished with state: %s\n", execution.getState().name());
63+
System.out.println(execution.getResult());
64+
return execution.getResult();
65+
}
66+
}
67+
// This return is never reached.
68+
return "";
69+
} catch (Exception e) {
70+
System.out.printf("Error executing workflow: %s\n", e);
71+
return "";
72+
}
73+
}
74+
75+
/**
76+
* Demonstrates using the Workflows API.
77+
*/
78+
public static void main(String... args) {
79+
if (GOOGLE_CLOUD_PROJECT.isEmpty()) System.out.println("GOOGLE_CLOUD_PROJECT is empty");
80+
if (LOCATION == null || LOCATION.isEmpty()) {
81+
LOCATION = "us-central1";
82+
}
83+
if (WORKFLOW == null || WORKFLOW.isEmpty()) {
84+
WORKFLOW = "myFirstWorkflow";
85+
}
86+
workflowsQuickstart(GOOGLE_CLOUD_PROJECT, LOCATION, WORKFLOW);
87+
}
88+
}
89+
// [END workflows_api_quickstart]
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
package com.example.workflows;
2+
3+
import com.google.api.gax.longrunning.OperationFuture;
4+
import com.google.cloud.workflows.v1.OperationMetadata;
5+
import com.google.cloud.workflows.v1.Workflow;
6+
import com.google.cloud.workflows.v1.WorkflowsClient;
7+
import org.junit.BeforeClass;
8+
import org.junit.Test;
9+
10+
import com.google.cloud.workflows.v1.WorkflowName;
11+
import static com.example.workflows.WorkflowsQuickstart.workflowsQuickstart;
12+
import static org.junit.Assert.*;
13+
14+
public class WorkflowsQuickstartTest {
15+
16+
private static String projectId;
17+
private static final String LOCATION_ID = "us-central1";
18+
private static final String WORKFLOW_ID = "myFirstWorkflow";
19+
20+
// Workflow source copied from:
21+
// https://github.com/GoogleCloudPlatform/workflows-samples/blob/main/src/myFirstWorkflow.workflows.yaml
22+
private static final String WORKFLOW_SOURCE = "# Copyright 2020 Google LLC\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n\n# [START workflows_myfirstworkflow]\n- getCurrentTime:\n call: http.get\n args:\n url: https://us-central1-workflowsample.cloudfunctions.net/datetime\n result: currentTime\n- readWikipedia:\n call: http.get\n args:\n url: https://en.wikipedia.org/w/api.php\n query:\n action: opensearch\n search: ${currentTime.body.dayOfTheWeek}\n result: wikiResult\n- returnResult:\n return: ${wikiResult.body[1]}\n# [END workflows_myfirstworkflow]\n";
23+
24+
@BeforeClass
25+
public static void beforeClass() {
26+
final String ENV_GOOGLE_CLOUD_PROJECT = "GOOGLE_CLOUD_PROJECT";
27+
projectId = System.getenv(ENV_GOOGLE_CLOUD_PROJECT);
28+
assertNotNull(
29+
String.format("Environment variable '%s' is required to perform these tests.", ENV_GOOGLE_CLOUD_PROJECT),
30+
projectId);
31+
}
32+
33+
@Test
34+
public void testQuickstart() {
35+
System.out.println("testing!!");
36+
System.out.println("testing!!");
37+
System.out.println("testing!!");
38+
System.out.println("testing!!");
39+
System.out.println("testing!!");
40+
// Deploy the workflow
41+
deployWorkflow(projectId, LOCATION_ID, WORKFLOW_ID);
42+
43+
// Run the workflow we deployed
44+
// String res = workflowsQuickstart(projectId, LOCATION_ID, WORKFLOW_ID);
45+
//
46+
// // A very basic assertion that we have some result.
47+
// assertNotNull("Result should not be null", res);
48+
// assertNotEquals("Result should not be empty", res, "");
49+
}
50+
51+
private boolean deployWorkflow(String projectId, String location, String workflowId) {
52+
// Create a new workflow if it doesn't exist
53+
if (!workflowExists(projectId, location, workflowId)) {
54+
System.out.println("START DEPLOY");
55+
try (WorkflowsClient workflowsClient = WorkflowsClient.create()) {
56+
// Deploy workflow
57+
Workflow workflow = Workflow.newBuilder()
58+
.setName(workflowId)
59+
.setSourceContents(WORKFLOW_SOURCE)
60+
.build();
61+
workflowsClient.createWorkflowAsync(location, workflow, workflowId);
62+
63+
// Wait until workflow is active
64+
Workflow deployedWorkflow = null;
65+
66+
System.out.println("DEPLOY START");
67+
// Wait for the deployment to finish
68+
do {
69+
System.out.println("SLEEP");
70+
deployedWorkflow = workflowsClient.getWorkflow(WorkflowName.newBuilder()
71+
.setProject(projectId)
72+
.setLocation(location)
73+
.setWorkflow(workflowId)
74+
.build());
75+
Thread.sleep(2_000);
76+
} while (deployedWorkflow == null || deployedWorkflow.getState().equals(Workflow.State.ACTIVE));
77+
78+
// Return true if the workflow is now active
79+
return deployedWorkflow.getState() != Workflow.State.ACTIVE;
80+
} catch (Exception e) {
81+
System.out.printf("Error deploying workflow: %s\n", e);
82+
}
83+
}
84+
return false;
85+
}
86+
87+
/**
88+
* Returns true if the workflow exists.
89+
* @return {boolean} True if the workflow exists already.
90+
*/
91+
private boolean workflowExists(String projectId, String location, String workflow) {
92+
try (WorkflowsClient workflowsClient = WorkflowsClient.create()) {
93+
WorkflowName parent = WorkflowName.of(projectId, location, workflow);
94+
return workflowsClient.getWorkflow(parent).getState() == Workflow.State.ACTIVE;
95+
} catch (Exception e) {
96+
return false;
97+
}
98+
}
99+
}

0 commit comments

Comments
 (0)