Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in
Toggle navigation
Menu
Open sidebar
project
subrequests
Commits
45ed3e84
Unverified
Commit
45ed3e84
authored
Sep 16, 2017
by
Mateu Aguiló Bosch
Browse files
feat(Blueprint): Allow multiple dependencies
parent
235bc9fb
Changes
10
Hide whitespace changes
Inline
Side-by-side
SPECIFICATION.md
View file @
45ed3e84
...
...
@@ -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 ID
s
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"
:
{
...
...
schema.json
View file @
45ed3e84
...
...
@@ -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
}
src/Normalizer/JsonBlueprintDenormalizer.php
View file @
45ed3e84
...
...
@@ -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
);
...
...
src/Subrequest.php
View file @
45ed3e84
...
...
@@ -29,9 +29,9 @@ class Subrequest {
public
$headers
;
/**
* The parent subrequest.
* The parent subrequest
s
.
*
* @var string
* @var string
[]
*/
public
$waitFor
;
...
...
src/SubrequestsTree.php
View file @
45ed3e84
...
...
@@ -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
);
}
}
tests/src/Unit/JsonPathReplacerTest.php
View file @
45ed3e84
...
...
@@ -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>'
);
...
...
tests/src/Unit/Normalizer/JsonBlueprintDenormalizerTest.php
View file @
45ed3e84
...
...
@@ -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
])
...
...
tests/src/Unit/Normalizer/JsonSubrequestDenormalizerTest.php
View file @
45ed3e84
...
...
@@ -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'
,
...
...
tests/src/Unit/SubrequestsManagerTest.php
View file @
45ed3e84
...
...
@@ -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
]]);
...
...
tests/src/Unit/SubrequestsTreeTest.php
View file @
45ed3e84
...
...
@@ -30,7 +30,7 @@ class SubrequestsTreeTest extends UnitTestCase {
'requestId'
=>
1
,
'body'
=>
''
,
'headers'
=>
[],
'waitFor'
=>
1
,
'waitFor'
=>
[
1
]
,
'_resolved'
=>
FALSE
,
'uri'
=>
''
,
'action'
=>
''
,
...
...
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment