Rule 17: omit needless words

Rule 17: omit needless words

:github-tag: master
:github-repo: spring-cloud/spring-cloud-connectors
:github-raw: http://raw.github.com/{github-repo}/{github-tag}
:github-code: http://github.com/{github-repo}/tree/{github-tag}
:toc: left
:toclevels: 3

= Spring Cloud Connectors

[[spring-cloud-connectors-install]]

== Introduction

Spring Cloud Connectors provides a simple abstraction for JVM-based applications running on cloud platforms to discover bound services and deployment information at runtime, and provides support for registering discovered services as Spring beans. It is based on a plugin model so that the identical compiled application can be deployed locally or on any of multiple cloud platforms, and it supports custom service definitions through Java Service Provider Interfaces (SPI).

The Connectors project provides out-of-the-box support for discovering common services on Heroku and Cloud Foundry clouds. It also includes a properties-based connector that can supply configuration for development and testing.

=== Concepts

The core Connectors concepts are described below.

[cols="3,7", width="100%"]
|===========================================================================================================================================================================
|**Cloud Connector** |A platform-specific interface that identifies the presence of the platform and discovers any services bound to the application deployment.
|**Service Connector** |An object that represents a runtime connection to a service (for example, a `javax.sql.DataSource`).
|**Service Information** |Information about the underlying service (such as host, port, and credentials).
|**Application Information** |Information about the application and the particular running instance.
|===========================================================================================================================================================================

=== Submodules

The project contains three major submodules.

* **Spring Cloud Connectors Core**: The core library, which is both cloud-agnostic and Spring-agnostic. It provides a programmatic entry point for developers who prefer to access cloud services and application information manually. It also provides basic service definitions for several common services (databases, message queues) and an SPI-based extension mechanism for contributing cloud and service connectors.
* **Spring Cloud Spring Service Connector**: A Spring library that exposes application information, cloud information, and discovered services as Spring beans of the appropriate type (for example, an SQL service will be exposed as a `javax.sql.DataSource` with optional connection pooling).
* The cloud connectors:
 ** **Spring Cloud Cloud Foundry Connector**: Connector for link:http://cloudfoundry.org/[Cloud Foundry].
 ** **Spring Cloud Heroku Connector**: Connector for link:https://www.heroku.com/[Heroku].
 ** **Spring Cloud local-configuration Connector**: Properties-based connector for manually providing configuration information during development or testing. Allows use of the same Spring Cloud configuration wiring in all stages of application deployment.

== Getting Started

See below for examples of how to include the appropriate dependencies using your build system.

=== Including Cloud Connectors

Include the connector for each cloud platform which you want to be discoverable. Including multiple connectors is perfectly fine; each connector will determine whether it should be active in a particular environment.

In Maven, replacing `${VERSION}` with the desired artifact version:

[source,xml]
----
<!-- To use Spring Cloud Connectors for development -->
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-localconfig-connector</artifactId>
    <version>${VERSION}</version>
</dependency>

<!-- If you intend to deploy the app to Cloud Foundry -->
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-cloudfoundry-connector</artifactId>
    <version>${VERSION}</version>
</dependency>

<!-- If you intend to deploy the app to Heroku -->
<dependency>
  <groupId>org.springframework.cloud</groupId>
  <artifactId>spring-cloud-heroku-connector</artifactId>
  <version>${VERSION}</version>
</dependency>
----

In Gradle, replacing `${VERSION}` with the desired version:

[source,groovy]
----
dependencies {

    // To use Spring Cloud Connectors for development
    compile 'org.springframework.cloud:spring-cloud-localconfig-connector:${VERSION}'

    // If you intend to deploy the app to Cloud Foundry
    compile 'org.springframework.cloud:spring-cloud-cloudfoundry-connector:${VERSION}'

    // If you intend to deploy the app to Heroku
    compile 'org.springframework.cloud:spring-cloud-heroku-connector:${VERSION}'

}
----

=== Spring Applications

If you're writing a Spring application, include the <<Spring Service Connector>> dependency in addition to your cloud connector dependencies.

In Maven:

[source,xml]
----
<dependency>
  <groupId>org.springframework.cloud</groupId>
  <artifactId>spring-cloud-spring-service-connector</artifactId>
  <version>${VERSION}</version>
