Skip to content

Commit

Permalink
feat: audit is now dynamic to gtw-config
Browse files Browse the repository at this point in the history
  • Loading branch information
gb-cic committed Nov 30, 2023
1 parent d726608 commit 4d89559
Show file tree
Hide file tree
Showing 17 changed files with 258 additions and 106 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@
package it.finanze.sanita.fse2.ms.gtw.dispatcher.adapter;

import it.finanze.sanita.fse2.ms.gtw.dispatcher.config.audit.AuditManager;
import it.finanze.sanita.fse2.ms.gtw.dispatcher.service.IConfigSRV;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.core.MethodParameter;
import org.springframework.http.MediaType;
import org.springframework.http.converter.HttpMessageConverter;
Expand All @@ -29,29 +29,45 @@

@ControllerAdvice
@Slf4j
@ConditionalOnProperty("ms.dispatcher.audit.enabled")
public class CustomResponseBodyAdviceAdapter implements ResponseBodyAdvice<Object> {

@Autowired
private IConfigSRV config;

@Autowired
private AuditManager manager;

@Override
public boolean supports(MethodParameter methodParameter, Class<? extends HttpMessageConverter<?>> aClass) {
public boolean supports(MethodParameter param, Class<? extends HttpMessageConverter<?>> clazz) {
return true;
}

@Override
public Object beforeBodyWrite(Object o, MethodParameter methodParameter, MediaType mediaType,
Class<? extends HttpMessageConverter<?>> aClass, ServerHttpRequest serverHttpRequest, ServerHttpResponse serverHttpResponse) {
if (serverHttpRequest instanceof ServletServerHttpRequest && serverHttpResponse instanceof ServletServerHttpResponse) {
public Object beforeBodyWrite(
Object body,
MethodParameter param,
MediaType type,
Class<? extends HttpMessageConverter<?>> clazz,
ServerHttpRequest req,
ServerHttpResponse res
) {
if (
req instanceof ServletServerHttpRequest &&
res instanceof ServletServerHttpResponse
) {
try {
manager.process(((ServletServerHttpRequest) serverHttpRequest).getServletRequest(), o);
if (config.isAuditEnable()) {
// Cast to HTTP request
ServletServerHttpRequest out = (ServletServerHttpRequest) req;
// Invoke processor
manager.process(out.getServletRequest(), body);
}
} catch(Exception ex) {
log.error("Errore nel before body write ", ex);
throw new BusinessException("Errore nel before body write " + ex);
log.error("Unable to invoke before-body write ", ex);
throw new BusinessException("Unable to invoke before-body write " + ex);
}
}

return o;
return body;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,15 @@
*/
package it.finanze.sanita.fse2.ms.gtw.dispatcher.client;

import it.finanze.sanita.fse2.ms.gtw.dispatcher.enums.ConfigItemTypeEnum;

/**
* Interface of gtw-config Client.
*/
public interface IConfigClient {

String getGatewayName();

Boolean isAuditEnable(ConfigItemTypeEnum type, String props);

}
Original file line number Diff line number Diff line change
Expand Up @@ -11,21 +11,24 @@
*/
package it.finanze.sanita.fse2.ms.gtw.dispatcher.client.impl;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Component;
import org.springframework.web.client.HttpStatusCodeException;
import org.springframework.web.client.ResourceAccessException;
import org.springframework.web.client.RestTemplate;

import it.finanze.sanita.fse2.ms.gtw.dispatcher.client.IConfigClient;
import it.finanze.sanita.fse2.ms.gtw.dispatcher.client.impl.base.AbstractClient;
import it.finanze.sanita.fse2.ms.gtw.dispatcher.client.response.WhoIsResponseDTO;
import it.finanze.sanita.fse2.ms.gtw.dispatcher.client.routes.ConfigClientRoutes;
import it.finanze.sanita.fse2.ms.gtw.dispatcher.config.Constants;
import it.finanze.sanita.fse2.ms.gtw.dispatcher.config.MicroservicesURLCFG;
import it.finanze.sanita.fse2.ms.gtw.dispatcher.enums.ConfigItemTypeEnum;
import it.finanze.sanita.fse2.ms.gtw.dispatcher.exceptions.BusinessException;
import it.finanze.sanita.fse2.ms.gtw.dispatcher.utility.ProfileUtility;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Component;
import org.springframework.web.client.HttpStatusCodeException;
import org.springframework.web.client.ResourceAccessException;
import org.springframework.web.client.RestTemplate;

import static it.finanze.sanita.fse2.ms.gtw.dispatcher.client.routes.base.ClientRoutes.Config.PROPS_NAME_AUDIT_ENABLED;
import static it.finanze.sanita.fse2.ms.gtw.dispatcher.enums.ConfigItemTypeEnum.*;

/**
* Implementation of gtw-config Client.
Expand All @@ -35,31 +38,30 @@
public class ConfigClient extends AbstractClient implements IConfigClient {

@Autowired
private MicroservicesURLCFG msUrlCFG;
private ConfigClientRoutes routes;

@Autowired
private RestTemplate restTemplate;
private RestTemplate client;

@Autowired
private ProfileUtility profileUtility;
private ProfileUtility profiles;

@Override
public String getGatewayName() {
String gatewayName = null;
try {
log.debug("Config Client - Calling Config Client to get Gateway Name");
final String endpoint = msUrlCFG.getConfigHost() + Constants.Client.Config.WHOIS_PATH;
final String endpoint = routes.whois();

final boolean isTestEnvironment = profileUtility.isDevOrDockerProfile() || profileUtility.isTestProfile();
final boolean isTestEnvironment = profiles.isDevOrDockerProfile() || profiles.isTestProfile();

// Check if the endpoint is reachable
if (isTestEnvironment && !isReachable()) {
log.warn("Config Client - Config Client is not reachable, mocking for testing purpose");
return Constants.Client.Config.MOCKED_GATEWAY_NAME;
}

final ResponseEntity<WhoIsResponseDTO> response = restTemplate.getForEntity(endpoint,
WhoIsResponseDTO.class);
final ResponseEntity<WhoIsResponseDTO> response = client.getForEntity(endpoint, WhoIsResponseDTO.class);

WhoIsResponseDTO body = response.getBody();

Expand All @@ -82,14 +84,30 @@ public String getGatewayName() {
return gatewayName;
}

@Override
public Boolean isAuditEnable(ConfigItemTypeEnum type, String props) {
boolean out = false;

String endpoint = routes.getConfigItem(GENERIC, PROPS_NAME_AUDIT_ENABLED);
log.debug("{} - Executing request: {}", routes.identifier(), endpoint);

if(isReachable()){
ResponseEntity<String> response = client.getForEntity(endpoint, String.class);
out = Boolean.parseBoolean(response.getBody());
}

return out;
}

private boolean isReachable() {
boolean out;
try {
final String endpoint = msUrlCFG.getConfigHost() + Constants.Client.Config.STATUS_PATH;
restTemplate.getForEntity(endpoint, String.class);
return true;
} catch (ResourceAccessException clientException) {
return false;
client.getForEntity(routes.status(), String.class);
out = true;
} catch (ResourceAccessException ex) {
out = false;
}
return out;
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
/*
* SPDX-License-Identifier: AGPL-3.0-or-later
*
* Copyright (C) 2023 Ministero della Salute
*
* This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package it.finanze.sanita.fse2.ms.gtw.dispatcher.client.routes;

import it.finanze.sanita.fse2.ms.gtw.dispatcher.enums.ConfigItemTypeEnum;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.web.util.UriComponentsBuilder;

import static it.finanze.sanita.fse2.ms.gtw.dispatcher.client.routes.base.ClientRoutes.Config.*;


@Component
public final class ConfigClientRoutes {

@Value("${ms.url.gtw-config}")
private String host;

public UriComponentsBuilder base() {
return UriComponentsBuilder.fromHttpUrl(host);
}

public String identifier() {
return IDENTIFIER;
}

public String microservice() {
return IDENTIFIER_MS;
}

public String status() {
return base()
.pathSegment(API_STATUS)
.build()
.toUriString();
}

public String whois() {
return base()
.pathSegment(API_WHOIS)
.build()
.toUriString();
}

public String getConfigItem(ConfigItemTypeEnum type, String props) {
return base()
.pathSegment(API_VERSION, API_CONFIG_ITEMS, API_PROPS)
.queryParam(QP_TYPE, type.name())
.queryParam(QP_PROPS, props)
.build()
.toUriString();
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -11,18 +11,18 @@
*/
package it.finanze.sanita.fse2.ms.gtw.dispatcher.client.routes.base;

import lombok.NoArgsConstructor;

import static lombok.AccessLevel.PRIVATE;

@NoArgsConstructor(access = PRIVATE)
public final class ClientRoutes {

private ClientRoutes() {}

@NoArgsConstructor(access = PRIVATE)
public static final class Ini {

private Ini() {}
// COMMON
public static final String IDENTIFIER_MS = "ini";
public static final String IDENTIFIER = "[INI]";
// PATH PARAMS
public static final String ID_DOC_PATH_PARAM = "{id}";
// ENDPOINT
public static final String API_VERSION = "v1";
public static final String DELETE_PATH = "ini-delete";
Expand All @@ -31,4 +31,23 @@ private Ini() {}
public static final String METADATA_PATH = "get-merged-metadati";
}

@NoArgsConstructor(access = PRIVATE)
public static final class Config {
// COMMON
public static final String IDENTIFIER_MS = "cfg";
public static final String IDENTIFIER = "[CFG]";
// ENDPOINT
public static final String API_VERSION = "v1";
public static final String API_CONFIG_ITEMS = "config-items";
public static final String API_PROPS = "props";
public static final String API_STATUS = "status";
public static final String API_WHOIS = "whois";
// QP
public static final String QP_TYPE = "type";
public static final String QP_PROPS = "props";
// VALUES
public static final String PROPS_NAME_AUDIT_ENABLED = "audit-enabled";

}

}
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,10 @@
*/
package it.finanze.sanita.fse2.ms.gtw.dispatcher.config;

import lombok.NoArgsConstructor;

import static lombok.AccessLevel.PRIVATE;

/**
* Constants application.
*/
Expand Down Expand Up @@ -84,18 +88,14 @@ public static final class App {

public static final String BEARER_PREFIX = "Bearer ";
public static final String SHA_ERROR = "Errore in fase di calcolo SHA-256";
public static final String HOST_ERROR = "Error while retrieving host informations";
public static final String SHA_ALGORITHM = "SHA-256";
public static final String JWT_MISSING_ISSUER_PLACEHOLDER = "UNDEFINED_JWT_ISSUER";
public static final String JWT_MISSING_SUBJECT_ROLE = "UNDEFINED_SUBJECT_ROLE";
public static final String JWT_MISSING_SUBJECT = "UNDEFINED_SUBJECT";
public static final String JWT_MISSING_LOCALITY = "UNDEFINED_LOCALITY";


public static final String MISSING_WORKFLOW_PLACEHOLDER = "UNKNOWN_WORKFLOW_ID";
public static final String MISSING_DOC_TYPE_PLACEHOLDER = "UNKNOWN_DOCUMENT_TYPE";

public static final String LOG_TYPE_KPI = "kpi-structured-log";
public static final String LOG_TYPE_CONTROL = "control-structured-log";
public static final int MAX_SIZE_WARNING = 200000;

Expand Down Expand Up @@ -141,34 +141,16 @@ private Misc() {
public static final class Client {

private Client() {}

public static final class Ini {

private Ini() {}

public static final String DELETE_PATH = "/v1/ini-delete";
public static final String UPDATE_PATH = "/v1/ini-update";
public static final String REFERENCE_PATH = "/v1/get-reference/{idDoc}";


}

@NoArgsConstructor(access = PRIVATE)
public static final class Eds {

private Eds() {}
public static final String DELETE_PATH = "/v1/documents/{idDoc}";
public static final String UPDATE_PATH = "/v1/documents/{idDoc}/metadata";
public static final String ID_DOC_PLACEHOLDER = "{idDoc}";
}

@NoArgsConstructor(access = PRIVATE)
public static final class Config {

private Config() {}

public static final String WHOIS_PATH = "/v1/whois";

public static final String STATUS_PATH = "/status";

public static final String MOCKED_GATEWAY_NAME = "mocked-gateway";
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,23 +12,22 @@
package it.finanze.sanita.fse2.ms.gtw.dispatcher.config;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

import it.finanze.sanita.fse2.ms.gtw.dispatcher.interceptor.LogInterceptor;

@Configuration
@ConditionalOnProperty("ms.dispatcher.audit.enabled")
public class WebCFG implements WebMvcConfigurer {

@Autowired
private LogInterceptor logInterceptor;

@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(logInterceptor);
registry.addInterceptor(logInterceptor);
}

}

Loading

0 comments on commit 4d89559

Please sign in to comment.