Skip to content

Commit

Permalink
feat(subform): Add GET and PUT endpoints for datamodel metadata (#14275)
Browse files Browse the repository at this point in the history
  • Loading branch information
Jondyr authored Dec 23, 2024
1 parent cc8754c commit ce1ab8b
Show file tree
Hide file tree
Showing 6 changed files with 190 additions and 63 deletions.
29 changes: 29 additions & 0 deletions backend/src/Designer/Controllers/DatamodelsController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
using System.Text.Json.Nodes;
using System.Threading;
using System.Threading.Tasks;
using Altinn.Platform.Storage.Interface.Models;
using Altinn.Studio.DataModeling.Validator.Json;
using Altinn.Studio.Designer.Filters;
using Altinn.Studio.Designer.Helpers;
Expand Down Expand Up @@ -248,6 +249,34 @@ public async Task<IActionResult> UseXsdFromRepo(string org, string repository, s
}
}

/// <summary>
/// Gets the dataType for a given data model.
/// </summary>
[HttpGet("datamodel/{modelName}/dataType")]
[UseSystemTextJson]
public async Task<ActionResult<DataType>> GetModelDataType(string org, string repository, string modelName)
{
DataType dataType = await _schemaModelService.GetModelDataType(org, repository, modelName);
return Ok(dataType);
}

/// <summary>
/// Updates the dataType for a given data model.
/// </summary>
[HttpPut("datamodel/{modelName}/dataType")]
[UseSystemTextJson]
public async Task<ActionResult> SetModelDataType(string org, string repository, string modelName, [FromBody] DataType dataType)
{
if (!Equals(modelName, dataType.Id))
{
return BadRequest("Model name in path and request body does not match");
}

await _schemaModelService.SetModelDataType(org, repository, modelName, dataType);
DataType updatedDataType = await _schemaModelService.GetModelDataType(org, repository, modelName);
return Ok(updatedDataType);
}

private static string GetFileNameFromUploadedFile(IFormFile thefile)
{
return ContentDispositionHeaderValue.Parse(new StringSegment(thefile.ContentDisposition)).FileName.ToString();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ public class SchemaModelService : ISchemaModelService
private readonly IXmlSchemaToJsonSchemaConverter _xmlSchemaToJsonSchemaConverter;
private readonly IJsonSchemaToXmlSchemaConverter _jsonSchemaToXmlSchemaConverter;
private readonly IModelMetadataToCsharpConverter _modelMetadataToCsharpConverter;
private readonly IApplicationMetadataService _applicationMetadataService;

/// <summary>
/// Initializes a new instance of the <see cref="SchemaModelService"/> class.
Expand All @@ -59,20 +60,23 @@ public class SchemaModelService : ISchemaModelService
/// <param name="jsonSchemaToXmlSchemaConverter">
/// Class for converting Json schemas to Xml schemas.</param>
/// <param name="modelMetadataToCsharpConverter">C# model generator</param>
/// <param name="applicationMetadataService"></param>
public SchemaModelService(
IAltinnGitRepositoryFactory altinnGitRepositoryFactory,
ILoggerFactory loggerFactory,
ServiceRepositorySettings serviceRepositorySettings,
IXmlSchemaToJsonSchemaConverter xmlSchemaToJsonSchemaConverter,
IJsonSchemaToXmlSchemaConverter jsonSchemaToXmlSchemaConverter,
IModelMetadataToCsharpConverter modelMetadataToCsharpConverter)
IModelMetadataToCsharpConverter modelMetadataToCsharpConverter,
IApplicationMetadataService applicationMetadataService)
{
_altinnGitRepositoryFactory = altinnGitRepositoryFactory;
_loggerFactory = loggerFactory;
_serviceRepositorySettings = serviceRepositorySettings;
_xmlSchemaToJsonSchemaConverter = xmlSchemaToJsonSchemaConverter;
_jsonSchemaToXmlSchemaConverter = jsonSchemaToXmlSchemaConverter;
_modelMetadataToCsharpConverter = modelMetadataToCsharpConverter;
_applicationMetadataService = applicationMetadataService;
}

/// <inheritdoc/>
Expand Down Expand Up @@ -431,5 +435,24 @@ private bool NamespaceNeedsToBeSeparated(ApplicationMetadata application,
{
return application.DataTypes.All(d => d.AppLogic?.ClassRef != $"Altinn.App.Models.{csharpModelName}");
}

public async Task<DataType> GetModelDataType(string org, string app, string modelId)
{
ApplicationMetadata applicationMetadata = await _applicationMetadataService.GetApplicationMetadataFromRepository(org, app);
DataType dataType = applicationMetadata.DataTypes.Find((dataType) => dataType.Id == modelId);
return dataType;
}

public async Task SetModelDataType(string org, string app, string modelId, DataType dataType)
{
if (dataType.Id != modelId)
{
throw new ArgumentException("Provided modelId does not match the DataType's Id");
}
ApplicationMetadata applicationMetadata = await _applicationMetadataService.GetApplicationMetadataFromRepository(org, app);
applicationMetadata.DataTypes.RemoveAll((dt) => dt.Id == dataType.Id);
applicationMetadata.DataTypes.Add(dataType);
await _applicationMetadataService.UpdateApplicationMetaDataLocally(org, app, applicationMetadata);
}
}
}
10 changes: 10 additions & 0 deletions backend/src/Designer/Services/Interfaces/ISchemaModelService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -84,5 +84,15 @@ public interface ISchemaModelService
/// <param name="cancellationToken">An <see cref="CancellationToken"/> that observes if operation is cancelled.</param>
/// <returns>Returns the model metadata</returns>
Task<ModelMetadata> GenerateModelMetadataFromJsonSchema(AltinnRepoEditingContext altinnRepoEditingContext, string relativeFilePath, CancellationToken cancellationToken = default);

