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

[SELC-6625] feat: added api to retrieve institutions given a list of ids #722

Open
wants to merge 3 commits into
base: main
Choose a base branch
from
Open
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
56 changes: 56 additions & 0 deletions apps/onboarding-ms/src/main/docs/openapi.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@
"name" : "Aggregates Controller"
}, {
"name" : "Document Controller"
}, {
"name" : "Institution Controller"
}, {
"name" : "Onboarding"
}, {
Expand Down Expand Up @@ -281,6 +283,47 @@
} ]
}
},
"/v1/institutions" : {
"post" : {
"tags" : [ "Institution Controller" ],
"summary" : "Retrieve list of institutions given ids in input.",
"description" : "Retrieve list of institutions given ids in input. If list in input is nullor empty, a bad request exception is thrown",
"operationId" : "getInstitutions",
"requestBody" : {
"content" : {
"application/json" : {
"schema" : {
"$ref" : "#/components/schemas/GetInstitutionRequest"
}
}
}
},
"responses" : {
"200" : {
"description" : "OK",
"content" : {
"application/json" : {
"schema" : {
"type" : "array",
"items" : {
"$ref" : "#/components/schemas/InstitutionResponse"
}
}
}
}
},
"401" : {
"description" : "Not Authorized"
},
"403" : {
"description" : "Not Allowed"
}
},
"security" : [ {
"SecurityScheme" : [ ]
} ]
}
},
"/v1/onboarding" : {
"get" : {
"tags" : [ "Onboarding Controller" ],
Expand Down Expand Up @@ -2154,6 +2197,19 @@
}
}
},
"GetInstitutionRequest" : {
"required" : [ "institutionIds" ],
"type" : "object",
"properties" : {
"institutionIds" : {
"minItems" : 1,
"type" : "array",
"items" : {
"type" : "string"
}
}
}
},
"InstitutionBaseRequest" : {
"required" : [ "institutionType", "origin", "originId", "digitalAddress" ],
"type" : "object",
Expand Down
39 changes: 39 additions & 0 deletions apps/onboarding-ms/src/main/docs/openapi.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ servers:
tags:
- name: Aggregates Controller
- name: Document Controller
- name: Institution Controller
- name: Onboarding
- name: Onboarding Controller
- name: billing-portal
Expand Down Expand Up @@ -205,6 +206,34 @@ paths:
description: Not Allowed
security:
- SecurityScheme: []
/v1/institutions:
post:
tags:
- Institution Controller
summary: Retrieve list of institutions given ids in input.
description: "Retrieve list of institutions given ids in input. If list in input\
\ is nullor empty, a bad request exception is thrown"
operationId: getInstitutions
requestBody:
content:
application/json:
schema:
$ref: "#/components/schemas/GetInstitutionRequest"
responses:
"200":
description: OK
content:
application/json:
schema:
type: array
items:
$ref: "#/components/schemas/InstitutionResponse"
"401":
description: Not Authorized
"403":
description: Not Allowed
security:
- SecurityScheme: []
/v1/onboarding:
get:
tags:
Expand Down Expand Up @@ -1557,6 +1586,16 @@ components:
type: string
desc:
type: string
GetInstitutionRequest:
required:
- institutionIds
type: object
properties:
institutionIds:
minItems: 1
type: array
items:
type: string
InstitutionBaseRequest:
required:
- institutionType
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
package it.pagopa.selfcare.onboarding.controller;

import io.quarkus.security.Authenticated;
import io.smallrye.mutiny.Multi;
import it.pagopa.selfcare.onboarding.controller.request.GetInstitutionRequest;
import it.pagopa.selfcare.onboarding.controller.response.InstitutionResponse;
import it.pagopa.selfcare.onboarding.service.InstitutionService;
import jakarta.validation.Valid;
import jakarta.ws.rs.Consumes;
import jakarta.ws.rs.POST;
import jakarta.ws.rs.Path;
import jakarta.ws.rs.Produces;
import jakarta.ws.rs.core.MediaType;
import java.util.List;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.eclipse.microprofile.openapi.annotations.Operation;
import org.eclipse.microprofile.openapi.annotations.tags.Tag;

@Authenticated
@Path("/v1/institutions")
@Tag(name = "Institution Controller")
@AllArgsConstructor
@Slf4j
public class InstitutionController {

private final InstitutionService institutionService;

@Operation(
summary = "Retrieve list of institutions given ids in input.",
description = "Retrieve list of institutions given ids in input. If list in input is null" +
"or empty, a bad request exception is thrown"
)
@POST
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
public Multi<InstitutionResponse> getInstitutions(@Valid GetInstitutionRequest institutionRequest) {
final List<String> institutionIds = institutionRequest.getInstitutionIds();
return institutionService.getInstitutions(institutionIds);
}


}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package it.pagopa.selfcare.onboarding.controller.request;

import jakarta.validation.constraints.NotEmpty;
import jakarta.validation.constraints.NotNull;
import lombok.Data;

import java.util.List;

@Data
public class GetInstitutionRequest {
@NotNull @NotEmpty
private List<String> institutionIds;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package it.pagopa.selfcare.onboarding.service;

import io.smallrye.mutiny.Multi;
import it.pagopa.selfcare.onboarding.controller.response.InstitutionResponse;
import java.util.List;

public interface InstitutionService {

Multi<InstitutionResponse> getInstitutions(List<String> institutionIds);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
package it.pagopa.selfcare.onboarding.service;

import static it.pagopa.selfcare.onboarding.util.QueryUtils.FieldNames.INSTITUTION_ID;

import io.smallrye.mutiny.Multi;
import it.pagopa.selfcare.onboarding.controller.response.InstitutionResponse;
import it.pagopa.selfcare.onboarding.entity.*;
import it.pagopa.selfcare.onboarding.util.QueryUtils;
import jakarta.enterprise.context.ApplicationScoped;
import java.util.*;

import org.bson.Document;
import org.jboss.logging.Logger;

@ApplicationScoped
public class InstitutionServiceDefault implements InstitutionService {

private static final Logger LOG = Logger.getLogger(InstitutionServiceDefault.class);

@Override
public Multi<InstitutionResponse> getInstitutions(List<String> institutionIds) {
if (Objects.isNull(institutionIds) || institutionIds.isEmpty()) {
LOG.error("The parameter institutionIds cannot be null or empty");
return Multi.createFrom().empty();
}
Map<String, Object> queryParameterMap = new HashMap<>();
queryParameterMap.put(INSTITUTION_ID, institutionIds);
Document query = QueryUtils.buildQuery(queryParameterMap);
return getDistinctOnboardings(query).onItem().transform(onboarding -> {
InstitutionResponse institutionResponse = new InstitutionResponse();
institutionResponse.setId(onboarding.getInstitution().getId());
institutionResponse.setInstitutionType(onboarding.getInstitution().getInstitutionType().name());
institutionResponse.setDescription(onboarding.getInstitution().getDescription());
return institutionResponse;
});
}

public Multi<Onboarding> getDistinctOnboardings(Document query) {
Set<String> seenInstitutionIds = new HashSet<>();
return Onboarding.find(query).stream().map(Onboarding.class::cast)
.filter(onboarding -> seenInstitutionIds.add(onboarding.getInstitution().getId()));
}
}
Original file line number Diff line number Diff line change
@@ -1,12 +1,18 @@
package it.pagopa.selfcare.onboarding.util;

import static it.pagopa.selfcare.onboarding.util.QueryUtils.FieldNames.*;

import com.mongodb.MongoClientSettings;
import com.mongodb.client.model.Filters;
import com.mongodb.client.model.Sorts;
import com.mongodb.client.model.Updates;
import it.pagopa.selfcare.onboarding.common.OnboardingStatus;
import it.pagopa.selfcare.onboarding.entity.Onboarding;
import it.pagopa.selfcare.onboarding.model.OnboardingGetFilters;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import org.apache.commons.lang3.StringUtils;
import org.bson.BsonDocument;
import org.bson.BsonDocumentReader;
Expand All @@ -15,19 +21,12 @@
import org.bson.codecs.DocumentCodec;
import org.bson.conversions.Bson;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;

import static it.pagopa.selfcare.onboarding.util.QueryUtils.FieldNames.*;

public class QueryUtils {

private QueryUtils() {
}

static class FieldNames {
public static class FieldNames {
private FieldNames() {
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
package it.pagopa.selfcare.onboarding.controller;

import static io.restassured.RestAssured.given;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertNotEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertNull;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.anyString;
import static org.mockito.Mockito.eq;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;

import io.quarkus.test.InjectMock;
import io.quarkus.test.common.QuarkusTestResource;
import io.quarkus.test.common.http.TestHTTPEndpoint;
import io.quarkus.test.junit.QuarkusTest;
import io.quarkus.test.mongodb.MongoTestResource;
import io.quarkus.test.security.TestSecurity;
import io.restassured.http.ContentType;
import io.restassured.response.Response;
import io.smallrye.mutiny.Multi;
import io.smallrye.mutiny.Uni;
import it.pagopa.selfcare.onboarding.common.InstitutionType;
import it.pagopa.selfcare.onboarding.common.OnboardingStatus;
import it.pagopa.selfcare.onboarding.common.Origin;
import it.pagopa.selfcare.onboarding.common.WorkflowType;
import it.pagopa.selfcare.onboarding.constants.CustomError;
import it.pagopa.selfcare.onboarding.controller.request.*;
import it.pagopa.selfcare.onboarding.controller.response.InstitutionResponse;
import it.pagopa.selfcare.onboarding.controller.response.OnboardingGet;
import it.pagopa.selfcare.onboarding.controller.response.OnboardingGetResponse;
import it.pagopa.selfcare.onboarding.controller.response.OnboardingResponse;
import it.pagopa.selfcare.onboarding.entity.Billing;
import it.pagopa.selfcare.onboarding.entity.CheckManagerResponse;
import it.pagopa.selfcare.onboarding.entity.Onboarding;
import it.pagopa.selfcare.onboarding.entity.OnboardingAggregationImportRequest;
import it.pagopa.selfcare.onboarding.exception.InvalidRequestException;
import it.pagopa.selfcare.onboarding.model.OnboardingGetFilters;
import it.pagopa.selfcare.onboarding.model.RecipientCodeStatus;
import it.pagopa.selfcare.onboarding.service.InstitutionService;
import it.pagopa.selfcare.onboarding.service.OnboardingService;
import java.io.File;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.ValueSource;
import org.mockito.ArgumentCaptor;
import org.mockito.Mockito;

@QuarkusTest
@TestHTTPEndpoint(InstitutionController.class)
@QuarkusTestResource(MongoTestResource.class)
class InstitutionControllerTest {

@InjectMock InstitutionService institutionService;

@Test
@TestSecurity(user = "userJwt")
void getInstitutions_withEmptyList() {

given()
.when()
.body(new GetInstitutionRequest())
.contentType(ContentType.JSON)
.post()
.then()
.statusCode(400);
}

@Test
@TestSecurity(user = "userJwt")
void getInstitutions() {
final String institutionId = "institutionId";
InstitutionResponse response = new InstitutionResponse();
response.setId(institutionId);
response.setInstitutionType(InstitutionType.GPU.name());

GetInstitutionRequest request = new GetInstitutionRequest();
request.setInstitutionIds(List.of(institutionId));

Mockito.when(institutionService.getInstitutions(any()))
.thenReturn(Multi.createFrom().item(response));

given().when().body(request).contentType(ContentType.JSON).post().then().statusCode(200);
}
}
Loading
Loading