Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SCRUM-3693: roll down MaTI DB between environments #69

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<quarkus.platform.artifact-id>quarkus-bom</quarkus.platform.artifact-id>
<quarkus.platform.group-id>io.quarkus.platform</quarkus.platform.group-id>
<quarkus.platform.version>3.6.5</quarkus.platform.version>
<quarkus.platform.version>3.7.2</quarkus.platform.version>
<surefire-plugin.version>3.1.2</surefire-plugin.version>
</properties>

Expand Down
52 changes: 37 additions & 15 deletions src/main/java/org/alliancegenome/mati/controller/AdminResource.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,27 +2,35 @@

import jakarta.enterprise.context.RequestScoped;
import jakarta.inject.Inject;
import jakarta.transaction.Transactional;
import jakarta.ws.rs.core.Response;
import org.alliancegenome.mati.configuration.ErrorResponse;
import org.alliancegenome.mati.entity.SubdomainEntity;
import org.alliancegenome.mati.interfaces.AdminRESTInterface;
import org.alliancegenome.mati.repository.SubdomainRepository;
import org.alliancegenome.mati.repository.SubdomainSequenceRepository;
import org.alliancegenome.mati.rolldownrepository.DBRoller;
import org.eclipse.microprofile.config.inject.ConfigProperty;

import java.util.List;
import java.util.Map;

