Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Save Asynchronous Operations with one Batch improvement #27257

Merged
merged 7 commits into from
Apr 1, 2020
Merged
Show file tree
Hide file tree
Changes from 6 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
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
<?php
/**
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/

declare(strict_types=1);

namespace Magento\AsynchronousOperations\Api;

use Magento\AsynchronousOperations\Api\Data\OperationInterface;

/**
* Interface for saving multiple operations
*
* @api
*/
interface SaveMultipleOperationsInterface
{
/**
* Save Operations for Bulk
*
* @param OperationInterface[] $operations
* @return void
*/
public function execute(array $operations): void;
}
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,6 @@ public function scheduleBulk($bulkUuid, array $operations, $description, $userId
$bulkSummary->setUserId($userId);
$bulkSummary->setUserType($userType);
$bulkSummary->setOperationCount((int)$bulkSummary->getOperationCount() + count($operations));

$this->entityManager->save($bulkSummary);

$connection->commit();
Expand Down
12 changes: 11 additions & 1 deletion app/code/Magento/AsynchronousOperations/Model/MassSchedule.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
use Magento\Framework\Bulk\BulkManagementInterface;
use Magento\Framework\DataObject\IdentityGeneratorInterface;
use Magento\Framework\Encryption\Encryptor;
use Magento\AsynchronousOperations\Api\SaveMultipleOperationsInterface;
use Magento\Framework\Exception\BulkException;
use Magento\Framework\Exception\LocalizedException;
use Psr\Log\LoggerInterface;
Expand Down Expand Up @@ -67,6 +68,11 @@ class MassSchedule
*/
private $encryptor;

/**
* @var SaveMultipleOperationsInterface
*/
private $saveMultipleOperations;

/**
* Initialize dependencies.
*
Expand All @@ -78,6 +84,7 @@ class MassSchedule
* @param OperationRepositoryInterface $operationRepository
* @param UserContextInterface $userContext
* @param Encryptor $encryptor
* @param SaveMultipleOperationsInterface $saveMultipleOperations
*/
public function __construct(
IdentityGeneratorInterface $identityService,
Expand All @@ -87,7 +94,8 @@ public function __construct(
LoggerInterface $logger,
OperationRepositoryInterface $operationRepository,
UserContextInterface $userContext,
Encryptor $encryptor
Encryptor $encryptor,
SaveMultipleOperationsInterface $saveMultipleOperations
) {
$this->identityService = $identityService;
$this->itemStatusInterfaceFactory = $itemStatusInterfaceFactory;
Expand All @@ -97,6 +105,7 @@ public function __construct(
$this->operationRepository = $operationRepository;
$this->userContext = $userContext;
$this->encryptor = $encryptor;
$this->saveMultipleOperations = $saveMultipleOperations;
}

/**
Expand Down Expand Up @@ -159,6 +168,7 @@ public function publishMass($topicName, array $entitiesArray, $groupId = null, $
}
}

$this->saveMultipleOperations->execute($operations);
if (!$this->bulkManagement->scheduleBulk($groupId, $operations, $bulkDescription, $userId)) {
throw new LocalizedException(
__('Something went wrong while processing the request.')
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
use Magento\Framework\EntityManager\EntityManager;

/**
* Class OperationManagement
* Class for managing Bulk Operations
*/
class OperationManagement implements \Magento\Framework\Bulk\OperationManagementInterface
{
Expand Down Expand Up @@ -45,7 +45,7 @@ public function __construct(
$this->operationFactory = $operationFactory;
$this->logger = $logger;
}

/**
* @inheritDoc
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,17 +7,21 @@
namespace Magento\AsynchronousOperations\Model\ResourceModel;

/**
* Class Operation
* Resource class for Bulk Operations
*/
class Operation extends \Magento\Framework\Model\ResourceModel\Db\AbstractDb
{

public const TABLE_NAME = "magento_operation";
public const TABLE_PRIMARY_KEY = "id";

/**
* Initialize banner sales rule resource model
*
* @return void
*/
protected function _construct()
{
$this->_init('magento_operation', 'id');
$this->_init(self::TABLE_NAME, self::TABLE_PRIMARY_KEY);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ public function createByTopic($topicName, $entityParams, $groupId)

/** @var OperationInterface $operation */
$operation = $this->operationFactory->create($data);
return $this->entityManager->save($operation);
return $operation;
}

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

declare(strict_types=1);

namespace Magento\AsynchronousOperations\Model;

use Magento\AsynchronousOperations\Api\SaveMultipleOperationsInterface;
use Magento\AsynchronousOperations\Model\ResourceModel\Operation as OperationResource;
use Magento\Framework\Exception\CouldNotSaveException;

/**
* Implementation for saving multiple operations
*/
class SaveMultipleOperations implements SaveMultipleOperationsInterface
{

/**
* @var OperationResource
*/
private $operationResource;

/**
* BulkSummary constructor.
*
* @param OperationResource $operationResource
*/
public function __construct(
OperationResource $operationResource
) {
$this->operationResource = $operationResource;
}

/**
* @inheritDoc
*/
public function execute(array $operations): void
Copy link
Contributor

Choose a reason for hiding this comment

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

You have declared OperationInterface[] expected type for '$operations', but in current implementation it will works correctly only with data in arrays.

Please keep contract on OperationInterface or do not make current service as API.

{
try {
$operationsToInsert = array_map(function ($operation) {
return $operation->getData();
}, $operations);

$connection = $this->operationResource->getConnection();
$connection->insertMultiple(
$this->operationResource->getTable(OperationResource::TABLE_NAME),
$operationsToInsert
);
} catch (\Exception $exception) {
throw new CouldNotSaveException(__($exception->getMessage()));
}
}
}
1 change: 1 addition & 0 deletions app/code/Magento/AsynchronousOperations/etc/di.xml
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
-->
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
<preference for="Magento\AsynchronousOperations\Api\Data\BulkSummaryInterface" type="Magento\AsynchronousOperations\Model\BulkSummary" />
<preference for="Magento\AsynchronousOperations\Api\SaveMultipleOperationsInterface" type="Magento\AsynchronousOperations\Model\SaveMultipleOperations" />
<preference for="Magento\AsynchronousOperations\Api\Data\OperationInterface" type="Magento\AsynchronousOperations\Model\Operation" />
<preference for="Magento\AsynchronousOperations\Api\Data\OperationListInterface" type="Magento\AsynchronousOperations\Model\OperationList" />
<preference for="Magento\Framework\Bulk\BulkManagementInterface" type="Magento\AsynchronousOperations\Model\BulkManagement" />
Expand Down
2 changes: 1 addition & 1 deletion app/code/Magento/WebapiAsync/Model/OperationRepository.php
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,6 @@ public function create($topicName, $entityParams, $groupId, $operationId): Opera

/** @var OperationInterface $operation */
$operation = $this->operationFactory->create($data);
return $this->entityManager->save($operation);
return $operation;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
<?php
/**
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/

namespace Magento\AsynchronousOperations\Model;

use Magento\AsynchronousOperations\Api\Data\OperationInterface;
use Magento\AsynchronousOperations\Api\Data\OperationInterfaceFactory;
use Magento\AsynchronousOperations\Api\SaveMultipleOperationsInterface;
use Magento\AsynchronousOperations\Model\BulkStatus;
use Magento\AsynchronousOperations\Api\Data\BulkSummaryInterface;
use Magento\AsynchronousOperations\Api\Data\BulkSummaryInterfaceFactory;
use Magento\Framework\EntityManager\EntityManager;

class SaveMultipleOperationsTest extends \PHPUnit\Framework\TestCase
{

private const BULK_UUID = "bulk-uuid-multiple-0";

/**
* @var BulkStatus
*/
private $bulkStatusManagement;

/**
* @var OperationInterfaceFactory
*/
private $operationFactory;

/**
* @var SaveMultipleOperationsInterface
*/
private $saveMultipleOperationsInterface;

/**
* @var EntityManager
*/
private $entityManager;

/**
* @var BulkSummaryInterfaceFactory
*/
private $bulkSummaryFactory;

/**
* Set Up the test
*/
protected function setUp()
{
$this->saveMultipleOperationsInterface = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create(
SaveMultipleOperationsInterface::class
);
$this->operationFactory = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create(
OperationInterfaceFactory::class
);
$this->bulkStatusManagement = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create(
BulkStatus::class
);
$this->bulkSummaryFactory = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create(
BulkSummaryInterfaceFactory::class
);
$this->entityManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create(
EntityManager::class
);
}

/**
* Test execute() of SaveMultipleOperations
*/
public function testExecute()
{
$operation = $this->createOperation();
$operations = [$operation, $operation, $operation];

$bulkSummary = $this->bulkSummaryFactory->create();
$this->entityManager->load($bulkSummary, self::BULK_UUID);
$bulkSummary->setBulkId(self::BULK_UUID);
$bulkSummary->setDescription("Test Bulk");
$bulkSummary->setUserId(1);
$bulkSummary->setUserType(1);
$bulkSummary->setOperationCount(count($operations));
$this->entityManager->save($bulkSummary);

$this->saveMultipleOperationsInterface->execute($operations);
$operationsCount = $this->bulkStatusManagement
->getOperationsCountByBulkIdAndStatus(self::BULK_UUID, OperationInterface::STATUS_TYPE_OPEN);
$this->assertEquals($operationsCount, 3);
}

/**
* Create Operation object and pre-fill with test data
* @return OperationInterface
*/
public function createOperation()
{
$serializedData = [
'entity_id' => null,
'entity_link' => '',
'meta_information' => json_encode([
'entity_id' => 5,
'meta_information' => 'Test'
])
];

$data = [
'data' => [
OperationInterface::BULK_ID => self::BULK_UUID,
OperationInterface::TOPIC_NAME => "topic-4",
OperationInterface::SERIALIZED_DATA => json_encode($serializedData),
OperationInterface::STATUS => OperationInterface::STATUS_TYPE_OPEN,
],
];
return $this->operationFactory->create($data);
}
}