You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by lb...@apache.org on 2017/08/04 16:09:54 UTC

[03/19] camel git commit: CAMEL-11550: Component extensions

http://git-wip-us.apache.org/repos/asf/camel/blob/42529399/components/camel-salesforce/camel-salesforce-component/src/test/java/org/apache/camel/component/salesforce/SalesforceComponentVerifierExtensionTest.java
----------------------------------------------------------------------
diff --git a/components/camel-salesforce/camel-salesforce-component/src/test/java/org/apache/camel/component/salesforce/SalesforceComponentVerifierExtensionTest.java b/components/camel-salesforce/camel-salesforce-component/src/test/java/org/apache/camel/component/salesforce/SalesforceComponentVerifierExtensionTest.java
new file mode 100644
index 0000000..bf7ed2a
--- /dev/null
+++ b/components/camel-salesforce/camel-salesforce-component/src/test/java/org/apache/camel/component/salesforce/SalesforceComponentVerifierExtensionTest.java
@@ -0,0 +1,183 @@
+/**
+ * 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.salesforce;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.camel.Component;
+import org.apache.camel.ComponentVerifier;
+import org.apache.camel.component.extension.ComponentVerifierExtension;
+import org.apache.camel.component.salesforce.api.SalesforceException;
+import org.apache.camel.test.junit4.CamelTestSupport;
+import org.apache.camel.util.ObjectHelper;
+import org.junit.Assert;
+import org.junit.Assume;
+import org.junit.Test;
+
+public class SalesforceComponentVerifierExtensionTest extends CamelTestSupport {
+    private static final String CLIENT_ID = getSystemPropertyOrEnvVar("salesforce.clientid");
+    private static final String CLIENT_SECRET = getSystemPropertyOrEnvVar("salesforce.clientsecret");
+    private static final String USERNAME = getSystemPropertyOrEnvVar("salesforce.userName");
+    private static final String PASSWORD = getSystemPropertyOrEnvVar("salesforce.password");
+
+    @Override
+    protected void doPreSetup() throws Exception {
+        Assume.assumeNotNull(CLIENT_ID);
+        Assume.assumeNotNull(CLIENT_SECRET);
+        Assume.assumeNotNull(USERNAME);
+        Assume.assumeNotNull(PASSWORD);
+    }
+
+    @Override
+    public boolean isUseRouteBuilder() {
+        return false;
+    }
+
+    // *********************************
+    // Helpers
+    // *********************************
+
+    protected Map<String, Object> getParameters() {
+        HashMap<String, Object> parameters = new HashMap<>();
+        parameters.put("clientId", CLIENT_ID);
+        parameters.put("clientSecret", CLIENT_SECRET);
+        parameters.put("userName", USERNAME);
+        parameters.put("password", PASSWORD);
+
+
+        return parameters;
+    }
+
+    public static String getSystemPropertyOrEnvVar(String systemProperty) {
+        String answer = System.getProperty(systemProperty);
+        if (ObjectHelper.isEmpty(answer)) {
+            String envProperty = systemProperty.toUpperCase().replaceAll("[.-]", "_");
+            answer = System.getenv(envProperty);
+        }
+
+        return answer;
+    }
+
+    protected ComponentVerifierExtension getExtension() {
+        Component component = context().getComponent("salesforce");
+        ComponentVerifierExtension verifier = component.getExtension(ComponentVerifierExtension.class).orElseThrow(IllegalStateException::new);
+
+        return verifier;
+    }
+
+    // *********************************
+    // Parameters validation
+    // *********************************
+
+    @Test
+    public void testUsernamePasswordParameters() {
+        HashMap<String, Object> parameters = new HashMap<>();
+        parameters.put("clientId", "clientId");
+        parameters.put("clientSecret", "clientSecret");
+        parameters.put("userName", "userName");
+        parameters.put("password", "password");
+
+        ComponentVerifierExtension.Result result = getExtension().verify(ComponentVerifierExtension.Scope.PARAMETERS, parameters);
+
+        Assert.assertEquals(ComponentVerifierExtension.Result.Status.OK, result.getStatus());
+    }
+
+    @Test
+    public void testRefreshTokenParameters() {
+        Map<String, Object> parameters = getParameters();
+        parameters.put("clientId", "clientId");
+        parameters.put("clientSecret", "clientSecret");
+        parameters.put("refreshToken", "refreshToken");
+
+        ComponentVerifierExtension.Result result = getExtension().verify(ComponentVerifierExtension.Scope.PARAMETERS, parameters);
+
+        Assert.assertEquals(ComponentVerifierExtension.Result.Status.OK, result.getStatus());
+    }
+
+    @Test
+    public void testWrongParameters() {
+        HashMap<String, Object> parameters = new HashMap<>();
+        parameters.put("clientId", "clientId");
+        parameters.put("clientSecret", "clientSecret");
+        parameters.put("password", "password");
+
+        ComponentVerifierExtension.Result result = getExtension().verify(ComponentVerifierExtension.Scope.PARAMETERS, parameters);
+
+        Assert.assertEquals(ComponentVerifierExtension.Result.Status.ERROR, result.getStatus());
+        Assert.assertEquals(3, result.getErrors().size());
+
+        Assert.assertEquals(ComponentVerifierExtension.VerificationError.StandardCode.INCOMPLETE_PARAMETER_GROUP, result.getErrors().get(0).getCode());
+        Assert.assertEquals(ComponentVerifierExtension.VerificationError.StandardCode.INCOMPLETE_PARAMETER_GROUP, result.getErrors().get(1).getCode());
+        Assert.assertEquals(ComponentVerifierExtension.VerificationError.StandardCode.INCOMPLETE_PARAMETER_GROUP, result.getErrors().get(2).getCode());
+    }
+
+    // *********************************
+    // Connectivity validation
+    // *********************************
+
+    @Test
+    public void testConnectivity() {
+        Map<String, Object> parameters = getParameters();
+        ComponentVerifierExtension.Result result = getExtension().verify(ComponentVerifierExtension.Scope.CONNECTIVITY, parameters);
+
+        Assert.assertEquals(ComponentVerifierExtension.Result.Status.OK, result.getStatus());
+    }
+
+    @Test
+    public void testConnectivityWithWrongUserName() {
+        Map<String, Object> parameters = getParameters();
+        parameters.put("userName", "not-a-salesforce-user");
+
+        ComponentVerifierExtension.Result result = getExtension().verify(ComponentVerifierExtension.Scope.CONNECTIVITY, parameters);
+
+        Assert.assertEquals(ComponentVerifierExtension.Result.Status.ERROR, result.getStatus());
+        Assert.assertEquals(2, result.getErrors().size());
+
+        // Exception
+        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 SalesforceException);
+        Assert.assertEquals(400, result.getErrors().get(0).getDetails().get(ComponentVerifierExtension.VerificationError.HttpAttribute.HTTP_CODE));
+
+        // Salesforce Error
+        Assert.assertEquals("invalid_grant", result.getErrors().get(1).getDetail("salesforce_code"));
+    }
+
+    @Test
+    public void testConnectivityWithWrongSecrets() {
+        Map<String, Object> parameters = getParameters();
+        parameters.put("clientId", "wrong-client-id");
+        parameters.put("clientSecret", "wrong-client-secret");
+
+        ComponentVerifierExtension.Result result = getExtension().verify(ComponentVerifierExtension.Scope.CONNECTIVITY, parameters);
+
+        Assert.assertEquals(ComponentVerifier.Result.Status.ERROR, result.getStatus());
+
+        Assert.assertEquals(ComponentVerifier.Result.Status.ERROR, result.getStatus());
+        Assert.assertEquals(2, result.getErrors().size());
+
+        // Exception
+        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 SalesforceException);
+        Assert.assertEquals(400, result.getErrors().get(0).getDetails().get(ComponentVerifier.VerificationError.HttpAttribute.HTTP_CODE));
+
+        // Salesforce Error
+        Assert.assertEquals("invalid_client_id", result.getErrors().get(1).getDetail("salesforce_code"));
+    }
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/42529399/components/camel-salesforce/camel-salesforce-component/src/test/java/org/apache/camel/component/salesforce/SalesforceComponentVerifierTest.java
----------------------------------------------------------------------
diff --git a/components/camel-salesforce/camel-salesforce-component/src/test/java/org/apache/camel/component/salesforce/SalesforceComponentVerifierTest.java b/components/camel-salesforce/camel-salesforce-component/src/test/java/org/apache/camel/component/salesforce/SalesforceComponentVerifierTest.java
index dc02d55..8b27265 100644
--- a/components/camel-salesforce/camel-salesforce-component/src/test/java/org/apache/camel/component/salesforce/SalesforceComponentVerifierTest.java
+++ b/components/camel-salesforce/camel-salesforce-component/src/test/java/org/apache/camel/component/salesforce/SalesforceComponentVerifierTest.java
@@ -20,7 +20,6 @@ import java.util.HashMap;
 import java.util.Map;
 
 import org.apache.camel.ComponentVerifier;
-import org.apache.camel.ComponentVerifier.VerificationError;
 import org.apache.camel.component.salesforce.api.SalesforceException;
 import org.apache.camel.test.junit4.CamelTestSupport;
 import org.apache.camel.util.ObjectHelper;
@@ -72,11 +71,9 @@ public class SalesforceComponentVerifierTest extends CamelTestSupport {
         return answer;
     }
 
-    protected SalesforceComponentVerifier getVerifier() {
+    protected ComponentVerifier getVerifier() {
         SalesforceComponent component = context().getComponent("salesforce", SalesforceComponent.class);
-        SalesforceComponentVerifier verifier = (SalesforceComponentVerifier)component.getVerifier();
-
-        return verifier;
+        return component.getVerifier();
     }
 
     // *********************************
@@ -120,9 +117,9 @@ public class SalesforceComponentVerifierTest extends CamelTestSupport {
         Assert.assertEquals(ComponentVerifier.Result.Status.ERROR, result.getStatus());
         Assert.assertEquals(3, result.getErrors().size());
 
-        Assert.assertEquals(VerificationError.StandardCode.INCOMPLETE_PARAMETER_GROUP, result.getErrors().get(0).getCode());
-        Assert.assertEquals(VerificationError.StandardCode.INCOMPLETE_PARAMETER_GROUP, result.getErrors().get(1).getCode());
-        Assert.assertEquals(VerificationError.StandardCode.INCOMPLETE_PARAMETER_GROUP, result.getErrors().get(2).getCode());
+        Assert.assertEquals(ComponentVerifier.VerificationError.StandardCode.INCOMPLETE_PARAMETER_GROUP, result.getErrors().get(0).getCode());
+        Assert.assertEquals(ComponentVerifier.VerificationError.StandardCode.INCOMPLETE_PARAMETER_GROUP, result.getErrors().get(1).getCode());
+        Assert.assertEquals(ComponentVerifier.VerificationError.StandardCode.INCOMPLETE_PARAMETER_GROUP, result.getErrors().get(2).getCode());
     }
 
     // *********************************
@@ -148,10 +145,10 @@ public class SalesforceComponentVerifierTest extends CamelTestSupport {
         Assert.assertEquals(2, result.getErrors().size());
 
         // Exception
-        Assert.assertEquals(VerificationError.StandardCode.EXCEPTION, result.getErrors().get(0).getCode());
-        Assert.assertNotNull(result.getErrors().get(0).getDetails().get(VerificationError.ExceptionAttribute.EXCEPTION_INSTANCE));
-        Assert.assertTrue(result.getErrors().get(0).getDetails().get(VerificationError.ExceptionAttribute.EXCEPTION_INSTANCE) instanceof SalesforceException);
-        Assert.assertEquals(400, result.getErrors().get(0).getDetails().get(VerificationError.HttpAttribute.HTTP_CODE));
+        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 SalesforceException);
+        Assert.assertEquals(400, result.getErrors().get(0).getDetails().get(ComponentVerifier.VerificationError.HttpAttribute.HTTP_CODE));
 
         // Salesforce Error
         Assert.assertEquals("invalid_grant", result.getErrors().get(1).getDetail("salesforce_code"));
@@ -171,9 +168,9 @@ public class SalesforceComponentVerifierTest extends CamelTestSupport {
         Assert.assertEquals(2, result.getErrors().size());
 
         // Exception
-        Assert.assertEquals(VerificationError.StandardCode.EXCEPTION, result.getErrors().get(0).getCode());
-        Assert.assertNotNull(result.getErrors().get(0).getDetails().get(VerificationError.ExceptionAttribute.EXCEPTION_INSTANCE));
-        Assert.assertTrue(result.getErrors().get(0).getDetails().get(VerificationError.ExceptionAttribute.EXCEPTION_INSTANCE) instanceof SalesforceException);
+        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 SalesforceException);
         Assert.assertEquals(400, result.getErrors().get(0).getDetails().get(ComponentVerifier.VerificationError.HttpAttribute.HTTP_CODE));
 
         // Salesforce Error

http://git-wip-us.apache.org/repos/asf/camel/blob/42529399/components/camel-servicenow/src/main/java/org/apache/camel/component/servicenow/ServiceNowComponent.java
----------------------------------------------------------------------
diff --git a/components/camel-servicenow/src/main/java/org/apache/camel/component/servicenow/ServiceNowComponent.java b/components/camel-servicenow/src/main/java/org/apache/camel/component/servicenow/ServiceNowComponent.java
index 8a5ab9e..ff414c8 100644
--- a/components/camel-servicenow/src/main/java/org/apache/camel/component/servicenow/ServiceNowComponent.java
+++ b/components/camel-servicenow/src/main/java/org/apache/camel/component/servicenow/ServiceNowComponent.java
@@ -16,14 +16,19 @@
  */
 package org.apache.camel.component.servicenow;
 
+import java.util.Collection;
+import java.util.Collections;
 import java.util.Map;
+import java.util.Optional;
 
 import org.apache.camel.CamelContext;
 import org.apache.camel.ComponentVerifier;
 import org.apache.camel.Endpoint;
 import org.apache.camel.SSLContextParametersAware;
 import org.apache.camel.VerifiableComponent;
-import org.apache.camel.impl.UriEndpointComponent;
+import org.apache.camel.component.extension.ComponentExtension;
+import org.apache.camel.component.extension.ComponentVerifierExtension;
+import org.apache.camel.impl.DefaultComponent;
 import org.apache.camel.spi.Metadata;
 import org.apache.camel.util.EndpointHelper;
 import org.apache.camel.util.IntrospectionSupport;
@@ -32,7 +37,7 @@ import org.apache.camel.util.IntrospectionSupport;
  * Represents the component that manages {@link ServiceNowEndpoint}.
  */
 @Metadata(label = "verifiers", enums = "parameters,connectivity")
-public class ServiceNowComponent extends UriEndpointComponent implements VerifiableComponent, SSLContextParametersAware {
+public class ServiceNowComponent extends DefaultComponent implements VerifiableComponent, SSLContextParametersAware {
 
     @Metadata(label = "advanced")
     private ServiceNowConfiguration configuration;
@@ -40,7 +45,11 @@ public class ServiceNowComponent extends UriEndpointComponent implements Verifia
     private boolean useGlobalSslContextParameters;
 
     public ServiceNowComponent() {
-        super(ServiceNowEndpoint.class);
+        this.configuration = new ServiceNowConfiguration();
+    }
+
+    public ServiceNowComponent(CamelContext camelContext) {
+        super(camelContext);
 
         this.configuration = new ServiceNowConfiguration();
     }
@@ -183,10 +192,24 @@ public class ServiceNowComponent extends UriEndpointComponent implements Verifia
         this.useGlobalSslContextParameters = useGlobalSslContextParameters;
     }
 
-    /**
-     * TODO: document
-     */
+    @Override
     public ComponentVerifier getVerifier() {
-        return new ServiceNowComponentVerifier(this);
+        return new ServiceNowComponentVerifierExtension(this);
+    }
+
+    @Override
+    public Collection<Class<? extends ComponentExtension>> getExtensionTypes() {
+        return Collections.singletonList(ComponentVerifierExtension.class);
+    }
+
+    @Override
+    public <T extends ComponentExtension> Optional<T> getExtension(Class<T> extensionType) {
+        if (ComponentVerifierExtension.class.isAssignableFrom(extensionType)) {
+            return Optional.of(
+                extensionType.cast(new ServiceNowComponentVerifierExtension(this))
+            );
+        }
+
+        return Optional.empty();
     }
 }

http://git-wip-us.apache.org/repos/asf/camel/blob/42529399/components/camel-servicenow/src/main/java/org/apache/camel/component/servicenow/ServiceNowComponentVerifier.java
----------------------------------------------------------------------
diff --git a/components/camel-servicenow/src/main/java/org/apache/camel/component/servicenow/ServiceNowComponentVerifier.java b/components/camel-servicenow/src/main/java/org/apache/camel/component/servicenow/ServiceNowComponentVerifier.java
deleted file mode 100644
index 8d4cf9d..0000000
--- a/components/camel-servicenow/src/main/java/org/apache/camel/component/servicenow/ServiceNowComponentVerifier.java
+++ /dev/null
@@ -1,113 +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.servicenow;
-
-import java.util.Map;
-import javax.ws.rs.HttpMethod;
-import javax.ws.rs.core.MediaType;
-
-import org.apache.camel.ComponentVerifier;
-import org.apache.camel.NoSuchOptionException;
-import org.apache.camel.impl.verifier.DefaultComponentVerifier;
-import org.apache.camel.impl.verifier.ResultBuilder;
-import org.apache.camel.impl.verifier.ResultErrorBuilder;
-
-public class ServiceNowComponentVerifier extends DefaultComponentVerifier {
-    private final ServiceNowComponent component;
-
-    ServiceNowComponentVerifier(ServiceNowComponent component) {
-        super("servicenow", component.getCamelContext());
-
-        this.component = component;
-    }
-
-    // *********************************
-    // Parameters validation
-    // *********************************
-
-    @Override
-    protected Result verifyParameters(Map<String, Object> parameters) {
-        ResultBuilder builder = ResultBuilder.withStatusAndScope(Result.Status.OK, Scope.PARAMETERS);
-
-        // Validate using the catalog
-        super.verifyParametersAgainstCatalog(builder, parameters);
-
-        return builder.build();
-    }
-
-    // *********************************
-    // Connectivity validation
-    // *********************************
-
-    @Override
-    protected Result verifyConnectivity(Map<String, Object> parameters) {
-        // Default is success
-        ResultBuilder builder = ResultBuilder.withStatusAndScope(Result.Status.OK, Scope.CONNECTIVITY);
-
-        try {
-            // Load ServiceNow Configuration
-            ServiceNowConfiguration configuration = new ServiceNowConfiguration();
-            setProperties(configuration, parameters);
-
-            String instanceName = getMandatoryOption(parameters, "instanceName", String.class);
-            String tableName = configuration.getTable() != null ? configuration.getTable() : "incident";
-
-            // Configure Api and OAuthToken ULRs using instanceName
-            if (!configuration.hasApiUrl()) {
-                configuration.setApiUrl(String.format("https://%s.service-now.com/api", instanceName));
-            }
-            if (!configuration.hasOauthTokenUrl()) {
-                configuration.setOauthTokenUrl(String.format("https://%s.service-now.com/oauth_token.do", instanceName));
-            }
-
-            new ServiceNowClient(getCamelContext(), configuration)
-                .types(MediaType.APPLICATION_JSON_TYPE)
-                .path("now")
-                .path(configuration.getApiVersion())
-                .path("table")
-                .path(tableName)
-                .query(ServiceNowParams.SYSPARM_LIMIT.getId(), 1L)
-                .invoke(HttpMethod.GET);
-        } catch (NoSuchOptionException e) {
-            builder.error(
-                ResultErrorBuilder.withMissingOption(e.getOptionName()).build()
-            );
-        } catch (ServiceNowException e) {
-            ResultErrorBuilder errorBuilder = ResultErrorBuilder.withException(e)
-                .detail(VerificationError.HttpAttribute.HTTP_CODE, e.getCode())
-                .detail("servicenow_error_message", e.getMessage())
-                .detail("servicenow_error_status", e.getStatus())
-                .detail("servicenow_error_detail", e.getDetail());
-
-            if (e.getCode() == 401) {
-                errorBuilder.code(VerificationError.StandardCode.AUTHENTICATION);
-                errorBuilder.parameterKey("userName");
-                errorBuilder.parameterKey("password");
-                errorBuilder.parameterKey("oauthClientId");
-                errorBuilder.parameterKey("oauthClientSecret");
-            }
-
-            builder.error(errorBuilder.build());
-        } catch (Exception e) {
-            builder.error(
-                ResultErrorBuilder.withException(e).build()
-            );
-        }
-
-        return builder.build();
-    }
-}

