Azure / Azure/data-api-builder
[Bug]: An item with the same key has already been added. Cosmos DB using two config files
- Dominant language
- C#
- Stars
- 1.5k
- Forks
- 370
- Avg merge
- 3d 17h
- Merged PRs (30d)
- 8
Description
### What happened?
**Background:**
To make management of configuration files and schemas simpler, and unit testable we want to utilize the [multiple data sources](https://github.com/Azure/data-api-builder/issues/1638) feature.
**Problem:**
An item with the same key has already been added. Key: EPCTransactionOrderByInput
**Notes:**
- All config files use the same connection string: `"connection-string":`
**Configurations:**
dab-config.json
```json
{
"$schema": "https://github.com/Azure/data-api-builder/releases/download/v1.2.11/dab.draft.schema.json",
"data-source": {
"database-type": "cosmosdb_nosql",
"connection-string": "AccountEndpoint=https://localhost:8081/;AccountKey=C2y6yDjf5/R+ob0N8A7Cgv30VRDJIWEHLM+4QDU5DE2nQ9nDuVTqobD4b8mGGyPMbIZnqyMsEcaGQy67XIw/Jw==",
"options": {
"database": "ratingreferencedata",
"container": "epc_version",
"schema": "epc_schema.gql"
}
},
"data-source-files": ["dab-config-pp.json"],
"runtime": {
"rest": {
"enabled": false,
"path": "/api",
"request-body-strict": true
},
"graphql": {
"enabled": true,
"path": "/graphql",
"allow-introspection": true
},
"host": {
"cors": {
"origins": [],
"allow-credentials": false
},
"authentication": {
"provider": "StaticWebApps"
},
"mode": "development"
}
},
"entities": {
"EPC": {
"source": {
"object": "epc_version",
"type": "table"
},
"graphql": {
"enabled": true,
"type": {
"singular": "EPC",
"plural": "EPCs"
}
},
"rest": {
"enabled": false
},
"permissions": [
{
"role": "anonymous",
"actions": [
{
"action": "read"
}
]
}
],
"mappings": {
"id": "id",
"version": "version"
}
},
"EPCHistory": {
"source": {
"object": "epc_version",
"type": "table"
},
"graphql": {
"enabled": true,
"type": {
"singular": "EPCHistory",
"plural": "EPCHistorys"
}
},
"rest": {
"enabled": false
},
"permissions": [
{
"role": "anonymous",
"actions": [
{
"action": "read"
}
]
}
],
"mappings": {
"id": "id",
"version": "version"
}
},
"EPCTransaction": {
"source": {
"object": "epc_version",
"type": "table"
},
"graphql": {
"enabled": true,
"type": {
"singular": "EPCTransaction",
"plural": "EPCTransactions"
}
},
"rest": {
"enabled": false
},
"permissions": [
{
"role": "anonymous",
"actions": [
{
"action": "read"
}
]
}
],
"mappings": {
"id": "id",
"version": "version"
}
}
}
}
```
dab-config-pp.json
```json
{
"$schema": "https://github.com/Azure/data-api-builder/releases/download/v1.2.11/dab.draft.schema.json",
"data-source": {
"database-type": "cosmosdb_nosql",
"connection-string": "AccountEndpoint=https://localhost:8081/;AccountKey=C2y6yDjf5/R+ob0N8A7Cgv30VRDJIWEHLM+4QDU5DE2nQ9nDuVTqobD4b8mGGyPMbIZnqyMsEcaGQy67XIw/Jw==",
"options": {
"database": "ratingreferencedata",
"container": "pp_version",
"schema": "pp_schema.gql"
}
},
"runtime": {
"rest": {
"enabled": false,
"path": "/api",
"request-body-strict": true
},
"graphql": {
"enabled": true,
"path": "/graphql",
"allow-introspection": true
},
"host": {
"cors": {
"origins": [],
"allow-credentials": false
},
"authentication": {
"provider": "StaticWebApps"
},
"mode": "development"
}
},
"entities": {
"price_paid": {
"source": {
"object": "pp_version",
"type": "table"
},
"graphql": {
"enabled": true,
"type": {
"singular": "price_paid",
"plural": "price_paids"
}
},
"rest": {
"enabled": false
},
"permissions": [
{
"role": "anonymous",
"actions": [
{
"action": "read"
}
]
}
],
"mappings": {
"id": "id",
"version": "version"
}
},
"PPHistory": {
"source": {
"object": "pp_version",
"type": "table"
},
"graphql": {
"enabled": true,
"type": {
"singular": "PPHistory",
"plural": "PPHistorys"
}
},
"rest": {
"enabled": false
},
"permissions": [
{
"role": "anonymous",
"actions": [
{
"action": "read"
}
]
}
],
"mappings": {
"id": "id",
"version": "version"
}
},
"PPTransaction": {
"source": {
"object": "pp_version",
"type": "table"
},
"graphql": {
"enabled": true,
"type": {
"singular": "PPTransaction",
"plural": "PPTransactions"
}
},
"rest": {
"enabled": false
},
"permissions": [
{
"role": "anonymous",
"actions": [
{
"action": "read"
}
]
}
],
"mappings": {
"id": "id",
"version": "version"
}
}
}
}
```
**Schemas:**
epc_schema.gql
```
type EPCTransaction {
Inspection_Date: String
Lodgement_Date: String
Energy_Efficiency_Current: Int
Energy_Rating_Current: String
Transaction_Type: String
Tenure: String
Floor_Area_Msq2: Float
Habitable_Rooms: Int
Extensions: Int
}
type EPCHistory {
transaction: [EPCTransaction]
}
type EPC @model{
id: String
uprn: String
EPC_version: String
CO2_Current_by_Area: String
Glazed_When: String
Lighting_Cost_Potential: String
Roof_Construct: String
Multi_Glaze: Int
Lighting_Cost_Current: String
Address1: String
Energy_Consumption_Potential: String
Property_Type: String
Postcode: String
Energy_Efficiency_Current: Int
Heating_Cost_Current: String
Inspection_Date: String
Energy_Rating_Current: String
Floor_Area_Msq2: Int
Mechanical_Vent_Flag: String
Hot_Water_Cost_Current: String
Habitable_Rooms: Int
Wind_Turbine_Count: String
Heating_Type: String
Lodgement_Date: String
Loft_Insulation: String
Hot_Water_Cost_Potential: String
Year_Built: String
Glazed_Area: String
Floor_if_flat: String
Energy_Consumption_Current: String
Underfloor_Heating: String
Heated_Rooms: Int
Open_Fires: Int
Roof_Slope: String
Hotwater: String
CO2_Current: String
Extensions: Int
Energy_Rating_Potential: String
Tenure: String
Wall_Construct: String
Energy_Tariff: String
Transaction_Type: String
House_Type: String
Oil: String
Wall_Desc: String
Identifier: String
Floor_Description: String
Solar: String
Energy_Efficiency_Potential: Int
Window_Glazing: String
Mains_Gas_Flag: String
Heating_Cost_Potential: String
version: String
History: EPCHistory
}
```
pp_schema.gql
```
type PPTransaction {
Date_Of_Transfer: String
Price: Int
}
type PPHistory {
transaction: [PPTransaction]
}
type price_paid @model {
uprn: Int
price: Int
Date_Of_Transfer: String
paon: String
saon: String
parent_uprn: String
Postcode: String
towncity: String
level: String
classification_code: String
waterfall_used: String
method_name: String
Identifier: String
Date_Built: String
PPD_Category_Type: String
price_paid_version: String
version: String
Property_Type: String
House_Type: String
New_Build_at_transaction: String
Tenure: String
abp_epoch: String
id: String
History: PPHistory
}
```
### Version
1.2.11+c7ca8db8558a63919c530e454c8f18b45d5b931c
### What database are you using?
CosmosDB NoSQL
### What hosting model are you using?
Local (including CLI)
### Which API approach are you accessing DAB through?
GraphQL
### Relevant log output
dab start
Information: Microsoft.DataApiBuilder 1.2.11
Information: Config not provided. Trying to get default config based on DAB_ENVIRONMENT...
Information: Environment variable DAB_ENVIRONMENT is (null)
Loading config file from dab-config.json.
Loading config file from dab-config-pp.json.
Information: Loaded config file: dab-config.json
Information: Setting default minimum LogLevel: Debug for Development mode.
Starting the runtime engine...
Loading config file from dab-config.json.
Loading config file from dab-config-pp.json.
info: Microsoft.AspNetCore.DataProtection.KeyManagement.XmlKeyManager[63]
User profile is available. Using 'C:\Users\EdMuzio\AppData\Local\ASP.NET\DataProtection-Keys' as key repository and Windows DPAPI to encrypt keys at rest.
info: Azure.DataApiBuilder.Service.Startup[0]
Successfully completed runtime initialization.
info: Microsoft.Hosting.Lifetime[14]
Now listening on: http://localhost:5000
info: Microsoft.Hosting.Lifetime[0]
Application started. Press Ctrl+C to shut down.
info: Microsoft.Hosting.Lifetime[0]
Hosting environment: Production
info: Microsoft.Hosting.Lifetime[0]
Content root path: C:\source\repos\Data-API-builder-for-Azure-Databases
info: Microsoft.AspNetCore.Hosting.Diagnostics[1]
Request starting HTTP/1.1 POST http://localhost:5000/graphql/ - application/json 3190
warn: Microsoft.AspNetCore.HttpsPolicy.HttpsRedirectionMiddleware[3]
Failed to determine the https port for redirect.
dbug: Azure.DataApiBuilder.Core.AuthenticationHelpers.ClientRoleHeaderAuthenticationMiddleware[0]
bebdd742-bfe9-4084-b31c-f97436b78b93 Request authentication state: Anonymous.
dbug: Azure.DataApiBuilder.Core.AuthenticationHelpers.ClientRoleHeaderAuthenticationMiddleware[0]
bebdd742-bfe9-4084-b31c-f97436b78b93 The request will be executed in the context of the role: Anonymous
info: Microsoft.AspNetCore.Routing.EndpointMiddleware[0]
Executing endpoint 'Hot Chocolate GraphQL Pipeline'
info: Microsoft.AspNetCore.Routing.EndpointMiddleware[1]
Executed endpoint 'Hot Chocolate GraphQL Pipeline'
fail: Microsoft.AspNetCore.Server.Kestrel[13]
Connection id "0HN7K8DLP1DHK", Request id "0HN7K8DLP1DHK:00000001": An unhandled exception was thrown by the application.
System.ArgumentException: An item with the same key has already been added. Key: EPCTransactionOrderByInput
at System.Collections.Generic.Dictionary`2.TryInsert(TKey key, TValue value, InsertionBehavior behavior)
at System.Collections.Generic.Dictionary`2.Add(TKey key, TValue value)
at Azure.DataApiBuilder.Service.GraphQLBuilder.Queries.InputTypeBuilder.GenerateInputTypeFromInputFields(IDictionary`2 inputTypes, List`1 inputFields, String inputTypeName, String inputTypeDescription) in /_/src/Service.GraphQLBuilder/Queries/InputTypeBuilder.cs:line 100
at Azure.DataApiBuilder.Service.GraphQLBuilder.Queries.InputTypeBuilder.GenerateOrderByInputTypeForObjectType(ObjectTypeDefinitionNode node, IDictionary`2 inputTypes) in /_/src/Service.GraphQLBuilder/Queries/InputTypeBuilder.cs:line 36
at Azure.DataApiBuilder.Service.GraphQLBuilder.Queries.InputTypeBuilder.GenerateInputTypesForObjectType(ObjectTypeDefinitionNode node, IDictionary`2 inputTypes) in /_/src/Service.GraphQLBuilder/Queries/InputTypeBuilder.cs:line 16
at Azure.DataApiBuilder.Core.Services.GraphQLSchemaCreator.GenerateCosmosGraphQLObjects(HashSet`1 dataSourceNames, Dictionary`2 inputObjects) in /_/src/Core/Services/GraphQLSchemaCreator.cs:line 560
at Azure.DataApiBuilder.Core.Services.GraphQLSchemaCreator.GenerateGraphQLObjects() in /_/src/Core/Services/GraphQLSchemaCreator.cs:line 609
at Azure.DataApiBuilder.Core.Services.GraphQLSchemaCreator.InitializeSchemaAndResolvers(ISchemaBuilder schemaBuilder) in /_/src/Core/Services/GraphQLSchemaCreator.cs:line 155
at Azure.DataApiBuilder.Service.Startup.<>c.b__14_0(IServiceProvider serviceProvider, ISchemaBuilder schemaBuilder) in /_/src/Service/Startup.cs:line 224
at HotChocolate.Execution.RequestExecutorResolver.CreateSchemaAsync(NameString schemaName, RequestExecutorSetup options, RequestExecutorOptions executorOptions, IServiceProvider serviceProvider, TypeModuleChangeMonitor typeModuleChangeMonitor, CancellationToken cancellationToken)
at HotChocolate.Execution.RequestExecutorResolver.CreateSchemaServicesAsync(NameString schemaName, RequestExecutorSetup options, CancellationToken cancellationToken)
at HotChocolate.Execution.RequestExecutorResolver.GetRequestExecutorNoLockAsync(NameString schemaName, CancellationToken cancellationToken)
at HotChocolate.Execution.RequestExecutorResolver.GetRequestExecutorAsync(NameString schemaName, CancellationToken cancellationToken)
at HotChocolate.Execution.RequestExecutorProxy.GetRequestExecutorAsync(CancellationToken cancellationToken)
at HotChocolate.AspNetCore.HttpPostMiddlewareBase.HandleRequestAsync(HttpContext context, AllowedContentType contentType)
at HotChocolate.AspNetCore.HttpPostMiddlewareBase.InvokeAsync(HttpContext context)
at Microsoft.AspNetCore.Builder.EndpointRouteBuilderExtensions.<>c__DisplayClass12_0.<b__1>d.MoveNext()
--- End of stack trace from previous location ---
at Microsoft.AspNetCore.Routing.EndpointMiddleware.g__AwaitRequestTask|7_0(Endpoint endpoint, Task requestTask, ILogger logger)
at Azure.DataApiBuilder.Core.Authorization.ClientRoleHeaderAuthorizationMiddleware.Invoke(HttpContext httpContext) in /_/src/Core/Authorization/ClientRoleHeaderAuthorizationMiddleware.cs:line 35
at Microsoft.AspNetCore.Authorization.AuthorizationMiddleware.Invoke(HttpContext context)
at Azure.DataApiBuilder.Core.AuthenticationHelpers.ClientRoleHeaderAuthenticationMiddleware.InvokeAsync(HttpContext httpContext) in /_/src/Core/AuthenticationHelpers/ClientRoleHeaderAuthenticationMiddleware.cs:line 139
at Microsoft.AspNetCore.Authentication.AuthenticationMiddleware.Invoke(HttpContext context)
at Azure.DataApiBuilder.Service.Startup.<>c__DisplayClass15_0.<b__3>d.MoveNext() in /_/src/Service/Startup.cs:line 356
--- End of stack trace from previous location ---
at Swashbuckle.AspNetCore.SwaggerUI.SwaggerUIMiddleware.Invoke(HttpContext httpContext)
at Azure.DataApiBuilder.Core.Services.PathRewriteMiddleware.InvokeAsync(HttpContext httpContext) in /_/src/Core/Services/PathRewriteMiddleware.cs:line 89
at Azure.DataApiBuilder.Core.Services.CorrelationIdMiddleware.Invoke(HttpContext httpContext) in /_/src/Core/Services/CorrelationIdMiddleware.cs:line 53
at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.HttpProtocol.ProcessRequests[TContext](IHttpApplication`1 application)
info: Microsoft.AspNetCore.Hosting.Diagnostics[2]
Request finished HTTP/1.1 POST http://localhost:5000/graphql/ - 500 0 - 138.0837ms
### Code of Conduct
- [x] I agree to follow this project's Code of Conduct
Contributor guide
Assessment
This issue has not been assessed yet.