What is the proper way to create a vertex with a set property in Bluemix Graph DB? - ibm-cloud

I am trying to create a new vertex in the Bluemix Graph DB service. The schema of my DB is as follows.
{"propertyKeys":[{"name":"name","dataType":"String","cardinality":"SINGLE"},{"name":"languages","dataType":"String","cardinality":"SET"},{"name":"picture","dataType":"String","cardinality":"SINGLE"},{"name":"preferred_language","dataType":"String","cardinality":"SINGLE"},{"name":"bytes","dataType":"Integer","cardinality":"SINGLE"},{"name":"github_id","dataType":"String","cardinality":"SINGLE"},{"name":"twitter_id","dataType":"String","cardinality":"SINGLE"},{"name":"language_percentage","dataType":"Float","cardinality":"SINGLE"}],"vertexLabels":[{"name":"person"},{"name":"language"}],"edgeLabels":[{"name":"codes_in","multiplicity":"MULTI"},{"name":"used_by","multiplicity":"MULTI"}],"vertexIndexes":[{"name":"vByName","propertyKeys":["name"],"composite":true,"unique":false},{"name":"vByPreferredLang","propertyKeys":["preferred_language"],"composite":true,"unique":false},{"name":"vByLanguages","propertyKeys":["languages"],"composite":false,"unique":false}],"edgeIndexes":[{"name":"eByName","propertyKeys":["name"],"composite":true,"unique":false},{"name":"eByLanguagePercentage","propertyKeys":["language_percentage"],"composite":true,"unique":false}]}
I am trying to create the vertex with the following POST body
{"name":"Bob","languages":["Node","Python"],"picture":"https://en.gravatar.com/userimage/12148147/46ccae88e5aae747d53e0b1863f72a4e.jpg?size=200","preferred_language":"Node","github_id":"Bob","twitter_id":"Bob"}
However this results in the following error
{"code":"BadRequestError","message":"Property 'languages' with meta properties need to have a 'val'"}
The languages property has a cardinality of SET, what is the right way to create a property for a SET dataType? I would have assumed it was a JSON array.

Ryan, SET isn't a data type. You could also make languages a string with delimited values.
The only types that are supported in the Beta release are : String,Integer,Boolean,Float

The issue is that you're attempting to create a single vertex property with a data type of List<String>, which is not supported in IBM Graph (only JSON-primitive types are supported). To take advantage of a property with a SET data type you'll need to create multiple vertex properties.
It turns out that the distinction between cardinalities and data types in TinkerPop can be a bit of a confusing. Here's an example that should clarify things:
$ curl https://ibmgraph/11/g/schema -XPOST -Hcontent-type:application/json -d '{"propertyKeys":[{"name":"languages","dataType":"String","cardinality":"SET"}]}' | jq .
{
"requestId": "9e0ea947-f9a1-407b-ab1a-cd9b7fd5d561",
"status": {
"message": "",
"code": 200,
"attributes": {}
},
"result": {
"data": [
{
"propertyKeys": [
{
"name": "languages",
"dataType": "String",
"cardinality": "SET"
}
],
"vertexLabels": [],
"edgeLabels": [],
"vertexIndexes": [],
"edgeIndexes": []
}
],
"meta": {}
}
}
$ curl https://ibmgraph/11/g/vertices -XPOST | jq .
{
"requestId": "2ce85907-2aca-4630-876f-31775e74e1de",
"status": {
"message": "",
"code": 200,
"attributes": {}
},
"result": {
"data": [
{
"id": 4112,
"label": "vertex",
"type": "vertex",
"properties": {}
}
],
"meta": {}
}
}
$ curl https://ibmgraph/11/g/vertices/4112 -XPOST -Hcontent-type:application/json -d '{"languages":"Node"}' | jq .
{
"requestId": "52ad6d49-46c9-41aa-9928-5a567099d773",
"status": {
"message": "",
"code": 200,
"attributes": {}
},
"result": {
"data": [
{
"id": 4112,
"label": "vertex",
"type": "vertex",
"properties": {
"languages": [
{
"id": "si-368-sl",
"value": "Node"
}
]
}
}
],
"meta": {}
}
}
$ curl https://ibmgraph/11/g/vertices/4112 -XPOST -Hcontent-type:application/json -d '{"languages":"Python"}' | jq .
{
"requestId": "19886949-6328-4e19-8cac-8fdab37ef2a5",
"status": {
"message": "",
"code": 200,
"attributes": {}
},
"result": {
"data": [
{
"id": 4112,
"label": "vertex",
"type": "vertex",
"properties": {
"languages": [
{
"id": "si-368-sl",
"value": "Node"
},
{
"id": "16q-368-sl",
"value": "Python"
}
]
}
}
],
"meta": {}
}
}

Related

How to pass paramters to argo workflow api

