CAMEL-10357: camel-servicenow: add per release model

Project: http://git-wip-us.apache.org/repos/asf/camel/repo
Commit: http://git-wip-us.apache.org/repos/asf/camel/commit/f655c941
Tree: http://git-wip-us.apache.org/repos/asf/camel/tree/f655c941
Diff: http://git-wip-us.apache.org/repos/asf/camel/diff/f655c941

Branch: refs/heads/camel-2.18.x
Commit: f655c94110ae14a3db5b2ce6409684deaa619846
Parents: 9916ee4
Author: lburgazzoli <lburgazz...@gmail.com>
Authored: Thu Sep 29 19:25:18 2016 +0200
Committer: lburgazzoli <lburgazz...@gmail.com>
Committed: Tue Oct 11 11:25:05 2016 +0200

----------------------------------------------------------------------
 .../src/main/docs/servicenow-component.adoc     | 242 ++++++++++++-----
 .../servicenow/AbstractServiceNowProcessor.java | 265 +++++++++++++++++++
 .../servicenow/AbstractServiceNowProducer.java  |  40 +++
 .../component/servicenow/ServiceNowClient.java  | 140 ++++++++++
 .../servicenow/ServiceNowComponent.java         |  10 +-
 .../servicenow/ServiceNowConfiguration.java     | 217 +++++++++++++++
 .../servicenow/ServiceNowConstants.java         |  88 +++---
 .../servicenow/ServiceNowDispatcher.java        |  55 ++++
 .../servicenow/ServiceNowEndpoint.java          |  46 +---
 .../servicenow/ServiceNowExceptionMapper.java   |  23 +-
 .../component/servicenow/ServiceNowParam.java   |  28 ++
 .../component/servicenow/ServiceNowParams.java  | 123 +++++++++
 .../servicenow/ServiceNowProducer.java          |  86 +-----
 .../servicenow/ServiceNowProducerProcessor.java | 139 ----------
 .../servicenow/ServiceNowProducerSupplier.java  |  22 ++
 .../component/servicenow/ServiceNowRelease.java |  41 +++
 .../auth/AuthenticationRequestFilter.java       |   4 +-
 .../component/servicenow/auth/OAuthToken.java   |   8 +-
 .../servicenow/model/ServiceNowAggregate.java   |  50 ----
 .../model/ServiceNowAggregateProcessor.java     |  68 -----
 .../servicenow/model/ServiceNowImportSet.java   |  48 ----
 .../model/ServiceNowImportSetProcessor.java     |  79 ------
 .../servicenow/model/ServiceNowTable.java       | 108 --------
 .../model/ServiceNowTableProcessor.java         | 169 ------------
 .../fuji/FujiServiceNowAggregateProcessor.java  |  68 +++++
 .../fuji/FujiServiceNowImportSetProcessor.java  |  77 ++++++
 .../releases/fuji/FujiServiceNowProcessor.java  |  55 ++++
 .../releases/fuji/FujiServiceNowProducer.java   |  36 +++
 .../fuji/FujiServiceNowTableProcessor.java      | 163 ++++++++++++
 .../HelsinkiServiceNowAggregateProcessor.java   |  74 ++++++
 .../HelsinkiServiceNowAttachmentProcessor.java  | 168 ++++++++++++
 .../HelsinkiServiceNowImportSetProcessor.java   |  82 ++++++
 .../HelsinkiServiceNowMiscProcessor.java        |  89 +++++++
 .../helsinki/HelsinkiServiceNowProducer.java    |  42 +++
 .../HelsinkiServiceNowScorecardProcessor.java   |  84 ++++++
 ...iServiceNowServiceCatalogCartsProcessor.java | 200 ++++++++++++++
 ...iceNowServiceCatalogCategoriesProcessor.java |  66 +++++
 ...iServiceNowServiceCatalogItemsProcessor.java | 199 ++++++++++++++
 ...lsinkiServiceNowServiceCatalogProcessor.java | 110 ++++++++
 .../HelsinkiServiceNowTableProcessor.java       | 191 +++++++++++++
 .../servicenow/ServiceNowAttachmentTest.java    | 133 ++++++++++
 .../servicenow/ServiceNowScorecardTest.java     |  67 +++++
 .../ServiceNowServiceCatalogTest.java           |  97 +++++++
 .../servicenow/ServiceNowTableTest.java         |  57 ++--
 .../component/servicenow/ServiceNowTest.java    |  10 +-
 .../servicenow/ServiceNowTestSupport.java       |   7 +-
 .../servicenow/model/AttachmentMeta.java        |  92 +++++++
 .../component/servicenow/model/Incident.java    |   1 +
 .../component/servicenow/model/Scorecard.java   |  46 ++++
 .../src/test/resources/my-content.txt           |  16 ++
 50 files changed, 3411 insertions(+), 918 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/camel/blob/f655c941/components/camel-servicenow/src/main/docs/servicenow-component.adoc
----------------------------------------------------------------------
diff --git 
a/components/camel-servicenow/src/main/docs/servicenow-component.adoc 
b/components/camel-servicenow/src/main/docs/servicenow-component.adoc
index d4537fb..5869258 100644
--- a/components/camel-servicenow/src/main/docs/servicenow-component.adoc
+++ b/components/camel-servicenow/src/main/docs/servicenow-component.adoc
@@ -4,9 +4,10 @@ ServiceNow Component
 
 *Available as of Camel 2.18*
 
-The ServiceNow component provides access to all of ServiceNow
-https://developer.servicenow.com/app.do#!/rest_api_doc?v=fuji[REST
-API]. 
+The ServiceNow component provides access to ServiceNow platform through their 
REST API.
+
+NOTE: From Camel 2.18.1 the component supports multiple version of ServiceNow 
platform with default to Helsinki. Supported version are <<ServiceNow-Fuji>> 
and <<ServiceNow-Helsinki>>
+
 
 Maven users will need to add the following dependency to their pom.xml
 for this component:
@@ -39,23 +40,36 @@ The ServiceNow component has no options.
 // component options: END
 
 
-
-
 // endpoint options: START
-The ServiceNow component supports 16 endpoint options which are listed below:
+The ServiceNow component supports 31 endpoint options which are listed below:
 
 {% raw %}
 [width="100%",cols="2,1,1m,1m,5",options="header"]
 |=======================================================================
 | Name | Group | Default | Java Type | Description
 | instanceName | producer |  | String | *Required* The ServiceNow instance name
+| display | producer | true | String | Set this parameter to true to return 
only scorecards where the indicator Display field is selected. Set this 
parameter to all to return scorecards with any Display field value. This 
parameter is true by default.
 | displayValue | producer | false | String | Return the display value (true) 
actual value (false) or both (all) for reference fields (default: false)
 | excludeReferenceLink | producer |  | Boolean | True to exclude Table API 
links for reference fields (default: false)
+| favorites | producer |  | Boolean | Set this parameter to true to return 
only scorecards that are favorites of the querying user.
+| includeAggregates | producer |  | Boolean | Set this parameter to true to 
always return all available aggregates for an indicator including when an 
aggregate has already been applied. If a value is not specified this parameter 
defaults to false and returns no aggregates.
+| includeAvailableAggregates | producer |  | Boolean | Set this parameter to 
true to return all available aggregates for an indicator when no aggregate has 
been applied. If a value is not specified this parameter defaults to false and 
returns no aggregates.
+| includeAvailableBreakdowns | producer |  | Boolean | Set this parameter to 
true to return all available breakdowns for an indicator. If a value is not 
specified this parameter defaults to false and returns no breakdowns.
+| includeScoreNotes | producer |  | Boolean | Set this parameter to true to 
return all notes associated with the score. The note element contains the note 
text as well as the author and timestamp when the note was added.
+| includeScores | producer |  | Boolean | Set this parameter to true to return 
all scores for a scorecard. If a value is not specified this parameter defaults 
to false and returns only the most recent score value.
 | inputDisplayValue | producer |  | Boolean | True to set raw value of input 
fields (default: false)
+| key | producer |  | Boolean | Set this parameter to true to return only 
scorecards for key indicators.
 | models | producer |  | String | Defines the default model to use for a table
+| perPage | producer | 10 | Integer | Enter the maximum number of scorecards 
each query can return. By default this value is 10 and the maximum is 100.
+| release | producer | HELSINKI | ServiceNowRelease | The ServiceNow release 
to target default to Helsinki See https://docs.servicenow.com
 | resource | producer |  | String | The default resource can be overridden by 
header CamelServiceNowResource
+| sortBy | producer |  | String | Specify the value to use when sorting 
results. By default queries sort records by value.
+| sortDir | producer |  | String | Specify the sort direction ascending or 
descending. By default queries sort records in descending order. Use 
sysparm_sortdir=asc to sort in ascending order.
 | suppressAutoSysField | producer |  | Boolean | True to suppress auto 
generation of system fields (default: false)
+| suppressPaginationHeader | producer |  | Boolean | Set this value to true to 
remove the Link header from the response. The Link header allows you to request 
additional pages of data when the number of records matching your query exceeds 
the query limit
 | table | producer |  | String | The default table can be overridden by header 
CamelServiceNowTable
+| target | producer |  | Boolean | Set this parameter to true to return only 
scorecards that have a target.
+| topLevelOnly | producer |  | Boolean | Gets only those categories whose 
parent is a catalog.
 | mapper | advanced |  | ObjectMapper | Sets Jackson's ObjectMapper to use for 
request/reply
 | synchronous | advanced | false | boolean | Sets whether synchronous 
processing should be strictly used or Camel is allowed to use asynchronous 
processing (if supported).
 | apiUrl | security |  | String | The ServiceNow REST API url
@@ -74,67 +88,160 @@ The ServiceNow component supports 16 endpoint options 
which are listed below:
 Headers
 ^^^^^^^
 
