Skip to content

Commit

Permalink
[TASK] Implement core admin api for solarium (#625)
Browse files Browse the repository at this point in the history
Resolves: #624
  • Loading branch information
timohund authored and Markus Kalkbrenner committed Sep 14, 2018
1 parent 54cad6a commit e8cf9e4
Show file tree
Hide file tree
Showing 49 changed files with 2,566 additions and 17 deletions.
2 changes: 2 additions & 0 deletions .travis.yml
Expand Up @@ -29,6 +29,8 @@ before_script:
# - pecl install pecl_http
- composer require --prefer-source --dev symfony/event-dispatcher:${SYMFONY_VERSION}
- solr-${SOLR_VERSION}/bin/solr start -e techproducts
# make configSet's available for techproducts instance
- cp -R solr-${SOLR_VERSION}/server/solr/configsets solr-${SOLR_VERSION}/example/techproducts/solr/

script:
- vendor/bin/phpunit -c phpunit.xml.travis -v
Expand Down
191 changes: 191 additions & 0 deletions docs/queries/server-query/core-admin-query.md
@@ -0,0 +1,191 @@
Core admin queries can be used to administrate cores on your solr server (https://lucene.apache.org/solr/guide/7_4/coreadmin-api.html)

The core admin api on the Apache Solr server has several "actions" available and every action can have a set of arguments.

Building an core admin query
----------------------------

The following example shows how your can build a core admin query that executes the status action:

```php
<?php

require(__DIR__.'/init.php');
htmlHeader();

// create a client instance
$client = new Solarium\Client($config);

// create a core admin query
$coreAdminQuery = $client->createCoreAdmin();

// use the core admin query to build a Status action
$statusAction = $coreAdminQuery->createStatus();
$statusAction->setCore('techproducts');
$coreAdminQuery->setAction($statusAction);

$response = $client->coreAdmin($coreAdminQuery);
$statusResult = $response->getStatusResult();

echo '<b>Core admin status action execution:</b><br/>';
echo 'Uptime of the core ( ' .$statusResult->getCoreName(). ' ): ' . $statusResult->getUptime();

htmlFooter();
```

Beside the **status** action there are several actions available that can be created with the create***ActionName()*** method.


Available actions
-----------------

The api implements the following actions

Create
======

Use to create a new core.

**Available action methods**:

| Name | Arguments | Description |
|-------------------|-------------------------------|---------------------------------------------------------------|
| setAsync | string $async | Identifier for async execution to request the status later |
| setCore | string $core | Name of the core |
| setInstanceDir | string $instanceDir | Instance dir that should be used |
| setConfig | string $config | Name of the config file relative to the instanceDir |
| setSchema | string $schema | Name of the schema file |
| setDataDir | string $dataDir | Name of the dataDir relative to the instance dir |
| setConfigSet | string $configSet | Name of the configSet that should be used |
| setCollection | string $collection | Name of the collection where this core belongs to |
| setShard | string $shard | ShardId that this core represents |
| setCoreProperty | string $name, string $value | Entry for the core.properties file, can be used n times |


MergeIndexes
============

Use to merge cores.

**Available action methods**:

| Name | Arguments | Description |
|-------------------|-------------------------------|---------------------------------------------------------------|
| setAsync | string $async | Identifier for async execution to request the status later |
| setCore | string $core | Name of the core where the data should be merged into |
| setIndexDir | array $indexDir | Array of index directories that should be merged |
| setSrcCore | array $srcCore | Array of source cores that should be merged |


Reload
======

Use to reload a core.

**Available action methods**:

| Name | Arguments | Description |
|-------------------|-------------------------------|---------------------------------------------------------------|
| setCore | string $core | Name of the core that should be reloaded |

Rename
======

Use to rename a core.

**Available action methods**:

| Name | Arguments | Description |
|-------------------|-------------------------------|---------------------------------------------------------------|
| setAsync | string $async | Identifier for async execution to request the status later |
| setCore | string $core | Name of the core that should be renamed |
| setOther | string $otherCoreName | New name of the core |


RequestRecovery
===============

Use to recover a core.

**Note**: Only relevant for solrcloud where cores are shards and a cover can be recovered from the leader (a copy of that core on another node)

**Available action methods**:

| Name | Arguments | Description |
|-------------------|-------------------------------|---------------------------------------------------------------|
| setCore | string $core | Name of the core that should be recovered |


RequestStatus
=============

Use to get the status from an asynchronous request. When you have previously passed an async identifier for another action,
RequestStatus can be used later to retrieve the state for that asynchronous action.

**Available action methods**:

| Name | Arguments | Description |
|-------------------|-------------------------------|---------------------------------------------------------------|
| setRequestId | string $requestId | Id of the asynchronous request that was previously executed. |

Split
=====

Use to split a core.

See also: https://lucene.apache.org/solr/guide/7_4/coreadmin-api.html#coreadmin-split

**Available action methods**:

| Name | Arguments | Description |
|-------------------|-------------------------------|------------------------------------------------------------------|
| setAsync | string $async | Identifier for async execution to request the status later |
| setCore | string $core | Name of the core that should be renamed |
| setPath | array $path | Array of pathes where the parts of the splitted index is written |
| setTargetCore | array $targetCore | Array of target core names that should be used for splitting |
| setRanges | string $ranges | Comma separated list of hash ranges in hexadecimal format |
| setSplitKey | string $splitKey | Key to be used for splitting the index |


Status
======

Use to get the status of one or all cores:

**Note**: When no name is passed the status for all cores will be retrieved.

**Available action methods**:

| Name | Arguments | Description |
|-------------------|-------------------------------|------------------------------------------------------------------|
| setCore | string $core | Optional name of the core where the status should be retrieved |

Swap
====

Use to swap a core.

**Available action methods**:

| Name | Arguments | Description |
|-------------------|-------------------------------|---------------------------------------------------------------|
| setAsync | string $async | Identifier for async execution to request the status later |
| setCore | string $core | Name of the core that should be swap |
| setOther | string $otherCoreName | Target core to swap with |

Unload
======

Use to unload a core.

**Available action methods**:

| Name | Arguments | Description |
|----------------------|-------------------------------|---------------------------------------------------------------|
| setAsync | string $async | Identifier for async execution to request the status later |
| setCore | string $core | Name of the core that should be swap |
| setDeleteIndex | bool $boolean | Deletes the index directory |
| setDeleteDataDir | bool $boolean | Deletes the data directory |
| setDeleteInstanceDir | bool $boolean | Deletes the instance directory |


24 changes: 24 additions & 0 deletions examples/2.9-server-core-admin-status.php
@@ -0,0 +1,24 @@
<?php

require(__DIR__.'/init.php');
htmlHeader();

// create a client instance
$client = new Solarium\Client($config);

// create a core admin query
$coreAdminQuery = $client->createCoreAdmin();

// use the core admin query to build a Status action
$statusAction = $coreAdminQuery->createStatus();
$coreAdminQuery->setAction($statusAction);

$response = $client->coreAdmin($coreAdminQuery);
$statusResults = $response->getStatusResults();

echo '<b>Core admin status action execution:</b><br/>';
foreach($statusResults as $statusResult) {
echo 'Uptime of the core ( ' .$statusResult->getCoreName(). ' ): ' . $statusResult->getUptime();
}

htmlFooter();
2 changes: 2 additions & 0 deletions examples/index.html
Expand Up @@ -90,6 +90,8 @@ <h1>Solarium examples</h1>
<li><a href="2.6-suggester-query.php">2.6 Suggester query</a></li>
<li><a href="2.7-extract-query.php">2.7 Extract query</a></li>
<li><a href="2.8-realtime-get-query.php">2.8 Realtime get query</a></li>

<li><a href="2.9-server-core-admin-status.php">2.9 Core admin query</a></li>
</ul>

<li>4. Usage modes</li>
Expand Down
4 changes: 3 additions & 1 deletion src/Core/Client/Adapter/Curl.php
Expand Up @@ -72,7 +72,9 @@ public function getResponse($handle, $httpResponse)
public function createHandle($request, $endpoint)
{
// @codeCoverageIgnoreStart
$uri = $endpoint->getBaseUri().$request->getUri();
$baseUri = $request->getIsServerRequest() ? $endpoint->getServerUri() : $endpoint->getCoreBaseUri();
$uri = $baseUri.$request->getUri();

$method = $request->getMethod();
$options = $this->createOptions($request, $endpoint);

Expand Down
4 changes: 3 additions & 1 deletion src/Core/Client/Adapter/Guzzle.php
Expand Up @@ -56,9 +56,11 @@ public function execute($request, $endpoint)
}

try {
$baseUri = $request->getIsServerRequest() ? $endpoint->getServerUri() : $endpoint->getCoreBaseUri();
$uri = $baseUri.$request->getUri();
$guzzleResponse = $this->getGuzzleClient()->request(
$request->getMethod(),
$endpoint->getBaseUri().$request->getUri(),
$uri,
$requestOptions
);

Expand Down
4 changes: 3 additions & 1 deletion src/Core/Client/Adapter/Guzzle3.php
Expand Up @@ -31,9 +31,11 @@ class Guzzle3 extends Configurable implements AdapterInterface
*/
public function execute($request, $endpoint)
{
$baseUri = $request->getIsServerRequest() ? $endpoint->getServerUri() : $endpoint->getCoreBaseUri();
$uri = $baseUri.$request->getUri();
$guzzleRequest = $this->getGuzzleClient()->createRequest(
$request->getMethod(),
$endpoint->getBaseUri().$request->getUri(),
$uri,
$this->getRequestHeaders($request),
$this->getRequestBody($request),
[
Expand Down
3 changes: 2 additions & 1 deletion src/Core/Client/Adapter/Http.php
Expand Up @@ -27,7 +27,8 @@ class Http extends Configurable implements AdapterInterface
public function execute($request, $endpoint)
{
$context = $this->createContext($request, $endpoint);
$uri = $endpoint->getBaseUri().$request->getUri();
$baseUri = $request->getIsServerRequest() ? $endpoint->getServerUri() : $endpoint->getCoreBaseUri();
$uri = $baseUri.$request->getUri();

list($data, $headers) = $this->getData($uri, $context);

Expand Down
3 changes: 2 additions & 1 deletion src/Core/Client/Adapter/PeclHttp.php
Expand Up @@ -63,7 +63,8 @@ public function execute($request, $endpoint)
*/
public function toHttpRequest($request, $endpoint)
{
$url = $endpoint->getBaseUri().$request->getUri();
$baseUri = $request->getIsServerRequest() ? $endpoint->getServerUri() : $endpoint->getCoreBaseUri();
$url = $baseUri.$request->getUri();
$httpRequest = new \HttpRequest($url);

$headers = [];
Expand Down
4 changes: 3 additions & 1 deletion src/Core/Client/Adapter/Zend2Http.php
Expand Up @@ -167,7 +167,9 @@ public function execute($request, $endpoint)
break;
}

$client->setUri($endpoint->getBaseUri().$request->getHandler());
$baseUri = $request->getIsServerRequest() ? $endpoint->getServerUri() : $endpoint->getCoreBaseUri();
$uri = $baseUri.$request->getUri();
$client->setUri($uri);
$client->setHeaders($request->getHeaders());
$this->timeout = $endpoint->getTimeout();

Expand Down
4 changes: 3 additions & 1 deletion src/Core/Client/Adapter/ZendHttp.php
Expand Up @@ -168,7 +168,9 @@ public function execute($request, $endpoint)
break;
}

$client->setUri($endpoint->getBaseUri().$request->getHandler());
$baseUri = $request->getIsServerRequest() ? $endpoint->getServerUri() : $endpoint->getCoreBaseUri();
$uri = $baseUri.$request->getUri();
$client->setUri($uri);
$client->setHeaders($request->getHeaders());
$this->timeout = $endpoint->getTimeout();

Expand Down
34 changes: 34 additions & 0 deletions src/Core/Client/Client.php
Expand Up @@ -107,6 +107,11 @@ class Client extends Configurable implements ClientInterface
*/
const QUERY_REALTIME_GET = 'get';

/**
* Querytype cores.
*/
const QUERY_CORE_ADMIN = 'cores';

/**
* Default options.
*
Expand Down Expand Up @@ -138,6 +143,7 @@ class Client extends Configurable implements ClientInterface
self::QUERY_GRAPH => 'Solarium\QueryType\Graph\Query',
self::QUERY_EXTRACT => 'Solarium\QueryType\Extract\Query',
self::QUERY_REALTIME_GET => 'Solarium\QueryType\RealtimeGet\Query',
self::QUERY_CORE_ADMIN => 'Solarium\QueryType\Server\CoreAdmin\Query\Query',
];

/**
Expand Down Expand Up @@ -986,6 +992,22 @@ public function realtimeGet(QueryInterface $query, $endpoint = null)
return $this->execute($query, $endpoint);
}

/**
* Execute a CoreAdmin query.
*
* This is a convenience method that forwards the query to the
* execute method, thus allowing for an easy to use and clean API.
*
* @param QueryInterface|\Solarium\QueryType\Server\CoreAdmin\Query\Query $query
* @param Endpoint|string|null $endpoint
*
* @return \Solarium\QueryType\Server\CoreAdmin\Result\Result
*/
public function coreAdmin(QueryInterface $query, $endpoint = null)
{
return $this->execute($query, $endpoint);
}

/**
* Create a query instance.
*
Expand Down Expand Up @@ -1190,6 +1212,18 @@ public function createRealtimeGet($options = null)
return $this->createQuery(self::QUERY_REALTIME_GET, $options);
}

/**
* Create a CoreAdmin query instance.
*
* @param mixed $options
*
* @return \Solarium\QueryType\Server\CoreAdmin\Query\Query
*/
public function createCoreAdmin($options = null)
{
return $this->createQuery(self::QUERY_CORE_ADMIN, $options);
}

/**
* Initialization hook.
*/
Expand Down

0 comments on commit e8cf9e4

Please sign in to comment.