1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48: 49: 50: 51: 52: 53: 54: 55: 56: 57: 58: 59: 60: 61: 62: 63: 64: 65: 66: 67: 68: 69: 70: 71: 72: 73: 74: 75: 76: 77: 78: 79: 80: 81: 82: 83: 84: 85: 86: 87: 88: 89: 90: 91: 92: 93: 94: 95: 96: 97: 98: 99: 100: 101: 102: 103: 104: 105: 106: 107: 108: 109: 110: 111: 112: 113: 114: 115: 116: 117: 118: 119: 120: 121: 122: 123: 124: 125: 126: 127: 128: 129: 130: 131: 132: 133: 134: 135: 136: 137: 138: 139: 140: 141: 142: 143: 144: 145: 146: 147: 148: 149: 150: 151: 152: 153: 154: 155: 156: 157: 158: 159: 160: 161: 162: 163: 164: 165: 166: 167: 168: 169: 170: 171: 172: 173: 174: 175: 176: 177: 178: 179: 180: 181: 182: 183: 184: 185: 186: 187: 188: 189: 190: 191: 192: 193: 194: 195: 196: 197: 198: 199: 200: 201: 202: 203: 204: 205: 206: 207: 208: 209: 210: 211: 212: 213: 214: 215: 216: 217: 218: 219: 220: 221: 222: 223: 224: 225: 226: 227: 228: 229: 230: 231: 232: 233: 234: 235: 236: 237: 238: 239: 240: 241: 242: 243: 244: 245: 246: 247: 248: 249: 250: 251: 252: 253: 254: 255: 256: 257: 258: 259: 260: 261: 262: 263: 264: 265: 266: 267: 268: 269: 270: 271: 272: 273:
<?php
namespace Apptus\ESales\Connector;
use Apptus\Util\Cache\SQLite3StateCache;
use Apptus\Util\Cache\StateCache;
use Apptus\Util\Http\ClientFactory;
/**
* Connector for on-premise instances of Apptus eSales.
*
* This class acts as a facade to the connector library. All requests to the eSales service are initiated by method calls to a
* connector object, or an object obtained via the connector.
*
*/
class OnPremConnector extends Connector {
/**
* Creates a connector for the given eSales cluster URI.
*
* The URI should be on the following format:
*
* esales://host1[:port1][;host2[:port2][;...]][?parameter1=value1[¶meter2=value2[&...]]]
*
* Example: esales://node1.apptus.com;node2.apptus.com:35811?query_timeout=3500¬ification_timeout=3500
*
* Unspecified ports defaults to 35810.
*
* The available parameters are:
* <ul>
* <li>connection_timeout - the connection timeout in milliseconds, default 2000</li>
* <li>query_timeout - the query timeout in milliseconds, default 3000</li>
* <li>export_timeout - the export timeout in milliseconds, default 60000</li>
* <li>import_timeout - the import timeout in milliseconds, default 600000</li>
* <li>notification_timeout - the notification timeout in milliseconds, default 3000</li>
* <li>health_check_timeout - the health check timeout in milliseconds, default 500</li>
* <li>compression_mode - what compression should be used when sending imports. Available settings:
* <ul>
* <li>none - No compression.</li>
* <li>gzip - Compress with GZIP. This is the default.</li>
* <li>pre_compressed_gzip - Send headers to indicate the import is compressed with GZIP, but don't do any compression.
* Use this if the file or InputStream you supply is already compressed.</li>
* </ul>
* Note that files with names that end with ".gz" or ".gzip" will behave as if compression_mode=pre_compressed_gzip,
* regardless of what compression_mode is actually set to.
* </li>
* </ul>
*
* Parameter values must be URL encoded in order to avoid ambiguity.
*
* @param string
* The base URI to an eSales cluster.
* @param \Apptus\Util\Cache\StateCache
* An instance of an object implementing the {@link StateCache} interface.
* Defaults to an SQLite3StateCache using the file 'esales.statecache' in the current working directory.
* @throws MalformedURLException if the given URL is malformed in some way.
* @return OnPremConnector
* A connector instance.
*/
public function __construct($uri, StateCache $stateCache = null) {
if ($stateCache === null) {
$testResult = SQLite3StateCache::testSQLite('esales.statecache');
if ($testResult !== true) {
throw new \InvalidArgumentException('No StateCache given, and SQLite3 test returned the following problem: ' . $testResult);
}
$stateCache = new SQLite3StateCache('esales.statecache');
}
$secureCluster = new OnPremCluster($uri, $stateCache);
parent::__construct($secureCluster, $secureCluster);
}
/**
* Defines a cluster. The format of the cluster string is <host>:<port>;<host>:<port>;...
* @param string
* A string defining a cluster.
* @throws BusyClusterException if the cluster is busy with another task
* @throws RequestFailedException
*/
public static function defineCluster($clusterString) {
$clusterString = (string) $clusterString;
$nodes = explode(';', $clusterString);
$nodeParts = explode(':', $nodes[0]);
if (count($nodeParts) !== 2) {
throw new \InvalidArgumentException('Invalid cluster string: ' . $clusterString);
}
$port = (int) $nodeParts[1];
if ($port < 1 || $port >= (1 << 16)) {
throw new \InvalidArgumentException('Invalid port number: ' . $nodeParts[1]);
}
$args = array ('cluster' => $clusterString);
try {
$client = ClientFactory::instance()->create($nodeParts[0], $port, false);
$client->setUserAgent(HttpRequestHelper::buildUserAgent('OnPrem'));
$response = $client->postAndGetBytes('/esales/cluster/define_cluster', $args, null, null);
} catch (\Apptus\Util\Http\ClientCreationException $e) {
throw new RequestFailedException('', $e);
} catch (\Apptus\Util\Http\RequestFailedException $e) {
throw new RequestFailedException('', $e);
}
self::readLongQueryResponse($response);
}
/**
* Synchronizes all eSales Servers in the eSales cluster.
*
* When ignore is set to true any inconsistencies between eSales Servers in the eSales
* cluster are ignored by clearing the update history on all servers.
*
* @param boolean
* True if inconsistencies in the cluster should be ignored.
* @throws BusyClusterException if the cluster is busy with another task
* @throws RequestFailedException if the request to the cluster fails.
*/
public function synchronize($ignore = false) {
$args = array ();
if ($ignore) {
$args['ignore'] = 'true';
}
$response = $this->secureCluster->postAndGet('/esales/cluster/synchronize', $args, null, null);
self::readLongQueryResponse($response);
}
/**
* Return query statistics for the specified eSales Server.
*
* @param int
* The (0-based) index of the eSales Server.
* @throws \InvalidArgumentException if there is no server for the given index.
* @throws RequestFailedException if the request to the server fails.
* @return string
* A string containing query statistics in the form of an XML document.
*/
public function queryStatistics($qp) {
$args = array ('_xsl' => '');
return $this->secureCluster->getFromQP($qp, '/querystats/display', $args);
}
/**
* Defragments the eSales Servers in the eSales cluster.
*
* @throws BusyClusterException if the cluster is busy with another task
* @throws RequestFailedException if the request to the cluster fails.
*/
public function defragment() {
$response = $this->secureCluster->postAndGet('/esales/cluster/defrag', array (), null, null);
self::readLongQueryResponse($response);
}
/**
* Return a list of available attribute types from the eSales cluster. Never returns null.
*
* @throws RequestFailedException if the request to the cluster fails.
* @return array
* An indexed array of type names.
*/
public function availableAttributeTypes() {
$result = $this->secureCluster->query('/esales/attribute_types');
return TypeParser::parse($result); // TODO: Unmodifiable?
}
/**
* Always returns an empty list.
*
* @deprecated No longer of any use.
* @return array
* An empty array.
*/
public function availableStringRules() {
return array();
}
/**
* Always returns an empty list.
*
* @deprecated No longer of any use.
* @return array
* An empty array.
*/
public function availableScanRules() {
return array();
}
/**
* Gets a list of the name of all product and variant attributes that has been imported to eSales.
*
* @return array An indexed array of product and variant attribute names.
* @throws RequestFailedException
*/
public function availableProductAttributes() {
$xml = $this->secureCluster->query('/esales/attributes');
return AttributeParser::productAttributes($xml);
}
/**
* Gets a list of the name of all ad attributes that has been imported to eSales.
*
* @return array An indexed array of ad attribute names.
* @throws RequestFailedException
*/
public function availableAdAttributes() {
$xml = $this->secureCluster->query('/esales/attributes');
return AttributeParser::adAttributes($xml);
}
/**
* Executes a panel from the specified panel definition.
*
* If a role is specified, then only the part of the panel specified by
* the role is executed.
*
* The arguments is always applied to the entire named panel.
*
* @param string
* The panel definition, as a string with an XML document.
* @param string
* The panel to execute.
* @param string
* The part of the panel the return results from.
* @param ArgMap|array|null
* The arguments of the panel.
* @throws ClusterUnavailableException if the request to the cluster fails.
* @throws RequestFailedException if the request fails in a way that indicate a client error.
* @return string
* The result as an XML document.
*/
public function testPanel($panelXml, $panel, $role, $arguments) {
$args = array (
'session_key' => 'TEST',
'event_number' => '1',
);
if ($arguments == null) {
$arguments = array ();
} elseif ($arguments instanceof ArgMap) {
$arguments = $arguments->getArgs();
}
foreach ($arguments as $k => $v) {
$args[$k] = $v;
}
$args['role'] = $role;
return $this->secureCluster->postAndGet('/esales/test/panels' . $panel, $args, null, $panelXml);
}
/**
* Executes a panel from the specified panel definition and parse the resulting XML.
*
* If a role is specified, then only the part of the panel specified by
* the role is executed.
*
* The arguments is always applied to the entire named panel.
*
* @param string
* The panel definition, as a string with an XML document.
* @param string
* The panel to execute.
* @param string
* The part of the panel the return results from.
* @param ArgMap|array|null
* The arguments of the panel.
* @throws ClusterUnavailableException if the request to the cluster fails.
* @throws RequestFailedException if the request fails in a way that indicate a client error.
* @return PanelContent
* The result as a PanelContent object.
*/
public function testPanelAndParse($panelXml, $panel, $role, $arguments) {
$response = $this->testPanel($panelXml, $panel, $role, $arguments);
$parser = new PanelParser(Path::root());
return $parser->parse($response);
}
}