-[width="100%",cols="10%,10%,80%",options="header",]
-|=======================================================================
-|Name |Type |Description
-
-|CamelServiceNowResource |String |The resource to access TABLE, AGGREGATE, 
IMPORT
-
-|CamelServiceNowTable |String |The table to access
-
-|CamelServiceNowAction |String |The action to perform RETRIEVE, CREATE, 
MODIFY, DELETE, UPDATE
-
-|CamelServiceNowModel |Class |The data model
-
-|CamelServiceNowSysId |String |ServiceNow sysy_id
-
-|CamelServiceNowQuery |String |An encoded query
-
-|CamelServiceNowDisplayValue |String |Return the display value (true), actual 
value (false), or both (all) for
-reference fields (default: false)
-
-|CamelServiceNowInputDisplayValue |Boolean |True to set raw value of input 
fields
-
-|CamelServiceNowExcludeReferenceLink |Boolean |True to exclude Table API links 
for reference fields
-
-|CamelServiceNowFields |String |Comma-separated field names to return in the 
response
-
-|CamelServiceNowMinFields |String |A comma-separated list of fields for which 
to calculate the minimum
-value
-
-|CamelServiceNowMaxFields |String |A comma-separated list of fields for which 
to calculate the maximum
-value
-
-|CamelServiceNowSumFields |String |A comma-separated list of fields for which 
to calculate the sum of the
-values
-
-|CamelServiceNowLimit |Integer |Limit to be applied on pagination
-
-|CamelServiceNowView |String |UI view to determine fields returned in the 
response.
-
-|CamelServiceNowSuppressAutoSysField |Boolean |True to suppress auto 
generation of system fields
-
-|CamelServiceNowAvgFields |String |A comma-separated list of fields for which 
to calculate the average
-value
-
-|CamelServiceNowCount |Boolean |A boolean flag. You can set this parameter to 
*true* for the number of
-records returned by the query
-
-|CamelServiceGroupBy |String |The fields to group the returned data by
-
-|CamelServiceOrderBy |String |A list of values to order grouped results by
-
-|CamelServiceHaving |String |An additional query allowing you to filter the 
data based on an
-aggregate operation
-|=======================================================================
+[width="100%",cols="10%,10%,10%,10%,60%",options="header",]
+|===
+|Name |Type |ServiceNow API Parameter |Endpoint option |Description
+|CamelServiceNowResource |String | - | - | The resource to access
+|CamelServiceNowAction |String | - | - | The action to perform
+|CamelServiceNowActionSubject | - | - | String |The subject to which the 
action should be applied
+|CamelServiceNowModel |Class | - | - | The data model
+|CamelServiceNowOffsetNext | - | - | - | -
+|CamelServiceNowOffsetPrev | - | - | - | -
+|CamelServiceNowOffsetFirst | - | - | - | -
+|CamelServiceNowOffsetLast | - | - | - | -
+|CamelServiceNowContentType | - | - | - | -
+|CamelServiceNowContentEncoding | - | - | - | -
+|CamelServiceNowContentMeta | - | - | - | -
+|CamelServiceNowSysId |String | sys_id | - | -
+|CamelServiceNowUserSysId |String | user_sysid | - | -
+|CamelServiceNowUserId |String | user_id | - | -
+|CamelServiceNowCartItemId |String | cart_item_id | - | -
+|CamelServiceNowFileName |String | file_name | - | -
+|CamelServiceNowTable |String | table_name | - | -
+|CamelServiceNowTableSysId |String | table_sys_id | - | -
+|CamelServiceNowEncryptionContext | String | encryption_context | - | -
+|CamelServiceNowCategory | String | sysparm_category  | - | -
+|CamelServiceNowType |String | sysparm_type | - | -
+|CamelServiceNowCatalog | String | sysparm_catalog | - | -
+|CamelServiceNowQuery |String | sysparm_query | - | -
+|CamelServiceNowDisplayValue |String | sysparm_display_value | displayValue  | 
-
+|CamelServiceNowInputDisplayValue |Boolean | sysparm_input_display_value | 
inputDisplayValue  | -
+|CamelServiceNowExcludeReferenceLink |Boolean | sysparm_exclude_reference_link 
| excludeReferenceLink  | -
+|CamelServiceNowFields |String | sysparm_fields | - | -
+|CamelServiceNowLimit |Integer | sysparm_limit | - | -
+|CamelServiceNowText | String | sysparm_text | - | -
+|CamelServiceNowOffset | Integer | sysparm_offset | - | -
+|CamelServiceNowView |String | sysparm_view | - | -
+|CamelServiceNowSuppressAutoSysField |Boolean | 
sysparm_suppress_auto_sys_field | suppressAutoSysField | -
+|CamelServiceNowSuppressPaginationHeader | Booleab | 
sysparm_suppress_pagination_header | suppressPaginationHeader | -
+|CamelServiceNowMinFields |String | sysparm_min_fields | - | -
+|CamelServiceNowMaxFields |String | sysparm_max_fields | - | -
+|CamelServiceNowSumFields |String | sysparm_sum_fields | - | -
+|CamelServiceNowAvgFields |String | sysparm_avg_fields | - | -
+|CamelServiceNowCount |Boolean | sysparm_count | - | -
+|CamelServiceGroupBy |String | sysparm_group_by | - | -
+|CamelServiceOrderBy |String | sysparm_order_by | - | -
+|CamelServiceHaving |String | sysparm_having | - | -
+|CamelServiceNowUUID |String | sysparm_uuid | - | -
+|CamelServiceNowBreakdown| String| sysparm_breakdown | - | -
+|CamelServiceNowIncludeScores| Boolean | sysparm_include_scores | 
includeScores | -
+|CamelServiceNowIncludeScoreNotes | Boolean | sysparm_include_score_notes | 
includeScoreNotes | -
+|CamelServiceNowIncludeAggregates | Boolean | sysparm_include_aggregates | 
includeAggregates | -
+|CamelServiceNowIncludeAvailableBreakdowns | Boolean | 
sysparm_include_available_breakdowns | includeAvailableBreakdowns | -
+|CamelServiceNowIncludeAvailableAggregates | Boolean | 
sysparm_include_available_aggregates | includeAvailableAggregates | -
+|CamelServiceNowFavorites | Boolean | sysparm_favorites | favorites | -
+|CamelServiceNowKey  | Boolean | sysparm_key | key | -
+|CamelServiceNowTarget | Boolean | sysparm_target | target | -
+|CamelServiceNowDisplay | String | sysparm_display | display | -
+|CamelServiceNowPerPage | Integer | sysparm_per_page | perPage | -
+|CamelServiceNowSortBy | String | sysparm_sortby | sortBy | -
+|CamelServiceNowSortDir | String | sysparm_sortdit | sortDir | -
+|CamelServiceNowContains | String | sysparm_contains | - | -
+|CamelServiceNowTags | String | sysparm_tags | - | -
+|CamelServiceNowPage | String | sysparm_page | - | -
+|CamelServiceNowElementsFilter | String | sysparm_elements_filter | - | -
+|CamelServiceNowBreakdownRelation | String | sysparm_breakdown_relation | - | -
+|CamelServiceNowDataSource | String | sysparm_data_source | - | -
+|CamelServiceNowTopLevelOnly | Boolean | sysparm_top_level_only | topLevelOnly 
| -
+|===
+
+[[ServiceNow-Fuji]]
+[cols="10%a,10%a,10%a,70%a", options="header"]
+.API Mapping
+|===
+| CamelServiceNowResource | CamelServiceNowAction | Method | API URI
+1.5+<.^|TABLE
+| RETRIEVE | GET | /api/now/v1/table/{table_name}/{sys_id}
+| CREATE | POST | /api/now/v1/table/{table_name}
+| MODIFY | PUT | /api/now/v1/table/{table_name}/{sys_id}
+| DELETE | DELETE | /api/now/v1/table/{table_name}/{sys_id}
+| UPDATE | PATCH | /api/now/v1/table/{table_name}/{sys_id}
+
+| AGGREGATE
+| RETRIEVE | GET | /api/now/v1/stats/{table_name}
+
+1.2+<.^|IMPORT
+| RETRIEVE | GET | /api/now/import/{table_name}/{sys_id}
+| CREATE | POST | /api/now/import/{table_name}
+|===
+
+NOTE: 
link:http://wiki.servicenow.com/index.php?title=REST_API#Available_APIs[Fuji 
REST API Documentation]
+
+[[ServiceNow-Helsinki]]
+[cols="10%a,10%a,10%a,10%a,60%a", options="header"]
+.API Mapping
+|===
+| CamelServiceNowResource | CamelServiceNowAction | 
CamelServiceNowActionSubject | Method | API URI
+1.5+<.^|TABLE
+| RETRIEVE | | GET | /api/now/v1/table/{table_name}/{sys_id}
+| CREATE | | POST | /api/now/v1/table/{table_name}
+| MODIFY | | PUT | /api/now/v1/table/{table_name}/{sys_id}
+| DELETE | | DELETE | /api/now/v1/table/{table_name}/{sys_id}
+| UPDATE | | PATCH | /api/now/v1/table/{table_name}/{sys_id}
+
+| AGGREGATE
+| RETRIEVE | | GET | /api/now/v1/stats/{table_name}
+
+1.2+<.^|IMPORT
+| RETRIEVE | | GET | /api/now/import/{table_name}/{sys_id}
+| CREATE | | POST | /api/now/import/{table_name}
+
+1.4+<.^|ATTACHMENT
+| RETRIEVE | | GET | /api/now/api/now/attachment/{sys_id}
+| CONTENT | | GET | /api/now/attachment/{sys_id}/file
+| UPLOAD | | POST | /api/now/api/now/attachment/file
+| DELETE | | DELETE | /api/now/attachment/{sys_id}
+
+| SCORECARDS
+| RETRIEVE | PERFORMANCE_ANALYTICS | GET | /api/now/pa/scorecards
+
+1.2+<.^|MISC
+| RETRIEVE | USER_ROLE_INHERITANCE | GET | /api/global/user_role_inheritance
+| CREATE | IDENTIFY_RECONCILE | POST | /api/now/identifyreconcile
+
+1.2+<.^|SERVICE_CATALOG
+| RETRIEVE | | GET | /sn_sc/servicecatalog/catalogs/{sys_id}
+| RETRIEVE | CATEGORIES |  GET | 
/sn_sc/servicecatalog/catalogs/{sys_id}/categories
+
+1.5+<.^|SERVICE_CATALOG_ITEMS
+| RETRIEVE | | GET | /sn_sc/servicecatalog/items/{sys_id}
+| RETRIEVE | SUBMIT_GUIDE | POST | 
/sn_sc/servicecatalog/items/{sys_id}/submit_guide
+| RETRIEVE | CHECKOUT_GUIDE | POST | 
/sn_sc/servicecatalog/items/{sys_id}/checkout_guide
+| CREATE | SUBJECT_CART | POST | 
/sn_sc/servicecatalog/items/{sys_id}/add_to_cart
+| CREATE | SUBJECT_PRODUCER | POST | 
/sn_sc/servicecatalog/items/{sys_id}/submit_producer
+
+1.6+<.^|SERVICE_CATALOG_CARTS
+| RETRIEVE | | GET | /sn_sc/servicecatalog/cart
+| RETRIEVE | DELIVERY_ADDRESS | GET | 
/sn_sc/servicecatalog/cart/delivery_address/{user_id}
+| RETRIEVE | CHECKOUT | POST | /sn_sc/servicecatalog/cart/checkout
+| UPDATE | | POST | /sn_sc/servicecatalog/cart/{cart_item_id}
+| UPDATE | CHECKOUT | POST | /sn_sc/servicecatalog/cart/submit_order
+| DELETE | | DELETE | /sn_sc/servicecatalog/cart/{sys_id}/empty
+
+| SERVICE_CATALOG_CATEGORIES
+| RETRIEVE | | GET | /sn_sc/servicecatalog/categories/{sys_id}
+
+|===
+
+NOTE: 
https://docs.servicenow.com/bundle/helsinki-servicenow-platform/page/integrate/inbound-rest/reference/r_RESTResources.html[Helsinki
 REST API Documentation]
 
 [[ServiceNow-Usageexamples]]
 Usage examples:
 ^^^^^^^^^^^^^^^