</dependency>
----

In Gradle:

[source,groovy]
----
dependencies {

    compile 'org.springframework.cloud:spring-cloud-spring-service-connector:${VERSION}'

}
----

Then follow the instructions in the <<Spring Service Connector>> documentation on Spring configuration <<spring-cloud-spring-service-connector.adoc#_the_java_configuration,using Java configuration>> or the <<spring-cloud-spring-service-connector.adoc#_the_code_cloud_code_namespace,`<cloud>` namespace>>.

=== Non-Spring Applications

The `spring-cloud-core` dependency is included by each cloud connector, so simply include the connectors for the platforms you want. Then follow the <<_spring_cloud_connectors_core,instructions on using the Spring Cloud Connectors API>>.

== Spring Cloud Connectors Core

This core library provides programmatic access to application and service information. This library has no Spring dependencies and may be used in non-Spring applications.

**This library requires Java 6 or newer.** It is cloud-agnostic; using the Java SPI, it supports pluggable cloud and service connectors. Support for Cloud Foundry and Heroku is available out-of-the-box, in addition to locally-provided configuration for development and testing.

=== Connecting to a Cloud

[NOTE]
====
If you are using Spring Cloud in a Spring application, you should consider <<_spring_service_connector,automatically injecting Spring beans>> instead.
====

* Include the desired cloud connectors on the runtime classpath, <<_getting_started,as described in the main documentation>>.

* Create a `CloudFactory` instance. Creation of a `CloudFactory` instance is a bit expensive, so we recommend using a singleton instance.  If you are using a dependency injection framework such as Spring, create a bean for the `CloudFactory`.
+
[source,java]
----
CloudFactory cloudFactory = new CloudFactory();
----

* Obtain the `Cloud` object for the environment in which the application is running.
+
[source,java]
----
Cloud cloud = cloudFactory.getCloud();
----
+
Note that you must have a `CloudConnector` suitable for your deployment environment on your classpath.  For example, if you are deploying the application to Cloud Foundry, you must add the <<_cloud_foundry_connector,Cloud Foundry Connector>> to your classpath. If no suitable `CloudConnector` is found, the `getCloud()` method will throw a `CloudException`.

* Use the `Cloud` instance to access application and service information and to create service connectors.
+
[source,java]
----
// ServiceInfo has all the information necessary to connect to the underlying service
List<ServiceInfo> serviceInfos = cloud.getServiceInfos();
----
+
[source,java]
----
// Find the `ServiceInfo` definitions suitable for connecting to a particular service type
List<ServiceInfo> databaseInfos = cloud.getServiceInfos(DataSource.class);
----
+
[source,java]
----
// Alternatively, let Spring Cloud create a service connector for you
String serviceId = "inventory-db";
DataSource ds = cloud.getServiceConnector(serviceId, DataSource.class,
                                            null /* default config */);
----

== Spring Service Connector

See <<spring-cloud-spring-service-connector.adoc#,Spring Cloud Spring Service Connector>>.

== Cloud Foundry Connector

See <<spring-cloud-cloud-foundry-connector.adoc#,Spring Cloud Cloud Foundry Connector>>.

== Heroku Connector

See <<spring-cloud-heroku-connector.adoc#,Spring Cloud Heroku Connector>>.

== local-configuration Connector

This connector provides the ability to configure Spring Cloud services locally for development or testing. **The current implementation reads from Java properties only.**

=== Quick Start

Since service URIs contain passwords and should not be stored in code, this connector does not attempt to read service definitions out of the classpath. You can provide service definitions as system properties.

[source,term]
----
java -Dspring.cloud.database='mysql://user:pass@host:1234/dbname' -jar my-app.jar
----

You can also provide service definitions from a configuration properties file, either by setting the `spring.cloud.propertiesFile` system property:

[source,term]
----
java -Dspring.cloud.propertiesFile=/path/to/spring-cloud.properties -jar my-app.jar
----

or by providing the bootstrap properties file `spring-cloud-bootstrap.properties` on the runtime classpath. This file will be inspected only for the property named `spring.cloud.propertiesFile`, and its value will be interpolated from the system properties.

[source,properties]
----
spring.cloud.propertiesFile: ${user.home}/.config/myApp/spring-cloud.properties
----

The system properties, or the configuration properties file, should contain an application ID and the desired services in the following format.

[source,properties]
----
spring.cloud.appId:    myApp
; spring.cloud.{id}:   URI
spring.cloud.database: mysql://user:pass@host:1234/dbname
----

The service type is determined by the URI scheme. The connector will activate if it finds a property (either in the system properties or in the configuration properties file) named `spring.cloud.appId`.

=== Property Sources

This connector first attempts to read the system properties generally and a system property named `spring.cloud.propertiesFile` specifically. If the system properties are not readable (if the security manager denies `checkPropertiesAccess`), then they will be treated as empty.  If a system property named `spring.cloud.propertiesFile` is found, then that file will be loaded as a property list.

==== Providing a Bootstrap Properties File

To avoid having to manually configure run configurations or test runners with the path to the configuration properties file, the connector can read a templated filename out of the runtime classpath. This file must be named `spring-cloud-bootstrap.properties` and be located at the classpath root. For security, the connector will not attempt to read any service URIs out of the file. If the connector does find the file, it will read the property `spring.cloud.propertiesFile` and link:http://commons.apache.org/proper/commons-lang/javadocs/api-release/index.html?org/apache/commons/lang3/text/StrSubstitutor.html[substitute the pattern `${system.property}`] with the appropriate value from the system properties. The most useful option is generally `${user.home}`.

A configuration properties file specified in the system properties will override any bootstrap file that may be available on the classpath.

==== Property Precedence

To provide the maximum configuration flexibility, the connector will override any properties (both application ID and service definitions) specified in the file at `spring.cloud.propertiesFile` with system properties defined at runtime. The connector will log a message at `WARN` if you override a service ID.

=== Activating the Connector

Spring Cloud Core expects exactly one cloud connector to match the runtime environment.  This connector identifies the “local cloud” by the presence of a property, in a configuration properties file or in the system properties, named `spring.cloud.appId`. This property will be used in the `ApplicationInstanceInfo`.

=== Service Definitions

If the connector is activated, it will iterate through all of the available properties for keys matching the pattern `spring.cloud.{serviceId}`. Each value is interpreted as a URI to a service, and the type of service is determined from the scheme. Every standard `UriBasedServiceInfo` is supported.

=== Instance ID

This connector creates a UUID for use as the instance ID, as Java does not provide any portable mechanism for reliably determining hostnames or PIDs.

== Extending Spring Cloud Connectors

Besides the built-in service and cloud support and the included Spring Service Connector, Spring Cloud Connectors can be extended to support additional cloud platforms, cloud services, or application frameworks. See below for details.

=== Adding Cloud Connectors

To allow Spring Cloud to detect a new cloud platform, add a cloud connector for the platform. A cloud connector determines whether the application is running in the specific cloud, identifies application information (such as the name and instance ID of the particular running instance), and maps bound services (such as URIs exposed in environment variables) as `ServiceInfo` objects.

[TIP]
====
See the https://github.com/spring-cloud/spring-cloud-connectors/tree/master/spring-cloud-cloudfoundry-connector[Cloud Foundry Connector] and https://github.com/spring-cloud/spring-cloud-connectors/tree/master/spring-cloud-heroku-connector[Heroku Connector] for examples.
====

Spring Cloud uses the https://docs.oracle.com/javase/tutorial/sound/SPI-intro.html[Java SPI] to discover available connectors.

Your connector classes must implement the http://docs.spring.io/autorepo/docs/spring-cloud/current/api/index.html?org/springframework/cloud/CloudConnector.html[`CloudConnector`] interface. It includes three methods:

* `boolean isInMatchingCloud()`: Determines whether the connector is operating in the cloud for which it provides support.
+
Spring Cloud Connectors will call `isInMatchingCloud()` on each cloud connector included in an application. The first connector to respond `true` will be activated.
* `ApplicationInstanceInfo getApplicationInstanceInfo()`: Returns information about the running application instance.
+
An `ApplicationInstanceInfo` must provide the instance id (`String`) and application id (`String`). Other properties can be added as needed to a `Map` and be returned via `getProperties()`.
* `List<ServiceInfo> getServiceInfos()`: Returns a `ServiceInfo` object for each service bound to the application.
+
`getServiceInfos()` can return an empty `List` if no services have been bound to the application.

New cloud connectors should list the fully-qualified class name in the provider-configuration file at `META-INF/services/org.springframework.cloud.CloudConnector`.

=== Adding Service Support

To allow Spring Cloud to discover a new type of service, create a `ServiceInfo` class containing the information necessary to connect to the service. If your service can be specified via a URI, extend http://docs.spring.io/autorepo/docs/spring-cloud/current/api/org/springframework/cloud/service/UriBasedServiceInfo.html[`UriBasedServiceInfo`] and provide the URI scheme in a call to the `super` constructor.

The following class will expose information for a `HelloWorldService` available at `helloworld://username:password@host:port/Bonjour`.

[source,java]
----
public class HelloWorldServiceInfo extends UriBasedServiceInfo {
    public static final String URI_SCHEME = "helloworld";

  // Needed to support structured service definitions such as Cloud Foundry's
    public HelloWorldServiceInfo(String id, String host, int port, String username, String password, String greeting) {
    super(id, URI_SCHEME, host, port, username, password, greeting);
    }

    // Needed to support URI-based service definitions such as Heroku's
    public HelloWorldServiceInfo(String id, String uri) {
        super(id, uri);
    }
}
----

After creating the `ServiceInfo` class, you will need to create a `ServiceInfoCreator` for each cloud platform you want to support.  If you are adding service support for a cloud platform already supported by Spring Cloud Connectors, you will probably want to extend the appropriate creator base class(es).

[cols="2,8", width="100%"]
|==================================================================
|**Cloud Foundry** | Extend `CloudFoundryServiceInfoCreator`.
|**Heroku** | Extend `HerokuServiceInfoCreator`.
|**local-configuration** | Extend `LocalConfigServiceInfoCreator`.
|==================================================================

A `ServiceInfoCreator` often can be as simple as a method that instantiates a new `ServiceInfo`.

[source,java]
----
@Override
public HelloWorldServiceInfo createServiceInfo(String id, String uri) {
  return new HelloWorldServiceInfo(id, uri);
}
----

Register your `ServiceInfoCreator` classes in the appropriate provider-configuration file for your cloud's `ServiceInfoCreator` base class.

[cols="2,8", width="100%"]
|=========================================================================================================================================================================
|**Cloud Foundry** | Add the fully-qualified class name for your creator to `META-INF/service/org.springframework.cloud.cloudfoundry.CloudFoundryServiceInfoCreator`.
|**Heroku** | Add the fully-qualified class name for your creator to `META-INF/service/org.springframework.cloud.heroku.HerokuServiceInfoCreator`.
|**local-configuration** | Add the fully-qualified class name for your creator to `META-INF/service/org.springframework.cloud.localconfig.LocalConfigServiceInfoCreator`.
|=========================================================================================================================================================================

=== Adding Service Connectors

To allow Spring Cloud to provide framework-specific service objects for supported cloud services, add a service connector for the framework. A service connector consumes a `ServiceInfo` discovered by the cloud connector and converts it into the appropriate service object (such as a `DataSource` in the case of a service definition that represents a SQL database).

[TIP]
====
Service connectors can be tightly bound to the framework whose service objects they are creating. For example, some connectors in the <<_spring_service_connector,Spring Service Connector>> create connection factories defined by Spring Data, for use in building Spring Data templates.
====

Your connector classes must implement the http://docs.spring.io/autorepo/docs/spring-cloud/current/api/index.html?org/springframework/cloud/service/ServiceConnectorCreator.html[`ServiceConnectorCreator`] interface. It has three methods:

* `SC create()`: Creates a service connection object from a given `ServiceInfo` and configuration.
* `Class<SC> getServiceConnectorType()`: Returns the type of the connection object that will be created.
* `Class<?> getServiceInfoType()`: Returns the type of the `ServiceInfo` that the class will accept.

List the fully-qualified connector class names in the provider-configuration file at `META-INF/services/org.springframework.cloud.service.ServiceConnectorCreator`.

:github-tag: master
:github-repo: spring-cloud/spring-cloud-connectors
:github-raw: http://raw.github.com/{github-repo}/{github-tag}
:github-code: http://github.com/{github-repo}/tree/{github-tag}
:toc: left
:toclevels: 3

= Spring Cloud Connectors

[[spring-cloud-connectors-install]]

== Introduction

Spring Cloud Connectors provides a simple abstraction for JVM-based applications running on cloud platforms to discover bound services and deployment information at runtime, and provides support for registering discovered services as Spring beans. It is based on a plugin model so that the identical compiled application can be deployed locally or on any of multiple cloud platforms, and it supports custom service definitions through Java Service Provider Interfaces (SPI).

The Connectors project provides out-of-the-box support for discovering common services on Heroku and Cloud Foundry clouds. It also includes a properties-based connector that can supply configuration for development and testing.

=== Concepts

The core Connectors concepts are described below.

[cols="3,7", width="100%"]
|===========================================================================================================================================================================
|**Cloud Connector** |A platform-specific interface that identifies the presence of the platform and discovers any services bound to the application deployment.
|**Service Connector** |An object that represents a runtime connection to a service (for example, a `javax.sql.DataSource`).
|**Service Information** |Information about the underlying service (such as host, port, and credentials).
|**Application Information** |Information about the application and the particular running instance.
|===========================================================================================================================================================================

=== Submodules

The project contains three major submodules.

* **Spring Cloud Connectors Core**: The core library, which is both cloud-agnostic and Spring-agnostic. It provides a programmatic entry point for developers who prefer to access cloud services and application information manually. It also provides basic service definitions for several common services (databases, message queues) and an SPI-based extension mechanism for contributing cloud and service connectors.
* **Spring Cloud Spring Service Connector**: A Spring library that exposes application information, cloud information, and discovered services as Spring beans of the appropriate type (for example, an SQL service will be exposed as a `javax.sql.DataSource` with optional connection pooling).
* The cloud connectors:
 ** **Spring Cloud Cloud Foundry Connector**: Connector for link:http://cloudfoundry.org/[Cloud Foundry].
 ** **Spring Cloud Heroku Connector**: Connector for link:https://www.heroku.com/[Heroku].
 ** **Spring Cloud local-configuration Connector**: Properties-based connector for manually providing configuration information during development or testing. Allows use of the same Spring Cloud configuration wiring in all stages of application deployment.

== Getting Started

See below for examples of how to include the appropriate dependencies using your build system.

=== Including Cloud Connectors

Include the connector for each cloud platform which you want to be discoverable. Including multiple connectors is perfectly fine; each connector will determine whether it should be active in a particular environment.

In Maven, replacing `${VERSION}` with the desired artifact version:

[source,xml]
----
<!-- To use Spring Cloud Connectors for development -->
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-localconfig-connector</artifactId>
    <version>${VERSION}</version>
</dependency>

<!-- If you intend to deploy the app to Cloud Foundry -->
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-cloudfoundry-connector</artifactId>
    <version>${VERSION}</version>
</dependency>

<!-- If you intend to deploy the app to Heroku -->
<dependency>
  <groupId>org.springframework.cloud</groupId>
  <artifactId>spring-cloud-heroku-connector</artifactId>
  <version>${VERSION}</version>
</dependency>
----

In Gradle, replacing `${VERSION}` with the desired version:

[source,groovy]
----
dependencies {

    // To use Spring Cloud Connectors for development
    compile 'org.springframework.cloud:spring-cloud-localconfig-connector:${VERSION}'

    // If you intend to deploy the app to Cloud Foundry
    compile 'org.springframework.cloud:spring-cloud-cloudfoundry-connector:${VERSION}'

    // If you intend to deploy the app to Heroku
    compile 'org.springframework.cloud:spring-cloud-heroku-connector:${VERSION}'

}
----

=== Spring Applications

If you're writing a Spring application, include the <<Spring Service Connector>> dependency in addition to your cloud connector dependencies.

In Maven:

[source,xml]
----
<dependency>
  <groupId>org.springframework.cloud</groupId>
  <artifactId>spring-cloud-spring-service-connector</artifactId>
  <version>${VERSION}</version>
