Skip to content

Commit ba5a84e

Browse files
committed
Merge commit 'refs/pull/11/head' of https://github.com/magento/bulk-api-ce into async-bulk-webapi
2 parents 85afb2a + 54b046a commit ba5a84e

File tree

11 files changed

+485
-10
lines changed

11 files changed

+485
-10
lines changed

app/code/Magento/AsynchronousOperations/Model/MassSchedule.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,7 @@ public function publishMass($topicName, array $entitiesArray, $groupId = null, $
110110
$requestItems = [];
111111
$bulkException = new BulkException();
112112
foreach ($entitiesArray as $key => $entityParams) {
113-
/** @var \Magento\WebapiAsync\Api\Data\ItemStatusInterface $requestItem */
113+
/** @var \Magento\AsynchronousOperations\Api\Data\ItemStatusInterface $requestItem */
114114
$requestItem = $this->itemStatusInterfaceFactory->create();
115115

116116
try {

app/code/Magento/Webapi/Model/Config.php

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
* @api
1818
* @since 100.0.2
1919
*/
20-
class Config
20+
class Config implements ConfigInterface
2121
{
2222
const CACHE_ID = 'webapi_config';
2323

@@ -66,9 +66,7 @@ public function __construct(
6666
}
6767

6868
/**
69-
* Return services loaded from cache if enabled or from files merged previously
70-
*
71-
* @return array
69+
* {@inheritdoc}
7270
*/
7371
public function getServices()
7472
{
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
<?php
2+
/**
3+
* Copyright © Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
7+
declare(strict_types=1);
8+
9+
namespace Magento\Webapi\Model;
10+
11+
/**
12+
* This class gives access to consolidated web API configuration from <Module_Name>/etc/webapi.xml files.
13+
*
14+
* @api
15+
*/
16+
interface ConfigInterface
17+
{
18+
/**
19+
* Return services loaded from cache if enabled or from files merged previously
20+
*
21+
* @return array
22+
*/
23+
public function getServices();
24+
}

app/code/Magento/Webapi/Model/Rest/Config.php

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
namespace Magento\Webapi\Model\Rest;
77

88
use Magento\Webapi\Controller\Rest\Router\Route;
9-
use Magento\Webapi\Model\Config as ModelConfig;
9+
use Magento\Webapi\Model\ConfigInterface as ModelConfigInterface;
1010
use Magento\Webapi\Model\Config\Converter;
1111

1212
/**
@@ -43,11 +43,13 @@ class Config
4343
protected $_routeFactory;
4444

4545
/**
46-
* @param ModelConfig $config
46+
* @param ModelConfigInterface $config
4747
* @param \Magento\Framework\Controller\Router\Route\Factory $routeFactory
4848
*/
49-
public function __construct(ModelConfig $config, \Magento\Framework\Controller\Router\Route\Factory $routeFactory)
50-
{
49+
public function __construct(
50+
ModelConfigInterface $config,
51+
\Magento\Framework\Controller\Router\Route\Factory $routeFactory
52+
) {
5153
$this->_config = $config;
5254
$this->_routeFactory = $routeFactory;
5355
}

app/code/Magento/Webapi/etc/di.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
*/
77
-->
88
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
9+
<preference for="Magento\Webapi\Model\ConfigInterface" type="Magento\Webapi\Model\Config" />
910
<type name="Magento\Framework\App\AreaList">
1011
<arguments>
1112
<argument name="areas" xsi:type="array">
Lines changed: 124 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,124 @@
1+
<?php
2+
/**
3+
* Copyright © Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
7+
declare(strict_types=1);
8+
9+
namespace Magento\WebapiAsync\Controller\Rest\Asynchronous;
10+
11+
use Magento\Framework\Webapi\ServiceInputProcessor;
12+
use Magento\Framework\Webapi\Rest\Request as RestRequest;
13+
use Magento\Webapi\Controller\Rest\Router;
14+
use Magento\Webapi\Controller\Rest\ParamsOverrider;
15+
use Magento\Webapi\Controller\Rest\RequestValidator;
16+
use Magento\Webapi\Controller\Rest\InputParamsResolver as WebapiInputParamsResolver;
17+
18+
/**
19+
* This class is responsible for retrieving resolved input data
20+
*/
21+
class InputParamsResolver
22+
{
23+
/**
24+
* @var RestRequest
25+
*/
26+
private $request;
27+
/**
28+
* @var ParamsOverrider
29+
*/
30+
private $paramsOverrider;
31+
/**
32+
* @var ServiceInputProcessor
33+
*/
34+
private $serviceInputProcessor;
35+
/**
36+
* @var Router
37+
*/
38+
private $router;
39+
/**
40+
* @var RequestValidator
41+
*/
42+
private $requestValidator;
43+
/**
44+
* @var \Magento\Webapi\Controller\Rest\InputParamsResolver
45+
*/
46+
private $inputParamsResolver;
47+
48+
/**
49+
* Initialize dependencies.
50+
*
51+
* @param \Magento\Framework\Webapi\Rest\Request $request
52+
* @param \Magento\Webapi\Controller\Rest\ParamsOverrider $paramsOverrider
53+
* @param \Magento\Framework\Webapi\ServiceInputProcessor $inputProcessor
54+
* @param \Magento\Webapi\Controller\Rest\Router $router
55+
* @param \Magento\Webapi\Controller\Rest\RequestValidator $requestValidator
56+
* @param \Magento\Webapi\Controller\Rest\InputParamsResolver $inputParamsResolver
57+
*/
58+
public function __construct(
59+
RestRequest $request,
60+
ParamsOverrider $paramsOverrider,
61+
ServiceInputProcessor $inputProcessor,
62+
Router $router,
63+
RequestValidator $requestValidator,
64+
WebapiInputParamsResolver $inputParamsResolver
65+
) {
66+
$this->request = $request;
67+
$this->paramsOverrider = $paramsOverrider;
68+
$this->serviceInputProcessor = $inputProcessor;
69+
$this->router = $router;
70+
$this->requestValidator = $requestValidator;
71+
$this->inputParamsResolver = $inputParamsResolver;
72+
}
73+
74+
/**
75+
* Process and resolve input parameters
76+
* Return array with validated input params
77+
* or throw \Exception if at least one request entity params is not valid
78+
*
79+
* @return array
80+
* @throws \Magento\Framework\Exception\InputException if no value is provided for required parameters
81+
* @throws \Magento\Framework\Webapi\Exception
82+
*/
83+
public function resolve()
84+
{
85+
$this->requestValidator->validate();
86+
$webapiResolvedParams = [];
87+
$inputData = $this->request->getRequestData();
88+
foreach ($inputData as $key => $singleEntityParams) {
89+
$webapiResolvedParams[$key] = $this->resolveBulkItemParams($singleEntityParams);
90+
}
91+
92+
return $webapiResolvedParams;
93+
}
94+
95+
/**
96+
* @return \Magento\Webapi\Controller\Rest\Router\Route
97+
*/
98+
public function getRoute()
99+
{
100+
return $this->inputParamsResolver->getRoute();
101+
}
102+
103+
/**
104+
* Convert the input array from key-value format to a list of parameters
105+
* suitable for the specified class / method.
106+
*
107+
* Instead of \Magento\Webapi\Controller\Rest\InputParamsResolver
108+
* we don't need to merge body params with url params and use only body params
109+
*
110+
* @param array $inputData data to send to method in key-value format
111+
* @return array list of parameters that can be used to call the service method
112+
* @throws \Magento\Framework\Exception\InputException if no value is provided for required parameters
113+
* @throws \Magento\Framework\Webapi\Exception
114+
*/
115+
private function resolveBulkItemParams($inputData)
116+
{
117+
$route = $this->getRoute();
118+
$serviceMethodName = $route->getServiceMethod();
119+
$serviceClassName = $route->getServiceClass();
120+
$inputParams = $this->serviceInputProcessor->process($serviceClassName, $serviceMethodName, $inputData);
121+
122+
return $inputParams;
123+
}
124+
}
Lines changed: 131 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,131 @@
1+
<?php
2+
/**
3+
* Copyright © Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
7+
declare(strict_types=1);
8+
9+
namespace Magento\WebapiAsync\Controller\Rest;
10+
11+
use Magento\Framework\Exception\BulkException;
12+
use Magento\Webapi\Controller\Rest\RequestProcessorInterface;
13+
use Magento\Framework\Webapi\Rest\Response as RestResponse;
14+
use Magento\WebapiAsync\Controller\Rest\Asynchronous\InputParamsResolver;
15+
use Magento\AsynchronousOperations\Model\MassSchedule;
16+
use Magento\AsynchronousOperations\Model\ConfigInterface as WebApiAsyncConfig;
17+
use Magento\Framework\Reflection\DataObjectProcessor;
18+
use Magento\AsynchronousOperations\Api\Data\AsyncResponseInterfaceFactory;
19+
use Magento\AsynchronousOperations\Api\Data\AsyncResponseInterface;
20+
21+
class AsynchronousBulkRequestProcessor implements RequestProcessorInterface
22+
{
23+
const PROCESSOR_PATH = "/^\\/async\/bulk(\\/V.+)/";
24+
/**
25+
* @var \Magento\Framework\Webapi\Rest\Response
26+
*/
27+
private $response;
28+
/**
29+
* @var \Magento\WebapiAsync\Controller\Rest\Asynchronous\InputParamsResolver
30+
*/
31+
private $inputParamsResolver;
32+
/**
33+
* @var MassSchedule
34+
*/
35+
private $asyncBulkPublisher;
36+
/**
37+
* @var WebApiAsyncConfig
38+
*/
39+
private $webapiAsyncConfig;
40+
/**
41+
* @var \Magento\Framework\Reflection\DataObjectProcessor
42+
*/
43+
private $dataObjectProcessor;
44+
/**
45+
* @var AsyncResponseInterfaceFactory
46+
*/
47+
private $asyncResponseFactory;
48+
49+
/**
50+
* Initialize dependencies.
51+
*
52+
* @param RestResponse $response
53+
* @param InputParamsResolver $inputParamsResolver
54+
* @param MassSchedule $asyncBulkPublisher
55+
* @param WebapiAsyncConfig $webapiAsyncConfig
56+
* @param DataObjectProcessor $dataObjectProcessor
57+
* @param AsyncResponseInterfaceFactory $asyncResponse
58+
*/
59+
public function __construct(
60+
RestResponse $response,
61+
InputParamsResolver $inputParamsResolver,
62+
MassSchedule $asyncBulkPublisher,
63+
WebApiAsyncConfig $webapiAsyncConfig,
64+
DataObjectProcessor $dataObjectProcessor,
65+
AsyncResponseInterfaceFactory $asyncResponse
66+
) {
67+
$this->response = $response;
68+
$this->inputParamsResolver = $inputParamsResolver;
69+
$this->asyncBulkPublisher = $asyncBulkPublisher;
70+
$this->webapiAsyncConfig = $webapiAsyncConfig;
71+
$this->dataObjectProcessor = $dataObjectProcessor;
72+
$this->asyncResponseFactory = $asyncResponse;
73+
}
74+
75+
/**
76+
* {@inheritdoc}
77+
*/
78+
public function process(\Magento\Framework\Webapi\Rest\Request $request)
79+
{
80+
$path = $request->getPathInfo();
81+
$path = preg_replace(self::PROCESSOR_PATH, "$1", $path);
82+
$request->setPathInfo(
83+
$path
84+
);
85+
$entitiesParamsArray = $this->inputParamsResolver->resolve();
86+
$topicName = $this->getTopicName($request);
87+
try {
88+
$asyncResponse = $this->asyncBulkPublisher->publishMass(
89+
$topicName,
90+
$entitiesParamsArray
91+
);
92+
} catch (BulkException $bulkException) {
93+
$asyncResponse = $bulkException->getData();
94+
}
95+
$responseData = $this->dataObjectProcessor->buildOutputDataArray(
96+
$asyncResponse,
97+
AsyncResponseInterface::class
98+
);
99+
$this->response->setStatusCode(RestResponse::STATUS_CODE_202)
100+
->prepareResponse($responseData);
101+
}
102+
103+
/**
104+
* @param \Magento\Framework\Webapi\Rest\Request $request
105+
* @return string
106+
*/
107+
private function getTopicName($request)
108+
{
109+
$route = $this->inputParamsResolver->getRoute();
110+
111+
return $this->webapiAsyncConfig->getTopicName(
112+
$route->getRoutePath(),
113+
$request->getHttpMethod()
114+
);
115+
}
116+
117+
/**
118+
* {@inheritdoc}
119+
*/
120+
public function canProcess(\Magento\Framework\Webapi\Rest\Request $request)
121+
{
122+
if ($request->getHttpMethod() === \Magento\Framework\Webapi\Rest\Request::HTTP_METHOD_GET) {
123+
return false;
124+
}
125+
if (preg_match(self::PROCESSOR_PATH, $request->getPathInfo()) === 1) {
126+
return true;
127+
}
128+
129+
return false;
130+
}
131+
}

0 commit comments

Comments
 (0)