Skip to content

Commit

Permalink
Merge pull request #370 from folio-org/MODFQMMGR-392-ebsco
Browse files Browse the repository at this point in the history
Adding an end point /fqm/migrate
  • Loading branch information
kjain110 authored Sep 12, 2024
2 parents 66f13ce + 0496743 commit 282e923
Show file tree
Hide file tree
Showing 6 changed files with 218 additions and 6 deletions.
15 changes: 14 additions & 1 deletion descriptors/ModuleDescriptor-template.json
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,12 @@
"permissionsRequired": ["fqm.version.get"],
"modulePermissions": ["perms.users.get"]
},
{
"methods": ["POST"],
"pathPattern": "/fqm/migrate",
"permissionsRequired": ["fqm.migrate.post"],
"modulePermissions": ["perms.users.get"]
},
{
"methods": ["POST"],
"pathPattern": "/query/contents",
Expand Down Expand Up @@ -183,6 +189,12 @@
"description": "Get the version of fqm",
"visible": true
},
{
"permissionName": "fqm.migrate.post",
"displayName": "FQM - Submit FQM Migration",
"description": "Submit FQM Migration and get results",
"visible": true
},
{
"permissionName": "fqm.materializedViews.post",
"displayName": "FQM - Refresh materialized views",
Expand All @@ -205,7 +217,8 @@
"fqm.query.async.results.get",
"fqm.query.async.delete",
"fqm.query.sync.get",
"fqm.version.get"
"fqm.version.get",
"fqm.migrate.post"
],
"visible": true
}
Expand Down
35 changes: 35 additions & 0 deletions src/main/java/org/folio/fqm/resource/MigrationController.java
Original file line number Diff line number Diff line change
@@ -1,18 +1,53 @@
package org.folio.fqm.resource;

import lombok.RequiredArgsConstructor;
import org.folio.fqm.domain.dto.FqmMigrateRequest;
import org.folio.fqm.domain.dto.FqmMigrateResponse;
import org.folio.fqm.domain.dto.FqmMigrateResponseWarningsInner;
import org.folio.fqm.migration.MigratableQueryInformation;
import org.folio.fqm.service.MigrationService;
import org.folio.spring.i18n.service.TranslationService;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.RestController;


@RestController
@RequiredArgsConstructor
public class MigrationController implements FqmVersionApi {
private final MigrationService migrationService;

private final TranslationService translationService;

@Override
public ResponseEntity<String> getFqmVersion() {
return new ResponseEntity<>(migrationService.getLatestVersion(), HttpStatus.OK);
}

@Override
public ResponseEntity<FqmMigrateResponse> fqmMigrate(FqmMigrateRequest fqmMigrateRequest) {
MigratableQueryInformation migratableQueryInformation = new MigratableQueryInformation(
fqmMigrateRequest.getEntityTypeId(),
fqmMigrateRequest.getFqlQuery(),
fqmMigrateRequest.getFields()
);

MigratableQueryInformation updatedQueryInfo = migrationService.migrate(migratableQueryInformation);

FqmMigrateResponse fqmMigrateResponse = new FqmMigrateResponse()
.entityTypeId(updatedQueryInfo.entityTypeId())
.fqlQuery(updatedQueryInfo.fqlQuery())
.fields(updatedQueryInfo.fields())
.warnings(updatedQueryInfo.warnings().stream()
.map(warning -> new FqmMigrateResponseWarningsInner()
.type(warning.getType() != null ? warning.getType().toString() : null)
.description(warning.getDescription(translationService) != null ?
warning.getDescription(translationService) : "No description provided"
)
)
.toList()
);

return new ResponseEntity<>(fqmMigrateResponse, HttpStatus.OK);
}
}
29 changes: 28 additions & 1 deletion src/main/resources/swagger.api/mod-fqm-manager.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,30 @@ paths:
$ref: '#/components/responses/badRequestResponse'
'500':
$ref: '#/components/responses/internalServerErrorResponse'
/fqm/migrate:
post:
summary: fqm migrate request
operationId: fqmMigrate
tags:
- fqmVersion
requestBody:
description: 'Request for FQM version submitted successfully'
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/fqmMigrateRequest'
responses:
'200':
description: 'FQM version updated successfully'
content:
application/json:
schema:
$ref: '#/components/schemas/fqmMigrateResponse'
'400':
$ref: '#/components/responses/badRequestResponse'
'500':
$ref: '#/components/responses/internalServerErrorResponse'

components:
parameters:
Expand Down Expand Up @@ -133,6 +157,10 @@ components:
type: array
items:
type: string
fqmMigrateRequest:
$ref: schemas/FqmMigrateRequest.json
fqmMigrateResponse:
$ref: schemas/FqmMigrateResponse.json

responses:
badRequestResponse:
Expand All @@ -155,4 +183,3 @@ components:
code: unexpected.error
schema:
$ref: "#/components/schemas/errorResponse"

27 changes: 27 additions & 0 deletions src/main/resources/swagger.api/schemas/FqmMigrateRequest.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"title": "Entity Upgrade Request",
"description": "Schema for a request to upgrade an entity payload, including an entity type ID, FQL query, and list of fields.",
"type": "object",
"properties": {
"entityTypeId": {
"description": "ID of the entity type to be upgraded",
"type": "string",
"format": "UUID"
},
"fqlQuery": {
"description": "FQL query string to be used for the upgrade",
"type": "string"
},
"fields": {
"description": "List of fields to be included in the upgrade",
"type": "array",
"items": {
"type": "string"
}
}
},
"required": [
"entityTypeId"
]
}
46 changes: 46 additions & 0 deletions src/main/resources/swagger.api/schemas/FqmMigrateResponse.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"title": "Entity Upgrade Response",
"description": "Schema for a response to upgrade FQM",
"type": "object",
"properties": {
"entityTypeId": {
"description": "ID of the entity type upgraded successfully",
"type": "string",
"format": "UUID"
},
"fqlQuery": {
"description": "FQL query string upgraded successfully",
"type": "string"
},
"fields": {
"description": "List of fields upgraded successfully",
"type": "array",
"items": {
"type": "string"
}
},
"warnings": {
"description": "List of warnings issued during the upgrade",
"type": "array",
"items": {
"type": "object",
"properties": {
"description": {
"description": "Description of the warning",
"type": "string"
},
"type": {
"description": "Type of warning",
"type": "string"
}
},
"required": [
]
}
}
},
"required": [
"entityTypeId"
]
}
Original file line number Diff line number Diff line change
@@ -1,24 +1,39 @@
package org.folio.fqm.controller;

import com.fasterxml.jackson.databind.ObjectMapper;
import org.folio.fqm.domain.dto.FqmMigrateRequest;
import org.folio.fqm.migration.MigratableQueryInformation;
import org.folio.fqm.migration.warnings.DeprecatedEntityWarning;
import org.folio.fqm.migration.warnings.Warning;
import org.folio.fqm.resource.MigrationController;
import org.folio.fqm.service.MigrationService;
import org.folio.spring.FolioExecutionContext;
import org.folio.spring.i18n.service.TranslationService;
import org.folio.spring.integration.XOkapiHeaders;
import org.jetbrains.annotations.NotNull;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.http.MediaType;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.RequestBuilder;
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;

import java.util.List;
import java.util.UUID;

import static org.hamcrest.Matchers.is;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
import static org.springframework.http.MediaType.APPLICATION_JSON;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;

@WebMvcTest(MigrationController.class)
class MigrationControllerTest {
private static final String GET_VERSION_URL = "/fqm/version";

private static final String POST_FQM_MIGRATE_REQUEST = "/fqm/migrate";
@Autowired
private MockMvc mockMvc;

Expand All @@ -28,17 +43,66 @@ class MigrationControllerTest {
@MockBean
private FolioExecutionContext executionContext;

@MockBean
private TranslationService translationService;

@Test
void shouldReturnVersion() throws Exception {
String tenantId = "tenant_01";
when(executionContext.getTenantId()).thenReturn(tenantId);
when(migrationService.getLatestVersion()).thenReturn("1");
RequestBuilder builder = MockMvcRequestBuilders
.get(GET_VERSION_URL)
.accept(MediaType.APPLICATION_JSON);
.accept(APPLICATION_JSON);
mockMvc
.perform(builder)
.andExpect(status().isOk())
.andExpect(content().string("1"));
}

@Test
void shouldMigrateFqmSuccessfully() throws Exception {
String tenantId = "tenant_01";
UUID entityTypeID = UUID.randomUUID();
FqmMigrateRequest fqmMigrateRequest = getFqmMigrateRequest(entityTypeID);

MigratableQueryInformation migratableQueryInformation = mock(MigratableQueryInformation.class);

Warning deprecatedEntityWarning = mock(DeprecatedEntityWarning.class);
List<Warning> warningList = List.of(deprecatedEntityWarning);

when(deprecatedEntityWarning.getType()).thenReturn(Warning.WarningType.DEPRECATED_ENTITY);
when(deprecatedEntityWarning.getDescription(any())).thenReturn("def");

when(executionContext.getTenantId()).thenReturn(tenantId);
when(migratableQueryInformation.entityTypeId()).thenReturn(entityTypeID);
when(migratableQueryInformation.fqlQuery()).thenReturn("users.active");
when(migratableQueryInformation.fields()).thenReturn(List.of("field1", "field2"));
when(migratableQueryInformation.warnings()).thenReturn(warningList);

when(migrationService.migrate(any(MigratableQueryInformation.class))).thenReturn(migratableQueryInformation);

RequestBuilder builder = MockMvcRequestBuilders
.post(POST_FQM_MIGRATE_REQUEST)
.header(XOkapiHeaders.TENANT, tenantId)
.contentType(APPLICATION_JSON)
.content(new ObjectMapper().writeValueAsString(fqmMigrateRequest));

mockMvc
.perform(builder)
.andExpect(status().isOk())
.andExpect(jsonPath("$.entityTypeId", is(entityTypeID.toString())))
.andExpect(jsonPath("$.fqlQuery", is("users.active")))
.andExpect(jsonPath("$.fields", is(List.of("field1", "field2"))))
.andExpect(jsonPath("$.warnings[0].type", is("DEPRECATED_ENTITY"))) // Matching the warning type
.andExpect(jsonPath("$.warnings[0].description", is("def"))); // Matching the warning description
}
@NotNull
private static FqmMigrateRequest getFqmMigrateRequest(UUID entityTypeID) {
FqmMigrateRequest fqmMigrateRequest = new FqmMigrateRequest();
fqmMigrateRequest.setEntityTypeId(entityTypeID);
fqmMigrateRequest.setFqlQuery("users.active");
fqmMigrateRequest.setFields(List.of("field1", "field2"));
return fqmMigrateRequest;
}
}

0 comments on commit 282e923

Please sign in to comment.