http://git-wip-us.apache.org/repos/asf/camel/blob/42529399/components/camel-servicenow/src/main/java/org/apache/camel/component/servicenow/ServiceNowComponentVerifierExtension.java
----------------------------------------------------------------------
diff --git a/components/camel-servicenow/src/main/java/org/apache/camel/component/servicenow/ServiceNowComponentVerifierExtension.java b/components/camel-servicenow/src/main/java/org/apache/camel/component/servicenow/ServiceNowComponentVerifierExtension.java
new file mode 100644
index 0000000..96313d2
--- /dev/null
+++ b/components/camel-servicenow/src/main/java/org/apache/camel/component/servicenow/ServiceNowComponentVerifierExtension.java
@@ -0,0 +1,112 @@
+/**
+ * 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.servicenow;
+
+import java.util.Map;
+import javax.ws.rs.HttpMethod;
+import javax.ws.rs.core.MediaType;
+
+import org.apache.camel.component.extension.verifier.DefaultComponentVerifierExtension;
+import org.apache.camel.component.extension.verifier.NoSuchOptionException;
+import org.apache.camel.component.extension.verifier.ResultBuilder;
+import org.apache.camel.component.extension.verifier.ResultErrorBuilder;
+
+public class ServiceNowComponentVerifierExtension extends DefaultComponentVerifierExtension {
+    private final ServiceNowComponent component;
+
+    ServiceNowComponentVerifierExtension(ServiceNowComponent component) {
+        super("servicenow", component.getCamelContext());
+
+        this.component = component;
+    }
+
+    // *********************************
+    // Parameters validation
+    // *********************************
+
+    @Override
+    protected Result verifyParameters(Map<String, Object> parameters) {
+        ResultBuilder builder = ResultBuilder.withStatusAndScope(Result.Status.OK, Scope.PARAMETERS);
+
+        // Validate using the catalog
+        super.verifyParametersAgainstCatalog(builder, parameters);
+
+        return builder.build();
+    }
+
+    // *********************************
+    // Connectivity validation
+    // *********************************
+
+    @Override
+    protected Result verifyConnectivity(Map<String, Object> parameters) {
+        // Default is success
+        ResultBuilder builder = ResultBuilder.withStatusAndScope(Result.Status.OK, Scope.CONNECTIVITY);
+
+        try {
+            // Load ServiceNow Configuration
+            ServiceNowConfiguration configuration = new ServiceNowConfiguration();
+            setProperties(configuration, parameters);
+
+            String instanceName = getMandatoryOption(parameters, "instanceName", String.class);
+            String tableName = configuration.getTable() != null ? configuration.getTable() : "incident";
+
+            // Configure Api and OAuthToken ULRs using instanceName
+            if (!configuration.hasApiUrl()) {
+                configuration.setApiUrl(String.format("https://%s.service-now.com/api", instanceName));
+            }
+            if (!configuration.hasOauthTokenUrl()) {
+                configuration.setOauthTokenUrl(String.format("https://%s.service-now.com/oauth_token.do", instanceName));
+            }
+
+            new ServiceNowClient(getCamelContext(), configuration)
+                .types(MediaType.APPLICATION_JSON_TYPE)
+                .path("now")
+                .path(configuration.getApiVersion())
+                .path("table")
+                .path(tableName)
+                .query(ServiceNowParams.SYSPARM_LIMIT.getId(), 1L)
+                .invoke(HttpMethod.GET);
+        } catch (NoSuchOptionException e) {
+            builder.error(
+                ResultErrorBuilder.withMissingOption(e.getOptionName()).build()
+            );
+        } catch (ServiceNowException e) {
+            ResultErrorBuilder errorBuilder = ResultErrorBuilder.withException(e)
+                .detail(VerificationError.HttpAttribute.HTTP_CODE, e.getCode())
+                .detail("servicenow_error_message", e.getMessage())
+                .detail("servicenow_error_status", e.getStatus())
+                .detail("servicenow_error_detail", e.getDetail());
+
+            if (e.getCode() == 401) {
+                errorBuilder.code(VerificationError.StandardCode.AUTHENTICATION);
+                errorBuilder.parameterKey("userName");
+                errorBuilder.parameterKey("password");
+                errorBuilder.parameterKey("oauthClientId");
+                errorBuilder.parameterKey("oauthClientSecret");
+            }
+
+            builder.error(errorBuilder.build());
+        } catch (Exception e) {
+            builder.error(
+                ResultErrorBuilder.withException(e).build()
+            );
+        }
+
+        return builder.build();
+    }
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/42529399/components/camel-servicenow/src/test/java/org/apache/camel/component/servicenow/ServiceNowComponentVerifierExtensionTest.java
----------------------------------------------------------------------
diff --git a/components/camel-servicenow/src/test/java/org/apache/camel/component/servicenow/ServiceNowComponentVerifierExtensionTest.java b/components/camel-servicenow/src/test/java/org/apache/camel/component/servicenow/ServiceNowComponentVerifierExtensionTest.java
new file mode 100644
index 0000000..a06d503
--- /dev/null
+++ b/components/camel-servicenow/src/test/java/org/apache/camel/component/servicenow/ServiceNowComponentVerifierExtensionTest.java
@@ -0,0 +1,151 @@
+/**
+ * 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.servicenow;
+
+import java.util.Map;
+import javax.ws.rs.ProcessingException;
+
+import org.apache.camel.Component;
+import org.apache.camel.component.extension.ComponentVerifierExtension;
+import org.junit.Assert;
+import org.junit.Test;
+
+public class ServiceNowComponentVerifierExtensionTest extends ServiceNowTestSupport {
+    public ServiceNowComponentVerifierExtensionTest() {
+        super(false);
+    }
+
+    @Override
+    public boolean isUseRouteBuilder() {
+        return false;
+    }
+
+    protected ComponentVerifierExtension getExtension() {
+        Component component = context().getComponent("servicenow");
+        ComponentVerifierExtension verifier = component.getExtension(ComponentVerifierExtension.class).orElseThrow(IllegalStateException::new);
+
+        return verifier;
+    }
+
+    // *********************************
+    // Parameters validation
+    // *********************************
+
+    @Test
+    public void testParameter() {
+        Map<String, Object> parameters = getParameters();
+        ComponentVerifierExtension.Result result = getExtension().verify(ComponentVerifierExtension.Scope.PARAMETERS, parameters);
+
+        Assert.assertEquals(ComponentVerifierExtension.Result.Status.OK, result.getStatus());
+    }
+
+    @Test
+    public void testMissingMandatoryParameter() {
+        Map<String, Object> parameters = getParameters();
+        parameters.remove("instanceName");
+        ComponentVerifierExtension.Result result = getExtension().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("instanceName", result.getErrors().get(0).getParameterKeys().iterator().next());
+    }
+
+    @Test
+    public void testMissingMandatoryAuthenticationParameter() {
+        Map<String, Object> parameters = getParameters();
+        parameters.remove("userName");
+        ComponentVerifierExtension.Result result = getExtension().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("userName", result.getErrors().get(0).getParameterKeys().iterator().next());
+    }
+
+    // *********************************
+    // Connectivity validation
+    // *********************************
+
+    @Test
+    public void testConnectivity() {
+        Map<String, Object> parameters = getParameters();
+        ComponentVerifierExtension.Result result = getExtension().verify(ComponentVerifierExtension.Scope.CONNECTIVITY, parameters);
+
+        Assert.assertEquals(ComponentVerifierExtension.Result.Status.OK, result.getStatus());
+    }
+
+    @Test
+    public void testConnectivityOnCustomTable() {
+        Map<String, Object> parameters = getParameters();
+        parameters.put("table", "ticket");
+
+        ComponentVerifierExtension.Result result = getExtension().verify(ComponentVerifierExtension.Scope.CONNECTIVITY, parameters);
+
+        Assert.assertEquals(ComponentVerifierExtension.Result.Status.OK, result.getStatus());
+    }
+
+    @Test
+    public void testConnectivityWithWrongInstance() {
+        Map<String, Object> parameters = getParameters();
+        parameters.put("instanceName", "unknown-instance");
+
+        ComponentVerifierExtension.Result result = getExtension().verify(ComponentVerifierExtension.Scope.CONNECTIVITY, parameters);
+
+        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 ProcessingException);
+    }
+
+    @Test
+    public void testConnectivityWithWrongTable() {
+        Map<String, Object> parameters = getParameters();
+        parameters.put("table", "unknown");
+
+        ComponentVerifierExtension.Result result = getExtension().verify(ComponentVerifierExtension.Scope.CONNECTIVITY, parameters);
+
+        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.assertEquals(400, result.getErrors().get(0).getDetails().get(ComponentVerifierExtension.VerificationError.HttpAttribute.HTTP_CODE));
+        Assert.assertTrue(result.getErrors().get(0).getDetails().get(ComponentVerifierExtension.VerificationError.ExceptionAttribute.EXCEPTION_INSTANCE) instanceof ServiceNowException);
+    }
+
+    @Test
+    public void testConnectivityWithWrongAuthentication() {
+        Map<String, Object> parameters = getParameters();
+        parameters.put("userName", "unknown-user");
+        parameters.remove("oauthClientId");
+        parameters.remove("oauthClientSecret");
+
+        ComponentVerifierExtension.Result result = getExtension().verify(ComponentVerifierExtension.Scope.CONNECTIVITY, parameters);
+
+        Assert.assertEquals(ComponentVerifierExtension.Result.Status.ERROR, result.getStatus());
+        Assert.assertEquals(1, result.getErrors().size());
+        Assert.assertEquals(ComponentVerifierExtension.VerificationError.StandardCode.AUTHENTICATION, result.getErrors().get(0).getCode());
+        Assert.assertNotNull(result.getErrors().get(0).getDetails().get(ComponentVerifierExtension.VerificationError.ExceptionAttribute.EXCEPTION_INSTANCE));
+        Assert.assertEquals(401, result.getErrors().get(0).getDetails().get(ComponentVerifierExtension.VerificationError.HttpAttribute.HTTP_CODE));
+        Assert.assertTrue(result.getErrors().get(0).getDetails().get(ComponentVerifierExtension.VerificationError.ExceptionAttribute.EXCEPTION_INSTANCE) instanceof ServiceNowException);
+        Assert.assertTrue(result.getErrors().get(0).getParameterKeys().contains("userName"));
+        Assert.assertTrue(result.getErrors().get(0).getParameterKeys().contains("password"));
+        Assert.assertTrue(result.getErrors().get(0).getParameterKeys().contains("oauthClientId"));
+        Assert.assertTrue(result.getErrors().get(0).getParameterKeys().contains("oauthClientSecret"));
+    }
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/42529399/components/camel-servicenow/src/test/java/org/apache/camel/component/servicenow/ServiceNowComponentVerifierTest.java
----------------------------------------------------------------------
diff --git a/components/camel-servicenow/src/test/java/org/apache/camel/component/servicenow/ServiceNowComponentVerifierTest.java b/components/camel-servicenow/src/test/java/org/apache/camel/component/servicenow/ServiceNowComponentVerifierTest.java
index 1fcd5bc..ddb3109 100644
--- a/components/camel-servicenow/src/test/java/org/apache/camel/component/servicenow/ServiceNowComponentVerifierTest.java
+++ b/components/camel-servicenow/src/test/java/org/apache/camel/component/servicenow/ServiceNowComponentVerifierTest.java
@@ -17,11 +17,9 @@
 package org.apache.camel.component.servicenow;
 
 import java.util.Map;
-
 import javax.ws.rs.ProcessingException;
 
 import org.apache.camel.ComponentVerifier;
-import org.apache.camel.ComponentVerifier.VerificationError;
 import org.junit.Assert;
 import org.junit.Test;
 
@@ -35,9 +33,9 @@ public class ServiceNowComponentVerifierTest extends ServiceNowTestSupport {
         return false;
     }
 
-    protected ServiceNowComponentVerifier getVerifier() {
+    protected ServiceNowComponentVerifierExtension getVerifier() {
         ServiceNowComponent component = context().getComponent("servicenow", ServiceNowComponent.class);
-        ServiceNowComponentVerifier verifier = (ServiceNowComponentVerifier)component.getVerifier();
+        ServiceNowComponentVerifierExtension verifier = (ServiceNowComponentVerifierExtension)component.getVerifier();
 
         return verifier;
     }
@@ -62,7 +60,7 @@ public class ServiceNowComponentVerifierTest extends ServiceNowTestSupport {
 
         Assert.assertEquals(ComponentVerifier.Result.Status.ERROR, result.getStatus());
         Assert.assertEquals(1, result.getErrors().size());
-        Assert.assertEquals(VerificationError.StandardCode.MISSING_PARAMETER, result.getErrors().get(0).getCode());
+        Assert.assertEquals(ComponentVerifier.VerificationError.StandardCode.MISSING_PARAMETER, result.getErrors().get(0).getCode());
         Assert.assertEquals("instanceName", result.getErrors().get(0).getParameterKeys().iterator().next());
     }
 
@@ -74,7 +72,7 @@ public class ServiceNowComponentVerifierTest extends ServiceNowTestSupport {
 
         Assert.assertEquals(ComponentVerifier.Result.Status.ERROR, result.getStatus());
         Assert.assertEquals(1, result.getErrors().size());
-        Assert.assertEquals(VerificationError.StandardCode.MISSING_PARAMETER, result.getErrors().get(0).getCode());
+        Assert.assertEquals(ComponentVerifier.VerificationError.StandardCode.MISSING_PARAMETER, result.getErrors().get(0).getCode());
         Assert.assertEquals("userName", result.getErrors().get(0).getParameterKeys().iterator().next());
     }
 
@@ -109,9 +107,9 @@ public class ServiceNowComponentVerifierTest extends ServiceNowTestSupport {
 
         Assert.assertEquals(ComponentVerifier.Result.Status.ERROR, result.getStatus());
         Assert.assertEquals(1, result.getErrors().size());
-        Assert.assertEquals(VerificationError.StandardCode.EXCEPTION, result.getErrors().get(0).getCode());
-        Assert.assertNotNull(result.getErrors().get(0).getDetails().get(VerificationError.ExceptionAttribute.EXCEPTION_INSTANCE));
-        Assert.assertTrue(result.getErrors().get(0).getDetails().get(VerificationError.ExceptionAttribute.EXCEPTION_INSTANCE) instanceof ProcessingException);
+        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 ProcessingException);
     }
 
     @Test
@@ -123,10 +121,10 @@ public class ServiceNowComponentVerifierTest extends ServiceNowTestSupport {
 
         Assert.assertEquals(ComponentVerifier.Result.Status.ERROR, result.getStatus());
         Assert.assertEquals(1, result.getErrors().size());
-        Assert.assertEquals(VerificationError.StandardCode.EXCEPTION, result.getErrors().get(0).getCode());
-        Assert.assertNotNull(result.getErrors().get(0).getDetails().get(VerificationError.ExceptionAttribute.EXCEPTION_INSTANCE));
-        Assert.assertEquals(400, result.getErrors().get(0).getDetails().get(VerificationError.HttpAttribute.HTTP_CODE));
-        Assert.assertTrue(result.getErrors().get(0).getDetails().get(VerificationError.ExceptionAttribute.EXCEPTION_INSTANCE) instanceof ServiceNowException);
+        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.assertEquals(400, result.getErrors().get(0).getDetails().get(ComponentVerifier.VerificationError.HttpAttribute.HTTP_CODE));
+        Assert.assertTrue(result.getErrors().get(0).getDetails().get(ComponentVerifier.VerificationError.ExceptionAttribute.EXCEPTION_INSTANCE) instanceof ServiceNowException);
     }
 
     @Test
@@ -140,10 +138,10 @@ public class ServiceNowComponentVerifierTest extends ServiceNowTestSupport {
 
         Assert.assertEquals(ComponentVerifier.Result.Status.ERROR, result.getStatus());
         Assert.assertEquals(1, result.getErrors().size());
-        Assert.assertEquals(VerificationError.StandardCode.AUTHENTICATION, result.getErrors().get(0).getCode());
-        Assert.assertNotNull(result.getErrors().get(0).getDetails().get(VerificationError.ExceptionAttribute.EXCEPTION_INSTANCE));
-        Assert.assertEquals(401, result.getErrors().get(0).getDetails().get(VerificationError.HttpAttribute.HTTP_CODE));
-        Assert.assertTrue(result.getErrors().get(0).getDetails().get(VerificationError.ExceptionAttribute.EXCEPTION_INSTANCE) instanceof ServiceNowException);
+        Assert.assertEquals(ComponentVerifier.VerificationError.StandardCode.AUTHENTICATION, result.getErrors().get(0).getCode());
+        Assert.assertNotNull(result.getErrors().get(0).getDetails().get(ComponentVerifier.VerificationError.ExceptionAttribute.EXCEPTION_INSTANCE));
+        Assert.assertEquals(401, result.getErrors().get(0).getDetails().get(ComponentVerifier.VerificationError.HttpAttribute.HTTP_CODE));
+        Assert.assertTrue(result.getErrors().get(0).getDetails().get(ComponentVerifier.VerificationError.ExceptionAttribute.EXCEPTION_INSTANCE) instanceof ServiceNowException);
         Assert.assertTrue(result.getErrors().get(0).getParameterKeys().contains("userName"));
         Assert.assertTrue(result.getErrors().get(0).getParameterKeys().contains("password"));
         Assert.assertTrue(result.getErrors().get(0).getParameterKeys().contains("oauthClientId"));

http://git-wip-us.apache.org/repos/asf/camel/blob/42529399/components/camel-twitter/src/main/java/org/apache/camel/component/twitter/AbstractTwitterComponent.java
----------------------------------------------------------------------
diff --git a/components/camel-twitter/src/main/java/org/apache/camel/component/twitter/AbstractTwitterComponent.java b/components/camel-twitter/src/main/java/org/apache/camel/component/twitter/AbstractTwitterComponent.java
index d86f603..552b548 100644
--- a/components/camel-twitter/src/main/java/org/apache/camel/component/twitter/AbstractTwitterComponent.java
+++ b/components/camel-twitter/src/main/java/org/apache/camel/component/twitter/AbstractTwitterComponent.java
@@ -22,6 +22,7 @@ import org.apache.camel.CamelContext;
 import org.apache.camel.ComponentVerifier;
 import org.apache.camel.Endpoint;
 import org.apache.camel.VerifiableComponent;
+import org.apache.camel.component.extension.ComponentVerifierExtension;
 import org.apache.camel.impl.DefaultComponent;
 import org.apache.camel.spi.Metadata;
 
@@ -29,7 +30,6 @@ import org.apache.camel.spi.Metadata;
  * Base Twitter component
  */
 public abstract class AbstractTwitterComponent extends DefaultComponent implements VerifiableComponent {
-
     @Metadata(label = "security", secret = true)
     private String consumerKey;
     @Metadata(label = "security", secret = true)
@@ -47,13 +47,17 @@ public abstract class AbstractTwitterComponent extends DefaultComponent implemen
     @Metadata(label = "proxy")
     private Integer httpProxyPort;
 
-    public AbstractTwitterComponent() {
+    protected AbstractTwitterComponent(String componentVerifierScheme) {
+        this(null, componentVerifierScheme);
     }
 
-    public AbstractTwitterComponent(CamelContext context) {
+    protected AbstractTwitterComponent(CamelContext context, String componentVerifierScheme) {
         super(context);
+
+        registerExtension(() -> new TwitterComponentVerifierExtension(componentVerifierScheme));
     }
 
+    @Override
     protected Endpoint createEndpoint(String uri, String remaining, Map<String, Object> parameters) throws Exception {
         TwitterConfiguration properties = new TwitterConfiguration();
         properties.setConsumerKey(consumerKey);
@@ -162,4 +166,11 @@ public abstract class AbstractTwitterComponent extends DefaultComponent implemen
         return httpProxyPort;
     }
 
+    /**
+     * Get a verifier for the component.
+     */
+    @Override
+    public ComponentVerifier getVerifier() {
+        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-twitter/src/main/java/org/apache/camel/component/twitter/DefaultTwitterComponentVerifier.java
----------------------------------------------------------------------
diff --git a/components/camel-twitter/src/main/java/org/apache/camel/component/twitter/DefaultTwitterComponentVerifier.java b/components/camel-twitter/src/main/java/org/apache/camel/component/twitter/DefaultTwitterComponentVerifier.java
deleted file mode 100644
index cdc1d6e..0000000
--- a/components/camel-twitter/src/main/java/org/apache/camel/component/twitter/DefaultTwitterComponentVerifier.java
+++ /dev/null
@@ -1,95 +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.twitter;
-
-import java.util.Map;
-
-import org.apache.camel.ComponentVerifier;
-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.impl.verifier.ResultErrorHelper;
-import twitter4j.Twitter;
-import twitter4j.TwitterException;
-
-public class DefaultTwitterComponentVerifier extends DefaultComponentVerifier {
-
-    public DefaultTwitterComponentVerifier(AbstractTwitterComponent component) {
-        super("twitter", component.getCamelContext());
-    }
-
-    public DefaultTwitterComponentVerifier(AbstractTwitterComponent component, String scheme) {
-        super(scheme, component.getCamelContext());
-    }
-
-    // *********************************
-    // Parameters validation
-    // *********************************
-
-    @Override
-    protected Result verifyParameters(Map<String, Object> parameters) {
-        ResultBuilder builder = ResultBuilder.withStatusAndScope(Result.Status.OK, Scope.PARAMETERS)
-            .error(ResultErrorHelper.requiresOption("accessToken", parameters))
-            .error(ResultErrorHelper.requiresOption("accessTokenSecret", parameters))
-            .error(ResultErrorHelper.requiresOption("consumerKey", parameters))
-            .error(ResultErrorHelper.requiresOption("consumerSecret", parameters));
-
-        // Validate using the catalog
-        super.verifyParametersAgainstCatalog(builder, parameters);
-
-        return builder.build();
-    }
-
-    // *********************************
-    // Connectivity validation
-    // *********************************
-
-    @Override
-    protected Result verifyConnectivity(Map<String, Object> parameters) {
-        return ResultBuilder.withStatusAndScope(Result.Status.OK, Scope.CONNECTIVITY)
-            .error(parameters, this::verifyCredentials)
-            .build();
-    }
-
-    private void verifyCredentials(ResultBuilder builder, Map<String, Object> parameters) throws Exception {
-        try {
-            TwitterConfiguration configuration = setProperties(new TwitterConfiguration(), parameters);
-            Twitter twitter = configuration.getTwitter();
-
-            twitter.verifyCredentials();
-        } catch (TwitterException e) {
-            // verifyCredentials throws TwitterException when Twitter service or
-            // network is unavailable or if supplied credential is wrong
-            ResultErrorBuilder errorBuilder = ResultErrorBuilder.withCodeAndDescription(VerificationError.StandardCode.AUTHENTICATION, e.getErrorMessage())
-                .detail("twitter_error_code", e.getErrorCode())
-                .detail("twitter_status_code", e.getStatusCode())
-                .detail("twitter_exception_code", e.getExceptionCode())
-                .detail("twitter_exception_message", e.getMessage())
-                .detail("twitter_exception_caused-by-network-issue", e.isCausedByNetworkIssue())
-                .detail(ComponentVerifier.VerificationError.ExceptionAttribute.EXCEPTION_CLASS, e.getClass().getName())
-                .detail(ComponentVerifier.VerificationError.ExceptionAttribute.EXCEPTION_INSTANCE, e);
-
-            // For a complete list of error codes see:
-            //   https://dev.twitter.com/overview/api/response-codes
-            if (e.getErrorCode() == 89) {
-                errorBuilder.parameterKey("accessToken");
-            }
-
-            builder.error(errorBuilder.build());
-        }
-    }
-}

http://git-wip-us.apache.org/repos/asf/camel/blob/42529399/components/camel-twitter/src/main/java/org/apache/camel/component/twitter/TwitterComponent.java
----------------------------------------------------------------------
diff --git a/components/camel-twitter/src/main/java/org/apache/camel/component/twitter/TwitterComponent.java b/components/camel-twitter/src/main/java/org/apache/camel/component/twitter/TwitterComponent.java
index a1b7e5d..92ea505 100644
--- a/components/camel-twitter/src/main/java/org/apache/camel/component/twitter/TwitterComponent.java
+++ b/components/camel-twitter/src/main/java/org/apache/camel/component/twitter/TwitterComponent.java
@@ -19,12 +19,7 @@ package org.apache.camel.component.twitter;
 import java.util.Map;
 
 import org.apache.camel.CamelContext;
-import org.apache.camel.ComponentVerifier;
 import org.apache.camel.Endpoint;
-import org.apache.camel.VerifiableComponent;
-import org.apache.camel.component.twitter.data.ConsumerType;
-import org.apache.camel.component.twitter.data.EndpointType;
-import org.apache.camel.impl.DefaultComponent;
 import org.apache.camel.spi.Metadata;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -35,7 +30,7 @@ import org.slf4j.LoggerFactory;
  * @deprecated Use
  * {@link org.apache.camel.component.twitter.directmessage.TwitterDirectMessageComponent},
  * {@link org.apache.camel.component.twitter.search.TwitterSearchComponent},
- * {@link org.apache.camel.component.twitter.streaming..TwitterStreamingComponent} or
+ * {@link org.apache.camel.component.twitter.streaming.TwitterStreamingComponent} or
  * {@link org.apache.camel.component.twitter.timeline.TwitterTimelineComponent}
  * instead.
  */
@@ -46,12 +41,14 @@ public class TwitterComponent extends AbstractTwitterComponent {
     private static final Logger LOG = LoggerFactory.getLogger(TwitterComponent.class);
 
     public TwitterComponent() {
+        super("twitter");
     }
 
     public TwitterComponent(CamelContext context) {
-        super(context);
+        super(context, "twitter");
     }
 
+    @Override
     protected Endpoint doCreateEndpoint(TwitterConfiguration properties, String uri, String remaining, Map<String, Object> parameters) throws Exception {
         String[] tokens = remaining.split("/");
         LOG.warn("The scheme syntax 'twitter:{}' has been deprecated. Use 'twitter-{}' instead.", tokens[0], tokens[0]);
@@ -73,11 +70,4 @@ public class TwitterComponent extends AbstractTwitterComponent {
         endpoint.setKeywords(getAndRemoveParameter(parameters, "keywords", String.class));
         return endpoint;
     }
-
-    /**
-     * Get a verifier for the twitter component.
-     */
-    public ComponentVerifier getVerifier() {
-        return new DefaultTwitterComponentVerifier(this);
-    }
 }

http://git-wip-us.apache.org/repos/asf/camel/blob/42529399/components/camel-twitter/src/main/java/org/apache/camel/component/twitter/TwitterComponentVerifierExtension.java
----------------------------------------------------------------------
diff --git a/components/camel-twitter/src/main/java/org/apache/camel/component/twitter/TwitterComponentVerifierExtension.java b/components/camel-twitter/src/main/java/org/apache/camel/component/twitter/TwitterComponentVerifierExtension.java
new file mode 100644
index 0000000..f92fa84
--- /dev/null
+++ b/components/camel-twitter/src/main/java/org/apache/camel/component/twitter/TwitterComponentVerifierExtension.java
@@ -0,0 +1,94 @@
+/**
+ * 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;
+
+import java.util.Map;
+
+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.component.extension.verifier.ResultErrorHelper;
+import twitter4j.Twitter;
+import twitter4j.TwitterException;
+
+public final class TwitterComponentVerifierExtension extends DefaultComponentVerifierExtension {
+
+    public TwitterComponentVerifierExtension() {
+        this("twitter");
+    }
+
+    public TwitterComponentVerifierExtension(String scheme) {
+        super(scheme);
+    }
+
+    // *********************************
+    // Parameters validation
+    // *********************************
+
+    @Override
+    protected Result verifyParameters(Map<String, Object> parameters) {
+        ResultBuilder builder = ResultBuilder.withStatusAndScope(Result.Status.OK, Scope.PARAMETERS)
+            .error(ResultErrorHelper.requiresOption("accessToken", parameters))
+            .error(ResultErrorHelper.requiresOption("accessTokenSecret", parameters))
+            .error(ResultErrorHelper.requiresOption("consumerKey", parameters))
+            .error(ResultErrorHelper.requiresOption("consumerSecret", parameters));
+
+        // Validate using the catalog
+        super.verifyParametersAgainstCatalog(builder, parameters);
+
+        return builder.build();
+    }
+
+    // *********************************
+    // Connectivity validation
+    // *********************************
+
+    @Override
+    protected Result verifyConnectivity(Map<String, Object> parameters) {
+        return ResultBuilder.withStatusAndScope(Result.Status.OK, Scope.CONNECTIVITY)
+            .error(parameters, this::verifyCredentials)
+            .build();
+    }
+
+    private void verifyCredentials(ResultBuilder builder, Map<String, Object> parameters) throws Exception {
+        try {
+            TwitterConfiguration configuration = setProperties(new TwitterConfiguration(), parameters);
+            Twitter twitter = configuration.getTwitter();
+
+            twitter.verifyCredentials();
+        } catch (TwitterException e) {
+            // verifyCredentials throws TwitterException when Twitter service or
+            // network is unavailable or if supplied credential is wrong
+            ResultErrorBuilder errorBuilder = ResultErrorBuilder.withCodeAndDescription(VerificationError.StandardCode.AUTHENTICATION, e.getErrorMessage())
+                .detail("twitter_error_code", e.getErrorCode())
+                .detail("twitter_status_code", e.getStatusCode())
+                .detail("twitter_exception_code", e.getExceptionCode())
+                .detail("twitter_exception_message", e.getMessage())
+                .detail("twitter_exception_caused-by-network-issue", e.isCausedByNetworkIssue())
+                .detail(VerificationError.ExceptionAttribute.EXCEPTION_CLASS, e.getClass().getName())
+                .detail(VerificationError.ExceptionAttribute.EXCEPTION_INSTANCE, e);
+
+            // For a complete list of error codes see:
+            //   https://dev.twitter.com/overview/api/response-codes
+            if (e.getErrorCode() == 89) {
+                errorBuilder.parameterKey("accessToken");
+            }
+
+            builder.error(errorBuilder.build());
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/42529399/components/camel-twitter/src/main/java/org/apache/camel/component/twitter/directmessage/TwitterDirectMessageComponent.java
----------------------------------------------------------------------
diff --git a/components/camel-twitter/src/main/java/org/apache/camel/component/twitter/directmessage/TwitterDirectMessageComponent.java b/components/camel-twitter/src/main/java/org/apache/camel/component/twitter/directmessage/TwitterDirectMessageComponent.java
index 516bb31..7ad0636 100644
--- a/components/camel-twitter/src/main/java/org/apache/camel/component/twitter/directmessage/TwitterDirectMessageComponent.java
+++ b/components/camel-twitter/src/main/java/org/apache/camel/component/twitter/directmessage/TwitterDirectMessageComponent.java
@@ -18,10 +18,9 @@ package org.apache.camel.component.twitter.directmessage;
 
 import java.util.Map;
 
-import org.apache.camel.ComponentVerifier;
+import org.apache.camel.CamelContext;
 import org.apache.camel.Endpoint;
 import org.apache.camel.component.twitter.AbstractTwitterComponent;
-import org.apache.camel.component.twitter.DefaultTwitterComponentVerifier;
 import org.apache.camel.component.twitter.TwitterConfiguration;
 import org.apache.camel.spi.Metadata;
 
@@ -31,14 +30,16 @@ import org.apache.camel.spi.Metadata;
 @Metadata(label = "verifiers", enums = "parameters,connectivity")
 public class TwitterDirectMessageComponent extends AbstractTwitterComponent {
 
-    protected Endpoint doCreateEndpoint(TwitterConfiguration properties, String uri, String remaining, Map<String, Object> parameters) throws Exception {
-        return new TwitterDirectMessageEndpoint(uri, remaining, this, properties);
+    public TwitterDirectMessageComponent() {
+        super("twitter-directmessage");
+    }
+
+    public TwitterDirectMessageComponent(CamelContext context) {
+        super(context, "twitter-directmessage");
     }
 
-    /**
-     * Get a verifier for the twitter directmessage component.
-     */
-    public ComponentVerifier getVerifier() {
-        return new DefaultTwitterComponentVerifier(this, "twitter-directmessage");
+    @Override
+    protected Endpoint doCreateEndpoint(TwitterConfiguration properties, String uri, String remaining, Map<String, Object> parameters) throws Exception {
+        return new TwitterDirectMessageEndpoint(uri, remaining, this, properties);
     }
 }

http://git-wip-us.apache.org/repos/asf/camel/blob/42529399/components/camel-twitter/src/main/java/org/apache/camel/component/twitter/search/TwitterSearchComponent.java
----------------------------------------------------------------------
diff --git a/components/camel-twitter/src/main/java/org/apache/camel/component/twitter/search/TwitterSearchComponent.java b/components/camel-twitter/src/main/java/org/apache/camel/component/twitter/search/TwitterSearchComponent.java
index 8457887..5123ab2 100644
--- a/components/camel-twitter/src/main/java/org/apache/camel/component/twitter/search/TwitterSearchComponent.java
+++ b/components/camel-twitter/src/main/java/org/apache/camel/component/twitter/search/TwitterSearchComponent.java
@@ -18,11 +18,9 @@ package org.apache.camel.component.twitter.search;
 
 import java.util.Map;
 
-import org.apache.camel.ComponentVerifier;
+import org.apache.camel.CamelContext;
 import org.apache.camel.Endpoint;
-import org.apache.camel.VerifiableComponent;
 import org.apache.camel.component.twitter.AbstractTwitterComponent;
-import org.apache.camel.component.twitter.DefaultTwitterComponentVerifier;
 import org.apache.camel.component.twitter.TwitterConfiguration;
 import org.apache.camel.spi.Metadata;
 
@@ -32,14 +30,16 @@ import org.apache.camel.spi.Metadata;
 @Metadata(label = "verifiers", enums = "parameters,connectivity")
 public class TwitterSearchComponent extends AbstractTwitterComponent {
 
-    protected Endpoint doCreateEndpoint(TwitterConfiguration properties, String uri, String remaining, Map<String, Object> parameters) throws Exception {
-        return new TwitterSearchEndpoint(uri, remaining, this, properties);
+    public TwitterSearchComponent() {
+        super("twitter-search");
+    }
+
+    public TwitterSearchComponent(CamelContext context) {
+        super(context, "twitter-search");
     }
 
-    /**
-     * Get a verifier for the twitter search component.
-     */
-    public ComponentVerifier getVerifier() {
-        return new DefaultTwitterComponentVerifier(this, "twitter-search");
+    @Override
+    protected Endpoint doCreateEndpoint(TwitterConfiguration properties, String uri, String remaining, Map<String, Object> parameters) throws Exception {
+        return new TwitterSearchEndpoint(uri, remaining, this, properties);
     }
 }

http://git-wip-us.apache.org/repos/asf/camel/blob/42529399/components/camel-twitter/src/main/java/org/apache/camel/component/twitter/streaming/TwitterStreamingComponent.java
----------------------------------------------------------------------
diff --git a/components/camel-twitter/src/main/java/org/apache/camel/component/twitter/streaming/TwitterStreamingComponent.java b/components/camel-twitter/src/main/java/org/apache/camel/component/twitter/streaming/TwitterStreamingComponent.java
index 1ccf160..5de57a0 100644
--- a/components/camel-twitter/src/main/java/org/apache/camel/component/twitter/streaming/TwitterStreamingComponent.java
+++ b/components/camel-twitter/src/main/java/org/apache/camel/component/twitter/streaming/TwitterStreamingComponent.java
@@ -18,10 +18,9 @@ package org.apache.camel.component.twitter.streaming;
 
 import java.util.Map;
 
-import org.apache.camel.ComponentVerifier;
+import org.apache.camel.CamelContext;
 import org.apache.camel.Endpoint;
 import org.apache.camel.component.twitter.AbstractTwitterComponent;
-import org.apache.camel.component.twitter.DefaultTwitterComponentVerifier;
 import org.apache.camel.component.twitter.TwitterConfiguration;
 import org.apache.camel.spi.Metadata;
 
@@ -31,15 +30,17 @@ import org.apache.camel.spi.Metadata;
 @Metadata(label = "verifiers", enums = "parameters,connectivity")
 public class TwitterStreamingComponent extends AbstractTwitterComponent {
 
+    public TwitterStreamingComponent() {
+        super("twitter-streaming");
+    }
+
+    public TwitterStreamingComponent(CamelContext context) {
+        super(context, "twitter-streaming");
+    }
+
+    @Override
     protected Endpoint doCreateEndpoint(TwitterConfiguration properties, String uri, String remaining, Map<String, Object> parameters) throws Exception {
         String keywords = getAndRemoveParameter(parameters, "keywords", String.class);
         return new TwitterStreamingEndpoint(uri, remaining, keywords, this, properties);
     }
-
-    /**
-     * Get a verifier for the twitter streaming component.
-     */
-    public ComponentVerifier getVerifier() {
-        return new DefaultTwitterComponentVerifier(this, "twitter-streaming");
-    }
 }

http://git-wip-us.apache.org/repos/asf/camel/blob/42529399/components/camel-twitter/src/main/java/org/apache/camel/component/twitter/timeline/TwitterTimelineComponent.java
----------------------------------------------------------------------
diff --git a/components/camel-twitter/src/main/java/org/apache/camel/component/twitter/timeline/TwitterTimelineComponent.java b/components/camel-twitter/src/main/java/org/apache/camel/component/twitter/timeline/TwitterTimelineComponent.java
index 0c9c885..ece0d0f 100644
--- a/components/camel-twitter/src/main/java/org/apache/camel/component/twitter/timeline/TwitterTimelineComponent.java
+++ b/components/camel-twitter/src/main/java/org/apache/camel/component/twitter/timeline/TwitterTimelineComponent.java
@@ -18,10 +18,9 @@ package org.apache.camel.component.twitter.timeline;
 
 import java.util.Map;
 
-import org.apache.camel.ComponentVerifier;
+import org.apache.camel.CamelContext;
 import org.apache.camel.Endpoint;
 import org.apache.camel.component.twitter.AbstractTwitterComponent;
-import org.apache.camel.component.twitter.DefaultTwitterComponentVerifier;
 import org.apache.camel.component.twitter.TwitterConfiguration;
 import org.apache.camel.spi.Metadata;
 
@@ -31,16 +30,17 @@ import org.apache.camel.spi.Metadata;
 @Metadata(label = "verifiers", enums = "parameters,connectivity")
 public class TwitterTimelineComponent extends AbstractTwitterComponent {
 
+    public TwitterTimelineComponent() {
+        super("twitter-timeline");
+    }
+
+    public TwitterTimelineComponent(CamelContext context) {
+        super(context, "twitter-timeline");
+    }
+
     @Override
     protected Endpoint doCreateEndpoint(TwitterConfiguration properties, String uri, String remaining, Map<String, Object> parameters) throws Exception {
         String user = getAndRemoveParameter(parameters, "user", String.class);
         return new TwitterTimelineEndpoint(uri, remaining, user, this, properties);
     }
-
-    /**
-     * Get a verifier for the twitter timeline component.
-     */
-    public ComponentVerifier getVerifier() {
-        return new DefaultTwitterComponentVerifier(this, "twitter-timeline");
-    }
 }

http://git-wip-us.apache.org/repos/asf/camel/blob/42529399/components/camel-twitter/src/test/java/org/apache/camel/component/twitter/AbstractComponentVerifierExtensionTest.java
----------------------------------------------------------------------
diff --git a/components/camel-twitter/src/test/java/org/apache/camel/component/twitter/AbstractComponentVerifierExtensionTest.java b/components/camel-twitter/src/test/java/org/apache/camel/component/twitter/AbstractComponentVerifierExtensionTest.java
new file mode 100644
index 0000000..21331da
--- /dev/null
+++ b/components/camel-twitter/src/test/java/org/apache/camel/component/twitter/AbstractComponentVerifierExtensionTest.java
@@ -0,0 +1,82 @@
+/**
+ * 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;
+
+import java.util.Map;
+
+import org.apache.camel.Component;
+import org.apache.camel.component.extension.ComponentVerifierExtension;
+import org.junit.Assert;
+import org.junit.Test;
+
+
+public abstract class AbstractComponentVerifierExtensionTest extends CamelTwitterTestSupport {
+
+    protected abstract String getComponentScheme();
+    
+    @Override
+    public boolean isUseRouteBuilder() {
+        return false;
+    }
+
+    @Test
+    public void testConnectivity() {
+        Component component = context().getComponent(getComponentScheme());
+        ComponentVerifierExtension verifier = component.getExtension(ComponentVerifierExtension.class).orElseThrow(IllegalStateException::new);
+
+        Map<String, Object> parameters = getParameters();
+        ComponentVerifierExtension.Result result = verifier.verify(ComponentVerifierExtension.Scope.CONNECTIVITY, parameters);
+
+        Assert.assertEquals(ComponentVerifierExtension.Result.Status.OK, result.getStatus());
+    }
+
+    @Test
+    public void testInvalidKeyConfiguration() {
+        Component component = context().getComponent(getComponentScheme());
+        ComponentVerifierExtension verifier = component.getExtension(ComponentVerifierExtension.class).orElseThrow(IllegalStateException::new);
+
+        Map<String, Object> parameters = getParameters();
+        parameters.put("consumerKey", "invalid");
+
+        ComponentVerifierExtension.Result result = verifier.verify(ComponentVerifierExtension.Scope.CONNECTIVITY, parameters);
+
+        Assert.assertEquals(ComponentVerifierExtension.Result.Status.ERROR, result.getStatus());
+        Assert.assertEquals(1, result.getErrors().size());
+        Assert.assertEquals(ComponentVerifierExtension.VerificationError.StandardCode.AUTHENTICATION, result.getErrors().get(0).getCode());
+        Assert.assertEquals(401, result.getErrors().get(0).getDetails().get(ComponentVerifierExtension.VerificationError.asAttribute("twitter_status_code")));
+        Assert.assertEquals(32, result.getErrors().get(0).getDetails().get(ComponentVerifierExtension.VerificationError.asAttribute("twitter_error_code")));
+    }
+
+    @Test
+    public void testInvalidTokenConfiguration() {
+        Component component = context().getComponent(getComponentScheme());
+        ComponentVerifierExtension verifier = component.getExtension(ComponentVerifierExtension.class).orElseThrow(IllegalStateException::new);
+
+        Map<String, Object> parameters = getParameters();
+        parameters.put("accessToken", "invalid");
+
+        ComponentVerifierExtension.Result result = verifier.verify(ComponentVerifierExtension.Scope.CONNECTIVITY, parameters);
+
+        Assert.assertEquals(ComponentVerifierExtension.Result.Status.ERROR, result.getStatus());
+        Assert.assertEquals(1, result.getErrors().size());
+        Assert.assertEquals(ComponentVerifierExtension.VerificationError.StandardCode.AUTHENTICATION, result.getErrors().get(0).getCode());
+        Assert.assertEquals(401, result.getErrors().get(0).getDetails().get(ComponentVerifierExtension.VerificationError.asAttribute("twitter_status_code")));
+        Assert.assertEquals(89, result.getErrors().get(0).getDetails().get(ComponentVerifierExtension.VerificationError.asAttribute("twitter_error_code")));
+        Assert.assertEquals(1, result.getErrors().get(0).getParameterKeys().size());
+        Assert.assertEquals("accessToken", result.getErrors().get(0).getParameterKeys().iterator().next());
+    }
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/42529399/components/camel-twitter/src/test/java/org/apache/camel/component/twitter/AbstractComponentVerifierTest.java
----------------------------------------------------------------------
diff --git a/components/camel-twitter/src/test/java/org/apache/camel/component/twitter/AbstractComponentVerifierTest.java b/components/camel-twitter/src/test/java/org/apache/camel/component/twitter/AbstractComponentVerifierTest.java
new file mode 100644
index 0000000..703f7cf
--- /dev/null
+++ b/components/camel-twitter/src/test/java/org/apache/camel/component/twitter/AbstractComponentVerifierTest.java
@@ -0,0 +1,81 @@
+/**
+ * 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;
+
+import java.util.Map;
+
+import org.apache.camel.ComponentVerifier;
+import org.junit.Assert;
+import org.junit.Test;
+
+
+public abstract class AbstractComponentVerifierTest extends CamelTwitterTestSupport {
+
+    protected abstract String getComponentScheme();
+    
+    @Override
+    public boolean isUseRouteBuilder() {
+        return false;
+    }
+
+    @Test
+    public void testConnectivity() {
+        AbstractTwitterComponent component = context().getComponent(getComponentScheme(), AbstractTwitterComponent.class);
+        ComponentVerifier verifier = component.getVerifier();
+
+        Map<String, Object> parameters = getParameters();
+        ComponentVerifier.Result result = verifier.verify(ComponentVerifier.Scope.CONNECTIVITY, parameters);
+
+        Assert.assertEquals(ComponentVerifier.Result.Status.OK, result.getStatus());
+    }
+
+    @Test
+    public void testInvalidKeyConfiguration() {
+        AbstractTwitterComponent component = context().getComponent(getComponentScheme(), AbstractTwitterComponent.class);
+        ComponentVerifier verifier = component.getVerifier();
+
+        Map<String, Object> parameters = getParameters();
+        parameters.put("consumerKey", "invalid");
+
+        ComponentVerifier.Result result = verifier.verify(ComponentVerifier.Scope.CONNECTIVITY, parameters);
+
+        Assert.assertEquals(ComponentVerifier.Result.Status.ERROR, result.getStatus());
+        Assert.assertEquals(1, result.getErrors().size());
+        Assert.assertEquals(ComponentVerifier.VerificationError.StandardCode.AUTHENTICATION, result.getErrors().get(0).getCode());
+        Assert.assertEquals(401, result.getErrors().get(0).getDetails().get(ComponentVerifier.VerificationError.asAttribute("twitter_status_code")));
+        Assert.assertEquals(32, result.getErrors().get(0).getDetails().get(ComponentVerifier.VerificationError.asAttribute("twitter_error_code")));
+    }
+
+    @Test
+    public void testInvalidTokenConfiguration() {
+        AbstractTwitterComponent component = context().getComponent(getComponentScheme(), AbstractTwitterComponent.class);
+        ComponentVerifier verifier = component.getVerifier();
+
+        Map<String, Object> parameters = getParameters();
+        parameters.put("accessToken", "invalid");
+
+        ComponentVerifier.Result result = verifier.verify(ComponentVerifier.Scope.CONNECTIVITY, parameters);
+
+        Assert.assertEquals(ComponentVerifier.Result.Status.ERROR, result.getStatus());
+        Assert.assertEquals(1, result.getErrors().size());
+        Assert.assertEquals(ComponentVerifier.VerificationError.StandardCode.AUTHENTICATION, result.getErrors().get(0).getCode());
+        Assert.assertEquals(401, result.getErrors().get(0).getDetails().get(ComponentVerifier.VerificationError.asAttribute("twitter_status_code")));
+        Assert.assertEquals(89, result.getErrors().get(0).getDetails().get(ComponentVerifier.VerificationError.asAttribute("twitter_error_code")));
+        Assert.assertEquals(1, result.getErrors().get(0).getParameterKeys().size());
+        Assert.assertEquals("accessToken", result.getErrors().get(0).getParameterKeys().iterator().next());
+    }
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/42529399/components/camel-twitter/src/test/java/org/apache/camel/component/twitter/CamelComponentVerifierTest.java
----------------------------------------------------------------------
diff --git a/components/camel-twitter/src/test/java/org/apache/camel/component/twitter/CamelComponentVerifierTest.java b/components/camel-twitter/src/test/java/org/apache/camel/component/twitter/CamelComponentVerifierTest.java
deleted file mode 100644
index 28c2992..0000000
--- a/components/camel-twitter/src/test/java/org/apache/camel/component/twitter/CamelComponentVerifierTest.java
+++ /dev/null
@@ -1,123 +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.twitter;
-
-import java.util.Collections;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Map;
-
-import org.apache.camel.ComponentVerifier;
-import org.apache.camel.ComponentVerifier.VerificationError;
-import org.apache.camel.component.twitter.search.TwitterSearchComponent;
-import org.junit.Assert;
-import org.junit.Test;
-
-import static org.apache.camel.ComponentVerifier.VerificationError.asAttribute;
-
-public class CamelComponentVerifierTest extends CamelTwitterTestSupport {
-
-    @Override
-    public boolean isUseRouteBuilder() {
-        return false;
-    }
-
-    @Test
-    public void testConnectivity() {
-        TwitterSearchComponent component = context().getComponent("twitter-search", TwitterSearchComponent.class);
-        DefaultTwitterComponentVerifier verifier = (DefaultTwitterComponentVerifier)component.getVerifier();
-
-        Map<String, Object> parameters = getParameters();
-        ComponentVerifier.Result result = verifier.verify(ComponentVerifier.Scope.CONNECTIVITY, parameters);
-
-        Assert.assertEquals(ComponentVerifier.Result.Status.OK, result.getStatus());
-    }
-
-    @Test
-    public void testInvalidKeyConfiguration() {
-        TwitterSearchComponent component = context().getComponent("twitter-search", TwitterSearchComponent.class);
-        DefaultTwitterComponentVerifier verifier = (DefaultTwitterComponentVerifier)component.getVerifier();
-
-        Map<String, Object> parameters = getParameters();
-        parameters.put("consumerKey", "invalid");
-
-        ComponentVerifier.Result result = verifier.verify(ComponentVerifier.Scope.CONNECTIVITY, parameters);
-
-        Assert.assertEquals(ComponentVerifier.Result.Status.ERROR, result.getStatus());
-        Assert.assertEquals(1, result.getErrors().size());
-        Assert.assertEquals(VerificationError.StandardCode.AUTHENTICATION, result.getErrors().get(0).getCode());
-        Assert.assertEquals(401, result.getErrors().get(0).getDetails().get(asAttribute("twitter_status_code")));
-        Assert.assertEquals(32, result.getErrors().get(0).getDetails().get(asAttribute("twitter_error_code")));
-    }
-
-    @Test
-    public void testInvalidTokenConfiguration() {
-        TwitterSearchComponent component = context().getComponent("twitter-search", TwitterSearchComponent.class);
-        DefaultTwitterComponentVerifier verifier = (DefaultTwitterComponentVerifier)component.getVerifier();
-
-        Map<String, Object> parameters = getParameters();
-        parameters.put("accessToken", "invalid");
-
-        ComponentVerifier.Result result = verifier.verify(ComponentVerifier.Scope.CONNECTIVITY, parameters);
-
-        Assert.assertEquals(ComponentVerifier.Result.Status.ERROR, result.getStatus());
-        Assert.assertEquals(1, result.getErrors().size());
-        Assert.assertEquals(VerificationError.StandardCode.AUTHENTICATION, result.getErrors().get(0).getCode());
-        Assert.assertEquals(401, result.getErrors().get(0).getDetails().get(asAttribute("twitter_status_code")));
-        Assert.assertEquals(89, result.getErrors().get(0).getDetails().get(asAttribute("twitter_error_code")));
-        Assert.assertEquals(1, result.getErrors().get(0).getParameterKeys().size());
-        Assert.assertEquals("accessToken", result.getErrors().get(0).getParameterKeys().iterator().next());
-    }
-
-    @Test
-    public void testEmptyConfiguration() {
-        TwitterSearchComponent component = context().getComponent("twitter-search", TwitterSearchComponent.class);
-        DefaultTwitterComponentVerifier verifier = (DefaultTwitterComponentVerifier)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 (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(VerificationError.StandardCode.EXCEPTION, result.getErrors().get(0).getCode());
-            Assert.assertNotNull(result.getErrors().get(0).getDetails().get(VerificationError.ExceptionAttribute.EXCEPTION_INSTANCE));
-            Assert.assertTrue(result.getErrors().get(0).getDetails().get(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/TwitterComponentVerifierExtensionTest.java
----------------------------------------------------------------------
diff --git a/components/camel-twitter/src/test/java/org/apache/camel/component/twitter/TwitterComponentVerifierExtensionTest.java b/components/camel-twitter/src/test/java/org/apache/camel/component/twitter/TwitterComponentVerifierExtensionTest.java
new file mode 100644
index 0000000..d3fc2da
--- /dev/null
+++ b/components/camel-twitter/src/test/java/org/apache/camel/component/twitter/TwitterComponentVerifierExtensionTest.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 TwitterComponentVerifierExtensionTest extends AbstractComponentVerifierExtensionTest {
+    @Override
+    protected String getComponentScheme() {
+        return "twitter";
+    }
+}