Can we declare stage name inside the template.serverless file? - asp.net-core

We are creating AWS Serverless Lambda function using .NET Core. When we deploy this lambda function it added automatically "Prod" suffix in the url. But we want change it to "dev". Can we declare stage name inside the serverless.template file?
Here is my serverless.template file:
{
"AWSTemplateFormatVersion" : "2010-09-09",
"Transform" : "AWS::Serverless-2016-10-31",
"Description" : "An AWS Serverless Application that uses the ASP.NET Core framework running in Amazon Lambda.",
"Parameters" : {
},
"Conditions" : {
},
"Resources" : {
"Get" : {
"Type" : "AWS::Serverless::Function",
"Properties": {
"Handler": "F2C.MAP.API.AWSLambda.PublicAPI::F2C.MAP.API.AWSLambda.PublicAPI.LambdaEntryPoint::FunctionHandlerAsync",
"Runtime": "dotnetcore2.0",
"CodeUri": "",
"MemorySize": 256,
"Timeout": 30,
"Role": null,
"Policies": [ "AWSLambdaFullAccess" ],
"Environment" : {
"Variables" : {
}
},
"Events": {
"PutResource": {
"Type": "Api",
"Properties": {
"Path": "/{proxy+}",
"Method": "GET"
}
}
}
}
},
"POST" : {
"Type" : "AWS::Serverless::Function",
"Properties": {
"Handler": "F2C.MAP.API.AWSLambda.PublicAPI::F2C.MAP.API.AWSLambda.PublicAPI.LambdaEntryPoint::FunctionHandlerAsync",
"Runtime": "dotnetcore2.0",
"CodeUri": "",
"MemorySize": 256,
"Timeout": 30,
"Role": null,
"Policies": [ "AWSLambdaFullAccess" ],
"Environment" : {
"Variables" : {
}
},
"Events": {
"PutResource": {
"Type": "Api",
"Properties": {
"Path": "/{proxy+}",
"Method": "POST"
}
}
}
}
}
},
"Outputs" : {
}
}
We are using AWS Toolkit for visual studio 2017 to deploy aws serverless lambda.("https://aws.amazon.com/blogs/developer/preview-of-the-aws-toolkit-for-visual-studio-2017")

The only way I could find to make this work is the specify a AWS::Serverless::Api to use. The following example sets both the StageName and the ASPNETCORE_ENVIRONMENT to the EnvironmentName parameter.
serverless.template:
{
"AWSTemplateFormatVersion" : "2010-09-09",
"Transform" : "AWS::Serverless-2016-10-31",
"Description" : "An AWS Serverless Application that uses the ASP.NET Core framework running in Amazon Lambda.",
"Parameters" : {
"EnvironmentName" : {
"Type" : "String",
"Description" : "Sets the ASPNETCORE_ENVIRONMENT variable as well as the API's StageName to this.",
"MinLength" : "0"
}
},
"Resources" : {
"ProxyFunction" : {
"Type" : "AWS::Serverless::Function",
"Properties": {
"Handler": "PeopleGateway::PeopleGateway.LambdaEntryPoint::FunctionHandlerAsync",
"Runtime": "dotnetcore2.0",
"CodeUri": "",
"MemorySize": 256,
"Timeout": 30,
"Role": null,
"Policies": [ "AWSLambdaFullAccess", "AWSLambdaVPCAccessExecutionRole" ],
"Environment" : {
"Variables" : {
"ASPNETCORE_ENVIRONMENT": { "Ref" : "EnvironmentName" }
}
},
"Events": {
"PutResource": {
"Type": "Api",
"Properties": {
"Path": "/{proxy+}",
"Method": "ANY",
"RestApiId": { "Ref": "APIGateway" }
}
}
}
}
},
"APIGateway": {
"Type" : "AWS::Serverless::Api",
"Properties": {
"StageName": { "Ref" : "EnvironmentName" },
"DefinitionBody": {
"swagger": "2.0",
"info": {
"title": {
"Ref": "AWS::StackName"
}
},
"paths": {
"/{proxy+}": {
"x-amazon-apigateway-any-method": {
"x-amazon-apigateway-integration": {
"httpMethod": "POST",
"type": "aws_proxy",
"uri": {
"Fn::Sub": "arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${ProxyFunction.Arn}/invocations"
}
},
"responses": {}
}
}
}
}
}
}
},
"Outputs" : {
"ApiURL" : {
"Description" : "API endpoint URL for the specified environment",
"Value" : { "Fn::Sub" : "https://${APIGateway}.execute-api.${AWS::Region}.amazonaws.com/${EnvironmentName}/" }
}
}
}

