Related
I have below code for the create function app :
{
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.1",
"parameters": {
"storage_account_name": {
"type": "string",
"defaultValue": "test"
},
"location": {
"defaultValue": "[resourceGroup().location]",
"type": "string"
},
"App_Plan_Name": {
"type": "string",
"defaultValue": "test1"
},
"Function_App_Name": {
"type": "string",
"defaultValue": "funapwp11"
},
"AI_Name": {
"type": "string",
"defaultValue": "appinsiwghts"
},
"Appsetting_For_Fun_App": {
"type": "object",
"defaultValue": {
"client_id": "",
"client_secret": "",
"subscription_id": "",
"tenant_id": "",
"FUNCTIONS_EXTENSION_VERSION": "~4",
"FUNCTIONS_WORKER_RUNTIME": "python"
}
}
},
"variables": {
"unique_Storage_Name": "[concat(parameters('storage_account_name'),uniqueString(resourceGroup().id))]",
//"Unique_App_Service_Name": "[concat(parameters('App_Service_Name'),uniqueString(resourceGroup().id))]",
"Unique_App_Plan_Name": "[concat(parameters('App_Plan_Name'),uniqueString(resourceGroup().id))]",
"Unique_Fun_App_Name": "[concat(parameters('Function_App_Name'),uniqueString(resourceGroup().id))]",
"Unique_AI_Name": "[concat(parameters('AI_Name'),uniqueString(resourceGroup().id))]"
},
"resources": [
{
"type": "Microsoft.Web/sites",
"apiVersion": "2022-03-01",
"location": "[parameters('location')]",
"name": "[variables('Unique_Fun_App_Name')]",
"kind": "functionapp",
"dependsOn": [
"[resourceId('Microsoft.Web/serverfarms', variables('Unique_App_Plan_Name'))]",
"[resourceId('Microsoft.Storage/storageAccounts',variables('unique_Storage_Name'))]",
"[resourceId('Microsoft.Insights/components',variables('Unique_AI_Name'))]"
],
"properties": {
"serverFarmId": "[resourceId('Microsoft.Web/serverfarms',variables('Unique_App_Plan_Name'))]",
"httpsOnly": true,
"enabled": true,
"adminEnabled": true,
"sku": "Basic",
"siteProperties": {
"properties": [
{
"name": "LinuxFxVersion",
"value": "Python|3.9"
},
{
"name": "WindowsFxVersion",
"value": null
}
]
},
"siteConfig": {
"linuxFxVersion": "Python|3.9",
"alwaysOn": true,
"pythonVersion": "3.9",
"appSettings": [
{
"name": "APPINSIGHTS_INSTRUMENTATIONKEY",
"value": "[reference(resourceId('Microsoft.Insights/components', variables('Unique_AI_Name'))).InstrumentationKey]"
},
{
"name": "APPLICATIONINSIGHTS_CONNECTION_STRING",
"value": "[reference(resourceId('Microsoft.Insights/components',variables('Unique_AI_Name')),'2020-02-02-preview').ConnectionString]"
},
{
"name": "AzureWebJobsStorage",
"value": "[format('DefaultEndpointsProtocol=https;AccountName={0};EndpointSuffix={1};AccountKey={2}', variables('Unique_Storage_Name'), environment().suffixes.storage, listKeys(resourceId('Microsoft.Storage/storageAccounts', variables('Unique_Storage_Name')), '2021-08-01').keys[0].value)]"
}
]
}
}
}
]
}
I want use Appsetting_For_Fun_App parameter inside the properties >> siteConfig >> appSettings.
Parameter:
"Appsetting_For_Fun_App": {
"type": "object",
"defaultValue": {
"client_id": "",
"client_secret": "",
"subscription_id": "",
"tenant_id": "",
"FUNCTIONS_EXTENSION_VERSION": "~4",
"FUNCTIONS_WORKER_RUNTIME": "python"
}
}
I need like that
"appSettings": [
{
"name": "[parameters('Appsetting_For_Fun_App')]",
"value": "[parameters('Appsetting_For_Fun_App')]"
},
I have tried multiple way but no luck.
You can refer the question: Azure resource manager template website app settings
Two options I can think of:
format the parameter as an object array - then no transform is needed in the template...
"parameters": {
"Appsetting_For_Fun_App": {
"type": "array",
"defaultValue": [
{
"name": "client_id",
"value": ""
},
{
"name": "client_secret",
"value": ""
},
{
"name": "subscription_Id",
"value": ""
}
]
}
And then on the web app:
"siteConfig": {
"linuxFxVersion": "Python|3.9",
"alwaysOn": true,
"pythonVersion": "3.9",
"appSettings": "[parameters('Appsettings_For_Fun_App')]"
but you can also do it via:
transform in the template, simplest to illustrate using a variable:
{
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"myValues": {
"type": "object",
"defaultValue": {
"setting1": "value1",
"setting2": "value2",
"setting3": "value3"
}
}
},
"variables": {
"copy": [
{
"name": "foo",
"count": "[length(items(parameters('myValues')))]",
"input": {
"name": "[items(parameters('myValues'))[copyIndex('foo')].key]",
"value": "[items(parameters('myValues'))[copyIndex('foo')].value]"
}
}
]
},
"resources": [],
"outputs": {
"bar": {
"type": "array",
"value": "[variables('foo')]"
}
}
}
I am defining my swagger file as below:
{
"swagger": "2.0",
"info": {
"title": "PSD2 Account API Specification",
"description": "PSD2 Account Swagger API Specification",
"version": "1.0.0"
},
"schemes": [
"https"
],
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"securityDefinitions": {
"basicAuth": {
"type": "basic"
}
},
"security": [
{
"basicAuth": []
}
],
"paths": {
"/accounts/{id}/transactionhistory": {
"get": {
"tags": [
"Accounts"
],
"summary": "Get transaction history",
"operationId": "GetTransactionHistory",
"produces": [
"application/json"
],
"parameters": [
{
"name": "id",
"in": "path",
"required": true,
"type": "string"
},
{
"name": "fromDate",
"in": "query",
"required": false,
"type": "string"
},
{
"name": "toDate",
"in": "query",
"required": false,
"type": "string",
"format": "date"
},
{
"name": "sumOrDetail",
"in": "query",
"required": false,
"type": "string"
},
{
"name": "noOfEntries",
"in": "query",
"required": false,
"type": "string"
},
{
"name": "toTime",
"in": "query",
"required": false,
"type": "string"
}
],
"responses": {
"200": {
"$ref": "#/definitions/200TransactionHistory"
}
}
}
}
},
"definitions": {
"200TransactionHistory": {
"type": "object",
"properties": {
"amount": {
"type": "string",
"maxLength": 25
},
"txnCodeDesc": {
"type": "string"
},
"accountDesc": {
"type": "string"
},
"txnCurrency": {
"type": "string",
"maxLength": 3
},
"accountIBAN": {
"type": "string"
},
"valueDate": {
"type": "string",
"format": "date"
},
"transactionCode": {
"type": "object",
"properties": {
"code": {
"type": "string",
"maxLength": 3
},
"subcode": {
"type": "string",
"maxLength": 3
}
}
},
"executionEndTime": {
"type": "string"
},
"stmtEntryId": {
"type": "string",
"maxLength": 90
},
"accountId": {
"type": "string"
},
"transReference": {
"type": "string",
"maxLength": 60
},
"exchangeRate": {
"type": "string",
"maxLength": 11
},
"remittanceInformation": {
"type": "string",
"maxLength": 65
},
"payeeCustomer": {
"type": "string"
},
"closeBalance": {
"type": "string"
},
"bookingDate": {
"type": "string",
"format": "date"
},
"currency": {
"type": "string",
"maxLength": 3
},
"id": {
"type": "string"
},
"txnCurrencyAmount": {
"type": "string",
"maxLength": 25
},
"payeeAccount": {
"type": "string"
},
"openBalance": {
"type": "string"
}
}
}
}
}
There is a simple GET request and I want in the response to have the following format:
"transactionCode": {
"code": "thisIsTheCode",
"SubsubCode": "thisIsTheSubCode"
}
As you can see in the response definition this is how I nest my objects:
"transactionCode": {
"type": "object",
"properties": {
"code": {
"type": "string",
"maxLength": 3
},
"subcode": {
"type": "string",
"maxLength": 3
}
}
}
When I am testing my request from Postman, I am getting the following error message:
com.fasterxml.jackson.core.JsonParseException: Unexpected character ('}' (code 125)): expected a valid value (number, String, array, object, 'true', 'false' or 'null')
at [Source: {"header":{"audit":{"T24_time":107,"parse_time":0},"page_start":0,"page_token":"5fc34084-2496-41f0-a968-084b3b519c88","total_size":0,"page_size":50},"body":}; line: 1, column: 158]
Can anyone tell what I am doing wrong? Is this something wrong in the way I am nesting the objects in the response?
I have an elastic search implementation with parent and child relationship.
The parent (products) type has two child types(productfeatures, supplierpna).
I have the search feature on my application which needs to return the parent document based on the productcode field in the "products" type.
What I need is to get all child documents attached to the parent as a sub nested list with a single filtered query.
e.g. productcode = "123456" will return 10 products but some products has the child object and some don't, but I want to get the parent document regardless the child document existence.
I tried has_child option but it do not return the parent document when there is no child objects
Here is my mapping, any help in this regard will be very helpful.
{ "itdealer": {
"aliases": {},
"mappings": {
"products": {
"properties": {
"categoryname": {
"type": "string",
"index_analyzer": "keylower",
"search_analyzer": "stem",
"fields": {
"categoryname_ags": {
"type": "string",
"index": "not_analyzed"
}
}
},
"highPic": {
"type": "string",
"index": "no",
"include_in_all": false
},
"id": {
"type": "string"
},
"longDescription": {
"type": "string"
},
"lowPic": {
"type": "string",
"index": "no",
"include_in_all": false
},
"manufacturername": {
"type": "string",
"index_analyzer": "keylower",
"search_analyzer": "stem",
"fields": {
"manufacturername_ags": {
"type": "string",
"index": "not_analyzed"
}
}
},
"modelName": {
"type": "string",
"index": "no",
"include_in_all": false
},
"productManualPdfUrl": {
"type": "string",
"index": "no",
"include_in_all": false
},
"productPdfUrl": {
"type": "string",
"index": "no",
"include_in_all": false
},
"productSpecifications": {
"type": "nested",
"include_in_parent": true,
"include_in_root": true,
"include_in_all": true,
"properties": {
"featureGroupName": {
"type": "string",
"index": "not_analyzed",
"index_analyzer": "keylower",
"include_in_all": true
},
"featureGroupName.featureName": {
"type": "string",
"index": "not_analyzed",
"index_analyzer": "keylower",
"include_in_all": true
},
"featureGroupName.featureValue": {
"type": "string",
"index": "not_analyzed",
"index_analyzer": "keylower",
"include_in_all": true
},
"productcode": {
"type": "string",
"index": "not_analyzed",
"index_analyzer": "special",
"include_in_all": true
}
}
},
"productcode": {
"type": "string",
"index": "not_analyzed",
"store": true,
"index_analyzer": "special"
},
"searchTerms": {
"type": "string",
"index_analyzer": "keylower",
"search_analyzer": "stem"
},
"shortDescription": {
"type": "string",
"store": true
},
"subCategoryname": {
"type": "string",
"index_analyzer": "keylower",
"search_analyzer": "stem",
"fields": {
"subCategoryname_ags": {
"type": "string",
"index": "not_analyzed"
}
}
},
"thumbPic": {
"type": "string",
"index": "no",
"include_in_all": false
},
"title": {
"type": "string",
"analyzer": "keylower",
"fields": {
"title_ac": {
"type": "string",
"index_analyzer": "pr_autocomplete",
"search_analyzer": "keylower"
},
"title_stem": {
"type": "string",
"index_analyzer": "stem",
"search_analyzer": "keylower"
}
}
},
"warrantyInfo": {
"type": "string",
"index": "no",
"include_in_all": false
}
}
},
"productfeatures": {
"_parent": {
"type": "products"
},
"_routing": {
"required": true
},
"properties": {
"featureGroupName": {
"type": "string",
"index": "not_analyzed",
"index_analyzer": "keylower"
},
"featureGroupName.featureName": {
"type": "string",
"index": "not_analyzed",
"index_analyzer": "keylower"
},
"featureGroupName.featureValue": {
"type": "string",
"index": "not_analyzed",
"index_analyzer": "keylower"
},
"features": {
"properties": {
"featureName": {
"type": "string"
},
"featureValue": {
"type": "string"
}
}
},
"productcode": {
"type": "string",
"index": "not_analyzed",
"index_analyzer": "special"
}
}
},
"supplierpna": {
"_parent": {
"type": "products"
},
"_routing": {
"required": true
},
"properties": {
"freeStock": {
"type": "string",
"index": "no",
"include_in_all": false
},
"manufacturer": {
"type": "string",
"index": "no",
"include_in_all": false
},
"partNumber": {
"type": "string",
"index": "not_analyzed",
"store": true,
"index_analyzer": "special"
},
"productcode": {
"type": "string",
"index": "not_analyzed",
"store": true
},
"rRP": {
"type": "double",
"store": true
},
"supplier": {
"type": "string",
"index": "not_analyzed",
"include_in_all": false
},
"supplierId": {
"type": "double",
"index": "no"
},
"supplierLogo": {
"type": "string",
"index": "no",
"include_in_all": false
},
"supplierName": {
"type": "string",
"index": "not_analyzed",
"index_analyzer": "keylower"
},
"supplierProductDescription": {
"type": "string",
"index": "no",
"include_in_all": false
},
"supplierURL": {
"type": "string",
"index": "no",
"include_in_all": false
},
"updatedDate": {
"type": "date",
"index": "no",
"format": "dateOptionalTime",
"include_in_all": false
}
}
}
},
"settings": {
"index": {
"mapping": {
"allow_type_wrapper": "true"
},
"search": {
"slowlog": {
"threshold": {
"fetch": {
"warn": "1s"
}
}
}
},
"number_of_shards": "5",
"merge": {
"policy": {
"merge_factor": "10"
}
},
"creation_date": "1432827491555",
"analysis": {
"filter": {
"special": {
"split_on_numerics": "false",
"generate_word_parts": "false",
"preserve_original": "true",
"generate_number_parts": "false",
"split_on_case_change": "false",
"type_table": [
"# => ALPHA",
"- => ALPHA",
"$ => ALPHA",
"% => ALPHA"
],
"type": "word_delimiter"
},
"stemming": {
"type": "stemmer",
"language": "light_english"
},
"autocomplete": {
"min_gram": "1",
"type": "edge_ngram",
"stopwords": "_english_",
"max_gram": "20"
}
},
"analyzer": {
"special": {
"filter": [
"lowercase",
"special"
],
"type": "custom",
"tokenizer": "keyword"
},
"keylower": {
"filter": "lowercase",
"tokenizer": "standard"
},
"pr_autocomplete": {
"type": "custom",
"filter": [
"lowercase",
"autocomplete"
],
"tokenizer": "standard"
},
"stem": {
"filter": [
"lowercase",
"stemming"
],
"type": "custom",
"tokenizer": "standard"
}
}
},
"number_of_replicas": "1",
"version": {
"created": "1050299"
},
"uuid": "D1spSYWURBWIfXYRcsY6cg"
}
},
"warmers": {}}}
My current normal search query data
{
"query": {
"filtered": {
"query": {
"multi_match": {
"fields": [
"searchTerms",
"manufacturername^7",
"subCategoryname^4",
"title_ac^10",
"categoryname",
"shortDescription",
"productcode"
],
"query": "hp desktop",
"type": "cross_fields",
"operator": "or",
"tie_breaker": 0.3
}
}
}
},
"size": "10",
"from": "0",
"aggs": {
"manufacture": {
"terms": {
"field": "manufacturername_ags",
"size": 0,
"order": {
"_count": "desc"
}
}
},
"category": {
"terms": {
"field": "categoryname_ags",
"size": 0,
"order": {
"_count": "desc"
}
}
},
"subcategory": {
"terms": {
"field": "subCategoryname_ags",
"size": 0,
"order": {
"_count": "desc"
}
}
}
}
}
Right now this query only returns the parent document I want this query to be modified so that I will include the child objects both (productfeatures and supplierpna) in each parent document.
I'm just starting with Swagger UI and I'm trying to understand how it works.
So far I've entered some JSON (manually) and this is the result:
{
"swagger": "2.0",
"info": {
"version": "1.0.0",
"title": "PhakeApps API",
"contact": {
"name": "PhakeApps API team",
"url": "http://phakeapps.com/"
},
"license": {
"name": "Creative Commons 4.0 International",
"url": "http://creativecommons.org/licenses/by/4.0/"
}
},
"host": "api.phakeapps.com",
"basePath": "/v1",
"schemes": [
"http"
],
"produces": [
"application/json"
],
"consumes": [
"application/json"
],
"paths": {
"/places/search": {
"post": {
"tags": [
"Places"
],
"description": "Search for (a) place(s) <br /><br /> <b>id</b> - The ID of the request. <br /> <b>api_key</b> - API Key for the platform the request is sent. <i>Currently, not required.</i> <br /> <b>Params</b> - Required. <i>See model & model schema.</i>",
"operationId": "PlacesSearch",
"produces": [
"application/json"
],
"consumes": [
"application/json"
],
"parameters": [
{
"name": "request",
"in": "body",
"paramType": "body",
"description": "Object containing the <u>id</u>, <u>api_key</u> and certain <u>params</u>.",
"required": true,
"schema": {
"$ref": "#/definitions/Search"
}
}
],
"responses": {
"200": {
"description": "Success",
"schema": {
"$ref": "#/definitions/PlacesResult"
}
},
"403": {
"description": "Validation error or Server Failure",
"schema": {
"$ref": "#/definitions/Error"
}
}
}
}
}
},
"definitions": {
"PlacesResult": {
"required": [
"data",
"id",
"code"
],
"properties": {
"data": {
"$ref": "#/definitions/Places"
},
"id": {
"type": "integer",
"format": "int32"
},
"code": {
"type": "integer",
"format": "int32"
}
}
},
"Places": {
"required": [
"places"
],
"properties": {
"places": {
"$ref": "#/definitions/Place"
}
}
},
"City": {
"required": [
"id",
"name"
],
"properties": {
"id": {
"type": "string"
},
"name": {
"type": "string"
}
}
},
"Neighbourhood": {
"required": [
"id",
"name"
],
"properties": {
"id": {
"type": "string"
},
"name": {
"type": "string"
}
}
},
"Cuisine": {
"required": [
"id",
"name"
],
"properties": {
"id": {
"type": "string"
},
"name": {
"type": "string"
}
}
},
"Place": {
"required": [
"id",
"name",
"city",
"neighbourhood",
"address",
"cuisine",
"price",
"photos_cnt",
"lat",
"lng",
"is_fav"
],
"properties": {
"id": {
"type": "string"
},
"name": {
"type": "string"
},
"city": {
"type": "array",
"items": {
"$ref": "#/definitions/City"
}
},
"neighbourhood": {
"type": "array",
"items": {
"$ref": "#/definitions/Neighbourhood"
}
},
"address": {
"type": "string"
},
"cuisine": {
"type": "array",
"items": {
"$ref": "#/definitions/Cuisine"
}
},
"price": {
"type": "integer",
"format": "int32"
},
"photos_cnt": {
"type": "integer",
"format": "int32"
},
"lat": {
"type": "double"
},
"lng": {
"type": "double"
},
"is_fav": {
"type": "boolean"
}
}
},
"Search": {
"required": [
"id",
"api_key",
"params"
],
"properties": {
"id": {
"type": "integer",
"format": "int64"
},
"api_key": {
"type": "string"
},
"params": {
"$ref": "#/definitions/SearchParams"
}
}
},
"SearchParams": {
"required": [
"user_id",
"city_id",
"people",
"dt",
"locale"
],
"properties": {
"user_id": {
"type": "string",
"default": "956dda4c21c72e48f5f17a7cd783a0f7"
},
"city_id": {
"type": "string",
"default": "4ec4b3e6098c9d23c925b0c2451eb06a"
},
"people": {
"type": "integer",
"format": "int32",
"minimum": 1,
"default": 2
},
"dt": {
"type": "integer",
"format": "int32",
"default": "1427742000"
},
"locale": {
"type": "string",
"default": "bg"
},
"place_id": {
"type": "string",
"default": "0"
},
"neighborhood_id": {
"type": "string",
"default": "0"
},
"cuisine_id": {
"type": "string",
"default": "0"
},
"kids_place": {
"type": "boolean",
"default": false
},
"price": {
"type": "integer",
"format": "int64",
"default": 1
},
"outdoors": {
"type": "boolean",
"default": false
}
}
},
"Error": {
"required": [
"code",
"data"
],
"properties": {
"code": {
"type": "integer",
"format": "int32"
},
"data": {
"type": "array",
"items": {
"type": "array"
}
}
}
}
}
}
However, swagger's validator says it's not valid. The error I get is this
[
{
"level": "error",
"domain": "validation",
"keyword": "anyOf",
"message": "instance failed to match at least one required schema among 2",
"schema": {
"loadingURI": "http://json-schema.org/draft-04/schema#",
"pointer": "/properties/type"
},
"instance": {
"pointer": "/definitions/Place/properties/lat/type"
}
}
]
Note that it works as expected (so far). It displays the data (models and models' structure) properly. Make requests and retrieves responses. Yet the validator says it's not valid. (The yellow badge saying 'Invalid', not the red one that says 'Error').
What am I missing?
Your spec is indeed not valid. In your Place definition, you use "type": "double" to describe the type of the lat (and also lng) property, but such a type does not exist.
If you want to describe a numeric value of 'double' size, you should change the definition as follows:
"lng": {
"type": "number",
"format": "double"
}
Do that everywhere you use the double type, and it should resolve that issue.
I'm using the following json to configure elasticsearch. The goal is to set up the index and the type in one swoop (this is the requirement, setting up docker images). This is as far as I've gotten that will allow elasticsearch to start successfully. The problem is that the index isn't created yet it doesn't error. Other forms I've tried prevents the service from starting.
{
"cluster": {
"name": "MyClusterName"
},
"node": {
"name": "MyNodeName"
},
"indices": {
"number_of_shards": 4,
"index.number_of_replicas": 4
},
"index": {
"analysis": {
"analyzer": {
"my_ngram_analyzer": {
"tokenizer": "my_ngram_tokenizer",
"filter": "lowercase"
},
"my_lowercase_whitespace_analyzer": {
"tokenizer": "whitespace",
"filter": "lowercase"
}
},
"tokenizer": {
"my_ngram_tokenizer": {
"type": "nGram",
"min_gram": "2",
"max_gram": "20"
}
}
},
"index": {
"settings": {
"_id": "indexindexer"
},
"mappings": {
"inventoryIndex": {
"_id": {
"path": "indexName"
},
"_routing": {
"required": true,
"path": "indexName"
},
"properties": {
"indexName": {
"type": "string",
"index": "not_analyzed"
},
"startedOn": {
"type": "date",
"index": "not_analyzed"
},
"deleted": {
"type": "boolean",
"index": "not_analyzed"
},
"deletedOn": {
"type": "date",
"index": "not_analyzed"
},
"archived": {
"type": "boolean",
"index": "not_analyzed"
},
"archivedOn": {
"type": "date",
"index": "not_analyzed"
},
"failure": {
"type": "boolean",
"index": "not_analyzed"
},
"failureOn": {
"type": "date",
"index": "not_analyzed"
}
}
}
}
}
}
}
I may have a workaround using curl in a post-boot script but I would prefer to have the configuration handled in the config file.
Thanks!
It appears that elasticsearch will not allow all the configuration to be done in a single yml. The workaround I've found is to create an index template and place it in the <es-config>/templates/ dir then after spinning up the service I use curl to create the index. The index matching will catch it and provision it according to the template.
http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/indices-templates.html