-
  
 {% raw %}
 [source,java]
+.Retrieve 10 Incidents
 
-------------------------------------------------------------------------------------------------------------------
 context.addRoutes(new RouteBuilder() {
     public void configure() {
@@ -144,12 +251,17 @@ context.addRoutes(new RouteBuilder() {
                + "&password={{env:SERVICENOW_PASSWORD}}"
                + "&oauthClientId={{env:SERVICENOW_OAUTH2_CLIENT_ID}}"
                + "&oauthClientSecret={{env:SERVICENOW_OAUTH2_CLIENT_SECRET}}"
-               + 
"&model.incident=org.apache.camel.component.servicenow.model.Incident")
            .to("mock:servicenow");
     }
-}); Map<String, Object> headers = new 
HashMap<>();headers.put(ServiceNowConstants.RESOURCE, "table");
-headers.put(ServiceNowConstants.ACTION, ServiceNowConstants.ACTION_RETRIEVE);
-headers.put(ServiceNowConstants.SYSPARM_LIMIT, "10");
-headers.put(ServiceNowConstants.TABLE, 
"incident");template.sendBodyAndHeaders("direct:servicenow", null, headers);
+}); 
+
+FluentProducerTemplate.on(context)
+    .withHeader(ServiceNowConstants.RESOURCE, "table")
+    .withHeader(ServiceNowConstants.ACTION, 
ServiceNowConstants.ACTION_RETRIEVE)
+    .withHeader(ServiceNowConstants.SYSPARM_LIMIT.getId(), "10")
+    .withHeader(ServiceNowConstants.TABLE, "incident")
+    .withHeader(ServiceNowConstants.MODEL, Incident.class)
+    .to("direct:servicenow")
+    .send();
 
-------------------------------------------------------------------------------------------------------------------
 {% endraw %}

http://git-wip-us.apache.org/repos/asf/camel/blob/f655c941/components/camel-servicenow/src/main/java/org/apache/camel/component/servicenow/AbstractServiceNowProcessor.java
----------------------------------------------------------------------
diff --git 
a/components/camel-servicenow/src/main/java/org/apache/camel/component/servicenow/AbstractServiceNowProcessor.java
 