</dependency>
----

In Gradle:

[source,groovy]
----
dependencies {

    compile 'org.springframework.cloud:spring-cloud-spring-service-connector:${VERSION}'

}
----

Then follow the instructions in the <<Spring Service Connector>> documentation on Spring configuration <<spring-cloud-spring-service-connector.adoc#_the_java_configuration,using Java configuration>> or the <<spring-cloud-spring-service-connector.adoc#_the_code_cloud_code_namespace,`<cloud>` namespace>>.

=== Non-Spring Applications

The `spring-cloud-core` dependency is included by each cloud connector, so simply include the connectors for the platforms you want. Then follow the <<_spring_cloud_connectors_core,instructions on using the Spring Cloud Connectors API>>.

== Spring Cloud Connectors Core

This core library provides programmatic access to application and service information. This library has no Spring dependencies and may be used in non-Spring applications.

**This library requires Java 6 or newer.** It is cloud-agnostic; using the Java SPI, it supports pluggable cloud and service connectors. Support for Cloud Foundry and Heroku is available out-of-the-box, in addition to locally-provided configuration for development and testing.

=== Connecting to a Cloud

[NOTE]
====
If you are using Spring Cloud in a Spring application, you should consider <<_spring_service_connector,automatically injecting Spring beans>> instead.
====

* Include the desired cloud connectors on the runtime classpath, <<_getting_started,as described in the main documentation>>.

* Create a `CloudFactory` instance. Creation of a `CloudFactory` instance is a bit expensive, so we recommend using a singleton instance.  If you are using a dependency injection framework such as Spring, create a bean for the `CloudFactory`.
+
[source,java]
----
CloudFactory cloudFactory = new CloudFactory();
----

* Obtain the `Cloud` object for the environment in which the application is running.
+
[source,java]
----
Cloud cloud = cloudFactory.getCloud();
----
+
Note that you must have a `CloudConnector` suitable for your deployment environment on your classpath.  For example, if you are deploying the application to Cloud Foundry, you must add the <<_cloud_foundry_connector,Cloud Foundry Connector>> to your classpath. If no suitable `CloudConnector` is found, the `getCloud()` method will throw a `CloudException`.

* Use the `Cloud` instance to access application and service information and to create service connectors.
+
[source,java]
----
// ServiceInfo has all the information necessary to connect to the underlying service
List<ServiceInfo> serviceInfos = cloud.getServiceInfos();
----
+
[source,java]
----
// Find the `ServiceInfo` definitions suitable for connecting to a particular service type
List<ServiceInfo> databaseInfos = cloud.getServiceInfos(DataSource.class);
----
+
[source,java]
----
// Alternatively, let Spring Cloud create a service connector for you
String serviceId = "inventory-db";
DataSource ds = cloud.getServiceConnector(serviceId, DataSource.class,
                                            null /* default config */);
----

== Spring Service Connector

See <<spring-cloud-spring-service-connector.adoc#,Spring Cloud Spring Service Connector>>.

== Cloud Foundry Connector

See <<spring-cloud-cloud-foundry-connector.adoc#,Spring Cloud Cloud Foundry Connector>>.

== Heroku Connector

See <<spring-cloud-heroku-connector.adoc#,Spring Cloud Heroku Connector>>.

== local-configuration Connector

This connector provides the ability to configure Spring Cloud services locally for development or testing. **The current implementation reads from Java properties only.**

=== Quick Start

Since service URIs contain passwords and should not be stored in code, this connector does not attempt to read service definitions out of the classpath. You can provide service definitions as system properties.

[source,term]
----
java -Dspring.cloud.database='mysql://user:pass@host:1234/dbname' -jar my-app.jar
----

You can also provide service definitions from a configuration properties file, either by setting the `spring.cloud.propertiesFile` system property:

[source,term]
----
java -Dspring.cloud.propertiesFile=/path/to/spring-cloud.properties -jar my-app.jar
----

or by providing the bootstrap properties file `spring-cloud-bootstrap.properties` on the runtime classpath. This file will be inspected only for the property named `spring.cloud.propertiesFile`, and its value will be interpolated from the system properties.