Related

Tyk - request body is forwarded without being transformed

I am new to api gateways and I wanted to try to use Tyk product
I installed the docker version and created an api using the documentation
I tried to do a transformation using templates but the request was forwarded without any transformation
here is the Api configuration
{
"name": "Hello-World",
"slug": "hello-world",
"api_id": "Hello-World",
"org_id": "1",
"use_keyless": true,
"auth": {
"auth_header_name": "Authorization"
},
"definition": {
"location": "header",
"key": "x-api-version"
},
"version_data": {
"not_versioned": true,
"versions": {
"Default": {
"name": "Default",
"use_extended_paths": true
},
"extended_paths": {
"transform": [
{
"path": "/widgets",
"method": "POST",
"template_data": {
"template_mode": "file",
"template_source": "./templates/transform_test.tmpl"
}
}
]
}
}
},
"proxy": {
"listen_path": "/widgets",
"target_url": "http://7857-102-158-57-156.ngrok.io/api/v1",
"strip_listen_path": true
},
"active": true
}
The target_url is pointing to dummy express service that responds with the request body.
here is the template I am using
{
"value1": "{{.value2}}",
"value2": "{{.value1}}",
"transformed_list": [
{{range $index, $element := .value_list}}
{{if $index}}
, "{{$element}}"
{{else}}
"{{$element}}"
{{end}}
{{end}}
]
}
and this is the input I am trying to transform
{
"value1": "value-1",
"value2": "value-2",
"value_list": [
"one",
"two",
"three"
]
}
There seems to be an issue with your API definition file. The extended_paths section should be a child of the Default field. This is what it should look like
{
"version_data": {
"not_versioned": true,
"versions": {
"Default": {
"name": "Default",
"use_extended_paths": true,
"extended_paths": {
"transform": [
{
"path": "/widgets",
"method": "POST",
"template_data": {
"template_mode": "file",
"template_source": "./templates/transform_test.tmpl"
}
}
]
}
}
}
}
}

Unomi use of UpdatePoperties event to enrich profil

We are tring to enrich a profil using UpdateProperties event.
Something wrong, it didn't work.
Step of our process :
Search of the profil :
Use of the prive API /profiles/search
So we find a profil and get the profilId "60de10fe-e6ff-11ec-8fea-0242ac120002" for next step.
Enrich profil :
Use of the API public /context.json to post the json
{
"sessionId": null,
"profileId": "60de10fe-e6ff-11ec-8fea-0242ac120002",
"events": [
{
"itemType": "event",
"scope": "myScope",
"eventType": "updateProperties",
"properties": {
"update": {
"properties.age": "24"
},
"add": {
"properties.kids" : "1"
}
}
}
]
}
Response :
{
"profileId": "60de10fe-e6ff-11ec-8fea-0242ac120002",
"sessionId": null,
"profileProperties": null,
"sessionProperties": null,
"profileSegments": null,
"profileScores": null,
"filteringResults": null,
"processedEvents": 1,
"personalizations": null,
"trackedConditions": [
{
"parameterValues": {
"operator": "and",
"subConditions": [
{
"parameterValues": {
"formId": "zoneLeadFormEvent"
},
"type": "formEventCondition"
}
]
},
"type": "booleanCondition"
},
{
"parameterValues": {
"formId": "testFormTracking",
"pagePath": "/tracker/"
},
"type": "formEventCondition"
},
{
"parameterValues": {
"formId": "searchForm"
},
"type": "formEventCondition"
},
{
"parameterValues": {
"formId": "advancedSearchForm"
},
"type": "formEventCondition"
}
],
"anonymousBrowsing": false,
"consents": {}
}
Validation of the profile changes
Get /cxs/profiles/60de10fe-e6ff-11ec-8fea-0242ac120002
So, the properties are not updated.
We use a rules the merge the profil on a custom identifier :
{
"metadata": {
"id": "update_with_custom_identifier",
"name": "UpdateWithCustomIdentifier",
"description": "Copy my properties to profile properties on update"
},
"condition": {
"parameterValues": {
"subConditions": [
{
"parameterValues": {
},
"type": "updatePropertiesEventCondition"
}
],
"operator": "and"
},
"type": "booleanCondition"
},
"actions": [
{
"parameterValues": {
"mergeProfilePropertyValue": "eventProperty::target.properties.myIdentifier",
"mergeProfilePropertyName": "mergeCustomIdentifier"
},
"type": "mergeProfilesOnPropertyAction"
},
{
"parameterValues": {
},
"type": "allEventToProfilePropertiesAction"
}
]
}
What's the good method ?
Thanks in advance

Logic App with azure monitor and conditions

I create a workflow with logicAPP. The goal is to notify a team when patch is missing for VM. I use azure monitor in the logic app to set the query. I decided to put after the Azure Monitor , a condition to know if the query table is empty or have data. if the table is empty, the logix is true , so it does'nt send notification, and when its false , it sends notification.
When I run , I got a logic errors. Normally , the table has not data but after condition , the function empty([my_table]) returns false and sends me notification with the result ("The query yielded no data")
what is the problem ??
Thanks
Based on the above shared requirement we have created the logic app & tested it our local environment , it is working fine.
Below is the complete logic code :
{
"definition": {
"$schema": "https://schema.management.azure.com/providers/Microsoft.Logic/schemas/2016-06-01/workflowdefinition.json#",
"actions": {
"Condition_2": {
"actions": {
"Terminate_2": {
"inputs": {
"runStatus": "Cancelled"
},
"runAfter": {},
"type": "Terminate"
}
},
"else": {
"actions": {
"Send_an_email_(V2)_2": {
"inputs": {
"body": {
"Body": "<p>#{base64ToString(body('Run_query_and_visualize_results')?['body'])}</p>",
"Subject": "list of vm from update management ",
"To": "<UserEmailId>"
},
"host": {
"connection": {
"name": "#parameters('$connections')['office365']['connectionId']"
}
},
"method": "post",
"path": "/v2/Mail"
},
"runAfter": {},
"type": "ApiConnection"
}
}
},
"expression": {
"and": [
{
"equals": [
"#length(body('Run_query_and_visualize_results')?['body'])",
0
]
}
]
},
"runAfter": {
"Run_query_and_visualize_results": [
"Succeeded"
]
},
"type": "If"
},
"Run_query_and_visualize_results": {
"inputs": {
"body": "Update\n| where Classification == 'Security Updates' or Classification == 'Critical Updates'\n| where UpdateState == 'Needed'\n| summarize by Computer,ResourceGroup,Classification,UpdateState\n|sort by Computer",
"host": {
"connection": {
"name": "#parameters('$connections')['azuremonitorlogs']['connectionId']"
}
},
"method": "post",
"path": "/visualizeQuery",
"queries": {
"resourcegroups": "<Resource_group_Name",
"resourcename": "<log analytics workspacename",
"resourcetype": "Log Analytics Workspace",
"subscriptions": "<subcription_id>",
"timerange": "Last 12 hours",
"visType": "Html Table"
}
},
"runAfter": {},
"type": "ApiConnection"
}
},
"contentVersion": "1.0.0.0",
"outputs": {},
"parameters": {
"$connections": {
"defaultValue": {},
"type": "Object"
}
},
"triggers": {
"Recurrence": {
"evaluatedRecurrence": {
"frequency": "Hour",
"interval": 3
},
"recurrence": {
"frequency": "Hour",
"interval": 3
},
"type": "Recurrence"
}
}
},
"parameters": {
"$connections": {
"value": {
"azuremonitorlogs": {
"connectionId": "/subscriptions/<subcription-id>/resourceGroups/<resource-group>/providers/Microsoft.Web/connections/azuremonitorlogs",
"connectionName": "azuremonitorlogs",
"id": "/subscriptions/<subcription-id>/providers/Microsoft.Web/locations/northcentralus/managedApis/azuremonitorlogs"
},
"office365": {
"connectionId": "/subscriptions/<subcription-id>/resourceGroups/<resource-group>/providers/Microsoft.Web/connections/office365",
"connectionName": "office365",
"id": "/subscriptions/<subcription-id>/providers/Microsoft.Web/locations/northcentralus/managedApis/office365"
}
}
}
}
}
please find the reference output of the above logic sample run :

Swagger UI execute button not working when file is uploading

