Skip to content
This repository was archived by the owner on May 10, 2018. It is now read-only.

PHP SDK: Load collections and entities #2

Merged
merged 12 commits into from
Jun 27, 2012
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,8 @@
# Generated documentation
docs/

# Generated code coverage report
coverage/

# Local settings
*.local.php
21 changes: 21 additions & 0 deletions Splunk/AmbiguousKeyException.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<?php
/**
* Copyright 2012 Splunk, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License"): you may
* not use this file except in compliance with the License. You may obtain
* a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*/

/**
* @package Splunk
*/
class Splunk_AmbiguousKeyException extends RuntimeException {}
73 changes: 73 additions & 0 deletions Splunk/AtomFeed.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
<?php
/**
* Copyright 2012 Splunk, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License"): you may
* not use this file except in compliance with the License. You may obtain
* a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*/

/**
* Contains utilities for parsing Atom feeds received from the Splunk REST API.
*
* @package Splunk
*/
class Splunk_AtomFeed
{
/** Name of the 's' namespace in Splunk Atom feeds. */
const NS_S = 'http://dev.splunk.com/ns/rest';

/**
* Parses and returns the value inside the specified XML element.
*
* @param SimpleXMLElement $containerXml
* @returns mixed
*/
public static function parseValueInside($containerXml)
{
$dictValue = $containerXml->children(Splunk_AtomFeed::NS_S)->dict;
$listValue = $containerXml->children(Splunk_AtomFeed::NS_S)->list;

if (Splunk_XmlUtil::elementExists($dictValue))
{
return Splunk_AtomFeed::parseDict($dictValue);
}
else if (Splunk_XmlUtil::elementExists($listValue))
{
return Splunk_AtomFeed::parseList($listValue);
}
else // value is scalar
{
return Splunk_XmlUtil::getTextContent($containerXml);
}
}

private static function parseDict($dictXml)
{
$dict = array();
foreach ($dictXml->children(Splunk_AtomFeed::NS_S)->key as $keyXml)
{
$key = Splunk_XmlUtil::getAttributeValue($keyXml, 'name');
$value = Splunk_AtomFeed::parseValueInside($keyXml);

$dict[$key] = $value;
}
return $dict;
}

private static function parseList($listXml)
{
$list = array();
foreach ($listXml->children(Splunk_AtomFeed::NS_S)->item as $itemXml)
$list[] = Splunk_AtomFeed::parseValueInside($itemXml);
return $list;
}
}
89 changes: 89 additions & 0 deletions Splunk/Collection.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
<?php
/**
* Copyright 2012 Splunk, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License"): you may
* not use this file except in compliance with the License. You may obtain
* a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*/

/**
* Represents a collection of entities accessible through Splunk's REST API.
*
* @package Splunk
*/
class Splunk_Collection extends Splunk_Endpoint
{
private $entries = NULL;

// === Load ===

protected function load()
{
$response = $this->service->get($this->path);
$xml = new SimpleXMLElement($response->body);

$entries = array();
foreach ($xml->entry as $entryData)
{
$entries[] = $this->loadEntry($entryData);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What does assigning to [] do?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It appends to the end of an array variable.

If the array variable does not exist, it creates it. My code always explicitly creates the array, so you shouldn't need to know that behavior.

}

$this->entries = $entries;
$this->loaded = TRUE;
}

private function loadEntry($entryData)
{
return new Splunk_Entity(
$this->service,
"{$this->path}/" . urlencode($entryData->title),
$entryData);
}

// === Children ===

/**
* Returns the unique entity with the specified name in this collection.
*
* @param string $name
* @return Splunk_Entity
* @throws Splunk_NoSuchKeyException
* @throws Splunk_AmbiguousKeyException
*/
public function get($name)
{
$results = array();
foreach ($this->validate()->entries as $entry)
{
if ($entry->getName() == $name)
{
$results[] = $entry;
}
}

if (count($results) == 0)
{
throw new Splunk_NoSuchKeyException(
"No value exists with key '{$name}'.");
}
else if (count($results) == 1)
{
return $results[0];
}
else
{
throw new Splunk_AmbiguousKeyException(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How can the user specify a namespace? Should get take a second, optional argument?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes I should. Namespace support is forthcoming.

"Multiple values exist with key '{$name}'. " .
"Specify a namespace to disambiguate.");
}
}
}
49 changes: 42 additions & 7 deletions Splunk/Context.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,25 +16,27 @@
*/

