Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
This change completely replaces the old README with a new one. This new version describes how to depend on, configure, use, and build the project. [Completes #109609586] [Completes #109609504] [Completes #109609244] [Completes #109607472]
- Loading branch information
Showing
2 changed files
with
194 additions
and
108 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,147 +1,233 @@ | ||
# Cloud Foundry Java Client | ||
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 which 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 a Cloud Foundry instance on its own. | ||
* `cloudfoundry-client-spring` – The default implementation of the `cloudfoundry-client` project. This implementation is based on the Spring Framework [`RestTemplate`][t]. | ||
* `cloudfoundry-operations` – An API and implementation that corresponds to the [Cloud Foundry CLI][c] operations. This project builds on the `cloudfoundry-cli` and therefore has a single implementation. | ||
* `cloudfoundry-maven-plugin` / `cloudfoundry-gradle-plugin` – Build plugins for [Maven][m] and [Gradle][g]. These projects build on `cloudfoundry-operations` and therefore have single implementations. | ||
|
||
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: | ||
|
||
```xml | ||
<dependencies> | ||
<dependency> | ||
<groupId>org.cloudfoundry</groupId> | ||
<artifactId>cloudfoundry-client-spring</artifactId> | ||
<version>${cf-java-client.version}</version> | ||
</dependency> | ||
<dependency> | ||
<groupId>org.cloudfoundry</groupId> | ||
<artifactId>cloudfoundry-operations</artifactId> | ||
<version>${cf-java-client.version}</version> | ||
</dependency> | ||
... | ||
</dependencies> | ||
``` | ||
|
||
The artifacts can be found in the Spring release and snapshot repositories: | ||
|
||
```xml | ||
<repositories> | ||
<repository> | ||
<id>spring-releases</id> | ||
<name>Spring Releases</name> | ||
<url>http://repo.spring.io/release</url> | ||
</repository> | ||
... | ||
</repositories> | ||
``` | ||
|
||
```xml | ||
<repositories> | ||
<repository> | ||
<id>spring-snapshots</id> | ||
<name>Spring Snapshots</name> | ||
<url>http://repo.spring.io/snapshot</url> | ||
<snapshots> | ||
<enabled>true</enabled> | ||
</snapshots> | ||
</repository> | ||
... | ||
</repositories> | ||
``` | ||
|
||
cf-java-client | ||
================ | ||
|
||
The cf-java-client repo contains a Java client library and tools for Cloud Foundry. Three major components are included | ||
in this repo. | ||
|
||
# Components | ||
|
||
## cloudfoundry-client-lib | ||
|
||
The cloudfoundry-client-lib is a Java library that provides a Java language binding for the Cloud Foundry Cloud Controller REST API. | ||
The library can be used by Java, Groovy, and Scala apps to interact with a Cloud Foundry service on behalf of a user. | ||
|
||
[Read more](http://docs.cloudfoundry.org/buildpacks/java/java-client.html) | ||
|
||
## cloudfoundry-maven-plugin | ||
|
||
The Cloud Foundry Maven plugin is a plugin for the [Maven build tool](http://maven.apache.org/) that allows you to | ||
deploy and manage applications with Maven goals. | ||
|
||
[Read more](./cloudfoundry-maven-plugin) | ||
|
||
## cloudfoundry-gradle-plugin | ||
|
||
The Cloud Foundry Gradle plugin is a plugin for the [Gradle build tool](http://www.gradle.org/) that allows you to | ||
deploy and manage applications with Gradle tasks. | ||
|
||
[Read more](./cloudfoundry-gradle-plugin) | ||
|
||
# Building | ||
|
||
## Prerequisites | ||
|
||
### Apache Maven | ||
|
||
The `cloudfoundry-client-lib` and `cloudfoundry-maven-plugin` components are built with [Apache Maven](http://maven.apache.org/). | ||
|
||
### Gradle | ||
For Gradle, the dependencies would be defined like this: | ||
|
||
The `cloudfoundry-gradle-plugin` component is built with [Gradle](http://www.gradle.org/). | ||
```groovy | ||
dependencies { | ||
compile "org.cloudfoundry:cloudfoundry-client-spring:$cfJavaClientVersion" | ||
compile "org.cloudfoundry:cloudfoundry-operations:$cfJavaClientVersion" | ||
... | ||
} | ||
``` | ||
|
||
### Protocol Buffer compiler | ||
The artifacts can be found in the Spring release and snapshot repositories: | ||
|
||
The `cloudfoundry-client-lib` uses Protocol Buffers to get logs from the Cloud Foundry [loggregator](https://github.com/cloudfoundry/loggregator) | ||
component. A `protoc` Protocol Buffer compiler is required at build time to compile message specifications. `protoc` version | ||
2.6.1 is required. | ||
```groovy | ||
repositories { | ||
maven { url "http://repo.spring.io/release" } | ||
... | ||
} | ||
``` | ||
|
||
On Linux with `apt`, run the [install-protoc-apt.sh](./bin/install-protoc-apt.sh) script in this repository to compile `protoc` from source. | ||
```groovy | ||
repositories { | ||
maven { url "http://repo.spring.io/snapshot" } | ||
... | ||
} | ||
``` | ||
|
||
On OSX, run the [install-protoc-osx.sh](./bin/install-protoc-osx.sh) script to install `protoc`. Alternatively you can install `protobuf` using [homebrew](http://brew.sh/) if homebrew supports the appropriate version. | ||
## Usage | ||
Both the `cloudfoundry-operations` and `cloudfoundry-client` projects follow a ["Reactive"][r] design pattern and expose their responses with [Reactive Streams][s] `Publisher`s. The choice to expose Reactive Streams `Publisher`s gives the project interoperability with the various reactive framework implementations such as [Project Reactor][p] and [RxJava][x]. In the examples that follow, Project Reactor is used, but all reactive frameworks work similarly. | ||
|
||
On Windows, download the `protoc` binary zip file from the [releases page](https://github.com/google/protobuf/releases), | ||
unzip it, and put `protoc.exe` in the path. | ||
### `CloudFoundryClient` and `CloudFoundryOperations` Builders | ||
|
||
After installing, run this command and check the output to make sure it is similar to the following: | ||
The lowest-level building block of the API is a `CloudFoundryClient`. This is only an interface and the default implementation of this is the `SpringCloudFoundryClient`. To instantiate one, you configure it with a builder: | ||
|
||
``` | ||
$ protoc --version | ||
libprotoc 2.6.1 | ||
```java | ||
SpringCloudFoundryClient.builder() | ||
.host("api.run.pivotal.io") | ||
.username("example-username") | ||
.password("example-password") | ||
.build(); | ||
``` | ||
|
||
## Compiling and Packaging | ||
|
||
To build `cloudfoundry-client-lib` and `cloudfoundry-maven-plugin`, run the following command from the project root directory: | ||
|
||
``` | ||
$ mvn clean install | ||
In Spring-based applications, you'll want to encapsulate this in a bean definition: | ||
|
||
```java | ||
@Bean | ||
CloudFoundryClient cloudFoundryClient(@Value("${cf.host}") String host, | ||
@Value("${cf.username}") String username, | ||
@Value("${cf.password}") String password) { | ||
return SpringCloudFoundryClient.builder() | ||
.host(host) | ||
.username(username) | ||
.password(password) | ||
.build(); | ||
} | ||
``` | ||
|
||
To build `cloudfoundry-gradle-plugin`, run the following command from the `cloudfoundry-gradle-plugin` sub-directory after | ||
building `cloudfoundry-client-lib`: | ||
The `CloudFoundryClient` provides 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: | ||
|
||
``` | ||
$ gradle clean install | ||
```java | ||
new CloudFoundryOperationsBuilder() | ||
.cloudFoundryClient(cloudFoundryClient) | ||
.target("example-organization", "example-space") | ||
.build(); | ||
``` | ||
|
||
## Running Integration Tests | ||
|
||
`cloudfoundry-client-lib` has an extensive set of integration tests which run against a Cloud Foundry service. To execute the | ||
integration tests, run the following command from the project root directory: | ||
|
||
``` | ||
$ mvn -P integration-test clean install -Dccng.target=<endpoint> -Dccng.email=<username> -Dccng.passwd=<password> -Dccng.org=<organization> -Dccng.space=<space> | ||
In Spring-based applications, you'll want to encapsulate this in a bean definition as well: | ||
|
||
```java | ||
@Bean | ||
CloudFoundryOperations cloudFoundryOperations(CloudFoundryClient cloudFoundryClient, | ||
@Value("${cf.organization}") String organization, | ||
@Value("${cf.space}") String space) { | ||
return new CloudFoundryOperationsBuilder() | ||
.cloudFoundryClient(cloudFoundryClient) | ||
.target(organization, space) | ||
.build(); | ||
} | ||
``` | ||
|
||
Following is a complete list of the `-D` parameters that can be passed to the integration test: | ||
### `CloudFoundryOperations` APIs | ||
|
||
| Parameter | Description | Required/Optional | | ||
| --------- | ----------- | ----------------- | | ||
| ccng.target | target Cloud Foundry endpoint (e.g. https://api.run.pivotal.io) | required | | ||
| ccng.email | Cloud Foundry username | required | | ||
| ccng.passwd | Cloud Foundry password | required | | ||
| ccng.org | Cloud Foundry organization to run tests against | required | | ||
| ccng.space | Cloud Foundry space to run tests against | required | | ||
| ccng.ssl | trust self-signed certificates from target endpoint | optional, default is `false` | | ||
| vcap.mysql.label | label of a MySQL service that can be created | optional, default is `cleardb` | | ||
| vcap.mysql.plan | plan of a MySQL service that can be created | optional, default is `spark` | | ||
| http.proxyHost | host name of an HTTP proxy | optional | | ||
| http.proxyPort | port of an HTTP proxy | optional | | ||
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: | ||
|
||
**Important** | ||
1. Requests a list of all organizations | ||
1. Extracts the name of each organization | ||
1. Prints the name of the each organization to `System.out` | ||
|
||
Integration tests should be run against an empty Cloud Foundry space. The integration tests are destructive, | ||
and will delete any apps, services, routes, and domains existing in the target space. | ||
```java | ||
Streams | ||
.wrap(this.cloudFoundryOperations.organizations().list()) | ||
.map(Organization::getName) | ||
.consume(System.out::println); | ||
``` | ||
|
||
# Cloud Foundry Resources | ||
To relate the example to the description above the following happens: | ||
|
||
_Cloud Foundry Open Source Platform as a Service_ | ||
1. `Streams.wrap(...)` – Wraps the Reactive Streams `Publisher` (an interoperability type) in the Reactor-native `Stream` type | ||
1. `.map(...)` – Maps an input type to an output type. This example uses a method a reference and the equivalent lambda would look like `organization -> organization.getName()`. | ||
1. `consume...` – The terminal operation that consumes each item in the stream. Again, this example uses a method reference and the the equivalent lambda would look like `name -> System.out.println(name)`. | ||
|
||
## Learn | ||
### `CloudFoundryClient` APIs | ||
|
||
Our documentation, currently a work in progress, is available here: [http://docs.cloudfoundry.org/buildpacks/java/java-client.html](http://docs.cloudfoundry.org/buildpacks/java/java-client.html) | ||
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): | ||
|
||
## Ask Questions | ||
```java | ||
ListOrganizationsRequest request = ListOrganizationsRequest.builder() | ||
.page(1) | ||
.build(); | ||
|
||
Questions about the Cloud Foundry Open Source Project can be directed to our Mailing Lists. | ||
Streams | ||
.wrap(cloudFoundryClient.organizations().list(request)) | ||
.flatMap(response -> Streams.from(response.getResources)) | ||
.map(resource -> { | ||
return Organization.builder() | ||
.id(resource.getMetadata().getId()) | ||
.name(resource.getEntity().getName()) | ||
.build(); | ||
}); | ||
``` | ||
|
||
* Cloud Foundry Developers: | ||
[cf-dev](https://lists.cloudfoundry.org/pipermail/cf-dev) | ||
* BOSH: | ||
[cf-bosh](https://lists.cloudfoundry.org/pipermail/cf-bosh) | ||
The above example is more complicated: | ||
|
||
## File a bug | ||
1. `Streams.wrap(...)` – Wraps the Reactive Streams `Publisher` in the Reactor-native `Stream` type | ||
1. `.flatMap(...)` – substitutes the original stream with a stream of the `Resource`s returned by the requested page | ||
1. `.map(...)` – Maps the `Resource` to an `Organization` type | ||
|
||
Bugs can be filed using Github Issues within the various repositories of the [Cloud Foundry](http://github.com/cloudfoundry) components, including for [this project](https://github.com/cloudfoundry/cf-java-client/issues) | ||
### Maven Plugin | ||
|
||
## OSS Contributions | ||
TODO: Document once implemented | ||
|
||
The Cloud Foundry team uses GitHub and accepts contributions via [pull request](https://help.github.com/articles/using-pull-requests) | ||
### Gradle Plugin | ||
|
||
Follow these steps to make a contribution to any of our open source repositories: | ||
TODO: Document once implemented | ||
|
||
1. Complete our CLA Agreement for [individuals](https://www.cloudfoundry.org/pdfs/CFF_Individual_CLA.pdf) or [corporations](https://www.cloudfoundry.org/pdfs/CFF_Corporate_CLA.pdf) | ||
2. Set your name and email | ||
## Development | ||
The project depends on Java 8 but is built to be Java 7 compatible. To build from source and install to your local Maven cache, run the following: | ||
|
||
``` | ||
$ git config --global user.name "Firstname Lastname" | ||
$ git config --global user.email "your_email@youremail.com" | ||
```shell | ||
$ ./mvnw clean install | ||
``` | ||
|
||
3. Fork the repo | ||
4. Make your changes on a topic branch, commit, and push to github and open a pull request. | ||
To run the the integration tests, run the following: | ||
|
||
```shell | ||
$ ./mvnw -Pintegration-test clean test | ||
``` | ||
|
||
Once your commits are approved by Concourse CI and reviewed by the core team, they will be merged. | ||
**IMPORTANT** | ||
Integration tests should be run against an empty Cloud Foundry instance. The integration tests are destructive, nearly everything on an instance given the chance. | ||
|
||
The integration tests require a running instance of Cloud Foundry to test against. We recommend using [MicroPCF][i] to start a local instance to test with. To configure the integration tests with the appropriate connection information use the following environment variables: | ||
|
||
Name | Description | ||
---- | ----------- | ||
`TEST_HOST` | The host of Cloud Foundry instance. Typically something like `api.local.micropcf.io`. | ||
`TEST_ORGANIZATION` | The default organization to use for testing | ||
`TEST_PASSWORD` | The test user's password | ||
`TEST_SKIPSSLVALIDATION` | Whether to skip SSL validation when connecting to the Cloud Foundry instance. Typically `true` when connecting to a MicroPCF instance. | ||
`TEST_SPACE` | The default space to use for testing | ||
`TEST_USERNAME` | The test user's username | ||
|
||
## Contributing | ||
[Pull requests][u] and [Issues][e] are welcome. | ||
|
||
## License | ||
This project is released under version 2.0 of the [Apache License][l]. | ||
|
||
[a]: https://apidocs.cloudfoundry.org/226/ | ||
[c]: https://github.com/cloudfoundry/cli | ||
[e]: https://github.com/cloudfoundry/cf-java-client/issues | ||
[g]: https://gradle.org | ||
[i]: https://github.com/pivotal-cf/micropcf | ||
[l]: https://www.apache.org/licenses/LICENSE-2.0 | ||
[m]: https://maven.apache.org | ||
[p]: https://projectreactor.io | ||
[r]: http://reactivex.io | ||
[s]: https://www.reactive-streams.org | ||
[t]: https://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/web/client/RestTemplate.html | ||
[u]: https://help.github.com/articles/using-pull-requests | ||
[x]: https://github.com/ReactiveX/RxJava |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters