From 8569129a6ca4c730b065396abcd65db070eb225d Mon Sep 17 00:00:00 2001 From: alisihab Date: Thu, 13 Jul 2023 16:19:52 +0200 Subject: [PATCH] Put zgw database logging back (#354) --- .../logging/LoggingRequestInterceptor.java | 52 +++++++++ .../impl/logging/LoggingRestTemplate.java | 45 ++++++++ .../logging/RequestResponseCycleService.java | 9 +- .../logging/RestTemplateConfiguration.java | 28 +++++ .../impl/logging/ZgwRequestResponseCycle.java | 102 ++++++++++++++++++ .../ZgwRequestResponseCycleRepository.java | 23 ++++ 6 files changed, 258 insertions(+), 1 deletion(-) create mode 100644 src/main/java/nl/haarlem/translations/zdstozgw/requesthandler/impl/logging/LoggingRequestInterceptor.java create mode 100644 src/main/java/nl/haarlem/translations/zdstozgw/requesthandler/impl/logging/LoggingRestTemplate.java create mode 100644 src/main/java/nl/haarlem/translations/zdstozgw/requesthandler/impl/logging/RestTemplateConfiguration.java create mode 100644 src/main/java/nl/haarlem/translations/zdstozgw/requesthandler/impl/logging/ZgwRequestResponseCycle.java create mode 100644 src/main/java/nl/haarlem/translations/zdstozgw/requesthandler/impl/logging/ZgwRequestResponseCycleRepository.java diff --git a/src/main/java/nl/haarlem/translations/zdstozgw/requesthandler/impl/logging/LoggingRequestInterceptor.java b/src/main/java/nl/haarlem/translations/zdstozgw/requesthandler/impl/logging/LoggingRequestInterceptor.java new file mode 100644 index 00000000..3d596b1e --- /dev/null +++ b/src/main/java/nl/haarlem/translations/zdstozgw/requesthandler/impl/logging/LoggingRequestInterceptor.java @@ -0,0 +1,52 @@ +package nl.haarlem.translations.zdstozgw.requesthandler.impl.logging; + +import java.io.IOException; +import java.io.UnsupportedEncodingException; + +import org.springframework.http.HttpRequest; +import org.springframework.http.client.ClientHttpRequestExecution; +import org.springframework.http.client.ClientHttpRequestInterceptor; +import org.springframework.http.client.ClientHttpResponse; +import org.springframework.web.context.request.RequestAttributes; +import org.springframework.web.context.request.RequestContextHolder; + +import nl.haarlem.translations.zdstozgw.config.SpringContext; + +public class LoggingRequestInterceptor implements ClientHttpRequestInterceptor { + + private RequestResponseCycleService requestResponseCycleService; + private ZgwRequestResponseCycle currentInterimRequestResponseCycle; +// private String referentienummer; + + @Override + public ClientHttpResponse intercept(HttpRequest request, byte[] body, ClientHttpRequestExecution execution) + throws IOException { + this.requestResponseCycleService = SpringContext.getBean(RequestResponseCycleService.class); + addRequestToDatabase(request, body); + ClientHttpResponse response = execution.execute(request, body); + addResponseToDatabase(response); + return response; + } + + private void addRequestToDatabase(HttpRequest request, byte[] body) throws UnsupportedEncodingException { + String referentienummer = (String) RequestContextHolder.getRequestAttributes().getAttribute("referentienummer", + RequestAttributes.SCOPE_REQUEST); + this.currentInterimRequestResponseCycle = new ZgwRequestResponseCycle(referentienummer, request, body); + //this.requestResponseCycleService.add(this.currentInterimRequestResponseCycle); + } + + private void addResponseToDatabase(ClientHttpResponse response) throws IOException { + // Added to prevent us from: + // org.springframework.orm.jpa.JpaSystemException: identifier of an instance of + // nl.haarlem.translations.zdstozgw.requesthandler.impl.logging.ZgwRequestResponseCycle + // was altered from 133274 to 133275; nested exception is org.hibernate.HibernateException: + // identifier of an instance of nl.haarlem.translations.zdstozgw.requesthandler.impl.logging.ZgwRequestResponseCycle + // was altered from 133274 to 133275 + //ZgwRequestResponseCycle existingRecordRef = this.requestResponseCycleService + // .getZgwRequestResponseCycleRepository() + // .findById(this.currentInterimRequestResponseCycle.getId()) + // .orElse(this.currentInterimRequestResponseCycle); + currentInterimRequestResponseCycle.setResponse(response); + this.requestResponseCycleService.add(currentInterimRequestResponseCycle); + } +} \ No newline at end of file diff --git a/src/main/java/nl/haarlem/translations/zdstozgw/requesthandler/impl/logging/LoggingRestTemplate.java b/src/main/java/nl/haarlem/translations/zdstozgw/requesthandler/impl/logging/LoggingRestTemplate.java new file mode 100644 index 00000000..e766c725 --- /dev/null +++ b/src/main/java/nl/haarlem/translations/zdstozgw/requesthandler/impl/logging/LoggingRestTemplate.java @@ -0,0 +1,45 @@ +package nl.haarlem.translations.zdstozgw.requesthandler.impl.logging; + +import java.security.cert.X509Certificate; + +import javax.net.ssl.SSLContext; + +import org.apache.http.conn.ssl.SSLConnectionSocketFactory; +import org.apache.http.conn.ssl.TrustStrategy; +import org.apache.http.impl.client.CloseableHttpClient; +import org.apache.http.impl.client.HttpClients; +import org.springframework.boot.web.client.RestTemplateCustomizer; +import org.springframework.http.client.BufferingClientHttpRequestFactory; +import org.springframework.http.client.HttpComponentsClientHttpRequestFactory; +import org.springframework.web.client.RestTemplate; + +public class LoggingRestTemplate implements RestTemplateCustomizer { + + public LoggingRestTemplate() { + } + + @Override + public void customize(RestTemplate restTemplate) { + restTemplate.setRequestFactory(new BufferingClientHttpRequestFactory(this.getAllCertsTrustingRequestFactory())); + restTemplate.getInterceptors().add(new LoggingRequestInterceptor()); + } + + private HttpComponentsClientHttpRequestFactory getAllCertsTrustingRequestFactory() { + TrustStrategy acceptingTrustStrategy = (X509Certificate[] chain, String authType) -> true; + + SSLContext sslContext = null; + try { + sslContext = org.apache.http.ssl.SSLContexts.custom().loadTrustMaterial(null, acceptingTrustStrategy) + .build(); + } catch (Exception ex) { + } + + SSLConnectionSocketFactory csf = new SSLConnectionSocketFactory(sslContext); + CloseableHttpClient httpClient = HttpClients.custom().setSSLSocketFactory(csf).build(); + + HttpComponentsClientHttpRequestFactory requestFactory = new HttpComponentsClientHttpRequestFactory(); + + requestFactory.setHttpClient(httpClient); + return requestFactory; + } +} diff --git a/src/main/java/nl/haarlem/translations/zdstozgw/requesthandler/impl/logging/RequestResponseCycleService.java b/src/main/java/nl/haarlem/translations/zdstozgw/requesthandler/impl/logging/RequestResponseCycleService.java index c6fa2c29..4826519e 100644 --- a/src/main/java/nl/haarlem/translations/zdstozgw/requesthandler/impl/logging/RequestResponseCycleService.java +++ b/src/main/java/nl/haarlem/translations/zdstozgw/requesthandler/impl/logging/RequestResponseCycleService.java @@ -1,5 +1,5 @@ /* - * Copyright 2020-2021 The Open Zaakbrug Contributors + * Copyright 2020-2023 The Open Zaakbrug Contributors * * Licensed under the EUPL, Version 1.2 or – as soon they will be approved by the * European Commission - subsequent versions of the EUPL (the "Licence"); @@ -26,12 +26,15 @@ public class RequestResponseCycleService { private final RequestResponseCycleRepository requestResponseCycleRepository; + private final ZgwRequestResponseCycleRepository zgwRequestResponseCycleRepository; private final ZdsRequestResponseCycleRepository zdsRequestResponseCycleRepository; @Autowired public RequestResponseCycleService(RequestResponseCycleRepository requestResponseCycleRepository, + ZgwRequestResponseCycleRepository zgwRequestResponseCycleRepository, ZdsRequestResponseCycleRepository zdsRequestResponseCycleRepository) { this.requestResponseCycleRepository = requestResponseCycleRepository; + this.zgwRequestResponseCycleRepository = zgwRequestResponseCycleRepository; this.zdsRequestResponseCycleRepository = zdsRequestResponseCycleRepository; } @@ -42,4 +45,8 @@ public RequestResponseCycle save(RequestResponseCycle requestResponseCycle) { public ZdsRequestResponseCycle add(ZdsRequestResponseCycle interimRequestResponseCycle) { return this.zdsRequestResponseCycleRepository.save(interimRequestResponseCycle); } + + public ZgwRequestResponseCycle add(ZgwRequestResponseCycle interimRequestResponseCycle) { + return this.zgwRequestResponseCycleRepository.save(interimRequestResponseCycle); + } } diff --git a/src/main/java/nl/haarlem/translations/zdstozgw/requesthandler/impl/logging/RestTemplateConfiguration.java b/src/main/java/nl/haarlem/translations/zdstozgw/requesthandler/impl/logging/RestTemplateConfiguration.java new file mode 100644 index 00000000..9a35e26a --- /dev/null +++ b/src/main/java/nl/haarlem/translations/zdstozgw/requesthandler/impl/logging/RestTemplateConfiguration.java @@ -0,0 +1,28 @@ +/* + * Copyright 2020,2023 The Open Zaakbrug Contributors + * + * Licensed under the EUPL, Version 1.2 or – as soon they will be approved by the + * European Commission - subsequent versions of the EUPL (the "Licence"); + * + * You may not use this work except in compliance with the Licence. + * You may obtain a copy of the Licence at: + * + * https://joinup.ec.europa.eu/software/page/eupl5 + * + * Unless required by applicable law or agreed to in writing, software distributed under the Licence is distributed on an "AS IS" basis, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the Licence for the specific language governing permissions and limitations under the Licence. + */ +package nl.haarlem.translations.zdstozgw.requesthandler.impl.logging; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +@Configuration +public class RestTemplateConfiguration { + + @Bean + public LoggingRestTemplate customRestTemplateCustomizer() { + return new LoggingRestTemplate(); + } +} \ No newline at end of file diff --git a/src/main/java/nl/haarlem/translations/zdstozgw/requesthandler/impl/logging/ZgwRequestResponseCycle.java b/src/main/java/nl/haarlem/translations/zdstozgw/requesthandler/impl/logging/ZgwRequestResponseCycle.java new file mode 100644 index 00000000..4f8e20dd --- /dev/null +++ b/src/main/java/nl/haarlem/translations/zdstozgw/requesthandler/impl/logging/ZgwRequestResponseCycle.java @@ -0,0 +1,102 @@ +/* + * Copyright 2020-2023 The Open Zaakbrug Contributors + * + * Licensed under the EUPL, Version 1.2 or – as soon they will be approved by the + * European Commission - subsequent versions of the EUPL (the "Licence"); + * + * You may not use this work except in compliance with the Licence. + * You may obtain a copy of the Licence at: + * + * https://joinup.ec.europa.eu/software/page/eupl5 + * + * Unless required by applicable law or agreed to in writing, software distributed under the Licence is distributed on an "AS IS" basis, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the Licence for the specific language governing permissions and limitations under the Licence. + */ +package nl.haarlem.translations.zdstozgw.requesthandler.impl.logging; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStreamReader; +import java.io.UnsupportedEncodingException; +import java.time.Duration; +import java.time.LocalDateTime; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.Id; +import javax.persistence.Index; +import javax.persistence.Table; + +import org.springframework.http.HttpRequest; +import org.springframework.http.client.ClientHttpResponse; + +import lombok.Data; + +@Data +@Entity +@Table(indexes = @Index(columnList = "referentienummer")) +public class ZgwRequestResponseCycle { + @Id + @GeneratedValue + private long id; + private String referentienummer; + + private LocalDateTime startdatetime; + private LocalDateTime stopdatetime; + private Long durationInMilliseconds; + + private String zgwMethod; + @Column(columnDefinition="TEXT") + private String zgwUrl; + @Column(columnDefinition="TEXT", name = "zgw_request_body") + private String zgwShortenedRequestBody; + private Integer zgwRequestSize; + + private int zgwResponseCode; + @Column(columnDefinition="TEXT", name = "zgw_response_body") + private String zgwShortenedResponseBody; + private Integer zgwResponseSize; + + public ZgwRequestResponseCycle() { + startdatetime = LocalDateTime.now(); + }; + + public ZgwRequestResponseCycle(String referentienummer, HttpRequest request, byte[] body) throws UnsupportedEncodingException { + this.referentienummer = referentienummer; + this.zgwMethod = request.getMethodValue(); + this.zgwUrl = request.getURI().toString(); + + var message = new String(body, "UTF-8"); + this.zgwRequestSize = message.length(); + this.zgwShortenedRequestBody = message; + + startdatetime = LocalDateTime.now(); + } + + public long getDurationInMilliseconds() { + var milliseconds = Duration.between(startdatetime, LocalDateTime.now()).toMillis(); + return milliseconds; + } + + public void setResponse(ClientHttpResponse response) throws UnsupportedEncodingException, IOException { + this.zgwResponseCode = response.getStatusCode().value(); + + StringBuilder inputStringBuilder = new StringBuilder(); + BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(response.getBody(), "UTF-8")); + String line = bufferedReader.readLine(); + while (line != null) { + line = line.replaceAll("\u0000", ""); + inputStringBuilder.append(line); + inputStringBuilder.append('\n'); + line = bufferedReader.readLine(); + } + var message = inputStringBuilder.toString(); + this.zgwResponseSize = message.length(); + this.zgwShortenedResponseBody = message; + + this.stopdatetime = LocalDateTime.now(); + this.durationInMilliseconds = Duration.between(startdatetime, stopdatetime).toMillis(); + } +} \ No newline at end of file diff --git a/src/main/java/nl/haarlem/translations/zdstozgw/requesthandler/impl/logging/ZgwRequestResponseCycleRepository.java b/src/main/java/nl/haarlem/translations/zdstozgw/requesthandler/impl/logging/ZgwRequestResponseCycleRepository.java new file mode 100644 index 00000000..41ea70d8 --- /dev/null +++ b/src/main/java/nl/haarlem/translations/zdstozgw/requesthandler/impl/logging/ZgwRequestResponseCycleRepository.java @@ -0,0 +1,23 @@ +/* + * Copyright 2020-2023 The Open Zaakbrug Contributors + * + * Licensed under the EUPL, Version 1.2 or – as soon they will be approved by the + * European Commission - subsequent versions of the EUPL (the "Licence"); + * + * You may not use this work except in compliance with the Licence. + * You may obtain a copy of the Licence at: + * + * https://joinup.ec.europa.eu/software/page/eupl5 + * + * Unless required by applicable law or agreed to in writing, software distributed under the Licence is distributed on an "AS IS" basis, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the Licence for the specific language governing permissions and limitations under the Licence. + */ +package nl.haarlem.translations.zdstozgw.requesthandler.impl.logging; + +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.stereotype.Repository; + +@Repository +public interface ZgwRequestResponseCycleRepository extends JpaRepository { +} \ No newline at end of file