Skip to content

Instantly share code, notes, and snippets.

@ernestom
Created May 1, 2015 04:32
Show Gist options
  • Save ernestom/c7d423b8f85d75f76588 to your computer and use it in GitHub Desktop.
Save ernestom/c7d423b8f85d75f76588 to your computer and use it in GitHub Desktop.
Akamai's CCU REST API abstraction library.
<?php
/**
* Simple abstraction for the Akamai's REST CCU API,
* to make fire-and-forget purge requests.
*
* @see https://api.ccu.akamai.com/ccu/v2/docs/
* @author Menta Network - www.menta.mx <dev@menta.com.mx>
* @license MIT License
*/
namespace AkamaiCCU;
/**
* Requests a CCU operation through Akamai's REST API.
*
* <?php
*
* require 'ccu.php';
* use AkamaiCCU\Request;
*
* Example usage:
* // Staging request
* $request = new Request('myUserName', 'p4ssw0rdZ');
* $request->useStaging()->invalidate(array(
* 'http://example.org/a/b/c.html',
* 'http://example.org/img/a.jpg'
* ));
*
* // Production request
* $request = new Request('myUserName', 'p4ssw0rdZ');
* $request->invalidate(array(
* 'http://example.org/a/b/c.html',
* 'http://example.org/img/a.jpg'
* ));
*
* ?>
*''
* Successful response example:
* {
* "httpStatus" : 201,
* "detail" : "Request accepted.",
* "estimatedSeconds" : 420,
* "purgeId" : "95b5a092-043f-4af0-843f-aaf0043faaf0",
* "progressUri" : "/ccu/v2/purges/95b5a092-043f-4af0-843f-aaf0043faaf0",
* "pingAfterSeconds" : 420,
* "supportId" : "17PY1321286429616716-211907680"
* }
*
* Failed response example:
*
* {
* "supportId" : "17PY1366767251622255-198714464",
* "title" : "unauthorized cpcode",
* "httpStatus" : 403,
* "detail" : "999",
* "describedBy" : "https://api.ccu.akamai.com/ccu/v2/errors/unauthorized-cpcode"
* }
*
*
*/
class Request
{
const BASE_URL = 'https://api.ccu.akamai.com';
const PURGE_QUEUE_ENDPOINT = '/ccu/v2/queues/default';
// Available `domain` values
const DOMAIN_PRODUCTION = 'production';
const DOMAIN_STAGING = 'staging';
// Available `type` values
const TYPE_CPCODE = 'cpcode';
const TYPE_ARL = 'arl';
// Available `action` values
const PURGE_ACTION_REMOVE = 'remove';
const PURGE_ACTION_INVALIDATE = 'invalidate';
protected $_domain;
protected $_type;
protected $_action;
protected $_objects;
protected $_userName;
protected $_password;
/** A response object with the properties: headers, body, and json */
public $response;
/**
* POSTs the given `$data` to the `$url` with the provided `$headers`.
* @param string $url
* @param array $data
* @param array $headers Optional.
* @return object A response object with the properties: headers, body, and json.
*/
protected function _postJSON($url, array $data, $headers = array())
{
$defaultHeaders = $headers = array(
'Content-type: application/json',
$this->_getAuthHeader(),
);
$headers = array_merge($headers, $defaultHeaders);
$channel = curl_init();
curl_setopt($channel, CURLOPT_URL, $url);
curl_setopt($channel, CURLOPT_HTTPHEADER, $headers);
curl_setopt($channel, CURLOPT_POST, true);
curl_setopt($channel, CURLOPT_HEADER, true);
curl_setopt($channel, CURLOPT_POSTFIELDS, json_encode($data));
curl_setopt($channel, CURLOPT_RETURNTRANSFER, true);
$response = curl_exec($channel);
list($headers, $body) = explode("\r\n\r\n", $response, 2);
curl_close($channel);
return (object) array(
'headers' => explode("\n", trim($headers)),
'body' => $body,
'json' => json_decode($body)
);
}
/**
* Returns the HTTP Basic Auth header.
* @return string
*/
protected function _getAuthHeader()
{
$credential = base64_encode($this->_userName . ':' . $this->_password);
return 'Authorization: Basic ' . $credential;
}
/**
* Performs a purge request for the given `$objects`.
* @param array $objects
* @param string $action a Valid `action` value
*/
protected function _requestPurge(array $objects, $action)
{
$validActions = array(
self::PURGE_ACTION_REMOVE,
self::PURGE_ACTION_INVALIDATE
);
if (empty($objects)) {
throw new \InvalidArgumentException('$objects must not be empty');
}
if ($this->_type == self::TYPE_CPCODE) {
foreach ($objects as $obj) {
if (!is_numeric($obj)) {
throw new \InvalidArgumentException(
'Invalid CPCode in $objects: ' . $obj
);
}
}
}
if (!in_array($action, $validActions)) {
throw new \InvalidArgumentException('Invalid $action ' . $action);
}
$this->_action = $action;
$this->_objects = $objects;
$url = self::BASE_URL . self::PURGE_QUEUE_ENDPOINT;
$data = array(
'domain' => $this->_domain,
'type' => $this->_type,
'action' => $this->_action,
'objects' => $this->_objects
);
$this->response = $this->_postJSON($url, $data);
}
/**
* Constructor.
* @param string $userName
* @param string $password
* @param string $type Optional. A valid `type` value.
*/
public function __construct($userName, $password, $type = null)
{
if (empty($userName) || empty($password)) {
throw new \InvalidArgumentException('$userName and $password are required');
}
$this->_userName = $userName;
$this->_password = $password;
$validTypes = array(self::TYPE_ARL, self::TYPE_CPCODE);
if ($type) {
if (!in_array($type, $validTypes)) {
throw new InvalidArgumentException('Invalid $type ' . $type);
}
$this->_type = $type;
} else {
$this->_type = self::TYPE_ARL;
}
$this->_domain = self::DOMAIN_PRODUCTION;
}
/**
* Instructs the request to be made on Akamai's staging network,
* by setting the `domain`.
* Chainable method.
* @return AkamaiCCURequest
*/
public function useStaging()
{
$this->_domain = self::DOMAIN_STAGING;
return $this;
}
/**
* Invalidates the provided objects.
* @param array $objects
*/
public function invalidate(array $objects)
{
$this->_requestPurge($objects, self::PURGE_ACTION_INVALIDATE);
}
/**
* Removes the provided objects.
* @param array $objects
*/
public function remove(array $objects)
{
$this->_requestPurge($objects, self::PURGE_ACTION_REMOVE);
}
}
<?php
require 'akamaiccu.php';
use AkamaiCCU\Request;
// Test variables
$userName = 'myUserName';
$password = 'p4s5w0rdZ';
$cpcode = '12345';
$urls = array(
'http://example.org/a/b/c.html',
'http://example.org/img/a.jpg'
);
// Staging request - ARL
$request = new Request($userName, $password);
$request->useStaging()->invalidate($urls);
print_r($request->response);
// Production request - ARL
$request = new Request($userName, $password);
$request->invalidate($urls);
print_r($request->response);
// Production request - CPCode
$request = new Request($userName, $password, Request::TYPE_CPCODE);
$request->invalidate(array($cpcode));
print_r($request->response);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment