MCPcopy Index your code
hub / github.com/cloudfoundry/cf-java-client

github.com/cloudfoundry/cf-java-client @v5.17.0.RELEASE

Chat with this repo
repository ↗ · DeepWiki ↗ · release v5.17.0.RELEASE ↗ · + Follow
13,898 symbols 84,782 edges 2,727 files 6,037 documented · 43% updated 9d agov5.17.0.RELEASE · 2026-05-19★ 33384 open issues
What it actually does AI analysis from the code graph — generated when you open this
loading…
README

Cloud Foundry Java Client

Maven Central

Artifact Javadocs
cloudfoundry-client javadoc
cloudfoundry-client-reactor javadoc
cloudfoundry-operations javadoc
cloudfoundry-util javadoc

The cf-java-client project is a Java language binding for interacting with a Cloud Foundry instance. The project is broken up into a number of components that expose different levels of abstraction depending on need.

  • cloudfoundry-client – Interfaces, request, and response objects mapping to the [Cloud Foundry REST APIs][a]. This project has no implementation and therefore cannot connect to a Cloud Foundry instance on its own.
  • cloudfoundry-client-reactor – The default implementation of the cloudfoundry-client project. This implementation is based on Reactor Netty [HttpClient][h].
  • cloudfoundry-operations – An API and implementation that corresponds to the [Cloud Foundry CLI][c] operations. This project builds on the cloudfoundry-client and therefore has a single implementation.

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 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() (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()); ```

The return type and envelope objects differ between the two APIs:

Doppler (org.cloudfoundry.doppler) Log Cache (org.cloudfoundry.logcache.v1)
Return type Flux<Envelope> Mono<ReadResponse> → unpack via response.getEnvelopes().getBatch()
Log access envelope.getLogMessage()LogMessage envelope.getLog()Log
Message text logMessage.getMessage() log.getPayloadAsText()
Message type MessageType.OUT / ERR LogType.OUT / ERR
Source metadata logMessage.getSourceType(), .getSourceInstance() envelope.getTags().get("source_type"), envelope.getInstanceId()

See the org.cloudfoundry.doppler and org.cloudfoundry.logcache.v1 Javadoc for full type details.

[!NOTE] Operations API users: Applications.logs(ApplicationLogsRequest) now uses Log Cache under the hood for recent logs (the default). No migration is needed at the Operations layer.

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:

<dependencies>
    <dependency>
        <groupId>org.cloudfoundry</groupId>
        <artifactId>cloudfoundry-client-reactor</artifactId>
        <version>latest.RELEASE</version>
    </dependency>
    <dependency>
        <groupId>org.cloudfoundry</groupId>
        <artifactId>cloudfoundry-operations</artifactId>
        <version>latest.RELEASE</version>
    </dependency>
    ...
</dependencies>

Snapshot artifacts can be found in the Spring snapshot repository:

<repositories>
    <repository>
        <id>spring-snapshots</id>
        <name>Spring Snapshots</name>
        <url>https://repo.spring.io/snapshot</url>
        <snapshots>
            <enabled>true</enabled>
        </snapshots>
    </repository>
    ...
</repositories>

For Gradle, the dependencies would be defined like this:

dependencies {
    compile 'org.cloudfoundry:cloudfoundry-client-reactor:<latest>.RELEASE'
    compile 'org.cloudfoundry:cloudfoundry-operations:<latest>.RELEASE'
    ...
}

Snapshot artifacts can be found in the Spring snapshot repository:

repositories {
    maven { url 'https://repo.spring.io/snapshot' }
    ...
}

Usage

Both the cloudfoundry-operations and cloudfoundry-client projects follow a ["Reactive"][r] design pattern and expose their responses with [Project Reactor][p] Monoss and Fluxs.

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 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:

DefaultConnectionContext.builder()
    .apiHost(apiHost)
    .build();

PasswordGrantTokenProvider.builder()
    .password(password)
    .username(username)
    .build();

In Spring-based applications, you'll want to encapsulate them in bean definitions:

@Bean
DefaultConnectionContext connectionContext(@Value("${cf.apiHost}") String apiHost) {
    return DefaultConnectionContext.builder()
        .apiHost(apiHost)
        .build();
}

@Bean
PasswordGrantTokenProvider tokenProvider(@Value("${cf.username}") String username,
                                         @Value("${cf.password}") String password) {
    return PasswordGrantTokenProvider.builder()
        .password(password)
        .username(username)
        .build();
}

CloudFoundryClient, DopplerClient, and UaaClient are only interfaces. Each has a [Reactor][p]-based implementation. To instantiate them, you configure them with builders:

ReactorCloudFoundryClient.builder()
    .connectionContext(connectionContext)
    .tokenProvider(tokenProvider)
    .build();

ReactorDopplerClient.builder()
    .connectionContext(connectionContext)
    .tokenProvider(tokenProvider)
    .build();

ReactorUaaClient.builder()
    .connectionContext(connectionContext)
    .tokenProvider(tokenProvider)
    .build();

In Spring-based applications, you'll want to encapsulate them in bean definitions:

@Bean
ReactorCloudFoundryClient cloudFoundryClient(ConnectionContext connectionContext, TokenProvider tokenProvider) {
    return ReactorCloudFoundryClient.builder()
        .connectionContext(connectionContext)
        .tokenProvider(tokenProvider)
        .build();
}

@Bean
ReactorDopplerClient dopplerClient(ConnectionContext connectionContext, TokenProvider tokenProvider) {
    return ReactorDopplerClient.builder()
        .connectionContext(connectionContext)
        .tokenProvider(tokenProvider)
        .build();
}

@Bean
ReactorUaaClient uaaClient(ConnectionContext connectionContext, TokenProvider tokenProvider) {
    return ReactorUaaClient.builder()
        .connectionContext(connectionContext)
        .tokenProvider(tokenProvider)
        .build();
}

CloudFoundryOperations Builder

The CloudFoundryClient, DopplerClient, and UaaClients provide direct access to the raw REST APIs. This level of abstraction provides the most detailed and powerful access to the Cloud Foundry instance, but also requires users to perform quite a lot of orchestration on their own. Most users will instead want to work at the CloudFoundryOperations layer. Once again this is only an interface and the default implementation of this is the DefaultCloudFoundryOperations. To instantiate one, you configure it with a builder:

NOTE: The DefaultCloudfoundryOperations type does not require all clients in order to run. Since not all operations touch all kinds of clients, you can selectively configure the minimum needed. If a client is missing, the first invocation of a method that requires that client will return an error.

DefaultCloudFoundryOperations.builder()
    .cloudFoundryClient(cloudFoundryClient)
    .dopplerClient(dopplerClient)
    .uaaClient(uaaClient)
    .organization("example-organization")
    .space("example-space")
    .build();

In Spring-based applications, you'll want to encapsulate this in a bean definition as well:

@Bean
DefaultCloudFoundryOperations cloudFoundryOperations(CloudFoundryClient cloudFoundryClient,
                                                     DopplerClient dopplerClient,
                                                     UaaClient uaaClient,
                                                     @Value("${cf.organization}") String organization,
                                                     @Value("${cf.space}") String space) {
    return DefaultCloudFoundryOperations.builder()
            .cloudFoundryClient(cloudFoundryClient)
            .dopplerClient(dopplerClient)
            .uaaClient(uaaClient)
            .organization(organization)
            .space(space)
            .build();
}

CloudFoundryOperations APIs

Once you've got a reference to the CloudFoundryOperations, it's time to start making calls to the Cloud Foundry instance. One of the simplest possible operations is list all of the organizations the user is a member of. The following example does three things:

  1. Requests a list of all organizations
  2. Extracts the name of each organization
  3. Prints the name of each organization to System.out
cloudFoundryOperations.organizations()
    .list()
    .map(OrganizationSummary::getName)
    .subscribe(System.out::println);

To relate the example to the description above the following happens:

  1. .list() – Lists the Cloud Foundry organizations as a Flux of elements of type Organization.
  2. .map(...) – Maps each organization to its name (type String). This example uses a method reference; the equivalent lambda would look like organizationSummary -> organizationSummary.getName().
  3. subscribe... – The terminal operation that receives each name in the Flux. Again, this example uses a method reference and the equivalent lambda would look like name -> System.out.println(name).

CloudFoundryClient APIs

As mentioned earlier, the cloudfoundry-operations implementation builds upon the cloudfoundry-client API. That implementation takes advantage of the same reactive style in the lower-level API. The implementation of the Organizations.list() method (which was demonstrated above) looks like the following (roughly):

cloudFoundryClient.organizations()
    .list(ListOrganizationsRequest.builder()
        .page(1)
        .build())
    .flatMapIterable(ListOrganizationsResponse::getResources)
    .map(resource -> OrganizationSummary.builder()
        .id(resource.getMetadata().getId())
        .name(resource.getEntity().getName())
        .build());

The above example is more complicated:

  1. .list(...) – Retrieves the first page of Cloud Foundry organizations.
  2. .flatMapIterable(...) – Substitutes the original Mono with a Flux of the Resources returned by the requested page.
  3. .map(...) – Maps the Resource to an OrganizationSummary type.

Troubleshooting

If you are having issues with the cf-java-client in your applications...

First, read this article on debugging reactive applications and watch this Spring Tips Video also on debugging reactive apps.

Beyond that, it is helpful to capture the following information:

  1. The version of cf-java-client you are using
  2. If you are using Spring Boot & if so, the version
  3. A description of the problem behavior.
  4. A list of things, if any, you have recently changed in your project (even if seemingly unrelated)
  5. If you are getting failures with an operation or client request, capture the request and response information.
    • You may capture basic request and response information by setting the log l

Extension points exported contracts — how you extend this code

Core symbols most depended-on inside this repo

Shape

Method 11,111
Class 2,586
Interface 139
Enum 62

Languages

Java100%

Modules by API surface

cloudfoundry-operations/src/test/java/org/cloudfoundry/operations/applications/DefaultApplicationsTest.java205 symbols
cloudfoundry-operations/src/main/java/org/cloudfoundry/operations/applications/DefaultApplications.java185 symbols
cloudfoundry-operations/src/test/java/org/cloudfoundry/operations/services/DefaultServicesTest.java106 symbols
integration-test/src/test/java/org/cloudfoundry/client/v2/OrganizationsTest.java105 symbols
integration-test/src/test/java/org/cloudfoundry/client/v2/SpacesTest.java104 symbols
integration-test/src/test/java/org/cloudfoundry/client/v2/UsersTest.java89 symbols
cloudfoundry-operations/src/main/java/org/cloudfoundry/operations/services/DefaultServices.java86 symbols
integration-test/src/test/java/org/cloudfoundry/operations/ApplicationsTest.java79 symbols
cloudfoundry-operations/src/test/java/org/cloudfoundry/operations/useradmin/DefaultUserAdminTest.java69 symbols
cloudfoundry-client-reactor/src/main/java/org/cloudfoundry/reactor/client/_ReactorCloudFoundryClient.java66 symbols
integration-test/src/test/java/org/cloudfoundry/client/v2/ApplicationsTest.java65 symbols
integration-test/src/test/java/org/cloudfoundry/NameFactory.java61 symbols

For agents

$ claude mcp add cf-java-client \
  -- python -m otcore.mcp_server <graph>

⬇ download graph artifact

Ask about this repo answers extend the page