This is an automated email from the ASF dual-hosted git repository. davsclaus pushed a commit to branch CAMEL-26161-zendesk-default-api in repository https://gitbox.apache.org/repos/asf/camel.git
commit 07349e0f84745c436f97f8af10e3ee515f4433f4 Author: Claus Ibsen <[email protected]> AuthorDate: Mon Nov 2 17:56:28 2026 +0100 CAMEL-26161: camel-zendesk - the documented syntax zendesk:methodName fails endpoint creation With a single path element the API component base passes an empty API name, and ZendeskComponent.getApiName converted "" to ZendeskApiName with the type converter, which fails as the only constant is DEFAULT. Only zendesk:default/methodName worked. An empty API name now maps to ZendeskApiName.DEFAULT, so zendesk:methodName (the endpoint syntax and the doc example) works. Co-Authored-By: Claude Opus 5.5 <[email protected]> Signed-off-by: Claus Ibsen <[email protected]> --- .../camel/component/zendesk/ZendeskComponent.java | 4 + .../component/zendesk/ZendeskApiNameTest.java | 101 +++++++++++++++++++++ 2 files changed, 105 insertions(+) diff --git a/components/camel-zendesk/src/main/java/org/apache/camel/component/zendesk/ZendeskComponent.java b/components/camel-zendesk/src/main/java/org/apache/camel/component/zendesk/ZendeskComponent.java index b7b714501f01..5a59926dbc67 100644 --- a/components/camel-zendesk/src/main/java/org/apache/camel/component/zendesk/ZendeskComponent.java +++ b/components/camel-zendesk/src/main/java/org/apache/camel/component/zendesk/ZendeskComponent.java @@ -54,6 +54,10 @@ public class ZendeskComponent extends AbstractApiComponent<ZendeskApiName, Zende @Override protected ZendeskApiName getApiName(String apiNameStr) { + // zendesk has a single API (DEFAULT) with an empty name, so zendesk:methodName has no API name in the path + if (apiNameStr == null || apiNameStr.isEmpty()) { + return ZendeskApiName.DEFAULT; + } return getCamelContext().getTypeConverter().convertTo(ZendeskApiName.class, apiNameStr); } diff --git a/components/camel-zendesk/src/test/java/org/apache/camel/component/zendesk/ZendeskApiNameTest.java b/components/camel-zendesk/src/test/java/org/apache/camel/component/zendesk/ZendeskApiNameTest.java new file mode 100644 index 000000000000..73ff15877782 --- /dev/null +++ b/components/camel-zendesk/src/test/java/org/apache/camel/component/zendesk/ZendeskApiNameTest.java @@ -0,0 +1,101 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); 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 org.apache.camel.component.zendesk; + +import java.io.IOException; +import java.io.OutputStream; +import java.net.InetSocketAddress; +import java.nio.charset.StandardCharsets; + +import com.sun.net.httpserver.HttpExchange; +import com.sun.net.httpserver.HttpServer; +import org.apache.camel.ResolveEndpointFailedException; +import org.apache.camel.TypeConversionException; +import org.apache.camel.component.zendesk.internal.ZendeskApiName; +import org.apache.camel.test.junit6.CamelTestSupport; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.Test; +import org.zendesk.client.v2.model.Ticket; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertInstanceOf; +import static org.junit.jupiter.api.Assertions.assertThrows; + +/** + * The zendesk component has a single API, so the API name in the path is optional: zendesk:methodName and + * zendesk:default/methodName are the same endpoint. + */ +public class ZendeskApiNameTest extends CamelTestSupport { + + private HttpServer server; + + @Override + protected void doPreSetup() throws Exception { + server = HttpServer.create(new InetSocketAddress("localhost", 0), 0); + server.createContext("/api/v2/tickets/42.json", this::ticket); + server.start(); + } + + @AfterEach + void stopServer() { + if (server != null) { + server.stop(0); + } + } + + private void ticket(HttpExchange exchange) throws IOException { + byte[] json = "{\"ticket\":{\"id\":42,\"subject\":\"Hello Camel\"}}".getBytes(StandardCharsets.UTF_8); + exchange.getResponseHeaders().add("Content-Type", "application/json"); + exchange.sendResponseHeaders(200, json.length); + try (OutputStream os = exchange.getResponseBody()) { + os.write(json); + } + } + + private String options() { + return "?inBody=id&serverUrl=http://localhost:" + server.getAddress().getPort() + "&username=camel&password=secret"; + } + + @Test + public void testMethodNameOnly() { + ZendeskEndpoint endpoint = context.getEndpoint("zendesk:getTicket" + options(), ZendeskEndpoint.class); + assertEquals(ZendeskApiName.DEFAULT, endpoint.getApiName()); + assertEquals("getTicket", endpoint.getMethodName()); + + Ticket ticket = template.requestBody(endpoint, 42L, Ticket.class); + assertEquals(42L, ticket.getId()); + assertEquals("Hello Camel", ticket.getSubject()); + } + + @Test + public void testDefaultApiName() { + ZendeskEndpoint endpoint = context.getEndpoint("zendesk:default/getTicket" + options(), ZendeskEndpoint.class); + assertEquals(ZendeskApiName.DEFAULT, endpoint.getApiName()); + assertEquals("getTicket", endpoint.getMethodName()); + + Ticket ticket = template.requestBody(endpoint, 42L, Ticket.class); + assertEquals(42L, ticket.getId()); + assertEquals("Hello Camel", ticket.getSubject()); + } + + @Test + public void testUnknownApiName() { + Exception e = assertThrows(ResolveEndpointFailedException.class, + () -> context.getEndpoint("zendesk:unknown/getTicket" + options())); + assertInstanceOf(TypeConversionException.class, e.getCause()); + } +}
