Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(subform): Add GET and PUT endpoints for datamodel metadata #14275

Merged
merged 10 commits into from
Dec 23, 2024
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")]
standeren marked this conversation as resolved.
Show resolved Hide resolved
[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);
standeren marked this conversation as resolved.
Show resolved Hide resolved
}
}
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>();
standeren marked this conversation as resolved.
Show resolved Hide resolved
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)
standeren marked this conversation as resolved.
Show resolved Hide resolved
{
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
Loading