[source,properties]
----
spring.cloud.propertiesFile: ${user.home}/.config/myApp/spring-cloud.properties
----

The system properties, or the configuration properties file, should contain an application ID and the desired services in the following format.

[source,properties]
----
spring.cloud.appId:    myApp
; spring.cloud.{id}:   URI
spring.cloud.database: mysql://user:pass@host:1234/dbname
----

The service type is determined by the URI scheme. The connector will activate if it finds a property (either in the system properties or in the configuration properties file) named `spring.cloud.appId`.

=== Property Sources

This connector first attempts to read the system properties generally and a system property named `spring.cloud.propertiesFile` specifically. If the system properties are not readable (if the security manager denies `checkPropertiesAccess`), then they will be treated as empty.  If a system property named `spring.cloud.propertiesFile` is found, then that file will be loaded as a property list.

==== Providing a Bootstrap Properties File

To avoid having to manually configure run configurations or test runners with the path to the configuration properties file, the connector can read a templated filename out of the runtime classpath. This file must be named `spring-cloud-bootstrap.properties` and be located at the classpath root. For security, the connector will not attempt to read any service URIs out of the file. If the connector does find the file, it will read the property `spring.cloud.propertiesFile` and link:http://commons.apache.org/proper/commons-lang/javadocs/api-release/index.html?org/apache/commons/lang3/text/StrSubstitutor.html[substitute the pattern `${system.property}`] with the appropriate value from the system properties. The most useful option is generally `${user.home}`.

A configuration properties file specified in the system properties will override any bootstrap file that may be available on the classpath.

==== Property Precedence

To provide the maximum configuration flexibility, the connector will override any properties (both application ID and service definitions) specified in the file at `spring.cloud.propertiesFile` with system properties defined at runtime. The connector will log a message at `WARN` if you override a service ID.

=== Activating the Connector

Spring Cloud Core expects exactly one cloud connector to match the runtime environment.  This connector identifies the “local cloud” by the presence of a property, in a configuration properties file or in the system properties, named `spring.cloud.appId`. This property will be used in the `ApplicationInstanceInfo`.

=== Service Definitions

If the connector is activated, it will iterate through all of the available properties for keys matching the pattern `spring.cloud.{serviceId}`. Each value is interpreted as a URI to a service, and the type of service is determined from the scheme. Every standard `UriBasedServiceInfo` is supported.

=== Instance ID

This connector creates a UUID for use as the instance ID, as Java does not provide any portable mechanism for reliably determining hostnames or PIDs.

== Extending Spring Cloud Connectors

Besides the built-in service and cloud support and the included Spring Service Connector, Spring Cloud Connectors can be extended to support additional cloud platforms, cloud services, or application frameworks. See below for details.

=== Adding Cloud Connectors

To allow Spring Cloud to detect a new cloud platform, add a cloud connector for the platform. A cloud connector determines whether the application is running in the specific cloud, identifies application information (such as the name and instance ID of the particular running instance), and maps bound services (such as URIs exposed in environment variables) as `ServiceInfo` objects.

[TIP]
====
See the https://github.com/spring-cloud/spring-cloud-connectors/tree/master/spring-cloud-cloudfoundry-connector[Cloud Foundry Connector] and https://github.com/spring-cloud/spring-cloud-connectors/tree/master/spring-cloud-heroku-connector[Heroku Connector] for examples.
====

Spring Cloud uses the https://docs.oracle.com/javase/tutorial/sound/SPI-intro.html[Java SPI] to discover available connectors.

To add new cloud connectors, your connector classes must implement the http://docs.spring.io/autorepo/docs/spring-cloud/current/api/index.html?org/springframework/cloud/CloudConnector.html[`CloudConnector`] interface. It includes three methods:

* `boolean isInMatchingCloud()`: Determines whether the connector is operating in the cloud for which it provides support.
+
Spring Cloud Connectors will call `isInMatchingCloud()` on each cloud connector included in an application. The first connector to respond `true` will be activated.
* `ApplicationInstanceInfo getApplicationInstanceInfo()`: Returns information about the running application instance.
+
An `ApplicationInstanceInfo` must provide the instance id (`String`) and application id (`String`). Other properties can be added as needed to a `Map` and be returned via `getProperties()`.
* `List<ServiceInfo> getServiceInfos()`: Returns a `ServiceInfo` object for each service bound to the application.
+
`getServiceInfos()` can return an empty `List` if no services have been bound to the application.

