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

[camel] 02/02: CAMEL-12434: Future proof the Salesforce Limits API

This is an automated email from the ASF dual-hosted git repository.

zregvart pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/camel.git

commit 94be8a2a4b7ef0945ac9f884ae374bc2110f5174
Author: Zoran Regvart <zr...@apache.org>
AuthorDate: Mon Apr 16 11:44:13 2018 +0200

    CAMEL-12434: Future proof the Salesforce Limits API
    
    Seems that we can't model the Limits as a map of Operation enum and
    Usage DTO, as this makes it fragile if Salesforce renames or adds a
    unsupported Operation. This makes the internal map type keyed by String
    instead of the Operation enum to support those cases.
---
 .../component/salesforce/api/TypeReferences.java   |  3 +-
 .../camel/component/salesforce/api/dto/Limits.java | 65 ++++++++++++----------
 .../component/salesforce/api/dto/LimitsTest.java   | 11 ++++
 3 files changed, 49 insertions(+), 30 deletions(-)

diff --git a/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/TypeReferences.java b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/TypeReferences.java
index 7128312..b6d6fc4 100644
--- a/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/TypeReferences.java
+++ b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/TypeReferences.java
@@ -21,7 +21,6 @@ import java.util.Map;
 
 import com.fasterxml.jackson.core.type.TypeReference;
 
-import org.apache.camel.component.salesforce.api.dto.Limits.Operation;
 import org.apache.camel.component.salesforce.api.dto.Limits.Usage;
 import org.apache.camel.component.salesforce.api.dto.RecentItem;
 import org.apache.camel.component.salesforce.api.dto.RestError;
