How to do either operation in IRItemplate in a Hydra:Operation? - rest

My hydra vocab is similar to Markus-lanthaler Vocab.Here is one of my operation on User Class to retrieve collection of Users.
{
"#id": "payu:retrieve_users",
"#type": "hydra:Operation",
"method": "GET",
"label": "Retrieve users",
"description": "Retrieves Users",
"expects": null,
"returns": "hydra:Collection",
"IriTemplate" : {
"#type" : "IriTemplate",
"template" : "{?userIds,firstName,lastName}",
"variableRepresentation": "BasicRepresentation",
"mapping" : [
{
"#type" : "IriTemplateMapping",
"variable" : "userIds",
"property" : "hydra:property",
"required" : false
},
{
"#type" : "IriTemplateMapping",
"variable" : "firstName",
"property" : "hydra:property",
"required" : false
},
{
"#type" : "IriTemplateMapping",
"variable" : "lastName",
"property" : "hydra:property",
"required" : false
}
]
}
}
As you can see in IRItemplate
"template" : "{?userIds,firstName,lastName}"
so I want to get control over retrieve either a third person will be able to retrieve through (userIds) or (firstName,lastName).
Should I make two separate hydra Operations having IRItemplate :
In First Operation:
"template" : "{?userIds}"
In Second Operation:
"template" : "{?firstName,lastName}"
Or Is there any existing way to do this in Hydra Specification using single operation ?

Currently there's no way to specify that for a single operation. You'll need to have two operations. Also, you need to associate the operation to the IriTemplate and not the other way round:
{
"#type" : "IriTemplate",
"template" : "{?userIds,firstName,lastName}",
...
"operation": {
"#id": "payu:retrieve_users",
"#type": "hydra:Operation",
"method": "GET",
...
}
}

Related

Simple JOLT transformation. Add one level and paste part of attributes here

Please, help to modify next json. I need add one level and paste part of attributes here.
Input:
{
"Name" : "Some order",
"Status" : "New",
"Project" : "Some project",
"Goal" : "Some goal",
"Urgency" : "",
"URL" : "",
"table_name": "Order"
}
Desired output:
{
"row": {
"Name" : "Some order",
"Status" : "New",
"Project" : "Some project",
"Goal" : "Some goal",
"Urgency" : "",
"URL" : ""
},
"table_name": "Order"
}
If you have some cool sources about JOLT, please, share.
You can use the following shift transformation spec
[
{
"operation": "shift",
"spec": {
"table_name": "&",
"*": "row.&"
}
}
]
where you just need to nest the elements under row key other than the element with table_name key. &(&0) represents the nearest key(without going up any level, eg. in that case you would need to use &1,&2...etc in order to go 1,2,.. levels up)
You can check this site out as a nice reference.

Terraform ARM-Template fails because of not unique ID

