Skip to content

Commit

Permalink
Merge pull request #2737 from hashicorp/data-api/support-common-types
Browse files Browse the repository at this point in the history
data-api: support for common types (models and constants)
  • Loading branch information
manicminer authored Jul 11, 2023
2 parents 1943da5 + d0691ee commit c303507
Show file tree
Hide file tree
Showing 18 changed files with 357 additions and 46 deletions.
1 change: 1 addition & 0 deletions data/Pandora.Api/Startup.cs
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ public Startup(IConfiguration configuration)
public void ConfigureServices(IServiceCollection services)
{
services.AddSingleton<IServiceReferencesRepository>(new ServiceReferencesRepository(SupportedServices.Get()));
services.AddSingleton<ICommonTypesRepository>(new CommonTypesRepository(SupportedCommonTypes.Get()));
services.AddControllers();
}

Expand Down
136 changes: 136 additions & 0 deletions data/Pandora.Api/V1/Controllers/CommonTypes.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,136 @@
using System.Collections.Generic;
using System.Linq;
using System.Text.Json.Serialization;
using Microsoft.AspNetCore.Mvc;
using Pandora.Api.V1.Helpers;
using Pandora.Data.Models;
using Pandora.Data.Repositories;

namespace Pandora.Api.V1.Controllers;

public class CommonTypesController : ControllerBase
{
private readonly ICommonTypesRepository _repo;

public CommonTypesController(ICommonTypesRepository repo)
{
_repo = repo;
}

[Route("/v1/microsoft-graph/{apiVersion}/commonTypes")]
public IActionResult MicrosoftGraph(string apiVersion)
{
var definitionType = apiVersion.ParseServiceDefinitionTypeFromApiVersion();
if (definitionType == null)
{
return BadRequest($"the API Version {apiVersion} is not supported");
}

return CommonTypes(definitionType.Value);
}

[Route("/v1/resource-manager/commonTypes")]
public IActionResult ResourceManager(string apiVersion)
{
return CommonTypes(ServiceDefinitionType.ResourceManager);
}

private IActionResult CommonTypes(ServiceDefinitionType serviceDefinitionType)
{
var commonTypes = _repo.Get(serviceDefinitionType);
return new JsonResult(MapResponse(commonTypes));
}

private class CommonTypesResponse
{
[JsonPropertyName("constants")]
public Dictionary<string, ConstantApiDefinition> Constants { get; set; }

[JsonPropertyName("models")]
public Dictionary<string, ModelApiDefinition> Models { get; set; }
}

private static CommonTypesResponse MapResponse(IEnumerable<CommonTypesDefinition> resource)
{
var constants = resource.SelectMany(c => c.Constants);
var models = resource.SelectMany(c => c.Models);

return new CommonTypesResponse
{
Constants = constants.ToDictionary(c => c.Name, ConstantApiDefinition.Map),
Models = models.ToDictionary(m => m.Name, MapModel),
};
}

private class ModelApiDefinition
{
[JsonPropertyName("fields")]
public Dictionary<string, PropertyApiDefinition> Fields { get; set; }

[JsonPropertyName("parentTypeName")]
public string? ParentTypeName { get; set; }

[JsonPropertyName("typeHintIn")]
public string? TypeHintIn { get; set; }

[JsonPropertyName("typeHintValue")]
public string? TypeHintValue { get; set; }
}

private static ModelApiDefinition MapModel(ModelDefinition model)
{
return new ModelApiDefinition
{
Fields = model.Properties.ToDictionary(p => p.Name, MapProperty),
ParentTypeName = model.ParentTypeName,
TypeHintIn = model.TypeHintIn,
TypeHintValue = model.TypeHintValue,
};
}

private class PropertyApiDefinition
{
[JsonPropertyName("dateFormat")]
public string? DateFormat { get; set; }

[JsonPropertyName("default")]
public object? Default { get; set; }

[JsonPropertyName("forceNew")]
public bool ForceNew { get; set; }

[JsonPropertyName("isTypeHint")]
public bool IsTypeHint { get; set; }

[JsonPropertyName("jsonName")]
public string JsonName { get; set; }

[JsonPropertyName("objectDefinition")]
public ApiObjectDefinition ObjectDefinition { get; set; }

[JsonPropertyName("optional")]
public bool Optional { get; set; }

[JsonPropertyName("required")]
public bool Required { get; set; }

[JsonPropertyName("validation")]
public ValidationApiDefinition? Validation { get; set; }
}

private static PropertyApiDefinition MapProperty(PropertyDefinition definition)
{
return new PropertyApiDefinition
{
DateFormat = definition.DateFormat,
Default = definition.Default,
ForceNew = definition.ForceNew,
JsonName = definition.JsonName,
IsTypeHint = definition.IsTypeHint,
ObjectDefinition = ApiObjectDefinitionMapper.Map(definition.ObjectDefinition),
Optional = definition.Optional,
Required = definition.Required,
Validation = ValidationApiDefinition.Map(definition.Validation),
};
}
}
2 changes: 1 addition & 1 deletion data/Pandora.Api/V1/Controllers/ServiceDetails.cs
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ private static ServiceDetailsResponse MapResponse(ServiceDefinition version, str
{
ResourceProvider = version.ResourceProvider!,
TerraformPackageName = version.TerraformPackageName,
TerraformUri = $"/v1/resource-manager/services/{serviceName}/terraform",
TerraformUri = $"{routePrefix}/services/{serviceName}/terraform",
Versions = version.Versions.ToDictionary(v => v.Version, v => MapVersion(v, serviceName, routePrefix))
};
}
Expand Down
10 changes: 6 additions & 4 deletions data/Pandora.Api/V1/Controllers/ServiceVersion.cs
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ public IActionResult MicrosoftGraph(string apiVersion, string serviceName, strin
return BadRequest($"the API Version {apiVersion} is not supported");
}