b/components/camel-servicenow/src/main/java/org/apache/camel/component/servicenow/AbstractServiceNowProcessor.java
new file mode 100644
index 0000000..56183b4
--- /dev/null
+++ 
b/components/camel-servicenow/src/main/java/org/apache/camel/component/servicenow/AbstractServiceNowProcessor.java
@@ -0,0 +1,265 @@
+/**
+ * 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.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import javax.ws.rs.core.HttpHeaders;
+import javax.ws.rs.core.Response;
+
+import com.fasterxml.jackson.databind.JavaType;
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import org.apache.camel.Exchange;
+import org.apache.camel.Message;
+import org.apache.camel.Processor;
+import org.apache.camel.util.ObjectHelper;
+import org.apache.camel.util.StringHelper;
+import org.apache.camel.util.URISupport;
+
+public abstract class AbstractServiceNowProcessor implements Processor {
+
+    protected final ServiceNowEndpoint endpoint;
+    protected final ServiceNowConfiguration config;
+    protected final ObjectMapper mapper;
+    protected final ServiceNowClient client;
+
+    // Cache for JavaTypes
+    private final JavaTypeCache javaTypeCache;
+    private final List<ServiceNowDispatcher> dispatchers;
+
+    protected AbstractServiceNowProcessor(ServiceNowEndpoint endpoint) throws 
Exception {
+        this.javaTypeCache = new JavaTypeCache();
+        this.endpoint = endpoint;
+        this.config = endpoint.getConfiguration();
+        this.mapper = ObjectHelper.notNull(config.getMapper(), "mapper");
+        this.client = new ServiceNowClient(config);
+        this.dispatchers = new ArrayList<>();
+    }
+
+    protected AbstractServiceNowProcessor setBodyAndHeaders(Message message, 
Class<?> model, Response response) throws Exception {
+        if (response != null) {
+            setHeaders(message, model, response);
+            setBody(message, model, response);
+        }
+
+        return this;
+    }
+
+    @Override
+    public void process(Exchange exchange) throws Exception {
+        final ServiceNowDispatcher dispatcher = findDispatcher(exchange);
+
+        if (dispatcher != null) {
+            dispatcher.process(exchange);
+        } else {
+            throw new IllegalArgumentException("Unable to process exchange");
+        }
+    }
+
+    // *********************************
+    // Header
+    // *********************************
+
+
+    protected AbstractServiceNowProcessor setHeaders(Message message, Class<?> 
model, Response response) throws Exception {
+        List<String> links = response.getStringHeaders().get(HttpHeaders.LINK);
+        if (links != null) {
+            for (String link : links) {
+                String[] parts = link.split(";");
+                if (parts.length != 2) {
+                    continue;
+                }
+
+                // Sanitize parts
+                String uri = ObjectHelper.between(parts[0], "<", ">");
+                String rel = 
StringHelper.removeQuotes(ObjectHelper.after(parts[1], "="));
+
+                Map<String, Object> query = URISupport.parseQuery(uri);
+                Object offset = 
query.get(ServiceNowParams.SYSPARM_OFFSET.getId());
+
+                if (offset != null) {
+                    switch (rel) {
+                    case ServiceNowConstants.LINK_FIRST:
+                        message.setHeader(ServiceNowConstants.OFFSET_FIRST, 
offset);
+                        break;
+                    case ServiceNowConstants.LINK_LAST:
+                        message.setHeader(ServiceNowConstants.OFFSET_LAST, 
offset);
+                        break;
+                    case ServiceNowConstants.LINK_NEXT:
+                        message.setHeader(ServiceNowConstants.OFFSET_NEXT, 
offset);
+                        break;
+                    case ServiceNowConstants.LINK_PREV:
+                        message.setHeader(ServiceNowConstants.OFFSET_PREV, 
offset);
+                        break;
+                    default:
+                        break;
+                    }
+                }
+            }
+        }
+
+        String attachmentMeta = 
response.getHeaderString(ServiceNowConstants.ATTACHMENT_META_HEADER);
+        if (ObjectHelper.isNotEmpty(attachmentMeta)) {
+            message.setHeader(
+                ServiceNowConstants.CONTENT_META,
+                mapper.readValue(attachmentMeta, Map.class)
+            );
+        }
+
+        copyHeader(response, HttpHeaders.CONTENT_TYPE, message, 
ServiceNowConstants.CONTENT_TYPE);
+        copyHeader(response, HttpHeaders.CONTENT_ENCODING, message, 
ServiceNowConstants.CONTENT_ENCODING);
+
+        if (model != null) {
+            message.getHeaders().putIfAbsent(ServiceNowConstants.MODEL, 
model.getName());
+        }
+
+        return this;
+    }
+
+    // *********************************
+    // Body
+    // *********************************
+
+    protected AbstractServiceNowProcessor setBody(Message message, Class<?> 
model, Response response) throws Exception {
+        if (message != null && response != null) {
+            if 
(ObjectHelper.isNotEmpty(response.getHeaderString(HttpHeaders.CONTENT_TYPE))) {
+                JsonNode node = response.readEntity(JsonNode.class);
+                Object body = unwrap(node, model);
+
+                if (body != null) {
+                    message.setBody(body);
+                }
+            }
+        }
+
+        return this;
+    }
+
+    protected AbstractServiceNowProcessor validateBody(Message message, 
Class<?> model) {
+        return validateBody(message.getBody(), model);
+    }
+
+    protected AbstractServiceNowProcessor validateBody(Object body, Class<?> 
model) {
+        ObjectHelper.notNull(body, "body");
+
+        if (!body.getClass().isAssignableFrom(model)) {
+            throw new IllegalArgumentException(
+                "Body is not compatible with model (body=" + body.getClass() + 
", model=" + model);
+        }
+
+        return this;
+    }
+
+    protected Object unwrap(JsonNode answer, Class<?> model) throws 
IOException {
+        Object result = null;
+
+        if (answer != null) {
+            JsonNode node = answer.get("result");
+            if (node != null) {
+                if (node.isArray()) {
+                    if (model.isInstance(Map.class)) {
+                        // If the model is a Map, there's no need to use any
+                        // specific JavaType to instruct Jackson about the
+                        // expected element type
+                        result = mapper.treeToValue(node, List.class);
+                    } else {
+                        result = mapper.readValue(node.traverse(), 
javaTypeCache.get(model));
+                    }
+                } else {
+                    result = mapper.treeToValue(node, model);
+                }
+            }
+        }
+
+        return result;
+    }
+
+    // *********************************
+    // Helpers
+    // *********************************
+
+    protected final void addDispatcher(ServiceNowDispatcher dispatcher) {
+        this.dispatchers.add(dispatcher);
+    }
+
+    protected final void addDispatcher(String action, Processor processor) {
+        addDispatcher(ServiceNowDispatcher.on(action, null, processor));
+    }
+
+    protected final void addDispatcher(String action, String subject, 
Processor processor) {
+        addDispatcher(ServiceNowDispatcher.on(action, subject, processor));
+    }
+
+    protected final ServiceNowDispatcher findDispatcher(Exchange exchange) {
+        ServiceNowDispatcher dispatcher = null;
+        for (int i = 0; i < dispatchers.size(); i++) {
+            dispatcher = dispatchers.get(i);
+            if (dispatcher.match(exchange)) {
+                return dispatcher;
+            }
+        }
+
+        return null;
+    }
+
+    protected Object getRequestParamFromHeader(ServiceNowParam sysParam, 
Message message) {
+        return message.getHeader(
+            sysParam.getHeader(),
+            sysParam.getDefaultValue(config),
+            sysParam.getType()
+        );
+    }
+
+    protected Object getMandatoryRequestParamFromHeader(ServiceNowParam 
sysParam, Message message) {
+        return ObjectHelper.notNull(
+            getRequestParamFromHeader(sysParam, message),
+            sysParam.getHeader()
+        );
+    }
+
+    protected void copyHeader(Response from, String fromId, Message to, String 
toId) {
+        Object fromValue = from.getHeaders().getFirst(fromId);
+        if (ObjectHelper.isNotEmpty(fromValue)) {
+            to.setHeader(toId, fromValue);
+        }
+    }
+
+    protected Class<?> getModel(Message message) {
+        return getModel(message, null);
+    }
+
+    protected Class<?> getModel(Message message, String modelName) {
+        return message.getHeader(
+            ServiceNowConstants.MODEL,
+            ObjectHelper.isEmpty(modelName) ? Map.class : 
config.getModel(modelName, Map.class),
+            Class.class);
+    }
+
+    // 
*************************************************************************
+    // Use ClassValue to lazy create and cache JavaType
+    // 
*************************************************************************
+
+    private class JavaTypeCache extends ClassValue<JavaType> {
+        @Override
+        protected JavaType computeValue(Class<?> type) {
+            return mapper.getTypeFactory().constructCollectionType(List.class, 
type);
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/f655c941/components/camel-servicenow/src/main/java/org/apache/camel/component/servicenow/AbstractServiceNowProducer.java
----------------------------------------------------------------------
diff --git 
a/components/camel-servicenow/src/main/java/org/apache/camel/component/servicenow/AbstractServiceNowProducer.java
 
b/components/camel-servicenow/src/main/java/org/apache/camel/component/servicenow/AbstractServiceNowProducer.java
new file mode 100644
index 0000000..0fd23d7
--- /dev/null
+++ 
b/components/camel-servicenow/src/main/java/org/apache/camel/component/servicenow/AbstractServiceNowProducer.java
@@ -0,0 +1,40 @@
+/**
+ * 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 org.apache.camel.impl.HeaderSelectorProducer;
+
+public abstract class AbstractServiceNowProducer extends 
HeaderSelectorProducer implements ServiceNowProducer {
+    private final ServiceNowRelease release;
+    private final ServiceNowEndpoint endpoint;
+
+    public AbstractServiceNowProducer(ServiceNowEndpoint endpoint, 
ServiceNowRelease release) {
+        super(endpoint, ServiceNowConstants.RESOURCE, 
endpoint.getConfiguration().getResource());
+
+        this.release = release;
+        this.endpoint = endpoint;
+    }
+
+    @Override
+    public ServiceNowRelease getRelease() {
+        return release;
+    }
+
+    protected final ServiceNowConfiguration getConfiguration() {
+        return endpoint.getConfiguration();
+    }
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/f655c941/components/camel-servicenow/src/main/java/org/apache/camel/component/servicenow/ServiceNowClient.java
----------------------------------------------------------------------
diff --git 
a/components/camel-servicenow/src/main/java/org/apache/camel/component/servicenow/ServiceNowClient.java
 
b/components/camel-servicenow/src/main/java/org/apache/camel/component/servicenow/ServiceNowClient.java
new file mode 100644
index 0000000..b5f4136
--- /dev/null
+++ 
b/components/camel-servicenow/src/main/java/org/apache/camel/component/servicenow/ServiceNowClient.java
@@ -0,0 +1,140 @@
+/**
+ * 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.Arrays;
+import java.util.Map;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+
+import com.fasterxml.jackson.jaxrs.json.JacksonJsonProvider;
+import org.apache.camel.CamelException;
+import org.apache.camel.Message;
+import org.apache.camel.component.servicenow.auth.AuthenticationRequestFilter;
+import org.apache.cxf.jaxrs.client.WebClient;
+
+public class ServiceNowClient {
+    private final ServiceNowConfiguration configuration;
+    private final WebClient client;
+
+    public ServiceNowClient(ServiceNowConfiguration configuration) throws 
Exception {
+        this.configuration = configuration;
+        this.client = WebClient.create(
+            configuration.getApiUrl(),
+            Arrays.asList(
+                new AuthenticationRequestFilter(configuration),
+                new JacksonJsonProvider(configuration.getMapper()),
+                new ServiceNowExceptionMapper(configuration.getMapper())
+            ),
+            true
+        );
+
+        WebClient.getConfig(client)
+            .getRequestContext()
+            .put("org.apache.cxf.http.header.split", true);
+    }
+
+    public ServiceNowClient types(MediaType type) {
+        return types(type, type);
+    }
+
+    public ServiceNowClient types(MediaType accept, MediaType type) {
+        client.accept(accept);
+        client.type(type);
+        return this;
+    }
+
+    public ServiceNowClient path(Object path) {
+        client.path(path);
+        return this;
+    }
+
+    public ServiceNowClient type(MediaType ct) {
+        client.type(ct);
+        return this;
+    }
+
+    public ServiceNowClient type(String type) {
+        client.type(type);
+        return this;
+    }
+
+    public ServiceNowClient accept(MediaType... types) {
+        client.accept(types);
+        return this;
+    }
+
+    public ServiceNowClient accept(String... types) {
+        client.accept(types);
+        return this;
+    }
+
+    public ServiceNowClient query(String name, Object... values) {
+        client.query(name, values);
+        return this;
+    }
+
+    public ServiceNowClient query(ServiceNowParam param, Message message) {
+        Object value = param.getHeaderValue(message, configuration);
+        if (value != null) {
+            client.query(param.getId(), value);
+        }
+
+        return this;
+    }
+
+    public Response invoke(String httpMethod) throws Exception {
+        return invoke(httpMethod, null);
+    }
+
+    public Response invoke(String httpMethod, Object body) throws Exception {
+        Response response = client.invoke(httpMethod, body);
+        int code = response.getStatus();
+
+        // Only ServiceNow known error status codes are mapped
+        // See 
http://wiki.servicenow.com/index.php?title=REST_API#REST_Response_HTTP_Status_Codes
+        switch(code) {
+        case 200:
+        case 201:
+        case 204:
+            // Success
+            break;
+        case 400:
+        case 401:
+        case 403:
+        case 404:
+        case 405:
+        case 406:
+        case 415:
+            throw response.readEntity(ServiceNowException.class);
+        default:
+            throw new CamelException(
+                String.format("Status (%d): %s", code, 
response.readEntity(Map.class))
+            );
+        }
+
+        return response;
+    }
+
+    public ServiceNowClient reset() {
+        client.back(true);
+        client.reset();
+        client.resetQuery();
+
+        return this;
+    }
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/f655c941/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 30135c9..db0c6f9 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
@@ -47,6 +47,14 @@ public class ServiceNowComponent extends 
UriEndpointComponent {
 
         setProperties(configuration, parameters);
 
-        return new ServiceNowEndpoint(uri, this, configuration, remaining);
+        String instanceName = 
getCamelContext().resolvePropertyPlaceholders(remaining);
+        if (!configuration.hasApiUrl()) {
+            
configuration.setApiUrl(String.format("https://%s.service-now.com/api";, 
instanceName));
+        }
+        if (!configuration.hasOautTokenUrl()) {
+            
configuration.setOauthTokenUrl(String.format("https://%s.service-now.com/oauth_token.do";,
 instanceName));
+        }
+
+        return new ServiceNowEndpoint(uri, this, configuration, instanceName);
     }
 }

http://git-wip-us.apache.org/repos/asf/camel/blob/f655c941/components/camel-servicenow/src/main/java/org/apache/camel/component/servicenow/ServiceNowConfiguration.java
----------------------------------------------------------------------
diff --git 
a/components/camel-servicenow/src/main/java/org/apache/camel/component/servicenow/ServiceNowConfiguration.java
 
b/components/camel-servicenow/src/main/java/org/apache/camel/component/servicenow/ServiceNowConfiguration.java
index 8a465d5..9abfdfd 100644
--- 
a/components/camel-servicenow/src/main/java/org/apache/camel/component/servicenow/ServiceNowConfiguration.java
+++ 
b/components/camel-servicenow/src/main/java/org/apache/camel/component/servicenow/ServiceNowConfiguration.java
@@ -58,6 +58,34 @@ public class ServiceNowConfiguration {
     private Boolean excludeReferenceLink = false;
     @UriParam
     private Boolean suppressAutoSysField = false;
+    @UriParam
+    private Boolean includeScores = false;
+    @UriParam
+    private Boolean includeAggregates = false;
+    @UriParam
+    private Boolean includeAvailableBreakdowns = false;
+    @UriParam
+    private Boolean includeAvailableAggregates = false;
+    @UriParam
+    private Boolean includeScoreNotes = false;
+    @UriParam
+    private Boolean topLevelOnly;
+    @UriParam
+    private Boolean favorites;
+    @UriParam
+    private Boolean key;
+    @UriParam
+    private Boolean target;
+    @UriParam(defaultValue = "true", enums = "false,true,all")
+    private String display = "true";
+    @UriParam(defaultValue = "10")
+    private Integer perPage = 10;
+    @UriParam(enums = 
"value,change,changeperc,gap,gapperc,duedate,name,order,default,group,indicator_group,frequency,target,date,trend,bullet,direction")
+    private String sortBy;
+    @UriParam(enums = "asc,desc")
+    private String sortDir;
+    @UriParam
+    private Boolean suppressPaginationHeader = false;
     @UriParam(defaultValue = "false", enums = "false,true,all")
     private String displayValue = "false";
     @UriParam
@@ -66,6 +94,8 @@ public class ServiceNowConfiguration {
     private Map<String, Class<?>> models;
     @UriParam(label = "advanced")
     private ObjectMapper mapper = MAPPER;
+    @UriParam(defaultValue = "HELSINKI", enums = "FUJI,GENEVA,HELSINKI")
+    private ServiceNowRelease release = ServiceNowRelease.HELSINKY;
 
 
     public String getUserName() {
@@ -198,6 +228,169 @@ public class ServiceNowConfiguration {
         this.suppressAutoSysField = suppressAutoSysField;
     }
 
+    public Boolean getSuppressPaginationHeader() {
+        return suppressPaginationHeader;
+    }
+
+    /**
+     * Set this value to true to remove the Link header from the response. The
+     * Link header allows you to request additional pages of data when the 
number
+     * of records matching your query exceeds the query limit
+     */
+    public void setSuppressPaginationHeader(Boolean suppressPaginationHeader) {
+        this.suppressPaginationHeader = suppressPaginationHeader;
+    }
+
+    public Boolean getIncludeScores() {
+        return includeScores;
+    }
+
+    /**
+     * Set this parameter to true to return all scores for a scorecard. If a 
value
+     * is not specified, this parameter defaults to false and returns only the 
most
+     * recent score value.
+     */
+    public void setIncludeScores(Boolean includeScores) {
+        this.includeScores = includeScores;
+    }
+
+    public Boolean getIncludeAggregates() {
+        return includeAggregates;
+    }
+
+    /**
+     * Set this parameter to true to always return all available aggregates for
+     * an indicator, including when an aggregate has already been applied. If a
+     * value is not specified, this parameter defaults to false and returns no
+     * aggregates.
+     */
+    public void setIncludeAggregates(Boolean includeAggregates) {
+        this.includeAggregates = includeAggregates;
+    }
+
+    public Boolean getIncludeAvailableBreakdowns() {
+        return includeAvailableBreakdowns;
+    }
+
+    /**
+     * Set this parameter to true to return all available breakdowns for an 
indicator.
+     * If a value is not specified, this parameter defaults to false and 
returns
+     * no breakdowns.
+     */
+    public void setIncludeAvailableBreakdowns(Boolean 
includeAvailableBreakdowns) {
+        this.includeAvailableBreakdowns = includeAvailableBreakdowns;
+    }
+
+    public Boolean getIncludeAvailableAggregates() {
+        return includeAvailableAggregates;
+    }
+
+    /**
+     * Set this parameter to true to return all available aggregates for an 
indicator
+     * when no aggregate has been applied. If a value is not specified, this 
parameter
+     * defaults to false and returns no aggregates.
+     */
+    public void setIncludeAvailableAggregates(Boolean 
includeAvailableAggregates) {
+        this.includeAvailableAggregates = includeAvailableAggregates;
+    }
+
+    public Boolean getIncludeScoreNotes() {
+        return includeScoreNotes;
+    }
+
+    /**
+     * Set this parameter to true to return all notes associated with the 
score.
+     * The note element contains the note text as well as the author and 
timestamp
+     * when the note was added.
+     */
+    public void setIncludeScoreNotes(Boolean includeScoreNotes) {
+        this.includeScoreNotes = includeScoreNotes;
+    }
+
+    public Boolean getFavorites() {
+        return favorites;
+    }
+
+    /**
+     * Set this parameter to true to return only scorecards that are favorites 
of
+     * the querying user.
+     */
+    public void setFavorites(Boolean favorites) {
+        this.favorites = favorites;
+    }
+
+    public Boolean getKey() {
+        return key;
+    }
+
+    /**
+     * Set this parameter to true to return only scorecards for key indicators.
+     */
+    public void setKey(Boolean key) {
+        this.key = key;
+    }
+
+    public Boolean getTarget() {
+        return target;
+    }
+
+    /**
+     * Set this parameter to true to return only scorecards that have a target.
+     */
+    public void setTarget(Boolean target) {
+        this.target = target;
+    }
+
+    public String getDisplay() {
+        return display;
+    }
+
+    /**
+     * Set this parameter to true to return only scorecards where the indicator
+     * Display field is selected. Set this parameter to all to return 
scorecards
+     * with any Display field value. This parameter is true by default.
+     */
+    public void setDisplay(String display) {
+        this.display = display;
+    }
+
+    public Integer getPerPage() {
+        return perPage;
+    }
+
+    /**
+     * Enter the maximum number of scorecards each query can return. By default
+     * this value is 10, and the maximum is 100.
+     */
+    public void setPerPage(Integer perPage) {
+        this.perPage = perPage;
+    }
+
+    public String getSortBy() {
+        return sortBy;
+    }
+
+    /**
+     * Specify the value to use when sorting results. By default, queries sort
+     * records by value.
+     */
+    public void setSortBy(String sortBy) {
+        this.sortBy = sortBy;
+    }
+
+    public String getSortDir() {
+        return sortDir;
+    }
+
+    /**
+     * Specify the sort direction, ascending or descending. By default, queries
+     * sort records in descending order. Use sysparm_sortdir=asc to sort in
+     * ascending order.
+     */
+    public void setSortDir(String sortDir) {
+        this.sortDir = sortDir;
+    }
+
     public String getDisplayValue() {
         return displayValue;
     }
