Skip to content

Commit

Permalink
Merge pull request kaltura#812 from kaltura/IX-9.8.0-PLAT-527
Browse files Browse the repository at this point in the history
KalturaFrontController - save the serialized multirequest results
  • Loading branch information
yossipapi committed Feb 3, 2014
2 parents 2bb0b95 + 58dc585 commit 9345f0d
Show file tree
Hide file tree
Showing 7 changed files with 181 additions and 80 deletions.
2 changes: 2 additions & 0 deletions alpha/apps/kaltura/lib/webservices/APIErrors.class.php
Original file line number Diff line number Diff line change
Expand Up @@ -409,4 +409,6 @@ public static function getErrorData( $errorString, $errorArgsArray = array() )
const ERROR_OCCURED_WHILE_GZUNCOMPRESS_JOB_DATA = "ERROR_OCCURED_WHILE_GZUNCOMPRESS_JOB_DATA;; error accored while gzuncompress job data";

const OBJECT_NOT_FOUND = "OBJECT_NOT_FOUND;;Object not found";

const UNKNOWN_RESPONSE_FORMAT = "UNKNOWN_RESPONSE_FORMAT;FORMAT;Response format provided [@FORMAT@] is not recognized by server";
}
174 changes: 95 additions & 79 deletions api_v3/lib/KalturaFrontController.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ class KalturaFrontController
private $service = "";
private $action = "";
private $disptacher = null;
private $serializer;

private function KalturaFrontController()
{
Expand Down Expand Up @@ -88,6 +89,13 @@ public function run()
set_error_handler(array(&$this, "errorHandler"));

KalturaLog::debug("Params [" . print_r($this->params, true) . "]");
try {
$this->setSerializerByFormat();
}
catch (Exception $e) {
return new kRendererDieError($e->getCode(), $e->getMessage());
}

if ($this->service == "multirequest")
{
set_exception_handler(null);
Expand All @@ -111,24 +119,21 @@ public function run()

$this->onRequestEnd($success, $errorCode);
}

if (isset($_REQUEST["ignoreNull"]))
$ignoreNull = ($_REQUEST["ignoreNull"] === "1") ? true : false;
else
$ignoreNull = false;

ob_end_clean();

$this->end = microtime(true);

return $this->serializeResponse($result, $ignoreNull);
return $this->serializeResponse($result);
}

public function handleMultiRequest()
{
// arrange the parameters by request index
$commonParams = array();
$listOfRequests = array();
$dependencies = array();
$pastResults = array();
foreach ($this->params as $paramName => $paramValue)
{
$explodedName = explode(':', $paramName, 2);
Expand All @@ -145,6 +150,16 @@ public function handleMultiRequest()
$listOfRequests[$requestIndex] = array();
}
$listOfRequests[$requestIndex][$paramName] = $paramValue;

$matches = array();
if (preg_match('/\{([0-9]*)\:result\:?(.*)?\}/', $paramValue, $matches))
{
$pastResultsIndex = $matches[0];
$resultIndex = $matches[1];
$resultKey = $matches[2];
if(!isset($dependencies[$requestIndex][$pastResultsIndex]))
$dependencies[$resultIndex][$pastResultsIndex] = $resultKey;
}
}

// process the requests
Expand Down Expand Up @@ -174,34 +189,14 @@ public function handleMultiRequest()
{
$currentParams['partnerId'] = $commonParams['partnerId'];
}
// check if we need to replace params with prev results

// check if we need to replace params with prev results
foreach($currentParams as $key => &$val)
{
$matches = array();

// keywords: multirequest, result, depend, pass
// figuring out if requested params should be extracted from previous result
// example: if you want to use KalturaPlaylist->playlistContent result from the first request
// in your second request, the second request will contain the following value:
// {1:result:playlistContent}
if (preg_match('/\{([0-9]*)\:result\:?(.*)?\}/', $val, $matches))
{
$resultIndex = $matches[1];
$resultKey = $matches[2];

if (count($results) >= $resultIndex) // if the result index is valid
{
if (strlen(trim($resultKey)) > 0)
$resultPathArray = explode(":",$resultKey);
else
$resultPathArray = array();

$val = $this->getValueFromObject($results[$resultIndex], $resultPathArray);
}
}
if(isset($pastResults[$val]))
$val = $pastResults[$val];
}

