Configuring Services

This section provides the APC syntax and examples for creating and consuming various types of services, including:

Creating services

To create a service you use the following command:

apc service create <service-name> [options]

The command options are as follows:

Type Description
--provider <name> Provider of the service
--name <name> Name of the binding; if job is specified, this is generated automatically
--description <desc> Description of the service
--job <name> Job to bind to the service (optional)
--type <type> Service type (optional, if the provider is specified)

You must specify a provider if the type uses a provider; otherwise specify a service type.

Consuming services

To consume a service, you must bind a job to it. Some services already exist in Apcera, so you can bind to them directly. In many cases, however, you must first create a service. For example, if you wish to connect to a PostgreSQL database server, you create a service, specifying a provider registered to provide services of type postgres.

Creating service bindings

Jobs connect to services through information stored in the bindings on the job. These bindings include a URI with the host and port of the service when the service is running outside Apcera, and the UUID and port of the job when the service is running inside Apcera. You can optionally upload a PEM file containing root certificate authorities that the service type's semantic pipeline (if available) uses when verifying server certificates.

To bind a job to a service, you use the following command:

apc service bind [options]

The command options are as follows:

Type Description
--job <name> Job to bind to the service (required)
--name <name> (Optional) If specified, used to create the name of the environment variable set on the job. See below for details.
--cacert FILE The path to a file containing root certificate authorities that semantic pipelines and service gateways use when verifying server certificates. This is only necessary if the service needs to connect to an external provider, such as an external MySQL server. You will typically add root certificates to a provider (see Adding root certificates to a provider).

If a value is provided for the --name parameter the environment variable set on the job takes the form of <BINDING-NAME>_URI, where <BINDING-NAME> is the specified name. If no binding name is specified then Apcera auto-generates a name in the form of BIND_<SERVICE-NAME>_<JOB-NAME>.

Note: Auto-generated binding names cannot be guaranteed to be unique since they are generated using (local) names of service and jobs, which are not guaranteed to be unique.

In addition, URIs for service consumption are replicated in the following three environment variables placed upon the job's container:

  • <service-type>_URI (e.g., MYSQL_URI for a MySQL database). In the case where an app is bound to multiple services of the same type, then this variable cannot be relied upon. Instead, use one of the environment variables listed below.
  • <binding-name>_URI (e.g., MY_BINDING_URI). If the specified binding name starts with a number then this environment variable will not exist on the job.
  • <service-name>_URI (e.g., MY_DB_URI). Any hyphens or other non-alphanumeric characters in the service name are replaced with underscores. If the service name starts with a number then this environment variable will not exist on the job.

For example, the following binds the customerdb service to the job todos using an auto-generated binding name:

apc service bind customerdb --job todos
...
Binding service "customerdb" to "todos"...
╭───────────────────────────────╮
│ Binding Environment Variables │
├───────────────────────────────┤
│ "BIND_CUSTOMERDB_TODOS_URI"   │
│ "CUSTOMERDB_URI"              │
│ "JDBC_MYSQL_URI"              │
│ "MYSQL_URI"                   │
╰───────────────────────────────╯
Success!

The following example binds the customerdb service to the job todos:

apc service bind customerdb --job todos --name mybind
...
╭───────────────────────────────╮
│ Binding Environment Variables │
├───────────────────────────────┤
│ "CUSTOMERDB_URI"              │
│ "JDBC_MYSQL_URI"              │
│ "MYBIND_URI"                  │
│ "MYSQL_URI"                   │
╰───────────────────────────────╯
Success!

When you bind a job to a MySQL or Postgres service, JDBC-specific environment variables are also set on the job. These variables contain JDBC-specific connection strings for those database types. See JDBC-specific Binding URIs.

To connect different apps to the same service, bind each app separately to the service using the apc service bind command.

JDBC-specific Binding URIs