@@ -268,4 +461,28 @@ public class ServiceNowConfiguration {
     public boolean hasMapper() {
         return mapper != null;
     }
+
+    /**
+     * The ServiceNow release to target, default to Helsinki
+     *
+     * See https://docs.servicenow.com
+     */
+    public void setRelease(ServiceNowRelease release) {
+        this.release = release;
+    }
+
+    public ServiceNowRelease getRelease() {
+        return release;
+    }
+
+    public Boolean getTopLevelOnly() {
+        return topLevelOnly;
+    }
+
+    /**
+     * Gets only those categories whose parent is a catalog.
+     */
+    public void setTopLevelOnly(Boolean topLevelOnly) {
+        this.topLevelOnly = topLevelOnly;
+    }
 }

http://git-wip-us.apache.org/repos/asf/camel/blob/f655c941/components/camel-servicenow/src/main/java/org/apache/camel/component/servicenow/ServiceNowConstants.java
----------------------------------------------------------------------
diff --git 
a/components/camel-servicenow/src/main/java/org/apache/camel/component/servicenow/ServiceNowConstants.java
 
b/components/camel-servicenow/src/main/java/org/apache/camel/component/servicenow/ServiceNowConstants.java
index 8cd6c4b..e699dd7 100644
--- 
a/components/camel-servicenow/src/main/java/org/apache/camel/component/servicenow/ServiceNowConstants.java
+++ 
b/components/camel-servicenow/src/main/java/org/apache/camel/component/servicenow/ServiceNowConstants.java
@@ -16,37 +16,59 @@
  */
 package org.apache.camel.component.servicenow;
 
