From 23977c44868518efd7c5394e7903f1ec10ec2f6f Mon Sep 17 00:00:00 2001 From: Vinay Venu Date: Fri, 3 Nov 2023 13:25:38 +0530 Subject: [PATCH] #102 | Refactor. Introduce a new BigQueryClient and domain object for FlowResult. Ability to use default BigQuery iterator. --- glific/build.gradle | 7 ++- .../glific/bigQuery/BigQueryClientNew.java | 53 +++++++++++++++++++ .../glific/bigQuery/domain/FlowResult.java | 40 ++++++++++++++ .../bigQuery/mapper/BigQueryResultMapper.java | 8 +++ .../mapper/BigQueryResultsMapper.java | 28 ++++++++++ .../bigQuery/mapper/FlowResultMapper.java | 20 +++++++ .../bigQuery/BigQueryClientNewTest.java | 41 ++++++++++++++ .../builder/FieldValueListBuilder.java | 17 ++++++ .../bigQuery/builder/SchemaBuilder.java | 16 ++++++ .../bigQuery/builder/TableResultBuilder.java | 34 ++++++++++++ .../bigQuery/domain/FlowResultTest.java | 43 +++++++++++++++ .../mapper/BigQueryResultsMapperTest.java | 37 +++++++++++++ .../bigQuery/mapper/FlowResultMapperTest.java | 29 ++++++++++ .../resources/sampleBigQueryResponse.json | 30 +++++++++++ .../src/test/resources/sampleFlowResult.json | 7 +++ .../util/ObjectJsonMapper.java | 10 ++++ 16 files changed, 418 insertions(+), 2 deletions(-) create mode 100644 glific/src/main/java/org/avni_integration_service/glific/bigQuery/BigQueryClientNew.java create mode 100644 glific/src/main/java/org/avni_integration_service/glific/bigQuery/domain/FlowResult.java create mode 100644 glific/src/main/java/org/avni_integration_service/glific/bigQuery/mapper/BigQueryResultMapper.java create mode 100644 glific/src/main/java/org/avni_integration_service/glific/bigQuery/mapper/BigQueryResultsMapper.java create mode 100644 glific/src/main/java/org/avni_integration_service/glific/bigQuery/mapper/FlowResultMapper.java create mode 100644 glific/src/test/java/org/avni_integration_service/glific/bigQuery/BigQueryClientNewTest.java create mode 100644 glific/src/test/java/org/avni_integration_service/glific/bigQuery/builder/FieldValueListBuilder.java create mode 100644 glific/src/test/java/org/avni_integration_service/glific/bigQuery/builder/SchemaBuilder.java create mode 100644 glific/src/test/java/org/avni_integration_service/glific/bigQuery/builder/TableResultBuilder.java create mode 100644 glific/src/test/java/org/avni_integration_service/glific/bigQuery/domain/FlowResultTest.java create mode 100644 glific/src/test/java/org/avni_integration_service/glific/bigQuery/mapper/BigQueryResultsMapperTest.java create mode 100644 glific/src/test/java/org/avni_integration_service/glific/bigQuery/mapper/FlowResultMapperTest.java create mode 100644 glific/src/test/resources/sampleBigQueryResponse.json create mode 100644 glific/src/test/resources/sampleFlowResult.json diff --git a/glific/build.gradle b/glific/build.gradle index 97b201a2..b0795aec 100644 --- a/glific/build.gradle +++ b/glific/build.gradle @@ -37,8 +37,7 @@ repositories { } dependencies { - testImplementation 'org.junit.jupiter:junit-jupiter-api:5.6.0' - testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine' + testImplementation 'org.junit.jupiter:junit-jupiter:5.10.0' // https://mvnrepository.com/artifact/org.springframework.cloud/spring-cloud-gcp-starter implementation 'org.springframework.cloud:spring-cloud-gcp-starter:1.2.6.RELEASE' @@ -46,6 +45,10 @@ dependencies { implementation 'org.springframework.cloud:spring-cloud-gcp-starter-bigquery:1.2.6.RELEASE' implementation "log4j:log4j:1.2.17" + implementation project(':util') + + testImplementation 'com.fasterxml.jackson.core:jackson-databind:2.0.1' + testImplementation 'org.mockito:mockito-core:3.+' } dependencyManagement { diff --git a/glific/src/main/java/org/avni_integration_service/glific/bigQuery/BigQueryClientNew.java b/glific/src/main/java/org/avni_integration_service/glific/bigQuery/BigQueryClientNew.java new file mode 100644 index 00000000..7d55ee14 --- /dev/null +++ b/glific/src/main/java/org/avni_integration_service/glific/bigQuery/BigQueryClientNew.java @@ -0,0 +1,53 @@ +package org.avni_integration_service.glific.bigQuery; + +import com.google.cloud.bigquery.*; +import org.apache.log4j.Logger; +import org.avni_integration_service.glific.bigQuery.config.BigQueryConnector; +import org.avni_integration_service.glific.bigQuery.mapper.BigQueryResultMapper; +import org.avni_integration_service.glific.bigQuery.mapper.BigQueryResultsMapper; +import org.springframework.stereotype.Component; + +import java.util.Iterator; +import java.util.UUID; + +@Component +public class BigQueryClientNew { + private final BigQueryConnector bigQueryConnector; + private static final Logger logger = Logger.getLogger(BigQueryClientNew.class); + + public BigQueryClientNew(BigQueryConnector bigQueryConnector) { + this.bigQueryConnector = bigQueryConnector; + } + + public Iterator getResults(String query, String date, int limit, BigQueryResultMapper resultMapper) { + QueryJobConfiguration queryConfig = + QueryJobConfiguration.newBuilder(query) + .addNamedParameter("updated_at", QueryParameterValue.string(date)) + .addNamedParameter("limit_count", QueryParameterValue.int64(limit)) + .build(); + TableResult tableResult = run(queryConfig); + return new BigQueryResultsMapper().map(tableResult, resultMapper); + } + + private TableResult run(QueryJobConfiguration queryJobConfiguration) { + try { + JobId jobId = JobId.of(UUID.randomUUID().toString()); + Job queryJob = bigQueryConnector.getBigQuery().create(JobInfo.newBuilder(queryJobConfiguration).setJobId(jobId).build()); + queryJob = queryJob.waitFor(); + + if (queryJob == null) { + logger.info("query job is null"); + throw new RuntimeException("Job no longer exists"); + } else if (queryJob.getStatus().getError() != null) { + // You can also look at queryJob.getStatus().getExecutionErrors() for all + // errors, not just the latest one. + logger.info(queryJob.getStatus().getError().toString()); + throw new RuntimeException(queryJob.getStatus().getError().toString()); + } + + return queryJob.getQueryResults(); + } catch (InterruptedException e) { + throw new RuntimeException(e); + } + } +} diff --git a/glific/src/main/java/org/avni_integration_service/glific/bigQuery/domain/FlowResult.java b/glific/src/main/java/org/avni_integration_service/glific/bigQuery/domain/FlowResult.java new file mode 100644 index 00000000..e7d697e2 --- /dev/null +++ b/glific/src/main/java/org/avni_integration_service/glific/bigQuery/domain/FlowResult.java @@ -0,0 +1,40 @@ +package org.avni_integration_service.glific.bigQuery.domain; + +import java.util.HashMap; +import java.util.Map; + +import static org.avni_integration_service.util.ObjectJsonMapper.readValue; + +public class FlowResult { + private final Map fields; + private final Map results; + + public FlowResult(Map fields) { + this.fields = fields; + results = readValue((String)this.fields.get("results"), Map.class); + } + + public String getContactPhone() { + return (String) fields.get("contact_phone"); + } + + public String getInsertedAt() { + return (String) fields.get("inserted_at"); + } + + public String getUpdatedAt() { + return (String) fields.get("updated_at"); + } + + public String getInput(String key) { + return (String) getResult(key).get("input"); + } + + public String getCategory(String key) { + return (String) getResult(key).get("category"); + } + + private Map getResult(String key) { + return (Map) results.getOrDefault(key, new HashMap<>()); + } +} diff --git a/glific/src/main/java/org/avni_integration_service/glific/bigQuery/mapper/BigQueryResultMapper.java b/glific/src/main/java/org/avni_integration_service/glific/bigQuery/mapper/BigQueryResultMapper.java new file mode 100644 index 00000000..125e0c24 --- /dev/null +++ b/glific/src/main/java/org/avni_integration_service/glific/bigQuery/mapper/BigQueryResultMapper.java @@ -0,0 +1,8 @@ +package org.avni_integration_service.glific.bigQuery.mapper; + +import com.google.cloud.bigquery.FieldValueList; +import com.google.cloud.bigquery.Schema; + +public interface BigQueryResultMapper { + T map(Schema schema, FieldValueList fieldValues); +} diff --git a/glific/src/main/java/org/avni_integration_service/glific/bigQuery/mapper/BigQueryResultsMapper.java b/glific/src/main/java/org/avni_integration_service/glific/bigQuery/mapper/BigQueryResultsMapper.java new file mode 100644 index 00000000..2324b19f --- /dev/null +++ b/glific/src/main/java/org/avni_integration_service/glific/bigQuery/mapper/BigQueryResultsMapper.java @@ -0,0 +1,28 @@ +package org.avni_integration_service.glific.bigQuery.mapper; + +import com.google.cloud.bigquery.FieldValueList; +import com.google.cloud.bigquery.Schema; +import com.google.cloud.bigquery.TableResult; + +import java.util.Iterator; + +public class BigQueryResultsMapper { + + public Iterator map(TableResult response, BigQueryResultMapper resultMapper) { + Schema schema = response.getSchema(); + Iterator iterator = response.iterateAll().iterator(); + + return new Iterator() { + @Override + public boolean hasNext() { + return iterator.hasNext(); + } + + @Override + public T next() { + return resultMapper.map(schema, iterator.next()); + } + }; + } + +} diff --git a/glific/src/main/java/org/avni_integration_service/glific/bigQuery/mapper/FlowResultMapper.java b/glific/src/main/java/org/avni_integration_service/glific/bigQuery/mapper/FlowResultMapper.java new file mode 100644 index 00000000..d4dc6e26 --- /dev/null +++ b/glific/src/main/java/org/avni_integration_service/glific/bigQuery/mapper/FlowResultMapper.java @@ -0,0 +1,20 @@ +package org.avni_integration_service.glific.bigQuery.mapper; + +import com.google.cloud.bigquery.*; +import org.avni_integration_service.glific.bigQuery.domain.FlowResult; + +import java.util.*; + +public class FlowResultMapper implements BigQueryResultMapper { + + @Override + public FlowResult map(Schema schema, FieldValueList fieldValues) { + HashMap fields = schema.getFields().stream() + .reduce(new HashMap<>(), + (hashMap, field) -> { + hashMap.merge(field.getName(), fieldValues.get(field.getName()).getValue(), Objects::equals); + return hashMap; + }, (first, second) -> {first.putAll(second);return first;}); + return new FlowResult(fields); + } +} diff --git a/glific/src/test/java/org/avni_integration_service/glific/bigQuery/BigQueryClientNewTest.java b/glific/src/test/java/org/avni_integration_service/glific/bigQuery/BigQueryClientNewTest.java new file mode 100644 index 00000000..1eac62e9 --- /dev/null +++ b/glific/src/test/java/org/avni_integration_service/glific/bigQuery/BigQueryClientNewTest.java @@ -0,0 +1,41 @@ +package org.avni_integration_service.glific.bigQuery; + +import com.google.cloud.bigquery.*; +import org.avni_integration_service.glific.bigQuery.builder.TableResultBuilder; +import org.avni_integration_service.glific.bigQuery.config.BigQueryConnector; +import org.avni_integration_service.glific.bigQuery.domain.FlowResult; +import org.avni_integration_service.glific.bigQuery.mapper.FlowResultMapper; +import org.junit.jupiter.api.Test; + +import java.util.Iterator; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +public class BigQueryClientNewTest { + + @Test + public void shouldMapResponseToMapper() throws InterruptedException { + FlowResultMapper flowResultMapper = new FlowResultMapper(); + TableResult tableResult = new TableResultBuilder().build(); + BigQueryConnector bqConnector = mock(BigQueryConnector.class); + BigQuery bigQuery = mock(BigQuery.class); + when(bqConnector.getBigQuery()).thenReturn(bigQuery); + Job job = mock(Job.class); + when(bigQuery.create(any(JobInfo.class))).thenReturn(job); + when(job.getQueryResults()).thenReturn(tableResult); + when(job.waitFor()).thenReturn(job); + JobStatus jobStatus = mock(JobStatus.class); + when(job.getStatus()).thenReturn(jobStatus); + when(jobStatus.getError()).thenReturn(null); + + Iterator results = new BigQueryClientNew(bqConnector).getResults("query", "2023-01-01", 5, flowResultMapper); + + FlowResult firstFlowResult = results.next(); + assertEquals("919317217785", firstFlowResult.getContactPhone()); + assertEquals("919317217785", firstFlowResult.getContactPhone()); + assertEquals("Suresh", firstFlowResult.getInput("avni_first_name")); + } +} diff --git a/glific/src/test/java/org/avni_integration_service/glific/bigQuery/builder/FieldValueListBuilder.java b/glific/src/test/java/org/avni_integration_service/glific/bigQuery/builder/FieldValueListBuilder.java new file mode 100644 index 00000000..6769a5b9 --- /dev/null +++ b/glific/src/test/java/org/avni_integration_service/glific/bigQuery/builder/FieldValueListBuilder.java @@ -0,0 +1,17 @@ +package org.avni_integration_service.glific.bigQuery.builder; + +import com.google.cloud.bigquery.*; + +import java.util.Arrays; + +public class FieldValueListBuilder { + public FieldValueList buildFlowResult(String contactPhone, String flowResultId, String results) { + return FieldValueList.of(Arrays.asList( + FieldValue.of(FieldValue.Attribute.PRIMITIVE, contactPhone), + FieldValue.of(FieldValue.Attribute.PRIMITIVE, flowResultId), + FieldValue.of(FieldValue.Attribute.PRIMITIVE, "2023-08-02T14:21:25.695844"), + FieldValue.of(FieldValue.Attribute.PRIMITIVE, results), + FieldValue.of(FieldValue.Attribute.PRIMITIVE, "2023-08-02T14:21:25.695844")), + new SchemaBuilder().flowResultSchema().getFields()); + } +} diff --git a/glific/src/test/java/org/avni_integration_service/glific/bigQuery/builder/SchemaBuilder.java b/glific/src/test/java/org/avni_integration_service/glific/bigQuery/builder/SchemaBuilder.java new file mode 100644 index 00000000..c183a3d5 --- /dev/null +++ b/glific/src/test/java/org/avni_integration_service/glific/bigQuery/builder/SchemaBuilder.java @@ -0,0 +1,16 @@ +package org.avni_integration_service.glific.bigQuery.builder; + +import com.google.cloud.bigquery.Field; +import com.google.cloud.bigquery.LegacySQLTypeName; +import com.google.cloud.bigquery.Schema; + +public class SchemaBuilder { + + public Schema flowResultSchema() { + return Schema.of(Field.of("contact_phone", LegacySQLTypeName.STRING), + Field.of("flowresult_id", LegacySQLTypeName.STRING), + Field.of("inserted_at", LegacySQLTypeName.DATETIME), + Field.of("results", LegacySQLTypeName.STRING), + Field.of("updated_at", LegacySQLTypeName.DATETIME)); + } +} diff --git a/glific/src/test/java/org/avni_integration_service/glific/bigQuery/builder/TableResultBuilder.java b/glific/src/test/java/org/avni_integration_service/glific/bigQuery/builder/TableResultBuilder.java new file mode 100644 index 00000000..bc4f7512 --- /dev/null +++ b/glific/src/test/java/org/avni_integration_service/glific/bigQuery/builder/TableResultBuilder.java @@ -0,0 +1,34 @@ +package org.avni_integration_service.glific.bigQuery.builder; + +import com.google.api.gax.paging.Page; +import com.google.cloud.PageImpl; +import com.google.cloud.bigquery.FieldValueList; +import com.google.cloud.bigquery.TableResult; +import com.google.common.collect.ImmutableList; + +public class TableResultBuilder { + public TableResult build() { + FieldValueListBuilder fieldValueListBuilder = new FieldValueListBuilder(); + ImmutableList queryResults = ImmutableList.of( + fieldValueListBuilder.buildFlowResult( + "919317217785", + "11041268", + "{\"avni_first_name\":{\"category\":\"^[A-Za-z ]+$\",\"input\":\"Suresh\",\"inserted_at\":\"2023-09-07T06:09:52.961071Z\",\"intent\":null},\"avni_last_name\":{\"category\":\"^[A-Za-z ]+$\",\"input\":\"Yadav\",\"inserted_at\":\"2023-09-07T06:09:59.008525Z\",\"intent\":null},\"avni_optin\":{\"category\":\"Yes\",\"input\":\"Yes\",\"inserted_at\":\"2023-09-07T06:09:44.764400Z\",\"intent\":null,\"interactive\":{\"id\":\"\",\"postbackText\":\"\",\"reply\":\"Yes 1\",\"title\":\"Yes\"}},\"child\":{\"Language\":{\"category\":\"English\",\"input\":\"English\",\"inserted_at\":\"2023-09-07T06:09:37.461253Z\",\"intent\":null,\"interactive\":{\"description\":\"\",\"id\":\"\",\"postbackText\":\"\",\"reply\":\"English 1\",\"title\":\"English\"}}},\"flow_keyword\":{\"category\":\"registerme\",\"input\":\"registerme\",\"inserted_at\":\"2023-09-07T06:09:28.125929Z\"}}"), + fieldValueListBuilder.buildFlowResult( + "919873249733", + "11041211", + "{\"avni_first_name\":{\"category\":\"^[A-Za-z ]+$\",\"input\":\"Sameer\",\"inserted_at\":\"2023-09-07T05:58:34.653513Z\",\"intent\":null},\"avni_last_name\":{\"category\":\"^[A-Za-z ]+$\",\"input\":\"Kohlapuri\",\"inserted_at\":\"2023-09-07T05:58:51.431716Z\",\"intent\":null},\"avni_optin\":{\"category\":\"Yes\",\"input\":\"Yes\",\"inserted_at\":\"2023-09-07T05:58:23.609434Z\",\"intent\":null,\"interactive\":{\"id\":\"\",\"postbackText\":\"\",\"reply\":\"Yes 1\",\"title\":\"Yes\"}},\"child\":{\"Language\":{\"category\":\"English\",\"input\":\"English\",\"inserted_at\":\"2023-09-07T05:58:09.972092Z\",\"intent\":null,\"interactive\":{\"description\":\"\",\"id\":\"\",\"postbackText\":\"\",\"reply\":\"English 1\",\"title\":\"English\"}}},\"flow_keyword\":{\"category\":\"registerme\",\"input\":\"registerme\",\"inserted_at\":\"2023-09-07T05:57:46.237686Z\"}}"), + fieldValueListBuilder.buildFlowResult( + "919900310515", + "10427672", + "{\"avni_first_name\":{\"category\":\"^[A-Za-z ]+$\",\"input\":\"Utkarsh\",\"inserted_at\":\"2023-08-21T08:46:34.140088Z\",\"intent\":null},\"avni_last_name\":{\"category\":\"^[A-Za-z ]+$\",\"input\":\"Hathi\",\"inserted_at\":\"2023-08-21T08:46:44.420595Z\",\"intent\":null},\"avni_optin\":{\"category\":\"Yes\",\"input\":\"Yes\",\"inserted_at\":\"2023-08-21T08:46:26.843587Z\",\"intent\":null,\"interactive\":{\"id\":\"\",\"postbackText\":\"\",\"reply\":\"Yes 1\",\"title\":\"Yes\"}},\"child\":{\"Language\":{\"category\":\"English\",\"input\":\"English\",\"inserted_at\":\"2023-08-21T08:46:17.715479Z\",\"intent\":null,\"interactive\":{\"description\":\"\",\"id\":\"\",\"postbackText\":\"\",\"reply\":\"English 1\",\"title\":\"English\"}}},\"flow_keyword\":{\"category\":\"registerme\",\"input\":\"registerme\",\"inserted_at\":\"2023-08-21T08:45:54.533500Z\"}}"), + fieldValueListBuilder.buildFlowResult( + "919317217785", + "9843637", + "{\"avni_optin\":{\"category\":\"Other\",\"input\":\"skillsonwheels\",\"inserted_at\":\"2023-08-18T09:53:26.753549Z\",\"intent\":null},\"child\":{\"Language\":{\"category\":\"English\",\"input\":\"English\",\"inserted_at\":\"2023-08-08T05:35:17.430486Z\",\"intent\":null,\"interactive\":{\"description\":\"\",\"id\":\"\",\"postbackText\":\"\",\"reply\":\"English 1\",\"title\":\"English\"}}},\"flow_keyword\":{\"category\":\"registerme\",\"input\":\"registerme\",\"inserted_at\":\"2023-08-08T05:34:43.903087Z\"}}") + ); + + Page resultsPage = new PageImpl<>((PageImpl.NextPageFetcher) () -> null, null, queryResults); + return new TableResult(new SchemaBuilder().flowResultSchema(), queryResults.size(), resultsPage); + } +} diff --git a/glific/src/test/java/org/avni_integration_service/glific/bigQuery/domain/FlowResultTest.java b/glific/src/test/java/org/avni_integration_service/glific/bigQuery/domain/FlowResultTest.java new file mode 100644 index 00000000..4c53ad69 --- /dev/null +++ b/glific/src/test/java/org/avni_integration_service/glific/bigQuery/domain/FlowResultTest.java @@ -0,0 +1,43 @@ +package org.avni_integration_service.glific.bigQuery.domain; + +import org.avni_integration_service.util.ObjectJsonMapper; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +import java.io.IOException; +import java.util.Map; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNull; + +public class FlowResultTest { + private FlowResult flowResult; + + @BeforeEach + public void setup() { + Map json = ObjectJsonMapper.readValue( + this.getClass().getResourceAsStream("/sampleFlowResult.json"), + Map.class); + flowResult = new FlowResult(json); + } + + @Test + public void shouldGetTopLevelFields() { + assertEquals("913652322176", flowResult.getContactPhone()); + } + + @Test + public void shouldGetResultItemInputByKey() throws IOException { + assertEquals("Singh", flowResult.getInput("avni_last_name")); + } + + @Test + public void shouldGetResultItemCategoryByKey() throws IOException { + assertEquals("Telangana", flowResult.getCategory("avni_state")); + } + + @Test + public void shouldReturnNullIfNotAvailable() throws IOException { + assertNull(flowResult.getCategory("non-existent-key")); + } +} diff --git a/glific/src/test/java/org/avni_integration_service/glific/bigQuery/mapper/BigQueryResultsMapperTest.java b/glific/src/test/java/org/avni_integration_service/glific/bigQuery/mapper/BigQueryResultsMapperTest.java new file mode 100644 index 00000000..3859737b --- /dev/null +++ b/glific/src/test/java/org/avni_integration_service/glific/bigQuery/mapper/BigQueryResultsMapperTest.java @@ -0,0 +1,37 @@ +package org.avni_integration_service.glific.bigQuery.mapper; + +import com.google.cloud.bigquery.TableResult; +import org.avni_integration_service.glific.bigQuery.builder.TableResultBuilder; +import org.avni_integration_service.glific.bigQuery.domain.FlowResult; +import org.junit.jupiter.api.Test; + +import java.util.Iterator; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +public class BigQueryResultsMapperTest { + + @Test + public void shouldCleanlyIterateOverABigQueryResult() { + TableResult tableResult = new TableResultBuilder().build(); + + Iterator flowResults = new BigQueryResultsMapper().map(tableResult, new FlowResultMapper()); + + FlowResult firstFlowResult = flowResults.next(); + assertEquals("919317217785", firstFlowResult.getContactPhone()); + assertEquals("919317217785", firstFlowResult.getContactPhone()); + assertEquals("Suresh", firstFlowResult.getInput("avni_first_name")); + + assertEquals(3, remainingItemsIn(flowResults)); + } + + private int remainingItemsIn(Iterator iterator) { + int count = 0; + while (iterator.hasNext()) { + count++; + iterator.next(); + } + return count; + } + +} diff --git a/glific/src/test/java/org/avni_integration_service/glific/bigQuery/mapper/FlowResultMapperTest.java b/glific/src/test/java/org/avni_integration_service/glific/bigQuery/mapper/FlowResultMapperTest.java new file mode 100644 index 00000000..0915ec80 --- /dev/null +++ b/glific/src/test/java/org/avni_integration_service/glific/bigQuery/mapper/FlowResultMapperTest.java @@ -0,0 +1,29 @@ +package org.avni_integration_service.glific.bigQuery.mapper; + +import com.google.cloud.bigquery.FieldValueList; +import com.google.cloud.bigquery.Schema; +import org.avni_integration_service.glific.bigQuery.builder.FieldValueListBuilder; +import org.avni_integration_service.glific.bigQuery.builder.SchemaBuilder; +import org.avni_integration_service.glific.bigQuery.domain.FlowResult; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +public class FlowResultMapperTest { + + @Test + public void shouldMapBigQueryResultsToFlowResult() { + Schema schema = new SchemaBuilder().flowResultSchema(); + FieldValueList fieldValues = new FieldValueListBuilder().buildFlowResult( + "913652322176", + "23318031", + "{\"avni_academic_year\":{\"category\":\"2023\",\"input\":\"2023-24\",\"inserted_at\":\"2023-10-20T09:08:58.566681Z\",\"intent\":null,\"interactive\":{\"description\":\"\",\"id\":\"\",\"postbackText\":\"\",\"reply\":\"2023-24 1\",\"title\":\"2023-24\"}},\"avni_alternate_contact\":{\"category\":\"All Responses\",\"input\":\"92\",\"inserted_at\":\"2023-10-20T09:09:25.764105Z\",\"intent\":null},\"avni_city_name\":{\"category\":\"^[A-Za-z ]+$\",\"input\":\"asld\",\"inserted_at\":\"2023-10-20T09:08:31.285480Z\",\"intent\":null},\"avni_date_of_birth\":{\"category\":\"dateofbirth\",\"input\":\"01-01-1890\",\"inserted_at\":\"2023-10-20T09:06:54.709856Z\",\"intent\":null},\"avni_district_name\":{\"category\":\"^[A-Za-z ]+$\",\"input\":\"sidtict\",\"inserted_at\":\"2023-10-20T09:08:27.573088Z\",\"intent\":null},\"avni_email\":{\"category\":\"Has Email\",\"input\":\"asdf@asdfa.com\",\"inserted_at\":\"2023-10-20T09:09:31.479192Z\",\"intent\":null},\"avni_father_name\":{\"category\":\"^[A-Za-z ]+$\",\"input\":\"fat\",\"inserted_at\":\"2023-10-20T09:07:06.684665Z\",\"intent\":null},\"avni_first_name\":{\"category\":\"^[A-Za-z ]+$\",\"input\":\"first name\",\"inserted_at\":\"2023-10-20T09:06:37.679357Z\",\"intent\":null},\"avni_gender\":{\"category\":\"Female\",\"input\":\"female\",\"inserted_at\":\"2023-10-20T09:07:01.398781Z\",\"intent\":null},\"avni_highest_qualification\":{\"category\":\"Graduation\",\"input\":\"Post Graduation\",\"inserted_at\":\"2023-10-20T09:08:47.861303Z\",\"intent\":null,\"interactive\":{\"description\":\"\",\"id\":\"\",\"postbackText\":\"\",\"reply\":\"Post Graduation 1\",\"title\":\"Post Graduation\"}},\"avni_last_name\":{\"category\":\"^[A-Za-z ]+$\",\"input\":\"Singh\",\"inserted_at\":\"2023-10-20T09:06:41.676437Z\",\"intent\":null},\"avni_optin\":{\"category\":\"Yes\",\"input\":\"yes\",\"inserted_at\":\"2023-10-20T09:06:23.045052Z\",\"intent\":null},\"avni_qualification_status\":{\"category\":\"Result\",\"input\":\"Result Awaited\",\"inserted_at\":\"2023-10-20T09:09:10.078292Z\",\"intent\":null,\"interactive\":{\"description\":\"\",\"id\":\"\",\"postbackText\":\"\",\"reply\":\"Result Awaited 1\",\"title\":\"Result Awaited\"}},\"avni_school_name\":{\"category\":\"All Responses\",\"input\":\"asdf. asdf.\",\"inserted_at\":\"2023-10-20T09:08:36.995705Z\",\"intent\":null},\"avni_state\":{\"category\":\"Telangana\",\"input\":\"telangana\",\"inserted_at\":\"2023-10-20T09:08:15.943382Z\",\"intent\":null},\"avni_vocational\":{\"category\":\"Non-Vocational\",\"input\":\"non-vocational\",\"inserted_at\":\"2023-10-20T09:09:19.441700Z\",\"intent\":null},\"child\":{\"Language\":{\"category\":\"English\",\"input\":\"english\",\"inserted_at\":\"2023-10-20T09:06:14.078443Z\",\"intent\":null}},\"flow_keyword\":{\"category\":\"Register me\",\"input\":\"registerme\",\"inserted_at\":\"2023-10-20T09:05:56.385111Z\"}}" + ); + + FlowResult flowResult = new FlowResultMapper().map(schema, fieldValues); + + assertEquals("913652322176", flowResult.getContactPhone()); + assertEquals("Singh", flowResult.getInput("avni_last_name")); + assertEquals("Telangana", flowResult.getCategory("avni_state")); + } +} diff --git a/glific/src/test/resources/sampleBigQueryResponse.json b/glific/src/test/resources/sampleBigQueryResponse.json new file mode 100644 index 00000000..34f32c05 --- /dev/null +++ b/glific/src/test/resources/sampleBigQueryResponse.json @@ -0,0 +1,30 @@ +[ + { + "contact_phone": "919903244183", + "flowresult_id": "11041268", + "inserted_at": "2023-09-07T11:39:28.134500", + "results": "{\"avni_first_name\":{\"category\":\"^[A-Za-z ]+$\",\"input\":\"Raghav\",\"inserted_at\":\"2023-09-07T06:09:52.961071Z\",\"intent\":null},\"avni_last_name\":{\"category\":\"^[A-Za-z ]+$\",\"input\":\"Kumar\",\"inserted_at\":\"2023-09-07T06:09:59.008525Z\",\"intent\":null},\"avni_optin\":{\"category\":\"Yes\",\"input\":\"Yes\",\"inserted_at\":\"2023-09-07T06:09:44.764400Z\",\"intent\":null,\"interactive\":{\"id\":\"\",\"postbackText\":\"\",\"reply\":\"Yes 1\",\"title\":\"Yes\"}},\"child\":{\"Language\":{\"category\":\"English\",\"input\":\"English\",\"inserted_at\":\"2023-09-07T06:09:37.461253Z\",\"intent\":null,\"interactive\":{\"description\":\"\",\"id\":\"\",\"postbackText\":\"\",\"reply\":\"English 1\",\"title\":\"English\"}}},\"flow_keyword\":{\"category\":\"registerme\",\"input\":\"registerme\",\"inserted_at\":\"2023-09-07T06:09:28.125929Z\"}}", + "updated_at": "2023-09-07T11:39:59.011236" + }, + { + "contact_phone": "919873249733", + "flowresult_id": "11041211", + "inserted_at": "2023-09-07T11:27:46.245475", + "results": "{\"avni_first_name\":{\"category\":\"^[A-Za-z ]+$\",\"input\":\"Ramesh\",\"inserted_at\":\"2023-09-07T05:58:34.653513Z\",\"intent\":null},\"avni_last_name\":{\"category\":\"^[A-Za-z ]+$\",\"input\":\"Kumar\",\"inserted_at\":\"2023-09-07T05:58:51.431716Z\",\"intent\":null},\"avni_optin\":{\"category\":\"Yes\",\"input\":\"Yes\",\"inserted_at\":\"2023-09-07T05:58:23.609434Z\",\"intent\":null,\"interactive\":{\"id\":\"\",\"postbackText\":\"\",\"reply\":\"Yes 1\",\"title\":\"Yes\"}},\"child\":{\"Language\":{\"category\":\"English\",\"input\":\"English\",\"inserted_at\":\"2023-09-07T05:58:09.972092Z\",\"intent\":null,\"interactive\":{\"description\":\"\",\"id\":\"\",\"postbackText\":\"\",\"reply\":\"English 1\",\"title\":\"English\"}}},\"flow_keyword\":{\"category\":\"registerme\",\"input\":\"registerme\",\"inserted_at\":\"2023-09-07T05:57:46.237686Z\"}}", + "updated_at": "2023-09-07T11:28:51.436290" + }, + { + "contact_phone": "919930370545", + "flowresult_id": "10427672", + "inserted_at": "2023-08-21T14:15:54.542957", + "results": "{\"avni_first_name\":{\"category\":\"^[A-Za-z ]+$\",\"input\":\"Pinky\",\"inserted_at\":\"2023-08-21T08:46:34.140088Z\",\"intent\":null},\"avni_last_name\":{\"category\":\"^[A-Za-z ]+$\",\"input\":\"Yadav\",\"inserted_at\":\"2023-08-21T08:46:44.420595Z\",\"intent\":null},\"avni_optin\":{\"category\":\"Yes\",\"input\":\"Yes\",\"inserted_at\":\"2023-08-21T08:46:26.843587Z\",\"intent\":null,\"interactive\":{\"id\":\"\",\"postbackText\":\"\",\"reply\":\"Yes 1\",\"title\":\"Yes\"}},\"child\":{\"Language\":{\"category\":\"English\",\"input\":\"English\",\"inserted_at\":\"2023-08-21T08:46:17.715479Z\",\"intent\":null,\"interactive\":{\"description\":\"\",\"id\":\"\",\"postbackText\":\"\",\"reply\":\"English 1\",\"title\":\"English\"}}},\"flow_keyword\":{\"category\":\"registerme\",\"input\":\"registerme\",\"inserted_at\":\"2023-08-21T08:45:54.533500Z\"}}", + "updated_at": "2023-08-21T14:16:44.423956" + }, + { + "contact_phone": "919357103013", + "flowresult_id": "9843637", + "inserted_at": "2023-08-08T11:04:43.915985", + "results": "{\"avni_optin\":{\"category\":\"Other\",\"input\":\"skillsonwheels\",\"inserted_at\":\"2023-08-18T09:53:26.753549Z\",\"intent\":null},\"child\":{\"Language\":{\"category\":\"English\",\"input\":\"English\",\"inserted_at\":\"2023-08-08T05:35:17.430486Z\",\"intent\":null,\"interactive\":{\"description\":\"\",\"id\":\"\",\"postbackText\":\"\",\"reply\":\"English 1\",\"title\":\"English\"}}},\"flow_keyword\":{\"category\":\"registerme\",\"input\":\"registerme\",\"inserted_at\":\"2023-08-08T05:34:43.903087Z\"}}", + "updated_at": "2023-08-18T15:23:26.759526" + } +] diff --git a/glific/src/test/resources/sampleFlowResult.json b/glific/src/test/resources/sampleFlowResult.json new file mode 100644 index 00000000..b31ac39e --- /dev/null +++ b/glific/src/test/resources/sampleFlowResult.json @@ -0,0 +1,7 @@ +{ + "contact_phone": "913652322176", + "flowresult_id": "23318031", + "inserted_at": "2023-08-02T14:21:25.695844", + "updated_at": "2023-08-02T14:24:12.267284", + "results": "{\"avni_academic_year\":{\"category\":\"2023\",\"input\":\"2023-24\",\"inserted_at\":\"2023-10-20T09:08:58.566681Z\",\"intent\":null,\"interactive\":{\"description\":\"\",\"id\":\"\",\"postbackText\":\"\",\"reply\":\"2023-24 1\",\"title\":\"2023-24\"}},\"avni_alternate_contact\":{\"category\":\"All Responses\",\"input\":\"92\",\"inserted_at\":\"2023-10-20T09:09:25.764105Z\",\"intent\":null},\"avni_city_name\":{\"category\":\"^[A-Za-z ]+$\",\"input\":\"asld\",\"inserted_at\":\"2023-10-20T09:08:31.285480Z\",\"intent\":null},\"avni_date_of_birth\":{\"category\":\"dateofbirth\",\"input\":\"01-01-1890\",\"inserted_at\":\"2023-10-20T09:06:54.709856Z\",\"intent\":null},\"avni_district_name\":{\"category\":\"^[A-Za-z ]+$\",\"input\":\"sidtict\",\"inserted_at\":\"2023-10-20T09:08:27.573088Z\",\"intent\":null},\"avni_email\":{\"category\":\"Has Email\",\"input\":\"asdf@asdfa.com\",\"inserted_at\":\"2023-10-20T09:09:31.479192Z\",\"intent\":null},\"avni_father_name\":{\"category\":\"^[A-Za-z ]+$\",\"input\":\"fat\",\"inserted_at\":\"2023-10-20T09:07:06.684665Z\",\"intent\":null},\"avni_first_name\":{\"category\":\"^[A-Za-z ]+$\",\"input\":\"first name\",\"inserted_at\":\"2023-10-20T09:06:37.679357Z\",\"intent\":null},\"avni_gender\":{\"category\":\"Female\",\"input\":\"female\",\"inserted_at\":\"2023-10-20T09:07:01.398781Z\",\"intent\":null},\"avni_highest_qualification\":{\"category\":\"Graduation\",\"input\":\"Post Graduation\",\"inserted_at\":\"2023-10-20T09:08:47.861303Z\",\"intent\":null,\"interactive\":{\"description\":\"\",\"id\":\"\",\"postbackText\":\"\",\"reply\":\"Post Graduation 1\",\"title\":\"Post Graduation\"}},\"avni_last_name\":{\"category\":\"^[A-Za-z ]+$\",\"input\":\"Singh\",\"inserted_at\":\"2023-10-20T09:06:41.676437Z\",\"intent\":null},\"avni_optin\":{\"category\":\"Yes\",\"input\":\"yes\",\"inserted_at\":\"2023-10-20T09:06:23.045052Z\",\"intent\":null},\"avni_qualification_status\":{\"category\":\"Result\",\"input\":\"Result Awaited\",\"inserted_at\":\"2023-10-20T09:09:10.078292Z\",\"intent\":null,\"interactive\":{\"description\":\"\",\"id\":\"\",\"postbackText\":\"\",\"reply\":\"Result Awaited 1\",\"title\":\"Result Awaited\"}},\"avni_school_name\":{\"category\":\"All Responses\",\"input\":\"asdf. asdf.\",\"inserted_at\":\"2023-10-20T09:08:36.995705Z\",\"intent\":null},\"avni_state\":{\"category\":\"Telangana\",\"input\":\"telangana\",\"inserted_at\":\"2023-10-20T09:08:15.943382Z\",\"intent\":null},\"avni_vocational\":{\"category\":\"Non-Vocational\",\"input\":\"non-vocational\",\"inserted_at\":\"2023-10-20T09:09:19.441700Z\",\"intent\":null},\"child\":{\"Language\":{\"category\":\"English\",\"input\":\"english\",\"inserted_at\":\"2023-10-20T09:06:14.078443Z\",\"intent\":null}},\"flow_keyword\":{\"category\":\"Register me\",\"input\":\"registerme\",\"inserted_at\":\"2023-10-20T09:05:56.385111Z\"}}" +} diff --git a/util/src/main/java/org/avni_integration_service/util/ObjectJsonMapper.java b/util/src/main/java/org/avni_integration_service/util/ObjectJsonMapper.java index 99e3d041..b571fb5c 100644 --- a/util/src/main/java/org/avni_integration_service/util/ObjectJsonMapper.java +++ b/util/src/main/java/org/avni_integration_service/util/ObjectJsonMapper.java @@ -7,6 +7,8 @@ import java.io.File; import java.io.IOException; +import java.io.InputStream; +import java.util.Map; public class ObjectJsonMapper { private static final Logger logger = Logger.getLogger(ObjectJsonMapper.class); @@ -45,4 +47,12 @@ public static T readValue(String json, TypeReference typeReference) { throw new RuntimeException(e); } } + + public static T readValue(InputStream stream, Class typeReference) { + try { + return (T) objectMapper.readValue(stream, typeReference); + } catch (Exception e) { + throw new RuntimeException(e); + } + } }