Table Of Contents

Deployment

In this phase, you will make the application service available for customers.

../../../_images/step-project.png ../../../_images/step-meta.png ../../../_images/step-provision.png ../../../_images/step-presentation.png ../../../_images/step-deploy-b.png ../../../_images/step-provisioning.png

Setting Default Product Configuration

Resource Mapping

According to the Sales Model, the provider must have a service template that contains resource types presenting APS resources and APS types of the application. The application Resource Model contains three APS types:

  • The app and license APS types must be used to create reference APS resources to be linked with many APS resources instantiated from the tenant APS type.

  • Reference APS resources must be created first, after which, you can create resource types representing those reference APS resources in a service template.

  • Unlike the above-mentioned resource types, a resource type representing a tenant (an application service) must be bound to the tenant APS type before instantiating APS resources from it. A tenant APS resource must be created when creating a subscription.

This resource mapping looks as follows:

APS Service

Resource class

Resource type

Description

Application instance

Application Service Reference

GitHub - App REF

A global resource representing the application instance

License

Application Service Reference

GitHub - License

Use this to represent application offers - SKUs

Tenant

Application Service

GitHub - Tenant

Local representation of a customer’s tenant in the remote cloud application

Product Configuration Methods

To assist service providers in product configuration, you should add the getInitWizardConfig method to the root service definition as explained in Deployment Configuration. Typically, this method returns a set of products (represented by service plans) along with other components that those products are based on. Those accompanying components are a service template with resource types and some business components used to arrange the product sales process.

In addition, the app service must also have the testConnection method to test a connection with the application to be integrated with the platform.

