Copyindex in deploying dashboard resources Azure ARM - azure

I am deploying a custom Azure Dashboard with a tile that makes use of a resource.
To call the resource I use following code
"[resourceId(parameters('analysisServiceResourceGroup'), '/Microsoft.AnalysisServices/servers', parameters('analysisServiceName'))]"
But in one of the tiles I need multiple resources so I tried something out to make a parameter file with following value
"analysisService": {
"value": [
{
"ResourceGroup": "RG",
"Name": "analysis1",
"Color": "#47BDF5"
},
{
"ResourceGroup": "RG",
"Name": "analysis2",
"Color": "#7E58FF"
},
{
"ResourceGroup": "RG",
"Name": "analysis3",
"Color": "#EB9371"
}
]
},
In my dashboard template i use following code to get the name and resource group.
"resourceId": "[resourceId(parameters('analysisService')[copyIndex()].ResourceGroup, '/Microsoft.AnalysisServices/servers', parameters('analysisService')[copyIndex()].Name)]"
The problem I got at the moment my copy object is not placed in the right place. I got this error
'The template function 'copyIndex' is not expected at this location. The function can only be used in a resource with copy specified. Please see https://aka.ms/arm-copy for usage details.'"
This says that my copy index block is not used in the right resource bracelet but I don't know where i can place this copy Index , tried to put this in every possible place where the copy index can access this but nothing works does anyone know what I do wrong or what I do wrong. It may be possible that copyindex doesn't work inside a dashboard resource.
Code
"12": {
"position": {
"x": 12,
"y": 9,
"colSpan": 6,
"rowSpan": 4
},
"metadata": {
"inputs": [
{
"name": "sharedTimeRange",
"isOptional": true
},
{
"name": "options",
"value": {
"charts": [
{
"metrics": [
{
"name": "CurrentUserSessions",
"resourceMetadata": {
"resourceId": "[resourceId(parameters('analysisService')[copyIndex()].ResourceGroup, '/Microsoft.AnalysisServices/servers', parameters('analysisService')[copyIndex()].Name)]"
},
"aggregationType": 1,
"copy": {
"name": "AnalysisServiceCopy",
"count": "[length(parameters('analysisService'))]"
},
}
],
"title": "Avg Current User Sessions for analysis1, analysis1, and analysis1",
"visualization": {
"chartType": 2,
"legend": {
"isVisible": true,
"position": 2,
"hideSubtitle": false
},
"axis": {
"x": {
"isVisible": true,
"axisType": 2,
"min": 1546508634047,
"max": 1546595034047
},
"y": {
"isVisible": true,
"axisType": 1
}
},
"timeBrushEnable": false
},
"itemDataModel": {
"id": "3464BA29-9AF2-4EAE-9CF4-A246059DDF46",
"chartHeight": 1,
"metrics": [
{
"id": {
"resourceDefinition": {
"id": "[resourceId(parameters('analysisService')[copyIndex()].ResourceGroup, '/Microsoft.AnalysisServices/servers', parameters('analysisService')[copyIndex()].Name)]"
},
"name": {
"id": "CurrentUserSessions",
"displayName": "Current User Sessions"
},
"namespace": {
"name": "microsoft.analysisservices/servers"
}
},
"metricAggregation": 4,
"color": "[parameters('analysisService')[copyIndex()].Color]"
,
"copy": {
"name": "AnalysisServiceCopy",
"count": "[length(parameters('analysisService'))]"
},
}
],
"priorPeriod": false,
"horizontalBars": true,
"showOther": false,
"aggregation": 1,
"palette": "multiColor",
"jsonDefinitionId": "59DCE403-7D8D-4E9F-9CDA-7AE7AC9D9220",
"version": {
"major": 1,
"minor": 0,
"build": 0
},
"filters": {
"filterType": 0,
"id": "C81486BB-3934-48C7-9251-A4EE633DB2BB",
"OperandFilters": [],
"LogicalOperator": 0
},
"yAxisOptions": {
"options": 1
},
"title": "Avg Current User Sessions for analysis1, analysis1, and analysis1",
"titleKind": "Auto",
"visualization": {
"chartType": 2,
"legend": {
"isVisible": true,
"position": 2,
"hideSubtitle": false
},
"axis": {
"x": {
"isVisible": true,
"axisType": 2,
"min": 1546508634047,
"max": 1546595034047
},
"y": {
"isVisible": true,
"axisType": 1
}
},
"timeBrushEnable": false
}
}
}
],
"v2charts": true,
"version": 1
},
"isOptional": true
}
],
"type": "Extension/HubsExtension/PartType/MonitorChartPart",
"settings": {
"content": {
"options": {
"charts": [
{
"metrics": [
{
"name": "CurrentUserSessions",
"resourceMetadata": {
"resourceId": "[resourceId(parameters('analysisService')[copyIndex()].ResourceGroup, '/Microsoft.AnalysisServices/servers', parameters('analysisService')[copyIndex()].Name)]"
},
"aggregationType": 1
,
"copy": {
"name": "AnalysisServiceCopy",
"count": "[length(parameters('analysisService'))]"
},
}
],
"title": "Avg Current User Sessions for analysis1, analysis1, and analysis1",
"visualization": {
"chartType": 2,
"legend": {
"isVisible": true,
"position": 2,
"hideSubtitle": false
},
"axis": {
"x": {
"isVisible": true,
"axisType": 2,
"min": 1546508634047,
"max": 1546595034047
},
"y": {
"isVisible": true,
"axisType": 1
}
},
"timeBrushEnable": false
},
"itemDataModel": {
"id": "3464BA29-9AF2-4EAE-9CF4-A246059DDF46",
"chartHeight": 1,
"metrics": [
{
"id": {
"resourceDefinition": {
"id": "[resourceId(parameters('analysisService')[copyIndex()].ResourceGroup, '/Microsoft.AnalysisServices/servers', parameters('analysisService')[copyIndex()].Name)]"
},
"name": {
"id": "CurrentUserSessions",
"displayName": "Current User Sessions"
},
"namespace": {
"name": "microsoft.analysisservices/servers"
}
},
"metricAggregation": 4,
"color": "[parameters('analysisService')[copyIndex()].Color]"
,
"copy": {
"name": "AnalysisServiceCopy",
"count": "[length(parameters('analysisService'))]"
},
}
],
"priorPeriod": false,
"horizontalBars": true,
"showOther": false,
"aggregation": 1,
"palette": "multiColor",
"jsonDefinitionId": "59DCE403-7D8D-4E9F-9CDA-7AE7AC9D9220",
"version": {
"major": 1,
"minor": 0,
"build": 0
},
"filters": {
"filterType": 0,
"id": "C81486BB-3934-48C7-9251-A4EE633DB2BB",
"OperandFilters": [],
"LogicalOperator": 0
},
"yAxisOptions": {
"options": 1
},
"title": "Avg Current User Sessions for analysis1, analysis1, and analysis1",
"titleKind": "Auto",
"visualization": {
"chartType": 2,
"legend": {
"isVisible": true,
"position": 2,
"hideSubtitle": false
},
"axis": {
"x": {
"isVisible": true,
"axisType": 2,
"min": 1546508634047,
"max": 1546595034047
},
"y": {
"isVisible": true,
"axisType": 1
}
},
"timeBrushEnable": false
}
},
"disablePinning": true
}
],
"v2charts": true,
"version": 1
}
}
}
}
},
"copy": {
"name": "AnalysisServiceCopy",
"count": "[length(parameters('analysisService'))]"
},

