From efd144610b422faedea54ced34fcb7fbb6d774e6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20Skj=C3=B8lberg?= Date: Mon, 19 Jan 2026 19:07:37 +0100 Subject: [PATCH 01/20] Spring Boot 4 support --- azure/README.md | 16 +++---- .../build.gradle | 2 +- .../AzureServiceContextJsonProvider.java | 6 +-- .../azure/micrometer/AzureLogbackMetrics.java | 4 -- .../micrometer/AzureMetricsTurboFilter.java | 4 -- .../build.gradle | 8 ++-- ...ureGrpcEcosystemTestAutoConfiguration.java | 4 +- ...ot.autoconfigure.AutoConfiguration.imports | 0 .../logbook/web/test/DemoApplication.java | 0 .../web/test/LoadContextLoggingTest.java | 0 .../README.md | 0 .../build.gradle | 4 +- ...seAzureGrpcEcosystemAutoConfiguration.java | 3 -- ...ot.autoconfigure.AutoConfiguration.imports | 0 .../build.gradle | 2 +- .../test/LogSeveritySyntaxHighlighter.java | 4 +- .../LogSeveritySyntaxHighlighterFactory.java | 12 ++--- .../resources/logback/logback-spring-test.xml | 5 +- .../build.gradle | 0 .../build.gradle | 2 +- ...EcosystemGrpcLoggingAutoConfiguration.java | 0 ...ot.autoconfigure.AutoConfiguration.imports | 0 build.gradle | 16 +++---- .../README.md | 2 +- .../build.gradle | 14 +++--- .../example/AbstractGreetingController.java | 0 .../grpc/azure/example/DemoApplication.java | 0 .../azure/example/GreetingController.java | 4 +- ...GreetingControllerWithOnDemandLogging.java | 5 +- .../grpc/azure/example/MyGrpcConfig.java | 0 .../MyValidationServerInterceptor.java | 0 .../src/main/proto/greeting_message.proto | 0 .../src/main/proto/greeting_service.proto | 0 .../src/main/resources/application.properties | 0 .../example/SpringAbstractGrpcTest.java} | 6 +-- .../azure/example/SpringGreetingTest.java} | 2 +- .../example/SpringGrpcLoggingFormatTest.java} | 2 +- .../SpringOndemandGrpcLoggingFormatTest.java} | 2 +- ...gOndemandGrpcLoggingHighLogLevelTest.java} | 2 +- examples/azure-web-example/build.gradle | 6 ++- .../example/web/config/WebSecurityConfig.java | 2 +- .../example/web/rest/DocumentEndpoint.java | 10 ++-- .../OndemandWebLoggingHttpBadRequestTest.java | 4 +- .../OndemandWebLoggingHttpNotFound1Test.java | 4 +- .../OndemandWebLoggingHttpNotFound2Test.java | 4 +- ...emandWebLoggingHttpOkHighLogLevelTest.java | 4 +- .../web/OndemandWebLoggingHttpOkTest.java | 4 +- ...ndWebLoggingHttpOkTroubleshootingTest.java | 4 +- .../example/web/WebLoggingFormatTest.java | 4 +- .../web/WebLoggingFormatViaProfileTest.java | 4 +- .../web/WebLoggingFormatViaPropertyTest.java | 4 +- .../WebLoggingFormatWithBigResponsesTest.java | 4 +- .../web/WebLoggingFormatWithNewlinesTest.java | 4 +- examples/gcp-async-web-example/build.gradle | 6 ++- .../example/web/config/WebSecurityConfig.java | 2 +- .../web/rest/AsyncDocumentEndpoint.java | 10 ++-- .../org/entur/example/web/ActuatorTest.java | 4 +- .../web/AsyncOndemandAllFeaturesTest.java | 4 +- ...cOndemandWebLoggingHttpBadRequestTest.java | 5 +- ...ncOndemandWebLoggingHttpNotFound1Test.java | 4 +- ...ncOndemandWebLoggingHttpNotFound2Test.java | 4 +- ...emandWebLoggingHttpOkHighLogLevelTest.java | 4 +- .../AsyncOndemandWebLoggingHttpOkTest.java | 4 +- ...ndWebLoggingHttpOkTroubleshootingTest.java | 4 +- ...yncOndemandWebLoggingSlowResponseTest.java | 4 +- .../web/AsyncWebLoggingFormatTest.java | 4 +- .../AsyncWebLoggingFormatViaProfileTest.java | 4 +- ...cWebLoggingFormatWithBigResponsesTest.java | 4 +- ...AsyncWebLoggingFormatWithNewlinesTest.java | 4 +- .../README.md | 2 +- .../build.gradle | 14 +++--- .../example/AbstractGreetingController.java | 0 .../entur/grpc/example/DemoApplication.java | 0 .../grpc/example/GreetingController.java | 4 +- ...GreetingControllerWithOnDemandLogging.java | 4 +- .../no/entur/grpc/example/MyGrpcConfig.java | 0 .../MyValidationServerInterceptor.java | 0 .../src/main/proto/greeting_message.proto | 0 .../src/main/proto/greeting_service.proto | 0 .../src/main/resources/application.properties | 0 .../grpc/example/SpringAbstractGrpcTest.java} | 6 +-- .../grpc/example/SpringGreetingTest.java} | 4 +- .../example/SpringGrpcLoggingFormatTest.java} | 2 +- .../SpringOndemandGrpcLoggingFormatTest.java} | 2 +- ...gOndemandGrpcLoggingHighLogLevelTest.java} | 2 +- .../README.md | 2 +- .../build.gradle | 10 ++-- .../example/AbstractGreetingController.java | 0 .../entur/grpc/example/DemoApplication.java | 0 .../grpc/example/GreetingController.java | 4 +- ...GreetingControllerWithOnDemandLogging.java | 4 +- .../no/entur/grpc/example/MyGrpcConfig.java | 0 .../MyValidationServerInterceptor.java | 0 .../src/main/proto/greeting_message.proto | 0 .../src/main/proto/greeting_service.proto | 0 .../src/main/resources/application.properties | 0 .../artifacts/SpringAbstractGrpcTest.java} | 8 ++-- .../test/artifacts/SpringGreetingTest.java} | 4 +- .../SpringGrpcLoggingFormatTest.java} | 4 +- .../SpringOndemandGrpcLoggingFormatTest.java} | 4 +- ...gOndemandGrpcLoggingHighLogLevelTest.java} | 5 +- .../build.gradle | 6 ++- .../example/web/rest/DocumentEndpoint.java | 18 +------ .../entur/example/web/rest/DummyEndpoint.java | 9 ---- .../example/web/WebLoggingFormatTest.java | 4 +- examples/gcp-web-example/build.gradle | 6 ++- .../example/web/config/WebSecurityConfig.java | 1 - .../example/web/rest/DocumentEndpoint.java | 10 ++-- .../org/entur/example/web/ActuatorTest.java | 4 +- .../web/ActuatorWithoutExcludesTest.java | 4 +- .../OndemandWebLoggingHttpBadRequestTest.java | 4 +- ...emandWebLoggingHttpNotFound1AsyncTest.java | 4 +- .../OndemandWebLoggingHttpNotFound1Test.java | 4 +- .../OndemandWebLoggingHttpNotFound2Test.java | 4 +- ...dWebLoggingHttpOkHighLogLevelLazyTest.java | 4 +- ...emandWebLoggingHttpOkHighLogLevelTest.java | 4 +- .../web/OndemandWebLoggingHttpOkTest.java | 4 +- ...ndWebLoggingHttpOkTroubleshootingTest.java | 4 +- .../OndemandWebLoggingSlowResponseTest.java | 4 +- .../web/WebLoggingFormatHttp401Test.java | 6 +-- .../web/WebLoggingFormatHttp403Test.java | 4 +- ...03ViaAuthorizationDeniedExceptionTest.java | 4 +- ...matHttp500ViaNullpointerExceptionTest.java | 4 +- .../example/web/WebLoggingFormatTest.java | 4 +- .../web/WebLoggingFormatViaProfileTest.java | 4 +- .../web/WebLoggingFormatViaPropertyTest.java | 4 +- .../WebLoggingFormatWithBigResponsesTest.java | 4 +- .../web/WebLoggingFormatWithNewlinesTest.java | 4 +- .../web/WebLoggingMessageFormatTest.java | 4 +- .../build.gradle | 6 ++- .../example/web/config/WebSecurityConfig.java | 2 +- .../OndemandWebLoggingHttpBadRequestTest.java | 4 +- .../OndemandWebLoggingHttpNotFound1Test.java | 4 +- .../OndemandWebLoggingHttpNotFound2Test.java | 4 +- ...emandWebLoggingHttpOkHighLogLevelTest.java | 4 +- .../web/OndemandWebLoggingHttpOkTest.java | 4 +- ...ndWebLoggingHttpOkTroubleshootingTest.java | 4 +- .../example/web/WebLoggingFormatTest.java | 4 +- .../web/WebLoggingMessageFormatTest.java | 4 +- .../build.gradle | 6 ++- .../example/web/config/WebSecurityConfig.java | 2 +- .../web/ErrorWebLoggingFormatTest.java | 4 +- .../example/web/WebLoggingFormatTest.java | 4 +- gcp/logback-logstash-encoder-gcp/build.gradle | 2 +- .../logstash/SimpleMdcJsonProvider.java | 6 +-- .../StackdriverLogSeverityJsonProvider.java | 4 +- .../StackdriverMessageJsonProvider.java | 4 +- ...iverOpenTelemetryTraceMdcJsonProvider.java | 12 ++--- ...StackdriverServiceContextJsonProvider.java | 6 +-- .../StackdriverTimestampJsonProvider.java | 10 ++-- .../micrometer/StackdriverLogbackMetrics.java | 4 -- .../StackdriverMetricsTurboFilter.java | 4 -- .../build.gradle | 10 ++-- ...GcpGrpcEcosystemTestAutoConfiguration.java | 4 +- ...ot.autoconfigure.AutoConfiguration.imports | 0 .../grpc/ecosystem}/test/DemoApplication.java | 2 +- .../test/LoadContextLoggingTest.java | 2 +- .../README.md | 0 .../build.gradle | 4 +- ...onseGcpGrpcEcosystemAutoConfiguration.java | 3 -- ...ot.autoconfigure.AutoConfiguration.imports | 0 .../build.gradle | 2 +- .../test/LogSeveritySyntaxHighlighter.java | 4 +- .../LogSeveritySyntaxHighlighterFactory.java | 12 ++--- .../resources/logback/logback-spring-test.xml | 5 +- .../build.gradle | 0 .../build.gradle | 2 +- ...EcosystemGrpcLoggingAutoConfiguration.java | 0 ...ot.autoconfigure.AutoConfiguration.imports | 0 gradle/wrapper/gradle-wrapper.jar | Bin 61574 -> 45633 bytes gradle/wrapper/gradle-wrapper.properties | 4 +- gradlew | 44 +++++++++++------- gradlew.bat | 26 ++++++----- guides/gRPC.md | 20 ++++---- .../micrometer/DevOpsLogbackMetrics.java | 4 -- .../micrometer/DevOpsMetricsTurboFilter.java | 4 -- ...cpWebOndemandLoggingAutoConfiguration.java | 4 +- request-response/logbook-filter/build.gradle | 4 +- .../logbook/filter/JsonMaxBodySizeFilter.java | 29 ++++++------ .../filter/JsonMaxValueLengthBodyFilter.java | 22 ++++----- .../LogbookLoggingTestAutoConfiguration.java | 4 +- request-response/logbook-test/build.gradle | 4 +- ...tyPrintingLogLevelLogstashLogbackSink.java | 12 ++--- ...tingRequestSingleFieldAppendingMarker.java | 18 +++---- ...ingResponseSingleFieldAppendingMarker.java | 15 +++--- .../logbook/test/PrettyPrintingSink.java | 41 +++++++++------- ...ttyPrintingLocalHttpMessageBodyWriter.java | 13 +++--- ...tingLocalMaxSizeHttpMessageBodyWriter.java | 20 ++++---- ...ngOndemandLogLevelLogstashLogbackSink.java | 34 +++++++------- ...tyPrintingRemoteHttpMessageBodyWriter.java | 25 +++++----- ...ingRemoteMaxSizeHttpMessageBodyWriter.java | 6 +-- request-response/logbook/build.gradle | 2 +- .../AbstractLogLevelLogstashLogbackSink.java | 10 ++-- .../AbstractSingleFieldAppendingMarker.java | 16 +++---- .../cloud/logbook/AbstractSinkBuilder.java | 9 ++-- .../logbook/LogLevelLogstashLogbackSink.java | 14 +++--- .../RequestSingleFieldAppendingMarker.java | 26 +++++------ .../ResponseSingleFieldAppendingMarker.java | 14 +++--- ...ctOndemandLogLevelLogstashLogbackSink.java | 8 ++-- ...actOndemandSingleFieldAppendingMarker.java | 8 ++-- .../ondemand/EmptyHttpMessageBodyWriter.java | 2 +- .../ondemand/HttpMessageBodyWriter.java | 2 +- .../ondemand/LocalHttpMessageBodyWriter.java | 4 +- .../MaxSizeLocalHttpMessageBodyWriter.java | 30 ++++++------ .../MaxSizeRemoteHttpMessageBodyWriter.java | 6 +-- .../OndemandLogLevelLogstashLogbackSink.java | 28 +++++------ .../ondemand/RemoteHttpMessageBodyWriter.java | 18 +++---- ...estOndemandSingleFieldAppendingMarker.java | 26 +++++------ ...nseOndemandSingleFieldAppendingMarker.java | 14 +++--- .../ondemand/StringHttpMessageBodyWriter.java | 4 +- .../cloud/logbook/util/JsonValidator.java | 12 ++--- .../cloud/logbook/util/MaxSizeJsonFilter.java | 36 +++++++------- ...stractLogLevelLogstashLogbackSinkTest.java | 10 ++-- .../logbook/util/MaxSizeJsonFilterTest.java | 13 +++--- request-response/netty-grpc-test/build.gradle | 4 +- .../rr/grpc/test/PrettyPrintingGrpcSink.java | 39 ++++++++++------ ...tingRequestSingleFieldAppendingMarker.java | 15 +++--- ...ingResponseSingleFieldAppendingMarker.java | 16 ++++--- request-response/netty-grpc/build.gradle | 2 +- .../mapper/DefaultMetadataJsonMapper.java | 4 +- .../rr/grpc/marker/GrpcConnectionMarker.java | 24 +++++----- .../rr/grpc/marker/GrpcRequestMarker.java | 10 ++-- .../rr/grpc/marker/GrpcResponseMarker.java | 10 ++-- .../README.md | 1 - ...ot.autoconfigure.AutoConfiguration.imports | 1 - .../README.md | 1 + .../build.gradle | 2 +- ...ionHandlerGrpcSpringAutoConfiguration.java | 39 ++++++++++++++++ ...tResponseGrpcSpringAutoConfiguration.java} | 32 +++++-------- .../RuntimeExceptionExceptionHandler.java | 30 ++++++++++++ ...tatusRuntimeExceptionExceptionHandler.java | 29 ++++++++++++ ...ot.autoconfigure.AutoConfiguration.imports | 2 + ...ttpMessageStateFilterMvcRegistrations.java | 3 +- .../web/LogbookWebAutoConfiguration.java | 2 +- settings.gradle | 14 +++--- test/test-logback/build.gradle | 2 +- trace/mdc-context-grpc-netty/build.gradle | 2 +- .../build.gradle | 2 +- 238 files changed, 896 insertions(+), 702 deletions(-) rename azure/{request-response-spring-boot-starter-azure-grpc-ecosystem-test => request-response-spring-boot-starter-azure-grpc-spring-test}/build.gradle (78%) rename azure/{request-response-spring-boot-starter-azure-grpc-ecosystem-test => request-response-spring-boot-starter-azure-grpc-spring-test}/src/main/java/no/entur/logging/cloud/azure/spring/grpc/ecosystem/test/RequestResponseAzureGrpcEcosystemTestAutoConfiguration.java (95%) rename azure/{request-response-spring-boot-starter-azure-grpc-ecosystem-test => request-response-spring-boot-starter-azure-grpc-spring-test}/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports (100%) rename azure/{request-response-spring-boot-starter-azure-grpc-ecosystem-test => request-response-spring-boot-starter-azure-grpc-spring-test}/src/test/java/no/entur/logging/cloud/spring/logbook/web/test/DemoApplication.java (100%) rename azure/{request-response-spring-boot-starter-azure-grpc-ecosystem-test => request-response-spring-boot-starter-azure-grpc-spring-test}/src/test/java/no/entur/logging/cloud/spring/logbook/web/test/LoadContextLoggingTest.java (100%) rename azure/{request-response-spring-boot-starter-azure-grpc-ecosystem => request-response-spring-boot-starter-azure-grpc-spring}/README.md (100%) rename azure/{request-response-spring-boot-starter-azure-grpc-ecosystem => request-response-spring-boot-starter-azure-grpc-spring}/build.gradle (80%) rename azure/{request-response-spring-boot-starter-azure-grpc-ecosystem => request-response-spring-boot-starter-azure-grpc-spring}/src/main/java/no/entur/logging/cloud/azure/spring/grpc/ecosystem/RequestResponseAzureGrpcEcosystemAutoConfiguration.java (76%) rename azure/{request-response-spring-boot-starter-azure-grpc-ecosystem => request-response-spring-boot-starter-azure-grpc-spring}/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports (100%) rename azure/{spring-boot-starter-azure-grpc-ecosystem-test => spring-boot-starter-azure-grpc-spring-test}/build.gradle (100%) rename azure/{spring-boot-starter-azure-grpc-ecosystem => spring-boot-starter-azure-grpc-spring}/build.gradle (89%) rename azure/{spring-boot-starter-azure-grpc-ecosystem => spring-boot-starter-azure-grpc-spring}/src/main/java/no/entur/logging/cloud/azure/spring/grpc/ecosystem/EcosystemGrpcLoggingAutoConfiguration.java (100%) rename azure/{spring-boot-starter-azure-grpc-ecosystem => spring-boot-starter-azure-grpc-spring}/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports (100%) rename examples/{gcp-grpc-ecosystem-example => azure-grpc-spring-example}/README.md (64%) rename examples/{azure-grpc-ecosystem-example => azure-grpc-spring-example}/build.gradle (89%) rename examples/{azure-grpc-ecosystem-example => azure-grpc-spring-example}/src/main/java/no/entur/grpc/azure/example/AbstractGreetingController.java (100%) rename examples/{azure-grpc-ecosystem-example => azure-grpc-spring-example}/src/main/java/no/entur/grpc/azure/example/DemoApplication.java (100%) rename examples/{azure-grpc-ecosystem-example => azure-grpc-spring-example}/src/main/java/no/entur/grpc/azure/example/GreetingController.java (91%) rename examples/{azure-grpc-ecosystem-example => azure-grpc-spring-example}/src/main/java/no/entur/grpc/azure/example/GreetingControllerWithOnDemandLogging.java (92%) rename examples/{azure-grpc-ecosystem-example => azure-grpc-spring-example}/src/main/java/no/entur/grpc/azure/example/MyGrpcConfig.java (100%) rename examples/{azure-grpc-ecosystem-example => azure-grpc-spring-example}/src/main/java/no/entur/grpc/azure/example/MyValidationServerInterceptor.java (100%) rename examples/{azure-grpc-ecosystem-example => azure-grpc-spring-example}/src/main/proto/greeting_message.proto (100%) rename examples/{azure-grpc-ecosystem-example => azure-grpc-spring-example}/src/main/proto/greeting_service.proto (100%) rename examples/{azure-grpc-ecosystem-example => azure-grpc-spring-example}/src/main/resources/application.properties (100%) rename examples/{azure-grpc-ecosystem-example/src/test/java/no/entur/grpc/azure/example/EcosystemAbstractGrpcTest.java => azure-grpc-spring-example/src/test/java/no/entur/grpc/azure/example/SpringAbstractGrpcTest.java} (93%) rename examples/{azure-grpc-ecosystem-example/src/test/java/no/entur/grpc/azure/example/EcosystemGreetingTest.java => azure-grpc-spring-example/src/test/java/no/entur/grpc/azure/example/SpringGreetingTest.java} (99%) rename examples/{azure-grpc-ecosystem-example/src/test/java/no/entur/grpc/azure/example/EcosystemGrpcLoggingFormatTest.java => azure-grpc-spring-example/src/test/java/no/entur/grpc/azure/example/SpringGrpcLoggingFormatTest.java} (95%) rename examples/{azure-grpc-ecosystem-example/src/test/java/no/entur/grpc/azure/example/EcosystemOndemandGrpcLoggingFormatTest.java => azure-grpc-spring-example/src/test/java/no/entur/grpc/azure/example/SpringOndemandGrpcLoggingFormatTest.java} (97%) rename examples/{azure-grpc-ecosystem-example/src/test/java/no/entur/grpc/azure/example/EcosystemOndemandGrpcLoggingHighLogLevelTest.java => azure-grpc-spring-example/src/test/java/no/entur/grpc/azure/example/SpringOndemandGrpcLoggingHighLogLevelTest.java} (95%) rename examples/{azure-grpc-ecosystem-example => gcp-grpc-spring-example}/README.md (62%) rename examples/{gcp-grpc-ecosystem-example => gcp-grpc-spring-example}/build.gradle (87%) rename examples/{gcp-grpc-ecosystem-example => gcp-grpc-spring-example}/src/main/java/no/entur/grpc/example/AbstractGreetingController.java (100%) rename examples/{gcp-grpc-ecosystem-example => gcp-grpc-spring-example}/src/main/java/no/entur/grpc/example/DemoApplication.java (100%) rename examples/{gcp-grpc-ecosystem-example => gcp-grpc-spring-example}/src/main/java/no/entur/grpc/example/GreetingController.java (92%) rename examples/{gcp-grpc-ecosystem-without-test-artifacts-example => gcp-grpc-spring-example}/src/main/java/no/entur/grpc/example/GreetingControllerWithOnDemandLogging.java (93%) rename examples/{gcp-grpc-ecosystem-example => gcp-grpc-spring-example}/src/main/java/no/entur/grpc/example/MyGrpcConfig.java (100%) rename examples/{gcp-grpc-ecosystem-example => gcp-grpc-spring-example}/src/main/java/no/entur/grpc/example/MyValidationServerInterceptor.java (100%) rename examples/{gcp-grpc-ecosystem-example => gcp-grpc-spring-example}/src/main/proto/greeting_message.proto (100%) rename examples/{gcp-grpc-ecosystem-example => gcp-grpc-spring-example}/src/main/proto/greeting_service.proto (100%) rename examples/{gcp-grpc-ecosystem-example => gcp-grpc-spring-example}/src/main/resources/application.properties (100%) rename examples/{gcp-grpc-ecosystem-without-test-artifacts-example/src/test/java/no/entur/grpc/example/EcosystemAbstractGrpcTest.java => gcp-grpc-spring-example/src/test/java/no/entur/grpc/example/SpringAbstractGrpcTest.java} (93%) rename examples/{gcp-grpc-ecosystem-example/src/test/java/no/entur/grpc/example/EcosystemGreetingTest.java => gcp-grpc-spring-example/src/test/java/no/entur/grpc/example/SpringGreetingTest.java} (98%) rename examples/{gcp-grpc-ecosystem-example/src/test/java/no/entur/grpc/example/EcosystemGrpcLoggingFormatTest.java => gcp-grpc-spring-example/src/test/java/no/entur/grpc/example/SpringGrpcLoggingFormatTest.java} (95%) rename examples/{gcp-grpc-ecosystem-example/src/test/java/no/entur/grpc/example/EcosystemOndemandGrpcLoggingFormatTest.java => gcp-grpc-spring-example/src/test/java/no/entur/grpc/example/SpringOndemandGrpcLoggingFormatTest.java} (97%) rename examples/{gcp-grpc-ecosystem-example/src/test/java/no/entur/grpc/example/EcosystemOndemandGrpcLoggingHighLogLevelTest.java => gcp-grpc-spring-example/src/test/java/no/entur/grpc/example/SpringOndemandGrpcLoggingHighLogLevelTest.java} (95%) rename examples/{gcp-grpc-ecosystem-without-test-artifacts-example => gcp-grpc-spring-without-test-artifacts-example}/README.md (73%) rename examples/{gcp-grpc-ecosystem-without-test-artifacts-example => gcp-grpc-spring-without-test-artifacts-example}/build.gradle (88%) rename examples/{gcp-grpc-ecosystem-without-test-artifacts-example => gcp-grpc-spring-without-test-artifacts-example}/src/main/java/no/entur/grpc/example/AbstractGreetingController.java (100%) rename examples/{gcp-grpc-ecosystem-without-test-artifacts-example => gcp-grpc-spring-without-test-artifacts-example}/src/main/java/no/entur/grpc/example/DemoApplication.java (100%) rename examples/{gcp-grpc-ecosystem-without-test-artifacts-example => gcp-grpc-spring-without-test-artifacts-example}/src/main/java/no/entur/grpc/example/GreetingController.java (92%) rename examples/{gcp-grpc-ecosystem-example => gcp-grpc-spring-without-test-artifacts-example}/src/main/java/no/entur/grpc/example/GreetingControllerWithOnDemandLogging.java (93%) rename examples/{gcp-grpc-ecosystem-without-test-artifacts-example => gcp-grpc-spring-without-test-artifacts-example}/src/main/java/no/entur/grpc/example/MyGrpcConfig.java (100%) rename examples/{gcp-grpc-ecosystem-without-test-artifacts-example => gcp-grpc-spring-without-test-artifacts-example}/src/main/java/no/entur/grpc/example/MyValidationServerInterceptor.java (100%) rename examples/{gcp-grpc-ecosystem-without-test-artifacts-example => gcp-grpc-spring-without-test-artifacts-example}/src/main/proto/greeting_message.proto (100%) rename examples/{gcp-grpc-ecosystem-without-test-artifacts-example => gcp-grpc-spring-without-test-artifacts-example}/src/main/proto/greeting_service.proto (100%) rename examples/{gcp-grpc-ecosystem-without-test-artifacts-example => gcp-grpc-spring-without-test-artifacts-example}/src/main/resources/application.properties (100%) rename examples/{gcp-grpc-ecosystem-example/src/test/java/no/entur/grpc/example/EcosystemAbstractGrpcTest.java => gcp-grpc-spring-without-test-artifacts-example/src/test/java/no/entur/grpc/example/without/test/artifacts/SpringAbstractGrpcTest.java} (92%) rename examples/{gcp-grpc-ecosystem-without-test-artifacts-example/src/test/java/no/entur/grpc/example/EcosystemGreetingTest.java => gcp-grpc-spring-without-test-artifacts-example/src/test/java/no/entur/grpc/example/without/test/artifacts/SpringGreetingTest.java} (98%) rename examples/{gcp-grpc-ecosystem-without-test-artifacts-example/src/test/java/no/entur/grpc/example/EcosystemGrpcLoggingFormatTest.java => gcp-grpc-spring-without-test-artifacts-example/src/test/java/no/entur/grpc/example/without/test/artifacts/SpringGrpcLoggingFormatTest.java} (83%) rename examples/{gcp-grpc-ecosystem-without-test-artifacts-example/src/test/java/no/entur/grpc/example/EcosystemOndemandGrpcLoggingFormatTest.java => gcp-grpc-spring-without-test-artifacts-example/src/test/java/no/entur/grpc/example/without/test/artifacts/SpringOndemandGrpcLoggingFormatTest.java} (91%) rename examples/{gcp-grpc-ecosystem-without-test-artifacts-example/src/test/java/no/entur/grpc/example/EcosystemOndemandGrpcLoggingHighLogLevelTest.java => gcp-grpc-spring-without-test-artifacts-example/src/test/java/no/entur/grpc/example/without/test/artifacts/SpringOndemandGrpcLoggingHighLogLevelTest.java} (87%) rename gcp/{request-response-spring-boot-starter-gcp-grpc-ecosystem-test => request-response-spring-boot-starter-gcp-grpc-spring-test}/build.gradle (71%) rename gcp/{request-response-spring-boot-starter-gcp-grpc-ecosystem-test => request-response-spring-boot-starter-gcp-grpc-spring-test}/src/main/java/no/entur/logging/cloud/gcp/spring/gcp/grpc/ecosystem/test/RequestResponseGcpGrpcEcosystemTestAutoConfiguration.java (95%) rename gcp/{request-response-spring-boot-starter-gcp-grpc-ecosystem-test => request-response-spring-boot-starter-gcp-grpc-spring-test}/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports (100%) rename gcp/{request-response-spring-boot-starter-gcp-grpc-ecosystem-test/src/test/java/no/entur/logging/cloud/spring/logbook/web => request-response-spring-boot-starter-gcp-grpc-spring-test/src/test/java/no/entur/logging/cloud/gcp/spring/gcp/grpc/ecosystem}/test/DemoApplication.java (80%) rename gcp/{request-response-spring-boot-starter-gcp-grpc-ecosystem-test/src/test/java/no/entur/logging/cloud/spring/logbook/web => request-response-spring-boot-starter-gcp-grpc-spring-test/src/test/java/no/entur/logging/cloud/gcp/spring/gcp/grpc/ecosystem}/test/LoadContextLoggingTest.java (97%) rename gcp/{request-response-spring-boot-starter-gcp-grpc-ecosystem => request-response-spring-boot-starter-gcp-grpc-spring}/README.md (100%) rename gcp/{request-response-spring-boot-starter-gcp-grpc-ecosystem => request-response-spring-boot-starter-gcp-grpc-spring}/build.gradle (80%) rename gcp/{request-response-spring-boot-starter-gcp-grpc-ecosystem => request-response-spring-boot-starter-gcp-grpc-spring}/src/main/java/no/entur/logging/cloud/gcp/spring/gcp/grpc/ecosystem/RequestResponseGcpGrpcEcosystemAutoConfiguration.java (77%) rename gcp/{request-response-spring-boot-starter-gcp-grpc-ecosystem => request-response-spring-boot-starter-gcp-grpc-spring}/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports (100%) rename gcp/{spring-boot-starter-gcp-grpc-ecosystem-test => spring-boot-starter-gcp-grpc-spring-test}/build.gradle (100%) rename gcp/{spring-boot-starter-gcp-grpc-ecosystem => spring-boot-starter-gcp-grpc-spring}/build.gradle (90%) rename gcp/{spring-boot-starter-gcp-grpc-ecosystem => spring-boot-starter-gcp-grpc-spring}/src/main/java/no/entur/logging/cloud/gcp/spring/grpc/ecosystem/EcosystemGrpcLoggingAutoConfiguration.java (100%) rename gcp/{spring-boot-starter-gcp-grpc-ecosystem => spring-boot-starter-gcp-grpc-spring}/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports (100%) delete mode 100644 request-response/request-response-spring-boot-autoconfigure-grpc-ecosystem/README.md delete mode 100644 request-response/request-response-spring-boot-autoconfigure-grpc-ecosystem/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports create mode 100644 request-response/request-response-spring-boot-autoconfigure-grpc-spring/README.md rename request-response/{request-response-spring-boot-autoconfigure-grpc-ecosystem => request-response-spring-boot-autoconfigure-grpc-spring}/build.gradle (83%) create mode 100644 request-response/request-response-spring-boot-autoconfigure-grpc-spring/src/main/java/no/entur/logging/cloud/spring/grpc/ecosystem/RequestResponseExceptionHandlerGrpcSpringAutoConfiguration.java rename request-response/{request-response-spring-boot-autoconfigure-grpc-ecosystem/src/main/java/no/entur/logging/cloud/spring/grpc/ecosystem/RequestResponseGrpcEcosystemAutoConfiguration.java => request-response-spring-boot-autoconfigure-grpc-spring/src/main/java/no/entur/logging/cloud/spring/grpc/ecosystem/RequestResponseGrpcSpringAutoConfiguration.java} (65%) create mode 100644 request-response/request-response-spring-boot-autoconfigure-grpc-spring/src/main/java/no/entur/logging/cloud/spring/grpc/ecosystem/RuntimeExceptionExceptionHandler.java create mode 100644 request-response/request-response-spring-boot-autoconfigure-grpc-spring/src/main/java/no/entur/logging/cloud/spring/grpc/ecosystem/StatusRuntimeExceptionExceptionHandler.java create mode 100644 request-response/request-response-spring-boot-autoconfigure-grpc-spring/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports diff --git a/azure/README.md b/azure/README.md index 47ca9b85..11ad0770 100644 --- a/azure/README.md +++ b/azure/README.md @@ -208,24 +208,24 @@ and ```xml no.entur.logging.cloud - spring-boot-starter-azure-grpc-ecosystem + spring-boot-starter-azure-grpc-spring ${cloud-logging.version} no.entur.logging.cloud - spring-boot-starter-azure-grpc-ecosystem-test + spring-boot-starter-azure-grpc-spring-test ${cloud-logging.version} test no.entur.logging.cloud - request-response-spring-boot-starter-azure-grpc-ecosystem + request-response-spring-boot-starter-azure-grpc-spring ${cloud-logging.version} no.entur.logging.cloud - request-response-spring-boot-starter-azure-grpc-ecosystem-test + request-response-spring-boot-starter-azure-grpc-spring-test ${cloud-logging.version} test @@ -285,11 +285,11 @@ ext { add ```groovy -implementation("no.entur.logging.cloud:spring-boot-starter-azure-grpc-ecosystem:${cloudLoggingVersion}") -testImplementation("no.entur.logging.cloud:spring-boot-starter-azure-grpc-ecosystem-test:${cloudLoggingVersion}") +implementation("no.entur.logging.cloud:spring-boot-starter-azure-grpc-spring:${cloudLoggingVersion}") +testImplementation("no.entur.logging.cloud:spring-boot-starter-azure-grpc-spring-test:${cloudLoggingVersion}") // requst-response logging -implementation("no.entur.logging.cloud:request-response-spring-boot-starter-azure-grpc-ecosystem:${cloudLoggingVersion}") -testImplementation("no.entur.logging.cloud:request-response-spring-boot-starter-azure-grpc-ecosystem-test:${cloudLoggingVersion}") +implementation("no.entur.logging.cloud:request-response-spring-boot-starter-azure-grpc-spring:${cloudLoggingVersion}") +testImplementation("no.entur.logging.cloud:request-response-spring-boot-starter-azure-grpc-spring-test:${cloudLoggingVersion}") // on-demand logging support implementation("no.entur.logging.cloud:on-demand-spring-boot-starter-grpc:${cloudLoggingVersion}") // metrics diff --git a/azure/logback-logstash-encoder-azure/build.gradle b/azure/logback-logstash-encoder-azure/build.gradle index 135179b7..7f4e5b78 100644 --- a/azure/logback-logstash-encoder-azure/build.gradle +++ b/azure/logback-logstash-encoder-azure/build.gradle @@ -7,7 +7,7 @@ dependencies { api ("ch.qos.logback:logback-core") api ("net.logstash.logback:logstash-logback-encoder:${logbackLogstashVersion}") - api("com.fasterxml.jackson.core:jackson-core") + api("tools.jackson.core:jackson-core") } diff --git a/azure/logback-logstash-encoder-azure/src/main/java/no/entur/logging/cloud/azure/logback/logstash/AzureServiceContextJsonProvider.java b/azure/logback-logstash-encoder-azure/src/main/java/no/entur/logging/cloud/azure/logback/logstash/AzureServiceContextJsonProvider.java index e223c086..d973005c 100644 --- a/azure/logback-logstash-encoder-azure/src/main/java/no/entur/logging/cloud/azure/logback/logstash/AzureServiceContextJsonProvider.java +++ b/azure/logback-logstash-encoder-azure/src/main/java/no/entur/logging/cloud/azure/logback/logstash/AzureServiceContextJsonProvider.java @@ -1,7 +1,7 @@ package no.entur.logging.cloud.azure.logback.logstash; import ch.qos.logback.classic.spi.ILoggingEvent; -import com.fasterxml.jackson.core.JsonGenerator; +import tools.jackson.core.JsonGenerator; import net.logstash.logback.composite.AbstractFieldJsonProvider; import net.logstash.logback.composite.FieldNamesAware; import net.logstash.logback.composite.JsonWritingUtils; @@ -76,9 +76,9 @@ public static String parseServiceNameFromHostname(String host) { } @Override - public void writeTo(JsonGenerator generator, ILoggingEvent event) throws IOException { + public void writeTo(JsonGenerator generator, ILoggingEvent event) { if(service != null) { - generator.writeObjectFieldStart(getFieldName()); + generator.writeObjectPropertyStart(getFieldName()); JsonWritingUtils.writeStringField(generator, "service", service); diff --git a/azure/micrometer-azure/src/main/java/no/entur/logging/cloud/azure/micrometer/AzureLogbackMetrics.java b/azure/micrometer-azure/src/main/java/no/entur/logging/cloud/azure/micrometer/AzureLogbackMetrics.java index 02b0062a..35a46ca6 100644 --- a/azure/micrometer-azure/src/main/java/no/entur/logging/cloud/azure/micrometer/AzureLogbackMetrics.java +++ b/azure/micrometer-azure/src/main/java/no/entur/logging/cloud/azure/micrometer/AzureLogbackMetrics.java @@ -2,8 +2,6 @@ import ch.qos.logback.classic.LoggerContext; import io.micrometer.core.instrument.MeterRegistry; -import io.micrometer.core.lang.NonNullApi; -import io.micrometer.core.lang.NonNullFields; import org.slf4j.LoggerFactory; import java.util.Map; @@ -15,8 +13,6 @@ * Logback driver with extra log levels. Originally copied from LogbackMetrics class in micrometer-core. * */ -@NonNullApi -@NonNullFields public class AzureLogbackMetrics extends io.micrometer.core.instrument.binder.logging.LogbackMetrics { // extend since there is not interface type private final LoggerContext loggerContext; private final Map metricsTurboFilters = new ConcurrentHashMap<>(); diff --git a/azure/micrometer-azure/src/main/java/no/entur/logging/cloud/azure/micrometer/AzureMetricsTurboFilter.java b/azure/micrometer-azure/src/main/java/no/entur/logging/cloud/azure/micrometer/AzureMetricsTurboFilter.java index 23754818..4e99a946 100644 --- a/azure/micrometer-azure/src/main/java/no/entur/logging/cloud/azure/micrometer/AzureMetricsTurboFilter.java +++ b/azure/micrometer-azure/src/main/java/no/entur/logging/cloud/azure/micrometer/AzureMetricsTurboFilter.java @@ -8,8 +8,6 @@ import io.micrometer.core.instrument.Counter; import io.micrometer.core.instrument.MeterRegistry; import io.micrometer.core.instrument.Tag; -import io.micrometer.core.lang.NonNullApi; -import io.micrometer.core.lang.NonNullFields; import no.entur.logging.cloud.api.DevOpsLevel; import no.entur.logging.cloud.api.DevOpsMarker; import org.slf4j.Marker; @@ -18,8 +16,6 @@ import java.util.List; -@NonNullApi -@NonNullFields public class AzureMetricsTurboFilter extends TurboFilter implements LoggingEventMetrics { private final Counter alertCounter; diff --git a/azure/request-response-spring-boot-starter-azure-grpc-ecosystem-test/build.gradle b/azure/request-response-spring-boot-starter-azure-grpc-spring-test/build.gradle similarity index 78% rename from azure/request-response-spring-boot-starter-azure-grpc-ecosystem-test/build.gradle rename to azure/request-response-spring-boot-starter-azure-grpc-spring-test/build.gradle index 3bf783b8..94b7e3f6 100644 --- a/azure/request-response-spring-boot-starter-azure-grpc-ecosystem-test/build.gradle +++ b/azure/request-response-spring-boot-starter-azure-grpc-spring-test/build.gradle @@ -1,14 +1,14 @@ dependencies { api project(":azure:spring-boot-autoconfigure-azure-test") - api project(':azure:request-response-spring-boot-starter-azure-grpc-ecosystem') - api project(':request-response:request-response-spring-boot-autoconfigure-grpc-ecosystem') + api project(':azure:request-response-spring-boot-starter-azure-grpc-spring') + api project(':request-response:request-response-spring-boot-autoconfigure-grpc-spring') - api ("org.entur.jackson:jackson-syntax-highlight:${jacksonSyntaxHighlightVersion}") + api ("org.entur.jackson:jackson-tools-syntax-highlight:${jacksonSyntaxHighlightVersion}") api ("org.entur.logback-logstash-syntax-highlighting-decorators:logback-logstash-syntax-highlighting-decorators:${logbackLogstashSyntaxHighlightingDecoratorsVersion}") api ("net.logstash.logback:logstash-logback-encoder:${logbackLogstashVersion}") - api ("com.fasterxml.jackson.core:jackson-core") + api ("tools.jackson.core:jackson-core") api("org.slf4j:slf4j-api") api("org.springframework.boot:spring-boot-autoconfigure") diff --git a/azure/request-response-spring-boot-starter-azure-grpc-ecosystem-test/src/main/java/no/entur/logging/cloud/azure/spring/grpc/ecosystem/test/RequestResponseAzureGrpcEcosystemTestAutoConfiguration.java b/azure/request-response-spring-boot-starter-azure-grpc-spring-test/src/main/java/no/entur/logging/cloud/azure/spring/grpc/ecosystem/test/RequestResponseAzureGrpcEcosystemTestAutoConfiguration.java similarity index 95% rename from azure/request-response-spring-boot-starter-azure-grpc-ecosystem-test/src/main/java/no/entur/logging/cloud/azure/spring/grpc/ecosystem/test/RequestResponseAzureGrpcEcosystemTestAutoConfiguration.java rename to azure/request-response-spring-boot-starter-azure-grpc-spring-test/src/main/java/no/entur/logging/cloud/azure/spring/grpc/ecosystem/test/RequestResponseAzureGrpcEcosystemTestAutoConfiguration.java index e613c04e..c6f3a1e8 100644 --- a/azure/request-response-spring-boot-starter-azure-grpc-ecosystem-test/src/main/java/no/entur/logging/cloud/azure/spring/grpc/ecosystem/test/RequestResponseAzureGrpcEcosystemTestAutoConfiguration.java +++ b/azure/request-response-spring-boot-starter-azure-grpc-spring-test/src/main/java/no/entur/logging/cloud/azure/spring/grpc/ecosystem/test/RequestResponseAzureGrpcEcosystemTestAutoConfiguration.java @@ -1,12 +1,12 @@ package no.entur.logging.cloud.azure.spring.grpc.ecosystem.test; import no.entur.logging.cloud.spring.rr.grpc.AbstractRequestResponseGrpcSinkAutoConfiguration; -import org.entur.jackson.jsh.AnsiSyntaxHighlight; -import org.entur.jackson.jsh.DefaultSyntaxHighlighter; import no.entur.logging.cloud.rr.grpc.GrpcSink; import no.entur.logging.cloud.rr.grpc.test.CompositeSink; import no.entur.logging.cloud.rr.grpc.test.PrettyPrintingLogLevelLogstashLogbackGrpcSink; import no.entur.logging.cloud.rr.grpc.test.PrettyPrintingGrpcSink; +import org.entur.jackson.tools.jsh.AnsiSyntaxHighlight; +import org.entur.jackson.tools.jsh.DefaultSyntaxHighlighter; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.slf4j.event.Level; diff --git a/azure/request-response-spring-boot-starter-azure-grpc-ecosystem-test/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports b/azure/request-response-spring-boot-starter-azure-grpc-spring-test/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports similarity index 100% rename from azure/request-response-spring-boot-starter-azure-grpc-ecosystem-test/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports rename to azure/request-response-spring-boot-starter-azure-grpc-spring-test/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports diff --git a/azure/request-response-spring-boot-starter-azure-grpc-ecosystem-test/src/test/java/no/entur/logging/cloud/spring/logbook/web/test/DemoApplication.java b/azure/request-response-spring-boot-starter-azure-grpc-spring-test/src/test/java/no/entur/logging/cloud/spring/logbook/web/test/DemoApplication.java similarity index 100% rename from azure/request-response-spring-boot-starter-azure-grpc-ecosystem-test/src/test/java/no/entur/logging/cloud/spring/logbook/web/test/DemoApplication.java rename to azure/request-response-spring-boot-starter-azure-grpc-spring-test/src/test/java/no/entur/logging/cloud/spring/logbook/web/test/DemoApplication.java diff --git a/azure/request-response-spring-boot-starter-azure-grpc-ecosystem-test/src/test/java/no/entur/logging/cloud/spring/logbook/web/test/LoadContextLoggingTest.java b/azure/request-response-spring-boot-starter-azure-grpc-spring-test/src/test/java/no/entur/logging/cloud/spring/logbook/web/test/LoadContextLoggingTest.java similarity index 100% rename from azure/request-response-spring-boot-starter-azure-grpc-ecosystem-test/src/test/java/no/entur/logging/cloud/spring/logbook/web/test/LoadContextLoggingTest.java rename to azure/request-response-spring-boot-starter-azure-grpc-spring-test/src/test/java/no/entur/logging/cloud/spring/logbook/web/test/LoadContextLoggingTest.java diff --git a/azure/request-response-spring-boot-starter-azure-grpc-ecosystem/README.md b/azure/request-response-spring-boot-starter-azure-grpc-spring/README.md similarity index 100% rename from azure/request-response-spring-boot-starter-azure-grpc-ecosystem/README.md rename to azure/request-response-spring-boot-starter-azure-grpc-spring/README.md diff --git a/azure/request-response-spring-boot-starter-azure-grpc-ecosystem/build.gradle b/azure/request-response-spring-boot-starter-azure-grpc-spring/build.gradle similarity index 80% rename from azure/request-response-spring-boot-starter-azure-grpc-ecosystem/build.gradle rename to azure/request-response-spring-boot-starter-azure-grpc-spring/build.gradle index e09c649f..b49c29ba 100644 --- a/azure/request-response-spring-boot-starter-azure-grpc-ecosystem/build.gradle +++ b/azure/request-response-spring-boot-starter-azure-grpc-spring/build.gradle @@ -4,14 +4,14 @@ dependencies { api project(':api') api project(':azure:logback-logstash-encoder-azure') api project(':request-response:netty-grpc') - api project(':request-response:request-response-spring-boot-autoconfigure-grpc-ecosystem') + api project(':request-response:request-response-spring-boot-autoconfigure-grpc-spring') api ("org.slf4j:slf4j-api") api ("org.springframework.boot:spring-boot-starter") api ("org.springframework.boot:spring-boot-autoconfigure") api ("org.springframework.boot:spring-boot-starter-logging") - api("net.devh:grpc-server-spring-boot-starter:${ecosystemGrpcVersion}") + api("org.springframework.grpc:spring-grpc-server-spring-boot-starter:${springGrpcVersion}") testImplementation("org.springframework.boot:spring-boot-starter-test") } diff --git a/azure/request-response-spring-boot-starter-azure-grpc-ecosystem/src/main/java/no/entur/logging/cloud/azure/spring/grpc/ecosystem/RequestResponseAzureGrpcEcosystemAutoConfiguration.java b/azure/request-response-spring-boot-starter-azure-grpc-spring/src/main/java/no/entur/logging/cloud/azure/spring/grpc/ecosystem/RequestResponseAzureGrpcEcosystemAutoConfiguration.java similarity index 76% rename from azure/request-response-spring-boot-starter-azure-grpc-ecosystem/src/main/java/no/entur/logging/cloud/azure/spring/grpc/ecosystem/RequestResponseAzureGrpcEcosystemAutoConfiguration.java rename to azure/request-response-spring-boot-starter-azure-grpc-spring/src/main/java/no/entur/logging/cloud/azure/spring/grpc/ecosystem/RequestResponseAzureGrpcEcosystemAutoConfiguration.java index 1e961e57..4d76a105 100644 --- a/azure/request-response-spring-boot-starter-azure-grpc-ecosystem/src/main/java/no/entur/logging/cloud/azure/spring/grpc/ecosystem/RequestResponseAzureGrpcEcosystemAutoConfiguration.java +++ b/azure/request-response-spring-boot-starter-azure-grpc-spring/src/main/java/no/entur/logging/cloud/azure/spring/grpc/ecosystem/RequestResponseAzureGrpcEcosystemAutoConfiguration.java @@ -1,13 +1,10 @@ package no.entur.logging.cloud.azure.spring.grpc.ecosystem; -import no.entur.logging.cloud.spring.grpc.ecosystem.RequestResponseGrpcEcosystemAutoConfiguration; -import no.entur.logging.cloud.spring.rr.grpc.AbstractRequestResponseGrpcSinkAutoConfiguration; import no.entur.logging.cloud.spring.rr.grpc.GrpcLoggingCloudProperties; import no.entur.logging.cloud.spring.rr.grpc.RequestResponseGrpcAutoConfiguration; import org.springframework.boot.autoconfigure.AutoConfigureBefore; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.PropertySource; @Configuration @AutoConfigureBefore(RequestResponseGrpcAutoConfiguration.class) diff --git a/azure/request-response-spring-boot-starter-azure-grpc-ecosystem/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports b/azure/request-response-spring-boot-starter-azure-grpc-spring/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports similarity index 100% rename from azure/request-response-spring-boot-starter-azure-grpc-ecosystem/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports rename to azure/request-response-spring-boot-starter-azure-grpc-spring/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports diff --git a/azure/spring-boot-autoconfigure-azure-test/build.gradle b/azure/spring-boot-autoconfigure-azure-test/build.gradle index 18406e31..9181cfab 100644 --- a/azure/spring-boot-autoconfigure-azure-test/build.gradle +++ b/azure/spring-boot-autoconfigure-azure-test/build.gradle @@ -15,7 +15,7 @@ dependencies { api("org.springframework.boot:spring-boot-starter-logging") api("org.springframework.boot:spring-boot-autoconfigure") - api ("org.entur.jackson:jackson-syntax-highlight:${jacksonSyntaxHighlightVersion}") + api ("org.entur.jackson:jackson-tools-syntax-highlight:${jacksonSyntaxHighlightVersion}") api ("org.entur.logback-logstash-syntax-highlighting-decorators:logback-logstash-syntax-highlighting-decorators:${logbackLogstashSyntaxHighlightingDecoratorsVersion}") annotationProcessor "org.springframework.boot:spring-boot-configuration-processor:${springBootVersion}" diff --git a/azure/spring-boot-autoconfigure-azure-test/src/main/java/no/entur/logging/cloud/azure/spring/test/LogSeveritySyntaxHighlighter.java b/azure/spring-boot-autoconfigure-azure-test/src/main/java/no/entur/logging/cloud/azure/spring/test/LogSeveritySyntaxHighlighter.java index f11ad834..0e8d6667 100644 --- a/azure/spring-boot-autoconfigure-azure-test/src/main/java/no/entur/logging/cloud/azure/spring/test/LogSeveritySyntaxHighlighter.java +++ b/azure/spring-boot-autoconfigure-azure-test/src/main/java/no/entur/logging/cloud/azure/spring/test/LogSeveritySyntaxHighlighter.java @@ -1,8 +1,8 @@ package no.entur.logging.cloud.azure.spring.test; import org.entur.decorators.syntaxhighlight.DelegateSyntaxHighlighter; -import org.entur.jackson.jsh.AnsiSyntaxHighlight; -import org.entur.jackson.jsh.SyntaxHighlighter; +import org.entur.jackson.tools.jsh.AnsiSyntaxHighlight; +import org.entur.jackson.tools.jsh.SyntaxHighlighter; public class LogSeveritySyntaxHighlighter extends DelegateSyntaxHighlighter { diff --git a/azure/spring-boot-autoconfigure-azure-test/src/main/java/no/entur/logging/cloud/azure/spring/test/LogSeveritySyntaxHighlighterFactory.java b/azure/spring-boot-autoconfigure-azure-test/src/main/java/no/entur/logging/cloud/azure/spring/test/LogSeveritySyntaxHighlighterFactory.java index 288ee94c..88f5542c 100644 --- a/azure/spring-boot-autoconfigure-azure-test/src/main/java/no/entur/logging/cloud/azure/spring/test/LogSeveritySyntaxHighlighterFactory.java +++ b/azure/spring-boot-autoconfigure-azure-test/src/main/java/no/entur/logging/cloud/azure/spring/test/LogSeveritySyntaxHighlighterFactory.java @@ -1,10 +1,10 @@ package no.entur.logging.cloud.azure.spring.test; -import com.fasterxml.jackson.core.JsonGenerator; +import org.entur.jackson.tools.jsh.AnsiSyntaxHighlight; +import org.entur.jackson.tools.jsh.DefaultSyntaxHighlighter; +import org.entur.jackson.tools.jsh.SyntaxHighlighter; +import tools.jackson.core.JsonGenerator; import org.entur.decorators.factory.ConfigurableSyntaxHighlighterFactory; -import org.entur.jackson.jsh.AnsiSyntaxHighlight; -import org.entur.jackson.jsh.DefaultSyntaxHighlighter; -import org.entur.jackson.jsh.SyntaxHighlighter; public class LogSeveritySyntaxHighlighterFactory extends ConfigurableSyntaxHighlighterFactory { @@ -50,9 +50,9 @@ public LogSeveritySyntaxHighlighterFactory() { } @Override - public SyntaxHighlighter createSyntaxHighlighter(JsonGenerator generator) { + public SyntaxHighlighter createSyntaxHighlighter() { if(cachedSyntaxHighlighter == null) { - cachedSyntaxHighlighter = super.createSyntaxHighlighter(generator); + cachedSyntaxHighlighter = super.createSyntaxHighlighter(); } return new LogSeveritySyntaxHighlighter(cachedSyntaxHighlighter, severity.defaultValue, severity.debug, severity.info, severity.warning, severity.error, loggerName, message); } diff --git a/azure/spring-boot-autoconfigure-azure-test/src/main/resources/logback/logback-spring-test.xml b/azure/spring-boot-autoconfigure-azure-test/src/main/resources/logback/logback-spring-test.xml index 195a00a3..18e1aab6 100644 --- a/azure/spring-boot-autoconfigure-azure-test/src/main/resources/logback/logback-spring-test.xml +++ b/azure/spring-boot-autoconfigure-azure-test/src/main/resources/logback/logback-spring-test.xml @@ -55,7 +55,7 @@ TODO this seems to add an extract space after the last newline, but as this is just the human readable format, this is not important. --> - + green @@ -63,7 +63,8 @@ blue magenta - + + diff --git a/azure/spring-boot-starter-azure-grpc-ecosystem-test/build.gradle b/azure/spring-boot-starter-azure-grpc-spring-test/build.gradle similarity index 100% rename from azure/spring-boot-starter-azure-grpc-ecosystem-test/build.gradle rename to azure/spring-boot-starter-azure-grpc-spring-test/build.gradle diff --git a/azure/spring-boot-starter-azure-grpc-ecosystem/build.gradle b/azure/spring-boot-starter-azure-grpc-spring/build.gradle similarity index 89% rename from azure/spring-boot-starter-azure-grpc-ecosystem/build.gradle rename to azure/spring-boot-starter-azure-grpc-spring/build.gradle index a0602534..1a3a8ca4 100644 --- a/azure/spring-boot-starter-azure-grpc-ecosystem/build.gradle +++ b/azure/spring-boot-starter-azure-grpc-spring/build.gradle @@ -17,7 +17,7 @@ dependencies { api("org.springframework.boot:spring-boot-autoconfigure") api("org.springframework.boot:spring-boot-starter-logging") - api("net.devh:grpc-server-spring-boot-starter:${ecosystemGrpcVersion}") + api("org.springframework.grpc:spring-grpc-server-spring-boot-starter:${springGrpcVersion}") api "io.grpc:grpc-netty:${grpcNettyVersion}" diff --git a/azure/spring-boot-starter-azure-grpc-ecosystem/src/main/java/no/entur/logging/cloud/azure/spring/grpc/ecosystem/EcosystemGrpcLoggingAutoConfiguration.java b/azure/spring-boot-starter-azure-grpc-spring/src/main/java/no/entur/logging/cloud/azure/spring/grpc/ecosystem/EcosystemGrpcLoggingAutoConfiguration.java similarity index 100% rename from azure/spring-boot-starter-azure-grpc-ecosystem/src/main/java/no/entur/logging/cloud/azure/spring/grpc/ecosystem/EcosystemGrpcLoggingAutoConfiguration.java rename to azure/spring-boot-starter-azure-grpc-spring/src/main/java/no/entur/logging/cloud/azure/spring/grpc/ecosystem/EcosystemGrpcLoggingAutoConfiguration.java diff --git a/azure/spring-boot-starter-azure-grpc-ecosystem/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports b/azure/spring-boot-starter-azure-grpc-spring/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports similarity index 100% rename from azure/spring-boot-starter-azure-grpc-ecosystem/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports rename to azure/spring-boot-starter-azure-grpc-spring/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports diff --git a/build.gradle b/build.gradle index 1dd4a2ef..b0ecbd9f 100644 --- a/build.gradle +++ b/build.gradle @@ -7,7 +7,7 @@ plugins { // Define version variables at root level so they're available everywhere ext { - springBootVersion = '3.5.9' // https://repo1.maven.org/maven2/org/springframework/boot/spring-boot-dependencies/ + springBootVersion = '4.0.1' // https://repo1.maven.org/maven2/org/springframework/boot/spring-boot-dependencies/ // The following versions are managed by Spring Boot BOM (no need to define here): // junitJupiterVersion, mockitoVersion, slf4jVersion, logbackVersion, // jacksonVersion, jacksonDatabindVersion, micrometerVersion, janinoVersion, @@ -16,10 +16,10 @@ ext { // Versions NOT in Spring Boot BOM - we manage these ourselves: googleTruthVersion = '1.4.5' - logbackLogstashVersion = '8.1' - logbookVersion = '3.12.3' - jacksonSyntaxHighlightVersion = '1.1.1' - logbackLogstashSyntaxHighlightingDecoratorsVersion = '1.1.1' + logbackLogstashVersion = '9.0' + logbookVersion = '4.0.0-RC.1' + jacksonSyntaxHighlightVersion = '2.0.0' + logbackLogstashSyntaxHighlightingDecoratorsVersion = '2.0.0-SNAPSHOT' commonsIoVersion = '2.21.0' commonsTextVersion = '1.15.0' nettyTcnativeBoringsslStaticVersion = '2.0.74.Final' @@ -28,7 +28,7 @@ ext { grpcVersion = '1.78.0' grpcCommonsVersion = '2.63.2' grpcProtobufVersion = '4.33.2' - ecosystemGrpcVersion = '3.1.0.RELEASE' + springGrpcVersion = '1.0.1' jsonAssertVersion = '0.8.0' } @@ -61,7 +61,7 @@ configure(exampleProjects()) { java { toolchain { - languageVersion = JavaLanguageVersion.of(17) // Specify desired Java version (e.g., Java 17) + languageVersion = JavaLanguageVersion.of(25) // Specify desired Java version (e.g., Java 17) } } @@ -92,7 +92,7 @@ configure(jvmProjects()) { test { useJUnitPlatform { - includeEngines 'junit-jupiter', 'junit-vintage' + includeEngines 'junit-jupiter' } } diff --git a/examples/gcp-grpc-ecosystem-example/README.md b/examples/azure-grpc-spring-example/README.md similarity index 64% rename from examples/gcp-grpc-ecosystem-example/README.md rename to examples/azure-grpc-spring-example/README.md index 39ab8c06..86c822be 100644 --- a/examples/gcp-grpc-ecosystem-example/README.md +++ b/examples/azure-grpc-spring-example/README.md @@ -1,4 +1,4 @@ -# gcp-grpc-ecosystem-example +# azure-grpc-spring-example Simple gRPC server example with a few unit tests. diff --git a/examples/azure-grpc-ecosystem-example/build.gradle b/examples/azure-grpc-spring-example/build.gradle similarity index 89% rename from examples/azure-grpc-ecosystem-example/build.gradle rename to examples/azure-grpc-spring-example/build.gradle index 3e139466..5f896509 100644 --- a/examples/azure-grpc-ecosystem-example/build.gradle +++ b/examples/azure-grpc-spring-example/build.gradle @@ -1,21 +1,21 @@ plugins { - id 'org.springframework.boot' version '3.5.7' + id 'org.springframework.boot' version '4.0.1' id "com.google.protobuf" version "0.9.6" } test { useJUnitPlatform { - includeEngines 'junit-jupiter', 'junit-vintage' + includeEngines 'junit-jupiter' } } dependencies { implementation project(':on-demand:on-demand-spring-boot-starter-grpc') - implementation project(':azure:spring-boot-starter-azure-grpc-ecosystem') - implementation project(':azure:request-response-spring-boot-starter-azure-grpc-ecosystem') + implementation project(':azure:spring-boot-starter-azure-grpc-spring') + implementation project(':azure:request-response-spring-boot-starter-azure-grpc-spring') implementation project(':trace:server:correlation-id-trace-grpc-netty') implementation project(':trace:mdc-context-grpc-netty') - implementation project(':request-response:request-response-spring-boot-autoconfigure-grpc-ecosystem') + implementation project(':request-response:request-response-spring-boot-autoconfigure-grpc-spring') implementation("io.grpc:grpc-api:$grpcVersion") implementation("io.grpc:grpc-core:$grpcVersion") @@ -31,8 +31,8 @@ dependencies { // added due to grpc plugin dependency resolution problem testImplementation "org.junit.platform:junit-platform-launcher" - testImplementation project(":azure:spring-boot-starter-azure-grpc-ecosystem-test") - testImplementation project(':azure:request-response-spring-boot-starter-azure-grpc-ecosystem-test') + testImplementation project(":azure:spring-boot-starter-azure-grpc-spring-test") + testImplementation project(':azure:request-response-spring-boot-starter-azure-grpc-spring-test') testImplementation("org.springframework.boot:spring-boot-starter-test") testImplementation project(":test:test-logback-junit") diff --git a/examples/azure-grpc-ecosystem-example/src/main/java/no/entur/grpc/azure/example/AbstractGreetingController.java b/examples/azure-grpc-spring-example/src/main/java/no/entur/grpc/azure/example/AbstractGreetingController.java similarity index 100% rename from examples/azure-grpc-ecosystem-example/src/main/java/no/entur/grpc/azure/example/AbstractGreetingController.java rename to examples/azure-grpc-spring-example/src/main/java/no/entur/grpc/azure/example/AbstractGreetingController.java diff --git a/examples/azure-grpc-ecosystem-example/src/main/java/no/entur/grpc/azure/example/DemoApplication.java b/examples/azure-grpc-spring-example/src/main/java/no/entur/grpc/azure/example/DemoApplication.java similarity index 100% rename from examples/azure-grpc-ecosystem-example/src/main/java/no/entur/grpc/azure/example/DemoApplication.java rename to examples/azure-grpc-spring-example/src/main/java/no/entur/grpc/azure/example/DemoApplication.java diff --git a/examples/azure-grpc-ecosystem-example/src/main/java/no/entur/grpc/azure/example/GreetingController.java b/examples/azure-grpc-spring-example/src/main/java/no/entur/grpc/azure/example/GreetingController.java similarity index 91% rename from examples/azure-grpc-ecosystem-example/src/main/java/no/entur/grpc/azure/example/GreetingController.java rename to examples/azure-grpc-spring-example/src/main/java/no/entur/grpc/azure/example/GreetingController.java index 43c5d868..e87cd60a 100644 --- a/examples/azure-grpc-ecosystem-example/src/main/java/no/entur/grpc/azure/example/GreetingController.java +++ b/examples/azure-grpc-spring-example/src/main/java/no/entur/grpc/azure/example/GreetingController.java @@ -1,11 +1,11 @@ package no.entur.grpc.azure.example; -import net.devh.boot.grpc.server.service.GrpcService; import no.entur.logging.cloud.spring.rr.grpc.OrderedGrpcLoggingServerInterceptor; import no.entur.logging.cloud.spring.rr.grpc.RequestResponseGrpcExceptionHandlerInterceptor; import no.entur.logging.cloud.trace.spring.grpc.interceptor.OrderedCorrelationIdGrpcMdcContextServerInterceptor; import org.springframework.context.annotation.Profile; +import org.springframework.grpc.server.service.GrpcService; // note: order is reversed compared to lognet @GrpcService(interceptors = { @@ -19,7 +19,7 @@ // Validation MyValidationServerInterceptor.class, -}, sortInterceptors = true) +}) @Profile("!ondemand") public class GreetingController extends AbstractGreetingController { diff --git a/examples/azure-grpc-ecosystem-example/src/main/java/no/entur/grpc/azure/example/GreetingControllerWithOnDemandLogging.java b/examples/azure-grpc-spring-example/src/main/java/no/entur/grpc/azure/example/GreetingControllerWithOnDemandLogging.java similarity index 92% rename from examples/azure-grpc-ecosystem-example/src/main/java/no/entur/grpc/azure/example/GreetingControllerWithOnDemandLogging.java rename to examples/azure-grpc-spring-example/src/main/java/no/entur/grpc/azure/example/GreetingControllerWithOnDemandLogging.java index 8bb2b429..497b0ade 100644 --- a/examples/azure-grpc-ecosystem-example/src/main/java/no/entur/grpc/azure/example/GreetingControllerWithOnDemandLogging.java +++ b/examples/azure-grpc-spring-example/src/main/java/no/entur/grpc/azure/example/GreetingControllerWithOnDemandLogging.java @@ -1,12 +1,13 @@ package no.entur.grpc.azure.example; -import net.devh.boot.grpc.server.service.GrpcService; + import no.entur.logging.cloud.spring.ondemand.grpc.scope.GrpcLoggingScopeContextInterceptor; import no.entur.logging.cloud.spring.rr.grpc.OrderedGrpcLoggingServerInterceptor; import no.entur.logging.cloud.spring.rr.grpc.RequestResponseGrpcExceptionHandlerInterceptor; import no.entur.logging.cloud.trace.spring.grpc.interceptor.OrderedCorrelationIdGrpcMdcContextServerInterceptor; import org.springframework.context.annotation.Profile; +import org.springframework.grpc.server.service.GrpcService; @Profile("ondemand") @GrpcService(interceptors = { @@ -20,7 +21,7 @@ // Validation MyValidationServerInterceptor.class, -}, sortInterceptors = true) +}) public class GreetingControllerWithOnDemandLogging extends AbstractGreetingController { } \ No newline at end of file diff --git a/examples/azure-grpc-ecosystem-example/src/main/java/no/entur/grpc/azure/example/MyGrpcConfig.java b/examples/azure-grpc-spring-example/src/main/java/no/entur/grpc/azure/example/MyGrpcConfig.java similarity index 100% rename from examples/azure-grpc-ecosystem-example/src/main/java/no/entur/grpc/azure/example/MyGrpcConfig.java rename to examples/azure-grpc-spring-example/src/main/java/no/entur/grpc/azure/example/MyGrpcConfig.java diff --git a/examples/azure-grpc-ecosystem-example/src/main/java/no/entur/grpc/azure/example/MyValidationServerInterceptor.java b/examples/azure-grpc-spring-example/src/main/java/no/entur/grpc/azure/example/MyValidationServerInterceptor.java similarity index 100% rename from examples/azure-grpc-ecosystem-example/src/main/java/no/entur/grpc/azure/example/MyValidationServerInterceptor.java rename to examples/azure-grpc-spring-example/src/main/java/no/entur/grpc/azure/example/MyValidationServerInterceptor.java diff --git a/examples/azure-grpc-ecosystem-example/src/main/proto/greeting_message.proto b/examples/azure-grpc-spring-example/src/main/proto/greeting_message.proto similarity index 100% rename from examples/azure-grpc-ecosystem-example/src/main/proto/greeting_message.proto rename to examples/azure-grpc-spring-example/src/main/proto/greeting_message.proto diff --git a/examples/azure-grpc-ecosystem-example/src/main/proto/greeting_service.proto b/examples/azure-grpc-spring-example/src/main/proto/greeting_service.proto similarity index 100% rename from examples/azure-grpc-ecosystem-example/src/main/proto/greeting_service.proto rename to examples/azure-grpc-spring-example/src/main/proto/greeting_service.proto diff --git a/examples/azure-grpc-ecosystem-example/src/main/resources/application.properties b/examples/azure-grpc-spring-example/src/main/resources/application.properties similarity index 100% rename from examples/azure-grpc-ecosystem-example/src/main/resources/application.properties rename to examples/azure-grpc-spring-example/src/main/resources/application.properties diff --git a/examples/azure-grpc-ecosystem-example/src/test/java/no/entur/grpc/azure/example/EcosystemAbstractGrpcTest.java b/examples/azure-grpc-spring-example/src/test/java/no/entur/grpc/azure/example/SpringAbstractGrpcTest.java similarity index 93% rename from examples/azure-grpc-ecosystem-example/src/test/java/no/entur/grpc/azure/example/EcosystemAbstractGrpcTest.java rename to examples/azure-grpc-spring-example/src/test/java/no/entur/grpc/azure/example/SpringAbstractGrpcTest.java index 7b99944e..f8373446 100644 --- a/examples/azure-grpc-ecosystem-example/src/test/java/no/entur/grpc/azure/example/EcosystemAbstractGrpcTest.java +++ b/examples/azure-grpc-spring-example/src/test/java/no/entur/grpc/azure/example/SpringAbstractGrpcTest.java @@ -9,7 +9,7 @@ import java.util.concurrent.TimeUnit; -public class EcosystemAbstractGrpcTest { +public class SpringAbstractGrpcTest { // https://github.com/olivere/grpc-demo/blob/master/java-client/src/main/java/com/altf4/grpc/client/ExampleClient.java public static final int MAX_INBOUND_MESSAGE_SIZE = 1 << 20; @@ -23,11 +23,11 @@ public class EcosystemAbstractGrpcTest { protected final int maxOutboundMessageSize; protected final int maxInboundMessageSize; - public EcosystemAbstractGrpcTest() { + public SpringAbstractGrpcTest() { this(MAX_INBOUND_MESSAGE_SIZE, MAX_OUTBOUND_MESSAGE_SIZE); } - public EcosystemAbstractGrpcTest(int maxInboundMessageSize, int maxOutboundMessageSize) { + public SpringAbstractGrpcTest(int maxInboundMessageSize, int maxOutboundMessageSize) { this.maxInboundMessageSize = maxInboundMessageSize; this.maxOutboundMessageSize = maxOutboundMessageSize; } diff --git a/examples/azure-grpc-ecosystem-example/src/test/java/no/entur/grpc/azure/example/EcosystemGreetingTest.java b/examples/azure-grpc-spring-example/src/test/java/no/entur/grpc/azure/example/SpringGreetingTest.java similarity index 99% rename from examples/azure-grpc-ecosystem-example/src/test/java/no/entur/grpc/azure/example/EcosystemGreetingTest.java rename to examples/azure-grpc-spring-example/src/test/java/no/entur/grpc/azure/example/SpringGreetingTest.java index 26f0947e..2e72a964 100644 --- a/examples/azure-grpc-ecosystem-example/src/test/java/no/entur/grpc/azure/example/EcosystemGreetingTest.java +++ b/examples/azure-grpc-spring-example/src/test/java/no/entur/grpc/azure/example/SpringGreetingTest.java @@ -40,7 +40,7 @@ @SpringBootTest @DirtiesContext @CaptureLogStatements(level = DevOpsLevel.DEBUG, value = {"no.entur", "org.entur"}) -public class EcosystemGreetingTest extends EcosystemAbstractGrpcTest { +public class SpringGreetingTest extends SpringAbstractGrpcTest { @Test public void testBlockingRequestsOnSameStub() throws InterruptedException { diff --git a/examples/azure-grpc-ecosystem-example/src/test/java/no/entur/grpc/azure/example/EcosystemGrpcLoggingFormatTest.java b/examples/azure-grpc-spring-example/src/test/java/no/entur/grpc/azure/example/SpringGrpcLoggingFormatTest.java similarity index 95% rename from examples/azure-grpc-ecosystem-example/src/test/java/no/entur/grpc/azure/example/EcosystemGrpcLoggingFormatTest.java rename to examples/azure-grpc-spring-example/src/test/java/no/entur/grpc/azure/example/SpringGrpcLoggingFormatTest.java index 7b739a2a..31280b40 100644 --- a/examples/azure-grpc-ecosystem-example/src/test/java/no/entur/grpc/azure/example/EcosystemGrpcLoggingFormatTest.java +++ b/examples/azure-grpc-spring-example/src/test/java/no/entur/grpc/azure/example/SpringGrpcLoggingFormatTest.java @@ -12,7 +12,7 @@ @SpringBootTest @DirtiesContext -public class EcosystemGrpcLoggingFormatTest extends EcosystemAbstractGrpcTest { +public class SpringGrpcLoggingFormatTest extends SpringAbstractGrpcTest { @Test public void useHumanReadablePlainEncoderTest() throws InterruptedException { diff --git a/examples/azure-grpc-ecosystem-example/src/test/java/no/entur/grpc/azure/example/EcosystemOndemandGrpcLoggingFormatTest.java b/examples/azure-grpc-spring-example/src/test/java/no/entur/grpc/azure/example/SpringOndemandGrpcLoggingFormatTest.java similarity index 97% rename from examples/azure-grpc-ecosystem-example/src/test/java/no/entur/grpc/azure/example/EcosystemOndemandGrpcLoggingFormatTest.java rename to examples/azure-grpc-spring-example/src/test/java/no/entur/grpc/azure/example/SpringOndemandGrpcLoggingFormatTest.java index 1bb59f11..158c828c 100644 --- a/examples/azure-grpc-ecosystem-example/src/test/java/no/entur/grpc/azure/example/EcosystemOndemandGrpcLoggingFormatTest.java +++ b/examples/azure-grpc-spring-example/src/test/java/no/entur/grpc/azure/example/SpringOndemandGrpcLoggingFormatTest.java @@ -18,7 +18,7 @@ @ActiveProfiles("ondemand") @TestPropertySource(properties = {"entur.logging.grpc.ondemand.enabled=true"}) @DirtiesContext -public class EcosystemOndemandGrpcLoggingFormatTest extends EcosystemAbstractGrpcTest { +public class SpringOndemandGrpcLoggingFormatTest extends SpringAbstractGrpcTest { @Test public void useHumanReadablePlainEncoderExpectFullLogging() { diff --git a/examples/azure-grpc-ecosystem-example/src/test/java/no/entur/grpc/azure/example/EcosystemOndemandGrpcLoggingHighLogLevelTest.java b/examples/azure-grpc-spring-example/src/test/java/no/entur/grpc/azure/example/SpringOndemandGrpcLoggingHighLogLevelTest.java similarity index 95% rename from examples/azure-grpc-ecosystem-example/src/test/java/no/entur/grpc/azure/example/EcosystemOndemandGrpcLoggingHighLogLevelTest.java rename to examples/azure-grpc-spring-example/src/test/java/no/entur/grpc/azure/example/SpringOndemandGrpcLoggingHighLogLevelTest.java index 82b92c36..02dbc652 100644 --- a/examples/azure-grpc-ecosystem-example/src/test/java/no/entur/grpc/azure/example/EcosystemOndemandGrpcLoggingHighLogLevelTest.java +++ b/examples/azure-grpc-spring-example/src/test/java/no/entur/grpc/azure/example/SpringOndemandGrpcLoggingHighLogLevelTest.java @@ -26,7 +26,7 @@ "entur.logging.http.ondemand.failure.logger.level=error", }) @DirtiesContext -public class EcosystemOndemandGrpcLoggingHighLogLevelTest extends EcosystemAbstractGrpcTest { +public class SpringOndemandGrpcLoggingHighLogLevelTest extends SpringAbstractGrpcTest { @Test public void useHumanReadablePlainEncoderExpectFullLogging() throws InterruptedException { diff --git a/examples/azure-web-example/build.gradle b/examples/azure-web-example/build.gradle index 0c56158c..4e45bf91 100644 --- a/examples/azure-web-example/build.gradle +++ b/examples/azure-web-example/build.gradle @@ -1,10 +1,10 @@ plugins { - id 'org.springframework.boot' version '3.5.7' + id 'org.springframework.boot' version '4.0.1' } test { useJUnitPlatform { - includeEngines 'junit-jupiter', 'junit-vintage' + includeEngines 'junit-jupiter' } } @@ -20,6 +20,8 @@ dependencies { testImplementation project(":azure:request-response-spring-boot-starter-azure-web-test"); testImplementation("org.springframework.boot:spring-boot-starter-test") + testImplementation("org.springframework.boot:spring-boot-restclient") + testImplementation("org.springframework.boot:spring-boot-resttestclient") // JUnit Jupiter API and TestEngine implementation testImplementation("org.junit.jupiter:junit-jupiter-api") diff --git a/examples/azure-web-example/src/main/java/org/entur/example/web/config/WebSecurityConfig.java b/examples/azure-web-example/src/main/java/org/entur/example/web/config/WebSecurityConfig.java index 04a96010..bed6c3b4 100644 --- a/examples/azure-web-example/src/main/java/org/entur/example/web/config/WebSecurityConfig.java +++ b/examples/azure-web-example/src/main/java/org/entur/example/web/config/WebSecurityConfig.java @@ -12,7 +12,7 @@ public class WebSecurityConfig { @Bean public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { http - .csrf().disable() + .csrf( (c) -> c.disable()) .authorizeHttpRequests((authz) -> authz .anyRequest().permitAll()); return http.build(); diff --git a/examples/azure-web-example/src/main/java/org/entur/example/web/rest/DocumentEndpoint.java b/examples/azure-web-example/src/main/java/org/entur/example/web/rest/DocumentEndpoint.java index afbe8461..02c7b515 100644 --- a/examples/azure-web-example/src/main/java/org/entur/example/web/rest/DocumentEndpoint.java +++ b/examples/azure-web-example/src/main/java/org/entur/example/web/rest/DocumentEndpoint.java @@ -1,7 +1,6 @@ package org.entur.example.web.rest; -import com.fasterxml.jackson.core.JsonFactory; -import com.fasterxml.jackson.core.JsonGenerator; +import tools.jackson.core.JsonGenerator; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.http.HttpStatus; @@ -12,6 +11,7 @@ import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; +import tools.jackson.core.json.JsonFactory; import java.io.ByteArrayOutputStream; import java.io.CharArrayWriter; @@ -69,9 +69,9 @@ ResponseEntity bigResponse() throws IOException { JsonGenerator generator = factory.createGenerator(writer); generator.writeStartObject(); - generator.writeStringField("start", "here"); - generator.writeStringField("longValue", generateLongString(64*1024)); - generator.writeStringField("end", "here"); + generator.writeStringProperty("start", "here"); + generator.writeStringProperty("longValue", generateLongString(64*1024)); + generator.writeStringProperty("end", "here"); generator.writeEndObject(); generator.flush(); diff --git a/examples/azure-web-example/src/test/java/org/entur/example/web/OndemandWebLoggingHttpBadRequestTest.java b/examples/azure-web-example/src/test/java/org/entur/example/web/OndemandWebLoggingHttpBadRequestTest.java index 71fdc556..efd2b550 100644 --- a/examples/azure-web-example/src/test/java/org/entur/example/web/OndemandWebLoggingHttpBadRequestTest.java +++ b/examples/azure-web-example/src/test/java/org/entur/example/web/OndemandWebLoggingHttpBadRequestTest.java @@ -5,9 +5,10 @@ import org.entur.example.web.rest.MyEntity; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.resttestclient.TestRestTemplate; +import org.springframework.boot.resttestclient.autoconfigure.AutoConfigureTestRestTemplate; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; -import org.springframework.boot.test.web.client.TestRestTemplate; import org.springframework.boot.test.web.server.LocalServerPort; import org.springframework.http.HttpEntity; import org.springframework.http.HttpHeaders; @@ -27,6 +28,7 @@ @SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT) @TestPropertySource(properties = {"entur.logging.http.ondemand.enabled=true", "entur.logging.http.ondemand.failure.http.statusCode.equalOrHigherThan=400"}) +@AutoConfigureTestRestTemplate public class OndemandWebLoggingHttpBadRequestTest { @LocalServerPort diff --git a/examples/azure-web-example/src/test/java/org/entur/example/web/OndemandWebLoggingHttpNotFound1Test.java b/examples/azure-web-example/src/test/java/org/entur/example/web/OndemandWebLoggingHttpNotFound1Test.java index 7ff37660..02a71c3b 100644 --- a/examples/azure-web-example/src/test/java/org/entur/example/web/OndemandWebLoggingHttpNotFound1Test.java +++ b/examples/azure-web-example/src/test/java/org/entur/example/web/OndemandWebLoggingHttpNotFound1Test.java @@ -5,9 +5,10 @@ import org.entur.example.web.rest.MyEntity; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.resttestclient.autoconfigure.AutoConfigureTestRestTemplate; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; -import org.springframework.boot.test.web.client.TestRestTemplate; +import org.springframework.boot.resttestclient.TestRestTemplate; import org.springframework.boot.test.web.server.LocalServerPort; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; @@ -23,6 +24,7 @@ @SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT) @TestPropertySource(properties = {"entur.logging.http.ondemand.enabled=true", "entur.logging.http.ondemand.failure.http.statusCode.equalOrHigherThan=400"}) +@AutoConfigureTestRestTemplate public class OndemandWebLoggingHttpNotFound1Test { @LocalServerPort diff --git a/examples/azure-web-example/src/test/java/org/entur/example/web/OndemandWebLoggingHttpNotFound2Test.java b/examples/azure-web-example/src/test/java/org/entur/example/web/OndemandWebLoggingHttpNotFound2Test.java index bad86893..960caa58 100644 --- a/examples/azure-web-example/src/test/java/org/entur/example/web/OndemandWebLoggingHttpNotFound2Test.java +++ b/examples/azure-web-example/src/test/java/org/entur/example/web/OndemandWebLoggingHttpNotFound2Test.java @@ -5,9 +5,10 @@ import org.entur.example.web.rest.MyEntity; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.resttestclient.autoconfigure.AutoConfigureTestRestTemplate; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; -import org.springframework.boot.test.web.client.TestRestTemplate; +import org.springframework.boot.resttestclient.TestRestTemplate; import org.springframework.boot.test.web.server.LocalServerPort; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; @@ -24,6 +25,7 @@ */ @TestPropertySource(properties = {"entur.logging.http.ondemand.enabled=true", "entur.logging.http.ondemand.failure.http.statusCode.equalOrHigherThan=400"}) +@AutoConfigureTestRestTemplate public class OndemandWebLoggingHttpNotFound2Test { @LocalServerPort diff --git a/examples/azure-web-example/src/test/java/org/entur/example/web/OndemandWebLoggingHttpOkHighLogLevelTest.java b/examples/azure-web-example/src/test/java/org/entur/example/web/OndemandWebLoggingHttpOkHighLogLevelTest.java index 6a26c6a4..d7cf5677 100644 --- a/examples/azure-web-example/src/test/java/org/entur/example/web/OndemandWebLoggingHttpOkHighLogLevelTest.java +++ b/examples/azure-web-example/src/test/java/org/entur/example/web/OndemandWebLoggingHttpOkHighLogLevelTest.java @@ -5,9 +5,10 @@ import org.entur.example.web.rest.MyEntity; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.resttestclient.autoconfigure.AutoConfigureTestRestTemplate; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; -import org.springframework.boot.test.web.client.TestRestTemplate; +import org.springframework.boot.resttestclient.TestRestTemplate; import org.springframework.boot.test.web.server.LocalServerPort; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; @@ -26,6 +27,7 @@ "entur.logging.http.ondemand.enabled=true", "entur.logging.http.ondemand.failure.logger.level=error", }) +@AutoConfigureTestRestTemplate public class OndemandWebLoggingHttpOkHighLogLevelTest { @LocalServerPort diff --git a/examples/azure-web-example/src/test/java/org/entur/example/web/OndemandWebLoggingHttpOkTest.java b/examples/azure-web-example/src/test/java/org/entur/example/web/OndemandWebLoggingHttpOkTest.java index 9b4d2753..08170873 100644 --- a/examples/azure-web-example/src/test/java/org/entur/example/web/OndemandWebLoggingHttpOkTest.java +++ b/examples/azure-web-example/src/test/java/org/entur/example/web/OndemandWebLoggingHttpOkTest.java @@ -5,9 +5,10 @@ import org.entur.example.web.rest.MyEntity; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.resttestclient.autoconfigure.AutoConfigureTestRestTemplate; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; -import org.springframework.boot.test.web.client.TestRestTemplate; +import org.springframework.boot.resttestclient.TestRestTemplate; import org.springframework.boot.test.web.server.LocalServerPort; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; @@ -18,6 +19,7 @@ @SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT) @TestPropertySource(properties = {"entur.logging.http.ondemand.enabled=true", "entur.logging.http.ondemand.failure.http.statusCode.equalOrHigherThan=400"}) +@AutoConfigureTestRestTemplate public class OndemandWebLoggingHttpOkTest { @LocalServerPort diff --git a/examples/azure-web-example/src/test/java/org/entur/example/web/OndemandWebLoggingHttpOkTroubleshootingTest.java b/examples/azure-web-example/src/test/java/org/entur/example/web/OndemandWebLoggingHttpOkTroubleshootingTest.java index e88a317d..92363f9e 100644 --- a/examples/azure-web-example/src/test/java/org/entur/example/web/OndemandWebLoggingHttpOkTroubleshootingTest.java +++ b/examples/azure-web-example/src/test/java/org/entur/example/web/OndemandWebLoggingHttpOkTroubleshootingTest.java @@ -5,9 +5,10 @@ import org.entur.example.web.rest.MyEntity; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.resttestclient.autoconfigure.AutoConfigureTestRestTemplate; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; -import org.springframework.boot.test.web.client.TestRestTemplate; +import org.springframework.boot.resttestclient.TestRestTemplate; import org.springframework.boot.test.web.server.LocalServerPort; import org.springframework.http.*; import org.springframework.test.context.TestPropertySource; @@ -21,6 +22,7 @@ "entur.logging.http.ondemand.failure.http.statusCode.equalOrHigherThan=400", "entur.logging.http.ondemand.troubleshoot.http.headers[0].name=X-DEBUG" }) +@AutoConfigureTestRestTemplate public class OndemandWebLoggingHttpOkTroubleshootingTest { @LocalServerPort diff --git a/examples/azure-web-example/src/test/java/org/entur/example/web/WebLoggingFormatTest.java b/examples/azure-web-example/src/test/java/org/entur/example/web/WebLoggingFormatTest.java index 5aeef7f4..6b828ab9 100644 --- a/examples/azure-web-example/src/test/java/org/entur/example/web/WebLoggingFormatTest.java +++ b/examples/azure-web-example/src/test/java/org/entur/example/web/WebLoggingFormatTest.java @@ -7,14 +7,16 @@ import org.entur.example.web.rest.MyEntity; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.resttestclient.autoconfigure.AutoConfigureTestRestTemplate; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; -import org.springframework.boot.test.web.client.TestRestTemplate; +import org.springframework.boot.resttestclient.TestRestTemplate; import org.springframework.boot.test.web.server.LocalServerPort; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; @SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT) +@AutoConfigureTestRestTemplate public class WebLoggingFormatTest { @LocalServerPort diff --git a/examples/azure-web-example/src/test/java/org/entur/example/web/WebLoggingFormatViaProfileTest.java b/examples/azure-web-example/src/test/java/org/entur/example/web/WebLoggingFormatViaProfileTest.java index 039197e6..554778f4 100644 --- a/examples/azure-web-example/src/test/java/org/entur/example/web/WebLoggingFormatViaProfileTest.java +++ b/examples/azure-web-example/src/test/java/org/entur/example/web/WebLoggingFormatViaProfileTest.java @@ -6,9 +6,10 @@ import org.junit.jupiter.api.Test; import org.springframework.beans.factory.InitializingBean; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.resttestclient.autoconfigure.AutoConfigureTestRestTemplate; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; -import org.springframework.boot.test.web.client.TestRestTemplate; +import org.springframework.boot.resttestclient.TestRestTemplate; import org.springframework.boot.test.web.server.LocalServerPort; import org.springframework.context.ApplicationListener; import org.springframework.context.annotation.Bean; @@ -24,6 +25,7 @@ @SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT) @ActiveProfiles("local") +@AutoConfigureTestRestTemplate public class WebLoggingFormatViaProfileTest { @LocalServerPort diff --git a/examples/azure-web-example/src/test/java/org/entur/example/web/WebLoggingFormatViaPropertyTest.java b/examples/azure-web-example/src/test/java/org/entur/example/web/WebLoggingFormatViaPropertyTest.java index 59ff0859..b39e7704 100644 --- a/examples/azure-web-example/src/test/java/org/entur/example/web/WebLoggingFormatViaPropertyTest.java +++ b/examples/azure-web-example/src/test/java/org/entur/example/web/WebLoggingFormatViaPropertyTest.java @@ -3,9 +3,10 @@ import org.entur.example.web.rest.MyEntity; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.resttestclient.autoconfigure.AutoConfigureTestRestTemplate; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; -import org.springframework.boot.test.web.client.TestRestTemplate; +import org.springframework.boot.resttestclient.TestRestTemplate; import org.springframework.boot.test.web.server.LocalServerPort; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; @@ -17,6 +18,7 @@ @TestPropertySource(properties = { "entur.logging.style=HumanReadableJson", }) +@AutoConfigureTestRestTemplate public class WebLoggingFormatViaPropertyTest { @LocalServerPort diff --git a/examples/azure-web-example/src/test/java/org/entur/example/web/WebLoggingFormatWithBigResponsesTest.java b/examples/azure-web-example/src/test/java/org/entur/example/web/WebLoggingFormatWithBigResponsesTest.java index b8779881..5ca80c03 100644 --- a/examples/azure-web-example/src/test/java/org/entur/example/web/WebLoggingFormatWithBigResponsesTest.java +++ b/examples/azure-web-example/src/test/java/org/entur/example/web/WebLoggingFormatWithBigResponsesTest.java @@ -5,9 +5,10 @@ import org.entur.example.web.rest.MyEntity; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.resttestclient.autoconfigure.AutoConfigureTestRestTemplate; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; -import org.springframework.boot.test.web.client.TestRestTemplate; +import org.springframework.boot.resttestclient.TestRestTemplate; import org.springframework.boot.test.web.server.LocalServerPort; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; @@ -15,6 +16,7 @@ import static org.assertj.core.api.Assertions.assertThat; @SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT) +@AutoConfigureTestRestTemplate public class WebLoggingFormatWithBigResponsesTest { @LocalServerPort diff --git a/examples/azure-web-example/src/test/java/org/entur/example/web/WebLoggingFormatWithNewlinesTest.java b/examples/azure-web-example/src/test/java/org/entur/example/web/WebLoggingFormatWithNewlinesTest.java index 0e9d7d4f..26503314 100644 --- a/examples/azure-web-example/src/test/java/org/entur/example/web/WebLoggingFormatWithNewlinesTest.java +++ b/examples/azure-web-example/src/test/java/org/entur/example/web/WebLoggingFormatWithNewlinesTest.java @@ -5,9 +5,10 @@ import org.entur.example.web.rest.MyEntity; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.resttestclient.autoconfigure.AutoConfigureTestRestTemplate; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; -import org.springframework.boot.test.web.client.TestRestTemplate; +import org.springframework.boot.resttestclient.TestRestTemplate; import org.springframework.boot.test.web.server.LocalServerPort; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; @@ -15,6 +16,7 @@ import static org.assertj.core.api.Assertions.assertThat; @SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT) +@AutoConfigureTestRestTemplate public class WebLoggingFormatWithNewlinesTest { @LocalServerPort diff --git a/examples/gcp-async-web-example/build.gradle b/examples/gcp-async-web-example/build.gradle index 6b27a7f7..7601e610 100644 --- a/examples/gcp-async-web-example/build.gradle +++ b/examples/gcp-async-web-example/build.gradle @@ -1,10 +1,10 @@ plugins { - id 'org.springframework.boot' version '3.5.7' + id 'org.springframework.boot' version '4.0.1' } test { useJUnitPlatform { - includeEngines 'junit-jupiter', 'junit-vintage' + includeEngines 'junit-jupiter' } } @@ -21,6 +21,8 @@ dependencies { testImplementation project(":gcp:request-response-spring-boot-starter-gcp-web-test"); testImplementation("org.springframework.boot:spring-boot-starter-test") + testImplementation("org.springframework.boot:spring-boot-restclient") + testImplementation("org.springframework.boot:spring-boot-resttestclient") // JUnit Jupiter API and TestEngine implementation testImplementation("org.junit.jupiter:junit-jupiter-api") diff --git a/examples/gcp-async-web-example/src/main/java/org/entur/example/web/config/WebSecurityConfig.java b/examples/gcp-async-web-example/src/main/java/org/entur/example/web/config/WebSecurityConfig.java index 04a96010..bed6c3b4 100644 --- a/examples/gcp-async-web-example/src/main/java/org/entur/example/web/config/WebSecurityConfig.java +++ b/examples/gcp-async-web-example/src/main/java/org/entur/example/web/config/WebSecurityConfig.java @@ -12,7 +12,7 @@ public class WebSecurityConfig { @Bean public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { http - .csrf().disable() + .csrf( (c) -> c.disable()) .authorizeHttpRequests((authz) -> authz .anyRequest().permitAll()); return http.build(); diff --git a/examples/gcp-async-web-example/src/main/java/org/entur/example/web/rest/AsyncDocumentEndpoint.java b/examples/gcp-async-web-example/src/main/java/org/entur/example/web/rest/AsyncDocumentEndpoint.java index efa45f6a..203cde38 100644 --- a/examples/gcp-async-web-example/src/main/java/org/entur/example/web/rest/AsyncDocumentEndpoint.java +++ b/examples/gcp-async-web-example/src/main/java/org/entur/example/web/rest/AsyncDocumentEndpoint.java @@ -1,7 +1,6 @@ package org.entur.example.web.rest; -import com.fasterxml.jackson.core.JsonFactory; -import com.fasterxml.jackson.core.JsonGenerator; +import tools.jackson.core.JsonGenerator; import no.entur.logging.cloud.spring.ondemand.web.scope.LoggingScopeThreadUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -9,6 +8,7 @@ import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.*; +import tools.jackson.core.json.JsonFactory; import java.io.CharArrayWriter; import java.io.IOException; @@ -120,9 +120,9 @@ public CompletableFuture> bigResponse() throws IOExceptio JsonGenerator generator = factory.createGenerator(writer); generator.writeStartObject(); - generator.writeStringField("start", "here"); - generator.writeStringField("longValue", generateLongString(64*1024)); - generator.writeStringField("end", "here"); + generator.writeStringProperty("start", "here"); + generator.writeStringProperty("longValue", generateLongString(64*1024)); + generator.writeStringProperty("end", "here"); generator.writeEndObject(); generator.flush(); diff --git a/examples/gcp-async-web-example/src/test/java/org/entur/example/web/ActuatorTest.java b/examples/gcp-async-web-example/src/test/java/org/entur/example/web/ActuatorTest.java index bc23e7db..310cdac5 100644 --- a/examples/gcp-async-web-example/src/test/java/org/entur/example/web/ActuatorTest.java +++ b/examples/gcp-async-web-example/src/test/java/org/entur/example/web/ActuatorTest.java @@ -6,9 +6,10 @@ import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; +import org.springframework.boot.resttestclient.autoconfigure.AutoConfigureTestRestTemplate; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; -import org.springframework.boot.test.web.client.TestRestTemplate; +import org.springframework.boot.resttestclient.TestRestTemplate; import org.springframework.boot.test.web.server.LocalServerPort; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; @@ -16,6 +17,7 @@ import static org.assertj.core.api.Assertions.assertThat; @SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT) +@AutoConfigureTestRestTemplate public class ActuatorTest { @LocalServerPort diff --git a/examples/gcp-async-web-example/src/test/java/org/entur/example/web/AsyncOndemandAllFeaturesTest.java b/examples/gcp-async-web-example/src/test/java/org/entur/example/web/AsyncOndemandAllFeaturesTest.java index eedc2b72..842f3ba6 100644 --- a/examples/gcp-async-web-example/src/test/java/org/entur/example/web/AsyncOndemandAllFeaturesTest.java +++ b/examples/gcp-async-web-example/src/test/java/org/entur/example/web/AsyncOndemandAllFeaturesTest.java @@ -3,9 +3,10 @@ import org.entur.example.web.rest.MyEntity; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.resttestclient.autoconfigure.AutoConfigureTestRestTemplate; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; -import org.springframework.boot.test.web.client.TestRestTemplate; +import org.springframework.boot.resttestclient.TestRestTemplate; import org.springframework.boot.test.web.server.LocalServerPort; import org.springframework.http.HttpEntity; import org.springframework.http.HttpHeaders; @@ -29,6 +30,7 @@ "entur.logging.http.ondemand.troubleshoot.http.headers[0].name=entur-debug-request", "entur.logging.http.ondemand.flush-mode=LAZY", }) +@AutoConfigureTestRestTemplate public class AsyncOndemandAllFeaturesTest { diff --git a/examples/gcp-async-web-example/src/test/java/org/entur/example/web/AsyncOndemandWebLoggingHttpBadRequestTest.java b/examples/gcp-async-web-example/src/test/java/org/entur/example/web/AsyncOndemandWebLoggingHttpBadRequestTest.java index 4ed37dd1..2c4df288 100644 --- a/examples/gcp-async-web-example/src/test/java/org/entur/example/web/AsyncOndemandWebLoggingHttpBadRequestTest.java +++ b/examples/gcp-async-web-example/src/test/java/org/entur/example/web/AsyncOndemandWebLoggingHttpBadRequestTest.java @@ -5,9 +5,10 @@ import org.entur.example.web.rest.MyEntity; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.resttestclient.autoconfigure.AutoConfigureTestRestTemplate; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; -import org.springframework.boot.test.web.client.TestRestTemplate; +import org.springframework.boot.resttestclient.TestRestTemplate; import org.springframework.boot.test.web.server.LocalServerPort; import org.springframework.http.HttpEntity; import org.springframework.http.HttpHeaders; @@ -30,6 +31,8 @@ "entur.logging.http.ondemand.enabled=true", "entur.logging.http.ondemand.failure.logger.enabled=false", }) +@AutoConfigureTestRestTemplate + public class AsyncOndemandWebLoggingHttpBadRequestTest { @LocalServerPort diff --git a/examples/gcp-async-web-example/src/test/java/org/entur/example/web/AsyncOndemandWebLoggingHttpNotFound1Test.java b/examples/gcp-async-web-example/src/test/java/org/entur/example/web/AsyncOndemandWebLoggingHttpNotFound1Test.java index b738feef..76cc3501 100644 --- a/examples/gcp-async-web-example/src/test/java/org/entur/example/web/AsyncOndemandWebLoggingHttpNotFound1Test.java +++ b/examples/gcp-async-web-example/src/test/java/org/entur/example/web/AsyncOndemandWebLoggingHttpNotFound1Test.java @@ -5,9 +5,10 @@ import org.entur.example.web.rest.MyEntity; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.resttestclient.autoconfigure.AutoConfigureTestRestTemplate; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; -import org.springframework.boot.test.web.client.TestRestTemplate; +import org.springframework.boot.resttestclient.TestRestTemplate; import org.springframework.boot.test.web.server.LocalServerPort; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; @@ -26,6 +27,7 @@ "entur.logging.http.ondemand.enabled=true", "entur.logging.http.ondemand.failure.logger.enabled=false", }) +@AutoConfigureTestRestTemplate public class AsyncOndemandWebLoggingHttpNotFound1Test { @LocalServerPort diff --git a/examples/gcp-async-web-example/src/test/java/org/entur/example/web/AsyncOndemandWebLoggingHttpNotFound2Test.java b/examples/gcp-async-web-example/src/test/java/org/entur/example/web/AsyncOndemandWebLoggingHttpNotFound2Test.java index ff9360b0..08a42fe7 100644 --- a/examples/gcp-async-web-example/src/test/java/org/entur/example/web/AsyncOndemandWebLoggingHttpNotFound2Test.java +++ b/examples/gcp-async-web-example/src/test/java/org/entur/example/web/AsyncOndemandWebLoggingHttpNotFound2Test.java @@ -5,9 +5,10 @@ import org.entur.example.web.rest.MyEntity; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.resttestclient.autoconfigure.AutoConfigureTestRestTemplate; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; -import org.springframework.boot.test.web.client.TestRestTemplate; +import org.springframework.boot.resttestclient.TestRestTemplate; import org.springframework.boot.test.web.server.LocalServerPort; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; @@ -27,6 +28,7 @@ "entur.logging.http.ondemand.enabled=true", "entur.logging.http.ondemand.failure.logger.enabled=false", }) +@AutoConfigureTestRestTemplate public class AsyncOndemandWebLoggingHttpNotFound2Test { @LocalServerPort diff --git a/examples/gcp-async-web-example/src/test/java/org/entur/example/web/AsyncOndemandWebLoggingHttpOkHighLogLevelTest.java b/examples/gcp-async-web-example/src/test/java/org/entur/example/web/AsyncOndemandWebLoggingHttpOkHighLogLevelTest.java index 2b40fe46..2d03f1ad 100644 --- a/examples/gcp-async-web-example/src/test/java/org/entur/example/web/AsyncOndemandWebLoggingHttpOkHighLogLevelTest.java +++ b/examples/gcp-async-web-example/src/test/java/org/entur/example/web/AsyncOndemandWebLoggingHttpOkHighLogLevelTest.java @@ -5,9 +5,10 @@ import org.entur.example.web.rest.MyEntity; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.resttestclient.autoconfigure.AutoConfigureTestRestTemplate; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; -import org.springframework.boot.test.web.client.TestRestTemplate; +import org.springframework.boot.resttestclient.TestRestTemplate; import org.springframework.boot.test.web.server.LocalServerPort; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; @@ -27,6 +28,7 @@ "entur.logging.http.ondemand.failure.http.enabled=false", "entur.logging.http.ondemand.failure.logger.level=error", }) +@AutoConfigureTestRestTemplate public class AsyncOndemandWebLoggingHttpOkHighLogLevelTest { @LocalServerPort diff --git a/examples/gcp-async-web-example/src/test/java/org/entur/example/web/AsyncOndemandWebLoggingHttpOkTest.java b/examples/gcp-async-web-example/src/test/java/org/entur/example/web/AsyncOndemandWebLoggingHttpOkTest.java index 39f47497..ad2f2a52 100644 --- a/examples/gcp-async-web-example/src/test/java/org/entur/example/web/AsyncOndemandWebLoggingHttpOkTest.java +++ b/examples/gcp-async-web-example/src/test/java/org/entur/example/web/AsyncOndemandWebLoggingHttpOkTest.java @@ -5,9 +5,10 @@ import org.entur.example.web.rest.MyEntity; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.resttestclient.autoconfigure.AutoConfigureTestRestTemplate; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; -import org.springframework.boot.test.web.client.TestRestTemplate; +import org.springframework.boot.resttestclient.TestRestTemplate; import org.springframework.boot.test.web.server.LocalServerPort; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; @@ -20,6 +21,7 @@ // Triggers by error log level or >= 400 status code by default @TestPropertySource(properties = {"entur.logging.http.ondemand.enabled=true"}) +@AutoConfigureTestRestTemplate public class AsyncOndemandWebLoggingHttpOkTest { @LocalServerPort diff --git a/examples/gcp-async-web-example/src/test/java/org/entur/example/web/AsyncOndemandWebLoggingHttpOkTroubleshootingTest.java b/examples/gcp-async-web-example/src/test/java/org/entur/example/web/AsyncOndemandWebLoggingHttpOkTroubleshootingTest.java index 5e55d000..3d8455b0 100644 --- a/examples/gcp-async-web-example/src/test/java/org/entur/example/web/AsyncOndemandWebLoggingHttpOkTroubleshootingTest.java +++ b/examples/gcp-async-web-example/src/test/java/org/entur/example/web/AsyncOndemandWebLoggingHttpOkTroubleshootingTest.java @@ -5,9 +5,10 @@ import org.entur.example.web.rest.MyEntity; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.resttestclient.autoconfigure.AutoConfigureTestRestTemplate; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; -import org.springframework.boot.test.web.client.TestRestTemplate; +import org.springframework.boot.resttestclient.TestRestTemplate; import org.springframework.boot.test.web.server.LocalServerPort; import org.springframework.http.*; import org.springframework.test.context.TestPropertySource; @@ -22,6 +23,7 @@ "entur.logging.http.ondemand.failure.logger.enabled=false", "entur.logging.http.ondemand.troubleshoot.http.headers[0].name=X-DEBUG" }) +@AutoConfigureTestRestTemplate public class AsyncOndemandWebLoggingHttpOkTroubleshootingTest { @LocalServerPort diff --git a/examples/gcp-async-web-example/src/test/java/org/entur/example/web/AsyncOndemandWebLoggingSlowResponseTest.java b/examples/gcp-async-web-example/src/test/java/org/entur/example/web/AsyncOndemandWebLoggingSlowResponseTest.java index 25b0f34c..2dedc579 100644 --- a/examples/gcp-async-web-example/src/test/java/org/entur/example/web/AsyncOndemandWebLoggingSlowResponseTest.java +++ b/examples/gcp-async-web-example/src/test/java/org/entur/example/web/AsyncOndemandWebLoggingSlowResponseTest.java @@ -5,9 +5,10 @@ import org.entur.example.web.rest.MyEntity; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.resttestclient.autoconfigure.AutoConfigureTestRestTemplate; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; -import org.springframework.boot.test.web.client.TestRestTemplate; +import org.springframework.boot.resttestclient.TestRestTemplate; import org.springframework.boot.test.web.server.LocalServerPort; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; @@ -29,6 +30,7 @@ "entur.logging.http.ondemand.failure.duration.enabled=true", "entur.logging.http.ondemand.failure.duration.after=500ms", }) +@AutoConfigureTestRestTemplate public class AsyncOndemandWebLoggingSlowResponseTest { @LocalServerPort diff --git a/examples/gcp-async-web-example/src/test/java/org/entur/example/web/AsyncWebLoggingFormatTest.java b/examples/gcp-async-web-example/src/test/java/org/entur/example/web/AsyncWebLoggingFormatTest.java index 0522d23f..442768d8 100644 --- a/examples/gcp-async-web-example/src/test/java/org/entur/example/web/AsyncWebLoggingFormatTest.java +++ b/examples/gcp-async-web-example/src/test/java/org/entur/example/web/AsyncWebLoggingFormatTest.java @@ -7,14 +7,16 @@ import org.entur.example.web.rest.MyEntity; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.resttestclient.autoconfigure.AutoConfigureTestRestTemplate; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; -import org.springframework.boot.test.web.client.TestRestTemplate; +import org.springframework.boot.resttestclient.TestRestTemplate; import org.springframework.boot.test.web.server.LocalServerPort; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; @SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT) +@AutoConfigureTestRestTemplate public class AsyncWebLoggingFormatTest { @LocalServerPort diff --git a/examples/gcp-async-web-example/src/test/java/org/entur/example/web/AsyncWebLoggingFormatViaProfileTest.java b/examples/gcp-async-web-example/src/test/java/org/entur/example/web/AsyncWebLoggingFormatViaProfileTest.java index 154086f0..5ea2b2c4 100644 --- a/examples/gcp-async-web-example/src/test/java/org/entur/example/web/AsyncWebLoggingFormatViaProfileTest.java +++ b/examples/gcp-async-web-example/src/test/java/org/entur/example/web/AsyncWebLoggingFormatViaProfileTest.java @@ -3,9 +3,10 @@ import org.entur.example.web.rest.MyEntity; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.resttestclient.autoconfigure.AutoConfigureTestRestTemplate; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; -import org.springframework.boot.test.web.client.TestRestTemplate; +import org.springframework.boot.resttestclient.TestRestTemplate; import org.springframework.boot.test.web.server.LocalServerPort; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; @@ -15,6 +16,7 @@ @SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT) @ActiveProfiles("local") +@AutoConfigureTestRestTemplate public class AsyncWebLoggingFormatViaProfileTest { @LocalServerPort diff --git a/examples/gcp-async-web-example/src/test/java/org/entur/example/web/AsyncWebLoggingFormatWithBigResponsesTest.java b/examples/gcp-async-web-example/src/test/java/org/entur/example/web/AsyncWebLoggingFormatWithBigResponsesTest.java index ddb872dd..738217a6 100644 --- a/examples/gcp-async-web-example/src/test/java/org/entur/example/web/AsyncWebLoggingFormatWithBigResponsesTest.java +++ b/examples/gcp-async-web-example/src/test/java/org/entur/example/web/AsyncWebLoggingFormatWithBigResponsesTest.java @@ -4,9 +4,10 @@ import no.entur.logging.cloud.logback.logstash.test.CompositeConsoleOutputControlClosable; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.resttestclient.autoconfigure.AutoConfigureTestRestTemplate; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; -import org.springframework.boot.test.web.client.TestRestTemplate; +import org.springframework.boot.resttestclient.TestRestTemplate; import org.springframework.boot.test.web.server.LocalServerPort; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; @@ -14,6 +15,7 @@ import static org.assertj.core.api.Assertions.assertThat; @SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT) +@AutoConfigureTestRestTemplate public class AsyncWebLoggingFormatWithBigResponsesTest { @LocalServerPort diff --git a/examples/gcp-async-web-example/src/test/java/org/entur/example/web/AsyncWebLoggingFormatWithNewlinesTest.java b/examples/gcp-async-web-example/src/test/java/org/entur/example/web/AsyncWebLoggingFormatWithNewlinesTest.java index bc68cb19..7668a813 100644 --- a/examples/gcp-async-web-example/src/test/java/org/entur/example/web/AsyncWebLoggingFormatWithNewlinesTest.java +++ b/examples/gcp-async-web-example/src/test/java/org/entur/example/web/AsyncWebLoggingFormatWithNewlinesTest.java @@ -5,9 +5,10 @@ import org.entur.example.web.rest.MyEntity; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.resttestclient.autoconfigure.AutoConfigureTestRestTemplate; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; -import org.springframework.boot.test.web.client.TestRestTemplate; +import org.springframework.boot.resttestclient.TestRestTemplate; import org.springframework.boot.test.web.server.LocalServerPort; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; @@ -15,6 +16,7 @@ import static org.assertj.core.api.Assertions.assertThat; @SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT) +@AutoConfigureTestRestTemplate public class AsyncWebLoggingFormatWithNewlinesTest { @LocalServerPort diff --git a/examples/azure-grpc-ecosystem-example/README.md b/examples/gcp-grpc-spring-example/README.md similarity index 62% rename from examples/azure-grpc-ecosystem-example/README.md rename to examples/gcp-grpc-spring-example/README.md index 87077ce1..27b35ed5 100644 --- a/examples/azure-grpc-ecosystem-example/README.md +++ b/examples/gcp-grpc-spring-example/README.md @@ -1,4 +1,4 @@ -# azure-grpc-ecosystem-example +# gcp-grpc-spring-example Simple gRPC server example with a few unit tests. diff --git a/examples/gcp-grpc-ecosystem-example/build.gradle b/examples/gcp-grpc-spring-example/build.gradle similarity index 87% rename from examples/gcp-grpc-ecosystem-example/build.gradle rename to examples/gcp-grpc-spring-example/build.gradle index 5a471f30..873cd14d 100644 --- a/examples/gcp-grpc-ecosystem-example/build.gradle +++ b/examples/gcp-grpc-spring-example/build.gradle @@ -1,21 +1,21 @@ plugins { - id 'org.springframework.boot' version '3.5.7' + id 'org.springframework.boot' version '4.0.1' id "com.google.protobuf" version "0.9.6" } test { useJUnitPlatform { - includeEngines 'junit-jupiter', 'junit-vintage' + includeEngines 'junit-jupiter' } } dependencies { implementation project(':on-demand:on-demand-spring-boot-starter-grpc') - implementation project(':gcp:spring-boot-starter-gcp-grpc-ecosystem') - implementation project(':gcp:request-response-spring-boot-starter-gcp-grpc-ecosystem') + implementation project(':gcp:spring-boot-starter-gcp-grpc-spring') + implementation project(':gcp:request-response-spring-boot-starter-gcp-grpc-spring') implementation project(':trace:server:correlation-id-trace-grpc-netty') implementation project(':trace:mdc-context-grpc-netty') - implementation project(':request-response:request-response-spring-boot-autoconfigure-grpc-ecosystem') + implementation project(':request-response:request-response-spring-boot-autoconfigure-grpc-spring') implementation("io.grpc:grpc-api:$grpcVersion") implementation("io.grpc:grpc-core:$grpcVersion") @@ -29,8 +29,8 @@ dependencies { implementation("javax.annotation:javax.annotation-api:1.3.2") - testImplementation project(":gcp:spring-boot-starter-gcp-grpc-ecosystem-test") - testImplementation project(':gcp:request-response-spring-boot-starter-gcp-grpc-ecosystem-test') + testImplementation project(":gcp:spring-boot-starter-gcp-grpc-spring-test") + testImplementation project(':gcp:request-response-spring-boot-starter-gcp-grpc-spring-test') testImplementation("org.springframework.boot:spring-boot-starter-test") // added due to grpc plugin dependency resolution problem diff --git a/examples/gcp-grpc-ecosystem-example/src/main/java/no/entur/grpc/example/AbstractGreetingController.java b/examples/gcp-grpc-spring-example/src/main/java/no/entur/grpc/example/AbstractGreetingController.java similarity index 100% rename from examples/gcp-grpc-ecosystem-example/src/main/java/no/entur/grpc/example/AbstractGreetingController.java rename to examples/gcp-grpc-spring-example/src/main/java/no/entur/grpc/example/AbstractGreetingController.java diff --git a/examples/gcp-grpc-ecosystem-example/src/main/java/no/entur/grpc/example/DemoApplication.java b/examples/gcp-grpc-spring-example/src/main/java/no/entur/grpc/example/DemoApplication.java similarity index 100% rename from examples/gcp-grpc-ecosystem-example/src/main/java/no/entur/grpc/example/DemoApplication.java rename to examples/gcp-grpc-spring-example/src/main/java/no/entur/grpc/example/DemoApplication.java diff --git a/examples/gcp-grpc-ecosystem-example/src/main/java/no/entur/grpc/example/GreetingController.java b/examples/gcp-grpc-spring-example/src/main/java/no/entur/grpc/example/GreetingController.java similarity index 92% rename from examples/gcp-grpc-ecosystem-example/src/main/java/no/entur/grpc/example/GreetingController.java rename to examples/gcp-grpc-spring-example/src/main/java/no/entur/grpc/example/GreetingController.java index 044bb3d0..6dea440c 100644 --- a/examples/gcp-grpc-ecosystem-example/src/main/java/no/entur/grpc/example/GreetingController.java +++ b/examples/gcp-grpc-spring-example/src/main/java/no/entur/grpc/example/GreetingController.java @@ -1,12 +1,12 @@ package no.entur.grpc.example; -import net.devh.boot.grpc.server.service.GrpcService; import no.entur.logging.cloud.gcp.trace.spring.grpc.interceptor.OrderedTraceIdGrpcMdcContextServerInterceptor; import no.entur.logging.cloud.spring.rr.grpc.OrderedGrpcLoggingServerInterceptor; import no.entur.logging.cloud.spring.rr.grpc.RequestResponseGrpcExceptionHandlerInterceptor; import no.entur.logging.cloud.trace.spring.grpc.interceptor.OrderedCorrelationIdGrpcMdcContextServerInterceptor; import org.springframework.context.annotation.Profile; +import org.springframework.grpc.server.service.GrpcService; // note: order is reversed compared to lognet @GrpcService(interceptors = { @@ -21,7 +21,7 @@ // Validation MyValidationServerInterceptor.class, -}, sortInterceptors = true) +}) @Profile("!ondemand") public class GreetingController extends AbstractGreetingController { diff --git a/examples/gcp-grpc-ecosystem-without-test-artifacts-example/src/main/java/no/entur/grpc/example/GreetingControllerWithOnDemandLogging.java b/examples/gcp-grpc-spring-example/src/main/java/no/entur/grpc/example/GreetingControllerWithOnDemandLogging.java similarity index 93% rename from examples/gcp-grpc-ecosystem-without-test-artifacts-example/src/main/java/no/entur/grpc/example/GreetingControllerWithOnDemandLogging.java rename to examples/gcp-grpc-spring-example/src/main/java/no/entur/grpc/example/GreetingControllerWithOnDemandLogging.java index 7570840f..4e3404ff 100644 --- a/examples/gcp-grpc-ecosystem-without-test-artifacts-example/src/main/java/no/entur/grpc/example/GreetingControllerWithOnDemandLogging.java +++ b/examples/gcp-grpc-spring-example/src/main/java/no/entur/grpc/example/GreetingControllerWithOnDemandLogging.java @@ -1,13 +1,13 @@ package no.entur.grpc.example; -import net.devh.boot.grpc.server.service.GrpcService; import no.entur.logging.cloud.gcp.trace.spring.grpc.interceptor.OrderedTraceIdGrpcMdcContextServerInterceptor; import no.entur.logging.cloud.spring.ondemand.grpc.scope.GrpcLoggingScopeContextInterceptor; import no.entur.logging.cloud.spring.rr.grpc.OrderedGrpcLoggingServerInterceptor; import no.entur.logging.cloud.spring.rr.grpc.RequestResponseGrpcExceptionHandlerInterceptor; import no.entur.logging.cloud.trace.spring.grpc.interceptor.OrderedCorrelationIdGrpcMdcContextServerInterceptor; import org.springframework.context.annotation.Profile; +import org.springframework.grpc.server.service.GrpcService; @Profile("ondemand") @GrpcService(interceptors = { @@ -22,7 +22,7 @@ // Validation MyValidationServerInterceptor.class, -}, sortInterceptors = true) +}) public class GreetingControllerWithOnDemandLogging extends AbstractGreetingController { } \ No newline at end of file diff --git a/examples/gcp-grpc-ecosystem-example/src/main/java/no/entur/grpc/example/MyGrpcConfig.java b/examples/gcp-grpc-spring-example/src/main/java/no/entur/grpc/example/MyGrpcConfig.java similarity index 100% rename from examples/gcp-grpc-ecosystem-example/src/main/java/no/entur/grpc/example/MyGrpcConfig.java rename to examples/gcp-grpc-spring-example/src/main/java/no/entur/grpc/example/MyGrpcConfig.java diff --git a/examples/gcp-grpc-ecosystem-example/src/main/java/no/entur/grpc/example/MyValidationServerInterceptor.java b/examples/gcp-grpc-spring-example/src/main/java/no/entur/grpc/example/MyValidationServerInterceptor.java similarity index 100% rename from examples/gcp-grpc-ecosystem-example/src/main/java/no/entur/grpc/example/MyValidationServerInterceptor.java rename to examples/gcp-grpc-spring-example/src/main/java/no/entur/grpc/example/MyValidationServerInterceptor.java diff --git a/examples/gcp-grpc-ecosystem-example/src/main/proto/greeting_message.proto b/examples/gcp-grpc-spring-example/src/main/proto/greeting_message.proto similarity index 100% rename from examples/gcp-grpc-ecosystem-example/src/main/proto/greeting_message.proto rename to examples/gcp-grpc-spring-example/src/main/proto/greeting_message.proto diff --git a/examples/gcp-grpc-ecosystem-example/src/main/proto/greeting_service.proto b/examples/gcp-grpc-spring-example/src/main/proto/greeting_service.proto similarity index 100% rename from examples/gcp-grpc-ecosystem-example/src/main/proto/greeting_service.proto rename to examples/gcp-grpc-spring-example/src/main/proto/greeting_service.proto diff --git a/examples/gcp-grpc-ecosystem-example/src/main/resources/application.properties b/examples/gcp-grpc-spring-example/src/main/resources/application.properties similarity index 100% rename from examples/gcp-grpc-ecosystem-example/src/main/resources/application.properties rename to examples/gcp-grpc-spring-example/src/main/resources/application.properties diff --git a/examples/gcp-grpc-ecosystem-without-test-artifacts-example/src/test/java/no/entur/grpc/example/EcosystemAbstractGrpcTest.java b/examples/gcp-grpc-spring-example/src/test/java/no/entur/grpc/example/SpringAbstractGrpcTest.java similarity index 93% rename from examples/gcp-grpc-ecosystem-without-test-artifacts-example/src/test/java/no/entur/grpc/example/EcosystemAbstractGrpcTest.java rename to examples/gcp-grpc-spring-example/src/test/java/no/entur/grpc/example/SpringAbstractGrpcTest.java index 041e2039..2a115c02 100644 --- a/examples/gcp-grpc-ecosystem-without-test-artifacts-example/src/test/java/no/entur/grpc/example/EcosystemAbstractGrpcTest.java +++ b/examples/gcp-grpc-spring-example/src/test/java/no/entur/grpc/example/SpringAbstractGrpcTest.java @@ -9,7 +9,7 @@ import java.util.concurrent.TimeUnit; -public class EcosystemAbstractGrpcTest { +public class SpringAbstractGrpcTest { // https://github.com/olivere/grpc-demo/blob/master/java-client/src/main/java/com/altf4/grpc/client/ExampleClient.java public static final int MAX_INBOUND_MESSAGE_SIZE = 1 << 20; @@ -23,11 +23,11 @@ public class EcosystemAbstractGrpcTest { protected final int maxOutboundMessageSize; protected final int maxInboundMessageSize; - public EcosystemAbstractGrpcTest() { + public SpringAbstractGrpcTest() { this(MAX_INBOUND_MESSAGE_SIZE, MAX_OUTBOUND_MESSAGE_SIZE); } - public EcosystemAbstractGrpcTest(int maxInboundMessageSize, int maxOutboundMessageSize) { + public SpringAbstractGrpcTest(int maxInboundMessageSize, int maxOutboundMessageSize) { this.maxInboundMessageSize = maxInboundMessageSize; this.maxOutboundMessageSize = maxOutboundMessageSize; } diff --git a/examples/gcp-grpc-ecosystem-example/src/test/java/no/entur/grpc/example/EcosystemGreetingTest.java b/examples/gcp-grpc-spring-example/src/test/java/no/entur/grpc/example/SpringGreetingTest.java similarity index 98% rename from examples/gcp-grpc-ecosystem-example/src/test/java/no/entur/grpc/example/EcosystemGreetingTest.java rename to examples/gcp-grpc-spring-example/src/test/java/no/entur/grpc/example/SpringGreetingTest.java index 9378bc68..f3ff284b 100644 --- a/examples/gcp-grpc-ecosystem-example/src/test/java/no/entur/grpc/example/EcosystemGreetingTest.java +++ b/examples/gcp-grpc-spring-example/src/test/java/no/entur/grpc/example/SpringGreetingTest.java @@ -7,8 +7,6 @@ import no.entur.logging.cloud.api.DevOpsLevel; import no.entur.logging.cloud.grpc.trace.CorrelationIdGrpcMdcContext; -import no.entur.logging.cloud.logback.logstash.test.CompositeConsoleOutputControl; -import no.entur.logging.cloud.logback.logstash.test.CompositeConsoleOutputControlClosable; import no.entur.logging.cloud.logback.logstash.test.junit.CaptureLogStatements; import no.entur.logging.cloud.logback.logstash.test.junit.LogStatement; import no.entur.logging.cloud.logback.logstash.test.junit.LogStatements; @@ -42,7 +40,7 @@ @SpringBootTest @DirtiesContext @CaptureLogStatements(level = DevOpsLevel.DEBUG, value = {"no.entur", "org.entur"}) -public class EcosystemGreetingTest extends EcosystemAbstractGrpcTest { +public class SpringGreetingTest extends SpringAbstractGrpcTest { @Test public void testBlockingRequestsOnSameStub() throws InterruptedException { diff --git a/examples/gcp-grpc-ecosystem-example/src/test/java/no/entur/grpc/example/EcosystemGrpcLoggingFormatTest.java b/examples/gcp-grpc-spring-example/src/test/java/no/entur/grpc/example/SpringGrpcLoggingFormatTest.java similarity index 95% rename from examples/gcp-grpc-ecosystem-example/src/test/java/no/entur/grpc/example/EcosystemGrpcLoggingFormatTest.java rename to examples/gcp-grpc-spring-example/src/test/java/no/entur/grpc/example/SpringGrpcLoggingFormatTest.java index e59d3f80..1165509d 100644 --- a/examples/gcp-grpc-ecosystem-example/src/test/java/no/entur/grpc/example/EcosystemGrpcLoggingFormatTest.java +++ b/examples/gcp-grpc-spring-example/src/test/java/no/entur/grpc/example/SpringGrpcLoggingFormatTest.java @@ -12,7 +12,7 @@ @SpringBootTest @DirtiesContext -public class EcosystemGrpcLoggingFormatTest extends EcosystemAbstractGrpcTest { +public class SpringGrpcLoggingFormatTest extends SpringAbstractGrpcTest { @Test public void useHumanReadablePlainEncoderTest() throws InterruptedException { diff --git a/examples/gcp-grpc-ecosystem-example/src/test/java/no/entur/grpc/example/EcosystemOndemandGrpcLoggingFormatTest.java b/examples/gcp-grpc-spring-example/src/test/java/no/entur/grpc/example/SpringOndemandGrpcLoggingFormatTest.java similarity index 97% rename from examples/gcp-grpc-ecosystem-example/src/test/java/no/entur/grpc/example/EcosystemOndemandGrpcLoggingFormatTest.java rename to examples/gcp-grpc-spring-example/src/test/java/no/entur/grpc/example/SpringOndemandGrpcLoggingFormatTest.java index f2fb4297..461aa03e 100644 --- a/examples/gcp-grpc-ecosystem-example/src/test/java/no/entur/grpc/example/EcosystemOndemandGrpcLoggingFormatTest.java +++ b/examples/gcp-grpc-spring-example/src/test/java/no/entur/grpc/example/SpringOndemandGrpcLoggingFormatTest.java @@ -18,7 +18,7 @@ @ActiveProfiles("ondemand") @TestPropertySource(properties = {"entur.logging.grpc.ondemand.enabled=true"}) @DirtiesContext -public class EcosystemOndemandGrpcLoggingFormatTest extends EcosystemAbstractGrpcTest { +public class SpringOndemandGrpcLoggingFormatTest extends SpringAbstractGrpcTest { @Test public void useHumanReadablePlainEncoderExpectFullLogging() { diff --git a/examples/gcp-grpc-ecosystem-example/src/test/java/no/entur/grpc/example/EcosystemOndemandGrpcLoggingHighLogLevelTest.java b/examples/gcp-grpc-spring-example/src/test/java/no/entur/grpc/example/SpringOndemandGrpcLoggingHighLogLevelTest.java similarity index 95% rename from examples/gcp-grpc-ecosystem-example/src/test/java/no/entur/grpc/example/EcosystemOndemandGrpcLoggingHighLogLevelTest.java rename to examples/gcp-grpc-spring-example/src/test/java/no/entur/grpc/example/SpringOndemandGrpcLoggingHighLogLevelTest.java index 5eee1b84..1a9059f9 100644 --- a/examples/gcp-grpc-ecosystem-example/src/test/java/no/entur/grpc/example/EcosystemOndemandGrpcLoggingHighLogLevelTest.java +++ b/examples/gcp-grpc-spring-example/src/test/java/no/entur/grpc/example/SpringOndemandGrpcLoggingHighLogLevelTest.java @@ -26,7 +26,7 @@ "entur.logging.http.ondemand.failure.logger.level=error", }) @DirtiesContext -public class EcosystemOndemandGrpcLoggingHighLogLevelTest extends EcosystemAbstractGrpcTest { +public class SpringOndemandGrpcLoggingHighLogLevelTest extends SpringAbstractGrpcTest { @Test public void useHumanReadablePlainEncoderExpectFullLogging() throws InterruptedException { diff --git a/examples/gcp-grpc-ecosystem-without-test-artifacts-example/README.md b/examples/gcp-grpc-spring-without-test-artifacts-example/README.md similarity index 73% rename from examples/gcp-grpc-ecosystem-without-test-artifacts-example/README.md rename to examples/gcp-grpc-spring-without-test-artifacts-example/README.md index cd627513..1ef325b7 100644 --- a/examples/gcp-grpc-ecosystem-without-test-artifacts-example/README.md +++ b/examples/gcp-grpc-spring-without-test-artifacts-example/README.md @@ -1,4 +1,4 @@ -# gcp-grpc-ecosystem-without-test-artifacts-example +# gcp-grpc-spring-without-test-artifacts-example Simple GRPC service example without test dependencies from this project. This emulates the deployed application (i.e. machine-readable JSON). diff --git a/examples/gcp-grpc-ecosystem-without-test-artifacts-example/build.gradle b/examples/gcp-grpc-spring-without-test-artifacts-example/build.gradle similarity index 88% rename from examples/gcp-grpc-ecosystem-without-test-artifacts-example/build.gradle rename to examples/gcp-grpc-spring-without-test-artifacts-example/build.gradle index 49f46454..7d431ea0 100644 --- a/examples/gcp-grpc-ecosystem-without-test-artifacts-example/build.gradle +++ b/examples/gcp-grpc-spring-without-test-artifacts-example/build.gradle @@ -1,20 +1,20 @@ plugins { - id 'org.springframework.boot' version '3.5.7' + id 'org.springframework.boot' version '4.0.1' id "com.google.protobuf" version "0.9.6" } test { useJUnitPlatform { - includeEngines 'junit-jupiter', 'junit-vintage' + includeEngines 'junit-jupiter' } } dependencies { implementation project(':on-demand:on-demand-spring-boot-starter-grpc') - implementation project(':gcp:spring-boot-starter-gcp-grpc-ecosystem') - implementation project(':gcp:request-response-spring-boot-starter-gcp-grpc-ecosystem') + implementation project(':gcp:spring-boot-starter-gcp-grpc-spring') + implementation project(':gcp:request-response-spring-boot-starter-gcp-grpc-spring') implementation project(':trace:server:correlation-id-trace-grpc-netty') - implementation project(':request-response:request-response-spring-boot-autoconfigure-grpc-ecosystem') + implementation project(':request-response:request-response-spring-boot-autoconfigure-grpc-spring') implementation project(':trace:mdc-context-grpc-netty') diff --git a/examples/gcp-grpc-ecosystem-without-test-artifacts-example/src/main/java/no/entur/grpc/example/AbstractGreetingController.java b/examples/gcp-grpc-spring-without-test-artifacts-example/src/main/java/no/entur/grpc/example/AbstractGreetingController.java similarity index 100% rename from examples/gcp-grpc-ecosystem-without-test-artifacts-example/src/main/java/no/entur/grpc/example/AbstractGreetingController.java rename to examples/gcp-grpc-spring-without-test-artifacts-example/src/main/java/no/entur/grpc/example/AbstractGreetingController.java diff --git a/examples/gcp-grpc-ecosystem-without-test-artifacts-example/src/main/java/no/entur/grpc/example/DemoApplication.java b/examples/gcp-grpc-spring-without-test-artifacts-example/src/main/java/no/entur/grpc/example/DemoApplication.java similarity index 100% rename from examples/gcp-grpc-ecosystem-without-test-artifacts-example/src/main/java/no/entur/grpc/example/DemoApplication.java rename to examples/gcp-grpc-spring-without-test-artifacts-example/src/main/java/no/entur/grpc/example/DemoApplication.java diff --git a/examples/gcp-grpc-ecosystem-without-test-artifacts-example/src/main/java/no/entur/grpc/example/GreetingController.java b/examples/gcp-grpc-spring-without-test-artifacts-example/src/main/java/no/entur/grpc/example/GreetingController.java similarity index 92% rename from examples/gcp-grpc-ecosystem-without-test-artifacts-example/src/main/java/no/entur/grpc/example/GreetingController.java rename to examples/gcp-grpc-spring-without-test-artifacts-example/src/main/java/no/entur/grpc/example/GreetingController.java index 044bb3d0..6dea440c 100644 --- a/examples/gcp-grpc-ecosystem-without-test-artifacts-example/src/main/java/no/entur/grpc/example/GreetingController.java +++ b/examples/gcp-grpc-spring-without-test-artifacts-example/src/main/java/no/entur/grpc/example/GreetingController.java @@ -1,12 +1,12 @@ package no.entur.grpc.example; -import net.devh.boot.grpc.server.service.GrpcService; import no.entur.logging.cloud.gcp.trace.spring.grpc.interceptor.OrderedTraceIdGrpcMdcContextServerInterceptor; import no.entur.logging.cloud.spring.rr.grpc.OrderedGrpcLoggingServerInterceptor; import no.entur.logging.cloud.spring.rr.grpc.RequestResponseGrpcExceptionHandlerInterceptor; import no.entur.logging.cloud.trace.spring.grpc.interceptor.OrderedCorrelationIdGrpcMdcContextServerInterceptor; import org.springframework.context.annotation.Profile; +import org.springframework.grpc.server.service.GrpcService; // note: order is reversed compared to lognet @GrpcService(interceptors = { @@ -21,7 +21,7 @@ // Validation MyValidationServerInterceptor.class, -}, sortInterceptors = true) +}) @Profile("!ondemand") public class GreetingController extends AbstractGreetingController { diff --git a/examples/gcp-grpc-ecosystem-example/src/main/java/no/entur/grpc/example/GreetingControllerWithOnDemandLogging.java b/examples/gcp-grpc-spring-without-test-artifacts-example/src/main/java/no/entur/grpc/example/GreetingControllerWithOnDemandLogging.java similarity index 93% rename from examples/gcp-grpc-ecosystem-example/src/main/java/no/entur/grpc/example/GreetingControllerWithOnDemandLogging.java rename to examples/gcp-grpc-spring-without-test-artifacts-example/src/main/java/no/entur/grpc/example/GreetingControllerWithOnDemandLogging.java index 7570840f..4e3404ff 100644 --- a/examples/gcp-grpc-ecosystem-example/src/main/java/no/entur/grpc/example/GreetingControllerWithOnDemandLogging.java +++ b/examples/gcp-grpc-spring-without-test-artifacts-example/src/main/java/no/entur/grpc/example/GreetingControllerWithOnDemandLogging.java @@ -1,13 +1,13 @@ package no.entur.grpc.example; -import net.devh.boot.grpc.server.service.GrpcService; import no.entur.logging.cloud.gcp.trace.spring.grpc.interceptor.OrderedTraceIdGrpcMdcContextServerInterceptor; import no.entur.logging.cloud.spring.ondemand.grpc.scope.GrpcLoggingScopeContextInterceptor; import no.entur.logging.cloud.spring.rr.grpc.OrderedGrpcLoggingServerInterceptor; import no.entur.logging.cloud.spring.rr.grpc.RequestResponseGrpcExceptionHandlerInterceptor; import no.entur.logging.cloud.trace.spring.grpc.interceptor.OrderedCorrelationIdGrpcMdcContextServerInterceptor; import org.springframework.context.annotation.Profile; +import org.springframework.grpc.server.service.GrpcService; @Profile("ondemand") @GrpcService(interceptors = { @@ -22,7 +22,7 @@ // Validation MyValidationServerInterceptor.class, -}, sortInterceptors = true) +}) public class GreetingControllerWithOnDemandLogging extends AbstractGreetingController { } \ No newline at end of file diff --git a/examples/gcp-grpc-ecosystem-without-test-artifacts-example/src/main/java/no/entur/grpc/example/MyGrpcConfig.java b/examples/gcp-grpc-spring-without-test-artifacts-example/src/main/java/no/entur/grpc/example/MyGrpcConfig.java similarity index 100% rename from examples/gcp-grpc-ecosystem-without-test-artifacts-example/src/main/java/no/entur/grpc/example/MyGrpcConfig.java rename to examples/gcp-grpc-spring-without-test-artifacts-example/src/main/java/no/entur/grpc/example/MyGrpcConfig.java diff --git a/examples/gcp-grpc-ecosystem-without-test-artifacts-example/src/main/java/no/entur/grpc/example/MyValidationServerInterceptor.java b/examples/gcp-grpc-spring-without-test-artifacts-example/src/main/java/no/entur/grpc/example/MyValidationServerInterceptor.java similarity index 100% rename from examples/gcp-grpc-ecosystem-without-test-artifacts-example/src/main/java/no/entur/grpc/example/MyValidationServerInterceptor.java rename to examples/gcp-grpc-spring-without-test-artifacts-example/src/main/java/no/entur/grpc/example/MyValidationServerInterceptor.java diff --git a/examples/gcp-grpc-ecosystem-without-test-artifacts-example/src/main/proto/greeting_message.proto b/examples/gcp-grpc-spring-without-test-artifacts-example/src/main/proto/greeting_message.proto similarity index 100% rename from examples/gcp-grpc-ecosystem-without-test-artifacts-example/src/main/proto/greeting_message.proto rename to examples/gcp-grpc-spring-without-test-artifacts-example/src/main/proto/greeting_message.proto diff --git a/examples/gcp-grpc-ecosystem-without-test-artifacts-example/src/main/proto/greeting_service.proto b/examples/gcp-grpc-spring-without-test-artifacts-example/src/main/proto/greeting_service.proto similarity index 100% rename from examples/gcp-grpc-ecosystem-without-test-artifacts-example/src/main/proto/greeting_service.proto rename to examples/gcp-grpc-spring-without-test-artifacts-example/src/main/proto/greeting_service.proto diff --git a/examples/gcp-grpc-ecosystem-without-test-artifacts-example/src/main/resources/application.properties b/examples/gcp-grpc-spring-without-test-artifacts-example/src/main/resources/application.properties similarity index 100% rename from examples/gcp-grpc-ecosystem-without-test-artifacts-example/src/main/resources/application.properties rename to examples/gcp-grpc-spring-without-test-artifacts-example/src/main/resources/application.properties diff --git a/examples/gcp-grpc-ecosystem-example/src/test/java/no/entur/grpc/example/EcosystemAbstractGrpcTest.java b/examples/gcp-grpc-spring-without-test-artifacts-example/src/test/java/no/entur/grpc/example/without/test/artifacts/SpringAbstractGrpcTest.java similarity index 92% rename from examples/gcp-grpc-ecosystem-example/src/test/java/no/entur/grpc/example/EcosystemAbstractGrpcTest.java rename to examples/gcp-grpc-spring-without-test-artifacts-example/src/test/java/no/entur/grpc/example/without/test/artifacts/SpringAbstractGrpcTest.java index 041e2039..055e9deb 100644 --- a/examples/gcp-grpc-ecosystem-example/src/test/java/no/entur/grpc/example/EcosystemAbstractGrpcTest.java +++ b/examples/gcp-grpc-spring-without-test-artifacts-example/src/test/java/no/entur/grpc/example/without/test/artifacts/SpringAbstractGrpcTest.java @@ -1,4 +1,4 @@ -package no.entur.grpc.example; +package no.entur.grpc.example.without.test.artifacts; import io.grpc.ManagedChannel; import io.grpc.ManagedChannelBuilder; @@ -9,7 +9,7 @@ import java.util.concurrent.TimeUnit; -public class EcosystemAbstractGrpcTest { +public class SpringAbstractGrpcTest { // https://github.com/olivere/grpc-demo/blob/master/java-client/src/main/java/com/altf4/grpc/client/ExampleClient.java public static final int MAX_INBOUND_MESSAGE_SIZE = 1 << 20; @@ -23,11 +23,11 @@ public class EcosystemAbstractGrpcTest { protected final int maxOutboundMessageSize; protected final int maxInboundMessageSize; - public EcosystemAbstractGrpcTest() { + public SpringAbstractGrpcTest() { this(MAX_INBOUND_MESSAGE_SIZE, MAX_OUTBOUND_MESSAGE_SIZE); } - public EcosystemAbstractGrpcTest(int maxInboundMessageSize, int maxOutboundMessageSize) { + public SpringAbstractGrpcTest(int maxInboundMessageSize, int maxOutboundMessageSize) { this.maxInboundMessageSize = maxInboundMessageSize; this.maxOutboundMessageSize = maxOutboundMessageSize; } diff --git a/examples/gcp-grpc-ecosystem-without-test-artifacts-example/src/test/java/no/entur/grpc/example/EcosystemGreetingTest.java b/examples/gcp-grpc-spring-without-test-artifacts-example/src/test/java/no/entur/grpc/example/without/test/artifacts/SpringGreetingTest.java similarity index 98% rename from examples/gcp-grpc-ecosystem-without-test-artifacts-example/src/test/java/no/entur/grpc/example/EcosystemGreetingTest.java rename to examples/gcp-grpc-spring-without-test-artifacts-example/src/test/java/no/entur/grpc/example/without/test/artifacts/SpringGreetingTest.java index 1b4209cf..0f3e8f7b 100644 --- a/examples/gcp-grpc-ecosystem-without-test-artifacts-example/src/test/java/no/entur/grpc/example/EcosystemGreetingTest.java +++ b/examples/gcp-grpc-spring-without-test-artifacts-example/src/test/java/no/entur/grpc/example/without/test/artifacts/SpringGreetingTest.java @@ -1,4 +1,4 @@ -package no.entur.grpc.example; +package no.entur.grpc.example.without.test.artifacts; import com.google.common.util.concurrent.ListenableFuture; import com.google.protobuf.Timestamp; @@ -33,7 +33,7 @@ */ @SpringBootTest @DirtiesContext -public class EcosystemGreetingTest extends EcosystemAbstractGrpcTest { +public class SpringGreetingTest extends SpringAbstractGrpcTest { @Test public void testBlockingRequestsOnSameStub() throws InterruptedException { diff --git a/examples/gcp-grpc-ecosystem-without-test-artifacts-example/src/test/java/no/entur/grpc/example/EcosystemGrpcLoggingFormatTest.java b/examples/gcp-grpc-spring-without-test-artifacts-example/src/test/java/no/entur/grpc/example/without/test/artifacts/SpringGrpcLoggingFormatTest.java similarity index 83% rename from examples/gcp-grpc-ecosystem-without-test-artifacts-example/src/test/java/no/entur/grpc/example/EcosystemGrpcLoggingFormatTest.java rename to examples/gcp-grpc-spring-without-test-artifacts-example/src/test/java/no/entur/grpc/example/without/test/artifacts/SpringGrpcLoggingFormatTest.java index 562fcef6..e9570c2d 100644 --- a/examples/gcp-grpc-ecosystem-without-test-artifacts-example/src/test/java/no/entur/grpc/example/EcosystemGrpcLoggingFormatTest.java +++ b/examples/gcp-grpc-spring-without-test-artifacts-example/src/test/java/no/entur/grpc/example/without/test/artifacts/SpringGrpcLoggingFormatTest.java @@ -1,4 +1,4 @@ -package no.entur.grpc.example; +package no.entur.grpc.example.without.test.artifacts; import org.entur.grpc.example.GreetingResponse; import org.entur.grpc.example.GreetingServiceGrpc; @@ -10,7 +10,7 @@ @SpringBootTest @DirtiesContext -public class EcosystemGrpcLoggingFormatTest extends EcosystemAbstractGrpcTest { +public class SpringGrpcLoggingFormatTest extends SpringAbstractGrpcTest { @Test public void useMachineReadableJsonEncoder() throws InterruptedException { diff --git a/examples/gcp-grpc-ecosystem-without-test-artifacts-example/src/test/java/no/entur/grpc/example/EcosystemOndemandGrpcLoggingFormatTest.java b/examples/gcp-grpc-spring-without-test-artifacts-example/src/test/java/no/entur/grpc/example/without/test/artifacts/SpringOndemandGrpcLoggingFormatTest.java similarity index 91% rename from examples/gcp-grpc-ecosystem-without-test-artifacts-example/src/test/java/no/entur/grpc/example/EcosystemOndemandGrpcLoggingFormatTest.java rename to examples/gcp-grpc-spring-without-test-artifacts-example/src/test/java/no/entur/grpc/example/without/test/artifacts/SpringOndemandGrpcLoggingFormatTest.java index c3ac0e50..8f5fa78a 100644 --- a/examples/gcp-grpc-ecosystem-without-test-artifacts-example/src/test/java/no/entur/grpc/example/EcosystemOndemandGrpcLoggingFormatTest.java +++ b/examples/gcp-grpc-spring-without-test-artifacts-example/src/test/java/no/entur/grpc/example/without/test/artifacts/SpringOndemandGrpcLoggingFormatTest.java @@ -1,4 +1,4 @@ -package no.entur.grpc.example; +package no.entur.grpc.example.without.test.artifacts; import io.grpc.StatusRuntimeException; import org.entur.grpc.example.GreetingResponse; @@ -16,7 +16,7 @@ @ActiveProfiles("ondemand") @TestPropertySource(properties = {"entur.logging.grpc.ondemand.enabled=true"}) @DirtiesContext -public class EcosystemOndemandGrpcLoggingFormatTest extends EcosystemAbstractGrpcTest { +public class SpringOndemandGrpcLoggingFormatTest extends SpringAbstractGrpcTest { @Test public void useMachineReadableJsonEncoderExpectFullLogging() throws InterruptedException { diff --git a/examples/gcp-grpc-ecosystem-without-test-artifacts-example/src/test/java/no/entur/grpc/example/EcosystemOndemandGrpcLoggingHighLogLevelTest.java b/examples/gcp-grpc-spring-without-test-artifacts-example/src/test/java/no/entur/grpc/example/without/test/artifacts/SpringOndemandGrpcLoggingHighLogLevelTest.java similarity index 87% rename from examples/gcp-grpc-ecosystem-without-test-artifacts-example/src/test/java/no/entur/grpc/example/EcosystemOndemandGrpcLoggingHighLogLevelTest.java rename to examples/gcp-grpc-spring-without-test-artifacts-example/src/test/java/no/entur/grpc/example/without/test/artifacts/SpringOndemandGrpcLoggingHighLogLevelTest.java index b87dfdcc..c9ed6f30 100644 --- a/examples/gcp-grpc-ecosystem-without-test-artifacts-example/src/test/java/no/entur/grpc/example/EcosystemOndemandGrpcLoggingHighLogLevelTest.java +++ b/examples/gcp-grpc-spring-without-test-artifacts-example/src/test/java/no/entur/grpc/example/without/test/artifacts/SpringOndemandGrpcLoggingHighLogLevelTest.java @@ -1,6 +1,5 @@ -package no.entur.grpc.example; +package no.entur.grpc.example.without.test.artifacts; -import io.grpc.StatusRuntimeException; import org.entur.grpc.example.GreetingResponse; import org.entur.grpc.example.GreetingServiceGrpc; import org.junit.jupiter.api.Test; @@ -25,7 +24,7 @@ "entur.logging.http.ondemand.failure.logger.level=error", }) @DirtiesContext -public class EcosystemOndemandGrpcLoggingHighLogLevelTest extends EcosystemAbstractGrpcTest { +public class SpringOndemandGrpcLoggingHighLogLevelTest extends SpringAbstractGrpcTest { @Test public void useMachineReadableJsonEncoderExpectFullLogging() throws InterruptedException { diff --git a/examples/gcp-web-apache-client-example/build.gradle b/examples/gcp-web-apache-client-example/build.gradle index 663c3a10..4c490a2d 100644 --- a/examples/gcp-web-apache-client-example/build.gradle +++ b/examples/gcp-web-apache-client-example/build.gradle @@ -1,10 +1,10 @@ plugins { - id 'org.springframework.boot' version '3.5.7' + id 'org.springframework.boot' version '4.0.1' } test { useJUnitPlatform { - includeEngines 'junit-jupiter', 'junit-vintage' + includeEngines 'junit-jupiter' } } @@ -23,6 +23,8 @@ dependencies { testImplementation project(":gcp:request-response-spring-boot-starter-gcp-web-test"); testImplementation("org.springframework.boot:spring-boot-starter-test") + testImplementation("org.springframework.boot:spring-boot-restclient") + testImplementation("org.springframework.boot:spring-boot-resttestclient") // JUnit Jupiter API and TestEngine implementation testImplementation("org.junit.jupiter:junit-jupiter-api") diff --git a/examples/gcp-web-apache-client-example/src/main/java/org/entur/example/web/rest/DocumentEndpoint.java b/examples/gcp-web-apache-client-example/src/main/java/org/entur/example/web/rest/DocumentEndpoint.java index b063d3bd..00c4609c 100644 --- a/examples/gcp-web-apache-client-example/src/main/java/org/entur/example/web/rest/DocumentEndpoint.java +++ b/examples/gcp-web-apache-client-example/src/main/java/org/entur/example/web/rest/DocumentEndpoint.java @@ -1,9 +1,5 @@ package org.entur.example.web.rest; -import com.fasterxml.jackson.core.JsonFactory; -import com.fasterxml.jackson.core.JsonGenerator; -import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.databind.ObjectMapper; import jakarta.servlet.http.HttpServletRequest; import org.apache.hc.client5.http.classic.methods.HttpPost; import org.apache.hc.client5.http.impl.classic.CloseableHttpClient; @@ -14,21 +10,11 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Value; -import org.springframework.core.env.Environment; -import org.springframework.http.HttpStatus; -import org.springframework.http.ResponseEntity; -import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; - -import java.io.ByteArrayOutputStream; -import java.io.CharArrayWriter; -import java.io.IOException; -import java.util.concurrent.CompletableFuture; +import tools.jackson.databind.json.JsonMapper; @RestController @RequestMapping("/api/document") @@ -39,7 +25,7 @@ public class DocumentEndpoint { @Autowired private CloseableHttpClient httpclient; - private ObjectMapper mapper = new ObjectMapper(); + private JsonMapper mapper = JsonMapper.builder().build(); @PostMapping("/some/method") public MyEntity someMessage(@RequestBody MyEntity entity, HttpServletRequest request) throws Exception { diff --git a/examples/gcp-web-apache-client-example/src/main/java/org/entur/example/web/rest/DummyEndpoint.java b/examples/gcp-web-apache-client-example/src/main/java/org/entur/example/web/rest/DummyEndpoint.java index 96588af3..790a193d 100644 --- a/examples/gcp-web-apache-client-example/src/main/java/org/entur/example/web/rest/DummyEndpoint.java +++ b/examples/gcp-web-apache-client-example/src/main/java/org/entur/example/web/rest/DummyEndpoint.java @@ -1,18 +1,9 @@ package org.entur.example.web.rest; -import com.fasterxml.jackson.core.JsonFactory; -import com.fasterxml.jackson.core.JsonGenerator; -import org.apache.hc.client5.http.impl.classic.CloseableHttpClient; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.http.HttpStatus; -import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.*; -import java.io.CharArrayWriter; -import java.io.IOException; - /** * * Simulation of downstream service diff --git a/examples/gcp-web-apache-client-example/src/test/java/org/entur/example/web/WebLoggingFormatTest.java b/examples/gcp-web-apache-client-example/src/test/java/org/entur/example/web/WebLoggingFormatTest.java index 5aeef7f4..6b828ab9 100644 --- a/examples/gcp-web-apache-client-example/src/test/java/org/entur/example/web/WebLoggingFormatTest.java +++ b/examples/gcp-web-apache-client-example/src/test/java/org/entur/example/web/WebLoggingFormatTest.java @@ -7,14 +7,16 @@ import org.entur.example.web.rest.MyEntity; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.resttestclient.autoconfigure.AutoConfigureTestRestTemplate; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; -import org.springframework.boot.test.web.client.TestRestTemplate; +import org.springframework.boot.resttestclient.TestRestTemplate; import org.springframework.boot.test.web.server.LocalServerPort; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; @SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT) +@AutoConfigureTestRestTemplate public class WebLoggingFormatTest { @LocalServerPort diff --git a/examples/gcp-web-example/build.gradle b/examples/gcp-web-example/build.gradle index 6b27a7f7..7601e610 100644 --- a/examples/gcp-web-example/build.gradle +++ b/examples/gcp-web-example/build.gradle @@ -1,10 +1,10 @@ plugins { - id 'org.springframework.boot' version '3.5.7' + id 'org.springframework.boot' version '4.0.1' } test { useJUnitPlatform { - includeEngines 'junit-jupiter', 'junit-vintage' + includeEngines 'junit-jupiter' } } @@ -21,6 +21,8 @@ dependencies { testImplementation project(":gcp:request-response-spring-boot-starter-gcp-web-test"); testImplementation("org.springframework.boot:spring-boot-starter-test") + testImplementation("org.springframework.boot:spring-boot-restclient") + testImplementation("org.springframework.boot:spring-boot-resttestclient") // JUnit Jupiter API and TestEngine implementation testImplementation("org.junit.jupiter:junit-jupiter-api") diff --git a/examples/gcp-web-example/src/main/java/org/entur/example/web/config/WebSecurityConfig.java b/examples/gcp-web-example/src/main/java/org/entur/example/web/config/WebSecurityConfig.java index c315dd7e..a5423a02 100644 --- a/examples/gcp-web-example/src/main/java/org/entur/example/web/config/WebSecurityConfig.java +++ b/examples/gcp-web-example/src/main/java/org/entur/example/web/config/WebSecurityConfig.java @@ -16,7 +16,6 @@ public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { .csrf( c -> c.disable() ) .authorizeHttpRequests((authorize) -> { authorize.requestMatchers("/api/secured/endpoint").fullyAuthenticated(); - authorize.anyRequest().permitAll(); } ); diff --git a/examples/gcp-web-example/src/main/java/org/entur/example/web/rest/DocumentEndpoint.java b/examples/gcp-web-example/src/main/java/org/entur/example/web/rest/DocumentEndpoint.java index e98f74e5..9389adbf 100644 --- a/examples/gcp-web-example/src/main/java/org/entur/example/web/rest/DocumentEndpoint.java +++ b/examples/gcp-web-example/src/main/java/org/entur/example/web/rest/DocumentEndpoint.java @@ -1,7 +1,6 @@ package org.entur.example.web.rest; -import com.fasterxml.jackson.core.JsonFactory; -import com.fasterxml.jackson.core.JsonGenerator; +import tools.jackson.core.JsonGenerator; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.http.HttpStatus; @@ -13,6 +12,7 @@ import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; +import tools.jackson.core.json.JsonFactory; import java.io.ByteArrayOutputStream; import java.io.CharArrayWriter; @@ -86,9 +86,9 @@ ResponseEntity bigResponse() throws IOException { JsonGenerator generator = factory.createGenerator(writer); generator.writeStartObject(); - generator.writeStringField("start", "here"); - generator.writeStringField("longValue", generateLongString(64*1024)); - generator.writeStringField("end", "here"); + generator.writeStringProperty("start", "here"); + generator.writeStringProperty("longValue", generateLongString(64*1024)); + generator.writeStringProperty("end", "here"); generator.writeEndObject(); generator.flush(); diff --git a/examples/gcp-web-example/src/test/java/org/entur/example/web/ActuatorTest.java b/examples/gcp-web-example/src/test/java/org/entur/example/web/ActuatorTest.java index a9b7baef..3d325402 100644 --- a/examples/gcp-web-example/src/test/java/org/entur/example/web/ActuatorTest.java +++ b/examples/gcp-web-example/src/test/java/org/entur/example/web/ActuatorTest.java @@ -6,9 +6,10 @@ import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; +import org.springframework.boot.resttestclient.autoconfigure.AutoConfigureTestRestTemplate; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; -import org.springframework.boot.test.web.client.TestRestTemplate; +import org.springframework.boot.resttestclient.TestRestTemplate; import org.springframework.boot.test.web.server.LocalServerPort; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; @@ -16,6 +17,7 @@ import static org.assertj.core.api.Assertions.assertThat; @SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT) +@AutoConfigureTestRestTemplate public class ActuatorTest { @LocalServerPort diff --git a/examples/gcp-web-example/src/test/java/org/entur/example/web/ActuatorWithoutExcludesTest.java b/examples/gcp-web-example/src/test/java/org/entur/example/web/ActuatorWithoutExcludesTest.java index eadfb3d7..1cbe9888 100644 --- a/examples/gcp-web-example/src/test/java/org/entur/example/web/ActuatorWithoutExcludesTest.java +++ b/examples/gcp-web-example/src/test/java/org/entur/example/web/ActuatorWithoutExcludesTest.java @@ -4,9 +4,10 @@ import no.entur.logging.cloud.logback.logstash.test.CompositeConsoleOutputControlClosable; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.resttestclient.autoconfigure.AutoConfigureTestRestTemplate; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; -import org.springframework.boot.test.web.client.TestRestTemplate; +import org.springframework.boot.resttestclient.TestRestTemplate; import org.springframework.boot.test.web.server.LocalServerPort; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; @@ -18,6 +19,7 @@ @TestPropertySource(properties = { "entur.logging.request-response.logbook.default-excludes=false" }) +@AutoConfigureTestRestTemplate public class ActuatorWithoutExcludesTest { @LocalServerPort diff --git a/examples/gcp-web-example/src/test/java/org/entur/example/web/OndemandWebLoggingHttpBadRequestTest.java b/examples/gcp-web-example/src/test/java/org/entur/example/web/OndemandWebLoggingHttpBadRequestTest.java index 89499596..4d7854d2 100644 --- a/examples/gcp-web-example/src/test/java/org/entur/example/web/OndemandWebLoggingHttpBadRequestTest.java +++ b/examples/gcp-web-example/src/test/java/org/entur/example/web/OndemandWebLoggingHttpBadRequestTest.java @@ -5,9 +5,10 @@ import org.entur.example.web.rest.MyEntity; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.resttestclient.autoconfigure.AutoConfigureTestRestTemplate; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; -import org.springframework.boot.test.web.client.TestRestTemplate; +import org.springframework.boot.resttestclient.TestRestTemplate; import org.springframework.boot.test.web.server.LocalServerPort; import org.springframework.http.HttpEntity; import org.springframework.http.HttpHeaders; @@ -30,6 +31,7 @@ "entur.logging.http.ondemand.enabled=true", "entur.logging.http.ondemand.failure.logger.enabled=false", }) +@AutoConfigureTestRestTemplate public class OndemandWebLoggingHttpBadRequestTest { @LocalServerPort diff --git a/examples/gcp-web-example/src/test/java/org/entur/example/web/OndemandWebLoggingHttpNotFound1AsyncTest.java b/examples/gcp-web-example/src/test/java/org/entur/example/web/OndemandWebLoggingHttpNotFound1AsyncTest.java index a2b6d220..4ed55268 100644 --- a/examples/gcp-web-example/src/test/java/org/entur/example/web/OndemandWebLoggingHttpNotFound1AsyncTest.java +++ b/examples/gcp-web-example/src/test/java/org/entur/example/web/OndemandWebLoggingHttpNotFound1AsyncTest.java @@ -7,9 +7,10 @@ import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.resttestclient.autoconfigure.AutoConfigureTestRestTemplate; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; -import org.springframework.boot.test.web.client.TestRestTemplate; +import org.springframework.boot.resttestclient.TestRestTemplate; import org.springframework.boot.test.web.server.LocalServerPort; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; @@ -27,6 +28,7 @@ @SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT) @ActiveProfiles("async") @TestPropertySource(properties = {"entur.logging.http.ondemand.enabled=true", "entur.logging.http.ondemand.failure.http.statusCode.equalOrHigherThan=400", "entur.logging.http.ondemand.failure.logger.level=error", "entur.logging.http.ondemand.failure.level=info"}) +@AutoConfigureTestRestTemplate public class OndemandWebLoggingHttpNotFound1AsyncTest { @LocalServerPort diff --git a/examples/gcp-web-example/src/test/java/org/entur/example/web/OndemandWebLoggingHttpNotFound1Test.java b/examples/gcp-web-example/src/test/java/org/entur/example/web/OndemandWebLoggingHttpNotFound1Test.java index b1e7934f..105be14f 100644 --- a/examples/gcp-web-example/src/test/java/org/entur/example/web/OndemandWebLoggingHttpNotFound1Test.java +++ b/examples/gcp-web-example/src/test/java/org/entur/example/web/OndemandWebLoggingHttpNotFound1Test.java @@ -5,9 +5,10 @@ import org.entur.example.web.rest.MyEntity; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.resttestclient.autoconfigure.AutoConfigureTestRestTemplate; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; -import org.springframework.boot.test.web.client.TestRestTemplate; +import org.springframework.boot.resttestclient.TestRestTemplate; import org.springframework.boot.test.web.server.LocalServerPort; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; @@ -26,6 +27,7 @@ "entur.logging.http.ondemand.enabled=true", "entur.logging.http.ondemand.failure.logger.enabled=false", }) +@AutoConfigureTestRestTemplate public class OndemandWebLoggingHttpNotFound1Test { @LocalServerPort diff --git a/examples/gcp-web-example/src/test/java/org/entur/example/web/OndemandWebLoggingHttpNotFound2Test.java b/examples/gcp-web-example/src/test/java/org/entur/example/web/OndemandWebLoggingHttpNotFound2Test.java index 563f0f84..aa04e47f 100644 --- a/examples/gcp-web-example/src/test/java/org/entur/example/web/OndemandWebLoggingHttpNotFound2Test.java +++ b/examples/gcp-web-example/src/test/java/org/entur/example/web/OndemandWebLoggingHttpNotFound2Test.java @@ -5,9 +5,10 @@ import org.entur.example.web.rest.MyEntity; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.resttestclient.autoconfigure.AutoConfigureTestRestTemplate; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; -import org.springframework.boot.test.web.client.TestRestTemplate; +import org.springframework.boot.resttestclient.TestRestTemplate; import org.springframework.boot.test.web.server.LocalServerPort; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; @@ -27,6 +28,7 @@ "entur.logging.http.ondemand.enabled=true", "entur.logging.http.ondemand.failure.logger.enabled=false" }) +@AutoConfigureTestRestTemplate public class OndemandWebLoggingHttpNotFound2Test { @LocalServerPort diff --git a/examples/gcp-web-example/src/test/java/org/entur/example/web/OndemandWebLoggingHttpOkHighLogLevelLazyTest.java b/examples/gcp-web-example/src/test/java/org/entur/example/web/OndemandWebLoggingHttpOkHighLogLevelLazyTest.java index 047a2d1a..31271645 100644 --- a/examples/gcp-web-example/src/test/java/org/entur/example/web/OndemandWebLoggingHttpOkHighLogLevelLazyTest.java +++ b/examples/gcp-web-example/src/test/java/org/entur/example/web/OndemandWebLoggingHttpOkHighLogLevelLazyTest.java @@ -5,9 +5,10 @@ import org.entur.example.web.rest.MyEntity; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.resttestclient.autoconfigure.AutoConfigureTestRestTemplate; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; -import org.springframework.boot.test.web.client.TestRestTemplate; +import org.springframework.boot.resttestclient.TestRestTemplate; import org.springframework.boot.test.web.server.LocalServerPort; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; @@ -28,6 +29,7 @@ "entur.logging.http.ondemand.failure.logger.level=error", "entur.logging.http.ondemand.flushMode=lazy", }) +@AutoConfigureTestRestTemplate public class OndemandWebLoggingHttpOkHighLogLevelLazyTest { @LocalServerPort diff --git a/examples/gcp-web-example/src/test/java/org/entur/example/web/OndemandWebLoggingHttpOkHighLogLevelTest.java b/examples/gcp-web-example/src/test/java/org/entur/example/web/OndemandWebLoggingHttpOkHighLogLevelTest.java index a5480078..f6a1d260 100644 --- a/examples/gcp-web-example/src/test/java/org/entur/example/web/OndemandWebLoggingHttpOkHighLogLevelTest.java +++ b/examples/gcp-web-example/src/test/java/org/entur/example/web/OndemandWebLoggingHttpOkHighLogLevelTest.java @@ -5,9 +5,10 @@ import org.entur.example.web.rest.MyEntity; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.resttestclient.autoconfigure.AutoConfigureTestRestTemplate; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; -import org.springframework.boot.test.web.client.TestRestTemplate; +import org.springframework.boot.resttestclient.TestRestTemplate; import org.springframework.boot.test.web.server.LocalServerPort; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; @@ -27,6 +28,7 @@ "entur.logging.http.ondemand.failure.http.enabled=false", "entur.logging.http.ondemand.failure.logger.level=error", }) +@AutoConfigureTestRestTemplate public class OndemandWebLoggingHttpOkHighLogLevelTest { @LocalServerPort diff --git a/examples/gcp-web-example/src/test/java/org/entur/example/web/OndemandWebLoggingHttpOkTest.java b/examples/gcp-web-example/src/test/java/org/entur/example/web/OndemandWebLoggingHttpOkTest.java index a5158063..d9b8a97f 100644 --- a/examples/gcp-web-example/src/test/java/org/entur/example/web/OndemandWebLoggingHttpOkTest.java +++ b/examples/gcp-web-example/src/test/java/org/entur/example/web/OndemandWebLoggingHttpOkTest.java @@ -5,9 +5,10 @@ import org.entur.example.web.rest.MyEntity; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.resttestclient.autoconfigure.AutoConfigureTestRestTemplate; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; -import org.springframework.boot.test.web.client.TestRestTemplate; +import org.springframework.boot.resttestclient.TestRestTemplate; import org.springframework.boot.test.web.server.LocalServerPort; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; @@ -20,6 +21,7 @@ // Triggers by error log level or >= 400 status code by default @TestPropertySource(properties = {"entur.logging.http.ondemand.enabled=true"}) +@AutoConfigureTestRestTemplate public class OndemandWebLoggingHttpOkTest { @LocalServerPort diff --git a/examples/gcp-web-example/src/test/java/org/entur/example/web/OndemandWebLoggingHttpOkTroubleshootingTest.java b/examples/gcp-web-example/src/test/java/org/entur/example/web/OndemandWebLoggingHttpOkTroubleshootingTest.java index a3e6d842..2a73a0f9 100644 --- a/examples/gcp-web-example/src/test/java/org/entur/example/web/OndemandWebLoggingHttpOkTroubleshootingTest.java +++ b/examples/gcp-web-example/src/test/java/org/entur/example/web/OndemandWebLoggingHttpOkTroubleshootingTest.java @@ -5,9 +5,10 @@ import org.entur.example.web.rest.MyEntity; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.resttestclient.autoconfigure.AutoConfigureTestRestTemplate; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; -import org.springframework.boot.test.web.client.TestRestTemplate; +import org.springframework.boot.resttestclient.TestRestTemplate; import org.springframework.boot.test.web.server.LocalServerPort; import org.springframework.http.*; import org.springframework.test.context.TestPropertySource; @@ -22,6 +23,7 @@ "entur.logging.http.ondemand.failure.logger.enabled=false", "entur.logging.http.ondemand.troubleshoot.http.headers[0].name=X-DEBUG" }) +@AutoConfigureTestRestTemplate public class OndemandWebLoggingHttpOkTroubleshootingTest { @LocalServerPort diff --git a/examples/gcp-web-example/src/test/java/org/entur/example/web/OndemandWebLoggingSlowResponseTest.java b/examples/gcp-web-example/src/test/java/org/entur/example/web/OndemandWebLoggingSlowResponseTest.java index a99e7998..b68e05ee 100644 --- a/examples/gcp-web-example/src/test/java/org/entur/example/web/OndemandWebLoggingSlowResponseTest.java +++ b/examples/gcp-web-example/src/test/java/org/entur/example/web/OndemandWebLoggingSlowResponseTest.java @@ -5,9 +5,10 @@ import org.entur.example.web.rest.MyEntity; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.resttestclient.autoconfigure.AutoConfigureTestRestTemplate; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; -import org.springframework.boot.test.web.client.TestRestTemplate; +import org.springframework.boot.resttestclient.TestRestTemplate; import org.springframework.boot.test.web.server.LocalServerPort; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; @@ -29,6 +30,7 @@ "entur.logging.http.ondemand.failure.duration.enabled=true", "entur.logging.http.ondemand.failure.duration.after=500ms", }) +@AutoConfigureTestRestTemplate public class OndemandWebLoggingSlowResponseTest { @LocalServerPort diff --git a/examples/gcp-web-example/src/test/java/org/entur/example/web/WebLoggingFormatHttp401Test.java b/examples/gcp-web-example/src/test/java/org/entur/example/web/WebLoggingFormatHttp401Test.java index c518b234..19639e8c 100644 --- a/examples/gcp-web-example/src/test/java/org/entur/example/web/WebLoggingFormatHttp401Test.java +++ b/examples/gcp-web-example/src/test/java/org/entur/example/web/WebLoggingFormatHttp401Test.java @@ -5,9 +5,10 @@ import org.entur.example.web.rest.MyEntity; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.resttestclient.autoconfigure.AutoConfigureTestRestTemplate; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; -import org.springframework.boot.test.web.client.TestRestTemplate; +import org.springframework.boot.resttestclient.TestRestTemplate; import org.springframework.boot.test.web.server.LocalServerPort; import org.springframework.http.HttpEntity; import org.springframework.http.HttpHeaders; @@ -28,8 +29,7 @@ "logbook.secure-filter.enabled=false" }) - - +@AutoConfigureTestRestTemplate public class WebLoggingFormatHttp401Test { @LocalServerPort diff --git a/examples/gcp-web-example/src/test/java/org/entur/example/web/WebLoggingFormatHttp403Test.java b/examples/gcp-web-example/src/test/java/org/entur/example/web/WebLoggingFormatHttp403Test.java index 39a0471a..b652cd06 100644 --- a/examples/gcp-web-example/src/test/java/org/entur/example/web/WebLoggingFormatHttp403Test.java +++ b/examples/gcp-web-example/src/test/java/org/entur/example/web/WebLoggingFormatHttp403Test.java @@ -5,9 +5,10 @@ import org.entur.example.web.rest.MyEntity; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.resttestclient.autoconfigure.AutoConfigureTestRestTemplate; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; -import org.springframework.boot.test.web.client.TestRestTemplate; +import org.springframework.boot.resttestclient.TestRestTemplate; import org.springframework.boot.test.web.server.LocalServerPort; import org.springframework.http.HttpEntity; import org.springframework.http.HttpHeaders; @@ -21,6 +22,7 @@ @TestPropertySource(properties = { "logbook.secure-filter.enabled=false" }) +@AutoConfigureTestRestTemplate public class WebLoggingFormatHttp403Test { @LocalServerPort diff --git a/examples/gcp-web-example/src/test/java/org/entur/example/web/WebLoggingFormatHttp403ViaAuthorizationDeniedExceptionTest.java b/examples/gcp-web-example/src/test/java/org/entur/example/web/WebLoggingFormatHttp403ViaAuthorizationDeniedExceptionTest.java index 2024103b..95c9321b 100644 --- a/examples/gcp-web-example/src/test/java/org/entur/example/web/WebLoggingFormatHttp403ViaAuthorizationDeniedExceptionTest.java +++ b/examples/gcp-web-example/src/test/java/org/entur/example/web/WebLoggingFormatHttp403ViaAuthorizationDeniedExceptionTest.java @@ -5,9 +5,10 @@ import org.entur.example.web.rest.MyEntity; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.resttestclient.autoconfigure.AutoConfigureTestRestTemplate; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; -import org.springframework.boot.test.web.client.TestRestTemplate; +import org.springframework.boot.resttestclient.TestRestTemplate; import org.springframework.boot.test.web.server.LocalServerPort; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; @@ -20,6 +21,7 @@ "logbook.secure-filter.enabled=false", // 401 and 403 is logged twice via Sink.writeBoth(..) "entur.logging.request-response.http.server.controller-advice.enabled=true" }) +@AutoConfigureTestRestTemplate public class WebLoggingFormatHttp403ViaAuthorizationDeniedExceptionTest { @LocalServerPort diff --git a/examples/gcp-web-example/src/test/java/org/entur/example/web/WebLoggingFormatHttp500ViaNullpointerExceptionTest.java b/examples/gcp-web-example/src/test/java/org/entur/example/web/WebLoggingFormatHttp500ViaNullpointerExceptionTest.java index 663eb58f..604e2afd 100644 --- a/examples/gcp-web-example/src/test/java/org/entur/example/web/WebLoggingFormatHttp500ViaNullpointerExceptionTest.java +++ b/examples/gcp-web-example/src/test/java/org/entur/example/web/WebLoggingFormatHttp500ViaNullpointerExceptionTest.java @@ -5,9 +5,10 @@ import org.entur.example.web.rest.MyEntity; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.resttestclient.autoconfigure.AutoConfigureTestRestTemplate; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; -import org.springframework.boot.test.web.client.TestRestTemplate; +import org.springframework.boot.resttestclient.TestRestTemplate; import org.springframework.boot.test.web.server.LocalServerPort; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; @@ -19,6 +20,7 @@ @TestPropertySource(properties = { "entur.logging.request-response.http.server.controller-advice.enabled=true" }) +@AutoConfigureTestRestTemplate public class WebLoggingFormatHttp500ViaNullpointerExceptionTest { @LocalServerPort diff --git a/examples/gcp-web-example/src/test/java/org/entur/example/web/WebLoggingFormatTest.java b/examples/gcp-web-example/src/test/java/org/entur/example/web/WebLoggingFormatTest.java index 5aeef7f4..6b828ab9 100644 --- a/examples/gcp-web-example/src/test/java/org/entur/example/web/WebLoggingFormatTest.java +++ b/examples/gcp-web-example/src/test/java/org/entur/example/web/WebLoggingFormatTest.java @@ -7,14 +7,16 @@ import org.entur.example.web.rest.MyEntity; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.resttestclient.autoconfigure.AutoConfigureTestRestTemplate; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; -import org.springframework.boot.test.web.client.TestRestTemplate; +import org.springframework.boot.resttestclient.TestRestTemplate; import org.springframework.boot.test.web.server.LocalServerPort; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; @SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT) +@AutoConfigureTestRestTemplate public class WebLoggingFormatTest { @LocalServerPort diff --git a/examples/gcp-web-example/src/test/java/org/entur/example/web/WebLoggingFormatViaProfileTest.java b/examples/gcp-web-example/src/test/java/org/entur/example/web/WebLoggingFormatViaProfileTest.java index 039197e6..554778f4 100644 --- a/examples/gcp-web-example/src/test/java/org/entur/example/web/WebLoggingFormatViaProfileTest.java +++ b/examples/gcp-web-example/src/test/java/org/entur/example/web/WebLoggingFormatViaProfileTest.java @@ -6,9 +6,10 @@ import org.junit.jupiter.api.Test; import org.springframework.beans.factory.InitializingBean; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.resttestclient.autoconfigure.AutoConfigureTestRestTemplate; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; -import org.springframework.boot.test.web.client.TestRestTemplate; +import org.springframework.boot.resttestclient.TestRestTemplate; import org.springframework.boot.test.web.server.LocalServerPort; import org.springframework.context.ApplicationListener; import org.springframework.context.annotation.Bean; @@ -24,6 +25,7 @@ @SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT) @ActiveProfiles("local") +@AutoConfigureTestRestTemplate public class WebLoggingFormatViaProfileTest { @LocalServerPort diff --git a/examples/gcp-web-example/src/test/java/org/entur/example/web/WebLoggingFormatViaPropertyTest.java b/examples/gcp-web-example/src/test/java/org/entur/example/web/WebLoggingFormatViaPropertyTest.java index 26edb1d3..b36f4754 100644 --- a/examples/gcp-web-example/src/test/java/org/entur/example/web/WebLoggingFormatViaPropertyTest.java +++ b/examples/gcp-web-example/src/test/java/org/entur/example/web/WebLoggingFormatViaPropertyTest.java @@ -3,9 +3,10 @@ import org.entur.example.web.rest.MyEntity; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.resttestclient.autoconfigure.AutoConfigureTestRestTemplate; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; -import org.springframework.boot.test.web.client.TestRestTemplate; +import org.springframework.boot.resttestclient.TestRestTemplate; import org.springframework.boot.test.web.server.LocalServerPort; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; @@ -18,6 +19,7 @@ @TestPropertySource(properties = { "entur.logging.style=HumanReadableJson", }) +@AutoConfigureTestRestTemplate public class WebLoggingFormatViaPropertyTest { @LocalServerPort diff --git a/examples/gcp-web-example/src/test/java/org/entur/example/web/WebLoggingFormatWithBigResponsesTest.java b/examples/gcp-web-example/src/test/java/org/entur/example/web/WebLoggingFormatWithBigResponsesTest.java index b8779881..5ca80c03 100644 --- a/examples/gcp-web-example/src/test/java/org/entur/example/web/WebLoggingFormatWithBigResponsesTest.java +++ b/examples/gcp-web-example/src/test/java/org/entur/example/web/WebLoggingFormatWithBigResponsesTest.java @@ -5,9 +5,10 @@ import org.entur.example.web.rest.MyEntity; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.resttestclient.autoconfigure.AutoConfigureTestRestTemplate; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; -import org.springframework.boot.test.web.client.TestRestTemplate; +import org.springframework.boot.resttestclient.TestRestTemplate; import org.springframework.boot.test.web.server.LocalServerPort; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; @@ -15,6 +16,7 @@ import static org.assertj.core.api.Assertions.assertThat; @SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT) +@AutoConfigureTestRestTemplate public class WebLoggingFormatWithBigResponsesTest { @LocalServerPort diff --git a/examples/gcp-web-example/src/test/java/org/entur/example/web/WebLoggingFormatWithNewlinesTest.java b/examples/gcp-web-example/src/test/java/org/entur/example/web/WebLoggingFormatWithNewlinesTest.java index 0e9d7d4f..26503314 100644 --- a/examples/gcp-web-example/src/test/java/org/entur/example/web/WebLoggingFormatWithNewlinesTest.java +++ b/examples/gcp-web-example/src/test/java/org/entur/example/web/WebLoggingFormatWithNewlinesTest.java @@ -5,9 +5,10 @@ import org.entur.example.web.rest.MyEntity; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.resttestclient.autoconfigure.AutoConfigureTestRestTemplate; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; -import org.springframework.boot.test.web.client.TestRestTemplate; +import org.springframework.boot.resttestclient.TestRestTemplate; import org.springframework.boot.test.web.server.LocalServerPort; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; @@ -15,6 +16,7 @@ import static org.assertj.core.api.Assertions.assertThat; @SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT) +@AutoConfigureTestRestTemplate public class WebLoggingFormatWithNewlinesTest { @LocalServerPort diff --git a/examples/gcp-web-example/src/test/java/org/entur/example/web/WebLoggingMessageFormatTest.java b/examples/gcp-web-example/src/test/java/org/entur/example/web/WebLoggingMessageFormatTest.java index 729eb1b2..a245a240 100644 --- a/examples/gcp-web-example/src/test/java/org/entur/example/web/WebLoggingMessageFormatTest.java +++ b/examples/gcp-web-example/src/test/java/org/entur/example/web/WebLoggingMessageFormatTest.java @@ -7,9 +7,10 @@ import org.entur.example.web.rest.MyEntity; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.resttestclient.autoconfigure.AutoConfigureTestRestTemplate; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; -import org.springframework.boot.test.web.client.TestRestTemplate; +import org.springframework.boot.resttestclient.TestRestTemplate; import org.springframework.boot.test.web.server.LocalServerPort; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; @@ -21,6 +22,7 @@ "entur.logging.request-response.format.server.message.host=false", "entur.logging.request-response.format.server.message.port=false" }) +@AutoConfigureTestRestTemplate public class WebLoggingMessageFormatTest { @LocalServerPort diff --git a/examples/gcp-web-without-test-artifacts-example/build.gradle b/examples/gcp-web-without-test-artifacts-example/build.gradle index 8def6231..f7008437 100644 --- a/examples/gcp-web-without-test-artifacts-example/build.gradle +++ b/examples/gcp-web-without-test-artifacts-example/build.gradle @@ -1,10 +1,10 @@ plugins { - id 'org.springframework.boot' version '3.5.7' + id 'org.springframework.boot' version '4.0.1' } test { useJUnitPlatform { - includeEngines 'junit-jupiter', 'junit-vintage' + includeEngines 'junit-jupiter' } } @@ -17,6 +17,8 @@ dependencies { implementation("org.springframework.boot:spring-boot-starter-web") testImplementation("org.springframework.boot:spring-boot-starter-test") + testImplementation("org.springframework.boot:spring-boot-restclient") + testImplementation("org.springframework.boot:spring-boot-resttestclient") // JUnit Jupiter API and TestEngine implementation testImplementation("org.junit.jupiter:junit-jupiter-api") diff --git a/examples/gcp-web-without-test-artifacts-example/src/main/java/org/entur/example/web/config/WebSecurityConfig.java b/examples/gcp-web-without-test-artifacts-example/src/main/java/org/entur/example/web/config/WebSecurityConfig.java index 04a96010..bed6c3b4 100644 --- a/examples/gcp-web-without-test-artifacts-example/src/main/java/org/entur/example/web/config/WebSecurityConfig.java +++ b/examples/gcp-web-without-test-artifacts-example/src/main/java/org/entur/example/web/config/WebSecurityConfig.java @@ -12,7 +12,7 @@ public class WebSecurityConfig { @Bean public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { http - .csrf().disable() + .csrf( (c) -> c.disable()) .authorizeHttpRequests((authz) -> authz .anyRequest().permitAll()); return http.build(); diff --git a/examples/gcp-web-without-test-artifacts-example/src/test/java/org/entur/example/web/OndemandWebLoggingHttpBadRequestTest.java b/examples/gcp-web-without-test-artifacts-example/src/test/java/org/entur/example/web/OndemandWebLoggingHttpBadRequestTest.java index 7d2f8be3..769647d4 100644 --- a/examples/gcp-web-without-test-artifacts-example/src/test/java/org/entur/example/web/OndemandWebLoggingHttpBadRequestTest.java +++ b/examples/gcp-web-without-test-artifacts-example/src/test/java/org/entur/example/web/OndemandWebLoggingHttpBadRequestTest.java @@ -3,9 +3,10 @@ import org.entur.example.web.rest.MyEntity; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.resttestclient.autoconfigure.AutoConfigureTestRestTemplate; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; -import org.springframework.boot.test.web.client.TestRestTemplate; +import org.springframework.boot.resttestclient.TestRestTemplate; import org.springframework.boot.test.web.server.LocalServerPort; import org.springframework.http.HttpEntity; import org.springframework.http.HttpHeaders; @@ -25,6 +26,7 @@ @SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT) @TestPropertySource(properties = {"entur.logging.http.ondemand.enabled=true", "entur.logging.http.ondemand.failure.http.statusCode.equalOrHigherThan=400"}) +@AutoConfigureTestRestTemplate public class OndemandWebLoggingHttpBadRequestTest { @LocalServerPort diff --git a/examples/gcp-web-without-test-artifacts-example/src/test/java/org/entur/example/web/OndemandWebLoggingHttpNotFound1Test.java b/examples/gcp-web-without-test-artifacts-example/src/test/java/org/entur/example/web/OndemandWebLoggingHttpNotFound1Test.java index 9c4614fa..a5d22758 100644 --- a/examples/gcp-web-without-test-artifacts-example/src/test/java/org/entur/example/web/OndemandWebLoggingHttpNotFound1Test.java +++ b/examples/gcp-web-without-test-artifacts-example/src/test/java/org/entur/example/web/OndemandWebLoggingHttpNotFound1Test.java @@ -3,9 +3,10 @@ import org.entur.example.web.rest.MyEntity; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.resttestclient.autoconfigure.AutoConfigureTestRestTemplate; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; -import org.springframework.boot.test.web.client.TestRestTemplate; +import org.springframework.boot.resttestclient.TestRestTemplate; import org.springframework.boot.test.web.server.LocalServerPort; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; @@ -21,6 +22,7 @@ @SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT) @TestPropertySource(properties = {"entur.logging.http.ondemand.enabled=true", "entur.logging.http.ondemand.failure.http.statusCode.equalOrHigherThan=400"}) +@AutoConfigureTestRestTemplate public class OndemandWebLoggingHttpNotFound1Test { @LocalServerPort diff --git a/examples/gcp-web-without-test-artifacts-example/src/test/java/org/entur/example/web/OndemandWebLoggingHttpNotFound2Test.java b/examples/gcp-web-without-test-artifacts-example/src/test/java/org/entur/example/web/OndemandWebLoggingHttpNotFound2Test.java index 348deda9..15a796b3 100644 --- a/examples/gcp-web-without-test-artifacts-example/src/test/java/org/entur/example/web/OndemandWebLoggingHttpNotFound2Test.java +++ b/examples/gcp-web-without-test-artifacts-example/src/test/java/org/entur/example/web/OndemandWebLoggingHttpNotFound2Test.java @@ -3,9 +3,10 @@ import org.entur.example.web.rest.MyEntity; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.resttestclient.autoconfigure.AutoConfigureTestRestTemplate; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; -import org.springframework.boot.test.web.client.TestRestTemplate; +import org.springframework.boot.resttestclient.TestRestTemplate; import org.springframework.boot.test.web.server.LocalServerPort; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; @@ -22,6 +23,7 @@ */ @TestPropertySource(properties = {"entur.logging.http.ondemand.enabled=true", "entur.logging.http.ondemand.failure.http.statusCode.equalOrHigherThan=400"}) +@AutoConfigureTestRestTemplate public class OndemandWebLoggingHttpNotFound2Test { @LocalServerPort diff --git a/examples/gcp-web-without-test-artifacts-example/src/test/java/org/entur/example/web/OndemandWebLoggingHttpOkHighLogLevelTest.java b/examples/gcp-web-without-test-artifacts-example/src/test/java/org/entur/example/web/OndemandWebLoggingHttpOkHighLogLevelTest.java index cefcc947..4a8ede64 100644 --- a/examples/gcp-web-without-test-artifacts-example/src/test/java/org/entur/example/web/OndemandWebLoggingHttpOkHighLogLevelTest.java +++ b/examples/gcp-web-without-test-artifacts-example/src/test/java/org/entur/example/web/OndemandWebLoggingHttpOkHighLogLevelTest.java @@ -3,9 +3,10 @@ import org.entur.example.web.rest.MyEntity; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.resttestclient.autoconfigure.AutoConfigureTestRestTemplate; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; -import org.springframework.boot.test.web.client.TestRestTemplate; +import org.springframework.boot.resttestclient.TestRestTemplate; import org.springframework.boot.test.web.server.LocalServerPort; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; @@ -24,6 +25,7 @@ "entur.logging.http.ondemand.enabled=true", "entur.logging.http.ondemand.failure.logger.level=error", }) +@AutoConfigureTestRestTemplate public class OndemandWebLoggingHttpOkHighLogLevelTest { @LocalServerPort diff --git a/examples/gcp-web-without-test-artifacts-example/src/test/java/org/entur/example/web/OndemandWebLoggingHttpOkTest.java b/examples/gcp-web-without-test-artifacts-example/src/test/java/org/entur/example/web/OndemandWebLoggingHttpOkTest.java index d4c04aa7..8cb05668 100644 --- a/examples/gcp-web-without-test-artifacts-example/src/test/java/org/entur/example/web/OndemandWebLoggingHttpOkTest.java +++ b/examples/gcp-web-without-test-artifacts-example/src/test/java/org/entur/example/web/OndemandWebLoggingHttpOkTest.java @@ -3,9 +3,10 @@ import org.entur.example.web.rest.MyEntity; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.resttestclient.autoconfigure.AutoConfigureTestRestTemplate; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; -import org.springframework.boot.test.web.client.TestRestTemplate; +import org.springframework.boot.resttestclient.TestRestTemplate; import org.springframework.boot.test.web.server.LocalServerPort; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; @@ -16,6 +17,7 @@ @SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT) @TestPropertySource(properties = {"entur.logging.http.ondemand.enabled=true", "entur.logging.http.ondemand.failure.http.statusCode.equalOrHigherThan=400"}) +@AutoConfigureTestRestTemplate public class OndemandWebLoggingHttpOkTest { @LocalServerPort diff --git a/examples/gcp-web-without-test-artifacts-example/src/test/java/org/entur/example/web/OndemandWebLoggingHttpOkTroubleshootingTest.java b/examples/gcp-web-without-test-artifacts-example/src/test/java/org/entur/example/web/OndemandWebLoggingHttpOkTroubleshootingTest.java index 27dc3ca0..e36c3414 100644 --- a/examples/gcp-web-without-test-artifacts-example/src/test/java/org/entur/example/web/OndemandWebLoggingHttpOkTroubleshootingTest.java +++ b/examples/gcp-web-without-test-artifacts-example/src/test/java/org/entur/example/web/OndemandWebLoggingHttpOkTroubleshootingTest.java @@ -3,9 +3,10 @@ import org.entur.example.web.rest.MyEntity; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.resttestclient.autoconfigure.AutoConfigureTestRestTemplate; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; -import org.springframework.boot.test.web.client.TestRestTemplate; +import org.springframework.boot.resttestclient.TestRestTemplate; import org.springframework.boot.test.web.server.LocalServerPort; import org.springframework.http.*; import org.springframework.test.context.TestPropertySource; @@ -19,6 +20,7 @@ "entur.logging.http.ondemand.failure.http.statusCode.equalOrHigherThan=400", "entur.logging.http.ondemand.troubleshoot.http.headers[0].name=X-DEBUG" }) +@AutoConfigureTestRestTemplate public class OndemandWebLoggingHttpOkTroubleshootingTest { @LocalServerPort diff --git a/examples/gcp-web-without-test-artifacts-example/src/test/java/org/entur/example/web/WebLoggingFormatTest.java b/examples/gcp-web-without-test-artifacts-example/src/test/java/org/entur/example/web/WebLoggingFormatTest.java index 56ce801c..0839b853 100644 --- a/examples/gcp-web-without-test-artifacts-example/src/test/java/org/entur/example/web/WebLoggingFormatTest.java +++ b/examples/gcp-web-without-test-artifacts-example/src/test/java/org/entur/example/web/WebLoggingFormatTest.java @@ -5,14 +5,16 @@ import org.entur.example.web.rest.MyEntity; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.resttestclient.autoconfigure.AutoConfigureTestRestTemplate; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; -import org.springframework.boot.test.web.client.TestRestTemplate; +import org.springframework.boot.resttestclient.TestRestTemplate; import org.springframework.boot.test.web.server.LocalServerPort; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; @SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT) +@AutoConfigureTestRestTemplate public class WebLoggingFormatTest { @LocalServerPort diff --git a/examples/gcp-web-without-test-artifacts-example/src/test/java/org/entur/example/web/WebLoggingMessageFormatTest.java b/examples/gcp-web-without-test-artifacts-example/src/test/java/org/entur/example/web/WebLoggingMessageFormatTest.java index a804db29..4ce02ec8 100644 --- a/examples/gcp-web-without-test-artifacts-example/src/test/java/org/entur/example/web/WebLoggingMessageFormatTest.java +++ b/examples/gcp-web-without-test-artifacts-example/src/test/java/org/entur/example/web/WebLoggingMessageFormatTest.java @@ -3,9 +3,10 @@ import org.entur.example.web.rest.MyEntity; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.resttestclient.autoconfigure.AutoConfigureTestRestTemplate; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; -import org.springframework.boot.test.web.client.TestRestTemplate; +import org.springframework.boot.resttestclient.TestRestTemplate; import org.springframework.boot.test.web.server.LocalServerPort; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; @@ -19,6 +20,7 @@ "entur.logging.request-response.format.server.message.host=false", "entur.logging.request-response.format.server.message.port=false" }) +@AutoConfigureTestRestTemplate public class WebLoggingMessageFormatTest { @LocalServerPort diff --git a/examples/gcp-web-without-test-or-ondemand-artifacts-example/build.gradle b/examples/gcp-web-without-test-or-ondemand-artifacts-example/build.gradle index 1ca24142..f1fdf86c 100644 --- a/examples/gcp-web-without-test-or-ondemand-artifacts-example/build.gradle +++ b/examples/gcp-web-without-test-or-ondemand-artifacts-example/build.gradle @@ -1,10 +1,10 @@ plugins { - id 'org.springframework.boot' version '3.5.7' + id 'org.springframework.boot' version '4.0.1' } test { useJUnitPlatform { - includeEngines 'junit-jupiter', 'junit-vintage' + includeEngines 'junit-jupiter' } } @@ -16,6 +16,8 @@ dependencies { implementation("org.springframework.boot:spring-boot-starter-web") testImplementation("org.springframework.boot:spring-boot-starter-test") + testImplementation("org.springframework.boot:spring-boot-restclient") + testImplementation("org.springframework.boot:spring-boot-resttestclient") // JUnit Jupiter API and TestEngine implementation testImplementation("org.junit.jupiter:junit-jupiter-api") diff --git a/examples/gcp-web-without-test-or-ondemand-artifacts-example/src/main/java/org/entur/example/web/config/WebSecurityConfig.java b/examples/gcp-web-without-test-or-ondemand-artifacts-example/src/main/java/org/entur/example/web/config/WebSecurityConfig.java index 04a96010..bed6c3b4 100644 --- a/examples/gcp-web-without-test-or-ondemand-artifacts-example/src/main/java/org/entur/example/web/config/WebSecurityConfig.java +++ b/examples/gcp-web-without-test-or-ondemand-artifacts-example/src/main/java/org/entur/example/web/config/WebSecurityConfig.java @@ -12,7 +12,7 @@ public class WebSecurityConfig { @Bean public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { http - .csrf().disable() + .csrf( (c) -> c.disable()) .authorizeHttpRequests((authz) -> authz .anyRequest().permitAll()); return http.build(); diff --git a/examples/gcp-web-without-test-or-ondemand-artifacts-example/src/test/java/org/entur/example/web/ErrorWebLoggingFormatTest.java b/examples/gcp-web-without-test-or-ondemand-artifacts-example/src/test/java/org/entur/example/web/ErrorWebLoggingFormatTest.java index ed1b57e7..9195bd53 100644 --- a/examples/gcp-web-without-test-or-ondemand-artifacts-example/src/test/java/org/entur/example/web/ErrorWebLoggingFormatTest.java +++ b/examples/gcp-web-without-test-or-ondemand-artifacts-example/src/test/java/org/entur/example/web/ErrorWebLoggingFormatTest.java @@ -3,15 +3,17 @@ import org.entur.example.web.rest.MyEntity; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.resttestclient.autoconfigure.AutoConfigureTestRestTemplate; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; -import org.springframework.boot.test.web.client.TestRestTemplate; +import org.springframework.boot.resttestclient.TestRestTemplate; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import static org.assertj.core.api.Assertions.assertThat; @SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT) +@AutoConfigureTestRestTemplate public class ErrorWebLoggingFormatTest { @Autowired diff --git a/examples/gcp-web-without-test-or-ondemand-artifacts-example/src/test/java/org/entur/example/web/WebLoggingFormatTest.java b/examples/gcp-web-without-test-or-ondemand-artifacts-example/src/test/java/org/entur/example/web/WebLoggingFormatTest.java index 45e4b0be..fbe7ae1b 100644 --- a/examples/gcp-web-without-test-or-ondemand-artifacts-example/src/test/java/org/entur/example/web/WebLoggingFormatTest.java +++ b/examples/gcp-web-without-test-or-ondemand-artifacts-example/src/test/java/org/entur/example/web/WebLoggingFormatTest.java @@ -5,14 +5,16 @@ import org.entur.example.web.rest.MyEntity; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.resttestclient.autoconfigure.AutoConfigureTestRestTemplate; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; -import org.springframework.boot.test.web.client.TestRestTemplate; +import org.springframework.boot.resttestclient.TestRestTemplate; import org.springframework.boot.test.web.server.LocalServerPort; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; @SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT) +@AutoConfigureTestRestTemplate public class WebLoggingFormatTest { @Autowired diff --git a/gcp/logback-logstash-encoder-gcp/build.gradle b/gcp/logback-logstash-encoder-gcp/build.gradle index 135179b7..7f4e5b78 100644 --- a/gcp/logback-logstash-encoder-gcp/build.gradle +++ b/gcp/logback-logstash-encoder-gcp/build.gradle @@ -7,7 +7,7 @@ dependencies { api ("ch.qos.logback:logback-core") api ("net.logstash.logback:logstash-logback-encoder:${logbackLogstashVersion}") - api("com.fasterxml.jackson.core:jackson-core") + api("tools.jackson.core:jackson-core") } diff --git a/gcp/logback-logstash-encoder-gcp/src/main/java/no/entur/logging/cloud/gcp/logback/logstash/SimpleMdcJsonProvider.java b/gcp/logback-logstash-encoder-gcp/src/main/java/no/entur/logging/cloud/gcp/logback/logstash/SimpleMdcJsonProvider.java index 9555bf89..fd339072 100644 --- a/gcp/logback-logstash-encoder-gcp/src/main/java/no/entur/logging/cloud/gcp/logback/logstash/SimpleMdcJsonProvider.java +++ b/gcp/logback-logstash-encoder-gcp/src/main/java/no/entur/logging/cloud/gcp/logback/logstash/SimpleMdcJsonProvider.java @@ -1,7 +1,7 @@ package no.entur.logging.cloud.gcp.logback.logstash; import ch.qos.logback.classic.spi.ILoggingEvent; -import com.fasterxml.jackson.core.JsonGenerator; +import tools.jackson.core.JsonGenerator; import net.logstash.logback.composite.AbstractJsonProvider; import java.io.IOException; @@ -16,7 +16,7 @@ public class SimpleMdcJsonProvider extends AbstractJsonProvider { @Override - public void writeTo(JsonGenerator generator, ILoggingEvent event) throws IOException { + public void writeTo(JsonGenerator generator, ILoggingEvent event) { Map mdcProperties = event.getMDCPropertyMap(); if (mdcProperties != null && !mdcProperties.isEmpty()) { for (Map.Entry entry : mdcProperties.entrySet()) { @@ -25,7 +25,7 @@ public void writeTo(JsonGenerator generator, ILoggingEvent event) throws IOExcep if(key == null || value == null) { continue; } - generator.writeStringField(key, value); + generator.writeStringProperty(key, value); } } } diff --git a/gcp/logback-logstash-encoder-gcp/src/main/java/no/entur/logging/cloud/gcp/logback/logstash/StackdriverLogSeverityJsonProvider.java b/gcp/logback-logstash-encoder-gcp/src/main/java/no/entur/logging/cloud/gcp/logback/logstash/StackdriverLogSeverityJsonProvider.java index 2e7df4bd..79d53a16 100644 --- a/gcp/logback-logstash-encoder-gcp/src/main/java/no/entur/logging/cloud/gcp/logback/logstash/StackdriverLogSeverityJsonProvider.java +++ b/gcp/logback-logstash-encoder-gcp/src/main/java/no/entur/logging/cloud/gcp/logback/logstash/StackdriverLogSeverityJsonProvider.java @@ -2,7 +2,7 @@ import ch.qos.logback.classic.Level; import ch.qos.logback.classic.spi.ILoggingEvent; -import com.fasterxml.jackson.core.JsonGenerator; +import tools.jackson.core.JsonGenerator; import net.logstash.logback.composite.AbstractFieldJsonProvider; import net.logstash.logback.composite.FieldNamesAware; import net.logstash.logback.composite.JsonWritingUtils; @@ -77,7 +77,7 @@ public StackdriverLogSeverityJsonProvider() { } @Override - public void writeTo(JsonGenerator generator, ILoggingEvent event) throws IOException { + public void writeTo(JsonGenerator generator, ILoggingEvent event) { JsonWritingUtils.writeStringField(generator, getFieldName(), getSeverity(event).toString()); } diff --git a/gcp/logback-logstash-encoder-gcp/src/main/java/no/entur/logging/cloud/gcp/logback/logstash/StackdriverMessageJsonProvider.java b/gcp/logback-logstash-encoder-gcp/src/main/java/no/entur/logging/cloud/gcp/logback/logstash/StackdriverMessageJsonProvider.java index e00fdbac..b18a732a 100644 --- a/gcp/logback-logstash-encoder-gcp/src/main/java/no/entur/logging/cloud/gcp/logback/logstash/StackdriverMessageJsonProvider.java +++ b/gcp/logback-logstash-encoder-gcp/src/main/java/no/entur/logging/cloud/gcp/logback/logstash/StackdriverMessageJsonProvider.java @@ -3,7 +3,7 @@ import ch.qos.logback.classic.spi.ILoggingEvent; import ch.qos.logback.classic.spi.IThrowableProxy; import ch.qos.logback.classic.spi.StackTraceElementProxy; -import com.fasterxml.jackson.core.JsonGenerator; +import tools.jackson.core.JsonGenerator; import net.logstash.logback.composite.JsonWritingUtils; import net.logstash.logback.composite.loggingevent.MessageJsonProvider; @@ -12,7 +12,7 @@ public class StackdriverMessageJsonProvider extends MessageJsonProvider { @Override - public void writeTo(JsonGenerator generator, ILoggingEvent event) throws IOException { + public void writeTo(JsonGenerator generator, ILoggingEvent event) { IThrowableProxy throwableProxy = event.getThrowableProxy(); if (throwableProxy != null) { String formattedMessage = event.getFormattedMessage(); diff --git a/gcp/logback-logstash-encoder-gcp/src/main/java/no/entur/logging/cloud/gcp/logback/logstash/StackdriverOpenTelemetryTraceMdcJsonProvider.java b/gcp/logback-logstash-encoder-gcp/src/main/java/no/entur/logging/cloud/gcp/logback/logstash/StackdriverOpenTelemetryTraceMdcJsonProvider.java index e27dd2a6..101fdf81 100644 --- a/gcp/logback-logstash-encoder-gcp/src/main/java/no/entur/logging/cloud/gcp/logback/logstash/StackdriverOpenTelemetryTraceMdcJsonProvider.java +++ b/gcp/logback-logstash-encoder-gcp/src/main/java/no/entur/logging/cloud/gcp/logback/logstash/StackdriverOpenTelemetryTraceMdcJsonProvider.java @@ -1,12 +1,8 @@ package no.entur.logging.cloud.gcp.logback.logstash; import ch.qos.logback.classic.spi.ILoggingEvent; -import ch.qos.logback.core.spi.DeferredProcessingAware; -import com.fasterxml.jackson.core.JsonGenerator; -import net.logstash.logback.composite.AbstractFieldJsonProvider; +import tools.jackson.core.JsonGenerator; import net.logstash.logback.composite.AbstractJsonProvider; -import net.logstash.logback.composite.FieldNamesAware; -import net.logstash.logback.fieldnames.LogstashFieldNames; import java.io.IOException; import java.util.Map; @@ -20,12 +16,12 @@ public class StackdriverOpenTelemetryTraceMdcJsonProvider extends AbstractJsonProvider { @Override - public void writeTo(JsonGenerator generator, ILoggingEvent event) throws IOException { + public void writeTo(JsonGenerator generator, ILoggingEvent event) { Map mdcProperties = event.getMDCPropertyMap(); if (mdcProperties != null && !mdcProperties.isEmpty()) { String traceId = mdcProperties.get("traceId"); if(traceId != null) { - generator.writeStringField("trace", traceId); + generator.writeStringProperty("trace", traceId); } for (Map.Entry entry : mdcProperties.entrySet()) { String key = entry.getKey(); @@ -33,7 +29,7 @@ public void writeTo(JsonGenerator generator, ILoggingEvent event) throws IOExcep if(key == null || value == null) { continue; } - generator.writeStringField(key, value); + generator.writeStringProperty(key, value); } } } diff --git a/gcp/logback-logstash-encoder-gcp/src/main/java/no/entur/logging/cloud/gcp/logback/logstash/StackdriverServiceContextJsonProvider.java b/gcp/logback-logstash-encoder-gcp/src/main/java/no/entur/logging/cloud/gcp/logback/logstash/StackdriverServiceContextJsonProvider.java index 8a5d6017..65d439c5 100644 --- a/gcp/logback-logstash-encoder-gcp/src/main/java/no/entur/logging/cloud/gcp/logback/logstash/StackdriverServiceContextJsonProvider.java +++ b/gcp/logback-logstash-encoder-gcp/src/main/java/no/entur/logging/cloud/gcp/logback/logstash/StackdriverServiceContextJsonProvider.java @@ -1,7 +1,7 @@ package no.entur.logging.cloud.gcp.logback.logstash; import ch.qos.logback.classic.spi.ILoggingEvent; -import com.fasterxml.jackson.core.JsonGenerator; +import tools.jackson.core.JsonGenerator; import net.logstash.logback.composite.AbstractFieldJsonProvider; import net.logstash.logback.composite.FieldNamesAware; import net.logstash.logback.composite.JsonWritingUtils; @@ -72,9 +72,9 @@ public static String parseServiceNameFromHostname(String host) { } @Override - public void writeTo(JsonGenerator generator, ILoggingEvent event) throws IOException { + public void writeTo(JsonGenerator generator, ILoggingEvent event) { if(service != null) { - generator.writeObjectFieldStart(getFieldName()); + generator.writeObjectPropertyStart(getFieldName()); JsonWritingUtils.writeStringField(generator, "service", service); diff --git a/gcp/logback-logstash-encoder-gcp/src/main/java/no/entur/logging/cloud/gcp/logback/logstash/StackdriverTimestampJsonProvider.java b/gcp/logback-logstash-encoder-gcp/src/main/java/no/entur/logging/cloud/gcp/logback/logstash/StackdriverTimestampJsonProvider.java index 3ddae3e8..335bbdf8 100644 --- a/gcp/logback-logstash-encoder-gcp/src/main/java/no/entur/logging/cloud/gcp/logback/logstash/StackdriverTimestampJsonProvider.java +++ b/gcp/logback-logstash-encoder-gcp/src/main/java/no/entur/logging/cloud/gcp/logback/logstash/StackdriverTimestampJsonProvider.java @@ -1,7 +1,7 @@ package no.entur.logging.cloud.gcp.logback.logstash; import ch.qos.logback.classic.spi.ILoggingEvent; -import com.fasterxml.jackson.core.JsonGenerator; +import tools.jackson.core.JsonGenerator; import net.logstash.logback.composite.AbstractJsonProvider; import net.logstash.logback.composite.JsonWritingUtils; @@ -20,10 +20,10 @@ public class StackdriverTimestampJsonProvider extends AbstractJsonProvider { @Override - public void writeTo(JsonGenerator generator, ILoggingEvent event) throws IOException { - generator.writeObjectFieldStart("timestamp"); - generator.writeNumberField("seconds", event.getTimeStamp() / 1000); - generator.writeNumberField("nanos", event.getNanoseconds()); + public void writeTo(JsonGenerator generator, ILoggingEvent event) { + generator.writeObjectPropertyStart("timestamp"); + generator.writeNumberProperty("seconds", event.getTimeStamp() / 1000); + generator.writeNumberProperty("nanos", event.getNanoseconds()); generator.writeEndObject(); } diff --git a/gcp/micrometer-gcp/src/main/java/no/entur/logging/cloud/gcp/micrometer/StackdriverLogbackMetrics.java b/gcp/micrometer-gcp/src/main/java/no/entur/logging/cloud/gcp/micrometer/StackdriverLogbackMetrics.java index 6edef34f..0260702a 100644 --- a/gcp/micrometer-gcp/src/main/java/no/entur/logging/cloud/gcp/micrometer/StackdriverLogbackMetrics.java +++ b/gcp/micrometer-gcp/src/main/java/no/entur/logging/cloud/gcp/micrometer/StackdriverLogbackMetrics.java @@ -2,8 +2,6 @@ import ch.qos.logback.classic.LoggerContext; import io.micrometer.core.instrument.MeterRegistry; -import io.micrometer.core.lang.NonNullApi; -import io.micrometer.core.lang.NonNullFields; import org.slf4j.LoggerFactory; import java.util.Map; @@ -15,8 +13,6 @@ * Logback driver with extra log levels. Originally copied from LogbackMetrics class in micrometer-core. * */ -@NonNullApi -@NonNullFields public class StackdriverLogbackMetrics extends io.micrometer.core.instrument.binder.logging.LogbackMetrics { // extend since there is not interface type protected final LoggerContext loggerContext; diff --git a/gcp/micrometer-gcp/src/main/java/no/entur/logging/cloud/gcp/micrometer/StackdriverMetricsTurboFilter.java b/gcp/micrometer-gcp/src/main/java/no/entur/logging/cloud/gcp/micrometer/StackdriverMetricsTurboFilter.java index 4fe6b56e..dc1b2d16 100644 --- a/gcp/micrometer-gcp/src/main/java/no/entur/logging/cloud/gcp/micrometer/StackdriverMetricsTurboFilter.java +++ b/gcp/micrometer-gcp/src/main/java/no/entur/logging/cloud/gcp/micrometer/StackdriverMetricsTurboFilter.java @@ -8,8 +8,6 @@ import io.micrometer.core.instrument.Counter; import io.micrometer.core.instrument.MeterRegistry; import io.micrometer.core.instrument.Tag; -import io.micrometer.core.lang.NonNullApi; -import io.micrometer.core.lang.NonNullFields; import no.entur.logging.cloud.api.DevOpsLevel; import no.entur.logging.cloud.api.DevOpsMarker; import no.entur.logging.cloud.micrometer.LoggingEventMetrics; @@ -17,8 +15,6 @@ import java.util.List; -@NonNullApi -@NonNullFields public class StackdriverMetricsTurboFilter extends TurboFilter implements LoggingEventMetrics { protected final Counter alertCounter; diff --git a/gcp/request-response-spring-boot-starter-gcp-grpc-ecosystem-test/build.gradle b/gcp/request-response-spring-boot-starter-gcp-grpc-spring-test/build.gradle similarity index 71% rename from gcp/request-response-spring-boot-starter-gcp-grpc-ecosystem-test/build.gradle rename to gcp/request-response-spring-boot-starter-gcp-grpc-spring-test/build.gradle index 8ea3508e..8b22ef47 100644 --- a/gcp/request-response-spring-boot-starter-gcp-grpc-ecosystem-test/build.gradle +++ b/gcp/request-response-spring-boot-starter-gcp-grpc-spring-test/build.gradle @@ -1,14 +1,16 @@ dependencies { api project(":gcp:spring-boot-autoconfigure-gcp-test") - api project(':gcp:request-response-spring-boot-starter-gcp-grpc-ecosystem') - api project(':request-response:request-response-spring-boot-autoconfigure-grpc-ecosystem') + api project(':gcp:request-response-spring-boot-starter-gcp-grpc-spring') + api project(':request-response:request-response-spring-boot-autoconfigure-grpc-spring') - api ("org.entur.jackson:jackson-syntax-highlight:${jacksonSyntaxHighlightVersion}") + api("org.springframework.grpc:spring-grpc-server-spring-boot-starter:${springGrpcVersion}") + + api ("org.entur.jackson:jackson-tools-syntax-highlight:${jacksonSyntaxHighlightVersion}") api ("org.entur.logback-logstash-syntax-highlighting-decorators:logback-logstash-syntax-highlighting-decorators:${logbackLogstashSyntaxHighlightingDecoratorsVersion}") api ("net.logstash.logback:logstash-logback-encoder:${logbackLogstashVersion}") - api ("com.fasterxml.jackson.core:jackson-core") + api ("tools.jackson.core:jackson-core") api("org.slf4j:slf4j-api") api("org.springframework.boot:spring-boot-autoconfigure") diff --git a/gcp/request-response-spring-boot-starter-gcp-grpc-ecosystem-test/src/main/java/no/entur/logging/cloud/gcp/spring/gcp/grpc/ecosystem/test/RequestResponseGcpGrpcEcosystemTestAutoConfiguration.java b/gcp/request-response-spring-boot-starter-gcp-grpc-spring-test/src/main/java/no/entur/logging/cloud/gcp/spring/gcp/grpc/ecosystem/test/RequestResponseGcpGrpcEcosystemTestAutoConfiguration.java similarity index 95% rename from gcp/request-response-spring-boot-starter-gcp-grpc-ecosystem-test/src/main/java/no/entur/logging/cloud/gcp/spring/gcp/grpc/ecosystem/test/RequestResponseGcpGrpcEcosystemTestAutoConfiguration.java rename to gcp/request-response-spring-boot-starter-gcp-grpc-spring-test/src/main/java/no/entur/logging/cloud/gcp/spring/gcp/grpc/ecosystem/test/RequestResponseGcpGrpcEcosystemTestAutoConfiguration.java index cc179b39..96b659c2 100644 --- a/gcp/request-response-spring-boot-starter-gcp-grpc-ecosystem-test/src/main/java/no/entur/logging/cloud/gcp/spring/gcp/grpc/ecosystem/test/RequestResponseGcpGrpcEcosystemTestAutoConfiguration.java +++ b/gcp/request-response-spring-boot-starter-gcp-grpc-spring-test/src/main/java/no/entur/logging/cloud/gcp/spring/gcp/grpc/ecosystem/test/RequestResponseGcpGrpcEcosystemTestAutoConfiguration.java @@ -2,12 +2,12 @@ import no.entur.logging.cloud.gcp.spring.gcp.grpc.ecosystem.RequestResponseGcpGrpcEcosystemAutoConfiguration; import no.entur.logging.cloud.spring.rr.grpc.AbstractRequestResponseGrpcSinkAutoConfiguration; -import org.entur.jackson.jsh.AnsiSyntaxHighlight; -import org.entur.jackson.jsh.DefaultSyntaxHighlighter; import no.entur.logging.cloud.rr.grpc.GrpcSink; import no.entur.logging.cloud.rr.grpc.test.CompositeSink; import no.entur.logging.cloud.rr.grpc.test.PrettyPrintingLogLevelLogstashLogbackGrpcSink; import no.entur.logging.cloud.rr.grpc.test.PrettyPrintingGrpcSink; +import org.entur.jackson.tools.jsh.AnsiSyntaxHighlight; +import org.entur.jackson.tools.jsh.DefaultSyntaxHighlighter; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.slf4j.event.Level; diff --git a/gcp/request-response-spring-boot-starter-gcp-grpc-ecosystem-test/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports b/gcp/request-response-spring-boot-starter-gcp-grpc-spring-test/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports similarity index 100% rename from gcp/request-response-spring-boot-starter-gcp-grpc-ecosystem-test/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports rename to gcp/request-response-spring-boot-starter-gcp-grpc-spring-test/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports diff --git a/gcp/request-response-spring-boot-starter-gcp-grpc-ecosystem-test/src/test/java/no/entur/logging/cloud/spring/logbook/web/test/DemoApplication.java b/gcp/request-response-spring-boot-starter-gcp-grpc-spring-test/src/test/java/no/entur/logging/cloud/gcp/spring/gcp/grpc/ecosystem/test/DemoApplication.java similarity index 80% rename from gcp/request-response-spring-boot-starter-gcp-grpc-ecosystem-test/src/test/java/no/entur/logging/cloud/spring/logbook/web/test/DemoApplication.java rename to gcp/request-response-spring-boot-starter-gcp-grpc-spring-test/src/test/java/no/entur/logging/cloud/gcp/spring/gcp/grpc/ecosystem/test/DemoApplication.java index 5ad9589d..240f1484 100644 --- a/gcp/request-response-spring-boot-starter-gcp-grpc-ecosystem-test/src/test/java/no/entur/logging/cloud/spring/logbook/web/test/DemoApplication.java +++ b/gcp/request-response-spring-boot-starter-gcp-grpc-spring-test/src/test/java/no/entur/logging/cloud/gcp/spring/gcp/grpc/ecosystem/test/DemoApplication.java @@ -1,4 +1,4 @@ -package no.entur.logging.cloud.spring.logbook.web.test; +package no.entur.logging.cloud.gcp.spring.gcp.grpc.ecosystem.test; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; diff --git a/gcp/request-response-spring-boot-starter-gcp-grpc-ecosystem-test/src/test/java/no/entur/logging/cloud/spring/logbook/web/test/LoadContextLoggingTest.java b/gcp/request-response-spring-boot-starter-gcp-grpc-spring-test/src/test/java/no/entur/logging/cloud/gcp/spring/gcp/grpc/ecosystem/test/LoadContextLoggingTest.java similarity index 97% rename from gcp/request-response-spring-boot-starter-gcp-grpc-ecosystem-test/src/test/java/no/entur/logging/cloud/spring/logbook/web/test/LoadContextLoggingTest.java rename to gcp/request-response-spring-boot-starter-gcp-grpc-spring-test/src/test/java/no/entur/logging/cloud/gcp/spring/gcp/grpc/ecosystem/test/LoadContextLoggingTest.java index 100a870e..f5562f72 100644 --- a/gcp/request-response-spring-boot-starter-gcp-grpc-ecosystem-test/src/test/java/no/entur/logging/cloud/spring/logbook/web/test/LoadContextLoggingTest.java +++ b/gcp/request-response-spring-boot-starter-gcp-grpc-spring-test/src/test/java/no/entur/logging/cloud/gcp/spring/gcp/grpc/ecosystem/test/LoadContextLoggingTest.java @@ -1,4 +1,4 @@ -package no.entur.logging.cloud.spring.logbook.web.test; +package no.entur.logging.cloud.gcp.spring.gcp.grpc.ecosystem.test; import no.entur.logging.cloud.api.DevOpsLogger; import no.entur.logging.cloud.api.DevOpsLoggerFactory; diff --git a/gcp/request-response-spring-boot-starter-gcp-grpc-ecosystem/README.md b/gcp/request-response-spring-boot-starter-gcp-grpc-spring/README.md similarity index 100% rename from gcp/request-response-spring-boot-starter-gcp-grpc-ecosystem/README.md rename to gcp/request-response-spring-boot-starter-gcp-grpc-spring/README.md diff --git a/gcp/request-response-spring-boot-starter-gcp-grpc-ecosystem/build.gradle b/gcp/request-response-spring-boot-starter-gcp-grpc-spring/build.gradle similarity index 80% rename from gcp/request-response-spring-boot-starter-gcp-grpc-ecosystem/build.gradle rename to gcp/request-response-spring-boot-starter-gcp-grpc-spring/build.gradle index 3b33f6bc..da707120 100644 --- a/gcp/request-response-spring-boot-starter-gcp-grpc-ecosystem/build.gradle +++ b/gcp/request-response-spring-boot-starter-gcp-grpc-spring/build.gradle @@ -4,14 +4,14 @@ dependencies { api project(':api') api project(':gcp:logback-logstash-encoder-gcp') api project(':request-response:netty-grpc') - api project(':request-response:request-response-spring-boot-autoconfigure-grpc-ecosystem') + api project(':request-response:request-response-spring-boot-autoconfigure-grpc-spring') api ("org.slf4j:slf4j-api") api ("org.springframework.boot:spring-boot-starter") api ("org.springframework.boot:spring-boot-autoconfigure") api ("org.springframework.boot:spring-boot-starter-logging") - api("net.devh:grpc-server-spring-boot-starter:${ecosystemGrpcVersion}") + api("org.springframework.grpc:spring-grpc-server-spring-boot-starter:${springGrpcVersion}") testImplementation("org.springframework.boot:spring-boot-starter-test") } diff --git a/gcp/request-response-spring-boot-starter-gcp-grpc-ecosystem/src/main/java/no/entur/logging/cloud/gcp/spring/gcp/grpc/ecosystem/RequestResponseGcpGrpcEcosystemAutoConfiguration.java b/gcp/request-response-spring-boot-starter-gcp-grpc-spring/src/main/java/no/entur/logging/cloud/gcp/spring/gcp/grpc/ecosystem/RequestResponseGcpGrpcEcosystemAutoConfiguration.java similarity index 77% rename from gcp/request-response-spring-boot-starter-gcp-grpc-ecosystem/src/main/java/no/entur/logging/cloud/gcp/spring/gcp/grpc/ecosystem/RequestResponseGcpGrpcEcosystemAutoConfiguration.java rename to gcp/request-response-spring-boot-starter-gcp-grpc-spring/src/main/java/no/entur/logging/cloud/gcp/spring/gcp/grpc/ecosystem/RequestResponseGcpGrpcEcosystemAutoConfiguration.java index 90470849..b0a69c9e 100644 --- a/gcp/request-response-spring-boot-starter-gcp-grpc-ecosystem/src/main/java/no/entur/logging/cloud/gcp/spring/gcp/grpc/ecosystem/RequestResponseGcpGrpcEcosystemAutoConfiguration.java +++ b/gcp/request-response-spring-boot-starter-gcp-grpc-spring/src/main/java/no/entur/logging/cloud/gcp/spring/gcp/grpc/ecosystem/RequestResponseGcpGrpcEcosystemAutoConfiguration.java @@ -1,13 +1,10 @@ package no.entur.logging.cloud.gcp.spring.gcp.grpc.ecosystem; -import no.entur.logging.cloud.spring.grpc.ecosystem.RequestResponseGrpcEcosystemAutoConfiguration; -import no.entur.logging.cloud.spring.rr.grpc.AbstractRequestResponseGrpcSinkAutoConfiguration; import no.entur.logging.cloud.spring.rr.grpc.GrpcLoggingCloudProperties; import no.entur.logging.cloud.spring.rr.grpc.RequestResponseGrpcAutoConfiguration; import org.springframework.boot.autoconfigure.AutoConfigureBefore; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.PropertySource; @Configuration @AutoConfigureBefore(RequestResponseGrpcAutoConfiguration.class) diff --git a/gcp/request-response-spring-boot-starter-gcp-grpc-ecosystem/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports b/gcp/request-response-spring-boot-starter-gcp-grpc-spring/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports similarity index 100% rename from gcp/request-response-spring-boot-starter-gcp-grpc-ecosystem/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports rename to gcp/request-response-spring-boot-starter-gcp-grpc-spring/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports diff --git a/gcp/spring-boot-autoconfigure-gcp-test/build.gradle b/gcp/spring-boot-autoconfigure-gcp-test/build.gradle index e63feb39..498d1407 100644 --- a/gcp/spring-boot-autoconfigure-gcp-test/build.gradle +++ b/gcp/spring-boot-autoconfigure-gcp-test/build.gradle @@ -15,7 +15,7 @@ dependencies { api("org.springframework.boot:spring-boot-starter-logging") api("org.springframework.boot:spring-boot-autoconfigure") - api ("org.entur.jackson:jackson-syntax-highlight:${jacksonSyntaxHighlightVersion}") + api ("org.entur.jackson:jackson-tools-syntax-highlight:${jacksonSyntaxHighlightVersion}") api ("org.entur.logback-logstash-syntax-highlighting-decorators:logback-logstash-syntax-highlighting-decorators:${logbackLogstashSyntaxHighlightingDecoratorsVersion}") annotationProcessor "org.springframework.boot:spring-boot-configuration-processor:${springBootVersion}" diff --git a/gcp/spring-boot-autoconfigure-gcp-test/src/main/java/no/entur/logging/cloud/gcp/spring/test/LogSeveritySyntaxHighlighter.java b/gcp/spring-boot-autoconfigure-gcp-test/src/main/java/no/entur/logging/cloud/gcp/spring/test/LogSeveritySyntaxHighlighter.java index 3cadfb79..55d0b6ac 100644 --- a/gcp/spring-boot-autoconfigure-gcp-test/src/main/java/no/entur/logging/cloud/gcp/spring/test/LogSeveritySyntaxHighlighter.java +++ b/gcp/spring-boot-autoconfigure-gcp-test/src/main/java/no/entur/logging/cloud/gcp/spring/test/LogSeveritySyntaxHighlighter.java @@ -1,8 +1,8 @@ package no.entur.logging.cloud.gcp.spring.test; import org.entur.decorators.syntaxhighlight.DelegateSyntaxHighlighter; -import org.entur.jackson.jsh.AnsiSyntaxHighlight; -import org.entur.jackson.jsh.SyntaxHighlighter; +import org.entur.jackson.tools.jsh.AnsiSyntaxHighlight; +import org.entur.jackson.tools.jsh.SyntaxHighlighter; public class LogSeveritySyntaxHighlighter extends DelegateSyntaxHighlighter { diff --git a/gcp/spring-boot-autoconfigure-gcp-test/src/main/java/no/entur/logging/cloud/gcp/spring/test/LogSeveritySyntaxHighlighterFactory.java b/gcp/spring-boot-autoconfigure-gcp-test/src/main/java/no/entur/logging/cloud/gcp/spring/test/LogSeveritySyntaxHighlighterFactory.java index d38360c6..a2ef2ca4 100644 --- a/gcp/spring-boot-autoconfigure-gcp-test/src/main/java/no/entur/logging/cloud/gcp/spring/test/LogSeveritySyntaxHighlighterFactory.java +++ b/gcp/spring-boot-autoconfigure-gcp-test/src/main/java/no/entur/logging/cloud/gcp/spring/test/LogSeveritySyntaxHighlighterFactory.java @@ -1,10 +1,10 @@ package no.entur.logging.cloud.gcp.spring.test; -import com.fasterxml.jackson.core.JsonGenerator; +import org.entur.jackson.tools.jsh.AnsiSyntaxHighlight; +import org.entur.jackson.tools.jsh.DefaultSyntaxHighlighter; +import org.entur.jackson.tools.jsh.SyntaxHighlighter; +import tools.jackson.core.JsonGenerator; import org.entur.decorators.factory.ConfigurableSyntaxHighlighterFactory; -import org.entur.jackson.jsh.AnsiSyntaxHighlight; -import org.entur.jackson.jsh.DefaultSyntaxHighlighter; -import org.entur.jackson.jsh.SyntaxHighlighter; public class LogSeveritySyntaxHighlighterFactory extends ConfigurableSyntaxHighlighterFactory { @@ -74,9 +74,9 @@ public LogSeveritySyntaxHighlighterFactory() { } @Override - public SyntaxHighlighter createSyntaxHighlighter(JsonGenerator generator) { + public SyntaxHighlighter createSyntaxHighlighter() { if(cachedSyntaxHighlighter == null) { - cachedSyntaxHighlighter = super.createSyntaxHighlighter(generator); + cachedSyntaxHighlighter = super.createSyntaxHighlighter(); } return new LogSeveritySyntaxHighlighter(cachedSyntaxHighlighter, severity.defaultValue, severity.debug, severity.info, severity.warning, severity.error, severity.critical, severity.alert, severity.emergency, loggerName, message); } diff --git a/gcp/spring-boot-autoconfigure-gcp-test/src/main/resources/logback/logback-spring-test.xml b/gcp/spring-boot-autoconfigure-gcp-test/src/main/resources/logback/logback-spring-test.xml index 359bb798..ac9c301c 100644 --- a/gcp/spring-boot-autoconfigure-gcp-test/src/main/resources/logback/logback-spring-test.xml +++ b/gcp/spring-boot-autoconfigure-gcp-test/src/main/resources/logback/logback-spring-test.xml @@ -22,7 +22,7 @@ TODO this seems to add an extract space after the last newline, but as this is just the human readable format, this is not important. --> - + green @@ -30,7 +30,8 @@ blue magenta - + + diff --git a/gcp/spring-boot-starter-gcp-grpc-ecosystem-test/build.gradle b/gcp/spring-boot-starter-gcp-grpc-spring-test/build.gradle similarity index 100% rename from gcp/spring-boot-starter-gcp-grpc-ecosystem-test/build.gradle rename to gcp/spring-boot-starter-gcp-grpc-spring-test/build.gradle diff --git a/gcp/spring-boot-starter-gcp-grpc-ecosystem/build.gradle b/gcp/spring-boot-starter-gcp-grpc-spring/build.gradle similarity index 90% rename from gcp/spring-boot-starter-gcp-grpc-ecosystem/build.gradle rename to gcp/spring-boot-starter-gcp-grpc-spring/build.gradle index 10b1c66d..8f368792 100644 --- a/gcp/spring-boot-starter-gcp-grpc-ecosystem/build.gradle +++ b/gcp/spring-boot-starter-gcp-grpc-spring/build.gradle @@ -18,7 +18,7 @@ dependencies { api("org.springframework.boot:spring-boot-autoconfigure") api("org.springframework.boot:spring-boot-starter-logging") - api("net.devh:grpc-server-spring-boot-starter:${ecosystemGrpcVersion}") + api("org.springframework.grpc:spring-grpc-server-spring-boot-starter:${springGrpcVersion}") api "io.grpc:grpc-netty:${grpcNettyVersion}" diff --git a/gcp/spring-boot-starter-gcp-grpc-ecosystem/src/main/java/no/entur/logging/cloud/gcp/spring/grpc/ecosystem/EcosystemGrpcLoggingAutoConfiguration.java b/gcp/spring-boot-starter-gcp-grpc-spring/src/main/java/no/entur/logging/cloud/gcp/spring/grpc/ecosystem/EcosystemGrpcLoggingAutoConfiguration.java similarity index 100% rename from gcp/spring-boot-starter-gcp-grpc-ecosystem/src/main/java/no/entur/logging/cloud/gcp/spring/grpc/ecosystem/EcosystemGrpcLoggingAutoConfiguration.java rename to gcp/spring-boot-starter-gcp-grpc-spring/src/main/java/no/entur/logging/cloud/gcp/spring/grpc/ecosystem/EcosystemGrpcLoggingAutoConfiguration.java diff --git a/gcp/spring-boot-starter-gcp-grpc-ecosystem/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports b/gcp/spring-boot-starter-gcp-grpc-spring/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports similarity index 100% rename from gcp/spring-boot-starter-gcp-grpc-ecosystem/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports rename to gcp/spring-boot-starter-gcp-grpc-spring/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar index 943f0cbfa754578e88a3dae77fce6e3dea56edbf..f8e1ee3125fe0768e9a76ee977ac089eb657005e 100644 GIT binary patch literal 45633 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�|d9Zj^A1Dgv5yzCONAB>8LM`TRL&7v_NKg(bEl#y&Z$py}mu<4DrT@8HHjE zqD@4|aM>vt!Yvc2;9Y#V;KJ8M>vPjiS2ycq52qkxInUK*QqA3$&OJ`jZBo zpzw&PT%w0$D94KD%}VN9c)eCueh1^)utGt2OQ+DP(BXszodfc1kFPWl~BQ5Psy*d`UIf zc}zQ8TVw35jdCSc78)MljC-g3$GX2$<0<3MEQXS&i<(ZFClz9WlL}}?%u>S2hhEk_ zyzfm&@Q%YVB-vw3KH|lU#c_)0aeG^;aDG&!bwfOz_9)6gLe;et;h(?*0d-RV0V)1l zzliq#`b9Y*c`0!*6;*mU@&EFSbW>9>L5xUX+unp%@tCW#kLfz)%3vwN{1<-R*g+B_C^W8)>?n%G z<#+`!wU$L&dn)Pz(9DGGI%RlmM2RpeDy9)31OZV$c2T>-Jl&4$6nul&e7){1u-{nP zE$uZs%gyanu+yBcAb+jTYGy(^<;&EzeLeqveN12Lvv)FQFn0o&*qAaH+gLJ)*xT9y z>`Y`W?M#K7%w26w?Oen>j7=R}EbZ;+jcowV&i}P|IfW^C5GJHt5D;Q~)|=gW3iQ;N zQGl4SQFtz=&~BGon6hO@mRnjpmM79ye^LY_L2no{f_M?j80pr`o3BrI7ice#8#Zt4 zO45G97Hpef+AUEU%jN-dLmPYHY(|t#D)9|IeB^i1X|eEq+ymld_Uj$l^zVAPRilx- z^II$sL4G~{^7?sik2BK7;ZV-VIVhrKjUxBIsf^N&K`)5;PjVg-DTm1Xtw4-tGtElU zJgVTCk4^N4#-kPuX=7p~GMf5Jj5A#>)GX)FIcOqY4lf}Vv2gjrOTuFusB@ERW-&fb zTp=E0E?gXkwzn)AMMY*QCftp%MOL-cbsG{02$0~b?-JD{-nwj58 zBHO1YL~yn~RpnZ6*;XA|MSJeBfX-D?afH*E!2uGjT%k!jtx~OG_jJ`Ln}lMQb7W41 zmTIRd%o$pu;%2}}@2J$x%fg{DZEa-Wxdu6mRP~Ea0zD2+g;Dl*to|%sO-5mUrZ`~C zjJ zUe^**YRgBvlxl<(r0LjxjSQKiTx+E<7$@9VO=RYgL9ldTyKzfqR;Y&gu^ub!fVX7u z3H@;8j#tVgga~EMuXv_#Q8<*uK@R{mGzn92eDYkF1sbxh5!P|M-D)T~Ae*SO`@u$Q z7=5s)HM)w~s2j5{I67cqSn6BLLhCMcn0=OTVE?T7bAmY!T+xZ_N3op~wZ3Oxlm6(a5qB({6KghlvBd9HJ#V6YY_zxbj-zI`%FN|C*Q`DiV z#>?Kk7VbuoE*I9tJaa+}=i7tJnMRn`P+(08 za*0VeuAz!eI7giYTsd26P|d^E2p1f#oF*t{#klPhgaShQ1*J7?#CTD@iDRQIV+Z$@ z>qE^3tR3~MVu=%U%*W(1(waaFG_1i5WE}mvAax;iwZKv^g1g}qXY7lAd;!QQa#5e= z1_8KLHje1@?^|6Wb(A{HQ_krJJP1GgE*|?H0Q$5yPBQJlGi;&Lt<3Qc+W4c}Ih~@* zj8lYvme}hwf@Js%Oj=4BxXm15E}7zS0(dW`7X0|$damJ|gJ6~&qKL>gB_eC7%1&Uh zLtOkf7N0b;B`Qj^9)Bfh-( z0or96!;EwEMnxwp!CphwxxJ+DDdP4y3F0i`zZp-sQ5wxGIHIsZCCQz5>QRetx8gq{ zA33BxQ}8Lpe!_o?^u2s3b!a-$DF$OoL=|9aNa7La{$zI#JTu_tYG{m2ly$k?>Yc); zTA9ckzd+ibu>SE6Rc=Yd&?GA9S5oaQgT~ER-|EwANJIAY74|6 z($#j^GP}EJqi%)^jURCj&i;Zl^-M9{=WE69<*p-cmBIz-400wEewWVEd^21}_@A#^ z2DQMldk_N)6bhFZeo8dDTWD@-IVunEY*nYRON_FYII-1Q@@hzzFe(lTvqm}InfjQ2 zN>>_rUG0Lhaz`s;GRPklV?0 z;~t4S8M)ZBW-ED?#UNbCrsWb=??P># zVc}MW_f80ygG_o~SW+Q6oeIUdFqV2Fzys*7+vxr^ZDeXcZZc;{kqK;(kR-DKL zByDdPnUQgnX^>x?1Tz~^wZ%Flu}ma$Xmgtc7pSmBIH%&H*Tnm=L-{GzCv^UBIrTH5 zaoPO|&G@SB{-N8Xq<+RVaM_{lHo@X-q}`zjeayVZ9)5&u*Y>1!$(wh9Qoe>yWbPgw zt#=gnjCaT_+$}w^*=pgiHD8N$hzqEuY5iVL_!Diw#>NP7mEd?1I@Io+?=$?7cU=yK zdDKk_(h_dB9A?NX+&=%k8g+?-f&`vhAR}&#zP+iG%;s}kq1~c{ac1@tfK4jP65Z&O zXj8Ew>l7c|PMp!cT|&;o+(3+)-|SK&0EVU-0-c&guW?6F$S`=hcKi zpx{Z)UJcyihmN;^E?*;fxjE3kLN4|&X?H&$md+Ege&9en#nUe=m>ep3VW#C?0V=aS zLhL6v)|%$G5AO4x?Jxy8e+?*)YR~<|-qrKO7k7`jlxpl6l5H&!C4sePiVjAT#)b#h zEwhfkpFN9eY%EAqg-h&%N>E0#%`InXY?sHyptcct{roG42Mli5l)sWt66D_nG2ed@ z#4>jF?sor7ME^`pDlPyQ(|?KL9Q88;+$C&3h*UV*B+*g$L<{yT9NG>;C^ZmPbVe(a z09K^qVO2agL`Hy{ISUJ{khPKh@5-)UG|S8Sg%xbJMF)wawbgll3bxk#^WRqmdY7qv zr_bqa3{`}CCbREypKd!>oIh^IUj4yl1I55=^}2mZAAW6z}Kpt3_o1b4__sQ;b zv)1=xHO?gE-1FL}Y$0YdD-N!US;VSH>UXnyKoAS??;T%tya@-u zfFo)@YA&Q#Q^?Mtam19`(PS*DL{PHjEZa(~LV7DNt5yoo1(;KT)?C7%^Mg;F!C)q= z6$>`--hQX4r?!aPEXn;L*bykF1r8JVDZ)x4aykACQy(5~POL;InZPU&s5aZm-w1L< z`crCS5=x>k_88n(*?zn=^w*;0+8>ui2i>t*Kr!4?aA1`yj*GXi#>$h8@#P{S)%8+N zCBeL6%!Ob1YJs5+a*yh{vZ8jH>5qpZhz_>(ph}ozKy9d#>gba1x3}`-s_zi+SqIeR z0NCd7B_Z|Fl+(r$W~l@xbeAPl5{uJ{`chq}Q;y8oUN0sUr4g@1XLZQ31z9h(fE_y( z_iQ(KB39LWd;qwPIzkvNNkL(P(6{Iu{)!#HvBlsbm`g2qy&cTsOsAbwMYOEw8!+75D!>V{9SZ?IP@pR9sFG{T#R*6ez2&BmP8*m^6+H2_ z>%9pg(+R^)*(S21iHjLmdt$fmq6y!B9L!%+;wL5WHc^MZRNjpL9EqbBMaMns2F(@h zN0BEqZ3EWGLjvY&I!8@-WV-o@>biD;nx;D}8DPapQF5ivpHVim8$G%3JrHtvN~U&) zb1;=o*lGfPq#=9Moe$H_UhQPBjzHuYw;&e!iD^U2veY8)!QX_E(X@3hAlPBIc}HoD z*NH1vvCi5xy@NS41F1Q3=Jkfu&G{Syin^RWwWX|JqUIX_`}l;_UIsj&(AFQ)ST*5$ z{G&KmdZcO;jGIoI^+9dsg{#=v5eRuPO41<*Ym!>=zHAXH#=LdeROU-nzj_@T4xr4M zJI+d{Pp_{r=IPWj&?%wfdyo`DG1~|=ef?>=DR@|vTuc)w{LHqNKVz9`Dc{iCOH;@H5T{ zc<$O&s%k_AhP^gCUT=uzrzlEHI3q`Z3em0*qOrPHpfl1v=8Xkp{!f9d2p!4 zL40+eJB4@5IT=JTTawIA=Z%3AFvv=l1A~JX>r6YUMV7GGLTSaIn-PUw| z;9L`a<)`D@Qs(@P(TlafW&-87mcZuwFxo~bpa01_M9;$>;4QYkMQlFPgmWv!eU8Ut zrV2<(`u-@1BTMc$oA*fX;OvklC1T$vQlZWS@&Wl}d!72MiXjOXxmiL8oq;sP{)oBe zS#i5knjf`OfBl}6l;BSHeY31w8c~8G>$sJ9?^^!)Z*Z*Xg zbTbkcbBpgFui(*n32hX~sC7gz{L?nlnOjJBd@ zUC4gd`o&YB4}!T9JGTe9tqo0M!JnEw4KH7WbrmTRsw^Nf z^>RxG?2A33VG3>E?iN|`G6jgr`wCzKo(#+zlOIzp-^E0W0%^a>zO)&f(Gc93WgnJ2p-%H-xhe{MqmO z8Iacz=Qvx$ML>Lhz$O;3wB(UI{yTk1LJHf+KDL2JPQ6#m%^bo>+kTj4-zQ~*YhcqS z2mOX!N!Q$d+KA^P0`EEA^%>c12X(QI-Z}-;2Rr-0CdCUOZ=7QqaxjZPvR%{pzd21HtcUSU>u1nw?)ZCy+ zAaYQGz59lqhNXR4GYONpUwBU+V&<{z+xA}`Q$fajmR86j$@`MeH}@zz*ZFeBV9Ot< ze8BLzuIIDxM&8=dS!1-hxiAB-x-cVmtpN}JcP^`LE#2r9ti-k8>Jnk{?@Gw>-WhL=v+H!*tv*mcNvtwo)-XpMnV#X>U1F z?HM?tn^zY$6#|(|S~|P!BPp6mur58i)tY=Z-9(pM&QIHq+I5?=itn>u1FkXiehCRC zW_3|MNOU)$-zrjKnU~{^@i9V^OvOJMp@(|iNnQ%|iojG2_Snnt`1Cqx2t)`vW&w2l zwb#`XLNY@FsnC-~O&9|#Lpvw7n!$wL9azSk)$O}?ygN@FEY({2%bTl)@F2wevCv`; zZb{`)uMENiwE|mti*q5U4;4puX{VWFJ#QIaa*%IHKyrU*HtjW_=@!3SlL~pqLRs?L zoqi&}JLsaP)yEH!=_)zmV-^xy!*MCtc{n|d%O zRM>N>eMG*Qi_XAxg@82*#zPe+!!f#;xBxS#6T-$ziegN-`dLm z=tTN|xpfCPng06|X^6_1JgN}dM<_;WsuL9lu#zLVt!0{%%D9*$nT2E>5@F(>Fxi%Y zpLHE%4LZSJ1=_qm0;^Wi%x56}k3h2Atro;!Ey}#g&*BpbNXXS}v>|nn=Mi0O(5?=1V7y1^1Bdt5h3}oL@VsG>NAH z1;5?|Sth=0*>dbXSQ%MQKB?eN$LRu?yBy@qQVaUl*f#p+sLy$Jd>*q;(l>brvNUbIF0OCf zk%Q;Zg!#0w0_#l)!t?3iz~`X8A>Yd3!P&A4Ov6&EdZmOixeTd4J`*Wutura(}4w@KV>i#rf(0PYL&v^89QiXBP6sj=N;q8kVxS}hA! z|3QaiYz!w+xQ%9&Zg${JgQ*Ip_bg2rmmG`JkX^}&5gbZF!Z(gDD1s5{QwarPK(li- zW9y-CiQ`5Ug1ceN1w7lCxl=2}7c*8_XH8W7y0AICn19qZ`w}z0iCJ$tJ}NjzQCH90 zc!UzpKvk%3;`XfFi2;F*q2eMQQ5fzO{!`KU1T^J?Z64|2Z}b1b6h80_H%~J)J)kbM0hsj+FV6%@_~$FjK9OG7lY}YA zRzyYxxy18z<+mCBiX?3Q{h{TrNRkHsyF|eGpLo0fKUQ|19Z0BamMNE9sW z?vq)r`Qge{9wN|ezzW=@ojpVQRwp##Q91F|B5c`a0A{HaIcW>AnqQ*0WT$wj^5sWOC1S;Xw7%)n(=%^in zw#N*+9bpt?0)PY$(vnU9SGSwRS&S!rpd`8xbF<1JmD&6fwyzyUqk){#Q9FxL*Z9%#rF$} zf8SsEkE+i91VY8d>Fap#FBacbS{#V&r0|8bQa;)D($^v2R1GdsQ8YUk(_L2;=DEyN%X*3 z;O@fS(pPLRGatI93mApLsX|H9$VL2)o(?EYqlgZMP{8oDYS8)3G#TWE<(LmZ6X{YA zRdvPLLBTatiUG$g@WK9cZzw%s6TT1Chmw#wQF&&opN6^(D`(5p0~ zNG~fjdyRsZv9Y?UCK(&#Q2XLH5G{{$9Y4vgMDutsefKVVPoS__MiT%qQ#_)3UUe=2fK)*36yXbQUp#E98ah(v`E$c3kAce_8a60#pa7rq6ZRtzSx6=I^-~A|D%>Riv{Y`F9n3CUPL>d`MZdRmBzCum2K%}z@Z(b7#K!-$Hb<+R@Rl9J6<~ z4Wo8!!y~j(!4nYsDtxPIaWKp+I*yY(ib`5Pg356Wa7cmM9sG6alwr7WB4IcAS~H3@ zWmYt|TByC?wY7yODHTyXvay9$7#S?gDlC?aS147Ed7zW!&#q$^E^_1sgB7GKfhhYu zOqe*Rojm~)8(;b!gsRgQZ$vl5mN>^LDgWicjGIcK9x4frI?ZR4Z%l1J=Q$0lSd5a9 z@(o?OxC72<>Gun*Y@Z8sq@od{7GGsf8lnBW^kl6sX|j~UA2$>@^~wtceTt^AtqMIx zO6!N}OC#Bh^qdQV+B=9hrwTj>7HvH1hfOQ{^#nf%e+l)*Kgv$|!kL5od^ka#S)BNT z{F(miX_6#U3+3k;KxPyYXE0*0CfL8;hDj!QHM@)sekF9uyBU$DRZkka4ie^-J2N8w z3PK+HEv7kMnJU1Y+>rheEpHdQ3_aTQkM3`0`tC->mpV=VtvU((Cq$^(S^p=+$P|@} zueLA}Us^NTI83TNI-15}vrC7j6s_S`f6T(BH{6Jj{Lt;`C+)d}vwPGx62x7WXOX19 z2mv1;f^p6cG|M`vfxMhHmZxkkmWHRNyu2PDTEpC(iJhH^af+tl7~h?Y(?qNDa`|Ogv{=+T@7?v344o zvge%8Jw?LRgWr7IFf%{-h>9}xlP}Y#GpP_3XM7FeGT?iN;BN-qzy=B# z=r$79U4rd6o4Zdt=$|I3nYy;WwCb^`%oikowOPGRUJ3IzChrX91DUDng5_KvhiEZwXl^y z+E!`Z6>}ijz5kq$nNM8JA|5gf_(J-);?SAn^N-(q2r6w31sQh6vLYp^ z<>+GyGLUe_6eTzX7soWpw{dDbP-*CsyKVw@I|u`kVX&6_h5m!A5&3#=UbYHYJ5GK& zLcq@0`%1;8KjwLiup&i&u&rmt*LqALkIqxh-)Exk&(V)gh9@Fn+WU=6-UG^X2~*Q-hnQ$;;+<&lRZ>g0I`~yuv!#84 zy>27(l&zrfDI!2PgzQyV*R(YFd`C`YwR_oNY+;|79t{NNMN1@fp?EaNjuM2DKuG%W z5749Br2aU6K|b=g4(IR39R8_!|B`uQ)bun^C9wR4!8isr$;w$VOtYk+1L9#CiJ#F) z)L}>^6>;X~0q&CO>>ZBo0}|Ex9$p*Hor@Ej9&75b&AGqzpGpM^dx}b~E^pPKau2i5 zr#tT^S+01mMm}z480>-WjU#q`6-gw4BJMWmW?+VXBZ#JPzPW5QQm@RM#+zbQMpr>M zX$huprL(A?yhv8Y81K}pTD|Gxs#z=K(Wfh+?#!I$js5u8+}vykZh~NcoLO?ofpg0! zlV4E9BAY_$pN~e-!VETD&@v%7J~_jdtS}<_U<4aRqEBa&LDpc?V;n72lTM?pIVG+> z*5cxz_iD@3vIL5f9HdHov{o()HQ@6<+c}hfC?LkpBEZ4xzMME^~AdB8?2F=#6ff!F740l&v7FN!n_ zoc1%OfX(q}cg4LDk-1%|iZ^=`x5Vs{oJYhXufP;BgVd*&@a04pSek6OS@*UH`*dAp z7wY#70IO^kSqLhoh9!qIj)8t4W6*`Kxy!j%Bi%(HKRtASZ2%vA0#2fZ=fHe0zDg8^ zucp;9(vmuO;Zq9tlNH)GIiPufZlt?}>i|y|haP!l#dn)rvm8raz5L?wKj9wTG znpl>V@};D!M{P!IE>evm)RAn|n=z-3M9m5J+-gkZHZ{L1Syyw|vHpP%hB!tMT+rv8 zIQ=keS*PTV%R7142=?#WHFnEJsTMGeG*h)nCH)GpaTT@|DGBJ6t>3A)XO)=jKPO<# zhkrgZtDV6oMy?rW$|*NdJYo#5?e|Nj>OAvCXHg~!MC4R;Q!W5xcMwX#+vXhI+{ywS zGP-+ZNr-yZmpm-A`e|Li#ehuWB{{ul8gB&6c98(k59I%mMN9MzK}i2s>Ejv_zVmcMsnobQLkp z)jmsJo2dwCR~lcUZs@-?3D6iNa z2k@iM#mvemMo^D1bu5HYpRfz(3k*pW)~jt8UrU&;(FDI5ZLE7&|ApGRFLZa{yynWx zEOzd$N20h|=+;~w$%yg>je{MZ!E4p4x05dc#<3^#{Fa5G4ZQDWh~%MPeu*hO-6}2*)t-`@rBMoz&gn0^@c)N>z|Ikj8|7Uvdf5@ng296rq2LiM#7KrWq{Jc7;oJ@djxbC1s6^OE>R6cuCItGJ? z6AA=5i=$b;RoVo7+GqbqKzFk>QKMOf?`_`!!S!6;PSCI~IkcQ?YGxRh_v86Q%go2) zG=snIC&_n9G^|`+KOc$@QwNE$b7wxBY*;g=K1oJnw8+ZR)ye`1Sn<@P&HZm0wDJV* z=rozX4l;bJROR*PEfHHSmFVY3M#_fw=4b_={0@MP<5k4RCa-ZShp|CIGvW^9$f|BM#Z`=3&=+=p zp%*DC-rEH3N;$A(Z>k_9rDGGj2&WPH|}=Pe3(g}v3=+`$+A=C5PLB3UEGUMk92-erU%0^)5FkU z^Yx#?Gjyt*$W>Os^Fjk-r-eu`{0ZJbhlsOsR;hD=`<~eP6ScQ)%8fEGvJ15u9+M0c|LM4@D(tTx!T(sRv zWg?;1n7&)-y0oXR+eBs9O;54ZKg=9eJ4gryudL84MAMsKwGo$85q6&cz+vi)9Y zvg#u>v&pQQ1NfOhD#L@}NNZe+l_~BQ+(xC1j-+({Cg3_jrZ(YpI{3=0F1GZsf+3&f z#+sRf=v7DVwTcYw;SiNxi5As}hE-Tpt)-2+lBmcAO)8cP55d0MXS*A3yI5A!Hq&IN zzb+)*y8d8WTE~Vm3(pgOzy%VI_e4lBx&hJEVBu!!P|g}j(^!S=rNaJ>H=Ef;;{iS$$0k-N(`n#J_K40VJP^8*3YR2S`* zED;iCzkrz@mP_(>i6ol5pMh!mnhrxM-NYm0gxPF<%(&Az*pqoRTpgaeC!~-qYKZHJ z2!g(qL_+hom-fp$7r=1#mU~Dz?(UFkV|g;&XovHh~^6 z1eq4BcKE%*aMm-a?zrj+p;2t>oJxxMgsmJ^Cm%SwDO?odL%v6fXU869KBEMoC0&x>qebmE%y+W z51;V2xca9B=wtmln74g7LcEgJe1z7o>kwc1W=K1X7WAcW%73eGwExo&{SSTnXR+pA zRL)j$LV7?Djn8{-8CVk94n|P>RAw}F9uvp$bpNz<>Yw3PgWVJo?zFYH9jzq zU|S+$C6I?B?Jm>V{P67c9aRvK283bnM(uikbL=``ew5E)AfV$SR4b8&4mPDkKT&M3 zok(sTB}>Gz%RzD{hz|7(AFjB$@#3&PZFF5_Ay&V3?c&mT8O;9(vSgWdwcy?@L-|`( z@@P4$nXBmVE&Xy(PFGHEl*K;31`*ilik77?w@N11G7IW!eL@1cz~XpM^02Z?CRv1R z5&x6kevgJ5Bh74Q8p(-u#_-3`246@>kY~V4!XlYgz|zMe18m7Vs`0+D!LQwTPzh?a zp?X169uBrRvG3p%4U@q_(*^M`uaNY!T6uoKk@>x(29EcJW_eY@I|Un z*d;^-XTsE{Vjde=Pp3`In(n!ohHxqB%V`0vSVMsYsbjN6}N6NC+Ea`Hhv~yo@ z|Ab%QndSEzidwOqoXCaF-%oZ?SFWn`*`1pjc1OIk2G8qSJ$QdrMzd~dev;uoh z>SneEICV>k}mz6&xMqp=Bs_0AW81D{_hqJXl6ZWPRNm@cC#+pF&w z{{TT0=$yGcqkPQL>NN%!#+tn}4H>ct#L#Jsg_I35#t}p)nNQh>j6(dfd6ng#+}x3^ zEH`G#vyM=;7q#SBQzTc%%Dz~faHJK+H;4xaAXn)7;)d(n*@Bv5cUDNTnM#byv)DTG zaD+~o&c-Z<$c;HIOc!sERIR>*&bsB8V_ldq?_>fT!y4X-UMddUmfumowO!^#*pW$- z_&)moxY0q!ypaJva)>Bc&tDs?D=Rta*Wc^n@uBO%dd+mnsCi0aBZ3W%?tz844FkZD zzhl+RuCVk=9Q#k;8EpXtSmR;sZUa5(o>dt+PBe96@6G}h`2)tAx(WKR4TqXy(YHIT z@feU+no42!!>y5*3Iv$!rn-B_%sKf6f4Y{2UpRgGg*dxU)B@IRQ`b{ncLrg9@Q)n$ zOZ7q3%zL99j1{56$!W(Wu{#m|@(6BBb-*zV23M!PmH7nzOD@~);0aK^iixd%>#BwR zyIlVF*t4-Ww*IPTGko3RuyJ*^bo-h}wJ{YkHa2y3mIK%U%>PFunkx0#EeIm{u93PX z4L24jUh+37=~WR47l=ug2cn_}7CLR(kWaIpH8ojFsD}GN3G}v6fI-IMK2sXnpgS5O zHt<|^d9q}_znrbP0~zxoJ-hh6o81y+N;i@6M8%S@#UT)#aKPYdm-xlbL@v*`|^%VS(M$ zMQqxcVVEKe5s~61T77N=9x7ndQ=dzWp^+#cX}v`1bbnH@&{k?%I%zUPTDB(DCWY6( zR`%eblFFkL&C{Q}T6PTF0@lW0JViFzz4s5Qt?P?wep8G8+z3QFAJ{Q8 z9J41|iAs{Um!2i{R7&sV=ESh*k(9`2MM2U#EXF4!WGl(6lI!mg_V%pRenG>dEhJug z^oLZ?bErlIPc@Jo&#@jy@~D<3Xo%x$)(5Si@~}ORyawQ{z^mzNSa$nwLYTh6E%!w_ zUe?c`JJ&RqFh1h18}LE47$L1AwR#xAny*v9NWjK$&6(=e0)H_v^+ZIJ{iVg^e_K-I z|L;t=x>(vU{1+G+P5=i7QzubN=dWIe(bqeBJ2fX85qrBYh5pj*f05=8WxcP7do(_h zkfEQ1Fhf^}%V~vr>ed9*Z2aL&OaYSRhJQFWHtirwJFFkfJdT$gZo;aq70{}E#rx((U`7NMIb~uf>{Y@Fy@-kmo{)ei*VjvpSH7AU zQG&3Eol$C{Upe`034cH43cD*~Fgt?^0R|)r(uoq3ZjaJqfj@tiI~`dQnxfcQIY8o| zx?Ye>NWZK8L1(kkb1S9^8Z8O_(anGZY+b+@QY;|DoLc>{O|aq(@x2=s^G<9MAhc~H z+C1ib(J*&#`+Lg;GpaQ^sWw~f&#%lNQ~GO}O<5{cJ@iXSW4#};tQz2#pIfu71!rQ( z4kCuX$!&s;)cMU9hv?R)rQE?_vV6Kg?&KyIEObikO?6Nay}u#c#`ywL(|Y-0_4B_| zZFZ?lHfgURDmYjMmoR8@i&Z@2Gxs;4uH)`pIv#lZ&^!198Fa^Jm;?}TWtz8sulPrL zKbu$b{{4m1$lv0`@ZWKA|0h5U!uIwqUkm{p7gFZ|dl@!5af*zlF% zpT-i|4JMt%M|0c1qZ$s8LIRgm6_V5}6l6_$cFS# z83cqh6K^W(X|r?V{bTQp14v|DQg;&;fZMu?5QbEN|DizzdZSB~$ZB%UAww;P??AT_-JFKAde%=4c z*WK^Iy5_Y`*IZ+cF`jvkCv~Urz3`nP{hF!UT7Z&e;MlB~LBDvL^hy{%; z7t5+&Ik;KwQ5H^i!;(ly8mfp@O>kH67-aW0cAAT~U)M1u`B>fG=Q2uC8k}6}DEV=% z<0n@WaN%dDBTe*&LIe^r-!r&t`a?#mEwYQuwZ69QU3&}7##(|SIP*4@y+}%v^Gb3# zrJ~68hi~77ya4=W-%{<(XErMm>&kvG`{7*$QxRf(jrz|KGXJN3Hs*8BfBx&9|5sZ1 zpFJ1(B%-bD42(%cOiT@2teyYoUBS`L%<(g;$b6nECbs|ADH5$LYxj?i3+2^#L@d{%E(US^chG<>aL7o>Fg~ zW@9wW@Mb&X;BoMz+kUPUcrDQOImm;-%|nxkXJ8xRz|MlPz5zcJHP<+yvqjB4hJAPE zRv>l{lLznW~SOGRU~u77UcOZyR#kuJrIH_){hzx!6NMX z>(OKAFh@s2V;jk|$k5-Q_ufVe;(KCrD}*^oBx{IZq^AB|7z*bH+g_-tkT~8S$bzdU zhbMY*g?Qb;-m|0`&Jm}A8SEI0twaTfXhIc=no}$>)n5^cc)v!C^YmpxLt=|kf%!%f zp5L$?mnzMt!o(fg7V`O^BLyjG=rNa}=$hiZzYo~0IVX$bp^H-hQn!;9JiFAF<3~nt zVhpABVoLWDQ}2vEEF3-?zzUA(yoYw&$YeHB#WGCXkK+YrG=+t0N~!OmTN;fK*k>^! zJW_v+4Q4n2GP7vgBmK;xHg^7zFqyTTfq|0+1^H2lXhn6PpG#TB*``?1STTC#wcaj3 zG~Q9!XHZ#1oPZo zB6h(BVIW5K+S@JG_HctDLHWb;wobZ0h(3xr6(uUspOSK0WoSHeF$ZLw@)cpoIP|kL zu`GnW>gD$rMt}J0qa9kJzn0s`@JNy1Crkb&;ve|()+_%!x%us>1_Xz|BS>9oQeD3O zy#CHX#(q^~`=@_p$XV6N&RG*~oEH$z96b8S16(6wqH)$vPs=ia!(xPVX5o&5OIYQ%E(-QAR1}CnLTIy zgu1MCqL{_wE)gkj0BAezF|AzPJs=8}H2bHAT-Q@Vuff?0GL=)t3hn{$Le?|+{-2N~`HWe24?!1a^UpC~3nK$(yZ_Gp(EzP~a{qe>xK@fN zEETlwEV_%9d1aWU0&?U>p3%4%>t5Pa@kMrL4&S@ zmSn!Dllj>DIO{6w+0^gt{RO_4fDC)f+Iq4?_cU@t8(B^je`$)eOOJh1Xs)5%u3hf; zjw$47aUJ9%1n1pGWTuBfjeBumDI)#nkldRmBPRW|;l|oDBL@cq1A~Zq`dXwO)hZkI zZ=P7a{Azp06yl(!tREU`!JsmXRps!?Z~zar>ix0-1C+}&t)%ist94(Ty$M}ZKn1sDaiZpcoW{q&ns8aWPf$bRkbMdSgG+=2BSRQ6GG_f%Lu#_F z&DxHu+nKZ!GuDhb>_o^vZn&^Sl8KWHRDV;z#6r*1Vp@QUndqwscd3kK;>7H!_nvYH zUl|agIWw_LPRj95F=+Ex$J05p??T9_#uqc|q>SXS&=+;eTYdcOOCJDhz7peuvzKoZhTAj&^RulU`#c?SktERgU|C$~O)>Q^$T8ippom{6Ze0_44rQB@UpR~wB? zPsL@8C)uCKxH7xrDor zeNvVfLLATsB!DD{STl{Fn3}6{tRWwG8*@a2OTysNQz2!b6Q2)r*|tZwIovIK9Ik#- z0k=RUmu97T$+6Lz%WQYdmL*MNII&MI^0WWWGKTTi&~H&*Ay7&^6Bpm!0yoVNlSvkB z;!l3U21sJyqc`dt)82)oXA5p>P_irU*EyG72iH%fEpUkm1K$?1^#-^$$Sb=c8_? zOWxxguW7$&-qzSI=Z{}sRGAqzy3J-%QYz2Cffj6SOU|{CshhHx z6?5L$V_QIUbI)HZ9pwP9S15 zXc%$`dxETq+S3_jrfmi$k=)YO5iUeuQ&uX}rCFvz&ubO?u)tv|^-G_`h$pb+8vn@f z7@eQe#Kx|8^37a4d0GulYIUAW|@I5|NIh%=OqHU{(>(UhKvJ}i_X*>!Geb+Rs0MWf66Lf z-cQ(4QOENSbTX$6w_9w4{5eR?14#?)Jqf2UCk5US4bnz8!e>vFduH6(cZZ=5*_!M# zUTZ_b<4v@}dSQOcH@wt-s;3JhkVDct$6k9!ETdi-tplkaxl^qF=p}Q8KMVm+ zeIa2q?RYr}nM0d_W2YWv%JKyCrGSePj8GrRN)<$Nsq8l$X=>`W;?>0eME3|8t&d$~ zH`XG45lBh>-te_f0Mh0??)=Ee0~zESx=sZPv<#!sAVv$0qTn@CmCUNJU<#=`GC)&P z9zuV~9*3_n2*ZQBUh)2xIi;0yo)9XXJxM-VB*6xpyz{Rx2ZCvFnF$2aPcYFG( zyXkO(B30?mt;5GW&{m^w3?!P`#_o;Y%P2z^A`|4%Bt2@3G?C2dcSPNy1#HMXZ>{+L z3BE#xvqR@Ub}uKfzGC=RO|W%dJpUK#m8p&Dk|6Ub8S+dN3qxf9dJ_|WFdM9CSNQv~ zjaFxIX`xx-($#Fq+EI76uB@kK=B4FS0k=9(c8UQnr(nLQxa2qWbuJyD7%`zuqH|eF zNrpM@SIBy@lKb%*$uLeRJQ->ko3yaG~8&}9|f z*KE`oMHQ(HdHlb&)jIzj5~&z8r}w?IM1KSdR=|GFYzDwbn8-uUfu+^h?80e*-9h%Nr;@)Q-TI#dN1V zQPT2;!Wk)DP`kiY<{o7*{on%It(j0&qSv=fNfg3qeNjT@CW{WT<)1Eig!g9lAGx6& zk9_Zrp2I+w_f!LRFsgxKA}gO=xSPSY``kn=c~orU4+0|^K762LWuk_~oK{!-4N8p8 zUDVu0ZhvoD0fN8!3RD~9Bz5GNEn%0~#+E-Js}NTBX;JXE@29MdGln$Aoa3Nzd@%Z= z^zuGY4xk?r(ax7i4RfxA?IPe27s87(e-2Z_KJ(~YI!7bhMQvfN4QX{!68nj@lz^-& z1Zwf=V5ir;j*30AT$nKSfB;K9(inDFwbI^%ohwEDOglz}2l}0!#LsdS3IW43= zBR#E@135bu#VExrtj?)RH^PM(K4B`d=Z6^kix`8$C1&q)w1<&?bAS?70}9fZwZU7R z5RYFo?2Q>e3RW2dl&3E^!&twE<~Lk+apY?#4PM5GWJb2xuWyZs6aAH-9gqg${<1?M zoK&n+$ZyGIi=hakHqRu{^8T4h@$xl?9OM46t;~1_mPs9}jV58E-sp!_CPH4<^A|Q5 zedUHmiyxTc2zgdxU?4PyQ{ON@r+Ucn1kjWSOsh6WzLV~Bv&vWLaj#Xz4VSDs*F#@M>#e^ixNCQ-J|iC=LcB*M4WUb>?v6C z14^8h9Ktd1>XhO$kb-rRL}SFTH)kSu+Dwds$oed7qL)Jbd zhQys4$Uw~yj03)6Kq+K-BsEDftLgjDZk@qLjAyrb5UMeuO^>D43g%0GoKJ~TO0o!D z9E$WfxEDFTT?~sT?|!7aYY*mpt`}i;WTgY|Cb4{Cscrmzb(?UE+nz1wC3#QSjbg>N zleu?7MGaQ&FtejK#?07Uq$vIZX5FqR*a=(zUm`Fq$VUl){GQ{2MA)_j4H$U8FZ`=A z&GU_an)?g%ULunbBq4EUT7uT=vI6~uapKC|H6uz1#Rqt$G(!hE7|c8_#JH%wp9+F? zX`ZigNe9GzC(|Nr8GlmwPre3*Nfu+ zF=SHtv_g@vvoVpev$Jxs|F7CH`X5#HAI=ke(>G6DQQ=h^U8>*J=t5Z3Fi>eH9}1|6 znwv3k>D=kufcp= zAyK#v05qERJxS_ts79QVns}M?sIf(hCO0Q9hKe49a@PzvqzZXTAde6a)iZLw|8V-) ziK`-s)d(oQSejO?eJki$UtP0ped)5T1b)uVFQJq*`7w8liL4TX*#K`hdS!pY9aLD+ zLt=c$c_wt^$Wp~N^!_nT(HiDVibxyq2oM^dw-jC~+3m-#=n!`h^8JYkDTP2fqcVC& zA`VWy*eJC$Eo7qIe@KK;HyTYo0c{Po-_yp=>J(1h#)aH5nV8WGT(oSP)LPgusH%N$?o%U%2I@Ftso10xd z)Tx(jT_vrmTQJDx0QI%9BRI1i!wMNy(LzFXM_wucgJGRBUefc413a9+)}~*UzvNI{KL# z_t4U&srNV|0+ZqwL(<}<%8QtjUD8kSB&p$v^y}vuEC2wyW{aXp2{LTi$EBEHjVnS# z+4=G$GUllsjw&hTbh6z%D2j=cG>gkNVlh|24QUfD*-x9OMzTO93n*pE(U7Vz7BaL% z@(c!GbEjK~fH}sqbB1JNI!~b+AYb5le<-qxDA9&r2o)|epl9@5Ya7}yVkcM)yW6KY7QOX_0-N=)+M!A$NpG? z6BvZ8Tb}Pw(i9f7S00=KbWmNvJGL(-MsAz3@aR~PM$Z>t)%AiCZu?A|?P*~UdhhFT`;Nb)MxIg*0QlkYVX+46( zSd%WoWR@kYToK7)(J=#qUD-ss;4M&27w#03y6$gk6X<-VL8AJM@NFTx#Z!n)F5T357%njjKyjro(yW8ceP{!%;*Y>DN`&_18p(z2Hg$%K zohbgJcp%+ux%q6F?(sc_mYJ<$;DxgkTEi?yjT6Du@+n(KsKtFHcO%7O z=AsfLSTdE2>7a@0^`;)?Fg|s2XOPV&fo<%Q)Izaw4s&RvrX0^+aPNq|yE?oSa7 zsnNs!+vGcTM4yM|$9so*2Nv;ngDD}b0MjH6i4e|l^O`lzCRj)-qa6f%|afJpmf(S1J2k7Nt^!;Q}0 z4ejPF?^M~Sv+@LYn&IFUk2;1h?kb8lfrT`oMm=JBm{fo5N|HY~yQQ`T*e2?!tF%*t zf+ncx15$NdF82GXrpP5rJ7!PVE3>u`ME$9Hw5RlP zUh+s#pg{9kEOsAhvu2pry#@dvbB3Lti+9VkLxPZSl;fNr9}wv1cTahUw_Py7%Xp;C zaz__|kz*ydKiYbsqK{?cXhqR(!1KMoV-+!mz>3S8S`Va4kD#(aKyqecGXB^nF*>mS z1gG>fKZc?R~Tye>%x+43D8=e zf0eKr-)>VEu7^I{%T}BT-WaGXO3+x<2w2jwnXePdc2#BdofU6wbE)ZWHsyj=_NT3o z)kySji#CTEnx8*-n=88Ld+TuNy;x$+vDpZ)=XwCr_Gx-+N=;=LCE7CqKX9 zQ-0{jIr zktqqWCgBa3PYK*qQqd=BO70DfM#|JvuW*0%zmTE{mBI$55J=Y2b2UoZ)Yk z3M%rrX7!nwk#@CXTr5=J__(3cI-8~*MC+>R);Z)0Zkj2kpsifdJeH)2uhA|9^B;S$ z4lT3;_fF@g%#qFotZ#|r-IB*zSo;fokxbsmMrfNfJEU&&TF%|!+YuN=#8jFS4^f*m zazCA-2krJ-;Tkufh!-urx#z*imYo|n6+NDGT#*EH355(vRfrGnr*x z5PWMD7>3IwEh=lO^V>O>iLP~S!GjrvI5lx<7oOg(d;6uEFqo5>IwptBQz;`>zx`n$ zjZQ#Hb)qJdQy#ML&qcfmb$KT+f_1#uYNo7HHDY}7xAw8qbl;9LWO-cndfI=5$%jBw zb}K3U%88Fg^|&0Vc~99bKl|$3JzdawRZ|`7%1S<8B7>9*rWAT0U<@mHDfnL1`~1U| zDw7m@<@}C|zqeHM(OK@di6~sKHiJvk^I0^S<LBe^_xZsUOzVkYSE)Bxn*NekQYbyTn5SRt!n{EseOo-$u)vjM(PV%6cIG3Kv$>dd}HUyXi;_Lv>}OyUj38dPe8+1Pr?{LXnIBCoTnocD60@vhsz+GG5lJB9ncgP8T6@LwuzZ)J zKETBS~AvzGE!{u^+Rd-|Gn!rc@UUnioP0{@_j_>tg8YI#?y zL-H$=&xXkCJ2Qe7&exbI!z`OyPxBp|4_ zZrrc;OAb%T4Ze%7E}FBB`8t$QN0sA3vpwU>?7QAmE%-ethXdCtby$Qm3v$lNxB2a7 ze6F5eEWV`={#W(G)Va}7?$D65WF|f0nmfZT;?=LE6Yz{{W3CV2h^Ma+LXdZ(HMVKZ z!YXJ*34lo!FA>)jSo@*!Hs_)IwmTo6pBr3c^j2u_amZ~g;&Z2jZIw!}v@w8DtZz7|A%rFksD4^HYB!xFAqX;u0HxPeG!3Z(z z4}+^N5-nckKf2YSR5R_}PD+2?Wq#BOiON74#{`u=4f59WKdy_77EYq~_|X6cNtno{ zZ?WLwbV57Z6uI|uY_;vzv~~`eiiOl($Au7C*X<&MY5v0b`KEu-GW}{2UNfmmrP!^Y zAOczy!}TIJsom=}kxH)9W`&Rp&rR6T7y&~5nXbut;wcs@M?aa^9j{ZDtx=1?P8TV{ zee2kKf%CE$mogyKKT=xQQ#)OCl9bjc)}{p2X$}aG`^B0w0yi-rI!d4e-u9uR$kJK3 zhqBG9Wx<-3DFw5olJ6neF@hB;8o(r(GB_;p1i>}cjN`JNEZg-dlxtLL=8~gfLrBy_ z1~bGh{I>_xqh(}?%bCf1U6~K@+N*i}bTi+pUAW)oM0`D*PeJq=S(-|Plxe9OqxBRg zM((r)xkSH@j!8@+=cA4US0fDL&O?W~x=Mlu>7zvHO2sy7D5_7ulP+YMecP~}F0b*K z3oO2j{o&WHd<&UWcyA(&6hvBJv}qUZ!@R<(mwKB^;y3zeE1>LzbDWSkRD1|5MZPx( zxd=&MsQi1eE@@6W+4N`cF?yh!3R5JlAV--&RONWQ#?SbrQ95<@ag>C{jQmGXpQX{) z1dbFg1_`qLxuDZnX#PKfCW*Jl3F&^7@gO&{>Nb8um$VBcF1!AL=N6`A%BFj=`QaPI z+m^`n+{o)KLif;Gt|7aQ(XXRP@x)jJt}s{&S`I3}jPTY>$@W0BD3Oif^ehs~!H7T1FUSWxLS&W;0q6+azjbWn?3!q$ z9qbmdr4H4Y)p^NOACJ^L>u}NS8T0_5hW)G z%Hv}dAqM}d@t;|hf8>+NHHPi*xePsRlqr46njzhiXXZti7i5+GTKcrlxA->OJ9*Pna`02EIA5~(SMV`T@H6F2VtwwP1$tYujbC1^VE$Yd&I`WSwB^1( zT7NP3|85z#R%&wktjwY_i*n_$RRZPM^ota{LPV%*>=>sAv%fn*cnkCIX{^SJRmwZv z!?f@T&D%Lz@*!mNYTGp{J|7)~PR*ib`;l^E)rQw@)Qn0ECnB8W1S_SbLZWdqcmo?V zX5g0_3qhn4TrN27^x#Qdq*4*G1L|)I^b8GuP_8O{p|M`uvZO6McXa>OSQRW|kQTNPZ#Zyj~SZ<`6B)Y+}jxpn+YT>MhZ!Rxyd@rU>N zP>MkDBLX|<)SJaO?Ge=!D>i+Wq&PgneO?ZXUq4IQuTq z+V{ZGkuw77o~o$!b>4ov`6CKJ)$cf=S6%1ZQyYU!kz_qiuNxY2*Bh;K9J6o_YV6xQ znW|>x+#Mymu&wF9P|3wP*(ZjwE+ou|{eFqMv}d_iEyH zQ?NSf3VX+EpbrIKmp|oD-t_rh(D#e)fp)dYbG{=yPj-3-#l+iu7r+~#w|(#wv@G0` z38`Yhf5CznhyDEhD;jzaz7fc8L?(n-m zR#|5hqq#yRoeTm+h^9J42mnB>BY>HSu&&O-Hxo6j!dqck)dGS&odS@Hsk2-*Z~x z0!%{@gT645S5DeF@JZeE$DFl*nJB8Z|JKvs%7d`KjbJ*AsA_=fEZ&V9=*+K{(TF^( ztjjYr(7@fV^tDs9c*#=8)ZRKO17A5Z`8v*)U+?hS>3sEfgh3`#vFO^7n}&&adV?}n zdy&BY1h|I@eBm=l*kqiJn>vNkOH4l$Op5Hw3K_w8lF!6T@-H)S2W|Km#6!-X#NqLJ zsiVDrc%*@I3^Gen$)6O0C_qw;8{aucF;}U^1%YE`?AYTtb`Z$B$vfhcHQF`VCB(Pf z_G#fV*Colv-k!O+=^nDNe(03?m+RTu&28d%>JrrwFNb{ND&?Ad(=DP@voz$usk1|w z&#gTB7F)#*LtY6@pIb(g72*LcnXRlTPQAD?)ZFnB*EsZqxM&Uk_KGXnR{4}K`I6i- zU9}R>tiO0De1Hx=kAy>7O+nKO@kGQEYOai&S9&WTY+flvR?uhI695W-xZnq4aRMh8 zwfp)+KYWVB#r=5AwwlSdM4@x7-R_{2;1iqz2lXL$7iu1>5W*+I)jlkMs>60=LN)Y= zbPw;;%U+%p_&{2Obemh$BLmbpDd31YxJ8#TpH3~3B8QLUMvx1X5Vl48hWSNN*UTlO zQgQyZbmyjGC-s$3tnB z0mfKUu2+_c`ZVvDVwUy#j3W*l^BSXXQ%=r6Z}C73jx8DAk!t7k{dK^udpHIcUejp# zyx}og$Hr+f>9kaZvno*Om`d|VTUce9tHM=R8thoG!a=NT$s;g@n_rAN%cp7nnLuav z6}j56TSSfPL$p#y#!5TVyqa3zTzi7@#IoeR=E6CdS`JrR+@i2DwZ?T*bh+(k5!a)0 zgRdF93z8XJ|5?>hDN!YAW5cK=+BwDLNT_+otd zqC@*{S0hCKZ+TnN*2&qx+WP;ZjHA`yytPcwKl~)uy)sQ}Q*0-&3X|YFYAjmolaciq zxS$r5^fxICetD*Dw78M9leVvhAOZ$=;SP7L!Vs?+0f1h*YCuTXIt03iAf)0=0KEvZ zB69o-zg`0C#hQ>`4`}1g=a~EID(j9HbjJG^tV-zumR-+fahTPveA{%0u2uQwMZ%}5 zwY!|}i0oTd&>^QSRhIKU+cMC#|C3f>|647?v1B(wH)EWb{vuJEJh~!#|J7%=h!x3| zCH6m}wg;>Q&?@5Ct1%n`lj%*>9a52d@wmvE`=aQjtz$sWj3V;fDns5<7d2*``)u1( zh!Ub>!#N0m=Vz1n1=El zwb2IVRw$6NIFRpGyUoM0iqc$IPehcmm7<0s7F*Yv+zq?_%pf*SS~~}s0M`m(rMbx% zi?|Wjr6fJN`_J8&B2$4+V+iO~m>s~Zr2T3Y3HGREFQ%%pEoU0N));AeSVM#gYQ>l} z0`RhgS`R^pJH31YQ~eTeJiI}g$&^|nv{!h?8mJK{{XDt+sG8D`7)$jvM#hjPI(5sS zfFW4s7wao%Lo| z#pJRC?iZOai;57ANs|vm6%}rPlGo}}Aso1t#xJn}%VW@~1WSjh(@JTgM$0x6ZQ)gB zdiox3f>kqGZY}+R<;wlNoWJ8#X-v)1;wRD*ec*wnvsN06Q@cZuD`deT-Bu&G;2fBC z0FE1%pG@{Yo2O87&dE;w???%`9s1gs=3GpM8xx_}=AB$K9y=cD);^iE*p4;T1RU%B zBPr)yqOBX<2}xt%g9qr>;z&|?4vhhw7@$a}Uy2b%_^VdB^VfzrebKUPnq;hliCNU% zVt3R5EHkhN^Pv`REF+npA@#HdCQN9IbQbqSDs^+zt(A6;rLwN+@Em}WrV5vPEo!w^ zSCd3RZ8{7a@d9@|IF&&G%irS7FHle?@49LctrtTt=rP$W)se*#RkFmyf)D1^U6EYI zfh+N?uH?-))O$9zM19VsuGn8?o~5`scXU?!P@_cWP&1U4PQqGus=sQzrX+YvKG%XBL3nt6!&M<#}wqA;Mo(}qrq<1lNkpQD-T#-y>grt|E+JNU) z2j+g+QPcA9VEFc0k;H(hSNOpp$I+!$ z&d&W6kBM9+c{X%vr_X0}tdB5dvEDyk5H2*T(QW8Yz-#tjvF?up=^Kfym``^!&O-X! z@HdfpHn;}_)y$Xjb-5cR$Q#-XdhKpmJG5pl>h*Q2(u*gt_4(>6?kG)%T3*&TT0qI( zL!aR~4HiJiaHlgdNcOQP6xx1f3AWx&8}(NEps|G!cO>J^rE2@&-t#_Jb7GYgnLnML~1ze1D$?~BwbgA^=pr55tC|d7w42vN11_8bS75u z_MRKqE7Xik8fk>6(VE5{qT}6rSzd|o}Zb>*aI*Bwg%ccE$_ytH;g2H z^i3qY!+aE*&s^BMH9TI6GLm&9c`D6)3{-+?2Pon+040Yuv$2(LqV*krKhTg5CHOj* zquacxc1&~=S(O@gR8aI#?R%)meONmw1rub9E2QzeM$pBBm2wbPNR3tab{op53<oFwaUbARdD5jSA_6zmKX7!VicEP1m)rYnk{P- zruRj;4c8S29Rd#Baf|fq_pA^r3K#qRHS;($XNoLI*`puZjM?bA0tH>FDiVc9qR*|3 zGn#nhqxkvqFwRfCB~2yA0pxWapfjCdAem$utuon-`*6}mUP?l%$CE(FjAwL%Oe7GQbu7*+&q>*(cAofJr^gg>xw>hx-SO7Lx2)I} zJ)tV1XKbkE4sS&La#-smSq>S9gBzGLH%v?KVezdGv%Xs}kDJZJi{lDl(FpLZupBta z3iDlkd6LlkRro}+El?GIObw06D%NTXpL{W}Ve*%u#{wTC=+VHS%o`sAez&cYz|Tn` zcK_~pvN%cd^8FlFypCjTjw9@ulLoJ^!QAK*++^wC2~}CFeoY;q6y~r&f^+0>LR6)n z$hSev@GzzGgDc>)#u5_;{T9^5y5I?m=z7=J!eVId8p6R5>NV8)h|bA}#3KUufq4CPGiWYvGj%0=H@Q66);F)#cDMND4 zX|?rg>Bb28q*a!_sgVF(A=OeC&je$C4>$0%yy;Fla-hl(|9Ww4!@Q#E2hpJMMxpQ2L+R;+ZMpS+|j*F`Fh}p)`a_*<`AaeFzNEq^- zlF$7BFKD%p@K+3$Vx%N{QOayKKWU#JOAwXiLO62cA6=|DiDG_Z=ef;f&gQ5-?+Pb+ z)4NsyEZXCdjq5tgDN39V9!6#w25+R1;PD7ss;hFvQn}Hnl3^3h<`ylzJdVEL>|Jj0 zg>=Pscwx&;pWEzMn`ld**$1F-nhqlMuX;G{lWrT<<4$7MZ^*4a2hAMf)3eYiT$lRz&9({j<=%DWIRpgu zoOns@gF}AQ_6Y5RhySg7yMtJcYQap6^hgy{`zX1Zv26q4<)g@t%aIi|-lmcySuRN8*5f*$aEFi8o#kMKRCMnrAY~l`= zez#50^@Qo+6r508>iKfAbbc3JwCnjnmw;~=mlMG`(H8EJz7W6mh@mdinO&)#zHX=| z&|fo@s`;njVkkCMczSnp+TnW8YPU4w2&QmzEh1}orF~KlT=V+`!!rH|PtULCcL!P*m0EaN0Ad2qBw%Gs40jfu=%`N*k@z2-p?&B?Yum-p+h?7(!D^ z&f2Bn_#t!4HM2y^*1GN;U+_x8T$Z2>U9Yx;p_9Qf=ww z2hxO^*{%p9-CwMKz}C4mTi8xvqhivltE|}Kgq5MK@f6tBT&`@RYzsFFi>*eMZ0Z6Y zKBl`GOh!U%C+PXJ|7PF)V*~#8eS80D@v-NL2U&;i62W}k+vJAC+7xF`eq%c0b?{PVTcqiDr%6jLBdkVcTwLJSd313SP)1r=;2`cORbMzrhqZxMWcTWru5-l_H8;f|?{^M%%7>sU zGx2{fX*t;7SewS|NvPR-6F5p(ji7d}CK#%7y}jsPkgj%F5cUbQ?b7uWpYks^|DL*n zau%X$^(%wXMS3c;C4=p*#q>ahmLH5woLsn-YcZP~mH-rGnRyl#KU4MsLu+G3z90+q zM$HCWgZYR`8_I%8)SYuBltP$sN`-6hcjnzhDsVl+Y}yqMN*4MWsJX_6R>Cyw8cHGQ z1>r%vkDxxc#ACA4+-ZO|QBMUz`YHrS{l-*$> zi(n_;4{Gn+d2gn)TA<9) zibWdKJv#s_f5K}vM=d0NaYrd;5A+Fy^=+WgKC`@bS>!P5@K4fzE#VYfMcNdbbvLPY zeR~!f3xU>|pfq-LOsoF=t94x%K!8>#8tR4KQ2G3Yr?Cb98^KL*+G8``rHMpNUN}-T z5HGAkiLh{WR;N$Nk3X_2^3pW=vOFTOb(LS0Wu)0)I{8sZj>}5ZGtD=va-72l&5`L= zhyzBWie2UrC|?(sTcuk$OwvV4oVlxc3ncXPj|cD%%*6(hoKMd5wzPQs^6g)B0xK#d zemOodB7D(!@v!|eYqMfx@M#b+D)PwAuvimOW#13i-xAR5)Ai; zXNX(A@M*y&+TVZI zGHo$F*Ipg~Rnp`KlMNAl2o86}r%Yv9#!O-oo`pe`880;-Y28tR)b4H%nqXXHxN9m0 zI&#!(XhT=T3$WS$)K4#Y=ceN`MsP0v1X{nIoQ14S2^--MnUp21=V3&Uv8|y}^}7Vl zI5tRbOp#?@ay6uncZFE0hg}kt(k%piw^M8;0yynsK_!l~uP??IqzmKJMUqAW^GG{~ z7Fg)Q&zBlp z%Tj8jOUpuR>YHP6zYsX?)aJ`)_pRwu+Tn8I;brOW_`v$u$`$9T)cO*O$j=?mg>dW$ zw=&3=v||fqCr`-$okN*$S9(Nyrs}+Lu#IwDg2xSBz_VfU*?A&26vwv>&>*U_TT7-7 zS~X}fT%9+q(Xvc0qzOG^8gmMcZE9izi5feqvY(aY=%reP+wVZ&cRd`^y6}-gJ&_6n zR%Wdl3vQ4DOt!X9ry7j%=+7pLPdus*@7dZMBo0_WKZPD1(o{=;D> zyc9_WFI3{URv=d6EXcnOG0$(J(R#8Oz$kmuSFQ{-Y20}1027!FkodTU!fouSybwqn zRO-$2BH(w4)$wiPo<1w-4*p=Q0@YKRm^cgiA>~ho)U8^e>SBk*!@xvr0CdvnLHS#CACVuQfgzF>8qV znqf{oO1}RWhiZ3g!Tx9sk!JfLqcP`>Ksx#vZuLg-DC6h4mT!vlU zqw0`0CzZgY!EN0*{sQnDNFn;T<+e_x$zY|n;p0@d^hK*n!S!=#^;P{*D^6~h!T7r6 zoiMxtovMo-dj*{qZPy*c3gaMBEDQDkINU%d8HeBZVlRuzkCId9rx{?L= z-dLlk$w&JX5wn+8`mtqCpKnx+w+$@6DEUI}8P%xN$MEsw%S1-$9PM6r^jP-@?cS<# zhg$wl0X=s3{8EZ2U9(};p{X_b1@jJuGgx`gDK{6MpF|XON_=Rv%-<Ee1cuuy?nl9xVDa~x=+8ppnOQ9 zN$53qi4QQ!co(;f!#YJ8(=Z>_9UF#(QOVjS7T!g2)*Oecrf-R^)tFugBkQsMVNua# zS;1V^#fJS{h+!O+FgS%0=Pd9;lMa0QHn?-n(<0b2$<|@r>fjiyw6u*UoGmU$ayJM@ zfp;c4@{$b*Z_v9?8ZEp{m6Q(mDHW<``n?jg-ZN)Hhvxn*l=O1f*K%{5s77WCt!ugS?*2oG5-Q)JEJd0+W5=doeD$Wh?U$ZRg)K$v8cmQ{hba9jw_mF&X zi-dV?WITgIz!!0uB~jE?(t`&qo{WGyUspX| zc6+F2K4l5$LqxERF#`I&k^^opVIMZjGhsJ^vI0c%kV+|&_k>~}ueTtj;^Dfb@xHs` z)-39elzVA~D~n_aoyBQ1>Qd2!;E!G*pZM&RX`r*y)b`yxvP2;#vM*;CQGPg|gni)} z47`Log3PUyVfdmJ2zvHBhg7T#D-H=myzkeUa$@);WC(yB4k^*$wda3=S-UH5Q1Hx6 zPcGxMP&kXBa+4$s#Sw3-V?mlHj^8&bLpIN~GkYj;!;M!$ZxvtQY4j&Ngz_mxuQRqx zYTbN6epx@-!0jRV5yiSIJ<^mCZ<|;&x2~a)t+(eAVB!1XpCZok*Z2C5P7&>z-Oy?t zf@F(_FLsSrfCus61+Vt~svP%(u<4pzT5{w*0XqfPV%~|=%aq^$=*U+_trGQaoUxbt zBV#Yqx+ULku8yPJs4gGcC?+3iRt_6)Oi0DNLxdb(!n!cup_XUZ3eDe(!DChZ!IG&L?_;T-1GB!R;;Sk;l3Y*JQ!I|l20_f}ZyC;4D7R@6F z>%z~wV;Bj1b(*kp26Ed!Y-OKxNbt3%t))xxOrazWsmwvW;uaSaJ0ou+{01vXvU>_V z6Ha@+;giVaiyg`J8ENQf)Pq>!Nf22>XFHnXTNk84&jp-^YwmlUqnOll8)5mzlO$o! z#fSMwH8Pn+Fy7O5M5#ZGr$cKfaGf8g;XN)<*TrQjMk<}_oRf&b6qZoR38Q{Zxo{V; zby+J_hCZT1>`4~jnQxo|ji%BQ0=BLzC6c!1=B(jS5+fcp%q)JI)=c3{D|=k5;0&c2 zrbRE|qxkNqah2nvextOvjYA{T43n1c6eO7B9DH)tLqB46E7;0xKM=%#wx-*-+*OY{ zQ#7gMStz%I&2&rbo>#T20OD_#g`WYbt9+!MC08%zSMhqMoRk)7VOk%~`sD%(U6zzO zdmSC9@x0GCv2_)umYc5@#%efP0_cu+=f^}k$H9$N_>piA_(5UM_o{++8+Yf8SJ)?C zDd3l=GGm3EEy;&Z6N=+XP@IM0L=uW^ooyYQYyx1vwFR?@U~BAtAqTu%Mi2 zTCQh$K=UZA{P`Cw0I$xAh_f?fq-Goe`7I38{3L8?K3`lRhSAyB)tHT@4c!Y;bJAAS z3u>Q7qx>9SJs4$EB=hxh)u`W5jp?>^g1s_MV7<1zN zXt{FSt?Mt&8aCy67<)b@eg@h0iCW@%+pF-V>p${fyEk6_Gvp|ms{Whi-9eNId?xzZ zm|MI>F;JSuaUnQp#|}k3o&ddCZEeTI608txuU4~7K(wg9 zg%+}(7h2@(%>LI1F*puF(h$ZD`Q+ar!VoVajPY0-XS$>6F_F?sc6Mr7>SL-&{pC;2 zKx@2{@ULz7RCpaKg$iu2rcY+y*~qaPo0}^7T1K$_(NPS<1;V zTj8-xC%WvgDI_YYEG{bySvyO3M>XKY)oXgGG*eB{yDgNQ3s3)A~@n>!O#lNh0! z(-dqW#_z&mMfq#2+u61N`L^({4UoU8wE5`4c}{SGFzKb(BK8hM%cf_zj_HmC48)M& z398ICVJTGzBaz7K{L+Ew=;z^0xA``wbtPs`r+Wrb^_vzzhukq{;A`t&-ktzb zbqy`Z0#D6fdVAiodjF3J+qI*vu#=OCjiL4bIIXEf4?zmN7(H|+<+WfR7@7jrMx7FY z5*0X1enhay-q^M?j}3Pd^|U9(C3#CQU3=hlc~@y9@NQD{UZNfC^5?Cuuuu{ebn_<7 zEzudv*b@QP%)N^5jP;86nQGb<*SOytCM5wmf-=rH#K{Wd$2(X#S$jF}XIxZC1)zir zU2Wq>hIB44nCTqx2x<{_wiVzLSJR}L%P!Y|lFHtA_=bDj=OqvmmSZ}ffuqPge#V-f zZDk|XX0RK}=73LxL`H%OXxK*^I2!fp&kxatErK~&tM3@j1a(Yrq$z)R()i?}p|0^Y zhW&8!IpRA1jJ3e!p66ZY=eBmEA+$A`!%s+{Cz!s$IA`{_Dh0^jt!vn;+Nw}hx019Q z_Wg=#-G-~&@>l=&H~48$L8`LX)!Bcq%(DFa2Loc91u@WcwlHzJwo{cdur>bQ;{fr_ z`rC5QRQ_)`8EadJzz-{K&sUI~>NX>P|c4l)fKS0gkuGe_P ziaQy!%CK(CtAwj-J8&#kyU=G(k%3y`!gS9dU&1xIrGRL|!&aVMEaezUIpopoET~xE zp`%~`LZfn!Lu^+00?>v4UOfM!HeeQoLZP<#o`^9oi69|$0BM?n17R~tGpY)eJiv@$ zTV-~ZZ*}C1J{a}p`>l$Bx8qRBq91;dLdmp84auzmcd|XzJG%I|r z^E-8Tm~jRn_>as(R=@~z3I2E3<=#hXn>A=0`wfOGIxiP)N2%!cG?&^w=E#TR z`lSY@Mm36zu4p3}+S#67MpL$d{gf@dnP%*ZMW=gCXK-%0E(xAC!^+b7hCSMF$m;Rn zCTErbBK#;a)>kHX5}w6PRmnw(!Gy>m_g*2opfklHyx>eb1bu|_lwJdf!ogxhk}X^v zc+^L;F7ta!8+i%6?M}XvQn4b%aOSCpDW+4#JDDG(wvXC*9%9(XBhbv4LX3R5G&(+@ z)nbdivYRQ5pW;9~@YGf{h~Rm(@MfV8Tj&T@EejO6(C#(+z7FVNBR`@j!#wScHM5ki%j+^GykUJ2m zYgpwm;#Q)~LoozUSV($?r3vQ~#ZU_}ggl~J%z*1dYt_^4K6e7o&qs_ORz{km+D+^a zqDdUO)d}|)v9h(Zz3}#DLWyRVCY!=PMCO{=PA)Upb@)1j?c)||l{6&pI=;U#bS#Jk zOOiwVH3FM!SuJDIPnN$|ZKz5fQwHmzn8f^?B+T2ew%~PSE#X_jk`Wu;a{4}9%AHg7 zZm8^bAee$bdpwklIE`$fV15=pI+tgJpll4uQjIM;Q!gvISFc_{@=lUSc-lABE%U?+ zHW$;!NcH1&F;AS~7RH=n<=!NTKnm3t`B@YeL?8d2{WGrmSjG;yBbY*9$N&DT^e?l2 z|1A2482Or7n7KF_TpRn|nmqD}`-=?QJ0z5q$C9Td^sML&aN7OGi+W$uYjDXKJg+0W@S=FoQP2dBI=48|FH>p2mh zFrdu!AwoG$NkvnZp_KT8HEo=RNNJ4IxucGXLr2N*I5Ao>Efb+pNOm9Zw0_7_s|9ac zS6}W##>$W*cBmksip;43p#a4&iTpM)8(gRGekW+AKm5zb)xpUFT>~b+FOH`Zs!$RDgpSCE z>;CL8Uu|EWeR~TvgDX@K=mtReFed;FZ!M2SjzW35i;UqfyemM?rq5yZS#hK5Y~|wt z2#^`Q6$b~uGT_++C3+B~#(oFHdSL&hh`Z8{t5#=ZkoaWVJoLm)3vT_@5HOnZGa;s~ z;4=E`3Eo@=$BxFjS`Iu|8SALB`<#TPTeE%h(dol+#CzJ=Zb&EHpw*=0H*~8x6 z`G`b<@>L2(AS*J!NVp`DN{g!8R#h(~URslf zC8PwGM$5V}+$WcoT*C~*$WmCpS6Gis&sZo|9OfRiwjX$f*&25Gjv6$YPde1smwGw( zb@y=gbl1!8>hm-il3&~zFca0~aJN!?b97+$E>2$Gn$31OR&UnE=Tm= zH44$Dx2HNN1lrCGjfuwo@+(m2j85w-oxre9FopupEV+6HACFyTbt}s-`lCCJ8om5RIE~T#Yg_DWu1u zyAp%jp;3&%D4;CRaR6g=f*ZvPqw2BadP=*ZYy_~CV3@wFx5YA(E8)jfqx z8tjEkMf>msMqi)zaY2fWrMq`lZzZdiMcluc(@(yxK(4hPEFk0~HO3^CUZk3;?Tv3` ze-rjZ8@hBrVPzA$^4hW?<33{d2)h7Jw?$t%V6(C_m+bNhXl9vXCJcBWmMeQoLDm5b zt9|A5pDHY#Y@(rlEo_WzXila!uaZE*WVc`=IM)SSc`#liZ2Wt*~fHgm9uH^ISX2d@)XGZ)_$qnbx6?J<14_=SS(ITs#LPDk03a&%x;bAuGz=P ze^<4p@tD@J|M;88;~IsEOPpB+&3C4!3q;}Kk2tb*WuuE z2u(BE$1(2AwbbBrmU-YLI4>#K((6&QZ~m2Yp;I14x0N8hos}{uoQuMG)Wy?ogaNayqmc&`I=8y6&dPf{Fky#B7 z#F=Xy213s`NFxjKuMqH3+ibWsFRi=QtH*j$9^)Zy8F|^vSmgj~l5<04MiU;BNyAn) zlM+c20Y#%@>WgdY>5kx}H)7*!D~BZJdg8d5iHx|>(jj=!MEmr)-$kH8?A#;DyBone(uz;e^|=9nIwfuWY?yw; zC|H`;8#O$vTPm5AW1Gg-Up&#Ca$<@!JZkAUDbmd*?X}QSA5$(*c+FZ|l+}F%*L1OH z{ck}P=j@=7>6ga#cqzj|ODXHD>ckIBmOd9Fh=~>?C7$uII_3rEX%UKdywsInR~{t- zg|t`~l=L1P_QPkZN53Q>!^A*QDZ zK(f;%VVQo)n1bsy)LWL#?&|wN`hL~Rnxhd3d-bOvlRQAiybH&=i;SlnwP$3P-!%x3^o)t6aoT-zXU}ARq-l^bOW-zg$@b|19Aua zF+k$V!uO;fNwCUEi;6!|5?4_MKtTq}|C`2gXh8EhWP1bTgZ)DqHZ&-x|E2*6Ka!RZ zS5jsHN&IW7%g1yUln@bn$cO!hR2b+`P~1-3dFIx!6EltRa{a z6Z@Y$_ug)~d%u)K$+?LYfc<87}bupdiK(3|m%hiA$Pc>zKNP0hqBj{X*L0rm@j(0s(f>>t{1L0?w#rS+#E)IdBKcF5|Dq-S zZ*-X3x;NeSuOSxS<3Q%uy1zwQ+?Kj&)Ou~-|2+&J{Zi^T=lx9+&+B^K_lQ;hY2H6D zeZ9T!H&;?$+kt+MLCs%i{8QEVi8<(Pft!mFt`}r~k5Y%93jAjQ!fgoD?Zh|Vi~q5A z27G^+_!lc1Zfo3}625-J{(B@p`IW|R4(!c|yX*Pn?*SA0)3iUGUB11uH>ab1{F$$g z|7q4=O#$9cezU54J)`wKI1_%J{14{0Zj0P3wEcKU`%-=?@(1PW+Zs0qGuI`%??IID dD~*3C;60WFKt@K_BOwYX49GZ$DDV2e{|AYb(KrAA literal 61574 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 ScNgau(U?ep-K_E5zy1%ZQTdPn diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index ac57dd15..19a6bdeb 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,7 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-9.2.1-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-9.3.0-bin.zip +networkTimeout=10000 +validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/gradlew b/gradlew index a69d9cb6..adff685a 100755 --- a/gradlew +++ b/gradlew @@ -1,7 +1,7 @@ #!/bin/sh # -# Copyright © 2015-2021 the original authors. +# Copyright © 2015 the original authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -15,6 +15,8 @@ # See the License for the specific language governing permissions and # limitations under the License. # +# SPDX-License-Identifier: Apache-2.0 +# ############################################################################## # @@ -55,7 +57,7 @@ # Darwin, MinGW, and NonStop. # # (3) This script is generated from the Groovy template -# https://github.com/gradle/gradle/blob/master/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt # within the Gradle project. # # You can find Gradle at https://github.com/gradle/gradle/. @@ -80,13 +82,11 @@ do esac done -APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit - -APP_NAME="Gradle" +# This is normally unused +# shellcheck disable=SC2034 APP_BASE_NAME=${0##*/} - -# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' +# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) +APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s\n' "$PWD" ) || exit # Use the maximum available, or set MAX_FD != -1 to use that value. MAX_FD=maximum @@ -114,7 +114,6 @@ case "$( uname )" in #( NONSTOP* ) nonstop=true ;; esac -CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar # Determine the Java command to use to start the JVM. @@ -133,22 +132,29 @@ location of your Java installation." fi else JAVACMD=java - which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + if ! command -v java >/dev/null 2>&1 + then + die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. Please set the JAVA_HOME variable in your environment to match the location of your Java installation." + fi fi # Increase the maximum file descriptors if we can. if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then case $MAX_FD in #( max*) + # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked. + # shellcheck disable=SC2039,SC3045 MAX_FD=$( ulimit -H -n ) || warn "Could not query maximum file descriptor limit" esac case $MAX_FD in #( '' | soft) :;; #( *) + # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked. + # shellcheck disable=SC2039,SC3045 ulimit -n "$MAX_FD" || warn "Could not set maximum file descriptor limit to $MAX_FD" esac @@ -165,7 +171,6 @@ fi # For Cygwin or MSYS, switch paths to Windows format before running java if "$cygwin" || "$msys" ; then APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) - CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) JAVACMD=$( cygpath --unix "$JAVACMD" ) @@ -193,16 +198,19 @@ if "$cygwin" || "$msys" ; then done fi -# Collect all arguments for the java command; -# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of -# shell script including quotes and variable substitutions, so put them in -# double quotes to make sure that they get re-expanded; and -# * put everything else in single quotes, so that it's not re-expanded. + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' + +# Collect all arguments for the java command: +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, +# and any embedded shellness will be escaped. +# * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be +# treated as '${Hostname}' itself on the command line. set -- \ "-Dorg.gradle.appname=$APP_BASE_NAME" \ - -classpath "$CLASSPATH" \ - org.gradle.wrapper.GradleWrapperMain \ + -jar "$APP_HOME/gradle/wrapper/gradle-wrapper.jar" \ "$@" # Stop when "xargs" is not available. diff --git a/gradlew.bat b/gradlew.bat index 53a6b238..e509b2dd 100644 --- a/gradlew.bat +++ b/gradlew.bat @@ -13,6 +13,8 @@ @rem See the License for the specific language governing permissions and @rem limitations under the License. @rem +@rem SPDX-License-Identifier: Apache-2.0 +@rem @if "%DEBUG%"=="" @echo off @rem ########################################################################## @@ -26,6 +28,7 @@ if "%OS%"=="Windows_NT" setlocal set DIRNAME=%~dp0 if "%DIRNAME%"=="" set DIRNAME=. +@rem This is normally unused set APP_BASE_NAME=%~n0 set APP_HOME=%DIRNAME% @@ -42,11 +45,11 @@ set JAVA_EXE=java.exe %JAVA_EXE% -version >NUL 2>&1 if %ERRORLEVEL% equ 0 goto execute -echo. -echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. +echo. 1>&2 +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2 +echo. 1>&2 +echo Please set the JAVA_HOME variable in your environment to match the 1>&2 +echo location of your Java installation. 1>&2 goto fail @@ -56,22 +59,21 @@ set JAVA_EXE=%JAVA_HOME%/bin/java.exe if exist "%JAVA_EXE%" goto execute -echo. -echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. +echo. 1>&2 +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2 +echo. 1>&2 +echo Please set the JAVA_HOME variable in your environment to match the 1>&2 +echo location of your Java installation. 1>&2 goto fail :execute @rem Setup the command line -set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar @rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %* :end @rem End local scope for the variables with windows NT shell diff --git a/guides/gRPC.md b/guides/gRPC.md index 5030dd39..0e8bdb4f 100644 --- a/guides/gRPC.md +++ b/guides/gRPC.md @@ -56,11 +56,11 @@ Add the spring-boot-starter artifact coordinates to your project. ```xml no.entur.logging.cloud - spring-boot-starter-gcp-grpc-ecosystem + spring-boot-starter-gcp-grpc-spring no.entur.logging.cloud - spring-boot-starter-gcp-grpc-ecosystem-test + spring-boot-starter-gcp-grpc-spring-test test ``` @@ -73,8 +73,8 @@ or

Gradle Spring Boot Starter coordinates ```groovy -implementation ("no.entur.logging.cloud:spring-boot-starter-gcp-grpc-ecosystem") -testImplementation ("no.entur.logging.cloud:spring-boot-starter-gcp-grpc-ecosystem-test") +implementation ("no.entur.logging.cloud:spring-boot-starter-gcp-grpc-spring") +testImplementation ("no.entur.logging.cloud:spring-boot-starter-gcp-grpc-spring-test") ``` @@ -114,11 +114,11 @@ Import the request-response Spring Boot starters: ```xml no.entur.logging.cloud - request-response-spring-boot-starter-gcp-grpc-ecosystem + request-response-spring-boot-starter-gcp-grpc-spring no.entur.logging.cloud - request-response-spring-boot-starter-gcp-grpc-ecosystem-test + request-response-spring-boot-starter-gcp-grpc-spring-test test ``` @@ -131,8 +131,8 @@ or Gradle Spring Boot Starter coordinates ```groovy -implementation ("no.entur.logging.cloud:request-response-spring-boot-starter-gcp-grpc-ecosystem") -testImplementation ("no.entur.logging.cloud:request-response-spring-boot-starter-gcp-grpc-ecosystem-test") +implementation ("no.entur.logging.cloud:request-response-spring-boot-starter-gcp-grpc-spring") +testImplementation ("no.entur.logging.cloud:request-response-spring-boot-starter-gcp-grpc-spring-test") ``` @@ -227,8 +227,8 @@ For 'classic' one-line log output when running a server locally, additionally ad ```groovy tasks.register("logPlainly") { dependencies { - implementation("no.entur.logging.cloud:request-response-spring-boot-starter-gcp-grpc-ecosystem-test") - implementation("no.entur.logging.cloud:spring-boot-starter-gcp-grpc-ecosystem-test") + implementation("no.entur.logging.cloud:request-response-spring-boot-starter-gcp-grpc-spring-test") + implementation("no.entur.logging.cloud:spring-boot-starter-gcp-grpc-spring-test") } } diff --git a/micrometer/src/main/java/no/entur/logging/cloud/micrometer/DevOpsLogbackMetrics.java b/micrometer/src/main/java/no/entur/logging/cloud/micrometer/DevOpsLogbackMetrics.java index 88de678f..5c9647a8 100644 --- a/micrometer/src/main/java/no/entur/logging/cloud/micrometer/DevOpsLogbackMetrics.java +++ b/micrometer/src/main/java/no/entur/logging/cloud/micrometer/DevOpsLogbackMetrics.java @@ -2,8 +2,6 @@ import ch.qos.logback.classic.LoggerContext; import io.micrometer.core.instrument.MeterRegistry; -import io.micrometer.core.lang.NonNullApi; -import io.micrometer.core.lang.NonNullFields; import org.slf4j.LoggerFactory; import java.util.Map; @@ -15,8 +13,6 @@ * Logback driver with extra log levels. Originally copied from LogbackMetrics class in micrometer-core. * */ -@NonNullApi -@NonNullFields public class DevOpsLogbackMetrics extends io.micrometer.core.instrument.binder.logging.LogbackMetrics { // extend since there is no interface type private final LoggerContext loggerContext; private final Map metricsTurboFilters = new ConcurrentHashMap<>(); diff --git a/micrometer/src/main/java/no/entur/logging/cloud/micrometer/DevOpsMetricsTurboFilter.java b/micrometer/src/main/java/no/entur/logging/cloud/micrometer/DevOpsMetricsTurboFilter.java index 577184c2..eac24328 100644 --- a/micrometer/src/main/java/no/entur/logging/cloud/micrometer/DevOpsMetricsTurboFilter.java +++ b/micrometer/src/main/java/no/entur/logging/cloud/micrometer/DevOpsMetricsTurboFilter.java @@ -8,16 +8,12 @@ import io.micrometer.core.instrument.Counter; import io.micrometer.core.instrument.MeterRegistry; import io.micrometer.core.instrument.Tag; -import io.micrometer.core.lang.NonNullApi; -import io.micrometer.core.lang.NonNullFields; import no.entur.logging.cloud.api.DevOpsLevel; import no.entur.logging.cloud.api.DevOpsMarker; import org.slf4j.Marker; import java.util.List; -@NonNullApi -@NonNullFields public class DevOpsMetricsTurboFilter extends TurboFilter implements LoggingEventMetrics { protected final Counter errorWakeMeUpRightNowCounter; diff --git a/on-demand/on-demand-spring-boot-starter-web/src/main/java/no/entur/logging/cloud/spring/ondemand/web/GcpWebOndemandLoggingAutoConfiguration.java b/on-demand/on-demand-spring-boot-starter-web/src/main/java/no/entur/logging/cloud/spring/ondemand/web/GcpWebOndemandLoggingAutoConfiguration.java index a675e01d..5834f2d2 100644 --- a/on-demand/on-demand-spring-boot-starter-web/src/main/java/no/entur/logging/cloud/spring/ondemand/web/GcpWebOndemandLoggingAutoConfiguration.java +++ b/on-demand/on-demand-spring-boot-starter-web/src/main/java/no/entur/logging/cloud/spring/ondemand/web/GcpWebOndemandLoggingAutoConfiguration.java @@ -23,7 +23,7 @@ import org.springframework.boot.web.servlet.FilterRegistrationBean; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; -import org.springframework.security.web.util.matcher.AntPathRequestMatcher; +import org.springframework.security.web.servlet.util.matcher.PathPatternRequestMatcher; import org.springframework.security.web.util.matcher.RequestMatcher; import java.time.Duration; @@ -86,7 +86,7 @@ public FilterRegistrationBean ondemandFilter() { continue; } HttpLoggingScopeFilter filter = toFilter(path.getMatcher(), path.getSuccess(), path.getFailure(), path.getTroubleshoot()); - RequestMatcher requestMatcher = AntPathRequestMatcher.antMatcher(path.getMatcher()); + RequestMatcher requestMatcher = PathPatternRequestMatcher.pathPattern(path.getMatcher()); filters.addFilter(requestMatcher, filter); } diff --git a/request-response/logbook-filter/build.gradle b/request-response/logbook-filter/build.gradle index c67351c8..9b21417e 100644 --- a/request-response/logbook-filter/build.gradle +++ b/request-response/logbook-filter/build.gradle @@ -4,8 +4,8 @@ dependencies { api("org.zalando:logbook-api:${logbookVersion}") api("org.zalando:logbook-api:${logbookVersion}") - api("com.fasterxml.jackson.core:jackson-core") - api("com.fasterxml.jackson.core:jackson-databind") + api("tools.jackson.core:jackson-core") + api("tools.jackson.core:jackson-databind") api "commons-io:commons-io:${commonsIoVersion}" // JUnit Jupiter API and TestEngine implementation diff --git a/request-response/logbook-filter/src/main/java/no/entur/logging/cloud/logbook/filter/JsonMaxBodySizeFilter.java b/request-response/logbook-filter/src/main/java/no/entur/logging/cloud/logbook/filter/JsonMaxBodySizeFilter.java index 468b25a0..91e570a3 100644 --- a/request-response/logbook-filter/src/main/java/no/entur/logging/cloud/logbook/filter/JsonMaxBodySizeFilter.java +++ b/request-response/logbook-filter/src/main/java/no/entur/logging/cloud/logbook/filter/JsonMaxBodySizeFilter.java @@ -1,14 +1,13 @@ package no.entur.logging.cloud.logbook.filter; -import com.fasterxml.jackson.core.JsonFactory; -import com.fasterxml.jackson.core.JsonGenerator; -import com.fasterxml.jackson.core.JsonParser; -import com.fasterxml.jackson.core.JsonStreamContext; -import com.fasterxml.jackson.core.JsonToken; -import com.fasterxml.jackson.databind.MappingJsonFactory; +import tools.jackson.core.JsonGenerator; +import tools.jackson.core.JsonParser; +import tools.jackson.core.JsonToken; import org.apache.commons.io.output.StringBuilderWriter; import org.zalando.logbook.BodyFilter; import org.zalando.logbook.ContentType; +import tools.jackson.core.TokenStreamContext; +import tools.jackson.databind.json.JsonMapper; import java.io.IOException; import java.util.function.LongSupplier; @@ -28,11 +27,11 @@ public static JsonMaxBodySizeFilter newInstance(int maxBodySize) { return new JsonMaxBodySizeFilter(maxBodySize); } - private JsonFactory factory; + private JsonMapper mapper; public JsonMaxBodySizeFilter(int maxBodySize) { this.maxBodySize = maxBodySize; - this.factory = new MappingJsonFactory(); + this.mapper = JsonMapper.builder().build(); } @Override @@ -44,11 +43,11 @@ public String filter(final String body) { if(body.length() > maxBodySize) { StringBuilder output = new StringBuilder(maxBodySize); try ( - final JsonParser parser = factory.createParser(body); + final JsonParser parser = mapper.createParser(body); StringBuilderWriter writer = new StringBuilderWriter(maxBodySize + 128); - JsonGenerator generator = factory.createGenerator(writer); + JsonGenerator generator = mapper.createGenerator(writer); ) { - process(parser, generator, () -> generator.getOutputBuffered() + output.length()); + process(parser, generator, () -> generator.streamWriteOutputBuffered() + output.length()); generator.flush(); return writer.toString(); @@ -75,7 +74,7 @@ public void process(final JsonParser parser, JsonGenerator generator, LongSuppli if(nextToken == null) { break; } - if(nextToken == JsonToken.FIELD_NAME) { + if(nextToken == JsonToken.PROPERTY_NAME) { fieldName = parser.currentName(); continue; @@ -101,11 +100,11 @@ public void process(final JsonParser parser, JsonGenerator generator, LongSuppli if(outputSize + size >= maxSize) { // write notification - JsonStreamContext ctxt = generator.getOutputContext(); + TokenStreamContext ctxt = generator.streamWriteContext(); if (ctxt.inArray()) { generator.writeString("Logger: " + message); } else if (ctxt.inObject()) { - generator.writeStringField("Logger", message); + generator.writeStringProperty("Logger", message); } generator.close(); @@ -114,7 +113,7 @@ public void process(final JsonParser parser, JsonGenerator generator, LongSuppli } if(fieldName != null) { - generator.writeFieldName(fieldName); + generator.writeName(fieldName); fieldName = null; } diff --git a/request-response/logbook-filter/src/main/java/no/entur/logging/cloud/logbook/filter/JsonMaxValueLengthBodyFilter.java b/request-response/logbook-filter/src/main/java/no/entur/logging/cloud/logbook/filter/JsonMaxValueLengthBodyFilter.java index a253d4da..697ae980 100644 --- a/request-response/logbook-filter/src/main/java/no/entur/logging/cloud/logbook/filter/JsonMaxValueLengthBodyFilter.java +++ b/request-response/logbook-filter/src/main/java/no/entur/logging/cloud/logbook/filter/JsonMaxValueLengthBodyFilter.java @@ -1,13 +1,11 @@ package no.entur.logging.cloud.logbook.filter; -import com.fasterxml.jackson.core.JsonFactory; -import com.fasterxml.jackson.core.JsonGenerator; -import com.fasterxml.jackson.core.JsonParser; -import com.fasterxml.jackson.core.JsonToken; -import com.fasterxml.jackson.databind.MappingJsonFactory; -import com.fasterxml.jackson.databind.ObjectMapper; +import tools.jackson.core.JsonGenerator; import org.zalando.logbook.BodyFilter; import org.zalando.logbook.ContentType; +import tools.jackson.core.JsonParser; +import tools.jackson.core.JsonToken; +import tools.jackson.databind.json.JsonMapper; import java.io.StringWriter; import java.util.function.Predicate; @@ -26,11 +24,11 @@ public static JsonMaxValueLengthBodyFilter newInstance(int maxFieldLength) { return new JsonMaxValueLengthBodyFilter(maxFieldLength); } - private JsonFactory factory; + private JsonMapper mapper; public JsonMaxValueLengthBodyFilter(int maxFieldLength) { this.maxFieldLength = maxFieldLength; - this.factory = new MappingJsonFactory(); + this.mapper = JsonMapper.builder().build(); } @Override @@ -40,9 +38,9 @@ public String filter(String contentType, String body) { public String filter(final String body) { try ( - final JsonParser parser = factory.createParser(body); + final JsonParser parser = mapper.createParser(body); StringWriter writer = new StringWriter(body.length()); - JsonGenerator generator = factory.createGenerator(writer); + JsonGenerator generator = mapper.createGenerator(writer); ) { JsonToken nextToken; @@ -50,9 +48,9 @@ public String filter(final String body) { if (nextToken == JsonToken.VALUE_STRING) { String valueAsString = parser.getValueAsString(); if(valueAsString.length() > maxFieldLength) { - generator.writeObject(valueAsString.substring(0, maxFieldLength)+"[filtered by logger]"); + generator.writePOJO(valueAsString.substring(0, maxFieldLength)+"[filtered by logger]"); } else { - generator.writeObject(valueAsString); + generator.writePOJO(valueAsString); } } else { diff --git a/request-response/logbook-spring-boot-autoconfigure-test/src/main/java/no/entur/logging/cloud/spring/logbook/test/LogbookLoggingTestAutoConfiguration.java b/request-response/logbook-spring-boot-autoconfigure-test/src/main/java/no/entur/logging/cloud/spring/logbook/test/LogbookLoggingTestAutoConfiguration.java index ede22c88..05844513 100644 --- a/request-response/logbook-spring-boot-autoconfigure-test/src/main/java/no/entur/logging/cloud/spring/logbook/test/LogbookLoggingTestAutoConfiguration.java +++ b/request-response/logbook-spring-boot-autoconfigure-test/src/main/java/no/entur/logging/cloud/spring/logbook/test/LogbookLoggingTestAutoConfiguration.java @@ -1,7 +1,5 @@ package no.entur.logging.cloud.spring.logbook.test; -import org.entur.jackson.jsh.AnsiSyntaxHighlight; -import org.entur.jackson.jsh.DefaultSyntaxHighlighter; import no.entur.logging.cloud.logbook.RemoteHttpMessageContextSupplier; import no.entur.logging.cloud.logbook.ondemand.state.RequestHttpMessageStateSupplierSource; import no.entur.logging.cloud.logbook.ondemand.state.ResponseHttpMessageStateSupplierSource; @@ -11,6 +9,8 @@ import no.entur.logging.cloud.logbook.logbook.test.ondemand.PrettyPrintingOndemandLogLevelLogstashLogbackSink; import no.entur.logging.cloud.spring.logbook.AbstractLogbookLoggingAutoConfiguration; import no.entur.logging.cloud.spring.logbook.LogbookLoggingAutoConfiguration; +import org.entur.jackson.tools.jsh.AnsiSyntaxHighlight; +import org.entur.jackson.tools.jsh.DefaultSyntaxHighlighter; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.slf4j.event.Level; diff --git a/request-response/logbook-test/build.gradle b/request-response/logbook-test/build.gradle index 88a02d02..6d47aa19 100644 --- a/request-response/logbook-test/build.gradle +++ b/request-response/logbook-test/build.gradle @@ -6,11 +6,11 @@ dependencies { api("org.zalando:logbook-api:${logbookVersion}") - api ("org.entur.jackson:jackson-syntax-highlight:${jacksonSyntaxHighlightVersion}") + api ("org.entur.jackson:jackson-tools-syntax-highlight:${jacksonSyntaxHighlightVersion}") api ("org.entur.logback-logstash-syntax-highlighting-decorators:logback-logstash-syntax-highlighting-decorators:${logbackLogstashSyntaxHighlightingDecoratorsVersion}") api ("net.logstash.logback:logstash-logback-encoder:${logbackLogstashVersion}") - api ("com.fasterxml.jackson.core:jackson-core") + api ("tools.jackson.core:jackson-core") api("org.apache.commons:commons-text:${commonsTextVersion}") } diff --git a/request-response/logbook-test/src/main/java/no/entur/logging/cloud/logbook/logbook/test/PrettyPrintingLogLevelLogstashLogbackSink.java b/request-response/logbook-test/src/main/java/no/entur/logging/cloud/logbook/logbook/test/PrettyPrintingLogLevelLogstashLogbackSink.java index 4416a059..e933c924 100644 --- a/request-response/logbook-test/src/main/java/no/entur/logging/cloud/logbook/logbook/test/PrettyPrintingLogLevelLogstashLogbackSink.java +++ b/request-response/logbook-test/src/main/java/no/entur/logging/cloud/logbook/logbook/test/PrettyPrintingLogLevelLogstashLogbackSink.java @@ -1,6 +1,5 @@ package no.entur.logging.cloud.logbook.logbook.test; -import com.fasterxml.jackson.core.JsonFactory; import no.entur.logging.cloud.logbook.AbstractLogLevelLogstashLogbackSink; import no.entur.logging.cloud.logbook.AbstractSinkBuilder; import no.entur.logging.cloud.logbook.DefaultRemoteHttpMessageContextSupplier; @@ -9,6 +8,7 @@ import org.slf4j.Marker; import org.zalando.logbook.HttpRequest; import org.zalando.logbook.HttpResponse; +import tools.jackson.databind.json.JsonMapper; import java.time.Duration; import java.util.function.BiConsumer; @@ -41,22 +41,22 @@ public PrettyPrintingLogLevelLogstashLogbackSink build() { if (server == null) { throw new IllegalStateException("Expected server message composer"); } - if (jsonFactory == null) { - jsonFactory = new JsonFactory(); + if (jsonMapper == null) { + jsonMapper = JsonMapper.builder().build(); } if (remoteHttpMessageContextSupplier == null) { remoteHttpMessageContextSupplier = new DefaultRemoteHttpMessageContextSupplier(); } return new PrettyPrintingLogLevelLogstashLogbackSink(loggerToBiConsumer(), logEnabledToBooleanSupplier(), - jsonFactory, Math.min(maxBodySize, maxSize), remoteHttpMessageContextSupplier, server, client); + jsonMapper, Math.min(maxBodySize, maxSize), remoteHttpMessageContextSupplier, server, client); } } public PrettyPrintingLogLevelLogstashLogbackSink(BiConsumer logConsumer, - BooleanSupplier logLevelEnabled, JsonFactory jsonFactory, int maxSize, + BooleanSupplier logLevelEnabled, JsonMapper jsonMapper, int maxSize, RemoteHttpMessageContextSupplier remoteHttpMessageContextSupplier, MessageComposer server, MessageComposer client) { - super(logConsumer, logLevelEnabled, jsonFactory, maxSize, remoteHttpMessageContextSupplier, server, client); + super(logConsumer, logLevelEnabled, jsonMapper, maxSize, remoteHttpMessageContextSupplier, server, client); } @Override diff --git a/request-response/logbook-test/src/main/java/no/entur/logging/cloud/logbook/logbook/test/PrettyPrintingRequestSingleFieldAppendingMarker.java b/request-response/logbook-test/src/main/java/no/entur/logging/cloud/logbook/logbook/test/PrettyPrintingRequestSingleFieldAppendingMarker.java index 6856d286..bbcb8788 100644 --- a/request-response/logbook-test/src/main/java/no/entur/logging/cloud/logbook/logbook/test/PrettyPrintingRequestSingleFieldAppendingMarker.java +++ b/request-response/logbook-test/src/main/java/no/entur/logging/cloud/logbook/logbook/test/PrettyPrintingRequestSingleFieldAppendingMarker.java @@ -1,15 +1,11 @@ package no.entur.logging.cloud.logbook.logbook.test; -import com.fasterxml.jackson.core.JsonFactory; -import com.fasterxml.jackson.core.JsonGenerator; -import com.fasterxml.jackson.core.JsonParser; -import com.fasterxml.jackson.core.PrettyPrinter; +import tools.jackson.core.JsonGenerator; import no.entur.logging.cloud.logbook.RequestSingleFieldAppendingMarker; import org.zalando.logbook.HttpRequest; - -import java.io.IOException; -import java.nio.charset.StandardCharsets; -import java.util.function.BooleanSupplier; +import tools.jackson.core.JsonParser; +import tools.jackson.core.PrettyPrinter; +import tools.jackson.core.TokenStreamFactory; public class PrettyPrintingRequestSingleFieldAppendingMarker extends RequestSingleFieldAppendingMarker { @@ -18,13 +14,13 @@ public PrettyPrintingRequestSingleFieldAppendingMarker(HttpRequest request, Stri } @Override - protected void writeWellformedBody(JsonGenerator generator) throws IOException { + protected void writeWellformedBody(JsonGenerator generator) { final PrettyPrinter prettyPrinter = generator.getPrettyPrinter(); - generator.writeFieldName("body"); + generator.writeName("body"); if (prettyPrinter == null) { generator.writeRawValue(body); } else { - final JsonFactory factory = generator.getCodec().getFactory(); + final TokenStreamFactory factory = generator.objectWriteContext().tokenStreamFactory(); // append to existing tree event by event try (final JsonParser parser = factory.createParser(body)) { diff --git a/request-response/logbook-test/src/main/java/no/entur/logging/cloud/logbook/logbook/test/PrettyPrintingResponseSingleFieldAppendingMarker.java b/request-response/logbook-test/src/main/java/no/entur/logging/cloud/logbook/logbook/test/PrettyPrintingResponseSingleFieldAppendingMarker.java index f5b961c6..a7e13f24 100644 --- a/request-response/logbook-test/src/main/java/no/entur/logging/cloud/logbook/logbook/test/PrettyPrintingResponseSingleFieldAppendingMarker.java +++ b/request-response/logbook-test/src/main/java/no/entur/logging/cloud/logbook/logbook/test/PrettyPrintingResponseSingleFieldAppendingMarker.java @@ -1,11 +1,12 @@ package no.entur.logging.cloud.logbook.logbook.test; -import com.fasterxml.jackson.core.JsonFactory; -import com.fasterxml.jackson.core.JsonGenerator; -import com.fasterxml.jackson.core.JsonParser; -import com.fasterxml.jackson.core.PrettyPrinter; +import tools.jackson.core.JsonGenerator; import no.entur.logging.cloud.logbook.ResponseSingleFieldAppendingMarker; import org.zalando.logbook.HttpResponse; +import tools.jackson.core.JsonParser; +import tools.jackson.core.PrettyPrinter; +import tools.jackson.core.TokenStreamFactory; +import tools.jackson.core.json.JsonFactory; import java.io.IOException; import java.time.Duration; @@ -18,13 +19,13 @@ public PrettyPrintingResponseSingleFieldAppendingMarker(HttpResponse response, D } @Override - protected void writeWellformedBody(JsonGenerator generator) throws IOException { + protected void writeWellformedBody(JsonGenerator generator) { final PrettyPrinter prettyPrinter = generator.getPrettyPrinter(); - generator.writeFieldName("body"); + generator.writeName("body"); if (prettyPrinter == null) { generator.writeRawValue(body); } else { - final JsonFactory factory = generator.getCodec().getFactory(); + final TokenStreamFactory factory = generator.objectWriteContext().tokenStreamFactory(); // append to existing tree event by event try (final JsonParser parser = factory.createParser(body)) { diff --git a/request-response/logbook-test/src/main/java/no/entur/logging/cloud/logbook/logbook/test/PrettyPrintingSink.java b/request-response/logbook-test/src/main/java/no/entur/logging/cloud/logbook/logbook/test/PrettyPrintingSink.java index 34fea8c3..033fce02 100644 --- a/request-response/logbook-test/src/main/java/no/entur/logging/cloud/logbook/logbook/test/PrettyPrintingSink.java +++ b/request-response/logbook-test/src/main/java/no/entur/logging/cloud/logbook/logbook/test/PrettyPrintingSink.java @@ -1,12 +1,10 @@ package no.entur.logging.cloud.logbook.logbook.test; -import com.fasterxml.jackson.core.JsonFactory; -import com.fasterxml.jackson.core.JsonGenerator; -import com.fasterxml.jackson.core.JsonParser; -import no.entur.logging.cloud.logbook.AbstractLogLevelLogstashLogbackSink; -import org.entur.jackson.jsh.AnsiSyntaxHighlight; -import org.entur.jackson.jsh.SyntaxHighlighter; -import org.entur.jackson.jsh.SyntaxHighlightingJsonGenerator; +import org.entur.jackson.tools.jsh.AnsiSyntaxHighlight; +import org.entur.jackson.tools.jsh.SyntaxHighlighter; +import org.entur.jackson.tools.jsh.SyntaxHighlightingJsonGenerator; +import org.entur.jackson.tools.jsh.SyntaxHighlightingPrettyPrinter; +import tools.jackson.core.JsonGenerator; import no.entur.logging.cloud.logbook.AbstractLogLevelSink; import no.entur.logging.cloud.logbook.AbstractSinkBuilder; import no.entur.logging.cloud.logbook.MessageComposer; @@ -16,6 +14,9 @@ import org.zalando.logbook.Correlation; import org.zalando.logbook.HttpRequest; import org.zalando.logbook.HttpResponse; +import tools.jackson.core.JsonParser; +import tools.jackson.databind.SerializationFeature; +import tools.jackson.databind.json.JsonMapper; import java.io.IOException; import java.io.StringWriter; @@ -47,8 +48,11 @@ public PrettyPrintingSink build() { if (syntaxHighlighter == null) { throw new IllegalStateException("Expected Json syntax highlighter level"); } - if (jsonFactory == null) { - jsonFactory = new JsonFactory(); + if (jsonMapper == null) { + jsonMapper = JsonMapper.builder() + .defaultPrettyPrinter(new SyntaxHighlightingPrettyPrinter(syntaxHighlighter)) + .configure(SerializationFeature.INDENT_OUTPUT, true) + .build(); } if (client == null) { throw new IllegalStateException("Expected client message composer"); @@ -61,21 +65,21 @@ public PrettyPrintingSink build() { // backend, but getting the same during testing as in production makes most // sense - return new PrettyPrintingSink(logEnabledToBooleanSupplier(), loggerToBiConsumer(), jsonFactory, + return new PrettyPrintingSink(logEnabledToBooleanSupplier(), loggerToBiConsumer(), jsonMapper, syntaxHighlighter, server, client); } } - protected final JsonFactory jsonFactory; + protected final JsonMapper jsonMapper; protected final SyntaxHighlighter syntaxHighlighter; public PrettyPrintingSink(BooleanSupplier logLevelEnabled, BiConsumer logConsumer, - JsonFactory jsonFactory, SyntaxHighlighter syntaxHighlighter, MessageComposer server, + JsonMapper jsonMapper, SyntaxHighlighter syntaxHighlighter, MessageComposer server, MessageComposer client) { super(logLevelEnabled, logConsumer, server, client); - this.jsonFactory = jsonFactory; + this.jsonMapper = jsonMapper; this.syntaxHighlighter = syntaxHighlighter; } @@ -160,16 +164,19 @@ public String prettyPrint(String body) { if (body != null && body.length() > 0) { try ( - JsonParser parser = jsonFactory.createParser(body); + JsonParser parser = jsonMapper.createParser(body); StringWriter writer = new StringWriter(body.length() * 2); - JsonGenerator generator = jsonFactory.createGenerator(writer);) { - JsonGenerator jsonGenerator = new SyntaxHighlightingJsonGenerator(generator, syntaxHighlighter, true); + JsonGenerator generator = jsonMapper.createGenerator(writer);) { + + SyntaxHighlightingPrettyPrinter prettyPrinter = (SyntaxHighlightingPrettyPrinter)generator.getPrettyPrinter(); + + JsonGenerator jsonGenerator = new SyntaxHighlightingJsonGenerator(generator, prettyPrinter, prettyPrinter.getObjectIndenter(), prettyPrinter.getArrayIndenter(), prettyPrinter.getSyntaxHighlighter()); while (parser.nextToken() != null) { jsonGenerator.copyCurrentEvent(parser); } jsonGenerator.flush(); return writer.toString(); - } catch (IOException e) { + } catch (Exception e) { // ignore, keep payload as-is } } diff --git a/request-response/logbook-test/src/main/java/no/entur/logging/cloud/logbook/logbook/test/ondemand/PrettyPrintingLocalHttpMessageBodyWriter.java b/request-response/logbook-test/src/main/java/no/entur/logging/cloud/logbook/logbook/test/ondemand/PrettyPrintingLocalHttpMessageBodyWriter.java index 0d3b3b9c..2fa231d9 100644 --- a/request-response/logbook-test/src/main/java/no/entur/logging/cloud/logbook/logbook/test/ondemand/PrettyPrintingLocalHttpMessageBodyWriter.java +++ b/request-response/logbook-test/src/main/java/no/entur/logging/cloud/logbook/logbook/test/ondemand/PrettyPrintingLocalHttpMessageBodyWriter.java @@ -1,10 +1,11 @@ package no.entur.logging.cloud.logbook.logbook.test.ondemand; -import com.fasterxml.jackson.core.JsonFactory; -import com.fasterxml.jackson.core.JsonGenerator; -import com.fasterxml.jackson.core.JsonParser; -import com.fasterxml.jackson.core.PrettyPrinter; import no.entur.logging.cloud.logbook.ondemand.HttpMessageBodyWriter; +import tools.jackson.core.JsonGenerator; +import tools.jackson.core.JsonParser; +import tools.jackson.core.PrettyPrinter; +import tools.jackson.core.TokenStreamFactory; +import tools.jackson.core.json.JsonFactory; import java.io.IOException; import java.nio.charset.StandardCharsets; @@ -24,13 +25,13 @@ public void prepareResult() { @Override public void writeBody(JsonGenerator generator) throws IOException { - generator.writeFieldName("body"); + generator.writeName("body"); PrettyPrinter prettyPrinter = generator.getPrettyPrinter(); if (prettyPrinter == null) { generator.writeRawValue(new String(input, StandardCharsets.UTF_8)); } else { - final JsonFactory factory = generator.getCodec().getFactory(); + final TokenStreamFactory factory = generator.objectWriteContext().tokenStreamFactory(); // append to existing tree event by event try (final JsonParser parser = factory.createParser(input)) { diff --git a/request-response/logbook-test/src/main/java/no/entur/logging/cloud/logbook/logbook/test/ondemand/PrettyPrintingLocalMaxSizeHttpMessageBodyWriter.java b/request-response/logbook-test/src/main/java/no/entur/logging/cloud/logbook/logbook/test/ondemand/PrettyPrintingLocalMaxSizeHttpMessageBodyWriter.java index 66cd4c5d..2a887761 100644 --- a/request-response/logbook-test/src/main/java/no/entur/logging/cloud/logbook/logbook/test/ondemand/PrettyPrintingLocalMaxSizeHttpMessageBodyWriter.java +++ b/request-response/logbook-test/src/main/java/no/entur/logging/cloud/logbook/logbook/test/ondemand/PrettyPrintingLocalMaxSizeHttpMessageBodyWriter.java @@ -1,9 +1,13 @@ package no.entur.logging.cloud.logbook.logbook.test.ondemand; -import com.fasterxml.jackson.core.*; import no.entur.logging.cloud.logbook.ondemand.HttpMessageBodyWriter; import no.entur.logging.cloud.logbook.ondemand.state.HttpMessageStateResult; import no.entur.logging.cloud.logbook.util.MaxSizeJsonFilter; +import tools.jackson.core.JsonGenerator; +import tools.jackson.core.JsonParser; +import tools.jackson.core.PrettyPrinter; +import tools.jackson.core.json.JsonFactory; +import tools.jackson.databind.json.JsonMapper; import java.io.IOException; import java.nio.charset.StandardCharsets; @@ -12,12 +16,12 @@ public class PrettyPrintingLocalMaxSizeHttpMessageBodyWriter implements HttpMess protected final byte[] input; protected final int maxSize; - protected final JsonFactory jsonFactory; + protected final JsonMapper jsonMapper; protected HttpMessageStateResult output; - public PrettyPrintingLocalMaxSizeHttpMessageBodyWriter(JsonFactory jsonFactory, byte[] input, int maxSize) { - this.jsonFactory = jsonFactory; + public PrettyPrintingLocalMaxSizeHttpMessageBodyWriter(JsonMapper jsonMapper, byte[] input, int maxSize) { + this.jsonMapper = jsonMapper; this.input = input; this.maxSize = maxSize; } @@ -47,13 +51,13 @@ public void writeBody(JsonGenerator generator) throws IOException { HttpMessageStateResult output = this.output; if(output.isWellformed()) { - generator.writeFieldName("body"); + generator.writeName("body"); PrettyPrinter prettyPrinter = generator.getPrettyPrinter(); if (prettyPrinter == null) { generator.writeRawValue(new String(input, StandardCharsets.UTF_8)); } else { - final JsonFactory factory = generator.getCodec().getFactory(); + JsonFactory factory = jsonMapper.tokenStreamFactory(); // append to existing tree event by event try (final JsonParser parser = factory.createParser(input)) { @@ -63,12 +67,12 @@ public void writeBody(JsonGenerator generator) throws IOException { } } } else { - generator.writeStringField("body", output.getBody()); + generator.writeStringProperty("body", output.getBody()); } } protected String filterMaxSize(byte[] body) { - MaxSizeJsonFilter filter = new MaxSizeJsonFilter(maxSize, jsonFactory); + MaxSizeJsonFilter filter = new MaxSizeJsonFilter(maxSize, jsonMapper); try { return filter.transform(body); diff --git a/request-response/logbook-test/src/main/java/no/entur/logging/cloud/logbook/logbook/test/ondemand/PrettyPrintingOndemandLogLevelLogstashLogbackSink.java b/request-response/logbook-test/src/main/java/no/entur/logging/cloud/logbook/logbook/test/ondemand/PrettyPrintingOndemandLogLevelLogstashLogbackSink.java index cdce4af3..8c5057b2 100644 --- a/request-response/logbook-test/src/main/java/no/entur/logging/cloud/logbook/logbook/test/ondemand/PrettyPrintingOndemandLogLevelLogstashLogbackSink.java +++ b/request-response/logbook-test/src/main/java/no/entur/logging/cloud/logbook/logbook/test/ondemand/PrettyPrintingOndemandLogLevelLogstashLogbackSink.java @@ -1,6 +1,5 @@ package no.entur.logging.cloud.logbook.logbook.test.ondemand; -import com.fasterxml.jackson.core.JsonFactory; import no.entur.logging.cloud.logbook.AbstractLogLevelLogstashLogbackSink; import no.entur.logging.cloud.logbook.DefaultRemoteHttpMessageContextSupplier; import no.entur.logging.cloud.logbook.MessageComposer; @@ -15,9 +14,8 @@ import org.zalando.logbook.HttpRequest; import org.zalando.logbook.HttpResponse; import org.zalando.logbook.Origin; +import tools.jackson.databind.json.JsonMapper; -import java.io.IOException; -import java.nio.charset.StandardCharsets; import java.util.function.BiConsumer; import java.util.function.BooleanSupplier; @@ -55,26 +53,26 @@ public PrettyPrintingOndemandLogLevelLogstashLogbackSink build() { if (server == null) { throw new IllegalStateException("Expected server message composer"); } - if (jsonFactory == null) { - jsonFactory = new JsonFactory(); + if (jsonMapper == null) { + jsonMapper = JsonMapper.builder().build(); } if (remoteHttpMessageContextSupplier == null) { remoteHttpMessageContextSupplier = new DefaultRemoteHttpMessageContextSupplier(); } return new PrettyPrintingOndemandLogLevelLogstashLogbackSink(loggerToBiConsumer(), - logEnabledToBooleanSupplier(), jsonFactory, requestBodyWellformedDecisionSupplier, + logEnabledToBooleanSupplier(), jsonMapper, requestBodyWellformedDecisionSupplier, responseBodyWellformedDecisionSupplier, maxBodySize, maxSize, remoteHttpMessageContextSupplier, server, client); } } public PrettyPrintingOndemandLogLevelLogstashLogbackSink(BiConsumer logConsumer, - BooleanSupplier logLevelEnabled, JsonFactory jsonFactory, + BooleanSupplier logLevelEnabled, JsonMapper jsonMapper, RequestHttpMessageStateSupplierSource requestHttpMessageStateSupplierSource, ResponseHttpMessageStateSupplierSource responseHttpMessageStateSupplierSource, int maxBodySize, int maxSize, RemoteHttpMessageContextSupplier remoteHttpMessageContextSupplier, MessageComposer server, MessageComposer client) { - super(logConsumer, logLevelEnabled, jsonFactory, requestHttpMessageStateSupplierSource, + super(logConsumer, logLevelEnabled, jsonMapper, requestHttpMessageStateSupplierSource, responseHttpMessageStateSupplierSource, maxBodySize, maxSize, remoteHttpMessageContextSupplier, server, client); } @@ -91,21 +89,21 @@ public Marker createRequestMarker(HttpRequest request) { if (body.length > maxBodySize) { writer = new PrettyPrintingLocalHttpMessageBodyWriter(body); } else { - writer = new PrettyPrintingLocalMaxSizeHttpMessageBodyWriter(jsonFactory, body, + writer = new PrettyPrintingLocalMaxSizeHttpMessageBodyWriter(jsonMapper, body, maxBodySize); } } else { HttpMessageStateSupplier httpMessageStateSupplier = requestHttpMessageStateSupplierSource.get(); if (body.length > maxBodySize) { - writer = new PrettyPrintingRemoteHttpMessageBodyWriter(jsonFactory, body, + writer = new PrettyPrintingRemoteHttpMessageBodyWriter(jsonMapper, body, httpMessageStateSupplier); } else { - writer = new PrettyPrintingRemoteMaxSizeHttpMessageBodyWriter(jsonFactory, body, maxSize, + writer = new PrettyPrintingRemoteMaxSizeHttpMessageBodyWriter(jsonMapper, body, maxSize, httpMessageStateSupplier); } } } - } catch (IOException e) { + } catch (Exception e) { // ignore } } else if (AbstractLogLevelLogstashLogbackSink.isXmlMediaType(request.getContentType())) { @@ -120,7 +118,7 @@ public Marker createRequestMarker(HttpRequest request) { writer = new StringHttpMessageBodyWriter(bodyAsString); } } - } catch (IOException e) { + } catch (Exception e) { // ignore } } @@ -141,22 +139,22 @@ public Marker createResponseMarker(Correlation correlation, HttpResponse respons if (body.length > maxBodySize) { writer = new PrettyPrintingLocalHttpMessageBodyWriter(body); } else { - writer = new PrettyPrintingLocalMaxSizeHttpMessageBodyWriter(jsonFactory, body, + writer = new PrettyPrintingLocalMaxSizeHttpMessageBodyWriter(jsonMapper, body, maxBodySize); } } else { HttpMessageStateSupplier httpMessageStateSupplier = responseHttpMessageStateSupplierSource .get(); if (body.length > maxBodySize) { - writer = new PrettyPrintingRemoteHttpMessageBodyWriter(jsonFactory, body, + writer = new PrettyPrintingRemoteHttpMessageBodyWriter(jsonMapper, body, httpMessageStateSupplier); } else { - writer = new PrettyPrintingRemoteMaxSizeHttpMessageBodyWriter(jsonFactory, body, maxSize, + writer = new PrettyPrintingRemoteMaxSizeHttpMessageBodyWriter(jsonMapper, body, maxSize, httpMessageStateSupplier); } } } - } catch (IOException e) { + } catch (Exception e) { // ignore } } else if (AbstractLogLevelLogstashLogbackSink.isXmlMediaType(response.getContentType())) { @@ -171,7 +169,7 @@ public Marker createResponseMarker(Correlation correlation, HttpResponse respons writer = new StringHttpMessageBodyWriter(bodyAsString); } } - } catch (IOException e) { + } catch (Exception e) { // ignore } } diff --git a/request-response/logbook-test/src/main/java/no/entur/logging/cloud/logbook/logbook/test/ondemand/PrettyPrintingRemoteHttpMessageBodyWriter.java b/request-response/logbook-test/src/main/java/no/entur/logging/cloud/logbook/logbook/test/ondemand/PrettyPrintingRemoteHttpMessageBodyWriter.java index 31e14995..674fa91c 100644 --- a/request-response/logbook-test/src/main/java/no/entur/logging/cloud/logbook/logbook/test/ondemand/PrettyPrintingRemoteHttpMessageBodyWriter.java +++ b/request-response/logbook-test/src/main/java/no/entur/logging/cloud/logbook/logbook/test/ondemand/PrettyPrintingRemoteHttpMessageBodyWriter.java @@ -1,12 +1,13 @@ package no.entur.logging.cloud.logbook.logbook.test.ondemand; -import com.fasterxml.jackson.core.JsonFactory; -import com.fasterxml.jackson.core.JsonGenerator; -import com.fasterxml.jackson.core.JsonParser; -import com.fasterxml.jackson.core.PrettyPrinter; import no.entur.logging.cloud.logbook.ondemand.state.HttpMessageState; import no.entur.logging.cloud.logbook.ondemand.state.HttpMessageStateResult; import no.entur.logging.cloud.logbook.ondemand.state.HttpMessageStateSupplier; +import tools.jackson.core.JsonGenerator; +import tools.jackson.core.JsonParser; +import tools.jackson.core.PrettyPrinter; +import tools.jackson.core.TokenStreamFactory; +import tools.jackson.databind.json.JsonMapper; import java.io.ByteArrayInputStream; import java.io.IOException; @@ -17,12 +18,12 @@ public class PrettyPrintingRemoteHttpMessageBodyWriter extends PrettyPrintingLoc protected final HttpMessageStateSupplier httpMessageStateSupplier; protected volatile HttpMessageStateResult output; - protected final JsonFactory jsonFactory; + protected final JsonMapper jsonMapper; - public PrettyPrintingRemoteHttpMessageBodyWriter(JsonFactory jsonFactory, byte[] input, HttpMessageStateSupplier httpMessageStateSupplier) { + public PrettyPrintingRemoteHttpMessageBodyWriter(JsonMapper jsonMapper, byte[] input, HttpMessageStateSupplier httpMessageStateSupplier) { super(input); - this.jsonFactory = jsonFactory; + this.jsonMapper = jsonMapper; this.httpMessageStateSupplier = httpMessageStateSupplier; } @@ -50,28 +51,28 @@ public void writeBody(JsonGenerator generator) throws IOException { this.output = output = createResult(); } if(output.isWellformed()) { - generator.writeFieldName("body"); + generator.writeName("body"); PrettyPrinter prettyPrinter = generator.getPrettyPrinter(); if (prettyPrinter == null) { generator.writeRawValue(output.getBody()); } else { - final JsonFactory factory = generator.getCodec().getFactory(); + final TokenStreamFactory factory = generator.objectWriteContext().tokenStreamFactory(); // append to existing tree event by event - try (final JsonParser parser = factory.createParser(output.getBody())) { + try (final JsonParser parser = jsonMapper.createParser(output.getBody())) { while (parser.nextToken() != null) { generator.copyCurrentEvent(parser); } } } } else { - generator.writeStringField("body", output.getBody()); + generator.writeStringProperty("body", output.getBody()); } } protected boolean isWellformedJson() { - try (JsonParser parser = jsonFactory.createParser(new ByteArrayInputStream(input))) { + try (JsonParser parser = jsonMapper.createParser(new ByteArrayInputStream(input))) { while(parser.nextToken() != null); } catch(Exception e) { return false; diff --git a/request-response/logbook-test/src/main/java/no/entur/logging/cloud/logbook/logbook/test/ondemand/PrettyPrintingRemoteMaxSizeHttpMessageBodyWriter.java b/request-response/logbook-test/src/main/java/no/entur/logging/cloud/logbook/logbook/test/ondemand/PrettyPrintingRemoteMaxSizeHttpMessageBodyWriter.java index 61bfd340..51ba7765 100644 --- a/request-response/logbook-test/src/main/java/no/entur/logging/cloud/logbook/logbook/test/ondemand/PrettyPrintingRemoteMaxSizeHttpMessageBodyWriter.java +++ b/request-response/logbook-test/src/main/java/no/entur/logging/cloud/logbook/logbook/test/ondemand/PrettyPrintingRemoteMaxSizeHttpMessageBodyWriter.java @@ -1,9 +1,9 @@ package no.entur.logging.cloud.logbook.logbook.test.ondemand; -import com.fasterxml.jackson.core.JsonFactory; import no.entur.logging.cloud.logbook.ondemand.state.HttpMessageState; import no.entur.logging.cloud.logbook.ondemand.state.HttpMessageStateResult; import no.entur.logging.cloud.logbook.ondemand.state.HttpMessageStateSupplier; +import tools.jackson.databind.json.JsonMapper; import java.nio.charset.StandardCharsets; @@ -11,8 +11,8 @@ public class PrettyPrintingRemoteMaxSizeHttpMessageBodyWriter extends PrettyPrin protected final HttpMessageStateSupplier httpMessageStateSupplier; - public PrettyPrintingRemoteMaxSizeHttpMessageBodyWriter(JsonFactory jsonFactory, byte[] input, int maxSize, HttpMessageStateSupplier httpMessageStateSupplier) { - super(jsonFactory, input, maxSize); + public PrettyPrintingRemoteMaxSizeHttpMessageBodyWriter(JsonMapper mapper, byte[] input, int maxSize, HttpMessageStateSupplier httpMessageStateSupplier) { + super(mapper, input, maxSize); this.httpMessageStateSupplier = httpMessageStateSupplier; } diff --git a/request-response/logbook/build.gradle b/request-response/logbook/build.gradle index 5faac32c..18482d09 100644 --- a/request-response/logbook/build.gradle +++ b/request-response/logbook/build.gradle @@ -9,7 +9,7 @@ dependencies { api "commons-io:commons-io:${commonsIoVersion}" api ("net.logstash.logback:logstash-logback-encoder:${logbackLogstashVersion}") - api("com.fasterxml.jackson.core:jackson-core") + api("tools.jackson.core:jackson-core") api("org.apache.commons:commons-text:${commonsTextVersion}") diff --git a/request-response/logbook/src/main/java/no/entur/logging/cloud/logbook/AbstractLogLevelLogstashLogbackSink.java b/request-response/logbook/src/main/java/no/entur/logging/cloud/logbook/AbstractLogLevelLogstashLogbackSink.java index 488e6368..9e42b206 100644 --- a/request-response/logbook/src/main/java/no/entur/logging/cloud/logbook/AbstractLogLevelLogstashLogbackSink.java +++ b/request-response/logbook/src/main/java/no/entur/logging/cloud/logbook/AbstractLogLevelLogstashLogbackSink.java @@ -1,6 +1,5 @@ package no.entur.logging.cloud.logbook; -import com.fasterxml.jackson.core.JsonFactory; import no.entur.logging.cloud.logbook.util.JsonValidator; import no.entur.logging.cloud.logbook.util.MaxSizeJsonFilter; import org.slf4j.Marker; @@ -9,6 +8,7 @@ import org.zalando.logbook.HttpRequest; import org.zalando.logbook.HttpResponse; import org.zalando.logbook.Origin; +import tools.jackson.databind.json.JsonMapper; import javax.annotation.Nullable; @@ -26,13 +26,13 @@ public abstract class AbstractLogLevelLogstashLogbackSink extends AbstractLogLev protected final RemoteHttpMessageContextSupplier remoteHttpMessageContextSupplier; public AbstractLogLevelLogstashLogbackSink(BiConsumer logConsumer, BooleanSupplier logLevelEnabled, - JsonFactory jsonFactory, int maxSize, RemoteHttpMessageContextSupplier remoteHttpMessageContextSupplier, - MessageComposer server, MessageComposer client) { + JsonMapper jsonMapper, int maxSize, RemoteHttpMessageContextSupplier remoteHttpMessageContextSupplier, + MessageComposer server, MessageComposer client) { super(logLevelEnabled, logConsumer, server, client); this.maxSize = maxSize; - this.maxSizeJsonFilter = new MaxSizeJsonFilter(maxSize, jsonFactory); - this.jsonValidator = new JsonValidator(jsonFactory); + this.maxSizeJsonFilter = new MaxSizeJsonFilter(maxSize, jsonMapper); + this.jsonValidator = new JsonValidator(jsonMapper); this.remoteHttpMessageContextSupplier = remoteHttpMessageContextSupplier; } diff --git a/request-response/logbook/src/main/java/no/entur/logging/cloud/logbook/AbstractSingleFieldAppendingMarker.java b/request-response/logbook/src/main/java/no/entur/logging/cloud/logbook/AbstractSingleFieldAppendingMarker.java index c0e5b0cb..9e3a1338 100644 --- a/request-response/logbook/src/main/java/no/entur/logging/cloud/logbook/AbstractSingleFieldAppendingMarker.java +++ b/request-response/logbook/src/main/java/no/entur/logging/cloud/logbook/AbstractSingleFieldAppendingMarker.java @@ -1,6 +1,6 @@ package no.entur.logging.cloud.logbook; -import com.fasterxml.jackson.core.JsonGenerator; +import tools.jackson.core.JsonGenerator; import net.logstash.logback.marker.SingleFieldAppendingMarker; import org.zalando.logbook.ContentType; import org.zalando.logbook.HttpMessage; @@ -40,14 +40,14 @@ protected void writeBody(JsonGenerator generator) { if (wellformed) { writeWellformedBody(generator); } else { - generator.writeStringField("body", body); + generator.writeStringProperty("body", body); } } catch (Exception e) { // should never happen, this is probably going to blow up somewhere else } } else { try { - generator.writeStringField("body", body); + generator.writeStringProperty("body", body); } catch (Exception e) { // should never happen, this is probably going to blow up somewhere else } @@ -55,20 +55,20 @@ protected void writeBody(JsonGenerator generator) { } } - protected void writeWellformedBody(JsonGenerator generator) throws IOException { - generator.writeFieldName("body"); + protected void writeWellformedBody(JsonGenerator generator) { + generator.writeName("body"); generator.writeRawValue(body); } - protected void writeHeaders(JsonGenerator generator) throws IOException { - generator.writeFieldName("headers"); + protected void writeHeaders(JsonGenerator generator) { + generator.writeName("headers"); generator.writeStartObject(); if(headers != null) { for (Map.Entry> stringListEntry : headers.entrySet()) { String key = stringListEntry.getKey(); if(key != null && !key.isEmpty()) { - generator.writeFieldName(key.toLowerCase()); + generator.writeName(key.toLowerCase()); generator.writeStartArray(); List values = stringListEntry.getValue(); diff --git a/request-response/logbook/src/main/java/no/entur/logging/cloud/logbook/AbstractSinkBuilder.java b/request-response/logbook/src/main/java/no/entur/logging/cloud/logbook/AbstractSinkBuilder.java index 1812b37c..2f2f3c9b 100644 --- a/request-response/logbook/src/main/java/no/entur/logging/cloud/logbook/AbstractSinkBuilder.java +++ b/request-response/logbook/src/main/java/no/entur/logging/cloud/logbook/AbstractSinkBuilder.java @@ -1,10 +1,9 @@ package no.entur.logging.cloud.logbook; -import com.fasterxml.jackson.core.JsonFactory; - import org.slf4j.Logger; import org.slf4j.Marker; import org.slf4j.event.Level; +import tools.jackson.databind.json.JsonMapper; import java.util.function.BiConsumer; import java.util.function.BooleanSupplier; @@ -17,7 +16,7 @@ public abstract class AbstractSinkBuilder protected Level level; - protected JsonFactory jsonFactory; + protected JsonMapper jsonMapper; protected int maxSize = -1; protected int maxBodySize = -1; @@ -32,8 +31,8 @@ public B withLogger(Logger logger) { return (B) this; } - public B withJsonFactory(JsonFactory jsonFactory) { - this.jsonFactory = jsonFactory; + public B withJsonFactory(JsonMapper jsonMapper) { + this.jsonMapper = jsonMapper; return (B) this; } diff --git a/request-response/logbook/src/main/java/no/entur/logging/cloud/logbook/LogLevelLogstashLogbackSink.java b/request-response/logbook/src/main/java/no/entur/logging/cloud/logbook/LogLevelLogstashLogbackSink.java index fbf864a9..aa351806 100644 --- a/request-response/logbook/src/main/java/no/entur/logging/cloud/logbook/LogLevelLogstashLogbackSink.java +++ b/request-response/logbook/src/main/java/no/entur/logging/cloud/logbook/LogLevelLogstashLogbackSink.java @@ -1,9 +1,9 @@ package no.entur.logging.cloud.logbook; -import com.fasterxml.jackson.core.JsonFactory; import org.slf4j.Marker; import org.zalando.logbook.HttpRequest; import org.zalando.logbook.HttpResponse; +import tools.jackson.databind.json.JsonMapper; import java.time.Duration; import java.util.function.BiConsumer; @@ -19,9 +19,9 @@ public class LogLevelLogstashLogbackSink extends AbstractLogLevelLogstashLogbackSink { public LogLevelLogstashLogbackSink(BiConsumer logConsumer, BooleanSupplier logLevelEnabled, - JsonFactory jsonFactory, int maxSize, RemoteHttpMessageContextSupplier remoteHttpMessageContextSupplier, - MessageComposer server, MessageComposer client) { - super(logConsumer, logLevelEnabled, jsonFactory, maxSize, remoteHttpMessageContextSupplier, server, client); + JsonMapper jsonMapper, int maxSize, RemoteHttpMessageContextSupplier remoteHttpMessageContextSupplier, + MessageComposer server, MessageComposer client) { + super(logConsumer, logLevelEnabled, jsonMapper, maxSize, remoteHttpMessageContextSupplier, server, client); } public static Builder newBuilder() { @@ -49,13 +49,13 @@ public LogLevelLogstashLogbackSink build() { if (server == null) { throw new IllegalStateException("Expected server message composer"); } - if (jsonFactory == null) { - jsonFactory = new JsonFactory(); + if (jsonMapper == null) { + jsonMapper = JsonMapper.builder().build(); } if (remoteHttpMessageContextSupplier == null) { remoteHttpMessageContextSupplier = new DefaultRemoteHttpMessageContextSupplier(); } - return new LogLevelLogstashLogbackSink(loggerToBiConsumer(), logEnabledToBooleanSupplier(), jsonFactory, + return new LogLevelLogstashLogbackSink(loggerToBiConsumer(), logEnabledToBooleanSupplier(), jsonMapper, Math.min(maxBodySize, maxSize), remoteHttpMessageContextSupplier, server, client); } } diff --git a/request-response/logbook/src/main/java/no/entur/logging/cloud/logbook/RequestSingleFieldAppendingMarker.java b/request-response/logbook/src/main/java/no/entur/logging/cloud/logbook/RequestSingleFieldAppendingMarker.java index 23100dd6..5b3c5548 100644 --- a/request-response/logbook/src/main/java/no/entur/logging/cloud/logbook/RequestSingleFieldAppendingMarker.java +++ b/request-response/logbook/src/main/java/no/entur/logging/cloud/logbook/RequestSingleFieldAppendingMarker.java @@ -1,6 +1,6 @@ package no.entur.logging.cloud.logbook; -import com.fasterxml.jackson.core.JsonGenerator; +import tools.jackson.core.JsonGenerator; import org.zalando.logbook.HttpRequest; import org.zalando.logbook.Origin; @@ -45,38 +45,38 @@ protected void prepareForDeferredProcessing(HttpRequest message) { } @Override - protected void writeFieldValue(JsonGenerator generator) throws IOException { + protected void writeFieldValue(JsonGenerator generator) { generator.writeStartObject(); if(origin != null) { - generator.writeStringField("origin", origin); + generator.writeStringProperty("origin", origin); } - generator.writeStringField("type", "request"); + generator.writeStringProperty("type", "request"); if(protocol != null) { - generator.writeStringField("protocol", protocol); + generator.writeStringProperty("protocol", protocol); } if(remote != null) { - generator.writeStringField("remote", remote); + generator.writeStringProperty("remote", remote); } if(method != null) { - generator.writeStringField("method", method); + generator.writeStringProperty("method", method); } if(uri != null) { - generator.writeStringField("uri", uri); + generator.writeStringProperty("uri", uri); } if(host != null) { - generator.writeStringField("host", host); + generator.writeStringProperty("host", host); } if(path != null) { - generator.writeStringField("path", path); + generator.writeStringProperty("path", path); } if(scheme != null) { - generator.writeStringField("scheme", scheme); + generator.writeStringProperty("scheme", scheme); } if(port.isEmpty()) { - generator.writeNumberField("port", 80); + generator.writeNumberProperty("port", 80); } else { - generator.writeNumberField("port", port.get()); + generator.writeNumberProperty("port", port.get()); } writeHeaders(generator); diff --git a/request-response/logbook/src/main/java/no/entur/logging/cloud/logbook/ResponseSingleFieldAppendingMarker.java b/request-response/logbook/src/main/java/no/entur/logging/cloud/logbook/ResponseSingleFieldAppendingMarker.java index 0555b6f8..4f9ff5b6 100644 --- a/request-response/logbook/src/main/java/no/entur/logging/cloud/logbook/ResponseSingleFieldAppendingMarker.java +++ b/request-response/logbook/src/main/java/no/entur/logging/cloud/logbook/ResponseSingleFieldAppendingMarker.java @@ -1,6 +1,6 @@ package no.entur.logging.cloud.logbook; -import com.fasterxml.jackson.core.JsonGenerator; +import tools.jackson.core.JsonGenerator; import org.zalando.logbook.HttpResponse; import org.zalando.logbook.Origin; @@ -36,20 +36,20 @@ protected void prepareForDeferredProcessing(HttpResponse message) { } @Override - protected void writeFieldValue(JsonGenerator generator) throws IOException { + protected void writeFieldValue(JsonGenerator generator) { generator.writeStartObject(); if(origin != null) { - generator.writeStringField("origin", origin); + generator.writeStringProperty("origin", origin); } - generator.writeStringField("type", "response"); + generator.writeStringProperty("type", "response"); if(duration != null) { - generator.writeNumberField("duration", duration.toMillis()); + generator.writeNumberProperty("duration", duration.toMillis()); } if(protocol != null) { - generator.writeStringField("protocol", protocol); + generator.writeStringProperty("protocol", protocol); } - generator.writeNumberField("status", status); + generator.writeNumberProperty("status", status); writeHeaders(generator); writeBody(generator); diff --git a/request-response/logbook/src/main/java/no/entur/logging/cloud/logbook/ondemand/AbstractOndemandLogLevelLogstashLogbackSink.java b/request-response/logbook/src/main/java/no/entur/logging/cloud/logbook/ondemand/AbstractOndemandLogLevelLogstashLogbackSink.java index 02def91f..cfef2b88 100644 --- a/request-response/logbook/src/main/java/no/entur/logging/cloud/logbook/ondemand/AbstractOndemandLogLevelLogstashLogbackSink.java +++ b/request-response/logbook/src/main/java/no/entur/logging/cloud/logbook/ondemand/AbstractOndemandLogLevelLogstashLogbackSink.java @@ -1,12 +1,12 @@ package no.entur.logging.cloud.logbook.ondemand; -import com.fasterxml.jackson.core.JsonFactory; import no.entur.logging.cloud.logbook.AbstractLogLevelSink; import no.entur.logging.cloud.logbook.MessageComposer; import no.entur.logging.cloud.logbook.RemoteHttpMessageContextSupplier; import no.entur.logging.cloud.logbook.ondemand.state.RequestHttpMessageStateSupplierSource; import no.entur.logging.cloud.logbook.ondemand.state.ResponseHttpMessageStateSupplierSource; import org.slf4j.Marker; +import tools.jackson.databind.json.JsonMapper; import java.util.function.BiConsumer; import java.util.function.BooleanSupplier; @@ -18,18 +18,18 @@ public abstract class AbstractOndemandLogLevelLogstashLogbackSink extends Abstra protected final RemoteHttpMessageContextSupplier remoteHttpMessageContextSupplier; - protected JsonFactory jsonFactory; + protected JsonMapper jsonMapper; protected final int maxBodySize; protected final int maxSize; public AbstractOndemandLogLevelLogstashLogbackSink(BiConsumer logConsumer, - BooleanSupplier logLevelEnabled, JsonFactory jsonFactory, + BooleanSupplier logLevelEnabled, JsonMapper jsonMapper, RequestHttpMessageStateSupplierSource requestHttpMessageStateSupplierSource, ResponseHttpMessageStateSupplierSource responseHttpMessageStateSupplierSource, int maxBodySize, int maxSize, RemoteHttpMessageContextSupplier remoteHttpMessageContextSupplier, MessageComposer server, MessageComposer client) { super(logLevelEnabled, logConsumer, server, client); - this.jsonFactory = jsonFactory; + this.jsonMapper = jsonMapper; this.requestHttpMessageStateSupplierSource = requestHttpMessageStateSupplierSource; this.responseHttpMessageStateSupplierSource = responseHttpMessageStateSupplierSource; this.maxBodySize = maxBodySize; diff --git a/request-response/logbook/src/main/java/no/entur/logging/cloud/logbook/ondemand/AbstractOndemandSingleFieldAppendingMarker.java b/request-response/logbook/src/main/java/no/entur/logging/cloud/logbook/ondemand/AbstractOndemandSingleFieldAppendingMarker.java index 99206a4b..9fc77373 100644 --- a/request-response/logbook/src/main/java/no/entur/logging/cloud/logbook/ondemand/AbstractOndemandSingleFieldAppendingMarker.java +++ b/request-response/logbook/src/main/java/no/entur/logging/cloud/logbook/ondemand/AbstractOndemandSingleFieldAppendingMarker.java @@ -1,6 +1,6 @@ package no.entur.logging.cloud.logbook.ondemand; -import com.fasterxml.jackson.core.JsonGenerator; +import tools.jackson.core.JsonGenerator; import net.logstash.logback.marker.SingleFieldAppendingMarker; import no.entur.logging.cloud.appender.scope.LoggingScopePostProcessing; import org.zalando.logbook.ContentType; @@ -60,15 +60,15 @@ protected void writeBody(JsonGenerator generator) { } - protected void writeHeaders(JsonGenerator generator) throws IOException { - generator.writeFieldName("headers"); + protected void writeHeaders(JsonGenerator generator) { + generator.writeName("headers"); generator.writeStartObject(); if(headers != null) { for (Map.Entry> stringListEntry : headers.entrySet()) { String key = stringListEntry.getKey(); if(key != null && !key.isEmpty()) { - generator.writeFieldName(key.toLowerCase()); + generator.writeName(key.toLowerCase()); generator.writeStartArray(); List values = stringListEntry.getValue(); diff --git a/request-response/logbook/src/main/java/no/entur/logging/cloud/logbook/ondemand/EmptyHttpMessageBodyWriter.java b/request-response/logbook/src/main/java/no/entur/logging/cloud/logbook/ondemand/EmptyHttpMessageBodyWriter.java index 9f48d6f7..821b6384 100644 --- a/request-response/logbook/src/main/java/no/entur/logging/cloud/logbook/ondemand/EmptyHttpMessageBodyWriter.java +++ b/request-response/logbook/src/main/java/no/entur/logging/cloud/logbook/ondemand/EmptyHttpMessageBodyWriter.java @@ -1,6 +1,6 @@ package no.entur.logging.cloud.logbook.ondemand; -import com.fasterxml.jackson.core.JsonGenerator; +import tools.jackson.core.JsonGenerator; import java.io.IOException; diff --git a/request-response/logbook/src/main/java/no/entur/logging/cloud/logbook/ondemand/HttpMessageBodyWriter.java b/request-response/logbook/src/main/java/no/entur/logging/cloud/logbook/ondemand/HttpMessageBodyWriter.java index 3effb7d0..d368c295 100644 --- a/request-response/logbook/src/main/java/no/entur/logging/cloud/logbook/ondemand/HttpMessageBodyWriter.java +++ b/request-response/logbook/src/main/java/no/entur/logging/cloud/logbook/ondemand/HttpMessageBodyWriter.java @@ -1,6 +1,6 @@ package no.entur.logging.cloud.logbook.ondemand; -import com.fasterxml.jackson.core.JsonGenerator; +import tools.jackson.core.JsonGenerator; import java.io.IOException; diff --git a/request-response/logbook/src/main/java/no/entur/logging/cloud/logbook/ondemand/LocalHttpMessageBodyWriter.java b/request-response/logbook/src/main/java/no/entur/logging/cloud/logbook/ondemand/LocalHttpMessageBodyWriter.java index 03f1b0ae..8da81c94 100644 --- a/request-response/logbook/src/main/java/no/entur/logging/cloud/logbook/ondemand/LocalHttpMessageBodyWriter.java +++ b/request-response/logbook/src/main/java/no/entur/logging/cloud/logbook/ondemand/LocalHttpMessageBodyWriter.java @@ -1,6 +1,6 @@ package no.entur.logging.cloud.logbook.ondemand; -import com.fasterxml.jackson.core.JsonGenerator; +import tools.jackson.core.JsonGenerator; import java.io.IOException; import java.nio.charset.StandardCharsets; @@ -20,7 +20,7 @@ public void prepareResult() { @Override public void writeBody(JsonGenerator generator) throws IOException { - generator.writeFieldName("body"); + generator.writeName("body"); generator.writeRawValue(new String(input, StandardCharsets.UTF_8)); } diff --git a/request-response/logbook/src/main/java/no/entur/logging/cloud/logbook/ondemand/MaxSizeLocalHttpMessageBodyWriter.java b/request-response/logbook/src/main/java/no/entur/logging/cloud/logbook/ondemand/MaxSizeLocalHttpMessageBodyWriter.java index f9dad3e3..c811448a 100644 --- a/request-response/logbook/src/main/java/no/entur/logging/cloud/logbook/ondemand/MaxSizeLocalHttpMessageBodyWriter.java +++ b/request-response/logbook/src/main/java/no/entur/logging/cloud/logbook/ondemand/MaxSizeLocalHttpMessageBodyWriter.java @@ -1,7 +1,11 @@ package no.entur.logging.cloud.logbook.ondemand; -import com.fasterxml.jackson.core.*; import no.entur.logging.cloud.logbook.ondemand.state.HttpMessageStateResult; +import tools.jackson.core.JsonGenerator; +import tools.jackson.core.JsonParser; +import tools.jackson.core.JsonToken; +import tools.jackson.core.TokenStreamContext; +import tools.jackson.databind.json.JsonMapper; import java.io.CharArrayWriter; import java.io.IOException; @@ -12,12 +16,12 @@ public class MaxSizeLocalHttpMessageBodyWriter implements HttpMessageBodyWriter protected final byte[] input; protected final int maxSize; - protected final JsonFactory jsonFactory; + protected final JsonMapper jsonMapper; protected HttpMessageStateResult output; - public MaxSizeLocalHttpMessageBodyWriter(JsonFactory jsonFactory, byte[] input, int maxSize) { - this.jsonFactory = jsonFactory; + public MaxSizeLocalHttpMessageBodyWriter(JsonMapper jsonMapper, byte[] input, int maxSize) { + this.jsonMapper = jsonMapper; this.input = input; this.maxSize = maxSize; } @@ -47,20 +51,20 @@ public void writeBody(JsonGenerator generator) throws IOException { HttpMessageStateResult output = this.output; if(output.isWellformed()) { - generator.writeFieldName("body"); + generator.writeName("body"); generator.writeRawValue(output.getBody()); } else { - generator.writeStringField("body", output.getBody()); + generator.writeStringProperty("body", output.getBody()); } } protected String filterMaxSize(byte[] body, int max) { try ( - JsonParser parser = jsonFactory.createParser(body); + JsonParser parser = jsonMapper.createParser(body); CharArrayWriter writer = new CharArrayWriter(max); - JsonGenerator generator = jsonFactory.createGenerator(writer); + JsonGenerator generator = jsonMapper.createGenerator(writer); ) { - process(parser, generator, () -> generator.getOutputBuffered() + writer.size(), max); + process(parser, generator, () -> generator.streamWriteOutputBuffered() + writer.size(), max); generator.flush(); return writer.toString(); @@ -85,7 +89,7 @@ public void process(final JsonParser parser, JsonGenerator generator, LongSuppli if(nextToken == null) { break; } - if(nextToken == JsonToken.FIELD_NAME) { + if(nextToken == JsonToken.PROPERTY_NAME) { fieldName = parser.currentName(); continue; @@ -111,11 +115,11 @@ public void process(final JsonParser parser, JsonGenerator generator, LongSuppli if(outputSize + size >= limit) { // write notification - JsonStreamContext ctxt = generator.getOutputContext(); + TokenStreamContext ctxt = generator.streamWriteContext(); if (ctxt.inArray()) { generator.writeString("Logger: " + message); } else if (ctxt.inObject()) { - generator.writeStringField("Logger", message); + generator.writeStringProperty("Logger", message); } generator.close(); @@ -124,7 +128,7 @@ public void process(final JsonParser parser, JsonGenerator generator, LongSuppli } if(fieldName != null) { - generator.writeFieldName(fieldName); + generator.writeName(fieldName); fieldName = null; } diff --git a/request-response/logbook/src/main/java/no/entur/logging/cloud/logbook/ondemand/MaxSizeRemoteHttpMessageBodyWriter.java b/request-response/logbook/src/main/java/no/entur/logging/cloud/logbook/ondemand/MaxSizeRemoteHttpMessageBodyWriter.java index ff7b4064..3408d590 100644 --- a/request-response/logbook/src/main/java/no/entur/logging/cloud/logbook/ondemand/MaxSizeRemoteHttpMessageBodyWriter.java +++ b/request-response/logbook/src/main/java/no/entur/logging/cloud/logbook/ondemand/MaxSizeRemoteHttpMessageBodyWriter.java @@ -1,9 +1,9 @@ package no.entur.logging.cloud.logbook.ondemand; -import com.fasterxml.jackson.core.JsonFactory; import no.entur.logging.cloud.logbook.ondemand.state.HttpMessageState; import no.entur.logging.cloud.logbook.ondemand.state.HttpMessageStateResult; import no.entur.logging.cloud.logbook.ondemand.state.HttpMessageStateSupplier; +import tools.jackson.databind.json.JsonMapper; import java.nio.charset.StandardCharsets; @@ -11,8 +11,8 @@ public class MaxSizeRemoteHttpMessageBodyWriter extends MaxSizeLocalHttpMessageB protected final HttpMessageStateSupplier httpMessageStateSupplier; - public MaxSizeRemoteHttpMessageBodyWriter(JsonFactory jsonFactory, byte[] input, int maxSize, HttpMessageStateSupplier httpMessageStateSupplier) { - super(jsonFactory, input, maxSize); + public MaxSizeRemoteHttpMessageBodyWriter(JsonMapper jsonMapper, byte[] input, int maxSize, HttpMessageStateSupplier httpMessageStateSupplier) { + super(jsonMapper, input, maxSize); this.httpMessageStateSupplier = httpMessageStateSupplier; } diff --git a/request-response/logbook/src/main/java/no/entur/logging/cloud/logbook/ondemand/OndemandLogLevelLogstashLogbackSink.java b/request-response/logbook/src/main/java/no/entur/logging/cloud/logbook/ondemand/OndemandLogLevelLogstashLogbackSink.java index e87e0f5c..c0c7bc36 100644 --- a/request-response/logbook/src/main/java/no/entur/logging/cloud/logbook/ondemand/OndemandLogLevelLogstashLogbackSink.java +++ b/request-response/logbook/src/main/java/no/entur/logging/cloud/logbook/ondemand/OndemandLogLevelLogstashLogbackSink.java @@ -1,6 +1,5 @@ package no.entur.logging.cloud.logbook.ondemand; -import com.fasterxml.jackson.core.JsonFactory; import no.entur.logging.cloud.logbook.AbstractLogLevelLogstashLogbackSink; import no.entur.logging.cloud.logbook.DefaultRemoteHttpMessageContextSupplier; import no.entur.logging.cloud.logbook.MessageComposer; @@ -10,6 +9,7 @@ import no.entur.logging.cloud.logbook.ondemand.state.ResponseHttpMessageStateSupplierSource; import org.slf4j.Marker; import org.zalando.logbook.*; +import tools.jackson.databind.json.JsonMapper; import java.io.IOException; import java.nio.charset.StandardCharsets; @@ -44,24 +44,24 @@ public OndemandLogLevelLogstashLogbackSink build() { if (level == null) { throw new IllegalStateException("Expected log level"); } - if (jsonFactory == null) { - jsonFactory = new JsonFactory(); + if (jsonMapper == null) { + jsonMapper = JsonMapper.builder().build(); } if (remoteHttpMessageContextSupplier == null) { remoteHttpMessageContextSupplier = new DefaultRemoteHttpMessageContextSupplier(); } return new OndemandLogLevelLogstashLogbackSink(loggerToBiConsumer(), logEnabledToBooleanSupplier(), - jsonFactory, requestBodyWellformedDecisionSupplier, responseBodyWellformedDecisionSupplier, + jsonMapper, requestBodyWellformedDecisionSupplier, responseBodyWellformedDecisionSupplier, maxBodySize, maxSize, remoteHttpMessageContextSupplier, server, client); } } public OndemandLogLevelLogstashLogbackSink(BiConsumer logConsumer, BooleanSupplier logLevelEnabled, - JsonFactory jsonFactory, RequestHttpMessageStateSupplierSource requestHttpMessageStateSupplierSource, + JsonMapper jsonMapper, RequestHttpMessageStateSupplierSource requestHttpMessageStateSupplierSource, ResponseHttpMessageStateSupplierSource responseHttpMessageStateSupplierSource, int maxBodySize, int maxSize, RemoteHttpMessageContextSupplier remoteHttpMessageContextSupplier, MessageComposer server, MessageComposer client) { - super(logConsumer, logLevelEnabled, jsonFactory, requestHttpMessageStateSupplierSource, + super(logConsumer, logLevelEnabled, jsonMapper, requestHttpMessageStateSupplierSource, responseHttpMessageStateSupplierSource, maxBodySize, maxSize, remoteHttpMessageContextSupplier, server, client); } @@ -78,7 +78,7 @@ public Marker createRequestMarker(HttpRequest request) { if (body.length < maxBodySize) { writer = new LocalHttpMessageBodyWriter(body); } else { - writer = new MaxSizeLocalHttpMessageBodyWriter(jsonFactory, body, maxBodySize); + writer = new MaxSizeLocalHttpMessageBodyWriter(jsonMapper, body, maxBodySize); } } else { boolean verify = remoteHttpMessageContextSupplier.verifyJsonSyntax(request); @@ -86,9 +86,9 @@ public Marker createRequestMarker(HttpRequest request) { HttpMessageStateSupplier httpMessageStateSupplier = requestHttpMessageStateSupplierSource .get(); if (body.length < maxBodySize) { - writer = new RemoteHttpMessageBodyWriter(jsonFactory, body, httpMessageStateSupplier); + writer = new RemoteHttpMessageBodyWriter(jsonMapper, body, httpMessageStateSupplier); } else { - writer = new MaxSizeRemoteHttpMessageBodyWriter(jsonFactory, body, maxSize, + writer = new MaxSizeRemoteHttpMessageBodyWriter(jsonMapper, body, maxSize, httpMessageStateSupplier); } } else { @@ -96,7 +96,7 @@ public Marker createRequestMarker(HttpRequest request) { if (body.length < maxBodySize) { writer = new LocalHttpMessageBodyWriter(body); } else { - writer = new MaxSizeLocalHttpMessageBodyWriter(jsonFactory, body, maxBodySize); + writer = new MaxSizeLocalHttpMessageBodyWriter(jsonMapper, body, maxBodySize); } } } @@ -136,7 +136,7 @@ public Marker createResponseMarker(Correlation correlation, HttpResponse respons if (body.length < maxBodySize) { writer = new LocalHttpMessageBodyWriter(body); } else { - writer = new MaxSizeLocalHttpMessageBodyWriter(jsonFactory, body, maxBodySize); + writer = new MaxSizeLocalHttpMessageBodyWriter(jsonMapper, body, maxBodySize); } } else { boolean verify = remoteHttpMessageContextSupplier.verifyJsonSyntax(response); @@ -144,9 +144,9 @@ public Marker createResponseMarker(Correlation correlation, HttpResponse respons HttpMessageStateSupplier httpMessageStateSupplier = responseHttpMessageStateSupplierSource .get(); if (body.length < maxBodySize) { - writer = new RemoteHttpMessageBodyWriter(jsonFactory, body, httpMessageStateSupplier); + writer = new RemoteHttpMessageBodyWriter(jsonMapper, body, httpMessageStateSupplier); } else { - writer = new MaxSizeRemoteHttpMessageBodyWriter(jsonFactory, body, maxSize, + writer = new MaxSizeRemoteHttpMessageBodyWriter(jsonMapper, body, maxSize, httpMessageStateSupplier); } } else { @@ -154,7 +154,7 @@ public Marker createResponseMarker(Correlation correlation, HttpResponse respons if (body.length < maxBodySize) { writer = new LocalHttpMessageBodyWriter(body); } else { - writer = new MaxSizeLocalHttpMessageBodyWriter(jsonFactory, body, maxBodySize); + writer = new MaxSizeLocalHttpMessageBodyWriter(jsonMapper, body, maxBodySize); } } } diff --git a/request-response/logbook/src/main/java/no/entur/logging/cloud/logbook/ondemand/RemoteHttpMessageBodyWriter.java b/request-response/logbook/src/main/java/no/entur/logging/cloud/logbook/ondemand/RemoteHttpMessageBodyWriter.java index d8679e91..184d3fd2 100644 --- a/request-response/logbook/src/main/java/no/entur/logging/cloud/logbook/ondemand/RemoteHttpMessageBodyWriter.java +++ b/request-response/logbook/src/main/java/no/entur/logging/cloud/logbook/ondemand/RemoteHttpMessageBodyWriter.java @@ -1,11 +1,11 @@ package no.entur.logging.cloud.logbook.ondemand; -import com.fasterxml.jackson.core.JsonFactory; -import com.fasterxml.jackson.core.JsonGenerator; -import com.fasterxml.jackson.core.JsonParser; +import tools.jackson.core.JsonGenerator; import no.entur.logging.cloud.logbook.ondemand.state.HttpMessageState; import no.entur.logging.cloud.logbook.ondemand.state.HttpMessageStateResult; import no.entur.logging.cloud.logbook.ondemand.state.HttpMessageStateSupplier; +import tools.jackson.core.JsonParser; +import tools.jackson.databind.json.JsonMapper; import java.io.ByteArrayInputStream; import java.io.IOException; @@ -16,12 +16,12 @@ public class RemoteHttpMessageBodyWriter extends LocalHttpMessageBodyWriter { protected final HttpMessageStateSupplier httpMessageStateSupplier; protected volatile HttpMessageStateResult output; - protected final JsonFactory jsonFactory; + protected final JsonMapper jsonMapper; - public RemoteHttpMessageBodyWriter(JsonFactory jsonFactory, byte[] input, HttpMessageStateSupplier httpMessageStateSupplier) { + public RemoteHttpMessageBodyWriter(JsonMapper jsonMapper, byte[] input, HttpMessageStateSupplier httpMessageStateSupplier) { super(input); - this.jsonFactory = jsonFactory; + this.jsonMapper = jsonMapper; this.httpMessageStateSupplier = httpMessageStateSupplier; } @@ -49,15 +49,15 @@ public void writeBody(JsonGenerator generator) throws IOException { this.output = output = createOutput(); } if(output.isWellformed()) { - generator.writeFieldName("body"); + generator.writeName("body"); generator.writeRawValue(output.getBody()); } else { - generator.writeStringField("body", output.getBody()); + generator.writeStringProperty("body", output.getBody()); } } protected boolean isWellformedJson() { - try (JsonParser parser = jsonFactory.createParser(new ByteArrayInputStream(input))) { + try (JsonParser parser = jsonMapper.createParser(new ByteArrayInputStream(input))) { while(parser.nextToken() != null); } catch(Exception e) { return false; diff --git a/request-response/logbook/src/main/java/no/entur/logging/cloud/logbook/ondemand/RequestOndemandSingleFieldAppendingMarker.java b/request-response/logbook/src/main/java/no/entur/logging/cloud/logbook/ondemand/RequestOndemandSingleFieldAppendingMarker.java index 405661f8..5112cfb1 100644 --- a/request-response/logbook/src/main/java/no/entur/logging/cloud/logbook/ondemand/RequestOndemandSingleFieldAppendingMarker.java +++ b/request-response/logbook/src/main/java/no/entur/logging/cloud/logbook/ondemand/RequestOndemandSingleFieldAppendingMarker.java @@ -1,6 +1,6 @@ package no.entur.logging.cloud.logbook.ondemand; -import com.fasterxml.jackson.core.JsonGenerator; +import tools.jackson.core.JsonGenerator; import net.logstash.logback.marker.SingleFieldAppendingMarker; import org.zalando.logbook.HttpRequest; import org.zalando.logbook.Origin; @@ -46,22 +46,22 @@ protected void prepareForDeferredProcessing(HttpRequest message) { } @Override - protected void writeFieldValue(JsonGenerator generator) throws IOException { + protected void writeFieldValue(JsonGenerator generator) { generator.writeStartObject(); - generator.writeStringField("origin", origin); - generator.writeStringField("type", "request"); - generator.writeStringField("protocol", protocol); - generator.writeStringField("remote", remote); - generator.writeStringField("method", method); - generator.writeStringField("uri", uri); - generator.writeStringField("host", host); - generator.writeStringField("path", path); - generator.writeStringField("scheme", scheme); + generator.writeStringProperty("origin", origin); + generator.writeStringProperty("type", "request"); + generator.writeStringProperty("protocol", protocol); + generator.writeStringProperty("remote", remote); + generator.writeStringProperty("method", method); + generator.writeStringProperty("uri", uri); + generator.writeStringProperty("host", host); + generator.writeStringProperty("path", path); + generator.writeStringProperty("scheme", scheme); if(port.isEmpty()) { - generator.writeNumberField("port", 80); + generator.writeNumberProperty("port", 80); } else { - generator.writeNumberField("port", port.get()); + generator.writeNumberProperty("port", port.get()); } writeHeaders(generator); diff --git a/request-response/logbook/src/main/java/no/entur/logging/cloud/logbook/ondemand/ResponseOndemandSingleFieldAppendingMarker.java b/request-response/logbook/src/main/java/no/entur/logging/cloud/logbook/ondemand/ResponseOndemandSingleFieldAppendingMarker.java index 00ae2e66..5e22ea5a 100644 --- a/request-response/logbook/src/main/java/no/entur/logging/cloud/logbook/ondemand/ResponseOndemandSingleFieldAppendingMarker.java +++ b/request-response/logbook/src/main/java/no/entur/logging/cloud/logbook/ondemand/ResponseOndemandSingleFieldAppendingMarker.java @@ -1,6 +1,6 @@ package no.entur.logging.cloud.logbook.ondemand; -import com.fasterxml.jackson.core.JsonGenerator; +import tools.jackson.core.JsonGenerator; import net.logstash.logback.marker.SingleFieldAppendingMarker; import org.zalando.logbook.HttpResponse; import org.zalando.logbook.Origin; @@ -36,20 +36,20 @@ protected void prepareForDeferredProcessing(HttpResponse message) { } @Override - protected void writeFieldValue(JsonGenerator generator) throws IOException { + protected void writeFieldValue(JsonGenerator generator) { generator.writeStartObject(); if(origin != null) { - generator.writeStringField("origin", origin); + generator.writeStringProperty("origin", origin); } - generator.writeStringField("type", "response"); + generator.writeStringProperty("type", "response"); if(duration != null) { - generator.writeNumberField("duration", duration.toMillis()); + generator.writeNumberProperty("duration", duration.toMillis()); } if(protocol != null) { - generator.writeStringField("protocol", protocol); + generator.writeStringProperty("protocol", protocol); } - generator.writeNumberField("status", status); + generator.writeNumberProperty("status", status); writeHeaders(generator); writeBody(generator); diff --git a/request-response/logbook/src/main/java/no/entur/logging/cloud/logbook/ondemand/StringHttpMessageBodyWriter.java b/request-response/logbook/src/main/java/no/entur/logging/cloud/logbook/ondemand/StringHttpMessageBodyWriter.java index 586ac29b..90a5f9b4 100644 --- a/request-response/logbook/src/main/java/no/entur/logging/cloud/logbook/ondemand/StringHttpMessageBodyWriter.java +++ b/request-response/logbook/src/main/java/no/entur/logging/cloud/logbook/ondemand/StringHttpMessageBodyWriter.java @@ -1,6 +1,6 @@ package no.entur.logging.cloud.logbook.ondemand; -import com.fasterxml.jackson.core.JsonGenerator; +import tools.jackson.core.JsonGenerator; import java.io.IOException; import java.nio.charset.StandardCharsets; @@ -20,7 +20,7 @@ public void prepareResult() { @Override public void writeBody(JsonGenerator generator) throws IOException { - generator.writeStringField("body", input); + generator.writeStringProperty("body", input); } } diff --git a/request-response/logbook/src/main/java/no/entur/logging/cloud/logbook/util/JsonValidator.java b/request-response/logbook/src/main/java/no/entur/logging/cloud/logbook/util/JsonValidator.java index 70ebac73..b6c100bd 100644 --- a/request-response/logbook/src/main/java/no/entur/logging/cloud/logbook/util/JsonValidator.java +++ b/request-response/logbook/src/main/java/no/entur/logging/cloud/logbook/util/JsonValidator.java @@ -1,20 +1,20 @@ package no.entur.logging.cloud.logbook.util; -import com.fasterxml.jackson.core.JsonFactory; -import com.fasterxml.jackson.core.JsonParser; +import tools.jackson.core.JsonParser; +import tools.jackson.databind.json.JsonMapper; import java.io.StringReader; public class JsonValidator { - private final JsonFactory jsonFactory; + private final JsonMapper jsonMapper; - public JsonValidator(JsonFactory jsonFactory) { - this.jsonFactory = jsonFactory; + public JsonValidator(JsonMapper jsonMapper) { + this.jsonMapper = jsonMapper; } public boolean isWellformedJson(String input) { - try (JsonParser parser = jsonFactory.createParser(new StringReader(input))) { + try (JsonParser parser = jsonMapper.createParser(new StringReader(input))) { while(parser.nextToken() != null); } catch(Exception e) { return false; diff --git a/request-response/logbook/src/main/java/no/entur/logging/cloud/logbook/util/MaxSizeJsonFilter.java b/request-response/logbook/src/main/java/no/entur/logging/cloud/logbook/util/MaxSizeJsonFilter.java index 0cfff370..1b4e4cd9 100644 --- a/request-response/logbook/src/main/java/no/entur/logging/cloud/logbook/util/MaxSizeJsonFilter.java +++ b/request-response/logbook/src/main/java/no/entur/logging/cloud/logbook/util/MaxSizeJsonFilter.java @@ -1,7 +1,11 @@ package no.entur.logging.cloud.logbook.util; -import com.fasterxml.jackson.core.*; import org.apache.commons.io.output.StringBuilderWriter; +import tools.jackson.core.JsonGenerator; +import tools.jackson.core.JsonParser; +import tools.jackson.core.JsonToken; +import tools.jackson.core.TokenStreamContext; +import tools.jackson.databind.json.JsonMapper; import java.io.IOException; import java.util.function.LongSupplier; @@ -15,26 +19,26 @@ public class MaxSizeJsonFilter { - public static MaxSizeJsonFilter newInstance(int maxBodySize, JsonFactory jsonFactory) { - return new MaxSizeJsonFilter(maxBodySize, jsonFactory); + public static MaxSizeJsonFilter newInstance(int maxBodySize, JsonMapper jsonMapper) { + return new MaxSizeJsonFilter(maxBodySize, jsonMapper); } - private JsonFactory factory; + private JsonMapper jsonMapper; private final int maxBodySize; - public MaxSizeJsonFilter(int maxBodySize, JsonFactory jsonFactory) { + public MaxSizeJsonFilter(int maxBodySize, JsonMapper jsonMapper) { this.maxBodySize = maxBodySize; - this.factory = jsonFactory; + this.jsonMapper = jsonMapper; } public String transform(String body) throws IOException { StringBuilder output = new StringBuilder(maxBodySize + 128); try ( - final JsonParser parser = factory.createParser(body); + final JsonParser parser = jsonMapper.createParser(body); StringBuilderWriter writer = new StringBuilderWriter(output); - JsonGenerator generator = factory.createGenerator(writer); + JsonGenerator generator = jsonMapper.createGenerator(writer); ) { - process(parser, generator, () -> generator.getOutputBuffered() + output.length()); + process(parser, generator, () -> generator.streamWriteOutputBuffered() + output.length()); generator.flush(); return writer.toString(); @@ -46,11 +50,11 @@ public String transform(String body) throws IOException { public String transform(byte[] body) throws IOException { StringBuilder output = new StringBuilder(maxBodySize + 128); try ( - final JsonParser parser = factory.createParser(body); + final JsonParser parser = jsonMapper.createParser(body); StringBuilderWriter writer = new StringBuilderWriter(output); - JsonGenerator generator = factory.createGenerator(writer); + JsonGenerator generator = jsonMapper.createGenerator(writer); ) { - process(parser, generator, () -> generator.getOutputBuffered() + output.length()); + process(parser, generator, () -> generator.streamWriteOutputBuffered() + output.length()); generator.flush(); return writer.toString(); @@ -74,7 +78,7 @@ public void process(final JsonParser parser, JsonGenerator generator, LongSuppli if(nextToken == null) { break; } - if(nextToken == JsonToken.FIELD_NAME) { + if(nextToken == JsonToken.PROPERTY_NAME) { fieldName = parser.currentName(); continue; @@ -100,11 +104,11 @@ public void process(final JsonParser parser, JsonGenerator generator, LongSuppli if(outputSize + size >= maxSize) { // write notification - JsonStreamContext ctxt = generator.getOutputContext(); + TokenStreamContext ctxt = generator.streamWriteContext(); if (ctxt.inArray()) { generator.writeString("Logger: " + message); } else if (ctxt.inObject()) { - generator.writeStringField("Logger", message); + generator.writeStringProperty("Logger", message); } generator.close(); @@ -113,7 +117,7 @@ public void process(final JsonParser parser, JsonGenerator generator, LongSuppli } if(fieldName != null) { - generator.writeFieldName(fieldName); + generator.writeName(fieldName); fieldName = null; } diff --git a/request-response/logbook/src/test/java/no/entur/logging/cloud/logbook/AbstractLogLevelLogstashLogbackSinkTest.java b/request-response/logbook/src/test/java/no/entur/logging/cloud/logbook/AbstractLogLevelLogstashLogbackSinkTest.java index eb03e85d..b098e958 100644 --- a/request-response/logbook/src/test/java/no/entur/logging/cloud/logbook/AbstractLogLevelLogstashLogbackSinkTest.java +++ b/request-response/logbook/src/test/java/no/entur/logging/cloud/logbook/AbstractLogLevelLogstashLogbackSinkTest.java @@ -1,13 +1,12 @@ package no.entur.logging.cloud.logbook; -import com.fasterxml.jackson.core.JsonFactory; -import com.fasterxml.jackson.databind.MappingJsonFactory; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; import org.slf4j.Marker; import org.zalando.logbook.HttpRequest; import org.zalando.logbook.HttpResponse; import org.zalando.logbook.Origin; +import tools.jackson.databind.json.JsonMapper; import java.io.IOException; import java.time.Duration; @@ -20,8 +19,8 @@ public class AbstractLogLevelLogstashLogbackSinkTest { public static class MockLogLevelLogstashLogbackSink extends AbstractLogLevelLogstashLogbackSink { - public MockLogLevelLogstashLogbackSink(BiConsumer logConsumer, BooleanSupplier logLevelEnabled, JsonFactory jsonFactory, int maxSize, RemoteHttpMessageContextSupplier remoteHttpMessageContextSupplier, MessageComposer server, MessageComposer client) { - super(logConsumer, logLevelEnabled, jsonFactory, maxSize, remoteHttpMessageContextSupplier, server, client); + public MockLogLevelLogstashLogbackSink(BiConsumer logConsumer, BooleanSupplier logLevelEnabled, JsonMapper jsonMapper, int maxSize, RemoteHttpMessageContextSupplier remoteHttpMessageContextSupplier, MessageComposer server, MessageComposer client) { + super(logConsumer, logLevelEnabled, jsonMapper, maxSize, remoteHttpMessageContextSupplier, server, client); } @Override @@ -181,7 +180,8 @@ private MockLogLevelLogstashLogbackSink createSink() { MessageComposer server = mock(MessageComposer.class); MessageComposer client = mock(MessageComposer.class); BooleanSupplier logLevelEnabled = () -> true; - MockLogLevelLogstashLogbackSink sink = new MockLogLevelLogstashLogbackSink(logConsumer, logLevelEnabled, new MappingJsonFactory(), maxSize, remoteHttpMessageContextSupplier, server, client); + + MockLogLevelLogstashLogbackSink sink = new MockLogLevelLogstashLogbackSink(logConsumer, logLevelEnabled, JsonMapper.builder().build(), maxSize, remoteHttpMessageContextSupplier, server, client); return spy(sink); } diff --git a/request-response/logbook/src/test/java/no/entur/logging/cloud/logbook/util/MaxSizeJsonFilterTest.java b/request-response/logbook/src/test/java/no/entur/logging/cloud/logbook/util/MaxSizeJsonFilterTest.java index d79f9755..605c8c3c 100644 --- a/request-response/logbook/src/test/java/no/entur/logging/cloud/logbook/util/MaxSizeJsonFilterTest.java +++ b/request-response/logbook/src/test/java/no/entur/logging/cloud/logbook/util/MaxSizeJsonFilterTest.java @@ -1,9 +1,10 @@ package no.entur.logging.cloud.logbook.util; -import com.fasterxml.jackson.core.JsonFactory; -import com.fasterxml.jackson.core.JsonGenerator; +import tools.jackson.core.JsonGenerator; import org.apache.commons.io.IOUtils; import org.junit.jupiter.api.Test; +import tools.jackson.core.json.JsonFactory; +import tools.jackson.databind.json.JsonMapper; import java.io.CharArrayWriter; import java.io.IOException; @@ -16,7 +17,7 @@ public class MaxSizeJsonFilterTest { private static final int MAX_BODY_SIZE = 14 * 1024; - private final MaxSizeJsonFilter filter = new MaxSizeJsonFilter(MAX_BODY_SIZE, new JsonFactory()); + private final MaxSizeJsonFilter filter = new MaxSizeJsonFilter(MAX_BODY_SIZE, JsonMapper.builder().build()); @Test public void testFilterTooBig() throws IOException { @@ -51,11 +52,11 @@ private String generateLongJson(int size) throws IOException { JsonGenerator generator = factory.createGenerator(writer); generator.writeStartObject(); - generator.writeStringField("start", "here"); + generator.writeStringProperty("start", "here"); for(int i = 0; i < size; i += chunkSize) { - generator.writeStringField("longValue", generateLongString(chunkSize)); + generator.writeStringProperty("longValue", generateLongString(chunkSize)); } - generator.writeStringField("end", "here"); + generator.writeStringProperty("end", "here"); generator.writeEndObject(); generator.flush(); diff --git a/request-response/netty-grpc-test/build.gradle b/request-response/netty-grpc-test/build.gradle index 81e0a8ea..959c79d2 100644 --- a/request-response/netty-grpc-test/build.gradle +++ b/request-response/netty-grpc-test/build.gradle @@ -3,11 +3,11 @@ dependencies { api project(':request-response:netty-grpc') api project(":test:test-logback") - api ("org.entur.jackson:jackson-syntax-highlight:${jacksonSyntaxHighlightVersion}") + api ("org.entur.jackson:jackson-tools-syntax-highlight:${jacksonSyntaxHighlightVersion}") api ("org.entur.logback-logstash-syntax-highlighting-decorators:logback-logstash-syntax-highlighting-decorators:${logbackLogstashSyntaxHighlightingDecoratorsVersion}") api ("net.logstash.logback:logstash-logback-encoder:${logbackLogstashVersion}") - api("com.fasterxml.jackson.core:jackson-core") + api("tools.jackson.core:jackson-core") api("org.apache.commons:commons-text:${commonsTextVersion}") diff --git a/request-response/netty-grpc-test/src/main/java/no/entur/logging/cloud/rr/grpc/test/PrettyPrintingGrpcSink.java b/request-response/netty-grpc-test/src/main/java/no/entur/logging/cloud/rr/grpc/test/PrettyPrintingGrpcSink.java index 9036c9d0..4a4ae15f 100644 --- a/request-response/netty-grpc-test/src/main/java/no/entur/logging/cloud/rr/grpc/test/PrettyPrintingGrpcSink.java +++ b/request-response/netty-grpc-test/src/main/java/no/entur/logging/cloud/rr/grpc/test/PrettyPrintingGrpcSink.java @@ -1,11 +1,10 @@ package no.entur.logging.cloud.rr.grpc.test; -import com.fasterxml.jackson.core.JsonFactory; -import com.fasterxml.jackson.core.JsonGenerator; -import com.fasterxml.jackson.core.JsonParser; -import org.entur.jackson.jsh.AnsiSyntaxHighlight; -import org.entur.jackson.jsh.SyntaxHighlighter; -import org.entur.jackson.jsh.SyntaxHighlightingJsonGenerator; +import org.entur.jackson.tools.jsh.AnsiSyntaxHighlight; +import org.entur.jackson.tools.jsh.SyntaxHighlighter; +import org.entur.jackson.tools.jsh.SyntaxHighlightingJsonGenerator; +import org.entur.jackson.tools.jsh.SyntaxHighlightingPrettyPrinter; +import tools.jackson.core.JsonGenerator; import no.entur.logging.cloud.rr.grpc.AbstractSinkBuilder; import no.entur.logging.cloud.rr.grpc.LogbackLogstashGrpcSink; import no.entur.logging.cloud.rr.grpc.message.GrpcConnect; @@ -13,6 +12,11 @@ import no.entur.logging.cloud.rr.grpc.message.GrpcRequest; import no.entur.logging.cloud.rr.grpc.message.GrpcResponse; import org.slf4j.Marker; +import tools.jackson.core.JsonParser; +import tools.jackson.core.PrettyPrinter; +import tools.jackson.core.json.JsonFactory; +import tools.jackson.databind.SerializationFeature; +import tools.jackson.databind.json.JsonMapper; import java.io.IOException; import java.io.StringWriter; @@ -44,19 +48,24 @@ public PrettyPrintingGrpcSink build() { throw new IllegalStateException("Expected Json syntax highlighter level"); } - return new PrettyPrintingGrpcSink(logEnabledToBooleanSupplier(), loggerToBiConsumer(), new JsonFactory(), syntaxHighlighter); + JsonMapper mapper = JsonMapper.builder().defaultPrettyPrinter(new SyntaxHighlightingPrettyPrinter(syntaxHighlighter)) + .configure(SerializationFeature.INDENT_OUTPUT, true) + .build(); + + return new PrettyPrintingGrpcSink(logEnabledToBooleanSupplier(), loggerToBiConsumer(), mapper, syntaxHighlighter); } } + protected final BiConsumer logConsumer; - protected final JsonFactory jsonFactory; + protected final JsonMapper mapper; protected final SyntaxHighlighter syntaxHighlighter; - public PrettyPrintingGrpcSink(BooleanSupplier logLevelEnabled, BiConsumer logConsumer, JsonFactory jsonFactory, SyntaxHighlighter syntaxHighlighter) { + public PrettyPrintingGrpcSink(BooleanSupplier logLevelEnabled, BiConsumer logConsumer, JsonMapper mapper, SyntaxHighlighter syntaxHighlighter) { super(logConsumer, logLevelEnabled); this.logConsumer = logConsumer; - this.jsonFactory = jsonFactory; + this.mapper = mapper; this.syntaxHighlighter = syntaxHighlighter; } @@ -167,11 +176,13 @@ public String prettyPrint(String body) { if (body != null && body.length() > 0) { try ( - JsonParser parser = jsonFactory.createParser(body); - StringWriter writer = new StringWriter(body.length() * 2); - JsonGenerator generator = jsonFactory.createGenerator(writer); + JsonParser parser = mapper.createParser(body); + StringWriter writer = new StringWriter(body.length() * 2); + JsonGenerator generator = mapper.createGenerator(writer); ) { - JsonGenerator jsonGenerator = new SyntaxHighlightingJsonGenerator(generator, syntaxHighlighter,true); + SyntaxHighlightingPrettyPrinter prettyPrinter = (SyntaxHighlightingPrettyPrinter) generator.getPrettyPrinter(); + + JsonGenerator jsonGenerator = new SyntaxHighlightingJsonGenerator(generator, prettyPrinter, prettyPrinter.getObjectIndenter(), prettyPrinter.getArrayIndenter(), prettyPrinter.getSyntaxHighlighter()); while (parser.nextToken() != null) { jsonGenerator.copyCurrentEvent(parser); } diff --git a/request-response/netty-grpc-test/src/main/java/no/entur/logging/cloud/rr/grpc/test/PrettyPrintingRequestSingleFieldAppendingMarker.java b/request-response/netty-grpc-test/src/main/java/no/entur/logging/cloud/rr/grpc/test/PrettyPrintingRequestSingleFieldAppendingMarker.java index 5f980d38..d75f2dde 100644 --- a/request-response/netty-grpc-test/src/main/java/no/entur/logging/cloud/rr/grpc/test/PrettyPrintingRequestSingleFieldAppendingMarker.java +++ b/request-response/netty-grpc-test/src/main/java/no/entur/logging/cloud/rr/grpc/test/PrettyPrintingRequestSingleFieldAppendingMarker.java @@ -1,11 +1,12 @@ package no.entur.logging.cloud.rr.grpc.test; -import com.fasterxml.jackson.core.JsonFactory; -import com.fasterxml.jackson.core.JsonGenerator; -import com.fasterxml.jackson.core.JsonParser; -import com.fasterxml.jackson.core.PrettyPrinter; +import tools.jackson.core.JsonGenerator; import no.entur.logging.cloud.rr.grpc.marker.GrpcRequestMarker; import no.entur.logging.cloud.rr.grpc.message.GrpcRequest; +import tools.jackson.core.JsonParser; +import tools.jackson.core.PrettyPrinter; +import tools.jackson.core.TokenStreamFactory; +import tools.jackson.core.json.JsonFactory; import java.io.IOException; @@ -17,14 +18,14 @@ public PrettyPrintingRequestSingleFieldAppendingMarker(GrpcRequest message) { } @Override - protected void writeBodyField(JsonGenerator generator, String body) throws IOException { - generator.writeFieldName("body"); + protected void writeBodyField(JsonGenerator generator, String body) { + generator.writeName("body"); final PrettyPrinter prettyPrinter = generator.getPrettyPrinter(); if (prettyPrinter == null || isRawStringValue(body)) { generator.writeRawValue(body); } else { - final JsonFactory factory = generator.getCodec().getFactory(); + final TokenStreamFactory factory = generator.objectWriteContext().tokenStreamFactory(); // append to existing tree event by event try (final JsonParser parser = factory.createParser(body)) { diff --git a/request-response/netty-grpc-test/src/main/java/no/entur/logging/cloud/rr/grpc/test/PrettyPrintingResponseSingleFieldAppendingMarker.java b/request-response/netty-grpc-test/src/main/java/no/entur/logging/cloud/rr/grpc/test/PrettyPrintingResponseSingleFieldAppendingMarker.java index 73cfd7be..c77d68bf 100644 --- a/request-response/netty-grpc-test/src/main/java/no/entur/logging/cloud/rr/grpc/test/PrettyPrintingResponseSingleFieldAppendingMarker.java +++ b/request-response/netty-grpc-test/src/main/java/no/entur/logging/cloud/rr/grpc/test/PrettyPrintingResponseSingleFieldAppendingMarker.java @@ -1,11 +1,13 @@ package no.entur.logging.cloud.rr.grpc.test; -import com.fasterxml.jackson.core.JsonFactory; -import com.fasterxml.jackson.core.JsonGenerator; -import com.fasterxml.jackson.core.JsonParser; -import com.fasterxml.jackson.core.PrettyPrinter; +import tools.jackson.core.JsonGenerator; import no.entur.logging.cloud.rr.grpc.marker.GrpcResponseMarker; import no.entur.logging.cloud.rr.grpc.message.GrpcResponse; +import tools.jackson.core.JsonParser; +import tools.jackson.core.PrettyPrinter; +import tools.jackson.core.TokenStreamFactory; +import tools.jackson.core.json.JsonFactory; + import java.io.IOException; public class PrettyPrintingResponseSingleFieldAppendingMarker extends GrpcResponseMarker { @@ -15,14 +17,14 @@ public PrettyPrintingResponseSingleFieldAppendingMarker(GrpcResponse message) { } @Override - protected void writeBodyField(JsonGenerator generator, String body) throws IOException { - generator.writeFieldName("body"); + protected void writeBodyField(JsonGenerator generator, String body) { + generator.writeName("body"); final PrettyPrinter prettyPrinter = generator.getPrettyPrinter(); if (prettyPrinter == null || isRawStringValue(body)) { generator.writeRawValue(body); } else { - final JsonFactory factory = generator.getCodec().getFactory(); + final TokenStreamFactory factory = generator.objectWriteContext().tokenStreamFactory(); // append to existing tree event by event try (final JsonParser parser = factory.createParser(body)) { diff --git a/request-response/netty-grpc/build.gradle b/request-response/netty-grpc/build.gradle index 31bf2d38..d30cb92b 100644 --- a/request-response/netty-grpc/build.gradle +++ b/request-response/netty-grpc/build.gradle @@ -8,7 +8,7 @@ dependencies { api("com.fasterxml.jackson.core:jackson-databind") api("com.fasterxml.jackson.core:jackson-annotations") - api("com.fasterxml.jackson.core:jackson-core") + api("tools.jackson.core:jackson-core") api("io.grpc:grpc-netty:${grpcNettyVersion}") api("io.grpc:grpc-services:${grpcNettyVersion}") diff --git a/request-response/netty-grpc/src/main/java/no/entur/logging/cloud/rr/grpc/mapper/DefaultMetadataJsonMapper.java b/request-response/netty-grpc/src/main/java/no/entur/logging/cloud/rr/grpc/mapper/DefaultMetadataJsonMapper.java index 8eb86ff3..c41ab584 100644 --- a/request-response/netty-grpc/src/main/java/no/entur/logging/cloud/rr/grpc/mapper/DefaultMetadataJsonMapper.java +++ b/request-response/netty-grpc/src/main/java/no/entur/logging/cloud/rr/grpc/mapper/DefaultMetadataJsonMapper.java @@ -1,6 +1,6 @@ package no.entur.logging.cloud.rr.grpc.mapper; -import com.fasterxml.jackson.core.JsonGenerator; +import tools.jackson.core.JsonGenerator; import com.fasterxml.jackson.databind.SerializerProvider; import com.fasterxml.jackson.databind.annotation.JsonSerialize; import com.fasterxml.jackson.databind.ser.std.StdSerializer; @@ -72,7 +72,7 @@ protected RawSerializer() { } @Override - public void serialize(RawString value, JsonGenerator gen, SerializerProvider provider) throws IOException { + public void serialize(RawString value, com.fasterxml.jackson.core.JsonGenerator gen, SerializerProvider provider) throws IOException { gen.writeRaw(value.getString()); } } diff --git a/request-response/netty-grpc/src/main/java/no/entur/logging/cloud/rr/grpc/marker/GrpcConnectionMarker.java b/request-response/netty-grpc/src/main/java/no/entur/logging/cloud/rr/grpc/marker/GrpcConnectionMarker.java index 85f2ca9d..ed0936f2 100644 --- a/request-response/netty-grpc/src/main/java/no/entur/logging/cloud/rr/grpc/marker/GrpcConnectionMarker.java +++ b/request-response/netty-grpc/src/main/java/no/entur/logging/cloud/rr/grpc/marker/GrpcConnectionMarker.java @@ -1,6 +1,6 @@ package no.entur.logging.cloud.rr.grpc.marker; -import com.fasterxml.jackson.core.JsonGenerator; +import tools.jackson.core.JsonGenerator; import net.logstash.logback.marker.LogstashMarker; import no.entur.logging.cloud.rr.grpc.message.GrpcMessage; @@ -21,8 +21,8 @@ protected GrpcConnectionMarker(String name, T message) { } @Override - public void writeTo(JsonGenerator generator) throws IOException { - generator.writeFieldName("http"); + public void writeTo(JsonGenerator generator) { + generator.writeName("http"); generator.writeStartObject(); writeFields(generator); @@ -30,34 +30,34 @@ public void writeTo(JsonGenerator generator) throws IOException { generator.writeEndObject(); } - protected void writeFields(JsonGenerator generator) throws IOException { + protected void writeFields(JsonGenerator generator) { String uri = message.getUri(); if(uri != null) { - generator.writeFieldName("uri"); + generator.writeName("uri"); generator.writeString(uri); } String type = message.getType(); if(type != null) { - generator.writeFieldName("type"); + generator.writeName("type"); generator.writeString(type); } String remote = message.getRemote(); if(remote != null) { - generator.writeFieldName("remote"); + generator.writeName("remote"); generator.writeString(remote); } String origin = message.getOrigin(); if(origin != null) { - generator.writeFieldName("origin"); + generator.writeName("origin"); generator.writeString(origin); } Map headers = message.getHeaders(); - generator.writeFieldName("headers"); + generator.writeName("headers"); generator.writeStartObject(); if(headers != null) { @@ -65,7 +65,7 @@ protected void writeFields(JsonGenerator generator) throws IOException { String key = entry.getKey(); if(key != null && !key.isEmpty()) { - generator.writeFieldName(key.toLowerCase()); + generator.writeName(key.toLowerCase()); generator.writeStartArray(); Object value = entry.getValue(); @@ -73,10 +73,10 @@ protected void writeFields(JsonGenerator generator) throws IOException { if (value instanceof List) { List values = (List) value; for (Object listValue : values) { - generator.writeObject(listValue); + generator.writePOJO(listValue); } } else { - generator.writeObject(value); + generator.writePOJO(value); } } generator.writeEndArray(); diff --git a/request-response/netty-grpc/src/main/java/no/entur/logging/cloud/rr/grpc/marker/GrpcRequestMarker.java b/request-response/netty-grpc/src/main/java/no/entur/logging/cloud/rr/grpc/marker/GrpcRequestMarker.java index 680d3eb9..1d1f382b 100644 --- a/request-response/netty-grpc/src/main/java/no/entur/logging/cloud/rr/grpc/marker/GrpcRequestMarker.java +++ b/request-response/netty-grpc/src/main/java/no/entur/logging/cloud/rr/grpc/marker/GrpcRequestMarker.java @@ -1,6 +1,6 @@ package no.entur.logging.cloud.rr.grpc.marker; -import com.fasterxml.jackson.core.JsonGenerator; +import tools.jackson.core.JsonGenerator; import no.entur.logging.cloud.rr.grpc.message.GrpcRequest; import java.io.IOException; @@ -14,12 +14,12 @@ public GrpcRequestMarker(GrpcRequest message) { } @Override - protected void writeFields(JsonGenerator generator) throws IOException { + protected void writeFields(JsonGenerator generator) { super.writeFields(generator); long timeRemaining = message.getTimeRemainingUntilDeadlineInMilliseconds(); if(timeRemaining != -1L) { - generator.writeFieldName("deadline-in"); + generator.writeName("deadline-in"); generator.writeNumber(timeRemaining); } @@ -29,8 +29,8 @@ protected void writeFields(JsonGenerator generator) throws IOException { } } - protected void writeBodyField(JsonGenerator generator, String body) throws IOException { - generator.writeFieldName("body"); + protected void writeBodyField(JsonGenerator generator, String body) { + generator.writeName("body"); generator.writeRawValue(body); } diff --git a/request-response/netty-grpc/src/main/java/no/entur/logging/cloud/rr/grpc/marker/GrpcResponseMarker.java b/request-response/netty-grpc/src/main/java/no/entur/logging/cloud/rr/grpc/marker/GrpcResponseMarker.java index bd3006dc..14dedab3 100644 --- a/request-response/netty-grpc/src/main/java/no/entur/logging/cloud/rr/grpc/marker/GrpcResponseMarker.java +++ b/request-response/netty-grpc/src/main/java/no/entur/logging/cloud/rr/grpc/marker/GrpcResponseMarker.java @@ -1,6 +1,6 @@ package no.entur.logging.cloud.rr.grpc.marker; -import com.fasterxml.jackson.core.JsonGenerator; +import tools.jackson.core.JsonGenerator; import no.entur.logging.cloud.rr.grpc.message.GrpcResponse; import java.io.IOException; @@ -14,8 +14,8 @@ public GrpcResponseMarker(GrpcResponse message) { } @Override - protected void writeFields(JsonGenerator generator) throws IOException { - generator.writeFieldName("status"); + protected void writeFields(JsonGenerator generator) { + generator.writeName("status"); generator.writeNumber(message.getStatusCode().value()); super.writeFields(generator); @@ -26,8 +26,8 @@ protected void writeFields(JsonGenerator generator) throws IOException { } } - protected void writeBodyField(JsonGenerator generator, String body) throws IOException { - generator.writeFieldName("body"); + protected void writeBodyField(JsonGenerator generator, String body) { + generator.writeName("body"); generator.writeRawValue(body); } diff --git a/request-response/request-response-spring-boot-autoconfigure-grpc-ecosystem/README.md b/request-response/request-response-spring-boot-autoconfigure-grpc-ecosystem/README.md deleted file mode 100644 index 3d74e45c..00000000 --- a/request-response/request-response-spring-boot-autoconfigure-grpc-ecosystem/README.md +++ /dev/null @@ -1 +0,0 @@ -# request-response-logging for ecosystem grpc diff --git a/request-response/request-response-spring-boot-autoconfigure-grpc-ecosystem/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports b/request-response/request-response-spring-boot-autoconfigure-grpc-ecosystem/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports deleted file mode 100644 index 4e5237da..00000000 --- a/request-response/request-response-spring-boot-autoconfigure-grpc-ecosystem/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports +++ /dev/null @@ -1 +0,0 @@ -no.entur.logging.cloud.spring.grpc.ecosystem.RequestResponseGrpcEcosystemAutoConfiguration \ No newline at end of file diff --git a/request-response/request-response-spring-boot-autoconfigure-grpc-spring/README.md b/request-response/request-response-spring-boot-autoconfigure-grpc-spring/README.md new file mode 100644 index 00000000..75678b8b --- /dev/null +++ b/request-response/request-response-spring-boot-autoconfigure-grpc-spring/README.md @@ -0,0 +1 @@ +# request-response-logging for spring grpc diff --git a/request-response/request-response-spring-boot-autoconfigure-grpc-ecosystem/build.gradle b/request-response/request-response-spring-boot-autoconfigure-grpc-spring/build.gradle similarity index 83% rename from request-response/request-response-spring-boot-autoconfigure-grpc-ecosystem/build.gradle rename to request-response/request-response-spring-boot-autoconfigure-grpc-spring/build.gradle index 436831d5..9314618a 100644 --- a/request-response/request-response-spring-boot-autoconfigure-grpc-ecosystem/build.gradle +++ b/request-response/request-response-spring-boot-autoconfigure-grpc-spring/build.gradle @@ -10,7 +10,7 @@ dependencies { api ("org.springframework.boot:spring-boot-autoconfigure") api ("org.springframework.boot:spring-boot-starter-logging") - api("net.devh:grpc-server-spring-boot-starter:${ecosystemGrpcVersion}") + api("org.springframework.grpc:spring-grpc-server-spring-boot-starter:${springGrpcVersion}") testImplementation("org.springframework.boot:spring-boot-starter-test") } diff --git a/request-response/request-response-spring-boot-autoconfigure-grpc-spring/src/main/java/no/entur/logging/cloud/spring/grpc/ecosystem/RequestResponseExceptionHandlerGrpcSpringAutoConfiguration.java b/request-response/request-response-spring-boot-autoconfigure-grpc-spring/src/main/java/no/entur/logging/cloud/spring/grpc/ecosystem/RequestResponseExceptionHandlerGrpcSpringAutoConfiguration.java new file mode 100644 index 00000000..7fd52682 --- /dev/null +++ b/request-response/request-response-spring-boot-autoconfigure-grpc-spring/src/main/java/no/entur/logging/cloud/spring/grpc/ecosystem/RequestResponseExceptionHandlerGrpcSpringAutoConfiguration.java @@ -0,0 +1,39 @@ +package no.entur.logging.cloud.spring.grpc.ecosystem; + +import no.entur.logging.cloud.rr.grpc.GrpcSink; +import no.entur.logging.cloud.rr.grpc.filter.GrpcServerLoggingFilters; +import no.entur.logging.cloud.rr.grpc.mapper.GrpcMetadataJsonMapper; +import no.entur.logging.cloud.rr.grpc.mapper.GrpcPayloadJsonMapper; +import no.entur.logging.cloud.spring.rr.grpc.OrderedGrpcLoggingServerInterceptor; +import no.entur.logging.cloud.spring.rr.grpc.RequestResponseGrpcExceptionHandlerInterceptor; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.boot.autoconfigure.AutoConfigureAfter; +import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; +import org.springframework.boot.grpc.server.autoconfigure.exception.GrpcExceptionHandlerAutoConfiguration; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.grpc.server.exception.GrpcExceptionHandlerInterceptor; + +/** + * + * We need the proper error handling to run before the response is logged, i.e. to make sure no exception is thrown through the + * request-response interceptor, we wrap the system error handler to run in an additional interceptor and make it run first. + * . + * + */ + +@Configuration +@AutoConfigureAfter(GrpcExceptionHandlerAutoConfiguration.class) +public class RequestResponseExceptionHandlerGrpcSpringAutoConfiguration { + + @Value("${entur.logging.request-response.grpc.server.exception-handler.interceptor-order:0}") + private int exceptionInterceptorOrder; + + @Bean + @ConditionalOnProperty(name = {"entur.logging.request-response.grpc.server.exception-handler.enabled"}, havingValue = "true", matchIfMissing = true) + public RequestResponseGrpcExceptionHandlerInterceptor requestResponseGRpcExceptionHandlerInterceptor(GrpcExceptionHandlerInterceptor interceptor) { + return new RequestResponseGrpcExceptionHandlerInterceptor(interceptor, exceptionInterceptorOrder); + } + +} \ No newline at end of file diff --git a/request-response/request-response-spring-boot-autoconfigure-grpc-ecosystem/src/main/java/no/entur/logging/cloud/spring/grpc/ecosystem/RequestResponseGrpcEcosystemAutoConfiguration.java b/request-response/request-response-spring-boot-autoconfigure-grpc-spring/src/main/java/no/entur/logging/cloud/spring/grpc/ecosystem/RequestResponseGrpcSpringAutoConfiguration.java similarity index 65% rename from request-response/request-response-spring-boot-autoconfigure-grpc-ecosystem/src/main/java/no/entur/logging/cloud/spring/grpc/ecosystem/RequestResponseGrpcEcosystemAutoConfiguration.java rename to request-response/request-response-spring-boot-autoconfigure-grpc-spring/src/main/java/no/entur/logging/cloud/spring/grpc/ecosystem/RequestResponseGrpcSpringAutoConfiguration.java index ad1ea11c..15f3f10d 100644 --- a/request-response/request-response-spring-boot-autoconfigure-grpc-ecosystem/src/main/java/no/entur/logging/cloud/spring/grpc/ecosystem/RequestResponseGrpcEcosystemAutoConfiguration.java +++ b/request-response/request-response-spring-boot-autoconfigure-grpc-spring/src/main/java/no/entur/logging/cloud/spring/grpc/ecosystem/RequestResponseGrpcSpringAutoConfiguration.java @@ -2,10 +2,6 @@ import io.grpc.Status; import io.grpc.StatusRuntimeException; -import net.devh.boot.grpc.server.advice.GrpcAdvice; -import net.devh.boot.grpc.server.advice.GrpcExceptionHandler; -import net.devh.boot.grpc.server.autoconfigure.GrpcAdviceAutoConfiguration; -import net.devh.boot.grpc.server.error.GrpcExceptionInterceptor; import no.entur.logging.cloud.rr.grpc.GrpcSink; import no.entur.logging.cloud.rr.grpc.filter.GrpcServerLoggingFilters; import no.entur.logging.cloud.rr.grpc.mapper.GrpcMetadataJsonMapper; @@ -13,12 +9,15 @@ import no.entur.logging.cloud.spring.rr.grpc.OrderedGrpcLoggingServerInterceptor; import no.entur.logging.cloud.spring.rr.grpc.RequestResponseGrpcExceptionHandlerInterceptor; import org.springframework.beans.factory.annotation.Value; +import org.springframework.boot.autoconfigure.AutoConfigureAfter; import org.springframework.boot.autoconfigure.AutoConfigureBefore; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; +import org.springframework.boot.grpc.server.autoconfigure.GrpcServerFactoryAutoConfiguration; +import org.springframework.boot.grpc.server.autoconfigure.exception.GrpcExceptionHandlerAutoConfiguration; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.Primary; +import org.springframework.grpc.server.exception.GrpcExceptionHandlerInterceptor; /** * @@ -29,11 +28,8 @@ */ @Configuration -@AutoConfigureBefore(GrpcAdviceAutoConfiguration.class) -public class RequestResponseGrpcEcosystemAutoConfiguration { - - @Value("${entur.logging.request-response.grpc.server.exception-handler.interceptor-order:0}") - private int exceptionInterceptorOrder; +@AutoConfigureBefore(GrpcExceptionHandlerAutoConfiguration.class) +public class RequestResponseGrpcSpringAutoConfiguration { @Value("${entur.logging.request-response.grpc.server.interceptor-order:5175}") private int serverInterceptorOrder; @@ -44,22 +40,16 @@ public OrderedGrpcLoggingServerInterceptor orderedGrpcLoggingServerInterceptor(G return new OrderedGrpcLoggingServerInterceptor(grpcSink, grpcServerLoggingFilters, grpcMetadataJsonMapper, grpcPayloadJsonMapper, serverInterceptorOrder); } - @GrpcAdvice + @Bean @ConditionalOnProperty(name = {"entur.logging.request-response.grpc.server.exception-handler.enabled"}, havingValue = "true", matchIfMissing = true) - public static class StatusRuntimeExceptionGrpcServiceAdvice { - @java.lang.SuppressWarnings("all") - - // this error mapper can be overriden by specifying value in the annotation - @GrpcExceptionHandler - public Status handle(StatusRuntimeException e) { - return e.getStatus(); - } + public StatusRuntimeExceptionExceptionHandler statusRuntimeExceptionExceptionHandler() { + return new StatusRuntimeExceptionExceptionHandler(0); } @Bean @ConditionalOnProperty(name = {"entur.logging.request-response.grpc.server.exception-handler.enabled"}, havingValue = "true", matchIfMissing = true) - public RequestResponseGrpcExceptionHandlerInterceptor requestResponseGRpcExceptionHandlerInterceptor(GrpcExceptionInterceptor interceptor) { - return new RequestResponseGrpcExceptionHandlerInterceptor(interceptor, exceptionInterceptorOrder); + public RuntimeExceptionExceptionHandler runtimeExceptionExceptionHandler() { + return new RuntimeExceptionExceptionHandler(0); } } \ No newline at end of file diff --git a/request-response/request-response-spring-boot-autoconfigure-grpc-spring/src/main/java/no/entur/logging/cloud/spring/grpc/ecosystem/RuntimeExceptionExceptionHandler.java b/request-response/request-response-spring-boot-autoconfigure-grpc-spring/src/main/java/no/entur/logging/cloud/spring/grpc/ecosystem/RuntimeExceptionExceptionHandler.java new file mode 100644 index 00000000..24830865 --- /dev/null +++ b/request-response/request-response-spring-boot-autoconfigure-grpc-spring/src/main/java/no/entur/logging/cloud/spring/grpc/ecosystem/RuntimeExceptionExceptionHandler.java @@ -0,0 +1,30 @@ +package no.entur.logging.cloud.spring.grpc.ecosystem; + +import io.grpc.Status; +import io.grpc.StatusException; +import io.grpc.StatusRuntimeException; +import org.jspecify.annotations.Nullable; +import org.springframework.core.Ordered; +import org.springframework.grpc.server.exception.GrpcExceptionHandler; + +public class RuntimeExceptionExceptionHandler implements GrpcExceptionHandler, Ordered { + + private final int order; + + public RuntimeExceptionExceptionHandler(int order) { + this.order = order; + } + + @Override + public @Nullable StatusException handleException(Throwable e) { + if (e instanceof RuntimeException s) { + return Status.INTERNAL.withDescription(s.getMessage()).asException(); + } + return null; + } + + @Override + public int getOrder() { + return order; + } +} diff --git a/request-response/request-response-spring-boot-autoconfigure-grpc-spring/src/main/java/no/entur/logging/cloud/spring/grpc/ecosystem/StatusRuntimeExceptionExceptionHandler.java b/request-response/request-response-spring-boot-autoconfigure-grpc-spring/src/main/java/no/entur/logging/cloud/spring/grpc/ecosystem/StatusRuntimeExceptionExceptionHandler.java new file mode 100644 index 00000000..813fd1a1 --- /dev/null +++ b/request-response/request-response-spring-boot-autoconfigure-grpc-spring/src/main/java/no/entur/logging/cloud/spring/grpc/ecosystem/StatusRuntimeExceptionExceptionHandler.java @@ -0,0 +1,29 @@ +package no.entur.logging.cloud.spring.grpc.ecosystem; + +import io.grpc.StatusException; +import io.grpc.StatusRuntimeException; +import org.jspecify.annotations.Nullable; +import org.springframework.core.Ordered; +import org.springframework.grpc.server.exception.GrpcExceptionHandler; + +public class StatusRuntimeExceptionExceptionHandler implements GrpcExceptionHandler, Ordered { + + private final int order; + + public StatusRuntimeExceptionExceptionHandler(int order) { + this.order = order; + } + + @Override + public @Nullable StatusException handleException(Throwable e) { + if (e instanceof StatusRuntimeException s) { + return s.getStatus().withDescription(e.getMessage()).asException(); + } + return null; + } + + @Override + public int getOrder() { + return order; + } +} diff --git a/request-response/request-response-spring-boot-autoconfigure-grpc-spring/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports b/request-response/request-response-spring-boot-autoconfigure-grpc-spring/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports new file mode 100644 index 00000000..6b963345 --- /dev/null +++ b/request-response/request-response-spring-boot-autoconfigure-grpc-spring/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports @@ -0,0 +1,2 @@ +no.entur.logging.cloud.spring.grpc.ecosystem.RequestResponseGrpcSpringAutoConfiguration +no.entur.logging.cloud.spring.grpc.ecosystem.RequestResponseExceptionHandlerGrpcSpringAutoConfiguration \ No newline at end of file diff --git a/request-response/request-response-spring-boot-autoconfigure-web/src/main/java/no/entur/logging/cloud/spring/logbook/web/HttpMessageStateFilterMvcRegistrations.java b/request-response/request-response-spring-boot-autoconfigure-web/src/main/java/no/entur/logging/cloud/spring/logbook/web/HttpMessageStateFilterMvcRegistrations.java index bdc3fb66..7aec2c81 100644 --- a/request-response/request-response-spring-boot-autoconfigure-web/src/main/java/no/entur/logging/cloud/spring/logbook/web/HttpMessageStateFilterMvcRegistrations.java +++ b/request-response/request-response-spring-boot-autoconfigure-web/src/main/java/no/entur/logging/cloud/spring/logbook/web/HttpMessageStateFilterMvcRegistrations.java @@ -1,6 +1,5 @@ package no.entur.logging.cloud.spring.logbook.web; - -import org.springframework.boot.autoconfigure.web.servlet.WebMvcRegistrations; +import org.springframework.boot.webmvc.autoconfigure.WebMvcRegistrations; import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter; public class HttpMessageStateFilterMvcRegistrations implements WebMvcRegistrations { diff --git a/request-response/request-response-spring-boot-autoconfigure-web/src/main/java/no/entur/logging/cloud/spring/logbook/web/LogbookWebAutoConfiguration.java b/request-response/request-response-spring-boot-autoconfigure-web/src/main/java/no/entur/logging/cloud/spring/logbook/web/LogbookWebAutoConfiguration.java index 31c4a774..2331339b 100644 --- a/request-response/request-response-spring-boot-autoconfigure-web/src/main/java/no/entur/logging/cloud/spring/logbook/web/LogbookWebAutoConfiguration.java +++ b/request-response/request-response-spring-boot-autoconfigure-web/src/main/java/no/entur/logging/cloud/spring/logbook/web/LogbookWebAutoConfiguration.java @@ -14,8 +14,8 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; -import org.springframework.boot.autoconfigure.web.servlet.WebMvcRegistrations; import org.springframework.boot.web.servlet.FilterRegistrationBean; +import org.springframework.boot.webmvc.autoconfigure.WebMvcRegistrations; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.http.HttpStatus; diff --git a/settings.gradle b/settings.gradle index de41fd74..63e4a46f 100644 --- a/settings.gradle +++ b/settings.gradle @@ -13,9 +13,9 @@ include 'micrometer' // GCP include 'gcp:logback-logstash-encoder-gcp', 'gcp:spring-boot-autoconfigure-gcp', 'gcp:spring-boot-autoconfigure-gcp-grpc-mdc', 'gcp:correlation-id-trace-spring-boot-gcp-web' -include 'gcp:spring-boot-starter-gcp-web', 'gcp:spring-boot-starter-gcp-web-test', 'gcp:spring-boot-starter-gcp-grpc-ecosystem-test', 'gcp:spring-boot-starter-gcp-grpc-ecosystem' +include 'gcp:spring-boot-starter-gcp-web', 'gcp:spring-boot-starter-gcp-web-test', 'gcp:spring-boot-starter-gcp-grpc-spring-test', 'gcp:spring-boot-starter-gcp-grpc-spring' include 'gcp:spring-boot-autoconfigure-gcp-test', 'gcp:request-response-spring-boot-starter-gcp-web', 'gcp:request-response-spring-boot-starter-gcp-web-test' -include 'gcp:request-response-spring-boot-starter-gcp-grpc-ecosystem', 'gcp:request-response-spring-boot-starter-gcp-grpc-ecosystem-test' +include 'gcp:request-response-spring-boot-starter-gcp-grpc-spring', 'gcp:request-response-spring-boot-starter-gcp-grpc-spring-test' include 'gcp:correlation-id-trace-spring-boot-gcp-grpc' include 'gcp:micrometer-gcp' @@ -23,9 +23,9 @@ include 'gcp:logbook-spring-boot-autoconfigure-gcp' // Azure include 'azure:logback-logstash-encoder-azure', 'azure:spring-boot-autoconfigure-azure', 'azure:spring-boot-autoconfigure-azure-grpc-mdc' -include 'azure:spring-boot-starter-azure-web', 'azure:spring-boot-starter-azure-web-test', 'azure:spring-boot-starter-azure-grpc-ecosystem-test', 'azure:spring-boot-starter-azure-grpc-ecosystem' +include 'azure:spring-boot-starter-azure-web', 'azure:spring-boot-starter-azure-web-test', 'azure:spring-boot-starter-azure-grpc-spring-test', 'azure:spring-boot-starter-azure-grpc-spring' include 'azure:spring-boot-autoconfigure-azure-test', 'azure:request-response-spring-boot-starter-azure-web', 'azure:request-response-spring-boot-starter-azure-web-test' -include 'azure:request-response-spring-boot-starter-azure-grpc-ecosystem', 'azure:request-response-spring-boot-starter-azure-grpc-ecosystem-test' +include 'azure:request-response-spring-boot-starter-azure-grpc-spring', 'azure:request-response-spring-boot-starter-azure-grpc-spring-test' include 'azure:micrometer-azure' include 'azure:logbook-spring-boot-autoconfigure-azure' @@ -36,12 +36,12 @@ include 'trace:mdc-context-grpc-netty', 'trace:server:correlation-id-trace-sprin include 'request-response:netty-grpc', 'request-response:netty-grpc-test', 'request-response:request-response-spring-boot-autoconfigure-grpc' include 'request-response:logbook-filter', 'request-response:logbook', 'request-response:logbook-test', 'request-response:logbook-spring-boot-autoconfigure', 'request-response:logbook-spring-boot-autoconfigure-test' include 'on-demand:on-demand-spring-boot-starter-web', 'on-demand:on-demand-spring-boot-starter-grpc', 'on-demand:on-demand-spring-boot-autoconfigure' -include 'request-response:request-response-spring-boot-autoconfigure-web', 'request-response:request-response-spring-boot-autoconfigure-grpc-ecosystem' +include 'request-response:request-response-spring-boot-autoconfigure-web', 'request-response:request-response-spring-boot-autoconfigure-grpc-spring' include 'bom' // GCP include 'examples:gcp-web-example', 'examples:gcp-async-web-example', 'examples:gcp-web-without-test-artifacts-example', 'examples:gcp-web-without-test-or-ondemand-artifacts-example' -include 'examples:gcp-grpc-ecosystem-example', 'examples:gcp-web-apache-client-example' +include 'examples:gcp-grpc-spring-example', 'examples:gcp-web-apache-client-example' // Azure -include 'examples:azure-web-example', 'examples:azure-grpc-ecosystem-example', 'examples:gcp-grpc-ecosystem-without-test-artifacts-example' +include 'examples:azure-web-example', 'examples:azure-grpc-spring-example', 'examples:gcp-grpc-spring-without-test-artifacts-example' diff --git a/test/test-logback/build.gradle b/test/test-logback/build.gradle index 32728d42..fbfa4746 100644 --- a/test/test-logback/build.gradle +++ b/test/test-logback/build.gradle @@ -7,7 +7,7 @@ dependencies { api ("ch.qos.logback:logback-classic") api ("ch.qos.logback:logback-core") - api ("org.entur.jackson:jackson-syntax-highlight:${jacksonSyntaxHighlightVersion}") + api ("org.entur.jackson:jackson-tools-syntax-highlight:${jacksonSyntaxHighlightVersion}") api ("org.entur.logback-logstash-syntax-highlighting-decorators:logback-logstash-syntax-highlighting-decorators:${logbackLogstashSyntaxHighlightingDecoratorsVersion}") // junit diff --git a/trace/mdc-context-grpc-netty/build.gradle b/trace/mdc-context-grpc-netty/build.gradle index 17ad6546..fbfbf8ad 100644 --- a/trace/mdc-context-grpc-netty/build.gradle +++ b/trace/mdc-context-grpc-netty/build.gradle @@ -9,7 +9,7 @@ dependencies { api("com.fasterxml.jackson.core:jackson-databind") api("com.fasterxml.jackson.core:jackson-annotations") - api("com.fasterxml.jackson.core:jackson-core") + api("tools.jackson.core:jackson-core") api("io.grpc:grpc-netty:${grpcNettyVersion}") api("io.grpc:grpc-services:${grpcNettyVersion}") diff --git a/trace/server/correlation-id-trace-grpc-netty/build.gradle b/trace/server/correlation-id-trace-grpc-netty/build.gradle index 1af67605..bd239389 100644 --- a/trace/server/correlation-id-trace-grpc-netty/build.gradle +++ b/trace/server/correlation-id-trace-grpc-netty/build.gradle @@ -10,7 +10,7 @@ dependencies { api("com.fasterxml.jackson.core:jackson-databind") api("com.fasterxml.jackson.core:jackson-annotations") - api("com.fasterxml.jackson.core:jackson-core") + api("tools.jackson.core:jackson-core") api("io.grpc:grpc-netty:${grpcNettyVersion}") api("io.grpc:grpc-services:${grpcNettyVersion}") From 0b37b4ab4099c3768fcc27859e645221477547ee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20Skj=C3=B8lberg?= Date: Mon, 19 Jan 2026 19:22:25 +0100 Subject: [PATCH 02/20] Rename ecosystem -> spring --- README.md | 2 +- ...onseAzureGrpcSpringTestAutoConfiguration.java | 8 ++++---- ....boot.autoconfigure.AutoConfiguration.imports | 2 +- .../README.md | 2 +- ...esponseAzureGrpcSpringAutoConfiguration.java} | 4 ++-- ....boot.autoconfigure.AutoConfiguration.imports | 2 +- .../EcosystemGrpcLoggingAutoConfiguration.java | 10 ---------- .../SpringGrpcLoggingAutoConfiguration.java | 10 ++++++++++ ....boot.autoconfigure.AutoConfiguration.imports | 2 +- examples/README.md | 4 ++-- gcp/README.md | 16 ++++++++-------- ...sponseGcpGrpcSpringTestAutoConfiguration.java | 7 ++++--- ....boot.autoconfigure.AutoConfiguration.imports | 2 +- .../test/DemoApplication.java | 2 +- .../test/LoadContextLoggingTest.java | 2 +- .../README.md | 2 +- ...tResponseGcpGrpcSpringAutoConfiguration.java} | 4 ++-- ....boot.autoconfigure.AutoConfiguration.imports | 2 +- .../EcosystemGrpcLoggingAutoConfiguration.java | 10 ---------- .../SpringGrpcLoggingAutoConfiguration.java | 10 ++++++++++ ....boot.autoconfigure.AutoConfiguration.imports | 2 +- ...eptionHandlerGrpcSpringAutoConfiguration.java | 8 +------- ...questResponseGrpcSpringAutoConfiguration.java | 8 +------- .../RuntimeExceptionExceptionHandler.java | 3 +-- .../StatusRuntimeExceptionExceptionHandler.java | 2 +- ....boot.autoconfigure.AutoConfiguration.imports | 4 ++-- ...tResponseGrpcExceptionHandlerInterceptor.java | 4 ++-- 27 files changed, 61 insertions(+), 73 deletions(-) rename gcp/request-response-spring-boot-starter-gcp-grpc-spring-test/src/main/java/no/entur/logging/cloud/gcp/spring/gcp/grpc/ecosystem/test/RequestResponseGcpGrpcEcosystemTestAutoConfiguration.java => azure/request-response-spring-boot-starter-azure-grpc-spring-test/src/main/java/no/entur/logging/cloud/azure/spring/grpc/spring/test/RequestResponseAzureGrpcSpringTestAutoConfiguration.java (85%) rename azure/request-response-spring-boot-starter-azure-grpc-spring/src/main/java/no/entur/logging/cloud/azure/spring/grpc/{ecosystem/RequestResponseAzureGrpcEcosystemAutoConfiguration.java => spring/RequestResponseAzureGrpcSpringAutoConfiguration.java} (85%) delete mode 100644 azure/spring-boot-starter-azure-grpc-spring/src/main/java/no/entur/logging/cloud/azure/spring/grpc/ecosystem/EcosystemGrpcLoggingAutoConfiguration.java create mode 100644 azure/spring-boot-starter-azure-grpc-spring/src/main/java/no/entur/logging/cloud/azure/spring/grpc/spring/SpringGrpcLoggingAutoConfiguration.java rename azure/request-response-spring-boot-starter-azure-grpc-spring-test/src/main/java/no/entur/logging/cloud/azure/spring/grpc/ecosystem/test/RequestResponseAzureGrpcEcosystemTestAutoConfiguration.java => gcp/request-response-spring-boot-starter-gcp-grpc-spring-test/src/main/java/no/entur/logging/cloud/gcp/spring/gcp/grpc/spring/test/RequestResponseGcpGrpcSpringTestAutoConfiguration.java (86%) rename gcp/request-response-spring-boot-starter-gcp-grpc-spring-test/src/test/java/no/entur/logging/cloud/gcp/spring/gcp/grpc/{ecosystem => spring}/test/DemoApplication.java (80%) rename gcp/request-response-spring-boot-starter-gcp-grpc-spring-test/src/test/java/no/entur/logging/cloud/gcp/spring/gcp/grpc/{ecosystem => spring}/test/LoadContextLoggingTest.java (97%) rename gcp/request-response-spring-boot-starter-gcp-grpc-spring/src/main/java/no/entur/logging/cloud/gcp/spring/gcp/grpc/{ecosystem/RequestResponseGcpGrpcEcosystemAutoConfiguration.java => spring/RequestResponseGcpGrpcSpringAutoConfiguration.java} (85%) delete mode 100644 gcp/spring-boot-starter-gcp-grpc-spring/src/main/java/no/entur/logging/cloud/gcp/spring/grpc/ecosystem/EcosystemGrpcLoggingAutoConfiguration.java create mode 100644 gcp/spring-boot-starter-gcp-grpc-spring/src/main/java/no/entur/logging/cloud/gcp/spring/grpc/spring/SpringGrpcLoggingAutoConfiguration.java rename request-response/request-response-spring-boot-autoconfigure-grpc-spring/src/main/java/no/entur/logging/cloud/spring/grpc/{ecosystem => spring}/RequestResponseExceptionHandlerGrpcSpringAutoConfiguration.java (77%) rename request-response/request-response-spring-boot-autoconfigure-grpc-spring/src/main/java/no/entur/logging/cloud/spring/grpc/{ecosystem => spring}/RequestResponseGrpcSpringAutoConfiguration.java (84%) rename request-response/request-response-spring-boot-autoconfigure-grpc-spring/src/main/java/no/entur/logging/cloud/spring/grpc/{ecosystem => spring}/RuntimeExceptionExceptionHandler.java (88%) rename request-response/request-response-spring-boot-autoconfigure-grpc-spring/src/main/java/no/entur/logging/cloud/spring/grpc/{ecosystem => spring}/StatusRuntimeExceptionExceptionHandler.java (93%) diff --git a/README.md b/README.md index bfe11b59..5e72f084 100644 --- a/README.md +++ b/README.md @@ -39,7 +39,7 @@ This library is mostly based on * SLF4J 2 * Logback + Logback logstash * GRPC - * [Ecosystem](https://github.com/grpc-ecosystem/grpc-spring) + * Spring GRPC * [Logbook](https://github.com/zalando/logbook) Supported web technologies are: diff --git a/gcp/request-response-spring-boot-starter-gcp-grpc-spring-test/src/main/java/no/entur/logging/cloud/gcp/spring/gcp/grpc/ecosystem/test/RequestResponseGcpGrpcEcosystemTestAutoConfiguration.java b/azure/request-response-spring-boot-starter-azure-grpc-spring-test/src/main/java/no/entur/logging/cloud/azure/spring/grpc/spring/test/RequestResponseAzureGrpcSpringTestAutoConfiguration.java similarity index 85% rename from gcp/request-response-spring-boot-starter-gcp-grpc-spring-test/src/main/java/no/entur/logging/cloud/gcp/spring/gcp/grpc/ecosystem/test/RequestResponseGcpGrpcEcosystemTestAutoConfiguration.java rename to azure/request-response-spring-boot-starter-azure-grpc-spring-test/src/main/java/no/entur/logging/cloud/azure/spring/grpc/spring/test/RequestResponseAzureGrpcSpringTestAutoConfiguration.java index 96b659c2..4bcf9b29 100644 --- a/gcp/request-response-spring-boot-starter-gcp-grpc-spring-test/src/main/java/no/entur/logging/cloud/gcp/spring/gcp/grpc/ecosystem/test/RequestResponseGcpGrpcEcosystemTestAutoConfiguration.java +++ b/azure/request-response-spring-boot-starter-azure-grpc-spring-test/src/main/java/no/entur/logging/cloud/azure/spring/grpc/spring/test/RequestResponseAzureGrpcSpringTestAutoConfiguration.java @@ -1,6 +1,6 @@ -package no.entur.logging.cloud.gcp.spring.gcp.grpc.ecosystem.test; +package no.entur.logging.cloud.azure.spring.grpc.spring.test; -import no.entur.logging.cloud.gcp.spring.gcp.grpc.ecosystem.RequestResponseGcpGrpcEcosystemAutoConfiguration; +import no.entur.logging.cloud.azure.spring.grpc.spring.RequestResponseAzureGrpcSpringAutoConfiguration; import no.entur.logging.cloud.spring.rr.grpc.AbstractRequestResponseGrpcSinkAutoConfiguration; import no.entur.logging.cloud.rr.grpc.GrpcSink; import no.entur.logging.cloud.rr.grpc.test.CompositeSink; @@ -17,11 +17,11 @@ import org.springframework.context.annotation.Configuration; @AutoConfigureBefore(value = { - RequestResponseGcpGrpcEcosystemAutoConfiguration.class, + RequestResponseAzureGrpcSpringAutoConfiguration.class, }) @Configuration -public class RequestResponseGcpGrpcEcosystemTestAutoConfiguration extends AbstractRequestResponseGrpcSinkAutoConfiguration { +public class RequestResponseAzureGrpcSpringTestAutoConfiguration extends AbstractRequestResponseGrpcSinkAutoConfiguration { @Bean @ConditionalOnMissingBean(GrpcSink.class) diff --git a/azure/request-response-spring-boot-starter-azure-grpc-spring-test/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports b/azure/request-response-spring-boot-starter-azure-grpc-spring-test/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports index 7f3a8e4f..350ee99f 100644 --- a/azure/request-response-spring-boot-starter-azure-grpc-spring-test/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports +++ b/azure/request-response-spring-boot-starter-azure-grpc-spring-test/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports @@ -1 +1 @@ -no.entur.logging.cloud.azure.spring.grpc.ecosystem.test.RequestResponseAzureGrpcEcosystemTestAutoConfiguration \ No newline at end of file +no.entur.logging.cloud.azure.spring.grpc.spring.test.RequestResponseAzureGrpcSpringTestAutoConfiguration \ No newline at end of file diff --git a/azure/request-response-spring-boot-starter-azure-grpc-spring/README.md b/azure/request-response-spring-boot-starter-azure-grpc-spring/README.md index f56a700b..7ce08656 100644 --- a/azure/request-response-spring-boot-starter-azure-grpc-spring/README.md +++ b/azure/request-response-spring-boot-starter-azure-grpc-spring/README.md @@ -1 +1 @@ -# request-response-logging for GCP + Ecosystem +# request-response-logging for GCP + Spring GRPC diff --git a/azure/request-response-spring-boot-starter-azure-grpc-spring/src/main/java/no/entur/logging/cloud/azure/spring/grpc/ecosystem/RequestResponseAzureGrpcEcosystemAutoConfiguration.java b/azure/request-response-spring-boot-starter-azure-grpc-spring/src/main/java/no/entur/logging/cloud/azure/spring/grpc/spring/RequestResponseAzureGrpcSpringAutoConfiguration.java similarity index 85% rename from azure/request-response-spring-boot-starter-azure-grpc-spring/src/main/java/no/entur/logging/cloud/azure/spring/grpc/ecosystem/RequestResponseAzureGrpcEcosystemAutoConfiguration.java rename to azure/request-response-spring-boot-starter-azure-grpc-spring/src/main/java/no/entur/logging/cloud/azure/spring/grpc/spring/RequestResponseAzureGrpcSpringAutoConfiguration.java index 4d76a105..8ddd4a63 100644 --- a/azure/request-response-spring-boot-starter-azure-grpc-spring/src/main/java/no/entur/logging/cloud/azure/spring/grpc/ecosystem/RequestResponseAzureGrpcEcosystemAutoConfiguration.java +++ b/azure/request-response-spring-boot-starter-azure-grpc-spring/src/main/java/no/entur/logging/cloud/azure/spring/grpc/spring/RequestResponseAzureGrpcSpringAutoConfiguration.java @@ -1,4 +1,4 @@ -package no.entur.logging.cloud.azure.spring.grpc.ecosystem; +package no.entur.logging.cloud.azure.spring.grpc.spring; import no.entur.logging.cloud.spring.rr.grpc.GrpcLoggingCloudProperties; import no.entur.logging.cloud.spring.rr.grpc.RequestResponseGrpcAutoConfiguration; @@ -8,7 +8,7 @@ @Configuration @AutoConfigureBefore(RequestResponseGrpcAutoConfiguration.class) -public class RequestResponseAzureGrpcEcosystemAutoConfiguration { +public class RequestResponseAzureGrpcSpringAutoConfiguration { @Bean public GrpcLoggingCloudProperties grpcLoggingCloudProperties() { diff --git a/azure/request-response-spring-boot-starter-azure-grpc-spring/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports b/azure/request-response-spring-boot-starter-azure-grpc-spring/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports index af355280..d24dd5d6 100644 --- a/azure/request-response-spring-boot-starter-azure-grpc-spring/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports +++ b/azure/request-response-spring-boot-starter-azure-grpc-spring/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports @@ -1 +1 @@ -no.entur.logging.cloud.azure.spring.grpc.ecosystem.RequestResponseAzureGrpcEcosystemAutoConfiguration \ No newline at end of file +no.entur.logging.cloud.azure.spring.grpc.spring.RequestResponseAzureGrpcSpringAutoConfiguration \ No newline at end of file diff --git a/azure/spring-boot-starter-azure-grpc-spring/src/main/java/no/entur/logging/cloud/azure/spring/grpc/ecosystem/EcosystemGrpcLoggingAutoConfiguration.java b/azure/spring-boot-starter-azure-grpc-spring/src/main/java/no/entur/logging/cloud/azure/spring/grpc/ecosystem/EcosystemGrpcLoggingAutoConfiguration.java deleted file mode 100644 index 82bd3937..00000000 --- a/azure/spring-boot-starter-azure-grpc-spring/src/main/java/no/entur/logging/cloud/azure/spring/grpc/ecosystem/EcosystemGrpcLoggingAutoConfiguration.java +++ /dev/null @@ -1,10 +0,0 @@ -package no.entur.logging.cloud.azure.spring.grpc.ecosystem; - -import org.springframework.context.annotation.Configuration; - -@Configuration -public class EcosystemGrpcLoggingAutoConfiguration { - - // error handlers - -} diff --git a/azure/spring-boot-starter-azure-grpc-spring/src/main/java/no/entur/logging/cloud/azure/spring/grpc/spring/SpringGrpcLoggingAutoConfiguration.java b/azure/spring-boot-starter-azure-grpc-spring/src/main/java/no/entur/logging/cloud/azure/spring/grpc/spring/SpringGrpcLoggingAutoConfiguration.java new file mode 100644 index 00000000..52e6cf2d --- /dev/null +++ b/azure/spring-boot-starter-azure-grpc-spring/src/main/java/no/entur/logging/cloud/azure/spring/grpc/spring/SpringGrpcLoggingAutoConfiguration.java @@ -0,0 +1,10 @@ +package no.entur.logging.cloud.azure.spring.grpc.spring; + +import org.springframework.context.annotation.Configuration; + +@Configuration +public class SpringGrpcLoggingAutoConfiguration { + + // error handlers + +} diff --git a/azure/spring-boot-starter-azure-grpc-spring/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports b/azure/spring-boot-starter-azure-grpc-spring/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports index 406825cc..f112fc89 100644 --- a/azure/spring-boot-starter-azure-grpc-spring/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports +++ b/azure/spring-boot-starter-azure-grpc-spring/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports @@ -1 +1 @@ -no.entur.logging.cloud.azure.spring.grpc.ecosystem.EcosystemGrpcLoggingAutoConfiguration \ No newline at end of file +no.entur.logging.cloud.azure.spring.grpc.spring.SpringGrpcLoggingAutoConfiguration \ No newline at end of file diff --git a/examples/README.md b/examples/README.md index ef618a5e..539ba5b1 100644 --- a/examples/README.md +++ b/examples/README.md @@ -12,7 +12,7 @@ Please note: * For local development, a shortened 'classic' one-line is the default * To examine log statements in more details use `CompositeConsoleOutputControl.useHumanReadableJsonEncoder()` for JSON output -# Ecosystem gRPC interceptors +# Spring gRPC interceptors The gRPC interceptor order overview: ## Service configuration @@ -30,7 +30,7 @@ The gRPC interceptor order overview: // Validation MyValidationServerInterceptor.class, -}, sortInterceptors = true) +}) ``` ## Interceptor order diff --git a/gcp/README.md b/gcp/README.md index be62a5af..06b79f23 100644 --- a/gcp/README.md +++ b/gcp/README.md @@ -208,24 +208,24 @@ and ```xml no.entur.logging.cloud - spring-boot-starter-gcp-grpc-ecosystem + spring-boot-starter-gcp-grpc-spring ${cloud-logging.version} no.entur.logging.cloud - spring-boot-starter-gcp-grpc-ecosystem-test + spring-boot-starter-gcp-grpc-spring-test ${cloud-logging.version} test no.entur.logging.cloud - request-response-spring-boot-starter-gcp-grpc-ecosystem + request-response-spring-boot-starter-gcp-grpc-spring ${cloud-logging.version} no.entur.logging.cloud - request-response-spring-boot-starter-gcp-grpc-ecosystem-test + request-response-spring-boot-starter-gcp-grpc-spring-test ${cloud-logging.version} test @@ -285,11 +285,11 @@ ext { add ```groovy -implementation("no.entur.logging.cloud:spring-boot-starter-gcp-grpc-ecosystem:${cloudLoggingVersion}") -testImplementation("no.entur.logging.cloud:spring-boot-starter-gcp-grpc-ecosystem-test:${cloudLoggingVersion}") +implementation("no.entur.logging.cloud:spring-boot-starter-gcp-grpc-spring:${cloudLoggingVersion}") +testImplementation("no.entur.logging.cloud:spring-boot-starter-gcp-grpc-spring-test:${cloudLoggingVersion}") // request-response logging -implementation("no.entur.logging.cloud:request-response-spring-boot-starter-gcp-grpc-ecosystem:${cloudLoggingVersion}") -testImplementation("no.entur.logging.cloud:request-response-spring-boot-starter-gcp-grpc-ecosystem-test:${cloudLoggingVersion}") +implementation("no.entur.logging.cloud:request-response-spring-boot-starter-gcp-grpc-spring:${cloudLoggingVersion}") +testImplementation("no.entur.logging.cloud:request-response-spring-boot-starter-gcp-grpc-spring-test:${cloudLoggingVersion}") // on-demand logging support implementation("no.entur.logging.cloud:on-demand-spring-boot-starter-grpc:${cloudLoggingVersion}") // metrics diff --git a/azure/request-response-spring-boot-starter-azure-grpc-spring-test/src/main/java/no/entur/logging/cloud/azure/spring/grpc/ecosystem/test/RequestResponseAzureGrpcEcosystemTestAutoConfiguration.java b/gcp/request-response-spring-boot-starter-gcp-grpc-spring-test/src/main/java/no/entur/logging/cloud/gcp/spring/gcp/grpc/spring/test/RequestResponseGcpGrpcSpringTestAutoConfiguration.java similarity index 86% rename from azure/request-response-spring-boot-starter-azure-grpc-spring-test/src/main/java/no/entur/logging/cloud/azure/spring/grpc/ecosystem/test/RequestResponseAzureGrpcEcosystemTestAutoConfiguration.java rename to gcp/request-response-spring-boot-starter-gcp-grpc-spring-test/src/main/java/no/entur/logging/cloud/gcp/spring/gcp/grpc/spring/test/RequestResponseGcpGrpcSpringTestAutoConfiguration.java index c6f3a1e8..9d98cf47 100644 --- a/azure/request-response-spring-boot-starter-azure-grpc-spring-test/src/main/java/no/entur/logging/cloud/azure/spring/grpc/ecosystem/test/RequestResponseAzureGrpcEcosystemTestAutoConfiguration.java +++ b/gcp/request-response-spring-boot-starter-gcp-grpc-spring-test/src/main/java/no/entur/logging/cloud/gcp/spring/gcp/grpc/spring/test/RequestResponseGcpGrpcSpringTestAutoConfiguration.java @@ -1,5 +1,6 @@ -package no.entur.logging.cloud.azure.spring.grpc.ecosystem.test; +package no.entur.logging.cloud.gcp.spring.gcp.grpc.spring.test; +import no.entur.logging.cloud.gcp.spring.gcp.grpc.spring.RequestResponseGcpGrpcSpringAutoConfiguration; import no.entur.logging.cloud.spring.rr.grpc.AbstractRequestResponseGrpcSinkAutoConfiguration; import no.entur.logging.cloud.rr.grpc.GrpcSink; import no.entur.logging.cloud.rr.grpc.test.CompositeSink; @@ -16,11 +17,11 @@ import org.springframework.context.annotation.Configuration; @AutoConfigureBefore(value = { - no.entur.logging.cloud.azure.spring.grpc.ecosystem.RequestResponseAzureGrpcEcosystemAutoConfiguration.class, + RequestResponseGcpGrpcSpringAutoConfiguration.class, }) @Configuration -public class RequestResponseAzureGrpcEcosystemTestAutoConfiguration extends AbstractRequestResponseGrpcSinkAutoConfiguration { +public class RequestResponseGcpGrpcSpringTestAutoConfiguration extends AbstractRequestResponseGrpcSinkAutoConfiguration { @Bean @ConditionalOnMissingBean(GrpcSink.class) diff --git a/gcp/request-response-spring-boot-starter-gcp-grpc-spring-test/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports b/gcp/request-response-spring-boot-starter-gcp-grpc-spring-test/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports index 5a80f128..1676f02d 100644 --- a/gcp/request-response-spring-boot-starter-gcp-grpc-spring-test/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports +++ b/gcp/request-response-spring-boot-starter-gcp-grpc-spring-test/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports @@ -1 +1 @@ -no.entur.logging.cloud.gcp.spring.gcp.grpc.ecosystem.test.RequestResponseGcpGrpcEcosystemTestAutoConfiguration \ No newline at end of file +no.entur.logging.cloud.gcp.spring.gcp.grpc.spring.test.RequestResponseGcpGrpcSpringTestAutoConfiguration \ No newline at end of file diff --git a/gcp/request-response-spring-boot-starter-gcp-grpc-spring-test/src/test/java/no/entur/logging/cloud/gcp/spring/gcp/grpc/ecosystem/test/DemoApplication.java b/gcp/request-response-spring-boot-starter-gcp-grpc-spring-test/src/test/java/no/entur/logging/cloud/gcp/spring/gcp/grpc/spring/test/DemoApplication.java similarity index 80% rename from gcp/request-response-spring-boot-starter-gcp-grpc-spring-test/src/test/java/no/entur/logging/cloud/gcp/spring/gcp/grpc/ecosystem/test/DemoApplication.java rename to gcp/request-response-spring-boot-starter-gcp-grpc-spring-test/src/test/java/no/entur/logging/cloud/gcp/spring/gcp/grpc/spring/test/DemoApplication.java index 240f1484..7df4033b 100644 --- a/gcp/request-response-spring-boot-starter-gcp-grpc-spring-test/src/test/java/no/entur/logging/cloud/gcp/spring/gcp/grpc/ecosystem/test/DemoApplication.java +++ b/gcp/request-response-spring-boot-starter-gcp-grpc-spring-test/src/test/java/no/entur/logging/cloud/gcp/spring/gcp/grpc/spring/test/DemoApplication.java @@ -1,4 +1,4 @@ -package no.entur.logging.cloud.gcp.spring.gcp.grpc.ecosystem.test; +package no.entur.logging.cloud.gcp.spring.gcp.grpc.spring.test; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; diff --git a/gcp/request-response-spring-boot-starter-gcp-grpc-spring-test/src/test/java/no/entur/logging/cloud/gcp/spring/gcp/grpc/ecosystem/test/LoadContextLoggingTest.java b/gcp/request-response-spring-boot-starter-gcp-grpc-spring-test/src/test/java/no/entur/logging/cloud/gcp/spring/gcp/grpc/spring/test/LoadContextLoggingTest.java similarity index 97% rename from gcp/request-response-spring-boot-starter-gcp-grpc-spring-test/src/test/java/no/entur/logging/cloud/gcp/spring/gcp/grpc/ecosystem/test/LoadContextLoggingTest.java rename to gcp/request-response-spring-boot-starter-gcp-grpc-spring-test/src/test/java/no/entur/logging/cloud/gcp/spring/gcp/grpc/spring/test/LoadContextLoggingTest.java index f5562f72..98b7d28a 100644 --- a/gcp/request-response-spring-boot-starter-gcp-grpc-spring-test/src/test/java/no/entur/logging/cloud/gcp/spring/gcp/grpc/ecosystem/test/LoadContextLoggingTest.java +++ b/gcp/request-response-spring-boot-starter-gcp-grpc-spring-test/src/test/java/no/entur/logging/cloud/gcp/spring/gcp/grpc/spring/test/LoadContextLoggingTest.java @@ -1,4 +1,4 @@ -package no.entur.logging.cloud.gcp.spring.gcp.grpc.ecosystem.test; +package no.entur.logging.cloud.gcp.spring.gcp.grpc.spring.test; import no.entur.logging.cloud.api.DevOpsLogger; import no.entur.logging.cloud.api.DevOpsLoggerFactory; diff --git a/gcp/request-response-spring-boot-starter-gcp-grpc-spring/README.md b/gcp/request-response-spring-boot-starter-gcp-grpc-spring/README.md index f56a700b..7ce08656 100644 --- a/gcp/request-response-spring-boot-starter-gcp-grpc-spring/README.md +++ b/gcp/request-response-spring-boot-starter-gcp-grpc-spring/README.md @@ -1 +1 @@ -# request-response-logging for GCP + Ecosystem +# request-response-logging for GCP + Spring GRPC diff --git a/gcp/request-response-spring-boot-starter-gcp-grpc-spring/src/main/java/no/entur/logging/cloud/gcp/spring/gcp/grpc/ecosystem/RequestResponseGcpGrpcEcosystemAutoConfiguration.java b/gcp/request-response-spring-boot-starter-gcp-grpc-spring/src/main/java/no/entur/logging/cloud/gcp/spring/gcp/grpc/spring/RequestResponseGcpGrpcSpringAutoConfiguration.java similarity index 85% rename from gcp/request-response-spring-boot-starter-gcp-grpc-spring/src/main/java/no/entur/logging/cloud/gcp/spring/gcp/grpc/ecosystem/RequestResponseGcpGrpcEcosystemAutoConfiguration.java rename to gcp/request-response-spring-boot-starter-gcp-grpc-spring/src/main/java/no/entur/logging/cloud/gcp/spring/gcp/grpc/spring/RequestResponseGcpGrpcSpringAutoConfiguration.java index b0a69c9e..1bb8003b 100644 --- a/gcp/request-response-spring-boot-starter-gcp-grpc-spring/src/main/java/no/entur/logging/cloud/gcp/spring/gcp/grpc/ecosystem/RequestResponseGcpGrpcEcosystemAutoConfiguration.java +++ b/gcp/request-response-spring-boot-starter-gcp-grpc-spring/src/main/java/no/entur/logging/cloud/gcp/spring/gcp/grpc/spring/RequestResponseGcpGrpcSpringAutoConfiguration.java @@ -1,4 +1,4 @@ -package no.entur.logging.cloud.gcp.spring.gcp.grpc.ecosystem; +package no.entur.logging.cloud.gcp.spring.gcp.grpc.spring; import no.entur.logging.cloud.spring.rr.grpc.GrpcLoggingCloudProperties; import no.entur.logging.cloud.spring.rr.grpc.RequestResponseGrpcAutoConfiguration; @@ -8,7 +8,7 @@ @Configuration @AutoConfigureBefore(RequestResponseGrpcAutoConfiguration.class) -public class RequestResponseGcpGrpcEcosystemAutoConfiguration { +public class RequestResponseGcpGrpcSpringAutoConfiguration { @Bean public GrpcLoggingCloudProperties grpcLoggingCloudProperties() { diff --git a/gcp/request-response-spring-boot-starter-gcp-grpc-spring/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports b/gcp/request-response-spring-boot-starter-gcp-grpc-spring/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports index 7be9f525..9c07902b 100644 --- a/gcp/request-response-spring-boot-starter-gcp-grpc-spring/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports +++ b/gcp/request-response-spring-boot-starter-gcp-grpc-spring/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports @@ -1 +1 @@ -no.entur.logging.cloud.gcp.spring.gcp.grpc.ecosystem.RequestResponseGcpGrpcEcosystemAutoConfiguration \ No newline at end of file +no.entur.logging.cloud.gcp.spring.gcp.grpc.spring.RequestResponseGcpGrpcSpringAutoConfiguration \ No newline at end of file diff --git a/gcp/spring-boot-starter-gcp-grpc-spring/src/main/java/no/entur/logging/cloud/gcp/spring/grpc/ecosystem/EcosystemGrpcLoggingAutoConfiguration.java b/gcp/spring-boot-starter-gcp-grpc-spring/src/main/java/no/entur/logging/cloud/gcp/spring/grpc/ecosystem/EcosystemGrpcLoggingAutoConfiguration.java deleted file mode 100644 index fba26387..00000000 --- a/gcp/spring-boot-starter-gcp-grpc-spring/src/main/java/no/entur/logging/cloud/gcp/spring/grpc/ecosystem/EcosystemGrpcLoggingAutoConfiguration.java +++ /dev/null @@ -1,10 +0,0 @@ -package no.entur.logging.cloud.gcp.spring.grpc.ecosystem; - -import org.springframework.context.annotation.Configuration; - -@Configuration -public class EcosystemGrpcLoggingAutoConfiguration { - - // error handlers - -} diff --git a/gcp/spring-boot-starter-gcp-grpc-spring/src/main/java/no/entur/logging/cloud/gcp/spring/grpc/spring/SpringGrpcLoggingAutoConfiguration.java b/gcp/spring-boot-starter-gcp-grpc-spring/src/main/java/no/entur/logging/cloud/gcp/spring/grpc/spring/SpringGrpcLoggingAutoConfiguration.java new file mode 100644 index 00000000..ed835e0b --- /dev/null +++ b/gcp/spring-boot-starter-gcp-grpc-spring/src/main/java/no/entur/logging/cloud/gcp/spring/grpc/spring/SpringGrpcLoggingAutoConfiguration.java @@ -0,0 +1,10 @@ +package no.entur.logging.cloud.gcp.spring.grpc.spring; + +import org.springframework.context.annotation.Configuration; + +@Configuration +public class SpringGrpcLoggingAutoConfiguration { + + // error handlers + +} diff --git a/gcp/spring-boot-starter-gcp-grpc-spring/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports b/gcp/spring-boot-starter-gcp-grpc-spring/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports index feb60d67..980cb44e 100644 --- a/gcp/spring-boot-starter-gcp-grpc-spring/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports +++ b/gcp/spring-boot-starter-gcp-grpc-spring/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports @@ -1 +1 @@ -no.entur.logging.cloud.gcp.spring.grpc.ecosystem.EcosystemGrpcLoggingAutoConfiguration \ No newline at end of file +no.entur.logging.cloud.gcp.spring.grpc.spring.SpringGrpcLoggingAutoConfiguration \ No newline at end of file diff --git a/request-response/request-response-spring-boot-autoconfigure-grpc-spring/src/main/java/no/entur/logging/cloud/spring/grpc/ecosystem/RequestResponseExceptionHandlerGrpcSpringAutoConfiguration.java b/request-response/request-response-spring-boot-autoconfigure-grpc-spring/src/main/java/no/entur/logging/cloud/spring/grpc/spring/RequestResponseExceptionHandlerGrpcSpringAutoConfiguration.java similarity index 77% rename from request-response/request-response-spring-boot-autoconfigure-grpc-spring/src/main/java/no/entur/logging/cloud/spring/grpc/ecosystem/RequestResponseExceptionHandlerGrpcSpringAutoConfiguration.java rename to request-response/request-response-spring-boot-autoconfigure-grpc-spring/src/main/java/no/entur/logging/cloud/spring/grpc/spring/RequestResponseExceptionHandlerGrpcSpringAutoConfiguration.java index 7fd52682..2ceccbce 100644 --- a/request-response/request-response-spring-boot-autoconfigure-grpc-spring/src/main/java/no/entur/logging/cloud/spring/grpc/ecosystem/RequestResponseExceptionHandlerGrpcSpringAutoConfiguration.java +++ b/request-response/request-response-spring-boot-autoconfigure-grpc-spring/src/main/java/no/entur/logging/cloud/spring/grpc/spring/RequestResponseExceptionHandlerGrpcSpringAutoConfiguration.java @@ -1,14 +1,8 @@ -package no.entur.logging.cloud.spring.grpc.ecosystem; +package no.entur.logging.cloud.spring.grpc.spring; -import no.entur.logging.cloud.rr.grpc.GrpcSink; -import no.entur.logging.cloud.rr.grpc.filter.GrpcServerLoggingFilters; -import no.entur.logging.cloud.rr.grpc.mapper.GrpcMetadataJsonMapper; -import no.entur.logging.cloud.rr.grpc.mapper.GrpcPayloadJsonMapper; -import no.entur.logging.cloud.spring.rr.grpc.OrderedGrpcLoggingServerInterceptor; import no.entur.logging.cloud.spring.rr.grpc.RequestResponseGrpcExceptionHandlerInterceptor; import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.autoconfigure.AutoConfigureAfter; -import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.boot.grpc.server.autoconfigure.exception.GrpcExceptionHandlerAutoConfiguration; import org.springframework.context.annotation.Bean; diff --git a/request-response/request-response-spring-boot-autoconfigure-grpc-spring/src/main/java/no/entur/logging/cloud/spring/grpc/ecosystem/RequestResponseGrpcSpringAutoConfiguration.java b/request-response/request-response-spring-boot-autoconfigure-grpc-spring/src/main/java/no/entur/logging/cloud/spring/grpc/spring/RequestResponseGrpcSpringAutoConfiguration.java similarity index 84% rename from request-response/request-response-spring-boot-autoconfigure-grpc-spring/src/main/java/no/entur/logging/cloud/spring/grpc/ecosystem/RequestResponseGrpcSpringAutoConfiguration.java rename to request-response/request-response-spring-boot-autoconfigure-grpc-spring/src/main/java/no/entur/logging/cloud/spring/grpc/spring/RequestResponseGrpcSpringAutoConfiguration.java index 15f3f10d..4597b697 100644 --- a/request-response/request-response-spring-boot-autoconfigure-grpc-spring/src/main/java/no/entur/logging/cloud/spring/grpc/ecosystem/RequestResponseGrpcSpringAutoConfiguration.java +++ b/request-response/request-response-spring-boot-autoconfigure-grpc-spring/src/main/java/no/entur/logging/cloud/spring/grpc/spring/RequestResponseGrpcSpringAutoConfiguration.java @@ -1,23 +1,17 @@ -package no.entur.logging.cloud.spring.grpc.ecosystem; +package no.entur.logging.cloud.spring.grpc.spring; -import io.grpc.Status; -import io.grpc.StatusRuntimeException; import no.entur.logging.cloud.rr.grpc.GrpcSink; import no.entur.logging.cloud.rr.grpc.filter.GrpcServerLoggingFilters; import no.entur.logging.cloud.rr.grpc.mapper.GrpcMetadataJsonMapper; import no.entur.logging.cloud.rr.grpc.mapper.GrpcPayloadJsonMapper; import no.entur.logging.cloud.spring.rr.grpc.OrderedGrpcLoggingServerInterceptor; -import no.entur.logging.cloud.spring.rr.grpc.RequestResponseGrpcExceptionHandlerInterceptor; import org.springframework.beans.factory.annotation.Value; -import org.springframework.boot.autoconfigure.AutoConfigureAfter; import org.springframework.boot.autoconfigure.AutoConfigureBefore; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; -import org.springframework.boot.grpc.server.autoconfigure.GrpcServerFactoryAutoConfiguration; import org.springframework.boot.grpc.server.autoconfigure.exception.GrpcExceptionHandlerAutoConfiguration; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; -import org.springframework.grpc.server.exception.GrpcExceptionHandlerInterceptor; /** * diff --git a/request-response/request-response-spring-boot-autoconfigure-grpc-spring/src/main/java/no/entur/logging/cloud/spring/grpc/ecosystem/RuntimeExceptionExceptionHandler.java b/request-response/request-response-spring-boot-autoconfigure-grpc-spring/src/main/java/no/entur/logging/cloud/spring/grpc/spring/RuntimeExceptionExceptionHandler.java similarity index 88% rename from request-response/request-response-spring-boot-autoconfigure-grpc-spring/src/main/java/no/entur/logging/cloud/spring/grpc/ecosystem/RuntimeExceptionExceptionHandler.java rename to request-response/request-response-spring-boot-autoconfigure-grpc-spring/src/main/java/no/entur/logging/cloud/spring/grpc/spring/RuntimeExceptionExceptionHandler.java index 24830865..041edbad 100644 --- a/request-response/request-response-spring-boot-autoconfigure-grpc-spring/src/main/java/no/entur/logging/cloud/spring/grpc/ecosystem/RuntimeExceptionExceptionHandler.java +++ b/request-response/request-response-spring-boot-autoconfigure-grpc-spring/src/main/java/no/entur/logging/cloud/spring/grpc/spring/RuntimeExceptionExceptionHandler.java @@ -1,8 +1,7 @@ -package no.entur.logging.cloud.spring.grpc.ecosystem; +package no.entur.logging.cloud.spring.grpc.spring; import io.grpc.Status; import io.grpc.StatusException; -import io.grpc.StatusRuntimeException; import org.jspecify.annotations.Nullable; import org.springframework.core.Ordered; import org.springframework.grpc.server.exception.GrpcExceptionHandler; diff --git a/request-response/request-response-spring-boot-autoconfigure-grpc-spring/src/main/java/no/entur/logging/cloud/spring/grpc/ecosystem/StatusRuntimeExceptionExceptionHandler.java b/request-response/request-response-spring-boot-autoconfigure-grpc-spring/src/main/java/no/entur/logging/cloud/spring/grpc/spring/StatusRuntimeExceptionExceptionHandler.java similarity index 93% rename from request-response/request-response-spring-boot-autoconfigure-grpc-spring/src/main/java/no/entur/logging/cloud/spring/grpc/ecosystem/StatusRuntimeExceptionExceptionHandler.java rename to request-response/request-response-spring-boot-autoconfigure-grpc-spring/src/main/java/no/entur/logging/cloud/spring/grpc/spring/StatusRuntimeExceptionExceptionHandler.java index 813fd1a1..fe762368 100644 --- a/request-response/request-response-spring-boot-autoconfigure-grpc-spring/src/main/java/no/entur/logging/cloud/spring/grpc/ecosystem/StatusRuntimeExceptionExceptionHandler.java +++ b/request-response/request-response-spring-boot-autoconfigure-grpc-spring/src/main/java/no/entur/logging/cloud/spring/grpc/spring/StatusRuntimeExceptionExceptionHandler.java @@ -1,4 +1,4 @@ -package no.entur.logging.cloud.spring.grpc.ecosystem; +package no.entur.logging.cloud.spring.grpc.spring; import io.grpc.StatusException; import io.grpc.StatusRuntimeException; diff --git a/request-response/request-response-spring-boot-autoconfigure-grpc-spring/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports b/request-response/request-response-spring-boot-autoconfigure-grpc-spring/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports index 6b963345..e259930d 100644 --- a/request-response/request-response-spring-boot-autoconfigure-grpc-spring/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports +++ b/request-response/request-response-spring-boot-autoconfigure-grpc-spring/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports @@ -1,2 +1,2 @@ -no.entur.logging.cloud.spring.grpc.ecosystem.RequestResponseGrpcSpringAutoConfiguration -no.entur.logging.cloud.spring.grpc.ecosystem.RequestResponseExceptionHandlerGrpcSpringAutoConfiguration \ No newline at end of file +no.entur.logging.cloud.spring.grpc.spring.RequestResponseGrpcSpringAutoConfiguration +no.entur.logging.cloud.spring.grpc.spring.RequestResponseExceptionHandlerGrpcSpringAutoConfiguration \ No newline at end of file diff --git a/request-response/request-response-spring-boot-autoconfigure-grpc/src/main/java/no/entur/logging/cloud/spring/rr/grpc/RequestResponseGrpcExceptionHandlerInterceptor.java b/request-response/request-response-spring-boot-autoconfigure-grpc/src/main/java/no/entur/logging/cloud/spring/rr/grpc/RequestResponseGrpcExceptionHandlerInterceptor.java index ce6990d4..d06c6d22 100644 --- a/request-response/request-response-spring-boot-autoconfigure-grpc/src/main/java/no/entur/logging/cloud/spring/rr/grpc/RequestResponseGrpcExceptionHandlerInterceptor.java +++ b/request-response/request-response-spring-boot-autoconfigure-grpc/src/main/java/no/entur/logging/cloud/spring/rr/grpc/RequestResponseGrpcExceptionHandlerInterceptor.java @@ -8,10 +8,10 @@ /** * - * This interceptor duplicates the ecosystem exception interceptor so to handle all errors before the request-response logging + * This interceptor duplicates the spring exception interceptor so to handle all errors before the request-response logging * while still having error handling earlier in the interceptor chain (i.e. for handling authentication errors and so on).

* - * This is useful when doing request-response between authentication and controller while using the ecosystem exception handling. + * This is useful when doing request-response between authentication and controller while using the spring exception handling. */ public class RequestResponseGrpcExceptionHandlerInterceptor implements ServerInterceptor, Ordered { From 4abd23307769e5374540b6d1fa080061b5e4ff08 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20Skj=C3=B8lberg?= Date: Mon, 19 Jan 2026 23:12:22 +0100 Subject: [PATCH 03/20] Adjust test + properties --- .../azure/example/SpringOndemandGrpcLoggingFormatTest.java | 5 ++++- .../grpc/example/SpringOndemandGrpcLoggingFormatTest.java | 5 ++++- .../spring/ondemand/grpc/properties/OndemandProperties.java | 2 +- 3 files changed, 9 insertions(+), 3 deletions(-) diff --git a/examples/azure-grpc-spring-example/src/test/java/no/entur/grpc/azure/example/SpringOndemandGrpcLoggingFormatTest.java b/examples/azure-grpc-spring-example/src/test/java/no/entur/grpc/azure/example/SpringOndemandGrpcLoggingFormatTest.java index 158c828c..463c34bd 100644 --- a/examples/azure-grpc-spring-example/src/test/java/no/entur/grpc/azure/example/SpringOndemandGrpcLoggingFormatTest.java +++ b/examples/azure-grpc-spring-example/src/test/java/no/entur/grpc/azure/example/SpringOndemandGrpcLoggingFormatTest.java @@ -16,7 +16,10 @@ @SpringBootTest @ActiveProfiles("ondemand") -@TestPropertySource(properties = {"entur.logging.grpc.ondemand.enabled=true"}) +@TestPropertySource(properties = { + "entur.logging.grpc.ondemand.enabled=true", + "entur.logging.grpc.ondemand.failure.logger.enabled=false", +}) @DirtiesContext public class SpringOndemandGrpcLoggingFormatTest extends SpringAbstractGrpcTest { diff --git a/examples/gcp-grpc-spring-example/src/test/java/no/entur/grpc/example/SpringOndemandGrpcLoggingFormatTest.java b/examples/gcp-grpc-spring-example/src/test/java/no/entur/grpc/example/SpringOndemandGrpcLoggingFormatTest.java index 461aa03e..b88745eb 100644 --- a/examples/gcp-grpc-spring-example/src/test/java/no/entur/grpc/example/SpringOndemandGrpcLoggingFormatTest.java +++ b/examples/gcp-grpc-spring-example/src/test/java/no/entur/grpc/example/SpringOndemandGrpcLoggingFormatTest.java @@ -16,7 +16,10 @@ @SpringBootTest @ActiveProfiles("ondemand") -@TestPropertySource(properties = {"entur.logging.grpc.ondemand.enabled=true"}) +@TestPropertySource(properties = { + "entur.logging.grpc.ondemand.enabled=true", + "entur.logging.grpc.ondemand.failure.logger.enabled=false", +}) @DirtiesContext public class SpringOndemandGrpcLoggingFormatTest extends SpringAbstractGrpcTest { diff --git a/on-demand/on-demand-spring-boot-starter-grpc/src/main/java/no/entur/logging/cloud/spring/ondemand/grpc/properties/OndemandProperties.java b/on-demand/on-demand-spring-boot-starter-grpc/src/main/java/no/entur/logging/cloud/spring/ondemand/grpc/properties/OndemandProperties.java index 7d08e0df..0607cead 100644 --- a/on-demand/on-demand-spring-boot-starter-grpc/src/main/java/no/entur/logging/cloud/spring/ondemand/grpc/properties/OndemandProperties.java +++ b/on-demand/on-demand-spring-boot-starter-grpc/src/main/java/no/entur/logging/cloud/spring/ondemand/grpc/properties/OndemandProperties.java @@ -7,7 +7,7 @@ import java.util.ArrayList; import java.util.List; -@ConfigurationProperties(prefix = "no.entur.logging.grpc.ondemand") +@ConfigurationProperties(prefix = "entur.logging.grpc.ondemand") public class OndemandProperties { private boolean enabled; From d90340beb78c2ef53daa48ad4ea6623690bb8a94 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20Skj=C3=B8lberg?= Date: Wed, 28 Jan 2026 15:55:52 +0100 Subject: [PATCH 04/20] bump spring --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index b0ecbd9f..414aff04 100644 --- a/build.gradle +++ b/build.gradle @@ -7,7 +7,7 @@ plugins { // Define version variables at root level so they're available everywhere ext { - springBootVersion = '4.0.1' // https://repo1.maven.org/maven2/org/springframework/boot/spring-boot-dependencies/ + springBootVersion = '4.0.2' // https://repo1.maven.org/maven2/org/springframework/boot/spring-boot-dependencies/ // The following versions are managed by Spring Boot BOM (no need to define here): // junitJupiterVersion, mockitoVersion, slf4jVersion, logbackVersion, // jacksonVersion, jacksonDatabindVersion, micrometerVersion, janinoVersion, From 6e7d0d513b432c2826cee1f0d0c7b94970150e8f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20Skj=C3=B8lberg?= Date: Thu, 29 Jan 2026 11:47:23 +0100 Subject: [PATCH 05/20] Bump lib --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index 414aff04..e5d8d7e8 100644 --- a/build.gradle +++ b/build.gradle @@ -19,7 +19,7 @@ ext { logbackLogstashVersion = '9.0' logbookVersion = '4.0.0-RC.1' jacksonSyntaxHighlightVersion = '2.0.0' - logbackLogstashSyntaxHighlightingDecoratorsVersion = '2.0.0-SNAPSHOT' + logbackLogstashSyntaxHighlightingDecoratorsVersion = '2.0.0' commonsIoVersion = '2.21.0' commonsTextVersion = '1.15.0' nettyTcnativeBoringsslStaticVersion = '2.0.74.Final' From 6b09a62887400f1dae1067ad1eae4ca0c9b4153f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20Skj=C3=B8lberg?= Date: Thu, 29 Jan 2026 15:02:49 +0100 Subject: [PATCH 06/20] Adjust examples and docs --- .../org/entur/example/web/rest/DocumentEndpoint.java | 2 +- .../entur/example/web/rest/AsyncDocumentEndpoint.java | 2 +- .../org/entur/example/web/rest/DocumentEndpoint.java | 2 +- guides/web.md | 9 ++++++++- 4 files changed, 11 insertions(+), 4 deletions(-) diff --git a/examples/azure-web-example/src/main/java/org/entur/example/web/rest/DocumentEndpoint.java b/examples/azure-web-example/src/main/java/org/entur/example/web/rest/DocumentEndpoint.java index 02c7b515..4f52f61a 100644 --- a/examples/azure-web-example/src/main/java/org/entur/example/web/rest/DocumentEndpoint.java +++ b/examples/azure-web-example/src/main/java/org/entur/example/web/rest/DocumentEndpoint.java @@ -70,7 +70,7 @@ ResponseEntity bigResponse() throws IOException { generator.writeStartObject(); generator.writeStringProperty("start", "here"); - generator.writeStringProperty("longValue", generateLongString(64*1024)); + generator.writeStringProperty("longValue", generateLongString(192*1024)); generator.writeStringProperty("end", "here"); generator.writeEndObject(); diff --git a/examples/gcp-async-web-example/src/main/java/org/entur/example/web/rest/AsyncDocumentEndpoint.java b/examples/gcp-async-web-example/src/main/java/org/entur/example/web/rest/AsyncDocumentEndpoint.java index 203cde38..0532ffc4 100644 --- a/examples/gcp-async-web-example/src/main/java/org/entur/example/web/rest/AsyncDocumentEndpoint.java +++ b/examples/gcp-async-web-example/src/main/java/org/entur/example/web/rest/AsyncDocumentEndpoint.java @@ -121,7 +121,7 @@ public CompletableFuture> bigResponse() throws IOExceptio generator.writeStartObject(); generator.writeStringProperty("start", "here"); - generator.writeStringProperty("longValue", generateLongString(64*1024)); + generator.writeStringProperty("longValue", generateLongString(192*1024)); generator.writeStringProperty("end", "here"); generator.writeEndObject(); diff --git a/examples/gcp-web-example/src/main/java/org/entur/example/web/rest/DocumentEndpoint.java b/examples/gcp-web-example/src/main/java/org/entur/example/web/rest/DocumentEndpoint.java index 9389adbf..34d6ba89 100644 --- a/examples/gcp-web-example/src/main/java/org/entur/example/web/rest/DocumentEndpoint.java +++ b/examples/gcp-web-example/src/main/java/org/entur/example/web/rest/DocumentEndpoint.java @@ -87,7 +87,7 @@ ResponseEntity bigResponse() throws IOException { generator.writeStartObject(); generator.writeStringProperty("start", "here"); - generator.writeStringProperty("longValue", generateLongString(64*1024)); + generator.writeStringProperty("longValue", generateLongString(192*1024)); generator.writeStringProperty("end", "here"); generator.writeEndObject(); diff --git a/guides/web.md b/guides/web.md index 023e96c1..e26b2379 100644 --- a/guides/web.md +++ b/guides/web.md @@ -122,6 +122,13 @@ testImplementation ("no.entur.logging.cloud:request-response-spring-boot-starter ``` +Please note: + + * Logging invalid JSON or making too long log statements might have unexpected consequences for fluentbit handling in GCP kubernetes. + * For request-response-logging, this library assumes that locally produced JSON has valid syntax and is without pretty-printing. + * This assumption is made so to avoid the processing overhead of unnecessarily parsing JSON documents known to be valid. + * If this assumption for some reason does not hold, use a BodyFilter to compensate. + Some Logbook excludes ([actuator, openapi](https://github.com/entur/cloud-logging/blob/main/request-response/logbook-spring-boot-autoconfigure/src/main/java/no/entur/logging/cloud/spring/logbook/LogbookLoggingAutoConfiguration.java)) are included by default. Add more using ```yml @@ -288,7 +295,7 @@ entur.logging.http.ondemand.troubleshoot.level=debug entur.logging.http.ondemand.troubleshoot.http.headers[0].name=x-debug-this-request ``` -which allows for additional logging in the precense of certain HTTP headers. +which allows for additional logging in the presence of certain HTTP headers. ### Toggle log output-format during testing Toggling between output modes in a unit test: From 481e0b3b5eb95aaafa2377dbf5cb201ce656770a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20Skj=C3=B8lberg?= Date: Thu, 29 Jan 2026 17:06:03 +0100 Subject: [PATCH 07/20] Adjust interceptor order for grpc --- build.gradle | 2 +- .../src/main/resources/application.properties | 7 ++++--- .../ondemand/grpc/properties/OndemandProperties.java | 2 +- .../grpc/scope/GrpcLoggingScopeContextInterceptor.java | 2 +- ...esponseExceptionHandlerGrpcSpringAutoConfiguration.java | 4 ++-- .../spring/RequestResponseGrpcSpringAutoConfiguration.java | 2 +- .../rr/grpc/OrderedGrpcLoggingServerInterceptor.java | 6 +----- .../trace/spring/grpc/properties/GrpcMdcProperties.java | 2 +- 8 files changed, 12 insertions(+), 15 deletions(-) diff --git a/build.gradle b/build.gradle index bf87f468..47144337 100644 --- a/build.gradle +++ b/build.gradle @@ -13,7 +13,7 @@ ext { // jacksonVersion, jacksonDatabindVersion, micrometerVersion, janinoVersion, // servletVersion (jakarta-servlet), annotationApiVersion (jakarta-annotation), // nettyVersion, jsonPathVersion - + // Versions NOT in Spring Boot BOM - we manage these ourselves: googleTruthVersion = '1.4.5' logbackLogstashVersion = '9.0' diff --git a/examples/gcp-grpc-spring-example/src/main/resources/application.properties b/examples/gcp-grpc-spring-example/src/main/resources/application.properties index 28667eaa..63fcf66f 100644 --- a/examples/gcp-grpc-spring-example/src/main/resources/application.properties +++ b/examples/gcp-grpc-spring-example/src/main/resources/application.properties @@ -11,6 +11,7 @@ logging.level.root=debug entur.jwt.mdc.enabled=true -entur.logging.grpc.trace.mdc.interceptor-order=50 -entur.logging.request-response.grpc.server.interceptor-order=5170 -entur.logging.request-response.grpc.server.exception-handler.interceptor-order=5175 +# Optional: +# entur.logging.grpc.trace.mdc.interceptor-order=1000 +# entur.logging.request-response.grpc.server.interceptor-order=2000 +# entur.logging.request-response.grpc.server.exception-handler.interceptor-order=3000 diff --git a/on-demand/on-demand-spring-boot-starter-grpc/src/main/java/no/entur/logging/cloud/spring/ondemand/grpc/properties/OndemandProperties.java b/on-demand/on-demand-spring-boot-starter-grpc/src/main/java/no/entur/logging/cloud/spring/ondemand/grpc/properties/OndemandProperties.java index 0607cead..bd375167 100644 --- a/on-demand/on-demand-spring-boot-starter-grpc/src/main/java/no/entur/logging/cloud/spring/ondemand/grpc/properties/OndemandProperties.java +++ b/on-demand/on-demand-spring-boot-starter-grpc/src/main/java/no/entur/logging/cloud/spring/ondemand/grpc/properties/OndemandProperties.java @@ -12,7 +12,7 @@ public class OndemandProperties { private boolean enabled; - private int interceptorOrder = Ordered.HIGHEST_PRECEDENCE; + private int interceptorOrder = 100; private OndemandSuccess success = new OndemandSuccess(); diff --git a/on-demand/on-demand-spring-boot-starter-grpc/src/main/java/no/entur/logging/cloud/spring/ondemand/grpc/scope/GrpcLoggingScopeContextInterceptor.java b/on-demand/on-demand-spring-boot-starter-grpc/src/main/java/no/entur/logging/cloud/spring/ondemand/grpc/scope/GrpcLoggingScopeContextInterceptor.java index c9f531fd..c84bc90f 100644 --- a/on-demand/on-demand-spring-boot-starter-grpc/src/main/java/no/entur/logging/cloud/spring/ondemand/grpc/scope/GrpcLoggingScopeContextInterceptor.java +++ b/on-demand/on-demand-spring-boot-starter-grpc/src/main/java/no/entur/logging/cloud/spring/ondemand/grpc/scope/GrpcLoggingScopeContextInterceptor.java @@ -30,7 +30,7 @@ public static Builder newBuilder() { public static class Builder { - private int order = Ordered.HIGHEST_PRECEDENCE; + private int order = 100; private GrpcLoggingScopeFilters filters; diff --git a/request-response/request-response-spring-boot-autoconfigure-grpc-spring/src/main/java/no/entur/logging/cloud/spring/grpc/spring/RequestResponseExceptionHandlerGrpcSpringAutoConfiguration.java b/request-response/request-response-spring-boot-autoconfigure-grpc-spring/src/main/java/no/entur/logging/cloud/spring/grpc/spring/RequestResponseExceptionHandlerGrpcSpringAutoConfiguration.java index 2ceccbce..6ca34de9 100644 --- a/request-response/request-response-spring-boot-autoconfigure-grpc-spring/src/main/java/no/entur/logging/cloud/spring/grpc/spring/RequestResponseExceptionHandlerGrpcSpringAutoConfiguration.java +++ b/request-response/request-response-spring-boot-autoconfigure-grpc-spring/src/main/java/no/entur/logging/cloud/spring/grpc/spring/RequestResponseExceptionHandlerGrpcSpringAutoConfiguration.java @@ -21,12 +21,12 @@ @AutoConfigureAfter(GrpcExceptionHandlerAutoConfiguration.class) public class RequestResponseExceptionHandlerGrpcSpringAutoConfiguration { - @Value("${entur.logging.request-response.grpc.server.exception-handler.interceptor-order:0}") + @Value("${entur.logging.request-response.grpc.server.exception-handler.interceptor-order:400}") private int exceptionInterceptorOrder; @Bean @ConditionalOnProperty(name = {"entur.logging.request-response.grpc.server.exception-handler.enabled"}, havingValue = "true", matchIfMissing = true) - public RequestResponseGrpcExceptionHandlerInterceptor requestResponseGRpcExceptionHandlerInterceptor(GrpcExceptionHandlerInterceptor interceptor) { + public RequestResponseGrpcExceptionHandlerInterceptor requestResponseGrpcExceptionHandlerInterceptor(GrpcExceptionHandlerInterceptor interceptor) { return new RequestResponseGrpcExceptionHandlerInterceptor(interceptor, exceptionInterceptorOrder); } diff --git a/request-response/request-response-spring-boot-autoconfigure-grpc-spring/src/main/java/no/entur/logging/cloud/spring/grpc/spring/RequestResponseGrpcSpringAutoConfiguration.java b/request-response/request-response-spring-boot-autoconfigure-grpc-spring/src/main/java/no/entur/logging/cloud/spring/grpc/spring/RequestResponseGrpcSpringAutoConfiguration.java index 4597b697..45f9a84a 100644 --- a/request-response/request-response-spring-boot-autoconfigure-grpc-spring/src/main/java/no/entur/logging/cloud/spring/grpc/spring/RequestResponseGrpcSpringAutoConfiguration.java +++ b/request-response/request-response-spring-boot-autoconfigure-grpc-spring/src/main/java/no/entur/logging/cloud/spring/grpc/spring/RequestResponseGrpcSpringAutoConfiguration.java @@ -25,7 +25,7 @@ @AutoConfigureBefore(GrpcExceptionHandlerAutoConfiguration.class) public class RequestResponseGrpcSpringAutoConfiguration { - @Value("${entur.logging.request-response.grpc.server.interceptor-order:5175}") + @Value("${entur.logging.request-response.grpc.server.interceptor-order:300}") private int serverInterceptorOrder; @Bean diff --git a/request-response/request-response-spring-boot-autoconfigure-grpc/src/main/java/no/entur/logging/cloud/spring/rr/grpc/OrderedGrpcLoggingServerInterceptor.java b/request-response/request-response-spring-boot-autoconfigure-grpc/src/main/java/no/entur/logging/cloud/spring/rr/grpc/OrderedGrpcLoggingServerInterceptor.java index 96384ae6..823d6519 100644 --- a/request-response/request-response-spring-boot-autoconfigure-grpc/src/main/java/no/entur/logging/cloud/spring/rr/grpc/OrderedGrpcLoggingServerInterceptor.java +++ b/request-response/request-response-spring-boot-autoconfigure-grpc/src/main/java/no/entur/logging/cloud/spring/rr/grpc/OrderedGrpcLoggingServerInterceptor.java @@ -17,11 +17,7 @@ public OrderedGrpcLoggingServerInterceptor( GrpcServerLoggingFilters filters, GrpcMetadataJsonMapper metadataJsonMapper, GrpcPayloadJsonMapper payloadJsonMapper, - - @Value("${entur.logging.request-response.grpc.interceptor-order:0}") - int order - - ) { + int order) { super(sink, filters, metadataJsonMapper, payloadJsonMapper); this.order = order; } diff --git a/trace/server/correlation-id-trace-spring-boot-grpc/src/main/java/no/entur/logging/cloud/trace/spring/grpc/properties/GrpcMdcProperties.java b/trace/server/correlation-id-trace-spring-boot-grpc/src/main/java/no/entur/logging/cloud/trace/spring/grpc/properties/GrpcMdcProperties.java index 2c00db01..0f2fbb8d 100644 --- a/trace/server/correlation-id-trace-spring-boot-grpc/src/main/java/no/entur/logging/cloud/trace/spring/grpc/properties/GrpcMdcProperties.java +++ b/trace/server/correlation-id-trace-spring-boot-grpc/src/main/java/no/entur/logging/cloud/trace/spring/grpc/properties/GrpcMdcProperties.java @@ -11,7 +11,7 @@ public class GrpcMdcProperties { private boolean response = true; - private int interceptorOrder; + private int interceptorOrder = 200; public int getInterceptorOrder() { return interceptorOrder; From 60b794a47f6f05a2b14e3ae58e23c18f3507c384 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20Skj=C3=B8lberg?= Date: Fri, 30 Jan 2026 10:59:47 +0100 Subject: [PATCH 08/20] Bump grpc to 1.0.2 --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index 47144337..d0626ffa 100644 --- a/build.gradle +++ b/build.gradle @@ -28,7 +28,7 @@ ext { grpcVersion = '1.78.0' grpcCommonsVersion = '2.65.0' grpcProtobufVersion = '4.33.4' - springGrpcVersion = '1.0.1' + springGrpcVersion = '1.0.2' jsonAssertVersion = '0.8.0' } From 570b58e55fe8f26571f23b3aff6b1657b68d9489 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20Skj=C3=B8lberg?= Date: Tue, 3 Feb 2026 21:34:34 +0100 Subject: [PATCH 09/20] Use ShortenedThrowableConverter to format stacktraces --- .../example/web/WebLoggingFormatTest.java | 2 + .../logstash/StackdriverLogstashEncoder.java | 5 ++ .../StackdriverMessageJsonProvider.java | 87 ++++++++----------- .../spring/web/LoadContextLoggingTest.java | 15 ++++ 4 files changed, 58 insertions(+), 51 deletions(-) diff --git a/examples/gcp-web-example/src/test/java/org/entur/example/web/WebLoggingFormatTest.java b/examples/gcp-web-example/src/test/java/org/entur/example/web/WebLoggingFormatTest.java index 5aeef7f4..38e0dddf 100644 --- a/examples/gcp-web-example/src/test/java/org/entur/example/web/WebLoggingFormatTest.java +++ b/examples/gcp-web-example/src/test/java/org/entur/example/web/WebLoggingFormatTest.java @@ -2,6 +2,8 @@ import static org.assertj.core.api.Assertions.assertThat; +import no.entur.logging.cloud.api.DevOpsLogger; +import no.entur.logging.cloud.api.DevOpsLoggerFactory; import no.entur.logging.cloud.logback.logstash.test.CompositeConsoleOutputControl; import no.entur.logging.cloud.logback.logstash.test.CompositeConsoleOutputControlClosable; import org.entur.example.web.rest.MyEntity; diff --git a/gcp/logback-logstash-encoder-gcp/src/main/java/no/entur/logging/cloud/gcp/logback/logstash/StackdriverLogstashEncoder.java b/gcp/logback-logstash-encoder-gcp/src/main/java/no/entur/logging/cloud/gcp/logback/logstash/StackdriverLogstashEncoder.java index bb3f1afb..1ba92893 100644 --- a/gcp/logback-logstash-encoder-gcp/src/main/java/no/entur/logging/cloud/gcp/logback/logstash/StackdriverLogstashEncoder.java +++ b/gcp/logback-logstash-encoder-gcp/src/main/java/no/entur/logging/cloud/gcp/logback/logstash/StackdriverLogstashEncoder.java @@ -22,8 +22,12 @@ public class StackdriverLogstashEncoder extends LogstashEncoder { + private final StackdriverMessageJsonProvider stackdriverMessageJsonProvider = new StackdriverMessageJsonProvider(); + @Override protected AbstractCompositeJsonFormatter createFormatter() { + System.out.println("Create formatter"); + LogstashFormatter formatter = (LogstashFormatter) super.createFormatter(); LoggingEventJsonProviders loggingEventJsonProviders = formatter.getProviders(); @@ -70,4 +74,5 @@ private boolean detectOpenTelemetry() { return false; } } + } diff --git a/gcp/logback-logstash-encoder-gcp/src/main/java/no/entur/logging/cloud/gcp/logback/logstash/StackdriverMessageJsonProvider.java b/gcp/logback-logstash-encoder-gcp/src/main/java/no/entur/logging/cloud/gcp/logback/logstash/StackdriverMessageJsonProvider.java index e00fdbac..9d37aaec 100644 --- a/gcp/logback-logstash-encoder-gcp/src/main/java/no/entur/logging/cloud/gcp/logback/logstash/StackdriverMessageJsonProvider.java +++ b/gcp/logback-logstash-encoder-gcp/src/main/java/no/entur/logging/cloud/gcp/logback/logstash/StackdriverMessageJsonProvider.java @@ -6,74 +6,59 @@ import com.fasterxml.jackson.core.JsonGenerator; import net.logstash.logback.composite.JsonWritingUtils; import net.logstash.logback.composite.loggingevent.MessageJsonProvider; +import net.logstash.logback.stacktrace.ShortenedThrowableConverter; import java.io.IOException; +import java.util.Arrays; public class StackdriverMessageJsonProvider extends MessageJsonProvider { + private ShortenedThrowableConverter throwableConverter; + + public StackdriverMessageJsonProvider() { + throwableConverter = new ShortenedThrowableConverter(); + throwableConverter.setMaxLength(24 * 1024); + throwableConverter.setOmitCommonFrames(true); + throwableConverter.setShortenedClassNameLength(192); + throwableConverter.setLineSeparator("\n"); + } + + @Override + public void start() { + super.start(); + throwableConverter.start(); + } + + @Override + public void stop() { + super.stop(); + throwableConverter.stop(); + } + @Override public void writeTo(JsonGenerator generator, ILoggingEvent event) throws IOException { IThrowableProxy throwableProxy = event.getThrowableProxy(); if (throwableProxy != null) { String formattedMessage = event.getFormattedMessage(); - String message = throwableProxy.getMessage(); - StringBuilder messageWithStackTrace = new StringBuilder(); - if(formattedMessage != null && !formattedMessage.isEmpty() && message != null && !message.isEmpty()) { + + String stacktrace = throwableConverter.convert(event); + + if(formattedMessage != null) { + StringBuilder messageWithStackTrace = new StringBuilder(formattedMessage.length() + 2 + stacktrace.length()); + messageWithStackTrace.append(formattedMessage); - - if(Character.isLetterOrDigit(formattedMessage.charAt(formattedMessage.length() - 1))) { + if (Character.isLetterOrDigit(formattedMessage.charAt(formattedMessage.length() - 1))) { messageWithStackTrace.append('.'); } - messageWithStackTrace.append(' '); - messageWithStackTrace.append(message); - messageWithStackTrace.append('\n'); - } else if(formattedMessage != null && !formattedMessage.isEmpty()) { - messageWithStackTrace.append(formattedMessage); - messageWithStackTrace.append('\n'); - } else if(message != null && !message.isEmpty()) { - messageWithStackTrace.append(message); - messageWithStackTrace.append('\n'); - } - - writeStack(throwableProxy, "", messageWithStackTrace); + messageWithStackTrace.append(throwableConverter.convert(event)); - JsonWritingUtils.writeStringField(generator, getFieldName(), messageWithStackTrace.toString()); + JsonWritingUtils.writeStringField(generator, getFieldName(), messageWithStackTrace.toString()); + } else { + JsonWritingUtils.writeStringField(generator, getFieldName(), stacktrace); + } } else { super.writeTo(generator, event); } } - - /** - * Format stack-trace - * - * @see https://github.com/GoogleCloudPlatform/google-cloud-java/tree/master/google-cloud-contrib/google-cloud-logging-logback - */ - - static void writeStack(IThrowableProxy throwProxy, String prefix, StringBuilder payload) { - if (throwProxy == null) { - return; - } - payload - .append(prefix) - .append(throwProxy.getClassName()) - .append(": ") - .append(throwProxy.getMessage()) - .append('\n'); - StackTraceElementProxy[] trace = throwProxy.getStackTraceElementProxyArray(); - if (trace == null) { - trace = new StackTraceElementProxy[0]; - } - - int commonFrames = throwProxy.getCommonFrames(); - int printFrames = trace.length - commonFrames; - for (int i = 0; i < printFrames; i++) { - payload.append(" ").append(trace[i]).append('\n'); - } - if (commonFrames != 0) { - payload.append(" ... ").append(commonFrames).append(" common frames elided\n"); - } - - writeStack(throwProxy.getCause(), "caused by: ", payload); - } } diff --git a/gcp/spring-boot-starter-gcp-web/src/test/java/no/entur/logging/cloud/gcp/spring/web/LoadContextLoggingTest.java b/gcp/spring-boot-starter-gcp-web/src/test/java/no/entur/logging/cloud/gcp/spring/web/LoadContextLoggingTest.java index 7a25f53b..abb051c0 100644 --- a/gcp/spring-boot-starter-gcp-web/src/test/java/no/entur/logging/cloud/gcp/spring/web/LoadContextLoggingTest.java +++ b/gcp/spring-boot-starter-gcp-web/src/test/java/no/entur/logging/cloud/gcp/spring/web/LoadContextLoggingTest.java @@ -30,4 +30,19 @@ public void testMachineReadableJson() throws IOException { LOGGER.errorWakeMeUpRightNow("Test error wake me up right now message"); } + @Test + public void testMachineReadableJsonWithException() throws IOException { + IOException e = new IOException("Something went wrong"); + + LOGGER.trace("Test trace message", e); + LOGGER.debug("Test debug message", e); + LOGGER.info("Test info message", e); + LOGGER.warn("Test warn message", e); + LOGGER.error("Test error message", e); + + LOGGER.errorTellMeTomorrow("Test error tell me tomorrow message", e); + LOGGER.errorInterruptMyDinner("Test error interrupt my dinner message", e); + LOGGER.errorWakeMeUpRightNow("Test error wake me up right now message", e); + } + } From afe5dc537736568b84a9ab98354af61ad624eaab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20Skj=C3=B8lberg?= Date: Tue, 3 Feb 2026 22:25:28 +0100 Subject: [PATCH 10/20] Adjust so that throwableConverter can be configured via xml --- .../logstash/StackdriverLogstashEncoder.java | 7 +++-- .../StackdriverMessageJsonProvider.java | 26 ++++++++++--------- .../StackdriverTimestampJsonProvider.java | 9 +++++-- .../logback/logback-default-server.xml | 5 ++++ .../spring/web/LoadContextLoggingTest.java | 18 ++++++------- 5 files changed, 38 insertions(+), 27 deletions(-) diff --git a/gcp/logback-logstash-encoder-gcp/src/main/java/no/entur/logging/cloud/gcp/logback/logstash/StackdriverLogstashEncoder.java b/gcp/logback-logstash-encoder-gcp/src/main/java/no/entur/logging/cloud/gcp/logback/logstash/StackdriverLogstashEncoder.java index 1ba92893..f290360a 100644 --- a/gcp/logback-logstash-encoder-gcp/src/main/java/no/entur/logging/cloud/gcp/logback/logstash/StackdriverLogstashEncoder.java +++ b/gcp/logback-logstash-encoder-gcp/src/main/java/no/entur/logging/cloud/gcp/logback/logstash/StackdriverLogstashEncoder.java @@ -22,12 +22,11 @@ public class StackdriverLogstashEncoder extends LogstashEncoder { - private final StackdriverMessageJsonProvider stackdriverMessageJsonProvider = new StackdriverMessageJsonProvider(); + public StackdriverLogstashEncoder() { + } @Override protected AbstractCompositeJsonFormatter createFormatter() { - System.out.println("Create formatter"); - LogstashFormatter formatter = (LogstashFormatter) super.createFormatter(); LoggingEventJsonProviders loggingEventJsonProviders = formatter.getProviders(); @@ -61,7 +60,7 @@ protected AbstractCompositeJsonFormatter createFormatter() { } loggingEventJsonProviders.addProvider(new StackdriverLogSeverityJsonProvider()); - loggingEventJsonProviders.addProvider(new StackdriverMessageJsonProvider()); + loggingEventJsonProviders.addProvider(new StackdriverMessageJsonProvider(formatter)); return formatter; } diff --git a/gcp/logback-logstash-encoder-gcp/src/main/java/no/entur/logging/cloud/gcp/logback/logstash/StackdriverMessageJsonProvider.java b/gcp/logback-logstash-encoder-gcp/src/main/java/no/entur/logging/cloud/gcp/logback/logstash/StackdriverMessageJsonProvider.java index 9d37aaec..5a023175 100644 --- a/gcp/logback-logstash-encoder-gcp/src/main/java/no/entur/logging/cloud/gcp/logback/logstash/StackdriverMessageJsonProvider.java +++ b/gcp/logback-logstash-encoder-gcp/src/main/java/no/entur/logging/cloud/gcp/logback/logstash/StackdriverMessageJsonProvider.java @@ -1,38 +1,39 @@ package no.entur.logging.cloud.gcp.logback.logstash; +import ch.qos.logback.classic.pattern.ThrowableHandlingConverter; import ch.qos.logback.classic.spi.ILoggingEvent; import ch.qos.logback.classic.spi.IThrowableProxy; -import ch.qos.logback.classic.spi.StackTraceElementProxy; import com.fasterxml.jackson.core.JsonGenerator; +import net.logstash.logback.LogstashFormatter; import net.logstash.logback.composite.JsonWritingUtils; import net.logstash.logback.composite.loggingevent.MessageJsonProvider; -import net.logstash.logback.stacktrace.ShortenedThrowableConverter; import java.io.IOException; -import java.util.Arrays; public class StackdriverMessageJsonProvider extends MessageJsonProvider { - private ShortenedThrowableConverter throwableConverter; + private final LogstashFormatter formatter; + private ThrowableHandlingConverter throwableConverter; - public StackdriverMessageJsonProvider() { - throwableConverter = new ShortenedThrowableConverter(); - throwableConverter.setMaxLength(24 * 1024); - throwableConverter.setOmitCommonFrames(true); - throwableConverter.setShortenedClassNameLength(192); - throwableConverter.setLineSeparator("\n"); + public StackdriverMessageJsonProvider(LogstashFormatter formatter) { + this.formatter = formatter; } @Override public void start() { super.start(); - throwableConverter.start(); + throwableConverter = formatter.getThrowableConverter(); + if(!throwableConverter.isStarted()) { + throwableConverter.start(); + } } @Override public void stop() { super.stop(); - throwableConverter.stop(); + if(throwableConverter.isStarted()) { + throwableConverter.stop(); + } } @Override @@ -61,4 +62,5 @@ public void writeTo(JsonGenerator generator, ILoggingEvent event) throws IOExcep super.writeTo(generator, event); } } + } diff --git a/gcp/logback-logstash-encoder-gcp/src/main/java/no/entur/logging/cloud/gcp/logback/logstash/StackdriverTimestampJsonProvider.java b/gcp/logback-logstash-encoder-gcp/src/main/java/no/entur/logging/cloud/gcp/logback/logstash/StackdriverTimestampJsonProvider.java index 3ddae3e8..fee04fc4 100644 --- a/gcp/logback-logstash-encoder-gcp/src/main/java/no/entur/logging/cloud/gcp/logback/logstash/StackdriverTimestampJsonProvider.java +++ b/gcp/logback-logstash-encoder-gcp/src/main/java/no/entur/logging/cloud/gcp/logback/logstash/StackdriverTimestampJsonProvider.java @@ -3,7 +3,6 @@ import ch.qos.logback.classic.spi.ILoggingEvent; import com.fasterxml.jackson.core.JsonGenerator; import net.logstash.logback.composite.AbstractJsonProvider; -import net.logstash.logback.composite.JsonWritingUtils; import java.io.IOException; @@ -23,7 +22,13 @@ public class StackdriverTimestampJsonProvider extends AbstractJsonProvider= 0) { + generator.writeNumberField("nanos", nanoseconds % 1000_000_000); + } else { + generator.writeNumberField("nanos", 0); + } generator.writeEndObject(); } diff --git a/gcp/logback-logstash-encoder-gcp/src/main/resources/logback/logback-default-server.xml b/gcp/logback-logstash-encoder-gcp/src/main/resources/logback/logback-default-server.xml index 477fa121..d005133d 100644 --- a/gcp/logback-logstash-encoder-gcp/src/main/resources/logback/logback-default-server.xml +++ b/gcp/logback-logstash-encoder-gcp/src/main/resources/logback/logback-default-server.xml @@ -8,6 +8,11 @@ + + + 24576 + 192 + \ No newline at end of file diff --git a/gcp/spring-boot-starter-gcp-web/src/test/java/no/entur/logging/cloud/gcp/spring/web/LoadContextLoggingTest.java b/gcp/spring-boot-starter-gcp-web/src/test/java/no/entur/logging/cloud/gcp/spring/web/LoadContextLoggingTest.java index abb051c0..09d45df9 100644 --- a/gcp/spring-boot-starter-gcp-web/src/test/java/no/entur/logging/cloud/gcp/spring/web/LoadContextLoggingTest.java +++ b/gcp/spring-boot-starter-gcp-web/src/test/java/no/entur/logging/cloud/gcp/spring/web/LoadContextLoggingTest.java @@ -34,15 +34,15 @@ public void testMachineReadableJson() throws IOException { public void testMachineReadableJsonWithException() throws IOException { IOException e = new IOException("Something went wrong"); - LOGGER.trace("Test trace message", e); - LOGGER.debug("Test debug message", e); - LOGGER.info("Test info message", e); - LOGGER.warn("Test warn message", e); - LOGGER.error("Test error message", e); - - LOGGER.errorTellMeTomorrow("Test error tell me tomorrow message", e); - LOGGER.errorInterruptMyDinner("Test error interrupt my dinner message", e); - LOGGER.errorWakeMeUpRightNow("Test error wake me up right now message", e); + LOGGER.trace("Test trace message with exception", e); + LOGGER.debug("Test debug message with exception", e); + LOGGER.info("Test info message with exception", e); + LOGGER.warn("Test warn message with exception", e); + LOGGER.error("Test error message with exception", e); + + LOGGER.errorTellMeTomorrow("Test error tell me tomorrow message with exception", e); + LOGGER.errorInterruptMyDinner("Test error interrupt my dinner message with exception", e); + LOGGER.errorWakeMeUpRightNow("Test error wake me up right now message with exception", e); } } From da1e2694b25b447e33665b507a5cd66f19ca21b8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20Skj=C3=B8lberg?= Date: Tue, 3 Feb 2026 22:28:46 +0100 Subject: [PATCH 11/20] Clean up --- .../test/java/org/entur/example/web/WebLoggingFormatTest.java | 2 -- .../gcp/logback/logstash/StackdriverLogstashEncoder.java | 4 ---- 2 files changed, 6 deletions(-) diff --git a/examples/gcp-web-example/src/test/java/org/entur/example/web/WebLoggingFormatTest.java b/examples/gcp-web-example/src/test/java/org/entur/example/web/WebLoggingFormatTest.java index 38e0dddf..5aeef7f4 100644 --- a/examples/gcp-web-example/src/test/java/org/entur/example/web/WebLoggingFormatTest.java +++ b/examples/gcp-web-example/src/test/java/org/entur/example/web/WebLoggingFormatTest.java @@ -2,8 +2,6 @@ import static org.assertj.core.api.Assertions.assertThat; -import no.entur.logging.cloud.api.DevOpsLogger; -import no.entur.logging.cloud.api.DevOpsLoggerFactory; import no.entur.logging.cloud.logback.logstash.test.CompositeConsoleOutputControl; import no.entur.logging.cloud.logback.logstash.test.CompositeConsoleOutputControlClosable; import org.entur.example.web.rest.MyEntity; diff --git a/gcp/logback-logstash-encoder-gcp/src/main/java/no/entur/logging/cloud/gcp/logback/logstash/StackdriverLogstashEncoder.java b/gcp/logback-logstash-encoder-gcp/src/main/java/no/entur/logging/cloud/gcp/logback/logstash/StackdriverLogstashEncoder.java index f290360a..f1f8f83b 100644 --- a/gcp/logback-logstash-encoder-gcp/src/main/java/no/entur/logging/cloud/gcp/logback/logstash/StackdriverLogstashEncoder.java +++ b/gcp/logback-logstash-encoder-gcp/src/main/java/no/entur/logging/cloud/gcp/logback/logstash/StackdriverLogstashEncoder.java @@ -22,9 +22,6 @@ public class StackdriverLogstashEncoder extends LogstashEncoder { - public StackdriverLogstashEncoder() { - } - @Override protected AbstractCompositeJsonFormatter createFormatter() { LogstashFormatter formatter = (LogstashFormatter) super.createFormatter(); @@ -73,5 +70,4 @@ private boolean detectOpenTelemetry() { return false; } } - } From 133e1457c48e43311d82837c50fbd8d0fb22709e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20Skj=C3=B8lberg?= Date: Wed, 4 Feb 2026 10:43:44 +0100 Subject: [PATCH 12/20] Revert --- .../logstash/StackdriverTimestampJsonProvider.java | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/gcp/logback-logstash-encoder-gcp/src/main/java/no/entur/logging/cloud/gcp/logback/logstash/StackdriverTimestampJsonProvider.java b/gcp/logback-logstash-encoder-gcp/src/main/java/no/entur/logging/cloud/gcp/logback/logstash/StackdriverTimestampJsonProvider.java index fee04fc4..3ddae3e8 100644 --- a/gcp/logback-logstash-encoder-gcp/src/main/java/no/entur/logging/cloud/gcp/logback/logstash/StackdriverTimestampJsonProvider.java +++ b/gcp/logback-logstash-encoder-gcp/src/main/java/no/entur/logging/cloud/gcp/logback/logstash/StackdriverTimestampJsonProvider.java @@ -3,6 +3,7 @@ import ch.qos.logback.classic.spi.ILoggingEvent; import com.fasterxml.jackson.core.JsonGenerator; import net.logstash.logback.composite.AbstractJsonProvider; +import net.logstash.logback.composite.JsonWritingUtils; import java.io.IOException; @@ -22,13 +23,7 @@ public class StackdriverTimestampJsonProvider extends AbstractJsonProvider= 0) { - generator.writeNumberField("nanos", nanoseconds % 1000_000_000); - } else { - generator.writeNumberField("nanos", 0); - } + generator.writeNumberField("nanos", event.getNanoseconds()); generator.writeEndObject(); } From ce12102133b140daae4c71e0269ac66276d73e5d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20Skj=C3=B8lberg?= Date: Wed, 4 Feb 2026 11:10:30 +0100 Subject: [PATCH 13/20] Also update machine readable formatting for testing output --- .../src/main/resources/logback/logback-default-server.xml | 3 +-- .../src/main/resources/logback/logback-spring-test.xml | 5 +++++ 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/gcp/logback-logstash-encoder-gcp/src/main/resources/logback/logback-default-server.xml b/gcp/logback-logstash-encoder-gcp/src/main/resources/logback/logback-default-server.xml index d005133d..a42d17fa 100644 --- a/gcp/logback-logstash-encoder-gcp/src/main/resources/logback/logback-default-server.xml +++ b/gcp/logback-logstash-encoder-gcp/src/main/resources/logback/logback-default-server.xml @@ -5,8 +5,7 @@ [ignore] [ignore] - - + diff --git a/gcp/spring-boot-autoconfigure-gcp-test/src/main/resources/logback/logback-spring-test.xml b/gcp/spring-boot-autoconfigure-gcp-test/src/main/resources/logback/logback-spring-test.xml index 359bb798..c1c51f44 100644 --- a/gcp/spring-boot-autoconfigure-gcp-test/src/main/resources/logback/logback-spring-test.xml +++ b/gcp/spring-boot-autoconfigure-gcp-test/src/main/resources/logback/logback-spring-test.xml @@ -40,6 +40,11 @@ + + + 24576 + 192 + From b541cf9d39c202a327ebf518c5cd31290af9bfe9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20Skj=C3=B8lberg?= Date: Wed, 4 Feb 2026 11:30:59 +0100 Subject: [PATCH 14/20] QA fixes --- .../StackdriverMessageJsonProvider.java | 44 +++++++++++++------ 1 file changed, 31 insertions(+), 13 deletions(-) diff --git a/gcp/logback-logstash-encoder-gcp/src/main/java/no/entur/logging/cloud/gcp/logback/logstash/StackdriverMessageJsonProvider.java b/gcp/logback-logstash-encoder-gcp/src/main/java/no/entur/logging/cloud/gcp/logback/logstash/StackdriverMessageJsonProvider.java index 5a023175..b49f6c71 100644 --- a/gcp/logback-logstash-encoder-gcp/src/main/java/no/entur/logging/cloud/gcp/logback/logstash/StackdriverMessageJsonProvider.java +++ b/gcp/logback-logstash-encoder-gcp/src/main/java/no/entur/logging/cloud/gcp/logback/logstash/StackdriverMessageJsonProvider.java @@ -1,5 +1,6 @@ package no.entur.logging.cloud.gcp.logback.logstash; +import ch.qos.logback.classic.pattern.ExtendedThrowableProxyConverter; import ch.qos.logback.classic.pattern.ThrowableHandlingConverter; import ch.qos.logback.classic.spi.ILoggingEvent; import ch.qos.logback.classic.spi.IThrowableProxy; @@ -23,17 +24,28 @@ public StackdriverMessageJsonProvider(LogstashFormatter formatter) { public void start() { super.start(); throwableConverter = formatter.getThrowableConverter(); + + if(throwableConverter == null) { + throwableConverter = createThrowableConverter(); + } + if(!throwableConverter.isStarted()) { throwableConverter.start(); } } - @Override + protected ThrowableHandlingConverter createThrowableConverter() { + return new ExtendedThrowableProxyConverter(); + } + + @Override public void stop() { super.stop(); - if(throwableConverter.isStarted()) { - throwableConverter.stop(); - } + if(throwableConverter != null) { + if(throwableConverter.isStarted()) { + throwableConverter.stop(); + } + } } @Override @@ -41,26 +53,32 @@ public void writeTo(JsonGenerator generator, ILoggingEvent event) throws IOExcep IThrowableProxy throwableProxy = event.getThrowableProxy(); if (throwableProxy != null) { String formattedMessage = event.getFormattedMessage(); - String stacktrace = throwableConverter.convert(event); - if(formattedMessage != null) { + if(formattedMessage != null && stacktrace != null) { StringBuilder messageWithStackTrace = new StringBuilder(formattedMessage.length() + 2 + stacktrace.length()); - messageWithStackTrace.append(formattedMessage); - if (Character.isLetterOrDigit(formattedMessage.charAt(formattedMessage.length() - 1))) { - messageWithStackTrace.append('.'); - } - messageWithStackTrace.append(' '); - messageWithStackTrace.append(throwableConverter.convert(event)); + if(!formattedMessage.isEmpty()) { + messageWithStackTrace.append(formattedMessage); + if (Character.isLetterOrDigit(formattedMessage.charAt(formattedMessage.length() - 1))) { + messageWithStackTrace.append('.'); + } + messageWithStackTrace.append(' '); + } + messageWithStackTrace.append(stacktrace); JsonWritingUtils.writeStringField(generator, getFieldName(), messageWithStackTrace.toString()); - } else { + } else if (stacktrace != null) { JsonWritingUtils.writeStringField(generator, getFieldName(), stacktrace); + } else if (formattedMessage != null) { + JsonWritingUtils.writeStringField(generator, getFieldName(), formattedMessage); } } else { super.writeTo(generator, event); } } + public void setThrowableConverter(ThrowableHandlingConverter throwableConverter) { + this.throwableConverter = throwableConverter; + } } From 6488d4f017c559f1c1718eb86a3d268c711b8168 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20Skj=C3=B8lberg?= Date: Wed, 4 Feb 2026 11:58:37 +0100 Subject: [PATCH 15/20] Simplify logic, remove use of stringbuilder --- .../StackdriverMessageJsonProvider.java | 31 +++++++++++-------- 1 file changed, 18 insertions(+), 13 deletions(-) diff --git a/gcp/logback-logstash-encoder-gcp/src/main/java/no/entur/logging/cloud/gcp/logback/logstash/StackdriverMessageJsonProvider.java b/gcp/logback-logstash-encoder-gcp/src/main/java/no/entur/logging/cloud/gcp/logback/logstash/StackdriverMessageJsonProvider.java index b49f6c71..2cbc83d1 100644 --- a/gcp/logback-logstash-encoder-gcp/src/main/java/no/entur/logging/cloud/gcp/logback/logstash/StackdriverMessageJsonProvider.java +++ b/gcp/logback-logstash-encoder-gcp/src/main/java/no/entur/logging/cloud/gcp/logback/logstash/StackdriverMessageJsonProvider.java @@ -53,25 +53,30 @@ public void writeTo(JsonGenerator generator, ILoggingEvent event) throws IOExcep IThrowableProxy throwableProxy = event.getThrowableProxy(); if (throwableProxy != null) { String formattedMessage = event.getFormattedMessage(); + String stacktrace = throwableConverter.convert(event); - if(formattedMessage != null && stacktrace != null) { - StringBuilder messageWithStackTrace = new StringBuilder(formattedMessage.length() + 2 + stacktrace.length()); + boolean writeFormattedMessage = formattedMessage != null && !formattedMessage.isEmpty(); + boolean writeStacktrace = stacktrace != null && !stacktrace.isEmpty(); - if(!formattedMessage.isEmpty()) { - messageWithStackTrace.append(formattedMessage); - if (Character.isLetterOrDigit(formattedMessage.charAt(formattedMessage.length() - 1))) { - messageWithStackTrace.append('.'); - } - messageWithStackTrace.append(' '); + if(writeFormattedMessage && writeStacktrace) { + // stacktrace is on the form: + // "exception-name colon exception-message newline tab at x.y.z newline tab at a.b.c and so on" + // so add a space and potentially a dot between the log statement message and the first line of the + // formatted stacktrace + String message; + if (Character.isLetterOrDigit(formattedMessage.charAt(formattedMessage.length() - 1))) { + message = formattedMessage + ". " + stacktrace; + } else { + message = formattedMessage + ' ' + stacktrace; } - messageWithStackTrace.append(stacktrace); - - JsonWritingUtils.writeStringField(generator, getFieldName(), messageWithStackTrace.toString()); - } else if (stacktrace != null) { + JsonWritingUtils.writeStringField(generator, getFieldName(), message); + } else if (writeStacktrace) { JsonWritingUtils.writeStringField(generator, getFieldName(), stacktrace); - } else if (formattedMessage != null) { + } else if (writeFormattedMessage) { JsonWritingUtils.writeStringField(generator, getFieldName(), formattedMessage); + } else { + super.writeTo(generator, event); } } else { super.writeTo(generator, event); From b433a032e7c725ae277e33246e93c558eb1f3ee5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20Skj=C3=B8lberg?= Date: Wed, 4 Feb 2026 12:07:54 +0100 Subject: [PATCH 16/20] Adjust for QA --- .../logback/logstash/StackdriverMessageJsonProvider.java | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/gcp/logback-logstash-encoder-gcp/src/main/java/no/entur/logging/cloud/gcp/logback/logstash/StackdriverMessageJsonProvider.java b/gcp/logback-logstash-encoder-gcp/src/main/java/no/entur/logging/cloud/gcp/logback/logstash/StackdriverMessageJsonProvider.java index 2cbc83d1..08fb9c2e 100644 --- a/gcp/logback-logstash-encoder-gcp/src/main/java/no/entur/logging/cloud/gcp/logback/logstash/StackdriverMessageJsonProvider.java +++ b/gcp/logback-logstash-encoder-gcp/src/main/java/no/entur/logging/cloud/gcp/logback/logstash/StackdriverMessageJsonProvider.java @@ -24,8 +24,8 @@ public StackdriverMessageJsonProvider(LogstashFormatter formatter) { public void start() { super.start(); throwableConverter = formatter.getThrowableConverter(); - if(throwableConverter == null) { + // this should never happen throwableConverter = createThrowableConverter(); } @@ -35,7 +35,9 @@ public void start() { } protected ThrowableHandlingConverter createThrowableConverter() { - return new ExtendedThrowableProxyConverter(); + ExtendedThrowableProxyConverter converter = new ExtendedThrowableProxyConverter(); + converter.setContext(getContext()); + return converter; } @Override From 5de9e5b2f2254f1edf55c167b8e2da7ebc8b1015 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20Skj=C3=B8lberg?= Date: Wed, 4 Feb 2026 12:09:04 +0100 Subject: [PATCH 17/20] Format --- .../StackdriverMessageJsonProvider.java | 70 +++++++++---------- 1 file changed, 35 insertions(+), 35 deletions(-) diff --git a/gcp/logback-logstash-encoder-gcp/src/main/java/no/entur/logging/cloud/gcp/logback/logstash/StackdriverMessageJsonProvider.java b/gcp/logback-logstash-encoder-gcp/src/main/java/no/entur/logging/cloud/gcp/logback/logstash/StackdriverMessageJsonProvider.java index 08fb9c2e..8a45cb6f 100644 --- a/gcp/logback-logstash-encoder-gcp/src/main/java/no/entur/logging/cloud/gcp/logback/logstash/StackdriverMessageJsonProvider.java +++ b/gcp/logback-logstash-encoder-gcp/src/main/java/no/entur/logging/cloud/gcp/logback/logstash/StackdriverMessageJsonProvider.java @@ -24,30 +24,30 @@ public StackdriverMessageJsonProvider(LogstashFormatter formatter) { public void start() { super.start(); throwableConverter = formatter.getThrowableConverter(); - if(throwableConverter == null) { - // this should never happen - throwableConverter = createThrowableConverter(); - } + if(throwableConverter == null) { + // this should never happen + throwableConverter = createThrowableConverter(); + } if(!throwableConverter.isStarted()) { throwableConverter.start(); } } - protected ThrowableHandlingConverter createThrowableConverter() { - ExtendedThrowableProxyConverter converter = new ExtendedThrowableProxyConverter(); - converter.setContext(getContext()); - return converter; - } + protected ThrowableHandlingConverter createThrowableConverter() { + ExtendedThrowableProxyConverter converter = new ExtendedThrowableProxyConverter(); + converter.setContext(getContext()); + return converter; + } - @Override + @Override public void stop() { super.stop(); - if(throwableConverter != null) { - if(throwableConverter.isStarted()) { - throwableConverter.stop(); - } - } + if(throwableConverter != null) { + if(throwableConverter.isStarted()) { + throwableConverter.stop(); + } + } } @Override @@ -58,34 +58,34 @@ public void writeTo(JsonGenerator generator, ILoggingEvent event) throws IOExcep String stacktrace = throwableConverter.convert(event); - boolean writeFormattedMessage = formattedMessage != null && !formattedMessage.isEmpty(); - boolean writeStacktrace = stacktrace != null && !stacktrace.isEmpty(); + boolean writeFormattedMessage = formattedMessage != null && !formattedMessage.isEmpty(); + boolean writeStacktrace = stacktrace != null && !stacktrace.isEmpty(); if(writeFormattedMessage && writeStacktrace) { - // stacktrace is on the form: - // "exception-name colon exception-message newline tab at x.y.z newline tab at a.b.c and so on" - // so add a space and potentially a dot between the log statement message and the first line of the - // formatted stacktrace - String message; - if (Character.isLetterOrDigit(formattedMessage.charAt(formattedMessage.length() - 1))) { - message = formattedMessage + ". " + stacktrace; - } else { - message = formattedMessage + ' ' + stacktrace; - } - JsonWritingUtils.writeStringField(generator, getFieldName(), message); + // stacktrace is on the form: + // "exception-name colon exception-message newline tab at x.y.z newline tab at a.b.c and so on" + // so add a space and potentially a dot between the log statement message and the first line of the + // formatted stacktrace + String message; + if (Character.isLetterOrDigit(formattedMessage.charAt(formattedMessage.length() - 1))) { + message = formattedMessage + ". " + stacktrace; + } else { + message = formattedMessage + ' ' + stacktrace; + } + JsonWritingUtils.writeStringField(generator, getFieldName(), message); } else if (writeStacktrace) { JsonWritingUtils.writeStringField(generator, getFieldName(), stacktrace); - } else if (writeFormattedMessage) { - JsonWritingUtils.writeStringField(generator, getFieldName(), formattedMessage); - } else { - super.writeTo(generator, event); + } else if (writeFormattedMessage) { + JsonWritingUtils.writeStringField(generator, getFieldName(), formattedMessage); + } else { + super.writeTo(generator, event); } } else { super.writeTo(generator, event); } } - public void setThrowableConverter(ThrowableHandlingConverter throwableConverter) { - this.throwableConverter = throwableConverter; - } + public void setThrowableConverter(ThrowableHandlingConverter throwableConverter) { + this.throwableConverter = throwableConverter; + } } From f4fd06dd0dc8e64d706009e82ed293e53fcb2f76 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20Skj=C3=B8lberg?= Date: Wed, 4 Feb 2026 12:10:13 +0100 Subject: [PATCH 18/20] Remove setter --- .../gcp/logback/logstash/StackdriverMessageJsonProvider.java | 3 --- 1 file changed, 3 deletions(-) diff --git a/gcp/logback-logstash-encoder-gcp/src/main/java/no/entur/logging/cloud/gcp/logback/logstash/StackdriverMessageJsonProvider.java b/gcp/logback-logstash-encoder-gcp/src/main/java/no/entur/logging/cloud/gcp/logback/logstash/StackdriverMessageJsonProvider.java index 8a45cb6f..252732ae 100644 --- a/gcp/logback-logstash-encoder-gcp/src/main/java/no/entur/logging/cloud/gcp/logback/logstash/StackdriverMessageJsonProvider.java +++ b/gcp/logback-logstash-encoder-gcp/src/main/java/no/entur/logging/cloud/gcp/logback/logstash/StackdriverMessageJsonProvider.java @@ -85,7 +85,4 @@ public void writeTo(JsonGenerator generator, ILoggingEvent event) throws IOExcep } } - public void setThrowableConverter(ThrowableHandlingConverter throwableConverter) { - this.throwableConverter = throwableConverter; - } } From 1dcce119e6d2bd5ac39371901e0e42b3980f8829 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20Skj=C3=B8lberg?= Date: Wed, 4 Feb 2026 17:13:51 +0100 Subject: [PATCH 19/20] Syntax-highlighted stacktraces --- .../resources/logback/logback-spring-test.xml | 2 +- .../logback/spring-defaults-test.xml | 8 ++- .../web/test/LoadContextLoggingTest.java | 6 +- ...ndedWhitespaceThrowableProxyConverter.java | 60 +++++++++++++++++++ 4 files changed, 70 insertions(+), 6 deletions(-) create mode 100644 test/test-logback/src/main/java/no/entur/logging/cloud/logback/test/ExtendedWhitespaceThrowableProxyConverter.java diff --git a/gcp/spring-boot-autoconfigure-gcp-test/src/main/resources/logback/logback-spring-test.xml b/gcp/spring-boot-autoconfigure-gcp-test/src/main/resources/logback/logback-spring-test.xml index c1c51f44..703d96b5 100644 --- a/gcp/spring-boot-autoconfigure-gcp-test/src/main/resources/logback/logback-spring-test.xml +++ b/gcp/spring-boot-autoconfigure-gcp-test/src/main/resources/logback/logback-spring-test.xml @@ -3,7 +3,7 @@ - + ${CONSOLE_LOG_THRESHOLD} diff --git a/gcp/spring-boot-autoconfigure-gcp-test/src/main/resources/logback/spring-defaults-test.xml b/gcp/spring-boot-autoconfigure-gcp-test/src/main/resources/logback/spring-defaults-test.xml index 6e8ca452..94c9640a 100644 --- a/gcp/spring-boot-autoconfigure-gcp-test/src/main/resources/logback/spring-defaults-test.xml +++ b/gcp/spring-boot-autoconfigure-gcp-test/src/main/resources/logback/spring-defaults-test.xml @@ -9,10 +9,14 @@ Default logback configuration provided for import by spring, modified to give me --> + + + + - + - + diff --git a/gcp/spring-boot-starter-gcp-web-test/src/test/java/no/entur/logging/cloud/gcp/spring/web/test/LoadContextLoggingTest.java b/gcp/spring-boot-starter-gcp-web-test/src/test/java/no/entur/logging/cloud/gcp/spring/web/test/LoadContextLoggingTest.java index 146e14bc..1068ffd9 100644 --- a/gcp/spring-boot-starter-gcp-web-test/src/test/java/no/entur/logging/cloud/gcp/spring/web/test/LoadContextLoggingTest.java +++ b/gcp/spring-boot-starter-gcp-web-test/src/test/java/no/entur/logging/cloud/gcp/spring/web/test/LoadContextLoggingTest.java @@ -28,9 +28,9 @@ public class LoadContextLoggingTest { public void testHumanReadablePlain() { CompositeConsoleOutputControl.useHumanReadablePlainEncoder(); - LOGGER.trace("Test trace message"); - LOGGER.debug("Test debug message"); - LOGGER.info("Test info message"); + LOGGER.trace("Test trace message", new IOException("Trace exception")); + LOGGER.debug("Test debug message", new IOException("Trace exception")); + LOGGER.info("Test info message", new IOException("Trace exception")); LOGGER.warn("Test warn message"); LOGGER.error("Test error message"); diff --git a/test/test-logback/src/main/java/no/entur/logging/cloud/logback/test/ExtendedWhitespaceThrowableProxyConverter.java b/test/test-logback/src/main/java/no/entur/logging/cloud/logback/test/ExtendedWhitespaceThrowableProxyConverter.java new file mode 100644 index 00000000..6128cbb2 --- /dev/null +++ b/test/test-logback/src/main/java/no/entur/logging/cloud/logback/test/ExtendedWhitespaceThrowableProxyConverter.java @@ -0,0 +1,60 @@ +package no.entur.logging.cloud.logback.test; + +import ch.qos.logback.classic.pattern.ExtendedThrowableProxyConverter; +import ch.qos.logback.classic.spi.IThrowableProxy; +import ch.qos.logback.core.CoreConstants; + +/** + * {@link ExtendedThrowableProxyConverter} that adds some additional whitespace around the + * stack trace. + * + * @author Phillip Webb + * @since 1.3.0 + */ +public class ExtendedWhitespaceThrowableProxyConverter extends ExtendedThrowableProxyConverter { + + private String keys; + + public ExtendedWhitespaceThrowableProxyConverter() { + super(); + } + + @Override + public void start() { + String datePattern = this.getFirstOption(); + System.out.println("Detect " + datePattern); + super.start(); + } + + @Override + protected String throwableProxyToString(IThrowableProxy tp) { + String str = CoreConstants.LINE_SEPARATOR + super.throwableProxyToString(tp) + CoreConstants.LINE_SEPARATOR; + + try { + StringBuilder builder = new StringBuilder(); + + String[] parts = str.split("\n"); + for (String part : parts) { + boolean format = part.contains("no.entur") || part.contains("org.entur"); + if (format) { + builder.append("-> "); + } + builder.append(part); + builder.append("\n"); + } + + return builder.toString(); + } catch (Exception e) { + e.printStackTrace(); + return ""; + } + } + + public void setKeys(String keys) { + this.keys = keys; + } + + public String getKeys() { + return keys; + } +} From 2b6c07d21a0b5687d04bf64644e56c40d9744494 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20Skj=C3=B8lberg?= Date: Wed, 4 Feb 2026 18:25:22 +0100 Subject: [PATCH 20/20] Adjust expression --- .../logback/spring-defaults-test.xml | 8 +- .../web/test/LoadContextLoggingTest.java | 5 +- ...ndedWhitespaceThrowableProxyConverter.java | 60 ------ .../HighlightingThrowableProxyConverter.java | 198 ++++++++++++++++++ 4 files changed, 207 insertions(+), 64 deletions(-) delete mode 100644 test/test-logback/src/main/java/no/entur/logging/cloud/logback/test/ExtendedWhitespaceThrowableProxyConverter.java create mode 100644 test/test-logback/src/main/java/no/entur/logging/cloud/logback/test/HighlightingThrowableProxyConverter.java diff --git a/gcp/spring-boot-autoconfigure-gcp-test/src/main/resources/logback/spring-defaults-test.xml b/gcp/spring-boot-autoconfigure-gcp-test/src/main/resources/logback/spring-defaults-test.xml index 94c9640a..a02133d6 100644 --- a/gcp/spring-boot-autoconfigure-gcp-test/src/main/resources/logback/spring-defaults-test.xml +++ b/gcp/spring-boot-autoconfigure-gcp-test/src/main/resources/logback/spring-defaults-test.xml @@ -6,17 +6,19 @@ Default logback configuration provided for import by spring, modified to give me - date and time zone - pid - application name + - stacktrace coloring of selected packages --> - + - + + - + diff --git a/gcp/spring-boot-starter-gcp-web-test/src/test/java/no/entur/logging/cloud/gcp/spring/web/test/LoadContextLoggingTest.java b/gcp/spring-boot-starter-gcp-web-test/src/test/java/no/entur/logging/cloud/gcp/spring/web/test/LoadContextLoggingTest.java index 1068ffd9..c5b9acc6 100644 --- a/gcp/spring-boot-starter-gcp-web-test/src/test/java/no/entur/logging/cloud/gcp/spring/web/test/LoadContextLoggingTest.java +++ b/gcp/spring-boot-starter-gcp-web-test/src/test/java/no/entur/logging/cloud/gcp/spring/web/test/LoadContextLoggingTest.java @@ -11,6 +11,7 @@ import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; import org.springframework.test.annotation.DirtiesContext; +import org.springframework.test.context.TestPropertySource; import org.springframework.test.context.junit.jupiter.SpringExtension; import java.io.IOException; @@ -18,7 +19,9 @@ @ExtendWith(SpringExtension.class) @SpringBootTest(webEnvironment = WebEnvironment.NONE) @DirtiesContext - +@TestPropertySource(properties = { + "entur.logging.test.format.stacktrace.highlight=no.entur,org.entur", +}) @EnableAutoConfiguration public class LoadContextLoggingTest { diff --git a/test/test-logback/src/main/java/no/entur/logging/cloud/logback/test/ExtendedWhitespaceThrowableProxyConverter.java b/test/test-logback/src/main/java/no/entur/logging/cloud/logback/test/ExtendedWhitespaceThrowableProxyConverter.java deleted file mode 100644 index 6128cbb2..00000000 --- a/test/test-logback/src/main/java/no/entur/logging/cloud/logback/test/ExtendedWhitespaceThrowableProxyConverter.java +++ /dev/null @@ -1,60 +0,0 @@ -package no.entur.logging.cloud.logback.test; - -import ch.qos.logback.classic.pattern.ExtendedThrowableProxyConverter; -import ch.qos.logback.classic.spi.IThrowableProxy; -import ch.qos.logback.core.CoreConstants; - -/** - * {@link ExtendedThrowableProxyConverter} that adds some additional whitespace around the - * stack trace. - * - * @author Phillip Webb - * @since 1.3.0 - */ -public class ExtendedWhitespaceThrowableProxyConverter extends ExtendedThrowableProxyConverter { - - private String keys; - - public ExtendedWhitespaceThrowableProxyConverter() { - super(); - } - - @Override - public void start() { - String datePattern = this.getFirstOption(); - System.out.println("Detect " + datePattern); - super.start(); - } - - @Override - protected String throwableProxyToString(IThrowableProxy tp) { - String str = CoreConstants.LINE_SEPARATOR + super.throwableProxyToString(tp) + CoreConstants.LINE_SEPARATOR; - - try { - StringBuilder builder = new StringBuilder(); - - String[] parts = str.split("\n"); - for (String part : parts) { - boolean format = part.contains("no.entur") || part.contains("org.entur"); - if (format) { - builder.append("-> "); - } - builder.append(part); - builder.append("\n"); - } - - return builder.toString(); - } catch (Exception e) { - e.printStackTrace(); - return ""; - } - } - - public void setKeys(String keys) { - this.keys = keys; - } - - public String getKeys() { - return keys; - } -} diff --git a/test/test-logback/src/main/java/no/entur/logging/cloud/logback/test/HighlightingThrowableProxyConverter.java b/test/test-logback/src/main/java/no/entur/logging/cloud/logback/test/HighlightingThrowableProxyConverter.java new file mode 100644 index 00000000..3f486ca6 --- /dev/null +++ b/test/test-logback/src/main/java/no/entur/logging/cloud/logback/test/HighlightingThrowableProxyConverter.java @@ -0,0 +1,198 @@ +/** + * Logback: the reliable, generic, fast and flexible logging framework. + * Copyright (C) 1999-2015, QOS.ch. All rights reserved. + * + * This program and the accompanying materials are dual-licensed under + * either the terms of the Eclipse Public License v1.0 as published by + * the Eclipse Foundation + * + * or (per the licensee's choosing) + * + * under the terms of the GNU Lesser General Public License version 2.1 + * as published by the Free Software Foundation. + */ +package no.entur.logging.cloud.logback.test; + +import ch.qos.logback.classic.pattern.ThrowableHandlingConverter; +import ch.qos.logback.classic.spi.ILoggingEvent; +import ch.qos.logback.classic.spi.IThrowableProxy; +import ch.qos.logback.classic.spi.StackTraceElementProxy; +import ch.qos.logback.classic.spi.ThrowableProxyUtil; +import ch.qos.logback.core.Context; +import ch.qos.logback.core.CoreConstants; +import ch.qos.logback.core.boolex.EvaluationException; +import ch.qos.logback.core.boolex.EventEvaluator; +import ch.qos.logback.core.status.ErrorStatus; +import org.entur.jackson.jsh.AnsiSyntaxHighlight; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.function.Predicate; + +/** + * Add a stack trace in case the event contains a Throwable. + * + * Copy of {@link ch.qos.logback.classic.pattern.ExtendedThrowableProxyConverter} + extra whitespace + */ +public class HighlightingThrowableProxyConverter extends ThrowableHandlingConverter { + + protected static final int BUILDER_CAPACITY = 2048; + + int lengthOption = Integer.MAX_VALUE; + protected Predicate matcher; + + @SuppressWarnings("unchecked") + public void start() { + + List optionList = getOptionList(); + if (optionList != null && !optionList.isEmpty()) { + this.matcher = createMatcher(optionList); + } + + super.start(); + } + + private Predicate createMatcher(List optionList) { + if(optionList.size() == 1) { + String option = optionList.get(0); + return (s) -> s.getClassName().startsWith(option); + } + + return (s) -> { + for(String option : optionList) { + if(s.getClassName().startsWith(option)) { + return true; + } + } + + return false; + }; + + } + + protected void extraData(StringBuilder builder, StackTraceElementProxy step) { + // nop + } + + public String convert(ILoggingEvent event) { + IThrowableProxy tp = event.getThrowableProxy(); + if (tp == null) { + return CoreConstants.EMPTY_STRING; + } + + return throwableProxyToString(tp); + } + + protected String throwableProxyToString(IThrowableProxy tp) { + StringBuilder sb = new StringBuilder(BUILDER_CAPACITY); + sb.append(CoreConstants.LINE_SEPARATOR); + + recursiveAppend(sb, null, ThrowableProxyUtil.REGULAR_EXCEPTION_INDENT, tp); + + sb.append(CoreConstants.LINE_SEPARATOR); + return sb.toString(); + } + + private void recursiveAppend(StringBuilder sb, String prefix, int indent, IThrowableProxy tp) { + if (tp == null) + return; + subjoinFirstLine(sb, prefix, indent, tp); + sb.append(CoreConstants.LINE_SEPARATOR); + subjoinSTEPArray(sb, indent, tp); + IThrowableProxy[] suppressed = tp.getSuppressed(); + if (suppressed != null) { + for (IThrowableProxy current : suppressed) { + recursiveAppend(sb, CoreConstants.SUPPRESSED, indent + ThrowableProxyUtil.SUPPRESSED_EXCEPTION_INDENT, + current); + } + } + recursiveAppend(sb, CoreConstants.CAUSED_BY, indent, tp.getCause()); + } + + private void subjoinFirstLine(StringBuilder buf, String prefix, int indent, IThrowableProxy tp) { + ThrowableProxyUtil.indent(buf, indent - 1); + if (prefix != null) { + buf.append(prefix); + } + ThrowableProxyUtil.subjoinExceptionMessage(buf, tp); + } + + + protected void subjoinSTEPArray(StringBuilder buf, int indent, IThrowableProxy tp) { + StackTraceElementProxy[] stepArray = tp.getStackTraceElementProxyArray(); + int commonFrames = tp.getCommonFrames(); + + boolean unrestrictedPrinting = lengthOption > stepArray.length; + + int maxIndex = (unrestrictedPrinting) ? stepArray.length : lengthOption; + if (commonFrames > 0 && unrestrictedPrinting) { + maxIndex -= commonFrames; + } + + int ignoredCount = 0; + for (int i = 0; i < maxIndex; i++) { + StackTraceElementProxy element = stepArray[i]; + if (!isIgnoredStackTraceLine(element.toString())) { + ThrowableProxyUtil.indent(buf, indent); + printStackLine(buf, ignoredCount, element); + ignoredCount = 0; + buf.append(CoreConstants.LINE_SEPARATOR); + } else { + ++ignoredCount; + if (maxIndex < stepArray.length) { + ++maxIndex; + } + } + } + if (ignoredCount > 0) { + printIgnoredCount(buf, ignoredCount); + buf.append(CoreConstants.LINE_SEPARATOR); + } + + if (commonFrames > 0 && unrestrictedPrinting) { + ThrowableProxyUtil.indent(buf, indent); + buf.append("... ").append(tp.getCommonFrames()).append(" common frames omitted") + .append(CoreConstants.LINE_SEPARATOR); + } + } + + private void printStackLine(StringBuilder buf, int ignoredCount, StackTraceElementProxy element) { + if(matcher != null) { + + if(matcher.test(element.getStackTraceElement())) { + buf.append(AnsiSyntaxHighlight.ESC_START); + buf.append(AnsiSyntaxHighlight.HIGH_INTENSITY); + buf.append(AnsiSyntaxHighlight.ESC_END); + buf.append(element); + buf.append(AnsiSyntaxHighlight.RESET); + } else { + buf.append(element); + } + } else { + buf.append(element); + } + extraData(buf, element); // allow other data to be added + if (ignoredCount > 0) { + printIgnoredCount(buf, ignoredCount); + } + } + + private void printIgnoredCount(StringBuilder buf, int ignoredCount) { + buf.append(" [").append(ignoredCount).append(" skipped]"); + } + + private boolean isIgnoredStackTraceLine(String line) { + /* + if (ignoredStackTraceLines != null) { + for (String ignoredStackTraceLine : ignoredStackTraceLines) { + if (line.contains(ignoredStackTraceLine)) { + return true; + } + } + } + */ + return false; + } + +}