Follow these steps to define the required methods:

  1. In the scripts/ folder, create a file containing the JSON definition of the data that the getInitWizardConfig method must return. The file format is explained in the Configuration for OSS document. To simplify the process, download the wizard_data.json file to the scripts/ folder:

    {
    "defaults": {
    	"appId": "http://aps-standard.org/samples/github/app/1.0",
    	"apsName": "GitHub Integration Demo",
    	"apsVersion": "2.2",
    	"apsResources": [
    		{
    			"apsType":"http://aps-standard.org/samples/github/license/1.0",
    			"type": "http://aps-standard.org/types/core/profile/service/1.0",
    			"id": "idc2922c137c7a58",
    			"fields": {
    				"profileName": "Basic access level",
    				"name": "Basic",
            "scopes": [
              "repo"
            ]
    			},
    			"relations": {
    				"app": "idglobals"
    			}
    		},
    		{
          "apsType":"http://aps-standard.org/samples/github/license/1.0",
          "type": "http://aps-standard.org/types/core/profile/service/1.0",
          "id": "idc2922c137c7a60",
          "fields": {
            "profileName": "Premium access level",
            "name": "Premium",
            "scopes": [
              "repo",
              "delete_repo"
            ]
          },
          "relations": {
            "app": "idglobals"
          }
    		}
      ],
      "resellerProfiles": [{
        "id": "idcced499b78e4d8",
        "apsType": "http://aps-standard.org/samples/github/reseller/1.0",
        "type": "http://aps-standard.org/types/core/profile/reseller/1.0",
        "fields": {
          "login": "login",
          "passwd": "passwd"
        },
        "relations": {
          "app": "idglobals"
        }
      }],
      "resourceTypes": [
      		{
      			"name": "GitHub Integration Demo - App REF",
      			"id": -500001,
      			"resClass": "rc.saas.service.link",
      			"required": true,
      			"actParams": {
    	  			"app_id": "idOAID",
    	  			"resource_uid": "idglobals"
      			}
      		},
      		{
      			"name": "GitHub Integration Demo - Basic access level",
      			"id": -500002,
      			"resClass": "rc.saas.service.link",
      			"required": false,
      			"rtfor": "http://aps-standard.org/types/core/profile/service/1.0",
      			"actParams": {
      				"resource_uid": "idc2922c137c7a58"
      			}
      		},
    			{
    				"name": "GitHub Integration Demo - Premium access level",
    				"id": -500004,
    				"resClass": "rc.saas.service.link",
    				"required": false,
    				"rtfor": "http://aps-standard.org/types/core/profile/service/1.0",
    				"actParams": {
    					"resource_uid": "idc2922c137c7a60"
    				}
    			},
    	    {
            "name": "GitHub Integration Demo - Tenant Environment",
            "id": -500005,
            "resClass": "rc.saas.service",
            "required": true,
            "actParams": {
               "service_id": "tenants",
               "autoprovide_service": 1
            }
          },
          {
            "name": "GitHub Integration Demo - Value added reseller",
            "id": -500006,
            "resClass": "rc.saas.service.link",
            "required": false,
            "rtfor": "http://aps-standard.org/types/core/profile/reseller/1.0",
            "actParams": {
              "resource_uid": "idcced499b78e4d8"
            }
          }
      ],
    	"serviceTemplate": {
    		"id": -600001,
    		"name": "GitHub Integration Demo",
    		"resources": [
    			{
    				"limit": 1,
    				"unlimited": false,
    				"rtID": -500001
    			},
    			{
    				"limit": 0,
    				"unlimited": false,
    				"rtID": -500002
    			},
    			{
    				"limit": 0,
    				"unlimited": false,
    				"rtID": -500004
    			},
    			{
    				"limit": 1,
    				"unlimited": false,
    				"rtID": -500005
    			},
          {
            "limit": 1,
            "unlimited": false,
            "rtID": -500006
          }
        ]
    	},
    	"billing": {
    		"planCategory": {
    			"id":-21,
    			"name": "GitHub Integration Demo",
    			"description": "Testing the integration with the GitHub API"
    		}, 
    		"salesCategory": {
    			"id":-22,
    			"inCCP": true,
    			"name": "GitHub Integration Demo",
    			"expand": true, 
    			"description": "Testing the integration with the GitHub API"
    		}, 
    		"resourceCategory": {
    			"id":-23,
    			"optional": false,
    			"name": "GitHub Integration Demo",
    			"description": "Testing the integration with the GitHub API",
    			"displayType": "radio"
    		}
    	}, 
    	"servicePlans": [
    		{
    			"name": "GitHub Integration Demo - Basic Access Level",
    			"id": -20,
    			"stId": -600001,
    			"shortDescription": "GitHub Integration - Basic Access Level",
    			"longDescription": "Testing the integration with the GitHub API - Basic Access Level",
    			"planBillingPeriod": 1, 
    			"renewOrderInterval": 0, 
    			"renewPointDays": 0, 
    			"subscrPeriodType": 2, 
    			"subscrRefundType": 0, 
    			"subscrPeriod": 1, 
    			"subscrRenewalFee": 0, 
    			"subscrRecurringFee": 4.25, 
    			"subscrDepositFee": 0, 
    			"subscrTrial": false, 
    			"subscrSetupFee": 2.0,
    			"subscrTransferFee": 0,
    			"resources": [{
    					"id": -700002,
    					"rtID": -500002,
    					"inCP": true,
    					"instore": true,
    					"incl": 3,
    					"min": 3,
    					"max": -1, 
    					"sFeePerUnit": true, 
    					"rFeePerUnit": true, 
    					"setupFee": 0, 
    					"recFee": 1.5,
    					"overFee": 2,
    					"measurable": false
    			}]
    		},
    		{
    			"name": "GitHub Integration Demo - Premium Access Level",
    			"id": -21,
    			"stId": -600001,
    			"shortDescription": "GitHub Integration - Premium Access Level",
    			"longDescription": "Testing the integration with the GitHub API - Premium Access Level",
    			"planBillingPeriod": 1,
    			"renewOrderInterval": 0,
    			"renewPointDays": 0,
    			"subscrPeriodType": 2,
    			"subscrRefundType": 0,
    			"subscrPeriod": 1,
    			"subscrRenewalFee": 0,
    			"subscrRecurringFee": 4.25,
    			"subscrDepositFee": 0,
    			"subscrTrial": false,
    			"subscrSetupFee": 2.0,
    			"subscrTransferFee": 0,
    			"resources": [{
    					"id": -700004,
    					"rtID": -500004,
    					"inCP": true,
    					"instore": true,
    					"incl": 3,
    					"min": 3,
    					"max": -1,
    					"sFeePerUnit": true,
    					"rFeePerUnit": true,
    					"setupFee": 0,
    					"recFee": 2.5,
    					"overFee": 3.0,
    					"measurable": false
    			}]
    		}
    	]
    }
    }
    
  2. In the scripts/app.php file, find the app class definition and add the getInitWizardConfig method inside it:

    /**
    * @verb(GET)
    * @path("/getInitWizardConfig")
    * @access(admin, true)
    * @access(owner, true)
    * @access(referrer, true)
    */
    public function getInitWizardConfig()
    {
       $myfile = fopen("./wizard_data.json", "r") or die("Unable to open file!");
       $data = fread($myfile,filesize("./wizard_data.json"));
       fclose($myfile);
       return json_decode($data);
    }
    

    This method returns the contents of the scripts/wizard_data.json file created in the previous step.

  3. In the same app class, add the testConnection method as follows:

    /**
    * @verb(GET)
    * @path("/testConnection")
    * @param(object,body)
    * @access(admin, true)
    * @access(owner, true)
    * @access(referrer, true)
    */
    public function testConnection($body)
    {
       return "";
    }
    

