Skip to content

Commit

Permalink
feat: [SRTP-81] setup controller and model generation (#20)
Browse files Browse the repository at this point in the history
  • Loading branch information
lucaconsalvi authored Nov 29, 2024
1 parent ecf5ed8 commit 9f7cd25
Show file tree
Hide file tree
Showing 32 changed files with 570 additions and 73 deletions.
23 changes: 18 additions & 5 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ plugins {
id 'org.springframework.boot' version '3.3.5'
id 'io.spring.dependency-management' version '1.1.6'
id 'org.graalvm.buildtools.native' version '0.10.3'
id("org.openapi.generator") version "7.5.0"
id("org.openapi.generator") version "7.10.0"
id "org.sonarqube" version "6.0.0.5145"
id 'jacoco'
}
Expand All @@ -29,16 +29,14 @@ ext {
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-actuator'
implementation 'org.springframework.boot:spring-boot-starter-webflux'
implementation 'org.springframework.boot:spring-boot-starter-data-mongodb-reactive'

// spring security + oauth2 resource server
// spring security + oauth2 resource server
implementation 'org.springframework.boot:spring-boot-starter-security'
implementation 'org.springframework.boot:spring-boot-starter-oauth2-resource-server'
implementation 'org.springframework.security:spring-security-oauth2-jose'

implementation("org.springframework.boot:spring-boot-starter-actuator")

// implementation 'com.azure.spring:spring-cloud-azure-starter-actuator'
// implementation 'com.azure.spring:spring-cloud-azure-starter-data-cosmos'
implementation("io.swagger.core.v3:swagger-annotations:2.2.8")
implementation("org.openapitools:jackson-databind-nullable:0.2.6")
implementation("com.fasterxml.jackson.datatype:jackson-datatype-jsr310")
Expand All @@ -53,6 +51,8 @@ dependencies {
testImplementation 'org.springframework.security:spring-security-test'
testImplementation 'io.projectreactor:reactor-test'
testRuntimeOnly 'org.junit.platform:junit-platform-launcher'
annotationProcessor("org.projectlombok:lombok")
compileOnly("org.projectlombok:lombok")
}

dependencyManagement {
Expand Down Expand Up @@ -107,6 +107,7 @@ openApiGenerate {
])
}


graalvmNative {
binaries {
main {
Expand All @@ -116,6 +117,17 @@ graalvmNative {
}
}

bootRun {
jvmArgs = [
'-Djava.security.properties=src/main/resources/custom.security'
]
}

tasks.withType(JavaExec) {
jvmArgs += '-Djava.security.properties=src/main/resources/custom.security'
}


test {
finalizedBy jacocoTestReport // report is always generated after tests run
}
Expand All @@ -134,3 +146,4 @@ sonarqube {
property 'sonar.projectKey', 'pagopa_rtp-activator'
}
}

45 changes: 32 additions & 13 deletions openapi/activation.openapi.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -450,6 +450,14 @@ components:
# --------------------------------------------------------------------------
# Domain specific basic types.
# --------------------------------------------------------------------------
Bic:
description: Bank Identification Code.
type: string
pattern: "^[A-Z0-9]{4}[A-Z]{2}[A-Z0-9]{2}([A-Z0-9]{3}){0,1}$"
minLength: 8
maxLength: 11
example: "UNCRITMM"

EffectiveActivationDate:
description: |
Effective activation date (B035).
Expand All @@ -461,7 +469,7 @@ components:

FiscalCode:
description: |
Fiscal (or tax) code.
Fiscal code.
It is used as identifier of the Payer (P009) and of the Payee (E005).
type: string
Expand All @@ -470,17 +478,28 @@ components:
maxLength: 16
example: "RSSMRA85T10A562S"

Lei:
description: |
Legal Entity Identifier is a code allocated to a party as described in
ISO 17442 "Financial Services - Legal Entity Identifier (LEI)".
type: string
pattern: "^[A-Z0-9]{18}[0-9]{2}$"
minLength: 20
maxLength: 20
example: "984500A9EB6B07AC2G71"

PartyId:
description: |
Unique and unambiguous identification of a party.
It is used as identifier of the Payer’s RTP Service Provider (N001) and
for Payee’s RTP Service Provider (N002).
It is used as identifier of the Payer's RTP Service Provider (N001) and
for Payee's RTP Service Provider (N002).
A Service Provider is identified by its BIC (Bank Identification Code)
if it is a PSP, otherwise it is identified by its LEI (Legal Entity
Identifier).
type: string
pattern: "^[ -~]{1,35}$"
minLength: 1
maxLength: 35
example: "12345678901"
pattern: "(^([A-Z0-9]{4}[A-Z]{2}[A-Z0-9]{2}([A-Z0-9]{3}){0,1})$)|(^[A-Z0-9]{18}[0-9]{2}$)"

# --------------------------------------------------------------------------
# Complex types for paging.
Expand Down Expand Up @@ -566,7 +585,7 @@ components:
effectiveActivationDate: "2024-10-30T16:39:34+01:00"
payer:
fiscalCode: "RSSMRA85T10A562S"
rtpSpId: "10987654321"
rtpSpId: "984500A9EB6B07AC2G71"

Activations:
description: List of RTP activations.
Expand All @@ -580,7 +599,7 @@ components:
effectiveActivationDate: "2024-10-30T16:39:34+01:00"
payer:
fiscalCode: "RSSMRA85T10A562S"
rtpSpId: "10987654321"
rtpSpId: "984500A9EB6B07AC2G71"

ActivationReq:
description: |
Expand All @@ -595,7 +614,7 @@ components:
example:
payer:
fiscalCode: "RSSMRA85T10A562S"
rtpSpId: "10987654321"
rtpSpId: "984500A9EB6B07AC2G71"

PageOfActivations:
description: Page of RTP activations.
Expand All @@ -615,7 +634,7 @@ components:
effectiveActivationDate: "2024-10-30T16:39:34+01:00"
payer:
fiscalCode: "RSSMRA85T10A562S"
rtpSpId: "10987654321"
rtpSpId: "984500A9EB6B07AC2G71"
page:
totalElements: 2
totalPages: 2
Expand All @@ -637,7 +656,7 @@ components:
- rtpSpId
example:
fiscalCode: "RSSMRA85T10A562S"
rtpSpId: "10987654321"
rtpSpId: "984500A9EB6B07AC2G71"

# ============================================================================
# Request bodies.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,17 @@

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.context.properties.ConfigurationPropertiesScan;

import reactor.core.publisher.Hooks;

@SpringBootApplication
@ConfigurationPropertiesScan()
public class RtpActivatorApplication {

public static void main(String[] args) {
Hooks.enableAutomaticContextPropagation();
SpringApplication.run(RtpActivatorApplication.class, args);
}

}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package it.gov.pagopa.rtp.activator.configuration;

import org.springframework.boot.context.properties.ConfigurationProperties;

import lombok.Getter;
import lombok.Setter;

@ConfigurationProperties(prefix = "activation")
@Getter
@Setter
public class ActivationPropertiesConfig{
private String baseUrl;

public ActivationPropertiesConfig(String baseUrl){
this.baseUrl = baseUrl;
}
}
Original file line number Diff line number Diff line change
@@ -1,32 +1,53 @@
package it.gov.pagopa.rtp.activator.controller;

import it.gov.pagopa.rtp.activator.controller.generated.CreateApi;
import it.gov.pagopa.rtp.activator.model.generated.ActivationReqDto;
import java.util.UUID;

import org.springframework.http.ResponseEntity;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.server.ServerWebExchange;

import it.gov.pagopa.rtp.activator.configuration.ActivationPropertiesConfig;
import it.gov.pagopa.rtp.activator.controller.generated.CreateApi;
import it.gov.pagopa.rtp.activator.domain.errors.PayerAlreadyExists;
import it.gov.pagopa.rtp.activator.model.generated.ActivationReqDto;
import it.gov.pagopa.rtp.activator.service.ActivationPayerService;
import reactor.core.publisher.Mono;

import org.springframework.security.access.prepost.PreAuthorize;

import java.net.URI;
import java.util.UUID;

import static it.gov.pagopa.rtp.activator.utils.Authorizations.verifySubjectRequest;

@RestController
@Validated
public class ActivationAPIControllerImpl implements CreateApi {

private final ActivationPayerService activationPayerService;

private final ActivationPropertiesConfig activationPropertiesConfig;

public ActivationAPIControllerImpl(ActivationPayerService activationPayerService,
ActivationPropertiesConfig activationPropertiesConfig) {
this.activationPayerService = activationPayerService;
this.activationPropertiesConfig = activationPropertiesConfig;
}

@Override
@PreAuthorize("hasRole('write_rtp_activations')")
public Mono<ResponseEntity<Void>> activate(
UUID requestId,
String version,
Mono<ActivationReqDto> activationReqDto,
ServerWebExchange exchange
) {
ServerWebExchange exchange) {

return verifySubjectRequest(activationReqDto, it -> it.getPayer().getRtpSpId())
.map(request -> ResponseEntity.created(URI.create("http://localhost")).build());
.flatMap(t -> activationPayerService.activatePayer(t.getPayer().getRtpSpId(),
t.getPayer().getFiscalCode()))
.<ResponseEntity<Void>>map(payer -> ResponseEntity
.created(URI.create(activationPropertiesConfig.getBaseUrl() + payer.payerID().toString()))
.build())
.onErrorReturn(PayerAlreadyExists.class, ResponseEntity.status(409).build());
}
}
6 changes: 6 additions & 0 deletions src/main/java/it/gov/pagopa/rtp/activator/domain/Payer.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package it.gov.pagopa.rtp.activator.domain;

import java.time.Instant;

public record Payer(PayerID payerID, String rtpSpId, String fiscalCode, Instant effectiveActivationDate) {
}
21 changes: 21 additions & 0 deletions src/main/java/it/gov/pagopa/rtp/activator/domain/PayerID.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package it.gov.pagopa.rtp.activator.domain;

import java.util.UUID;

import lombok.Getter;

@Getter
public class PayerID {

private final UUID id;

public PayerID(UUID uuid) {
this.id = uuid;
}

public static PayerID createNew() {
UUID uuid = UUID.randomUUID();
return new PayerID(uuid);
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package it.gov.pagopa.rtp.activator.domain;


import reactor.core.publisher.Mono;

public interface PayerRepository {

// Used to check if a specific payer is already registered.
Mono<Payer> findByFiscalCode(String fiscalCode);

Mono<Payer> save(Payer payer);

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package it.gov.pagopa.rtp.activator.domain.errors;

public class PayerAlreadyExists extends Throwable{
// You can insert here payer info.
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package it.gov.pagopa.rtp.activator.repository;



import org.springframework.data.mongodb.repository.ReactiveMongoRepository;
import org.springframework.stereotype.Repository;

import reactor.core.publisher.Mono;

@Repository
public interface ActivationDB extends ReactiveMongoRepository<ActivationEntity, String> {
Mono<ActivationEntity> findByFiscalCode(String fiscalCode);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package it.gov.pagopa.rtp.activator.repository;


import org.springframework.stereotype.Repository;

import it.gov.pagopa.rtp.activator.domain.Payer;
import it.gov.pagopa.rtp.activator.domain.PayerRepository;
import reactor.core.publisher.Mono;

@Repository
public class ActivationDBRepository implements PayerRepository {

private final ActivationDB activationDB;
private final ActivationMapper activationMapper;

public ActivationDBRepository(ActivationDB activationDB,
ActivationMapper activationMapper) {
this.activationDB = activationDB;
this.activationMapper = activationMapper;
}

@Override
public Mono<Payer> findByFiscalCode(String fiscalCode) {
return activationDB.findByFiscalCode(fiscalCode)
.map(activationMapper::toDomain);
}

@Override
public Mono<Payer> save(Payer payer) {
return activationDB.save(activationMapper.toDbEntity(payer)).map(activationMapper::toDomain);
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package it.gov.pagopa.rtp.activator.repository;

import java.time.Instant;

import org.springframework.data.annotation.Id;
import org.springframework.data.mongodb.core.mapping.Document;

import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;

@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
@Document("activations")
public class ActivationEntity {
@Id
private String id;
private String rtpSpId;
private Instant effectiveActivationDate;

private String fiscalCode;
}
Loading

0 comments on commit 9f7cd25

Please sign in to comment.