/**
* This class allows clients to issue HTTP requests to a Splunk server.
* Allows clients to issue HTTP requests to a Splunk server.
*
* @package Splunk
*/
class Splunk_Context
{
private $username;
private $password;
private $token;
private $host;
private $port;
private $scheme;
private $http;

private $token;

/**
* @param array $args {
* 'username' => (optional) The username to login with. Defaults to "admin".
* 'password' => (optional) The password to login with. Defaults to "changeme".
* 'token' => (optional) The authentication token to use. If provided,
* the username and password are ignored and there is no
* need to call login(). In the format "Splunk SESSION_KEY".
* 'host' => (optional) The hostname of the Splunk server. Defaults to "localhost".
* 'port' => (optional) The port of the Splunk server. Defaults to 8089.
* 'scheme' => (optional) The scheme to use: either "http" or "https". Defaults to "https".
Expand All @@ -46,6 +48,7 @@ public function __construct($args)
$args = array_merge(array(
'username' => 'admin',
'password' => 'changeme',
'token' => NULL,
'host' => 'localhost',
'port' => 8089,
'scheme' => 'https',
Expand All @@ -54,6 +57,7 @@ public function __construct($args)

$this->username = $args['username'];
$this->password = $args['password'];
$this->token = $args['token'];
$this->host = $args['host'];
$this->port = $args['port'];
$this->scheme = $args['scheme'];
Expand All @@ -72,11 +76,25 @@ public function login()
'password' => $this->password,
));

$sessionKey = Splunk_Util::getTextContentAtXpath(
new SimpleXMLElement($response['body']),
$sessionKey = Splunk_XmlUtil::getTextContentAtXpath(
new SimpleXMLElement($response->body),
'/response/sessionKey');

$this->token = 'Splunk ' . $sessionKey;
$this->token = "Splunk {$sessionKey}";
}

/**
* Performs an HTTP GET request to the endpoint at the specified path.
*
* @param string $path relative or absolute URL path.
* @return array
* @see Splunk_Http::get
*/
public function get($path)
{
return $this->http->get($this->url($path), array(
'Authorization' => $this->token,
));
}

// === Accessors ===
Expand All @@ -92,8 +110,25 @@ public function getToken()

// === Utility ===

/**
* @param string $path relative or absolute URL path.
* @return string absolute URL.
*/
private function url($path)
{
return "{$this->scheme}://{$this->host}:{$this->port}{$path}";
return "{$this->scheme}://{$this->host}:{$this->port}{$this->abspath($path)}";
}

/**
* @param string $path relative or absolute URL path.
* @return string absolute URL path.
*/
private function abspath($path)
{
if ((strlen($path) >= 1) && ($path[0] == '/'))
return $path;

// TODO: Support namespaces
return "/services/{$path}";
}
}
55 changes: 55 additions & 0 deletions Splunk/Endpoint.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
<?php
/**
* Copyright 2012 Splunk, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License"): you may
* not use this file except in compliance with the License. You may obtain
* a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*/

/**
* Represents a single endpoint in the Splunk REST API.
*
* @package Splunk
*/
abstract class Splunk_Endpoint
{
protected $service;
protected $path;

protected $loaded = FALSE;

public function __construct($service, $path)
{
$this->service = $service;
$this->path = $path;
}

// === Load ===

/** Loads this resource if not already done. Returns self. */
protected function validate()
{
if (!$this->loaded)
{
$this->load();
assert($this->loaded);
}
return $this;
}

/**
* Loads this resource.
*
* Implementations must set $this->loaded to TRUE before returning.
*/
protected abstract function load();
}
Loading