The above configuration makes the APS package ready for the final Create Products for Sale step in the deployment phase. But before going to that step, you must prepare the APS package for the APS application deployment as the next section explains.

Deployment Schema

The APS package must provide some data to be used for deploying an APS connector. The best practice is to install an APS connector from an image using the Docker virtualization technology as explained in this document.

Let us look at the deployment schema in more detail taking into account the Docker technique.

../../../_images/deployment-schema-docker.png

In this schema, every APS connector is functioning inside its own Docker container. The latter must be installed from an image stored in the Docker registry. The management node must be aware of the Docker registry address to be used for deploying Docker containers. During installation, the management node is configured to use the default Docker registry supported by the APS team.

Prerequisites

Connect to Docker Registry

When preparing an APS application for deployment, you must have access to a Docker registry where you are going to save the APS application image that the system will use during the application deployment.

In the platform configuration, check the Docker registry connection parameters configured currently. For this, in the provider control panel, navigate to System > Settings and in the Integration section click on the Docker Registry Settings link. You will find the domain name or IP address of the Docker registry, as in the example below:

../../../_images/docker-registry-hostname.png

You should replace it with a Docker registry available for your development environment and for the platform you are going to use. In most cases, it must be the Docker official hub docker.io. To upload your APS application images there, you should have an account registered at Docker Hub. In the following examples, we suppose that the account name (login) is “isv1”. With these assumptions, do the following:

  1. Click Edit and replace the Docker Registry Hostname with docker.io.

    ../../../_images/docker-registry-official.png
  2. Click Submit to save the configuration without providing any certificate.

Register Endpoint Host

In addition to the OSS management node, the deployment schema contains a separate endpoint host based on a virtual machine or a physical server for installation of APS connectors inside Docker containers. If your platform does not have it yet, follow the below instructions in this section to register such a node.

The endpoint host must meet the following requirements:

  • The CentOS-7 operating system is on it.

  • The SELinux service is disabled as explained in the respective CentOS document.

  • The host must be available for the management node on its backend interface.

  • It must have access to the Docker registry that provides the necessary images for installing Docker containers.

  • There is no Docker engine on the host, since you will add it during the service node registration as explained in the next section.

The following instruction helps you register your CentOS-7 host as an APS Endpoint Node:

  1. In the provider control panel, navigate to Infrastructure > Service Nodes.

  2. Click Add New Node.

  3. Select the APS Endpoint Node role.

  4. Enter the host name and authentication parameters:

    ../../../_images/endpoint-node-registration.png
  5. Click Next.

  6. Configure the other parameters:

    • Optionally, assign a convenient Hostname

    • Specify the Backnet IP address

    ../../../_images/endpoint-node-configuration.png
  7. Wait for a couple of minutes until the management node adds the server as a service node and installs the Docker engine on it.

    ../../../_images/service-nodes.png

Docker Engine

The best way to deploy the provisioning (backend) logic of an APS application in the platform is to use a Docker image of the backend part (APS connector contents) of the APS application. To create an image, you will need to use the Docker engine in one of these two ways:

  • Use the Docker engine on the APS endpoint host that you have registered already in the platform. In this case, you do not need to install the Docker engine on your local computer.

  • Install the Docker engine on the same computer you use for development. For example, follow the Install Docker on CentOS document to install the Docker engine in CentOS.

Docker Image

Edit Image Settings

The project template includes the deploy-image/ folder that contains the Apache with APS PHP framework configuration structure in the etc/ folder and data structure in the var/ folder. This typical data set makes APS provisioning scripts available on the /endpoint/ alias.

