From 09d4736ceb4075e0a254440d7f2c037409bb3dd7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alberto=20C=2E=20R=C3=ADos?= Date: Mon, 17 Apr 2023 11:03:21 +0200 Subject: [PATCH] Deleting logging modules --- build.gradle | 3 +- settings.gradle | 2 - .../build.gradle | 8 - ...iceInstanceLogStreamAutoConfiguration.java | 83 --------- ...ceInstanceRecentLogsAutoConfiguration.java | 49 ----- ...ot.autoconfigure.AutoConfiguration.imports | 2 - ...nstanceLogStreamAutoConfigurationTest.java | 96 ---------- ...stanceRecentLogsAutoConfigurationTest.java | 85 --------- spring-cloud-app-broker-logging/build.gradle | 35 ---- .../logging/ApplicationIdsProvider.java | 25 --- .../cloud/appbroker/logging/LoggingUtils.java | 111 ----------- .../recent/ApplicationRecentLogsProvider.java | 60 ------ .../logging/recent/RecentLogsProvider.java | 26 --- .../recent/endpoint/EncodingException.java | 27 --- .../recent/endpoint/LogMessageComparator.java | 42 ----- .../recent/endpoint/MultipartEncoder.java | 66 ------- .../recent/endpoint/RecentLogsController.java | 63 ------- .../ApplicationLogStreamPublisher.java | 148 --------------- .../streaming/DopplerLogStreamPublisher.java | 68 ------- .../logging/streaming/LogStreamPublisher.java | 25 --- .../ServiceInstanceNotFoundException.java | 27 --- .../StreamingLogWebSocketHandler.java | 122 ------------ .../events/ServiceInstanceLogEvent.java | 45 ----- .../events/ServiceInstanceLoggingEvent.java | 56 ------ .../StartServiceInstanceLoggingEvent.java | 27 --- .../StopServiceInstanceLoggingEvent.java | 27 --- .../example/recentlog/RecentLogsTestApp.java | 46 ----- .../streaming/LogStreamingTestApp.java | 65 ------- .../recent/ServiceInstanceRecentLogsTest.java | 98 ---------- .../ServiceInstanceLogStreamingTest.java | 174 ------------------ .../build.gradle | 22 --- 31 files changed, 1 insertion(+), 1732 deletions(-) delete mode 100644 spring-cloud-app-broker-autoconfigure/src/main/java/org/springframework/cloud/appbroker/autoconfigure/ServiceInstanceLogStreamAutoConfiguration.java delete mode 100644 spring-cloud-app-broker-autoconfigure/src/main/java/org/springframework/cloud/appbroker/autoconfigure/ServiceInstanceRecentLogsAutoConfiguration.java delete mode 100644 spring-cloud-app-broker-autoconfigure/src/test/java/org/springframework/cloud/appbroker/autoconfigure/ServiceInstanceLogStreamAutoConfigurationTest.java delete mode 100644 spring-cloud-app-broker-autoconfigure/src/test/java/org/springframework/cloud/appbroker/autoconfigure/ServiceInstanceRecentLogsAutoConfigurationTest.java delete mode 100644 spring-cloud-app-broker-logging/build.gradle delete mode 100644 spring-cloud-app-broker-logging/src/main/java/org/springframework/cloud/appbroker/logging/ApplicationIdsProvider.java delete mode 100644 spring-cloud-app-broker-logging/src/main/java/org/springframework/cloud/appbroker/logging/LoggingUtils.java delete mode 100644 spring-cloud-app-broker-logging/src/main/java/org/springframework/cloud/appbroker/logging/recent/ApplicationRecentLogsProvider.java delete mode 100644 spring-cloud-app-broker-logging/src/main/java/org/springframework/cloud/appbroker/logging/recent/RecentLogsProvider.java delete mode 100644 spring-cloud-app-broker-logging/src/main/java/org/springframework/cloud/appbroker/logging/recent/endpoint/EncodingException.java delete mode 100644 spring-cloud-app-broker-logging/src/main/java/org/springframework/cloud/appbroker/logging/recent/endpoint/LogMessageComparator.java delete mode 100644 spring-cloud-app-broker-logging/src/main/java/org/springframework/cloud/appbroker/logging/recent/endpoint/MultipartEncoder.java delete mode 100644 spring-cloud-app-broker-logging/src/main/java/org/springframework/cloud/appbroker/logging/recent/endpoint/RecentLogsController.java delete mode 100644 spring-cloud-app-broker-logging/src/main/java/org/springframework/cloud/appbroker/logging/streaming/ApplicationLogStreamPublisher.java delete mode 100644 spring-cloud-app-broker-logging/src/main/java/org/springframework/cloud/appbroker/logging/streaming/DopplerLogStreamPublisher.java delete mode 100644 spring-cloud-app-broker-logging/src/main/java/org/springframework/cloud/appbroker/logging/streaming/LogStreamPublisher.java delete mode 100644 spring-cloud-app-broker-logging/src/main/java/org/springframework/cloud/appbroker/logging/streaming/endpoint/ServiceInstanceNotFoundException.java delete mode 100644 spring-cloud-app-broker-logging/src/main/java/org/springframework/cloud/appbroker/logging/streaming/endpoint/StreamingLogWebSocketHandler.java delete mode 100644 spring-cloud-app-broker-logging/src/main/java/org/springframework/cloud/appbroker/logging/streaming/events/ServiceInstanceLogEvent.java delete mode 100644 spring-cloud-app-broker-logging/src/main/java/org/springframework/cloud/appbroker/logging/streaming/events/ServiceInstanceLoggingEvent.java delete mode 100644 spring-cloud-app-broker-logging/src/main/java/org/springframework/cloud/appbroker/logging/streaming/events/StartServiceInstanceLoggingEvent.java delete mode 100644 spring-cloud-app-broker-logging/src/main/java/org/springframework/cloud/appbroker/logging/streaming/events/StopServiceInstanceLoggingEvent.java delete mode 100644 spring-cloud-app-broker-logging/src/test/java/com/example/recentlog/RecentLogsTestApp.java delete mode 100644 spring-cloud-app-broker-logging/src/test/java/com/example/streaming/LogStreamingTestApp.java delete mode 100644 spring-cloud-app-broker-logging/src/test/java/org/springframework/cloud/appbroker/logging/recent/ServiceInstanceRecentLogsTest.java delete mode 100644 spring-cloud-app-broker-logging/src/test/java/org/springframework/cloud/appbroker/logging/streaming/ServiceInstanceLogStreamingTest.java delete mode 100644 spring-cloud-starter-app-broker-logging/build.gradle diff --git a/build.gradle b/build.gradle index 7d91f48..60ef6f9 100644 --- a/build.gradle +++ b/build.gradle @@ -426,8 +426,7 @@ def getTestProjects() { def getStarterProjects() { [project(":spring-cloud-starter-app-broker"), - project(":spring-cloud-starter-app-broker-cloudfoundry"), - project(":spring-cloud-starter-app-broker-logging")] as Set + project(":spring-cloud-starter-app-broker-cloudfoundry")] as Set } def getLibraryProjects() { diff --git a/settings.gradle b/settings.gradle index 8ea48e1..4133fa3 100644 --- a/settings.gradle +++ b/settings.gradle @@ -32,7 +32,5 @@ include "spring-cloud-app-broker-autoconfigure" include "spring-cloud-app-broker-integration-tests" include "spring-cloud-app-broker-acceptance-tests" include "spring-cloud-app-broker-security-credhub" -include "spring-cloud-app-broker-logging" include "spring-cloud-starter-app-broker" include "spring-cloud-starter-app-broker-cloudfoundry" -include "spring-cloud-starter-app-broker-logging" diff --git a/spring-cloud-app-broker-autoconfigure/build.gradle b/spring-cloud-app-broker-autoconfigure/build.gradle index 11cdee6..9908edc 100644 --- a/spring-cloud-app-broker-autoconfigure/build.gradle +++ b/spring-cloud-app-broker-autoconfigure/build.gradle @@ -22,12 +22,6 @@ plugins { description = "Spring Cloud App Broker Autoconfiguration" -java { - registerFeature("logging") { - usingSourceSet(sourceSets.main) - } -} - dependencies { annotationProcessor platform(SpringBootPlugin.BOM_COORDINATES) annotationProcessor "org.springframework.boot:spring-boot-configuration-processor" @@ -43,8 +37,6 @@ dependencies { api "org.cloudfoundry:cloudfoundry-operations:${cfJavaClientVersion}" api "org.springframework.credhub:spring-credhub-starter:${springCredhubVersion}" - loggingImplementation project(":spring-cloud-app-broker-logging") - testImplementation "org.springframework.boot:spring-boot-starter-test" testImplementation "org.springframework.boot:spring-boot-starter-webflux" testImplementation "io.projectreactor.tools:blockhound-junit-platform:${blockHoundVersion}" diff --git a/spring-cloud-app-broker-autoconfigure/src/main/java/org/springframework/cloud/appbroker/autoconfigure/ServiceInstanceLogStreamAutoConfiguration.java b/spring-cloud-app-broker-autoconfigure/src/main/java/org/springframework/cloud/appbroker/autoconfigure/ServiceInstanceLogStreamAutoConfiguration.java deleted file mode 100644 index 4b437c8..0000000 --- a/spring-cloud-app-broker-autoconfigure/src/main/java/org/springframework/cloud/appbroker/autoconfigure/ServiceInstanceLogStreamAutoConfiguration.java +++ /dev/null @@ -1,83 +0,0 @@ -/* - * Copyright 2016-2020 the original author or authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.appbroker.autoconfigure; - -import java.util.HashMap; -import java.util.Map; - -import org.cloudfoundry.client.CloudFoundryClient; -import org.cloudfoundry.doppler.DopplerClient; -import org.cloudfoundry.doppler.Envelope; - -import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; -import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; -import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; -import org.springframework.cloud.appbroker.logging.ApplicationIdsProvider; -import org.springframework.cloud.appbroker.logging.streaming.ApplicationLogStreamPublisher; -import org.springframework.cloud.appbroker.logging.streaming.DopplerLogStreamPublisher; -import org.springframework.cloud.appbroker.logging.streaming.LogStreamPublisher; -import org.springframework.cloud.appbroker.logging.streaming.endpoint.StreamingLogWebSocketHandler; -import org.springframework.context.ApplicationEventPublisher; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.web.reactive.HandlerMapping; -import org.springframework.web.reactive.handler.SimpleUrlHandlerMapping; -import org.springframework.web.reactive.socket.WebSocketHandler; -import org.springframework.web.reactive.socket.server.support.WebSocketHandlerAdapter; - -@Configuration -@ConditionalOnClass(ApplicationLogStreamPublisher.class) -@ConditionalOnBean(ApplicationIdsProvider.class) -public class ServiceInstanceLogStreamAutoConfiguration { - - @Bean - public StreamingLogWebSocketHandler streamingLogWebSocketHandler( - ApplicationEventPublisher applicationEventPublisher) { - return new StreamingLogWebSocketHandler(applicationEventPublisher); - } - - @Bean - @ConditionalOnMissingBean - public WebSocketHandlerAdapter handlerAdapter() { - return new WebSocketHandlerAdapter(); - } - - @Bean - public HandlerMapping logsHandlerMapping(StreamingLogWebSocketHandler webSocketHandler) { - Map map = new HashMap<>(); - map.put("/logs/**", webSocketHandler); - - SimpleUrlHandlerMapping handlerMapping = new SimpleUrlHandlerMapping(); - handlerMapping.setOrder(1); - handlerMapping.setUrlMap(map); - return handlerMapping; - } - - @Bean - @ConditionalOnMissingBean - public LogStreamPublisher streamLogsPublisher(CloudFoundryClient cloudFoundryClient, - DopplerClient dopplerClient, ApplicationIdsProvider applicationIdsProvider) { - return new DopplerLogStreamPublisher(cloudFoundryClient, dopplerClient, applicationIdsProvider); - } - - @Bean - public ApplicationLogStreamPublisher applicationLogsPublisher(LogStreamPublisher logStreamPublisher, - ApplicationEventPublisher eventPublisher) { - return new ApplicationLogStreamPublisher(logStreamPublisher, eventPublisher); - } - -} diff --git a/spring-cloud-app-broker-autoconfigure/src/main/java/org/springframework/cloud/appbroker/autoconfigure/ServiceInstanceRecentLogsAutoConfiguration.java b/spring-cloud-app-broker-autoconfigure/src/main/java/org/springframework/cloud/appbroker/autoconfigure/ServiceInstanceRecentLogsAutoConfiguration.java deleted file mode 100644 index f6408a5..0000000 --- a/spring-cloud-app-broker-autoconfigure/src/main/java/org/springframework/cloud/appbroker/autoconfigure/ServiceInstanceRecentLogsAutoConfiguration.java +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright 2016-2020 the original author or authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.appbroker.autoconfigure; - -import org.cloudfoundry.client.CloudFoundryClient; -import org.cloudfoundry.doppler.DopplerClient; - -import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; -import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; -import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; -import org.springframework.cloud.appbroker.logging.ApplicationIdsProvider; -import org.springframework.cloud.appbroker.logging.recent.ApplicationRecentLogsProvider; -import org.springframework.cloud.appbroker.logging.recent.RecentLogsProvider; -import org.springframework.cloud.appbroker.logging.recent.endpoint.RecentLogsController; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; - -@Configuration -@ConditionalOnClass(ApplicationRecentLogsProvider.class) -@ConditionalOnBean(ApplicationIdsProvider.class) -public class ServiceInstanceRecentLogsAutoConfiguration { - - @Bean - public RecentLogsProvider recentLogsProvider(CloudFoundryClient cloudFoundryClient, DopplerClient dopplerClient, - ApplicationIdsProvider applicationIdsProvider) { - return new ApplicationRecentLogsProvider(cloudFoundryClient, dopplerClient, applicationIdsProvider); - } - - @Bean - @ConditionalOnMissingBean - public RecentLogsController recentLogsController(RecentLogsProvider recentLogsProvider) { - return new RecentLogsController(recentLogsProvider); - } - -} diff --git a/spring-cloud-app-broker-autoconfigure/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports b/spring-cloud-app-broker-autoconfigure/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports index c9fcdb1..438a2ff 100644 --- a/spring-cloud-app-broker-autoconfigure/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports +++ b/spring-cloud-app-broker-autoconfigure/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports @@ -1,5 +1,3 @@ org.springframework.cloud.appbroker.autoconfigure.AppBrokerAutoConfiguration org.springframework.cloud.appbroker.autoconfigure.CloudFoundryAppDeployerAutoConfiguration org.springframework.cloud.appbroker.autoconfigure.CredHubAutoConfiguration -org.springframework.cloud.appbroker.autoconfigure.ServiceInstanceRecentLogsAutoConfiguration -org.springframework.cloud.appbroker.autoconfigure.ServiceInstanceLogStreamAutoConfiguration diff --git a/spring-cloud-app-broker-autoconfigure/src/test/java/org/springframework/cloud/appbroker/autoconfigure/ServiceInstanceLogStreamAutoConfigurationTest.java b/spring-cloud-app-broker-autoconfigure/src/test/java/org/springframework/cloud/appbroker/autoconfigure/ServiceInstanceLogStreamAutoConfigurationTest.java deleted file mode 100644 index 7127678..0000000 --- a/spring-cloud-app-broker-autoconfigure/src/test/java/org/springframework/cloud/appbroker/autoconfigure/ServiceInstanceLogStreamAutoConfigurationTest.java +++ /dev/null @@ -1,96 +0,0 @@ -/* - * Copyright 2002-2020 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.appbroker.autoconfigure; - -import org.junit.jupiter.api.Test; -import reactor.core.publisher.Flux; - -import org.springframework.boot.autoconfigure.AutoConfigurations; -import org.springframework.boot.test.context.FilteredClassLoader; -import org.springframework.boot.test.context.TestConfiguration; -import org.springframework.boot.test.context.runner.ApplicationContextRunner; -import org.springframework.cloud.appbroker.logging.ApplicationIdsProvider; -import org.springframework.cloud.appbroker.logging.streaming.ApplicationLogStreamPublisher; -import org.springframework.cloud.appbroker.logging.streaming.LogStreamPublisher; -import org.springframework.cloud.appbroker.logging.streaming.endpoint.StreamingLogWebSocketHandler; -import org.springframework.context.annotation.Bean; -import org.springframework.web.reactive.HandlerMapping; -import org.springframework.web.reactive.socket.server.support.WebSocketHandlerAdapter; - -import static org.assertj.core.api.Assertions.assertThat; - -class ServiceInstanceLogStreamAutoConfigurationTest { - - private final ApplicationContextRunner contextRunner = new ApplicationContextRunner() - .withConfiguration(AutoConfigurations.of( - AppBrokerAutoConfiguration.class, - CloudFoundryAppDeployerAutoConfiguration.class, - ServiceInstanceLogStreamAutoConfiguration.class - )) - .withPropertyValues( - "spring.cloud.appbroker.deployer.cloudfoundry.api-host=https://api.example.local", - "spring.cloud.appbroker.deployer.cloudfoundry.username=user", - "spring.cloud.appbroker.deployer.cloudfoundry.password=secret" - ); - - @Test - void servicesAreNotCreatedWithoutLoggingOnClasspath() { - contextRunner - .withClassLoader(new FilteredClassLoader(ApplicationLogStreamPublisher.class)) - .withUserConfiguration(LoggingConfiguration.class) - .run(context -> assertThat(context) - .doesNotHaveBean(StreamingLogWebSocketHandler.class) - .doesNotHaveBean(WebSocketHandlerAdapter.class) - .doesNotHaveBean(HandlerMapping.class) - .doesNotHaveBean(LogStreamPublisher.class) - .doesNotHaveBean(ApplicationLogStreamPublisher.class)); - } - - @Test - void servicesAreNotCreatedWithoutRequiredBeansOnClasspath() { - contextRunner - .run(context -> assertThat(context) - .doesNotHaveBean(StreamingLogWebSocketHandler.class) - .doesNotHaveBean(WebSocketHandlerAdapter.class) - .doesNotHaveBean(HandlerMapping.class) - .doesNotHaveBean(LogStreamPublisher.class) - .doesNotHaveBean(ApplicationLogStreamPublisher.class)); - } - - @Test - void servicesAreCreatedWithLoggingConfigured() { - contextRunner - .withUserConfiguration(LoggingConfiguration.class) - .run(context -> assertThat(context) - .hasSingleBean(StreamingLogWebSocketHandler.class) - .hasSingleBean(WebSocketHandlerAdapter.class) - .hasSingleBean(HandlerMapping.class) - .hasSingleBean(LogStreamPublisher.class) - .hasSingleBean(ApplicationLogStreamPublisher.class)); - } - - @TestConfiguration - public static class LoggingConfiguration { - - @Bean - public ApplicationIdsProvider applicationIdsProvider() { - return serviceInstanceId -> Flux.just("app1"); - } - - } - -} diff --git a/spring-cloud-app-broker-autoconfigure/src/test/java/org/springframework/cloud/appbroker/autoconfigure/ServiceInstanceRecentLogsAutoConfigurationTest.java b/spring-cloud-app-broker-autoconfigure/src/test/java/org/springframework/cloud/appbroker/autoconfigure/ServiceInstanceRecentLogsAutoConfigurationTest.java deleted file mode 100644 index e523d1a..0000000 --- a/spring-cloud-app-broker-autoconfigure/src/test/java/org/springframework/cloud/appbroker/autoconfigure/ServiceInstanceRecentLogsAutoConfigurationTest.java +++ /dev/null @@ -1,85 +0,0 @@ -/* - * Copyright 2002-2020 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.appbroker.autoconfigure; - -import org.junit.jupiter.api.Test; -import reactor.core.publisher.Flux; - -import org.springframework.boot.autoconfigure.AutoConfigurations; -import org.springframework.boot.test.context.FilteredClassLoader; -import org.springframework.boot.test.context.TestConfiguration; -import org.springframework.boot.test.context.runner.ApplicationContextRunner; -import org.springframework.cloud.appbroker.logging.ApplicationIdsProvider; -import org.springframework.cloud.appbroker.logging.recent.ApplicationRecentLogsProvider; -import org.springframework.cloud.appbroker.logging.recent.RecentLogsProvider; -import org.springframework.cloud.appbroker.logging.recent.endpoint.RecentLogsController; -import org.springframework.context.annotation.Bean; - -import static org.assertj.core.api.Assertions.assertThat; - -class ServiceInstanceRecentLogsAutoConfigurationTest { - - private final ApplicationContextRunner contextRunner = new ApplicationContextRunner() - .withConfiguration(AutoConfigurations.of( - AppBrokerAutoConfiguration.class, - CloudFoundryAppDeployerAutoConfiguration.class, - ServiceInstanceRecentLogsAutoConfiguration.class - )) - .withPropertyValues( - "spring.cloud.appbroker.deployer.cloudfoundry.api-host=https://api.example.local", - "spring.cloud.appbroker.deployer.cloudfoundry.username=user", - "spring.cloud.appbroker.deployer.cloudfoundry.password=secret" - ); - - @Test - void servicesAreNotCreatedWithoutLoggingOnClasspath() { - contextRunner - .withClassLoader(new FilteredClassLoader(ApplicationRecentLogsProvider.class)) - .withUserConfiguration(LoggingConfiguration.class) - .run(context -> assertThat(context) - .doesNotHaveBean(RecentLogsProvider.class) - .doesNotHaveBean(RecentLogsController.class)); - } - - @Test - void servicesAreNotCreatedWithoutRequiredBeansOnClasspath() { - contextRunner - .run(context -> assertThat(context) - .doesNotHaveBean(RecentLogsProvider.class) - .doesNotHaveBean(RecentLogsController.class)); - } - - @Test - void servicesAreCreatedWithLoggingConfigured() { - contextRunner - .withUserConfiguration(LoggingConfiguration.class) - .run(context -> assertThat(context) - .hasSingleBean(RecentLogsProvider.class) - .hasSingleBean(RecentLogsController.class)); - } - - @TestConfiguration - public static class LoggingConfiguration { - - @Bean - public ApplicationIdsProvider applicationIdsProvider() { - return serviceInstanceId -> Flux.just("app1"); - } - - } - -} diff --git a/spring-cloud-app-broker-logging/build.gradle b/spring-cloud-app-broker-logging/build.gradle deleted file mode 100644 index 4813bed..0000000 --- a/spring-cloud-app-broker-logging/build.gradle +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright 2002-2020 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import org.springframework.boot.gradle.plugin.SpringBootPlugin - -plugins { - id 'org.springframework.boot' apply false -} - -description = "Spring Cloud App Broker Logging" - -dependencies { - api platform(SpringBootPlugin.BOM_COORDINATES) - api "org.springframework.boot:spring-boot-starter-webflux" - api "org.cloudfoundry:cloudfoundry-client-reactor:${cfJavaClientVersion}" - api "org.cloudfoundry:cloudfoundry-operations:${cfJavaClientVersion}" - - testImplementation project(":spring-cloud-starter-app-broker-logging") - testImplementation "org.springframework.boot:spring-boot-starter-test" - testImplementation "org.junit.jupiter:junit-jupiter-api" - testImplementation "org.awaitility:awaitility" -} diff --git a/spring-cloud-app-broker-logging/src/main/java/org/springframework/cloud/appbroker/logging/ApplicationIdsProvider.java b/spring-cloud-app-broker-logging/src/main/java/org/springframework/cloud/appbroker/logging/ApplicationIdsProvider.java deleted file mode 100644 index 7321534..0000000 --- a/spring-cloud-app-broker-logging/src/main/java/org/springframework/cloud/appbroker/logging/ApplicationIdsProvider.java +++ /dev/null @@ -1,25 +0,0 @@ -/* - * Copyright 2002-2020 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.appbroker.logging; - -import reactor.core.publisher.Flux; - -public interface ApplicationIdsProvider { - - Flux getApplicationIds(String serviceInstanceId); - -} diff --git a/spring-cloud-app-broker-logging/src/main/java/org/springframework/cloud/appbroker/logging/LoggingUtils.java b/spring-cloud-app-broker-logging/src/main/java/org/springframework/cloud/appbroker/logging/LoggingUtils.java deleted file mode 100644 index 0a93848..0000000 --- a/spring-cloud-app-broker-logging/src/main/java/org/springframework/cloud/appbroker/logging/LoggingUtils.java +++ /dev/null @@ -1,111 +0,0 @@ -/* - * Copyright 2002-2020 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.appbroker.logging; - -import okio.ByteString; -import org.cloudfoundry.doppler.EventType; -import org.cloudfoundry.doppler.MessageType; -import org.cloudfoundry.dropsonde.events.Envelope; -import org.cloudfoundry.dropsonde.events.LogMessage; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -public final class LoggingUtils { - - private static final Logger LOG = LoggerFactory.getLogger(LoggingUtils.class); - - private LoggingUtils() { - } - - public static Envelope convertDopplerEnvelopeToDropsonde(org.cloudfoundry.doppler.Envelope envelope) { - final Envelope.Builder builder = new Envelope.Builder() - .deployment(envelope.getDeployment()) - .eventType(toDropsondeEventType(envelope.getEventType())) - .index(envelope.getIndex()) - .ip(envelope.getIp()) - .job(envelope.getJob()) - .origin(envelope.getOrigin()) - .tags(envelope.getTags()) - .timestamp(envelope.getTimestamp()); - - if (envelope.getEventType() == EventType.LOG_MESSAGE) { - final org.cloudfoundry.doppler.LogMessage logMessage = envelope.getLogMessage(); - if (LOG.isDebugEnabled()) { - LOG.debug("Decoding message [" + logMessage.getTimestamp() + "]: " + logMessage.getMessage()); - } - - builder.logMessage(new LogMessage.Builder() - .app_id(logMessage.getApplicationId()) - .message(ByteString.encodeUtf8(logMessage.getMessage())) - .message_type(toDropsondeMessageType(logMessage.getMessageType())) - .source_instance(logMessage.getSourceInstance()) - .source_type(logMessage.getSourceType()) - .timestamp(logMessage.getTimestamp()) - .build()); - } - else { - if (LOG.isDebugEnabled()) { - LOG.debug("Unable to decode message of type " + envelope.getEventType()); - } - } - - return builder.build(); - } - - public static org.cloudfoundry.doppler.Envelope injectAppNameIntoLogSourceInstance(String appName, - org.cloudfoundry.doppler.Envelope envelope) { - if (envelope.getEventType() != EventType.LOG_MESSAGE) { - return envelope; - } - return org.cloudfoundry.doppler.Envelope.builder().from(envelope).logMessage( - org.cloudfoundry.doppler.LogMessage.builder().from(envelope.getLogMessage()) - .sourceInstance(appName + " " + envelope.getLogMessage().getSourceInstance()) - .build() - ).build(); - } - - - private static LogMessage.MessageType toDropsondeMessageType(MessageType messageType) { - switch (messageType) { - case ERR: - return LogMessage.MessageType.ERR; - case OUT: - return LogMessage.MessageType.OUT; - default: - throw new IllegalArgumentException("Unknown message type " + messageType); - } - } - - private static Envelope.EventType toDropsondeEventType(EventType eventType) { - switch (eventType) { - case ERROR: - return Envelope.EventType.Error; - case CONTAINER_METRIC: - return Envelope.EventType.ContainerMetric; - case COUNTER_EVENT: - return Envelope.EventType.CounterEvent; - case HTTP_START_STOP: - return Envelope.EventType.HttpStartStop; - case LOG_MESSAGE: - return Envelope.EventType.LogMessage; - case VALUE_METRIC: - return Envelope.EventType.ValueMetric; - } - throw new IllegalArgumentException("Unknown event type: " + eventType); - } - -} diff --git a/spring-cloud-app-broker-logging/src/main/java/org/springframework/cloud/appbroker/logging/recent/ApplicationRecentLogsProvider.java b/spring-cloud-app-broker-logging/src/main/java/org/springframework/cloud/appbroker/logging/recent/ApplicationRecentLogsProvider.java deleted file mode 100644 index a057df4..0000000 --- a/spring-cloud-app-broker-logging/src/main/java/org/springframework/cloud/appbroker/logging/recent/ApplicationRecentLogsProvider.java +++ /dev/null @@ -1,60 +0,0 @@ -/* - * Copyright 2002-2020 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.appbroker.logging.recent; - -import org.cloudfoundry.client.CloudFoundryClient; -import org.cloudfoundry.client.v2.applications.GetApplicationRequest; -import org.cloudfoundry.doppler.DopplerClient; -import org.cloudfoundry.doppler.RecentLogsRequest; -import org.cloudfoundry.dropsonde.events.Envelope; -import reactor.core.publisher.Flux; - -import org.springframework.cloud.appbroker.logging.ApplicationIdsProvider; -import org.springframework.cloud.appbroker.logging.LoggingUtils; - -public class ApplicationRecentLogsProvider implements RecentLogsProvider { - - private final CloudFoundryClient client; - - private final DopplerClient dopplerClient; - - private final ApplicationIdsProvider applicationIdsProvider; - - public ApplicationRecentLogsProvider(CloudFoundryClient client, DopplerClient dopplerClient, - ApplicationIdsProvider applicationIdsProvider) { - this.client = client; - this.dopplerClient = dopplerClient; - this.applicationIdsProvider = applicationIdsProvider; - } - - @Override - public Flux getLogs(String serviceInstanceId) { - return this.applicationIdsProvider.getApplicationIds(serviceInstanceId) - .flatMap(this::recentLogs) - .map(LoggingUtils::convertDopplerEnvelopeToDropsonde); - } - - protected Flux recentLogs(String applicationId) { - return client.applicationsV2().get(GetApplicationRequest.builder().applicationId(applicationId).build()) - .map(response -> response.getEntity().getName()) - .flatMapMany(appName -> - dopplerClient.recentLogs(RecentLogsRequest.builder().applicationId(applicationId).build()) - .map(envelope -> LoggingUtils.injectAppNameIntoLogSourceInstance(appName, envelope)) - ); - } - -} diff --git a/spring-cloud-app-broker-logging/src/main/java/org/springframework/cloud/appbroker/logging/recent/RecentLogsProvider.java b/spring-cloud-app-broker-logging/src/main/java/org/springframework/cloud/appbroker/logging/recent/RecentLogsProvider.java deleted file mode 100644 index a987fae..0000000 --- a/spring-cloud-app-broker-logging/src/main/java/org/springframework/cloud/appbroker/logging/recent/RecentLogsProvider.java +++ /dev/null @@ -1,26 +0,0 @@ -/* - * Copyright 2002-2020 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.appbroker.logging.recent; - -import org.cloudfoundry.dropsonde.events.Envelope; -import reactor.core.publisher.Flux; - -public interface RecentLogsProvider { - - Flux getLogs(String serviceInstanceId); - -} diff --git a/spring-cloud-app-broker-logging/src/main/java/org/springframework/cloud/appbroker/logging/recent/endpoint/EncodingException.java b/spring-cloud-app-broker-logging/src/main/java/org/springframework/cloud/appbroker/logging/recent/endpoint/EncodingException.java deleted file mode 100644 index 28ee96b..0000000 --- a/spring-cloud-app-broker-logging/src/main/java/org/springframework/cloud/appbroker/logging/recent/endpoint/EncodingException.java +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Copyright 2002-2020 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.appbroker.logging.recent.endpoint; - -class EncodingException extends RuntimeException { - - private static final long serialVersionUID = 1837485200518028161L; - - public EncodingException(Throwable throwable) { - super("Failed to encode: " + throwable.getMessage(), throwable); - } - -} diff --git a/spring-cloud-app-broker-logging/src/main/java/org/springframework/cloud/appbroker/logging/recent/endpoint/LogMessageComparator.java b/spring-cloud-app-broker-logging/src/main/java/org/springframework/cloud/appbroker/logging/recent/endpoint/LogMessageComparator.java deleted file mode 100644 index 443da51..0000000 --- a/spring-cloud-app-broker-logging/src/main/java/org/springframework/cloud/appbroker/logging/recent/endpoint/LogMessageComparator.java +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright 2002-2020 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.appbroker.logging.recent.endpoint; - -import java.util.Comparator; - -import org.cloudfoundry.dropsonde.events.Envelope; - -class LogMessageComparator implements Comparator { - - @Override - public int compare(Envelope o1, Envelope o2) { - return Long.compare(getTimestamp(o1), getTimestamp(o2)); - } - - private long getTimestamp(Envelope e) { - if (e.logMessage != null && e.logMessage.timestamp != null) { - return e.logMessage.timestamp; - } - if (e.timestamp == null) { - return 0; - } - else { - return e.timestamp; - } - } - -} diff --git a/spring-cloud-app-broker-logging/src/main/java/org/springframework/cloud/appbroker/logging/recent/endpoint/MultipartEncoder.java b/spring-cloud-app-broker-logging/src/main/java/org/springframework/cloud/appbroker/logging/recent/endpoint/MultipartEncoder.java deleted file mode 100644 index fb3139e..0000000 --- a/spring-cloud-app-broker-logging/src/main/java/org/springframework/cloud/appbroker/logging/recent/endpoint/MultipartEncoder.java +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Copyright 2002-2020 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.appbroker.logging.recent.endpoint; - -import java.io.ByteArrayOutputStream; -import java.io.IOException; - -class MultipartEncoder { - - private final byte[] bytesCRLF = {'\r', '\n'}; - - private final byte[] bytesSEP = {'-', '-'}; - - private final byte[] boundary; - - private final ByteArrayOutputStream out = new ByteArrayOutputStream(); - - public MultipartEncoder(String boundary) { - this.boundary = boundary.getBytes(); - } - - public void append(byte[] part) { - try { - out.write(bytesCRLF); - out.write(bytesSEP); - out.write(boundary); - out.write(bytesCRLF); - out.write(bytesCRLF); - out.write(part); - } - catch (IOException e) { - throw new EncodingException(e); - } - } - - public byte[] terminateAndGetBytes() { - try { - out.write(bytesCRLF); - out.write(bytesSEP); - out.write(boundary); - out.write(bytesSEP); - out.write(bytesCRLF); - final byte[] bytes = out.toByteArray(); - out.close(); - return bytes; - } - catch (IOException e) { - throw new EncodingException(e); - } - } - -} diff --git a/spring-cloud-app-broker-logging/src/main/java/org/springframework/cloud/appbroker/logging/recent/endpoint/RecentLogsController.java b/spring-cloud-app-broker-logging/src/main/java/org/springframework/cloud/appbroker/logging/recent/endpoint/RecentLogsController.java deleted file mode 100644 index ad61918..0000000 --- a/spring-cloud-app-broker-logging/src/main/java/org/springframework/cloud/appbroker/logging/recent/endpoint/RecentLogsController.java +++ /dev/null @@ -1,63 +0,0 @@ -/* - * Copyright 2002-2020 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.appbroker.logging.recent.endpoint; - -import java.util.UUID; - -import org.cloudfoundry.dropsonde.events.Envelope; -import reactor.core.publisher.Mono; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.cloud.appbroker.logging.recent.RecentLogsProvider; -import org.springframework.http.HttpHeaders; -import org.springframework.http.HttpStatus; -import org.springframework.http.ResponseEntity; -import org.springframework.web.bind.annotation.PathVariable; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RestController; - -@RestController -public class RecentLogsController { - - private static final LogMessageComparator LOG_MESSAGE_COMPARATOR = new LogMessageComparator(); - - private final RecentLogsProvider recentLogsProviders; - - public RecentLogsController(@Autowired(required = false) RecentLogsProvider recentLogsProviders) { - this.recentLogsProviders = recentLogsProviders; - } - - @RequestMapping("/logs/{serviceInstanceId}/recentlogs") - public Mono> recentLogs(@PathVariable("serviceInstanceId") String serviceInstanceId) { - final String multipartBoundary = UUID.randomUUID().toString(); - final HttpHeaders headers = new HttpHeaders(); - headers.add(HttpHeaders.CONTENT_TYPE, "multipart/mixed; boundary=" + multipartBoundary); - - return recentLogsProviders.getLogs(serviceInstanceId) - .collectList() - .doOnNext(envelopes -> envelopes.sort(LOG_MESSAGE_COMPARATOR)) - .map(envelopes -> { - final MultipartEncoder multipart = new MultipartEncoder(multipartBoundary); - for (Envelope message : envelopes) { - multipart.append(Envelope.ADAPTER.encode(message)); - } - - return new ResponseEntity<>(multipart.terminateAndGetBytes(), headers, HttpStatus.OK); - }); - } - -} diff --git a/spring-cloud-app-broker-logging/src/main/java/org/springframework/cloud/appbroker/logging/streaming/ApplicationLogStreamPublisher.java b/spring-cloud-app-broker-logging/src/main/java/org/springframework/cloud/appbroker/logging/streaming/ApplicationLogStreamPublisher.java deleted file mode 100644 index 7dc02b8..0000000 --- a/spring-cloud-app-broker-logging/src/main/java/org/springframework/cloud/appbroker/logging/streaming/ApplicationLogStreamPublisher.java +++ /dev/null @@ -1,148 +0,0 @@ -/* - * Copyright 2002-2020 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.appbroker.logging.streaming; - -import java.util.HashMap; -import java.util.Map; - -import org.cloudfoundry.doppler.Envelope; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import reactor.core.Disposable; -import reactor.core.publisher.Flux; - -import org.springframework.cloud.appbroker.logging.LoggingUtils; -import org.springframework.cloud.appbroker.logging.streaming.events.ServiceInstanceLogEvent; -import org.springframework.cloud.appbroker.logging.streaming.events.ServiceInstanceLoggingEvent; -import org.springframework.context.ApplicationEventPublisher; -import org.springframework.context.ApplicationListener; - -public class ApplicationLogStreamPublisher implements ApplicationListener { - - private static final Logger LOG = LoggerFactory.getLogger(ApplicationLogStreamPublisher.class); - - private final Map registry = new HashMap<>(); - - private final LogStreamPublisher logStreamPublisher; - - private final ApplicationEventPublisher publisher; - - public ApplicationLogStreamPublisher(LogStreamPublisher logStreamPublisher, - ApplicationEventPublisher publisher) { - this.logStreamPublisher = logStreamPublisher; - this.publisher = publisher; - } - - @Override - public void onApplicationEvent(ServiceInstanceLoggingEvent event) { - final String serviceInstanceId = event.getServiceInstanceId(); - switch (event.getOperation()) { - case START: - LOG.debug("Received event to begin listening to logs for {}", serviceInstanceId); - this.startPublishing(serviceInstanceId); - return; - case STOP: - LOG.debug("Received event to stop listening to logs for {}", serviceInstanceId); - this.stopPublishing(serviceInstanceId); - return; - - default: - throw new IllegalArgumentException("Unknown operation: " + event.getOperation()); - } - } - - private void startPublishing(String serviceInstanceId) { - synchronized (registry) { - final Registration registration = registry.get(serviceInstanceId); - if (registration != null) { - LOG.debug("Incrementing registration subscription count for {}", serviceInstanceId); - registration.increment(); - - return; - } - - Flux logStream = this.logStreamPublisher - .getLogStream(serviceInstanceId); - - final Disposable subscription = logStream - .map(LoggingUtils::convertDopplerEnvelopeToDropsonde) - .doOnNext( - envelope -> publisher.publishEvent(new ServiceInstanceLogEvent(this, serviceInstanceId, envelope))) - .subscribe(); - - LOG.debug("Creating new registration for {}", serviceInstanceId); - registry.put(serviceInstanceId, new Registration(subscription)); - } - } - - private void stopPublishing(String serviceInstanceId) { - if (LOG.isDebugEnabled()) { - LOG.debug("Received event to stop listening to logs for {}", serviceInstanceId); - } - - synchronized (registry) { - final Registration registration = registry.get(serviceInstanceId); - if (registration == null) { - if (LOG.isWarnEnabled()) { - LOG.warn("Received deregister event for service instance {} but there no event handler registered", - serviceInstanceId); - } - } - else if (registration.decrement() == 0) { - if (LOG.isDebugEnabled()) { - LOG.debug("Disposing of registration since there are no more subscriptions"); - } - - registration.getSubscription().dispose(); - registry.remove(serviceInstanceId); - } - } - } - - private final static class Registration { - - private final Disposable subscription; - - private int count = 1; - - private Registration(Disposable subscription) { - this.subscription = subscription; - } - - public void increment() { - if (LOG.isDebugEnabled()) { - LOG.debug("Incrementing subscription count from {} to {}", count, count + 1); - } - - ++count; - } - - public int decrement() { - if (LOG.isDebugEnabled()) { - LOG.debug("Decrementing subscription count from {} to {}", count, count - 1); - } - - return --count; - } - - public Disposable getSubscription() { - return subscription; - } - - } - -} diff --git a/spring-cloud-app-broker-logging/src/main/java/org/springframework/cloud/appbroker/logging/streaming/DopplerLogStreamPublisher.java b/spring-cloud-app-broker-logging/src/main/java/org/springframework/cloud/appbroker/logging/streaming/DopplerLogStreamPublisher.java deleted file mode 100644 index 47f0367..0000000 --- a/spring-cloud-app-broker-logging/src/main/java/org/springframework/cloud/appbroker/logging/streaming/DopplerLogStreamPublisher.java +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Copyright 2002-2020 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.appbroker.logging.streaming; - -import org.cloudfoundry.client.CloudFoundryClient; -import org.cloudfoundry.client.v2.applications.GetApplicationRequest; -import org.cloudfoundry.doppler.DopplerClient; -import org.cloudfoundry.doppler.Envelope; -import org.cloudfoundry.doppler.StreamRequest; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import reactor.core.publisher.Flux; - -import org.springframework.cloud.appbroker.logging.ApplicationIdsProvider; -import org.springframework.cloud.appbroker.logging.LoggingUtils; - -public class DopplerLogStreamPublisher implements LogStreamPublisher { - - private static final Logger LOG = LoggerFactory.getLogger(DopplerLogStreamPublisher.class); - - private final CloudFoundryClient client; - - private final DopplerClient dopplerClient; - - private final ApplicationIdsProvider applicationIdsProvider; - - public DopplerLogStreamPublisher( - CloudFoundryClient client, - DopplerClient dopplerClient, - ApplicationIdsProvider applicationIdsProvider - ) { - this.client = client; - this.dopplerClient = dopplerClient; - this.applicationIdsProvider = applicationIdsProvider; - } - - @Override - public Flux getLogStream(String serviceInstanceId) { - return this.applicationIdsProvider - .getApplicationIds(serviceInstanceId) - .doOnNext(id -> LOG.debug("Starting log streaming for app with ID {}", id)) - .flatMap(this::createApplicationStreamer); - } - - protected Flux createApplicationStreamer(String applicationId) { - return client.applicationsV2().get(GetApplicationRequest.builder().applicationId(applicationId).build()) - .map(response -> response.getEntity().getName()) - .flatMapMany(appName -> - dopplerClient.stream(StreamRequest.builder().applicationId(applicationId).build()) - .map(envelope -> LoggingUtils.injectAppNameIntoLogSourceInstance(appName, envelope)) - ); - } - -} diff --git a/spring-cloud-app-broker-logging/src/main/java/org/springframework/cloud/appbroker/logging/streaming/LogStreamPublisher.java b/spring-cloud-app-broker-logging/src/main/java/org/springframework/cloud/appbroker/logging/streaming/LogStreamPublisher.java deleted file mode 100644 index 2513669..0000000 --- a/spring-cloud-app-broker-logging/src/main/java/org/springframework/cloud/appbroker/logging/streaming/LogStreamPublisher.java +++ /dev/null @@ -1,25 +0,0 @@ -/* - * Copyright 2002-2020 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.appbroker.logging.streaming; - -import reactor.core.publisher.Flux; - -public interface LogStreamPublisher { - - Flux getLogStream(String serviceInstanceId); - -} diff --git a/spring-cloud-app-broker-logging/src/main/java/org/springframework/cloud/appbroker/logging/streaming/endpoint/ServiceInstanceNotFoundException.java b/spring-cloud-app-broker-logging/src/main/java/org/springframework/cloud/appbroker/logging/streaming/endpoint/ServiceInstanceNotFoundException.java deleted file mode 100644 index 907a336..0000000 --- a/spring-cloud-app-broker-logging/src/main/java/org/springframework/cloud/appbroker/logging/streaming/endpoint/ServiceInstanceNotFoundException.java +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Copyright 2002-2020 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.appbroker.logging.streaming.endpoint; - -import org.springframework.http.HttpStatus; -import org.springframework.web.bind.annotation.ResponseStatus; - -@ResponseStatus(code = HttpStatus.NOT_FOUND) -class ServiceInstanceNotFoundException extends RuntimeException { - - private static final long serialVersionUID = 8672053621926030384L; - -} diff --git a/spring-cloud-app-broker-logging/src/main/java/org/springframework/cloud/appbroker/logging/streaming/endpoint/StreamingLogWebSocketHandler.java b/spring-cloud-app-broker-logging/src/main/java/org/springframework/cloud/appbroker/logging/streaming/endpoint/StreamingLogWebSocketHandler.java deleted file mode 100644 index daf6a72..0000000 --- a/spring-cloud-app-broker-logging/src/main/java/org/springframework/cloud/appbroker/logging/streaming/endpoint/StreamingLogWebSocketHandler.java +++ /dev/null @@ -1,122 +0,0 @@ -/* - * Copyright 2002-2020 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.appbroker.logging.streaming.endpoint; - -import java.net.URI; -import java.util.Map; -import java.util.concurrent.ConcurrentHashMap; - -import org.cloudfoundry.dropsonde.events.Envelope; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import reactor.core.publisher.Mono; -import reactor.core.publisher.Sinks; - -import org.springframework.cloud.appbroker.logging.streaming.events.ServiceInstanceLogEvent; -import org.springframework.cloud.appbroker.logging.streaming.events.StartServiceInstanceLoggingEvent; -import org.springframework.cloud.appbroker.logging.streaming.events.StopServiceInstanceLoggingEvent; -import org.springframework.context.ApplicationEventPublisher; -import org.springframework.context.ApplicationListener; -import org.springframework.web.reactive.socket.WebSocketHandler; -import org.springframework.web.reactive.socket.WebSocketSession; -import org.springframework.web.util.UriTemplate; - -public class StreamingLogWebSocketHandler implements WebSocketHandler, ApplicationListener { - - private static final Logger LOG = LoggerFactory.getLogger(StreamingLogWebSocketHandler.class); - - private static final UriTemplate LOGGING_URI_TEMPLATE = new UriTemplate("/logs/{serviceInstanceId}/stream"); - - private final ApplicationEventPublisher eventPublisher; - - private final ConcurrentHashMap> envelopeSinks = new ConcurrentHashMap<>(); - - public StreamingLogWebSocketHandler(ApplicationEventPublisher eventPublisher) { - this.eventPublisher = eventPublisher; - } - - @Override - public Mono handle(WebSocketSession session) { - String serviceInstanceId = getServiceInstanceId(session); - LOG.info("Connection established [{}}], service instance {}", - session.getHandshakeInfo().getRemoteAddress(), - serviceInstanceId); - - Sinks.One envelopeSink = envelopeSinks - .computeIfAbsent(serviceInstanceId, s -> Sinks.one()); - - eventPublisher.publishEvent(new StartServiceInstanceLoggingEvent(this, serviceInstanceId)); - LOG.info("Published event to start streaming logs for service instance with ID {}", serviceInstanceId); - - return session - .send(envelopeSink.asMono().map(envelope -> session - .binaryMessage(dataBufferFactory -> dataBufferFactory.wrap(Envelope.ADAPTER.encode(envelope))))) - .then() - .doFinally(signalType -> afterConnectionClosed(session)) - .doOnError(throwable -> LOG - .error("Error handling logging stream for service instance " + serviceInstanceId, throwable)); - } - - @Override - public void onApplicationEvent(ServiceInstanceLogEvent event) { - broadcastLogMessage(event); - } - - public void broadcastLogMessage(ServiceInstanceLogEvent event) { - if (LOG.isDebugEnabled()) { - LOG.debug("Received event to broadcast log message for " + event.getServiceInstanceId()); - } - - Sinks.One envelopeSink = this.envelopeSinks.get(event.getServiceInstanceId()); - if (envelopeSink == null) { - if (LOG.isWarnEnabled()) { - LOG.warn("No sink found for {}, stopping log streaming", event.getServiceInstanceId()); - } - - eventPublisher.publishEvent(new StopServiceInstanceLoggingEvent(this, event.getServiceInstanceId())); - - return; - } - - if (LOG.isDebugEnabled()) { - LOG.debug("Sending message to client for {}", event.getServiceInstanceId()); - } - - envelopeSink.tryEmitValue(event.getEnvelope()); - } - - private void afterConnectionClosed(WebSocketSession webSocketSession) { - if (LOG.isInfoEnabled()) { - LOG.info("Connection closed [" + webSocketSession.getHandshakeInfo().getRemoteAddress() + "]"); - } - - final String serviceInstanceId = getServiceInstanceId(webSocketSession); - eventPublisher.publishEvent(new StopServiceInstanceLoggingEvent(this, serviceInstanceId)); - envelopeSinks.computeIfPresent(serviceInstanceId, (s, envelopeSink) -> null); - } - - private String getServiceInstanceId(WebSocketSession webSocketSession) { - URI uri = webSocketSession.getHandshakeInfo().getUri(); - final Map match = LOGGING_URI_TEMPLATE.match(uri.getPath()); - if (match.isEmpty()) { - throw new ServiceInstanceNotFoundException(); - } - - return match.get("serviceInstanceId"); - } - -} diff --git a/spring-cloud-app-broker-logging/src/main/java/org/springframework/cloud/appbroker/logging/streaming/events/ServiceInstanceLogEvent.java b/spring-cloud-app-broker-logging/src/main/java/org/springframework/cloud/appbroker/logging/streaming/events/ServiceInstanceLogEvent.java deleted file mode 100644 index c36546c..0000000 --- a/spring-cloud-app-broker-logging/src/main/java/org/springframework/cloud/appbroker/logging/streaming/events/ServiceInstanceLogEvent.java +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright 2002-2020 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.appbroker.logging.streaming.events; - -import org.cloudfoundry.dropsonde.events.Envelope; - -import org.springframework.context.ApplicationEvent; - -public class ServiceInstanceLogEvent extends ApplicationEvent { - - private static final long serialVersionUID = 4391048666734944603L; - - private final String serviceInstanceId; - - private final Envelope envelope; - - public ServiceInstanceLogEvent(Object source, String serviceInstanceId, Envelope envelope) { - super(source); - this.serviceInstanceId = serviceInstanceId; - this.envelope = envelope; - } - - public String getServiceInstanceId() { - return serviceInstanceId; - } - - public Envelope getEnvelope() { - return envelope; - } - -} diff --git a/spring-cloud-app-broker-logging/src/main/java/org/springframework/cloud/appbroker/logging/streaming/events/ServiceInstanceLoggingEvent.java b/spring-cloud-app-broker-logging/src/main/java/org/springframework/cloud/appbroker/logging/streaming/events/ServiceInstanceLoggingEvent.java deleted file mode 100644 index 197091a..0000000 --- a/spring-cloud-app-broker-logging/src/main/java/org/springframework/cloud/appbroker/logging/streaming/events/ServiceInstanceLoggingEvent.java +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Copyright 2002-2020 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.appbroker.logging.streaming.events; - -import org.springframework.context.ApplicationEvent; - -public class ServiceInstanceLoggingEvent extends ApplicationEvent { - - private static final long serialVersionUID = 3721553379568462887L; - - public enum Operation { - - /** - * Start publishing log stream for a given service instance id - */ - START, - - /** - * Stop publishing log stream for a given service instance id - */ - STOP - } - - private final String serviceInstanceId; - - private final Operation operation; - - public ServiceInstanceLoggingEvent(Object source, String serviceInstanceId, Operation operation) { - super(source); - this.serviceInstanceId = serviceInstanceId; - this.operation = operation; - } - - public String getServiceInstanceId() { - return serviceInstanceId; - } - - public Operation getOperation() { - return operation; - } - -} diff --git a/spring-cloud-app-broker-logging/src/main/java/org/springframework/cloud/appbroker/logging/streaming/events/StartServiceInstanceLoggingEvent.java b/spring-cloud-app-broker-logging/src/main/java/org/springframework/cloud/appbroker/logging/streaming/events/StartServiceInstanceLoggingEvent.java deleted file mode 100644 index fcc1aa8..0000000 --- a/spring-cloud-app-broker-logging/src/main/java/org/springframework/cloud/appbroker/logging/streaming/events/StartServiceInstanceLoggingEvent.java +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Copyright 2002-2020 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.appbroker.logging.streaming.events; - -public class StartServiceInstanceLoggingEvent extends ServiceInstanceLoggingEvent { - - private static final long serialVersionUID = -5940715663862240039L; - - public StartServiceInstanceLoggingEvent(Object source, String serviceInstanceId) { - super(source, serviceInstanceId, Operation.START); - } - -} diff --git a/spring-cloud-app-broker-logging/src/main/java/org/springframework/cloud/appbroker/logging/streaming/events/StopServiceInstanceLoggingEvent.java b/spring-cloud-app-broker-logging/src/main/java/org/springframework/cloud/appbroker/logging/streaming/events/StopServiceInstanceLoggingEvent.java deleted file mode 100644 index 0afebdb..0000000 --- a/spring-cloud-app-broker-logging/src/main/java/org/springframework/cloud/appbroker/logging/streaming/events/StopServiceInstanceLoggingEvent.java +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Copyright 2002-2020 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.appbroker.logging.streaming.events; - -public class StopServiceInstanceLoggingEvent extends ServiceInstanceLoggingEvent { - - private static final long serialVersionUID = 2858399700112202361L; - - public StopServiceInstanceLoggingEvent(Object source, String serviceInstanceId) { - super(source, serviceInstanceId, Operation.STOP); - } - -} diff --git a/spring-cloud-app-broker-logging/src/test/java/com/example/recentlog/RecentLogsTestApp.java b/spring-cloud-app-broker-logging/src/test/java/com/example/recentlog/RecentLogsTestApp.java deleted file mode 100644 index f437e18..0000000 --- a/spring-cloud-app-broker-logging/src/test/java/com/example/recentlog/RecentLogsTestApp.java +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright 2002-2020 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.example.recentlog; - -import java.util.UUID; - -import reactor.core.publisher.Flux; - -import org.springframework.boot.autoconfigure.SpringBootApplication; -import org.springframework.cloud.appbroker.logging.ApplicationIdsProvider; -import org.springframework.cloud.servicebroker.autoconfigure.web.ServiceBrokerAutoConfiguration; -import org.springframework.cloud.servicebroker.autoconfigure.web.reactive.ServiceBrokerWebFluxAutoConfiguration; -import org.springframework.context.annotation.Bean; - -@SpringBootApplication(exclude = { - ServiceBrokerAutoConfiguration.class, - ServiceBrokerWebFluxAutoConfiguration.class -}) -public class RecentLogsTestApp { - - static final String APP_ID = UUID.randomUUID().toString(); - - public static String getAppId() { - return APP_ID; - } - - @Bean - ApplicationIdsProvider applicationIdsProvider() { - return serviceInstanceId -> Flux.just(APP_ID); - } - -} diff --git a/spring-cloud-app-broker-logging/src/test/java/com/example/streaming/LogStreamingTestApp.java b/spring-cloud-app-broker-logging/src/test/java/com/example/streaming/LogStreamingTestApp.java deleted file mode 100644 index d981061..0000000 --- a/spring-cloud-app-broker-logging/src/test/java/com/example/streaming/LogStreamingTestApp.java +++ /dev/null @@ -1,65 +0,0 @@ -/* - * Copyright 2002-2020 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.example.streaming; - -import java.util.UUID; - -import reactor.core.publisher.Flux; - -import org.springframework.boot.autoconfigure.SpringBootApplication; -import org.springframework.cloud.appbroker.logging.ApplicationIdsProvider; -import org.springframework.cloud.appbroker.logging.streaming.events.StopServiceInstanceLoggingEvent; -import org.springframework.cloud.servicebroker.autoconfigure.web.ServiceBrokerAutoConfiguration; -import org.springframework.cloud.servicebroker.autoconfigure.web.reactive.ServiceBrokerWebFluxAutoConfiguration; -import org.springframework.context.annotation.Bean; -import org.springframework.context.event.EventListener; - -@SpringBootApplication(exclude = { - ServiceBrokerAutoConfiguration.class, - ServiceBrokerWebFluxAutoConfiguration.class -}) -public class LogStreamingTestApp { - - private static final String APP_ID = UUID.randomUUID().toString(); - - private static boolean receivedStopEvent; - private static String receivedStopEventServiceInstanceId; - - public static String getAppId() { - return APP_ID; - } - - public static boolean isReceivedStopEvent() { - return receivedStopEvent; - } - - public static String getReceivedStopEventServiceInstanceId() { - return receivedStopEventServiceInstanceId; - } - - @Bean - ApplicationIdsProvider applicationIdsProvider() { - return serviceInstanceId -> Flux.just(APP_ID); - } - - @EventListener - public void onStop(StopServiceInstanceLoggingEvent stopServiceInstanceLoggingEvent) { - receivedStopEventServiceInstanceId = stopServiceInstanceLoggingEvent.getServiceInstanceId(); - receivedStopEvent = true; - } - -} diff --git a/spring-cloud-app-broker-logging/src/test/java/org/springframework/cloud/appbroker/logging/recent/ServiceInstanceRecentLogsTest.java b/spring-cloud-app-broker-logging/src/test/java/org/springframework/cloud/appbroker/logging/recent/ServiceInstanceRecentLogsTest.java deleted file mode 100644 index 5a5504f..0000000 --- a/spring-cloud-app-broker-logging/src/test/java/org/springframework/cloud/appbroker/logging/recent/ServiceInstanceRecentLogsTest.java +++ /dev/null @@ -1,98 +0,0 @@ -/* - * Copyright 2002-2020 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.appbroker.logging.recent; - -import java.time.Instant; -import java.util.UUID; - -import com.example.recentlog.RecentLogsTestApp; -import org.cloudfoundry.client.CloudFoundryClient; -import org.cloudfoundry.client.v2.applications.ApplicationEntity; -import org.cloudfoundry.client.v2.applications.GetApplicationRequest; -import org.cloudfoundry.client.v2.applications.GetApplicationResponse; -import org.cloudfoundry.doppler.DopplerClient; -import org.cloudfoundry.doppler.Envelope; -import org.cloudfoundry.doppler.EventType; -import org.cloudfoundry.doppler.LogMessage; -import org.cloudfoundry.doppler.MessageType; -import org.cloudfoundry.doppler.RecentLogsRequest; -import org.hamcrest.Matchers; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import org.mockito.Answers; -import reactor.core.publisher.Flux; -import reactor.core.publisher.Mono; - -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.boot.test.mock.mockito.MockBean; -import org.springframework.boot.test.web.server.LocalServerPort; -import org.springframework.test.web.reactive.server.WebTestClient; - -import static org.mockito.BDDMockito.given; - -@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, classes = RecentLogsTestApp.class) -class ServiceInstanceRecentLogsTest { - - @LocalServerPort - int port; - - @MockBean - DopplerClient dopplerClient; - - @MockBean(answer = Answers.RETURNS_DEEP_STUBS) - CloudFoundryClient cloudFoundryClient; - - private String expectedTestMessage; - - @BeforeEach - void setUp() { - expectedTestMessage = "test message " + UUID.randomUUID(); - - RecentLogsRequest request = RecentLogsRequest.builder().applicationId(RecentLogsTestApp.getAppId()).build(); - LogMessage testMessage = LogMessage - .builder() - .message(expectedTestMessage) - .timestamp(Instant.now().toEpochMilli()) - .messageType(MessageType.OUT).build(); - - Envelope testEnvelope = Envelope - .builder() - .eventType(EventType.LOG_MESSAGE).origin("test") - .logMessage(testMessage).build(); - - given(dopplerClient.recentLogs(request)) - .willReturn(Flux.just(testEnvelope)); - - given(cloudFoundryClient.applicationsV2() - .get(GetApplicationRequest.builder().applicationId(RecentLogsTestApp.getAppId()).build())) - .willReturn(Mono.just( - GetApplicationResponse.builder().entity(ApplicationEntity.builder().name("test-app").build()).build())); - } - - @Test - void shouldFetchLogs() { - String serviceInstanceId = UUID.randomUUID().toString(); - WebTestClient client = WebTestClient.bindToServer().baseUrl("http://localhost:" + port).build(); - - client.get().uri("/logs/{serviceInstanceId}/recentlogs", serviceInstanceId) - .exchange() - .expectStatus().isOk() - .expectBody(String.class) - .value(Matchers.containsString(expectedTestMessage)); - } - -} diff --git a/spring-cloud-app-broker-logging/src/test/java/org/springframework/cloud/appbroker/logging/streaming/ServiceInstanceLogStreamingTest.java b/spring-cloud-app-broker-logging/src/test/java/org/springframework/cloud/appbroker/logging/streaming/ServiceInstanceLogStreamingTest.java deleted file mode 100644 index c35a073..0000000 --- a/spring-cloud-app-broker-logging/src/test/java/org/springframework/cloud/appbroker/logging/streaming/ServiceInstanceLogStreamingTest.java +++ /dev/null @@ -1,174 +0,0 @@ -/* - * Copyright 2002-2020 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.appbroker.logging.streaming; - -import java.io.IOException; -import java.net.URI; -import java.time.Instant; -import java.util.UUID; -import java.util.concurrent.atomic.AtomicReference; - -import com.example.streaming.LogStreamingTestApp; -import org.cloudfoundry.client.CloudFoundryClient; -import org.cloudfoundry.client.v2.applications.ApplicationEntity; -import org.cloudfoundry.client.v2.applications.GetApplicationRequest; -import org.cloudfoundry.client.v2.applications.GetApplicationResponse; -import org.cloudfoundry.doppler.DopplerClient; -import org.cloudfoundry.doppler.EventType; -import org.cloudfoundry.doppler.MessageType; -import org.cloudfoundry.doppler.StreamRequest; -import org.cloudfoundry.dropsonde.events.Envelope; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import org.mockito.Answers; -import reactor.core.Disposable; -import reactor.core.publisher.Flux; -import reactor.core.publisher.Mono; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.boot.test.mock.mockito.MockBean; -import org.springframework.boot.test.web.server.LocalServerPort; -import org.springframework.cloud.appbroker.logging.LoggingUtils; -import org.springframework.cloud.appbroker.logging.streaming.events.ServiceInstanceLogEvent; -import org.springframework.context.ApplicationEventPublisher; -import org.springframework.core.io.buffer.DataBuffer; -import org.springframework.web.reactive.socket.WebSocketHandler; -import org.springframework.web.reactive.socket.client.ReactorNettyWebSocketClient; -import org.springframework.web.reactive.socket.client.WebSocketClient; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.awaitility.Awaitility.await; -import static org.mockito.BDDMockito.given; - -@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, classes = LogStreamingTestApp.class) -class ServiceInstanceLogStreamingTest { - - @LocalServerPort - int port; - - @MockBean - DopplerClient dopplerClient; - - @MockBean(answer = Answers.RETURNS_DEEP_STUBS) - CloudFoundryClient cloudFoundryClient; - - @Autowired - ApplicationEventPublisher applicationEventPublisher; - - private Envelope expectedEnvelope; - - private final AtomicReference actualEnvelope = new AtomicReference<>(); - - private String serviceInstanceId; - - @BeforeEach - void setUp() { - serviceInstanceId = UUID.randomUUID().toString(); - String expectedTestMessage = "test message " + serviceInstanceId; - - org.cloudfoundry.doppler.LogMessage testMessage = org.cloudfoundry.doppler.LogMessage - .builder() - .message(expectedTestMessage) - .timestamp(Instant.now().toEpochMilli()) - .messageType(MessageType.OUT).build(); - - org.cloudfoundry.doppler.Envelope testEnvelope = org.cloudfoundry.doppler.Envelope - .builder() - .eventType(EventType.LOG_MESSAGE).origin("test") - .logMessage(testMessage).build(); - - // expectations are instances of Dropsnode Envelope + LogMessage - Envelope envelope = LoggingUtils.convertDopplerEnvelopeToDropsonde(testEnvelope); - org.cloudfoundry.dropsonde.events.LogMessage expectedMessage = new org.cloudfoundry.dropsonde.events.LogMessage.Builder() - .message_type(envelope.logMessage.message_type) - .source_instance("test-app null") - .timestamp(envelope.logMessage.timestamp) - .message(envelope.logMessage.message) - .build(); - - expectedEnvelope = new Envelope.Builder() - .eventType(envelope.eventType) - .logMessage(expectedMessage) - .origin("test") - .build(); - - StreamRequest request = StreamRequest.builder().applicationId(LogStreamingTestApp.getAppId()).build(); - given(dopplerClient.stream(request)).willReturn(Flux.just(testEnvelope)); - given(cloudFoundryClient.applicationsV2().get( - GetApplicationRequest.builder().applicationId(LogStreamingTestApp.getAppId()).build())) - .willReturn(Mono.just( - GetApplicationResponse.builder().entity(ApplicationEntity.builder().name("test-app").build()).build())); - - } - - @Test - void shouldPublishWebSocketEndpoint() { - Disposable subscription = connectToLogsStreamEndpoint(); - - await().untilAsserted(() -> assertThat(actualEnvelope).hasValue(expectedEnvelope)); - - subscription.dispose(); - } - - @Test - void shouldPublishEventOnDisconnect() { - Disposable subscription = connectToLogsStreamEndpoint(); - - await().untilAsserted(() -> assertThat(actualEnvelope.get()).isNotNull()); - - subscription.dispose(); - - await().untilAsserted(() -> assertThat(LogStreamingTestApp.isReceivedStopEvent()).isTrue()); - } - - @Test - void shouldStopStreamingIfNoClient() { - // CLI plugin doesn't always handle disconnect gracefully, so sometimes it is possible that log stream is - // being published but there is no listener. In this case log streaming should be stopped. - - Disposable subscription = connectToLogsStreamEndpoint(); - subscription.dispose(); - - applicationEventPublisher.publishEvent(new ServiceInstanceLogEvent(this, serviceInstanceId, expectedEnvelope)); - await().untilAsserted(() -> assertThat(LogStreamingTestApp.getReceivedStopEventServiceInstanceId()).isEqualTo(serviceInstanceId)); - } - - private Disposable connectToLogsStreamEndpoint() { - URI uri = URI.create("ws://localhost:" + port + "/logs/" + serviceInstanceId + "/stream"); - - WebSocketClient client = new ReactorNettyWebSocketClient(); - return client.execute(uri, getWebSocketHandler()).subscribe(); - } - - private WebSocketHandler getWebSocketHandler() { - return session -> session - .receive() - .doOnNext(message -> { - DataBuffer buffer = message.getPayload(); - try { - actualEnvelope.set(Envelope.ADAPTER.decode( - buffer.asInputStream())); - } - catch (IOException e) { - throw new RuntimeException(e); - } - }) - .then(); - } - -} diff --git a/spring-cloud-starter-app-broker-logging/build.gradle b/spring-cloud-starter-app-broker-logging/build.gradle deleted file mode 100644 index b152010..0000000 --- a/spring-cloud-starter-app-broker-logging/build.gradle +++ /dev/null @@ -1,22 +0,0 @@ -/* - * Copyright 2002-2020 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -description = "Spring Cloud App Broker Starter for Logging" - -dependencies { - api project(":spring-cloud-starter-app-broker") - api project(":spring-cloud-app-broker-logging") -}