so, as a general rule, you can only use copy loop to create arrays, not object, so to construct you metrics array you would do something like this:
"charts": [
{
"copy": [
{
"name": "metrics",
"count": "[length(parameters('analysisService'))]",
"input": {
"name": "CurrentUserSessions",
"resourceMetadata": {
"resourceId": "[resourceId(parameters('analysisService')[copyIndex('metrics')].ResourceGroup, '/Microsoft.AnalysisServices/servers', parameters('analysisService')[copyIndex('metrics')].Name)]"
},
"aggregationType": 1
}
}
],
"title": "Avg Current User Sessions for analysis1, analysis1, and analysis1",
"visualization": { redacted for brievity },
"itemDataModel": { redacted for brievity },
"disablePinning": true
}
],
you would need to do this everywhere you need to construct an array. as a workaround (if they are identical) you can use the same construct to create a variable and use that variable:
"variables": {
"copy": [
{
"name": "metrics",
"count": "[length(parameters('analysisService'))]",
"input": {
"name": "CurrentUserSessions",
"resourceMetadata": {
"resourceId": "[resourceId(parameters('analysisService')[copyIndex('metrics')].ResourceGroup, '/Microsoft.AnalysisServices/servers', parameters('analysisService')[copyIndex('metrics')].Name)]"
},
"aggregationType": 1
}
}
],
}
the above will create a variable called "metrics" which you can use anywhere in the template like so:
"[variables('metrics')]"