@@ -35,7 +34,7 @@ import org.apache.camel.component.salesforce.api.dto.analytics.reports.ReportIns
  */
 public final class TypeReferences {
 
-    public static final TypeReference<Map<Operation, Usage>> USAGES_TYPE = new TypeReference<Map<Operation, Usage>>() {
+    public static final TypeReference<Map<String, Usage>> USAGES_TYPE = new TypeReference<Map<String, Usage>>() {
     };
 
     public static final TypeReference<List<RestError>> REST_ERROR_LIST_TYPE = new TypeReference<List<RestError>>() {
diff --git a/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/dto/Limits.java b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/dto/Limits.java
index fc69eb4..d1c53cc 100644
--- a/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/dto/Limits.java
+++ b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/dto/Limits.java
@@ -21,6 +21,7 @@ import java.io.Serializable;
 import java.util.Collections;
 import java.util.HashMap;
 import java.util.Map;
+import java.util.Map.Entry;
 import java.util.Optional;
 import java.util.Set;
 import java.util.stream.Collectors;
@@ -52,7 +53,7 @@ public final class Limits implements Serializable {
         public Object deserialize(final JsonParser parser, final DeserializationContext context)
                 throws IOException, JsonProcessingException {
 
-            final Map<Operation, Usage> usages = parser.readValueAs(TypeReferences.USAGES_TYPE);
+            final Map<String, Usage> usages = parser.readValueAs(TypeReferences.USAGES_TYPE);
 
             return new Limits(usages);
         }
@@ -157,146 +158,154 @@ public final class Limits implements Serializable {
 
     private static final Usage UNDEFINED = new Usage(Usage.UNKNOWN_VAL, Usage.UNKNOWN_VAL);
 
-    private final Map<Operation, Usage> usages;
+    private final Map<String, Usage> usages;
 
-    public Limits(final Map<Operation, Usage> usages) {
-        this.usages = usages;
+    public Limits(final Map<?, Usage> usages) {
+        if (usages == null) {
+            this.usages = new HashMap<>();
+        } else {
+            this.usages = usages.entrySet().stream().collect(Collectors.toMap(e -> String.valueOf(e.getKey()), Entry::getValue));
+        }
     }
 
     public Usage forOperation(final Operation operation) {
         return usages.getOrDefault(operation, UNDEFINED);
     }
 
+    public Usage forOperation(final String name) {
+        return usages.getOrDefault(name, UNDEFINED);
+    }
+
     /** Concurrent REST API requests for results of asynchronous report runs */
     public Usage getConcurrentAsyncGetReportInstances() {
-        return forOperation(Operation.ConcurrentAsyncGetReportInstances);
+        return forOperation(Operation.ConcurrentAsyncGetReportInstances.name());
     }
 
     /** Concurrent synchronous report runs via REST API */
     public Usage getConcurrentSyncReportRuns() {
-        return forOperation(Operation.ConcurrentSyncReportRuns);
+        return forOperation(Operation.ConcurrentSyncReportRuns.name());
     }
 
     /** Daily API calls */
     public Usage getDailyApiRequests() {
-        return forOperation(Operation.DailyApiRequests);
+        return forOperation(Operation.DailyApiRequests.name());
     }
 
     /** Daily Batch Apex and future method executions */
     public Usage getDailyAsyncApexExecutions() {
-        return forOperation(Operation.DailyAsyncApexExecutions);
+        return forOperation(Operation.DailyAsyncApexExecutions.name());
     }
 
     /** Daily Bulk API calls */
     public Usage getDailyBulkApiRequests() {
-        return forOperation(Operation.DailyBulkApiRequests);
+        return forOperation(Operation.DailyBulkApiRequests.name());
     }
 
     /**
      * Daily durable generic streaming events (if generic streaming is enabled for your organization)
      */
     public Usage getDailyDurableGenericStreamingApiEvents() {
-        return forOperation(Operation.DailyDurableGenericStreamingApiEvents);
+        return forOperation(Operation.DailyDurableGenericStreamingApiEvents.name());
     }
 
     /**
      * Daily durable streaming events (if generic streaming is enabled for your organization)
      */
     public Usage getDailyDurableStreamingApiEvents() {
-        return forOperation(Operation.DailyDurableStreamingApiEvents);
+        return forOperation(Operation.DailyDurableStreamingApiEvents.name());
     }
 
     /**
      * Daily generic streaming events (if generic streaming is enabled for your organization)
      */
     public Usage getDailyGenericStreamingApiEvents() {
-        return forOperation(Operation.DailyGenericStreamingApiEvents);
+        return forOperation(Operation.DailyGenericStreamingApiEvents.name());
     }
 
     /** Daily Streaming API events */
     public Usage getDailyStreamingApiEvents() {
-        return forOperation(Operation.DailyStreamingApiEvents);
+        return forOperation(Operation.DailyStreamingApiEvents.name());
     }
 
     /** Daily workflow emails */
     public Usage getDailyWorkflowEmails() {
-        return forOperation(Operation.DailyWorkflowEmails);
+        return forOperation(Operation.DailyWorkflowEmails.name());
     }
 
     /** Data storage (MB) */
     public Usage getDataStorageMB() {
-        return forOperation(Operation.DataStorageMB);
+        return forOperation(Operation.DataStorageMB.name());
     }
 
     /** Streaming API concurrent clients */
     public Usage getDurableStreamingApiConcurrentClients() {
-        return forOperation(Operation.DurableStreamingApiConcurrentClients);
+        return forOperation(Operation.DurableStreamingApiConcurrentClients.name());
     }
 
     /** File storage (MB) */
     public Usage getFileStorageMB() {
-        return forOperation(Operation.FileStorageMB);
+        return forOperation(Operation.FileStorageMB.name());
     }
 
     /** Hourly asynchronous report runs via REST API */
     public Usage getHourlyAsyncReportRuns() {
-        return forOperation(Operation.HourlyAsyncReportRuns);
+        return forOperation(Operation.HourlyAsyncReportRuns.name());
     }
 
     /** Hourly dashboard refreshes via REST API */
     public Usage getHourlyDashboardRefreshes() {
-        return forOperation(Operation.HourlyDashboardRefreshes);
+        return forOperation(Operation.HourlyDashboardRefreshes.name());
     }
 
     /** Hourly REST API requests for dashboard results */
     public Usage getHourlyDashboardResults() {
-        return forOperation(Operation.HourlyDashboardResults);
+        return forOperation(Operation.HourlyDashboardResults.name());
     }
 
     /** Hourly dashboard status requests via REST API */
     public Usage getHourlyDashboardStatuses() {
-        return forOperation(Operation.HourlyDashboardStatuses);
+        return forOperation(Operation.HourlyDashboardStatuses.name());
     }
 
     /** Hourly OData callouts */
     public Usage getHourlyODataCallout() {
-        return forOperation(Operation.HourlyODataCallout);
+        return forOperation(Operation.HourlyODataCallout.name());
     }
 
     /** Hourly synchronous report runs via REST API */
     public Usage getHourlySyncReportRuns() {
-        return forOperation(Operation.HourlySyncReportRuns);
+        return forOperation(Operation.HourlySyncReportRuns.name());
     }
 
     /** Hourly workflow time triggers */
     public Usage getHourlyTimeBasedWorkflow() {
-        return forOperation(Operation.HourlyTimeBasedWorkflow);
+        return forOperation(Operation.HourlyTimeBasedWorkflow.name());
     }
 
     /**
      * Daily number of mass emails that are sent to external email addresses by using Apex or Force.com APIs
      */
     public Usage getMassEmail() {
-        return forOperation(Operation.MassEmail);
+        return forOperation(Operation.MassEmail.name());
     }
 
     /**
      * Usage of permission sets.
      */
     public Usage getPermissionSets() {
-        return forOperation(Operation.PermissionSets);
+        return forOperation(Operation.PermissionSets.name());
     }
 
     /**
      * Daily number of single emails that are sent to external email addresses by using Apex or Force.com APIs
      */
     public Usage getSingleEmail() {
-        return forOperation(Operation.SingleEmail);
+        return forOperation(Operation.SingleEmail.name());
     }
 
     /** Durable streaming API concurrent clients */
     public Usage getStreamingApiConcurrentClients() {
-        return forOperation(Operation.StreamingApiConcurrentClients);
+        return forOperation(Operation.StreamingApiConcurrentClients.name());
     }
 
     /** {@inheritDoc} */
diff --git a/components/camel-salesforce/camel-salesforce-component/src/test/java/org/apache/camel/component/salesforce/api/dto/LimitsTest.java b/components/camel-salesforce/camel-salesforce-component/src/test/java/org/apache/camel/component/salesforce/api/dto/LimitsTest.java
index b5f5a84..d8d8b10 100644
--- a/components/camel-salesforce/camel-salesforce-component/src/test/java/org/apache/camel/component/salesforce/api/dto/LimitsTest.java
+++ b/components/camel-salesforce/camel-salesforce-component/src/test/java/org/apache/camel/component/salesforce/api/dto/LimitsTest.java
@@ -67,6 +67,17 @@ public class LimitsTest {
     }
 
     @Test
+    public void shouldDeserializeWithUnsupportedKeys() throws JsonProcessingException, IOException {
+        final ObjectMapper mapper = JsonUtils.createObjectMapper();
+
+        final Limits withUnsupported = mapper.readerFor(Limits.class)
+            .readValue("{\"Camel-NotSupportedKey\": {\"Max\": 200,\"Remaining\": 200}}");
+
+        assertNotNull(withUnsupported);
+        assertNotNull(withUnsupported.forOperation("Camel-NotSupportedKey"));
+    }
+
+    @Test
     public void shouldSupportGettingAllDefinedUsages() throws IntrospectionException {
         final BeanInfo beanInfo = Introspector.getBeanInfo(Limits.class);
 

-- 
To stop receiving notification emails like this one, please contact
zregvart@apache.org.