Skip to content
This repository was archived by the owner on Apr 29, 2019. It is now read-only.

Commit 1c9a0a8

Browse files
authored
ENGCOM-3638: Change WebapiAsync topic to use Service contract name #21
2 parents 0c2f1d3 + 2ee9bf0 commit 1c9a0a8

File tree

3 files changed

+142
-14
lines changed

3 files changed

+142
-14
lines changed

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

Lines changed: 46 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,9 @@
1515
use Magento\Framework\Exception\LocalizedException;
1616
use Magento\Webapi\Model\Config\Converter;
1717

18+
/**
19+
* Class for accessing to Webapi_Async configuration.
20+
*/
1821
class Config implements \Magento\AsynchronousOperations\Model\ConfigInterface
1922
{
2023
/**
@@ -55,7 +58,7 @@ public function __construct(
5558
}
5659

5760
/**
58-
* {@inheritdoc}
61+
* @inheritdoc
5962
*/
6063
public function getServices()
6164
{
@@ -73,26 +76,30 @@ public function getServices()
7376
}
7477

7578
/**
76-
* {@inheritdoc}
79+
* @inheritdoc
7780
*/
7881
public function getTopicName($routeUrl, $httpMethod)
7982
{
8083
$services = $this->getServices();
81-
$topicName = $this->generateTopicNameByRouteData(
84+
$lookupKey = $this->generateLookupKeyByRouteData(
8285
$routeUrl,
8386
$httpMethod
8487
);
8588

86-
if (array_key_exists($topicName, $services) === false) {
89+
if (array_key_exists($lookupKey, $services) === false) {
8790
throw new LocalizedException(
88-
__('WebapiAsync config for "%topicName" does not exist.', ['topicName' => $topicName])
91+
__('WebapiAsync config for "%lookupKey" does not exist.', ['lookupKey' => $lookupKey])
8992
);
9093
}
9194

92-
return $services[$topicName][self::SERVICE_PARAM_KEY_TOPIC];
95+
return $services[$lookupKey][self::SERVICE_PARAM_KEY_TOPIC];
9396
}
9497

9598
/**
99+
* Generate topic data for all defined services
100+
*
101+
* Topic data is indexed by a lookup key that is derived from route data
102+
*
96103
* @return array
97104
*/
98105
private function generateTopicsDataFromWebapiConfig()
@@ -105,11 +112,18 @@ private function generateTopicsDataFromWebapiConfig()
105112
$serviceInterface = $httpMethodData[Converter::KEY_SERVICE][Converter::KEY_SERVICE_CLASS];
106113
$serviceMethod = $httpMethodData[Converter::KEY_SERVICE][Converter::KEY_SERVICE_METHOD];
107114

108-
$topicName = $this->generateTopicNameByRouteData(
115+
$lookupKey = $this->generateLookupKeyByRouteData(
109116
$routeUrl,
110117
$httpMethod
111118
);
112-
$services[$topicName] = [
119+
120+
$topicName = $this->generateTopicNameFromService(
121+
$serviceInterface,
122+
$serviceMethod,
123+
$httpMethod
124+
);
125+
126+
$services[$lookupKey] = [
113127
self::SERVICE_PARAM_KEY_INTERFACE => $serviceInterface,
114128
self::SERVICE_PARAM_KEY_METHOD => $serviceMethod,
115129
self::SERVICE_PARAM_KEY_TOPIC => $topicName,
@@ -122,7 +136,7 @@ private function generateTopicsDataFromWebapiConfig()
122136
}
123137

124138
/**
125-
* Generate topic name based on service type and method name.
139+
* Generate lookup key name based on route and method
126140
*
127141
* Perform the following conversion:
128142
* self::TOPIC_PREFIX + /V1/products + POST => async.V1.products.POST
@@ -131,19 +145,39 @@ private function generateTopicsDataFromWebapiConfig()
131145
* @param string $httpMethod
132146
* @return string
133147
*/
134-
private function generateTopicNameByRouteData($routeUrl, $httpMethod)
148+
private function generateLookupKeyByRouteData($routeUrl, $httpMethod)
135149
{
136-
return self::TOPIC_PREFIX . $this->generateTopicName($routeUrl, $httpMethod, '/', false);
150+
return self::TOPIC_PREFIX . $this->generateKey($routeUrl, $httpMethod, '/', false);
137151
}
138152

139153
/**
154+
* Generate topic name based on service type and method name.
155+
*
156+
* Perform the following conversion:
157+
* self::TOPIC_PREFIX + Magento\Catalog\Api\ProductRepositoryInterface + save + POST
158+
* => async.magento.catalog.api.productrepositoryinterface.save.POST
159+
*
160+
* @param string $serviceInterface
161+
* @param string $serviceMethod
162+
* @param string $httpMethod
163+
* @return string
164+
*/
165+
private function generateTopicNameFromService($serviceInterface, $serviceMethod, $httpMethod)
166+
{
167+
$typeName = strtolower(sprintf('%s.%s', $serviceInterface, $serviceMethod));
168+
return strtolower(self::TOPIC_PREFIX . $this->generateKey($typeName, $httpMethod, '\\', false));
169+
}
170+
171+
/**
172+
* Join and simplify input type and method into a string that can be used as an array key
173+
*
140174
* @param string $typeName
141175
* @param string $methodName
142176
* @param string $delimiter
143177
* @param bool $lcfirst
144178
* @return string
145179
*/
146-
private function generateTopicName($typeName, $methodName, $delimiter = '\\', $lcfirst = true)
180+
private function generateKey($typeName, $methodName, $delimiter = '\\', $lcfirst = true)
147181
{
148182
$parts = explode($delimiter, ltrim($typeName, $delimiter));
149183
foreach ($parts as &$part) {
Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
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\Test\Unit\Model;
10+
11+
use Magento\Framework\Serialize\SerializerInterface;
12+
use Magento\Webapi\Model\Cache\Type\Webapi;
13+
use Magento\Webapi\Model\Config as WebapiConfig;
14+
use Magento\WebapiAsync\Model\Config;
15+
use Magento\Webapi\Model\Config\Converter;
16+
17+
class ConfigTest extends \PHPUnit\Framework\TestCase
18+
{
19+
/**
20+
* @var Config
21+
*/
22+
private $config;
23+
24+
/**
25+
* @var Webapi|\PHPUnit_Framework_MockObject_MockObject
26+
*/
27+
private $webapiCacheMock;
28+
29+
/**
30+
* @var WebapiConfig|\PHPUnit_Framework_MockObject_MockObject
31+
*/
32+
private $configMock;
33+
34+
/**
35+
* @var SerializerInterface|\PHPUnit_Framework_MockObject_MockObject
36+
*/
37+
private $serializerMock;
38+
39+
protected function setUp()
40+
{
41+
$objectManager = new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this);
42+
43+
$this->webapiCacheMock = $this->createMock(\Magento\Webapi\Model\Cache\Type\Webapi::class);
44+
$this->configMock = $this->createMock(WebapiConfig::class);
45+
$this->serializerMock = $this->createMock(SerializerInterface::class);
46+
47+
$this->config = $objectManager->getObject(
48+
Config::class,
49+
[
50+
'cache' => $this->webapiCacheMock,
51+
'webApiConfig' => $this->configMock,
52+
'serializer' => $this->serializerMock
53+
]
54+
);
55+
}
56+
57+
public function testGetServicesSetsTopicFromServiceContractName()
58+
{
59+
$services = [
60+
Converter::KEY_ROUTES => [
61+
'/V1/products' => [
62+
'POST' => [
63+
'service' => [
64+
'class' => \Magento\Catalog\Api\ProductRepositoryInterface::class,
65+
'method' => 'save',
66+
]
67+
]
68+
]
69+
]
70+
];
71+
$this->configMock->expects($this->once())
72+
->method('getServices')
73+
->willReturn($services);
74+
75+
/* example of what $this->config->getServices() returns
76+
$result = [
77+
'async.V1.products.POST' => [
78+
'interface' => 'Magento\Catalog\Api\ProductRepositoryInterface',
79+
'method' => 'save',
80+
'topic' => 'async.magento.catalog.api.productrepositoryinterface.save.post',
81+
]
82+
];
83+
*/
84+
$result = $this->config->getServices();
85+
86+
$expectedTopic = 'async.magento.catalog.api.productrepositoryinterface.save.post';
87+
$lookupKey = 'async.V1.products.POST';
88+
$this->assertArrayHasKey($lookupKey, $result);
89+
$this->assertEquals($result[$lookupKey]['topic'], $expectedTopic);
90+
}
91+
}

dev/tests/integration/testsuite/Magento/AsynchronousOperations/Model/MassScheduleTest.php

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,10 @@ public function sendBulk($products)
128128
}
129129
$this->clearProducts();
130130

131-
$result = $this->massSchedule->publishMass('async.V1.products.POST', $products);
131+
$result = $this->massSchedule->publishMass(
132+
'async.magento.catalog.api.productrepositoryinterface.save.post',
133+
$products
134+
);
132135

133136
//assert bulk accepted with no errors
134137
$this->assertFalse($result->isErrors());
@@ -206,7 +209,7 @@ public function testScheduleMassOneEntityFailure($products)
206209

207210
$expectedErrorMessage = "Data item corresponding to \"product\" " .
208211
"must be specified in the message with topic " .
209-
"\"async.V1.products.POST\".";
212+
"\"async.magento.catalog.api.productrepositoryinterface.save.post\".";
210213
$this->assertEquals(
211214
$expectedErrorMessage,
212215
$reasonException->getMessage()

0 commit comments

Comments
 (0)