The Docker build command will use the Dockerfile configuration, the deploy-image/ contents, and the APS application scripts/ contents to build an image containing the APS application provisioning logic, that is the APS application connector image.

Create Image

Follow these steps to create an image:

  1. Ensure the whole project package is on the host that has the Docker engine, for example, by copying it to the host registered as the endpoint service node:

    $ scp -r github root@docker-endpoint.a.isv1.apsdemo.org:
    
  2. In the host where the Docker engine is running, change your current directory to the github/ folder, that is the top folder of your project.

  3. Run the Docker build command to build an image locally:

    # docker build -f deploy-image/Dockerfile -t isv1/github:1.0-0 .
    

    Note

    1. The “isv1” prefix is a placeholder for your actual account registered at the Docker official hub.

    2. The image tag version, for example, 1.0-0, must be the same as the APS package version specified in the APP-META.xml file.

    3. Do not miss the dot . at the end of the command. It specifies the current folder as the Docker build context.

  4. Log in to the Docker hub:

    # docker login ## You will be prompted for the login name (for example, "isv1") and password
    
  5. Push the image to the Docker registry:

    # docker push isv1/github:1.0-0
    

    Note

    Do not forget to replace “isv1” with your actual account at the Docker hub.

Build APS Package

Build your APS package on a computer with the installed APS tools and APS PHP runtime. Change your current directory one level above the project folder and build the APS package, for example:

# cd ..
# aps build github/

Import APS Package

Import the APS package to the platform as follows.

  1. Log in to the platform Provider Control Panel (PCP). For example, if the OSS management node is a.isv1.apsdemo.org, enter http://a.isv1.apsdemo.org:8080 in the browser address field. Log in as admin.

  2. In PCP, navigate to Services > Applications and click Import Package.

  3. Browse your local storage for the APS package, select it, and then click Submit to import the package to the platform. Click the Refresh icon on top right of the screen.

    You will see the imported application on the bottom of the list.

Deploy APS Application Instance

In PCP, follow these steps to deploy an APS application instance.

  1. Open the imported application and on the Instances tab, click Add Instance.

  2. Make sure the following deployment options are chosen:

    • The Automatically deploy application’s backend option is selected

    • The Accept the impersonation level box is checked:

  3. Click Next and configure the GitHub access parameters:

    ../../../_images/github-login-params.png
  4. Click Next and then Finish.

Wait until the new instance appears and its status is Ready periodically refreshing the screen contents by clicking the Refresh button in the upper right corner.

If it takes longer than 2 minutes, navigate to Operations > Tasks to clarify the cause of the delay.

Create Products for Sale

A service template and the service plan based on it are used to create subscriptions for customers. A service template must contain all resource types representing the application services defined in the APS package. Every resource type is limited or unlimited in a service template.

The root app service of the APS application contains the getInitWizardConfig method that returns the default configuration of the products to be sold, including all of the components mentioned above.

To use the wizard, open the imported APS package on the Instances tab and click the Configure Product button.

../../../_images/github-initwizard-start.png

Follow the wizard steps as explained here.

  1. In the Application Instance Selection step, ensure that your demo application instance is selected.

    ../../../_images/github-initwizard-1.png
  2. In the Application Instance Settings step, the application access parameters must show up again in case you want to change them. You can click the Test connection button. This calls the testConnection method you have configured in the app service.

  3. In the Service Profiles step, you will find the two license resources you have configured in your default product configuration:

    ../../../_images/github-initwizard-3.png
  4. In the Service Template step, find the default service template configuration proposed by the application:

    ../../../_images/github-initwizard-4.png
  5. In the Billing Configuration step, leave all settings intact.

  6. In the Service Plans step, ensure there are the expected two service plans as in the default configuration:

    ../../../_images/github-initwizard-4.png

    Also, open those service plans one by one to ensure every plan contains only one resource rate representing a license.

  7. In the Summary step, review the final configuration of the service template and click Finish.

The new service plans must appear in the list of service plans. To verify this, switch to the BSS provider control panel and navigate to Products > Service Plans. Open the new service plans one by one and make sure their configuration corresponds to the default configuration the APS application package provides in the scripts/wizard_data.json file, for example:

../../../_images/github-service-plan.png

Conclusion

You have created an APS application package and a Docker image of the respective APS connector. You used these things to deploy the application on the platform and then configured two application-based products for sale. Now the system is ready to provision the application services to customers.