diff --git a/NOTICE b/NOTICE index 84bffb8e3a5a4a15e6d887430acc2506faecefb2..f9658d07bcca8448a0da9c4e120434ca84335518 100644 --- a/NOTICE +++ b/NOTICE @@ -205,6 +205,8 @@ CC-BY-2.5 ======================================================================== CC0-1.0 ======================================================================== +The following software have components provided under the terms of this license: + - reactive-streams (from http://www.reactive-streams.org/) ======================================================================== @@ -221,11 +223,13 @@ The following software have components provided under the terms of this license: - HK2 Spring Bridge (from https://repo1.maven.org/maven2/org/glassfish/hk2/spring-bridge) - HK2 config types (from https://repo1.maven.org/maven2/org/glassfish/hk2/config-types) - HK2 configuration module (from https://repo1.maven.org/maven2/org/glassfish/hk2/hk2-config) +- HK2 module of HK2 itself (from https://repo1.maven.org/maven2/org/glassfish/hk2/hk2) - Java Architecture for XML Binding (from http://jaxb.java.net/, https://repo1.maven.org/maven2/javax/xml/bind/jaxb-api) - JavaBeans Activation Framework - JavaBeans(TM) Activation Framework (from http://java.sun.com/javase/technologies/desktop/javabeans/jaf/index.jsp) - JavaMail API (from https://repo1.maven.org/maven2/com/sun/mail/javax.mail) - OSGi resource locator (from https://repo1.maven.org/maven2/org/glassfish/hk2/osgi-resource-locator) +- Run Level Service (from https://repo1.maven.org/maven2/org/glassfish/hk2/hk2-runlevel) - Servlet Specification 2.5 API (from http://jetty.mortbay.org, https://repo1.maven.org/maven2/org/mortbay/jetty/servlet-api-2.5) - javax.annotation-api (from http://jcp.org/en/jsr/detail?id=250) - tomcat-embed-core (from http://tomcat.apache.org/) @@ -434,7 +438,7 @@ public-domain ======================================================================== The following software have components provided under the terms of this license: -- Bouncy Castle PKIX, CMS, EAC, TSP, PKCS, OCSP, CMP, and CRMF APIs (from http://www.bouncycastle.org/java.html, https://www.bouncycastle.org/java.html) +- Bouncy Castle PKIX, CMS, EAC, TSP, PKCS, OCSP, CMP, and CRMF APIs (from http://www.bouncycastle.org/java.html, https://maven.repository.redhat.com/ga/org/bouncycastle/bcpkix-jdk15on, https://www.bouncycastle.org/java.html) - 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/) @@ -452,7 +456,7 @@ unknown ======================================================================== The following software have components provided under the terms of this license: -- Bouncy Castle PKIX, CMS, EAC, TSP, PKCS, OCSP, CMP, and CRMF APIs (from http://www.bouncycastle.org/java.html, https://www.bouncycastle.org/java.html) +- Bouncy Castle PKIX, CMS, EAC, TSP, PKCS, OCSP, CMP, and CRMF APIs (from http://www.bouncycastle.org/java.html, https://maven.repository.redhat.com/ga/org/bouncycastle/bcpkix-jdk15on, https://www.bouncycastle.org/java.html) - Bouncy Castle Provider (from http://www.bouncycastle.org/java.html, https://www.bouncycastle.org/java.html) - Byte Buddy (without dependencies) (from https://repo1.maven.org/maven2/net/bytebuddy/byte-buddy) - Checker Qual (from https://checkerframework.org) diff --git a/docs/tutorial/IndexerService.md b/docs/tutorial/IndexerService.md index c65489ba596b332bc6b85374cb954c3607b1778a..106753b26f384f1206b682f81855d8f791b11e7d 100644 --- a/docs/tutorial/IndexerService.md +++ b/docs/tutorial/IndexerService.md @@ -145,6 +145,24 @@ will use the same schema and overwrite records with the same ids. Default value [Back to table of contents](#TOC) +## Delete API <a name="delete"></a> +Delete API is used to delete an index for a specific kind. +Only users who belong to the Entitlement groups 'users.datalake.ops' can make calls to this API. + +``` +DELETE /api/indexer/v2/index?kind=opendes:welldb:wellbore:1.0.0 +``` + +<details><summary>**Curl**</summary> + +```bash +curl --request DELETE \ + --url '/api/indexer/v2/index?kind=opendes:welldb:wellbore:1.0.0' \ + --header 'authorization: Bearer <JWT>' \ + --header 'content-type: application/json' \ + --header 'data-partition-id: opendes' +``` + ### Data Partition provision <a name="data-partition-provision"></a> Configures Search backend for a data partition. 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 5c58742f89bcf3fad892289ef7e407cbdf25a5eb..518f877ad3f21b08dda6c3e6af5b38597b8cf80e 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 @@ -20,7 +20,9 @@ import com.google.gson.JsonParseException; import java.lang.reflect.Type; import java.util.List; import java.util.stream.Collectors; +import javax.inject.Inject; import javax.validation.Valid; +import javax.validation.constraints.NotBlank; import javax.validation.constraints.NotNull; import lombok.extern.java.Log; import org.opengroup.osdu.core.common.model.http.AppException; @@ -28,18 +30,25 @@ import org.opengroup.osdu.core.common.model.http.DpsHeaders; import org.opengroup.osdu.core.common.model.indexer.RecordInfo; import org.opengroup.osdu.core.common.model.search.RecordChangedMessages; import org.opengroup.osdu.core.common.model.search.SearchServiceRole; +import org.opengroup.osdu.core.common.model.storage.validation.ValidKind; +import org.opengroup.osdu.core.common.search.ElasticIndexNameResolver; import org.opengroup.osdu.indexer.SwaggerDoc; import org.opengroup.osdu.indexer.logging.AuditLogger; import org.opengroup.osdu.indexer.service.IndexerService; +import org.opengroup.osdu.indexer.service.IndicesServiceImpl; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpStatus; +import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity; import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.web.bind.annotation.DeleteMapping; import org.springframework.web.bind.annotation.PostMapping; 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 @RestController @@ -52,6 +61,14 @@ public class CleanupIndiciesApi { @Autowired private AuditLogger auditLogger; + @Inject + private ElasticIndexNameResolver elasticIndexNameResolver; + + @Inject + private IndicesServiceImpl indicesService; + + private static final String ENTITLEMENT_GROUP = "users.datalake.ops"; + @ApiIgnore @PostMapping(path = "/index-cleanup", consumes = "application/json") @PreAuthorize("@authorizationFilter.hasPermission('" + SearchServiceRole.ADMIN + "')") @@ -89,4 +106,22 @@ public class CleanupIndiciesApi { throw new AppException(HttpStatus.BAD_REQUEST.value(), "Unknown error", "An unknown error has occurred.", e); } } + + @DeleteMapping(value = "/index", produces = MediaType.APPLICATION_JSON_VALUE) + @PreAuthorize("@authorizationFilter.hasPermission('" + ENTITLEMENT_GROUP + "')") + public ResponseEntity deleteIndex(@RequestParam("kind") @NotBlank @ValidKind String kind) { + String index = elasticIndexNameResolver.getIndexNameFromKind(kind); + try { + boolean responseStatus = indicesService.deleteIndex(index); + if (responseStatus) { + this.auditLogger.indexDeleteSuccess(singletonList(index)); + } + return new ResponseEntity(HttpStatus.OK); + } catch (AppException e) { + throw e; + } catch (Exception e) { + this.auditLogger.indexDeleteFail(singletonList(index)); + throw new AppException(HttpStatus.INTERNAL_SERVER_ERROR.value(), "Unknown error", "An unknown error has occurred.", e); + } + } } diff --git a/indexer-core/src/main/java/org/opengroup/osdu/indexer/logging/AuditEvents.java b/indexer-core/src/main/java/org/opengroup/osdu/indexer/logging/AuditEvents.java index fc07fc61ac12bbe429b0f8cb5e5b84117f8fc77a..ad0a6cc98435dd6efbf1e6457617656ac1ded7f0 100644 --- a/indexer-core/src/main/java/org/opengroup/osdu/indexer/logging/AuditEvents.java +++ b/indexer-core/src/main/java/org/opengroup/osdu/indexer/logging/AuditEvents.java @@ -59,6 +59,10 @@ public class AuditEvents { private static final String CONFIGURE_PARTITION_ACTION_ID = "IN0012"; private static final String CONFIGURE_PARTITION_OPERATION = "Data partition cluster configuration update"; + private static final String INDEX_DELETE_ACTION_ID = "IN0013"; + private static final String INDEX_DELETE_SUCCESS = "Successfully deleted index"; + private static final String INDEX_DELETE_FAILURE = "Failed deleting index"; + private final String user; public AuditEvents(String user) { @@ -134,6 +138,28 @@ public class AuditEvents { .build(); } + public AuditPayload getIndexDeleteFailEvent(List<String> resources) { + return AuditPayload.builder() + .action(AuditAction.DELETE) + .status(AuditStatus.FAILURE) + .actionId(INDEX_DELETE_ACTION_ID) + .message(INDEX_DELETE_FAILURE) + .resources(resources) + .user(this.user) + .build(); + } + + public AuditPayload getIndexDeleteSuccessEvent(List<String> resources) { + return AuditPayload.builder() + .action(AuditAction.DELETE) + .status(AuditStatus.SUCCESS) + .actionId(INDEX_DELETE_ACTION_ID) + .message(INDEX_DELETE_SUCCESS) + .resources(resources) + .user(this.user) + .build(); + } + public AuditPayload getIndexPurgeRecordSuccessEvent(List<String> resources) { return AuditPayload.builder() .action(AuditAction.DELETE) diff --git a/indexer-core/src/main/java/org/opengroup/osdu/indexer/logging/AuditLogger.java b/indexer-core/src/main/java/org/opengroup/osdu/indexer/logging/AuditLogger.java index c85e6d7a2a4dda8fb78662cc165928efdc51c130..e02f7a2ea8ab30659fd943f81567472f13400151 100644 --- a/indexer-core/src/main/java/org/opengroup/osdu/indexer/logging/AuditLogger.java +++ b/indexer-core/src/main/java/org/opengroup/osdu/indexer/logging/AuditLogger.java @@ -65,6 +65,14 @@ public class AuditLogger { this.writeLog(this.getAuditEvents().getIndexDeleteRecordFailEvent(resources)); } + public void indexDeleteSuccess(List<String> resources) { + this.writeLog(this.getAuditEvents().getIndexDeleteSuccessEvent(resources)); + } + + public void indexDeleteFail(List<String> resources) { + this.writeLog(this.getAuditEvents().getIndexDeleteFailEvent(resources)); + } + public void indexPurgeRecordSuccess(List<String> resources) { this.writeLog(this.getAuditEvents().getIndexPurgeRecordSuccessEvent(resources)); } diff --git a/provider/indexer-reference/src/main/java/org/opengroup/osdu/indexer/service/IndexerServiceImpl.java b/provider/indexer-reference/src/main/java/org/opengroup/osdu/indexer/service/IndexerServiceImpl.java index 505180648b2233d5062d3a48c895efe898e51add..748d130fe4482ebc7086de100d7d4a8a8b3323b9 100644 --- a/provider/indexer-reference/src/main/java/org/opengroup/osdu/indexer/service/IndexerServiceImpl.java +++ b/provider/indexer-reference/src/main/java/org/opengroup/osdu/indexer/service/IndexerServiceImpl.java @@ -56,6 +56,7 @@ import org.opengroup.osdu.core.common.model.indexer.RecordIndexerPayload; import org.opengroup.osdu.core.common.model.indexer.RecordInfo; import org.opengroup.osdu.core.common.model.indexer.RecordStatus; import org.opengroup.osdu.core.common.model.indexer.Records; +import org.opengroup.osdu.core.common.model.search.IndexInfo; import org.opengroup.osdu.core.common.model.search.RecordChangedMessages; import org.opengroup.osdu.core.common.model.search.RecordMetaAttribute; import org.opengroup.osdu.core.common.provider.interfaces.IRequestInfo;