// cached parameters should be different when the request is part of a multirequest
// as part of multirequest - the cached data is a serialized php object
// when not part of multirequest - the cached data is the actual response
Expand Down Expand Up @@ -239,8 +234,22 @@ public function handleMultiRequest()
$cache->storeCache($currentResult, "", true);
}
$this->onRequestEnd($success, $errorCode, $i);

if(isset($dependencies[$i]))
{
foreach($dependencies[$i] as $currentDependency => $dependencyName)
{
if (strlen(trim($dependencyName)) > 0)
$resultPathArray = explode(":",$dependencyName);
else
$resultPathArray = array();

$currValue = $this->getValueFromObject($currentResult, $resultPathArray);
$pastResults[$currentDependency] = $currValue;
}
}

$results[$i] = $currentResult;
$results[$i] = $this->serializer->serialize($currentResult);

// in case a serve action is included in a multirequest, return only the result of the serve action
// in order to avoid serializing the kRendererBase object and returning the internal server paths to the client
Expand Down Expand Up @@ -398,16 +407,13 @@ public function getExceptionObject($ex)
}


public function serializeResponse($object, $ignoreNull = false)
public function setSerializerByFormat()
{
if ($object instanceof kRendererBase)
{
return $object;
}
if (isset($this->params["ignoreNull"]))
$ignoreNull = ($this->params["ignoreNull"] === "1") ? true : false;
else
$ignoreNull = false;

$start = microtime(true);
KalturaLog::debug("Serialize start");

// Determine the output format (or default to XML)
$format = isset($this->params["format"]) ? $this->params["format"] : KalturaResponseType::RESPONSE_TYPE_XML;

Expand All @@ -434,51 +440,61 @@ public function serializeResponse($object, $ignoreNull = false)
$serializer = KalturaPluginManager::loadObject('KalturaSerializer', $format);
break;
}

if(empty($serializer))
throw new KalturaAPIException(APIErrors::UNKNOWN_RESPONSE_FORMAT, $format);

$this->serializer = $serializer;
}

public function serializeResponse($object)
{
if ($object instanceof kRendererBase)
{
return $object;
}

$start = microtime(true);
KalturaLog::debug("Serialize start");

if ( ! empty( $serializer ) ) // Got a serializer for the given format?
// Set HTTP headers
if(isset($this->params['content-type']))
{
// Set HTTP headers
if(isset($this->params['content-type']))
{
header('Content-Type: ' . $this->params['content-type']);
}
else
{
$serializer->setHttpHeaders();
}
header('Content-Type: ' . $this->params['content-type']);
}
else
{
$this->serializer->setHttpHeaders();
}

// Serialize the object
$serializedObject = $serializer->serialize($object);
// Check if this is multi request if yes than object are already serialized so we will skip otherwise serialize the object
if ($this->service != "multirequest")
$serializedObject = $this->serializer->serialize($object);
else
$serializedObject = $this->handleSerializedObjectArray($object);

// Post processing (handle special cases)
switch($format)
{
case KalturaResponseType::RESPONSE_TYPE_XML:
$result =
'<?xml version="1.0" encoding="utf-8"?>' .
'<xml>' .
'<result>' .
$serializedObject .
'</result>' .
'<executionTime>' . ($this->end - $this->start) . '</executionTime>' .
'</xml>';
break;

case KalturaResponseType::RESPONSE_TYPE_JSONP:
$callback = isset($_GET["callback"]) ? $_GET["callback"] : null;
if (is_null($callback))
die("Expecting \"callback\" parameter for jsonp format");
$response = array();
$result = $callback . "(" . $serializedObject . ");";
break;

default:
$result = $serializedObject;
break;
}
}
// Post processing (handle special cases)
$result = $this->serializer->getHeader() . $serializedObject . $this->serializer->getFooter($this->end - $this->start);

