embulk-input-marketo-through-proxy 0.6.20

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (90) hide show
  1. checksums.yaml +7 -0
  2. data/.github/CODEOWNERS +1 -0
  3. data/.github/PULL_REQUEST_TEMPLATE.md +37 -0
  4. data/.github/workflows/build.yml +38 -0
  5. data/.gitignore +14 -0
  6. data/CHANGELOG.md +178 -0
  7. data/LICENSE.txt +21 -0
  8. data/README.md +231 -0
  9. data/build.gradle +105 -0
  10. data/config/checkstyle/checkstyle.xml +128 -0
  11. data/config/checkstyle/default.xml +108 -0
  12. data/gradle/wrapper/gradle-wrapper.jar +0 -0
  13. data/gradle/wrapper/gradle-wrapper.properties +6 -0
  14. data/gradlew +169 -0
  15. data/gradlew.bat +84 -0
  16. data/lib/embulk/input/marketo.rb +3 -0
  17. data/settings.gradle +1 -0
  18. data/src/main/java/org/embulk/input/marketo/CsvTokenizer.java +695 -0
  19. data/src/main/java/org/embulk/input/marketo/MarketoInputPlugin.java +15 -0
  20. data/src/main/java/org/embulk/input/marketo/MarketoInputPluginDelegate.java +100 -0
  21. data/src/main/java/org/embulk/input/marketo/MarketoService.java +47 -0
  22. data/src/main/java/org/embulk/input/marketo/MarketoServiceImpl.java +258 -0
  23. data/src/main/java/org/embulk/input/marketo/MarketoUtils.java +212 -0
  24. data/src/main/java/org/embulk/input/marketo/delegate/ActivityBulkExtractInputPlugin.java +169 -0
  25. data/src/main/java/org/embulk/input/marketo/delegate/CampaignInputPlugin.java +48 -0
  26. data/src/main/java/org/embulk/input/marketo/delegate/CustomObjectInputPlugin.java +124 -0
  27. data/src/main/java/org/embulk/input/marketo/delegate/CustomObjectResponseMapperBuilder.java +81 -0
  28. data/src/main/java/org/embulk/input/marketo/delegate/LeadBulkExtractInputPlugin.java +68 -0
  29. data/src/main/java/org/embulk/input/marketo/delegate/LeadServiceResponseMapperBuilder.java +85 -0
  30. data/src/main/java/org/embulk/input/marketo/delegate/LeadWithListInputPlugin.java +89 -0
  31. data/src/main/java/org/embulk/input/marketo/delegate/LeadWithProgramInputPlugin.java +85 -0
  32. data/src/main/java/org/embulk/input/marketo/delegate/MarketoBaseBulkExtractInputPlugin.java +448 -0
  33. data/src/main/java/org/embulk/input/marketo/delegate/MarketoBaseInputPluginDelegate.java +160 -0
  34. data/src/main/java/org/embulk/input/marketo/delegate/ProgramInputPlugin.java +234 -0
  35. data/src/main/java/org/embulk/input/marketo/exception/MarketoAPIException.java +30 -0
  36. data/src/main/java/org/embulk/input/marketo/model/BulkExtractRangeHeader.java +26 -0
  37. data/src/main/java/org/embulk/input/marketo/model/MarketoAccessTokenResponse.java +92 -0
  38. data/src/main/java/org/embulk/input/marketo/model/MarketoBulkExtractRequest.java +68 -0
  39. data/src/main/java/org/embulk/input/marketo/model/MarketoError.java +40 -0
  40. data/src/main/java/org/embulk/input/marketo/model/MarketoField.java +126 -0
  41. data/src/main/java/org/embulk/input/marketo/model/MarketoResponse.java +82 -0
  42. data/src/main/java/org/embulk/input/marketo/model/filter/DateRangeFilter.java +40 -0
  43. data/src/main/java/org/embulk/input/marketo/rest/MarketoBaseRestClient.java +344 -0
  44. data/src/main/java/org/embulk/input/marketo/rest/MarketoInputStreamResponseEntityReader.java +69 -0
  45. data/src/main/java/org/embulk/input/marketo/rest/MarketoRESTEndpoint.java +47 -0
  46. data/src/main/java/org/embulk/input/marketo/rest/MarketoResponseJetty92EntityReader.java +89 -0
  47. data/src/main/java/org/embulk/input/marketo/rest/MarketoRestClient.java +601 -0
  48. data/src/main/java/org/embulk/input/marketo/rest/RecordPagingIterable.java +180 -0
  49. data/src/test/java/org/embulk/input/marketo/MarketoServiceImplTest.java +147 -0
  50. data/src/test/java/org/embulk/input/marketo/MarketoUtilsTest.java +89 -0
  51. data/src/test/java/org/embulk/input/marketo/delegate/ActivityBulkExtractInputPluginTest.java +129 -0
  52. data/src/test/java/org/embulk/input/marketo/delegate/CampaignInputPluginTest.java +73 -0
  53. data/src/test/java/org/embulk/input/marketo/delegate/CustomObjectInputPluginTest.java +175 -0
  54. data/src/test/java/org/embulk/input/marketo/delegate/LeadBulkExtractInputPluginTest.java +102 -0
  55. data/src/test/java/org/embulk/input/marketo/delegate/LeadServiceResponseMapperBuilderTest.java +119 -0
  56. data/src/test/java/org/embulk/input/marketo/delegate/LeadWithListInputPluginTest.java +132 -0
  57. data/src/test/java/org/embulk/input/marketo/delegate/LeadWithProgramInputPluginTest.java +134 -0
  58. data/src/test/java/org/embulk/input/marketo/delegate/MarketoBaseBulkExtractInputPluginTest.java +171 -0
  59. data/src/test/java/org/embulk/input/marketo/delegate/MarketoBaseInputPluginDelegateTest.java +60 -0
  60. data/src/test/java/org/embulk/input/marketo/delegate/ProgramInputPluginTest.java +325 -0
  61. data/src/test/java/org/embulk/input/marketo/rest/MarketoBaseRestClientTest.java +368 -0
  62. data/src/test/java/org/embulk/input/marketo/rest/MarketoRestClientTest.java +649 -0
  63. data/src/test/resources/config/activity_bulk_extract_config.yaml +7 -0
  64. data/src/test/resources/config/custom_object_config.yaml +8 -0
  65. data/src/test/resources/config/lead_bulk_extract_config.yaml +8 -0
  66. data/src/test/resources/config/rest_config.yaml +3 -0
  67. data/src/test/resources/fixtures/activity_extract1.csv +35 -0
  68. data/src/test/resources/fixtures/activity_extract2.csv +22 -0
  69. data/src/test/resources/fixtures/activity_types.json +22 -0
  70. data/src/test/resources/fixtures/all_program_full.json +53 -0
  71. data/src/test/resources/fixtures/campaign_response.json +38 -0
  72. data/src/test/resources/fixtures/campaign_response_full.json +102 -0
  73. data/src/test/resources/fixtures/custom_object_describe.json +124 -0
  74. data/src/test/resources/fixtures/custom_object_describe_marketo_fields_full.json +22 -0
  75. data/src/test/resources/fixtures/custom_object_expected.json +66 -0
  76. data/src/test/resources/fixtures/custom_object_response.json +24 -0
  77. data/src/test/resources/fixtures/custom_object_response_full.json +23 -0
  78. data/src/test/resources/fixtures/lead_by_list.json +33 -0
  79. data/src/test/resources/fixtures/lead_by_program_response.json +47 -0
  80. data/src/test/resources/fixtures/lead_describe.json +221 -0
  81. data/src/test/resources/fixtures/lead_describe_expected.json +66 -0
  82. data/src/test/resources/fixtures/lead_describe_marketo_fields_full.json +518 -0
  83. data/src/test/resources/fixtures/lead_extract1.csv +11 -0
  84. data/src/test/resources/fixtures/lead_response_full.json +2402 -0
  85. data/src/test/resources/fixtures/lead_with_program_full.json +17 -0
  86. data/src/test/resources/fixtures/leads_extract2.csv +10 -0
  87. data/src/test/resources/fixtures/list_reponse_full.json +191 -0
  88. data/src/test/resources/fixtures/lists_response.json +31 -0
  89. data/src/test/resources/fixtures/program_response.json +71 -0
  90. metadata +173 -0