/**
* Controller for administrative endpoints
* Controller for:
* getting the current values of the counters (subdomains)
* and rolling down the MaTI database
*/
@RequestScoped
public class AdminResource implements AdminRESTInterface {

@Inject
SubdomainSequenceRepository subdomainSequenceRepository;

@Inject
SubdomainRepository subdomainRepository;
DBRoller dbRoller;

@ConfigProperty(name = "NET")
String NET;

public Response getCounters(String auth_header) {
public Response getCounters() {
Map<String,Long> counters = subdomainSequenceRepository.getSubdomainCounters();
if (counters.isEmpty()) {
ErrorResponse.ErrorMessage errorMessage = new ErrorResponse.ErrorMessage("admin.getCounters","No subdomains in database");
Expand All @@ -32,20 +40,34 @@ public Response getCounters(String auth_header) {
return Response.ok().entity(counters).build();
}

public Response setCounter(String auth_header, String subdomain, int value) {
SubdomainEntity subdomainEntity = subdomainRepository.findByName(subdomain);
if (subdomainEntity == null) {
ErrorResponse.ErrorMessage errorMessage = new ErrorResponse.ErrorMessage("admin.setCounter","ID subdomain " + subdomain +" not found");
ErrorResponse errorResponse = new ErrorResponse(errorMessage);
return Response.status(Response.Status.BAD_REQUEST).entity(errorResponse).build();
/**
* rolls down the status of Mati counters for the curation application
* @param auth_header with authorization
* @return a success/failure HTTP response
*/
@Transactional
public Response rolldown_for_curation(String auth_header) {
if (NET.equals("alpha")) {
return Response.ok().build();
}
boolean isDone = subdomainSequenceRepository.setSubdomainCounter(subdomainEntity, value);
if (isDone) {
List<String> subdomains = List.of("disease_annotation");
return rolldown(subdomains);
}

/**
* rolls down the status of Mati counters from one environment to another
* prod -> beta
* beta -> alpha
* @param subdomains the list of subdomains to roll down
* @return a success/failure HTTP response
*/
private Response rolldown(List<String> subdomains) {
Map<String,Long> counters = subdomainSequenceRepository.getSubdomainCounters();
if (dbRoller.setSubdomainCounters(subdomains, counters)) {
return Response.ok().build();
}
else {
return Response.notModified("Failure changing the value").build();
return Response.notModified("Failure changing the values").build();
}
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -13,40 +13,28 @@
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON)
@Tag(name = "Admin", description = "Administrative tasks")
@Authenticated
public interface AdminRESTInterface {

/**
* Gets the counters for all the subdomains
*
* @param auth_header Authorization Header
* @return an HTTP response
*/
@Operation(summary = "Get Counter Values")
@Path("/counters")
@GET
Response getCounters(@NotNull @HeaderParam("Authorization") String auth_header);

Response getCounters();

/**
* Sets the counters for a subdomain
*
* Rolls down the counters to another environment
* prod to beta, beta to alpha
* @param auth_header Authorization Header
* @param subdomain the subdomain to change
* @param value the value to assign
* @return an HTTP response
*/
@Operation(summary = "Set Counter Value")
@Path("/counter")
@PUT
Response setCounter(
@NotNull(message = "Header does not have Authorization") @HeaderParam("Authorization")
String auth_header,

@NotNull(message = "Header does not have subdomain") @HeaderParam("subdomain")
String subdomain,

@NotNull(message = "Header does not have increment value") @HeaderParam("value")
int value
);
@Operation(summary = "Roll down")
@Path("/rolldown_for_curation")
@POST
@Authenticated
Response rolldown_for_curation(
@NotNull(message = "Header does not have Authorization") @HeaderParam("Authorization") String auth_header);
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package org.alliancegenome.mati.repository;

import io.quarkus.hibernate.orm.PersistenceUnit;
import jakarta.enterprise.context.ApplicationScoped;
import jakarta.inject.Inject;
import jakarta.persistence.EntityManager;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
package org.alliancegenome.mati.rolldownrepository;

import io.quarkus.hibernate.orm.PersistenceUnit;
import jakarta.enterprise.context.RequestScoped;
import jakarta.inject.Inject;
import jakarta.persistence.EntityManager;
import jakarta.persistence.Query;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
* Rolls-down the MaTI database from one environment to other
* prod -> beta
* beta -> alpha
*/
@RequestScoped
public class DBRoller {

@PersistenceUnit("rolldown")
@Inject
EntityManager entityManager;

/**
* Creates the SQL sentences for setting the PostgreSQL sequences values
* @param subdomains the list of subdomains
* @param counters a dictionary mapping subdomains to values (e.g. subdomain_person -> 120 )
* @return a list of SQL statements. For example:
* [ SETVAL('subdomain_name1_seq',10) ... SETVAL('subdomain_nameN_seq',N) ]
*/
private List<String> prepareSETVALStatements(List<String> subdomains, Map<String,Long> counters) {
List<String> setVALStatements = new ArrayList<>();
for (String subdomain : subdomains) {
if (counters.containsKey(subdomain)) {
Long counter = counters.get(subdomain);
if (counter > 0) {
setVALStatements.add("SETVAL('subdomain_" + subdomain + "_seq'," + counter + ")");
}
}
}
return setVALStatements;
}

/**
* Rolls down the values from one environment to other
* @param subdomains the list of subdomains
* @param counters a dictionary mapping subdomains to values (e.g. subdomain_reference -> 20 )
* @return a success/failure value
*/
public boolean setSubdomainCounters(List<String> subdomains, Map<String,Long> counters) {
List<String> setStatements = prepareSETVALStatements(subdomains, counters);
if (!setStatements.isEmpty()) {
String body = String.join(",", setStatements);
String sql = "SELECT " + body;
Query query = entityManager.createNativeQuery(sql);
try {
int num_queries = query.getResultList().size();
if (num_queries == setStatements.size()) {
return true;
}
} catch (Exception e) {
return false;
}
}
return true;
}
}
19 changes: 15 additions & 4 deletions src/main/resources/application.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,17 +20,25 @@ quarkus:
access-control-max-age: -1
headers: "*"
datasource:
db-kind: postgresql
jdbc:
driver: org.postgresql.Driver
url: jdbc:postgresql://localhost:5432/mati
username: postgres
password: postgres
rolldown:
db-kind: postgresql
jdbc:
url: jdbc:postgresql://localhost:5432/roll
flyway:
migrate-at-start: true
hibernate-orm:
dialect: org.hibernate.dialect.PostgreSQLDialect
database:
generation: none
packages: ['org.alliancegenome.mati.entity','org.alliancegenome.mati.repository','io.quarkus.hibernate.orm.panache']
rolldown:
packages: ['org.alliancegenome.mati.rolldownrepository']
datasource: rolldown
validate-in-dev-mode: false
swagger-ui:
always-include: true
smallrye-openapi.management.enabled: false
Expand All @@ -48,5 +56,8 @@ quarkus:

"%test":
quarkus.datasource.jdbc:
driver: org.testcontainers.jdbc.ContainerDatabaseDriver
url: jdbc:tc:postgresql:13:///mati
driver: org.testcontainers.jdbc.ContainerDatabaseDriver
url: jdbc:tc:postgresql:13:///mati
quarkus.datasource.rolldown.jdbc:
driver: org.testcontainers.jdbc.ContainerDatabaseDriver
url: jdbc:tc:postgresql:13:///roll
Original file line number Diff line number Diff line change
Expand Up @@ -10,57 +10,31 @@
import static io.restassured.RestAssured.given;
import static io.restassured.http.ContentType.JSON;

/**
* Tests the /api/admin/counters endpoint
* It runs *after* the IdentifierResourceITcase tests
* that mint some identifiers
*/
@QuarkusIntegrationTest
@QuarkusTestResource(PostgresResource.class)
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
@Order(3)
public class AdminResourceITCase {
private String authorization;
@BeforeAll
void setup() {
authorization = "Bearer: " + OktaHelper.fetchOktaToken();
}

@Test
public void setCounterDA() {
setCounterandCheckStatus("disease_annotation", 2);
}

@Test
public void setCounterPerson() {
setCounterandCheckStatus("person", 4);
}

@Test
public void setCounterResource() {
setCounterandCheckStatus("resource", 8);
}

@Test
public void getCounters() {
Map<String,Integer> counters = given().
contentType(JSON).
header("Accept", "application/json").
header("Authorization", authorization).
when().
get("http://localhost:8081/api/admin/counters").
then().
statusCode(200)
.extract().body().as(Map.class);

Assertions.assertEquals(counters.get("disease_annotation"), 2);
contentType(JSON).
header("Accept", "application/json").
when().
get("http://localhost:8081/api/admin/counters").
then().
statusCode(200)
.extract().body().as(Map.class);

Assertions.assertEquals(counters.get("disease_annotation"), 5);
Assertions.assertEquals(counters.get("person"), 4);
Assertions.assertEquals(counters.get("resource"), 8);
}

private void setCounterandCheckStatus(String subdomain, int value) {
given().
contentType(JSON).
header("Authorization", authorization).
header("subdomain", subdomain).
header("value", value).
when().
put("http://localhost:8081/api/admin/counter").
then().
statusCode(200);
Assertions.assertEquals(counters.get("resource"), 6);
Assertions.assertEquals(counters.get("reference"), 3);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,18 @@

import org.alliancegenome.mati.configuration.PostgresResource;
import org.alliancegenome.mati.entity.IdentifiersRange;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.TestInstance;
import org.junit.jupiter.api.*;

import static io.restassured.RestAssured.given;

/**
* Tests the /api/identifier (PUT, POST) endpoints
* for minting identifiers
*/
@QuarkusIntegrationTest
@QuarkusTestResource(PostgresResource.class)
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
@Order(2)
class IdentifierResourceITCase {
private String authorization;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import org.alliancegenome.mati.entity.SubdomainEntity;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Order;
import org.junit.jupiter.api.Test;

import java.util.List;
Expand All @@ -18,6 +19,7 @@

@QuarkusIntegrationTest
@QuarkusTestResource(PostgresResource.class)
@Order(1)
class SubdomainResourceITCase {

@BeforeEach
Expand Down
2 changes: 2 additions & 0 deletions src/test/resources/junit-platform.properties
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
junit.jupiter.testclass.order.default = \
org.junit.jupiter.api.ClassOrderer$OrderAnnotation
Loading