apsconnect/connect-sdk

APS Connect 快速入门 SDK

22.0 2021-06-18 12:59 UTC

README

Build Status Latest Stable Version License codecov PHP Version Quality Gate Status

入门指南

Connect PHP SDK 允许您通过基于 PHP 的集成轻松快速地与 CloudBlue Connect 履约和用法 API 集成。此 SDK 使您能够自动化产品的订单履约,并报告其使用数据。

在使用库之前,请先阅读 Connect 知识库中的文档,该文档可以作为此 SDK 使用的其他 RESTful API 的信息来源。

类功能

此库可用于在项目中实现履约逻辑的自动化以及使用报告。一旦将此类导入到项目中,您就可以

  • 建立与 Connect API 的连接
  • 列出所有请求并应用如下过滤器
    • 按产品过滤请求
    • 按状态过滤请求
    • 按资产过滤请求
    • 等。
  • 处理每个请求并获取请求的完整详细信息
  • 修改请求的参数以
    • 查询更改
    • 将信息存储到履约请求中
  • 将请求的状态从初始挂起状态更改为查询、失败或批准。
  • 生成并上传使用文件以报告活跃合同和列表的使用情况
  • 处理使用文件状态更改
  • 与请求的备注进行交互
  • 生成日志
  • 在失败的情况下收集调试日志

您的代码可以使用任何调度器执行,从简单的 cron 到 Azure、Google、Amazon 或其他云平台上的云调度器。

安装与加载

Connect PHP SDK 通过 Packagist 提供(使用语义版本控制),并且通过 Composer 安装是推荐的方法。只需将这些行添加到您的 composer.json 文件中

{
  "require": {
    "apsconnect/connect-sdk": "^18.0"
    }
}

或运行

composer require apsconnect/connect-sdk --no-dev --prefer-dist --classmap-authoritative

请注意,vendor 文件夹和 vendor/autoload.php 脚本是由 Composer 生成的

履约简单示例

此示例演示了一个脚本,它将检索所有挂起状态的请求并根据它们的类型(购买、更改、取消、暂停或恢复)进行处理

<?php

require_once "vendor/autoload.php";

class ProductRequests extends \Connect\FulfillmentAutomation
{
    
    public function processRequest($request)
    {
        $this->logger->info("Processing Request: " . $request->id . " for asset: " . $request->asset->id);
        switch ($request->type) {
            case "purchase":
                //Get value of a parameter with id "email"
                $email = $request->asset->getParameterByID('email');
                if($email->value == ""){
                    throw new \Connect\Inquire(array(
                        $request->asset->params['email']->error("Email address has not been provided, please provide one")
                    ));
                }
                //Get value for a concrete item using MPN
                $itemX = $request->asset->getItemByMPN('itemX');
                foreach ($request->asset->items as $item) {
                    if ($item->quantity > 1000000) {
                        $this->logger->info("Is Not possible to purchase product " . $item->id . " more than 1000000 time, requested: " . $item->quantity);
                        throw new \Connect\Fail("Is Not possible to purchase product " . $item->id . " more than 1000000 time, requested: " . $item->quantity);
                    }
                    else {
                        //Do some provisioning operation
                        //Update the parameters to store data
                        $paramsUpdate[] = new \Connect\Param('ActivationKey', 'somevalue');
                        $request->requestProcessor->fulfillment->updateParameters($request, $paramsUpdate);
                        //Potential actions to be done with a request:
                        // Set a parameter that requires changes and move request to inquire
                        if($requiresChanges){
                            throw new \Connect\Inquire([
                                new \Connect\Param([
                                     "id" => "email",
                                     "value_error" => "Invalid email"
                                ])
                             ]);
                        }
                        //Fail request
                        throw new \Connect\Fail("Request Can't be processed");
                        //Approve a template
                        //We may use a template defined on vendor portal as activation response, this will be what customer sees on panel
                        return new \Connect\ActivationTemplateResponse("TL-497-535-242");
                        // We may use arbitrary output to be returned as approval, this will be seen on customer panel. Please see that output must be in markup format
                        return new \Connect\ActivationTileResponse('\n# Welcome to Fallball!\n\nYes, you decided to have an account in our amazing service!\n\n');
                        // If we return empty, is approved with default message
                        return;
                    }
                }
            case "cancel":
                //Handle cancellation request
            case "change":
                //Handle change request
                //get added items:
                $newItems = $request->getNewItems();
                // get removed items:
                $removed = $request->getRemovedItems();
                // Get changed items, in other words the ones that quantity has been modified
                $changed = $request->getChangedItems();
            default:
                throw new \Connect\Fail("Operation not supported:".$request->type);
        }
    }

