Using GemFire for Pivotal Cloud Foundry

As you would expect with any data service on Pivotal Cloud Foundry (PCF), the GemFire service simplifies the deployment and configuration of software that supports your applications. When you create a GemFire service instance, you are instantly provided with a dedicated cluster of GemFire members runing on dedicated VMs, that use JVM and GemFire settings automatically tuned for most use cases. You can then configure the cluster based on your application needs. For example, you might want to use an existing GemFire configuration from a GemFire development environment on your laptop. In that case, you can export the cluster configuration using GemFire’s gfsh export cluster-configuration, and upload it to a GemFire service instance in your PCF environment using the GemFire service CLI for PCF. GemFire CLI is provided as a CF CLI plugin that includes commands for restarting, and configuring GemFire service instances, as well as downloading GemFire configuration and logs, on a per cluster basis.

Creating a GemFire Service Instance

The following procedure describes how to create a GemFire service instance in the Pivotal Cloud Foundry Elastic Runtime environment.

  1. If you have not done so already, install the Pivotal Cloud Foundry Command Line Interface. See Installing the PCF CLI. Installation binaries are available here.

  2. Log in to PCF using the PCF CLI.

    $ cf login

  3. Run the following command to target the API endpoint, org and space where you want to create the service:

    $ cf target -a <api-endpoint> -o <organization> -s <space name>

  4. Run the following command to view the available service plans.

    $ cf marketplace

    Getting services from marketplace in org staging / space staging as admin...
    OK
    service         plans                description
    p-gemfire       GemFireServicePlan1  Dedicated GemFire instance.
    TIP:  Use 'cf marketplace -s SERVICE' to view descriptions of individual plans of a
    given service.
    
  5. Type the following command to create the service plan:

    $ cf create-service GemFireServicePlan1 <service-plan-name> <service-instance-name>

    where is the name of the Service Plan you see in the marketplace– in this example, “GemFireServicePlan1”– and is a descriptive name that you want to use for the service.

    For example:

    $ cf create-service p-gemfire GemFireServicePlan1 my-gemfire-test
    Creating service my-gemfire-test in org staging / space staging as admin...
    OK
    

Configuring a GemFire Service Instance

To configure a GemFire service instance (cluster) with your cache configuration and gemfire properties, you will need to use the GemFire service CF CLI plugin. If you have not installed the plugin yet, follow the instructions for installation described in Using the GemFire for Cloud Foundry CLI Plug-in.

Applying a cluster configuration involves uploading the configuration zip file to the cluster, and restarting the cluster. The configuration zip file is in the format used by the GemFire gfsh commands for exporting and importing cluster configurations (see Exporting and Importing Cluster Configurations in the Pivotal GemFire documentation). That allows for a cluster configuration to be exported from an existing deployment and used for a GemFire service instance on PCF. Alternatively, a cluster configuration zip file can be created manually from an existing GemFire cache xml configuration, GemFire properties, and any accompanying implementation and their dependency jars, as follows:

  • Create a directory called cluster
  • Copy your cache xml configuration file into the directory, and rename it to cluster.xml
  • If there are any gemfire properties that should be set on the cluster, copy your gemfire properties file into the directory, and rename it to cluster.properties
  • If there are any implementation jars and their dependency jars that should be deployed to the servers:
    • copy the implementation jars into cluster directory
    • copy any dependency jars into a directory called lib under cluster directory
  • Create a zip file from cluster directory

The following example shows the contents of a configuration zip file:

$ unzip -t cluster_config.zip
Archive:  cluster_config.zip
    testing: cluster/                 OK
    testing: cluster/cluster.properties   OK
    testing: cluster/cluster.xml      OK
    testing: cluster/myCallbacks.jar     OK
    testing: cluster/lib/      OK
    testing: cluster/lib/myDependency1.jar      OK
    testing: cluster/lib/myDependency2.jar      OK
No errors detected in compressed data of cluster_config.zip.

In this example myCallbacks.jar contains the implementation of the callbacks referenced in the cache configuration, cluster.xml, and the lib directory contains the jars that myCalllbacks.jar depends on.

Upload and apply your configuration using cf restart-gemfire command with --cluster-config option. For example:

