summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMateu Aguiló Bosch2017-09-16 03:46:14 +0200
committerMateu Aguiló Bosch2017-09-16 05:07:23 +0200
commit45ed3e84aa787657a9d6412422c45a237164c5f4 (patch)
tree55628fd27b68831e5378eadc90db720ff8126ef2
parent235bc9fbfd129b15b17fae1113742f8251297d70 (diff)
feat(Blueprint): Allow multiple dependencies
-rw-r--r--SPECIFICATION.md12
-rw-r--r--schema.json10
-rw-r--r--src/Normalizer/JsonBlueprintDenormalizer.php13
-rw-r--r--src/Subrequest.php4
-rw-r--r--src/SubrequestsTree.php18
-rw-r--r--tests/src/Unit/JsonPathReplacerTest.php4
-rw-r--r--tests/src/Unit/Normalizer/JsonBlueprintDenormalizerTest.php6
-rw-r--r--tests/src/Unit/Normalizer/JsonSubrequestDenormalizerTest.php4
-rw-r--r--tests/src/Unit/SubrequestsManagerTest.php6
-rw-r--r--tests/src/Unit/SubrequestsTreeTest.php2
10 files changed, 48 insertions, 31 deletions
diff --git a/SPECIFICATION.md b/SPECIFICATION.md
index fc6bf07..f66aae2 100644
--- a/SPECIFICATION.md
+++ b/SPECIFICATION.md
@@ -97,10 +97,10 @@ properties:
* `body`: the serialized content of the body for the subrequest.
* `headers`: an object of key value pairs. Each key **MUST** be interpreted as
a header name for the subrequest, and the values as the header value.
- * `waitFor`: contains the request ID from another request. Indicates that the
- current subrequest depends on the other subrequest. When this property is
- present, the that particular subrequest cannot be processed until the
- referenced request has generated a response.
+ * `waitFor`: contains the array of request IDs from another request. Indicates
+ that the current subrequest depends on the other subrequest. When this
+ property is present, the that particular subrequest cannot be processed
+ until the referenced request has generated a response.
### Sequential requests
Many times it is necessary to use the information of previous requests in order
@@ -166,7 +166,7 @@ the request blueprint to express dependencies.
},
{
"requestId": "req-2",
- "waitFor": "req-1",
+ "waitFor": ["req-1"],
"uri": "/menus/{{req-1.body@$.rels.meny.id}}",
"action": "view",
"headers": {
@@ -175,7 +175,7 @@ the request blueprint to express dependencies.
},
{
"requestId": "req-3",
- "waitFor": "req-2",
+ "waitFor": ["req-2"],
"uri": "/menus/{{req-1.body@$.rels.meny.id}}/courses/{{req-2.body@$.mainCourse.id}}",
"action": "view",
"headers": {
diff --git a/schema.json b/schema.json
index d9222c7..67be6bf 100644
--- a/schema.json
+++ b/schema.json
@@ -61,10 +61,14 @@
},
"waitFor": {
"title": "Parent ID",
- "description": "ID of another request that is a dependeny for this one.",
- "type": "string"
+ "description": "ID of other requests that this request depends on.",
+ "type": "array",
+ "items": {
+ "type": "string",
+ "description": "ID of another request that is a dependency for this one."
+ }
}
}
}
}
-} \ No newline at end of file
+}
diff --git a/src/Normalizer/JsonBlueprintDenormalizer.php b/src/Normalizer/JsonBlueprintDenormalizer.php
index bc0afd1..19b4554 100644
--- a/src/Normalizer/JsonBlueprintDenormalizer.php
+++ b/src/Normalizer/JsonBlueprintDenormalizer.php
@@ -4,12 +4,10 @@ namespace Drupal\subrequests\Normalizer;
use Drupal\Component\Serialization\Json;
use Drupal\Component\Uuid\Php;
-use Drupal\subrequests\Blueprint\RequestTree;
use Drupal\subrequests\Subrequest;
use Drupal\subrequests\SubrequestsTree;
use JsonSchema\Validator;
use Psr\Log\LoggerInterface;
-use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpKernel\Exception\BadRequestHttpException;
use Symfony\Component\Serializer\Normalizer\DenormalizerInterface;
use Symfony\Component\Serializer\SerializerAwareInterface;
@@ -121,7 +119,7 @@ class JsonBlueprintDenormalizer implements DenormalizerInterface, SerializerAwar
$raw_item['body'] = Json::decode($raw_item['body']);
}
$raw_item['headers'] = !empty($raw_item['headers']) ? $raw_item['headers'] : [];
- $raw_item['waitFor'] = !empty($raw_item['waitFor']) ? $raw_item['waitFor'] : '<ROOT>';
+ $raw_item['waitFor'] = !empty($raw_item['waitFor']) ? $raw_item['waitFor'] : ['<ROOT>'];
$raw_item['_resolved'] = FALSE;
return $raw_item;
@@ -175,19 +173,16 @@ class JsonBlueprintDenormalizer implements DenormalizerInterface, SerializerAwar
public function buildExecutionSequence(array $parsed) {
$sequence = new SubrequestsTree();
$rooted_reqs = array_filter($parsed, function (Subrequest $item) {
- return $item->waitFor === '<ROOT>';
+ return $item->waitFor === ['<ROOT>'];
});
$sequence->stack($rooted_reqs);
$subreqs_with_unresolved_deps = array_values(
array_filter($parsed, function (Subrequest $item) {
- return $item->waitFor !== '<ROOT>';
+ return $item->waitFor !== ['<ROOT>'];
})
);
$dependency_is_resolved = function (Subrequest $item) use ($sequence) {
- $parent = array_filter($sequence->getLowestLevel(), function (Subrequest $dep) use ($item) {
- return $dep->requestId === $item->waitFor;
- });
- return !empty($parent);
+ return empty(array_diff($item->waitFor, $sequence->allIds()));
};
while (count($subreqs_with_unresolved_deps)) {
$no_deps = array_filter($subreqs_with_unresolved_deps, $dependency_is_resolved);
diff --git a/src/Subrequest.php b/src/Subrequest.php
index a8872bf..d66c2f7 100644
--- a/src/Subrequest.php
+++ b/src/Subrequest.php
@@ -29,9 +29,9 @@ class Subrequest {
public $headers;
/**
- * The parent subrequest.
+ * The parent subrequests.
*
- * @var string
+ * @var string[]
*/
public $waitFor;
diff --git a/src/SubrequestsTree.php b/src/SubrequestsTree.php
index e3429f6..07edeec 100644
--- a/src/SubrequestsTree.php
+++ b/src/SubrequestsTree.php
@@ -67,4 +67,22 @@ class SubrequestsTree extends \ArrayObject {
$this->masterRequest = $request;
}
+ /**
+ * Gets all the subrequest IDs.
+ *
+ * @return \Drupal\subrequests\Subrequest[]
+ * All the subrequests in all levels.
+ */
+ public function allIds() {
+ $subrequests = [];
+ foreach ($this as $item) {
+ $subrequests = array_merge($subrequests, array_values($item));
+ }
+ $all_request_ids = array_map(function (Subrequest $subrequest) {
+ return $subrequest->requestId;
+ }, $subrequests);
+ array_unshift($all_request_ids, '<ROOT>');
+ return array_unique($all_request_ids);
+ }
+
}
diff --git a/tests/src/Unit/JsonPathReplacerTest.php b/tests/src/Unit/JsonPathReplacerTest.php
index ea7fe81..59fb7f0 100644
--- a/tests/src/Unit/JsonPathReplacerTest.php
+++ b/tests/src/Unit/JsonPathReplacerTest.php
@@ -35,7 +35,7 @@ class JsonPathReplacerTest extends UnitTestCase {
'headers' => [],
'_resolved' => FALSE,
'body' => ['answer' => '{{foo.body@$.stuff}}'],
- 'waitFor' => 'foo',
+ 'waitFor' => ['foo'],
]);
$batch[] = new Subrequest([
'uri' => '/dolor/{{foo.body@$.stuff}}',
@@ -44,7 +44,7 @@ class JsonPathReplacerTest extends UnitTestCase {
'headers' => [],
'_resolved' => FALSE,
'body' => 'bar',
- 'waitFor' => 'foo',
+ 'waitFor' => ['foo'],
]);
$response = Response::create('{"things":["what","keep","talking"],"stuff":42}');
$response->headers->set('Content-ID', '<foo>');
diff --git a/tests/src/Unit/Normalizer/JsonBlueprintDenormalizerTest.php b/tests/src/Unit/Normalizer/JsonBlueprintDenormalizerTest.php
index 1248fa5..f3d93d2 100644
--- a/tests/src/Unit/Normalizer/JsonBlueprintDenormalizerTest.php
+++ b/tests/src/Unit/Normalizer/JsonBlueprintDenormalizerTest.php
@@ -56,18 +56,18 @@ class JsonBlueprintDenormalizerTest extends UnitTestCase {
'action' => 'sing',
'requestId' => 'oop',
'body' => '[]',
- 'waitFor' => 'foo',
+ 'waitFor' => ['foo'],
];
$subrequests[] = [
'uri' => 'lorem',
'action' => 'create',
'requestId' => 'oof',
'body' => '"bar"',
- 'waitFor' => 'foo',
+ 'waitFor' => ['foo'],
];
$actual = $this->sut->denormalize($subrequests, SubrequestsTree::class, 'json', []);
$tree = new SubrequestsTree();
- $tree->stack([new Subrequest(['waitFor' => '<ROOT>', '_resolved' => FALSE, 'body' => 'bar'] + $subrequests[0])]);
+ $tree->stack([new Subrequest(['waitFor' => ['<ROOT>'], '_resolved' => FALSE, 'body' => 'bar'] + $subrequests[0])]);
$tree->stack([
new Subrequest(['headers' => [], '_resolved' => FALSE, 'body' => []] + $subrequests[1]),
new Subrequest(['headers' => [], '_resolved' => FALSE, 'body' => 'bar'] + $subrequests[2])
diff --git a/tests/src/Unit/Normalizer/JsonSubrequestDenormalizerTest.php b/tests/src/Unit/Normalizer/JsonSubrequestDenormalizerTest.php
index 2dbdd1d..77e54a3 100644
--- a/tests/src/Unit/Normalizer/JsonSubrequestDenormalizerTest.php
+++ b/tests/src/Unit/Normalizer/JsonSubrequestDenormalizerTest.php
@@ -34,7 +34,7 @@ class JsonSubrequestDenormalizerTest extends UnitTestCase {
'requestId' => 'oof',
'body' => ['bar' => 'foo'],
'headers' => ['Authorization' => 'Basic ' . base64_encode('lorem:ipsum')],
- 'waitFor' => 'lorem',
+ 'waitFor' => ['lorem'],
'_resolved' => FALSE,
'uri' => 'oop',
'action' => 'create',
@@ -63,7 +63,7 @@ class JsonSubrequestDenormalizerTest extends UnitTestCase {
'requestId' => 'oof',
'body' => ['bar' => 'foo'],
'headers' => [],
- 'waitFor' => 'lorem',
+ 'waitFor' => ['lorem'],
'_resolved' => FALSE,
'uri' => 'oop',
'action' => 'create',
diff --git a/tests/src/Unit/SubrequestsManagerTest.php b/tests/src/Unit/SubrequestsManagerTest.php
index 24b3f2e..2d2912c 100644
--- a/tests/src/Unit/SubrequestsManagerTest.php
+++ b/tests/src/Unit/SubrequestsManagerTest.php
@@ -65,7 +65,7 @@ class SubrequestsManagerTest extends UnitTestCase {
'action' => 'view',
'requestId' => 'foo',
'headers' => [],
- 'waitFor' => '<ROOT>',
+ 'waitFor' => ['<ROOT>'],
'_resolved' => FALSE,
'body' => 'bar',
]);
@@ -76,7 +76,7 @@ class SubrequestsManagerTest extends UnitTestCase {
'headers' => [],
'_resolved' => FALSE,
'body' => [],
- 'waitFor' => 'foo',
+ 'waitFor' => ['foo'],
]);
$subrequests[] = new Subrequest([
'uri' => 'dolor',
@@ -85,7 +85,7 @@ class SubrequestsManagerTest extends UnitTestCase {
'headers' => [],
'_resolved' => FALSE,
'body' => 'bar',
- 'waitFor' => 'foo',
+ 'waitFor' => ['foo'],
]);
$tree->stack([$subrequests[0]]);
$tree->stack([$subrequests[1], $subrequests[2]]);
diff --git a/tests/src/Unit/SubrequestsTreeTest.php b/tests/src/Unit/SubrequestsTreeTest.php
index daee7e6..cdedf97 100644
--- a/tests/src/Unit/SubrequestsTreeTest.php
+++ b/tests/src/Unit/SubrequestsTreeTest.php
@@ -30,7 +30,7 @@ class SubrequestsTreeTest extends UnitTestCase {
'requestId' => 1,
'body' => '',
'headers' => [],
- 'waitFor' => 1,
+ 'waitFor' => [1],
'_resolved' => FALSE,
'uri' => '',
'action' => '',