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:10:08 UTC

[17/19] camel git commit: CAMEL-11555: ServiceNow : create a maven plugin to generate models based on table layout

http://git-wip-us.apache.org/repos/asf/camel/blob/109da7c9/components/camel-servicenow/camel-servicenow-component/src/main/java/org/apache/camel/component/servicenow/auth/OAuthToken.java
----------------------------------------------------------------------
diff --git a/components/camel-servicenow/camel-servicenow-component/src/main/java/org/apache/camel/component/servicenow/auth/OAuthToken.java b/components/camel-servicenow/camel-servicenow-component/src/main/java/org/apache/camel/component/servicenow/auth/OAuthToken.java
new file mode 100644
index 0000000..880cf7f
--- /dev/null
+++ b/components/camel-servicenow/camel-servicenow-component/src/main/java/org/apache/camel/component/servicenow/auth/OAuthToken.java
@@ -0,0 +1,107 @@
+/**
+ * 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.auth;
+
+import java.util.concurrent.TimeUnit;
+
+import org.apache.camel.component.servicenow.ServiceNowConfiguration;
+import org.apache.cxf.jaxrs.client.WebClient;
+import org.apache.cxf.rs.security.oauth2.client.Consumer;
+import org.apache.cxf.rs.security.oauth2.client.OAuthClientUtils;
+import org.apache.cxf.rs.security.oauth2.common.ClientAccessToken;
+import org.apache.cxf.rs.security.oauth2.grants.owner.ResourceOwnerGrant;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class OAuthToken {
+    private static final Logger LOGGER = LoggerFactory.getLogger(OAuthToken.class);
+
+    private final ServiceNowConfiguration configuration;
+    private ClientAccessToken token;
+    private String authString;
+    private long expireAt;
+
+    public OAuthToken(ServiceNowConfiguration configuration) {
+        this.configuration = configuration;
+        this.token = null;
+        this.authString = null;
+        this.expireAt = 0;
+    }
+
+    private synchronized void getOrRefreshAccessToken() {
+        if (token == null) {
+            LOGGER.debug("Generate OAuth token");
+
+            token = OAuthClientUtils.getAccessToken(
+                WebClient.create(configuration.getOauthTokenUrl()),
+                new Consumer(
+                    configuration.getOauthClientId(),
+                    configuration.getOauthClientSecret()),
+                new ResourceOwnerGrant(
+                    configuration.getUserName(),
+                    configuration.getPassword()),
+                true
+            );
+
+            LOGGER.debug("OAuth token expires in {}s", token.getExpiresIn());
+
+            // Set expiration time related info in milliseconds
+            token.setIssuedAt(System.currentTimeMillis());
+            token.setExpiresIn(TimeUnit.MILLISECONDS.convert(token.getExpiresIn(), TimeUnit.SECONDS));
+
+            authString = token.toString();
+
+            if (token.getExpiresIn() > 0) {
+                expireAt = token.getIssuedAt() + token.getExpiresIn();
+            }
+        } else if (expireAt > 0 && System.currentTimeMillis() >= expireAt) {
+            LOGGER.debug("OAuth token is expired, refresh it");
+
+            token = OAuthClientUtils.refreshAccessToken(
+                WebClient.create(configuration.getOauthTokenUrl()),
+                new Consumer(
+                    configuration.getOauthClientId(),
+                    configuration.getOauthClientSecret()),
+                token,
+                null,
+                false
+            );
+
+            LOGGER.debug("Refreshed OAuth token expires in {}s", token.getExpiresIn());
+
+            // Set expiration time related info in milliseconds
+            token.setIssuedAt(System.currentTimeMillis());
+            token.setExpiresIn(TimeUnit.MILLISECONDS.convert(token.getExpiresIn(), TimeUnit.SECONDS));
+
+            authString = token.toString();
+
+            if (token.getExpiresIn() > 0) {
+                expireAt = token.getIssuedAt() + token.getExpiresIn();
+            }
+        }
+    }
+
+    public ClientAccessToken getClientAccess() {
+        getOrRefreshAccessToken();
+        return token;
+    }
+
+    public String getAuthString() {
+        getOrRefreshAccessToken();
+        return authString;
+    }
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/109da7c9/components/camel-servicenow/camel-servicenow-component/src/main/java/org/apache/camel/component/servicenow/model/DictionaryEntry.java
----------------------------------------------------------------------
diff --git a/components/camel-servicenow/camel-servicenow-component/src/main/java/org/apache/camel/component/servicenow/model/DictionaryEntry.java b/components/camel-servicenow/camel-servicenow-component/src/main/java/org/apache/camel/component/servicenow/model/DictionaryEntry.java
new file mode 100644
index 0000000..af7aa5b
--- /dev/null
+++ b/components/camel-servicenow/camel-servicenow-component/src/main/java/org/apache/camel/component/servicenow/model/DictionaryEntry.java
@@ -0,0 +1,56 @@
+/**
+ * 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.model;
+
+import com.fasterxml.jackson.annotation.JsonCreator;
+import com.fasterxml.jackson.annotation.JsonProperty;
+
+public class DictionaryEntry {
+    private final Reference internalType;
+    private final Reference reference;
+    private final Integer maxLength;
+    private final boolean mandatory;
+
+    @JsonCreator
+    public DictionaryEntry(
+        @JsonProperty(value = "internal_type") Reference internalType,
+        @JsonProperty(value = "reference") Reference reference,
+        @JsonProperty(value = "max_length") Integer maxLength,
+        @JsonProperty(value = "mandatory", defaultValue = "false") boolean mandatory) {
+
+        this.internalType = internalType;
+        this.reference = reference;
+        this.maxLength = maxLength;
+        this.mandatory = mandatory;
+    }
+
+    public Reference getInternalType() {
+        return internalType;
+    }
+
+    public Reference getReference() {
+        return reference;
+    }
+
+    public Integer getMaxLength() {
+        return maxLength;
+    }
+
+    public boolean isMandatory() {
+        return mandatory;
+    }
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/109da7c9/components/camel-servicenow/camel-servicenow-component/src/main/java/org/apache/camel/component/servicenow/model/ImportSetResponse.java
----------------------------------------------------------------------
diff --git a/components/camel-servicenow/camel-servicenow-component/src/main/java/org/apache/camel/component/servicenow/model/ImportSetResponse.java b/components/camel-servicenow/camel-servicenow-component/src/main/java/org/apache/camel/component/servicenow/model/ImportSetResponse.java
new file mode 100644
index 0000000..348dd8d
--- /dev/null
+++ b/components/camel-servicenow/camel-servicenow-component/src/main/java/org/apache/camel/component/servicenow/model/ImportSetResponse.java
@@ -0,0 +1,57 @@
+/**
+ * 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.model;
+
+import java.util.Collections;
+import java.util.List;
+
+import com.fasterxml.jackson.annotation.JsonCreator;
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import org.apache.camel.component.servicenow.annotations.ServiceNowSysParm;
+
+@ServiceNowSysParm(name = "sysparm_exclude_reference_link", value = "true")
+@JsonIgnoreProperties(ignoreUnknown = true)
+@JsonInclude(JsonInclude.Include.NON_NULL)
+public class ImportSetResponse {
+    private final String importSet;
+    private final String stagingTable;
+    private final List<ImportSetResult> results;
+
+    @JsonCreator
+    public ImportSetResponse(
+        @JsonProperty("import_set") String importSet,
+        @JsonProperty("staging_table") String stagingTable,
+        @JsonProperty("result") List<ImportSetResult> results) {
+        this.importSet = importSet;
+        this.stagingTable = stagingTable;
+        this.results = results == null ? Collections.emptyList() : results;
+    }
+
+    public String getImportSet() {
+        return importSet;
+    }
+
+    public String getStagingTable() {
+        return stagingTable;
+    }
+
+    public List<ImportSetResult> getResults() {
+        return results;
+    }
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/109da7c9/components/camel-servicenow/camel-servicenow-component/src/main/java/org/apache/camel/component/servicenow/model/ImportSetResult.java
----------------------------------------------------------------------
diff --git a/components/camel-servicenow/camel-servicenow-component/src/main/java/org/apache/camel/component/servicenow/model/ImportSetResult.java b/components/camel-servicenow/camel-servicenow-component/src/main/java/org/apache/camel/component/servicenow/model/ImportSetResult.java
new file mode 100644
index 0000000..e5962e0
--- /dev/null
+++ b/components/camel-servicenow/camel-servicenow-component/src/main/java/org/apache/camel/component/servicenow/model/ImportSetResult.java
@@ -0,0 +1,83 @@
+/**
+ * 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.model;
+
+import com.fasterxml.jackson.annotation.JsonCreator;
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import org.apache.camel.component.servicenow.annotations.ServiceNowSysParm;
+
+@ServiceNowSysParm(name = "sysparm_exclude_reference_link", value = "true")
+@JsonIgnoreProperties(ignoreUnknown = true)
+@JsonInclude(JsonInclude.Include.NON_NULL)
+public class ImportSetResult {
+    private final String transformMap;
+    private final String table;
+    private final String displayName;
+    private final String displayValue;
+    private final String recordLink;
+    private final String status;
+    private final String sysId;
+
+    @JsonCreator
+    public ImportSetResult(
+        @JsonProperty(value = "transform_map") String transformMap,
+        @JsonProperty(value = "table", required = true) String table,
+        @JsonProperty(value = "display_name") String displayName,
+        @JsonProperty(value = "display_value") String displayValue,
+        @JsonProperty(value = "record_link") String recordLink,
+        @JsonProperty(value = "status", required = true) String status,
+        @JsonProperty(value = "sys_id", required = true) String sysId) {
+
+        this.transformMap = transformMap;
+        this.table = table;
+        this.displayName = displayName;
+        this.displayValue = displayValue;
+        this.recordLink = recordLink;
+        this.status = status;
+        this.sysId = sysId;
+    }
+
+    public String getTransformMap() {
+        return transformMap;
+    }
+
+    public String getTable() {
+        return table;
+    }
+
+    public String getDisplayName() {
+        return displayName;
+    }
+
+    public String getDisplayValue() {
+        return displayValue;
+    }
+
+    public String getRecordLink() {
+        return recordLink;
+    }
+
+    public String getStatus() {
+        return status;
+    }
+
+    public String getSysId() {
+        return sysId;
+    }
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/109da7c9/components/camel-servicenow/camel-servicenow-component/src/main/java/org/apache/camel/component/servicenow/model/Reference.java
----------------------------------------------------------------------
diff --git a/components/camel-servicenow/camel-servicenow-component/src/main/java/org/apache/camel/component/servicenow/model/Reference.java b/components/camel-servicenow/camel-servicenow-component/src/main/java/org/apache/camel/component/servicenow/model/Reference.java
new file mode 100644
index 0000000..1bcb2a7
--- /dev/null
+++ b/components/camel-servicenow/camel-servicenow-component/src/main/java/org/apache/camel/component/servicenow/model/Reference.java
@@ -0,0 +1,56 @@
+/**
+ * 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.model;
+
+import com.fasterxml.jackson.annotation.JsonCreator;
+import com.fasterxml.jackson.annotation.JsonProperty;
+
+public class Reference {
+    private final String link;
+    private final String value;
+    private final String displayValue;
+
+    @JsonCreator
+    public Reference(String value) {
+        this.link = null;
+        this.value = value;
+        this.displayValue = null;
+    }
+
+    @JsonCreator
+    public Reference(
+        @JsonProperty(value = "link", required = false) String link,
+        @JsonProperty(value = "value", required = true) String value,
+        @JsonProperty(value = "display_value", required = false) String displayValue) {
+
+        this.link = link;
+        this.value = value;
+        this.displayValue = displayValue;
+    }
+
+    public String getLink() {
+        return link;
+    }
+
+    public String getValue() {
+        return value;
+    }
+
+    public String getDisplayValue() {
+        return displayValue;
+    }
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/109da7c9/components/camel-servicenow/camel-servicenow-component/src/main/java/org/apache/camel/component/servicenow/releases/fuji/FujiServiceNowAggregateProcessor.java
----------------------------------------------------------------------
diff --git a/components/camel-servicenow/camel-servicenow-component/src/main/java/org/apache/camel/component/servicenow/releases/fuji/FujiServiceNowAggregateProcessor.java b/components/camel-servicenow/camel-servicenow-component/src/main/java/org/apache/camel/component/servicenow/releases/fuji/FujiServiceNowAggregateProcessor.java
new file mode 100644
index 0000000..7fe9352
--- /dev/null
+++ b/components/camel-servicenow/camel-servicenow-component/src/main/java/org/apache/camel/component/servicenow/releases/fuji/FujiServiceNowAggregateProcessor.java
@@ -0,0 +1,72 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.camel.component.servicenow.releases.fuji;
+
+import javax.ws.rs.HttpMethod;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+
+import org.apache.camel.Exchange;
+import org.apache.camel.Message;
+import org.apache.camel.component.servicenow.ServiceNowConstants;
+import org.apache.camel.component.servicenow.ServiceNowEndpoint;
+import org.apache.camel.component.servicenow.ServiceNowParams;
+import org.apache.camel.util.ObjectHelper;
+
+class FujiServiceNowAggregateProcessor extends FujiServiceNowProcessor {
+
+    FujiServiceNowAggregateProcessor(ServiceNowEndpoint endpoint) throws Exception {
+        super(endpoint);
+    }
+
+    @Override
+    protected void doProcess(Exchange exchange, Class<?> requestModel, Class<?> responseModel, String action, String apiVersion, String tableName, String sysId) throws Exception {
+        Response response;
+        if (ObjectHelper.equal(ServiceNowConstants.ACTION_RETRIEVE, action, true)) {
+            response = retrieveStats(exchange.getIn(), requestModel, responseModel, tableName);
+        } else {
+            throw new IllegalArgumentException("Unknown action " + action);
+        }
+
+        setBodyAndHeaders(exchange.getIn(), responseModel, response);
+    }
+
+    private Response retrieveStats(Message in, Class<?> requestModel, Class<?> responseModel, String tableName) throws Exception {
+        final String apiVersion = getApiVersion(in);
+
+        return client.reset()
+            .types(MediaType.APPLICATION_JSON_TYPE)
+            .path("now")
+            .path(apiVersion)
+            .path("stats")
+            .path(tableName)
+            .query(ServiceNowParams.SYSPARM_QUERY, in)
+            .query(ServiceNowParams.SYSPARM_AVG_FIELDS, in)
+            .query(ServiceNowParams.SYSPARM_COUNT, in)
+            .query(ServiceNowParams.SYSPARM_MIN_FIELDS, in)
+            .query(ServiceNowParams.SYSPARM_QUERY, in)
+            .query(ServiceNowParams.SYSPARM_MAX_FIELDS, in)
+            .query(ServiceNowParams.SYSPARM_SUM_FIELDS, in)
+            .query(ServiceNowParams.SYSPARM_GROUP_BY, in)
+            .query(ServiceNowParams.SYSPARM_ORDER_BY, in)
+            .query(ServiceNowParams.SYSPARM_HAVING, in)
+            .query(ServiceNowParams.SYSPARM_DISPLAY_VALUE, in)
+            .query(responseModel)
+            .invoke(HttpMethod.GET);
+    }
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/109da7c9/components/camel-servicenow/camel-servicenow-component/src/main/java/org/apache/camel/component/servicenow/releases/fuji/FujiServiceNowImportSetProcessor.java
----------------------------------------------------------------------
diff --git a/components/camel-servicenow/camel-servicenow-component/src/main/java/org/apache/camel/component/servicenow/releases/fuji/FujiServiceNowImportSetProcessor.java b/components/camel-servicenow/camel-servicenow-component/src/main/java/org/apache/camel/component/servicenow/releases/fuji/FujiServiceNowImportSetProcessor.java
new file mode 100644
index 0000000..2080045
--- /dev/null
+++ b/components/camel-servicenow/camel-servicenow-component/src/main/java/org/apache/camel/component/servicenow/releases/fuji/FujiServiceNowImportSetProcessor.java
@@ -0,0 +1,86 @@
+/**
+ * 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.releases.fuji;
+
+import javax.ws.rs.HttpMethod;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+
+import org.apache.camel.Exchange;
+import org.apache.camel.Message;
+import org.apache.camel.component.servicenow.ServiceNowConstants;
+import org.apache.camel.component.servicenow.ServiceNowEndpoint;
+import org.apache.camel.util.ObjectHelper;
+
+class FujiServiceNowImportSetProcessor extends FujiServiceNowProcessor {
+
+    FujiServiceNowImportSetProcessor(ServiceNowEndpoint endpoint) throws Exception {
+        super(endpoint);
+    }
+
+    @Override
+    protected void doProcess(Exchange exchange, Class<?> requestModel, Class<?> responseModel, String action, String apiVersion, String tableName, String sysId) throws Exception {
+        Response response;
+        if (ObjectHelper.equal(ServiceNowConstants.ACTION_RETRIEVE, action, true)) {
+            response = retrieveRecord(exchange.getIn(), requestModel, responseModel, apiVersion, tableName, sysId);
+        } else if (ObjectHelper.equal(ServiceNowConstants.ACTION_CREATE, action, true)) {
+            response = createRecord(exchange.getIn(), requestModel, responseModel, apiVersion, tableName);
+        } else {
+            throw new IllegalArgumentException("Unknown action " + action);
+        }
+
+        setBodyAndHeaders(exchange.getIn(), responseModel, response);
+    }
+
+    /*
+     * GET
+     * https://instance.service-now.com/api/now/import/{tableName}/{sys_id}
+     */
+    private Response retrieveRecord(Message in, Class<?> requestModel, Class<?> responseModel, String apiVersion, String tableName, String sysId) throws Exception {
+        return client.reset()
+            .types(MediaType.APPLICATION_JSON_TYPE)
+            .path("now")
+            .path(apiVersion)
+            .path("import")
+            .path(tableName)
+            .path(ObjectHelper.notNull(sysId, "sysId"))
+            .query(responseModel)
+            .invoke(HttpMethod.GET);
+    }
+
+    /*
+     * POST
+     * https://instance.service-now.com/api/now/import/{tableName}
+     */
+    private Response createRecord(Message in, Class<?> requestModel, Class<?> responseModel, String apiVersion, String tableName) throws Exception {
+        if (in.getHeader(ServiceNowConstants.RETRIEVE_TARGET_RECORD, config::getRetrieveTargetRecordOnImport, Boolean.class)) {
+            throw new UnsupportedOperationException("RetrieveTargetRecordOnImport is supported from Helsinky");
+        }
+
+        validateBody(in, requestModel);
+
+        return client.reset()
+            .types(MediaType.APPLICATION_JSON_TYPE)
+            .path("now")
+            .path(apiVersion)
+            .path("import")
+            .path(tableName)
+            .query(responseModel)
+            .invoke(HttpMethod.POST, in.getMandatoryBody());
+    }
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/109da7c9/components/camel-servicenow/camel-servicenow-component/src/main/java/org/apache/camel/component/servicenow/releases/fuji/FujiServiceNowProcessor.java
----------------------------------------------------------------------
diff --git a/components/camel-servicenow/camel-servicenow-component/src/main/java/org/apache/camel/component/servicenow/releases/fuji/FujiServiceNowProcessor.java b/components/camel-servicenow/camel-servicenow-component/src/main/java/org/apache/camel/component/servicenow/releases/fuji/FujiServiceNowProcessor.java
new file mode 100644
index 0000000..52b81bb
--- /dev/null
+++ b/components/camel-servicenow/camel-servicenow-component/src/main/java/org/apache/camel/component/servicenow/releases/fuji/FujiServiceNowProcessor.java
@@ -0,0 +1,60 @@
+/**
+ * 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.releases.fuji;
+
+import org.apache.camel.Exchange;
+import org.apache.camel.Message;
+import org.apache.camel.component.servicenow.AbstractServiceNowProcessor;
+import org.apache.camel.component.servicenow.ServiceNowConstants;
+import org.apache.camel.component.servicenow.ServiceNowEndpoint;
+import org.apache.camel.util.ObjectHelper;
+
+public abstract class FujiServiceNowProcessor extends AbstractServiceNowProcessor {
+    protected FujiServiceNowProcessor(ServiceNowEndpoint endpoint) throws Exception {
+        super(endpoint);
+    }
+
+    @Override
+    public void process(Exchange exchange) throws Exception {
+        final Message in = exchange.getIn();
+        final String tableName = getTableName(in);
+        final Class<?> requestModel = getRequestModel(in, tableName);
+        final Class<?> responseModel = getResponseModel(in, tableName);
+        final String apiVersion = getApiVersion(in);
+        final String action = in.getHeader(ServiceNowConstants.ACTION, String.class);
+        final String sysId = getSysID(in);
+
+        doProcess(
+            exchange,
+            ObjectHelper.notNull(requestModel, "requestModel"),
+            ObjectHelper.notNull(responseModel, "responseModel"),
+            apiVersion,
+            ObjectHelper.notNull(action, "action"),
+            ObjectHelper.notNull(tableName, "tableName"),
+            sysId);
+    }
+
+    protected abstract void doProcess(
+        Exchange exchange,
+        Class<?> requestModel,
+        Class<?> responseModel,
+        String apiVersion,
+        String action,
+        String tableName,
+        String sysId) throws Exception;
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/109da7c9/components/camel-servicenow/camel-servicenow-component/src/main/java/org/apache/camel/component/servicenow/releases/fuji/FujiServiceNowProducer.java
----------------------------------------------------------------------
diff --git a/components/camel-servicenow/camel-servicenow-component/src/main/java/org/apache/camel/component/servicenow/releases/fuji/FujiServiceNowProducer.java b/components/camel-servicenow/camel-servicenow-component/src/main/java/org/apache/camel/component/servicenow/releases/fuji/FujiServiceNowProducer.java
new file mode 100644
index 0000000..3d2f6cc
--- /dev/null
+++ b/components/camel-servicenow/camel-servicenow-component/src/main/java/org/apache/camel/component/servicenow/releases/fuji/FujiServiceNowProducer.java
@@ -0,0 +1,36 @@
+/**
+ * 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.releases.fuji;
+
+import org.apache.camel.component.servicenow.AbstractServiceNowProducer;
+import org.apache.camel.component.servicenow.ServiceNowConstants;
+import org.apache.camel.component.servicenow.ServiceNowEndpoint;
+import org.apache.camel.component.servicenow.ServiceNowRelease;
+
+/**
+ * The Fuji ServiceNow producer.
+ */
+public class FujiServiceNowProducer extends AbstractServiceNowProducer {
+    public FujiServiceNowProducer(ServiceNowEndpoint endpoint) throws Exception {
+        super(endpoint, ServiceNowRelease.FUJI);
+
+        bind(ServiceNowConstants.RESOURCE_TABLE, new FujiServiceNowTableProcessor(endpoint));
+        bind(ServiceNowConstants.RESOURCE_AGGREGATE, new FujiServiceNowAggregateProcessor(endpoint));
+        bind(ServiceNowConstants.RESOURCE_IMPORT, new FujiServiceNowImportSetProcessor(endpoint));
+    }
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/109da7c9/components/camel-servicenow/camel-servicenow-component/src/main/java/org/apache/camel/component/servicenow/releases/fuji/FujiServiceNowTableProcessor.java
----------------------------------------------------------------------
diff --git a/components/camel-servicenow/camel-servicenow-component/src/main/java/org/apache/camel/component/servicenow/releases/fuji/FujiServiceNowTableProcessor.java b/components/camel-servicenow/camel-servicenow-component/src/main/java/org/apache/camel/component/servicenow/releases/fuji/FujiServiceNowTableProcessor.java
new file mode 100644
index 0000000..0781811
--- /dev/null
+++ b/components/camel-servicenow/camel-servicenow-component/src/main/java/org/apache/camel/component/servicenow/releases/fuji/FujiServiceNowTableProcessor.java
@@ -0,0 +1,175 @@
+/**
+ * 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.releases.fuji;
+
+import javax.ws.rs.HttpMethod;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+
+import org.apache.camel.Exchange;
+import org.apache.camel.Message;
+import org.apache.camel.component.servicenow.ServiceNowConstants;
+import org.apache.camel.component.servicenow.ServiceNowEndpoint;
+import org.apache.camel.component.servicenow.ServiceNowParams;
+import org.apache.camel.util.ObjectHelper;
+
+class FujiServiceNowTableProcessor extends FujiServiceNowProcessor {
+    FujiServiceNowTableProcessor(ServiceNowEndpoint endpoint) throws Exception {
+        super(endpoint);
+    }
+
+    @Override
+    protected void doProcess(Exchange exchange, Class<?> requestModel, Class<?> responseModel, String apiVersion, String action, String tableName, String sysId) throws Exception {
+        Response response;
+        if (ObjectHelper.equal(ServiceNowConstants.ACTION_RETRIEVE, action, true)) {
+            response = retrieveRecord(exchange.getIn(), requestModel, responseModel, apiVersion, tableName, sysId);
+        } else if (ObjectHelper.equal(ServiceNowConstants.ACTION_CREATE, action, true)) {
+            response = createRecord(exchange.getIn(), requestModel, responseModel, apiVersion, tableName);
+        } else if (ObjectHelper.equal(ServiceNowConstants.ACTION_MODIFY, action, true)) {
+            response = modifyRecord(exchange.getIn(), requestModel, responseModel, apiVersion, tableName, sysId);
+        } else if (ObjectHelper.equal(ServiceNowConstants.ACTION_DELETE, action, true)) {
+            response = deleteRecord(exchange.getIn(), requestModel, responseModel, apiVersion, tableName, sysId);
+        } else if (ObjectHelper.equal(ServiceNowConstants.ACTION_UPDATE, action, true)) {
+            response = updateRecord(exchange.getIn(), requestModel, responseModel, apiVersion, tableName, sysId);
+        } else {
+            throw new IllegalArgumentException("Unknown action " + action);
+        }
+
+        setBodyAndHeaders(exchange.getIn(), responseModel, response);
+    }
+
+    /*
+     * GET
+     * https://instance.service-now.com/api/now/table/{tableName}
+     * https://instance.service-now.com/api/now/table/{tableName}/{sys_id}
+     */
+    private Response retrieveRecord(Message in, Class<?> requestModel, Class<?> responseModel, String apiVersion, String tableName, String sysId) throws Exception {
+        return ObjectHelper.isEmpty(sysId)
+            ? client.reset()
+                .types(MediaType.APPLICATION_JSON_TYPE)
+                .path("now")
+                .path(apiVersion)
+                .path("table")
+                .path(tableName)
+                .query(ServiceNowParams.SYSPARM_QUERY, in)
+                .query(ServiceNowParams.SYSPARM_DISPLAY_VALUE, in)
+                .query(ServiceNowParams.SYSPARM_EXCLUDE_REFERENCE_LINK, in)
+                .query(ServiceNowParams.SYSPARM_FIELDS, in)
+                .query(ServiceNowParams.SYSPARM_LIMIT, in)
+                .query(ServiceNowParams.SYSPARM_VIEW, in)
+                .query(responseModel)
+                .invoke(HttpMethod.GET)
+            : client.reset()
+                .types(MediaType.APPLICATION_JSON_TYPE)
+                .path("now")
+                .path(apiVersion)
+                .path("table")
+                .path(tableName)
+                .path(sysId)
+                .query(ServiceNowParams.SYSPARM_DISPLAY_VALUE, in)
+                .query(ServiceNowParams.SYSPARM_EXCLUDE_REFERENCE_LINK, in)
+                .query(ServiceNowParams.SYSPARM_FIELDS, in)
+                .query(ServiceNowParams.SYSPARM_VIEW, in)
+                .query(responseModel)
+                .invoke(HttpMethod.GET);
+    }
+
+    /*
+     * POST
+     * https://instance.service-now.com/api/now/table/{tableName}
+     */
+    private Response createRecord(Message in, Class<?> requestModel, Class<?> responseModel, String apiVersion, String tableName) throws Exception {
+        validateBody(in, requestModel);
+        return client.reset()
+            .types(MediaType.APPLICATION_JSON_TYPE)
+            .path("now")
+            .path(apiVersion)
+            .path("table")
+            .path(tableName)
+            .query(ServiceNowParams.SYSPARM_DISPLAY_VALUE, in)
+            .query(ServiceNowParams.SYSPARM_EXCLUDE_REFERENCE_LINK, in)
+            .query(ServiceNowParams.SYSPARM_FIELDS, in)
+            .query(ServiceNowParams.SYSPARM_INPUT_DISPLAY_VALUE, in)
+            .query(ServiceNowParams.SYSPARM_SUPPRESS_AUTO_SYS_FIELD, in)
+            .query(ServiceNowParams.SYSPARM_VIEW, in)
+            .query(responseModel)
+            .invoke(HttpMethod.POST, in.getMandatoryBody());
+    }
+
+    /*
+     * PUT
+     * https://instance.service-now.com/api/now/table/{tableName}/{sys_id}
+     */
+    private Response modifyRecord(Message in, Class<?> requestModel, Class<?> responseModel, String apiVersion, String tableName, String sysId) throws Exception {
+        validateBody(in, requestModel);
+        return client.reset()
+            .types(MediaType.APPLICATION_JSON_TYPE)
+            .path("now")
+            .path(apiVersion)
+            .path("table")
+            .path(tableName)
+            .path(ObjectHelper.notNull(sysId, "sysId"))
+            .query(ServiceNowParams.SYSPARM_DISPLAY_VALUE, in)
+            .query(ServiceNowParams.SYSPARM_EXCLUDE_REFERENCE_LINK, in)
+            .query(ServiceNowParams.SYSPARM_FIELDS, in)
+            .query(ServiceNowParams.SYSPARM_INPUT_DISPLAY_VALUE, in)
+            .query(ServiceNowParams.SYSPARM_SUPPRESS_AUTO_SYS_FIELD, in)
+            .query(ServiceNowParams.SYSPARM_VIEW, in)
+            .query(responseModel)
+            .invoke(HttpMethod.PUT, in.getMandatoryBody());
+    }
+
+    /*
+     * DELETE
+     * https://instance.service-now.com/api/now/table/{tableName}/{sys_id}
+     */
+    private Response deleteRecord(Message in, Class<?> requestModel, Class<?> responseModel, String apiVersion, String tableName, String sysId) throws Exception {
+        return client.reset()
+            .types(MediaType.APPLICATION_JSON_TYPE)
+            .path("now")
+            .path(apiVersion)
+            .path("table")
+            .path(tableName)
+            .path(ObjectHelper.notNull(sysId, "sysId"))
+            .query(responseModel)
+            .invoke(HttpMethod.DELETE);
+    }
+
+    /*
+     * PATCH
+     * http://instance.service-now.com/api/now/table/{tableName}/{sys_id}
+     */
+    private Response updateRecord(Message in, Class<?> requestModel, Class<?> responseModel, String apiVersion, String tableName, String sysId) throws Exception {
+        validateBody(in, requestModel);
+        return client.reset()
+            .types(MediaType.APPLICATION_JSON_TYPE)
+            .path("now")
+            .path(apiVersion)
+            .path("table")
+            .path(tableName)
+            .path(ObjectHelper.notNull(sysId, "sysId"))
+            .query(ServiceNowParams.SYSPARM_DISPLAY_VALUE, in)
+            .query(ServiceNowParams.SYSPARM_EXCLUDE_REFERENCE_LINK, in)
+            .query(ServiceNowParams.SYSPARM_FIELDS, in)
+            .query(ServiceNowParams.SYSPARM_INPUT_DISPLAY_VALUE, in)
+            .query(ServiceNowParams.SYSPARM_SUPPRESS_AUTO_SYS_FIELD, in)
+            .query(ServiceNowParams.SYSPARM_VIEW, in)
+            .query(responseModel)
+            .invoke("PATCH", in.getMandatoryBody());
+    }
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/109da7c9/components/camel-servicenow/camel-servicenow-component/src/main/java/org/apache/camel/component/servicenow/releases/helsinki/HelsinkiServiceNowAggregateProcessor.java
----------------------------------------------------------------------
diff --git a/components/camel-servicenow/camel-servicenow-component/src/main/java/org/apache/camel/component/servicenow/releases/helsinki/HelsinkiServiceNowAggregateProcessor.java b/components/camel-servicenow/camel-servicenow-component/src/main/java/org/apache/camel/component/servicenow/releases/helsinki/HelsinkiServiceNowAggregateProcessor.java
new file mode 100644
index 0000000..d895718
--- /dev/null
+++ b/components/camel-servicenow/camel-servicenow-component/src/main/java/org/apache/camel/component/servicenow/releases/helsinki/HelsinkiServiceNowAggregateProcessor.java
@@ -0,0 +1,77 @@
+/**
+ * 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.releases.helsinki;
+
+import javax.ws.rs.HttpMethod;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+
+import org.apache.camel.Exchange;
+import org.apache.camel.Message;
+import org.apache.camel.component.servicenow.AbstractServiceNowProcessor;
+import org.apache.camel.component.servicenow.ServiceNowEndpoint;
+import org.apache.camel.component.servicenow.ServiceNowParams;
+
+import static org.apache.camel.component.servicenow.ServiceNowConstants.ACTION_RETRIEVE;
+
+class HelsinkiServiceNowAggregateProcessor extends AbstractServiceNowProcessor {
+
+    HelsinkiServiceNowAggregateProcessor(ServiceNowEndpoint endpoint) throws Exception {
+        super(endpoint);
+
+        addDispatcher(ACTION_RETRIEVE, this::retrieveStats);
+    }
+
+    /*
+     * This method retrieves records for the specified table and performs aggregate
+     * functions on the returned values.
+     *
+     * Method:
+     * - GET
+     *
+     * URL Format:
+     * - /api/now/api/stats/{tableName}
+     */
+    private void retrieveStats(Exchange exchange) throws Exception {
+        final Message in = exchange.getIn();
+        final String tableName = getTableName(in);
+        final String apiVersion = getApiVersion(in);
+        final Class<?> responseModel = getResponseModel(in, tableName);
+
+        Response response = client.reset()
+            .types(MediaType.APPLICATION_JSON_TYPE)
+            .path("now")
+            .path(apiVersion)
+            .path("stats")
+            .path(tableName)
+            .query(ServiceNowParams.SYSPARM_QUERY, in)
+            .query(ServiceNowParams.SYSPARM_AVG_FIELDS, in)
+            .query(ServiceNowParams.SYSPARM_COUNT, in)
+            .query(ServiceNowParams.SYSPARM_MIN_FIELDS, in)
+            .query(ServiceNowParams.SYSPARM_QUERY, in)
+            .query(ServiceNowParams.SYSPARM_MAX_FIELDS, in)
+            .query(ServiceNowParams.SYSPARM_SUM_FIELDS, in)
+            .query(ServiceNowParams.SYSPARM_GROUP_BY, in)
+            .query(ServiceNowParams.SYSPARM_ORDER_BY, in)
+            .query(ServiceNowParams.SYSPARM_HAVING, in)
+            .query(ServiceNowParams.SYSPARM_DISPLAY_VALUE, in)
+            .query(responseModel)
+            .invoke(HttpMethod.GET);
+
+        setBodyAndHeaders(in, responseModel, response);
+    }
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/109da7c9/components/camel-servicenow/camel-servicenow-component/src/main/java/org/apache/camel/component/servicenow/releases/helsinki/HelsinkiServiceNowAttachmentProcessor.java
----------------------------------------------------------------------
diff --git a/components/camel-servicenow/camel-servicenow-component/src/main/java/org/apache/camel/component/servicenow/releases/helsinki/HelsinkiServiceNowAttachmentProcessor.java b/components/camel-servicenow/camel-servicenow-component/src/main/java/org/apache/camel/component/servicenow/releases/helsinki/HelsinkiServiceNowAttachmentProcessor.java
new file mode 100644
index 0000000..b25bcc0
--- /dev/null
+++ b/components/camel-servicenow/camel-servicenow-component/src/main/java/org/apache/camel/component/servicenow/releases/helsinki/HelsinkiServiceNowAttachmentProcessor.java
@@ -0,0 +1,179 @@
+/**
+ * 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.releases.helsinki;
+
+import java.io.InputStream;
+import javax.ws.rs.HttpMethod;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+
+import org.apache.camel.Exchange;
+import org.apache.camel.Message;
+import org.apache.camel.component.servicenow.AbstractServiceNowProcessor;
+import org.apache.camel.component.servicenow.ServiceNowConstants;
+import org.apache.camel.component.servicenow.ServiceNowEndpoint;
+import org.apache.camel.component.servicenow.ServiceNowParams;
+import org.apache.camel.util.ObjectHelper;
+
+import static org.apache.camel.component.servicenow.ServiceNowConstants.ACTION_CONTENT;
+import static org.apache.camel.component.servicenow.ServiceNowConstants.ACTION_DELETE;
+import static org.apache.camel.component.servicenow.ServiceNowConstants.ACTION_RETRIEVE;
+import static org.apache.camel.component.servicenow.ServiceNowConstants.ACTION_UPLOAD;
+
+public class HelsinkiServiceNowAttachmentProcessor extends AbstractServiceNowProcessor {
+    protected HelsinkiServiceNowAttachmentProcessor(ServiceNowEndpoint endpoint) throws Exception {
+        super(endpoint);
+
+        addDispatcher(ACTION_RETRIEVE, this::retrieveMeta);
+        addDispatcher(ACTION_CONTENT, this::retrieveContent);
+        addDispatcher(ACTION_UPLOAD, this::uploadContent);
+        addDispatcher(ACTION_DELETE, this::deleteContent);
+    }
+
+    /*
+     * This method gets the metadata for multiple attachments or for a specific
+     * attachment with a specific sys_id value
+     *
+     * Method:
+     * - GET
+     *
+     * URL Format:
+     * - /api/now/api/now/attachment
+     * - /api/now/api/now/attachment/{sys_id}
+     */
+    private void retrieveMeta(Exchange exchange) throws Exception {
+        final Message in = exchange.getIn();
+        final String tableName = getTableName(in);
+        final String apiVersion = getApiVersion(in);
+        final Class<?> responseModel = getResponseModel(in, tableName);
+        final String sysId = getSysID(in);
+
+        Response response = ObjectHelper.isEmpty(sysId)
+            ? client.reset()
+                .types(MediaType.APPLICATION_JSON_TYPE)
+                .path("now")
+                .path(apiVersion)
+                .path("attachment")
+                .query(ServiceNowParams.SYSPARM_QUERY, in)
+                .query(ServiceNowParams.SYSPARM_LIMIT, in)
+                .query(ServiceNowParams.SYSPARM_OFFSET, in)
+                .query(ServiceNowParams.SYSPARM_SUPPRESS_PAGINATION_HEADER, in)
+                .invoke(HttpMethod.GET)
+            : client.reset()
+                .types(MediaType.APPLICATION_JSON_TYPE)
+                .path("now")
+                .path(apiVersion)
+                .path("attachment")
+                .path(ObjectHelper.notNull(sysId, "sysId"))
+                .invoke(HttpMethod.GET);
+
+        setBodyAndHeaders(in, responseModel, response);
+    }
+
+    /*
+     * This method gets the binary file attachment with a specific sys_id value.
+     *
+     * Method:
+     * - GET
+     *
+     * URL Format:
+     * - /api/now/attachment/{sys_id}/file
+     */
+    private void retrieveContent(Exchange exchange) throws Exception {
+        final Message in = exchange.getIn();
+        final String apiVersion = getApiVersion(in);
+        final String sysId = getSysID(in);
+
+        Response response = client.reset()
+            .type(MediaType.APPLICATION_JSON_TYPE)
+            .accept("*/*")
+            .path("now")
+            .path(apiVersion)
+            .path("attachment")
+            .path(ObjectHelper.notNull(sysId, "sysId"))
+            .path("file")
+            .invoke(HttpMethod.GET);
+
+        // Header
+        setHeaders(in, null, response);
+
+        in.setBody(response.readEntity(InputStream.class));
+    }
+
+    /*
+     * This method uploads a binary file specified in the request body as an attachment.
+     *
+     * Method:
+     * - POST
+     *
+     * URL Format:
+     * - /api/now/api/now/attachment/file
+     */
+    private void uploadContent(Exchange exchange) throws Exception {
+        final Message in = exchange.getIn();
+        final String tableName = getTableName(in);
+        final String apiVersion = getApiVersion(in);
+        final Class<?> responseModel = getResponseModel(in, tableName);
+
+        Response response = client.reset()
+            .type(ObjectHelper.notNull(
+                in.getHeader(ServiceNowConstants.CONTENT_TYPE, String.class),
+                ServiceNowConstants.CONTENT_TYPE))
+            .accept(MediaType.APPLICATION_JSON_TYPE)
+            .path("now")
+            .path(apiVersion)
+            .path("attachment")
+            .path("file")
+            .query(ServiceNowParams.PARAM_FILE_NAME, in)
+            .query(ServiceNowParams.PARAM_TABLE_NAME, in)
+            .query(ServiceNowParams.PARAM_TABLE_SYS_ID, in)
+            .query(ServiceNowParams.PARAM_ENCRYPTION_CONTEXT, in)
+            .query(responseModel)
+            .invoke(HttpMethod.POST, in.getMandatoryBody(InputStream.class));
+
+        setBodyAndHeaders(in, responseModel, response);
+    }
+
+    /*
+     * This method deletes the attachment with a specific sys_id value.
+     *
+     * Method:
+     * - DELETE
+     *
+     * URL Format:
+     * - /api/now/attachment/{sys_id}
+     */
+    private void deleteContent(Exchange exchange) throws Exception {
+        final Message in = exchange.getIn();
+        final String tableName = getTableName(in);
+        final String apiVersion = getApiVersion(in);
+        final Class<?> responseModel = getResponseModel(in, tableName);
+        final String sysId = getSysID(in);
+
+        Response response = client.reset()
+            .types(MediaType.APPLICATION_JSON_TYPE)
+            .path("now")
+            .path(apiVersion)
+            .path("attachment")
+            .path(ObjectHelper.notNull(sysId, "sysId"))
+            .query(responseModel)
+            .invoke(HttpMethod.DELETE);
+
+        setBodyAndHeaders(in, responseModel, response);
+    }
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/109da7c9/components/camel-servicenow/camel-servicenow-component/src/main/java/org/apache/camel/component/servicenow/releases/helsinki/HelsinkiServiceNowImportSetProcessor.java
----------------------------------------------------------------------
diff --git a/components/camel-servicenow/camel-servicenow-component/src/main/java/org/apache/camel/component/servicenow/releases/helsinki/HelsinkiServiceNowImportSetProcessor.java b/components/camel-servicenow/camel-servicenow-component/src/main/java/org/apache/camel/component/servicenow/releases/helsinki/HelsinkiServiceNowImportSetProcessor.java
new file mode 100644
index 0000000..feb5d47
--- /dev/null
+++ b/components/camel-servicenow/camel-servicenow-component/src/main/java/org/apache/camel/component/servicenow/releases/helsinki/HelsinkiServiceNowImportSetProcessor.java
@@ -0,0 +1,143 @@
+/**
+ * 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.releases.helsinki;
+
+import javax.ws.rs.HttpMethod;
+import javax.ws.rs.core.HttpHeaders;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+
+import org.apache.camel.Exchange;
+import org.apache.camel.Message;
+import org.apache.camel.component.servicenow.AbstractServiceNowProcessor;
+import org.apache.camel.component.servicenow.ServiceNowConstants;
+import org.apache.camel.component.servicenow.ServiceNowEndpoint;
+import org.apache.camel.component.servicenow.ServiceNowParams;
+import org.apache.camel.component.servicenow.model.ImportSetResponse;
+import org.apache.camel.component.servicenow.model.ImportSetResult;
+import org.apache.camel.util.ObjectHelper;
+
+import static org.apache.camel.component.servicenow.ServiceNowConstants.ACTION_CREATE;
+import static org.apache.camel.component.servicenow.ServiceNowConstants.ACTION_RETRIEVE;
+
+class HelsinkiServiceNowImportSetProcessor extends AbstractServiceNowProcessor {
+
+    HelsinkiServiceNowImportSetProcessor(ServiceNowEndpoint endpoint) throws Exception {
+        super(endpoint);
+
+        addDispatcher(ACTION_RETRIEVE, this::retrieveRecord);
+        addDispatcher(ACTION_CREATE, this::createRecord);
+    }
+
+    /*
+     * GET
+     * https://instance.service-now.com/api/now/import/{tableName}/{sys_id}
+     */
+    private void retrieveRecord(Exchange exchange) throws Exception {
+        final Message in = exchange.getIn();
+        final String tableName = getTableName(in);
+        final String apiVersion = getApiVersion(in);
+        final Class<?> responseModel = getResponseModel(in, tableName);
+        final String sysId = getSysID(in);
+
+        Response response = client.reset()
+            .types(MediaType.APPLICATION_JSON_TYPE)
+            .path("now")
+            .path(apiVersion)
+            .path("import")
+            .path(ObjectHelper.notNull(tableName, "tableName"))
+            .path(ObjectHelper.notNull(sysId, "sysId"))
+            .query(responseModel)
+            .invoke(HttpMethod.GET);
+
+        setBodyAndHeaders(in, responseModel, response);
+    }
+
+    /*
+     * POST
+     * https://instance.service-now.com/api/now/import/{tableName}
+     */
+    private void createRecord(Exchange exchange) throws Exception {
+        final Message in = exchange.getIn();
+        final String tableName = getTableName(in);
+        final String apiVersion = getApiVersion(in);
+        final Class<?> requestModel = getRequestModel(in, tableName);
+        final boolean retrieve = in.getHeader(ServiceNowConstants.RETRIEVE_TARGET_RECORD, config::getRetrieveTargetRecordOnImport, Boolean.class);
+
+        Class<?> responseModel = getResponseModel(in, tableName);
+        Response response;
+
+        validateBody(in, requestModel);
+
+        if (retrieve) {
+            // If the endpoint is configured to retrieve the target record, the
+            // import response model is ignored and the response is ImportSetResponse
+
+            response = client.reset()
+                .types(MediaType.APPLICATION_JSON_TYPE)
+                .path("now")
+                .path(apiVersion)
+                .path("import")
+                .path(tableName)
+                .invoke(HttpMethod.POST, in.getMandatoryBody());
+
+            if (ObjectHelper.isNotEmpty(response.getHeaderString(HttpHeaders.CONTENT_TYPE))) {
+                for (ImportSetResult result : response.readEntity(ImportSetResponse.class).getResults()) {
+                    final String status = result.getStatus();
+                    final String table = result.getTable();
+                    final String sysId = result.getSysId();
+
+                    if (ObjectHelper.equalIgnoreCase("inserted", status)) {
+
+                        // If the endpoint is configured to retrieve the target
+                        // record, the response model is related to the target
+                        // table
+                        responseModel = getResponseModel(in, table);
+
+                        // Do get the record
+                        response = client.reset()
+                            .types(MediaType.APPLICATION_JSON_TYPE)
+                            .path("now")
+                            .path(apiVersion)
+                            .path("table")
+                            .path(ObjectHelper.notNull(table, "table"))
+                            .path(ObjectHelper.notNull(sysId, "sys_id"))
+                            .query(ServiceNowParams.SYSPARM_DISPLAY_VALUE, in)
+                            .query(ServiceNowParams.SYSPARM_EXCLUDE_REFERENCE_LINK, in)
+                            .query(ServiceNowParams.SYSPARM_FIELDS, in)
+                            .query(ServiceNowParams.SYSPARM_VIEW, in)
+                            .query(responseModel)
+                            .invoke(HttpMethod.GET);
+
+                        break;
+                    }
+                }
+            }
+        } else {
+            response = client.reset()
+                .types(MediaType.APPLICATION_JSON_TYPE)
+                .path("now")
+                .path(apiVersion)
+                .path("import")
+                .path(tableName)
+                .query(responseModel)
+                .invoke(HttpMethod.POST, in.getMandatoryBody());
+        }
+
+        setBodyAndHeaders(in, responseModel, response);
+    }
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/109da7c9/components/camel-servicenow/camel-servicenow-component/src/main/java/org/apache/camel/component/servicenow/releases/helsinki/HelsinkiServiceNowMiscProcessor.java
----------------------------------------------------------------------
diff --git a/components/camel-servicenow/camel-servicenow-component/src/main/java/org/apache/camel/component/servicenow/releases/helsinki/HelsinkiServiceNowMiscProcessor.java b/components/camel-servicenow/camel-servicenow-component/src/main/java/org/apache/camel/component/servicenow/releases/helsinki/HelsinkiServiceNowMiscProcessor.java
new file mode 100644
index 0000000..c4e9d1b
--- /dev/null
+++ b/components/camel-servicenow/camel-servicenow-component/src/main/java/org/apache/camel/component/servicenow/releases/helsinki/HelsinkiServiceNowMiscProcessor.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.servicenow.releases.helsinki;
+
+import javax.ws.rs.HttpMethod;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+
+import org.apache.camel.Exchange;
+import org.apache.camel.Message;
+import org.apache.camel.component.servicenow.AbstractServiceNowProcessor;
+import org.apache.camel.component.servicenow.ServiceNowEndpoint;
+import org.apache.camel.component.servicenow.ServiceNowParams;
+
+import static org.apache.camel.component.servicenow.ServiceNowConstants.ACTION_CREATE;
+import static org.apache.camel.component.servicenow.ServiceNowConstants.ACTION_RETRIEVE;
+import static org.apache.camel.component.servicenow.ServiceNowConstants.ACTION_SUBJECT_IDENTIFY_RECONCILE;
+import static org.apache.camel.component.servicenow.ServiceNowConstants.ACTION_SUBJECT_USER_ROLE_INHERITANCE;
+
+class HelsinkiServiceNowMiscProcessor extends AbstractServiceNowProcessor {
+
+    HelsinkiServiceNowMiscProcessor(ServiceNowEndpoint endpoint) throws Exception {
+        super(endpoint);
+
+        addDispatcher(ACTION_RETRIEVE, ACTION_SUBJECT_USER_ROLE_INHERITANCE, this::retrieveUserRoleInheritance);
+        addDispatcher(ACTION_CREATE, ACTION_SUBJECT_IDENTIFY_RECONCILE, this::uploadIdentifyReconcile);
+    }
+
+    /*
+     * This method retrieves the roles the user has an determine what was inherited.
+     *
+     * Method:
+     * - GET
+     *
+     * URL Format:
+     * - /api/global/user_role_inheritance
+     */
+    private void retrieveUserRoleInheritance(Exchange exchange) throws Exception {
+        final Message in = exchange.getIn();
+        final Class<?> responseModel = getResponseModel(in);
+        final String apiVersion = getApiVersion(in);
+
+        Response response = client.reset()
+            .types(MediaType.APPLICATION_JSON_TYPE)
+            .path("global")
+            .path("user_role_inheritance")
+            .query(ServiceNowParams.PARAM_USER_SYS_ID, in)
+            .query(responseModel)
+            .invoke(HttpMethod.GET);
+
+        setBodyAndHeaders(in, responseModel, response);
+    }
+
+    /*
+     * This method retrieves the roles the user has an determine what was inherited.
+     *
+     * Method:
+     * - POST
+     *
+     * URL Format:
+     * - /api/now/identifyreconcile
+     */
+    private void uploadIdentifyReconcile(Exchange exchange) throws Exception {
+        final Message in = exchange.getIn();
+        final Class<?> responseModel = getResponseModel(in);
+        final String apiVersion = getApiVersion(in);
+
+        Response response = client.reset()
+            .types(MediaType.APPLICATION_JSON_TYPE)
+            .path("now")
+            .path(apiVersion)
+            .path("identifyreconcile")
+            .query(ServiceNowParams.SYSPARM_DATA_SOURCE, in)
+            .query(responseModel)
+            .invoke(HttpMethod.POST, in.getMandatoryBody());
+
+        setBodyAndHeaders(in, responseModel, response);
+    }
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/109da7c9/components/camel-servicenow/camel-servicenow-component/src/main/java/org/apache/camel/component/servicenow/releases/helsinki/HelsinkiServiceNowProducer.java
----------------------------------------------------------------------
diff --git a/components/camel-servicenow/camel-servicenow-component/src/main/java/org/apache/camel/component/servicenow/releases/helsinki/HelsinkiServiceNowProducer.java b/components/camel-servicenow/camel-servicenow-component/src/main/java/org/apache/camel/component/servicenow/releases/helsinki/HelsinkiServiceNowProducer.java
new file mode 100644
index 0000000..69a86af
--- /dev/null
+++ b/components/camel-servicenow/camel-servicenow-component/src/main/java/org/apache/camel/component/servicenow/releases/helsinki/HelsinkiServiceNowProducer.java
@@ -0,0 +1,42 @@
+/**
+ * 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.releases.helsinki;
+
+import org.apache.camel.component.servicenow.AbstractServiceNowProducer;
+import org.apache.camel.component.servicenow.ServiceNowConstants;
+import org.apache.camel.component.servicenow.ServiceNowEndpoint;
+import org.apache.camel.component.servicenow.ServiceNowRelease;
+
+/**
+ * The Helsinki ServiceNow producer.
+ */
+public class HelsinkiServiceNowProducer extends AbstractServiceNowProducer {
+    public HelsinkiServiceNowProducer(ServiceNowEndpoint endpoint) throws Exception {
+        super(endpoint, ServiceNowRelease.HELSINKI);
+
+        bind(ServiceNowConstants.RESOURCE_TABLE, new HelsinkiServiceNowTableProcessor(endpoint));
+        bind(ServiceNowConstants.RESOURCE_AGGREGATE, new HelsinkiServiceNowAggregateProcessor(endpoint));
+        bind(ServiceNowConstants.RESOURCE_IMPORT, new HelsinkiServiceNowImportSetProcessor(endpoint));
+        bind(ServiceNowConstants.RESOURCE_ATTACHMENT, new HelsinkiServiceNowAttachmentProcessor(endpoint));
+        bind(ServiceNowConstants.RESOURCE_SCORECARDS, new HelsinkiServiceNowScorecardProcessor(endpoint));
+        bind(ServiceNowConstants.RESOURCE_MISC, new HelsinkiServiceNowMiscProcessor(endpoint));
+        bind(ServiceNowConstants.RESOURCE_SERVICE_CATALOG, new HelsinkiServiceNowServiceCatalogProcessor(endpoint));
+        bind(ServiceNowConstants.RESOURCE_SERVICE_CATALOG_ITEMS, new HelsinkiServiceNowServiceCatalogItemsProcessor(endpoint));
+        bind(ServiceNowConstants.RESOURCE_SERVICE_CATALOG_CARTS, new HelsinkiServiceNowServiceCatalogCartsProcessor(endpoint));
+        bind(ServiceNowConstants.RESOURCE_SERVICE_CATALOG_CATEGORIES, new HelsinkiServiceNowServiceCatalogCategoriesProcessor(endpoint));
+    }
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/109da7c9/components/camel-servicenow/camel-servicenow-component/src/main/java/org/apache/camel/component/servicenow/releases/helsinki/HelsinkiServiceNowScorecardProcessor.java
----------------------------------------------------------------------
diff --git a/components/camel-servicenow/camel-servicenow-component/src/main/java/org/apache/camel/component/servicenow/releases/helsinki/HelsinkiServiceNowScorecardProcessor.java b/components/camel-servicenow/camel-servicenow-component/src/main/java/org/apache/camel/component/servicenow/releases/helsinki/HelsinkiServiceNowScorecardProcessor.java
new file mode 100644
index 0000000..78cace8
--- /dev/null
+++ b/components/camel-servicenow/camel-servicenow-component/src/main/java/org/apache/camel/component/servicenow/releases/helsinki/HelsinkiServiceNowScorecardProcessor.java
@@ -0,0 +1,87 @@
+/**
+ * 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.releases.helsinki;
+
+import javax.ws.rs.HttpMethod;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+
+import org.apache.camel.Exchange;
+import org.apache.camel.Message;
+import org.apache.camel.component.servicenow.AbstractServiceNowProcessor;
+import org.apache.camel.component.servicenow.ServiceNowEndpoint;
+import org.apache.camel.component.servicenow.ServiceNowParams;
+
+import static org.apache.camel.component.servicenow.ServiceNowConstants.ACTION_RETRIEVE;
+import static org.apache.camel.component.servicenow.ServiceNowConstants.ACTION_SUBJECT_PERFORMANCE_ANALYTICS;
+
+class HelsinkiServiceNowScorecardProcessor extends AbstractServiceNowProcessor {
+
+    HelsinkiServiceNowScorecardProcessor(ServiceNowEndpoint endpoint) throws Exception {
+        super(endpoint);
+
+        addDispatcher(ACTION_RETRIEVE, ACTION_SUBJECT_PERFORMANCE_ANALYTICS, this::retrievePerformanceAnalytics);
+    }
+
+    /*
+     * This method retrieves Performance Analytics scorecard details.
+     *
+     * Method:
+     * - GET
+     *
+     * URL Format:
+     * - /api/now/pa/scorecards
+     */
+    private void retrievePerformanceAnalytics(Exchange exchange) throws Exception {
+        final Message in = exchange.getIn();
+        final Class<?> responseModel = getResponseModel(in);
+        final String apiVersion = getApiVersion(in);
+
+        Response response = client.reset()
+            .types(MediaType.APPLICATION_JSON_TYPE)
+            .path("now")
+            .path(apiVersion)
+            .path("pa")
+            .path("scorecards")
+            .query(ServiceNowParams.SYSPARM_UUID, in)
+            .query(ServiceNowParams.SYSPARM_BREAKDOWN, in)
+            .query(ServiceNowParams.SYSPARM_INCLUDE_SCORES, in)
+            .query(ServiceNowParams.SYSPARM_INCLUDE_AGGREGATES, in)
+            .query(ServiceNowParams.SYSPARM_INCLUDE_AVAILABLE_BREAKDOWNS, in)
+            .query(ServiceNowParams.SYSPARM_INCLUDE_AVAILABLE_AGGREGATES, in)
+            .query(ServiceNowParams.SYSPARM_DISPLAY_VALUE, in)
+            .query(ServiceNowParams.SYSPARM_EXCLUDE_REFERENCE_LINK, in)
+            .query(ServiceNowParams.SYSPARM_FAVORITES, in)
+            .query(ServiceNowParams.SYSPARM_KEY, in)
+            .query(ServiceNowParams.SYSPARM_TARGET, in)
+            .query(ServiceNowParams.SYSPARM_DISPLAY, in)
+            .query(ServiceNowParams.SYSPARM_CONTAINS, in)
+            .query(ServiceNowParams.SYSPARM_TAGS, in)
+            .query(ServiceNowParams.SYSPARM_PER_PAGE, in)
+            .query(ServiceNowParams.SYSPARM_PAGE, in)
+            .query(ServiceNowParams.SYSPARM_SORT_BY, in)
+            .query(ServiceNowParams.SYSPARM_SORT_DIR, in)
+            .query(ServiceNowParams.SYSPARM_ELEMENTS_FILTER, in)
+            .query(ServiceNowParams.SYSPARM_BREAKDOWN_RELATION, in)
+            .query(ServiceNowParams.SYSPARM_INCLUDE_SCORE_NOTES, in)
+            .query(responseModel)
+            .invoke(HttpMethod.GET);
+
+        setBodyAndHeaders(in, responseModel, response);
+    }
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/109da7c9/components/camel-servicenow/camel-servicenow-component/src/main/java/org/apache/camel/component/servicenow/releases/helsinki/HelsinkiServiceNowServiceCatalogCartsProcessor.java
----------------------------------------------------------------------
diff --git a/components/camel-servicenow/camel-servicenow-component/src/main/java/org/apache/camel/component/servicenow/releases/helsinki/HelsinkiServiceNowServiceCatalogCartsProcessor.java b/components/camel-servicenow/camel-servicenow-component/src/main/java/org/apache/camel/component/servicenow/releases/helsinki/HelsinkiServiceNowServiceCatalogCartsProcessor.java
new file mode 100644
index 0000000..d890172
--- /dev/null
+++ b/components/camel-servicenow/camel-servicenow-component/src/main/java/org/apache/camel/component/servicenow/releases/helsinki/HelsinkiServiceNowServiceCatalogCartsProcessor.java
@@ -0,0 +1,218 @@
+/**
+ * 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.releases.helsinki;
+
+import javax.ws.rs.HttpMethod;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+
+import org.apache.camel.Exchange;
+import org.apache.camel.Message;
+import org.apache.camel.component.servicenow.AbstractServiceNowProcessor;
+import org.apache.camel.component.servicenow.ServiceNowEndpoint;
+import org.apache.camel.component.servicenow.ServiceNowParams;
+
+import static org.apache.camel.component.servicenow.ServiceNowConstants.ACTION_DELETE;
+import static org.apache.camel.component.servicenow.ServiceNowConstants.ACTION_RETRIEVE;
+import static org.apache.camel.component.servicenow.ServiceNowConstants.ACTION_SUBJECT_CHECKOUT;
+import static org.apache.camel.component.servicenow.ServiceNowConstants.ACTION_SUBJECT_DELIVERY_ADDRESS;
+import static org.apache.camel.component.servicenow.ServiceNowConstants.ACTION_UPDATE;
+    
+class HelsinkiServiceNowServiceCatalogCartsProcessor extends AbstractServiceNowProcessor {
+
+    HelsinkiServiceNowServiceCatalogCartsProcessor(ServiceNowEndpoint endpoint) throws Exception {
+        super(endpoint);
+
+        addDispatcher(ACTION_RETRIEVE, ACTION_SUBJECT_DELIVERY_ADDRESS, this::retrieveDeliveryAddress);
+        addDispatcher(ACTION_RETRIEVE, ACTION_SUBJECT_CHECKOUT, this::retrieveCheckoutCart);
+        addDispatcher(ACTION_RETRIEVE, ACTION_SUBJECT_CHECKOUT, this::retrieveCarts);
+        addDispatcher(ACTION_UPDATE, ACTION_SUBJECT_CHECKOUT, this::checkoutCart);
+        addDispatcher(ACTION_UPDATE, this::updateCart);
+        addDispatcher(ACTION_DELETE, this::deleteCart);
+    }
+
+    /*
+     * This method retrieves the default list of cart contents, cart details,
+     * and price shown on the two-step checkout page.
+     *
+     * Method:
+     * - GET
+     *
+     * URL Format:
+     * - /sn_sc/servicecatalog/cart
+     */
+    private void retrieveCarts(Exchange exchange) throws Exception {
+        final Message in = exchange.getIn();
+        final Class<?> responseModel = getResponseModel(in);
+        final String apiVersion = getApiVersion(in);
+
+        Response response = client.reset()
+            .types(MediaType.APPLICATION_JSON_TYPE)
+            .path("sn_sc")
+            .path(apiVersion)
+            .path("servicecatalog")
+            .path("cart")
+            .query(responseModel)
+            .invoke(HttpMethod.GET);
+
+        setBodyAndHeaders(in, responseModel, response);
+    }
+
+    /*
+     * This method retrieves the shipping address of the requested user.
+     *
+     * Method:
+     * - GET
+     *
+     * URL Format:
+     * - /sn_sc/servicecatalog/cart/delivery_address/{user_id}
+     */
+    private void retrieveDeliveryAddress(Exchange exchange) throws Exception {
+        final Message in = exchange.getIn();
+        final Class<?> responseModel = getResponseModel(in);
+        final String apiVersion = getApiVersion(in);
+
+        Response response = client.reset()
+            .types(MediaType.APPLICATION_JSON_TYPE)
+            .path("sn_sc")
+            .path(apiVersion)
+            .path("servicecatalog")
+            .path("cart")
+            .path("delivery_address")
+            .path(getMandatoryRequestParamFromHeader(ServiceNowParams.PARAM_USER_ID, in))
+            .query(responseModel)
+            .invoke(HttpMethod.GET);
+
+        setBodyAndHeaders(in, responseModel, response);
+    }
+
+    /*
+     * This method edits and updates any item in the cart.
+     *
+     * Method:
+     * - POST
+     *
+     * URL Format:
+     * - /sn_sc/servicecatalog/cart/{cart_item_id}
+     */
+    private void updateCart(Exchange exchange) throws Exception {
+        final Message in = exchange.getIn();
+        final Class<?> responseModel = getResponseModel(in);
+        final String apiVersion = getApiVersion(in);
+
+        Response response = client.reset()
+            .types(MediaType.APPLICATION_JSON_TYPE)
+            .path("sn_sc")
+            .path(apiVersion)
+            .path("servicecatalog")
+            .path("cart")
+            .path(getMandatoryRequestParamFromHeader(ServiceNowParams.PARAM_CART_ITEM_ID, in))
+            .query(responseModel)
+            .invoke(HttpMethod.POST, in.getMandatoryBody());
+
+        setBodyAndHeaders(in, responseModel, response);
+    }
+
+    /*
+     * This method deletes the cart and contents of the cart for a given user
+     * role and sys_id.
+     *
+     * Method:
+     * - DELETE
+     *
+     * URL Format:
+     * - /sn_sc/servicecatalog/cart/{sys_id}/empty
+     */
+    private void deleteCart(Exchange exchange) throws Exception {
+        final Message in = exchange.getIn();
+        final Class<?> responseModel = getResponseModel(in);
+        final String apiVersion = getApiVersion(in);
+
+        Response response = client.reset()
+            .types(MediaType.APPLICATION_JSON_TYPE)
+            .path("sn_sc")
+            .path(apiVersion)
+            .path("servicecatalog")
+            .path("cart")
+            .path(getMandatoryRequestParamFromHeader(ServiceNowParams.PARAM_SYS_ID, in))
+            .path("empty")
+            .query(responseModel)
+            .invoke(HttpMethod.DELETE);
+
+        setBodyAndHeaders(in, responseModel, response);
+    }
+
+    /*
+     * This method retrieves the checkout cart details based on the two-step
+     * checkout process enabled or disabled. If the user enables two-step checkout,
+     * the method returns cart order status and all the information required for
+     * two-step checkout. If the user disables two-step checkout, the method
+     * checks out the cart and returns the request number and request order ID.
+     *
+     * Method:
+     * - POST
+     *
+     * URL Format:
+     * - /sn_sc/servicecatalog/cart/checkout
+     */
+    private void retrieveCheckoutCart(Exchange exchange) throws Exception {
+        final Message in = exchange.getIn();
+        final Class<?> responseModel = getResponseModel(in);
+        final String apiVersion = getApiVersion(in);
+
+        Response response = client.reset()
+            .types(MediaType.APPLICATION_JSON_TYPE)
+            .path("sn_sc")
+            .path(apiVersion)
+            .path("servicecatalog")
+            .path("cart")
+            .path("checkout")
+            .query(responseModel)
+            .invoke(HttpMethod.POST);
+
+        setBodyAndHeaders(in, responseModel, response);
+    }
+
+    /*
+     * This method checks out the user cart, whether two-step parameter is
+     * enabled or disabled.
+     *
+     * Method:
+     * - POST
+     *
+     * URL Format:
+     * - /sn_sc/servicecatalog/cart/submit_order
+     */
+    private void checkoutCart(Exchange exchange) throws Exception {
+        final Message in = exchange.getIn();
+        final Class<?> responseModel = getResponseModel(in);
+        final String apiVersion = getApiVersion(in);
+
+        Response response = client.reset()
+            .types(MediaType.APPLICATION_JSON_TYPE)
+            .path("sn_sc")
+            .path(apiVersion)
+            .path("servicecatalog")
+            .path("cart")
+            .path("submit_order")
+            .query(responseModel)
+            .invoke(HttpMethod.POST);
+
+        setBodyAndHeaders(in, responseModel, response);
+    }
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/109da7c9/components/camel-servicenow/camel-servicenow-component/src/main/java/org/apache/camel/component/servicenow/releases/helsinki/HelsinkiServiceNowServiceCatalogCategoriesProcessor.java
----------------------------------------------------------------------
diff --git a/components/camel-servicenow/camel-servicenow-component/src/main/java/org/apache/camel/component/servicenow/releases/helsinki/HelsinkiServiceNowServiceCatalogCategoriesProcessor.java b/components/camel-servicenow/camel-servicenow-component/src/main/java/org/apache/camel/component/servicenow/releases/helsinki/HelsinkiServiceNowServiceCatalogCategoriesProcessor.java
new file mode 100644
index 0000000..bd5e905
--- /dev/null
+++ b/components/camel-servicenow/camel-servicenow-component/src/main/java/org/apache/camel/component/servicenow/releases/helsinki/HelsinkiServiceNowServiceCatalogCategoriesProcessor.java
@@ -0,0 +1,69 @@
+/**
+ * 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.releases.helsinki;
+
+import javax.ws.rs.HttpMethod;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+
+import org.apache.camel.Exchange;
+import org.apache.camel.Message;
+import org.apache.camel.component.servicenow.AbstractServiceNowProcessor;
+import org.apache.camel.component.servicenow.ServiceNowEndpoint;
+import org.apache.camel.component.servicenow.ServiceNowParams;
+import org.apache.camel.util.ObjectHelper;
+
+import static org.apache.camel.component.servicenow.ServiceNowConstants.ACTION_RETRIEVE;
+
+class HelsinkiServiceNowServiceCatalogCategoriesProcessor extends AbstractServiceNowProcessor {
+
+    HelsinkiServiceNowServiceCatalogCategoriesProcessor(ServiceNowEndpoint endpoint) throws Exception {
+        super(endpoint);
+
+        addDispatcher(ACTION_RETRIEVE, this::retrieveCategory);
+    }
+
+    /*
+     * This method retrieves all the information about a requested category.
+     *
+     * Method:
+     * - GET
+     *
+     * URL Format:
+     * - /sn_sc/servicecatalog/categories/{sys_id}
+     */
+    private void retrieveCategory(Exchange exchange) throws Exception {
+        final Message in = exchange.getIn();
+        final Class<?> responseModel = getResponseModel(in);
+        final String sysId = getSysID(in);
+        final String apiVersion = getApiVersion(in);
+
+        Response response = client.reset()
+            .types(MediaType.APPLICATION_JSON_TYPE)
+            .path("sn_sc")
+            .path(apiVersion)
+            .path("servicecatalog")
+            .path("categories")
+            .path(ObjectHelper.notNull(sysId, "sysId"))
+            .query(ServiceNowParams.SYSPARM_VIEW, in)
+            .query(responseModel)
+            .invoke(HttpMethod.GET);
+
+        setBodyAndHeaders(in, responseModel, response);
+    }
+}