-public interface ServiceNowConstants {
-    String RESOURCE = "CamelServiceNowResource";
-    String TABLE = "CamelServiceNowTable";
-    String ACTION = "CamelServiceNowAction";
-    String MODEL = "CamelServiceNowModel";
-
-    String RESOURCE_TABLE = "table";
-    String RESOURCE_AGGREGATE = "aggregate";
-    String RESOURCE_IMPORT = "import";
-
-    String ACTION_RETRIEVE = "retrieve";
-    String ACTION_CREATE = "create";
-    String ACTION_MODIFY = "modify";
-    String ACTION_DELETE = "delete";
-    String ACTION_UPDATE = "update";
-
-    String SYSPARM_ID = "CamelServiceNowSysId";
-    String SYSPARM_QUERY = "CamelServiceNowQuery";
-    String SYSPARM_DISPLAY_VALUE = "CamelServiceNowDisplayValue";
-    String SYSPARM_INPUT_DISPLAY_VALUE = "CamelServiceNowInputDisplayValue";
-    String SYSPARM_EXCLUDE_REFERENCE_LINK = 
"CamelServiceNowExcludeReferenceLink";
-    String SYSPARM_FIELDS = "CamelServiceNowFields";
-    String SYSPARM_MIN_FIELDS = "CamelServiceNowMinFields";
-    String SYSPARM_MAX_FIELDS = "CamelServiceNowMaxFields";
-    String SYSPARM_SUM_FIELDS = "CamelServiceNowSumFields";
-    String SYSPARM_LIMIT = "CamelServiceNowLimit";
-    String SYSPARM_VIEW = "CamelServiceNowView";
-    String SYSPARM_SUPPRESS_AUTO_SYS_FIELD = 
"CamelServiceNowSuppressAutoSysField";
-    String SYSPARM_AVG_FIELDS = "CamelServiceNowAvgFields";
-    String SYSPARM_COUNT = "CamelServiceNowCount";
-    String SYSPARM_GROUP_BY = "CamelServiceGroupBy";
-    String SYSPARM_ORDER_BY = "CamelServiceOrderBy";
-    String SYSPARM_HAVING = "CamelServiceHaving";
+public final class ServiceNowConstants {
+    public static final String CAMEL_HEADER_PREFIX = "CamelServiceNow";
+
+    public static final String RESOURCE = "CamelServiceNowResource";
+    public static final String ACTION = "CamelServiceNowAction";
+    public static final String ACTION_SUBJECT = "CamelServiceNowActionSubject";
+    public static final String MODEL = "CamelServiceNowModel";
+    public static final String OFFSET_NEXT = "CamelServiceNowOffsetNext";
+    public static final String OFFSET_PREV = "CamelServiceNowOffsetPrev";
+    public static final String OFFSET_FIRST = "CamelServiceNowOffsetFirst";
+    public static final String OFFSET_LAST = "CamelServiceNowOffsetLast";
+    public static final String CONTENT_TYPE = "CamelServiceNowContentType";
+    public static final String CONTENT_ENCODING = 
"CamelServiceNowContentEncoding";
+    public static final String CONTENT_META = "CamelServiceNowContentMeta";
+
+    public static final String ATTACHMENT_META_HEADER = 
"X-Attachment-Metadata";
+
+    public static final String RESOURCE_TABLE = "table";
+    public static final String RESOURCE_AGGREGATE = "aggregate";
+    public static final String RESOURCE_IMPORT = "import";
+    public static final String RESOURCE_ATTACHMENT = "attachment";
+    public static final String RESOURCE_SCORECARDS = "scorecards";
+    public static final String RESOURCE_MISC = "misc";
+    public static final String RESOURCE_SERVICE_CATALOG = "service_catalog";
+    public static final String RESOURCE_SERVICE_CATALOG_ITEMS = 
"service_catalog_items";
+    public static final String RESOURCE_SERVICE_CATALOG_CARTS = 
"service_catalog_cart";
+    public static final String RESOURCE_SERVICE_CATALOG_CATEGORIES = 
"service_catalog_categories";
+
+    public static final String ACTION_RETRIEVE = "retrieve";
+    public static final String ACTION_CONTENT = "content";
+    public static final String ACTION_CREATE = "create";
+    public static final String ACTION_MODIFY = "modify";
+    public static final String ACTION_DELETE = "delete";
+    public static final String ACTION_UPDATE = "update";
+    public static final String ACTION_UPLOAD = "upload";
+
+    public static final String ACTION_SUBJECT_CATEGORIES = "categories";
+    public static final String ACTION_SUBJECT_CART = "cart";
+    public static final String ACTION_SUBJECT_PRODUCER = "producer";
+    public static final String ACTION_SUBJECT_GUIDE = "guide";
+    public static final String ACTION_SUBJECT_SUBMIT_GUIDE = "submit_guide";
+    public static final String ACTION_SUBJECT_CHECKOUT_GUIDE = 
"checkout_guide";
+    public static final String ACTION_SUBJECT_PERFORMANCE_ANALYTICS = 
"performance_analytics";
+    public static final String ACTION_SUBJECT_USER_ROLE_INHERITANCE = 
"user_role_inheritance";
+    public static final String ACTION_SUBJECT_IDENTIFY_RECONCILE = 
"identify_reconcile";
+    public static final String ACTION_SUBJECT_DELIVERY_ADDRESS = 
"delivery_address";
+    public static final String ACTION_SUBJECT_CHECKOUT = "checkout";
+
+    public static final String LINK_NEXT = "next";
+    public static final String LINK_PREV = "prev";
+    public static final String LINK_FIRST = "first";
+    public static final String LINK_LAST = "last";
+
+    private ServiceNowConstants() {
+    }
 }

http://git-wip-us.apache.org/repos/asf/camel/blob/f655c941/components/camel-servicenow/src/main/java/org/apache/camel/component/servicenow/ServiceNowDispatcher.java
----------------------------------------------------------------------
diff --git 
a/components/camel-servicenow/src/main/java/org/apache/camel/component/servicenow/ServiceNowDispatcher.java
 
b/components/camel-servicenow/src/main/java/org/apache/camel/component/servicenow/ServiceNowDispatcher.java
new file mode 100644
index 0000000..e3a0473
--- /dev/null
+++ 
b/components/camel-servicenow/src/main/java/org/apache/camel/component/servicenow/ServiceNowDispatcher.java
@@ -0,0 +1,55 @@
+/**
+ * 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.function.Predicate;
+
+import org.apache.camel.Exchange;
+import org.apache.camel.Message;
+import org.apache.camel.Processor;
+import org.apache.camel.util.ObjectHelper;
+
+public class ServiceNowDispatcher {
+    private final Predicate<Exchange> predicate;
+    private final Processor delegate;
+
+    public ServiceNowDispatcher(Predicate<Exchange> predicate, Processor 
delegate) {
+        this.predicate = ObjectHelper.notNull(predicate, "predicate");
+        this.delegate = ObjectHelper.notNull(delegate, "delegate");
+    }
+
+    public boolean match(Exchange exchange) {
+        return predicate.test(exchange);
+    }
+
+    public void process(Exchange exchange) throws Exception {
+        delegate.process(exchange);
+    }
+
+    // ********************
+    // Helpers
+    // ********************
+
+    public static ServiceNowDispatcher on(final String action, final String 
subject, final Processor delegate) {
+        return new ServiceNowDispatcher(e -> matches(e.getIn(), action, 
subject), delegate);
+    }
+
+    public static boolean matches(Message in, String action, final String 
subject) {
+        return ObjectHelper.equal(action, 
in.getHeader(ServiceNowConstants.ACTION, String.class), true)
+            && ObjectHelper.equal(subject, 
in.getHeader(ServiceNowConstants.ACTION_SUBJECT, String.class), true);
+    }
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/f655c941/components/camel-servicenow/src/main/java/org/apache/camel/component/servicenow/ServiceNowEndpoint.java
----------------------------------------------------------------------
diff --git 
a/components/camel-servicenow/src/main/java/org/apache/camel/component/servicenow/ServiceNowEndpoint.java
 
b/components/camel-servicenow/src/main/java/org/apache/camel/component/servicenow/ServiceNowEndpoint.java
index 2fa39a7..8234482 100644
--- 
a/components/camel-servicenow/src/main/java/org/apache/camel/component/servicenow/ServiceNowEndpoint.java
+++ 
b/components/camel-servicenow/src/main/java/org/apache/camel/component/servicenow/ServiceNowEndpoint.java
@@ -16,26 +16,23 @@
  */
 package org.apache.camel.component.servicenow;
 
-import java.util.Arrays;
-
-import com.fasterxml.jackson.jaxrs.json.JacksonJsonProvider;
 import org.apache.camel.Consumer;
 import org.apache.camel.Processor;
 import org.apache.camel.Producer;
-import org.apache.camel.component.servicenow.auth.AuthenticationRequestFilter;
-import org.apache.camel.component.servicenow.auth.OAuthToken;
 import org.apache.camel.impl.DefaultEndpoint;
 import org.apache.camel.spi.Metadata;
 import org.apache.camel.spi.UriEndpoint;
 import org.apache.camel.spi.UriParam;
 import org.apache.camel.spi.UriPath;
-import org.apache.cxf.jaxrs.client.JAXRSClientFactory;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 /**
  * Represents a ServiceNow endpoint.
  */
 @UriEndpoint(scheme = "servicenow", title = "ServiceNow", syntax = 
"servicenow:instanceName", producerOnly = true, label = "api,cloud,management")
 public class ServiceNowEndpoint extends DefaultEndpoint {
+    private static final Logger LOGGER = 
LoggerFactory.getLogger(ServiceNowEndpoint.class);
 
     @UriPath(description = "The ServiceNow instance name ")
     @Metadata(required = "true")
@@ -43,31 +40,24 @@ public class ServiceNowEndpoint extends DefaultEndpoint {
 
     @UriParam
     private final ServiceNowConfiguration configuration;
-    private final String apiUrl;
-    private final String oauthUrl;
-    private final OAuthToken token;
 
     public ServiceNowEndpoint(String uri, ServiceNowComponent component, 
ServiceNowConfiguration configuration, String instanceName) throws Exception {
         super(uri, component);
 
         this.configuration = configuration;
-        this.instanceName = 
component.getCamelContext().resolvePropertyPlaceholders(instanceName);
-
-        this.apiUrl = configuration.hasApiUrl()
-            ? configuration.getApiUrl()
-            : String.format("https://%s.service-now.com/api/now";, 
instanceName);
-        this.oauthUrl = configuration.hasOautTokenUrl()
-            ? configuration.getOauthTokenUrl()
-            : String.format("https://%s.service-now.com/oauth_token.do";, 
instanceName);
-
-        this.token = configuration.hasOAuthAuthentication()
-            ? new OAuthToken(this.oauthUrl, this.configuration)
-            : null;
+        this.instanceName = instanceName;
     }
 
     @Override
     public Producer createProducer() throws Exception {
-        return new ServiceNowProducer(this);
+        ServiceNowProducer producer = configuration.getRelease().get(this);
+        LOGGER.info("Producer for ServiceNow Rel. {} = {}/{}",
+            configuration.getRelease().name(),
+            producer.getRelease().name(),
+            producer.getClass().getName()
+        );
+
+        return producer;
     }
 
     @Override
@@ -87,16 +77,4 @@ public class ServiceNowEndpoint extends DefaultEndpoint {
     public String getInstanceName() {
         return instanceName;
     }
-
-    public <T> T createClient(Class<T> type) throws Exception {
-        return JAXRSClientFactory.create(
-            apiUrl,
-            type,
-            Arrays.asList(
-                new AuthenticationRequestFilter(configuration, token),
-                new JacksonJsonProvider(configuration.getMapper()),
-                new ServiceNowExceptionMapper(configuration.getMapper())
-            )
-        );
-    }
 }

http://git-wip-us.apache.org/repos/asf/camel/blob/f655c941/components/camel-servicenow/src/main/java/org/apache/camel/component/servicenow/ServiceNowExceptionMapper.java
----------------------------------------------------------------------
diff --git 
a/components/camel-servicenow/src/main/java/org/apache/camel/component/servicenow/ServiceNowExceptionMapper.java
 
b/components/camel-servicenow/src/main/java/org/apache/camel/component/servicenow/ServiceNowExceptionMapper.java
index 5b80c69..d864246 100644
--- 
a/components/camel-servicenow/src/main/java/org/apache/camel/component/servicenow/ServiceNowExceptionMapper.java
+++ 
b/components/camel-servicenow/src/main/java/org/apache/camel/component/servicenow/ServiceNowExceptionMapper.java
@@ -42,13 +42,22 @@ public class ServiceNowExceptionMapper implements 
ResponseExceptionMapper<Servic
         try {
             // Only ServiceNow known error status codes are mapped
             // See 
http://wiki.servicenow.com/index.php?title=REST_API#REST_Response_HTTP_Status_Codes
-            if (code == Response.Status.NOT_FOUND.getStatusCode()
-                || code == Response.Status.BAD_REQUEST.getStatusCode()
-                || code == Response.Status.UNAUTHORIZED.getStatusCode()
-                || code == Response.Status.FORBIDDEN.getStatusCode()
-                || code == Response.Status.METHOD_NOT_ALLOWED.getStatusCode()) 
{
-
-                return mapper.readValue((InputStream)r.getEntity(), 
ServiceNowException.class);
+            switch(code) {
+            case 200:
+            case 201:
+            case 204:
+                // Success
+                break;
+            case 400:
+            case 401:
+            case 403:
+            case 404:
+            case 405:
+            case 406:
+            case 415:
+                return mapper.readValue(r.readEntity(InputStream.class), 
ServiceNowException.class);
+            default:
+                break;
             }
         } catch (IOException e) {
             return new ServiceNowException(e);

http://git-wip-us.apache.org/repos/asf/camel/blob/f655c941/components/camel-servicenow/src/main/java/org/apache/camel/component/servicenow/ServiceNowParam.java
----------------------------------------------------------------------
diff --git 
a/components/camel-servicenow/src/main/java/org/apache/camel/component/servicenow/ServiceNowParam.java
 
b/components/camel-servicenow/src/main/java/org/apache/camel/component/servicenow/ServiceNowParam.java
new file mode 100644
index 0000000..5353753
--- /dev/null
+++ 
b/components/camel-servicenow/src/main/java/org/apache/camel/component/servicenow/ServiceNowParam.java
@@ -0,0 +1,28 @@
+/**
+ * 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 org.apache.camel.Message;
+
+public interface ServiceNowParam {
+    String getId();
+    String getHeader();
+    Class<?> getType();
+    Object getDefaultValue(ServiceNowConfiguration configuration);
+    Object getHeaderValue(Message message);
+    Object getHeaderValue(Message message, ServiceNowConfiguration 
configuration);
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/f655c941/components/camel-servicenow/src/main/java/org/apache/camel/component/servicenow/ServiceNowParams.java
----------------------------------------------------------------------
diff --git 
a/components/camel-servicenow/src/main/java/org/apache/camel/component/servicenow/ServiceNowParams.java
 
b/components/camel-servicenow/src/main/java/org/apache/camel/component/servicenow/ServiceNowParams.java
new file mode 100644
index 0000000..75f16f9
--- /dev/null
+++ 
b/components/camel-servicenow/src/main/java/org/apache/camel/component/servicenow/ServiceNowParams.java
@@ -0,0 +1,123 @@
+/**
+ * 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.function.Function;
+
+import org.apache.camel.Message;
+import org.apache.camel.util.ObjectHelper;
+
+public enum ServiceNowParams implements ServiceNowParam {
+    PARAM_SYS_ID("sys_id", "CamelServiceNowSysId", String.class),
+    PARAM_USER_SYS_ID("user_sysid", "CamelServiceNowUserSysId", String.class),
+    PARAM_USER_ID("user_id", "CamelServiceNowUserId", String.class),
+    PARAM_CART_ITEM_ID("cart_item_id", "CamelServiceNowCartItemId", 
String.class),
+    PARAM_FILE_NAME("file_name", "CamelServiceNowFileName", String.class),
+    PARAM_TABLE_NAME("table_name", "CamelServiceNowTable", String.class),
+    PARAM_TABLE_SYS_ID("table_sys_id", "CamelServiceNowTableSysId", 
String.class),
+    PARAM_ENCRYPTION_CONTEXT("encryption_context", 
"CamelServiceNowEncryptionContext", String.class),
+    SYSPARM_CATEGORY("sysparm_category", "CamelServiceNowCategory", 
String.class),
+    SYSPARM_TYPE("sysparm_type", "CamelServiceNowType", String.class),
+    SYSPARM_CATALOG("sysparm_catalog", "CamelServiceNowCatalog", String.class),
+    SYSPARM_QUERY("sysparm_query", "CamelServiceNowQuery", String.class),
+    SYSPARM_DISPLAY_VALUE("sysparm_display_value", 
"CamelServiceNowDisplayValue", String.class, 
ServiceNowConfiguration::getDisplayValue),
+    SYSPARM_INPUT_DISPLAY_VALUE("sysparm_input_display_value", 
"CamelServiceNowInputDisplayValue", Boolean.class, 
ServiceNowConfiguration::getInputDisplayValue),
+    SYSPARM_EXCLUDE_REFERENCE_LINK("sysparm_exclude_reference_link", 
"CamelServiceNowExcludeReferenceLink", Boolean.class, 
ServiceNowConfiguration::getExcludeReferenceLink),
+    SYSPARM_FIELDS("sysparm_fields", "CamelServiceNowFields", String.class),
+    SYSPARM_LIMIT("sysparm_limit", "CamelServiceNowLimit", Integer.class),
+    SYSPARM_TEXT("sysparm_text", "CamelServiceNowText", String.class),
+    SYSPARM_OFFSET("sysparm_offset", "CamelServiceNowOffset", Integer.class),
+    SYSPARM_VIEW("sysparm_view", "CamelServiceNowView", String.class),
+    SYSPARM_SUPPRESS_AUTO_SYS_FIELD("sysparm_suppress_auto_sys_field", 
"CamelServiceNowSuppressAutoSysField", Boolean.class, 
ServiceNowConfiguration::getSuppressAutoSysField),
+    SYSPARM_SUPPRESS_PAGINATION_HEADER("sysparm_suppress_pagination_header", 
"CamelServiceNowSuppressPaginationHeader", Boolean.class, 
ServiceNowConfiguration::getSuppressPaginationHeader),
+    SYSPARM_MIN_FIELDS("sysparm_min_fields", "CamelServiceNowMinFields", 
String.class),
+    SYSPARM_MAX_FIELDS("sysparm_max_fields", "CamelServiceNowMaxFields", 
String.class),
+    SYSPARM_SUM_FIELDS("sysparm_sum_fields", "CamelServiceNowSumFields", 
String.class),
+    SYSPARM_AVG_FIELDS("sysparm_avg_fields", "CamelServiceNowAvgFields", 
String.class),
+    SYSPARM_COUNT("sysparm_count", "CamelServiceNowCount", Boolean.class),
+    SYSPARM_GROUP_BY("sysparm_group_by", "CamelServiceNowGroupBy", 
String.class),
+    SYSPARM_ORDER_BY("sysparm_order_by", "CamelServiceNowOrderBy", 
String.class),
+    SYSPARM_HAVING("sysparm_having", "CamelServiceNowHaving", String.class),
+    SYSPARM_UUID("sysparm_uuid", "CamelServiceNowUUID", String.class),
+    SYSPARM_BREAKDOWN("sysparm_breakdown", "CamelServiceNowBreakdown", 
String.class),
+    SYSPARM_INCLUDE_SCORES("sysparm_include_scores", 
"CamelServiceNowIncludeScores", Boolean.class, 
ServiceNowConfiguration::getIncludeScores),
+    SYSPARM_INCLUDE_SCORE_NOTES("sysparm_include_score_notes", 
"CamelServiceNowIncludeScoreNotes", Boolean.class, 
ServiceNowConfiguration::getIncludeScoreNotes),
+    SYSPARM_INCLUDE_AGGREGATES("sysparm_include_aggregates", 
"CamelServiceNowIncludeAggregates", Boolean.class, 
ServiceNowConfiguration::getIncludeAggregates),
+    
SYSPARM_INCLUDE_AVAILABLE_BREAKDOWNS("sysparm_include_available_breakdowns", 
"CamelServiceNowIncludeAvailableBreakdowns", Boolean.class, 
ServiceNowConfiguration::getIncludeAvailableBreakdowns),
+    
SYSPARM_INCLUDE_AVAILABLE_AGGREGATES("sysparm_include_available_aggregates", 
"CamelServiceNowIncludeAvailableAggregates", Boolean.class, 
ServiceNowConfiguration::getIncludeAvailableAggregates),
+    SYSPARM_FAVORITES("sysparm_favorites", "CamelServiceNowFavorites", 
Boolean.class, ServiceNowConfiguration::getFavorites),
+    SYSPARM_KEY("sysparm_key", "CamelServiceNowKey", Boolean.class, 
ServiceNowConfiguration::getKey),
+    SYSPARM_TARGET("sysparm_target", "CamelServiceNowTarget", Boolean.class, 
ServiceNowConfiguration::getTarget),
+    SYSPARM_DISPLAY("sysparm_display", "CamelServiceNowDisplay", String.class, 
ServiceNowConfiguration::getDisplay),
+    SYSPARM_PER_PAGE("sysparm_per_page", "CamelServiceNowPerPage", 
Integer.class, ServiceNowConfiguration::getPerPage),
+    SYSPARM_SORT_BY("sysparm_sortby", "CamelServiceNowSortBy", String.class, 
ServiceNowConfiguration::getSortBy),
+    SYSPARM_SORT_DIR("sysparm_sortdir", "CamelServiceNowSortDir", 
String.class, ServiceNowConfiguration::getSortDir),
+    SYSPARM_CONTAINS("sysparm_contains", "CamelServiceNowContains", 
String.class),
+    SYSPARM_TAGS("sysparm_tags", "CamelServiceNowTags", String.class),
+    SYSPARM_PAGE("sysparm_page", "CamelServiceNowPage", String.class),
+    SYSPARM_ELEMENTS_FILTER("sysparm_elements_filter", 
"CamelServiceNowElementsFilter", String.class),
+    SYSPARM_BREAKDOWN_RELATION("sysparm_breakdown_relation", 
"CamelServiceNowBreakdownRelation", String.class),
+    SYSPARM_DATA_SOURCE("sysparm_data_source", "CamelServiceNowDataSource", 
String.class),
+    SYSPARM_TOP_LEVEL_ONLY("sysparm_top_level_only", 
"CamelServiceNowTopLevelOnly", Boolean.class, 
ServiceNowConfiguration::getTopLevelOnly);
+
+    private final String id;
+    private final String header;
+    private final Class<?> type;
+    private final Function<ServiceNowConfiguration, ?> defaultValueSupplier;
+
+    ServiceNowParams(String id, String header, Class<?> type) {
+        this(id, header, type, null);
+    }
+
+    ServiceNowParams(String id, String header, Class<?> type, 
Function<ServiceNowConfiguration, ?> defaultValueSupplier) {
+        ObjectHelper.notNull(id, "ServiceNowSysParam (id)");
+        ObjectHelper.notNull(header, "ServiceNowSysParam (header)");
+        ObjectHelper.notNull(type, "ServiceNowSysParam (type)");
+
+        this.id = id;
+        this.header = 
header.startsWith(ServiceNowConstants.CAMEL_HEADER_PREFIX)
+            ? header
+            : ServiceNowConstants.CAMEL_HEADER_PREFIX + 
ObjectHelper.capitalize(header);
+
+        this.type = type;
+        this.defaultValueSupplier = defaultValueSupplier;
+    }
+
+    public String getId() {
+        return id;
+    }
+
+    public String getHeader() {
+        return header;
+    }
+
+    public Class<?> getType() {
+        return type;
+    }
+
+    public Object getDefaultValue(ServiceNowConfiguration configuration) {
+        return defaultValueSupplier != null ? 
defaultValueSupplier.apply(configuration) : null;
+    }
+
+    public Object getHeaderValue(Message message) {
+        return message.getHeader(header, type);
+    }
+
+    public Object getHeaderValue(Message message, ServiceNowConfiguration 
configuration) {
+        return message.getHeader(header, getDefaultValue(configuration), type);
+    }
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/f655c941/components/camel-servicenow/src/main/java/org/apache/camel/component/servicenow/ServiceNowProducer.java
----------------------------------------------------------------------
diff --git 
a/components/camel-servicenow/src/main/java/org/apache/camel/component/servicenow/ServiceNowProducer.java
 
b/components/camel-servicenow/src/main/java/org/apache/camel/component/servicenow/ServiceNowProducer.java
index d0c91c5..67e08bb 100644
--- 
a/components/camel-servicenow/src/main/java/org/apache/camel/component/servicenow/ServiceNowProducer.java
+++ 
b/components/camel-servicenow/src/main/java/org/apache/camel/component/servicenow/ServiceNowProducer.java
@@ -16,88 +16,8 @@
  */
 package org.apache.camel.component.servicenow;
 
-import java.lang.ref.WeakReference;
+import org.apache.camel.Producer;
 
-import org.apache.camel.Exchange;
-import org.apache.camel.Processor;
-import 
org.apache.camel.component.servicenow.model.ServiceNowAggregateProcessor;
-import 
org.apache.camel.component.servicenow.model.ServiceNowImportSetProcessor;
-import org.apache.camel.component.servicenow.model.ServiceNowTableProcessor;
-import org.apache.camel.impl.DefaultProducer;
-import org.apache.camel.util.ObjectHelper;
-
-/**
- * The ServiceNow producer.
- */
-public class ServiceNowProducer extends DefaultProducer {
-
-    private final ServiceNowEndpoint endpoint;
-    private final ServiceNowConfiguration configuration;
-    private final WeakThreadLocal tableCache;
-    private final WeakThreadLocal aggregateCache;
-    private final WeakThreadLocal importSetCache;
-
-    public ServiceNowProducer(ServiceNowEndpoint endpoint) {
-        super(endpoint);
-
-        this.endpoint = endpoint;
-        this.configuration = endpoint.getConfiguration();
-        this.tableCache = new 
WeakThreadLocal(ServiceNowTableProcessor.SUPPLIER);
-        this.aggregateCache = new 
WeakThreadLocal(ServiceNowAggregateProcessor.SUPPLIER);
-        this.importSetCache = new 
WeakThreadLocal(ServiceNowImportSetProcessor.SUPPLIER);
-    }
-
-    @Override
-    public void process(Exchange exchange) throws Exception {
-        String resource = 
exchange.getIn().getHeader(ServiceNowConstants.RESOURCE, 
configuration.getResource(), String.class);
-
-        if (ObjectHelper.equal(ServiceNowConstants.RESOURCE_TABLE, resource, 
true)) {
-            tableCache.get().process(exchange);
-        } else if (ObjectHelper.equal(ServiceNowConstants.RESOURCE_AGGREGATE, 
resource, true)) {
-            aggregateCache.get().process(exchange);
-        } else if (ObjectHelper.equal(ServiceNowConstants.RESOURCE_IMPORT, 
resource, true)) {
-            importSetCache.get().process(exchange);
-        } else {
-            throw new IllegalArgumentException("Unknown resource type: " + 
resource);
-        }
-    }
-
-    // 
*************************************************************************
-    // Thread-Local processor instances as CXF client proxies are not thread
-    // safe. To be refactored once moved to Java 8 as 
ServiceNowProcessorSupplier
-    // can be replaced by:
-    //
-    //     java.util.function.Function<ServiceNowEndpoint, Processor>
-    //
-    // so an instance of a specific processor can be obtained by a constructor
-    // ref, i.e:
-    //
-    //     ServiceNowImportSetProcessor::new
-    //
-    // 
*************************************************************************
-
-    private final class WeakThreadLocal {
-        private final ThreadLocal<WeakReference<Processor>> cache;
-        private final ServiceNowProducerProcessor.Supplier supplier;
-
-        WeakThreadLocal(ServiceNowProducerProcessor.Supplier supplier) {
-            this.cache = new ThreadLocal<>();
-            this.supplier = supplier;
-        }
-
-        public Processor get() throws Exception {
-            Processor processor = null;
-            WeakReference<Processor> ref = cache.get();
-            if (ref != null) {
-                processor = ref.get();
-            }
-
-            if (processor == null) {
-                processor = supplier.get(endpoint);
-                cache.set(new WeakReference<>(processor));
-            }
-
-            return processor;
-        }
-    }
+public interface ServiceNowProducer extends Producer {
+    ServiceNowRelease getRelease();
 }

http://git-wip-us.apache.org/repos/asf/camel/blob/f655c941/components/camel-servicenow/src/main/java/org/apache/camel/component/servicenow/ServiceNowProducerProcessor.java
----------------------------------------------------------------------
diff --git 
a/components/camel-servicenow/src/main/java/org/apache/camel/component/servicenow/ServiceNowProducerProcessor.java
 
b/components/camel-servicenow/src/main/java/org/apache/camel/component/servicenow/ServiceNowProducerProcessor.java
deleted file mode 100644
index 83b61ce..0000000
--- 
a/components/camel-servicenow/src/main/java/org/apache/camel/component/servicenow/ServiceNowProducerProcessor.java
+++ /dev/null
@@ -1,139 +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.List;
-import java.util.Map;
-
-import com.fasterxml.jackson.databind.JavaType;
-import com.fasterxml.jackson.databind.JsonNode;
-import com.fasterxml.jackson.databind.ObjectMapper;
-import org.apache.camel.Exchange;
-import org.apache.camel.Message;
-import org.apache.camel.Processor;
-import org.apache.camel.util.ObjectHelper;
-
-public abstract class ServiceNowProducerProcessor<T> implements Processor {
-
-    protected final ServiceNowEndpoint endpoint;
-    protected final ServiceNowConfiguration config;
-    protected final T client;
-    protected final ObjectMapper mapper;
-    
-    // Cache for JavaTypes
-    private final JavaTypeCache javaTypeCache;
-
-    protected ServiceNowProducerProcessor(ServiceNowEndpoint endpoint, 
Class<T> type) throws Exception {
-        this.javaTypeCache = new JavaTypeCache();
-        this.endpoint = endpoint;
-        this.config = endpoint.getConfiguration();
-        this.client = endpoint.createClient(type);
-        this.mapper = ObjectHelper.notNull(config.getMapper(), "mapper");
-    }
-
-    @Override
-    public void process(Exchange exchange) throws Exception {
-        final Message in = exchange.getIn();
-        final String tableName = in.getHeader(ServiceNowConstants.TABLE, 
config.getTable(), String.class);
-        final Class<?> model = in.getHeader(ServiceNowConstants.MODEL, 
config.getModel(tableName, Map.class), Class.class);
-        final String action = in.getHeader(ServiceNowConstants.ACTION, 
String.class);
-        final String sysId = in.getHeader(ServiceNowConstants.SYSPARM_ID, 
String.class);
-
-        doProcess(
-            exchange,
-            ObjectHelper.notNull(model, "model"),
-            ObjectHelper.notNull(action, "action"),
-            ObjectHelper.notNull(tableName, "tableName"),
-            sysId);
-    }
-
-    protected abstract void doProcess(
-        Exchange exchange,
-        Class<?> model,
-        String action,
-        String tableName,
-        String sysId) throws Exception;
-
-
-    protected ServiceNowProducerProcessor<T> validateBody(Message message, 
Class<?> model) {
-        return validateBody(message.getBody(), model);
-    }
-
-    protected ServiceNowProducerProcessor<T> validateBody(Object body, 
Class<?> model) {
-        ObjectHelper.notNull(body, "body");
-
-        if (!body.getClass().isAssignableFrom(model)) {
-            throw new IllegalArgumentException(
-                "Body is not compatible with model (body=" + body.getClass() + 
", model=" + model);
-        }
-
-        return this;
-    }
-
-    protected ServiceNowProducerProcessor<T> setBody(Message message, Class<?> 
model, JsonNode answer) throws Exception {
-        message.setBody(unwrap(answer, model));
-
-        return this;
-    }
-
-    protected Object unwrap(JsonNode answer, Class<?> model) throws Exception {
-        Object result = null;
-
-        if (answer != null) {
-            JsonNode node = answer.get("result");
-            if (node != null) {
-                if (node.isArray()) {
-                    if (model.isInstance(Map.class)) {
-                        // If the model is a Map, there's no need to use any
-                        // specific JavaType to instruct Jackson about the
-                        // expected element type
-                        result = mapper.treeToValue(node, List.class);
-                    } else {
-                        result = mapper.readValue(node.traverse(), 
javaTypeCache.get(model));
-                    }
-                } else {
-                    result = mapper.treeToValue(node, model);
-                }
-            }
-        }
-
-        return result;
-    }
-
-    // 
*************************************************************************
-    // Use ClassValue to lazy create and cache JavaType
-    // 
*************************************************************************
-
-    private class JavaTypeCache extends ClassValue<JavaType> {
-        @Override
-        protected JavaType computeValue(Class<?> type) {
-            return mapper.getTypeFactory().constructCollectionType(List.class, 
type);
-        }
-    }
-
-    // 
*************************************************************************
-    // To be replaced with:
-    //
-    //     java.util.function.Function<ServiceNowEndpoint, Processor>
-    //
-    // Once Camel will be Java 8 ready
-    // 
*************************************************************************
-
-    public interface Supplier {
-        Processor get(ServiceNowEndpoint endpoint) throws Exception;
-    }
-}

http://git-wip-us.apache.org/repos/asf/camel/blob/f655c941/components/camel-servicenow/src/main/java/org/apache/camel/component/servicenow/ServiceNowProducerSupplier.java
----------------------------------------------------------------------
diff --git 
a/components/camel-servicenow/src/main/java/org/apache/camel/component/servicenow/ServiceNowProducerSupplier.java
 
b/components/camel-servicenow/src/main/java/org/apache/camel/component/servicenow/ServiceNowProducerSupplier.java
new file mode 100644
index 0000000..d339417
--- /dev/null
+++ 
b/components/camel-servicenow/src/main/java/org/apache/camel/component/servicenow/ServiceNowProducerSupplier.java
@@ -0,0 +1,22 @@
+/**
+ * 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;
+
+public interface ServiceNowProducerSupplier {
+    ServiceNowProducer get(ServiceNowEndpoint endpoint) throws Exception;
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/f655c941/components/camel-servicenow/src/main/java/org/apache/camel/component/servicenow/ServiceNowRelease.java
----------------------------------------------------------------------
diff --git 
a/components/camel-servicenow/src/main/java/org/apache/camel/component/servicenow/ServiceNowRelease.java
 
b/components/camel-servicenow/src/main/java/org/apache/camel/component/servicenow/ServiceNowRelease.java
new file mode 100644
index 0000000..84f475a
--- /dev/null
+++ 
b/components/camel-servicenow/src/main/java/org/apache/camel/component/servicenow/ServiceNowRelease.java
@@ -0,0 +1,41 @@
+/**
+ * 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 
org.apache.camel.component.servicenow.releases.fuji.FujiServiceNowProducer;
+import 
org.apache.camel.component.servicenow.releases.helsinki.HelsinkiServiceNowProducer;
+
+public enum ServiceNowRelease implements ServiceNowProducerSupplier {
+    FUJI {
+        @Override
+        public ServiceNowProducer get(ServiceNowEndpoint endpoint) throws 
Exception {
+            return new FujiServiceNowProducer(endpoint);
+        }
+    },
+    GENEVA {
+        @Override
+        public ServiceNowProducer get(ServiceNowEndpoint endpoint) throws 
Exception {
+            return null;
+        }
+    },
+    HELSINKY {
+        @Override
+        public ServiceNowProducer get(ServiceNowEndpoint endpoint) throws 
Exception {
+            return new HelsinkiServiceNowProducer(endpoint);
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/f655c941/components/camel-servicenow/src/main/java/org/apache/camel/component/servicenow/auth/AuthenticationRequestFilter.java
----------------------------------------------------------------------
diff --git 
a/components/camel-servicenow/src/main/java/org/apache/camel/component/servicenow/auth/AuthenticationRequestFilter.java
 
b/components/camel-servicenow/src/main/java/org/apache/camel/component/servicenow/auth/AuthenticationRequestFilter.java
index d6e3b05..9e934ad 100644
--- 
a/components/camel-servicenow/src/main/java/org/apache/camel/component/servicenow/auth/AuthenticationRequestFilter.java
+++ 
b/components/camel-servicenow/src/main/java/org/apache/camel/component/servicenow/auth/AuthenticationRequestFilter.java
@@ -35,9 +35,9 @@ public class AuthenticationRequestFilter implements 
ClientRequestFilter {
     private final OAuthToken token;
     private final String authString;
 
-    public AuthenticationRequestFilter(ServiceNowConfiguration configuration, 
OAuthToken token) throws IOException {
+    public AuthenticationRequestFilter(ServiceNowConfiguration configuration) 
throws IOException {
         this.configuration = configuration;
-        this.token = token;
+        this.token = configuration.hasOAuthAuthentication() ? new 
OAuthToken(this.configuration) : null;
         this.authString = buildBasicAuthString(configuration);
     }
 

Reply via email to