I tried to match jsonpath assertion in SOAPUI 5.5.0 with the following statement:
$.root[*][?(#.id==1)].updates
expected = 2
response to test:
{
"root": [
[
{
"id": 2,
"title": "hello world",
"kind": "post",
"updates": 3,
"comments": [...]
},
{
"id": 3,
"title": "how to best practices",
"kind": "post",
"updates": 0,
"comments": [...]
}
],
[
{
"id": 1,
"title": "Release notes...",
"kind": "newsletter",
"updates": 2,
"forks": [...]
}
]
]
}
soapui seems not to find my nested entity with id=1.
There are array of arrays in the root.
You can use below JSONpath to get the desired output
$..[?(#.id==1)].updates[0]
Related
I've been working on an issue and seem to be stuck, so asking on so in case anyone can help.
To describe the issue, I've got an existing Azure Key Vault setup, and wish to add a number of access policies to this resource group. It needs to be conditional as if the function name is "false" then that function should not be added to key vault access policy.
variable section:
"variables": {
"functionAccess": {
"value": [
{
"name": "[parameters('Function_1')]"
},
{
"name": "[parameters('Function_2')]"
},
{
"name": "[parameters('Function_3')]"
}
]
}
}
My Template :
{
"apiVersion": "2016-10-01",
"condition": "[not(equals(variables('functionAccess')[CopyIndex()].name, 'false'))]",
"copy": {
"batchSize": 1,
"count": "[length(variables('functionAccess'))]",
"mode": "Serial",
"name": "accessPolicies"
},
"name": "[concat(parameters('KeyVault_Name'), '/add')]",
"properties": {
"accessPolicies": [
{
"tenantId": "[subscription().tenantId]",
"objectId": "[if(not(equals(variables('functionAccess')[CopyIndex()].name, 'false')), reference(concat('Microsoft.Web/sites/', variables('functionAccess')[CopyIndex()].name), '2016-08-01', 'Full').identity.principalId, json('null'))]",
"permissions": {
"keys": [
"get",
"list"
],
"secrets": [
"get",
"list"
],
"certificates": [
"get",
"list"
]
}
}
]
},
"type": "Microsoft.KeyVault/vaults/accessPolicies"
}
When I deploy my ARM template for the azure key vault I got this error message:
The language expression property '0' can't be evaluated, property name must be a string.
also tried below, but same error:
{
"apiVersion": "2018-02-14",
"name": "[concat(parameters('KeyVault_Name'), '/add')]",
"properties": {
"copy": [
{
"batchSize": 1,
"count": "[length(variables('functionAccess'))]",
"mode": "serial",
"name": "accessPolicies",
"input": {
"condition": "[not(equals(variables('functionAccess')[copyIndex('accessPolicies')].name, 'false'))]",
"tenantId": "[subscription().tenantId]",
"objectId": "[if(not(equals(variables('functionAccess')[copyIndex('accessPolicies')].name, 'false')), reference(concat('Microsoft.Web/sites/', variables('functionAccess')[copyIndex('accessPolicies')].name), '2016-08-01', 'Full').identity.principalId, json('null'))]",
"permissions": {
"keys": [
"get",
"list"
],
"secrets": [
"get",
"list"
],
"certificates": [
"get",
"list"
]
}
}
}
]
},
"type": "Microsoft.KeyVault/vaults/accessPolicies"
}
There are a few options for dealing with filtering an array for copy operation. I deploy my ARM templates from PowerShell scripts and use PowerShell to setup parameter values. When I need special logic handle different inputs for different environments, I let PowerShell handle it.
If you must handle the filtering in ARM and you have the option to input a CSV list of functions, then perhaps the following will work. You can then use the functionAccessArray to iterate over in the copy operation.
{
"$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {
},
"variables": {
"functionAccessCsv": "Function-0,Function-1,false,Function-4,false,Function-6,Function-7",
"functionAccessFiltered": "[replace(replace(variables('functionAccessCsv'), 'false', ''), ',,', ',')]",
"functionAccessArray": "[split(variables('functionAccessFiltered'), ',')]"
},
"resources": [
],
"outputs": {
"functionAccessCsvFiltered": {
"type": "string",
"value": "[variables('functionAccessFiltered')]"
},
"functionAccessArray": {
"type": "array",
"value": "[variables('functionAccessArray')]"
}
}
}
The result:
I just had the same issue. By using an array parameter with a default value instead of a variable, I got it to work.
"parameters": {
"functionAccess": {
"type": "array",
"defaultValue": [
"value1",
"value2",
"value3"
]
}
}
I just start to use Api platform and immediately stuck with problem how to filter data.
I have entity User and i want to filter data that are present in response ( JSON API format)
{
"links": {
"self": "/api/users"
},
"meta": {
"totalItems": 2,
"itemsPerPage": 30,
"currentPage": 1
},
"data": [
{
"id": "/api/users/1",
"type": "User",
"attributes": {
"_id": 1,
"username": "jonhdoe",
"isActive": true,
"address": null
}
},
{
"id": "/api/users/3",
"type": "User",
"attributes": {
"_id": 3,
"username": "test",
"isActive": true,
"address": null
}
}
]
}
so I want to remove e.g. User with id 3, but not use filters sent via request. I just want to set filter that will be always run when someone go to /api/users.
I look to api-platform extensions but this will be applied on each request e.g. /api/trucks. So at end I just want to get something like
{
"links": {
"self": "/api/users"
},
"meta": {
"totalItems": 1,
"itemsPerPage": 30,
"currentPage": 1
},
"data": [
{
"id": "/api/users/1",
"type": "User",
"attributes": {
"_id": 1,
"username": "jonhdoe",
"isActive": true,
"address": null
}
}
]
}
As you pointed out, extensions are the way to go.
The applyToCollection method gets a $resourceClass parameter containing the current resource class.
So you can apply the WHERE clause only for a specific class in this method like:
public function applyToCollection(QueryBuilder $queryBuilder, QueryNameGeneratorInterface $queryNameGenerator, string $resourceClass, string $operationName = null)
{
if (User::class === $resourceClass) {
$queryBuilder->doSomething();
}
// Do nothing for other classes
}
We’ve got a provider test that is only failing on Jenkins, which is preventing me from debugging.
Here are some relevant logs from Jenkins:
Error Message
0 - $.body.2 -> Expected name='FXUHHqWrZZcodhHBmeLf' but was missing
0) a request to get all clients returns a response which has a matching body
$.body.2 -> Expected name='FXUHHqWrZZcodhHBmeLf' but was missing
Diff:
(some ommissions…)
#10
],
- "id": "c53927c3-0d1c-48a8-8f0a-7560be89daa5",
- "name": "FXUHHqWrZZcodhHBmeLf",
+ "id": "9daaad0a-8a2d-4e73-a963-fa1625cec110",
+ "name": "name",
+ "privileges": [
+ "CHECK_TOKEN",
+ "MANAGE_CLIENT",
+ "MANAGE_IDP",
+ "MANAGE_USER"
+ ],
"redirectUris": [
And the interaction looks like this in the pact file:
{
"description": "a request to get all clients",
"request": {
"method": "GET",
"path": "/some/url/client"
},
"response": {
"status": 200,
"headers": {
"Content-Type": "application/json; charset=UTF-8"
},
"body": [
{
"accessTokenValiditySeconds": 42721462,
"allowedScopes": [
"JnTfAlnHKVSDzoWnUqZv"
],
"autoApprove": true,
"grantTypes": [
"VfWudsTQINERQCnVKvoK"
],
"id": "c53927c3-0d1c-48a8-8f0a-7560be89daa5",
"name": "FXUHHqWrZZcodhHBmeLf",
"redirectUris": [
"vWxSTjgJQvwUtwphDGcn"
],
"refreshTokenValiditySeconds": 12393550,
"secretRequired": true
}
],
"matchingRules": {
"$.body[*].allowedScopes[*]": {
"match": "type"
},
"$.body[*].redirectUris[*]": {
"match": "type"
},
"$.body[*].grantTypes[*]": {
"match": "type"
},
"$.body[*].redirectUris": {
"min": 0,
"match": "type"
},
"$.body[*].autoApprove": {
"match": "type"
},
"$.body": {
"min": 1,
"match": "type"
},
"$.body[*].id": {
"regex": "[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}"
},
"$.body[*].accessTokenValiditySeconds": {
"match": "integer"
},
"$.body[*].secretRequired": {
"match": "type"
},
"$.body[*].refreshTokenValiditySeconds": {
"match": "integer"
},
"$.body[*].name": {
"match": "type"
},
"$.body[*].allowedScopes": {
"min": 0,
"match": "type"
},
"$.body[*].grantTypes": {
"min": 0,
"match": "type"
}
}
},
"providerState": "the 'zero' client exists"
},
I'm under the impression that the name should be matching on type instead of the exact value, and it appears that there is a "name" field in the diff.
Why is this test failing?
edit:
This is the code to produce the pact fragment:
builder
.given("the 'zero' client exists")
.uponReceiving("a request to get all clients")
.path("/some/url/client")
.method("GET")
.willRespondWith()
.status(200)
.body(PactDslJsonArray
.arrayMinLike(1)
.uuid("id")
.booleanType("secretRequired")
.eachLike("allowedScopes", stringType())
.eachLike("grantTypes", stringType())
.eachLike("redirectUris", stringType())
.integerType("accessTokenValiditySeconds")
.integerType("refreshTokenValiditySeconds")
.booleanType("autoApprove")
.stringType("name")
.closeObject())
.toFragment();
The important bit of information in the logs is the 'but was missing' bit. It seems to indicate that the third item in the array (matched by '$.body.2') was missing the name attribute.
Can you double check the full response, and if there is a name attribute in the third item, then could you kindly raise an issue at https://github.com/DiUS/pact-jvm.
I'm trying following query :
g.V(835776).out('Follow').in('WallPost').order().by('PostedTimeLong', decr).range(0,2)
and I'm getting following response :
{
"requestId": "524462bc-5e46-40bf-aafd-64d00351dc87",
"status": {
"message": "",
"code": 200,
"attributes": { }
},
"result": {
"data": [
{
"id": 1745112,
"label": "Post",
"type": "vertex",
"properties": {
"PostImage": [
{
"id": "sd97-11ejc-2wat",
"value": ""
}
],
"PostedByUser": [
{
"id": "sc2j-11ejc-2txh",
"value": "orbitpage#gmail.com"
}
],
"PostedTime": [
{
"id": "scgr-11ejc-2upx",
"value": "2016-06-19T09:17:27.6791521Z"
}
],
"PostMessage": [
{
"id": "sbob-11ejc-2t51",
"value": "Hello #[tag:Urnotice_Profile|835776|1] , #[tag:Abhinav_Srivastava|872488|1] and #[tag:Rituraj_Rathore|839840|1]"
}
],
"PostedTimeLong": [
{
"id": "scuz-11ejc-2vid",
"value": 636019246476802029
}
]
}
},
{
"id": 1745112,
"label": "Post",
"type": "vertex",
"properties": {
"PostImage": [
{
"id": "sd97-11ejc-2wat",
"value": ""
}
],
"PostedByUser": [
{
"id": "sc2j-11ejc-2txh",
"value": "orbitpage#gmail.com"
}
],
"PostedTime": [
{
"id": "scgr-11ejc-2upx",
"value": "2016-06-19T09:17:27.6791521Z"
}
],
"PostMessage": [
{
"id": "sbob-11ejc-2t51",
"value": "Hello #[tag:Urnotice_Profile|835776|1] , #[tag:Abhinav_Srivastava|872488|1] and #[tag:Rituraj_Rathore|839840|1]"
}
],
"PostedTimeLong": [
{
"id": "scuz-11ejc-2vid",
"value": 636019246476802029
}
]
}
}
],
"meta": { }
}
}
since same post is posted on two different Id's it is coming twice in response. I want to group by response on basis of vertex id ( both have same vertex id. or i just want to get one object out of them as both are same only.
I've tried following queries but nothing worked for me :
g.V(835776).out('Follow').in('WallPost').groupBy{it.id}.order().by('PostedTimeLong', decr).range(0,3)
g.V(835776).out('Follow').in('WallPost').group().by(id).order().by('PostedTimeLong', decr).range(0,3)
How can I group by the result on basis of vertex id.
The query
g.V(835776).out('Follow').in('WallPost').group().by(id).order().by('PostedTimeLong', decr).range(0,3)
should work, although order().by() and range() will have no effect. However, I don'tthink you really want to group(), you more likely want to dedup():
g.V(835776).out('Follow').in('WallPost').dedup().order().by('PostedTimeLong', decr).limit(3)
I'm thinking of using the JSONAPI standard for the design of our API. One thing this API must be able to do, is accept a compound document (several layers deep) and create it. The root object owns all descendants ('to-many' relationships) which the server knows nothing about at that point, so it's not possible for the client to provide an id.
Is this supported by the specification or does the client have to issue http requests for every object in the document in order?
from http://jsonapi.org/format/#document-compound-documents
Compound documents require "full linkage", meaning that every included
resource MUST be identified by at least one resource identifier object
in the same document. These resource identifier objects could either
be primary data or represent resource linkage contained within primary
or included resources. The only exception to the full linkage
requirement is when relationship fields that would otherwise contain
linkage data are excluded via sparse fieldsets.
{
"data": [{
"type": "articles",
"id": "1",
"attributes": {
"title": "JSON API paints my bikeshed!"
},
"links": {
"self": "http://example.com/articles/1"
},
"relationships": {
"author": {
"links": {
"self": "http://example.com/articles/1/relationships/author",
"related": "http://example.com/articles/1/author"
},
"data": { "type": "people", "id": "9" }
},
"comments": {
"links": {
"self": "http://example.com/articles/1/relationships/comments",
"related": "http://example.com/articles/1/comments"
},
"data": [
{ "type": "comments", "id": "5" },
{ "type": "comments", "id": "12" }
]
}
}
}],
"included": [{
"type": "people",
"id": "9",
"attributes": {
"first-name": "Dan",
"last-name": "Gebhardt",
"twitter": "dgeb"
},
"links": {
"self": "http://example.com/people/9"
}
}, {
"type": "comments",
"id": "5",
"attributes": {
"body": "First!"
},
"links": {
"self": "http://example.com/comments/5"
}
}, {
"type": "comments",
"id": "12",
"attributes": {
"body": "I like XML better"
},
"links": {
"self": "http://example.com/comments/12"
}
}]
}