When you create a service binding between a job and a MySQL or Postgres service, Apcera adds environment variables that contain JDBC-specific connection URIs for those database types. These allow Java applications to easily connect to those service types without having to parse the connection information into the JDBC format (jdbc:mysql://<host>:<port>/<database>?user=uname&password=pwd or jdbc:postgresql://<host>:<port>/<database>?user=uname&password=pwd).

For instance, suppose you create a binding between a job and a MySQL service:

$ apc service bind mysql-service --job myjob

This would add the following environment variables to the job:

  • JDBC_MYSQL_URI
  • MYSQLSERVICE_URI
  • MYSQL_URI

The MYSQL_URI environment variable contains the native MySQL connection string, for example:

mysql://user:password@169.254.195.56:20000/database-name

The JDBC_MYSQL_URI environment variable contains the JDBC-specific connection string to connect to the MySQL database, for example:

jdbc:mysql://169.254.195.56:20000/database-name?user=user&password=password&useSSL=true

Similarly, if you bind a job to a PostgreSQL service a JDBC_POSTGRES_URI environment variable is set on the job:

jdbc:postgresql://169.254.150.77:20000/database-name?user=user&password=password

For example, the following Java code example shows how an application can use the value of JDBC_MYSQL_URI to connect to a MySQL database:

import java.sql.*;
public class JdbcMysql
{
  private static final String dbClassName = "com.mysql.jdbc.Driver";
  private static final String CONNECTION = System.getenv("JDBC_MYSQL_URI");
  public static void main(String[] args) throws
                                        ClassNotFoundException,SQLException
  {
    Class.forName(dbClassName);
    Connection c = null;
    try {
        c = DriverManager.getConnection(CONNECTION);
    }
    catch (Exception e) {
        System.out.println(e);
        e.printStackTrace();
        System.exit(1);
    }
    finally {
        c.close();
    }
    System.out.println("MySQL Connection Successful!");
  }
}

Note: If you bind a job to more than one MySQL or Postgres service, the JDBC-specific environment variable will contain the connection information for the most recently bound MySQL or Postgres service.

Unbinding jobs from services

To unbind a job from a service, use the following command:

apc service unbind <service> --job <name>

This command deletes the binding between the job and the service. If more than one binding exists between the job and the service, use --name <binding name> to specify which binding to delete.

If necessary you can force the unbinding of a service from a job using the following command:

apc service unbind <service> -j <job> --force

Removing services gracefully

If a job is bound to a service, you cannot delete the service. To completely remove a service, follow this procedure to do so gracefully:

  1. Unbind the service from the job:

     apc service unbind --job <name>
    

    Use --force, if necessary:

     apc service unbind <service> -j <job> --force
    
  2. Delete the service:

     apc service delete <service>
    

    Use --force, if necessary:

     apc service delete <service> --force
    

    Using the --force option may be necessary if the service has become orphaned by a non-existing provider. You should try the standard service delete method first before using the --force option.

  3. Optionally, if the job and/or provider are no longer needed, you can fully clean up your state using the following commands:

     apc job delete <job>
     apc provider delete <provider>
    

Managing services

Use the following commands to manage services in the cluster.

apc service list

List the services in the current namespace:

apc service list

List the services in the root namespace:

apc service list -ns /

Use the -l option to produce a list of fully qualified names (FQNs) of services:

apc service list -l Or apc service list -ns / -l

apc service show

Display information (for example FQN, type, provider, and jobs bound to it) about a specific service:

apc service <service name> show

Beginning with version 0.19.5 of the APC client, you can query the Apcera cluster for definitions of existing Network services using the apc show service comand.

The following example demonstrates this, including service creation and network definitions after creation:

apc service create gabe-test --type network –- --ipnet 184.168.61.190/32 --protocol tcp --portrange 443
╭──────────────────────────────────────────────────────────────╮
│ Service Creation Settings                                    │
├───────────────┬──────────────────────────────────────────────┤
│ Service:      │ service::/apcera/service-gateways::gabe-test │
│ Service Type: │ network                                      │
╰───────────────┴──────────────────────────────────────────────╯

Is this correct? [Y/n]: Y
Creating service... done
Success!

Run apc service show to see the network details:

apc service show gabe-test
╭─────────────┬──────────────────────────────────────────────╮
│ Service:    │ gabe-test                                    │
├─────────────┼──────────────────────────────────────────────┤
│ FQN:        │ service::/apcera/service-gateways::gabe-test │
│ Type:       │ network                                      │
│ ipnet:      │ 184.168.61.190/32                            │
│ portrange:  │ 443                                          │
│ protocol:   │ tcp                                          │
│             │                                              │
│ Created by: │ hyang@apcera.com                             │
│ Created at: │ 2015-09-10 21:23:38.084201271 +0000 UTC      │
╰─────────────┴──────────────────────────────────────────────╯

apc service delete

Delete a service from the cluster:

apc service delete <service name>

Force removal of a named service from the cluster when the provider is no longer available.

apc service delete <service> --force

See also Removing services gracefully.

Managing service gateways

You use the apc gateway <command> [options] command to perform operations specific to service gateways, such as promoting an application to service gateway, listing service gateways, and starting or stopping service gateways. View all of the options using apc help gateway. See also the service examples that follow.

To view the list of available service types (that is, service gateways) on your cluster, use the apc gateway list -ns / command. See Supported Service Types for a full list of service gateways supplied by Apcera. You can also create your own service gateways using the Service Gateway API.

Managing service providers

Use the command apc provider <command> [options] to perform operations on providers such as registering a provider, promoting a provider, listing all providers, and deleting a provider.

See Working with Providers for guidance.