From b220f1ba3bcd7904ca89ec9c7a2c165ea6b22d4e Mon Sep 17 00:00:00 2001 From: Vlad Kolotov Date: Mon, 6 Nov 2017 19:05:04 +1300 Subject: [PATCH 1/6] Implementing upsert method Signed-off-by: Vlad Kolotov --- .../java/com/force/api/CreateResponse.java | 24 +------- src/main/java/com/force/api/ForceApi.java | 60 +++++++++++++++---- src/main/java/com/force/api/UpsertResult.java | 15 +++++ src/main/java/com/force/api/UpsertStatus.java | 8 +++ 4 files changed, 71 insertions(+), 36 deletions(-) create mode 100644 src/main/java/com/force/api/UpsertResult.java create mode 100644 src/main/java/com/force/api/UpsertStatus.java diff --git a/src/main/java/com/force/api/CreateResponse.java b/src/main/java/com/force/api/CreateResponse.java index bc8a0f9..fa8c369 100644 --- a/src/main/java/com/force/api/CreateResponse.java +++ b/src/main/java/com/force/api/CreateResponse.java @@ -1,27 +1,5 @@ package com.force.api; -public class CreateResponse { - String id; - ApiError[] errors; - boolean success; - public String getId() { - return id; - } - public void setId(String id) { - this.id = id; - } - public ApiError[] getErrors() { - return errors; - } - public void setErrors(ApiError[] errors) { - this.errors = errors; - } - public boolean isSuccess() { - return success; - } - public void setSuccess(boolean success) { - this.success = success; - } +public class CreateResponse extends ApiResponse { - } diff --git a/src/main/java/com/force/api/ForceApi.java b/src/main/java/com/force/api/ForceApi.java index d91932b..8e17357 100644 --- a/src/main/java/com/force/api/ForceApi.java +++ b/src/main/java/com/force/api/ForceApi.java @@ -279,6 +279,40 @@ public CreateOrUpdateResult createOrUpdateSObject(String type, String externalId } } + public UpsertResult upsertSObject(String type, String externalIdField, String externalIdValue, Object sObject) { + try { + String method = externalIdValue != null ? "PATCH" : "POST"; + String idValue = externalIdValue != null ? "/" + URLEncoder.encode(externalIdValue, "UTF-8") : null; + HttpResponse res = + apiRequest(new HttpRequest() + .url(uriBase() + "/sobjects/" + type + "/" + externalIdField + idValue) + .method(method) + .header("Accept", "application/json") + .header("Content-Type", "application/json") + .content(jsonMapper.writeValueAsBytes(sObject)) + ); + UpsertResult upsertResult = jsonMapper.readValue(res.getStream(), UpsertResult.class); + if (res.getResponseCode() == 201) { + upsertResult.setStatus(UpsertStatus.INSERTED); + return upsertResult; + } else if (res.getResponseCode() == 204) { + upsertResult.setStatus(UpsertStatus.UPDATED); + return upsertResult; + } else { + logger.debug("Code: {}", res.getResponseCode()); + logger.debug("Message: {}", res.getString()); + throw new RuntimeException(); + } + + } catch (JsonGenerationException e) { + throw new ResourceException(e); + } catch (JsonMappingException e) { + throw new ResourceException(e); + } catch (IOException e) { + throw new ResourceException(e); + } + } + public QueryResult query(String query, Class clazz) { try { return queryAny(uriBase() + "/query/?q=" + URLEncoder.encode(query, "UTF-8"), clazz); @@ -416,11 +450,11 @@ public DescribeSObject describeSObject(String sobject) { throw new ResourceException(e); } } - + private final String uriBase() { return(session.getApiEndpoint()+"/services/data/"+config.getApiVersionString()); } - + private final HttpResponse apiRequest(HttpRequest req) { req.setAuthorization("Bearer "+session.getAccessToken()); req.setRequestTimeout(this.config.getRequestTimeout()); @@ -454,7 +488,7 @@ private final HttpResponse apiRequest(HttpRequest req) { return res; } } - + /** * Normalizes the JSON response in case it contains responses from * relationship queries. For e.g. @@ -462,9 +496,9 @@ private final HttpResponse apiRequest(HttpRequest req) { * * Query: * select Id,Name,(select Id,Email,FirstName from Contacts) from Account - * + * * Json Response Returned: - * + * * { * "totalSize" : 1, * "done" : true, @@ -491,9 +525,9 @@ private final HttpResponse apiRequest(HttpRequest req) { * } ] * } * - * + * * Will get normalized to: - * + * * * { * "totalSize" : 1, @@ -515,12 +549,12 @@ private final HttpResponse apiRequest(HttpRequest req) { * "FirstName" : "John" * } ] * } ] - * } + * } * Date: Mon, 6 Nov 2017 19:06:46 +1300 Subject: [PATCH 2/6] Implementing upsert method - adding a missed file Signed-off-by: Vlad Kolotov --- src/main/java/com/force/api/ApiResponse.java | 33 ++++++++++++++++++++ 1 file changed, 33 insertions(+) create mode 100644 src/main/java/com/force/api/ApiResponse.java diff --git a/src/main/java/com/force/api/ApiResponse.java b/src/main/java/com/force/api/ApiResponse.java new file mode 100644 index 0000000..c6543a8 --- /dev/null +++ b/src/main/java/com/force/api/ApiResponse.java @@ -0,0 +1,33 @@ +package com.force.api; + +public class ApiResponse { + + private String id; + private ApiError[] errors; + private boolean success; + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public ApiError[] getErrors() { + return errors; + } + + public void setErrors(ApiError[] errors) { + this.errors = errors; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + +} From 7f9743f00b3d846e8f74d85ea5ff4b8dbcc1008f Mon Sep 17 00:00:00 2001 From: Vlad Kolotov Date: Mon, 6 Nov 2017 21:26:56 +1300 Subject: [PATCH 3/6] Implementing upsert method - bugfixing (if the value is null) Signed-off-by: Vlad Kolotov --- src/main/java/com/force/api/ForceApi.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/force/api/ForceApi.java b/src/main/java/com/force/api/ForceApi.java index 8e17357..5c33b26 100644 --- a/src/main/java/com/force/api/ForceApi.java +++ b/src/main/java/com/force/api/ForceApi.java @@ -282,7 +282,7 @@ public CreateOrUpdateResult createOrUpdateSObject(String type, String externalId public UpsertResult upsertSObject(String type, String externalIdField, String externalIdValue, Object sObject) { try { String method = externalIdValue != null ? "PATCH" : "POST"; - String idValue = externalIdValue != null ? "/" + URLEncoder.encode(externalIdValue, "UTF-8") : null; + String idValue = externalIdValue != null ? "/" + URLEncoder.encode(externalIdValue, "UTF-8") : ""; HttpResponse res = apiRequest(new HttpRequest() .url(uriBase() + "/sobjects/" + type + "/" + externalIdField + idValue) From 345dc948de182e2e19f018d1b4697e78dfd2046d Mon Sep 17 00:00:00 2001 From: Vlad Kolotov Date: Tue, 7 Nov 2017 16:15:28 +1300 Subject: [PATCH 4/6] Implementing upsert method - bugfixing (PATCH http method) Signed-off-by: Vlad Kolotov --- src/main/java/com/force/api/ForceApi.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main/java/com/force/api/ForceApi.java b/src/main/java/com/force/api/ForceApi.java index 5c33b26..96df214 100644 --- a/src/main/java/com/force/api/ForceApi.java +++ b/src/main/java/com/force/api/ForceApi.java @@ -281,12 +281,12 @@ public CreateOrUpdateResult createOrUpdateSObject(String type, String externalId public UpsertResult upsertSObject(String type, String externalIdField, String externalIdValue, Object sObject) { try { - String method = externalIdValue != null ? "PATCH" : "POST"; String idValue = externalIdValue != null ? "/" + URLEncoder.encode(externalIdValue, "UTF-8") : ""; HttpResponse res = apiRequest(new HttpRequest() - .url(uriBase() + "/sobjects/" + type + "/" + externalIdField + idValue) - .method(method) + .url(uriBase() + "/sobjects/" + type + "/" + externalIdField + idValue + + "?_HttpMethod=PATCH") + .method("POST") .header("Accept", "application/json") .header("Content-Type", "application/json") .content(jsonMapper.writeValueAsBytes(sObject)) From 6333756018fe0c088639cf5aea63f44ce3ce5812 Mon Sep 17 00:00:00 2001 From: Vlad Kolotov Date: Tue, 7 Nov 2017 16:38:41 +1300 Subject: [PATCH 5/6] Implementing upsert method - bugfixing (HTTP Method 'PATCH' not allowed. Allowed are GET,HEAD,POST) Signed-off-by: Vlad Kolotov --- src/main/java/com/force/api/ForceApi.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/force/api/ForceApi.java b/src/main/java/com/force/api/ForceApi.java index 96df214..f8763dd 100644 --- a/src/main/java/com/force/api/ForceApi.java +++ b/src/main/java/com/force/api/ForceApi.java @@ -281,11 +281,11 @@ public CreateOrUpdateResult createOrUpdateSObject(String type, String externalId public UpsertResult upsertSObject(String type, String externalIdField, String externalIdValue, Object sObject) { try { + String method = externalIdValue != null ? "?_HttpMethod=PATCH" : ""; String idValue = externalIdValue != null ? "/" + URLEncoder.encode(externalIdValue, "UTF-8") : ""; HttpResponse res = apiRequest(new HttpRequest() - .url(uriBase() + "/sobjects/" + type + "/" + externalIdField + idValue - + "?_HttpMethod=PATCH") + .url(uriBase() + "/sobjects/" + type + "/" + externalIdField + idValue + method) .method("POST") .header("Accept", "application/json") .header("Content-Type", "application/json") From 1b5ebd64ce2a6d93d739aa292a385f6f57f69dfa Mon Sep 17 00:00:00 2001 From: Vlad Kolotov Date: Wed, 8 Nov 2017 00:14:08 +1300 Subject: [PATCH 6/6] Implementing upsert method - bugfixing (Salesforce returns empty response body for the 204 code) Signed-off-by: Vlad Kolotov --- src/main/java/com/force/api/ForceApi.java | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/force/api/ForceApi.java b/src/main/java/com/force/api/ForceApi.java index f8763dd..be2c59b 100644 --- a/src/main/java/com/force/api/ForceApi.java +++ b/src/main/java/com/force/api/ForceApi.java @@ -291,11 +291,15 @@ public UpsertResult upsertSObject(String type, String externalIdField, String ex .header("Content-Type", "application/json") .content(jsonMapper.writeValueAsBytes(sObject)) ); - UpsertResult upsertResult = jsonMapper.readValue(res.getStream(), UpsertResult.class); if (res.getResponseCode() == 201) { + UpsertResult upsertResult = jsonMapper.readValue(res.getStream(), UpsertResult.class); upsertResult.setStatus(UpsertStatus.INSERTED); return upsertResult; } else if (res.getResponseCode() == 204) { + UpsertResult upsertResult = new UpsertResult(); + if ("Id".equals(externalIdField)) { + upsertResult.setId(externalIdValue); + } upsertResult.setStatus(UpsertStatus.UPDATED); return upsertResult; } else {