Skip to content

Commit 8d02be4

Browse files
authored
Merge branch 'main' into shopping-cart-app
2 parents 371226c + 887402f commit 8d02be4

File tree

8 files changed

+235
-4
lines changed

8 files changed

+235
-4
lines changed

README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,8 @@ Each sample demonstrates one feature of the SDK, together with tests.
3232

3333
- [**Dynamic mTLS hello world**](./dynamicmtls): Simple example showing how to refresh mTLS credentials. This allows for credentials to be refreshed without restarting the worker.
3434

35+
- [**Basic apiKey hello world**](./helloworld-apiKey): Simple example of a
36+
Workflow Definition and an Activity Definition using API Key to authenticate with Temporal Cloud.
3537
### API demonstrations
3638

3739
- **Async activity completion**: Example of

early-return/worker/main.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@ func main() {
1919
w := worker.New(c, earlyreturn.TaskQueueName, worker.Options{})
2020

2121
w.RegisterWorkflow(earlyreturn.Workflow)
22+
w.RegisterActivity(earlyreturn.CompleteTransaction)
23+
w.RegisterActivity(earlyreturn.CancelTransaction)
2224

2325
err = w.Run(worker.InterruptCh())
2426
if err != nil {

helloworld-apiKey/README.md

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
### Steps to run this sample:
2+
1) Configure a [Temporal Server](https://github.com/temporalio/samples-go/tree/main/#how-to-use) (such as Temporal Cloud) with apiKey.
3+
4+
2) Run the following command to start the worker
5+
```
6+
go run ./helloworld-apiKey/worker \
7+
-target-host my.namespace.tmprl.cloud:7233 \
8+
-namespace my.namespace \
9+
-api-key CLIENT_API_KEY
10+
```
11+
3) Run the following command to start the example
12+
```
13+
go run ./helloworld-apiKey/starter \
14+
-target-host my.namespace.tmprl.cloud:7233 \
15+
-namespace my.namespace \
16+
-api-key CLIENT_API_KEY
17+
```

helloworld-apiKey/helloworld.go

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
package helloworldapiKey
2+
3+
import (
4+
"context"
5+
"crypto/tls"
6+
"flag"
7+
"fmt"
8+
"os"
9+
"time"
10+
11+
"go.temporal.io/sdk/activity"
12+
"go.temporal.io/sdk/client"
13+
"go.temporal.io/sdk/workflow"
14+
"google.golang.org/grpc"
15+
"google.golang.org/grpc/metadata"
16+
)
17+
18+
// Workflow is a Hello World workflow definition.
19+
func Workflow(ctx workflow.Context, name string) (string, error) {
20+
ao := workflow.ActivityOptions{
21+
StartToCloseTimeout: 10 * time.Second,
22+
}
23+
ctx = workflow.WithActivityOptions(ctx, ao)
24+
25+
logger := workflow.GetLogger(ctx)
26+
logger.Info("HelloWorld workflow started", "name", name)
27+
28+
var result string
29+
err := workflow.ExecuteActivity(ctx, Activity, name).Get(ctx, &result)
30+
if err != nil {
31+
logger.Error("Activity failed.", "Error", err)
32+
return "", err
33+
}
34+
35+
logger.Info("HelloWorld workflow completed.", "result", result)
36+
37+
return result, nil
38+
}
39+
40+
func Activity(ctx context.Context, name string) (string, error) {
41+
logger := activity.GetLogger(ctx)
42+
logger.Info("Activity", "name", name)
43+
return "Hello " + name + "!", nil
44+
}
45+
46+
// ParseClientOptionFlags parses the given arguments into client options. In
47+
// some cases a failure will be returned as an error, in others the process may
48+
// exit with help info.
49+
func ParseClientOptionFlags(args []string) (client.Options, error) {
50+
// Parse args
51+
set := flag.NewFlagSet("hello-world-api-key", flag.ExitOnError)
52+
targetHost := set.String("target-host", "localhost:7233", "Host:port for the server")
53+
namespace := set.String("namespace", "default", "Namespace for the server")
54+
apiKey := set.String("api-key", "", "Optional API key, mutually exclusive with cert/key")
55+
56+
if err := set.Parse(args); err != nil {
57+
return client.Options{}, fmt.Errorf("failed parsing args: %w", err)
58+
}
59+
60+
if *apiKey == "" {
61+
*apiKey = os.Getenv("TEMPORAL_CLIENT_API_KEY")
62+
}
63+
if *apiKey == "" {
64+
return client.Options{}, fmt.Errorf("-api-key or TEMPORAL_CLIENT_API_KEY env is required required")
65+
}
66+
67+
connectionOptions := client.ConnectionOptions{
68+
TLS: &tls.Config{},
69+
DialOptions: []grpc.DialOption{
70+
grpc.WithUnaryInterceptor(
71+
func(ctx context.Context, method string, req any, reply any, cc *grpc.ClientConn, invoker grpc.UnaryInvoker, opts ...grpc.CallOption) error {
72+
return invoker(
73+
metadata.AppendToOutgoingContext(ctx, "temporal-namespace", *namespace),
74+
method,
75+
req,
76+
reply,
77+
cc,
78+
opts...,
79+
)
80+
},
81+
),
82+
},
83+
}
84+
credentials := client.NewAPIKeyStaticCredentials(*apiKey)
85+
86+
return client.Options{
87+
HostPort: *targetHost,
88+
Namespace: *namespace,
89+
ConnectionOptions: connectionOptions,
90+
Credentials: credentials,
91+
}, nil
92+
}
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
package helloworldapiKey
2+
3+
import (
4+
"testing"
5+
6+
"github.com/stretchr/testify/mock"
7+
"github.com/stretchr/testify/require"
8+
"go.temporal.io/sdk/testsuite"
9+
)
10+
11+
func Test_Workflow(t *testing.T) {
12+
testSuite := &testsuite.WorkflowTestSuite{}
13+
env := testSuite.NewTestWorkflowEnvironment()
14+
15+
// Mock activity implementation
16+
env.OnActivity(Activity, mock.Anything, "Temporal").Return("Hello Temporal!", nil)
17+
18+
env.ExecuteWorkflow(Workflow, "Temporal")
19+
20+
require.True(t, env.IsWorkflowCompleted())
21+
require.NoError(t, env.GetWorkflowError())
22+
var result string
23+
require.NoError(t, env.GetWorkflowResult(&result))
24+
require.Equal(t, "Hello Temporal!", result)
25+
}
26+
27+
func Test_Activity(t *testing.T) {
28+
testSuite := &testsuite.WorkflowTestSuite{}
29+
env := testSuite.NewTestActivityEnvironment()
30+
env.RegisterActivity(Activity)
31+
32+
val, err := env.ExecuteActivity(Activity, "World")
33+
require.NoError(t, err)
34+
35+
var res string
36+
require.NoError(t, val.Get(&res))
37+
require.Equal(t, "Hello World!", res)
38+
}

