Skip to content

Commit b9948a7

Browse files
authored
Merge pull request #132 from cloudsufi/feature/PLUGIN-1940
PLUGIN-1940 : Support Array Type
2 parents 42846e3 + b370732 commit b9948a7

20 files changed

+228
-45
lines changed

src/e2e-test/java/io/cdap/plugin/servicenowsink/actions/ServiceNowSinkPropertiesPageActions.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ public static void getRecordFromServiceNowTable(String query, String tableName)
6060
System.getenv("SERVICE_NOW_REST_API_ENDPOINT"),
6161
System.getenv("SERVICE_NOW_USERNAME"),
6262
System.getenv("SERVICE_NOW_PASSWORD"),
63-
"", "", "", null);
63+
"", "", "", null, false);
6464

6565
ServiceNowTableAPIClientImpl tableAPIClient = new ServiceNowTableAPIClientImpl(config.getConnection(), true);
6666
responseFromServiceNowTable = tableAPIClient.getRecordFromServiceNowTable(tableName, query);

src/e2e-test/java/io/cdap/plugin/tests/hooks/TestSetupHooks.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ public static void initializeServiceNowSourceConfig() {
5959
System.getenv("SERVICE_NOW_REST_API_ENDPOINT"),
6060
System.getenv("SERVICE_NOW_USERNAME"),
6161
System.getenv("SERVICE_NOW_PASSWORD"),
62-
"", "", "", null);
62+
"", "", "", null, false);
6363
}
6464

6565
@Before(order = 2, value = "@SN_PRODUCT_CATALOG_ITEM")