    public function processTierConfigRequest($tierConfigRequest){
        //This method allows processing Tier Requests, in same manner as simple requests.
        // Is required to be implemented since v15
    }
}

//Main Code Block

try {
    //In case Config is not passed into constructor, configuration from config.json is used
    $requests = new ProductRequests(new \Connect\Config([
        'apiKey' => 'Key_Available_in_ui',
        'apiEndpoint' => 'https://api.connect.cloudblue.com/public/v1',
        'products' => 'CN-631-322-641' #Optional value
    ]));
    
    $requests->process();
    
} catch (Exception $e) {
    
    print "Error processing requests:" . $e->getMessage();
}

使用文件报告简单示例

<?php

require_once "vendor/autoload.php";

class UploadUsage extends \Connect\UsageAutomation
{

    public function processUsageForListing($listing)
    {
        //Detect concrete Provider Contract
        if($listing->contract->id === 'CRD-41560-05399-123') {
            //This is for Provider XYZ, also can be seen from $listing->provider->id and parametrized further via marketplace available at $listing->marketplace->id
            date_default_timezone_set('UTC'); //reporting must be always based on UTC
            $usages = [];
            //Creating QT SCHEMA records, pplease check Connect\Usage\FileUsageRecord for further possible data to be passed
            array_push($usages, new Connect\Usage\FileUsageRecord([
                'record_id' => 'unique record value',
                'item_search_criteria' => 'item.mpn', //Possible values are item.mpn or item.local_id
                'item_search_value' => 'SKUA', //Value defined as MPN on vendor portal
                'quantity' => 1, //Quantity to be reported
                'start_time_utc' => date('d-m-Y H:i:s', strtotime("-1 days")), //From when to report
                'end_time_utc' => date("Y-m-d H:i:s"), //Till when to report
                'asset_search_criteria' => 'parameter.param_b', //How to find the asset on Connect, typical use case is to use a parameter provided by vendor, in this case called param_b, additionally can be used asset.id in case you want to use Connect identifiers
                'asset_search_value' => 'tenant2'
            ]));
            $usageFile = new \Connect\Usage\File([
                "period" => [
                        "from"=> date('Y-m-d H:i:s', strtotime("-1 days")),
                        "to"=> date("Y-m-d H:i:s")
                    ],
                'product' => new \Connect\Product(
                    ['id' => $listing->product->id]
                ),
                'contract' => new \Connect\Contract(
                    ['id' => $listing->contract->id]
                )
            ]);
            $this->usage->submitUsage($usageFile, $usages);
            return "processing done"
        }
        else{
            //Do Something different
        }
    }

}

//Main Code Block

try {
    
    $usageAutomation = new UploadUsage();
    $usageAutomation->process();

} catch (Exception $e) {
    print "Error processing usage for active listing requests:" . $e->getMessage();
}

自动化使用文件工作流简单示例

<?php

require_once "vendor/autoload.php";

class UsageFilesWorkflow extends \Connect\UsageFileAutomation
{
    
    public function processUsageFiles($usageFile)
    {
        switch ($usageFile->status){
            case 'invalid':
                //vendor and provider may handle invalid cases different, probably notifying their staff
                throw new \Connect\Usage\Delete("Not needed anymore");
                break;
            case 'ready':
                //Vendor may move to file to provider
                throw new \Connect\Usage\Submit("Ready for Provider");
            case 'pending':
                //Provider use case, needs to be reviewed and accept it
                throw new \Connect\Usage\Accept("File looks good");
            default:
                throw new \Connect\Usage\Skip("not valid status");
        }
    }
}

//Main Code Block

try {
    
    $usageWorkflow = new UsageFilesWorkflow();
    
    // is possible to ask to process all via parsing true, only applicable for
    // providers who automates own products
    $usageWorkflow->process(); 

} catch (Exception $e) {
    print "Error processing usage for active listing requests:" . $e->getMessage();
}

自动化层账户请求工作流简单示例

