From f1bf2691c2b88c8d7a41b044f54f45cb39a9984a Mon Sep 17 00:00:00 2001 From: Oleksii Ivanov <108869886+Oleksiivanov@users.noreply.github.com> Date: Fri, 16 Feb 2024 13:38:24 +0200 Subject: [PATCH] feat(logging): Introduce InvalidInboundConnectorException and adjust log level for missing definitions (#1956) * feat(logging): Introduce InvalidInboundConnectorException and adjust log level for missing definitions * feat(logging): improve log message, move InvalidInboundConnectorDefinitionException to runtime-core * feat(logging): added to InvalidInboundConnectorDefinitionException ability to add more context information (cherry picked from commit c879a987a8bb3087e1dbe053e2ca99e40d1770ac) --- ...idInboundConnectorDefinitionException.java | 129 ++++++++++++++++++ .../importer/ProcessDefinitionInspector.java | 38 ++++-- 2 files changed, 156 insertions(+), 11 deletions(-) create mode 100644 connector-runtime/connector-runtime-core/src/main/java/io/camunda/connector/runtime/core/error/InvalidInboundConnectorDefinitionException.java diff --git a/connector-runtime/connector-runtime-core/src/main/java/io/camunda/connector/runtime/core/error/InvalidInboundConnectorDefinitionException.java b/connector-runtime/connector-runtime-core/src/main/java/io/camunda/connector/runtime/core/error/InvalidInboundConnectorDefinitionException.java new file mode 100644 index 0000000000..829f5ad14b --- /dev/null +++ b/connector-runtime/connector-runtime-core/src/main/java/io/camunda/connector/runtime/core/error/InvalidInboundConnectorDefinitionException.java @@ -0,0 +1,129 @@ +/* + * Copyright Camunda Services GmbH and/or licensed to Camunda Services GmbH + * under one or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information regarding copyright + * ownership. Camunda licenses this file to you under the Apache License, + * Version 2.0; you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.camunda.connector.runtime.core.error; + +import java.io.Serial; + +/** + * Represents an unchecked exception indicating an invalid definition for an inbound connector. + * Enhanced to include process definition context for precise diagnostics. + */ +public class InvalidInboundConnectorDefinitionException extends RuntimeException { + + @Serial private static final long serialVersionUID = 1L; + + private final String processDefinitionName; + private final Long processDefinitionKey; + private final Long processDefinitionVersion; + + /** + * Constructor for exception without process definition context. + * + * @param message Detailed message about the invalid connector definition. + */ + public InvalidInboundConnectorDefinitionException(String message) { + this(message, null, null, null, null); + } + + /** + * Constructor for exception with cause but without process definition context. + * + * @param message Detailed message about the invalid connector definition. + * @param cause The cause of this exception. + */ + public InvalidInboundConnectorDefinitionException(String message, Throwable cause) { + this(message, null, null, null, cause); + } + + /** + * Constructor for exception with detailed process definition context. + * + * @param message Detailed message about the invalid connector definition. + * @param processDefinitionName Name of the process definition, nullable. + * @param processDefinitionKey Key of the process definition, nullable. + * @param processDefinitionVersion Version of the process definition, nullable. + */ + public InvalidInboundConnectorDefinitionException( + String message, + String processDefinitionName, + Long processDefinitionKey, + Long processDefinitionVersion) { + this(message, processDefinitionName, processDefinitionKey, processDefinitionVersion, null); + } + + /** + * Constructor to handle all initializations. + * + * @param message Detailed message about the invalid connector definition. + * @param processDefinitionName Name of the process definition, nullable. + * @param processDefinitionKey Key of the process definition, nullable. + * @param processDefinitionVersion Version of the process definition, nullable. + * @param cause The cause of this exception, nullable. + */ + public InvalidInboundConnectorDefinitionException( + String message, + String processDefinitionName, + Long processDefinitionKey, + Long processDefinitionVersion, + Throwable cause) { + super(message, cause); + this.processDefinitionName = processDefinitionName; + this.processDefinitionKey = processDefinitionKey; + this.processDefinitionVersion = processDefinitionVersion; + } + + /** + * Builds a detailed exception message. + * + * @param message Initial message about the invalid definition. + * @param processDefinitionName Name of the process definition, may be null. + * @param processDefinitionKey Key of the process definition, may be null. + * @param processDefinitionVersion Version of the process definition, may be null. + * @return Constructed detailed message. + */ + private static String buildMessage( + String message, + String processDefinitionName, + Long processDefinitionKey, + Long processDefinitionVersion) { + StringBuilder sb = new StringBuilder(message); + if (processDefinitionName != null) + sb.append(" [Process Definition Name: ").append(processDefinitionName).append("]"); + if (processDefinitionKey != null) sb.append(", Key: ").append(processDefinitionKey); + if (processDefinitionVersion != null) sb.append(", Version: ").append(processDefinitionVersion); + return sb.toString(); + } + + public String getProcessDefinitionName() { + return processDefinitionName; + } + + public Long getProcessDefinitionKey() { + return processDefinitionKey; + } + + public Long getProcessDefinitionVersion() { + return processDefinitionVersion; + } + + @Override + public String toString() { + return String.format( + "InvalidInboundConnectorDefinitionException{message='%s', processDefinitionName='%s', processDefinitionKey='%s', processDefinitionVersion='%s'}", + getMessage(), processDefinitionName, processDefinitionKey, processDefinitionVersion); + } +} diff --git a/connector-runtime/connector-runtime-spring/src/main/java/io/camunda/connector/runtime/inbound/importer/ProcessDefinitionInspector.java b/connector-runtime/connector-runtime-spring/src/main/java/io/camunda/connector/runtime/inbound/importer/ProcessDefinitionInspector.java index eb86767fe9..0474d5a747 100644 --- a/connector-runtime/connector-runtime-spring/src/main/java/io/camunda/connector/runtime/inbound/importer/ProcessDefinitionInspector.java +++ b/connector-runtime/connector-runtime-spring/src/main/java/io/camunda/connector/runtime/inbound/importer/ProcessDefinitionInspector.java @@ -20,6 +20,7 @@ import static io.camunda.connector.runtime.core.Keywords.INBOUND_TYPE_KEYWORD; import static io.camunda.connector.runtime.core.Keywords.MESSAGE_ID_EXPRESSION; +import io.camunda.connector.runtime.core.error.InvalidInboundConnectorDefinitionException; import io.camunda.connector.runtime.core.inbound.InboundConnectorDefinitionImpl; import io.camunda.connector.runtime.core.inbound.correlation.BoundaryEventCorrelationPoint; import io.camunda.connector.runtime.core.inbound.correlation.MessageCorrelationPoint; @@ -184,17 +185,32 @@ private Collection collectFlowElements( private Optional getCorrelationPointForElement( BaseElement element, Process process, ProcessDefinition definition) { - - if (element instanceof StartEvent se) { - return getCorrelationPointForStartEvent(se, process, definition); - } else if (element instanceof IntermediateCatchEvent ice) { - return getCorrelationPointForIntermediateCatchEvent(ice); - } else if (element instanceof BoundaryEvent be) { - return getCorrelationPointForIntermediateBoundaryEvent(be); - } else if (element instanceof ReceiveTask rt) { - return getCorrelationPointForReceiveTask(rt); + try { + if (element instanceof StartEvent se) { + return getCorrelationPointForStartEvent(se, process, definition); + } else if (element instanceof IntermediateCatchEvent ice) { + return getCorrelationPointForIntermediateCatchEvent(ice); + } else if (element instanceof BoundaryEvent be) { + return getCorrelationPointForIntermediateBoundaryEvent(be); + } else if (element instanceof ReceiveTask rt) { + return getCorrelationPointForReceiveTask(rt); + } + LOG.warn( + "Unsupported Inbound element type: {}, in process definition: {} (Key: {}, Version: {})", + element.getClass().getSimpleName(), + definition.getName(), + definition.getKey(), + definition.getVersion()); + } catch (InvalidInboundConnectorDefinitionException e) { + LOG.warn( + "Error getting correlation point for {} in process definition: {} (Key: {}, Version: {}): {}", + element.getClass().getSimpleName(), + definition.getName(), + definition.getKey(), + definition.getVersion(), + e.getMessage(), + e); } - LOG.warn("Unsupported Inbound element type: " + element.getClass()); return Optional.empty(); } @@ -216,7 +232,7 @@ private Optional getCorrelationPointCatchEvent(CatchEve .findAny() .orElseThrow( () -> - new IllegalStateException( + new InvalidInboundConnectorDefinitionException( "Sanity check failed: " + catchEvent.getClass().getSimpleName() + " must contain at least one event definition"));