src/main/java/io/cdap/plugin/servicenow/apiclient/ServiceNowTableAPIClientImpl.java

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
import com.google.gson.JsonArray;
2828
import com.google.gson.JsonObject;
2929
import com.google.gson.reflect.TypeToken;
30+
import com.sun.org.apache.xpath.internal.operations.Bool;
3031
import io.cdap.cdap.api.data.schema.Schema;
3132
import io.cdap.cdap.etl.api.FailureCollector;
3233
import io.cdap.plugin.servicenow.connector.ServiceNowConnectorConfig;
@@ -291,7 +292,7 @@ public MetadataAPISchemaResponse parseSchemaResponse(String responseBody) {
291292
*/
292293
public Schema fetchTableSchema(String tableName, SourceValueType valueType)
293294
throws ServiceNowAPIException {
294-
return fetchTableSchema(tableName, getAccessToken(), valueType, schemaType);
295+
return fetchTableSchema(tableName, getAccessToken(), valueType, schemaType, false);
295296
}
296297

297298
private SchemaType getSchemaTypeBasedOnUseConnection(Boolean useConnection) {
@@ -310,10 +311,11 @@ private SchemaType getSchemaTypeBasedOnUseConnection(Boolean useConnection) {
310311
* @param accessToken Access Token to use
311312
* @param valueType Type of value (Actual/Display)
312313
* @param schemaType Enum to determine which approach to take to fetch schema.
314+
* @param enableNewDataTypes Flag to enable new data types
313315
* @return schema for given ServiceNow table
314316
*/
315317
public Schema fetchTableSchema(String tableName, String accessToken, SourceValueType valueType,
316-
SchemaType schemaType)
318+
SchemaType schemaType, Boolean enableNewDataTypes)
317319
throws ServiceNowAPIException {
318320
ServiceNowTableAPIRequestBuilder requestBuilder = new ServiceNowTableAPIRequestBuilder(
319321
this.conf.getRestApiEndpoint(), tableName, true, schemaType)
@@ -325,7 +327,7 @@ public Schema fetchTableSchema(String tableName, String accessToken, SourceValue
325327
List<ServiceNowColumn> columns = new ArrayList<>();
326328

327329
if (schemaType == SchemaType.METADATA_API_BASED) {
328-
return prepareSchemaWithMetadataAPI(restAPIResponse, columns, tableName, valueType);
330+
return prepareSchemaWithMetadataAPI(restAPIResponse, columns, tableName, valueType, enableNewDataTypes);
329331
} else if (schemaType == SchemaType.SCHEMA_API_BASED) {
330332
return prepareSchemaWithSchemaAPI(restAPIResponse, columns, tableName);
331333
} else {
@@ -362,7 +364,7 @@ private Schema prepareSchemaWithSchemaAPI(RestAPIResponse restAPIResponse, List<
362364
for (SchemaAPISchemaField field : schemaAPISchemaResponse.getResult()) {
363365
columns.add(new ServiceNowColumn(field.getName(), field.getInternalType()));
364366
}
365-
return SchemaBuilder.constructSchema(tableName, columns);
367+
return SchemaBuilder.constructSchema(tableName, columns, false);
366368
}
367369

368370
/**
@@ -384,8 +386,7 @@ private Schema prepareSchemaWithSchemaAPI(RestAPIResponse restAPIResponse, List<
384386
* @throws RuntimeException if the response does not contain valid column information.
385387
*/
386388
private Schema prepareSchemaWithMetadataAPI(RestAPIResponse restAPIResponse, List<ServiceNowColumn> columns,
387-
String tableName, SourceValueType valueType) throws
388-
ServiceNowAPIException {
389+
String tableName, SourceValueType valueType, Boolean enableNewDataTypes) throws ServiceNowAPIException {
389390
MetadataAPISchemaResponse metadataAPISchemaResponse = parseSchemaResponse(restAPIResponse.getResponseBody());
390391

391392
if (metadataAPISchemaResponse.getResult() == null || metadataAPISchemaResponse.getResult().getColumns() == null ||
@@ -410,7 +411,7 @@ private Schema prepareSchemaWithMetadataAPI(RestAPIResponse restAPIResponse, Lis
410411
columns.add(new ServiceNowColumn(field.getName(), field.getInternalType()));
411412
}
412413
}
413-
return SchemaBuilder.constructSchema(tableName, columns);
414+
return SchemaBuilder.constructSchema(tableName, columns, enableNewDataTypes);
414415
}
415416

416417
/**
@@ -552,7 +553,7 @@ private Schema prepareStringBasedSchema(RestAPIResponse restAPIResponse, List<Se
552553
for (String key : firstRecord.keySet()) {
553554
columns.add(new ServiceNowColumn(key, "string"));
554555
}
555-
return SchemaBuilder.constructSchema(tableName, columns);
556+
return SchemaBuilder.constructSchema(tableName, columns, false);
556557
}
557558
return null;
558559
}

src/main/java/io/cdap/plugin/servicenow/connector/ServiceNowConnector.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -193,7 +193,7 @@ private List<StructuredRecord> getTableData(String tableName, int limit)
193193
StructuredRecord.Builder recordBuilder = StructuredRecord.builder(schema);
194194
for (Schema.Field field : tableFields) {
195195
String fieldName = field.getName();
196-
ServiceNowRecordConverter.convertToValue(fieldName, field.getSchema(), result.get(i), recordBuilder);
196+
ServiceNowRecordConverter.convertToValue(fieldName, field.getSchema(), result.get(i), recordBuilder, false);
197197
}
198198
StructuredRecord structuredRecord = recordBuilder.build();
199199
recordList.add(structuredRecord);

src/main/java/io/cdap/plugin/servicenow/connector/ServiceNowRecordConverter.java

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
import java.util.List;
3333
import java.util.Locale;
3434
import java.util.Map;
35+
import java.util.stream.Collectors;
3536

3637
/**
3738
* Utility class for converting the record from ServiceNow data type to CDAP schema data types
@@ -83,7 +84,7 @@ public class ServiceNowRecordConverter {
8384
));
8485

8586
public static void convertToValue(String fieldName, Schema fieldSchema, Map<String, String> record,
86-
StructuredRecord.Builder recordBuilder) {
87+
StructuredRecord.Builder recordBuilder, Boolean enableNewDataTypes) {
8788
String fieldValue = record.get(fieldName);
8889
if (fieldValue == null || fieldValue.isEmpty()) {
8990
// Set 'null' value as it is
@@ -128,13 +129,26 @@ public static void convertToValue(String fieldName, Schema fieldSchema, Map<Stri
128129
case BOOLEAN:
129130
recordBuilder.set(fieldName, convertToBooleanValue(fieldValue));
130131
return;
132+
case ARRAY:
133+
recordBuilder.set(fieldName, enableNewDataTypes.equals(Boolean.TRUE) ? convertToList(fieldValue) : fieldValue);
134+
return;
131135
default:
132136
throw new IllegalStateException(
133137
String.format("Record type '%s' is not supported for field '%s'", fieldType.name(), fieldName));
134138
}
135139

136140
}
137141

142+
public static List<String> convertToList(String fieldValue) {
143+
if (fieldValue.trim().isEmpty()) {
144+
return Collections.emptyList();
145+
}
146+
return Arrays.stream(fieldValue.split(","))
147+
.map(String::trim)
148+
.filter(s -> !s.isEmpty())
149+
.collect(Collectors.toList());
150+
}
151+
138152
@VisibleForTesting
139153
public static Double convertToDoubleValue(String fieldValue) {
140154
try {

src/main/java/io/cdap/plugin/servicenow/source/ServiceNowBaseSourceConfig.java

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,11 @@ public class ServiceNowBaseSourceConfig extends ServiceNowBaseConfig {
7474
@Nullable
7575
@Description("The number of records to fetch from ServiceNow. Default is 5000.")
7676
private Integer pageSize;
77+
78+
@Name(ServiceNowConstants.PROPERTY_ENABLE_NEW_DATA_TYPES)
79+
@Nullable
80+
@Description("Enable support for new data types such as array (glide_list) ")
81+
private Boolean enableNewDataTypes;
7782

7883
/**
7984
* Constructor for ServiceNowSourceConfig object.
@@ -92,14 +97,16 @@ public class ServiceNowBaseSourceConfig extends ServiceNowBaseConfig {
9297
*/
9398
public ServiceNowBaseSourceConfig(String referenceName, String clientId, String clientSecret, String restApiEndpoint,
9499
String user, String password, String tableNameField, String valueType,
95-
@Nullable String startDate, @Nullable String endDate, Integer pageSize) {
100+
@Nullable String startDate, @Nullable String endDate, Integer pageSize,
101+
Boolean enableNewDataTypes) {
96102
super(clientId, clientSecret, restApiEndpoint, user, password);
97103
this.referenceName = referenceName;
98104
this.tableNameField = tableNameField;
99105
this.valueType = valueType;
100106
this.startDate = startDate;
101107
this.endDate = endDate;
102108
this.pageSize = pageSize;
109+
this.enableNewDataTypes = enableNewDataTypes;
103110
}
104111

105112
public String getReferenceName() {
@@ -124,6 +131,10 @@ public Integer getPageSize() {
124131
return pageSize == null ? ServiceNowConstants.PAGE_SIZE : pageSize;
125132
}
126133

134+
public Boolean getEnableNewDataTypes() {
135+
return enableNewDataTypes == null ? Boolean.FALSE : enableNewDataTypes;
136+
}
137+
127138
/**
128139
* Validates {@link ServiceNowBaseSourceConfig} instance.
129140
*/

src/main/java/io/cdap/plugin/servicenow/source/ServiceNowMultiRecordReader.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ public class ServiceNowMultiRecordReader extends ServiceNowBaseRecordReader {
3636

3737
private final ServiceNowMultiSourceConfig multiSourcePluginConf;
3838
private ServiceNowTableAPIClientImpl restApi;
39+
private Boolean enableNewDataTypes;
3940

4041
ServiceNowMultiRecordReader(ServiceNowMultiSourceConfig multiSourcePluginConf) {
4142
super();
@@ -81,8 +82,8 @@ public StructuredRecord getCurrentValue() throws IOException {
8182
try {
8283
for (Schema.Field field : tableFields) {
8384
String fieldName = field.getName();
84-
ServiceNowRecordConverter.convertToValue(fieldName, field.getSchema(), row,
85-
recordBuilder);
85+
ServiceNowRecordConverter.convertToValue(fieldName, field.getSchema(), row, recordBuilder,
86+
multiSourcePluginConf.getEnableNewDataTypes());
8687
}
8788
} catch (Exception e) {
8889
throw new IOException("Error decoding row from table " + tableName, e);

src/main/java/io/cdap/plugin/servicenow/source/ServiceNowMultiSourceConfig.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -55,9 +55,9 @@ public class ServiceNowMultiSourceConfig extends ServiceNowBaseSourceConfig {
5555
public ServiceNowMultiSourceConfig(String referenceName, String clientId, String clientSecret, String restApiEndpoint,
5656
String user, String password, String tableNameField, String valueType,
5757
@Nullable String startDate, @Nullable String endDate, Integer pageSize,
58-
String tableNames) {
58+
String tableNames, Boolean enableNewDataTypes) {
5959
super(referenceName, clientId, clientSecret, restApiEndpoint, user, password, tableNameField, valueType, startDate,
60-
endDate, pageSize);
60+
endDate, pageSize, enableNewDataTypes);
6161
this.tableNames = tableNames;
6262
}
6363

src/main/java/io/cdap/plugin/servicenow/source/ServiceNowRecordReader.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ public class ServiceNowRecordReader extends ServiceNowBaseRecordReader {
3838
private static final Logger LOG = LoggerFactory.getLogger(ServiceNowRecordReader.class);
3939
private final ServiceNowSourceConfig pluginConf;
4040
private ServiceNowTableAPIClientImpl restApi;
41+
private Boolean enableNewDataTypes;
4142

4243
public ServiceNowRecordReader(ServiceNowSourceConfig pluginConf) {
4344
super();
@@ -94,7 +95,8 @@ public StructuredRecord getCurrentValue() throws IOException {
9495
try {
9596
for (Schema.Field field : tableFields) {
9697
String fieldName = field.getName();
97-
ServiceNowRecordConverter.convertToValue(fieldName, field.getSchema(), row, recordBuilder);
98+
ServiceNowRecordConverter.convertToValue(fieldName, field.getSchema(), row, recordBuilder,
99+
pluginConf.getEnableNewDataTypes());
98100
}
99101
} catch (Exception e) {
100102
LOG.error("Error decoding row from table " + tableName, e);

src/main/java/io/cdap/plugin/servicenow/source/ServiceNowSourceConfig.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -79,9 +79,9 @@ public ServiceNowSourceConfig(String referenceName, String queryMode, @Nullable
7979
@Nullable String tableNameField, @Nullable String tableName, String clientId,
8080
String clientSecret, String restApiEndpoint, String user, String password,
8181
String valueType, @Nullable String startDate, @Nullable String endDate,
82-
Integer pageSize) {
82+
Integer pageSize, Boolean enableNewDataTypes) {
8383
super(referenceName, clientId, clientSecret, restApiEndpoint, user, password, tableNameField, valueType, startDate,
84-
endDate, pageSize);
84+
endDate, pageSize, enableNewDataTypes);
8585
this.referenceName = referenceName;
8686
this.queryMode = queryMode;
8787
this.applicationName = applicationName;

0 commit comments

Comments
 (0)