$ cf restart-gemfire my-gemfire-cluster --cluster-config ./cluster_config.zip
Broker HTTP Username>*****
Broker HTTP Password>*****
Cluster successfully restarted

In the above example, a cluster configuration contained in cluster_config.zip file in the current directory is uploaded to the service instance my-gemfire-cluster, and applied to it upon restarting the service instance (applying a cluster configuration requires that all the servers in the cluster be restarted).

See the section on Broker Credentials on how to obtain the Broker HTTP Username and Password.

Configuring a Service Instance Using a Spring Application Context XML

If you use Spring you can configure your GemFire service instances using a Spring Application Context XML file instead of GemFire cache XML configuration. To use this approach you must include a Spring application context XML file in a jar that is provisioned in your configuration zip file, under a lib subdirectory of a cluster directory. In addition, you must place all implementation and dependency jars in the cluster/lib directory of the configuration zip file. The following are detailed steps for creating a Spring configuration zip file:

  1. Create a directory called cluster, then a subdirectory under it called lib.
  2. Place your Spring application context XML file in an implementation jar, and note the full classpath to the XML file as it appears in the JAR. You will need to reference this path later in the cf restart-gemfire command.
  3. Copy all of the implementation and dependency JARs that should be deployed to the servers to the cluster/lib directory.
  4. Create a zip file of the cluster directory.

For example, the following command shows the sample contents of a configuration zip file:

$ unzip -t cluster_spring_config.zip
Archive:  cluster_spring_config.zip
    testing: cluster/                 OK
    testing: cluster/lib/      OK
    testing: cluster/lib/myImplementation.jar      OK
    testing: cluster/lib/myDependency1.jar      OK
    testing: cluster/lib/myDependency2.jar      OK
No errors detected in compressed data of cluster_spring_config.zip.

In the above example, a Spring XML file could be placed in any of the JAR files under the cluster/lib directory. The configuration would then be uploaded and applied to a service instance using the cf restart-gemfire command with --cluster-config and --spring-xml options. For example:

cf restart-gemfire my-gemfire-cluster --cluster-config ./cluster_spring_config.zip --spring-xml /com/myCompany/myApp/myAppContext.xml
Broker HTTP Username>*****
Broker HTTP Password>*****
Cluster successfully restarted

In the above example, the cluster configuration file, ./cluster_spring_config.zip, is uploaded to the my-gemfire-cluster service instance, and then applied after restarting the service instance. The --spring-xml option references the classpath to a Spring XML configuration file is included in one of the JAR files in cluster_spring_config.zip.

See the section on Broker Credentials on how to obtain the Broker HTTP Username and Password.

Configuring JVM and GemFire Properties

The GemFire cluster configuration lacks the ability to set any JVM or GemFire immutable properties (the properties that have to be provided at the JVM startup). Those properties can be set using an optional --properties argument that takes a yaml file containing optional JVM and GemFire properties for locators and servers. For example:

$ cat ./properties.yml
properties:
  server:
      jvmargs:
          - "-XX:PermSize=96m"
          - "-XX:MaxPermSize=96m"
          - "-Dgemfire.OSProcess.ENABLE_OUTPUT_REDIRECTION=true"
      gemfire:
          statistic-sample-rate: 3000
  locator:
      jvmargs:
          - "-XX:PermSize=96m"
          - "-XX:MaxPermSize=96m"
      gemfire:
          statistic-sample-rate: 2000

The settings provided in this way will augment the existing (default) settings. This allows for the values of the existing properties to be modified, and new ones to be applied. The following command, for example:

$ cf restart-gemfire my-gemfire-cluster --cluster-config ./cluster_config.zip --properties ./properties.yml
Broker HTTP Username>*****
Broker HTTP Password>*****
Cluster successfully restarted

applies the properties from ./properties.yml shown above to the servers and locators in the cluster my-gemfire-cluster, and the cluster configuration provided in cluster_config.zip. For more information about all the available CLI commands see Using the GemFire for Cloud Foundry CLI Plug-in.

See the section on Broker Credentials on how to obtain the Broker HTTP Username and Password.

Cloud Deployment Considerations