require_once "vendor/autoload.php";
class ProcessTAR extends \Connect\TierAccountRequestsAutomation
{
    public function processTierAccountRequest(\Connect\TierAccountRequest $request)
    {
        //$request is instance of \Connect\TierAccountRequest
       try{
            //Get changes
            $changes = $request->account->diffWithPreviousVersion();
            
            //Do something with external system to change TA data
            
            throw new \Connect\TierAccountRequestAccept("Proocessed");
       } 
       catch (Exception $e){
            throw new \Connect\TierAccountRequestIgnore("Issue while processing, we ignore");
        }
    }

}

//Main Code Block

try{
    $tarProcessor = new ProcessTar();
    $tarProcessor->process();
} catch (Exception $e) {
    print "error ".$e->getMessage();
}

客户端类

从 Connect PHP SDK 版本 17 开始引入客户端类。此类允许在 Connect 中运行多个操作,例如获取请求列表、配置等。可以从任何应用程序实例化客户端类以获取运行操作所需的信息,例如,在操作上下文中获取资产信息。客户端将提供访问权限

  • 目录
  • 履约
  • 层配置

创建客户端

以下是一个创建客户端的示例

<?php
require_once ("./vendor/autoload.php");

##Note that in case of no Configuration passed to constructor, system will check if config.json exists
$connect = new Connect\ConnectClient(new \Connect\Config([
    "apiKey" => "SU-677-956-738:ca95348138a3c122943ba968a9b69e42d30bde6c",
       "apiEndpoint" =>  "https://api.cnct.info/public/v1",
       "logLevel"=> 7,
       "timeout" =>  120,
       "sslVerifyHost"=> false
]));
$connect->directory->listTierConfigs()

Connect 客户端使用示例

  • 检索层配置
<?php
$connect = new Connect\ConnectClient();
$tierConfigurations = $connect->directory->listTierConfigs();
$tierConfigurations = $connect->directory->listTierConfigs(["account.id" => 'T-0-123123132123123']);
  • 检索层配置
<?php
$connect = new Connect\ConnectClient();
$tierConfiguration = $connect->directory->getTierConfigById('TC-000-000-000');
  • 检索资产列表
<?php
$connect = new Connect\ConnectClient();
$assets = $connect->directory->listAssets();
$assets = $connect->directory->listAssets(["product.id" => "PRD-XXXX-XXXX-XXXX"]);
  • 检索资产
<?php
$connect = new Connect\ConnectClient();
$asset = $connect->directory->getAssetById('AS-123-123-123');
  • 获取产品信息
<?php
$connect = new Connect\ConnectClient();
$products = $connect->directory->listProducts();
  • 获取产品信息
<?php
$connect = new Connect\ConnectClient();
$product = $connect->directory->getProduct('PRD-XXXX-XXXX-XXXX');
  • 列出所有请求

如果没有过滤器,则返回挂起的请求

<?php
$connect = new Connect\ConnectClient();
$requests = $connect->fulfillment->listRequests();
$requests = $connect->fulfillment->listRequests(['status' => 'approved']);
  • 获取具体请求
<?php
$connect = new Connect\ConnectClient();
$request = $connect->fulfillment->getRequest('PR-XXXX-XXXX-XXXXX');
  • 列出所有层级账户
<?php
$connect = new Connect\ConnectClient();
//List all tier accounts from a given marketplace
$tierAccounts = $connect->directory->listTierAccounts(['marketplace' => 'MP-XXXXXXX']);
  • 获取具体的层级账户
<?php
$connect = new Connect\ConnectClient();
$tierAccounts = $connect->directory->getTierAccountById('TA-XXXXXX-XXXXX');
  • 列出层级账户请求
<?php
$connect = new Connect\ConnectClient();
$tar = $connect->directory->listTierAccountRequests(['status' => 'pending']);
  • 列出资产订阅
<?php
$connect = new Connect\ConnectClient();
$billingAssets = $connect->subscriptions->listSubscriptionAssets();
  • 获取订阅资产
<?php
$connect = new Connect\ConnectClient();
$billingAsset = $connect->subscriptions->getSubscriptionAssetById('AS-1234-1234');
  • 获取计费订阅请求
<?php
$connect = new Connect\ConnectClient();
$billingRequests = $connect->subscriptions->listSubscriptionRequests();
  • 获取具体的计费请求
<?php
$connect = new Connect\ConnectClient();
$billingAsset = $connect->subscriptions->getSubscriptionRequestById('PR-XXXXX-XXXXX-XXXXX');