I use the following Terraform ARM template to deploy to Azure Stack:
...
resource "azurestack_template_deployment" "nsg-rule1" {
count = "${var.nsgr_map["nsg_sourceportranges"] == "" && var.nsgr_map["nsg_destinationportranges"] == "" && var.nsgr_map["nsg_sourceaddressprefixes"] == "" && var.nsgr_map["nsg_destinationaddressprefixes"] == "" ? 1 : 0}"
name = "${var.nsgr_map["nsg_rulename"]}"
resource_group_name = "${var.nsgr_map["rsg_name"]}"
template_body = <<DEPLOY
{
"$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"networkSecurityGroupName": {
"type": "String"
},
"networkSecurityGroupRuleName": {
"type" : "String"
},
"protocol" : {
"type" : "String"
},
"sourcePortRange": {
"type" : "String"
},
"destinationPortRange": {
"type" : "String"
},
"sourceAddressPrefix" : {
"type" : "String"
},
"destinationAddressPrefix" : {
"type" : "String"
},
"access" : {
"type" : "String"
},
"priority" : {
"type" : "String"
},
"direction" : {
"type" : "String"
},
"sourcePortRanges" : {
"type" : "String"
},
"destinationPortRanges" : {
"type" : "String"
},
"sourceAddressPrefixes" : {
"type" : "String"
},
"destinationAddressPrefixes" : {
"type" : "String"
}
},
"variables": {},
"resources": [
{
"type": "Microsoft.Network/networkSecurityGroups/securityRules",
"apiVersion": "2017-10-01",
"name": "[concat(parameters('networkSecurityGroupName'),'/',parameters('networkSecurityGroupRuleName'))]",
"properties": {
"protocol": "[parameters('protocol')]",
"sourcePortRange": "[parameters('sourcePortRange')]",
"destinationPortRange": "[parameters('destinationPortRange')]",
"sourceAddressPrefix": "[parameters('sourceAddressPrefix')]",
"destinationAddressPrefix": "[parameters('destinationAddressPrefix')]",
"access": "[parameters('access')]",
"priority": "[parameters('priority')]",
"direction": "[parameters('direction')]",
"sourcePortRanges": "[parameters('sourcePortRanges')]",
"destinationPortRanges": "[parameters('destinationPortRanges')]",
"sourceAddressPrefixes": "[parameters('sourceAddressPrefixes')]",
"destinationAddressPrefixes": "[parameters('destinationAddressPrefixes')]"
}
}
]
}
DEPLOY
# these key-value pairs are passed into the ARM Template's `parameters` block
parameters = {
networkSecurityGroupName = "${var.nsgr_map["nsg_name"]}"
networkSecurityGroupRuleName = "${var.nsgr_map["nsg_rulename"]}"
protocol = "${var.nsgr_map["nsg_protocol"]}"
sourcePortRange = "${var.nsgr_map["nsg_source_portrange"]}"
destinationPortRange = "${var.nsgr_map["nsg_destination_portrange"]}"
sourceAddressPrefix ="${var.nsgr_map["nsg_sourceaddressprefix"]}"
destinationAddressPrefix = "${var.nsgr_map["nsg_destinationaddressprefix"]}"
access = "${var.nsgr_map["nsg_access"]}"
priority = "${var.nsgr_map["nsg_priority"]}"
direction = "${var.nsgr_map["nsg_direction"]}"
sourcePortRanges = ""
destinationPortRanges = ""
sourceAddressPrefixes = ""
destinationAddressPrefixes = ""
}
deployment_mode = "Incremental"
}
...
In fact I want to add to an existing Network Security Group (NSG) on Azure Stack, some NSG-rules.
The problem is that if I deploy different rules with the same name under the same resource group the deployment fails because the NSG is not part of the ID, which identifies the resource to create.
In other words I have two rules with the same name - say 'NSG_Rule_Open_VPN' under the resource group 'Virtual_Network_1' but for two different network security groups 'nsg_1' and 'nsg_2'.
Then the deployment fails with an error, because Terraform deploys the same resource twice (but the targeted NSG's are not the same)
If I look to the activity protocol on Azure Stack it becomes clear that Terraform doesn't use the name of the targeted NSG in the ID to create the resource:
"resourceId": "/subscriptions/yyyxxx/resourcegroups/RSG_99_VirtualNetwork_01/providers/Microsoft.Resources/deployments/NSR_out_TCP_allow_VMtoINTERNET-HTTPS",
It uses only the resource group name 'RSG_99_VirtualNetwork_01' and the rule name 'NSR_out_TCP_allow_VMtoINTERNET-HTTPS' but not the NSG name.
Is there a way to avoid this. so that Terraform creates a resourceID which also has a dependency to the NSG name?
this happens because this is the deployment name, not the NSG rule name. so you need to update this bit to include nsg-name or some counter or something random:
resource "azurestack_template_deployment" "nsg-rule1" {
count = not_important_removed
name = "${var.nsgr_map["nsg_rulename"]}" # this bit needs to be updated
resource_group_name = "${var.nsgr_map["rsg_name"]}"

aws cloudformation -resource property error

I have defined my parameters like this:
{
"PrivateSubnets":{
"Description":"db subnetlist",
"Type": "List<AWS::EC2::Subnet::Id>"
},
"VPCLIST": {
"Description": "VPC list",
"Type": "List<AWS::EC2::VPC::Id>"
}
}
and referring the above parameters in "resources" section like below:
"InstanceSecurityGroup" : {
"Type" : "AWS::EC2::SecurityGroup",
"Properties" : {
"VpcId" : {"Ref": "VPCLIST"} ,
"GroupDescription" : "Enable 3306/80/SSH access via port 22"
}
and while executing this I am getting the below error.
AWS::EC2::SecurityGroup InstanceSecurityGroup "Value of property VpcId must be of type String"
Note: I have only default VPC available which is not taken as string? any solutions to this issue...
The correct way is make this change:
{
"PrivateSubnets": {
"Description":"db subnetlist",
"Type": "AWS::EC2::Subnet::Id"
},
"VPCLIST": {
"Description": "VPC list",
"Type": "AWS::EC2::VPC::Id"
}
}
The Security Groups requires the VpcId to be a string, the property is an array list, So you need to change the property to Type: String, or use the
Fn::Select function.
{ "Fn::Select" : [ 0, VPCLIST ] }
List – An array of VPC IDs
{
"Type" : "AWS::EC2::SecurityGroup",
"Properties" : {
"GroupName" : String,
"GroupDescription" : String,
"SecurityGroupEgress" : [ Security Group Rule, ... ],
"SecurityGroupIngress" : [ Security Group Rule, ... ],
"Tags" : [ Resource Tag, ... ],
"VpcId" : String
}
}
http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-security-group.html

Multiple entities in schema.org

How do I nest one or multiple recipes in a NewsArticle or BlogPosting.
I tried this but Google's Structured Data Testing Tool throws an error complaining about recipe1 key. I'm not sure what to change recipe1 key to:
<script type="application/ld+json">
{
"#context" : "http://schema.org",
"#type" : "NewsArticle",
"author" : { "#type" : "Person",
"name" : "hgezim"
},
"dateModified" : "2016-09-21T06:25:35+00:00",
"datePublished" : "2016-09-21T06:25:35+00:00",
"headline" : "Chicken Papriak",
"mainEntityOfPage" : "http://localhost:8080/2016/09/21/chicken-papriak/",
"publisher" : { "#type" : "Organization",
"name" : "Dev Blog"
},
"recipe1": {
"#context": "http://schema.org",
"#type": "Recipe",
"author": "John Smith",
"cookTime": "PT1H",
"datePublished": "2009-05-08",
"description": "This classic banana bread recipe comes from my mom -- the walnuts add a nice texture and flavor to the banana bread.",
"image": "bananabread.jpg",
"recipeIngredient": [
"3 or 4 ripe bananas, smashed",
"1 egg",
"3/4 cup of sugar"
],
"interactionStatistic": {
"#type": "InteractionCounter",
"interactionType": "http://schema.org/Comment",
"userInteractionCount": "140"
},
"name": "Mom's World Famous Banana Bread",
"nutrition": {
"#type": "NutritionInformation",
"calories": "240 calories",
"fatContent": "9 grams fat"
},
"prepTime": "PT15M",
"recipeInstructions": "Preheat the oven to 350 degrees. Mix in the ingredients in a bowl. Add the flour last. Pour the mixture into a loaf pan and bake for one hour.",
"recipeYield": "1 loaf",
"suitableForDiet": "http://schema.org/LowFatDiet"
}
}
</script>
It depends on how the entities are related to each other. You have to use a property that is defined to convey this relation.
To look for a suitable property, check BlogPosting for properties that have Recipe or one of its parent types (CreativeWork, Thing) as expected value.
For example:
about could be used if the blog post is about this specific recipe (e.g., you describe how you liked it)
hasPart could be used if the recipe forms a part of the blog post
mentions could be used if you just reference this recipe in the blog post
…
Thanks #unor. I've used hasPart as follows:
<script type="application/ld+json">
{ "#context" : "http://schema.org",
"#type" : "NewsArticle",
"author" : { "#type" : "Person",
"name" : "hgezim"
},
"dateModified" : "2016-09-21T06:25:35+00:00",
"datePublished" : "2016-09-21T06:25:35+00:00",
"hasPart" : { "#context" : "http://schema.org",
"#type" : "Recipe",
"author" : "John Smith",
"cookTime" : "PT1H",
"datePublished" : "2009-05-08",
"description" : "This classic banana bread recipe comes from my mom -- the walnuts add a nice texture and flavor to the banana bread.",
"image" : "bananabread.jpg",
"interactionStatistic" : { "#type" : "InteractionCounter",
"interactionType" : "http://schema.org/Comment",
"userInteractionCount" : "140"
},
"name" : "Mom's World Famous Banana Bread",
"nutrition" : { "#type" : "NutritionInformation",
"calories" : "240 calories",
"fatContent" : "9 grams fat"
},
"prepTime" : "PT15M",
"recipeIngredient" : [ "3 or 4 ripe bananas, smashed",
"1 egg",
"3/4 cup of sugar"
],
"recipeInstructions" : "Preheat the oven to 350 degrees. Mix in the ingredients in a bowl. Add the flour last. Pour the mixture into a loaf pan and bake for one hour.",
"recipeYield" : "1 loaf",
"suitableForDiet" : "http://schema.org/LowFatDiet"
},
"headline" : "Chicken Papriak",
"mainEntityOfPage" : "http://localhost:8080/2016/09/21/chicken-papriak/",
"publisher" : { "#type" : "Organization",
"name" : "Dev Blog"
}
}
</script>
It validates as validates JSON-LD.

Get a collection of sub-resources at once with JSON-LD and Hydra

In the RESTful Web API book, the authors advise to expose a profile and use a content type which acknowledges link relations. JSON-LD extended by Hydra seem to match these requirements, and I want to use them in the design of my new API.
I am currently stuck with a performance issue. Let say that I have an online bike store, and I want to retrieve information about the wheels of a given bike.
With the Hydra specification, it seems to me that I need to send 2 requests to get the details about the wheels.
The first request is toward the bike itself:
GET /mybike HTTP/1.1
Host: wowbike.com
The response contains a Hydra::Link to the collection of wheels:
HTTP/1.1 200 OK
Content-Type: application/ld+json
{
"#context" :
{
"Bike": "/contexts/vocab#Bike"
},
"#id" : "/mybike",
"#type" : "Bike",
"size" : "L",
"wheels" : "/mybike/wheels" // "wheels" is a "hydra:Link"
}
Now I can send a second request to the wheels resource to get the details:
GET /mybike/wheels HTTP/1.1
Host: wowbike.com
HTTP/1.1 200 OK
Content-Type: application/ld+json
{
"#context":
{
"Collection": "http://www.w3.org/ns/hydra/core#Collection",
"Wheel" : "/contexts/vocab#Wheel"
},
"#type" : "Collection",
"#id" : "/mybike/wheels",
"member" :
[
{
"#id" : "/mybike/wheels/firstwheel",
"#type" : "Wheel",
"color" : "blue"
},
{
"#id" : "/mybike/wheels/secondwheel",
"#type" : "Wheel",
"color" : "white"
}
]
}
Is it valid to send a single request and get a response such as the one below?
GET /mybike HTTP/1.1
Host: wowbike.com
HTTP/1.1 200 OK
Content-Type: application/ld+json
{
"#context" :
{
"Collection": "http://www.w3.org/ns/hydra/core#Collection",
"Bike" : "/contexts/vocab#Bike",
"Wheel" : "/contexts/vocab#Wheel"
},
"#id" : "/mybike",
"#type" : "Bike",
"size" : "L",
"wheels" :
{
"#id" : "/mybike/wheels",
"#type" : "Link",
"member":
[
{
"#id" : "/mybike/wheels/firstwheel",
"#type" : "Wheel",
"color" : "blue"
},
{
"#id" : "/mybike/wheels/secondwheel",
"#type" : "Wheel",
"color" : "white"
}
]
}
}
Great to see that you consider using JSON-LD and Hydra. Of course it is possible to get all the data in a single response. You don't have to change the type of the collection from Collection to Link though. Also, you might want to tweak your context a bit. Summed up, your response would look somewhat like this:
{
"#context": [
"http://www.w3.org/ns/hydra/context.jsonld",
{ "#vocab": "/contexts/vocab#" }
],
"#id": "/mybike",
"#type": "Bike",
"size": "L",
"wheels": {
"#id" : "/mybike/wheels",
"#type" : "Collection",
"member": [
{
"#id" : "/mybike/wheels/firstwheel",
"#type" : "Wheel",
"color" : "blue"
},
{
"#id" : "/mybike/wheels/secondwheel",
"#type" : "Wheel",
"color" : "white"
}
]
}
}
I'm importing Hydra's context here and then overlaying a default vocabulary which means that everything that isn't already defined in Hydra's context is expanded by appending it to /contexts/vocab#. So, Bike for instance will be expanded to /contexts/vocab#Bike.
Btw. there's a W3C Community Groupw working on Hydra which you should join if you are using it. We also have a mailing list on which all your questions will be answered.
The instructions to join the group can be found at http://www.hydra-cg.com/#community