diff --git a/NOTICE b/NOTICE index 198982354c3ca938405fdba0d7bf311b2209d23b..fea0d6963433213ad11768617a23cffe3f54bb35 100644 --- a/NOTICE +++ b/NOTICE @@ -368,6 +368,7 @@ The following software have components provided under the terms of this license: - Asynchronous Http Client Netty Utils (from https://repo1.maven.org/maven2/org/asynchttpclient/async-http-client-netty-utils) - AutoValue Annotations (from https://github.com/google/auto/tree/master/value, https://repo1.maven.org/maven2/com/google/auto/value/auto-value-annotations) - BSON (from http://bsonspec.org, https://bsonspec.org) +- BSON Record Codec (from https://www.mongodb.com/) - Bean Validation API (from http://beanvalidation.org) - Brave (from https://repo1.maven.org/maven2/io/zipkin/brave/brave) - Brave Instrumentation: Http Adapters (from https://repo1.maven.org/maven2/io/zipkin/brave/brave-instrumentation-http) @@ -466,6 +467,7 @@ The following software have components provided under the terms of this license: - Jakarta RESTful WS API (from https://github.com/eclipse-ee4j/jaxrs-api) - Jakarta Servlet (from https://javaee.github.io/servlet-spec/, https://projects.eclipse.org/projects/ee4j.servlet) - Jakarta XML Binding API (from https://repo1.maven.org/maven2/jakarta/xml/bind/jakarta.xml.bind-api, https://repo1.maven.org/maven2/org/jboss/spec/javax/xml/bind/jboss-jaxb-api_2.3_spec) +- Java Architecture for XML Binding (from http://jaxb.java.net/, https://repo1.maven.org/maven2/javax/xml/bind/jaxb-api) - Java Libraries for Amazon Simple WorkFlow (from https://github.com/aws/aws-swf-flow-library) - Java Native Access (from https://github.com/java-native-access/jna, https://github.com/twall/jna, https://repo1.maven.org/maven2/net/java/dev/jna/jna) - Java Native Access Platform (from https://github.com/java-native-access/jna) @@ -484,6 +486,8 @@ The following software have components provided under the terms of this license: - KeePassJava2 :: Simple (from https://repo1.maven.org/maven2/org/linguafranca/pwdb/KeePassJava2-simple) - Kotlin Stdlib (from https://kotlinlang.org/, https://repo1.maven.org/maven2/org/jetbrains/kotlin/kotlin-stdlib) - Kotlin Stdlib Common (from https://kotlinlang.org/) +- Kotlin Stdlib Jdk7 (from https://kotlinlang.org/) +- Kotlin Stdlib Jdk8 (from https://kotlinlang.org/) - Lang (from https://repo1.maven.org/maven2/commons-lang/commons-lang) - LatencyUtils (from http://latencyutils.github.io/LatencyUtils/) - Lucene Common Analyzers (from https://repo1.maven.org/maven2/org/apache/lucene/lucene-analyzers-common) @@ -560,6 +564,9 @@ The following software have components provided under the terms of this license: - PowerMock (from http://www.powermock.org, https://repo1.maven.org/maven2/org/powermock/powermock-api-mockito) - Prometheus Java Simpleclient (from https://repo1.maven.org/maven2/io/prometheus/simpleclient) - Prometheus Java Simpleclient Common (from https://repo1.maven.org/maven2/io/prometheus/simpleclient_common) +- Prometheus Java Span Context Supplier - Common (from https://repo1.maven.org/maven2/io/prometheus/simpleclient_tracer_common) +- Prometheus Java Span Context Supplier - OpenTelemetry (from https://repo1.maven.org/maven2/io/prometheus/simpleclient_tracer_otel) +- Prometheus Java Span Context Supplier - OpenTelemetry Agent (from https://repo1.maven.org/maven2/io/prometheus/simpleclient_tracer_otel_agent) - Protocol Buffer Java API (from http://code.google.com/p/protobuf, https://repo1.maven.org/maven2/com/google/protobuf/protobuf-java) - Protocol Buffer extensions to the Google HTTP Client Library for Java. (from https://repo1.maven.org/maven2/com/google/http-client/google-http-client-protobuf) - Proton-J (from https://repo1.maven.org/maven2/org/apache/qpid/proton-j) @@ -623,6 +630,7 @@ The following software have components provided under the terms of this license: - Spring Web (from http://www.springframework.org, https://github.com/spring-projects/spring-framework, https://repo1.maven.org/maven2/org/springframework/spring-web) - Spring Web MVC (from https://github.com/spring-projects/spring-framework, https://repo1.maven.org/maven2/org/springframework/spring-webmvc) - Spring WebFlux (from https://github.com/spring-projects/spring-framework) +- Swagger UI (from http://webjars.org) - Vavr (from http://vavr.io, https://www.vavr.io) - Vavr Match (from http://vavr.io) - Woodstox (from https://github.com/FasterXML/woodstox) @@ -694,30 +702,22 @@ The following software have components provided under the terms of this license: - resilience4j (from https://github.com/resilience4j/resilience4j, https://resilience4j.readme.io, ttps://resilience4j.readme.io) - rest (from https://github.com/elastic/elasticsearch) - rest-high-level (from https://github.com/elastic/elasticsearch) +- spring-security-crypto (from http://spring.io/spring-security, https://spring.io/projects/spring-security, https://spring.io/spring-security) - spring-security-oauth2-client (from http://spring.io/spring-security, https://spring.io/projects/spring-security, https://spring.io/spring-security) - spring-security-oauth2-core (from http://spring.io/spring-security, https://spring.io/projects/spring-security, https://spring.io/spring-security) - spring-security-oauth2-jose (from http://spring.io/spring-security, https://spring.io/projects/spring-security, https://spring.io/spring-security) - spring-security-test (from http://spring.io/spring-security, https://spring.io/projects/spring-security, https://spring.io/spring-security) -- springfox-bean-validators (from https://github.com/springfox/springfox) -- springfox-boot-starter (from https://github.com/springfox/springfox) -- springfox-core (from https://github.com/springfox/springfox) -- springfox-data-rest (from https://github.com/springfox/springfox) -- springfox-oas (from https://github.com/springfox/springfox) -- springfox-schema (from https://github.com/springfox/springfox) -- springfox-spi (from https://github.com/springfox/springfox) -- springfox-spring-web (from https://github.com/springfox/springfox) -- springfox-spring-webflux (from https://github.com/springfox/springfox) -- springfox-spring-webmvc (from https://github.com/springfox/springfox) -- springfox-swagger-common (from https://github.com/springfox/springfox) -- springfox-swagger-ui (from https://github.com/springfox/springfox) -- springfox-swagger2 (from https://github.com/springfox/springfox) +- springdoc-openapi-common (from https://repo1.maven.org/maven2/org/springdoc/springdoc-openapi-common) +- springdoc-openapi-ui (from https://github.com/springdoc/springdoc-openapi, https://repo1.maven.org/maven2/org/springdoc/springdoc-openapi-ui) +- springdoc-openapi-webmvc-core (from https://repo1.maven.org/maven2/org/springdoc/springdoc-openapi-webmvc-core) - swagger-annotations (from https://repo1.maven.org/maven2/io/swagger/core/v3/swagger-annotations, https://repo1.maven.org/maven2/io/swagger/swagger-annotations) -- swagger-core (from https://repo1.maven.org/maven2/io/swagger/swagger-core) +- swagger-core (from https://repo1.maven.org/maven2/io/swagger/core/v3/swagger-core, https://repo1.maven.org/maven2/io/swagger/swagger-core) - swagger-jaxrs (from https://repo1.maven.org/maven2/io/swagger/swagger-jaxrs) -- swagger-models (from https://repo1.maven.org/maven2/io/swagger/core/v3/swagger-models) +- swagger-models (from https://repo1.maven.org/maven2/io/swagger/core/v3/swagger-models, https://repo1.maven.org/maven2/io/swagger/swagger-models) - t-digest (from https://github.com/tdunning/t-digest) - tomcat-annotations-api (from http://tomcat.apache.org/, https://tomcat.apache.org/) - tomcat-embed-core (from http://tomcat.apache.org/) +- tomcat-embed-el (from http://tomcat.apache.org/, https://tomcat.apache.org/) - tomcat-embed-websocket (from http://tomcat.apache.org/, https://tomcat.apache.org/) - xml-apis (from https://repo1.maven.org/maven2/xml-apis/xml-apis) @@ -823,6 +823,7 @@ The following software have components provided under the terms of this license: - jakarta.inject (from https://repo1.maven.org/maven2/org/glassfish/hk2/external/jakarta.inject) - jaxen (from http://jaxen.codehaus.org/, http://www.cafeconleche.org/jaxen, https://repo1.maven.org/maven2/jaxen/jaxen) - jersey-container-servlet (from https://repo1.maven.org/maven2/org/glassfish/jersey/containers/jersey-container-servlet) +- jersey-core-client (from https://repo1.maven.org/maven2/org/glassfish/jersey/core/jersey-client) - jersey-core-common (from https://repo1.maven.org/maven2/org/glassfish/jersey/core/jersey-common) - jersey-core-server (from https://repo1.maven.org/maven2/org/glassfish/jersey/core/jersey-server) - jersey-ext-bean-validation (from https://repo1.maven.org/maven2/org/glassfish/jersey/ext/jersey-bean-validation) @@ -898,6 +899,7 @@ The following software have components provided under the terms of this license: - Apache Log4j Core (from https://repo1.maven.org/maven2/org/apache/logging/log4j/log4j-core) - Jakarta Activation API (from https://github.com/eclipse-ee4j/jaf, https://repo1.maven.org/maven2/jakarta/activation/jakarta.activation-api) - Jakarta Servlet (from https://javaee.github.io/servlet-spec/, https://projects.eclipse.org/projects/ee4j.servlet) +- Java Architecture for XML Binding (from http://jaxb.java.net/, https://repo1.maven.org/maven2/javax/xml/bind/jaxb-api) - JavaBeans Activation Framework (from https://repo1.maven.org/maven2/com/sun/activation/javax.activation) - JavaBeans(TM) Activation Framework (from http://java.sun.com/javase/technologies/desktop/javabeans/jaf/index.jsp) - Servlet Specification 2.5 API (from http://jetty.mortbay.org, https://repo1.maven.org/maven2/org/mortbay/jetty/servlet-api-2.5) @@ -1101,6 +1103,7 @@ The following software have components provided under the terms of this license: - Expression Language 3.0 (from http://el-spec.java.net, http://uel.java.net, https://projects.eclipse.org/projects/ee4j.el) - Jakarta Annotations API (from https://projects.eclipse.org/projects/ee4j.ca) +- Java Architecture for XML Binding (from http://jaxb.java.net/, https://repo1.maven.org/maven2/javax/xml/bind/jaxb-api) - OSGi resource locator (from https://repo1.maven.org/maven2/org/glassfish/hk2/osgi-resource-locator) - Project Lombok (from http://projectlombok.org, https://projectlombok.org) - javax.ws.rs-api (from https://github.com/eclipse-ee4j/jaxrs-api) @@ -1128,6 +1131,7 @@ The following software have components provided under the terms of this license: - Java Native Access Platform (from https://github.com/java-native-access/jna) - Spring Security - Core (from http://spring.io/spring-security, https://repo1.maven.org/maven2/org/springframework/security/spring-security-core, https://spring.io/projects/spring-security, https://spring.io/spring-security) +- spring-security-crypto (from http://spring.io/spring-security, https://spring.io/projects/spring-security, https://spring.io/spring-security) ======================================================================== ImageMagick @@ -1189,6 +1193,10 @@ The following software have components provided under the terms of this license: ======================================================================== LGPL-3.0-only ======================================================================== +The following software have components provided under the terms of this license: + +- Logback Classic Module (from http://logback.qos.ch, https://repo1.maven.org/maven2/ch/qos/logback/logback-classic) +- Logback Core Module (from http://logback.qos.ch, https://repo1.maven.org/maven2/ch/qos/logback/logback-core) - RabbitMQ Java Client (from http://www.rabbitmq.com, https://www.rabbitmq.com) ======================================================================== @@ -1280,6 +1288,7 @@ The following software have components provided under the terms of this license: - msal4j (from https://github.com/AzureAD/microsoft-authentication-library-for-java) - msal4j-persistence-extension (from https://github.com/AzureAD/microsoft-authentication-extensions-for-java) - qpid-proton-j-extensions (from https://github.com/Azure/qpid-proton-j-extensions) +- webjars-locator-core (from http://webjars.org) ======================================================================== MPL-1.1 @@ -1410,6 +1419,7 @@ The following software have components provided under the terms of this license: - Bouncy Castle Provider (from http://www.bouncycastle.org/java.html, https://www.bouncycastle.org/java.html) - Guava: Google Core Libraries for Java (from http://code.google.com/p/guava-libraries, https://github.com/google/guava, https://repo1.maven.org/maven2/com/google/guava/guava) - HdrHistogram (from http://hdrhistogram.github.io/HdrHistogram/) +- JBoss Logging 3 (from http://www.jboss.org) - JTidy (from http://jtidy.sourceforge.net) - LatencyUtils (from http://latencyutils.github.io/LatencyUtils/) - PostgreSQL JDBC Driver diff --git a/devops/aws/chart/Chart.yaml b/devops/aws/chart/Chart.yaml index 8205906f52b05d09d671c7543cedcb99037c5889..5fbb0d73c247f5b40dd93de2d44f5f67c744a97e 100644 --- a/devops/aws/chart/Chart.yaml +++ b/devops/aws/chart/Chart.yaml @@ -1,6 +1,6 @@ apiVersion: v2 name: "os-indexer" -version: +version: __CHART_VERSION__ kubeVersion: "v1.21.x-x-x" description: Indexer Helm Chart for Kubernetes type: application diff --git a/devops/aws/chart/values.yaml b/devops/aws/chart/values.yaml index 6085b61d6a55b72dc027fb7e21a3b2592714dd14..fddd17ff15b32642c3ce0f97335752cd0dd6a73d 100644 --- a/devops/aws/chart/values.yaml +++ b/devops/aws/chart/values.yaml @@ -82,7 +82,7 @@ autoscaling: # targetMemoryUtilizationPercentage: 80 # Security Config -serviceAccountRole: arn:aws:iam::{{ .Values.global.accountID }}:role/{{ .Values.global.resourcePrefix }}-{{ include "common.name" . }} +serviceAccountRole: arn:aws:iam::{{ .Values.global.accountID }}:role/osdu-{{ .Values.global.resourcePrefix }}-{{ .Values.global.region }}-{{ include "common.name" . }} securityContext: {} # capabilities: # drop: diff --git a/indexer-core/src/main/java/org/opengroup/osdu/indexer/api/CleanupIndiciesApi.java b/indexer-core/src/main/java/org/opengroup/osdu/indexer/api/CleanupIndiciesApi.java index 518f877ad3f21b08dda6c3e6af5b38597b8cf80e..a1f427d8e0396531d964437cadcf48654afe2c5b 100644 --- a/indexer-core/src/main/java/org/opengroup/osdu/indexer/api/CleanupIndiciesApi.java +++ b/indexer-core/src/main/java/org/opengroup/osdu/indexer/api/CleanupIndiciesApi.java @@ -24,6 +24,8 @@ import javax.inject.Inject; import javax.validation.Valid; import javax.validation.constraints.NotBlank; import javax.validation.constraints.NotNull; + +import io.swagger.v3.oas.annotations.Operation; import lombok.extern.java.Log; import org.opengroup.osdu.core.common.model.http.AppException; import org.opengroup.osdu.core.common.model.http.DpsHeaders; @@ -47,7 +49,6 @@ import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; import org.springframework.web.context.annotation.RequestScope; -import springfox.documentation.annotations.ApiIgnore; import static java.util.Collections.singletonList; @Log @@ -69,7 +70,7 @@ public class CleanupIndiciesApi { private static final String ENTITLEMENT_GROUP = "users.datalake.ops"; - @ApiIgnore + @Operation(hidden = true) @PostMapping(path = "/index-cleanup", consumes = "application/json") @PreAuthorize("@authorizationFilter.hasPermission('" + SearchServiceRole.ADMIN + "')") public ResponseEntity cleanupIndices(@NotNull(message = SwaggerDoc.REQUEST_VALIDATION_NOT_NULL_BODY) diff --git a/indexer-core/src/main/java/org/opengroup/osdu/indexer/api/RecordIndexerApi.java b/indexer-core/src/main/java/org/opengroup/osdu/indexer/api/RecordIndexerApi.java index 4cb1ef2386d18e5b188cedbbcf5e1cb79bcb44b5..6f38cd0644e62c2ade527f2a69d79ede2c2181e6 100644 --- a/indexer-core/src/main/java/org/opengroup/osdu/indexer/api/RecordIndexerApi.java +++ b/indexer-core/src/main/java/org/opengroup/osdu/indexer/api/RecordIndexerApi.java @@ -18,7 +18,7 @@ import com.google.common.reflect.TypeToken; import com.google.gson.Gson; import com.google.gson.JsonParseException; -import io.swagger.annotations.ApiOperation; +import io.swagger.v3.oas.annotations.Operation; import lombok.extern.java.Log; import org.opengroup.osdu.core.common.model.http.DpsHeaders; import org.opengroup.osdu.core.common.model.http.AppException; @@ -31,6 +31,7 @@ import org.opengroup.osdu.core.common.model.search.RecordChangedMessages; import org.opengroup.osdu.indexer.SwaggerDoc; import org.opengroup.osdu.indexer.service.IndexerService; import org.opengroup.osdu.indexer.service.ReindexService; +import org.opengroup.osdu.indexer.service.SchemaEventsProcessor; import org.opengroup.osdu.indexer.service.SchemaService; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; @@ -56,11 +57,13 @@ public class RecordIndexerApi { private ReindexService reIndexService; @Inject private SchemaService schemaService; + @Inject + private SchemaEventsProcessor eventsProcessingService; // THIS IS AN INTERNAL USE API ONLY // THAT MEANS WE DON'T DOCUMENT IT IN SWAGGER, ACCESS IS LIMITED TO CLOUD TASK QUEUE CALLS ONLY @PostMapping(path = "/index-worker", consumes = "application/json") - @ApiOperation(hidden = true, value = "", notes = "") + @Operation(hidden = true, summary = "", description = "") public ResponseEntity<JobStatus> indexWorker ( @NotNull(message = SwaggerDoc.REQUEST_VALIDATION_NOT_NULL_BODY) @Valid @RequestBody RecordChangedMessages recordChangedMessages) throws Exception { @@ -96,7 +99,7 @@ public class RecordIndexerApi { // THIS IS AN INTERNAL USE API ONLY // THAT MEANS WE DON'T DOCUMENT IT IN SWAGGER, ACCESS IS LIMITED TO CLOUD TASK QUEUE CALLS ONLY @PostMapping("/reindex-worker") - @ApiOperation(hidden = true, value = "", notes = "") + @Operation(hidden = true, summary = "", description = "") public ResponseEntity<?> reindex( @RequestBody @NotNull(message = SwaggerDoc.REQUEST_VALIDATION_NOT_NULL_BODY) @Valid RecordReindexRequest recordReindexRequest) { @@ -106,7 +109,7 @@ public class RecordIndexerApi { // THIS IS AN INTERNAL USE API ONLY // THAT MEANS WE DON'T DOCUMENT IT IN SWAGGER, ACCESS IS LIMITED TO CLOUD TASK QUEUE CALLS ONLY @PostMapping("/schema-worker") - @ApiOperation(hidden = true, value = "", notes = "") + @Operation(hidden = true, summary = "", description = "") public ResponseEntity<?> schemaWorker( @NotNull(message = SwaggerDoc.REQUEST_VALIDATION_NOT_NULL_BODY) @Valid @RequestBody SchemaChangedMessages schemaChangedMessage) throws IOException { @@ -127,7 +130,7 @@ public class RecordIndexerApi { log.warning("none of schema-change message can be deserialized"); return new ResponseEntity(org.springframework.http.HttpStatus.OK); } - this.schemaService.processSchemaMessages(schemaInfos); + this.eventsProcessingService.processSchemaMessages(schemaInfos); return new ResponseEntity(HttpStatus.OK); } catch (JsonParseException e) { throw new AppException(org.apache.http.HttpStatus.SC_BAD_REQUEST, "Request payload parsing error", "Unable to parse request payload.", e); diff --git a/indexer-core/src/main/java/org/opengroup/osdu/indexer/service/IndexerMappingServiceImpl.java b/indexer-core/src/main/java/org/opengroup/osdu/indexer/service/IndexerMappingServiceImpl.java index 2cf24b15feef30ee36288dd09e18c93cb4bb2841..c77f4af7802cf34a347a306cda283d5e97eba15f 100644 --- a/indexer-core/src/main/java/org/opengroup/osdu/indexer/service/IndexerMappingServiceImpl.java +++ b/indexer-core/src/main/java/org/opengroup/osdu/indexer/service/IndexerMappingServiceImpl.java @@ -53,6 +53,8 @@ import java.util.*; @Service public class IndexerMappingServiceImpl extends MappingServiceImpl implements IMappingService { + private static TimeValue REQUEST_TIMEOUT = TimeValue.timeValueMinutes(1); + @Inject private JaxRsDpsLog log; @Inject @@ -60,11 +62,8 @@ public class IndexerMappingServiceImpl extends MappingServiceImpl implements IMa @Autowired private PartitionSafeIndexCache indexCache; @Autowired - private IMappingService mappingService; - @Autowired private ElasticIndexNameResolver elasticIndexNameResolver; - private static TimeValue REQUEST_TIMEOUT = TimeValue.timeValueMinutes(1); /** @@ -180,14 +179,14 @@ public class IndexerMappingServiceImpl extends MappingServiceImpl implements IMa final String cacheKey = String.format("metaAttributeMappingSynced-%s", index); try { - Boolean mappingSynced = (Boolean) this.indexCache.get(cacheKey); + Boolean mappingSynced = this.indexCache.get(cacheKey); if (mappingSynced != null && mappingSynced) return; } catch (RedisException ex) { //In case the format of cache changes then clean the cache this.indexCache.delete(cacheKey); } - String jsonResponse = this.mappingService.getIndexMapping(restClient, index); + String jsonResponse = this.getIndexMapping(restClient, index); Type type = new TypeToken<Map<String, Object>>() {}.getType(); Map<String, Object> mappings = new Gson().fromJson(jsonResponse, type); diff --git a/indexer-core/src/main/java/org/opengroup/osdu/indexer/service/SchemaEventsProcessor.java b/indexer-core/src/main/java/org/opengroup/osdu/indexer/service/SchemaEventsProcessor.java new file mode 100644 index 0000000000000000000000000000000000000000..3312c81768c535201fb58b744c2c556219ebf075 --- /dev/null +++ b/indexer-core/src/main/java/org/opengroup/osdu/indexer/service/SchemaEventsProcessor.java @@ -0,0 +1,31 @@ +/* + * Copyright 2020-2022 Google LLC + * Copyright 2020-2022 EPAM Systems, Inc + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.opengroup.osdu.indexer.service; + +import java.io.IOException; +import java.util.List; +import org.opengroup.osdu.core.common.model.indexer.SchemaInfo; + +public interface SchemaEventsProcessor { + + /** + * @param schemaInfos schema change event + * @throws IOException + */ + void processSchemaMessages(List<SchemaInfo> schemaInfos) throws IOException; +} diff --git a/indexer-core/src/main/java/org/opengroup/osdu/indexer/service/SchemaEventsProcessorImpl.java b/indexer-core/src/main/java/org/opengroup/osdu/indexer/service/SchemaEventsProcessorImpl.java new file mode 100644 index 0000000000000000000000000000000000000000..44bf856cb0f415d42975bc6067946f8751daafcd --- /dev/null +++ b/indexer-core/src/main/java/org/opengroup/osdu/indexer/service/SchemaEventsProcessorImpl.java @@ -0,0 +1,85 @@ +/* + * Copyright 2020-2022 Google LLC + * Copyright 2020-2022 EPAM Systems, Inc + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.opengroup.osdu.indexer.service; + +import static java.util.Collections.singletonList; + +import java.io.IOException; +import java.net.URISyntaxException; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import javax.inject.Inject; +import org.apache.http.HttpStatus; +import org.elasticsearch.ElasticsearchStatusException; +import org.elasticsearch.client.RestHighLevelClient; +import org.opengroup.osdu.core.common.model.http.AppException; +import org.opengroup.osdu.core.common.model.indexer.SchemaInfo; +import org.opengroup.osdu.core.common.model.indexer.SchemaOperationType; +import org.opengroup.osdu.indexer.config.SchemaEventsListenerConfiguration; +import org.opengroup.osdu.indexer.logging.AuditLogger; +import org.opengroup.osdu.indexer.util.ElasticClientHandler; +import org.springframework.stereotype.Component; + +@Component +public class SchemaEventsProcessorImpl implements SchemaEventsProcessor { + + @Inject + private SchemaEventsListenerConfiguration schemaEventsListenerConfiguration; + @Inject + private ElasticClientHandler elasticClientHandler; + @Inject + private IndexSchemaService indexSchemaService; + @Inject + private AuditLogger auditLogger; + + @Override + public void processSchemaMessages(List<SchemaInfo> schemaInfos) throws IOException { + Map<String, SchemaOperationType> messages = new HashMap<>(); + + if (schemaEventsListenerConfiguration.isListenCreateEvent()) { + Map<String, SchemaOperationType> createSchemaMessages = SchemaInfo.getCreateSchemaEvents(schemaInfos); + if (!createSchemaMessages.isEmpty()) { + messages.putAll(createSchemaMessages); + } + } + + if (schemaEventsListenerConfiguration.isListenUpdateEvent()) { + Map<String, SchemaOperationType> updateSchemaMessages = SchemaInfo.getUpdateSchemaEvents(schemaInfos); + if (!updateSchemaMessages.isEmpty()) { + messages.putAll(updateSchemaMessages); + } + } + + if (messages.isEmpty()) { + return; + } + + try (RestHighLevelClient restClient = this.elasticClientHandler.createRestClient()) { + messages.forEach((key, value) -> { + try { + this.indexSchemaService.processSchemaUpsertEvent(restClient, key); + this.auditLogger.indexMappingUpsertSuccess(singletonList(key)); + } catch (IOException | ElasticsearchStatusException | URISyntaxException e) { + this.auditLogger.indexMappingUpsertFail(singletonList(key)); + throw new AppException(HttpStatus.SC_INTERNAL_SERVER_ERROR, "unable to process schema upsert event", e.getMessage(), e); + } + }); + } + } +} diff --git a/indexer-core/src/main/java/org/opengroup/osdu/indexer/service/SchemaProviderImpl.java b/indexer-core/src/main/java/org/opengroup/osdu/indexer/service/SchemaProviderImpl.java index c82d538a234ae20cbc41f166ec36e08749891da0..51770155425ab393c603a08f0f40c0798beefe82 100644 --- a/indexer-core/src/main/java/org/opengroup/osdu/indexer/service/SchemaProviderImpl.java +++ b/indexer-core/src/main/java/org/opengroup/osdu/indexer/service/SchemaProviderImpl.java @@ -15,35 +15,23 @@ package org.opengroup.osdu.indexer.service; import com.google.api.client.http.HttpMethods; -import com.google.gson.Gson; +import java.io.UnsupportedEncodingException; +import java.net.URISyntaxException; +import java.net.URLEncoder; +import java.nio.charset.StandardCharsets; +import java.util.Objects; +import javax.inject.Inject; import org.apache.http.HttpStatus; -import org.elasticsearch.ElasticsearchStatusException; -import org.elasticsearch.client.RestHighLevelClient; import org.opengroup.osdu.core.common.http.FetchServiceHttpRequest; import org.opengroup.osdu.core.common.http.IUrlFetchService; import org.opengroup.osdu.core.common.logging.JaxRsDpsLog; -import org.opengroup.osdu.core.common.model.http.AppException; import org.opengroup.osdu.core.common.model.http.HttpResponse; -import org.opengroup.osdu.core.common.model.indexer.SchemaInfo; -import org.opengroup.osdu.core.common.model.indexer.SchemaOperationType; import org.opengroup.osdu.core.common.provider.interfaces.IRequestInfo; import org.opengroup.osdu.indexer.config.IndexerConfigurationProperties; -import org.opengroup.osdu.indexer.config.SchemaEventsListenerConfiguration; import org.opengroup.osdu.indexer.logging.AuditLogger; import org.opengroup.osdu.indexer.schema.converter.interfaces.SchemaToStorageFormat; -import org.opengroup.osdu.indexer.util.ElasticClientHandler; import org.springframework.stereotype.Component; -import javax.inject.Inject; -import java.io.IOException; -import java.io.UnsupportedEncodingException; -import java.net.URISyntaxException; -import java.net.URLEncoder; -import java.nio.charset.StandardCharsets; -import java.util.*; - -import static java.util.Collections.singletonList; - /** * Provides implementation of the client service that retrieves schemas from the Schema Service */ @@ -68,58 +56,15 @@ public class SchemaProviderImpl implements SchemaService { @Inject private StorageService storageService; - @Inject - private IndexSchemaService indexSchemaService; - - @Inject - private ElasticClientHandler elasticClientHandler; - @Inject private AuditLogger auditLogger; - @Inject - private SchemaEventsListenerConfiguration schemaEventsListenerConfiguration; - - @Override public String getSchema(String kind) throws URISyntaxException, UnsupportedEncodingException { String schemaServiceSchema = getFromSchemaService(kind); return Objects.nonNull(schemaServiceSchema) ? schemaServiceSchema : getFromStorageService(kind); } - @Override - public void processSchemaMessages(List<SchemaInfo> schemaInfos) throws IOException { - Map<String, SchemaOperationType> messages = new HashMap<>(); - - if (schemaEventsListenerConfiguration.isListenCreateEvent()) { - Map<String, SchemaOperationType> createSchemaMessages = SchemaInfo.getCreateSchemaEvents(schemaInfos); - if (createSchemaMessages != null && !createSchemaMessages.isEmpty()) { - messages.putAll(createSchemaMessages); - } - } - - if (schemaEventsListenerConfiguration.isListenUpdateEvent()) { - Map<String, SchemaOperationType> updateSchemaMessages = SchemaInfo.getUpdateSchemaEvents(schemaInfos); - if (updateSchemaMessages != null && !updateSchemaMessages.isEmpty()) { - messages.putAll(updateSchemaMessages); - } - } - - if (messages.isEmpty()) return; - - try (RestHighLevelClient restClient = this.elasticClientHandler.createRestClient()) { - messages.entrySet().forEach(msg -> { - try { - this.indexSchemaService.processSchemaUpsertEvent(restClient, msg.getKey()); - this.auditLogger.indexMappingUpsertSuccess(singletonList(msg.getKey())); - } catch (IOException | ElasticsearchStatusException | URISyntaxException e) { - this.auditLogger.indexMappingUpsertFail(singletonList(msg.getKey())); - throw new AppException(HttpStatus.SC_INTERNAL_SERVER_ERROR, "unable to process schema upsert event", e.getMessage()); - } - }); - } - } - protected String getFromSchemaService(String kind) throws UnsupportedEncodingException, URISyntaxException { HttpResponse response = getSchemaServiceResponse(kind); diff --git a/indexer-core/src/main/java/org/opengroup/osdu/indexer/service/SchemaService.java b/indexer-core/src/main/java/org/opengroup/osdu/indexer/service/SchemaService.java index 5e87ca8ddf3f86cc7a8571ab8736720602240af8..cb161958c76d27981321707df057b17c03cf3317 100644 --- a/indexer-core/src/main/java/org/opengroup/osdu/indexer/service/SchemaService.java +++ b/indexer-core/src/main/java/org/opengroup/osdu/indexer/service/SchemaService.java @@ -14,12 +14,8 @@ package org.opengroup.osdu.indexer.service; -import org.opengroup.osdu.core.common.model.indexer.SchemaInfo; - -import java.io.IOException; import java.io.UnsupportedEncodingException; import java.net.URISyntaxException; -import java.util.List; /** * Interface to consume schemas from the Schema Service @@ -34,10 +30,4 @@ public interface SchemaService { */ String getSchema(String kind) throws URISyntaxException, UnsupportedEncodingException; - /** - * - * @param schemaInfos schema change event - * @throws IOException - */ - void processSchemaMessages(List<SchemaInfo> schemaInfos) throws IOException; } diff --git a/indexer-core/src/main/java/org/opengroup/osdu/indexer/swagger/HomeController.java b/indexer-core/src/main/java/org/opengroup/osdu/indexer/swagger/HomeController.java index 9638ba469d37d45fa83d27b614e4743f975daae6..b3ab482f149f66ca89fa993ad858d4c364ce508e 100644 --- a/indexer-core/src/main/java/org/opengroup/osdu/indexer/swagger/HomeController.java +++ b/indexer-core/src/main/java/org/opengroup/osdu/indexer/swagger/HomeController.java @@ -7,6 +7,6 @@ import org.springframework.web.bind.annotation.RequestMapping; public class HomeController { @RequestMapping(value = "/swagger") public String swagger() { - return "redirect:swagger-ui/index.html"; + return "redirect:swagger-ui.html"; } } diff --git a/indexer-core/src/main/java/org/opengroup/osdu/indexer/swagger/SpringfoxSwaggerHostResolver.java b/indexer-core/src/main/java/org/opengroup/osdu/indexer/swagger/SpringfoxSwaggerHostResolver.java deleted file mode 100644 index ba3701ff9f9710030c27805d69d8c6f825da9e01..0000000000000000000000000000000000000000 --- a/indexer-core/src/main/java/org/opengroup/osdu/indexer/swagger/SpringfoxSwaggerHostResolver.java +++ /dev/null @@ -1,35 +0,0 @@ -package org.opengroup.osdu.indexer.swagger; - -import io.swagger.v3.oas.models.OpenAPI; -import io.swagger.v3.oas.models.servers.Server; -import org.springframework.core.Ordered; -import org.springframework.core.annotation.Order; -import org.springframework.stereotype.Component; -import springfox.documentation.oas.web.OpenApiTransformationContext; -import springfox.documentation.oas.web.WebMvcOpenApiTransformationFilter; -import springfox.documentation.spi.DocumentationType; - -import javax.servlet.http.HttpServletRequest; - -@Component -@Order(Ordered.LOWEST_PRECEDENCE) -public class SpringfoxSwaggerHostResolver implements WebMvcOpenApiTransformationFilter { - - @Override - public boolean supports(DocumentationType delimiter) { - return delimiter == DocumentationType.OAS_30; - } - - @Override - public OpenAPI transform(OpenApiTransformationContext<HttpServletRequest> context) { - OpenAPI swagger = context.getSpecification(); - - Server server = swagger.getServers().get(0); - if (server.getUrl().contains(":443")) { - // via the gateway - server.setUrl(server.getUrl().replace(":443", "")); - } - - return swagger; - } -} \ No newline at end of file diff --git a/indexer-core/src/main/java/org/opengroup/osdu/indexer/swagger/SwaggerConfiguration.java b/indexer-core/src/main/java/org/opengroup/osdu/indexer/swagger/SwaggerConfiguration.java new file mode 100644 index 0000000000000000000000000000000000000000..f40606837a5b52a489ba3de99cdcf8ba07f348bd --- /dev/null +++ b/indexer-core/src/main/java/org/opengroup/osdu/indexer/swagger/SwaggerConfiguration.java @@ -0,0 +1,53 @@ +package org.opengroup.osdu.indexer.swagger; + +import io.swagger.v3.oas.models.servers.Server; +import org.springframework.context.annotation.Configuration; +import io.swagger.v3.oas.models.Components; +import io.swagger.v3.oas.models.OpenAPI; +import io.swagger.v3.oas.models.info.Info; +import io.swagger.v3.oas.models.parameters.Parameter; +import io.swagger.v3.oas.models.security.SecurityRequirement; +import io.swagger.v3.oas.models.security.SecurityScheme; +import org.opengroup.osdu.core.common.model.http.DpsHeaders; +import org.springdoc.core.customizers.OperationCustomizer; +import org.springframework.context.annotation.Bean; + +import javax.servlet.ServletContext; +import java.util.Collections; + +@Configuration +public class SwaggerConfiguration { + + @Bean + public OpenAPI openApi(ServletContext servletContext) { + Server server = new Server().url(servletContext.getContextPath()); + return new OpenAPI() + .servers(Collections.singletonList(server)) + .info(new Info() + .description("Indexer service that provides a set of APIs " + + "to index storage records against Elasticsearch") + .title("Indexer Service") + .version("1.0")) + .components(new Components() + .addSecuritySchemes("Authorization", + new SecurityScheme() + .type(SecurityScheme.Type.HTTP) + .scheme("bearer") + .bearerFormat("Authorization") + .in(SecurityScheme.In.HEADER) + .name("Authorization"))) + .addSecurityItem( + new SecurityRequirement() + .addList("Authorization")); + } + + @Bean + public OperationCustomizer customize() { + return (operation, handlerMethod) -> operation.addParametersItem( + new Parameter() + .in("header") + .required(true) + .description("Tenant Id") + .name(DpsHeaders.DATA_PARTITION_ID)); + } +} diff --git a/indexer-core/src/main/java/org/opengroup/osdu/indexer/swagger/SwaggerDocumentationConfig.java b/indexer-core/src/main/java/org/opengroup/osdu/indexer/swagger/SwaggerDocumentationConfig.java deleted file mode 100644 index 1581a366b7392e361ca159b87d9447fe2b61421c..0000000000000000000000000000000000000000 --- a/indexer-core/src/main/java/org/opengroup/osdu/indexer/swagger/SwaggerDocumentationConfig.java +++ /dev/null @@ -1,65 +0,0 @@ -package org.opengroup.osdu.indexer.swagger; - -import org.opengroup.osdu.core.common.model.http.DpsHeaders; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import springfox.documentation.builders.PathSelectors; -import springfox.documentation.builders.RequestHandlerSelectors; -import springfox.documentation.builders.RequestParameterBuilder; -import springfox.documentation.oas.annotations.EnableOpenApi; -import springfox.documentation.service.ApiKey; -import springfox.documentation.service.AuthorizationScope; -import springfox.documentation.service.ParameterType; -import springfox.documentation.service.RequestParameter; -import springfox.documentation.service.SecurityReference; -import springfox.documentation.spi.DocumentationType; -import springfox.documentation.spi.service.contexts.SecurityContext; -import springfox.documentation.spring.web.plugins.Docket; -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; - -@Configuration -@EnableOpenApi -public class SwaggerDocumentationConfig { - public static final String AUTHORIZATION_HEADER = "Authorization"; - public static final String DEFAULT_INCLUDE_PATTERN = "/.*"; - - @Bean - public Docket api() { - RequestParameterBuilder builder = new RequestParameterBuilder(); - List<RequestParameter> parameters = new ArrayList<>(); - builder.name(DpsHeaders.DATA_PARTITION_ID) - .description("data partition id") - .in(ParameterType.HEADER) - .required(true) - .build(); - parameters.add(builder.build()); - return new Docket(DocumentationType.OAS_30) - .globalRequestParameters(parameters) - .select() - .apis(RequestHandlerSelectors.basePackage("org.opengroup.osdu.indexer.api")) - .build() - .securityContexts(Collections.singletonList(securityContext())) - .securitySchemes(Collections.singletonList(apiKey())); - } - - private ApiKey apiKey() { - return new ApiKey(AUTHORIZATION_HEADER, AUTHORIZATION_HEADER, "header"); - } - - private SecurityContext securityContext() { - return SecurityContext.builder() - .securityReferences(defaultAuth()) - .operationSelector(o -> PathSelectors.regex(DEFAULT_INCLUDE_PATTERN).test(o.requestMappingPattern())) - .build(); - } - List<SecurityReference> defaultAuth() { - AuthorizationScope authorizationScope - = new AuthorizationScope("global", "accessEverything"); - AuthorizationScope[] authorizationScopes = - new AuthorizationScope[]{authorizationScope}; - return Collections.singletonList( - new SecurityReference(AUTHORIZATION_HEADER, authorizationScopes)); - } -} diff --git a/indexer-core/src/test/java/org/opengroup/osdu/indexer/api/RecordIndexerApiTest.java b/indexer-core/src/test/java/org/opengroup/osdu/indexer/api/RecordIndexerApiTest.java index a54d2161f71a06c37c21456ff1af00f3ef6f948b..4c008d8646ded0eaf6d247d7f55d283a2e90d29e 100644 --- a/indexer-core/src/test/java/org/opengroup/osdu/indexer/api/RecordIndexerApiTest.java +++ b/indexer-core/src/test/java/org/opengroup/osdu/indexer/api/RecordIndexerApiTest.java @@ -14,6 +14,10 @@ package org.opengroup.osdu.indexer.api; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.fail; +import static org.mockito.MockitoAnnotations.initMocks; + import com.google.gson.Gson; import org.junit.Before; import org.junit.Test; @@ -27,6 +31,7 @@ import org.opengroup.osdu.core.common.model.http.DpsHeaders; import org.opengroup.osdu.core.common.model.indexer.SchemaChangedMessages; import org.opengroup.osdu.core.common.model.search.RecordChangedMessages; import org.opengroup.osdu.indexer.service.IndexerService; +import org.opengroup.osdu.indexer.service.SchemaEventsProcessor; import org.opengroup.osdu.indexer.service.SchemaService; import org.opengroup.osdu.indexer.util.IndexerQueueTaskBuilder; import org.powermock.core.classloader.annotations.PrepareForTest; @@ -34,10 +39,6 @@ import org.powermock.modules.junit4.PowerMockRunner; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.fail; -import static org.mockito.MockitoAnnotations.initMocks; - @RunWith(PowerMockRunner.class) @PrepareForTest({HeadersUtil.class, IndexerQueueTaskBuilder.class, DpsHeaders.class}) public class RecordIndexerApiTest { @@ -59,6 +60,8 @@ public class RecordIndexerApiTest { private IndexerService indexService; @Mock private SchemaService schemaService; + @Mock + private SchemaEventsProcessor eventsProcessingService; @Mock private DpsHeaders dpsHeaders; diff --git a/indexer-core/src/test/java/org/opengroup/osdu/indexer/service/IndexerMappingServiceTest.java b/indexer-core/src/test/java/org/opengroup/osdu/indexer/service/IndexerMappingServiceTest.java index 45f23f8a255188ede7d8c0861b566da26a8ab64f..dd12c8e66405c42d8aa87dc208764e49dc2d89a7 100644 --- a/indexer-core/src/test/java/org/opengroup/osdu/indexer/service/IndexerMappingServiceTest.java +++ b/indexer-core/src/test/java/org/opengroup/osdu/indexer/service/IndexerMappingServiceTest.java @@ -14,16 +14,37 @@ package org.opengroup.osdu.indexer.service; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.fail; +import static org.mockito.Matchers.any; +import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.mockingDetails; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.MockitoAnnotations.initMocks; +import static org.powermock.api.mockito.PowerMockito.spy; +import static org.powermock.api.mockito.PowerMockito.when; + import com.google.gson.Gson; +import java.io.IOException; +import java.util.Collection; +import java.util.HashMap; +import java.util.Map; import org.apache.http.StatusLine; import org.elasticsearch.action.support.master.AcknowledgedResponse; -import org.elasticsearch.client.*; +import org.elasticsearch.client.IndicesClient; +import org.elasticsearch.client.RequestOptions; +import org.elasticsearch.client.Response; +import org.elasticsearch.client.RestClient; +import org.elasticsearch.client.RestHighLevelClient; import org.elasticsearch.client.indices.PutMappingRequest; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.InjectMocks; import org.mockito.Mock; +import org.mockito.Spy; +import org.mockito.invocation.Invocation; import org.opengroup.osdu.core.common.logging.JaxRsDpsLog; import org.opengroup.osdu.core.common.model.indexer.IndexSchema; import org.opengroup.osdu.core.common.model.search.RecordMetaAttribute; @@ -35,21 +56,6 @@ import org.powermock.api.mockito.PowerMockito; import org.powermock.core.classloader.annotations.PrepareForTest; import org.powermock.modules.junit4.PowerMockRunner; -import java.io.IOException; -import java.util.HashMap; -import java.util.Map; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.fail; -import static org.mockito.Matchers.any; -import static org.mockito.Mockito.doReturn; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.verifyNoMoreInteractions; -import static org.mockito.MockitoAnnotations.initMocks; -import static org.powermock.api.mockito.PowerMockito.spy; -import static org.powermock.api.mockito.PowerMockito.when; - @RunWith(PowerMockRunner.class) @PrepareForTest({RestHighLevelClient.class, IndicesClient.class}) public class IndexerMappingServiceTest { @@ -73,11 +79,13 @@ public class IndexerMappingServiceTest { @Mock private PartitionSafeIndexCache indexCache; @Mock - private IMappingService mappingService; + private IndicesService indicesService; @Mock private ElasticIndexNameResolver elasticIndexNameResolver; + + @Spy @InjectMocks - private IndexerMappingServiceImpl sut; + private IndexerMappingServiceImpl sut = new IndexerMappingServiceImpl(); private IndexSchema indexSchema; private IndicesClient indicesClient; @@ -190,16 +198,15 @@ public class IndexerMappingServiceTest { when(this.indexCache.get(cacheKey)).thenReturn(true); this.sut.syncIndexMappingIfRequired(restHighLevelClient, indexSchema); - - verifyNoMoreInteractions(this.mappingService); + Collection<Invocation> invocations = mockingDetails(this.sut).getInvocations(); + assertEquals(1,invocations.size()); } @Test public void should_applyNoUpdate_givenUpdateIndex() throws Exception { final String cacheKey = String.format("metaAttributeMappingSynced-%s", index); final String mapping = "{\"dynamic\":\"false\",\"properties\":{\"acl\":{\"properties\":{\"owners\":{\"type\":\"keyword\"},\"viewers\":{\"type\":\"keyword\"}}},\"ancestry\":{\"properties\":{\"parents\":{\"type\":\"keyword\"}}},\"authority\":{\"type\":\"constant_keyword\",\"value\":\"opendes\"},\"createTime\":{\"type\":\"date\"},\"createUser\":{\"type\":\"keyword\"},\"data\":{\"properties\":{\"message\":{\"type\":\"text\",\"fields\":{\"keyword\":{\"type\":\"keyword\",\"null_value\":\"null\",\"ignore_above\":256}}}}},\"id\":{\"type\":\"keyword\"},\"index\":{\"properties\":{\"lastUpdateTime\":{\"type\":\"date\"},\"statusCode\":{\"type\":\"integer\"},\"trace\":{\"type\":\"text\"}}},\"kind\":{\"type\":\"keyword\"},\"legal\":{\"properties\":{\"legaltags\":{\"type\":\"keyword\"},\"otherRelevantDataCountries\":{\"type\":\"keyword\"},\"status\":{\"type\":\"keyword\"}}},\"modifyTime\":{\"type\":\"date\"},\"modifyUser\":{\"type\":\"keyword\"},\"namespace\":{\"type\":\"keyword\"},\"source\":{\"type\":\"constant_keyword\",\"value\":\"test\"},\"tags\":{\"type\":\"flattened\"},\"type\":{\"type\":\"keyword\"},\"version\":{\"type\":\"long\"},\"x-acl\":{\"type\":\"keyword\"}}}"; - when(this.mappingService.getIndexMapping(restHighLevelClient, index)).thenReturn(mapping); - + doReturn(mapping).when(this.sut).getIndexMapping(restHighLevelClient, index); this.sut.syncIndexMappingIfRequired(restHighLevelClient, indexSchema); verify(this.indexCache, times(1)).get(cacheKey); @@ -210,7 +217,7 @@ public class IndexerMappingServiceTest { public void should_applyUpdate_givenExistingIndex() throws Exception { final String cacheKey = String.format("metaAttributeMappingSynced-%s", index); final String mapping = "{\"dynamic\":\"false\",\"properties\":{\"acl\":{\"properties\":{\"owners\":{\"type\":\"keyword\"},\"viewers\":{\"type\":\"keyword\"}}},\"ancestry\":{\"properties\":{\"parents\":{\"type\":\"keyword\"}}},\"data\":{\"properties\":{\"message\":{\"type\":\"text\",\"fields\":{\"keyword\":{\"type\":\"keyword\",\"null_value\":\"null\",\"ignore_above\":256}}}}},\"id\":{\"type\":\"keyword\"},\"index\":{\"properties\":{\"lastUpdateTime\":{\"type\":\"date\"},\"statusCode\":{\"type\":\"integer\"},\"trace\":{\"type\":\"text\"}}},\"kind\":{\"type\":\"keyword\"},\"legal\":{\"properties\":{\"legaltags\":{\"type\":\"keyword\"},\"otherRelevantDataCountries\":{\"type\":\"keyword\"},\"status\":{\"type\":\"keyword\"}}},\"namespace\":{\"type\":\"keyword\"},\"tags\":{\"type\":\"flattened\"},\"type\":{\"type\":\"keyword\"},\"version\":{\"type\":\"long\"},\"x-acl\":{\"type\":\"keyword\"}}}"; - when(this.mappingService.getIndexMapping(restHighLevelClient, index)).thenReturn(mapping); + doReturn(mapping).when(this.sut).getIndexMapping(restHighLevelClient, index); AcknowledgedResponse mappingResponse = new AcknowledgedResponse(true); doReturn(this.indicesClient).when(this.restHighLevelClient).indices(); @@ -222,4 +229,4 @@ public class IndexerMappingServiceTest { verify(this.indexCache, times(1)).put(cacheKey, true); verify(this.indicesClient, times(1)).putMapping(any(PutMappingRequest.class), any(RequestOptions.class)); } -} \ No newline at end of file +} diff --git a/indexer-core/src/test/java/org/opengroup/osdu/indexer/service/SchemaEventsProcessorImplTest.java b/indexer-core/src/test/java/org/opengroup/osdu/indexer/service/SchemaEventsProcessorImplTest.java new file mode 100644 index 0000000000000000000000000000000000000000..31effd715d41d28f21ab7a74920769c85dc24654 --- /dev/null +++ b/indexer-core/src/test/java/org/opengroup/osdu/indexer/service/SchemaEventsProcessorImplTest.java @@ -0,0 +1,130 @@ +/* + * Copyright 2020-2022 Google LLC + * Copyright 2020-2022 EPAM Systems, Inc + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.opengroup.osdu.indexer.service; + +import static java.util.Collections.singletonList; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.fail; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyString; +import static org.mockito.Mockito.doThrow; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.powermock.api.mockito.PowerMockito.when; +import static org.springframework.http.HttpStatus.BAD_REQUEST; +import static org.springframework.http.HttpStatus.INTERNAL_SERVER_ERROR; + +import java.io.IOException; +import java.net.URISyntaxException; +import org.elasticsearch.ElasticsearchStatusException; +import org.elasticsearch.client.RestHighLevelClient; +import org.elasticsearch.rest.RestStatus; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.opengroup.osdu.core.common.model.http.AppException; +import org.opengroup.osdu.core.common.model.indexer.SchemaInfo; +import org.opengroup.osdu.indexer.config.SchemaEventsListenerConfiguration; +import org.opengroup.osdu.indexer.logging.AuditLogger; +import org.opengroup.osdu.indexer.util.ElasticClientHandler; +import org.powermock.api.mockito.PowerMockito; +import org.springframework.test.context.junit4.SpringRunner; + +@RunWith(SpringRunner.class) +public class SchemaEventsProcessorImplTest { + + @Mock + private IndexSchemaService indexSchemaService; + @Mock + private ElasticClientHandler elasticClientHandler; + @Mock + private AuditLogger auditLogger; + @Mock + private SchemaEventsListenerConfiguration schemaEventsListenerConfiguration; + @InjectMocks + private SchemaEventsProcessorImpl sut; + private RestHighLevelClient restClient; + + @Before + public void setup() { + when(this.schemaEventsListenerConfiguration.isListenCreateEvent()).thenReturn(true); + when(this.schemaEventsListenerConfiguration.isListenUpdateEvent()).thenReturn(true); + } + + + @Test + public void should_process_validSchemaCreateEvent() throws IOException, URISyntaxException { + SchemaInfo event1 = new SchemaInfo("slb:indexer:test-data--SchemaEventIntegration:1.0.0", "create"); + this.restClient = PowerMockito.mock(RestHighLevelClient.class); + when(elasticClientHandler.createRestClient()).thenReturn(restClient); + + this.sut.processSchemaMessages(singletonList(event1)); + + verify(this.indexSchemaService, times(1)).processSchemaUpsertEvent(this.restClient, event1.getKind()); + verify(this.auditLogger, times(1)).indexMappingUpsertSuccess(singletonList(event1.getKind())); + } + + @Test + public void should_process_validSchemaUpdateEvent() throws IOException, URISyntaxException { + SchemaInfo event1 = new SchemaInfo("slb:indexer:test-data--SchemaEventIntegration:1.0.0", "update"); + this.restClient = PowerMockito.mock(RestHighLevelClient.class); + when(elasticClientHandler.createRestClient()).thenReturn(restClient); + + this.sut.processSchemaMessages(singletonList(event1)); + + verify(this.indexSchemaService, times(1)).processSchemaUpsertEvent(this.restClient, event1.getKind()); + verify(this.auditLogger, times(1)).indexMappingUpsertSuccess(singletonList(event1.getKind())); + } + + @Test + public void should_throwError_given_unsupportedEvent() { + SchemaInfo event1 = new SchemaInfo("slb:indexer:test-data--SchemaEventIntegration:1.0.0", "delete"); + + try { + this.sut.processSchemaMessages(singletonList(event1)); + fail("Should throw exception"); + } catch (AppException e) { + assertEquals(BAD_REQUEST.value(), e.getError().getCode()); + assertEquals("Error parsing schema events in request payload.", e.getError().getMessage()); + } catch (Exception e) { + fail("Should not throw this exception" + e.getMessage()); + } + } + + @Test + public void should_throwError_given_schemaUpsertFails() throws IOException, URISyntaxException { + SchemaInfo event1 = new SchemaInfo("slb:indexer:test-data--SchemaEventIntegration:1.0.0", "update"); + this.restClient = PowerMockito.mock(RestHighLevelClient.class); + when(elasticClientHandler.createRestClient()).thenReturn(restClient); + doThrow(new ElasticsearchStatusException("unknown error", RestStatus.INTERNAL_SERVER_ERROR)).when(this.indexSchemaService) + .processSchemaUpsertEvent(any(RestHighLevelClient.class), anyString()); + + try { + this.sut.processSchemaMessages(singletonList(event1)); + fail("Should throw exception"); + } catch (AppException e) { + assertEquals(INTERNAL_SERVER_ERROR.value(), e.getError().getCode()); + assertEquals("unknown error", e.getError().getMessage()); + verify(this.auditLogger, times(1)).indexMappingUpsertFail(singletonList(event1.getKind())); + } catch (Exception e) { + fail("Should not throw this exception" + e.getMessage()); + } + } +} diff --git a/indexer-core/src/test/java/org/opengroup/osdu/indexer/service/SchemaProviderImplTest.java b/indexer-core/src/test/java/org/opengroup/osdu/indexer/service/SchemaProviderImplTest.java index 3c40aa24ca8ffc38ed84c51275d67975092364ac..7d1b5982c0afe6f2649f44b2337e333fd51faf9a 100644 --- a/indexer-core/src/test/java/org/opengroup/osdu/indexer/service/SchemaProviderImplTest.java +++ b/indexer-core/src/test/java/org/opengroup/osdu/indexer/service/SchemaProviderImplTest.java @@ -14,45 +14,41 @@ package org.opengroup.osdu.indexer.service; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.inOrder; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.powermock.api.mockito.PowerMockito.when; + import com.fasterxml.jackson.core.type.TypeReference; import com.fasterxml.jackson.databind.ObjectMapper; +import java.io.UnsupportedEncodingException; +import java.net.URISyntaxException; +import java.util.Map; import org.apache.http.HttpStatus; -import org.elasticsearch.ElasticsearchStatusException; -import org.elasticsearch.client.RestHighLevelClient; -import org.elasticsearch.rest.RestStatus; import org.junit.Assert; -import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; -import org.mockito.*; +import org.mockito.InOrder; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.Mockito; +import org.mockito.Spy; import org.opengroup.osdu.core.common.http.IUrlFetchService; import org.opengroup.osdu.core.common.logging.JaxRsDpsLog; -import org.opengroup.osdu.core.common.model.http.AppException; import org.opengroup.osdu.core.common.model.http.HttpResponse; -import org.opengroup.osdu.core.common.model.indexer.SchemaInfo; import org.opengroup.osdu.core.common.provider.interfaces.IRequestInfo; import org.opengroup.osdu.indexer.config.IndexerConfigurationProperties; -import org.opengroup.osdu.indexer.config.SchemaEventsListenerConfiguration; import org.opengroup.osdu.indexer.logging.AuditLogger; import org.opengroup.osdu.indexer.schema.converter.SchemaToStorageFormatImpl; -import org.opengroup.osdu.indexer.util.ElasticClientHandler; import org.powermock.api.mockito.PowerMockito; import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder; import org.springframework.test.context.junit4.SpringRunner; -import java.io.IOException; -import java.io.UnsupportedEncodingException; -import java.net.URISyntaxException; -import java.util.Map; - -import static java.util.Collections.singletonList; -import static org.junit.Assert.*; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.Mockito.*; -import static org.powermock.api.mockito.PowerMockito.when; -import static org.springframework.http.HttpStatus.BAD_REQUEST; -import static org.springframework.http.HttpStatus.INTERNAL_SERVER_ERROR; - @RunWith(SpringRunner.class) public class SchemaProviderImplTest { @@ -73,25 +69,13 @@ public class SchemaProviderImplTest { @Mock private IndexerConfigurationProperties configurationProperties; - @Mock - private ElasticClientHandler elasticClientHandler; + @Mock private AuditLogger auditLogger; - @Mock - private IndexSchemaService indexSchemaService; - @Mock - private SchemaEventsListenerConfiguration schemaEventsListenerConfiguration; + @InjectMocks private SchemaProviderImpl sut; - private RestHighLevelClient restClient; - - @Before - public void setup() { - when(this.schemaEventsListenerConfiguration.isListenCreateEvent()).thenReturn(true); - when(this.schemaEventsListenerConfiguration.isListenUpdateEvent()).thenReturn(true); - } - @Test public void test_empty_schema() throws UnsupportedEncodingException, URISyntaxException { org.opengroup.osdu.core.common.model.http.HttpResponse httpResponse = @@ -202,61 +186,4 @@ public class SchemaProviderImplTest { verify(schemaService, times(0)).getFromStorageService(any()); } - @Test - public void should_process_validSchemaCreateEvent() throws IOException, URISyntaxException { - SchemaInfo event1 = new SchemaInfo("slb:indexer:test-data--SchemaEventIntegration:1.0.0", "create"); - this.restClient = PowerMockito.mock(RestHighLevelClient.class); - when(elasticClientHandler.createRestClient()).thenReturn(restClient); - - this.sut.processSchemaMessages(singletonList(event1)); - - verify(this.indexSchemaService, times(1)).processSchemaUpsertEvent(this.restClient, event1.getKind()); - verify(this.auditLogger, times(1)).indexMappingUpsertSuccess(singletonList(event1.getKind())); - } - - @Test - public void should_process_validSchemaUpdateEvent() throws IOException, URISyntaxException { - SchemaInfo event1 = new SchemaInfo("slb:indexer:test-data--SchemaEventIntegration:1.0.0", "update"); - this.restClient = PowerMockito.mock(RestHighLevelClient.class); - when(elasticClientHandler.createRestClient()).thenReturn(restClient); - - this.sut.processSchemaMessages(singletonList(event1)); - - verify(this.indexSchemaService, times(1)).processSchemaUpsertEvent(this.restClient, event1.getKind()); - verify(this.auditLogger, times(1)).indexMappingUpsertSuccess(singletonList(event1.getKind())); - } - - @Test - public void should_throwError_given_unsupportedEvent() { - SchemaInfo event1 = new SchemaInfo("slb:indexer:test-data--SchemaEventIntegration:1.0.0", "delete"); - - try { - this.sut.processSchemaMessages(singletonList(event1)); - fail("Should throw exception"); - } catch (AppException e) { - assertEquals(BAD_REQUEST.value(), e.getError().getCode()); - assertEquals("Error parsing schema events in request payload.", e.getError().getMessage()); - } catch (Exception e) { - fail("Should not throw this exception" + e.getMessage()); - } - } - - @Test - public void should_throwError_given_schemaUpsertFails() throws IOException, URISyntaxException { - SchemaInfo event1 = new SchemaInfo("slb:indexer:test-data--SchemaEventIntegration:1.0.0", "update"); - this.restClient = PowerMockito.mock(RestHighLevelClient.class); - when(elasticClientHandler.createRestClient()).thenReturn(restClient); - doThrow(new ElasticsearchStatusException("unknown error", RestStatus.INTERNAL_SERVER_ERROR)).when(this.indexSchemaService).processSchemaUpsertEvent(any(RestHighLevelClient.class), anyString()); - - try { - this.sut.processSchemaMessages(singletonList(event1)); - fail("Should throw exception"); - } catch (AppException e) { - assertEquals(INTERNAL_SERVER_ERROR.value(), e.getError().getCode()); - assertEquals("unknown error", e.getError().getMessage()); - verify(this.auditLogger, times(1)).indexMappingUpsertFail(singletonList(event1.getKind())); - } catch (Exception e) { - fail("Should not throw this exception" + e.getMessage()); - } - } -} \ No newline at end of file +} diff --git a/pom.xml b/pom.xml index a25f97f38f858a427647d57ecb5775ed22fe3628..393e42e415ab6154eb4c925ba36ec03922da139f 100644 --- a/pom.xml +++ b/pom.xml @@ -13,10 +13,11 @@ <maven.compiler.target>1.8</maven.compiler.target> <maven.compiler.source>1.8</maven.compiler.source> <spring-cloud.version>Greenwich.SR2</spring-cloud.version> - <os-core-common.version>0.14.0-rc8</os-core-common.version> + <os-core-common.version>0.16.1</os-core-common.version> <snakeyaml.version>1.26</snakeyaml.version> <hibernate-validator.version>6.1.5.Final</hibernate-validator.version> - <jackson.version>2.11.4</jackson.version> + <jackson-databind.version>2.13.2.2</jackson-databind.version> + <jackson.version>2.13.2</jackson.version> <tomcat-embed-core.version>9.0.45</tomcat-embed-core.version> <common-codec.version>1.14</common-codec.version> <elasticsearch.version>7.8.1</elasticsearch.version> @@ -31,8 +32,7 @@ <!-- <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>--> <!-- <failOnMissingWebXml>false</failOnMissingWebXml>--> <!-- <spring-cloud.version>Greenwich.SR2</spring-cloud.version>--> -<!-- <springfox-version>2.7.0</springfox-version>--> - <springfox.version>3.0.0</springfox.version> + <openapi.version>1.6.9</openapi.version> </properties> <licenses> @@ -82,7 +82,7 @@ <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-databind</artifactId> - <version>${jackson.version}</version> + <version>${jackson-databind.version}</version> </dependency> <dependency> <groupId>com.fasterxml.jackson.core</groupId> @@ -144,22 +144,12 @@ <version>1.18.16</version> <scope>provided</scope> </dependency> - <!--Swagger --> - <dependency> - <groupId>io.springfox</groupId> - <artifactId>springfox-boot-starter</artifactId> - <version>${springfox.version}</version> - <exclusions> - <exclusion> - <groupId>org.springframework.plugin</groupId> - <artifactId>spring-plugin-core</artifactId> - </exclusion> - <exclusion> - <groupId>org.springframework.plugin</groupId> - <artifactId>spring-plugin-metadata</artifactId> - </exclusion> - </exclusions> - </dependency> + <!--OpenApi --> + <dependency> + <groupId>org.springdoc</groupId> + <artifactId>springdoc-openapi-ui</artifactId> + <version>${openapi.version}</version> + </dependency> <dependency> <groupId>org.springframework.plugin</groupId> <artifactId>spring-plugin-core</artifactId> diff --git a/provider/indexer-aws/build-aws/buildspec.yaml b/provider/indexer-aws/build-aws/buildspec.yaml index 45269f8416c836e628cafb5e01f83903ce8464b0..07568c7d890cc73bd33b26f6ed515ece36a7d665 100644 --- a/provider/indexer-aws/build-aws/buildspec.yaml +++ b/provider/indexer-aws/build-aws/buildspec.yaml @@ -42,9 +42,12 @@ phases: - echo $JAVA_HOME #WHY - mkdir -p /root/.m2 - cp ./provider/indexer-aws/maven/settings.xml /root/.m2/settings.xml # copy the AWS-specific settings.xml to the CodeBuild instance's .m2 folder - - wget https://github.com/mikefarah/yq/releases/download/v4.27.2/yq_linux_amd64 -q -O /usr/bin/yq && chmod +x /usr/bin/yq - export AWS_ACCOUNT_ID=`aws sts get-caller-identity | grep Account | cut -d':' -f 2 | cut -d'"' -f 2` - export AWS_OSDU_DEV_MAVEN_AUTH_TOKEN=`aws codeartifact get-authorization-token --domain $AWS_OSDU_DEV_MAVEN_DOMAIN --domain-owner $AWS_ACCOUNT_ID --query authorizationToken --output text` + # Install git secrets + - git clone https://github.com/awslabs/git-secrets.git + - cd git-secrets && make install && cd .. + - git secrets --install && git secrets --register-aws pre_build: commands: - echo "Logging in to Amazon ECR..." @@ -66,13 +69,17 @@ phases: - export VERSION=${pom_version%-*} - printenv + - GIT_SECRETS_SCAN_RESULT=$(git secrets --scan 2> ${OUTPUT_DIR}/git_secrets.out.txt && echo OK || echo FAILED) + - if [ "$GIT_SECRETS_SCAN_RESULT" = "FAILED" ]; then echo "Secrets detected!" && exit 1; fi + - echo "Building primary service assemblies..." - mvn -ntp -B test install sonar:sonar -pl .,indexer-core,provider/indexer-aws -Ddeployment.environment=prod -Dsonar.login=${SONAR_USERNAME} -Dsonar.password=${SONAR_PASSWORD} -Dsonar.branch.name=${BRANCH_NAME} - echo "Building integration testing assemblies and gathering artifacts..." - ./testing/indexer-test-aws/build-aws/prepare-dist.sh - - yq -i '.version = strenv(VERSION)' devops/aws/chart/Chart.yaml + - sed -i "s|__CHART_VERSION__|$VERSION|" devops/aws/chart/Chart.yaml + - sed -i "s|__CONTAINER__|$ECR_IMAGE|" devops/aws/chart/values.yaml - echo "--Copying Helm Charts to ${OUTPUT_DIR:-dist}--" - rsync -r devops/aws/* "${OUTPUT_DIR:-dist}" diff --git a/provider/indexer-aws/src/main/resources/application.properties b/provider/indexer-aws/src/main/resources/application.properties index 213017d86608eba1c781ecae4c74857f3224f594..c1fb5c941d31d5a857188a4ed9ee60136713d5d5 100644 --- a/provider/indexer-aws/src/main/resources/application.properties +++ b/provider/indexer-aws/src/main/resources/application.properties @@ -61,4 +61,4 @@ server.ssl.key-alias=${SSL_KEY_ALIAS:osduonaws} server.ssl.key-password=${SSL_KEY_PASSWORD:} server.ssl.key-store-password=${SSL_KEY_STORE_PASSWORD:} -spring.autoconfigure.exclude=org.springframework.boot.autoconfigure.security.SecurityAutoConfiguration \ No newline at end of file +spring.autoconfigure.exclude=org.springframework.boot.autoconfigure.security.SecurityAutoConfiguration diff --git a/provider/indexer-ibm/src/main/resources/application.properties b/provider/indexer-ibm/src/main/resources/application.properties index 1e3ac9496d6694cfe536d328681b201dea528004..aaf4ceb6cf42aaa7a1fcaa8d72e71830700d4b27 100644 --- a/provider/indexer-ibm/src/main/resources/application.properties +++ b/provider/indexer-ibm/src/main/resources/application.properties @@ -66,4 +66,4 @@ ELASTIC_DATASTORE_ID=indexer-service ELASTIC_HOST=elasticsearch.com ELASTIC_PORT=443 -ELASTIC_USER_PASSWORD=REPLACE_ME:REPLACE_ME \ No newline at end of file +ELASTIC_USER_PASSWORD=REPLACE_ME:REPLACE_ME