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. 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.
cloudfoundry-operations – An API and implementation that corresponds to the Cloud Foundry CLI 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.
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:
Both the cloudfoundry-operations and cloudfoundry-client projects follow a "Reactive" design pattern and expose their responses with Project ReactorMonoss and Fluxs.
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:
CloudFoundryClient, DopplerClient, and UaaClient are only interfaces. Each has a Reactor-based implementation. To instantiate them, you configure them with builders:
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.
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:
Requests a list of all organizations
Extracts the name of each organization
Prints the name of each organization to System.out
To relate the example to the description above the following happens:
.list() – Lists the Cloud Foundry organizations as a Flux of elements of type Organization.
.map(...) – Maps each organization to its name (type String). This example uses a method reference; the equivalent lambda would look like organizationSummary -> organizationSummary.getName().
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):
Beyond that, it is helpful to capture the following information:
The version of cf-java-client you are using
If you are using Spring Boot & if so, the version
A description of the problem behavior.
A list of things, if any, you have recently changed in your project (even if seemingly unrelated)
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 level for cloudfoundry-client to DEBUG. For example with Spring Boot, set logging.level.cloudfoundry-client=debug.
You may perform a wire capture by setting the log level for cloudfoundry-client.wire to TRACE. For example with Spring Boot, set logging.level.cloudfoundry-client.wire=trace.
If you open a Github issue with a request for help, please include as much of the information above as possible and do not forget to sanitize any request/response data posted.
Development
The project depends on Java 8. To build from source and install to your local Maven cache, run the following:
It also depends on Immutables and won't compile in IDEs like Eclipse or IntelliJ unless you also have an enabled annotation processor. See this guide for instructions on how to configure your IDE.
To run the integration tests, run the following:
$ ./mvnw -Pintegration-test clean test
To run a specific integration test, run the following replacing with -Dtest=org.cloudfoundry.TestClass#test-method (#test-method is optional):
./mvnw -Pintegration-test clean test -Dtest=org.cloudfoundry.client.v3.ServiceBrokersTest#update
To run tests & enable HTTP trace output, execute:
CLIENT_LOGGING_LEVEL=trace ./mvnw -Pintegration-test clean test
IMPORTANT
Integration tests require admin access and should be run against an empty Cloud Foundry instance. The integration tests are destructive, affecting nearly everything on an instance given the chance.
The integration tests require a running instance of Cloud Foundry to test against. To configure the integration tests with the appropriate connection information use the following environment variables:
Name
Description
TEST_ADMIN_CLIENTID
Client ID for a client with permissions for a Client Credentials grant
TEST_ADMIN_CLIENTSECRET
Client secret for a client with permissions for a Client Credentials grant
TEST_ADMIN_PASSWORD
Password for a user with admin permissions
TEST_ADMIN_USERNAME
Username for a user with admin permissions
TEST_APIHOST
The host of a Cloud Foundry instance. Typically something like api.local.pcfdev.io.
TEST_PROXY_HOST
(Optional) The host of a proxy to route all requests through
TEST_PROXY_PASSWORD
(Optional) The password for a proxy to route all requests through
TEST_PROXY_PORT
(Optional) The port of a proxy to route all requests through. Defaults to 8080.
TEST_PROXY_USERNAME
(Optional) The username for a proxy to route all requests through
TEST_SKIPSSLVALIDATION
(Optional) Whether to skip SSL validation when connecting to the Cloud Foundry instance. Defaults to false.
If you do not have access to a CloudFoundry instance with admin access, you can run one locally using bosh-deployment & cf-deployment and Virtualbox.
Lastly before running the tests, it is strongly recommended that you take a snapshot of the VMs in the environment. This allows for the quick rollback of the environment should the tests break something (they don't generally, integration tests should clean up after themselves).
请发表评论