@@ -0,0 +1,73 @@
1
+ package org.embulk.input.marketo.delegate;
2
+
3
+ import com.fasterxml.jackson.databind.JavaType;
4
+ import com.fasterxml.jackson.databind.ObjectMapper;
5
+ import com.fasterxml.jackson.databind.node.ObjectNode;
6
+ import org.embulk.EmbulkTestRuntime;
7
+ import org.embulk.base.restclient.ServiceResponseMapper;
8
+ import org.embulk.base.restclient.record.RecordImporter;
9
+ import org.embulk.base.restclient.record.ValueLocator;
10
+ import org.embulk.config.ConfigLoader;
11
+ import org.embulk.config.ConfigSource;
12
+ import org.embulk.input.marketo.rest.MarketoRestClient;
13
+ import org.embulk.input.marketo.rest.RecordPagingIterable;
14
+ import org.embulk.spi.PageBuilder;
15
+ import org.embulk.spi.Schema;
16
+ import org.junit.Before;
17
+ import org.junit.Rule;
18
+ import org.junit.Test;
19
+ import org.mockito.ArgumentCaptor;
20
+ import org.mockito.Mockito;
21
+
22
+ import java.io.IOException;
23
+ import java.util.List;
24
+
25
+ import static org.junit.Assert.assertArrayEquals;
26
+
27
+ /**
28
+ * Created by tai.khuu on 10/10/17.
29
+ */
30
+ public class CampaignInputPluginTest
31
+ {
32
+ private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper();
33
+
34
+ @Rule
35
+ public EmbulkTestRuntime embulkTestRuntime = new EmbulkTestRuntime();
36
+
37
+ private ConfigSource configSource;
38
+
39
+ private CampaignInputPlugin campaignInputPlugin;
40
+
41
+ private MarketoRestClient mockMarketoRestClient;
42
+
43
+ @Before
44
+ public void setUp() throws Exception
45
+ {
46
+ campaignInputPlugin = Mockito.spy(new CampaignInputPlugin());
47
+ ConfigLoader configLoader = embulkTestRuntime.getInjector().getInstance(ConfigLoader.class);
48
+ configSource = configLoader.fromYaml(this.getClass().getResourceAsStream("/config/rest_config.yaml"));
49
+ mockMarketoRestClient = Mockito.mock(MarketoRestClient.class);
50
+ Mockito.doReturn(mockMarketoRestClient).when(campaignInputPlugin).createMarketoRestClient(Mockito.any(CampaignInputPlugin.PluginTask.class));
51
+ }
52
+
53
+ @Test
54
+ public void testRun() throws IOException
55
+ {
56
+ RecordPagingIterable<ObjectNode> mockRecordPagingIterable = Mockito.mock(RecordPagingIterable.class);
57
+ JavaType javaType = OBJECT_MAPPER.getTypeFactory().constructParametrizedType(List.class, List.class, ObjectNode.class);
58
+ List<ObjectNode> objectNodeList = OBJECT_MAPPER.readValue(this.getClass().getResourceAsStream("/fixtures/campaign_response_full.json"), javaType);
59
+ Mockito.when(mockRecordPagingIterable.iterator()).thenReturn(objectNodeList.iterator());
60
+ Mockito.when(mockMarketoRestClient.getCampaign()).thenReturn(mockRecordPagingIterable);
61
+ CampaignInputPlugin.PluginTask task = configSource.loadConfig(CampaignInputPlugin.PluginTask.class);
62
+ ServiceResponseMapper<? extends ValueLocator> mapper = campaignInputPlugin.buildServiceResponseMapper(task);
63
+ RecordImporter recordImporter = mapper.createRecordImporter();
64
+ PageBuilder mockPageBuilder = Mockito.mock(PageBuilder.class);
65
+ campaignInputPlugin.ingestServiceData(task, recordImporter, 1, mockPageBuilder);
66
+ Mockito.verify(mockMarketoRestClient, Mockito.times(1)).getCampaign();
67
+ Schema embulkSchema = mapper.getEmbulkSchema();
68
+ ArgumentCaptor<Long> longArgumentCaptor = ArgumentCaptor.forClass(Long.class);
69
+ Mockito.verify(mockPageBuilder, Mockito.times(10)).setLong(Mockito.eq(embulkSchema.lookupColumn("id")), longArgumentCaptor.capture());
70
+ List<Long> allValues = longArgumentCaptor.getAllValues();
71
+ assertArrayEquals(new Long[]{1003L, 1004L, 1005L, 1006L, 1007L, 1008L, 1029L, 1048L, 1051L, 1065L}, allValues.toArray());
72
+ }
73
+ }
@@ -0,0 +1,175 @@
1
+ package org.embulk.input.marketo.delegate;
2
+
3
+ import com.fasterxml.jackson.databind.JavaType;
4
+ import com.fasterxml.jackson.databind.ObjectMapper;
5
+ import com.fasterxml.jackson.databind.node.ObjectNode;
6
+ import org.embulk.EmbulkTestRuntime;
7
+ import org.embulk.base.restclient.ServiceResponseMapper;
8
+ import org.embulk.base.restclient.record.RecordImporter;
9
+ import org.embulk.base.restclient.record.ValueLocator;
10
+ import org.embulk.config.ConfigException;
11
+ import org.embulk.config.ConfigLoader;
12
+ import org.embulk.config.ConfigSource;
13
+ import org.embulk.input.marketo.model.MarketoField;
14
+ import org.embulk.input.marketo.rest.MarketoRestClient;
15
+ import org.embulk.input.marketo.rest.RecordPagingIterable;
16
+ import org.embulk.spi.PageBuilder;
17
+ import org.embulk.spi.Schema;
18
+ import org.junit.Assert;
19
+ import org.junit.Before;
20
+ import org.junit.Rule;
21
+ import org.junit.Test;
22
+ import org.mockito.ArgumentCaptor;
23
+ import org.mockito.Mockito;
24
+
25
+ import java.io.IOException;
26
+ import java.util.List;
27
+
28
+ import static org.junit.Assert.assertArrayEquals;
29
+
30
+ public class CustomObjectInputPluginTest
31
+ {
32
+ private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper();
33
+
34
+ @Rule
35
+ public EmbulkTestRuntime embulkTestRuntime = new EmbulkTestRuntime();
36
+
37
+ private CustomObjectInputPlugin customObjectInputPlugin;
38
+
39
+ private ConfigSource configSource;
40
+
41
+ private MarketoRestClient mockMarketoRestClient;
42
+
43
+ @Before
44
+ public void setUp() throws Exception
45
+ {
46
+ customObjectInputPlugin = Mockito.spy(new CustomObjectInputPlugin());
47
+ ConfigLoader configLoader = embulkTestRuntime.getInjector().getInstance(ConfigLoader.class);
48
+ configSource = configLoader.fromYaml(this.getClass().getResourceAsStream("/config/custom_object_config.yaml"));
49
+ mockMarketoRestClient = Mockito.mock(MarketoRestClient.class);
50
+ Mockito.doReturn(mockMarketoRestClient).when(customObjectInputPlugin).createMarketoRestClient(Mockito.any(CustomObjectInputPlugin.PluginTask.class));
51
+ }
52
+
53
+ @Test
54
+ public void testValidPluginTask()
55
+ {
56
+ CustomObjectInputPlugin.PluginTask pluginTask = configSource.loadConfig(CustomObjectInputPlugin.PluginTask.class);
57
+ // should not cause exception
58
+ customObjectInputPlugin.validateInputTask(pluginTask);
59
+ }
60
+
61
+ @Test
62
+ public void testCustomObjectFilterTypeError()
63
+ {
64
+ CustomObjectInputPlugin.PluginTask pluginTask = configSource
65
+ .set("custom_object_filter_type", "")
66
+ .loadConfig(CustomObjectInputPlugin.PluginTask.class);
67
+ Assert.assertThrows(ConfigException.class, () -> customObjectInputPlugin.validateInputTask(pluginTask));
68
+ }
69
+
70
+ @Test
71
+ public void testCustomObjectAPINameError()
72
+ {
73
+ CustomObjectInputPlugin.PluginTask pluginTask = configSource
74
+ .set("custom_object_api_name", "")
75
+ .loadConfig(CustomObjectInputPlugin.PluginTask.class);
76
+ Assert.assertThrows(ConfigException.class, () -> customObjectInputPlugin.validateInputTask(pluginTask));
77
+ }
78
+
79
+ @Test
80
+ public void testFromValueGreaterThanToValueError()
81
+ {
82
+ CustomObjectInputPlugin.PluginTask pluginTask = configSource
83
+ .set("custom_object_filter_from_value", "10")
84
+ .set("custom_object_filter_to_value", "5").loadConfig(CustomObjectInputPlugin.PluginTask.class);
85
+ Assert.assertThrows(ConfigException.class, () -> customObjectInputPlugin.validateInputTask(pluginTask));
86
+ }
87
+
88
+ @Test
89
+ public void testEmptyStringFilterValues()
90
+ {
91
+ CustomObjectInputPlugin.PluginTask pluginTask = configSource
92
+ .set("custom_object_filter_values", "").loadConfig(CustomObjectInputPlugin.PluginTask.class);
93
+
94
+ Assert.assertThrows(ConfigException.class, () -> customObjectInputPlugin.validateInputTask(pluginTask));
95
+ }
96
+
97
+ @Test
98
+ public void testAllEmptyStringFilterValues()
99
+ {
100
+ CustomObjectInputPlugin.PluginTask pluginTask = configSource
101
+ .set("custom_object_filter_values", ",, , ").loadConfig(CustomObjectInputPlugin.PluginTask.class);
102
+
103
+ Assert.assertThrows(ConfigException.class, () -> customObjectInputPlugin.validateInputTask(pluginTask));
104
+ }
105
+
106
+ @Test
107
+ public void testRunStringFilterValues() throws IOException
108
+ {
109
+ RecordPagingIterable<ObjectNode> mockRecordPagingIterable = mockAndGetResponse();
110
+ Mockito.when(mockMarketoRestClient.getCustomObject(Mockito.anyString(), Mockito.anyString(), Mockito.anyString(), Mockito.anyString())).thenReturn(mockRecordPagingIterable);
111
+
112
+ CustomObjectInputPlugin.PluginTask task = configSource.set("custom_object_filter_values", "value1,value2,value3,value4").loadConfig(CustomObjectInputPlugin.PluginTask.class);
113
+ ServiceResponseMapper<? extends ValueLocator> mapper = customObjectInputPlugin.buildServiceResponseMapper(task);
114
+ RecordImporter recordImporter = mapper.createRecordImporter();
115
+ PageBuilder mockPageBuilder = Mockito.mock(PageBuilder.class);
116
+ customObjectInputPlugin.ingestServiceData(task, recordImporter, 1, mockPageBuilder);
117
+ Mockito.verify(mockMarketoRestClient, Mockito.times(1)).getCustomObject(Mockito.anyString(), Mockito.anyString(), Mockito.anyString(), Mockito.anyString());
118
+
119
+ verifyAfterRun(mapper, mockPageBuilder);
120
+ }
121
+
122
+ @Test
123
+ public void testRunWithFilterRange() throws IOException
124
+ {
125
+ RecordPagingIterable<ObjectNode> mockRecordPagingIterable = mockAndGetResponse();
126
+ Mockito.when(mockMarketoRestClient.getCustomObject(Mockito.anyString(), Mockito.anyString(), Mockito.anyString(), Mockito.anyString())).thenReturn(mockRecordPagingIterable);
127
+
128
+ CustomObjectInputPlugin.PluginTask task = configSource.loadConfig(CustomObjectInputPlugin.PluginTask.class);
129
+ ServiceResponseMapper<? extends ValueLocator> mapper = customObjectInputPlugin.buildServiceResponseMapper(task);
130
+ RecordImporter recordImporter = mapper.createRecordImporter();
131
+ PageBuilder mockPageBuilder = Mockito.mock(PageBuilder.class);
132
+ customObjectInputPlugin.ingestServiceData(task, recordImporter, 1, mockPageBuilder);
133
+ Mockito.verify(mockMarketoRestClient, Mockito.times(1)).getCustomObject(Mockito.anyString(), Mockito.anyString(), Mockito.anyString(), Mockito.anyString());
134
+
135
+ verifyAfterRun(mapper, mockPageBuilder);
136
+ }
137
+
138
+ @Test
139
+ public void testRunFromOnlyFilter() throws IOException
140
+ {
141
+ RecordPagingIterable<ObjectNode> mockRecordPagingIterable = mockAndGetResponse();
142
+ Mockito.when(mockMarketoRestClient.getCustomObject(Mockito.anyString(), Mockito.anyString(), Mockito.anyString(), Mockito.anyInt(), Mockito.isNull())).thenReturn(mockRecordPagingIterable);
143
+
144
+ CustomObjectInputPlugin.PluginTask task = configSource.remove("custom_object_filter_to_value").loadConfig(CustomObjectInputPlugin.PluginTask.class);
145
+ ServiceResponseMapper<? extends ValueLocator> mapper = customObjectInputPlugin.buildServiceResponseMapper(task);
146
+ RecordImporter recordImporter = mapper.createRecordImporter();
147
+ PageBuilder mockPageBuilder = Mockito.mock(PageBuilder.class);
148
+ customObjectInputPlugin.ingestServiceData(task, recordImporter, 1, mockPageBuilder);
149
+ Mockito.verify(mockMarketoRestClient, Mockito.times(1)).getCustomObject(Mockito.anyString(), Mockito.anyString(), Mockito.anyString(), Mockito.anyInt(), Mockito.isNull());
150
+
151
+ verifyAfterRun(mapper, mockPageBuilder);
152
+ }
153
+
154
+ private void verifyAfterRun(ServiceResponseMapper<? extends ValueLocator> mapper, PageBuilder mockPageBuilder)
155
+ {
156
+ Mockito.verify(mockMarketoRestClient, Mockito.times(1)).describeCustomObject(Mockito.anyString());
157
+ Schema schema = mapper.getEmbulkSchema();
158
+ ArgumentCaptor<Long> longArgumentCaptor = ArgumentCaptor.forClass(Long.class);
159
+ Mockito.verify(mockPageBuilder, Mockito.times(3)).setLong(Mockito.eq(schema.lookupColumn("mk_id")), longArgumentCaptor.capture());
160
+ List<Long> allValues = longArgumentCaptor.getAllValues();
161
+ assertArrayEquals(new Long[]{1L, 2L, 3L}, allValues.toArray());
162
+ }
163
+
164
+ private RecordPagingIterable<ObjectNode> mockAndGetResponse() throws IOException
165
+ {
166
+ RecordPagingIterable<ObjectNode> mockRecordPagingIterable = Mockito.mock(RecordPagingIterable.class);
167
+ JavaType javaType = OBJECT_MAPPER.getTypeFactory().constructParametrizedType(List.class, List.class, ObjectNode.class);
168
+ List<ObjectNode> objectNodeList = OBJECT_MAPPER.readValue(this.getClass().getResourceAsStream("/fixtures/custom_object_response_full.json"), javaType);
169
+ JavaType marketoFieldsType = OBJECT_MAPPER.getTypeFactory().constructParametrizedType(List.class, List.class, MarketoField.class);
170
+ List<MarketoField> marketoFields = OBJECT_MAPPER.readValue(this.getClass().getResourceAsStream("/fixtures/custom_object_describe_marketo_fields_full.json"), marketoFieldsType);
171
+ Mockito.when(mockRecordPagingIterable.iterator()).thenReturn(objectNodeList.iterator());
172
+ Mockito.when(mockMarketoRestClient.describeCustomObject(Mockito.anyString())).thenReturn(marketoFields);
173
+ return mockRecordPagingIterable;
174
+ }
175
+ }
@@ -0,0 +1,102 @@
1
+ package org.embulk.input.marketo.delegate;
2
+
3
+ import com.fasterxml.jackson.databind.JavaType;
4
+ import com.fasterxml.jackson.databind.ObjectMapper;
5
+ import org.embulk.EmbulkTestRuntime;
6
+ import org.embulk.base.restclient.ServiceResponseMapper;
7
+ import org.embulk.base.restclient.record.ValueLocator;
8
+ import org.embulk.config.ConfigDiff;
9
+ import org.embulk.config.ConfigLoader;
10
+ import org.embulk.config.ConfigSource;
11
+ import org.embulk.config.TaskReport;
12
+ import org.embulk.input.marketo.MarketoUtils;
13
+ import org.embulk.input.marketo.model.BulkExtractRangeHeader;
14
+ import org.embulk.input.marketo.model.MarketoField;
15
+ import org.embulk.input.marketo.rest.MarketoRestClient;
16
+ import org.embulk.spi.Column;
17
+ import org.embulk.spi.PageBuilder;
18
+ import org.embulk.spi.Schema;
19
+ import org.junit.Assert;
20
+ import org.junit.Before;
21
+ import org.junit.Rule;
22
+ import org.junit.Test;
23
+ import org.mockito.ArgumentCaptor;
24
+ import org.mockito.Mockito;
25
+
26
+ import java.io.IOException;
27
+ import java.text.DateFormat;
28
+ import java.text.SimpleDateFormat;
29
+ import java.time.OffsetDateTime;
30
+ import java.time.ZoneOffset;
31
+ import java.util.Arrays;
32
+ import java.util.Date;
33
+ import java.util.List;
34
+
35
+ import static org.mockito.ArgumentMatchers.any;
36
+ import static org.mockito.ArgumentMatchers.eq;
37
+
38
+ /**
39
+ * Created by khuutantaitai on 10/3/17.
40
+ */
41
+ public class LeadBulkExtractInputPluginTest
42
+ {
43
+ private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper();
44
+
45
+ @Rule
46
+ public EmbulkTestRuntime embulkTestRuntime = new EmbulkTestRuntime();
47
+
48
+ private LeadBulkExtractInputPlugin bulkExtractInputPlugin;
49
+
50
+ private ConfigSource configSource;
51
+
52
+ private MarketoRestClient mockMarketoRestclient;
53
+
54
+ @Before
55
+ public void prepare() throws IOException
56
+ {
57
+ bulkExtractInputPlugin = Mockito.spy(new LeadBulkExtractInputPlugin());
58
+ ConfigLoader configLoader = embulkTestRuntime.getInjector().getInstance(ConfigLoader.class);
59
+ configSource = configLoader.fromYaml(this.getClass().getResourceAsStream("/config/lead_bulk_extract_config.yaml"));
60
+ mockMarketoRestclient = Mockito.mock(MarketoRestClient.class);
61
+ Mockito.doReturn(mockMarketoRestclient).when(bulkExtractInputPlugin).createMarketoRestClient(any(LeadBulkExtractInputPlugin.PluginTask.class));
62
+ }
63
+
64
+ @Test
65
+ public void testRun() throws InterruptedException, IOException
66
+ {
67
+ LeadBulkExtractInputPlugin.PluginTask task = configSource.loadConfig(LeadBulkExtractInputPlugin.PluginTask.class);
68
+ OffsetDateTime startDate = OffsetDateTime.ofInstant(task.getFromDate().toInstant(), ZoneOffset.UTC);
69
+ PageBuilder pageBuilder = Mockito.mock(PageBuilder.class);
70
+ String exportId1 = "exportId1";
71
+ String exportId2 = "exportId2";
72
+ JavaType javaType = OBJECT_MAPPER.getTypeFactory().constructParametrizedType(List.class, List.class, MarketoField.class);
73
+ List<MarketoField> marketoFields = OBJECT_MAPPER.readValue(this.getClass().getResourceAsStream("/fixtures/lead_describe_marketo_fields_full.json"), javaType);
74
+ List<String> fieldNameFromMarketoFields = MarketoUtils.getFieldNameFromMarketoFields(marketoFields);
75
+ Mockito.when(mockMarketoRestclient.describeLead()).thenReturn(marketoFields);
76
+ Mockito.when(mockMarketoRestclient.createLeadBulkExtract(any(Date.class), any(Date.class), any(List.class), any(String.class))).thenReturn(exportId1).thenReturn(exportId2).thenReturn(null);
77
+ Mockito.when(mockMarketoRestclient.getLeadBulkExtractResult(eq(exportId1), any(BulkExtractRangeHeader.class))).thenReturn(this.getClass().getResourceAsStream("/fixtures/lead_extract1.csv"));
78
+ Mockito.when(mockMarketoRestclient.getLeadBulkExtractResult(eq(exportId2), any(BulkExtractRangeHeader.class))).thenReturn(this.getClass().getResourceAsStream("/fixtures/leads_extract2.csv"));
79
+ ServiceResponseMapper<? extends ValueLocator> mapper = bulkExtractInputPlugin.buildServiceResponseMapper(task);
80
+ bulkExtractInputPlugin.validateInputTask(task);
81
+ TaskReport taskReport = bulkExtractInputPlugin.ingestServiceData(task, mapper.createRecordImporter(), 1, pageBuilder);
82
+ ArgumentCaptor<Long> argumentCaptor = ArgumentCaptor.forClass(Long.class);
83
+ Column idColumn = mapper.getEmbulkSchema().lookupColumn("mk_id");
84
+ Mockito.verify(pageBuilder, Mockito.times(19)).setLong(eq(idColumn), argumentCaptor.capture());
85
+ Mockito.verify(mockMarketoRestclient, Mockito.times(1)).startLeadBulkExtract(eq(exportId1));
86
+ Mockito.verify(mockMarketoRestclient, Mockito.times(1)).waitLeadExportJobComplete(eq(exportId1), eq(task.getPollingIntervalSecond()), eq(task.getBulkJobTimeoutSecond()));
87
+ Mockito.verify(mockMarketoRestclient, Mockito.times(1)).startLeadBulkExtract(eq(exportId2));
88
+ Mockito.verify(mockMarketoRestclient, Mockito.times(1)).waitLeadExportJobComplete(eq(exportId2), eq(task.getPollingIntervalSecond()), eq(task.getBulkJobTimeoutSecond()));
89
+ String filterField = "createdAt";
90
+ Mockito.verify(mockMarketoRestclient, Mockito.times(1)).createLeadBulkExtract(Date.from(startDate.toInstant()),
91
+ Date.from(startDate.plusDays(30).toInstant()), fieldNameFromMarketoFields, filterField);
92
+ OffsetDateTime startDate2 = startDate.plusDays(30).plusSeconds(1);
93
+ Mockito.verify(mockMarketoRestclient, Mockito.times(1)).createLeadBulkExtract(Date.from(startDate2.toInstant()),
94
+ Date.from(startDate.plusDays(task.getFetchDays()).toInstant()), fieldNameFromMarketoFields, filterField);
95
+ List<Long> leadIds = argumentCaptor.getAllValues();
96
+ Assert.assertEquals(19, leadIds.size());
97
+ ConfigDiff configDiff = bulkExtractInputPlugin.buildConfigDiff(task, Mockito.mock(Schema.class), 1, Arrays.asList(taskReport));
98
+ DateFormat df = new SimpleDateFormat(MarketoUtils.MARKETO_DATE_SIMPLE_DATE_FORMAT);
99
+ Assert.assertEquals(df.format(Date.from(startDate.plusDays(task.getFetchDays()).toInstant())), configDiff.get(String.class, "from_date"));
100
+ Assert.assertArrayEquals(new Long[]{102488L, 102456L, 102445L, 102439L, 102471L, 102503L, 102424L, 102473L, 102505L, 102492L, 102495L, 102452L, 102435L, 102467L, 102420L, 102496L, 102448L, 102499L, 102431L}, leadIds.toArray());
101
+ }
102
+ }
@@ -0,0 +1,119 @@
1
+ package org.embulk.input.marketo.delegate;
2
+
3
+ import com.fasterxml.jackson.databind.JavaType;
4
+ import org.embulk.EmbulkTestRuntime;
5
+ import org.embulk.base.restclient.ServiceResponseMapper;
6
+ import org.embulk.base.restclient.record.ValueLocator;
7
+ import org.embulk.config.ConfigLoader;
8
+ import org.embulk.config.ConfigSource;
9
+ import org.embulk.input.marketo.MarketoService;
10
+ import org.embulk.input.marketo.MarketoUtils;
11
+ import org.embulk.input.marketo.model.MarketoField;
12
+ import org.embulk.spi.Schema;
13
+ import org.junit.Assert;
14
+ import org.junit.Before;
15
+ import org.junit.Rule;
16
+ import org.junit.Test;
17
+ import org.mockito.Mockito;
18
+
19
+ import java.io.IOException;
20
+ import java.util.ArrayList;
21
+ import java.util.List;
22
+
23
+ /**
24
+ * Created by tai.khuu on 5/24/18.
25
+ */
26
+ public class LeadServiceResponseMapperBuilderTest
27
+ {
28
+ private LeadServiceResponseMapperBuilder<LeadServiceResponseMapperBuilder.PluginTask> leadServiceResponseMapperBuilder;
29
+
30
+ @Rule
31
+ public EmbulkTestRuntime embulkTestRuntime = new EmbulkTestRuntime();
32
+
33
+ private LeadServiceResponseMapperBuilder.PluginTask pluginTask;
34
+
35
+ private ConfigSource configSource;
36
+
37
+ private MarketoService marketoService;
38
+
39
+ @Before
40
+ public void setUp() throws Exception
41
+ {
42
+ ConfigLoader configLoader = embulkTestRuntime.getExec().getInjector().getInstance(ConfigLoader.class);
43
+ configSource = configLoader.fromYamlString("--- \n" +
44
+ "account_id: 389-FLQ-873\n" +
45
+ "client_id: 87bdd058-12ff-49b8-8d29-c0518669e59a\n" +
46
+ "client_secret: 2uauyk43zzwjlUZwboZVxQ3SMTHe8ILY\n" +
47
+ "included_fields: \n" +
48
+ " - company\n" +
49
+ " - site\n" +
50
+ " - billingstreet\n" +
51
+ " - billingcity\n" +
52
+ " - billingstate\n" +
53
+ " - billingcountry\n" +
54
+ " - billingpostalCode\n" +
55
+ " - website\n" +
56
+ " - mainphone\n" +
57
+ " - annualrevenue\n" +
58
+ " - numberofemployees\n" +
59
+ " - industry\n" +
60
+ " - siccode\n" +
61
+ " - mktoCompanyNotes\n" +
62
+ " - externalcompanyId\n" +
63
+ " - id\n" +
64
+ "target: all_lead_with_list_id\n");
65
+ pluginTask = configSource.loadConfig(LeadServiceResponseMapperBuilder.PluginTask.class);
66
+ marketoService = Mockito.mock(MarketoService.class);
67
+ JavaType marketoFieldsType = MarketoUtils.OBJECT_MAPPER.getTypeFactory().constructParametrizedType(List.class, List.class, MarketoField.class);
68
+ List<MarketoField> marketoFields = MarketoUtils.OBJECT_MAPPER.readValue(this.getClass().getResourceAsStream("/fixtures/lead_describe_marketo_fields_full.json"), marketoFieldsType);
69
+ Mockito.when(marketoService.describeLead()).thenReturn(marketoFields);
70
+ }
71
+
72
+ @Test
73
+ public void buildServiceResponseMapper() throws Exception
74
+ {
75
+ leadServiceResponseMapperBuilder = new LeadServiceResponseMapperBuilder<>(pluginTask, marketoService);
76
+ ServiceResponseMapper<? extends ValueLocator> serviceResponseMapper = leadServiceResponseMapperBuilder.buildServiceResponseMapper(pluginTask);
77
+ Assert.assertFalse(pluginTask.getExtractedFields().isEmpty());
78
+ Assert.assertEquals(16, pluginTask.getExtractedFields().size());
79
+ Schema embulkSchema = serviceResponseMapper.getEmbulkSchema();
80
+ Assert.assertEquals(16, embulkSchema.getColumns().size());
81
+ Assert.assertEquals("mk_billingStreet", embulkSchema.getColumns().get(2).getName());
82
+ Assert.assertEquals("mk_company", embulkSchema.getColumn(0).getName());
83
+ Assert.assertEquals("mk_billingStreet", embulkSchema.getColumn(2).getName());
84
+ Assert.assertEquals("mk_id", embulkSchema.getColumn(15).getName());
85
+ }
86
+
87
+ @Test
88
+ public void getLeadColumnsIncludedEmpty() throws IOException
89
+ {
90
+ configSource = configSource.set("included_fields", MarketoUtils.OBJECT_MAPPER.readTree("[]"));
91
+ pluginTask = configSource.loadConfig(LeadServiceResponseMapperBuilder.PluginTask.class);
92
+ leadServiceResponseMapperBuilder = new LeadServiceResponseMapperBuilder<>(pluginTask, marketoService);
93
+ List<MarketoField> leadColumns = leadServiceResponseMapperBuilder.getLeadColumns();
94
+ Assert.assertEquals(129, leadColumns.size());
95
+ }
96
+
97
+ @Test
98
+ public void getLeadColumnsIncluded1() throws IOException
99
+ {
100
+ configSource = configSource.set("included_fields", MarketoUtils.OBJECT_MAPPER.readTree("[\"company\",\"incorrect_value\"]"));
101
+ pluginTask = configSource.loadConfig(LeadServiceResponseMapperBuilder.PluginTask.class);
102
+ leadServiceResponseMapperBuilder = new LeadServiceResponseMapperBuilder<>(pluginTask, marketoService);
103
+ List<MarketoField> leadColumns = leadServiceResponseMapperBuilder.getLeadColumns();
104
+ Assert.assertEquals(1, leadColumns.size());
105
+ Assert.assertEquals("company", leadColumns.get(0).getName());
106
+ }
107
+
108
+ @Test
109
+ public void getLeadColumnsIncluded2() throws IOException
110
+ {
111
+ configSource = configSource.set("included_fields", MarketoUtils.OBJECT_MAPPER.readTree("[\"company\",\"incorrect_value\"]"));
112
+ pluginTask = configSource.loadConfig(LeadServiceResponseMapperBuilder.PluginTask.class);
113
+ marketoService = Mockito.mock(MarketoService.class);
114
+ leadServiceResponseMapperBuilder = new LeadServiceResponseMapperBuilder<>(pluginTask, marketoService);
115
+ Mockito.when(marketoService.describeLead()).thenReturn(new ArrayList<MarketoField>());
116
+ List<MarketoField> leadColumns = leadServiceResponseMapperBuilder.getLeadColumns();
117
+ Assert.assertTrue(leadColumns.isEmpty());
118
+ }
119
+ }