http://git-wip-us.apache.org/repos/asf/camel/blob/42529399/components/camel-twitter/src/test/java/org/apache/camel/component/twitter/TwitterComponentVerifierTest.java ---------------------------------------------------------------------- diff --git a/components/camel-twitter/src/test/java/org/apache/camel/component/twitter/TwitterComponentVerifierTest.java b/components/camel-twitter/src/test/java/org/apache/camel/component/twitter/TwitterComponentVerifierTest.java new file mode 100644 index 0000000..5d24a04 --- /dev/null +++ b/components/camel-twitter/src/test/java/org/apache/camel/component/twitter/TwitterComponentVerifierTest.java @@ -0,0 +1,24 @@ +/** + * 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.twitter; + +public class TwitterComponentVerifierTest extends AbstractComponentVerifierTest { + @Override + protected String getComponentScheme() { + return "twitter"; + } +}
http://git-wip-us.apache.org/repos/asf/camel/blob/42529399/components/camel-twitter/src/test/java/org/apache/camel/component/twitter/directmessage/TwitterDirectmessageComponentVerifierExtensionTest.java ---------------------------------------------------------------------- diff --git a/components/camel-twitter/src/test/java/org/apache/camel/component/twitter/directmessage/TwitterDirectmessageComponentVerifierExtensionTest.java b/components/camel-twitter/src/test/java/org/apache/camel/component/twitter/directmessage/TwitterDirectmessageComponentVerifierExtensionTest.java new file mode 100644 index 0000000..a5de409 --- /dev/null +++ b/components/camel-twitter/src/test/java/org/apache/camel/component/twitter/directmessage/TwitterDirectmessageComponentVerifierExtensionTest.java @@ -0,0 +1,26 @@ +/** + * 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.twitter.directmessage; + +import org.apache.camel.component.twitter.AbstractComponentVerifierExtensionTest; + +public class TwitterDirectmessageComponentVerifierExtensionTest extends AbstractComponentVerifierExtensionTest { + @Override + protected String getComponentScheme() { + return "twitter-directmessage"; + } +} http://git-wip-us.apache.org/repos/asf/camel/blob/42529399/components/camel-twitter/src/test/java/org/apache/camel/component/twitter/directmessage/TwitterDirectmessageComponentVerifierTest.java ---------------------------------------------------------------------- diff --git a/components/camel-twitter/src/test/java/org/apache/camel/component/twitter/directmessage/TwitterDirectmessageComponentVerifierTest.java b/components/camel-twitter/src/test/java/org/apache/camel/component/twitter/directmessage/TwitterDirectmessageComponentVerifierTest.java new file mode 100644 index 0000000..8292712 --- /dev/null +++ b/components/camel-twitter/src/test/java/org/apache/camel/component/twitter/directmessage/TwitterDirectmessageComponentVerifierTest.java @@ -0,0 +1,26 @@ +/** + * 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.twitter.directmessage; + +import org.apache.camel.component.twitter.AbstractComponentVerifierTest; + +public class TwitterDirectmessageComponentVerifierTest extends AbstractComponentVerifierTest { + @Override + protected String getComponentScheme() { + return "twitter-directmessage"; + } +} http://git-wip-us.apache.org/repos/asf/camel/blob/42529399/components/camel-twitter/src/test/java/org/apache/camel/component/twitter/search/TwitterSearchComponentVerifierExtensionTest.java ---------------------------------------------------------------------- diff --git a/components/camel-twitter/src/test/java/org/apache/camel/component/twitter/search/TwitterSearchComponentVerifierExtensionTest.java b/components/camel-twitter/src/test/java/org/apache/camel/component/twitter/search/TwitterSearchComponentVerifierExtensionTest.java new file mode 100644 index 0000000..ae8428f --- /dev/null +++ b/components/camel-twitter/src/test/java/org/apache/camel/component/twitter/search/TwitterSearchComponentVerifierExtensionTest.java @@ -0,0 +1,72 @@ +/** + * 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.twitter.search; + +import java.util.Collections; +import java.util.LinkedList; +import java.util.List; + +import org.apache.camel.Component; +import org.apache.camel.component.extension.ComponentVerifierExtension; +import org.apache.camel.component.twitter.AbstractComponentVerifierExtensionTest; +import org.junit.Assert; +import org.junit.Test; + +public class TwitterSearchComponentVerifierExtensionTest extends AbstractComponentVerifierExtensionTest { + @Override + protected String getComponentScheme() { + return "twitter-search"; + } + + @Test + public void testEmptyConfiguration() { + Component component = context().getComponent(getComponentScheme()); + ComponentVerifierExtension verifier = component.getExtension(ComponentVerifierExtension.class).orElseThrow(IllegalStateException::new); + + { + // Parameters validation + ComponentVerifierExtension.Result result = verifier.verify(ComponentVerifierExtension.Scope.PARAMETERS, Collections.emptyMap()); + + Assert.assertEquals(ComponentVerifierExtension.Result.Status.ERROR, result.getStatus()); + Assert.assertEquals(5, result.getErrors().size()); + + List<String> expected = new LinkedList<>(); + expected.add("keywords"); + expected.add("consumerKey"); + expected.add("consumerSecret"); + expected.add("accessToken"); + expected.add("accessTokenSecret"); + + for (ComponentVerifierExtension.VerificationError error : result.getErrors()) { + expected.removeAll(error.getParameterKeys()); + } + + Assert.assertTrue("Missing expected params: " + expected.toString(), expected.isEmpty()); + } + + { + // Connectivity validation + ComponentVerifierExtension.Result result = verifier.verify(ComponentVerifierExtension.Scope.CONNECTIVITY, Collections.emptyMap()); + + Assert.assertEquals(ComponentVerifierExtension.Result.Status.ERROR, result.getStatus()); + Assert.assertEquals(1, result.getErrors().size()); + Assert.assertEquals(ComponentVerifierExtension.VerificationError.StandardCode.EXCEPTION, result.getErrors().get(0).getCode()); + Assert.assertNotNull(result.getErrors().get(0).getDetails().get(ComponentVerifierExtension.VerificationError.ExceptionAttribute.EXCEPTION_INSTANCE)); + Assert.assertTrue(result.getErrors().get(0).getDetails().get(ComponentVerifierExtension.VerificationError.ExceptionAttribute.EXCEPTION_INSTANCE) instanceof IllegalArgumentException); + } + } +} http://git-wip-us.apache.org/repos/asf/camel/blob/42529399/components/camel-twitter/src/test/java/org/apache/camel/component/twitter/search/TwitterSearchComponentVerifierTest.java ---------------------------------------------------------------------- diff --git a/components/camel-twitter/src/test/java/org/apache/camel/component/twitter/search/TwitterSearchComponentVerifierTest.java b/components/camel-twitter/src/test/java/org/apache/camel/component/twitter/search/TwitterSearchComponentVerifierTest.java new file mode 100644 index 0000000..6bf6275 --- /dev/null +++ b/components/camel-twitter/src/test/java/org/apache/camel/component/twitter/search/TwitterSearchComponentVerifierTest.java @@ -0,0 +1,72 @@ +/** + * 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.twitter.search; + +import java.util.Collections; +import java.util.LinkedList; +import java.util.List; + +import org.apache.camel.ComponentVerifier; +import org.apache.camel.component.twitter.AbstractComponentVerifierTest; +import org.apache.camel.component.twitter.AbstractTwitterComponent; +import org.junit.Assert; +import org.junit.Test; + +public class TwitterSearchComponentVerifierTest extends AbstractComponentVerifierTest { + @Override + protected String getComponentScheme() { + return "twitter-search"; + } + + @Test + public void testEmptyConfiguration() { + AbstractTwitterComponent component = context().getComponent(getComponentScheme(), AbstractTwitterComponent.class); + ComponentVerifier verifier = component.getVerifier(); + + { + // Parameters validation + ComponentVerifier.Result result = verifier.verify(ComponentVerifier.Scope.PARAMETERS, Collections.emptyMap()); + + Assert.assertEquals(ComponentVerifier.Result.Status.ERROR, result.getStatus()); + Assert.assertEquals(5, result.getErrors().size()); + + List<String> expected = new LinkedList<>(); + expected.add("keywords"); + expected.add("consumerKey"); + expected.add("consumerSecret"); + expected.add("accessToken"); + expected.add("accessTokenSecret"); + + for (ComponentVerifier.VerificationError error : result.getErrors()) { + expected.removeAll(error.getParameterKeys()); + } + + Assert.assertTrue("Missing expected params: " + expected.toString(), expected.isEmpty()); + } + + { + // Connectivity validation + ComponentVerifier.Result result = verifier.verify(ComponentVerifier.Scope.CONNECTIVITY, Collections.emptyMap()); + + Assert.assertEquals(ComponentVerifier.Result.Status.ERROR, result.getStatus()); + Assert.assertEquals(1, result.getErrors().size()); + Assert.assertEquals(ComponentVerifier.VerificationError.StandardCode.EXCEPTION, result.getErrors().get(0).getCode()); + Assert.assertNotNull(result.getErrors().get(0).getDetails().get(ComponentVerifier.VerificationError.ExceptionAttribute.EXCEPTION_INSTANCE)); + Assert.assertTrue(result.getErrors().get(0).getDetails().get(ComponentVerifier.VerificationError.ExceptionAttribute.EXCEPTION_INSTANCE) instanceof IllegalArgumentException); + } + } +} http://git-wip-us.apache.org/repos/asf/camel/blob/42529399/components/camel-twitter/src/test/java/org/apache/camel/component/twitter/streaming/TwitterStreamingComponentVerifierExtensionTest.java ---------------------------------------------------------------------- diff --git a/components/camel-twitter/src/test/java/org/apache/camel/component/twitter/streaming/TwitterStreamingComponentVerifierExtensionTest.java b/components/camel-twitter/src/test/java/org/apache/camel/component/twitter/streaming/TwitterStreamingComponentVerifierExtensionTest.java new file mode 100644 index 0000000..9dcdb78 --- /dev/null +++ b/components/camel-twitter/src/test/java/org/apache/camel/component/twitter/streaming/TwitterStreamingComponentVerifierExtensionTest.java @@ -0,0 +1,26 @@ +/** + * 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.twitter.streaming; + +import org.apache.camel.component.twitter.AbstractComponentVerifierExtensionTest; + +public class TwitterStreamingComponentVerifierExtensionTest extends AbstractComponentVerifierExtensionTest { + @Override + protected String getComponentScheme() { + return "twitter-streaming"; + } +} http://git-wip-us.apache.org/repos/asf/camel/blob/42529399/components/camel-twitter/src/test/java/org/apache/camel/component/twitter/streaming/TwitterStreamingComponentVerifierTest.java ---------------------------------------------------------------------- diff --git a/components/camel-twitter/src/test/java/org/apache/camel/component/twitter/streaming/TwitterStreamingComponentVerifierTest.java b/components/camel-twitter/src/test/java/org/apache/camel/component/twitter/streaming/TwitterStreamingComponentVerifierTest.java new file mode 100644 index 0000000..8d6da45 --- /dev/null +++ b/components/camel-twitter/src/test/java/org/apache/camel/component/twitter/streaming/TwitterStreamingComponentVerifierTest.java @@ -0,0 +1,26 @@ +/** + * 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.twitter.streaming; + +import org.apache.camel.component.twitter.AbstractComponentVerifierTest; + +public class TwitterStreamingComponentVerifierTest extends AbstractComponentVerifierTest { + @Override + protected String getComponentScheme() { + return "twitter-streaming"; + } +} http://git-wip-us.apache.org/repos/asf/camel/blob/42529399/components/camel-twitter/src/test/java/org/apache/camel/component/twitter/timeline/TwitterTimelineComponentVerifierExtensionTest.java ---------------------------------------------------------------------- diff --git a/components/camel-twitter/src/test/java/org/apache/camel/component/twitter/timeline/TwitterTimelineComponentVerifierExtensionTest.java b/components/camel-twitter/src/test/java/org/apache/camel/component/twitter/timeline/TwitterTimelineComponentVerifierExtensionTest.java new file mode 100644 index 0000000..1ea478c --- /dev/null +++ b/components/camel-twitter/src/test/java/org/apache/camel/component/twitter/timeline/TwitterTimelineComponentVerifierExtensionTest.java @@ -0,0 +1,26 @@ +/** + * 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.twitter.timeline; + +import org.apache.camel.component.twitter.AbstractComponentVerifierExtensionTest; + +public class TwitterTimelineComponentVerifierExtensionTest extends AbstractComponentVerifierExtensionTest { + @Override + protected String getComponentScheme() { + return "twitter-timeline"; + } +} http://git-wip-us.apache.org/repos/asf/camel/blob/42529399/components/camel-twitter/src/test/java/org/apache/camel/component/twitter/timeline/TwitterTimelineComponentVerifierTest.java ---------------------------------------------------------------------- diff --git a/components/camel-twitter/src/test/java/org/apache/camel/component/twitter/timeline/TwitterTimelineComponentVerifierTest.java b/components/camel-twitter/src/test/java/org/apache/camel/component/twitter/timeline/TwitterTimelineComponentVerifierTest.java new file mode 100644 index 0000000..2081db5 --- /dev/null +++ b/components/camel-twitter/src/test/java/org/apache/camel/component/twitter/timeline/TwitterTimelineComponentVerifierTest.java @@ -0,0 +1,26 @@ +/** + * 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.twitter.timeline; + +import org.apache.camel.component.twitter.AbstractComponentVerifierTest; + +public class TwitterTimelineComponentVerifierTest extends AbstractComponentVerifierTest { + @Override + protected String getComponentScheme() { + return "twitter-timeline"; + } +} http://git-wip-us.apache.org/repos/asf/camel/blob/42529399/components/camel-undertow/src/main/java/org/apache/camel/component/undertow/UndertowComponent.java ---------------------------------------------------------------------- diff --git a/components/camel-undertow/src/main/java/org/apache/camel/component/undertow/UndertowComponent.java b/components/camel-undertow/src/main/java/org/apache/camel/component/undertow/UndertowComponent.java index ff522f7..b3623d4 100644 --- a/components/camel-undertow/src/main/java/org/apache/camel/component/undertow/UndertowComponent.java +++ b/components/camel-undertow/src/main/java/org/apache/camel/component/undertow/UndertowComponent.java @@ -31,6 +31,7 @@ import org.apache.camel.Processor; import org.apache.camel.Producer; import org.apache.camel.SSLContextParametersAware; import org.apache.camel.VerifiableComponent; +import org.apache.camel.component.extension.ComponentVerifierExtension; import org.apache.camel.impl.DefaultComponent; import org.apache.camel.spi.Metadata; import org.apache.camel.spi.RestApiConsumerFactory; @@ -67,10 +68,13 @@ public class UndertowComponent extends DefaultComponent implements RestConsumerF private UndertowHostOptions hostOptions; public UndertowComponent() { + this(null); } public UndertowComponent(CamelContext context) { super(context); + + registerExtension(UndertowComponentVerifierExtension::new); } @Override @@ -361,11 +365,9 @@ public class UndertowComponent extends DefaultComponent implements RestConsumerF this.hostOptions = hostOptions; } - /** - * - */ + @Override public ComponentVerifier getVerifier() { - return new UndertowComponentVerifier(this); + return (scope, parameters) -> getExtension(ComponentVerifierExtension.class).orElseThrow(UnsupportedOperationException::new).verify(scope, parameters); } } http://git-wip-us.apache.org/repos/asf/camel/blob/42529399/components/camel-undertow/src/main/java/org/apache/camel/component/undertow/UndertowComponentVerifier.java ---------------------------------------------------------------------- diff --git a/components/camel-undertow/src/main/java/org/apache/camel/component/undertow/UndertowComponentVerifier.java b/components/camel-undertow/src/main/java/org/apache/camel/component/undertow/UndertowComponentVerifier.java deleted file mode 100644 index 03a73f5..0000000 --- a/components/camel-undertow/src/main/java/org/apache/camel/component/undertow/UndertowComponentVerifier.java +++ /dev/null @@ -1,239 +0,0 @@ -/** - * 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.undertow; - -import java.io.IOException; -import java.net.URI; -import java.net.URISyntaxException; -import java.util.HashMap; -import java.util.Map; -import java.util.Optional; - -import io.undertow.client.ClientCallback; -import io.undertow.client.ClientConnection; -import io.undertow.client.ClientExchange; -import io.undertow.client.ClientRequest; -import io.undertow.client.ClientResponse; -import io.undertow.client.UndertowClient; -import io.undertow.connector.ByteBufferPool; -import io.undertow.server.DefaultByteBufferPool; -import io.undertow.util.Headers; -import io.undertow.util.HttpString; -import io.undertow.util.Methods; -import org.apache.camel.impl.verifier.DefaultComponentVerifier; -import org.apache.camel.impl.verifier.ResultBuilder; -import org.apache.camel.impl.verifier.ResultErrorBuilder; -import org.apache.camel.util.FileUtil; -import org.apache.camel.util.ObjectHelper; -import org.apache.camel.util.URISupport; -import org.apache.camel.util.UnsafeUriCharactersEncoder; -import org.xnio.AbstractIoFuture; -import org.xnio.IoFuture; -import org.xnio.OptionMap; -import org.xnio.Xnio; -import org.xnio.XnioWorker; - -public final class UndertowComponentVerifier extends DefaultComponentVerifier { - private final UndertowComponent component; - - public UndertowComponentVerifier(UndertowComponent component) { - super("undertow", component.getCamelContext()); - - this.component = component; - } - - // ********************************* - // Parameters validation - // ********************************* - - @Override - protected Result verifyParameters(Map<String, Object> parameters) { - // Default is success - final ResultBuilder builder = ResultBuilder.withStatusAndScope(Result.Status.OK, Scope.PARAMETERS); - // Make a copy to avoid clashing with parent validation - final HashMap<String, Object> verifyParams = new HashMap<>(parameters); - // Check if validation is rest-related - final boolean isRest = verifyParams.entrySet().stream().anyMatch(e -> e.getKey().startsWith("rest.")); - - if (isRest) { - String httpUri = getOption(verifyParams, "rest.host", String.class).orElse(null); - String path = getOption(verifyParams, "rest.path", String.class).map(FileUtil::stripLeadingSeparator).orElse(null); - - if (ObjectHelper.isNotEmpty(httpUri) && ObjectHelper.isNotEmpty(path)) { - httpUri = httpUri + "/" + path; - } - - verifyParams.put("httpURI", httpUri); - - // Cleanup parameters map from rest related stuffs - verifyParams.entrySet().removeIf(e -> e.getKey().startsWith("rest.")); - } - - // Validate using the catalog - super.verifyParametersAgainstCatalog(builder, verifyParams); - - return builder.build(); - } - - // ********************************* - // Connectivity validation - // ********************************* - - @Override - protected Result verifyConnectivity(Map<String, Object> parameters) { - // Default is success - final ResultBuilder builder = ResultBuilder.withStatusAndScope(Result.Status.OK, Scope.CONNECTIVITY); - // Make a copy to avoid clashing with parent validation - final HashMap<String, Object> verifyParams = new HashMap<>(parameters); - // Check if validation is rest-related - final boolean isRest = verifyParams.entrySet().stream().anyMatch(e -> e.getKey().startsWith("rest.")); - - String httpUri; - Optional<String> httpMethod; - - if (isRest) { - // We are doing rest endpoint validation but as today the endpoint - // can't do any param substitution so the validation is performed - // against the http uri - httpUri = getOption(verifyParams, "rest.host", String.class).orElse(null); - httpMethod = getOption(verifyParams, "rest.method", String.class); - - String path = getOption(verifyParams, "rest.path", String.class).map(FileUtil::stripLeadingSeparator).orElse(null); - if (ObjectHelper.isNotEmpty(httpUri) && ObjectHelper.isNotEmpty(path)) { - httpUri = httpUri + "/" + path; - } - - verifyParams.put("httpURI", httpUri); - - // Cleanup parameters from rest related stuffs - verifyParams.entrySet().removeIf(e -> e.getKey().startsWith("rest.")); - } - - httpUri = getOption(verifyParams, "httpURI", String.class).orElse(null); - httpMethod = Optional.empty(); - - // Check whether the http uri is null or empty - if (ObjectHelper.isEmpty(httpUri)) { - builder.error( - ResultErrorBuilder.withMissingOption("httpURI") - .detail("rest", isRest) - .build() - ); - - // lack of httpURI is a blocking issue so no need to go further - // with the validation - return builder.build(); - } - - try { - final UndertowClientWrapper wrapper = new UndertowClientWrapper(); - final ClientResponse response = wrapper.send(httpUri, httpMethod); - - if (response != null) { - int code = response.getResponseCode(); - if (code == 401) { - // Unauthorized, add authUsername and authPassword to the list - // of parameters in error - builder.error( - ResultErrorBuilder.withHttpCode(code) - .description(response.getStatus()) - .build() - ); - } else if (code >= 300 && code < 400) { - // redirect - builder.error( - ResultErrorBuilder.withHttpCode(code) - .description(response.getStatus()) - .parameterKey("httpURI") - .detail( - VerificationError.HttpAttribute.HTTP_REDIRECT, - () -> Optional.ofNullable(response.getResponseHeaders().get(Headers.LOCATION).getFirst())) - .build() - ); - } else if (code >= 400) { - // generic http error - builder.error( - ResultErrorBuilder.withHttpCode(code) - .description(response.getStatus()) - .build() - ); - } - } - - } catch (Exception e) { - builder.error( - ResultErrorBuilder.withException(e).build() - ); - } - - return builder.build(); - } - - // ********************************* - // Helpers - // ********************************* - - private final class UndertowClientWrapper { - private final XnioWorker worker; - private final ByteBufferPool pool; - private UndertowClient client; - - private UndertowClientWrapper() throws IOException, URISyntaxException { - this.worker = Xnio.getInstance().createWorker(OptionMap.EMPTY); - this.pool = new DefaultByteBufferPool(true, 17 * 1024); - this.client = UndertowClient.getInstance(); - } - - public ClientResponse send(String httpUri, Optional<String> httpMethod) throws Exception { - URI uri = new URI(UnsafeUriCharactersEncoder.encodeHttpURI(httpUri)); - HttpString method = httpMethod.map(Methods::fromString).orElse(Methods.GET); - - ClientRequest request = new ClientRequest(); - request.setMethod(method); - request.setPath(URISupport.pathAndQueryOf(uri)); - - IoFuture<ClientConnection> connectFuture = client.connect(uri, worker, pool, OptionMap.EMPTY); - UndertowClientResponseFuture responseFuture = new UndertowClientResponseFuture(); - - connectFuture.get().sendRequest(request, responseFuture); - - // We should set a timeout - return responseFuture.get().getResponse(); - } - } - - private static final class UndertowClientResponseFuture extends AbstractIoFuture<ClientExchange> implements ClientCallback<ClientExchange> { - @Override - public void completed(ClientExchange result) { - result.setResponseListener(new ClientCallback<ClientExchange>() { - @Override - public void completed(ClientExchange result) { - setResult(result); - } - @Override - public void failed(IOException e) { - setException(e); - } - }); - } - - @Override - public void failed(IOException e) { - setException(e); - } - } -} http://git-wip-us.apache.org/repos/asf/camel/blob/42529399/components/camel-undertow/src/main/java/org/apache/camel/component/undertow/UndertowComponentVerifierExtension.java ---------------------------------------------------------------------- diff --git a/components/camel-undertow/src/main/java/org/apache/camel/component/undertow/UndertowComponentVerifierExtension.java b/components/camel-undertow/src/main/java/org/apache/camel/component/undertow/UndertowComponentVerifierExtension.java new file mode 100644 index 0000000..7be54be --- /dev/null +++ b/components/camel-undertow/src/main/java/org/apache/camel/component/undertow/UndertowComponentVerifierExtension.java @@ -0,0 +1,236 @@ +/** + * 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.undertow; + +import java.io.IOException; +import java.net.URI; +import java.net.URISyntaxException; +import java.util.HashMap; +import java.util.Map; +import java.util.Optional; + +import io.undertow.client.ClientCallback; +import io.undertow.client.ClientConnection; +import io.undertow.client.ClientExchange; +import io.undertow.client.ClientRequest; +import io.undertow.client.ClientResponse; +import io.undertow.client.UndertowClient; +import io.undertow.connector.ByteBufferPool; +import io.undertow.server.DefaultByteBufferPool; +import io.undertow.util.Headers; +import io.undertow.util.HttpString; +import io.undertow.util.Methods; +import org.apache.camel.component.extension.verifier.DefaultComponentVerifierExtension; +import org.apache.camel.component.extension.verifier.ResultBuilder; +import org.apache.camel.component.extension.verifier.ResultErrorBuilder; +import org.apache.camel.util.FileUtil; +import org.apache.camel.util.ObjectHelper; +import org.apache.camel.util.URISupport; +import org.apache.camel.util.UnsafeUriCharactersEncoder; +import org.xnio.AbstractIoFuture; +import org.xnio.IoFuture; +import org.xnio.OptionMap; +import org.xnio.Xnio; +import org.xnio.XnioWorker; + +public final class UndertowComponentVerifierExtension extends DefaultComponentVerifierExtension { + + UndertowComponentVerifierExtension() { + super("undertow"); + } + + // ********************************* + // Parameters validation + // ********************************* + + @Override + protected Result verifyParameters(Map<String, Object> parameters) { + // Default is success + final ResultBuilder builder = ResultBuilder.withStatusAndScope(Result.Status.OK, Scope.PARAMETERS); + // Make a copy to avoid clashing with parent validation + final HashMap<String, Object> verifyParams = new HashMap<>(parameters); + // Check if validation is rest-related + final boolean isRest = verifyParams.entrySet().stream().anyMatch(e -> e.getKey().startsWith("rest.")); + + if (isRest) { + String httpUri = getOption(verifyParams, "rest.host", String.class).orElse(null); + String path = getOption(verifyParams, "rest.path", String.class).map(FileUtil::stripLeadingSeparator).orElse(null); + + if (ObjectHelper.isNotEmpty(httpUri) && ObjectHelper.isNotEmpty(path)) { + httpUri = httpUri + "/" + path; + } + + verifyParams.put("httpURI", httpUri); + + // Cleanup parameters map from rest related stuffs + verifyParams.entrySet().removeIf(e -> e.getKey().startsWith("rest.")); + } + + // Validate using the catalog + super.verifyParametersAgainstCatalog(builder, verifyParams); + + return builder.build(); + } + + // ********************************* + // Connectivity validation + // ********************************* + + @Override + protected Result verifyConnectivity(Map<String, Object> parameters) { + // Default is success + final ResultBuilder builder = ResultBuilder.withStatusAndScope(Result.Status.OK, Scope.CONNECTIVITY); + // Make a copy to avoid clashing with parent validation + final HashMap<String, Object> verifyParams = new HashMap<>(parameters); + // Check if validation is rest-related + final boolean isRest = verifyParams.entrySet().stream().anyMatch(e -> e.getKey().startsWith("rest.")); + + String httpUri; + Optional<String> httpMethod; + + if (isRest) { + // We are doing rest endpoint validation but as today the endpoint + // can't do any param substitution so the validation is performed + // against the http uri + httpUri = getOption(verifyParams, "rest.host", String.class).orElse(null); + httpMethod = getOption(verifyParams, "rest.method", String.class); + + String path = getOption(verifyParams, "rest.path", String.class).map(FileUtil::stripLeadingSeparator).orElse(null); + if (ObjectHelper.isNotEmpty(httpUri) && ObjectHelper.isNotEmpty(path)) { + httpUri = httpUri + "/" + path; + } + + verifyParams.put("httpURI", httpUri); + + // Cleanup parameters from rest related stuffs + verifyParams.entrySet().removeIf(e -> e.getKey().startsWith("rest.")); + } + + httpUri = getOption(verifyParams, "httpURI", String.class).orElse(null); + httpMethod = Optional.empty(); + + // Check whether the http uri is null or empty + if (ObjectHelper.isEmpty(httpUri)) { + builder.error( + ResultErrorBuilder.withMissingOption("httpURI") + .detail("rest", isRest) + .build() + ); + + // lack of httpURI is a blocking issue so no need to go further + // with the validation + return builder.build(); + } + + try { + final UndertowClientWrapper wrapper = new UndertowClientWrapper(); + final ClientResponse response = wrapper.send(httpUri, httpMethod); + + if (response != null) { + int code = response.getResponseCode(); + if (code == 401) { + // Unauthorized, add authUsername and authPassword to the list + // of parameters in error + builder.error( + ResultErrorBuilder.withHttpCode(code) + .description(response.getStatus()) + .build() + ); + } else if (code >= 300 && code < 400) { + // redirect + builder.error( + ResultErrorBuilder.withHttpCode(code) + .description(response.getStatus()) + .parameterKey("httpURI") + .detail( + VerificationError.HttpAttribute.HTTP_REDIRECT, + () -> Optional.ofNullable(response.getResponseHeaders().get(Headers.LOCATION).getFirst())) + .build() + ); + } else if (code >= 400) { + // generic http error + builder.error( + ResultErrorBuilder.withHttpCode(code) + .description(response.getStatus()) + .build() + ); + } + } + + } catch (Exception e) { + builder.error( + ResultErrorBuilder.withException(e).build() + ); + } + + return builder.build(); + } + + // ********************************* + // Helpers + // ********************************* + + private final class UndertowClientWrapper { + private final XnioWorker worker; + private final ByteBufferPool pool; + private UndertowClient client; + + private UndertowClientWrapper() throws IOException, URISyntaxException { + this.worker = Xnio.getInstance().createWorker(OptionMap.EMPTY); + this.pool = new DefaultByteBufferPool(true, 17 * 1024); + this.client = UndertowClient.getInstance(); + } + + public ClientResponse send(String httpUri, Optional<String> httpMethod) throws Exception { + URI uri = new URI(UnsafeUriCharactersEncoder.encodeHttpURI(httpUri)); + HttpString method = httpMethod.map(Methods::fromString).orElse(Methods.GET); + + ClientRequest request = new ClientRequest(); + request.setMethod(method); + request.setPath(URISupport.pathAndQueryOf(uri)); + + IoFuture<ClientConnection> connectFuture = client.connect(uri, worker, pool, OptionMap.EMPTY); + UndertowClientResponseFuture responseFuture = new UndertowClientResponseFuture(); + + connectFuture.get().sendRequest(request, responseFuture); + + // We should set a timeout + return responseFuture.get().getResponse(); + } + } + + private static final class UndertowClientResponseFuture extends AbstractIoFuture<ClientExchange> implements ClientCallback<ClientExchange> { + @Override + public void completed(ClientExchange result) { + result.setResponseListener(new ClientCallback<ClientExchange>() { + @Override + public void completed(ClientExchange result) { + setResult(result); + } + @Override + public void failed(IOException e) { + setException(e); + } + }); + } + + @Override + public void failed(IOException e) { + setException(e); + } + } +} http://git-wip-us.apache.org/repos/asf/camel/blob/42529399/components/camel-undertow/src/test/java/org/apache/camel/component/undertow/UndertowComponentVerifierExtensionTest.java ---------------------------------------------------------------------- diff --git a/components/camel-undertow/src/test/java/org/apache/camel/component/undertow/UndertowComponentVerifierExtensionTest.java b/components/camel-undertow/src/test/java/org/apache/camel/component/undertow/UndertowComponentVerifierExtensionTest.java new file mode 100644 index 0000000..dc6cd6e --- /dev/null +++ b/components/camel-undertow/src/test/java/org/apache/camel/component/undertow/UndertowComponentVerifierExtensionTest.java @@ -0,0 +1,104 @@ +/** + * 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.undertow; + +import java.nio.channels.UnresolvedAddressException; +import java.util.HashMap; +import java.util.Map; + +import org.apache.camel.Component; +import org.apache.camel.builder.RouteBuilder; +import org.apache.camel.component.extension.ComponentVerifierExtension; +import org.junit.Assert; +import org.junit.Test; + +public class UndertowComponentVerifierExtensionTest extends BaseUndertowTest { + @Test + public void testParameters() throws Exception { + Component component = context().getComponent("undertow"); + ComponentVerifierExtension verifier = component.getExtension(ComponentVerifierExtension.class).orElseThrow(IllegalStateException::new); + + Map<String, Object> parameters = new HashMap<>(); + parameters.put("httpURI", "http://localhost:" + getPort()); + parameters.put("tcpNoDelay", "true"); + + ComponentVerifierExtension.Result result = verifier.verify(ComponentVerifierExtension.Scope.PARAMETERS, parameters); + + Assert.assertEquals(ComponentVerifierExtension.Result.Status.OK, result.getStatus()); + } + + @Test + public void testMissingParameters() throws Exception { + Component component = context().getComponent("undertow"); + ComponentVerifierExtension verifier = component.getExtension(ComponentVerifierExtension.class).orElseThrow(IllegalStateException::new); + + Map<String, Object> parameters = new HashMap<>(); + parameters.put("tcpNoDelay", "true"); + + ComponentVerifierExtension.Result result = verifier.verify(ComponentVerifierExtension.Scope.PARAMETERS, parameters); + + Assert.assertEquals(ComponentVerifierExtension.Result.Status.ERROR, result.getStatus()); + Assert.assertEquals(1, result.getErrors().size()); + Assert.assertEquals(ComponentVerifierExtension.VerificationError.StandardCode.MISSING_PARAMETER, result.getErrors().get(0).getCode()); + Assert.assertEquals(1, result.getErrors().get(0).getParameterKeys().size()); + Assert.assertTrue(result.getErrors().get(0).getParameterKeys().contains("httpURI")); + } + + @Test + public void testConnectivity() throws Exception { + Component component = context().getComponent("undertow"); + ComponentVerifierExtension verifier = component.getExtension(ComponentVerifierExtension.class).orElseThrow(IllegalStateException::new); + + Map<String, Object> parameters = new HashMap<>(); + parameters.put("httpURI", "http://localhost:" + getPort()); + parameters.put("tcpNoDelay", "true"); + + ComponentVerifierExtension.Result result = verifier.verify(ComponentVerifierExtension.Scope.CONNECTIVITY, parameters); + + Assert.assertEquals(ComponentVerifierExtension.Result.Status.OK, result.getStatus()); + } + + @Test + public void testConnectivityError() throws Exception { + Component component = context().getComponent("undertow"); + ComponentVerifierExtension verifier = component.getExtension(ComponentVerifierExtension.class).orElseThrow(IllegalStateException::new); + + Map<String, Object> parameters = new HashMap<>(); + parameters.put("httpURI", "http://no-host:" + getPort()); + + ComponentVerifierExtension.Result result = verifier.verify(ComponentVerifierExtension.Scope.CONNECTIVITY, parameters); + + Assert.assertEquals(ComponentVerifierExtension.Result.Status.ERROR, result.getStatus()); + Assert.assertEquals(1, result.getErrors().size()); + + ComponentVerifierExtension.VerificationError error = result.getErrors().get(0); + + Assert.assertEquals(ComponentVerifierExtension.VerificationError.StandardCode.EXCEPTION, error.getCode()); + Assert.assertTrue(error.getDetail(ComponentVerifierExtension.VerificationError.ExceptionAttribute.EXCEPTION_INSTANCE) instanceof UnresolvedAddressException); + } + + @Override + protected RouteBuilder createRouteBuilder() throws Exception { + return new RouteBuilder() { + @Override + public void configure() throws Exception { + from("undertow:http://localhost:{{port}}") + .process(e -> e.getOut().setBody("ok")); + } + }; + } +} http://git-wip-us.apache.org/repos/asf/camel/blob/42529399/connectors/camel-connector-maven-plugin/src/main/java/org/apache/camel/maven/connector/SpringBootAutoConfigurationMojo.java ---------------------------------------------------------------------- diff --git a/connectors/camel-connector-maven-plugin/src/main/java/org/apache/camel/maven/connector/SpringBootAutoConfigurationMojo.java b/connectors/camel-connector-maven-plugin/src/main/java/org/apache/camel/maven/connector/SpringBootAutoConfigurationMojo.java index c8ca459..23a2396 100644 --- a/connectors/camel-connector-maven-plugin/src/main/java/org/apache/camel/maven/connector/SpringBootAutoConfigurationMojo.java +++ b/connectors/camel-connector-maven-plugin/src/main/java/org/apache/camel/maven/connector/SpringBootAutoConfigurationMojo.java @@ -211,7 +211,7 @@ public class SpringBootAutoConfigurationMojo extends AbstractMojo { prefix += connectorScheme.toLowerCase(Locale.US); for (OptionModel option : model.getComponentOptions()) { - boolean isComponentOption= componentOptions != null && componentOptions.stream().anyMatch(o -> o.equals(option.getName())); + boolean isComponentOption = componentOptions != null && componentOptions.stream().anyMatch(o -> o.equals(option.getName())); boolean isEndpointOption = endpointOptions != null && endpointOptions.stream().anyMatch(o -> o.equals(option.getName())); // only include the options that has been explicit configured in the http://git-wip-us.apache.org/repos/asf/camel/blob/42529399/connectors/camel-connector/src/main/java/org/apache/camel/component/connector/DefaultConnectorComponent.java ---------------------------------------------------------------------- diff --git a/connectors/camel-connector/src/main/java/org/apache/camel/component/connector/DefaultConnectorComponent.java b/connectors/camel-connector/src/main/java/org/apache/camel/component/connector/DefaultConnectorComponent.java index 50d1407..d9f24eb 100644 --- a/connectors/camel-connector/src/main/java/org/apache/camel/component/connector/DefaultConnectorComponent.java +++ b/connectors/camel-connector/src/main/java/org/apache/camel/component/connector/DefaultConnectorComponent.java @@ -26,6 +26,7 @@ import java.util.Iterator; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; +import java.util.Optional; import org.apache.camel.CamelContext; import org.apache.camel.Component; @@ -36,9 +37,10 @@ import org.apache.camel.Processor; import org.apache.camel.VerifiableComponent; import org.apache.camel.catalog.CamelCatalog; import org.apache.camel.catalog.DefaultCamelCatalog; +import org.apache.camel.component.extension.ComponentVerifierExtension; +import org.apache.camel.component.extension.verifier.ResultBuilder; +import org.apache.camel.component.extension.verifier.ResultErrorBuilder; import org.apache.camel.impl.DefaultComponent; -import org.apache.camel.impl.verifier.ResultBuilder; -import org.apache.camel.impl.verifier.ResultErrorBuilder; import org.apache.camel.util.IntrospectionSupport; import org.apache.camel.util.ObjectHelper; import org.apache.camel.util.URISupport; @@ -83,6 +85,8 @@ public abstract class DefaultConnectorComponent extends DefaultComponent impleme if (!catalog.findComponentNames().contains(componentScheme)) { this.catalog.addComponent(componentScheme, this.model.getBaseJavaType(), catalog.componentJSonSchema(baseScheme)); } + + registerExtension(this::getComponentVerifierExtension); } @Override @@ -172,16 +176,20 @@ public abstract class DefaultConnectorComponent extends DefaultComponent impleme this.options = Collections.unmodifiableMap(new HashMap<>(baseComponentOptions)); } - @SuppressWarnings("unchecked") @Override public ComponentVerifier getVerifier() { + return (scope, parameters) -> getExtension(ComponentVerifierExtension.class).orElseThrow(UnsupportedOperationException::new).verify(scope, parameters); + } + + private ComponentVerifierExtension getComponentVerifierExtension() { try { // Create the component but no need to add it to the camel context // nor to start it. final Component component = createNewBaseComponent(); + final Optional<ComponentVerifierExtension> extension = component.getExtension(ComponentVerifierExtension.class); - if (component instanceof VerifiableComponent) { - return (scope, map) -> { + if (extension.isPresent()) { + return (ComponentVerifierExtension.Scope scope, Map<String, Object> map) -> { Map<String, Object> options; try { @@ -192,18 +200,18 @@ public abstract class DefaultConnectorComponent extends DefaultComponent impleme } catch (URISyntaxException | NoTypeConversionAvailableException e) { // If a failure is detected while reading the catalog, wrap it // and stop the validation step. - return ResultBuilder.withStatusAndScope(ComponentVerifier.Result.Status.OK, scope) + return ResultBuilder.withStatusAndScope(ComponentVerifierExtension.Result.Status.OK, scope) .error(ResultErrorBuilder.withException(e).build()) .build(); } - return ((VerifiableComponent) component).getVerifier().verify(scope, options); + return extension.get().verify(scope, options); }; } else { return (scope, map) -> { - return ResultBuilder.withStatusAndScope(ComponentVerifier.Result.Status.UNSUPPORTED, scope) + return ResultBuilder.withStatusAndScope(ComponentVerifierExtension.Result.Status.UNSUPPORTED, scope) .error( - ResultErrorBuilder.withCode(ComponentVerifier.VerificationError.StandardCode.UNSUPPORTED) + ResultErrorBuilder.withCode(ComponentVerifierExtension.VerificationError.StandardCode.UNSUPPORTED) .detail("camel_connector_name", getConnectorName()) .detail("camel_component_name", getComponentName()) .build()) @@ -212,7 +220,7 @@ public abstract class DefaultConnectorComponent extends DefaultComponent impleme } } catch (Exception e) { return (scope, map) -> { - return ResultBuilder.withStatusAndScope(ComponentVerifier.Result.Status.OK, scope) + return ResultBuilder.withStatusAndScope(ComponentVerifierExtension.Result.Status.OK, scope) .error(ResultErrorBuilder.withException(e).build()) .build(); };