Skip to content

Commit 5bc024b

Browse files
committed
TLS Helloworld sample for gRPC calls to cadence
1 parent 48e7403 commit 5bc024b

File tree

6 files changed

+265
-2
lines changed

6 files changed

+265
-2
lines changed

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,3 +15,6 @@ vendor/
1515
# Executables produced by cadence-samples repo
1616
bin/
1717
docker-compose.yml
18+
19+
# Credentials
20+
new_samples/client_samples/helloworld_tls/credentials/
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
## Running the Sample
2+
3+
### Step 1: Download Certificates
4+
```bash
5+
cd new_samples/client_samples/helloworld_tls/credentials
6+
chmod +x download-certs.sh
7+
./download-certs.sh
8+
cd ..
9+
```
10+
11+
### Step 2: Register the Domain
12+
Before running workflows, you must register the "default" domain:
13+
14+
```bash
15+
cd new_samples/client_samples/helloworld_tls
16+
go run register_domain.go
17+
```
18+
19+
Expected output:
20+
```
21+
Successfully registered domain {"domain": "default"}
22+
```
23+
24+
If the domain already exists, you'll see:
25+
```
26+
Domain already exists {"domain": "default"}
27+
```
28+
29+
### Step 3: Run the Sample
30+
In another terminal:
31+
```bash
32+
cd new_samples/client_samples/helloworld_tls
33+
go run hello_world_tls.go
34+
```
35+
36+
## References
37+
38+
- [Cadence Official Certificates](https://github.com/cadence-workflow/cadence/tree/master/config/credentials)
39+
- [Cadence Documentation](https://cadenceworkflow.io/)
40+
- [Go TLS Package](https://pkg.go.dev/crypto/tls)
41+
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
#!/bin/bash
2+
# Script to download certificates from Cadence repository
3+
# Based on: https://github.com/cadence-workflow/cadence/tree/master/config/credentials
4+
5+
set -e
6+
7+
echo "Downloading certificates from Cadence repository..."
8+
9+
BASE_URL="https://raw.githubusercontent.com/cadence-workflow/cadence/master/config/credentials"
10+
11+
# Download all certificate files
12+
echo "Downloading ca.cert..."
13+
curl -L -o ca.cert "${BASE_URL}/ca.cert"
14+
15+
echo "Downloading server.cert..."
16+
curl -L -o server.cert "${BASE_URL}/server.cert"
17+
18+
echo "Downloading server.key..."
19+
curl -L -o server.key "${BASE_URL}/server.key"
20+
21+
echo "Downloading client.cert..."
22+
curl -L -o client.cert "${BASE_URL}/client.cert"
23+
24+
echo "Downloading client.key..."
25+
curl -L -o client.key "${BASE_URL}/client.key"
26+
27+
# Also try to get .pem versions if they exist
28+
echo "Trying to download .pem versions..."
29+
curl -L -o ca.pem "${BASE_URL}/ca.pem" 2>/dev/null || echo "ca.pem not found, skipping"
30+
curl -L -o server.pem "${BASE_URL}/server.pem" 2>/dev/null || echo "server.pem not found, skipping"
31+
curl -L -o client.pem "${BASE_URL}/client.pem" 2>/dev/null || echo "client.pem not found, skipping"
32+
33+
# Create symlinks for compatibility with existing code
34+
if [ -f "client.cert" ]; then
35+
ln -sf client.cert client.crt 2>/dev/null || cp client.cert client.crt
36+
fi
37+
38+
if [ -f "ca.cert" ]; then
39+
ln -sf ca.cert keytest.crt 2>/dev/null || cp ca.cert keytest.crt
40+
fi
41+
42+
echo ""
43+
echo "✓ Certificates downloaded successfully from Cadence repository!"
44+
echo ""
45+
echo "Downloaded files:"
46+
ls -lh *.cert *.key 2>/dev/null || true
47+
ls -lh *.pem 2>/dev/null || true
48+
ls -lh *.crt 2>/dev/null || true
49+
echo ""
50+
echo "These are the official Cadence test certificates."
51+
echo "Reference: https://github.com/cadence-workflow/cadence/tree/master/config/credentials"
52+
Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
package main
2+
3+
import (
4+
"context"
5+
"crypto/tls"
6+
"crypto/x509"
7+
"fmt"
8+
"os"
9+
"time"
10+
11+
"github.com/google/uuid"
12+
"github.com/uber-common/cadence-samples/new_samples/worker"
13+
"go.uber.org/cadence/.gen/go/shared"
14+
"go.uber.org/yarpc/transport/grpc"
15+
"go.uber.org/zap"
16+
"google.golang.org/grpc/credentials"
17+
)
18+
19+
func main() {
20+
withTLSDialOption, err := withTLSDialOption()
21+
if err != nil {
22+
panic(err)
23+
}
24+
cadenceClient := worker.BuildCadenceClient(withTLSDialOption)
25+
logger := worker.BuildLogger()
26+
27+
domain := "default"
28+
tasklist := "default-tasklist"
29+
workflowID := uuid.New().String()
30+
requestID := uuid.New().String()
31+
executionTimeout := int32(60)
32+
closeTimeout := int32(60)
33+
34+
workflowType := "cadence_samples.HelloWorldWorkflow"
35+
input := []byte(`{"message": "Uber"}`)
36+
37+
req := shared.StartWorkflowExecutionRequest{
38+
Domain: &domain,
39+
WorkflowId: &workflowID,
40+
WorkflowType: &shared.WorkflowType{
41+
Name: &workflowType,
42+
},
43+
TaskList: &shared.TaskList{
44+
Name: &tasklist,
45+
},
46+
Input: input,
47+
ExecutionStartToCloseTimeoutSeconds: &executionTimeout,
48+
TaskStartToCloseTimeoutSeconds: &closeTimeout,
49+
RequestId: &requestID,
50+
}
51+
52+
ctx, cancel := context.WithTimeout(context.Background(), time.Minute)
53+
defer cancel()
54+
resp, err := cadenceClient.StartWorkflowExecution(ctx, &req)
55+
if err != nil {
56+
logger.Error("Failed to create workflow", zap.Error(err))
57+
panic("Failed to create workflow.")
58+
}
59+
60+
logger.Info("successfully started HelloWorld workflow", zap.String("runID", resp.GetRunId()))
61+
}
62+
63+
func withTLSDialOption() (grpc.DialOption, error) {
64+
// Present client cert for mutual TLS (if enabled on server)
65+
clientCert, err := tls.LoadX509KeyPair("credentials/client.crt", "credentials/client.key")
66+
if err != nil {
67+
return nil, fmt.Errorf("Failed to load client certificate: %v", zap.Error(err))
68+
}
69+
70+
// Load server CA
71+
caCert, err := os.ReadFile("credentials/keytest.crt")
72+
if err != nil {
73+
return nil, fmt.Errorf("Failed to load server CA certificate: %v", zap.Error(err))
74+
}
75+
caCertPool := x509.NewCertPool()
76+
caCertPool.AppendCertsFromPEM(caCert)
77+
tlsConfig := tls.Config{
78+
InsecureSkipVerify: true,
79+
RootCAs: caCertPool,
80+
Certificates: []tls.Certificate{clientCert},
81+
}
82+
creds := credentials.NewTLS(&tlsConfig)
83+
grpc.DialerCredentials(creds)
84+
return grpc.DialerCredentials(creds), nil
85+
}
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
package main
2+
3+
// func main() {
4+
// logger := worker.BuildLogger()
5+
// logger.Info("Registering default domain for cadence-vishwa with TLS...")
6+
7+
// withTLSDialOption, err := buildTLSDialOption()
8+
// if err != nil {
9+
// logger.Fatal("Failed to build TLS dial option", zap.Error(err))
10+
// }
11+
12+
// cadenceClient := worker.BuildCadenceClient(withTLSDialOption)
13+
14+
// // Register the domain
15+
// domain := "default"
16+
// retentionDays := int32(7)
17+
// emitMetric := true
18+
19+
// req := &shared.RegisterDomainRequest{
20+
// Name: &domain,
21+
// Description: stringPtr("Default domain for cadence samples"),
22+
// WorkflowExecutionRetentionPeriodInDays: &retentionDays,
23+
// EmitMetric: &emitMetric,
24+
// }
25+
26+
// ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
27+
// defer cancel()
28+
29+
// err = cadenceClient.RegisterDomain(ctx, req)
30+
// if err != nil {
31+
// // Check if domain already exists
32+
// if _, ok := err.(*shared.DomainAlreadyExistsError); ok {
33+
// logger.Info("Domain already exists", zap.String("domain", domain))
34+
// return
35+
// }
36+
// logger.Fatal("Failed to register domain", zap.Error(err))
37+
// }
38+
39+
// logger.Info("Successfully registered domain", zap.String("domain", domain))
40+
// }
41+
42+
// func buildTLSDialOption() (grpc.DialOption, error) {
43+
// // Load client certificate
44+
// clientCert, err := tls.LoadX509KeyPair("credentials/client.crt", "credentials/client.key")
45+
// if err != nil {
46+
// return nil, fmt.Errorf("failed to load client certificate: %w", err)
47+
// }
48+
49+
// // Load server CA
50+
// caCert, err := os.ReadFile("credentials/keytest.crt")
51+
// if err != nil {
52+
// return nil, fmt.Errorf("failed to load server CA certificate: %w", err)
53+
// }
54+
55+
// caCertPool := x509.NewCertPool()
56+
// if !caCertPool.AppendCertsFromPEM(caCert) {
57+
// return nil, fmt.Errorf("failed to append CA certificate")
58+
// }
59+
60+
// tlsConfig := &tls.Config{
61+
// InsecureSkipVerify: true,
62+
// RootCAs: caCertPool,
63+
// Certificates: []tls.Certificate{clientCert},
64+
// MinVersion: tls.VersionTLS12,
65+
// }
66+
67+
// creds := credentials.NewTLS(tlsConfig)
68+
// return grpc.DialerCredentials(creds), nil
69+
// }
70+
71+
// func stringPtr(s string) *string {
72+
// return &s
73+
// }

new_samples/worker/worker.go

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@ import (
1111
"go.uber.org/cadence/worker"
1212
"go.uber.org/cadence/workflow"
1313
"go.uber.org/yarpc"
14+
"go.uber.org/yarpc/peer"
15+
yarpchostport "go.uber.org/yarpc/peer/hostport"
1416
"go.uber.org/yarpc/transport/grpc"
1517
"go.uber.org/zap"
1618
"go.uber.org/zap/zapcore"
@@ -69,11 +71,18 @@ func StartWorker() {
6971

7072
}
7173

72-
func BuildCadenceClient() workflowserviceclient.Interface {
74+
func BuildCadenceClient(dialOptions ...grpc.DialOption) workflowserviceclient.Interface {
75+
grpcTransport := grpc.NewTransport()
76+
myChooser := peer.NewSingle(
77+
yarpchostport.Identify(HostPort),
78+
grpcTransport.NewDialer(dialOptions...),
79+
)
80+
outbound := grpcTransport.NewOutbound(myChooser)
81+
7382
dispatcher := yarpc.NewDispatcher(yarpc.Config{
7483
Name: ClientName,
7584
Outbounds: yarpc.Outbounds{
76-
CadenceService: {Unary: grpc.NewTransport().NewSingleOutbound(HostPort)},
85+
CadenceService: {Unary: outbound},
7786
},
7887
})
7988
if err := dispatcher.Start(); err != nil {

0 commit comments

Comments
 (0)