From bbb59ad5417b569c45e17a7f65753baf932c0dc7 Mon Sep 17 00:00:00 2001 From: Amara Graham Date: Wed, 5 Jul 2023 15:35:34 -0500 Subject: [PATCH] Update Go Guide (#2250) * AKG updates * add link to Go * add link to Zeebe Go Client repo * go 1.19 * go 1.19 * add changes to 8.2 --------- Co-authored-by: christinaausley <84338309+christinaausley@users.noreply.github.com> --- docs/apis-tools/go-client/go-get-started.md | 212 ++++++++++++++++-- docs/apis-tools/go-client/index.md | 6 +- .../apis-tools/go-client/go-get-started.md | 212 ++++++++++++++++-- .../version-8.2/apis-tools/go-client/index.md | 6 +- 4 files changed, 400 insertions(+), 36 deletions(-) diff --git a/docs/apis-tools/go-client/go-get-started.md b/docs/apis-tools/go-client/go-get-started.md index d4e074e7cc..263c7d5564 100644 --- a/docs/apis-tools/go-client/go-get-started.md +++ b/docs/apis-tools/go-client/go-get-started.md @@ -4,6 +4,9 @@ title: Getting started with the Go client sidebar_label: "Getting started with the Go client" --- +import Tabs from "@theme/Tabs"; +import TabItem from "@theme/TabItem"; + In this tutorial, you will learn how to use the Go client in a Go application to interact with Camunda Platform 8. You can find a complete example on [GitHub](https://github.com/camunda/camunda-platform-get-started/tree/main/go). @@ -13,7 +16,7 @@ You can find a complete example on [GitHub](https://github.com/camunda/camunda-p - [Camunda Platform 8 account](/guides/create-account.md) - [Cluster](/guides/create-cluster.md) - [Client credentials](/guides/setup-client-connection-credentials.md) -- Go v1.13+ environment installed +- [Go v1.13+ environment installed](https://go.dev/) ## Set up a project @@ -22,9 +25,9 @@ First, we need a new Go project. To do this, complete the following steps: 1. Create a new project using your IDE, or create a new Go module with the following command: ``` -mkdir -p $GOPATH/src/github.com/zb-user/zb-example -cd $GOPATH/src/github.com/zb-user/zb-example -go mod init +mkdir github.com/zb-user/zb-example +cd github.com/zb-user/zb-example +go mod init zb-user/zb-example ``` 2. To use the Zeebe Go client library, add the following dependency to your `go.mod`: @@ -32,12 +35,12 @@ go mod init ``` module github.com/zb-user/zb-example -go 1.17 +go 1.19 -require github.com/camunda/zeebe/clients/go/v8 v8.0.0 +require github.com/camunda/zeebe/clients/go/v8@v8.2.7 ``` -3. Set the connection settings and client credentials as environment variables: +3. Set the connection settings and client credentials as environment variables in your terminal: ```bash export ZEEBE_ADDRESS='[Zeebe API]' @@ -115,15 +118,42 @@ Broker 0.0.0.0 : 26501 Now, we need a simple process we can deploy. Later, we will extend the process with more functionality. For now, follow the steps below: -1. Open Web Modeler and create a new BPMN diagram. + + + + +1. Open Web Modeler and create a new BPMN diagram named `order-process.bpmn`. + +2. Add a start event named `Order Placed` and an end event named `Order Delivered` to the diagram. Then, connect the events. + +![model-process-step-1](assets/order-process-simple.png) + +3. Set the ID (the BPMN process id) to `order-process` instead of the autogenerated value so it's easier to work with in this example. + +4. [Optional] Download the BPMN file to the root of the project. + + + + + +1. Open Desktop Modeler and create a new Camunda Platform 8 BPMN diagram named `order-process.bpmn`. 2. Add a start event named `Order Placed` and an end event named `Order Delivered` to the diagram. Then, connect the events. ![model-process-step-1](assets/order-process-simple.png) -3. Set the **id** (the BPMN process id), and mark the diagram as **executable**. +3. Set the ID (the BPMN process id) to `order-process` instead of the autogenerated value so it's easier to work with in this example. + +4. Place the BPMN diagram in the root of the project. + + -4. Save the diagram as `src/main/resources/order-process.bpmn` under the project's folder. + ## Deploy a process @@ -131,9 +161,27 @@ Next, we want to deploy the modeled process to the broker. The broker stores the process under its BPMN process id and assigns a version. + + + + +Using Web Modeler, you can deploy the BPMN diagram in the UI using the **Deploy** button. + +Alternatively, if you took the optional step and downloaded your BPMN diagram, you can follow the instructions for Desktop Modeler for this section. + + + + + +Add the following to `main.go` at the bottom of `func main()`. + ```go - // After the client is created - ctx := context.Background() + // After the client is created (add this to the end of your func main()) response, err := client.NewDeployResourceCommand().AddResourceFile("order-process.bpmn").Send(ctx) if err != nil { panic(err) @@ -149,6 +197,9 @@ You should see a similar output: key:2251799813685254 processes:{bpmnProcessId:"order-process" version:3 processDefinitionKey:2251799813685253 resourceName:"order-process.bpmn"} ``` + + + ## Create a process instance We are ready to create our first instance of the deployed process. @@ -199,7 +250,9 @@ Now, we want to do some work within our process. Follow the steps below: 2. Extend your `main.go` file and activate a job. These are created when the process instance reaches a service task. -3. Open the BPMN diagram in the modeler. Insert three service tasks between the start and the end event. +3. Open the BPMN diagram in Modeler. Keeping in mind how you want to [deploy your model](#deploy-a-process), you can choose either Web Modeler or Desktop Modeler. + +4. Insert three service tasks between the start and the end event. - Name the first task `Collect Money`. - Name the second task `Fetch Items`. @@ -207,16 +260,141 @@ Now, we want to do some work within our process. Follow the steps below: ![model-process-step-2](assets/order-process.png) -4. Set the **type** of each task, which identifies the nature of the work to be performed. +5. Using the properties panel **Task definition** section, set the **type** of each task, which identifies the nature of the work to be performed. - Set the **type** of the first task to `payment-service`. - Set the **type** of the second task to `fetcher-service`. - Set the **type** of the third task to `shipping-service`. -5. Additionally, for the service task `Collect Money` set a [**task-header**](/docs/next/components/modeler/bpmn/service-tasks/#task-headers) with the key `method` and the value `VISA`. This header is used as a configuration parameter for the payment-service worker to hand over the payment method. +6. Additionally, for the service task `Collect Money` set a [**task-header**](/docs/next/components/modeler/bpmn/service-tasks/#task-headers) with the key `method` and the value `VISA`. This header is used as a configuration parameter for the payment-service worker to hand over the payment method. The consolidated example looks as follows: + + + + +```go +package main + +import ( + "context" + "fmt" + "github.com/camunda/zeebe/clients/go/v8/pkg/entities" + "github.com/camunda/zeebe/clients/go/v8/pkg/worker" + "github.com/camunda/zeebe/clients/go/v8/pkg/zbc" + "log" + "os" +) + +const ZeebeAddr = "0.0.0.0:26500" + +var readyClose = make(chan struct{}) + +func main() { + gatewayAddr := os.Getenv("ZEEBE_ADDRESS") + plainText:= false + + if (gatewayAddr == "") { + gatewayAddr = ZeebeAddr + plainText = true + } + + zbClient, err := zbc.NewClient(&zbc.ClientConfig{ + GatewayAddress: gatewayAddr, + UsePlaintextConnection: plainText, + }) + + if err != nil { + panic(err) + } + + ctx := context.Background() + + // deploy process happens in the Web Modeler UI + + // create a new process instance + variables := make(map[string]interface{}) + variables["orderId"] = "31243" + + request, err := zbClient.NewCreateInstanceCommand().BPMNProcessId("order-process-4").LatestVersion().VariablesFromMap(variables) + if err != nil { + panic(err) + } + + result, err := request.Send(ctx) + if err != nil { + panic(err) + } + + fmt.Println(result.String()) + + jobWorker := zbClient.NewJobWorker().JobType("payment-service").Handler(handleJob).Open() + + <-readyClose + jobWorker.Close() + jobWorker.AwaitClose() +} + +func handleJob(client worker.JobClient, job entities.Job) { + jobKey := job.GetKey() + + headers, err := job.GetCustomHeadersAsMap() + if err != nil { + // failed to handle job as we require the custom job headers + failJob(client, job) + return + } + + variables, err := job.GetVariablesAsMap() + if err != nil { + // failed to handle job as we require the variables + failJob(client, job) + return + } + + variables["totalPrice"] = 46.50 + request, err := client.NewCompleteJobCommand().JobKey(jobKey).VariablesFromMap(variables) + if err != nil { + // failed to set the updated variables + failJob(client, job) + return + } + + log.Println("Complete job", jobKey, "of type", job.Type) + log.Println("Processing order:", variables["orderId"]) + log.Println("Collect money using payment method:", headers["method"]) + + ctx := context.Background() + _, err = request.Send(ctx) + if err != nil { + panic(err) + } + + log.Println("Successfully completed job") + close(readyClose) +} + +func failJob(client worker.JobClient, job entities.Job) { + log.Println("Failed to complete job", job.GetKey()) + + ctx := context.Background() + _, err := client.NewFailJobCommand().JobKey(job.GetKey()).Retries(job.Retries - 1).Send(ctx) + if err != nil { + panic(err) + } +} +``` + + + + + ```go package main @@ -334,6 +512,10 @@ func failJob(client worker.JobClient, job entities.Job) { } ``` + + + + In this example, we open a [job worker](/components/concepts/job-workers.md) for jobs of type `payment-service`. The job worker will repeatedly poll for new jobs of the type `payment-service` and activate them subsequently. Each activated job will then be passed to the job handler, which implements the business logic of the job worker. diff --git a/docs/apis-tools/go-client/index.md b/docs/apis-tools/go-client/index.md index a707b823cd..662e5da683 100644 --- a/docs/apis-tools/go-client/index.md +++ b/docs/apis-tools/go-client/index.md @@ -7,14 +7,14 @@ description: "Instantiate the client by passing in the address of the cluster yo ## Dependencies -To use the Zeebe Go client library, add the following dependency to your `go.mod`: +To use the [Zeebe Go client library](https://github.com/camunda/camunda-platform-get-started/tree/main/go), add the following dependency to your `go.mod`: ``` module github.com/zb-user/zb-example -go 1.17 +go 1.19 -require github.com/camunda/zeebe/clients/go/v8 v8.0.0 +require github.com/camunda/zeebe/clients/go/v8@v8.2.7 ``` ## Bootstrapping diff --git a/versioned_docs/version-8.2/apis-tools/go-client/go-get-started.md b/versioned_docs/version-8.2/apis-tools/go-client/go-get-started.md index d4e074e7cc..263c7d5564 100644 --- a/versioned_docs/version-8.2/apis-tools/go-client/go-get-started.md +++ b/versioned_docs/version-8.2/apis-tools/go-client/go-get-started.md @@ -4,6 +4,9 @@ title: Getting started with the Go client sidebar_label: "Getting started with the Go client" --- +import Tabs from "@theme/Tabs"; +import TabItem from "@theme/TabItem"; + In this tutorial, you will learn how to use the Go client in a Go application to interact with Camunda Platform 8. You can find a complete example on [GitHub](https://github.com/camunda/camunda-platform-get-started/tree/main/go). @@ -13,7 +16,7 @@ You can find a complete example on [GitHub](https://github.com/camunda/camunda-p - [Camunda Platform 8 account](/guides/create-account.md) - [Cluster](/guides/create-cluster.md) - [Client credentials](/guides/setup-client-connection-credentials.md) -- Go v1.13+ environment installed +- [Go v1.13+ environment installed](https://go.dev/) ## Set up a project @@ -22,9 +25,9 @@ First, we need a new Go project. To do this, complete the following steps: 1. Create a new project using your IDE, or create a new Go module with the following command: ``` -mkdir -p $GOPATH/src/github.com/zb-user/zb-example -cd $GOPATH/src/github.com/zb-user/zb-example -go mod init +mkdir github.com/zb-user/zb-example +cd github.com/zb-user/zb-example +go mod init zb-user/zb-example ``` 2. To use the Zeebe Go client library, add the following dependency to your `go.mod`: @@ -32,12 +35,12 @@ go mod init ``` module github.com/zb-user/zb-example -go 1.17 +go 1.19 -require github.com/camunda/zeebe/clients/go/v8 v8.0.0 +require github.com/camunda/zeebe/clients/go/v8@v8.2.7 ``` -3. Set the connection settings and client credentials as environment variables: +3. Set the connection settings and client credentials as environment variables in your terminal: ```bash export ZEEBE_ADDRESS='[Zeebe API]' @@ -115,15 +118,42 @@ Broker 0.0.0.0 : 26501 Now, we need a simple process we can deploy. Later, we will extend the process with more functionality. For now, follow the steps below: -1. Open Web Modeler and create a new BPMN diagram. + + + + +1. Open Web Modeler and create a new BPMN diagram named `order-process.bpmn`. + +2. Add a start event named `Order Placed` and an end event named `Order Delivered` to the diagram. Then, connect the events. + +![model-process-step-1](assets/order-process-simple.png) + +3. Set the ID (the BPMN process id) to `order-process` instead of the autogenerated value so it's easier to work with in this example. + +4. [Optional] Download the BPMN file to the root of the project. + + + + + +1. Open Desktop Modeler and create a new Camunda Platform 8 BPMN diagram named `order-process.bpmn`. 2. Add a start event named `Order Placed` and an end event named `Order Delivered` to the diagram. Then, connect the events. ![model-process-step-1](assets/order-process-simple.png) -3. Set the **id** (the BPMN process id), and mark the diagram as **executable**. +3. Set the ID (the BPMN process id) to `order-process` instead of the autogenerated value so it's easier to work with in this example. + +4. Place the BPMN diagram in the root of the project. + + -4. Save the diagram as `src/main/resources/order-process.bpmn` under the project's folder. + ## Deploy a process @@ -131,9 +161,27 @@ Next, we want to deploy the modeled process to the broker. The broker stores the process under its BPMN process id and assigns a version. + + + + +Using Web Modeler, you can deploy the BPMN diagram in the UI using the **Deploy** button. + +Alternatively, if you took the optional step and downloaded your BPMN diagram, you can follow the instructions for Desktop Modeler for this section. + + + + + +Add the following to `main.go` at the bottom of `func main()`. + ```go - // After the client is created - ctx := context.Background() + // After the client is created (add this to the end of your func main()) response, err := client.NewDeployResourceCommand().AddResourceFile("order-process.bpmn").Send(ctx) if err != nil { panic(err) @@ -149,6 +197,9 @@ You should see a similar output: key:2251799813685254 processes:{bpmnProcessId:"order-process" version:3 processDefinitionKey:2251799813685253 resourceName:"order-process.bpmn"} ``` + + + ## Create a process instance We are ready to create our first instance of the deployed process. @@ -199,7 +250,9 @@ Now, we want to do some work within our process. Follow the steps below: 2. Extend your `main.go` file and activate a job. These are created when the process instance reaches a service task. -3. Open the BPMN diagram in the modeler. Insert three service tasks between the start and the end event. +3. Open the BPMN diagram in Modeler. Keeping in mind how you want to [deploy your model](#deploy-a-process), you can choose either Web Modeler or Desktop Modeler. + +4. Insert three service tasks between the start and the end event. - Name the first task `Collect Money`. - Name the second task `Fetch Items`. @@ -207,16 +260,141 @@ Now, we want to do some work within our process. Follow the steps below: ![model-process-step-2](assets/order-process.png) -4. Set the **type** of each task, which identifies the nature of the work to be performed. +5. Using the properties panel **Task definition** section, set the **type** of each task, which identifies the nature of the work to be performed. - Set the **type** of the first task to `payment-service`. - Set the **type** of the second task to `fetcher-service`. - Set the **type** of the third task to `shipping-service`. -5. Additionally, for the service task `Collect Money` set a [**task-header**](/docs/next/components/modeler/bpmn/service-tasks/#task-headers) with the key `method` and the value `VISA`. This header is used as a configuration parameter for the payment-service worker to hand over the payment method. +6. Additionally, for the service task `Collect Money` set a [**task-header**](/docs/next/components/modeler/bpmn/service-tasks/#task-headers) with the key `method` and the value `VISA`. This header is used as a configuration parameter for the payment-service worker to hand over the payment method. The consolidated example looks as follows: + + + + +```go +package main + +import ( + "context" + "fmt" + "github.com/camunda/zeebe/clients/go/v8/pkg/entities" + "github.com/camunda/zeebe/clients/go/v8/pkg/worker" + "github.com/camunda/zeebe/clients/go/v8/pkg/zbc" + "log" + "os" +) + +const ZeebeAddr = "0.0.0.0:26500" + +var readyClose = make(chan struct{}) + +func main() { + gatewayAddr := os.Getenv("ZEEBE_ADDRESS") + plainText:= false + + if (gatewayAddr == "") { + gatewayAddr = ZeebeAddr + plainText = true + } + + zbClient, err := zbc.NewClient(&zbc.ClientConfig{ + GatewayAddress: gatewayAddr, + UsePlaintextConnection: plainText, + }) + + if err != nil { + panic(err) + } + + ctx := context.Background() + + // deploy process happens in the Web Modeler UI + + // create a new process instance + variables := make(map[string]interface{}) + variables["orderId"] = "31243" + + request, err := zbClient.NewCreateInstanceCommand().BPMNProcessId("order-process-4").LatestVersion().VariablesFromMap(variables) + if err != nil { + panic(err) + } + + result, err := request.Send(ctx) + if err != nil { + panic(err) + } + + fmt.Println(result.String()) + + jobWorker := zbClient.NewJobWorker().JobType("payment-service").Handler(handleJob).Open() + + <-readyClose + jobWorker.Close() + jobWorker.AwaitClose() +} + +func handleJob(client worker.JobClient, job entities.Job) { + jobKey := job.GetKey() + + headers, err := job.GetCustomHeadersAsMap() + if err != nil { + // failed to handle job as we require the custom job headers + failJob(client, job) + return + } + + variables, err := job.GetVariablesAsMap() + if err != nil { + // failed to handle job as we require the variables + failJob(client, job) + return + } + + variables["totalPrice"] = 46.50 + request, err := client.NewCompleteJobCommand().JobKey(jobKey).VariablesFromMap(variables) + if err != nil { + // failed to set the updated variables + failJob(client, job) + return + } + + log.Println("Complete job", jobKey, "of type", job.Type) + log.Println("Processing order:", variables["orderId"]) + log.Println("Collect money using payment method:", headers["method"]) + + ctx := context.Background() + _, err = request.Send(ctx) + if err != nil { + panic(err) + } + + log.Println("Successfully completed job") + close(readyClose) +} + +func failJob(client worker.JobClient, job entities.Job) { + log.Println("Failed to complete job", job.GetKey()) + + ctx := context.Background() + _, err := client.NewFailJobCommand().JobKey(job.GetKey()).Retries(job.Retries - 1).Send(ctx) + if err != nil { + panic(err) + } +} +``` + + + + + ```go package main @@ -334,6 +512,10 @@ func failJob(client worker.JobClient, job entities.Job) { } ``` + + + + In this example, we open a [job worker](/components/concepts/job-workers.md) for jobs of type `payment-service`. The job worker will repeatedly poll for new jobs of the type `payment-service` and activate them subsequently. Each activated job will then be passed to the job handler, which implements the business logic of the job worker. diff --git a/versioned_docs/version-8.2/apis-tools/go-client/index.md b/versioned_docs/version-8.2/apis-tools/go-client/index.md index a707b823cd..662e5da683 100644 --- a/versioned_docs/version-8.2/apis-tools/go-client/index.md +++ b/versioned_docs/version-8.2/apis-tools/go-client/index.md @@ -7,14 +7,14 @@ description: "Instantiate the client by passing in the address of the cluster yo ## Dependencies -To use the Zeebe Go client library, add the following dependency to your `go.mod`: +To use the [Zeebe Go client library](https://github.com/camunda/camunda-platform-get-started/tree/main/go), add the following dependency to your `go.mod`: ``` module github.com/zb-user/zb-example -go 1.17 +go 1.19 -require github.com/camunda/zeebe/clients/go/v8 v8.0.0 +require github.com/camunda/zeebe/clients/go/v8@v8.2.7 ``` ## Bootstrapping