Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
refactor(runtime): reuse process lock key derivation
Agent-Logs-Url: https://github.com/camunda/connectors/sessions/330b3d47-05bd-41dc-a7a6-c53ce3f9a1b0

Co-authored-by: johnBgood <1797846+johnBgood@users.noreply.github.com>
  • Loading branch information
Copilot and johnBgood committed Apr 27, 2026
commit d91190f1e9162ebd887bea14b0903d69d7314328
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ public ConnectorInstances getConnectorInstance(
.orElseThrow(() -> new DataNotFoundException(ConnectorInstances.class, type));
}

@GetMapping("/{type}/executables/{executableId}")
@GetMapping({"/{type}/executables/{executableId}", "/executables/{executableId}"})
public ActiveInboundConnectorResponse getConnectorInstanceExecutable(
HttpServletRequest request,
@RequestHeader(name = X_CAMUNDA_FORWARDED_FOR, required = false) String forwardedFor,
Expand All @@ -95,7 +95,7 @@ public ActiveInboundConnectorResponse getConnectorInstanceExecutable(
() -> new DataNotFoundException(ActiveInboundConnectorResponse.class, executableId));
}

@GetMapping("/{type}/executables/{executableId}/health")
@GetMapping({"/{type}/executables/{executableId}/health", "/executables/{executableId}/health"})
public List<InstanceAwareModel.InstanceAwareHealth> getConnectorInstanceExecutableHealth(
HttpServletRequest request,
@RequestHeader(name = X_CAMUNDA_FORWARDED_FOR, required = false) String forwardedFor,
Expand All @@ -108,7 +108,7 @@ public List<InstanceAwareModel.InstanceAwareHealth> getConnectorInstanceExecutab
new TypeReference<>() {});
}

@GetMapping("/{type}/executables/{executableId}/logs")
@GetMapping({"/{type}/executables/{executableId}/logs", "/executables/{executableId}/logs"})
public List<InstanceAwareModel.InstanceAwareActivity> getConnectorInstanceExecutableLogs(
HttpServletRequest request,
@RequestHeader(name = X_CAMUNDA_FORWARDED_FOR, required = false) String forwardedFor,
Expand All @@ -120,7 +120,7 @@ public List<InstanceAwareModel.InstanceAwareActivity> getConnectorInstanceExecut
new TypeReference<>() {});
}

@PostMapping("/{type}/executables/{executableId}/reset")
@PostMapping("/executables/{executableId}/reset")
public ActiveInboundConnectorResponse resetConnectorInstanceExecutable(
HttpServletRequest request,
@RequestHeader(name = X_CAMUNDA_FORWARDED_FOR, required = false) String forwardedFor,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -116,9 +116,9 @@
event.elementsByProcessDefinitionKey().size());
LOG.debug("Received target elements: {}", event.elementsByProcessDefinitionKey());

var processId = event.tenantId() + event.bpmnProcessId();
var processLockKey = processLockKey(event.tenantId(), event.bpmnProcessId());

synchronized (processId.intern()) {
synchronized (processLockKey.intern()) {

Check failure

Code scanning / CodeQL

Synchronization on boxed types or strings Error

Do not synchronize on objects of type String.
Comment thread
johnBgood marked this conversation as resolved.
Dismissed
try {
List<InboundConnectorElement> allElements =
event.elementsByProcessDefinitionKey().values().stream().flatMap(List::stream).toList();
Expand Down Expand Up @@ -348,7 +348,11 @@
*/
private String extractProcessLockKey(RegisteredExecutable executable) {
var element = extractContext(executable).connectorElements().getFirst();
return element.tenantId() + element.element().bpmnProcessId();
return processLockKey(element.tenantId(), element.element().bpmnProcessId());
}

private String processLockKey(String tenantId, String bpmnProcessId) {
return tenantId + bpmnProcessId;
}
Comment thread
chillleader marked this conversation as resolved.

private InboundConnectorManagementContext extractContext(RegisteredExecutable executable) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -306,13 +306,7 @@ public void shouldResetConnectorInstanceExecutable() throws Exception {
// re-uses the existing query mock and returns the same response
var response =
mockMvc
.perform(
post(
"/inbound-instances/"
+ TYPE_1
+ "/executables/"
+ RANDOM_ID_1.getId()
+ "/reset"))
.perform(post("/inbound-instances/executables/" + RANDOM_ID_1.getId() + "/reset"))
.andExpect(status().isOk())
.andReturn()
.getResponse()
Expand All @@ -328,7 +322,7 @@ public void shouldResetConnectorInstanceExecutable() throws Exception {
@Test
public void shouldReturn404_whenResettingUnknownExecutableId() throws Exception {
mockMvc
.perform(post("/inbound-instances/" + TYPE_1 + "/executables/UNKNOWN-ID/reset"))
.perform(post("/inbound-instances/executables/UNKNOWN-ID/reset"))
.andExpect(status().isNotFound())
.andExpect(
content()
Expand All @@ -342,11 +336,54 @@ public void shouldReturn500_whenResetFails() throws Exception {
doThrow(new RuntimeException("Reset failed")).when(executableRegistry).reset(RANDOM_ID_1);

mockMvc
.perform(
post("/inbound-instances/" + TYPE_1 + "/executables/" + RANDOM_ID_1.getId() + "/reset"))
.perform(post("/inbound-instances/executables/" + RANDOM_ID_1.getId() + "/reset"))
.andExpect(status().isInternalServerError());
}

@Test
public void shouldReturnSingleExecutable_withoutType() throws Exception {
var response =
mockMvc
.perform(get("/inbound-instances/executables/" + RANDOM_ID_1.getId()))
.andExpect(status().isOk())
.andReturn()
.getResponse()
.getContentAsString();

ActiveInboundConnectorResponse executable =
ConnectorsObjectMapperSupplier.getCopy()
.readValue(response, ActiveInboundConnectorResponse.class);
assertEquals(RANDOM_ID_1, executable.executableId());
assertEquals("ProcessA", executable.elements().getFirst().bpmnProcessId());
}

@Test
public void shouldReturnActivityLogs_withoutType() throws Exception {
var response =
mockMvc
.perform(get("/inbound-instances/executables/" + RANDOM_ID_3.getId() + "/logs"))
.andExpect(status().isOk())
.andReturn()
.getResponse()
.getContentAsString();

List<Activity> logs =
ConnectorsObjectMapperSupplier.getCopy().readValue(response, new TypeReference<>() {});
assertEquals(2, logs.size());
}

@Test
public void shouldReturn404_whenUnknownExecutableId_withoutType() throws Exception {
mockMvc
.perform(get("/inbound-instances/executables/UNKNOWN-ID"))
.andExpect(status().isNotFound())
.andExpect(
content()
.string(
containsString(
"Data of type 'ActiveInboundConnectorResponse' with id 'UNKNOWN-ID' not found")));
}

private boolean matchesQuery(ActiveExecutableResponse response, ActiveExecutableQuery query) {
var elements = response.elements();
if (elements.isEmpty()) {
Expand Down
Loading