I have been using google maps for awhile now and have run into limitations with the kml layer(no mouseover only click)
so I thought I would tryout the data layer(geojson)
I cannot seem to figure out how to change the icons(marker image).
I am able to change all the markers to a specific image but I would like to be able to use one of 8 different images depending on the feature.property.generated from my db
map.data.loadGeoJson('http://www.example.com/geojson.php?city_id=017');
// Set mouseover event for each feature.
map.data.addListener('mouseover', function(event) {
$('.map-tooltip').text(event.feature.getProperty('name'));
});
my JSON FILE
{
"type":"FeatureCollection",
"features":[
{
"type":"Feature",
"geometry":{
"type":"Point",
"coordinates":[
-117.1405,
33.551667
]
},
"icon":"http://maps.google.com/mapfiles/dir_0.png",
"properties":{
"name":"017001",
"heading":null,
"face":"North"
}
},
{
"type":"Feature",
"geometry":{
"type":"Point",
"coordinates":[
-117.123269,
33.552172
]
},
"icon":"http://maps.google.com/mapfiles/dir_90.png",
"properties":{
"name":"050010",
"heading":null,
"face":"East"
}
},
{
"type":"Feature",
"geometry":{
"type":"Point",
"coordinates":[
-117.122675,
33.55155
]
},
"icon":"http://maps.google.com/mapfiles/dir_60.png",
"properties":{
"name":"050011",
"heading":null,
"face":"South"
}
},
{
"type":"Feature",
"geometry":{
"type":"Point",
"coordinates":[
-117.120978,
33.551613
]
},
"icon":"http://maps.google.com/mapfiles/dir_30.png",
"properties":{
"name":"050012",
"heading":null,
"face":"West"
}
},
{
"type":"Feature",
"geometry":{
"type":"Point",
"coordinates":[
-117.118667,
33.6055
]
},
"icon":"http://maps.google.com/mapfiles/dir_walk_18.png",
"properties":{
"name":"017069",
"heading":null,
"face":"SE"
}
},
{
"type":"Feature",
"geometry":{
"type":"Point",
"coordinates":[
-117.118667,
33.6055
]
},
"icon":"http://maps.google.com/mapfiles/dir_111.png",
"properties":{
"name":"017069",
"heading":null,
"face":"SW"
}
},
{
"type":"Feature",
"geometry":{
"type":"Point",
"coordinates":[
-117.11,
33.5835
]
},
"icon":"http://maps.google.com/mapfiles/dir_81.png",
"properties":{
"name":"017070",
"heading":null,
"face":"NW"
}
},
{
"type":"Feature",
"geometry":{
"type":"Point",
"coordinates":[
-117.11,
33.5835
]
},
"icon":"http://maps.google.com/mapfiles/dir_42.png",
"properties":{
"name":"017070",
"heading":null,
"face":"NE"
}
}
]
}
so I am not sure how to get the icon files to work
TIA for any help
To access the icon property in your geoJson (at least using the dataLayer methods) you need to move it into the "properties" object. Then you can do this (like this example of dynamic styles in the documentation)
map.data.setStyle(function(feature) {
var icon=null;
if (feature.getProperty('icon')) {
icon = feature.getProperty('icon');
}
return /** #type {google.maps.Data.StyleOptions} */({
icon: icon
});
});
proof of concept fiddle
code snippet:
var map;
var bounds = new google.maps.LatLngBounds();
function initialize() {
var map = new google.maps.Map(
document.getElementById("map_canvas"), {
center: new google.maps.LatLng(37.4419, -122.1419),
zoom: 13,
mapTypeId: google.maps.MapTypeId.ROADMAP
});
google.maps.event.addListener(map.data, 'addfeature', function(e) {
// auto center map on markers
if (e.feature.getGeometry().getType() === 'Point') {
bounds.extend(e.feature.getGeometry().get());
}
map.fitBounds(bounds);
});
// Set the icon from the "icon" property in the geoJson
map.data.setStyle(function(feature) {
var icon = null;
if (feature.getProperty('icon')) {
icon = feature.getProperty('icon');
}
return /** #type {google.maps.Data.StyleOptions} */ ({
icon: icon
});
});
map.data.addGeoJson(geoJson);
}
google.maps.event.addDomListener(window, "load", initialize);
// modified geoJson
var geoJson = {
"type": "FeatureCollection",
"features": [{
"type": "Feature",
"geometry": {
"type": "Point",
"coordinates": [-117.1405,
33.551667
]
},
"properties": {
"name": "017001",
"heading": null,
"face": "North",
"icon": "http://maps.google.com/mapfiles/dir_0.png"
}
}, {
"type": "Feature",
"geometry": {
"type": "Point",
"coordinates": [-117.123269,
33.552172
]
},
"properties": {
"name": "050010",
"heading": null,
"icon": "http://maps.google.com/mapfiles/dir_90.png",
"face": "East"
}
}, {
"type": "Feature",
"geometry": {
"type": "Point",
"coordinates": [-117.122675,
33.55155
]
},
"properties": {
"icon": "http://maps.google.com/mapfiles/dir_60.png",
"name": "050011",
"heading": null,
"face": "South"
}
}, {
"type": "Feature",
"geometry": {
"type": "Point",
"coordinates": [-117.120978,
33.551613
]
},
"properties": {
"icon": "http://maps.google.com/mapfiles/dir_30.png",
"name": "050012",
"heading": null,
"face": "West"
}
}, {
"type": "Feature",
"geometry": {
"type": "Point",
"coordinates": [-117.118667,
33.6055
]
},
"properties": {
"icon": "http://maps.google.com/mapfiles/dir_walk_18.png",
"name": "017069",
"heading": null,
"face": "SE"
}
}, {
"type": "Feature",
"geometry": {
"type": "Point",
"coordinates": [-117.118667,
33.6055
]
},
"properties": {
"icon": "http://maps.google.com/mapfiles/dir_111.png",
"name": "017069",
"heading": null,
"face": "SW"
}
}, {
"type": "Feature",
"geometry": {
"type": "Point",
"coordinates": [-117.11,
33.5835
]
},
"properties": {
"icon": "http://maps.google.com/mapfiles/dir_81.png",
"name": "017070",
"heading": null,
"face": "NW"
}
}, {
"type": "Feature",
"geometry": {
"type": "Point",
"coordinates": [-117.11,
33.5835
]
},
"properties": {
"icon": "http://maps.google.com/mapfiles/dir_42.png",
"name": "017070",
"heading": null,
"face": "NE"
}
}]
};
html,
body,
#map_canvas {
height: 500px;
width: 500px;
margin: 0px;
padding: 0px
}
<script src="https://maps.googleapis.com/maps/api/js"></script>
<div id="map_canvas" style="border: 2px solid #3872ac;"></div>
Related
When I query a resolver in my GraphQL API, in which I have added a $util.error($ctx) to return the context object, I get the following result (removed unnecessary values).
{
"data": {
"listXData": null
},
"errors": [
{
"message": {
"arguments": {},
"args": {},
"info": {
"fieldName": "listXData",
"variables": {},
"parentTypeName": "Query",
"selectionSetList": [
"items",
"items/id",
"items/createdAt",
"items/updatedAt",
"nextToken"
],
"selectionSetGraphQL": "{\n items {\n id\n createdAt\n updatedAt\n }\n nextToken\n}"
},
"request": {...},
"identity": {
"sub": "",
"issuer": "",
"username": "013fe9d2-95f7-4885-83ec-b7e2e0a1423f",
"sourceIp": "",
"claims": {
"origin_jti": "",
"sub": "",
"event_id": "",
"token_use": "",
"scope": "",
"auth_time": ,
"iss": "",
"exp": ,
"iat": ,
"jti": "",
"client_id": "",
"username": "013fe9d2-95f7-4885-83ec-b7e2e0a1423f"
},
"defaultAuthStrategy": "ALLOW"
},
"stash": {},
"source": null,
"result": {
"items": [],
"scannedCount": 0,
"nextToken": null
},
"error": null,
"prev": {
"result": {}
}
},
"errorType": null,
"data": null,
"errorInfo": null,
"path": [
"listXData"
],
"locations": [
{
"line": 2,
"column": 3,
"sourceName": "GraphQL request"
}
]
}
]
}
As you can see, the username is an ID, however I would prefer to (also) have the email. Is it possible to get the user email (within the Velocity template)?
Let me know if I need to add more details or if my question is unclear.
The identity context only returns back the Cognito username for the user pool. You will need to setup pipeline functions to perform additional queries to get your user information. Here is one intro to setting them up.
At this point, it seems that it is not possible to do this purely by vtl.
I have implemented it using a lambda function, as follow:
Lambda function (node):
/* Amplify Params - DO NOT EDIT
ENV
REGION
Amplify Params - DO NOT EDIT */
const aws = require('aws-sdk')
const cognitoidentityserviceprovider = new aws.CognitoIdentityServiceProvider({
apiVersion: '2016-04-18',
region: 'eu-west-1'
})
exports.handler = async (context, event, callback) => {
if (!context.identity?.username) {
callback('Not signed in')
}
const params = {
'AccessToken': context.request.headers.authorization
}
const result = await cognitoidentityserviceprovider.getUser(params).promise()
const email = result.UserAttributes.find(attribute => attribute.Name === 'email')
callback(null, JSON.stringify({ email }))
}
CustomResources.json
{
"AWSTemplateFormatVersion": "2010-09-09",
"Description": "An auto-generated nested stack.",
"Metadata": {...},
"Parameters": {...},
"Resources": {
"GetEmailLambdaDataSourceRole": {
"Type": "AWS::IAM::Role",
"Properties": {
"RoleName": {
"Fn::If": [
"HasEnvironmentParameter",
{
"Fn::Join": [
"-",
[
"GetEmail17ec",
{
"Ref": "GetAttGraphQLAPIApiId"
},
{
"Ref": "env"
}
]
]
},
{
"Fn::Join": [
"-",
[
"GetEmail17ec",
{
"Ref": "GetAttGraphQLAPIApiId"
}
]
]
}
]
},
"AssumeRolePolicyDocument": {
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Service": "appsync.amazonaws.com"
},
"Action": "sts:AssumeRole"
}
]
},
"Policies": [
{
"PolicyName": "InvokeLambdaFunction",
"PolicyDocument": {
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"lambda:InvokeFunction"
],
"Resource": {
"Fn::If": [
"HasEnvironmentParameter",
{
"Fn::Sub": [
"arn:aws:lambda:${AWS::Region}:${AWS::AccountId}:function:GetEmail-${env}",
{
"env": {
"Ref": "env"
}
}
]
},
{
"Fn::Sub": [
"arn:aws:lambda:${AWS::Region}:${AWS::AccountId}:function:GetEmail",
{}
]
}
]
}
}
]
}
}
]
}
},
"GetEmailLambdaDataSource": {
"Type": "AWS::AppSync::DataSource",
"Properties": {
"ApiId": {
"Ref": "AppSyncApiId"
},
"Name": "GetEmailLambdaDataSource",
"Type": "AWS_LAMBDA",
"ServiceRoleArn": {
"Fn::GetAtt": [
"GetEmailLambdaDataSourceRole",
"Arn"
]
},
"LambdaConfig": {
"LambdaFunctionArn": {
"Fn::If": [
"HasEnvironmentParameter",
{
"Fn::Sub": [
"arn:aws:lambda:${AWS::Region}:${AWS::AccountId}:function:GetEmail-${env}",
{
"env": {
"Ref": "env"
}
}
]
},
{
"Fn::Sub": [
"arn:aws:lambda:${AWS::Region}:${AWS::AccountId}:function:GetEmail",
{}
]
}
]
}
}
},
"DependsOn": "GetEmailLambdaDataSourceRole"
},
"InvokeGetEmailLambdaDataSource": {
"Type": "AWS::AppSync::FunctionConfiguration",
"Properties": {
"ApiId": {
"Ref": "AppSyncApiId"
},
"Name": "InvokeGetEmailLambdaDataSource",
"DataSourceName": "GetEmailLambdaDataSource",
"FunctionVersion": "2018-05-29",
"RequestMappingTemplateS3Location": {
"Fn::Sub": [
"s3://${S3DeploymentBucket}/${S3DeploymentRootKey}/pipelineFunctions/${ResolverFileName}",
{
"S3DeploymentBucket": {
"Ref": "S3DeploymentBucket"
},
"S3DeploymentRootKey": {
"Ref": "S3DeploymentRootKey"
},
"ResolverFileName": {
"Fn::Join": [
".",
[
"InvokeGetEmailLambdaDataSource",
"req",
"vtl"
]
]
}
}
]
},
"ResponseMappingTemplateS3Location": {
"Fn::Sub": [
"s3://${S3DeploymentBucket}/${S3DeploymentRootKey}/pipelineFunctions/${ResolverFileName}",
{
"S3DeploymentBucket": {
"Ref": "S3DeploymentBucket"
},
"S3DeploymentRootKey": {
"Ref": "S3DeploymentRootKey"
},
"ResolverFileName": {
"Fn::Join": [
".",
[
"InvokeGetEmailLambdaDataSource",
"res",
"vtl"
]
]
}
}
]
}
},
"DependsOn": "GetEmailLambdaDataSource"
},
"IsOrganizationMember": {
"Type": "AWS::AppSync::FunctionConfiguration",
"Properties": {
"FunctionVersion": "2018-05-29",
"ApiId": {
"Ref": "AppSyncApiId"
},
"Name": "IsOrganizationMember",
"DataSourceName": "PermissionsPerOrganizationTable",
"RequestMappingTemplateS3Location": {
"Fn::Sub": [
"s3://${S3DeploymentBucket}/${S3DeploymentRootKey}/resolvers/Query.isOrganizationMember.req.vtl",
{
"S3DeploymentBucket": {
"Ref": "S3DeploymentBucket"
},
"S3DeploymentRootKey": {
"Ref": "S3DeploymentRootKey"
}
}
]
},
"ResponseMappingTemplateS3Location": {
"Fn::Sub": [
"s3://${S3DeploymentBucket}/${S3DeploymentRootKey}/resolvers/Query.isOrganizationMember.res.vtl",
{
"S3DeploymentBucket": {
"Ref": "S3DeploymentBucket"
},
"S3DeploymentRootKey": {
"Ref": "S3DeploymentRootKey"
}
}
]
}
}
},
"OrganizationAccessPipeline": {
"Type": "AWS::AppSync::Resolver",
"Properties": {
"ApiId": {
"Ref": "AppSyncApiId"
},
"TypeName": "Query",
"Kind": "PIPELINE",
"FieldName": "listXData",
"PipelineConfig": {
"Functions": [
{
"Fn::GetAtt": [
"InvokeGetEmailLambdaDataSource",
"FunctionId"
]
},
{
"Fn::GetAtt": [
"IsOrganizationMember",
"FunctionId"
]
}
]
},
"RequestMappingTemplate": "{}",
"ResponseMappingTemplate": "$util.toJson($ctx.result)"
}
}
},
"Conditions": {...},
"Outputs": {...}
}
The lambda is created with the CLI and IsOrganizationMember is a regular VTL which has the user email in the $context.prev.result.
Let's say I have the following GeoJSON file:
{
"type": "FeatureCollection",
"features": [
{
"type": "Feature",
"properties": {
"algorithm": "parameterA"
},
"geometry": {
"type": "MultiPolygon",
"coordinates": []
}
},
{
"type": "Feature",
"properties": {
"algorithm": "parameterB"
},
"geometry": {
"type": "MultiPolygon",
"coordinates": []
}
},
{
"type": "Feature",
"properties": {
"algorithm": "parameterB"
},
"geometry": {
"type": "MultiPolygon",
"coordinates": []
}
},
{
"type": "Feature",
"properties": {
"algorithm": "parameterA"
},
"geometry": {
"type": "MultiPolygon",
"coordinates": []
}
}
],
"properties": {
"name": "myGeoJSON"
}
}
I'd like to find a way of erasing only the arrays containing a specific algorithm key. Let's say I want to erase all arrays which algorithm is equal to parameterA, so I'd get the following result:
{
"type": "FeatureCollection",
"features": [
{
"type": "Feature",
"properties": {
"algorithm": "parameterB"
},
"geometry": {
"type": "MultiPolygon",
"coordinates": []
}
},
{
"type": "Feature",
"properties": {
"algorithm": "parameterB"
},
"geometry": {
"type": "MultiPolygon",
"coordinates": []
}
}
],
"properties": {
"name": "myGeoJSON"
}
}
I know I can erase a specific value from my array by using something like jq del'(.features[0] )' file.json. But I don't know how to use a condition in it that will erase only array blocks that have a specific property. How can I do it using jq?
jq 'del( .features[] | select(.properties.algorithm == "parameterA") )'
jqplay
I'm setting up an action which uses push notifications. Yet, on firebase I can't get "UPDATES_USER_ID" of user to save. It returns "undefined".
I followed the guide on this link and here is my code to get UPDATES_USER_ID.
app.intent('Setup', (conv, params) => {
conv.ask(new UpdatePermission({
intent: "notificationResponseIntent"
}));
});
app.intent("FinishNotificationSetup", (conv, params) => {
if (conv.arguments.get('PERMISSION')) {
conv.data.GoogleUserID = conv.arguments.get("UPDATES_USER_ID");
console.log(conv.data.GoogleUserID);
conv.ask("some response....");
}
});
And here is my webhook request when FinishNotificationSetup intent is invoked.
{
"responseId": "2f425fe5-db42-47dc-90a1-c9bc85f725d2",
"queryResult": {
"queryText": "actions_intent_PERMISSION",
"parameters": {},
"allRequiredParamsPresent": true,
"fulfillmentMessages": [
{
"text": {
"text": [
""
]
}
}
],
"outputContexts": [
{
"name": "projects/projectname/agent/sessions/ABwppHGD33Tyho41g9Mr2vzxePlskNmvOzCTxUiDGzENcl3C7RQs94aOQ8ae_DUlOApR0VBO9DuwAWdWr2frAA/contexts/actions_capability_screen_output"
},
{
"name": "projects/projectname-10c22/agent/sessions/ABwppHGD33Tyho41g9Mr2vzxePlskNmvOzCTxUiDGzENcl3C7RQs94aOQ8ae_DUlOApR0VBO9DuwAWdWr2frAA/contexts/actions_intent_permission",
"parameters": {
"PERMISSION": true,
"text": ""
}
},
{
"name": "projects/projectname-10c22/agent/sessions/ABwppHGD33Tyho41g9Mr2vzxePlskNmvOzCTxUiDGzENcl3C7RQs94aOQ8ae_DUlOApR0VBO9DuwAWdWr2frAA/contexts/_actions_on_google",
"lifespanCount": 98,
"parameters": {
"data": "{\"***":\"***",\"***":\"***"}"
}
},
{
"name": "projects/projectname-10c22/agent/sessions/ABwppHGD33Tyho41g9Mr2vzxePlskNmvOzCTxUiDGzENcl3C7RQs94aOQ8ae_DUlOApR0VBO9DuwAWdWr2frAA/contexts/actions_capability_account_linking"
},
{
"name": "projects/projectname-10c22/agent/sessions/ABwppHGD33Tyho41g9Mr2vzxePlskNmvOzCTxUiDGzENcl3C7RQs94aOQ8ae_DUlOApR0VBO9DuwAWdWr2frAA/contexts/actions_capability_audio_output"
},
{
"name": "projects/projectname-10c22/agent/sessions/ABwppHGD33Tyho41g9Mr2vzxePlskNmvOzCTxUiDGzENcl3C7RQs94aOQ8ae_DUlOApR0VBO9DuwAWdWr2frAA/contexts/google_assistant_input_type_keyboard"
},
{
"name": "projects/projectname-10c22/agent/sessions/ABwppHGD33Tyho41g9Mr2vzxePlskNmvOzCTxUiDGzENcl3C7RQs94aOQ8ae_DUlOApR0VBO9DuwAWdWr2frAA/contexts/actions_capability_web_browser"
},
{
"name": "projects/projectname-10c22/agent/sessions/ABwppHGD33Tyho41g9Mr2vzxePlskNmvOzCTxUiDGzENcl3C7RQs94aOQ8ae_DUlOApR0VBO9DuwAWdWr2frAA/contexts/actions_capability_media_response_audio"
}
],
"intent": {
"name": "projects/projectname-10c22/agent/intents/a12b6d3f-0f24-45e9-a1b2-5649083831b0",
"displayName": "FinishNotificationSetup"
},
"intentDetectionConfidence": 1,
"languageCode": "tr"
},
"originalDetectIntentRequest": {
"source": "google",
"version": "2",
"payload": {
"isInSandbox": true,
"surface": {
"capabilities": [
{
"name": "actions.capability.SCREEN_OUTPUT"
},
{
"name": "actions.capability.WEB_BROWSER"
},
{
"name": "actions.capability.ACCOUNT_LINKING"
},
{
"name": "actions.capability.MEDIA_RESPONSE_AUDIO"
},
{
"name": "actions.capability.AUDIO_OUTPUT"
}
]
},
"requestType": "SIMULATOR",
"inputs": [
{
"rawInputs": [
{
"inputType": "KEYBOARD"
}
],
"arguments": [
{
"textValue": "true",
"name": "PERMISSION",
"boolValue": true
},
{
"name": "text"
}
],
"intent": "actions.intent.PERMISSION"
}
],
"user": {
"lastSeen": "2019-04-30T07:23:23Z",
"permissions": [
"UPDATE"
],
"locale": "tr-TR",
"userId": "ABwppHHCEdtf23ZaNg0DaCv3fvshSUXUvYGXHe6kR7jbKacwIS6vDBBL7YXbN70jYa8KaXWZqbsyhFFSdsYLiw"
},
"conversation": {
"conversationId": "ABwppHGD33Tyho41g9Mr2vzxePlskNmvOzCTxUiDGzENcl3C7RQs94aOQ8ae_DUlOApR0VBO9DuwAWdWr2frAA",
"type": "ACTIVE",
"conversationToken": "[\"_actions_on_google\"]"
},
"availableSurfaces": [
{
"capabilities": [
{
"name": "actions.capability.AUDIO_OUTPUT"
},
{
"name": "actions.capability.SCREEN_OUTPUT"
},
{
"name": "actions.capability.WEB_BROWSER"
}
]
}
]
}
},
"session": "projects/projectname-10c22/agent/sessions/ABwppHGD33Tyho41g9Mr2vzxePlskNmvOzCTxUiDGzENcl3C7RQs94aOQ8ae_DUlOApR0VBO9DuwAWdWr2frAA"
}
To send notification, I've been using userID instead of UPDATES_USER_ID and it is working. Yet, it will be deprecated soon. So, I need to find a solution to get this ID and couldn't make it working. What do I need to do to get this ID?
I've found solution for this problem. While getting UPDATES_USER_ID conv.arguments.get() only works for first attempt. So, while building your action you must save it. If you didn't store or save, you can reset your profile and try again, you will be able to get.
app.intent("FinishNotificationSetup", (conv, params) => {
if (conv.arguments.get('PERMISSION')) {
if(!conv.user.storage.GoogleUserID)
{
conv.user.storage.GoogleUserID = conv.arguments.get("UPDATES_USER_ID");
//For best case
//store ID in your db.
}
console.log(conv.user.storage.GoogleUserID);
conv.ask("some response....");
}
});
For best case, try saving this to your database because conv.user.storage does not work sometimes.
I have template below which errors out during deployment with error below. Samples on documentation page seems to be erroneous and don't even compile.
"message": "VM has reported a failure when processing extension
'Microsoft.Powershell.DSC'. Error message: \"The DSC Extension failed
to install: Invalid type for parameter RegistrationKey of type
PSCredential.\nMore information about the failure can be found in the
logs located under
'C:\WindowsAzure\Logs\Plugins\Microsoft.Powershell.DSC\2.74.0.0'
on the VM.\nTo retry install, please remove the extension from the VM
first. \"."
Template
{
"$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"resources": [
{
"name": "[parameters('swarmmanager1Name')]",
"type": "Microsoft.Compute/virtualMachines",
"location": "[resourceGroup().location]",
"apiVersion": "2015-06-15",
"tags": {
"displayName": "swarmmanager1"
},
"properties": {
"hardwareProfile": {
"vmSize": "[parameters('swarmmanager1VmSize')]"
},
"licenseType": "[parameters('LicenseType')]",
"osProfile": {
"computerName": "[parameters('swarmmanager1Name')]",
"adminUsername": "[parameters('adminUsername')]",
"adminPassword": "[parameters('adminPassword')]"
},
"storageProfile": {
"imageReference": {
"publisher": "[parameters('swarmmanager1ImagePublisher')]",
"offer": "[parameters('swarmmanager1ImageOffer')]",
"sku": "[parameters('windowsOSVersion')]",
"version": "latest"
},
"osDisk": {
"name": "swarmmanager1OSDisk",
"vhd": {
"uri": "[concat(reference(resourceId('Microsoft.Storage/storageAccounts', parameters('dockerswarmstorageaccountName')), '2016-01-01').primaryEndpoints.blob, parameters('swarmmanager1StorageAccountContainerName'), '/', parameters('swarmmanager1OSDiskName'), '.vhd')]"
},
"caching": "ReadWrite",
"createOption": "FromImage"
}
},
"networkProfile": {
"networkInterfaces": [
{
"id": "[resourceId('Microsoft.Network/networkInterfaces', parameters('swarmmanager1NicName'))]"
}
]
}
},
"resources": [
{
"name": "Microsoft.Powershell.DSC",
"type": "extensions",
"location": "[resourceGroup().location]",
"apiVersion": "2015-06-15",
"dependsOn": [
"[resourceId('Microsoft.Compute/virtualMachines', parameters('swarmmanager1Name'))]"
],
"tags": {
"displayName": "DSC"
},
"properties": {
"publisher": "Microsoft.Powershell",
"typeHandlerVersion": "2.26",
"type": "DSC",
"autoUpgradeMinorVersion": true,
"forceUpdateTag": "[parameters('DSCExtensionManagerTagVersion')]",
"settings": {
"wmfVersion": "latest",
"configurationArguments": {
//"RegistrationKey": {
// "UserName": "PLACEHOLDER_DONOTUSE",
// "Password": "PrivateSettingsRef:registrationKeyPrivate"
// },
"RegistrationKey": "[parameters('RegistrationKey')]",
"RegistrationUrl": "[parameters('registrationUrl')]",
"NodeConfigurationName": "SwarmManager.localhost",
"RebootNodeIfNeeded": true
}
},
"protectedSettings": {
"Items": {
"registrationKeyPrivate": "[parameters('RegistrationKey')]"
}
}
}
}
]
},
{
"name": "[parameters('dockerswarmstorageaccountName')]",
"type": "Microsoft.Storage/storageAccounts",
"location": "[resourceGroup().location]",
"apiVersion": "2016-01-01",
"sku": {
"name": "[parameters('dockerswarmstorageaccountType')]"
},
"dependsOn": [],
"tags": {
"displayName": "dockerswarmstorageaccount"
},
"kind": "Storage"
},
{
"name": "[parameters('swarmmanager1NicName')]",
"type": "Microsoft.Network/networkInterfaces",
"location": "[resourceGroup().location]",
"apiVersion": "2016-03-30",
"tags": {
"displayName": "swarmmanager1Nic"
},
"properties": {
"ipConfigurations": [
{
"name": "ipconfig1",
"properties": {
"privateIPAllocationMethod": "Dynamic",
"subnet": {
"id": "[parameters('swarmmanager1SubnetRef')]"
},
"publicIPAddress": {
"id": "[resourceId('Microsoft.Network/publicIPAddresses', parameters('swarmmanagerpublicIPName'))]"
}
}
}
]
}
},
{
"apiVersion": "2016-03-30",
"dependsOn": [],
"location": "[resourceGroup().location]",
"name": "[parameters('swarmmanagerpublicIPName')]",
"properties": {
"publicIPAllocationMethod": "Dynamic",
"dnsSettings": {
"domainNameLabel": "[parameters('swarmmanagerpublicIPDnsName')]"
}
},
"tags": {
"displayName": "swarmmanagerpublicIP"
},
"type": "Microsoft.Network/publicIPAddresses"
}
],
"parameters": {
"swarmmanager1Name": { "type": "string" },
"swarmmanager1VmSize": { "type": "string" },
"adminUsername": { "type": "string" },
"adminPassword": { "type": "securestring" },
"dockerswarmstorageaccountName": { "type": "string" },
"dockerswarmstorageaccountType": { "type": "string" },
"swarmmanager1NicName": { "type": "string" },
"swarmmanagerpublicIPName": { "type": "string" },
"swarmmanager1SubnetRef": { "type": "string" },
"swarmmanager1ImagePublisher": { "type": "string" },
"swarmmanager1ImageOffer": { "type": "string" },
"windowsOSVersion": { "type": "string" },
"swarmmanager1StorageAccountContainerName": { "type": "string" },
"swarmmanager1OSDiskName": { "type": "string" },
"swarmmanagerpublicIPDnsName": { "type": "string" },
"DSCConfigurationURL": { "type": "string" },
"DSCExtensionManagerTagVersion": { "type": "string" },
"RegistrationKey": { "type": "securestring" },
"RegistrationUrl": { "type": "string" },
"LicenseType": {"type": "string"}
},
"outputs": {
"returnedIPAddress": {
"type": "string",
"value": "[reference(parameters('swarmmanager1NicName')).ipConfigurations[0].properties.privateIPAddress]"
}
}
}
if you want to pass in ps credentials do this:
"protectedSettings": {
"configurationArguments": {
"RegistrationKey": {
"userName": "whatever",
"password": "[parameters('RegistrationKey')]"
}
}
}
How can I Deploy a logic app that calls a SQL DB stored procedure? I've tried the following action.
"actions": {
"Execute_stored_procedure": {
"conditions": [ ],
"inputs": {
"body": null,
"host": {
"api": {
"runtimeUrl": "https://logic-apis-northcentralus.azure-apim.net/apim/sql"
},
"connection": {
"name": "<sql connection string>"
}
},
"method": "post",
"path": "/datasets/default/procedures/#{encodeURIComponent(encodeURIComponent(string('<stored-procedure-name>')))}"
},
"type": "apiconnection"
}
}
When I deploy this template, the logic app get's created but it's throwing errors or the SQL Connection action is not showing up on the design view. What am I doing wrong here? Is Logic App for calling SQL Stored Proc supported by arm currently?
Here is a sample template for LogicApp ARM template + 'connections' resource
https://blogs.msdn.microsoft.com/logicapps/2016/02/23/deploying-in-the-logic-apps-preview-refresh/
https://github.com/jeffhollan/logicapps-deployments/blob/master/ftp_to_blob.json
I've finally figured this out from #TusharJ links and I'm posting the template I've used below to configure a LogicApp that calls a SQL DB stored procedure in specific intervals.
resources:
[
{
"type": "Microsoft.Web/connections",
"apiVersion": "2015-08-01-preview",
"location": "[resourceGroup().location]",
"name": "sqlconnector",
"properties": {
"api": {
"id": "[concat('subscriptions/', subscription().subscriptionId, '/providers/Microsoft.Web/locations/', resourceGroup().location, '/managedApis/sql')]"
},
"displayName": "sqlconnector",
"parameterValues": {
"sqlConnectionString": "<sql db connection string>"
}
}
},
{
"type": "Microsoft.Logic/workflows",
"apiVersion": "2015-08-01-preview",
"name": "[parameters('logicAppName')]",
"location": "[resourceGroup().location]",
"tags": {
"displayName": "LogicApp"
},
"properties": {
"sku": {
"name": "[parameters('workflowSkuName')]",
"plan": {
"id": "[concat(resourceGroup().id, '/providers/Microsoft.Web/serverfarms/', parameters('svcPlanName'))]"
}
},
"definition": {
"$schema": "https://schema.management.azure.com/providers/Microsoft.Logic/schemas/2015-08-01-preview/workflowdefinition.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"$connections": {
"defaultValue": { },
"type": "Object"
}
},
"triggers": {
"recurrence": {
"type": "recurrence",
"recurrence": {
"frequency": "Hour",
"interval": 1
}
}
},
"actions": {
"Execute_stored_procedure": {
"conditions": [ ],
"inputs": {
"body": null,
"host": {
"api": {
"runtimeUrl": "[concat('https://logic-apis-', resourceGroup().location, '.azure-apim.net/apim/sql')]"
},
"connection": {
"name": "#parameters('$connections')['sql']['connectionId']"
}
},
"method": "post",
"path": "/datasets/default/procedures/#{encodeURIComponent(encodeURIComponent(string('[dbo].[<Stored Proc Name>]')))}"
},
"type": "apiconnection"
}
},
"outputs": { }
},
"parameters": {
"$connections": {
"value": {
"sql": {
"connectionId": "[resourceId('Microsoft.Web/connections', 'sqlconnector')]",
"connectionName": "sqlconnector",
"id": "[reference(concat('Microsoft.Web/connections/', 'sqlconnector'), '2015-08-01-preview').api.id]"
}
}
}
}
}
}
]
Things may have changed in the API since the previous answer was given. Here is what worked for me as of 10/2016. Note: I used parameters (definitions not shown) for many of the variables:
{
"type": "Microsoft.Web/connections",
"apiVersion": "2015-08-01-preview",
"location": "[parameters('location')]",
"name": "[variables('sql_conn_name')]",
"properties": {
"api": {
"id": "[concat(subscription().id, '/providers/Microsoft.Web/locations/', resourceGroup().location, '/managedApis/sql')]"
},
"displayName": "sql_connection",
"parameterValues": {
"server": "[concat(variables('dbserver_unique_name'), '.database.windows.net')]",
"database": "[parameters('databases_name')]",
"authType": "windows",
"username": "[parameters('databases_admin_user')]",
"password": "[parameters('databases_admin_password')]"
}
}
},
{
"type": "Microsoft.Logic/workflows",
"name": "[variables('logic_app_name')]",
"apiVersion": "2016-06-01",
"location": "[parameters('location')]",
"properties": {
"state": "Enabled",
"definition": {
"$schema": "https://schema.management.azure.com/providers/Microsoft.Logic/schemas/2016-06-01/workflowdefinition.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"$connections": {
"defaultValue": { },
"type": "Object"
}
},
"triggers": {
"Recurrence": {
"recurrence": {
"frequency": "Hour",
"interval": 1
},
"type": "Recurrence"
}
},
"actions": {
"Execute_stored_procedure": {
"runAfter": { },
"type": "ApiConnection",
"inputs": {
"body": {
"timeoffset": "-4"
},
"host": {
"api": {
"runtimeUrl": "[concat('https://logic-apis-', parameters('location'), '.azure-apim.net/apim/sql')]"
},
"connection": {
"name": "#parameters('$connections')['sql']['connectionId']"
}
},
"method": "post",
"path": "/datasets/default/procedures/#{encodeURIComponent(encodeURIComponent('[dbo].[usp_UpdateHourlyOos]'))}"
}
}
},
"outputs": { }
},
"parameters": {
"$connections": {
"value": {
"sql": {
"connectionId": "[concat(subscription().id, '/resourceGroups/', resourceGroup().name, '/providers/Microsoft.Web/connections/', variables('sql_conn_name'))]",
"connectionName": "[variables('sql_conn_name')]",
"id": "[concat(subscription().id,'/providers/Microsoft.Web/locations/', resourceGroup().location, '/managedApis/sql')]"
}
}
}
}
},
"resources": [ ],
"dependsOn": [
"[resourceId('Microsoft.Web/connections', variables('sql_conn_name'))]"
]
}