helloworld-apiKey/starter/main.go

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
package main
2+
3+
import (
4+
"context"
5+
"log"
6+
"os"
7+
8+
"github.com/temporalio/samples-go/helloworld-apiKey"
9+
"go.temporal.io/sdk/client"
10+
)
11+
12+
func main() {
13+
// The client is a heavyweight object that should be created once per process.
14+
clientOptions, err := helloworldapiKey.ParseClientOptionFlags(os.Args[1:])
15+
if err != nil {
16+
log.Fatalf("Invalid arguments: %v", err)
17+
}
18+
c, err := client.Dial(clientOptions)
19+
if err != nil {
20+
log.Fatalln("Unable to create client", err)
21+
}
22+
defer c.Close()
23+
24+
workflowOptions := client.StartWorkflowOptions{
25+
ID: "hello_world_workflowID",
26+
TaskQueue: "hello-world-apiKey",
27+
}
28+
29+
we, err := c.ExecuteWorkflow(context.Background(), workflowOptions, helloworldapiKey.Workflow, "Temporal")
30+
if err != nil {
31+
log.Fatalln("Unable to execute workflow", err)
32+
}
33+
34+
log.Println("Started workflow", "WorkflowID", we.GetID(), "RunID", we.GetRunID())
35+
36+
// Synchronously wait for the workflow completion.
37+
var result string
38+
err = we.Get(context.Background(), &result)
39+
if err != nil {
40+
log.Fatalln("Unable get workflow result", err)
41+
}
42+
log.Println("Workflow result:", result)
43+
}

helloworld-apiKey/worker/main.go

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
package main
2+
3+
import (
4+
"log"
5+
"os"
6+
7+
"github.com/temporalio/samples-go/helloworld-apiKey"
8+
"go.temporal.io/sdk/client"
9+
"go.temporal.io/sdk/worker"
10+
)
11+
12+
func main() {
13+
// The client and worker are heavyweight objects that should be created once per process.
14+
clientOptions, err := helloworldapiKey.ParseClientOptionFlags(os.Args[1:])
15+
if err != nil {
16+
log.Fatalf("Invalid arguments: %v", err)
17+
}
18+
c, err := client.Dial(clientOptions)
19+
if err != nil {
20+
log.Fatalln("Unable to create client", err)
21+
}
22+
defer c.Close()
23+
24+
w := worker.New(c, "hello-world-apiKey", worker.Options{})
25+
26+
w.RegisterWorkflow(helloworldapiKey.Workflow)
27+
w.RegisterActivity(helloworldapiKey.Activity)
28+
29+
err = w.Run(worker.InterruptCh())
30+
if err != nil {
31+
log.Fatalln("Unable to start worker", err)
32+
}
33+
}

safe_message_handler/workflow.go

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -314,10 +314,14 @@ func (cm *ClusterManager) run(ctx workflow.Context) (ClusterManagerResult, error
314314
return ClusterManagerResult{}, err
315315
}
316316
cm.logger.Info("Continuing as new")
317-
return ClusterManagerResult{}, workflow.NewContinueAsNewError(ctx, ClusterManagerInput{
318-
State: &cm.state,
319-
TestContinueAsNew: cm.testContinueAsNew,
320-
})
317+
return ClusterManagerResult{}, workflow.NewContinueAsNewError(
318+
ctx,
319+
ClusterManagerWorkflow,
320+
ClusterManagerInput{
321+
State: &cm.state,
322+
TestContinueAsNew: cm.testContinueAsNew,
323+
},
324+
)
321325
}
322326

323327
}

0 commit comments

Comments
 (0)