KalturaLog::debug("Serialize took - " . (microtime(true) - $start));
return $result;
}

public function handleSerializedObjectArray($objects)
{
$objectsCount = count($objects);
$serializedObject = '';
$serializedObject .= $this->serializer->getMulitRequestHeader($objectsCount);
for($i = 1 ; $i <= $objectsCount; $i++)
{
$serializedObject .= $this->serializer->getItemHeader($i-1);
$serializedObject .= $objects[$i];
//check if item is the last one to avoid putting footer chars in json and jsonp serializers
$lastItem = ($i == $objectsCount);
$serializedObject .= $this->serializer->getItemFooter($lastItem);
}
$serializedObject .= $this->serializer->getMulitRequestFooter();

return $serializedObject;
}
}
15 changes: 15 additions & 0 deletions api_v3/lib/KalturaJsonProcSerializer.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,19 @@ public function setHttpHeaders()
{
header("Content-Type: application/javascript");
}

public function getHeader()
{
$callback = isset($_GET["callback"]) ? $_GET["callback"] : null;
if (is_null($callback))
die("Expecting \"callback\" parameter for jsonp format");
$response = array();

return $callback . "(";
}

public function getFooter($execTime = null)
{
return ");";
}
}
18 changes: 18 additions & 0 deletions api_v3/lib/KalturaJsonSerializer.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,4 +15,22 @@ function serialize($object)
$object = parent::prepareSerializedObject($object);
return json_encode($object);
}

public function getItemFooter($lastItem = false)
{
if(!$lastItem)
return ',';

return '';
}

public function getMulitRequestHeader($itemsCount = null)
{
return '[';
}

public function getMulitRequestFooter()
{
return ']';
}
}
15 changes: 15 additions & 0 deletions api_v3/lib/KalturaPhpSerializer.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,19 @@ function serialize($object)
$result = serialize($object); // Let PHP's built-in serialize() function do the work
return $result;
}

public function getItemHeader($itemIndex = null)
{
return 'i:' .$itemIndex . ';';
}

public function getMulitRequestHeader($itemsCount = null)
{
return 'a:' . $itemsCount . ':{';
}

public function getMulitRequestFooter()
{
return '}';
}
}
10 changes: 9 additions & 1 deletion api_v3/lib/KalturaSerializer.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,15 @@ protected function prepareSerializedObject($object)

public function setHttpHeaders() {}

public function serialize($object) { return ''; }
abstract public function serialize($object);

public function getHeader() { return '';}
public function getMulitRequestHeader($itemsCount = null) { return '';}
public function getItemHeader($itemIndex = null) { return '';}

public function getFooter($execTime = null) { return '';}
public function getMulitRequestFooter() { return '';}
public function getItemFooter($lastItem = false) { return '';}

protected function convertExceptionsToPhpArrays($object)
{
Expand Down
27 changes: 27 additions & 0 deletions api_v3/lib/KalturaXmlSerializer.php
Original file line number Diff line number Diff line change
Expand Up @@ -168,4 +168,31 @@ function writeTag($tag, $value)
echo $value;
echo '</'.$tag.'>';
}

public function getHeader()
{
return '<?xml version="1.0" encoding="utf-8"?>' .
'<xml>' .
'<result>' ;
}

public function getFooter($execTime = null)
{
if(is_null($execTime))
$execTime = 0;

return '</result>' .
'<executionTime>' . $execTime . '</executionTime>' .
'</xml>';
}

public function getItemHeader($itemIndex = null)
{
return '<item>';
}

public function getItemFooter($lastItem = false)
{
return '</item>';
}
}

0 comments on commit 9345f0d

Please sign in to comment.