Certain GemFire configuration settings are affected by the cloud nature of service instance deployments. Notable examples are any GemFire properties that take an IP address or hostname for value. Such properties should not be used. Also, disk directories for GemFire overflow and persistence disk stores are not supported. Disk stores must be configured without disk directories. As a result, disk stores are created in the working directory.

Network Partition Detection

As of v1.5.0.0, the GemFire for PCF service ships with the enable-network-partition-detection property enabled.

This built-in functionality of GemFire helps detect and resolve problems that result from adverse network events. Without this functionality, you run the risk of entering a split-brain situation where GemFire locators and servers cannot communicate with the rest of the cluster, leading to downtime and data loss.

Since the enable-network-partition-detection property can only be enabled or disabled across the entire cluster at once, the cluster must be brought down together. Hence, upgrades from an earlier version to v1.5.0.0 cannot happen in a rolling fashion. Further instructions can be found in our release notes.

Please refer to the Pivotal GemFire documentation for more information on Network Partitioning.

Working with a GemFire Service Instance

For the administration, configuration and monitoring of GemFire service instances the following tools are available:

  • GemFire Pulse provides a graphical dashboard for monitoring vital, real-time health and performance of GemFire clusters, members, and regions. Use Pulse to examine total memory, CPU, and disk space used by members, uptime statistics, client connections, WAN connections, and critical notifications
  • GemFire service plugin for CF CLI provides CLI commands for configuring, and restarting GemFire clusters, as well as accessing the GemFire logs and statistics.
  • GemFire gfsh provides remote access to GemFire clusters and many management, monitoring, and configuration features.

Accessing a Cluster via Pulse

Each GemFire service instance (cluster) has its own Pulse instance, which can be accessed via a Manage link located under the service instance in the Developer Console.

Restarting a Cluster

A GemFire cluster is restarted using the GemFire CLI command cf restart-gemfire. This command has multiple options (use it with -h to see all of them) that can be used in any combination to accomplish desired tasks during a restart.

This command also requires the Broker HTTP Username and Password. See the section on Broker Credentials on how to obtain the Broker HTTP Username and Password.

Accessing GemFire Logs and Statistics, and Cluster Configuration

GemFire logs and statistics files for a cluster can be downloaded using the GemFire CLI command cf export-gemfire. For example:

$ cf export-gemfire cluster1 --logs ./cluster1_logs.zip
Broker HTTP Username>*****
Broker HTTP Password>*****
Successfully wrote logs and stats to `./cluster1_logs.zip`

cluster1 is the name of the cluster to get the logs from.

cf export-gemfire is used to access the cluster configuration as well. For example:

$ cf export-gemfire demo1 --cluster-config ./demo1_config.zip --properties ./demo1_props.yaml
Broker HTTP Username>*****
Broker HTTP Password>*****
Successfully wrote cluster config to `./demo1_config.zip`
Successfully wrote cluster properties to `./demo1_props.yaml`

In this example, cf export-gemfire is used to download the cluster configuration to the file named demo1_config.zip and properties to the file named demo1_props.yaml for the cluster named demo1.

Note that the GemFire log files also include the full configuration.

See the section on Broker Credentials on how to obtain the Broker HTTP Username and Password.

Accessing a Cluster via gfsh

GemFire clusters can be accessed via gfsh from any machine within the Cloud Foundry network.

First identify the locator IP address of your cluster with a service key:

$ cf create-service-key demo1 my-service-key
Creating service key my-service-key for service instance demo1 as admin...
OK
$ cf service-key demo1 my-service-key
Getting key my-service-key for service instance demo1 as admin...
{
 "locators": [
  "10.244.0.50[55221]",
  "10.244.0.51[55221]"
 ],
 "password": "<CLUSTER_USERNAME>",
 "username": "<CLUSTER_PASSWORD>"
}

Use the locator IP addresses to connect with gfsh running on a host within the Cloud Foundry network:

$ gfsh
gfsh>connect --locator=10.244.0.50[55221]
Connecting to Locator at [host=10.244.0.50, port=55221] ..
Connecting to Manager at [host=10.244.0.50, port=1099] ..
Successfully connected to: [host=10.244.0.50, port=1099]

Accessing GemFire Service Connection Information (Binding)