New cloud connectors should list the fully-qualified class name in the provider-configuration file at `META-INF/services/org.springframework.cloud.CloudConnector`.

=== Adding Service Support

To allow Spring Cloud to discover a new type of service, create a `ServiceInfo` class containing the information necessary to connect to the service. If your service can be specified via a URI, extend http://docs.spring.io/autorepo/docs/spring-cloud/current/api/org/springframework/cloud/service/UriBasedServiceInfo.html[`UriBasedServiceInfo`] and provide the URI scheme in a call to the `super` constructor.

The following class will expose information for a `HelloWorldService` available at `helloworld://username:password@host:port/Bonjour`.

[source,java]
----
public class HelloWorldServiceInfo extends UriBasedServiceInfo {
    public static final String URI_SCHEME = "helloworld";

  // Needed to support structured service definitions such as Cloud Foundry's
    public HelloWorldServiceInfo(String id, String host, int port, String username, String password, String greeting) {
    super(id, URI_SCHEME, host, port, username, password, greeting);
    }

    // Needed to support URI-based service definitions such as Heroku's
    public HelloWorldServiceInfo(String id, String uri) {
        super(id, uri);
    }
}
----

After creating the `ServiceInfo` class, you will need to create a `ServiceInfoCreator` for each cloud platform you want to support.  If you are adding service support for a cloud platform already supported by Spring Cloud Connectors, you will probably want to extend the appropriate creator base class(es).

[cols="2,8", width="100%"]
|==================================================================
|**Cloud Foundry** | Extend `CloudFoundryServiceInfoCreator`.
|**Heroku** | Extend `HerokuServiceInfoCreator`.
|**local-configuration** | Extend `LocalConfigServiceInfoCreator`.
|==================================================================

A `ServiceInfoCreator` often can be as simple as a method that instantiates a new `ServiceInfo`.

[source,java]
----
@Override
public HelloWorldServiceInfo createServiceInfo(String id, String uri) {
  return new HelloWorldServiceInfo(id, uri);
}
----

Register your `ServiceInfoCreator` classes in the appropriate provider-configuration file for your cloud's `ServiceInfoCreator` base class.

[cols="2,8", width="100%"]
|=========================================================================================================================================================================
|**Cloud Foundry** | Add the fully-qualified class name for your creator to `META-INF/service/org.springframework.cloud.cloudfoundry.CloudFoundryServiceInfoCreator`.
|**Heroku** | Add the fully-qualified class name for your creator to `META-INF/service/org.springframework.cloud.heroku.HerokuServiceInfoCreator`.
|**local-configuration** | Add the fully-qualified class name for your creator to `META-INF/service/org.springframework.cloud.localconfig.LocalConfigServiceInfoCreator`.
|=========================================================================================================================================================================

=== Adding Service Connectors

To allow Spring Cloud to provide framework-specific service objects for supported cloud services, add a service connector for the framework. A service connector consumes a `ServiceInfo` discovered by the cloud connector and converts it into the appropriate service object (such as a `DataSource` in the case of a service definition that represents a SQL database).

[TIP]
====
Service connectors can be tightly bound to the framework whose service objects they are creating. For example, some connectors in the <<_spring_service_connector,Spring Service Connector>> create connection factories defined by Spring Data, for use in building Spring Data templates.
====

To add new service connectors, your connector classes must implement the http://docs.spring.io/autorepo/docs/spring-cloud/current/api/index.html?org/springframework/cloud/service/ServiceConnectorCreator.html[`ServiceConnectorCreator`] interface. It has three methods:

* `SC create()`: Creates a service connection object from a given `ServiceInfo` and configuration.
* `Class<SC> getServiceConnectorType()`: Returns the type of the connection object that will be created.
* `Class<?> getServiceInfoType()`: Returns the type of the `ServiceInfo` that the class will accept.

List the fully-qualified connector class names in the provider-configuration file at `META-INF/services/org.springframework.cloud.service.ServiceConnectorCreator`.