#4c74356b41
I tried it like this , I directly get an green error line beneath copy that this varbiable never is used.
"variables": {
"copy": [
{
"name": "metrics",
"count": "[length(parameters('analysisService'))]",
"input": {
"name": "qpu_metric",
"resourceMetadata": {
"resourceId": "[resourceId(parameters('analysisService')[copyIndex('metrics')].ResourceGroup, 'Microsoft.AnalysisServices/servers', parameters('analysisService')[copyIndex('metrics')].Name)]"
},
"aggregationType": 1
}
}
]
},
In my code I call the variable like this
"charts": [
{
"metrics" : "[variables('metrics')]",
"title": "Avg QPU",
"visualization": {

Related

How to use filter on cloud/roleName in Azure Application Insights?

I created the "New Failures Analysis" workbook in Azure Application Insights. In that, I added a custom chart using the below query to display the count of requests, failures, exceptions, etc. based on the cloud/roleName property.
{
"type": 10,
"content": {
"chartId": "xxxxxxxxxxxxxxxxxxx",
"version": "MetricsItem/2.0",
"size": 3,
"chartType": 0,
"resourceType": "microsoft.insights/components",
"metricScope": 0,
"resourceIds": [
"xxxxxxxxxxx"
],
"timeContext": {
"durationMs": 86400000
},
"metrics": [
{
"namespace": "microsoft.insights/components",
"metric": "microsoft.insights/components--requests/count",
"aggregation": 7
},
{
"namespace": "microsoft.insights/components",
"metric": "microsoft.insights/components--requests/failed",
"aggregation": 7
},
{
"namespace": "microsoft.insights/components",
"metric": "microsoft.insights/components--exceptions/count",
"aggregation": 7
},
{
"namespace": "microsoft.insights/components",
"metric": "microsoft.insights/components--requests/duration",
"aggregation": 4
},
{
"namespace": "microsoft.insights/components",
"metric": "microsoft.insights/components--requests/rate",
"aggregation": 4
}
],
"gridFormatType": 2,
"filters": [
{
"key": "cloud/roleName",
"operator": 0,
"values": [
"xxxxxxxxx"
]
}
],
"gridSettings": {
"formatters": [
{
"columnMatch": "Subscription",
"formatter": 5
},
{
"columnMatch": "Name",
"formatter": 5,
"formatOptions": {
"linkTarget": "Resource"
}
},
{
"columnMatch": "Segment",
"formatter": 5
},
{
"columnMatch": "microsoft.insights/components--requests/count",
"formatter": 8,
"formatOptions": {
"min": 0,
"max": 5000,
"palette": "green"
},
"numberFormat": {
"unit": 0,
"options": {
"style": "decimal"
}
}
},
{
"columnMatch": "microsoft.insights/components--requests/count Timeline",
"formatter": 5
},
{
"columnMatch": "microsoft.insights/components--requests/failed",
"formatter": 8,
"formatOptions": {
"min": 0,
"max": 20,
"palette": "orangeRed"
},
"numberFormat": {
"unit": 0,
"options": {
"style": "decimal"
}
}
},
{
"columnMatch": "microsoft.insights/components--requests/failed Timeline",
"formatter": 5
},
{
"columnMatch": "microsoft.insights/components--exceptions/count",
"formatter": 8,
"formatOptions": {
"min": 0,
"max": 20,
"palette": "yellowOrangeRed"
},
"numberFormat": {
"unit": 0,
"options": {
"style": "decimal"
}
}
},
{
"columnMatch": "microsoft.insights/components--exceptions/count Timeline",
"formatter": 5
},
{
"columnMatch": "microsoft.insights/components--requests/duration",
"formatter": 8,
"formatOptions": {
"min": 0,
"max": 1000,
"palette": "yellowGreenBlue"
}
},
{
"columnMatch": "microsoft.insights/components--requests/duration Timeline",
"formatter": 5
},
{
"columnMatch": "microsoft.insights/components--requests/rate",
"formatter": 8,
"formatOptions": {
"min": 0,
"palette": "blueGreen"
},
"numberFormat": {
"unit": 31,
"options": {
"style": "decimal"
}
}
},
{
"columnMatch": "microsoft.insights/components--requests/rate Timeline",
"formatter": 5
}
],
"rowLimit": 10000,
"labelSettings": [
{
"columnId": "microsoft.insights/components--requests/count",
"label": "Requests"
},
{
"columnId": "microsoft.insights/components--requests/count Timeline",
"label": "microsoft.insights/components--requests/count (Count) Timeline"
},
{
"columnId": "microsoft.insights/components--requests/failed",
"label": "Failed"
},
{
"columnId": "microsoft.insights/components--requests/failed Timeline",
"label": "microsoft.insights/components--requests/failed (Count) Timeline"
},
{
"columnId": "microsoft.insights/components--exceptions/count",
"label": "Exceptions"
},
{
"columnId": "microsoft.insights/components--exceptions/count Timeline",
"label": "microsoft.insights/components--exceptions/count (Count) Timeline"
},
{
"columnId": "microsoft.insights/components--requests/duration",
"label": "Avg Response Time"
},
{
"columnId": "microsoft.insights/components--requests/duration Timeline",
"label": "microsoft.insights/components--requests/duration (Average) Timeline"
},
{
"columnId": "microsoft.insights/components--requests/rate",
"label": "Request Rate"
},
{
"columnId": "microsoft.insights/components--requests/rate Timeline",
"label": "microsoft.insights/components--requests/rate (Average) Timeline"
}
]
}
},
"name": "metric - 01"
}
The above query worked fine a few days ago, but suddenly this query is not giving any results, even though the logs are available in the Azure Application Insights for the specific cloud/roleName property.
The metric ID doesn't look quite right. When I add a metric in Workbooks, say, failed requests, I get the ID "metric": "microsoft.insights/components-Failures-requests/failed" instead of "metric": "microsoft.insights/components--requests/failed". I'm curious how this Workbook JSON was generated? I would recreate this metrics step again and check if the issue persists. If it does, also check if you are seeing no results in the Metrics blade as well. If the Workbook continues to show incorrect results afterwards, I would recommend submitting a support request.

Shopware 6 API Create a Product with Variants

I created my products with the API and all is ok. But we have some products with variants. These looking good in the backend, but in the frontend shopware doesn't display the product. Where is my error in the payload?
Thank you for helping me!
Here is my code:
{
"write-product":
{
"entity": "product",
"action": "upsert",
"payload": [
{
"id": "17cf3bac8966cc4de52aa557f59e5fd3",
"active": true,
"deliveryTimeId": "1e04777cb17d4396b424129b2d8e3a79",
"description": "Produktbeschreibung",
"ean": null,
"featureSetId": null,
"manufacturerId": null,
"manufacturerNumber": null,
"minPurchase": 1,
"name": "Produktname",
"productNumber": "Nummer",
"releaseDate": "2022-09-28T14:12:18.03",
"stock": 999999,
"taxId": "2842fd17d5a7424795853e7fe7072448",
"price":[
{
"currencyId": "b7d2554b0ce847cd82f3ac9bd1c0dfca",
"net": 13.77,
"gross": 16.39,
"linked": false
}
],
"categories":[
{
"id":"648875017ed54637a41c8c1f972c239f",
"name":"Kategoriename"
}
],
"configuratorSettings": [
{
"productId": "17cf3bac8966cc4de52aa557f59e5fd3",
"optionId": "2ab9df7d2dd94ad38eb53cf7dcf16e56"
},
{
"productId": "17cf3bac8966cc4de52aa557f59e5fd3",
"optionId": "0fcf784970ea448bac1f7db542df9b86"
},
{
"productId": "17cf3bac8966cc4de52aa557f59e5fd3",
"optionId": "0014aa7dc0b644b78cd4b39193f580b4"
}
],
"properties": [
{
"groupId":"ca74efd59b5545f2b4e4f532c217b2ce",
"name": "1,0 m"
},
{
"groupId":"fa7f63d697d44684a5bb74ba5a73d3c7",
"name": "2,0 mm"
},
{
"groupId":"a431bc98fe0149c3bf3ececf629e9740",
"name": "Material"
}
],
"visibilities": [
{
"id": "17cf3bac8966cc4de52aa557f59e5fd3",
"salesChannelId": "840a0403b56240b6a11502af1d46521e",
"visibility": 30
}
],
"coverId": "0f9ab99638bd0ea5e907234bf425819e",
"cover":
{
"mediaId": "0f9ab99638bd0ea5e907234bf425819e"
},
"media": [
{
"media":
{
"id": "0f9ab99638bd0ea5e907234bf425819e",
"position": 0,
"mediaFolderId": "d8f460870e454c0bbca540614ca30029",
"alt": "Bildname",
"description": "Bildbeschreibung",
"title": "Bildtitel"
}
}
],
"children": [
{
"id": "25c8876fb7577cad78df7539737d25ce",
"active": true,
"deliveryTimeId": "1e04777cb17d4396b424129b2d8e3a79",
"description": "Beschreibung Kindelement",
"ean": null,
"featureSetId": null,
"manufacturerId": null,
"manufacturerNumber": null,
"minPurchase": 1,
"name": "Name Kindelement",
"productNumber": "Nummer Kindelement",
"releaseDate": "2022-09-16T14:14:31.41",
"stock": 999999,
"taxId": "2842fd17d5a7424795853e7fe7072448",
"price":[
{
"currencyId": "b7d2554b0ce847cd82f3ac9bd1c0dfca",
"net": 82.63,
"gross": 98.33,
"linked": false
}
],
"categories":[
{
"id":"648875017ed54637a41c8c1f972c239f",
"name":"Kategoriename"
}
],
"configuratorSettings": [
{
"productId": "25c8876fb7577cad78df7539737d25ce",
"optionId": "b224173313cb4f8da03578ef83702751"
},
{
"productId": "25c8876fb7577cad78df7539737d25ce",
"optionId": "0fcf784970ea448bac1f7db542df9b86"
},
{
"productId": "25c8876fb7577cad78df7539737d25ce",
"optionId": "0014aa7dc0b644b78cd4b39193f580b4"
}
],
"properties": [
{
"groupId":"ca74efd59b5545f2b4e4f532c217b2ce",
"name": "6,0 m"
},
{
"groupId":"fa7f63d697d44684a5bb74ba5a73d3c7",
"name": "2,0 mm"
},
{
"groupId":"a431bc98fe0149c3bf3ececf629e9740",
"name": "Material"
}
],
"parentId": "17cf3bac8966cc4de52aa557f59e5fd3",
"options": [
{
"id":"b224173313cb4f8da03578ef83702751",
"group": {
"id":"ca74efd59b5545f2b4e4f532c217b2ce"}
},
{
"id":"0fcf784970ea448bac1f7db542df9b86",
"group": {
"id":"fa7f63d697d44684a5bb74ba5a73d3c7"}
},
{
"id":"0014aa7dc0b644b78cd4b39193f580b4",
"group": {
"id":"a431bc98fe0149c3bf3ececf629e9740"
}
}
],
"visibilities": [
{
"id": "25c8876fb7577cad78df7539737d25ce",
"salesChannelId": "840a0403b56240b6a11502af1d46521e",
"visibility": 30
}
],
"media": [
{
"media": {
"id": "fba6e74294488b554aa88f7dcf6f38f2",
"position": 0,
"mediaFolderId": "d8f460870e454c0bbca540614ca30029",
"alt": "Bildname Kindelement",
"description": "Beschreibung Kindelement",
"title": "Bildtitel Kindelement"
}
}
]
}
]
}
]
}
}
I'm searching in different boards and looking in the API Browser, Using swagger for the api and so on. No result. I need the main-product and the variants be visible in the frontend. At the moment all products with variants are invisible in the frontend.
Double check your Visibility & Categories. It could be them. Also, maybe you need to re-index after creation?
You have way too much stuff going on at the moment for us to help you out.
Try to split your calls into smaller chunks (for us). Also start with less data when creating a product. With every step check the frontend. Can you even create a simple product & display it on the frontend? Yes? Then try create the most basic child that inherits most of the visible parent.
For a child you do not need much data, e.g.
{
"write-product": {
"entity": "product",
"action": "upsert",
"payload": [
{
"parentId": "",
"options": [
{
"id": ""
}
],
"price": [
{
"currencyId": "{{gen_salesChannel_currency_id}}",
"gross": 0.0,
"net": 0.0,
"linked": false
}
]
"productNumber": "",
"stock": 999
}
]
}
}
Another tip is to use the network tab in the admin to see how it creates these relationships. Here is an image of how it looks like:

How do I send customer data from twilio to stripe?

I'm using Twilio to allow my customers to pay automatically over the phone via to stripe. I followed this tutorial: Is there a way to enter dollars/cents via DTMF?
The issue I'm running into is how do I send the "phone number" as a "customer" into stripe? The reason I want this is to be able to see who bought what and how many times etc. Currently, they are all coming into stripe as unknown/guest.
My only success has been (I'm using the studio) entering {{trigger.call.From}} into the "payment description". That still doesn't solve the issue fully though.
Any help would be greatly appreciated!
Here is my flow code:
{
"description": "A New Flow",
"states": [
{
"name": "Trigger",
"type": "trigger",
"transitions": [
{
"next": "received_message_forward",
"event": "incomingMessage"
},
{
"next": "gather_1",
"event": "incomingCall"
},
{
"event": "incomingConversationMessage"
},
{
"event": "incomingRequest"
},
{
"event": "incomingParent"
}
],
"properties": {
"offset": {
"x": 0,
"y": 0
}
}
},
{
"name": "gather_1",
"type": "gather-input-on-call",
"transitions": [
{
"next": "function_1",
"event": "keypress"
},
{
"event": "speech"
},
{
"next": "gather_1",
"event": "timeout"
}
],
"properties": {
"voice": "man",
"speech_timeout": "auto",
"offset": {
"x": 30,
"y": 270
},
"loop": 1,
"finish_on_key": "#",
"say": "Welcome and thank you for calling the donation line. Please enter the amount you wish to donate, then press pound. To enter with cents use the star key. for example to enter $18.50, press one eight star five zero.",
"language": "en-US",
"stop_gather": true,
"gather_language": "en",
"profanity_filter": "true",
"timeout": 5
}
},
{
"name": "function_1",
"type": "run-function",
"transitions": [
{
"next": "confirm_donation_amount",
"event": "success"
},
{
"event": "fail"
}
],
"properties": {
"offset": {
"x": -60,
"y": 530
},
"parameters": [
{
"value": "{{widgets.gather_1.Digits}}",
"key": "amount"
}
],
"url": "https://sand-pointer-5043.twil.io/pay_from_exchange"
}
},
{
"name": "say_play_2",
"type": "say-play",
"transitions": [
{
"event": "audioComplete"
}
],
"properties": {
"voice": "man",
"offset": {
"x": -60,
"y": 840
},
"loop": 1,
"say": "You entered ${{widgets.function_1.body}}",
"language": "en-US"
}
},
{
"name": "pay_1",
"type": "capture-payments",
"transitions": [
{
"next": "say_play_3",
"event": "success"
},
{
"next": "say_play_4",
"event": "maxFailedAttempts"
},
{
"next": "say_play_4",
"event": "providerError"
},
{
"next": "say_play_4",
"event": "payInterrupted"
},
{
"next": "say_play_4",
"event": "hangup"
},
{
"next": "say_play_4",
"event": "validationError"
}
],
"properties": {
"security_code": true,
"offset": {
"x": -70,
"y": 1140
},
"max_attempts": 2,
"payment_connector": "",
"payment_amount": "{{widgets.function_1.body}}",
"description": "{{trigger.call.From}} via Twilio",
"currency": "usd",
"language": "en-US",
"postal_code": "false",
"payment_token_type": "reusable",
"timeout": 5,
"valid_card_types": [
"visa",
"master-card",
"amex",
"discover"
]
}
},
{
"name": "say_play_3",
"type": "say-play",
"transitions": [
{
"next": "send_success_message_1",
"event": "audioComplete"
}
],
"properties": {
"voice": "man",
"offset": {
"x": -185,
"y": 1433
},
"loop": 1,
"say": "Your donation of ${{widgets.function_1.body}} was successful, Thank you.",
"language": "en-US"
}
},
{
"name": "say_play_4",
"type": "say-play",
"transitions": [
{
"next": "send_fail_message_1",
"event": "audioComplete"
}
],
"properties": {
"voice": "man",
"offset": {
"x": 190,
"y": 1456
},
"loop": 1,
"say": "There was an error with your donation. Please verify your details and call back to try again. Thanks!",
"language": "en-US"
}
},
{
"name": "send_success_message_1",
"type": "send-message",
"transitions": [
{
"event": "sent"
},
{
"event": "failed"
}
],
"properties": {
"offset": {
"x": -100,
"y": 1700
},
"service": "{{trigger.message.InstanceSid}}",
"channel": "{{trigger.message.ChannelSid}}",
"from": "{{flow.channel.address}}",
"to": "{{contact.channel.address}}",
"body": "Your donation of ${{widgets.function_1.body}} was successful, Thank you!."
}
},
{
"name": "send_fail_message_1",
"type": "send-message",
"transitions": [
{
"event": "sent"
},
{
"event": "failed"
}
],
"properties": {
"offset": {
"x": 250,
"y": 1700
},
"service": "{{trigger.message.InstanceSid}}",
"channel": "{{trigger.message.ChannelSid}}",
"from": "{{flow.channel.address}}",
"to": "{{contact.channel.address}}",
"body": "There was an error with your donation. Please verify your details and call back to try again. Thanks!"
}
},
{
"name": "confirm_donation_amount",
"type": "gather-input-on-call",
"transitions": [
{
"next": "split_2",
"event": "keypress"
},
{
"event": "speech"
},
{
"next": "confirm_donation_amount",
"event": "timeout"
}
],
"properties": {
"number_of_digits": 1,
"speech_timeout": "auto",
"offset": {
"x": 420,
"y": 530
},
"loop": 1,
"finish_on_key": "#",
"say": "You entered ${{widgets.function_1.body}}. Press 1 to confirm, or press 2 to enter a different amount.",
"stop_gather": true,
"gather_language": "en",
"profanity_filter": "true",
"timeout": 5
}
},
{
"name": "split_2",
"type": "split-based-on",
"transitions": [
{
"next": "confirm_donation_amount",
"event": "noMatch"
},
{
"next": "pay_1",
"event": "match",
"conditions": [
{
"friendly_name": "If value equal_to 1",
"arguments": [
"{{widgets.confirm_donation_amount.Digits}}"
],
"type": "equal_to",
"value": "1"
}
]
},
{
"next": "gather_1",
"event": "match",
"conditions": [
{
"friendly_name": "If value equal_to 2",
"arguments": [
"{{widgets.confirm_donation_amount.Digits}}"
],
"type": "equal_to",
"value": "2"
}
]
}
],
"properties": {
"input": "{{widgets.confirm_donation_amount.Digits}}",
"offset": {
"x": 430,
"y": 800
}
}
},
{
"name": "received_message_forward",
"type": "send-message",
"transitions": [
{
"event": "sent"
},
{
"event": "failed"
}
],
"properties": {
"offset": {
"x": -300,
"y": 250
},
"service": "{{trigger.message.InstanceSid}}",
"channel": "{{trigger.message.ChannelSid}}",
"from": "{{flow.channel.address}}",
"to": "{{contact.channel.address}}",
"body": "Thanks for texting the Donation line. To donate, please call us on this same number. We do not accept donations via text."
}
}
],
"initial_state": "Trigger",
"flags": {
"allow_concurrent_calls": true
}
}
Here is the function:
exports.handler = function(context, event, callback) {
const amount = event.amount;
const convert = amount.replace('*', '.');
callback(null, convert);
};

Why don't store properly on nested object MongoDB

I need to update a document with an object, but my approach looks like don't apply the changes on DB, can someone explain me what I'm doing wrong, please?
let dishes = await this.dishesModel.find({});
let dishesPromise = dishes.map((dish, i) => {
dish.ingredients.forEach((item) => {
if (item?.item) {
if (item['item']['unit']['_id'].toString() === payload._id) {
item['item']['unit'] = unit;
}
}
});
return dish.save();
});
await Promise.all(dishesPromise)
In the above code I get unit previously and the objective is to use this unit in: item['item']['unit']
A dish document looks like:
{
"_id": { "$oid": "62cc00bfad995c0e7d8bbb7d" },
"name": "Bologne pasta",
"price": 6.99,
"ingredients": [
{
"quantity": 3,
"item": {
"_id": { "$oid": "62cbe92821464145f0eb280e" },
"name": "Cow beef",
"code": "meat-01",
"price": 9.99,
"value": 100,
"internal": true,
"categories": [
{
"_id": { "$oid": "62cbe83221464145f0eb27ea" },
"name": "Meat",
"disabled": false
}
],
"unit": {
"name": "GRAMASO 2",
"abbr": "gr.",
"_id": { "$oid": "62befe5ff6f95cf46a4cfe5b" }
},
"disabled": false,
"__v": 0,
"translation": { "es": { "name": "Carne de vaca" } }
}
},
{
"quantity": 2,
"item": {
"_id": { "$oid": "62cbea3121464145f0eb283a" },
"name": "Tomato",
"code": "vegetable-02",
"price": 1.5,
"value": 20,
"internal": true,
"categories": [
{
"_id": { "$oid": "62cbe82921464145f0eb27e6" },
"name": "Vegetables",
"disabled": false
}
],
"unit": {
"name": "GRAMASO 2",
"abbr": "gr.",
"_id": { "$oid": "62befe5ff6f95cf46a4cfe5b" }
},
"disabled": false,
"__v": 0,
"translation": { "es": { "name": "Tomate" } }
}
},
{
"quantity": 1,
"item": {
"_id": { "$oid": "62cbee5621464145f0eb2865" },
"name": "Spagetti",
"code": "pasta-01",
"price": 1.5,
"value": 100,
"internal": true,
"categories": [
{
"_id": { "$oid": "62cbee3e21464145f0eb285f" },
"name": "Pasta",
"disabled": false
}
],
"unit": {
"name": "GRAMASO 2",
"abbr": "gr.",
"_id": { "$oid": "62befe5ff6f95cf46a4cfe5b" }
},
"disabled": false,
"__v": 0,
"translation": { "es": { "name": "Espaguetti" } }
}
}
],
"categories": [
{
"_id": { "$oid": "62cbe84721464145f0eb27f6" },
"name": "Italian",
"disabled": false,
"translation": { "en": { "name": "Italiana" } }
}
],
"__v": 0,
"translation": { "es": { "name": "Pasta con salsa boloƱesa" } }
}
At last, the changes are not reflecting on DB, but I don't figure out what's wrong.

Hyperledger Fabric: Add new organization to existing channel using JsonPath

I want to add a new Organization to an existing Channel in Hyperledger Fabric.
First I obtain the channel configuration in JSON format using the following code snippet:
byte[] configBytes = channel.getChannelConfigurationBytes();
String configtxlator = props.getProperty("configtxlator");
HttpPost httppost = new HttpPost(configtxlator + "/protolator/decode/common.Config");
httppost.setEntity(new ByteArrayEntity(configBytes));
HttpClient httpclient = HttpClients.createDefault();
HttpResponse response = httpclient.execute(httppost);
int statuscode = response.getStatusLine().getStatusCode();
if (statuscode == 200) {
return EntityUtils.toString(response.getEntity());
} else {
return "";
}
The result is the following JSON string:
{
"channel_group": {
"groups": {
"Application": {
"groups": {
"Org1MSP": {
"groups": {},
"mod_policy": "Admins",
"policies": {
"Admins": {
"mod_policy": "Admins",
"policy": {
"type": 1,
"value": {
"identities": [
{
"principal": {
"msp_identifier": "Org1MSP",
"role": "ADMIN"
},
"principal_classification": "ROLE"
}
],
"rule": {
"n_out_of": {
"n": 1,
"rules": [
{
"signed_by": 0
}
]
}
},
"version": 0
}
},
"version": "0"
},
"Readers": {
"mod_policy": "Admins",
"policy": {
"type": 1,
"value": {
"identities": [
{
"principal": {
"msp_identifier": "Org1MSP",
"role": "ADMIN"
},
"principal_classification": "ROLE"
},
{
"principal": {
"msp_identifier": "Org1MSP",
"role": "PEER"
},
"principal_classification": "ROLE"
},
{
"principal": {
"msp_identifier": "Org1MSP",
"role": "CLIENT"
},
"principal_classification": "ROLE"
}
],
"rule": {
"n_out_of": {
"n": 1,
"rules": [
{
"signed_by": 0
},
{
"signed_by": 1
},
{
"signed_by": 2
}
]
}
},
"version": 0
}
},
"version": "0"
},
"Writers": {
"mod_policy": "Admins",
"policy": {
"type": 1,
"value": {
"identities": [
{
"principal": {
"msp_identifier": "Org1MSP",
"role": "ADMIN"
},
"principal_classification": "ROLE"
},
{
"principal": {
"msp_identifier": "Org1MSP",
"role": "CLIENT"
},
"principal_classification": "ROLE"
}
],
"rule": {
"n_out_of": {
"n": 1,
"rules": [
{
"signed_by": 0
},
{
"signed_by": 1
}
]
}
},
"version": 0
}
},
"version": "0"
}
},
"values": {
"AnchorPeers": {
"mod_policy": "Admins",
"value": {
"anchor_peers": [
{
"host": "peer1.org1.isprint.com",
"port": 7051
},
{
"host": "peer2.org1.isprint.com",
"port": 7051
}
]
},
"version": "0"
},
"MSP": {
"mod_policy": "Admins",
"value": {
"config": {
"admins": [],
"crypto_config": {
"identity_identifier_hash_function": "SHA256",
"signature_hash_family": "SHA2"
},
"fabric_node_ous": {
"admin_ou_identifier": {
"certificate": "...",
"organizational_unit_identifier": "admin"
},
"client_ou_identifier": {
"certificate": "...",
"organizational_unit_identifier": "client"
},
"enable": true,
"orderer_ou_identifier": {
"certificate": "...",
"organizational_unit_identifier": "orderer"
},
"peer_ou_identifier": {
"certificate": "...",
"organizational_unit_identifier": "peer"
}
},
"intermediate_certs": [],
"name": "Org1MSP",
"organizational_unit_identifiers": [],
"revocation_list": [],
"root_certs": [
"..."
],
"signing_identity": null,
"tls_intermediate_certs": [],
"tls_root_certs": [
"..."
]
},
"type": 0
},
"version": "0"
}
},
"version": "1"
}
},
"mod_policy": "Admins",
"policies": {
"Admins": {
"mod_policy": "Admins",
"policy": {
"type": 3,
"value": {
"rule": "MAJORITY",
"sub_policy": "Admins"
}
},
"version": "0"
},
"Readers": {
"mod_policy": "Admins",
"policy": {
"type": 3,
"value": {
"rule": "ANY",
"sub_policy": "Readers"
}
},
"version": "0"
},
"Writers": {
"mod_policy": "Admins",
"policy": {
"type": 3,
"value": {
"rule": "ANY",
"sub_policy": "Writers"
}
},
"version": "0"
}
},
"values": {
"Capabilities": {
"mod_policy": "Admins",
"value": {
"capabilities": {
"V1_4_2": {}
}
},
"version": "0"
}
},
"version": "1"
},
"Orderer": {
"groups": {
"OrdererOrg": {
"groups": {},
"mod_policy": "Admins",
"policies": {
"Admins": {
"mod_policy": "Admins",
"policy": {
"type": 1,
"value": {
"identities": [
{
"principal": {
"msp_identifier": "OrdererMSP",
"role": "ADMIN"
},
"principal_classification": "ROLE"
}
],
"rule": {
"n_out_of": {
"n": 1,
"rules": [
{
"signed_by": 0
}
]
}
},
"version": 0
}
},
"version": "0"
},
"Readers": {
"mod_policy": "Admins",
"policy": {
"type": 1,
"value": {
"identities": [
{
"principal": {
"msp_identifier": "OrdererMSP",
"role": "MEMBER"
},
"principal_classification": "ROLE"
}
],
"rule": {
"n_out_of": {
"n": 1,
"rules": [
{
"signed_by": 0
}
]
}
},
"version": 0
}
},
"version": "0"
},
"Writers": {
"mod_policy": "Admins",
"policy": {
"type": 1,
"value": {
"identities": [
{
"principal": {
"msp_identifier": "OrdererMSP",
"role": "MEMBER"
},
"principal_classification": "ROLE"
}
],
"rule": {
"n_out_of": {
"n": 1,
"rules": [
{
"signed_by": 0
}
]
}
},
"version": 0
}
},
"version": "0"
}
},
"values": {
"MSP": {
"mod_policy": "Admins",
"value": {
"config": {
"admins": [],
"crypto_config": {
"identity_identifier_hash_function": "SHA256",
"signature_hash_family": "SHA2"
},
"fabric_node_ous": {
"admin_ou_identifier": {
"certificate": "...",
"organizational_unit_identifier": "admin"
},
"client_ou_identifier": {
"certificate": "...",
"organizational_unit_identifier": "client"
},
"enable": true,
"orderer_ou_identifier": {
"certificate": "...",
"organizational_unit_identifier": "orderer"
},
"peer_ou_identifier": {
"certificate": "...",
"organizational_unit_identifier": "peer"
}
},
"intermediate_certs": [],
"name": "OrdererMSP",
"organizational_unit_identifiers": [],
"revocation_list": [],
"root_certs": [
"..."
],
"signing_identity": null,
"tls_intermediate_certs": [],
"tls_root_certs": [
"..."
]
},
"type": 0
},
"version": "0"
}
},
"version": "0"
}
},
"mod_policy": "Admins",
"policies": {
"Admins": {
"mod_policy": "Admins",
"policy": {
"type": 3,
"value": {
"rule": "MAJORITY",
"sub_policy": "Admins"
}
},
"version": "0"
},
"BlockValidation": {
"mod_policy": "Admins",
"policy": {
"type": 3,
"value": {
"rule": "ANY",
"sub_policy": "Writers"
}
},
"version": "0"
},
"Readers": {
"mod_policy": "Admins",
"policy": {
"type": 3,
"value": {
"rule": "ANY",
"sub_policy": "Readers"
}
},
"version": "0"
},
"Writers": {
"mod_policy": "Admins",
"policy": {
"type": 3,
"value": {
"rule": "ANY",
"sub_policy": "Writers"
}
},
"version": "0"
}
},
"values": {
"BatchSize": {
"mod_policy": "Admins",
"value": {
"absolute_max_bytes": 103809024,
"max_message_count": 100,
"preferred_max_bytes": 524288
},
"version": "0"
},
"BatchTimeout": {
"mod_policy": "Admins",
"value": {
"timeout": "30s"
},
"version": "0"
},
"Capabilities": {
"mod_policy": "Admins",
"value": {
"capabilities": {
"V1_4_2": {}
}
},
"version": "0"
},
"ChannelRestrictions": {
"mod_policy": "Admins",
"value": null,
"version": "0"
},
"ConsensusType": {
"mod_policy": "Admins",
"value": {
"metadata": {
"consenters": [
{
"client_tls_cert": "...",
"host": "orderer1.isprint.com",
"port": 7050,
"server_tls_cert": "..."
},
{
"client_tls_cert": "...",
"host": "orderer2.isprint.com",
"port": 7050,
"server_tls_cert": "..."
},
{
"client_tls_cert": "...",
"host": "orderer3.isprint.com",
"port": 7050,
"server_tls_cert": "..."
}
],
"options": {
"election_tick": 10,
"heartbeat_tick": 1,
"max_inflight_blocks": 5,
"snapshot_interval_size": 20971520,
"tick_interval": "500ms"
}
},
"state": "STATE_NORMAL",
"type": "etcdraft"
},
"version": "0"
}
},
"version": "0"
}
},
"mod_policy": "Admins",
"policies": {
"Admins": {
"mod_policy": "Admins",
"policy": {
"type": 3,
"value": {
"rule": "MAJORITY",
"sub_policy": "Admins"
}
},
"version": "0"
},
"Readers": {
"mod_policy": "Admins",
"policy": {
"type": 3,
"value": {
"rule": "ANY",
"sub_policy": "Readers"
}
},
"version": "0"
},
"Writers": {
"mod_policy": "Admins",
"policy": {
"type": 3,
"value": {
"rule": "ANY",
"sub_policy": "Writers"
}
},
"version": "0"
}
},
"values": {
"BlockDataHashingStructure": {
"mod_policy": "Admins",
"value": {
"width": 4294967295
},
"version": "0"
},
"Capabilities": {
"mod_policy": "Admins",
"value": {
"capabilities": {
"V1_4_3": {}
}
},
"version": "0"
},
"Consortium": {
"mod_policy": "Admins",
"value": {
"name": "SampleConsortium"
},
"version": "0"
},
"HashingAlgorithm": {
"mod_policy": "Admins",
"value": {
"name": "SHA256"
},
"version": "0"
},
"OrdererAddresses": {
"mod_policy": "/Channel/Orderer/Admins",
"value": {
"addresses": [
"orderer1.isprint.com:7050",
"orderer2.isprint.com:7050",
"orderer3.isprint.com:7050"
]
},
"version": "0"
}
},
"version": "0"
},
"sequence": "2"
}
I have written a code snippet using JsonPath:
DocumentContext context = JsonPath.parse(json);
String pathOrg1MSP = "$.channel_group.groups.Application.groups.Org1MSP";
Map<String,Object> mapOrg1MSP = context.read(pathOrg1MSP);
Map<String,Object> mapOrg2MSP = new LinkedHashMap<String,Object>();
mapOrg1MSP.forEach((k,v) -> {
mapOrg2MSP.put(k, v);
});
String pathOrg2MSP = "$.channel_group.groups.Application.groups";
context.put(pathOrg2MSP, "Org2MSP", mapOrg2MSP);
The intention is to create an exact clone first, then change whatever values need to be changed (peers, certs etc), and then splice it into the original Json.
Would this achieve what I intend to do?
What values would I need to change to prevent any possible conflicts with existing organizations?
Generate crypto materials for Org2
Generate Org2-specific configuration materials
Fetch the latest config block from orderer, trim it down and convert it to JSON (I believe u have done this step already)
Add Org2-specific configuration materials to the JSON
Convert original JSON and newly edited JSON to protobuf format
Compute difference between the new and original block (.pb files)
Convert it to JSON format and add back header
Convert it to protobuf format
Sign transaction by Org1
For the detailed commands, you can refer to this official documentation. https://hyperledger-fabric.readthedocs.io/en/release-1.4/channel_update_tutorial.html

Resources