I am running my workflow through argo workflow api ,and I am not able to pass dynamic input paramters
curl -k --request POST \
--url https://localhost:2746/api/v1/workflows/argo \
--header 'content-type: application/json' \
--data '{
"namespace": "argo",
"serverDryRun": false,
"workflow": {
"metadata": {
"generateName": "hello-world-",
"namespace": "argo",
"labels": {
"workflows.argoproj.io/completed": "false"
}
},
"spec": {
"templates": [
{
"name": "whalesay",
"arguments": {},
"inputs": {
"parameters":{
"name":"sh#yahoo.com"
}
},
"outputs": {},
"metadata": {},
"container": {
"name": "",
"image": "gandalf/patientreg",
"command": [
"./app"
],
"args": [
""
],
"resources": {}
}
}
],
"entrypoint": "whalesay",
"arguments": {}
}
}
}'
I am getting this error while running the workflow
{"code":3,"message":"json: cannot unmarshal object into Go struct
field Inputs.workflow.spec.templates.inputs.parameters of type
[]v1alpha1.Parameter"}%
I want to pass dynamic email through api and receive if as command line arguments in my app such that I can run my workflow .
How to achieve that ?
You can pass parameters to the workflow which instead can be sent to any step inside the workflow. The parameter should have a name. In your example you are only passing the value directly to the step.
Here is an example payload.
{
"workflow": {
"metadata": {
"name": "awesome-dragon",
"namespace": "argo",
"labels": {
"example": "true"
}
},
"spec": {
"arguments": {
"parameters": [
{
"name": "workflow-arg",
"value": "mail.from#outside.code"
}
]
},
"entrypoint": "argosay",
"templates": [
{
"name": "argosay",
"inputs": {
"parameters": [
{
"name": "step-level-arg",
"value": "{{workflow.parameters.workflow-arg}}"
}
]
},
"container": {
"name": "main",
"image": "argoproj/argosay:v2",
"command": [
"/argosay"
],
"args": [
"echo",
"{{inputs.parameters.step-level-arg}}"
]
}
}
],
"ttlStrategy": {
"secondsAfterCompletion": 300
},
"podGC": {
"strategy": "OnPodCompletion"
}
}
}
}
Note that an named argument is passed from outside to the argo workflow. The same workflow argument can be utilized any template inside.

What is the reason fo this difference in Facebook messages webhook JSON scheme?

I'm reading the Facebook Send API and events docs, and I'm surprised to see some examples define the message at the top level of the JSON object hierarchy (here for "text message")
{
"sender":{
"id":"<PSID>"
},
"recipient":{
"id":"<PAGE_ID>"
},
"timestamp":1458692752478,
"message":{
"mid":"mid.1457764197618:41d102a3e1ae206a38",
"text":"hello, world!",
"quick_reply": {
"payload": "<DEVELOPER_DEFINED_PAYLOAD>"
}
}
}
While others examples have a different object structure:
{
"id": "682498302938465",
"time": 1518479195594,
"messaging": [
{
"sender": {
"id": "<PSID>"
},
"recipient": {
"id": "<PAGE_ID>"
},
"timestamp": 1518479195308,
"message": {
"mid": "mid.$cAAJdkrCd2ORnva8ErFhjGm0X_Q_c",
"attachments": [
{
"type": "<image|video|audio|file>",
"payload": {
"url": "<ATTACHMENT_URL>"
}
}
]
}
}
]
}
Here is seems like the object is the first example is instead contained in a messaging array. I can't find either what id corresponds to in this second example : there is no table detailing the fields on why the hierarchy is different here.
Finally, there is another example with a different structure:
{
"object": "page",
"entry": [
{
"id": "<PAGE_ID>",
"time": 1583173667623,
"messaging": [
{
"sender": {
"id": "<PSID>"
},
"recipient": {
"id": "<PAGE_ID>"
},
"timestamp": 1583173666767,
"message": {
"mid": "m_toDnmD...",
"text": "This is where I want to go: https:\/\/youtu.be\/bbo_fZAjIhg",
"attachments": [
{
"type": "fallback",
"payload": {
"url": "<ATTACHMENT_URL >",
"title": "TAHITI - Heaven on Earth"
}
}
]
}
}
]
}
]
}
Are these differences documented elsewhere? Why do they exist in the first place? Why is messaging an array? Can it contain multiple messages at once?

Upserting multiple entities to context broker

Is there a way to upsert multiple enitites to the Context Broker v2 in a single http-request like submitting an array in the request?
I have something like this in mind:
[POST] /v2/entities/?options=upsert
[
{
id: 'urn:ngsi-ld:xyz:123',
type: 'xyz',
...
},
{
id: 'urn:ngsi-ld:xyz:456',
type: 'xyz',
...
},
...
]
Yes, using POST /v2/update with append action type. For instance (example taken from NGSIv2 API walkthrough):
POST /v2/op/update
{
"actionType": "append",
"entities": [
{
"type": "Room",
"id": "Room3",
"temperature": {
"value": 21.2,
"type": "Float"
},
"pressure": {
"value": 722,
"type": "Integer"
}
},
{
"type": "Room",
"id": "Room4",
"temperature": {
"value": 31.8,
"type": "Float"
},
"pressure": {
"value": 712,
"type": "Integer"
}
}
]
}
That will update Room3 and Room4 entities if they previously exist or create them if they don't previously exist.

Perseo rule can't be created: Event type not found

I'm emulating a dummy scenario to play around with Perseo and Orion. I'm using 4 docker containers: Mongo, Orion, Perseo FE, and Perseo Core. All of them running healthy.
The steps that I'm doing are:
First, I create the entity with POST to Orion (localhost:1026/v2/entities). This entity looks like this:
{
"id": "DummyEvent1",
"type": "DummyEvent",
"identification": {
"value": "default",
"type": "String"
}
}
Second, I create a subscription with a POST to Orion (localhost:1026/v2/subscriptions) in order to push this DummyEvent from Orion to Perseo:
{
"description": "A subscription to get info about DummyEvent1",
"subject": {
"entities": [
{
"id": "DummyEvent1",
"type": "DummyEvent"
}
],
"condition": {
"attrs": [ ]
}
},
"notification": {
"http": {
"url": "http://perseo-fe:9090/notices"
},
"attrs": [
"identification"
]
}
}
Third, If I GET all the subscriptions in Orion (localhost:1026/v2/subscriptions), I can see that Orion is forwading the DummyEvent correctly to Perseo:
{
"id": "5ca5c18ab07f5ae96aa12152",
"description": "A subscription to get info about DummyEvent1",
"status": "active",
"subject": {
"entities": [
{
"id": "DummyEvent1",
"type": "DummyEvent"
}
],
"condition": {
"attrs": []
}
},
"notification": {
"timesSent": 1,
"lastNotification": "2019-04-04T08:34:18.00Z",
"attrs": [
"identification"
],
"attrsFormat": "normalized",
"http": {
"url": "http://perseo-fe:9090/notices"
},
"lastSuccess": "2019-04-04T08:34:18.00Z",
"lastSuccessCode": 200
}
}
Fourth, But the problem appears when I try to POST a rule in Perseo (localhost:8080/perseo-core/rules) using this DummyEvent:
{
"name": "dummy_rule",
"text": "select * from DummyEvent",
"action": {
"type": "update",
"parameters": {
"name": "identification",
"value": "updatedValue",
"type": "string"
}
}
}
Perseo tells me this:
{
"error": "Failed to resolve event type: Event type or class named 'DummyEvent' was not found [select * from DummyEvent]"
}
What am I doing wrong?
Thanks!

FIWARE Orion: use query string in subscription payload

Currently the '=' sign is forbidden in Orion:
http://fiware-orion.readthedocs.io/en/1.5.0/user/forbidden_characters/index.html
But this prevents to make a subscription with a query string:
$ (curl broker.waziup.io/v1/subscribeContext -s -S --header 'Content-Type: application/json' \
--header 'Accept: application/json' --header 'Fiware-Service:waziup' --header 'Fiware-ServicePath:/TEST' -d #- | python -mjson.tool) <<EOF
{
"entities": [
{
"type": "SensingDevice",
"isPattern": "false",
"id": "Sensor1"
}
],
"attributes": [
"temperature"
],
"reference": "http://localhost/v1/sms/send?contact=0039&msg=Sensor1",
"duration": "P1M",
"notifyConditions": [
{
"type": "ONCHANGE",
"condValues": [
"temperature"
]
}
],
"throttling": "PT1S"
}
EOF
Results in:
{
"subscribeError": {
"errorCode": {
"code": "400",
"details": "Illegal value for JSON field",
"reasonPhrase": "Bad Request"
}
}
}
The query string is used to pass parameters to the callback server (I don't see other ways to do it).
Any way around this?
There is a way of setting query parameters in the notification URL, based in custom notifications in NGSIv2. Have a look to "Custom Notifications" section in the NGSIv2 specification.
The subscription you are doing would be something like this:
POST /v2/subscriptions
...
{
"subject": {
"entities": [
{
"id": "Sensor1",
"type": "SensingDevice"
}
],
"condition": {
"attrs": [ "temperature" ]
}
},
"notification": {
"httpCustom": {
"url": "http://localhost/v1/sms/send",
"qs": {
"contact": "0039",
"msg": "Sensor1"
}
},
"attrs": [ "temperature"]
},
"expires": "2016-05-07T18:30:00.00Z",
"throttling": 1
}
Note that you could even generalize the subscriptions for all your sensors using templates, in the following way:
POST /v2/subscriptions
...
{
"subject": {
"entities": [
{
"idPattern": "Sensor.*",
"type": "SensingDevice"
}
],
"condition": {
"attrs": [ "temperature" ]
}
},
"notification": {
"httpCustom": {
"url": "http://localhost/v1/sms/send",
"qs": {
"contact": "0039",
"msg": "${id}"
}
},
"attrs": [ "temperature"]
},
"expires": "2016-05-07T18:30:00.00Z",
"throttling": 1
}