/// <summary>
/// Gets the dataType for a given model.
/// </summary>
Task<DataType> GetModelDataType(string org, string app, string modelId);

/// <summary>
/// Updates the dataType for a given model.
/// </summary>
Task SetModelDataType(string org, string app, string modelId, DataType dataType);
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
using System.Net;
using System.Collections.Generic;
using System.Net;
using System.Net.Http;
using System.Net.Http.Json;
using System.Threading.Tasks;
using Altinn.Platform.Storage.Interface.Models;
using Designer.Tests.Controllers.ApiTests;
using FluentAssertions;
using Microsoft.AspNetCore.Mvc.Testing;
Expand All @@ -26,4 +29,42 @@ public async Task GetDatamodel_ValidPath_ShouldReturnContent(string modelPath, s
using var response = await HttpClient.SendAsync(httpRequestMessage);
response.StatusCode.Should().Be(HttpStatusCode.OK);
}

[Theory]
[InlineData("Kursdomene_HvemErHvem_M_2021-04-08_5742_34627_SERES", "ttd", "hvem-er-hvem")]
public async Task GetDatamodelDataType_ShouldReturnContent(string modelName, string org, string repo)
{
string url = $"{VersionPrefix(org, repo)}/datamodel/{modelName}/dataType";
using var httpRequestMessage = new HttpRequestMessage(HttpMethod.Get, url);

using HttpResponseMessage response = await HttpClient.SendAsync(httpRequestMessage);
response.StatusCode.Should().Be(HttpStatusCode.OK);
DataType dataTypeResponse = await response.Content.ReadFromJsonAsync<DataType>();
dataTypeResponse.Should().NotBeNull();
dataTypeResponse.Should().BeEquivalentTo(new DataType
{
Id = "Kursdomene_HvemErHvem_M_2021-04-08_5742_34627_SERES",
AllowedContentTypes = new List<string> { "application/xml" },
AppLogic = new ApplicationLogic
{
AutoCreate = true,
ClassRef = "Altinn.App.Models.HvemErHvem_M"
},
TaskId = "Task_1",
MaxCount = 1,
MinCount = 1
});
}

[Theory]
[InlineData("notfound", "ttd", "hvem-er-hvem")]
public async Task GetDatamodelDataType_ShouldNullWhenNotFound(string modelName, string org, string repo)
{
string url = $"{VersionPrefix(org, repo)}/datamodel/{modelName}/dataType";
using var httpRequestMessage = new HttpRequestMessage(HttpMethod.Get, url);

using HttpResponseMessage response = await HttpClient.SendAsync(httpRequestMessage);
response.StatusCode.Should().Be(HttpStatusCode.OK);
(await response.Content.ReadAsStringAsync()).Should().Be("null");
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,15 @@
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Net.Http.Json;
using System.Net.Mime;
using System.Text;
using System.Text.Json;
using System.Threading.Tasks;
using System.Web;
using System.Xml;
using System.Xml.Schema;
using Altinn.Platform.Storage.Interface.Models;
using Altinn.Studio.DataModeling.Converter.Json;
using Altinn.Studio.DataModeling.Converter.Json.Strategy;
using Altinn.Studio.DataModeling.Converter.Metadata;
Expand Down Expand Up @@ -144,6 +146,54 @@ public async Task IncompatibleSchema_ShouldReturn422(string modelPath, string sc
}
}

[Theory]
[InlineData("testmodelname", "ttd", "hvem-er-hvem")]
public async Task PutDatamodelDataType_ShouldReturnWithoutErrors(string datamodelName, string org, string repo)
{
string url = $"{VersionPrefix(org, TargetTestRepository)}/datamodel/{datamodelName}/dataType";
await CopyRepositoryForTest(org, repo, "testUser", TargetTestRepository);

DataType dataType = new()
{
Id = datamodelName,
MaxCount = 1,
MinCount = 1,
};
using var putRequest = new HttpRequestMessage(HttpMethod.Put, url)
{
Content = JsonContent.Create(dataType)
};

HttpResponseMessage response = await HttpClient.SendAsync(putRequest);
response.StatusCode.Should().Be(HttpStatusCode.OK);
DataType dataTypeResponse = await response.Content.ReadFromJsonAsync<DataType>();
dataTypeResponse.Should().NotBeNull();
dataTypeResponse.Should().BeEquivalentTo(dataType);
}

[Theory]
[InlineData("testmodelname", "ttd", "hvem-er-hvem")]
public async Task PutDatamodelDataType_FailsIfDatamodelNameMismatchesObjectId(string datamodelName, string org, string repo)
{
string url = $"{VersionPrefix(org, TargetTestRepository)}/datamodel/{datamodelName}/dataType";
await CopyRepositoryForTest(org, repo, "testUser", TargetTestRepository);

DataType dataType = new()
{
Id = "wrongId",
MaxCount = 1,
MinCount = 1,
};
using var putRequest = new HttpRequestMessage(HttpMethod.Put, url)
{
Content = JsonContent.Create(dataType)
};

HttpResponseMessage response = await HttpClient.SendAsync(putRequest);
response.StatusCode.Should().Be(HttpStatusCode.BadRequest);
}


private async Task FilesWithCorrectNameAndContentShouldBeCreated(string modelName)
{
var location = Path.GetFullPath(Path.Combine(TestRepoPath, "App", "models"));
Expand Down
Loading

0 comments on commit ce1ab8b

Please sign in to comment.