return ForService(serviceName, serviceApiVersion, definitionType.Value, "/v1/microsoft-graph/{apiVersion}");
return ForService(serviceName, serviceApiVersion, definitionType.Value, $"/v1/microsoft-graph/{apiVersion}");
}

[Route("/v1/resource-manager/services/{serviceName}/{serviceApiVersion}")]
Expand Down Expand Up @@ -69,11 +69,12 @@ private static string MapSource(Data.Models.ApiDefinitionsSource input)
{
switch (input)
{
// TODO: support a Graph source
case Data.Models.ApiDefinitionsSource.HandWritten:
return ApiDefinitionsSource.HandWritten.ToString();
case Data.Models.ApiDefinitionsSource.ResourceManagerRestApiSpecs:
return ApiDefinitionsSource.ResourceManagerRestApiSpecs.ToString();
case Data.Models.ApiDefinitionsSource.MicrosoftGraphMetadata:
return ApiDefinitionsSource.MicrosoftGraphMetadata.ToString();
}

throw new NotSupportedException($"unsupported/unmapped Source {input.ToString()}");
Expand Down Expand Up @@ -115,8 +116,9 @@ public enum ApiDefinitionsSource
ResourceManagerRestApiSpecs,

[Description("HandWritten")]
HandWritten
HandWritten,

// TODO: support for Graph
[Description("MicrosoftGraphMetadata")]
MicrosoftGraphMetadata,
}
}
23 changes: 23 additions & 0 deletions data/Pandora.Data/CommonTypeDefinitions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
using System.Collections.Generic;
using System.Linq;
using Pandora.Data.Models;
using Pandora.Definitions.Interfaces;
using CommonTypesDefinition = Pandora.Definitions.Interfaces.CommonTypesDefinition;

namespace Pandora.Data;

public static class SupportedCommonTypes
{
public static Dictionary<ServiceDefinitionType, IEnumerable<CommonTypesDefinition>> Get()
{
var data = DefinitionTypes.Get();
var output = new Dictionary<ServiceDefinitionType, IEnumerable<CommonTypesDefinition>>();
foreach (var item in data)
{
var commonTypes = item.Value.Select(Definitions.Discovery.CommonTypesDefinition.ForServiceDefinition);
output.Add(item.Key, commonTypes);
}

return output;
}
}
50 changes: 50 additions & 0 deletions data/Pandora.Data/DefinitionTypes.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
using System.Collections.Generic;
using Pandora.Data.Models;
using Pandora.Definitions.DataPlane;
using Pandora.Definitions.HandDefined;
using Pandora.Definitions.Interfaces;
using Pandora.Definitions.MicrosoftGraph.Beta;
using Pandora.Definitions.MicrosoftGraph.StableV1;
using Pandora.Definitions.ResourceManager;
using ServiceDefinition = Pandora.Definitions.Interfaces.ServiceDefinition;

namespace Pandora.Data;

public static class DefinitionTypes
{
public static Dictionary<ServiceDefinitionType, List<ServicesDefinition>> Get()
{
return new Dictionary<ServiceDefinitionType, List<ServicesDefinition>>
{
{
ServiceDefinitionType.DataPlane,
new List<ServicesDefinition>
{
new DataPlaneServices(),
}
},
{
ServiceDefinitionType.MicrosoftGraphBeta,
new List<ServicesDefinition>
{
new MicrosoftGraphBetaServices(),
}
},
{
ServiceDefinitionType.MicrosoftGraphStableV1,
new List<ServicesDefinition>
{
new MicrosoftGraphStableV1Services(),
}
},
{
ServiceDefinitionType.ResourceManager,
new List<ServicesDefinition>
{
new HandDefinedServices(),
new ResourceManagerServices(),
}
},
};
}
}
5 changes: 4 additions & 1 deletion data/Pandora.Data/Models/ApiDefinitionsSource.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,5 +10,8 @@ public enum ApiDefinitionsSource
ResourceManagerRestApiSpecs,