After you deploy a Java Buildpack application and bind it to a GemFire for Pivotal Cloud Foundry service instance, your application receives the GemFire cluster locator addresses and credentials in the VCAP_SERVICES environment variable. If you have enabled the GemFire REST API, then the REST URL is also provided as metadata in VCAP_SERVICES.

VCAP_SERVICES provides data as a JSON document, so you can use a variety of techniques to access the relevant connection information. See Viewing Binding Meta Data for an example of the data provided in VCAP_SERVICES.

Note: GemFire for Pivotal Cloud Foundry only supports deploying GemFire client applications. You cannot deploy an application that participates in the bound GemFire cluster as a peer member.

Using a JSON Library to Acquire Connection Information

Because VCAP_SERVICES provides a JSON document, you can also use a Java JSON library to parse the data for connection information. This example code uses the Jackson library to parse the document:

package pivotal;

import com.fasterxml.jackson.core.JsonParseException;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import pivotal.GemFireClient.Locator;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

public class EnvParser {

    private static EnvParser instance;

    private EnvParser() {
    }

    public static EnvParser getInstance() {
        if (instance != null) {
            return instance;
        }
        synchronized (EnvParser.class) {
            if (instance == null) {
                instance = new EnvParser();
            }
        }
        return instance;
    }

    public List<Locator> getLocators() throws JsonParseException, JsonMappingException, IOException {
        List<Locator> locatorList = new ArrayList<GemFireClient.Locator>();
        Map credentials = getCredentials();
        List<String> locators = (List<String>) credentials.get("locators");
        for (String locator : locators) {
            String locatorIP = locator.substring(0, locator.indexOf("["));
            String portString = locator.substring(locator.indexOf("[") + 1,
                    locator.indexOf("]"));
            locatorList.add(new Locator(locatorIP, Integer.parseInt(portString)));
        }
        return locatorList;
    }

    public String getUsername() throws JsonParseException, JsonMappingException, IOException {
        String username = null;
        Map credentials = getCredentials();
        username = (String) credentials.get("username");
        return username;
    }

    public String getPasssword() throws JsonParseException, JsonMappingException, IOException {
        String password = null;
        Map credentials = getCredentials();
        password = (String) credentials.get("password");
        return password;
    }

    private Map getCredentials() throws JsonParseException, JsonMappingException, IOException {
        Map credentials = null;
        String envContent = System.getenv().get("VCAP_SERVICES");
        List<Locator> locatorList = new ArrayList<GemFireClient.Locator>();
        ObjectMapper objectMapper = new ObjectMapper();
        Map services = objectMapper.readValue(envContent, Map.class);
        List gemfireService = getGemFireService(services);
        if (gemfireService != null) {
            Map serviceInstance = (Map) gemfireService.get(0);
            credentials = (Map) serviceInstance.get("credentials");
        }
        return credentials;

    }

    private List getGemFireService(Map services) {
        return  (List) services.get("p-gemfire");
    }
}

To authenticate your client application, you must implement the GemFire AuthInitialize interface, as shown in this example:

package pivotal;

import com.gemstone.gemfire.LogWriter;
import com.gemstone.gemfire.distributed.DistributedMember;
import com.gemstone.gemfire.security.AuthInitialize;
import com.gemstone.gemfire.security.AuthenticationFailedException;

import java.io.IOException;
import java.util.Properties;

public class ClientAuthInitialize implements AuthInitialize {

    private EnvParser env = EnvParser.getInstance();

    public static final String USER_NAME = "security-username";
    public static final String PASSWORD = "security-password";

    public static AuthInitialize create() {
        return new ClientAuthInitialize();
    }

    @Override
    public void close() {
    }

    @Override
    public Properties getCredentials(Properties arg0, DistributedMember arg1,
                                     boolean arg2) throws AuthenticationFailedException {
        Properties props = new Properties();
        try {
            String username = env.getUsername();
            String password = env.getPasssword();
            props.put(USER_NAME, username);
            props.put(PASSWORD, password);
        } catch (IOException e) {
            throw new AuthenticationFailedException("Exception reading username/password from env variables ", e);
        }
        return props;
    }

    @Override
    public void init(LogWriter arg0, LogWriter arg1)
            throws AuthenticationFailedException {
    }
}

The authenticated application can then create a GemFire ClientCache as follows:

Properties props = new Properties();
props.setProperty("security-client-auth-init", "pivotal.ClientAuthInitialize.create");
ClientCacheFactory ccf = new ClientCacheFactory(props);
try {
    List<URI> locatorList = EnvParser.getInstance().getLocators();
    for (URI locator : locatorList) {
        ccf.addPoolLocator(locator.getHost(), locator.getPort());
    }
    ClientCache client = ccf.create();
} catch (IOException e) {
           // handle
}

Using spring-cloud to Acquire Connection Information

As an alternative to use a Java JSON library, you can use spring-cloud with the Spring Cloud GemFire Connector to parse the JSON data. Note that this method does not require your application to be a Spring project or to have spring-core as a dependency. You only need to specify spring-cloud and spring-cloud-gemfire-cloudfoundry-connector as dependencies as shown in this exerpt:

<dependency>
        <groupId>com.gemstone.gemfire</groupId>
        <artifactId>gemfire</artifactId>
        <version>8.1.0</version>
    </dependency>
    <dependency>
        <groupId>io.pivotal.spring.cloud</groupId>
        <artifactId>spring-cloud-gemfire-cloudfoundry-connector</artifactId>
        <version>1.0.0.BUILD-SNAPSHOT</version>
    </dependency>
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-core</artifactId>
        <version>1.2.0.RC1</version>
    </dependency>
...
        <repository>
            <id>spring-milestones</id>
            <url>http://repo.spring.io/libs-milestone/</url>
        </repository>
        <repository>
            <id>gemfire-repository</id>
            <name>Gemfire Repository</name>
            <url>http://dist.gemstone.com/maven/release</url>
        </repository>

For an application that binds to a GemFire service named MyService, you would then use the CloudFactory API to obtain a service connection from which you get metadata such as the available locators, username, and password. For example:

CloudFactory cloudFactory = new CloudFactory();
Cloud cloud = cloudFactory.getCloud();
GemfireServiceInfo myService = (GemfireServiceInfo) cloud.getServiceInfo("MyService");

URI[] locators = myService.getLocators();
String userName = myService.getUsername();
String password = myService.getPassword();

To authenticate your client application, you must implement the GemFire AuthInitialize interface, as shown in this example:

public class ClientAuthInitialize implements AuthInitialize {

  public static final String USER_NAME = "security-username";
  public static final String PASSWORD = "security-password";

  public GemfireServiceInfo serviceInfo;

  private ClientAuthInitialize() {
    CloudFactory cloudFactory = new CloudFactory();
    Cloud cloud = cloudFactory.getCloud();
    serviceInfo = (GemfireServiceInfo) cloud.getServiceInfo("MyService");
  }

  public static AuthInitialize create() {
    return new ClientAuthInitialize();
  }

  @Override
  public void close() {
  }

  @Override
  public Properties getCredentials(Properties arg0, DistributedMember arg1,
                                   boolean arg2) throws AuthenticationFailedException {
    Properties props = new Properties();

    String username = serviceInfo.getUsername();
    String password = serviceInfo.getPassword();
    props.put(USER_NAME, username);
    props.put(PASSWORD, password);

    return props;
  }

  @Override
  public void init(LogWriter arg0, LogWriter arg1)
      throws AuthenticationFailedException {
  }
}

The code to initialize the client, obtain authorization, and finally create a GemFire ClientCache would resemble:

CloudFactory cloudFactory = new CloudFactory();
Cloud cloud = cloudFactory.getCloud();
GemfireServiceInfo myService = (GemfireServiceInfo) cloud.getServiceInfo("MyService");
Properties props = new Properties();
props.setProperty("security-client-auth-init", "pivotal.ClientAuthInitialize.create");
ClientCacheFactory ccf = new ClientCacheFactory(props);
URI[] locators = myService.getLocators();
for (URI locator : locators) {
   ccf.addPoolLocator(locator.getHost(), locator.getPort());
}
ClientCache cache = ccf.create();

Acquiring a Connection from a Spring Application