One of the endpoint in my API is for uploading a file and submitting details about the file . The API is implemented in ASP.Net Core. NSwag package is installed in my project. OAS 3 specification is implemented
On Swagger UI I can submit data without uploading file. if the file is chosen using file browser, the execute button is not working when clicked.
I checked Console and Network tab in Chrome Dev tools. There is no network movement. There is no request at all. Neither errors nor any logs were seen in console.
I used bearer token authorisation according to this. I tried in both cases of when in authorised and not authorised state. In both case Execute button not working when file is chosen. When bearer token was not given, and I execute with other parameters except file. I got 401 status response. If the file chosen , the click of execute button has no effect.
The swagger file is:
{
"x-generator": "NSwag v13.1.5.0 (NJsonSchema v10.0.27.0 (Newtonsoft.Json v12.0.0.0))",
"openapi": "3.0.0",
"info": {
"title": "My Title",
"version": "1.0.0"
},
"servers": [
{
"url": "https://localhost:5300"
}
],
"paths": {
"/api/Order": {
"post": {
"tags": [
"Order"
],
"operationId": "Order_Post",
"responses": {
"200": {
"description": "",
"content": {
"application/octet-stream": {
"schema": {
"type": "string",
"format": "binary"
}
}
}
}
}
}
},
"/api/Order/{action}/document": {
"post": {
"tags": [
"Order"
],
"operationId": "Order_CreateDocument",
"parameters": [
{
"name": "FileName",
"in": "formData",
"schema": {
"type": "string",
"nullable": true
},
"x-position": 1
},
{
"name": "FileType",
"in": "formData",
"schema": {
"type": "string",
"nullable": true
},
"x-position": 2
},
{
"name": "DocumentType",
"in": "formData",
"schema": {
"type": "string",
"nullable": true
},
"x-position": 3
},
{
"name": "Description",
"in": "formData",
"schema": {
"type": "string",
"nullable": true
},
"x-position": 4
},
{
"name": "Owners",
"in": "formData",
"collectionFormat": "multi",
"schema": {
"type": "array",
"nullable": true,
"items": {
"type": "string"
}
},
"x-position": 5
},
{
"type": "file",
"name": "SomeFile",
"in": "formData",
"schema": {
"type": "string",
"format": "binary",
"nullable": true
},
"nullable": true
}
],
"responses": {
"200": {
"description": "",
"content": {
"application/octet-stream": {
"schema": {
"type": "string",
"format": "binary"
}
}
}
}
}
}
},
"/api/Debug": {
"get": {
"tags": [
"Debug"
],
"operationId": "Debug_Get",
"parameters": [
{
"name": "message",
"in": "query",
"schema": {
"type": "string",
"nullable": true
},
"x-position": 1
}
],
"responses": {
"200": {
"description": "",
"content": {
"application/json": {
"schema": {
"type": "string"
}
}
}
}
}
}
}
},
"components": {
"securitySchemes": {
"authorization": {
"type": "apiKey",
"name": "authorization",
"in": "header"
}
}
},
"security": [
{
"authorization": []
}
]
}
I want to submit the file and other details as multipart form data.
ASP.Net Core code for the endpoint:
[HttpPost("document")]
public ActionResult CreateDocument([FromForm]Document request)
{ ... }
Document Class :
public class Document
{
public string FileName { get; set; }
public string FileType { get; set; }
public string DocumentType { get; set; }
public string Description { get; set; }
public List<string> Owners { get; set; } = new List<string>();
public Microsoft.AspNetCore.Http.IFormFile SomeFile { get; set; }
}
In Startup.cs :
public void ConfigureServices(IServiceCollection services)
{
....
...
// Register the Swagger services
services.AddOpenApiDocument(document =>
{
document.AddSecurity("authorization", Enumerable.Empty<string>(), new NSwag.OpenApiSecurityScheme
{
Type = NSwag.OpenApiSecuritySchemeType.ApiKey,
Name = "authorization",
In = NSwag.OpenApiSecurityApiKeyLocation.Header
});
document.OperationProcessors.Add(
new NSwag.Generation.Processors.Security.AspNetCoreOperationSecurityScopeProcessor("bearer"));
}); // registers a OpenAPI v3.0 document
}
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
. . . . . .
. . . . . .
// Register the Swagger generator and the Swagger UI middlewares
app.UseOpenApi();
app.UseSwaggerUi3();
}
Why is execute button in Swagger-UI not working ? How can i upload file from Swagger-UI ?
#Helen has commented and pointed the issue. It is NSwag.AspNetCore package/library.
It seems NSwag library has a bug in Swagger Generation for ASP.Core API in OpenAPI sepecification 3.0 . the issues for this error. It is only when using FromForm attribute for Model binding. In my case one of the property is Microsoft.AspNetCore.Http.IFormFile type that also may cause this error.
Changing to OAS 2.0 is temporary solution.

AWS API Gateway Query parameter validation