[Description("HandWritten")]
HandWritten
HandWritten,

[Description("MicrosoftGraphMetadata")]
MicrosoftGraphMetadata,
}
10 changes: 10 additions & 0 deletions data/Pandora.Data/Models/CommonTypesDefinition.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
using System.Collections.Generic;

namespace Pandora.Data.Models;

public class CommonTypesDefinition
{
public ServiceDefinitionType ServiceDefinitionType { get; set; }
public IEnumerable<ConstantDefinition> Constants { get; set; }
public IEnumerable<ModelDefinition> Models { get; set; }
}
32 changes: 32 additions & 0 deletions data/Pandora.Data/Repositories/CommonTypesRepository.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
using System.Collections.Generic;
using System.Linq;
using Pandora.Data.Models;
using CommonTypesDefinition = Pandora.Data.Models.CommonTypesDefinition;

namespace Pandora.Data.Repositories;

public class CommonTypesRepository : ICommonTypesRepository
{
private readonly Dictionary<ServiceDefinitionType, List<CommonTypesDefinition>> _commonTypes;

public CommonTypesRepository(Dictionary<ServiceDefinitionType, IEnumerable<Definitions.Interfaces.CommonTypesDefinition>> commonTypes)
{
_commonTypes = new Dictionary<ServiceDefinitionType, List<CommonTypesDefinition>>();
foreach (var commonType in commonTypes)
{
var mapped = commonType.Value.Select(s => Transformers.CommonTypes.Map(s, commonType.Key)).ToList();
_commonTypes.Add(commonType.Key, mapped);
}
}

public IEnumerable<CommonTypesDefinition> Get(ServiceDefinitionType serviceDefinitionType)
{
var commonTypes = _commonTypes.Where(c => c.Key == serviceDefinitionType);
if (!commonTypes.Any())
{
return null;
}

return commonTypes.SelectMany(v => v.Value).ToList();
}
}
9 changes: 9 additions & 0 deletions data/Pandora.Data/Repositories/ICommonTypesRepository.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
using System.Collections.Generic;
using Pandora.Data.Models;

namespace Pandora.Data.Repositories;

public interface ICommonTypesRepository
{
IEnumerable<CommonTypesDefinition> Get(ServiceDefinitionType serviceDefinitionType);
}
39 changes: 1 addition & 38 deletions data/Pandora.Data/ServiceDefinitions.cs
Original file line number Diff line number Diff line change
@@ -1,12 +1,6 @@
using System.Collections.Generic;
using System.Linq;
using Pandora.Data.Models;
using Pandora.Definitions.DataPlane;
using Pandora.Definitions.HandDefined;
using Pandora.Definitions.Interfaces;
using Pandora.Definitions.MicrosoftGraph.Beta;
using Pandora.Definitions.MicrosoftGraph.Stable;
using Pandora.Definitions.ResourceManager;
using ServiceDefinition = Pandora.Definitions.Interfaces.ServiceDefinition;

namespace Pandora.Data;
Expand All @@ -15,38 +9,7 @@ public static class SupportedServices
{
public static Dictionary<ServiceDefinitionType, IEnumerable<ServiceDefinition>> Get()
{
var data = new Dictionary<ServiceDefinitionType, List<ServicesDefinition>>
{
{
ServiceDefinitionType.DataPlane,
new List<ServicesDefinition>
{
new DataPlaneServices(),
}
},
{
ServiceDefinitionType.MicrosoftGraphBeta,
new List<ServicesDefinition>
{
new MicrosoftGraphBetaServices(),
}
},
{
ServiceDefinitionType.MicrosoftGraphStableV1,
new List<ServicesDefinition>
{
new MicrosoftGraphStableV1Services(),
}
},
{
ServiceDefinitionType.ResourceManager,
new List<ServicesDefinition>
{
new HandDefinedServices(),
new ResourceManagerServices(),
}
},
};
var data = DefinitionTypes.Get();
var output = new Dictionary<ServiceDefinitionType, IEnumerable<ServiceDefinition>>();
foreach (var item in data)
{
Expand Down
2 changes: 1 addition & 1 deletion data/Pandora.Data/ServiceDefinitionsTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
using Pandora.Definitions.HandDefined;
using Pandora.Definitions.Interfaces;
using Pandora.Definitions.MicrosoftGraph.Beta;
using Pandora.Definitions.MicrosoftGraph.Stable;
using Pandora.Definitions.MicrosoftGraph.StableV1;
using Pandora.Definitions.ResourceManager;
using ServiceDefinition = Pandora.Data.Models.ServiceDefinition;

Expand Down
Loading

0 comments on commit c303507

Please sign in to comment.