diff --git a/README.md b/README.md
index 6f6e77f4ae..617d1e1b9c 100644
--- a/README.md
+++ b/README.md
@@ -17,6 +17,41 @@ The `cf-java-client` project is a Java language binding for interacting with a C
## Versions
The Cloud Foundry Java Client has two active versions. The `5.x` line is compatible with Spring Boot `2.4.x - 2.6.x` just to manage its dependencies, while the `4.x` line uses Spring Boot `2.3.x`.
+## Deprecations
+
+### `DopplerClient.recentLogs()` — Recent Logs via Doppler
+
+> [!WARNING]
+> **Deprecated since cf-java-client `5.17.x`**
+>
+> The `DopplerClient.recentLogs()` endpoint (and the related `RecentLogsRequest` / `LogMessage` types from the `org.cloudfoundry.doppler` package) are **deprecated** and will be removed in a future release.
+>
+> This API relies on the [Loggregator][loggregator] Doppler/Traffic Controller endpoint `/apps/{id}/recentlogs`, which was removed in **Loggregator ≥ 107.0**.
+> The affected platform versions are:
+>
+> | Platform | Last version with Doppler recent-logs support |
+> | -------- | --------------------------------------------- |
+> | CF Deployment (CFD) | `< 24.3` |
+> | Tanzu Application Service (TAS) | `< 4.0` |
+>
+> **Migration:** Replace any call to `DopplerClient.recentLogs()` with [`LogCacheClient.read()`][log-cache-api] (available via `org.cloudfoundry.logcache.v1.LogCacheClient`).
+>
+> ```java
+> // Before (deprecated)
+> dopplerClient.recentLogs(RecentLogsRequest.builder()
+> .applicationId(appId)
+> .build());
+>
+> // After
+> logCacheClient.read(ReadRequest.builder()
+> .sourceId(appId)
+> .envelopeTypes(EnvelopeType.LOG)
+> .build());
+> ```
+
+[loggregator]: https://github.com/cloudfoundry/loggregator
+[log-cache-api]: https://github.com/cloudfoundry/log-cache
+
## Dependencies
Most projects will need two dependencies; the Operations API and an implementation of the Client API. For Maven, the dependencies would be defined like this:
@@ -76,6 +111,9 @@ Both the `cloudfoundry-operations` and `cloudfoundry-client` projects follow a [
### `CloudFoundryClient`, `DopplerClient`, `UaaClient` Builders
+> [!NOTE]
+> **`DopplerClient` — partial deprecation:** The `recentLogs()` method on `DopplerClient` is deprecated and only works against Loggregator \< 107.0 (CFD \< 24.3 / TAS \< 4.0). See the [Deprecations](#deprecations) section above for the migration path to `LogCacheClient`.
+
The lowest-level building blocks of the API are `ConnectionContext` and `TokenProvider`. These types are intended to be shared between instances of the clients, and come with out of the box implementations. To instantiate them, you configure them with builders:
```java
diff --git a/cloudfoundry-client/src/main/java/org/cloudfoundry/doppler/DopplerClient.java b/cloudfoundry-client/src/main/java/org/cloudfoundry/doppler/DopplerClient.java
index a9c03441cf..3d61922734 100644
--- a/cloudfoundry-client/src/main/java/org/cloudfoundry/doppler/DopplerClient.java
+++ b/cloudfoundry-client/src/main/java/org/cloudfoundry/doppler/DopplerClient.java
@@ -42,9 +42,15 @@ public interface DopplerClient {
/**
* Makes the Recent Logs request
*
+ * @deprecated Use {@link org.cloudfoundry.logcache.v1.LogCacheClient#read(org.cloudfoundry.logcache.v1.ReadRequest)} instead.
+ * Only works with {@code Loggregator < 107.0}, shipped in {@code CFD < 24.3} and {@code TAS < 4.0}.
* @param request the Recent Logs request
- * @return the events from the recent logs
+ * @return a flux of events from the recent logs
+ * @see Loggregator
+ * @see Log Cache
+ * @see org.cloudfoundry.logcache.v1.LogCacheClient#read(org.cloudfoundry.logcache.v1.ReadRequest)
*/
+ @Deprecated
Flux recentLogs(RecentLogsRequest request);
/**
diff --git a/cloudfoundry-operations/src/main/java/org/cloudfoundry/operations/_DefaultCloudFoundryOperations.java b/cloudfoundry-operations/src/main/java/org/cloudfoundry/operations/_DefaultCloudFoundryOperations.java
index 1d21f29b2b..4db0bd8489 100644
--- a/cloudfoundry-operations/src/main/java/org/cloudfoundry/operations/_DefaultCloudFoundryOperations.java
+++ b/cloudfoundry-operations/src/main/java/org/cloudfoundry/operations/_DefaultCloudFoundryOperations.java
@@ -23,6 +23,7 @@
import org.cloudfoundry.client.v3.spaces.ListSpacesRequest;
import org.cloudfoundry.client.v3.spaces.SpaceResource;
import org.cloudfoundry.doppler.DopplerClient;
+import org.cloudfoundry.logcache.v1.LogCacheClient;
import org.cloudfoundry.networking.NetworkingClient;
import org.cloudfoundry.operations.advanced.Advanced;
import org.cloudfoundry.operations.advanced.DefaultAdvanced;
@@ -79,7 +80,7 @@ public Advanced advanced() {
@Override
@Value.Derived
public Applications applications() {
- return new DefaultApplications(getCloudFoundryClientPublisher(), getDopplerClientPublisher(), getSpaceId());
+ return new DefaultApplications(getCloudFoundryClientPublisher(), getDopplerClientPublisher(), getLogCacheClientPublisher(), getSpaceId());
}
@Override
@@ -197,6 +198,19 @@ Mono getDopplerClientPublisher() {
.orElse(Mono.error(new IllegalStateException("DopplerClient must be set")));
}
+ /**
+ * The {@link LogCacheClient} to use for operations functionality
+ */
+ @Nullable
+ abstract LogCacheClient getLogCacheClient();
+
+ @Value.Derived
+ Mono getLogCacheClientPublisher() {
+ return Optional.ofNullable(getLogCacheClient())
+ .map(Mono::just)
+ .orElse(Mono.error(new IllegalStateException("LogCacheClient must be set")));
+ }
+
/**
* The {@link NetworkingClient} to use for operations functionality
*/
diff --git a/cloudfoundry-operations/src/main/java/org/cloudfoundry/operations/applications/Applications.java b/cloudfoundry-operations/src/main/java/org/cloudfoundry/operations/applications/Applications.java
index 5196fef6c8..53317ccb63 100644
--- a/cloudfoundry-operations/src/main/java/org/cloudfoundry/operations/applications/Applications.java
+++ b/cloudfoundry-operations/src/main/java/org/cloudfoundry/operations/applications/Applications.java
@@ -17,6 +17,8 @@
package org.cloudfoundry.operations.applications;
import org.cloudfoundry.doppler.LogMessage;
+import org.cloudfoundry.logcache.v1.Log;
+import org.cloudfoundry.logcache.v1.ReadRequest;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
@@ -126,6 +128,15 @@ public interface Applications {
@Deprecated
Flux logs(LogsRequest request);
+ /**
+ * List the applications logs from logCacheClient.
+ * If no messages are available, an empty Flux is returned.
+ *
+ * @param request the application logs request
+ * @return the applications logs
+ */
+ Flux logsRecent(ReadRequest request);
+
/**
* List the applications logs.
* Only works with {@code Loggregator < 107.0}, shipped in {@code CFD < 24.3}
diff --git a/cloudfoundry-operations/src/main/java/org/cloudfoundry/operations/applications/DefaultApplications.java b/cloudfoundry-operations/src/main/java/org/cloudfoundry/operations/applications/DefaultApplications.java
index e51ddbb472..b247261d10 100644
--- a/cloudfoundry-operations/src/main/java/org/cloudfoundry/operations/applications/DefaultApplications.java
+++ b/cloudfoundry-operations/src/main/java/org/cloudfoundry/operations/applications/DefaultApplications.java
@@ -154,6 +154,10 @@
import org.cloudfoundry.doppler.LogMessage;
import org.cloudfoundry.doppler.RecentLogsRequest;
import org.cloudfoundry.doppler.StreamRequest;
+import org.cloudfoundry.logcache.v1.EnvelopeBatch;
+import org.cloudfoundry.logcache.v1.Log;
+import org.cloudfoundry.logcache.v1.LogCacheClient;
+import org.cloudfoundry.logcache.v1.ReadRequest;
import org.cloudfoundry.operations.util.OperationsLogging;
import org.cloudfoundry.util.DateUtils;
import org.cloudfoundry.util.DelayTimeoutException;
@@ -200,6 +204,10 @@ public final class DefaultApplications implements Applications {
private static final Comparator LOG_MESSAGE_COMPARATOR =
Comparator.comparing(LogMessage::getTimestamp);
+ private static final Comparator
+ LOG_MESSAGE_COMPARATOR_LOG_CACHE =
+ Comparator.comparing(org.cloudfoundry.logcache.v1.Envelope::getTimestamp);
+
private static final Duration LOG_MESSAGE_TIMESPAN = Duration.ofMillis(500);
private static final int MAX_NUMBER_OF_RECENT_EVENTS = 50;
@@ -214,6 +222,8 @@ public final class DefaultApplications implements Applications {
private final Mono dopplerClient;
+ private final Mono logCacheClient;
+
private final RandomWords randomWords;
private final Mono spaceId;
@@ -221,17 +231,20 @@ public final class DefaultApplications implements Applications {
public DefaultApplications(
Mono cloudFoundryClient,
Mono dopplerClient,
+ Mono logCacheClient,
Mono spaceId) {
- this(cloudFoundryClient, dopplerClient, new WordListRandomWords(), spaceId);
+ this(cloudFoundryClient, dopplerClient, logCacheClient, new WordListRandomWords(), spaceId);
}
DefaultApplications(
Mono cloudFoundryClient,
Mono dopplerClient,
+ Mono logCacheClient,
RandomWords randomWords,
Mono spaceId) {
this.cloudFoundryClient = cloudFoundryClient;
this.dopplerClient = dopplerClient;
+ this.logCacheClient = logCacheClient;
this.randomWords = randomWords;
this.spaceId = spaceId;
}
@@ -529,6 +542,7 @@ public Flux listTasks(ListApplicationTasksRequest request) {
.checkpoint();
}
+ @Deprecated
@Override
public Flux logs(LogsRequest request) {
return Mono.zip(this.cloudFoundryClient, this.spaceId)
@@ -544,6 +558,13 @@ public Flux logs(LogsRequest request) {
.checkpoint();
}
+ @Override
+ public Flux logsRecent(ReadRequest request) {
+ return getRecentLogsLogCache(this.logCacheClient, request)
+ .transform(OperationsLogging.log("Get Application Logs"))
+ .checkpoint();
+ }
+
@Override
public Flux logs(ApplicationLogsRequest request) {
return logs(LogsRequest.builder()
@@ -673,7 +694,6 @@ public Mono pushManifestV3(PushManifestV3Request request) {
} catch (IOException e) {
throw new RuntimeException("Could not serialize manifest", e);
}
-
return Mono.zip(this.cloudFoundryClient, this.spaceId)
.flatMap(
function(
@@ -1617,6 +1637,14 @@ private static Flux getLogs(
}
}
+ private static Flux getRecentLogsLogCache(
+ Mono logCacheClient, ReadRequest readRequest) {
+ return requestLogsRecentLogCache(logCacheClient, readRequest)
+ .flatMapIterable(EnvelopeBatch::getBatch)
+ .sort(LOG_MESSAGE_COMPARATOR_LOG_CACHE)
+ .mapNotNull(org.cloudfoundry.logcache.v1.Envelope::getLog);
+ }
+
@SuppressWarnings("unchecked")
private static Map getMetadataRequest(EventEntity entity) {
Map> metadata =
@@ -2501,6 +2529,7 @@ private static Flux requestListTasks(
.build()));
}
+ @Deprecated
private static Flux requestLogsRecent(
Mono dopplerClient, String applicationId) {
return dopplerClient.flatMapMany(
@@ -2509,6 +2538,14 @@ private static Flux requestLogsRecent(
RecentLogsRequest.builder().applicationId(applicationId).build()));
}
+ private static Mono requestLogsRecentLogCache(
+ Mono logCacheClient, ReadRequest readRequest) {
+ return logCacheClient.flatMap(
+ client ->
+ client.read(readRequest)
+ .flatMap(response -> Mono.justOrEmpty(response.getEnvelopes())));
+ }
+
private static Flux requestLogsStream(
Mono dopplerClient, String applicationId) {
return dopplerClient.flatMapMany(
diff --git a/cloudfoundry-operations/src/test/java/org/cloudfoundry/operations/AbstractOperationsTest.java b/cloudfoundry-operations/src/test/java/org/cloudfoundry/operations/AbstractOperationsTest.java
index ab1250658a..9dd97126e8 100644
--- a/cloudfoundry-operations/src/test/java/org/cloudfoundry/operations/AbstractOperationsTest.java
+++ b/cloudfoundry-operations/src/test/java/org/cloudfoundry/operations/AbstractOperationsTest.java
@@ -53,6 +53,7 @@
import org.cloudfoundry.client.v3.stacks.StacksV3;
import org.cloudfoundry.client.v3.tasks.Tasks;
import org.cloudfoundry.doppler.DopplerClient;
+import org.cloudfoundry.logcache.v1.LogCacheClient;
import org.cloudfoundry.routing.RoutingClient;
import org.cloudfoundry.routing.v1.routergroups.RouterGroups;
import org.cloudfoundry.uaa.UaaClient;
@@ -104,6 +105,8 @@ public abstract class AbstractOperationsTest {
protected final DopplerClient dopplerClient = mock(DopplerClient.class, RETURNS_SMART_NULLS);
+ protected final LogCacheClient logCacheClient = mock(LogCacheClient.class, RETURNS_SMART_NULLS);
+
protected final Events events = mock(Events.class, RETURNS_SMART_NULLS);
protected final FeatureFlags featureFlags = mock(FeatureFlags.class, RETURNS_SMART_NULLS);
diff --git a/cloudfoundry-operations/src/test/java/org/cloudfoundry/operations/applications/DefaultApplicationsTest.java b/cloudfoundry-operations/src/test/java/org/cloudfoundry/operations/applications/DefaultApplicationsTest.java
index cdc9619d2d..a5724a5efa 100644
--- a/cloudfoundry-operations/src/test/java/org/cloudfoundry/operations/applications/DefaultApplicationsTest.java
+++ b/cloudfoundry-operations/src/test/java/org/cloudfoundry/operations/applications/DefaultApplicationsTest.java
@@ -139,11 +139,17 @@
import org.cloudfoundry.client.v3.tasks.CreateTaskResponse;
import org.cloudfoundry.client.v3.tasks.TaskResource;
import org.cloudfoundry.doppler.DopplerClient;
-import org.cloudfoundry.doppler.Envelope;
import org.cloudfoundry.doppler.EventType;
import org.cloudfoundry.doppler.LogMessage;
import org.cloudfoundry.doppler.RecentLogsRequest;
import org.cloudfoundry.doppler.StreamRequest;
+import org.cloudfoundry.logcache.v1.Envelope;
+import org.cloudfoundry.logcache.v1.EnvelopeBatch;
+import org.cloudfoundry.logcache.v1.Log;
+import org.cloudfoundry.logcache.v1.LogCacheClient;
+import org.cloudfoundry.logcache.v1.LogType;
+import org.cloudfoundry.logcache.v1.ReadRequest;
+import org.cloudfoundry.logcache.v1.ReadResponse;
import org.cloudfoundry.operations.AbstractOperationsTest;
import org.cloudfoundry.util.DateUtils;
import org.cloudfoundry.util.FluentMap;
@@ -163,6 +169,7 @@ final class DefaultApplicationsTest extends AbstractOperationsTest {
new DefaultApplications(
Mono.just(this.cloudFoundryClient),
Mono.just(this.dopplerClient),
+ Mono.just(this.logCacheClient),
this.randomWords,
Mono.just(TEST_SPACE_ID));
@@ -1306,8 +1313,9 @@ void listTasks() {
.verify(Duration.ofSeconds(5));
}
+ @SuppressWarnings("deprecation")
@Test
- void logs() {
+ void logsDoppler() {
requestApplications(
this.cloudFoundryClient,
"test-application-name",
@@ -1318,13 +1326,14 @@ void logs() {
this.applications
.logs(LogsRequest.builder().name("test-application-name").recent(false).build())
.as(StepVerifier::create)
- .expectNext(fill(LogMessage.builder(), "log-message-").build())
+ .expectNextMatches(log -> log.getMessage().equals("test-log-message-message"))
.expectComplete()
.verify(Duration.ofSeconds(5));
}
+ @SuppressWarnings("deprecation")
@Test
- void logsNoApp() {
+ void logsNoAppDoppler() {
requestApplicationsEmpty(this.cloudFoundryClient, "test-application-name", TEST_SPACE_ID);
this.applications
@@ -1339,8 +1348,9 @@ void logsNoApp() {
.verify(Duration.ofSeconds(5));
}
+ @SuppressWarnings("deprecation")
@Test
- void logsRecent() {
+ void logsRecentDoppler() {
requestApplications(
this.cloudFoundryClient,
"test-application-name",
@@ -1351,13 +1361,31 @@ void logsRecent() {
this.applications
.logs(LogsRequest.builder().name("test-application-name").recent(true).build())
.as(StepVerifier::create)
- .expectNext(fill(LogMessage.builder(), "log-message-").build())
+ .expectNextMatches(log -> log.getMessage().equals("test-log-message-message"))
.expectComplete()
.verify(Duration.ofSeconds(5));
}
@Test
- void logsRecentNotSet() {
+ void logsRecentLogCache() {
+ requestApplications(
+ this.cloudFoundryClient,
+ "test-application-name",
+ TEST_SPACE_ID,
+ "test-metadata-id");
+ requestLogsRecentLogCache(this.logCacheClient, "test-metadata-id", "test-payload");
+
+ this.applications
+ .logsRecent(ReadRequest.builder().sourceId("test-metadata-id").build())
+ .as(StepVerifier::create)
+ .expectNext(fill(Log.builder()).type(LogType.OUT).build())
+ .expectComplete()
+ .verify(Duration.ofSeconds(5));
+ }
+
+ @SuppressWarnings("deprecation")
+ @Test
+ void logsRecentNotSetDoppler() {
requestApplications(
this.cloudFoundryClient,
"test-application-name",
@@ -5317,12 +5345,13 @@ private static void requestListTasksEmpty(
.build()));
}
+ @SuppressWarnings("deprecation")
private static void requestLogsRecent(DopplerClient dopplerClient, String applicationId) {
when(dopplerClient.recentLogs(
RecentLogsRequest.builder().applicationId(applicationId).build()))
.thenReturn(
Flux.just(
- Envelope.builder()
+ org.cloudfoundry.doppler.Envelope.builder()
.eventType(EventType.LOG_MESSAGE)
.logMessage(
fill(LogMessage.builder(), "log-message-").build())
@@ -5330,11 +5359,36 @@ private static void requestLogsRecent(DopplerClient dopplerClient, String applic
.build()));
}
+ private static void requestLogsRecentLogCache(
+ LogCacheClient logCacheClient, String sourceId, String payload) {
+ when(logCacheClient.read(ReadRequest.builder().sourceId(sourceId).build()))
+ .thenReturn(
+ Mono.just(
+ fill(ReadResponse.builder())
+ .envelopes(
+ fill(EnvelopeBatch.builder())
+ .batch(
+ Arrays.asList(
+ fill(Envelope.builder())
+ .log(
+ Log
+ .builder()
+ .payload(
+ payload)
+ .type(
+ LogType
+ .OUT)
+ .build())
+ .build()))
+ .build())
+ .build()));
+ }
+
private static void requestLogsStream(DopplerClient dopplerClient, String applicationId) {
when(dopplerClient.stream(StreamRequest.builder().applicationId(applicationId).build()))
.thenReturn(
Flux.just(
- Envelope.builder()
+ org.cloudfoundry.doppler.Envelope.builder()
.eventType(EventType.LOG_MESSAGE)
.logMessage(
fill(LogMessage.builder(), "log-message-").build())
diff --git a/integration-test/src/test/java/org/cloudfoundry/IntegrationTestConfiguration.java b/integration-test/src/test/java/org/cloudfoundry/IntegrationTestConfiguration.java
index 36c30c3578..58b01252f0 100644
--- a/integration-test/src/test/java/org/cloudfoundry/IntegrationTestConfiguration.java
+++ b/integration-test/src/test/java/org/cloudfoundry/IntegrationTestConfiguration.java
@@ -48,6 +48,7 @@
import org.cloudfoundry.client.v2.stacks.StackResource;
import org.cloudfoundry.client.v2.userprovidedserviceinstances.CreateUserProvidedServiceInstanceRequest;
import org.cloudfoundry.doppler.DopplerClient;
+import org.cloudfoundry.logcache.v1.LogCacheClient;
import org.cloudfoundry.logcache.v1.TestLogCacheEndpoints;
import org.cloudfoundry.networking.NetworkingClient;
import org.cloudfoundry.operations.DefaultCloudFoundryOperations;
@@ -273,6 +274,7 @@ ReactorCloudFoundryClient cloudFoundryClient(
DefaultCloudFoundryOperations cloudFoundryOperations(
CloudFoundryClient cloudFoundryClient,
DopplerClient dopplerClient,
+ LogCacheClient logCacheClient,
NetworkingClient networkingClient,
RoutingClient routingClient,
UaaClient uaaClient,
@@ -281,6 +283,7 @@ DefaultCloudFoundryOperations cloudFoundryOperations(
return DefaultCloudFoundryOperations.builder()
.cloudFoundryClient(cloudFoundryClient)
.dopplerClient(dopplerClient)
+ .logCacheClient(logCacheClient)
.networkingClient(networkingClient)
.routingClient(routingClient)
.uaaClient(uaaClient)
diff --git a/integration-test/src/test/java/org/cloudfoundry/operations/ApplicationsTest.java b/integration-test/src/test/java/org/cloudfoundry/operations/ApplicationsTest.java
index 36e1bd9456..d5455d5b1e 100644
--- a/integration-test/src/test/java/org/cloudfoundry/operations/ApplicationsTest.java
+++ b/integration-test/src/test/java/org/cloudfoundry/operations/ApplicationsTest.java
@@ -25,6 +25,7 @@
import java.util.Collections;
import java.util.List;
import java.util.Map;
+import java.util.logging.Level;
import org.cloudfoundry.AbstractIntegrationTest;
import org.cloudfoundry.CleanupCloudFoundryAfterClass;
import org.cloudfoundry.CloudFoundryVersion;
@@ -86,6 +87,7 @@
import org.cloudfoundry.operations.services.CreateUserProvidedServiceInstanceRequest;
import org.cloudfoundry.operations.services.GetServiceInstanceRequest;
import org.cloudfoundry.operations.services.ServiceInstance;
+import org.cloudfoundry.operations.util.OperationsLogging;
import org.cloudfoundry.util.FluentMap;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
@@ -93,6 +95,7 @@
import org.springframework.core.io.ClassPathResource;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
+import reactor.core.publisher.SignalType;
import reactor.test.StepVerifier;
@CleanupCloudFoundryAfterClass
@@ -511,6 +514,7 @@ public void listTasks() throws IOException {
* Doppler was dropped in PCF 4.x in favor of logcache. This test does not work
* on TAS 4.x.
*/
+ @Deprecated
@Test
@IfCloudFoundryVersion(lessThan = CloudFoundryVersion.PCF_4_v2)
public void logs() throws IOException {
@@ -537,6 +541,33 @@ public void logs() throws IOException {
.verify(Duration.ofMinutes(5));
}
+ @Test
+ @IfCloudFoundryVersion(greaterThanOrEqualTo = CloudFoundryVersion.PCF_4_v2)
+ public void logsRecent() throws IOException {
+ String applicationName = this.nameFactory.getApplicationName();
+ Mono applicationGuid =
+ getAppGuidFromAppName(cloudFoundryOperations, applicationName);
+ createApplication(
+ this.cloudFoundryOperations,
+ new ClassPathResource("test-application.zip").getFile().toPath(),
+ applicationName,
+ false)
+ .then(
+ applicationGuid
+ .map(ApplicationsTest::getReadRequest)
+ .flatMapMany(
+ readRequest ->
+ callLogsRecent(
+ this.cloudFoundryOperations,
+ readRequest)
+ .log(null, Level.ALL, SignalType.ON_NEXT))
+ .map(ApplicationsTest::checkOneLogEntry)
+ .then())
+ .as(StepVerifier::create)
+ .expectComplete()
+ .verify(Duration.ofMinutes(5));
+ }
+
/**
* Exercise the LogCache client. Serves as a reference for using the logcache client,
* and will help with the transition to the new
@@ -2156,4 +2187,27 @@ private static Mono requestSshEnabled(
.applications()
.sshEnabled(ApplicationSshEnabledRequest.builder().name(applicationName).build());
}
+
+ private static ReadRequest getReadRequest(String applicationId) {
+ return ReadRequest.builder().sourceId(applicationId).build();
+ }
+
+ private static Flux callLogsRecent(
+ CloudFoundryOperations cloudFoundryOperations, ReadRequest readRequest) {
+ return cloudFoundryOperations.applications().logsRecent(readRequest);
+ }
+
+ private static Mono getAppGuidFromAppName(
+ CloudFoundryOperations cloudFoundryOperations, String applicationName) {
+ return cloudFoundryOperations
+ .applications()
+ .get(GetApplicationRequest.builder().name(applicationName).build())
+ .map(ApplicationDetail::getId);
+ }
+
+ private static Log checkOneLogEntry(Log log) {
+ OperationsLogging.log("one log entry: " + log.getType() + " " + log.getPayloadAsText());
+ assertThat(log.getType()).isIn(LogType.OUT, LogType.ERR);
+ return log;
+ }
}