Skip to content
This repository has been archived by the owner on May 20, 2019. It is now read-only.

Operations Status Search API Endpoint #12

Merged
merged 10 commits into from
Jun 27, 2018
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
<?php
/**
*
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/

declare(strict_types=1);

namespace Magento\AsynchronousOperations\Api\Data;

/**
* @api
*/
interface OperationSearchResultsInterface extends \Magento\Framework\Api\SearchResultsInterface

Choose a reason for hiding this comment

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

Please add description to all new classes/interfaces

{
/**
* Get attributes list.

Choose a reason for hiding this comment

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

attributes list => operations list ?

*
* @return \Magento\AsynchronousOperations\Api\Data\OperationInterface[]
*/
public function getItems();

/**
* Set attributes list.
*
* @param \Magento\AsynchronousOperations\Api\Data\OperationInterface[] $items
* @return $this
*/
public function setItems(array $items);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<?php
/**
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/

declare(strict_types=1);

namespace Magento\AsynchronousOperations\Api;

/**
* @api
*/
interface OperationRepositoryInterface
{
/**
* Find operation entities by criteria
*
* @param \Magento\Framework\Api\SearchCriteriaInterface $searchCriteria
* @return \Magento\AsynchronousOperations\Api\Data\OperationSearchResultsInterface
*/
public function getList(\Magento\Framework\Api\SearchCriteriaInterface $searchCriteria);
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
/**
* Class Operation
*/
class Operation extends DataObject implements DetailedOperationStatusInterface, ExtensibleDataInterface
class Operation extends DataObject implements DetailedOperationStatusInterface
{
/**
* @inheritDoc
Expand Down
121 changes: 121 additions & 0 deletions app/code/Magento/AsynchronousOperations/Model/OperationRepository.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
<?php
/**
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/

declare(strict_types=1);

namespace Magento\AsynchronousOperations\Model;

use Magento\Framework\App\ObjectManager;
use Magento\AsynchronousOperations\Api\Data\DetailedOperationStatusInterfaceFactory;
use Magento\Framework\EntityManager\EntityManager;
use Magento\Framework\Api\SearchCriteria\CollectionProcessorInterface;
use Magento\AsynchronousOperations\Api\Data\OperationSearchResultsInterfaceFactory as SearchResultFactory;
use Magento\AsynchronousOperations\Api\Data\OperationExtensionInterfaceFactory;
use Magento\AsynchronousOperations\Model\ResourceModel\Operation\CollectionFactory;
use Magento\Framework\Api\ExtensionAttribute\JoinProcessorInterface;
use Magento\Framework\Exception\InputException;
use Magento\Framework\Exception\NoSuchEntityException;

/**
* Class OperationManagement
*/
class OperationRepository implements \Magento\AsynchronousOperations\Api\OperationRepositoryInterface
{
/**
* @var EntityManager
*/
private $entityManager;

/**
* @var CollectionFactory
*/
private $collectionFactory;

/**
* @var SearchResultFactory
*/
private $searchResultFactory;

/**
* @var JoinProcessorInterface
*/
private $joinProcessor;

/**
* @var \Magento\AsynchronousOperations\Api\Data\OperationExtensionInterfaceFactory
*/
private $operationExtensionFactory;

/**
* @var CollectionProcessorInterface
*/
private $collectionProcessor;

/**
* @var \Psr\Log\LoggerInterface
*/
private $logger;

/**
* Initialize dependencies.
*
* @param \Magento\Framework\EntityManager\EntityManager $entityManager
* @param \Magento\AsynchronousOperations\Model\ResourceModel\Operation\CollectionFactory $collectionFactory
* @param \Magento\AsynchronousOperations\Api\Data\OperationSearchResultsInterfaceFactory $searchResultFactory
* @param \Magento\Framework\Api\ExtensionAttribute\JoinProcessorInterface $joinProcessor
* @param \Magento\AsynchronousOperations\Api\Data\OperationExtensionInterfaceFactory $operationExtensionFactory
* @param \Magento\Framework\Api\SearchCriteria\CollectionProcessorInterface|null $collectionProcessor
* @param \Psr\Log\LoggerInterface $logger
*/
public function __construct(
EntityManager $entityManager,
CollectionFactory $collectionFactory,
SearchResultFactory $searchResultFactory,
JoinProcessorInterface $joinProcessor,
OperationExtensionInterfaceFactory $operationExtension,
CollectionProcessorInterface $collectionProcessor = null,

Choose a reason for hiding this comment

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

This argument should not be optional.

\Psr\Log\LoggerInterface $logger
) {
$this->entityManager = $entityManager;
$this->collectionFactory = $collectionFactory;
$this->searchResultFactory = $searchResultFactory;
$this->joinProcessor = $joinProcessor;
$this->operationExtensionFactory = $operationExtension;
$this->collectionProcessor = $collectionProcessor ? : ObjectManager::getInstance()

Choose a reason for hiding this comment

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

This is a new class, what is the reason to use object manager (it is normally used for backward compatibility)?

->get(\Magento\Framework\Api\SearchCriteria\CollectionProcessorInterface::class);
$this->logger = $logger;
}

/**
* @inheritDoc
*/
public function getList(\Magento\Framework\Api\SearchCriteriaInterface $searchCriteria)
{
/** @var \Magento\AsynchronousOperations\Api\Data\OperationSearchResultsInterface $searchResult */
$searchResult = $this->searchResultFactory->create();

/** @var \Magento\AsynchronousOperations\Model\ResourceModel\Operation\Collection $collection */
$collection = $this->collectionFactory->create();
$this->joinProcessor->process($collection, \Magento\AsynchronousOperations\Api\Data\OperationInterface::class);
$this->collectionProcessor->process($searchCriteria, $collection);
$searchResult->setSearchCriteria($searchCriteria);
$searchResult->setTotalCount($collection->getSize());

$items = [];
foreach ($collection->getItems() as $item) {
$extensionAttributes = $item->getExtensionAttributes();
if ($extensionAttributes == null) {
$extensionAttributes = $this->operationExtensionFactory->create();
}
$extensionAttributes->setStartTime('dsadsa');

Choose a reason for hiding this comment

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

What does 'dsadsa' mean?

$item->setExtensionAttributes($extensionAttributes);
$items[] = $item;
}
$searchResult->setItems($items);

return $searchResult;
}
}
2 changes: 2 additions & 0 deletions app/code/Magento/AsynchronousOperations/etc/di.xml
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@
<preference for="Magento\AsynchronousOperations\Api\Data\SummaryOperationStatusInterface" type="Magento\AsynchronousOperations\Model\OperationStatus" />
<preference for="Magento\AsynchronousOperations\Api\Data\DetailedBulkOperationsStatusInterface" type="Magento\AsynchronousOperations\Model\BulkStatus\Detailed" />
<preference for="Magento\AsynchronousOperations\Api\Data\BulkOperationsStatusInterface" type="Magento\AsynchronousOperations\Model\BulkStatus\Short" />
<preference for="Magento\AsynchronousOperations\Api\Data\OperationSearchResultsInterface" type="Magento\Framework\Api\SearchResults" />
<preference for="Magento\AsynchronousOperations\Api\OperationRepositoryInterface" type="Magento\AsynchronousOperations\Model\OperationRepository" />
<type name="Magento\Framework\EntityManager\MetadataPool">
<arguments>
<argument name="metadata" xsi:type="array">
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<?xml version="1.0"?>
<!--
/**
* Copyright © 2016 Magento. All rights reserved.
* See COPYING.txt for license details.
*/
-->
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Api/etc/extension_attributes.xsd">
<extension_attributes for="Magento\AsynchronousOperations\Api\Data\OperationInterface">
<attribute code="start_time" type="string">
<resources>
<resource ref="Magento_Logging::system_magento_logging_bulk_operations"/>
</resources>
<join reference_table="magento_bulk" join_on_field="bulk_uuid" reference_field="uuid">
<field column="start_time">start_time</field>
</join>
</attribute>
</extension_attributes>
</config>
7 changes: 7 additions & 0 deletions app/code/Magento/AsynchronousOperations/etc/webapi.xml
Original file line number Diff line number Diff line change
Expand Up @@ -29,4 +29,11 @@
</resources>
</route>

<route url="/V1/bulk" method="GET">
<service class="Magento\AsynchronousOperations\Api\OperationRepositoryInterface" method="getList"/>
<resources>
<resource ref="Magento_Logging::system_magento_logging_bulk_operations" />
</resources>
</route>

</routes>
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
<?php
/**
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/

declare(strict_types=1);

namespace Magento\AsynchronousOperations\Api;

use Magento\Framework\Webapi\Rest\Request;
use Magento\TestFramework\TestCase\WebapiAbstract;
use Magento\Framework\Bulk\OperationInterface;

class OperationRepositoryInterfaceTest extends WebapiAbstract
{
const RESOURCE_PATH = '/V1/bulk';
const SERVICE_NAME = 'asynchronousOperationsOperationRepositoryV1';

/**
* @magentoApiDataFixture Magento/AsynchronousOperations/_files/operation_searchable.php
*/
public function testGetListByBulkStartTime()
{
$searchCriteria = [
'searchCriteria' => [
'filter_groups' => [
[
'filters' => [
[
'field' => 'start_time',
'value' => '2010-10-10 00:00:00',
'condition_type' => 'lteq',
],
],
],
],
'current_page' => 1,
],
];

$serviceInfo = [
'rest' => [
'resourcePath' => self::RESOURCE_PATH . '?' . http_build_query($searchCriteria),
'httpMethod' => Request::HTTP_METHOD_GET,
],
'soap' => [
'service' => self::SERVICE_NAME,
'operation' => self::SERVICE_NAME . 'GetList',
],
];

$response = $this->_webApiCall($serviceInfo, $searchCriteria);

$this->assertArrayHasKey('search_criteria', $response);
$this->assertArrayHasKey('total_count', $response);
$this->assertArrayHasKey('items', $response);

$this->assertEquals($searchCriteria['searchCriteria'], $response['search_criteria']);
$this->assertEquals(3, $response['total_count']);
$this->assertEquals(3, count($response['items']));

foreach ($response['items'] as $item) {
$this->assertEquals('bulk-uuid-searchable-6', $item['bulk_uuid']);
}
}

/**
* @magentoApiDataFixture Magento/AsynchronousOperations/_files/operation_searchable.php
*/
public function testGetList()
{
$searchCriteria = [
'searchCriteria' => [
'filter_groups' => [
[
'filters' => [
[
'field' => 'bulk_uuid',
'value' => 'bulk-uuid-searchable-6',
'condition_type' => 'eq',
],
],
],
[
'filters' => [
[
'field' => 'status',
'value' => OperationInterface::STATUS_TYPE_NOT_RETRIABLY_FAILED,
'condition_type' => 'eq',
],
],
],
],
'current_page' => 1,
],
];

$serviceInfo = [
'rest' => [
'resourcePath' => self::RESOURCE_PATH . '?' . http_build_query($searchCriteria),
'httpMethod' => Request::HTTP_METHOD_GET,
],
'soap' => [
'service' => self::SERVICE_NAME,
'operation' => self::SERVICE_NAME . 'GetList',
],
];

$response = $this->_webApiCall($serviceInfo, $searchCriteria);

$this->assertArrayHasKey('search_criteria', $response);
$this->assertArrayHasKey('total_count', $response);
$this->assertArrayHasKey('items', $response);

$this->assertEquals($searchCriteria['searchCriteria'], $response['search_criteria']);
$this->assertEquals(1, $response['total_count']);
$this->assertEquals(1, count($response['items']));

foreach ($response['items'] as $item) {
$this->assertEquals('bulk-uuid-searchable-6', $item['bulk_uuid']);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@
'user_id' => 1,
'description' => 'Bulk Description',
'operation_count' => 2,
]
],
];
// Only processed operations are saved into database (i.e. operations that are not in 'open' state)
$operations = [
Expand Down Expand Up @@ -88,7 +88,6 @@
'error_code' => 2222,
'result_message' => 'Entity with ID=4 does not exist',
],

];

$bulkQuery = "INSERT INTO {$bulkTable} (`uuid`, `user_id`, `description`, `operation_count`)"
Expand Down
Loading