If you are developing a Spring Application, then acquiring GemFire service connection information is a simple, two-step process:

  1. Configure GemFire, spring-cloud and spring-cloud-gemfire-cloudfoundry-connector as dependencies in your project:

    dependencies {
    compile("com.gemstone.gemfire:gemfire:8.1.0")
    compile("io.pivotal.spring.cloud:spring-cloud-gemfire-spring-connector:1.0.0.BUILD-SNAPSHOT")
    compile("io.pivotal.spring.cloud:spring-cloud-gemfire-cloudfoundry-connector:1.0.0.BUILD-SNAPSHOT")
    }
    
  2. In your application, auto-wire the GemFire ClientCache:

    @Configuration
    @ServiceScan
    @RestController
    public class MyController {
    
      @Autowired
      ClientCache cache;
    

Configuring a Java REST Client to Access a Service Instance via HTTPS

To support Java client applications accessing a service instance REST API endpoint via HTTPS, you must modify the Java Buildpack to provision security artifacts. You will need to obtain the correct SSL certificate from your Cloud Foundry HAProxy credentials and import it into the JRE truststore of the Java Buildpack. Importing the certificate then makes it available to your Java applications.

You configure the JRE with additional resources by adding the resource files to the appropriate location under the resources directory of the buildpack. For SSL certificates that should be added to the OpenJDK JRE truststore, the correct location is resources/open_jdk_jre/lib/security under the buildpack root. To add custom SSL certificates, add your cacerts file to resources/open_jdk_jre/lib/security/cacerts. This file is overlayed onto the OpenJDK distribution. The exact procedure to follow is:

  1. Get the SSL certificate from your PCF Ops Manager by going to the Credentials tab in Elastic Runtime and copying the SSL RSA certificate from the HAProxy section. Save the certificate to a new file (for example, myCert.cert).
  2. Import the saved certificate file to your trust store.
  3. Clone the java build-pack.
  4. Copy your truststore from Step 2 above into resources/open_jdk_jre/lib/security/cacerts under your buildpack root directory.
  5. Rebuild your Java Buildpack. This example uses offline mode:

    $ cd ~/projects/java-buildpack
    $ bundle install
    $ bundle exec rake package OFFLINE=true
    
  6. Upload the build pack. For example:

    $ cf create-buildpack secure-java-buildpack build/java-buildpack-offline-<sha>.zip 1
    
  7. Make sure client applications use HTTPS when forming the REST API endpoint URL.

  8. Use the new buildpack when pushing your client applications. For example:

    $ cf push -f app.yml -t 30 -b secure-java-buildpack
    

Deploying Applications for Use with the GemFire Service

This section provides tips on pushing your application to the Pivotal Cloud Foundry Elastic Runtime environment for use with the GemFire service. Some of the application deployment steps may differ depending on what kind of application you are deploying.

Re-deploying your application does not affect data stored in any existing service instances bound to the application.

See Deploy an Application in the Pivotal Cloud Foundry Documentation for detailed information on pushing CF applications.

Using the Java Buildpack

Important: Pivotal recommends that you use the latest Java Buildpack when pushing your applications. Specify the location of the buildpack using the -b parameter:

$ cf push <your-app-name> -p <location-of-your-app-file> \
-b https://github.com/cloudfoundry/java-buildpack.git

To avoid having to restage your application after binding the service, you can push the application initially with the --no-start command:

$ cf push <your-app-name> -p <location-of-your-app-file> \
 -b https://github.com/cloudfoundry/java-buildpack.git --no-start

Binding an Application to the GemFire Service

The following procedures describe how to bind a GemFire service instance to your Pivotal Cloud Foundry application.

PCF Developer Console Instructions

  1. Log in to the Pivotal Cloud Foundry Developer Console.

  2. Select your Org from the drop-down list on the left. This should be the same Org where you created the service instance.

  3. Select the space where your GemFire service instance and bound application have been deployed.

  4. Select the application that you wish to bind to the service. A page displays showing the already bound services and instances for this application.

  5. Click Bind. A list of available services displays.

  6. Click the Bind button for the GemFire service you want to bind to this application.

  7. Using the Pivotal Cloud Foundry CLI, start or restage your application. See Pushing or Restaging Applications After Changes.

CLI Instructions

Alternately via the CLI:

  1. Log in to your Pivotal Cloud Foundry environment using the Pivotal Cloud Foundry CLI.

    $ cf login

  2. Run the following command to target the specific org and space where you want to create the service plan.

    $ cf target -o <organization> -s <space_name>

  3. Run the following command to view running service instances:

    $ cf services

    Getting services in org staging / space staging as admin...
    OK
    name              service          plan                 bound apps
    my-gemfire-test   gemfire           GemFireSmallPlan
    
  4. Run the following command to bind the application to the service instance:

    $ cf bind-service <application> <service-instance-name>

    For example:

    $ cf bind-service gfe-app my-gemfire-test
    Binding service my-gemfire-test to app gfe-app
    in org staging / space  staging as admin...
    OK
    TIP: Use 'cf restage' to ensure your env variable changes take effect
    
  5. Restage your application.

    $ cf restage <application>

Pushing or Restaging Applications After Service Changes

To ensure that your application picks up the correct environment variables, you must restage or re-push your applications after binding them to the GemFire service. This can currently be done using the CLI. In addition, if you make any other changes to the GemFire Service while it is bound to your application (for example, add, modify or delete the service), you will need to re-push or restage your application afterwards.

Pushing or re-staging your application does not affect data stored in the existing service instance.

To restage or re-push your application using the Pivotal Cloud Foundry CLI:

  1. Log in to your Pivotal Cloud Foundry environment using the Pivotal Cloud Foundry CLI.

    $ cf login

  2. Run the following command to target the API endpoint, org and space where you want to push or restage the application. For example:

    $ cf target -a <api-endpoint> -o <organization> -s <space_name>

  3. Push or restage your existing application:

    $ cf push <application> -p <location-of-your-app-file> -b <buildpack-location>

    or

    $ cf restage <application>

    Alternately, if you pushed your application without starting it, you can start your application now to pick up the newly bound service.

    $ cf start <application>

For more details on deploying applications, see Deploy an Application in the Pivotal Cloud Foundry documentation.

Viewing Binding Meta Data

To view the binding variables, use the following procedures.

PCF Developer Console Instructions

  1. Log in to the Pivotal Cloud Foundry Developer Console.
  2. Select your Org from the drop-down list on the left.
  3. Select the space where your GemFire service instance and bound application have been deployed.
  4. Select the application that you have bound to the GemFire service.
  5. Click on the Env Variables tab. The environment variables for the service binding display:

    GemFire Service Bindings

    Alternately, you can also view credentials used by the service when binding to the application by clicking on the Services tab and clicking Show credentials.

    Service credentials and locator address information displays:

    GemFire Credentials

CLI Instructions

To view the binding variables in the CLI, type the following command after you have bound your application to the GemFire service:

$ cf env <application-name>

If successful, you should see similar to the following in the returned output:

Getting env variables for app  in org  / space  as ...
OK
System-Provided:
{
 "VCAP_SERVICES": {
  "p-gemfire": [
   {
    "credentials": {
     "locators": [
      "10.0.0.55[55221]",
      "10.0.0.56[55221]"
     ],
     "password": "15587128842615488747",
     "rest_url": "",
     "username": "dacaf950-1633-4741-7dc5-eb11ce5f33e2"
    },
    "label": "p-gemfire",
    "name": "MyService",
    "plan": "GemFireServicePlan1",
    "tags": [
     "gemfire"
    ]
   }
  ]
 }
}
No user-defined env variables have been set
No running env variables have been set
No staging env variables have been set

Unbinding an Application from the GemFire Service

When you create a GemFire service instance, the GemFire Service Broker allocates a specific cluster of GemFire locators and servers. You can bind, unbind and the bind again to that particular service instance as often as you want. The service instance always uses the same cluster and the Service Broker does not do anything to the data in that service instance.

PCF Developer Console Instructions

To unbind the application from the GemFire service:

  1. Log in to the Pivotal Cloud Foundry Developer Console.
  2. Select your Org from the drop-down list on the left.
  3. Select the space where your GemFire service instance and bound application have been deployed.
  4. Select the application that you have bound to the GemFire service. A page displays that show the bound services and instances for this application.
  5. Locate the bound service instance you want to unbind and click Unbind.

    Unbinding a GemFire Service

  6. A confirmation dialog box displays. Click Unbind again.

  7. If successful, the following message will appear at the top of the screen:

    Service successfully unbound from the application. TIP: Use ‘cf push’ to ensure your env variable changes take effect.
  8. Use the Pivotal Cloud Foundry CLI to push or restage your application for the changes to take effect. See Pushing or Restaging Applications After Changes.

CLI Instructions

  1. Log in to your Pivotal Cloud Foundry environment using the Pivotal Cloud Foundry CLI.

    $ cf login

  2. Run the following command to target the org and space where you want to push or restage the application. For example:

    $ cf target -o <organization> -s <space_name>

  3. Run the following command:

    $ cf unbind-service <application> <service-instance-name>

    where is the name of the GemFire instance you are unbinding from the specified .

    For example:

    $ cf unbind-service gfe-app my-gemfire-test
    Unbinding app gfe-app from service my-gemfire-test in org staging / space
    staging as admin...
    OK
    
  4. Restage or re-push your application for the application changes to take effect. See Pushing or Restaging Applications After Changes.

Deleting a GemFire Service Instance

When you delete a GemFire service instance, all applications that are bound to that service are automatically unbound and any data in the service instance is cleared. In addition, the allocated service instance (GemFire cluster) is returned to the pool of available clusters and those locators and cache servers are now available to future applications.

PCF Developer Console Instructions

To delete a service instance using the Pivotal Cloud Foundry Developer Console:

  1. Log in to the Pivotal Cloud Foundry Developer Console.
  2. Select your Org from the drop-down list on the left.
  3. Locate the row under Services that contains the service instance you want to delete and click Delete.
  4. If you had applications that were bound to this service, you may need to restage or re-push your application for the application changes to take effect. See Pushing or Restaging Applications After Changes.

CLI Instructions

  1. Log in to your Pivotal Cloud Foundry environment using the Pivotal Cloud Foundry CLI.

    $ cf login

  2. Run the following command to target the org and space where you want to push or restage the application. For example:

    $ cf target -o <organization> -s <space_name>

  3. Run the following command:

    $ cf delete-service <service-instance-name>

    where is the name of the GemFire service you are deleting. Enter ‘y’ when prompted.

    For example:

    $ cf delete-service my-gemfire-test
    Really delete the service my-gemfire-test?> y
    Deleting service my-gemfire-test in org staging / space staging as admin...
    OK

  4. If you had applications that were bound to this service, you may need to restage or re-push your application for the application changes to take effect. See Pushing or Restaging Applications After Changes.

Configuring Multi-site (WAN) Connections Between Two or More GemFire Service Instances

You can configure GemFire service instances for multi-site (WAN) communication. For information about GemFire multi-site replication capabilities, see Multi-site (WAN) Configuration in the GemFire User’s Guide.

A key prerequisite for multi-site replication is network connectivity between the GemFire instances to be configured for multi-site connections. GemFire nodes on the opposite sides of a multi-site (WAN) link must be able to establish direct connections to each other.

The GemFire service for PCF provides functionality that makes the WAN configuration process easier for GemFire clusters in PCF. The service provides support for configuring service instances so that they discover each other and establish WAN connections. You must still create WAN senders and receivers, and configure data regions for multi-site replication.

The steps to enable WAN connections between two GemFire service instances are as follows:

  1. For each service instance, obtain the WAN configuration URL using the command:

    cf show-wan-config-url <service_instance>
    
  2. When you create the cluster configuration for each service instance, configure the WAN senders and receivers, and data regions that should be replicated over the WAN.

  3. Set the GemFire property distributed-system-id to a unique integer value in the properties yml file for each service instance (see the previous section for more information about configuring GemFire properties for a service instance).

  4. Restart each service instance with the WAN configuration URLs for the other instances passed as argument to the --enable-wan option of the cf restart-gemfire command. For example:

    cf restart-gemfire <service_instance_A> \
      --cluster-config <cluster_A_config_zip> \
        --properties <properties_cluster_A_yml> \
        --enable-wan <cluster_B_WAN_config_URL>
    

    The above command restarts the locators in addition to the servers. This command also requires the Broker HTTP Username and Password. See the section on Broker Credentials on how to obtain the Broker HTTP Username and Password. After restarting, the clusters are enabled for WAN communication to each other.

Create a pull request or raise an issue on the source for this page in GitHub