Skip to content

Commit ad76b88

Browse files
authored
spring boot custom actuator worker endpoint sample (#639)
Signed-off-by: Tihomir Surdilovic <tihomir@temporal.io>
1 parent 825ca12 commit ad76b88

File tree

7 files changed

+151
-1
lines changed

7 files changed

+151
-1
lines changed

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,7 @@ More info on each sample:
161161
- [**Kafka Request / Reply**](/springboot/src/main/java/io/temporal/samples/springboot/kafka): Sample showing possible integration with event streaming platforms such as Kafka
162162
- [**Customize Options**](/springboot/src/main/java/io/temporal/samples/springboot/customize): Sample showing how to customize options such as WorkerOptions, WorkerFactoryOptions, etc (see options config [here](springboot/src/main/java/io/temporal/samples/springboot/customize/TemporalOptionsConfig.java))
163163
- [**Apache Camel Route**](/springboot/src/main/java/io/temporal/samples/springboot/camel): Sample showing how to start Workflow execution from a Camel Route
164+
- [**Custom Actuator Endpoint**](/springboot/src/main/java/io/temporal/samples/springboot/actuator): Sample showing how to create a custom Actuator endpoint that shows registered Workflow and Activity impls per task queue.
164165

165166
#### Temporal Cloud
166167
To run any of the SpringBoot samples in your Temporal Cloud namespace:

springboot/src/main/java/io/temporal/samples/springboot/SamplesController.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -182,4 +182,10 @@ public String camel(Model model) {
182182
model.addAttribute("sample", "Camel Route");
183183
return "camel";
184184
}
185+
186+
@GetMapping("/customendpoint")
187+
public String customEndpoint(Model model) {
188+
model.addAttribute("sample", "Custom Actuator Worker Info Endpoint");
189+
return "actuator";
190+
}
185191
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
# SpringBoot Actuator Worker Info Endpoint - Sample
2+
3+
1. Start SpringBoot from main samples repo directory:
4+
5+
./gradlew bootRun
6+
7+
2. In your browser navigate to:
8+
9+
http://localhost:3030/actuator/temporalworkerinfo
10+
11+
This sample shows how to create a custom Actuator Endpoint that
12+
displays registered workflow and activity implementations per task queue.
13+
This information comes from actually registered workers done by autoconfig module.
Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
/*
2+
* Copyright (c) 2020 Temporal Technologies, Inc. All Rights Reserved
3+
*
4+
* Copyright 2012-2016 Amazon.com, Inc. or its affiliates. All Rights Reserved.
5+
*
6+
* Modifications copyright (C) 2017 Uber Technologies, Inc.
7+
*
8+
* Licensed under the Apache License, Version 2.0 (the "License"). You may not
9+
* use this file except in compliance with the License. A copy of the License is
10+
* located at
11+
*
12+
* http://aws.amazon.com/apache2.0
13+
*
14+
* or in the "license" file accompanying this file. This file is distributed on
15+
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
16+
* express or implied. See the License for the specific language governing
17+
* permissions and limitations under the License.
18+
*/
19+
20+
package io.temporal.samples.springboot.actuator;
21+
22+
import io.temporal.common.metadata.*;
23+
import io.temporal.spring.boot.autoconfigure.template.WorkersTemplate;
24+
import java.lang.reflect.Method;
25+
import java.util.Map;
26+
import java.util.stream.Collectors;
27+
import org.springframework.beans.factory.annotation.Autowired;
28+
import org.springframework.beans.factory.annotation.Qualifier;
29+
import org.springframework.boot.actuate.endpoint.annotation.Endpoint;
30+
import org.springframework.boot.actuate.endpoint.annotation.ReadOperation;
31+
import org.springframework.stereotype.Component;
32+
33+
@Component
34+
@Endpoint(id = "temporalworkerinfo")
35+
public class WorkerActuatorEndpoint {
36+
@Autowired
37+
@Qualifier("temporalWorkersTemplate")
38+
private WorkersTemplate workersTemplate;
39+
40+
@ReadOperation
41+
public String workerInfo() {
42+
StringBuilder sb = new StringBuilder();
43+
Map<String, WorkersTemplate.RegisteredInfo> registeredInfo =
44+
workersTemplate.getRegisteredInfo();
45+
sb.append("Worker Info:");
46+
registeredInfo.forEach(
47+
(taskQueue, info) -> {
48+
sb.append("\n\n\tTask Queue: ").append(taskQueue);
49+
info.getRegisteredWorkflowInfo()
50+
.forEach(
51+
(workflowInfo) -> {
52+
sb.append("\n\t\t Workflow Interface: ").append(workflowInfo.getClassName());
53+
POJOWorkflowImplMetadata metadata = workflowInfo.getMetadata();
54+
sb.append("\n\t\t\t Workflow Methods: ");
55+
sb.append(
56+
metadata.getWorkflowMethods().stream()
57+
.map(POJOWorkflowMethodMetadata::getWorkflowMethod)
58+
.map(Method::getName)
59+
.collect(Collectors.joining(", ")));
60+
sb.append("\n\t\t\t Query Methods: ");
61+
sb.append(
62+
metadata.getQueryMethods().stream()
63+
.map(POJOWorkflowMethodMetadata::getWorkflowMethod)
64+
.map(Method::getName)
65+
.collect(Collectors.joining(", ")));
66+
sb.append("\n\t\t\t Signal Methods: ");
67+
sb.append(
68+
metadata.getSignalMethods().stream()
69+
.map(POJOWorkflowMethodMetadata::getWorkflowMethod)
70+
.map(Method::getName)
71+
.collect(Collectors.joining(", ")));
72+
sb.append("\n\t\t\t Update Methods: ");
73+
sb.append(
74+
metadata.getUpdateMethods().stream()
75+
.map(POJOWorkflowMethodMetadata::getWorkflowMethod)
76+
.map(Method::getName)
77+
.collect(Collectors.joining(",")));
78+
sb.append("\n\t\t\t Update Validator Methods: ");
79+
sb.append(
80+
metadata.getUpdateValidatorMethods().stream()
81+
.map(POJOWorkflowMethodMetadata::getWorkflowMethod)
82+
.map(Method::getName)
83+
.collect(Collectors.joining(", ")));
84+
});
85+
info.getRegisteredActivityInfo()
86+
.forEach(
87+
(activityInfo) -> {
88+
sb.append("\n\t\t Activity Impl: ").append(activityInfo.getClassName());
89+
POJOActivityImplMetadata metadata = activityInfo.getMetadata();
90+
sb.append("\n\t\t\t Activity Interfaces: ");
91+
sb.append(
92+
metadata.getActivityInterfaces().stream()
93+
.map(POJOActivityInterfaceMetadata::getInterfaceClass)
94+
.map(Class::getName)
95+
.collect(Collectors.joining(",")));
96+
sb.append("\n\t\t\t Activity Methods: ");
97+
sb.append(
98+
metadata.getActivityMethods().stream()
99+
.map(POJOActivityMethodMetadata::getMethod)
100+
.map(Method::getName)
101+
.collect(Collectors.joining(", ")));
102+
});
103+
});
104+
105+
return sb.toString();
106+
}
107+
}

springboot/src/main/resources/application.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ management:
4949
endpoints:
5050
web:
5151
exposure:
52-
include: prometheus
52+
include: prometheus,temporalworkerinfo
5353
# specific for samples
5454
samples:
5555
data:
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
<!DOCTYPE html>
2+
<html lang="en" xmlns:th="http://www.thymeleaf.org" xmlns="http://www.w3.org/1999/html">
3+
<head th:replace="fragments :: samples-header"></head>
4+
<body>
5+
<div class="container">
6+
<div class="card">
7+
<div class="card-body">
8+
<h4 class="card-title" th:text="'Temporal Java SDK Samples: ' + ${sample}">Temporal Java SDK Samples</h4>
9+
<h6>In this sample we show how to create a custom Actuator Endpoint showing Worker Info.</h6>
10+
<br/><br/>
11+
<div>
12+
<h6><a href="https://docs.spring.io/spring-boot/docs/current/reference/html/actuator.html" target="_blank">Spring Actuator</a> allows
13+
us to create custom endpoints. This sample shows how to create a Worker Info custom endpoint that shows registered Workflow and Activity impls per task queue.</h6><br/>
14+
View the custom endpoint at <a href="http://localhost:3030/actuator/temporalworkerinfo" target="_blank">localhost:3030/actuator/temporalworkerinfo</a>
15+
</div>
16+
</div>
17+
</div>
18+
<footer th:replace="fragments :: samples-footer"></footer>
19+
</body>
20+
</html>

springboot/src/main/resources/templates/index.html

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,9 @@ <h5 class="card-title">Temporal Java SDK Samples</h5>
2525
<div class="list-group">
2626
<a href="/camel" class="list-group-item list-group-item-action">Apache Camel Route</a>
2727
</div>
28+
<div class="list-group">
29+
<a href="/customendpoint" class="list-group-item list-group-item-action">Custom Actuator Endpoint - Worker Info</a>
30+
</div>
2831
</div>
2932
</div>
3033
</div>

0 commit comments

Comments
 (0)