I have been trying to validate my request parameters using x-amazon-apigateway-request-validator, but unfortunately it is not working. Below is swagger file-
{
"swagger": "2.0",
"info": {
"title": "API Gateway - Request Validation Demo"
},
"schemes": [
"https"
],
"produces": [
"application/json"
],
"x-amazon-apigateway-request-validators" : {
"full" : {
"validateRequestBody" : true,
"validateRequestParameters" : true
},
"body-only" : {
"validateRequestBody" : true,
"validateRequestParameters" : false
}
},
"x-amazon-apigateway-request-validator" : "full",
"paths": {
"/orders": {
"post": {
"x-amazon-apigateway-request-validator": "body-only",
"parameters": [
{
"in": "body",
"name": "CreateOrders",
"required": true,
"schema": {
"$ref": "#/definitions/CreateOrders"
}
}
],
"responses": {
"200": {
"schema": {
"$ref": "#/definitions/Message"
}
},
"400" : {
"schema": {
"$ref": "#/definitions/Message"
}
}
},
"x-amazon-apigateway-integration": {
"responses": {
"default": {
"statusCode": "200",
"responseTemplates": {
"application/json": "{\"message\" : \"Orders successfully created\"}"
}
}
},
"requestTemplates": {
"application/json": "{\"statusCode\": 200}"
},
"passthroughBehavior": "never",
"type": "mock"
}
},
"get": {
"x-amazon-apigateway-request-validator": "full",
"parameters": [
{
"in": "header",
"name": "Account-Id",
"required": true
},
{
"in": "query",
"name": "type",
"required": false,
"schema": {
"$ref": "#/definitions/InputOrders"
}
}
],
"responses": {
"200" : {
"schema": {
"$ref": "#/definitions/Orders"
}
},
"400" : {
"schema": {
"$ref": "#/definitions/Message"
}
}
},
"x-amazon-apigateway-integration": {
"responses": {
"default": {
"statusCode": "200",
"responseTemplates": {
"application/json": "[{\"order-id\" : \"qrx987\",\n \"type\" : \"STOCK\",\n \"symbol\" : \"AMZN\",\n \"shares\" : 100,\n \"time\" : \"1488217405\",\n \"state\" : \"COMPLETED\"\n},\n{\n \"order-id\" : \"foo123\",\n \"type\" : \"STOCK\",\n \"symbol\" : \"BA\",\n \"shares\" : 100,\n \"time\" : \"1488213043\",\n \"state\" : \"COMPLETED\"\n}\n]"
}
}
},
"requestTemplates": {
"application/json": "{\"statusCode\": 200}"
},
"passthroughBehavior": "never",
"type": "mock"
}
}
}
},
"definitions": {
"CreateOrders": {
"$schema": "http://json-schema.org/draft-04/schema#",
"title": "Create Orders Schema",
"type": "array",
"minItems" : 1,
"items": {
"type": "object",
"$ref" : "#/definitions/Order"
}
},
"Orders" : {
"type": "array",
"$schema": "http://json-schema.org/draft-04/schema#",
"title": "Get Orders Schema",
"items": {
"type": "object",
"properties": {
"order_id": { "type": "string" },
"time" : { "type": "string" },
"state" : {
"type": "string",
"enum": [
"PENDING",
"COMPLETED"
]
},
"order" : {
"$ref" : "#/definitions/Order"
}
}
}
},
"Order" : {
"type": "object",
"$schema": "http://json-schema.org/draft-04/schema#",
"title": "Schema for a single Order",
"required": [
"account-id",
"type",
"symbol",
"shares",
"details"
],
"properties" : {
"account-id": {
"type": "string",
"pattern": "[A-Za-z]{6}[0-9]{6}"
},
"type": {
"type" : "string",
"enum" : [
"STOCK",
"BOND",
"CASH"]
},
"symbol" : {
"type": "string",
"minLength": 1,
"maxLength": 4
},
"shares": {
"type": "number",
"minimum": 1,
"maximum": 1000
},
"details": {
"type": "object",
"required": [
"limit"
],
"properties": {
"limit": {
"type": "number"
}
}
}
}
},
"InputOrder" : {
"type": "object",
"$schema": "http://json-schema.org/draft-04/schema#",
"title": "Schema for a Input Order",
"required": [
"type"
],
"properties" : {
"type": {
"type" : "string",
"enum" : [
"STOCK",
"BOND",
"CASH"]
}
}
},
"Message": {
"type": "object",
"properties": {
"message" : {
"type" : "string"
}
}
}
}
}
I am trying to validate my request parameters against some regex and enum values.
I am not sure if this is even possible or not. Can anybody please help me with this?
For HTTP parameter validation, API Gateway only supports marking one as 'required'. It does not support regex/enum values for parameters.