embulk-input-marketo_extended 0.6.18
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.
- checksums.yaml +7 -0
- data/.github/PULL_REQUEST_TEMPLATE.md +37 -0
- data/.gitignore +14 -0
- data/.travis.yml +6 -0
- data/CHANGELOG.md +170 -0
- data/LICENSE.txt +21 -0
- data/README.md +213 -0
- data/build.gradle +103 -0
- data/config/checkstyle/checkstyle.xml +128 -0
- data/config/checkstyle/default.xml +108 -0
- data/gradle/wrapper/gradle-wrapper.jar +0 -0
- data/gradle/wrapper/gradle-wrapper.properties +6 -0
- data/gradlew +169 -0
- data/gradlew.bat +84 -0
- data/lib/embulk/input/marketo.rb +3 -0
- data/settings.gradle +1 -0
- data/src/main/java/org/embulk/input/marketo/CsvTokenizer.java +700 -0
- data/src/main/java/org/embulk/input/marketo/MarketoInputPlugin.java +15 -0
- data/src/main/java/org/embulk/input/marketo/MarketoInputPluginDelegate.java +100 -0
- data/src/main/java/org/embulk/input/marketo/MarketoService.java +38 -0
- data/src/main/java/org/embulk/input/marketo/MarketoServiceImpl.java +245 -0
- data/src/main/java/org/embulk/input/marketo/MarketoUtils.java +212 -0
- data/src/main/java/org/embulk/input/marketo/delegate/ActivityBulkExtractInputPlugin.java +167 -0
- data/src/main/java/org/embulk/input/marketo/delegate/CampaignInputPlugin.java +48 -0
- data/src/main/java/org/embulk/input/marketo/delegate/CustomObjectInputPlugin.java +75 -0
- data/src/main/java/org/embulk/input/marketo/delegate/CustomObjectResponseMapperBuilder.java +81 -0
- data/src/main/java/org/embulk/input/marketo/delegate/LeadBulkExtractInputPlugin.java +66 -0
- data/src/main/java/org/embulk/input/marketo/delegate/LeadServiceResponseMapperBuilder.java +85 -0
- data/src/main/java/org/embulk/input/marketo/delegate/LeadWithListInputPlugin.java +64 -0
- data/src/main/java/org/embulk/input/marketo/delegate/LeadWithProgramInputPlugin.java +60 -0
- data/src/main/java/org/embulk/input/marketo/delegate/MarketoBaseBulkExtractInputPlugin.java +441 -0
- data/src/main/java/org/embulk/input/marketo/delegate/MarketoBaseInputPluginDelegate.java +92 -0
- data/src/main/java/org/embulk/input/marketo/delegate/ProgramInputPlugin.java +228 -0
- data/src/main/java/org/embulk/input/marketo/exception/MarketoAPIException.java +30 -0
- data/src/main/java/org/embulk/input/marketo/model/BulkExtractRangeHeader.java +26 -0
- data/src/main/java/org/embulk/input/marketo/model/MarketoAccessTokenResponse.java +92 -0
- data/src/main/java/org/embulk/input/marketo/model/MarketoBulkExtractRequest.java +68 -0
- data/src/main/java/org/embulk/input/marketo/model/MarketoError.java +40 -0
- data/src/main/java/org/embulk/input/marketo/model/MarketoField.java +126 -0
- data/src/main/java/org/embulk/input/marketo/model/MarketoResponse.java +82 -0
- data/src/main/java/org/embulk/input/marketo/model/filter/DateRangeFilter.java +40 -0
- data/src/main/java/org/embulk/input/marketo/rest/MarketoBaseRestClient.java +306 -0
- data/src/main/java/org/embulk/input/marketo/rest/MarketoInputStreamResponseEntityReader.java +69 -0
- data/src/main/java/org/embulk/input/marketo/rest/MarketoRESTEndpoint.java +47 -0
- data/src/main/java/org/embulk/input/marketo/rest/MarketoResponseJetty92EntityReader.java +89 -0
- data/src/main/java/org/embulk/input/marketo/rest/MarketoRestClient.java +569 -0
- data/src/main/java/org/embulk/input/marketo/rest/RecordPagingIterable.java +180 -0
- data/src/test/java/org/embulk/input/marketo/MarketoServiceImplTest.java +140 -0
- data/src/test/java/org/embulk/input/marketo/MarketoUtilsTest.java +87 -0
- data/src/test/java/org/embulk/input/marketo/delegate/ActivityBulkExtractInputPluginTest.java +128 -0
- data/src/test/java/org/embulk/input/marketo/delegate/CampaignInputPluginTest.java +73 -0
- data/src/test/java/org/embulk/input/marketo/delegate/CustomObjectInputPluginTest.java +102 -0
- data/src/test/java/org/embulk/input/marketo/delegate/LeadBulkExtractInputPluginTest.java +99 -0
- data/src/test/java/org/embulk/input/marketo/delegate/LeadServiceResponseMapperBuilderTest.java +119 -0
- data/src/test/java/org/embulk/input/marketo/delegate/LeadWithListInputPluginTest.java +101 -0
- data/src/test/java/org/embulk/input/marketo/delegate/LeadWithProgramInputPluginTest.java +103 -0
- data/src/test/java/org/embulk/input/marketo/delegate/MarketoBaseBulkExtractInputPluginTest.java +169 -0
- data/src/test/java/org/embulk/input/marketo/delegate/ProgramInputPluginTest.java +343 -0
- data/src/test/java/org/embulk/input/marketo/rest/MarketoBaseRestClientTest.java +368 -0
- data/src/test/java/org/embulk/input/marketo/rest/MarketoRestClientTest.java +584 -0
- data/src/test/resources/config/activity_bulk_extract_config.yaml +7 -0
- data/src/test/resources/config/custom_object_config.yaml +8 -0
- data/src/test/resources/config/lead_bulk_extract_config.yaml +8 -0
- data/src/test/resources/config/rest_config.yaml +3 -0
- data/src/test/resources/fixtures/activity_extract1.csv +35 -0
- data/src/test/resources/fixtures/activity_extract2.csv +22 -0
- data/src/test/resources/fixtures/activity_types.json +22 -0
- data/src/test/resources/fixtures/all_program_full.json +53 -0
- data/src/test/resources/fixtures/campaign_response.json +38 -0
- data/src/test/resources/fixtures/campaign_response_full.json +102 -0
- data/src/test/resources/fixtures/custom_object_describe.json +124 -0
- data/src/test/resources/fixtures/custom_object_describe_marketo_fields_full.json +22 -0
- data/src/test/resources/fixtures/custom_object_expected.json +66 -0
- data/src/test/resources/fixtures/custom_object_response.json +24 -0
- data/src/test/resources/fixtures/custom_object_response_full.json +23 -0
- data/src/test/resources/fixtures/lead_by_list.json +33 -0
- data/src/test/resources/fixtures/lead_by_program_response.json +47 -0
- data/src/test/resources/fixtures/lead_describe.json +221 -0
- data/src/test/resources/fixtures/lead_describe_expected.json +66 -0
- data/src/test/resources/fixtures/lead_describe_marketo_fields_full.json +518 -0
- data/src/test/resources/fixtures/lead_extract1.csv +11 -0
- data/src/test/resources/fixtures/lead_response_full.json +2402 -0
- data/src/test/resources/fixtures/lead_with_program_full.json +17 -0
- data/src/test/resources/fixtures/leads_extract2.csv +10 -0
- data/src/test/resources/fixtures/list_reponse_full.json +191 -0
- data/src/test/resources/fixtures/lists_response.json +31 -0
- data/src/test/resources/fixtures/program_response.json +71 -0
- metadata +171 -0
@@ -0,0 +1,103 @@
|
|
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.apache.commons.lang3.StringUtils;
|
7
|
+
import org.embulk.EmbulkTestRuntime;
|
8
|
+
import org.embulk.base.restclient.ServiceResponseMapper;
|
9
|
+
import org.embulk.base.restclient.record.RecordImporter;
|
10
|
+
import org.embulk.base.restclient.record.ValueLocator;
|
11
|
+
import org.embulk.config.ConfigLoader;
|
12
|
+
import org.embulk.config.ConfigSource;
|
13
|
+
import org.embulk.input.marketo.MarketoUtils;
|
14
|
+
import org.embulk.input.marketo.model.MarketoField;
|
15
|
+
import org.embulk.input.marketo.rest.MarketoRestClient;
|
16
|
+
import org.embulk.input.marketo.rest.RecordPagingIterable;
|
17
|
+
import org.embulk.spi.PageBuilder;
|
18
|
+
import org.embulk.spi.Schema;
|
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.ArrayList;
|
27
|
+
import java.util.List;
|
28
|
+
|
29
|
+
import static org.junit.Assert.assertEquals;
|
30
|
+
import static org.mockito.ArgumentMatchers.any;
|
31
|
+
import static org.mockito.ArgumentMatchers.anyString;
|
32
|
+
import static org.mockito.ArgumentMatchers.eq;
|
33
|
+
|
34
|
+
/**
|
35
|
+
* Created by tai.khuu on 10/10/17.
|
36
|
+
*/
|
37
|
+
public class LeadWithProgramInputPluginTest
|
38
|
+
{
|
39
|
+
private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper();
|
40
|
+
|
41
|
+
@Rule
|
42
|
+
public EmbulkTestRuntime embulkTestRuntime = new EmbulkTestRuntime();
|
43
|
+
|
44
|
+
private ConfigSource configSource;
|
45
|
+
|
46
|
+
private LeadWithProgramInputPlugin leadWithProgramInputPlugin;
|
47
|
+
|
48
|
+
private MarketoRestClient mockMarketoRestClient;
|
49
|
+
|
50
|
+
@Before
|
51
|
+
public void setUp() throws Exception
|
52
|
+
{
|
53
|
+
leadWithProgramInputPlugin = Mockito.spy(new LeadWithProgramInputPlugin());
|
54
|
+
ConfigLoader configLoader = embulkTestRuntime.getInjector().getInstance(ConfigLoader.class);
|
55
|
+
configSource = configLoader.fromYaml(this.getClass().getResourceAsStream("/config/rest_config.yaml"));
|
56
|
+
mockMarketoRestClient = Mockito.mock(MarketoRestClient.class);
|
57
|
+
Mockito.doReturn(mockMarketoRestClient).when(leadWithProgramInputPlugin).createMarketoRestClient(any(LeadWithProgramInputPlugin.PluginTask.class));
|
58
|
+
}
|
59
|
+
|
60
|
+
@Test
|
61
|
+
public void testRun() throws IOException
|
62
|
+
{
|
63
|
+
RecordPagingIterable<ObjectNode> mockLeadRecordPagingIterable = Mockito.mock(RecordPagingIterable.class);
|
64
|
+
RecordPagingIterable<ObjectNode> mockLeadEmptyRecordPagingIterable = Mockito.mock(RecordPagingIterable.class);
|
65
|
+
RecordPagingIterable<ObjectNode> mockProgramRecords = Mockito.mock(RecordPagingIterable.class);
|
66
|
+
|
67
|
+
Mockito.when(mockLeadEmptyRecordPagingIterable.iterator()).thenReturn(new ArrayList<ObjectNode>().iterator());
|
68
|
+
JavaType objectNodeListType = OBJECT_MAPPER.getTypeFactory().constructParametrizedType(List.class, List.class, ObjectNode.class);
|
69
|
+
JavaType marketoFieldsType = OBJECT_MAPPER.getTypeFactory().constructParametrizedType(List.class, List.class, MarketoField.class);
|
70
|
+
List<ObjectNode> leads = OBJECT_MAPPER.readValue(this.getClass().getResourceAsStream("/fixtures/lead_with_program_full.json"), objectNodeListType);
|
71
|
+
List<ObjectNode> programs = OBJECT_MAPPER.readValue(this.getClass().getResourceAsStream("/fixtures/all_program_full.json"), objectNodeListType);
|
72
|
+
Mockito.when(mockProgramRecords.iterator()).thenReturn(programs.iterator());
|
73
|
+
List<MarketoField> marketoFields = OBJECT_MAPPER.readValue(this.getClass().getResourceAsStream("/fixtures/lead_describe_marketo_fields_full.json"), marketoFieldsType);
|
74
|
+
Mockito.when(mockLeadRecordPagingIterable.iterator()).thenReturn(leads.iterator());
|
75
|
+
Mockito.when(mockMarketoRestClient.describeLead()).thenReturn(marketoFields);
|
76
|
+
Mockito.when(mockMarketoRestClient.getPrograms()).thenReturn(mockProgramRecords);
|
77
|
+
List<String> fieldNameFromMarketoFields = MarketoUtils.getFieldNameFromMarketoFields(marketoFields);
|
78
|
+
String fieldNameString = StringUtils.join(fieldNameFromMarketoFields, ",");
|
79
|
+
Mockito.when(mockMarketoRestClient.getLeadsByProgram(anyString(), eq(fieldNameString))).thenReturn(mockLeadEmptyRecordPagingIterable);
|
80
|
+
Mockito.when(mockMarketoRestClient.getLeadsByProgram("1003", fieldNameString)).thenReturn(mockLeadRecordPagingIterable);
|
81
|
+
|
82
|
+
LeadWithProgramInputPlugin.PluginTask task = configSource.loadConfig(LeadWithProgramInputPlugin.PluginTask.class);
|
83
|
+
ServiceResponseMapper<? extends ValueLocator> mapper = leadWithProgramInputPlugin.buildServiceResponseMapper(task);
|
84
|
+
|
85
|
+
RecordImporter recordImporter = mapper.createRecordImporter();
|
86
|
+
PageBuilder mockPageBuilder = Mockito.mock(PageBuilder.class);
|
87
|
+
|
88
|
+
leadWithProgramInputPlugin.ingestServiceData(task, recordImporter, 1, mockPageBuilder);
|
89
|
+
Mockito.verify(mockMarketoRestClient, Mockito.times(1)).getPrograms();
|
90
|
+
Mockito.verify(mockMarketoRestClient, Mockito.times(3)).getLeadsByProgram(anyString(), eq(fieldNameString));
|
91
|
+
Mockito.verify(mockMarketoRestClient, Mockito.times(1)).describeLead();
|
92
|
+
|
93
|
+
Schema embulkSchema = mapper.getEmbulkSchema();
|
94
|
+
ArgumentCaptor<Long> longArgumentCaptor = ArgumentCaptor.forClass(Long.class);
|
95
|
+
|
96
|
+
Mockito.verify(mockPageBuilder, Mockito.times(1)).setLong(eq(embulkSchema.lookupColumn("mk_id")), longArgumentCaptor.capture());
|
97
|
+
Mockito.verify(mockPageBuilder, Mockito.times(1)).setString(eq(embulkSchema.lookupColumn("mk_programId")), eq("1003"));
|
98
|
+
|
99
|
+
List<Long> allValues = longArgumentCaptor.getAllValues();
|
100
|
+
long actualValue = allValues.get(0);
|
101
|
+
assertEquals(102519L, actualValue);
|
102
|
+
}
|
103
|
+
}
|
data/src/test/java/org/embulk/input/marketo/delegate/MarketoBaseBulkExtractInputPluginTest.java
ADDED
@@ -0,0 +1,169 @@
|
|
1
|
+
package org.embulk.input.marketo.delegate;
|
2
|
+
|
3
|
+
import com.google.common.base.Optional;
|
4
|
+
|
5
|
+
import org.embulk.EmbulkTestRuntime;
|
6
|
+
import org.embulk.config.ConfigDiff;
|
7
|
+
import org.embulk.config.ConfigException;
|
8
|
+
import org.embulk.config.ConfigLoader;
|
9
|
+
import org.embulk.config.ConfigSource;
|
10
|
+
import org.embulk.config.TaskReport;
|
11
|
+
import org.embulk.input.marketo.MarketoInputPluginDelegate;
|
12
|
+
import org.embulk.input.marketo.MarketoUtils;
|
13
|
+
import org.embulk.spi.Schema;
|
14
|
+
import org.joda.time.DateTime;
|
15
|
+
import org.junit.Before;
|
16
|
+
import org.junit.Rule;
|
17
|
+
import org.junit.Test;
|
18
|
+
import org.mockito.ArgumentCaptor;
|
19
|
+
import org.mockito.Mockito;
|
20
|
+
|
21
|
+
import java.io.IOException;
|
22
|
+
import java.text.DateFormat;
|
23
|
+
import java.text.SimpleDateFormat;
|
24
|
+
import java.util.Arrays;
|
25
|
+
import java.util.Date;
|
26
|
+
|
27
|
+
import static org.junit.Assert.assertEquals;
|
28
|
+
import static org.junit.Assert.fail;
|
29
|
+
import static org.mockito.AdditionalAnswers.delegatesTo;
|
30
|
+
import static org.mockito.Mockito.mock;
|
31
|
+
import static org.mockito.Mockito.when;
|
32
|
+
|
33
|
+
/**
|
34
|
+
* Created by khuutantaitai on 10/3/17.
|
35
|
+
*/
|
36
|
+
public class MarketoBaseBulkExtractInputPluginTest
|
37
|
+
{
|
38
|
+
@Rule
|
39
|
+
public EmbulkTestRuntime embulkTestRuntime = new EmbulkTestRuntime();
|
40
|
+
|
41
|
+
private MarketoBaseBulkExtractInputPlugin<MarketoBaseBulkExtractInputPlugin.PluginTask> baseBulkExtractInputPlugin;
|
42
|
+
private MarketoBaseBulkExtractInputPlugin.PluginTask validBaseTask;
|
43
|
+
|
44
|
+
@Before
|
45
|
+
public void prepare() throws IOException
|
46
|
+
{
|
47
|
+
baseBulkExtractInputPlugin = Mockito.mock(MarketoBaseBulkExtractInputPlugin.class, Mockito.CALLS_REAL_METHODS);
|
48
|
+
ConfigLoader configLoader = embulkTestRuntime.getInjector().getInstance(ConfigLoader.class);
|
49
|
+
ConfigSource configSource = configLoader.fromYaml(
|
50
|
+
this.getClass().getResourceAsStream("/config/activity_bulk_extract_config.yaml"));
|
51
|
+
validBaseTask = configSource.loadConfig(MarketoBaseBulkExtractInputPlugin.PluginTask.class);
|
52
|
+
}
|
53
|
+
|
54
|
+
@Test(expected = ConfigException.class)
|
55
|
+
public void validateInputTaskError()
|
56
|
+
{
|
57
|
+
MarketoBaseBulkExtractInputPlugin.PluginTask pluginTask = Mockito.mock(MarketoBaseBulkExtractInputPlugin.PluginTask.class);
|
58
|
+
Mockito.when(pluginTask.getFromDate()).thenReturn(null);
|
59
|
+
baseBulkExtractInputPlugin.validateInputTask(pluginTask);
|
60
|
+
}
|
61
|
+
|
62
|
+
@Test(expected = ConfigException.class)
|
63
|
+
public void invalidInputTaskWhenIncrementalByUpdatedAt()
|
64
|
+
{
|
65
|
+
MarketoBaseBulkExtractInputPlugin.PluginTask task = mock(
|
66
|
+
MarketoBaseBulkExtractInputPlugin.PluginTask.class,
|
67
|
+
delegatesTo(validBaseTask));
|
68
|
+
when(task.getIncrementalColumn()).thenReturn(Optional.of("updatedAt"));
|
69
|
+
when(task.getIncremental()).thenReturn(true);
|
70
|
+
baseBulkExtractInputPlugin.validateInputTask(task);
|
71
|
+
}
|
72
|
+
|
73
|
+
@Test
|
74
|
+
public void validInputTaskWhenIncrementalOtherThanUpdatedAt()
|
75
|
+
{
|
76
|
+
MarketoBaseBulkExtractInputPlugin.PluginTask task = mock(
|
77
|
+
MarketoBaseBulkExtractInputPlugin.PluginTask.class,
|
78
|
+
delegatesTo(validBaseTask));
|
79
|
+
when(task.getIncremental()).thenReturn(true);
|
80
|
+
when(task.getIncrementalColumn()).thenReturn(Optional.of("anythingButUpdatedAt"));
|
81
|
+
baseBulkExtractInputPlugin.validateInputTask(task); // should not throw
|
82
|
+
}
|
83
|
+
|
84
|
+
@Test
|
85
|
+
public void validInputTaskWhenNonIncrementalWhileSetUpdatedAt()
|
86
|
+
{
|
87
|
+
MarketoBaseBulkExtractInputPlugin.PluginTask task = mock(
|
88
|
+
MarketoBaseBulkExtractInputPlugin.PluginTask.class,
|
89
|
+
delegatesTo(validBaseTask));
|
90
|
+
when(task.getIncremental()).thenReturn(false);
|
91
|
+
when(task.getIncrementalColumn()).thenReturn(Optional.of("updatedAt"));
|
92
|
+
baseBulkExtractInputPlugin.validateInputTask(task); // should not throw
|
93
|
+
}
|
94
|
+
|
95
|
+
@Test()
|
96
|
+
public void validateInputTaskToDateLessThanJobStartTime()
|
97
|
+
{
|
98
|
+
Date fromDate = new Date(1504224000000L);
|
99
|
+
DateTime jobStartTime = new DateTime(1506842144000L);
|
100
|
+
MarketoBaseBulkExtractInputPlugin.PluginTask pluginTask = Mockito.mock(MarketoBaseBulkExtractInputPlugin.PluginTask.class);
|
101
|
+
Mockito.when(pluginTask.getFromDate()).thenReturn(fromDate);
|
102
|
+
Mockito.when(pluginTask.getJobStartTime()).thenReturn(jobStartTime);
|
103
|
+
Mockito.when(pluginTask.getFetchDays()).thenReturn(7);
|
104
|
+
baseBulkExtractInputPlugin.validateInputTask(pluginTask);
|
105
|
+
ArgumentCaptor<Optional<Date>> argumentCaptor = ArgumentCaptor.forClass(Optional.class);
|
106
|
+
Mockito.verify(pluginTask, Mockito.times(1)).setToDate(argumentCaptor.capture());
|
107
|
+
assertEquals(1504828800000L, argumentCaptor.getValue().get().getTime());
|
108
|
+
}
|
109
|
+
|
110
|
+
@Test()
|
111
|
+
public void validateInputTaskFromDateMoreThanJobStartTime()
|
112
|
+
{
|
113
|
+
Date fromDate = new Date(1507619744000L);
|
114
|
+
DateTime jobStartTime = new DateTime(1506842144000L);
|
115
|
+
MarketoBaseBulkExtractInputPlugin.PluginTask pluginTask = Mockito.mock(MarketoBaseBulkExtractInputPlugin.PluginTask.class);
|
116
|
+
Mockito.when(pluginTask.getFromDate()).thenReturn(fromDate);
|
117
|
+
Mockito.when(pluginTask.getJobStartTime()).thenReturn(jobStartTime);
|
118
|
+
|
119
|
+
try {
|
120
|
+
baseBulkExtractInputPlugin.validateInputTask(pluginTask);
|
121
|
+
}
|
122
|
+
catch (ConfigException ex) {
|
123
|
+
return;
|
124
|
+
}
|
125
|
+
fail();
|
126
|
+
}
|
127
|
+
|
128
|
+
@Test()
|
129
|
+
public void validateInputTaskToDateMoreThanJobStartTime()
|
130
|
+
{
|
131
|
+
Date fromDate = new Date(1504224000000L);
|
132
|
+
DateTime jobStartTime = new DateTime(1504396800000L);
|
133
|
+
MarketoBaseBulkExtractInputPlugin.PluginTask pluginTask = Mockito.mock(MarketoBaseBulkExtractInputPlugin.PluginTask.class);
|
134
|
+
Mockito.when(pluginTask.getFromDate()).thenReturn(fromDate);
|
135
|
+
Mockito.when(pluginTask.getFetchDays()).thenReturn(7);
|
136
|
+
Mockito.when(pluginTask.getJobStartTime()).thenReturn(jobStartTime);
|
137
|
+
baseBulkExtractInputPlugin.validateInputTask(pluginTask);
|
138
|
+
ArgumentCaptor<Optional<Date>> toDateArgumentCaptor = ArgumentCaptor.forClass(Optional.class);
|
139
|
+
Mockito.verify(pluginTask, Mockito.times(1)).setToDate(toDateArgumentCaptor.capture());
|
140
|
+
assertEquals(jobStartTime.getMillis(), toDateArgumentCaptor.getValue().get().getTime());
|
141
|
+
}
|
142
|
+
|
143
|
+
@Test
|
144
|
+
public void getToDate() throws Exception
|
145
|
+
{
|
146
|
+
DateTime date = new DateTime(1505033728000L);
|
147
|
+
DateTime jobStartTime = new DateTime(1507625728000L);
|
148
|
+
MarketoBaseBulkExtractInputPlugin.PluginTask pluginTask = Mockito.mock(MarketoInputPluginDelegate.PluginTask.class);
|
149
|
+
Mockito.when(pluginTask.getFromDate()).thenReturn(date.toDate());
|
150
|
+
Mockito.when(pluginTask.getFetchDays()).thenReturn(30);
|
151
|
+
Mockito.when(pluginTask.getJobStartTime()).thenReturn(jobStartTime);
|
152
|
+
DateTime toDate = baseBulkExtractInputPlugin.getToDate(pluginTask);
|
153
|
+
assertEquals(toDate, jobStartTime);
|
154
|
+
}
|
155
|
+
|
156
|
+
@Test
|
157
|
+
public void buildConfigDiff() throws Exception
|
158
|
+
{
|
159
|
+
TaskReport taskReport1 = Mockito.mock(TaskReport.class);
|
160
|
+
MarketoInputPluginDelegate.PluginTask task = Mockito.mock(MarketoInputPluginDelegate.PluginTask.class);
|
161
|
+
Mockito.when(task.getIncremental()).thenReturn(true);
|
162
|
+
Mockito.when(task.getIncrementalColumn()).thenReturn(Optional.of("createdAt"));
|
163
|
+
Date toDate = new Date(1507625728000L);
|
164
|
+
Mockito.when(task.getToDate()).thenReturn(Optional.of(toDate));
|
165
|
+
ConfigDiff configDiff = baseBulkExtractInputPlugin.buildConfigDiff(task, Mockito.mock(Schema.class), 1, Arrays.asList(taskReport1));
|
166
|
+
DateFormat df = new SimpleDateFormat(MarketoUtils.MARKETO_DATE_SIMPLE_DATE_FORMAT);
|
167
|
+
assertEquals(df.format(toDate), configDiff.get(String.class, "from_date"));
|
168
|
+
}
|
169
|
+
}
|
@@ -0,0 +1,343 @@
|
|
1
|
+
package org.embulk.input.marketo.delegate;
|
2
|
+
|
3
|
+
import com.fasterxml.jackson.core.JsonParseException;
|
4
|
+
import com.fasterxml.jackson.databind.JavaType;
|
5
|
+
import com.fasterxml.jackson.databind.JsonMappingException;
|
6
|
+
import com.fasterxml.jackson.databind.ObjectMapper;
|
7
|
+
import com.fasterxml.jackson.databind.node.ObjectNode;
|
8
|
+
import com.google.common.base.Optional;
|
9
|
+
import com.google.common.base.Predicate;
|
10
|
+
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
|
11
|
+
import org.embulk.EmbulkTestRuntime;
|
12
|
+
import org.embulk.base.restclient.ServiceResponseMapper;
|
13
|
+
import org.embulk.base.restclient.record.RecordImporter;
|
14
|
+
import org.embulk.base.restclient.record.ValueLocator;
|
15
|
+
import org.embulk.config.ConfigDiff;
|
16
|
+
import org.embulk.config.ConfigException;
|
17
|
+
import org.embulk.config.ConfigLoader;
|
18
|
+
import org.embulk.config.ConfigSource;
|
19
|
+
import org.embulk.config.TaskReport;
|
20
|
+
import org.embulk.input.marketo.MarketoUtils;
|
21
|
+
import org.embulk.input.marketo.delegate.ProgramInputPlugin.PluginTask;
|
22
|
+
import org.embulk.input.marketo.delegate.ProgramInputPlugin.QueryBy;
|
23
|
+
import org.embulk.input.marketo.rest.MarketoRestClient;
|
24
|
+
import org.embulk.input.marketo.rest.RecordPagingIterable;
|
25
|
+
import org.embulk.spi.PageBuilder;
|
26
|
+
import org.embulk.spi.Schema;
|
27
|
+
import org.joda.time.DateTime;
|
28
|
+
import org.joda.time.Duration;
|
29
|
+
import org.joda.time.format.DateTimeFormat;
|
30
|
+
import org.joda.time.format.DateTimeFormatter;
|
31
|
+
import org.junit.Before;
|
32
|
+
import org.junit.Rule;
|
33
|
+
import org.junit.Test;
|
34
|
+
import org.junit.rules.ExpectedException;
|
35
|
+
import org.junit.rules.RuleChain;
|
36
|
+
import org.junit.rules.TestRule;
|
37
|
+
import org.mockito.ArgumentCaptor;
|
38
|
+
import org.mockito.Mockito;
|
39
|
+
|
40
|
+
import java.io.IOException;
|
41
|
+
import java.util.Arrays;
|
42
|
+
import java.util.Date;
|
43
|
+
import java.util.List;
|
44
|
+
|
45
|
+
import static org.junit.Assert.assertArrayEquals;
|
46
|
+
import static org.junit.Assert.assertEquals;
|
47
|
+
|
48
|
+
public class ProgramInputPluginTest
|
49
|
+
{
|
50
|
+
private static final DateTimeFormatter DATE_FORMATTER = DateTimeFormat.forPattern(MarketoUtils.MARKETO_DATE_SIMPLE_DATE_FORMAT);
|
51
|
+
|
52
|
+
private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper();
|
53
|
+
|
54
|
+
@Rule
|
55
|
+
public EmbulkTestRuntime runtime = new EmbulkTestRuntime();
|
56
|
+
|
57
|
+
private ExpectedException thrown = ExpectedException.none();
|
58
|
+
|
59
|
+
@Rule
|
60
|
+
@SuppressFBWarnings("URF_UNREAD_PUBLIC_OR_PROTECTED_FIELD")
|
61
|
+
public TestRule chain = RuleChain.outerRule(runtime).around(thrown);
|
62
|
+
|
63
|
+
private ConfigSource baseConfig;
|
64
|
+
|
65
|
+
private ProgramInputPlugin mockPlugin;
|
66
|
+
|
67
|
+
private MarketoRestClient mockRestClient;
|
68
|
+
|
69
|
+
@Before
|
70
|
+
public void setUp() throws Exception
|
71
|
+
{
|
72
|
+
mockPlugin = Mockito.spy(new ProgramInputPlugin());
|
73
|
+
baseConfig = config();
|
74
|
+
mockRestClient = Mockito.mock(MarketoRestClient.class);
|
75
|
+
Mockito.doReturn(mockRestClient).when(mockPlugin).createMarketoRestClient(Mockito.any(ProgramInputPlugin.PluginTask.class));
|
76
|
+
}
|
77
|
+
|
78
|
+
// -----------Verify configs --------------
|
79
|
+
@Test
|
80
|
+
public void testQueryByTagTypeConfigMissingTagType()
|
81
|
+
{
|
82
|
+
thrown.expect(ConfigException.class);
|
83
|
+
thrown.expectMessage("tag_type and tag_value are required when query by Tag Type");
|
84
|
+
ConfigSource config = baseConfig.set("query_by", Optional.of(QueryBy.TAG_TYPE)).set("tag_value", Optional.of("dummy"));
|
85
|
+
mockPlugin.validateInputTask(config.loadConfig(PluginTask.class));
|
86
|
+
}
|
87
|
+
|
88
|
+
@Test
|
89
|
+
public void testQueryByTagTypeConfigMissingTagValue()
|
90
|
+
{
|
91
|
+
thrown.expect(ConfigException.class);
|
92
|
+
thrown.expectMessage("tag_type and tag_value are required when query by Tag Type");
|
93
|
+
ConfigSource config = baseConfig.set("query_by", Optional.of(QueryBy.TAG_TYPE)).set("tag_type", Optional.of("dummy"));
|
94
|
+
mockPlugin.validateInputTask(config.loadConfig(PluginTask.class));
|
95
|
+
}
|
96
|
+
|
97
|
+
@Test
|
98
|
+
public void testQueryByDateRangeConfigMissingEarliestUpatedAt()
|
99
|
+
{
|
100
|
+
thrown.expect(ConfigException.class);
|
101
|
+
thrown.expectMessage("`earliest_updated_at` is required when query by Date Range");
|
102
|
+
ConfigSource config = baseConfig.set("query_by", Optional.of(QueryBy.DATE_RANGE)).set("latest_updated_at", Optional.of(DateTime.now().minusDays(10).toDate()));
|
103
|
+
mockPlugin.validateInputTask(config.loadConfig(PluginTask.class));
|
104
|
+
}
|
105
|
+
|
106
|
+
@Test
|
107
|
+
public void testQueryByDateRangeConfigMissingLatestUpdatedAt()
|
108
|
+
{
|
109
|
+
thrown.expect(ConfigException.class);
|
110
|
+
thrown.expectMessage("`latest_updated_at` is required when query by Date Range");
|
111
|
+
ConfigSource config = baseConfig.set("query_by", Optional.of(QueryBy.DATE_RANGE)).set("earliest_updated_at", Optional.of(DateTime.now().minusDays(10).toDate()));
|
112
|
+
mockPlugin.validateInputTask(config.loadConfig(PluginTask.class));
|
113
|
+
}
|
114
|
+
|
115
|
+
@Test
|
116
|
+
public void testQueryByDateRangeConfigMissingLatestUpdatedAtNonIncremental()
|
117
|
+
{
|
118
|
+
thrown.expect(ConfigException.class);
|
119
|
+
thrown.expectMessage("`latest_updated_at` is required when query by Date Range");
|
120
|
+
ConfigSource config = baseConfig
|
121
|
+
.set("query_by", Optional.of(QueryBy.DATE_RANGE))
|
122
|
+
.set("incremental", Boolean.FALSE)
|
123
|
+
.set("earliest_updated_at", Optional.of(DateTime.now().minusDays(10).toDate()));
|
124
|
+
mockPlugin.validateInputTask(config.loadConfig(PluginTask.class));
|
125
|
+
}
|
126
|
+
|
127
|
+
@Test
|
128
|
+
public void testNoErrorQueryByDateRangeConfigHasReportDurationNonIncremental()
|
129
|
+
{
|
130
|
+
ConfigSource config = baseConfig
|
131
|
+
.set("query_by", Optional.of(QueryBy.DATE_RANGE))
|
132
|
+
.set("report_duration", Optional.of(60L * 1000))
|
133
|
+
.set("incremental", Boolean.FALSE)
|
134
|
+
.set("earliest_updated_at", Optional.of(DateTime.now().minusDays(10).toDate()));
|
135
|
+
mockPlugin.validateInputTask(config.loadConfig(PluginTask.class));
|
136
|
+
}
|
137
|
+
|
138
|
+
@Test
|
139
|
+
public void testNoErrorQueryByDateRangeConfigHasReportDuration()
|
140
|
+
{
|
141
|
+
ConfigSource config = baseConfig
|
142
|
+
.set("report_duration", Optional.of(60L * 1000))
|
143
|
+
.set("query_by", Optional.of(QueryBy.DATE_RANGE))
|
144
|
+
.set("earliest_updated_at", Optional.of(DateTime.now().minusDays(10).toDate()));
|
145
|
+
mockPlugin.validateInputTask(config.loadConfig(PluginTask.class));
|
146
|
+
}
|
147
|
+
|
148
|
+
@Test
|
149
|
+
public void testQueryByDateRangeConfigHasEarliestUpdatedAtExceededNow()
|
150
|
+
{
|
151
|
+
DateTime earliestUpdatedAt = DateTime.now().plusDays(1);
|
152
|
+
DateTime latestUpdatedAt = DateTime.now().minusDays(2);
|
153
|
+
thrown.expect(ConfigException.class);
|
154
|
+
thrown.expectMessage(String.format("`earliest_updated_at` (%s) cannot precede the current date ", earliestUpdatedAt.toString(DATE_FORMATTER)));
|
155
|
+
ConfigSource config = baseConfig
|
156
|
+
.set("query_by", Optional.of(QueryBy.DATE_RANGE))
|
157
|
+
.set("earliest_updated_at", Optional.of(earliestUpdatedAt))
|
158
|
+
.set("latest_updated_at", Optional.of(latestUpdatedAt));
|
159
|
+
mockPlugin.validateInputTask(config.loadConfig(PluginTask.class));
|
160
|
+
}
|
161
|
+
|
162
|
+
@Test
|
163
|
+
public void testQueryByDateRangeConfigHasEarliestUpdatedAtExceededLatestUpdatedAt()
|
164
|
+
{
|
165
|
+
DateTime earliestUpdatedAt = DateTime.now().minusDays(10);
|
166
|
+
DateTime latestUpdatedAt = DateTime.now().minusDays(20);
|
167
|
+
thrown.expect(ConfigException.class);
|
168
|
+
thrown.expectMessage(String.format("Invalid date range. `earliest_updated_at` (%s) cannot precede the `latest_updated_at` (%s).",
|
169
|
+
earliestUpdatedAt.toString(DATE_FORMATTER),
|
170
|
+
latestUpdatedAt.toString(DATE_FORMATTER)));
|
171
|
+
|
172
|
+
ConfigSource config = baseConfig
|
173
|
+
.set("query_by", Optional.of(QueryBy.DATE_RANGE))
|
174
|
+
.set("earliest_updated_at", Optional.of(earliestUpdatedAt))
|
175
|
+
.set("latest_updated_at", Optional.of(latestUpdatedAt));
|
176
|
+
mockPlugin.validateInputTask(config.loadConfig(PluginTask.class));
|
177
|
+
}
|
178
|
+
|
179
|
+
@Test
|
180
|
+
public void testHasFilterTypeButMissingFilterValue()
|
181
|
+
{
|
182
|
+
DateTime earliestUpdatedAt = DateTime.now().minusDays(20);
|
183
|
+
DateTime latestUpdatedAt = DateTime.now().minusDays(10);
|
184
|
+
thrown.expect(ConfigException.class);
|
185
|
+
thrown.expectMessage("filter_value is required when selected filter_type");
|
186
|
+
|
187
|
+
ConfigSource config = baseConfig
|
188
|
+
.set("query_by", Optional.of(QueryBy.DATE_RANGE))
|
189
|
+
.set("earliest_updated_at", Optional.of(earliestUpdatedAt))
|
190
|
+
.set("latest_updated_at", Optional.of(latestUpdatedAt))
|
191
|
+
.set("filter_type", Optional.of("dummy"));
|
192
|
+
mockPlugin.validateInputTask(config.loadConfig(PluginTask.class));
|
193
|
+
}
|
194
|
+
|
195
|
+
@Test
|
196
|
+
public void testSkipIncrementalRunIfLastUpdatedAtExceedsNow()
|
197
|
+
{
|
198
|
+
DateTime earliestUpdatedAt = DateTime.now().minusDays(20);
|
199
|
+
DateTime latestUpdatedAt = earliestUpdatedAt.plusDays(21);
|
200
|
+
//21 days
|
201
|
+
long reportDuration = 21 * 24 * 60 * 60 * 1000;
|
202
|
+
|
203
|
+
ConfigSource config = baseConfig
|
204
|
+
.set("query_by", Optional.of(QueryBy.DATE_RANGE))
|
205
|
+
.set("earliest_updated_at", Optional.of(earliestUpdatedAt))
|
206
|
+
.set("latest_updated_at", Optional.of(latestUpdatedAt))
|
207
|
+
.set("report_duration", reportDuration)
|
208
|
+
.set("incremental", true);
|
209
|
+
ServiceResponseMapper<? extends ValueLocator> mapper = mockPlugin.buildServiceResponseMapper(config.loadConfig(PluginTask.class));
|
210
|
+
RecordImporter recordImporter = mapper.createRecordImporter();
|
211
|
+
PageBuilder mockPageBuilder = Mockito.mock(PageBuilder.class);
|
212
|
+
TaskReport taskReport = mockPlugin.ingestServiceData(config.loadConfig(PluginTask.class), recordImporter, 1, mockPageBuilder);
|
213
|
+
// page builder object should never get called.
|
214
|
+
Mockito.verify(mockPageBuilder, Mockito.never()).addRecord();
|
215
|
+
|
216
|
+
String earliestUpdatedAtStr = taskReport.get(String.class, "earliest_updated_at");
|
217
|
+
long duration = taskReport.get(Long.class, "report_duration");
|
218
|
+
assertEquals(duration, reportDuration);
|
219
|
+
assertEquals(earliestUpdatedAtStr, earliestUpdatedAt.toString(DATE_FORMATTER));
|
220
|
+
}
|
221
|
+
|
222
|
+
@Test
|
223
|
+
public void testBuildConfigDiff() throws Exception
|
224
|
+
{
|
225
|
+
TaskReport taskReport1 = Mockito.mock(TaskReport.class);
|
226
|
+
DateTime earliestUpdatedAt = DateTime.now().minusDays(20);
|
227
|
+
DateTime latestUpdatedAt = DateTime.now().minusDays(10);
|
228
|
+
ConfigSource config = baseConfig
|
229
|
+
.set("query_by", Optional.of(QueryBy.DATE_RANGE))
|
230
|
+
.set("earliest_updated_at", Optional.of(earliestUpdatedAt))
|
231
|
+
.set("latest_updated_at", Optional.of(latestUpdatedAt))
|
232
|
+
.set("incremental", true);
|
233
|
+
|
234
|
+
ConfigDiff diff = mockPlugin.buildConfigDiff(config.loadConfig(PluginTask.class), Mockito.mock(Schema.class), 1, Arrays.asList(taskReport1));
|
235
|
+
|
236
|
+
long reportDuration = diff.get(Long.class, "report_duration");
|
237
|
+
String nextErliestUpdatedAt = diff.get(String.class, "earliest_updated_at");
|
238
|
+
|
239
|
+
assertEquals(reportDuration, new Duration(earliestUpdatedAt, latestUpdatedAt).getMillis());
|
240
|
+
assertEquals(nextErliestUpdatedAt, latestUpdatedAt.plusSeconds(1).toString(DATE_FORMATTER));
|
241
|
+
}
|
242
|
+
|
243
|
+
@SuppressWarnings("unchecked")
|
244
|
+
private void testRun(ConfigSource config, Predicate<MarketoRestClient> expectedCall) throws JsonParseException, JsonMappingException, IOException
|
245
|
+
{
|
246
|
+
// Mock response data
|
247
|
+
RecordPagingIterable<ObjectNode> mockRecordPagingIterable = Mockito.mock(RecordPagingIterable.class);
|
248
|
+
JavaType javaType = OBJECT_MAPPER.getTypeFactory().constructParametrizedType(List.class, List.class, ObjectNode.class);
|
249
|
+
List<ObjectNode> objectNodeList = OBJECT_MAPPER.readValue(this.getClass().getResourceAsStream("/fixtures/all_program_full.json"), javaType);
|
250
|
+
Mockito.when(mockRecordPagingIterable.iterator()).thenReturn(objectNodeList.iterator());
|
251
|
+
Mockito.when(mockRestClient.getProgramsByTag(Mockito.anyString(), Mockito.anyString())).thenReturn(mockRecordPagingIterable);
|
252
|
+
Mockito.when(mockRestClient.getPrograms()).thenReturn(mockRecordPagingIterable);
|
253
|
+
Mockito.when(mockRestClient.getProgramsByDateRange(
|
254
|
+
Mockito.any(Date.class),
|
255
|
+
Mockito.any(Date.class),
|
256
|
+
Mockito.nullable(String.class),
|
257
|
+
Mockito.nullable(List.class))).thenReturn(mockRecordPagingIterable);
|
258
|
+
|
259
|
+
ServiceResponseMapper<? extends ValueLocator> mapper = mockPlugin.buildServiceResponseMapper(config.loadConfig(PluginTask.class));
|
260
|
+
RecordImporter recordImporter = mapper.createRecordImporter();
|
261
|
+
PageBuilder mockPageBuilder = Mockito.mock(PageBuilder.class);
|
262
|
+
mockPlugin.ingestServiceData(config.loadConfig(PluginTask.class), recordImporter, 1, mockPageBuilder);
|
263
|
+
|
264
|
+
// The method getProgramByTag is called 1 time
|
265
|
+
// Mockito.verify(mockRestClient, Mockito.times(1)).getProgramsByTag(Mockito.anyString(), Mockito.anyString());
|
266
|
+
expectedCall.apply(mockRestClient);
|
267
|
+
|
268
|
+
Schema embulkSchema = mapper.getEmbulkSchema();
|
269
|
+
// 17 columns
|
270
|
+
assertEquals(embulkSchema.size(), 17);
|
271
|
+
// verify 3 times the method setLong for column id has been called
|
272
|
+
ArgumentCaptor<Long> longArgumentCaptor = ArgumentCaptor.forClass(Long.class);
|
273
|
+
Mockito.verify(mockPageBuilder, Mockito.times(3)).setLong(Mockito.eq(embulkSchema.lookupColumn("id")), longArgumentCaptor.capture());
|
274
|
+
List<Long> allValues = longArgumentCaptor.getAllValues();
|
275
|
+
assertArrayEquals(new Long[]{1004L, 1001L, 1003L}, allValues.toArray());
|
276
|
+
}
|
277
|
+
|
278
|
+
@Test
|
279
|
+
public void testRunQueryByTagType() throws JsonParseException, JsonMappingException, IOException
|
280
|
+
{
|
281
|
+
ConfigSource config = baseConfig
|
282
|
+
.set("query_by", Optional.of(QueryBy.TAG_TYPE))
|
283
|
+
.set("tag_type", Optional.of("dummy"))
|
284
|
+
.set("tag_value", Optional.of("dummy"));
|
285
|
+
Predicate<MarketoRestClient> expectedCall = new Predicate<MarketoRestClient>()
|
286
|
+
{
|
287
|
+
@Override
|
288
|
+
public boolean apply(MarketoRestClient mockRest)
|
289
|
+
{
|
290
|
+
Mockito.verify(mockRest, Mockito.times(1)).getProgramsByTag(Mockito.anyString(), Mockito.anyString());
|
291
|
+
return true;
|
292
|
+
}
|
293
|
+
};
|
294
|
+
testRun(config, expectedCall);
|
295
|
+
}
|
296
|
+
|
297
|
+
@Test
|
298
|
+
public void testRunWithoutQueryBy() throws JsonParseException, JsonMappingException, IOException
|
299
|
+
{
|
300
|
+
Predicate<MarketoRestClient> expectedCall = new Predicate<MarketoRestClient>()
|
301
|
+
{
|
302
|
+
@Override
|
303
|
+
public boolean apply(MarketoRestClient input)
|
304
|
+
{
|
305
|
+
Mockito.verify(input, Mockito.times(1)).getPrograms();
|
306
|
+
return true;
|
307
|
+
}
|
308
|
+
};
|
309
|
+
testRun(baseConfig, expectedCall);
|
310
|
+
}
|
311
|
+
|
312
|
+
@Test
|
313
|
+
public void testRunQueryByDateRange() throws JsonParseException, JsonMappingException, IOException
|
314
|
+
{
|
315
|
+
DateTime earliestUpdatedAt = DateTime.now().minusDays(20);
|
316
|
+
DateTime latestUpdatedAt = DateTime.now().minusDays(10);
|
317
|
+
ConfigSource config = baseConfig
|
318
|
+
.set("query_by", Optional.of(QueryBy.DATE_RANGE))
|
319
|
+
.set("earliest_updated_at", Optional.of(earliestUpdatedAt))
|
320
|
+
.set("latest_updated_at", Optional.of(latestUpdatedAt));
|
321
|
+
Predicate<MarketoRestClient> expectedCall = new Predicate<MarketoRestClient>()
|
322
|
+
{
|
323
|
+
@SuppressWarnings("unchecked")
|
324
|
+
@Override
|
325
|
+
public boolean apply(MarketoRestClient input)
|
326
|
+
{
|
327
|
+
Mockito.verify(input, Mockito.times(1)).getProgramsByDateRange(
|
328
|
+
Mockito.any(Date.class),
|
329
|
+
Mockito.any(Date.class),
|
330
|
+
Mockito.nullable(String.class),
|
331
|
+
Mockito.nullable(List.class));
|
332
|
+
return true;
|
333
|
+
}
|
334
|
+
};
|
335
|
+
testRun(config, expectedCall);
|
336
|
+
}
|
337
|
+
|
338
|
+
public ConfigSource config() throws IOException
|
339
|
+
{
|
340
|
+
ConfigLoader configLoader = runtime.getInjector().getInstance(ConfigLoader.class);
|
341
|
+
return configLoader.fromYaml(this.getClass().getResourceAsStream("/config/rest_config.yaml"));
|
342
|
+
}
|
343
|
+
}
|