Skip to content

Commit

Permalink
Merge branch 'main' into 13955-replace-altinncontentloader-with-studi…
Browse files Browse the repository at this point in the history
…ospinner
  • Loading branch information
standeren authored Nov 8, 2024
2 parents a64a53b + eab5110 commit 192d489
Show file tree
Hide file tree
Showing 337 changed files with 8,889 additions and 1,736 deletions.
4 changes: 4 additions & 0 deletions .github/workflows/deploy-designer.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,11 @@ jobs:
config-chart-name: altinn-designer-config
artifact-name: altinn-designer
helm-set-arguments: environmentName=${{ matrix.environment == 'preapproved-prod' && 'prod' || matrix.environment }},chartVersion=0.1.0+${{ needs.determine-tag.outputs.tag }},imageTag=${{ needs.determine-tag.outputs.tag }},dbMigrationsTag=${{ needs.determine-tag.outputs.tag }}
trace-workflow: true
trace-team-name: 'team-studio'
secrets:
client-id: ${{ secrets.AZURE_CLIENT_ID_FC }}
tenant-id: ${{ secrets.AZURE_TENANT_ID_FC }}
subscription-id: ${{ secrets.AZURE_SUBSCRIPTION_ID_FC }}
trace-connetion-string: ${{ secrets.APP_INSIGHTS_CONNECTION_STRING }}
trace-repo-token: ${{ secrets.GITHUB_TOKEN }}
6 changes: 6 additions & 0 deletions .github/workflows/deploy-loadbalancer.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ jobs:
tag: 0.1.0+${{ needs.get-short-sha.outputs.short-sha }} # Helm version needs to be valid sematic version
chart-name: altinn-loadbalancer
registry-name: altinntjenestercontainerregistry.azurecr.io
environment: dev # dev environment has push access and doesn't require review
secrets:
client-id: ${{ secrets.AZURE_CLIENT_ID_FC }}
tenant-id: ${{ secrets.AZURE_TENANT_ID_FC }}
Expand All @@ -46,7 +47,12 @@ jobs:
config-chart-name: altinn-loadbalancer-config
artifact-name: altinn-loadbalancer
helm-set-arguments: environmentName=${{ matrix.environment }},chartVersion=0.1.0+${{ needs.get-short-sha.outputs.short-sha }}
trace-workflow: true
trace-team-name: 'team-studio'
secrets:
client-id: ${{ secrets.AZURE_CLIENT_ID_FC }}
tenant-id: ${{ secrets.AZURE_TENANT_ID_FC }}
subscription-id: ${{ secrets.AZURE_SUBSCRIPTION_ID_FC }}
trace-connection-string: ${{ secrets.APP_INSIGHTS_CONNECTION_STRING }}
trace-repo-token: ${{ secrets.GITHUB_TOKEN }}

22 changes: 22 additions & 0 deletions .github/workflows/template-flux-config-push.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,15 @@ on:
helm-set-arguments:
required: false
type: string
trace-workflow:
required: false
type: boolean
default: false
trace-team-name:
required: false
type: string
default: ''


secrets:
client-id:
Expand All @@ -32,6 +41,10 @@ on:
required: true
subscription-id:
required: true
trace-connection-string:
required: true
trace-repo-token:
required: true

jobs:
config-oci-artifact-push:
Expand Down Expand Up @@ -86,3 +99,12 @@ jobs:
artifact_env=${{ inputs.artifact-environment || inputs.environment }}
flux tag artifact oci://${{ inputs.registry-name }}/configs/${{ inputs.artifact-name }}-${artifact_env}:${{ inputs.tag }} --tag latest
- name: Send Trace to Azure Monitor
if: ${{ inputs.trace-workflow }}
uses: altinn/altinn-platform/actions/[email protected]
with:
connection_string: ${{ secrets.trace-connection-string }}
app: "${{ inputs.artifact-name }}"
team: "${{ inputs.trace-team-name }}"
repo_token: ${{ secrets.trace-repo-token }}
environment: ${{ inputs.artifact-environment || inputs.environment }}
Original file line number Diff line number Diff line change
Expand Up @@ -182,7 +182,7 @@ private void ParseFieldProperty(ElementMetadata element, StringBuilder classBuil
else
{
elementOrder += 1;
classBuilder.AppendLine(Indent(2) + "[XmlElement(\"" + element.XName + "\", Order = " + elementOrder + ")]");
AddXmlElementAnnotation(element, classBuilder, elementOrder);

// Temporary fix - as long as we use System.Text.Json for serialization and Newtonsoft.Json for
// deserialization, we need both JsonProperty and JsonPropertyName annotations.
Expand Down Expand Up @@ -223,7 +223,7 @@ private void ParseGroupProperty(ElementMetadata element, StringBuilder classBuil
var nullableReference = useNullableReferenceTypes ? "?" : string.Empty;
WriteRestrictionAnnotations(classBuilder, element);
elementOrder += 1;
classBuilder.AppendLine(Indent(2) + "[XmlElement(\"" + element.XName + "\", Order = " + elementOrder + ")]");
AddXmlElementAnnotation(element, classBuilder, elementOrder);

// Temporary fix - as long as we use System.Text.Json for serialization and Newtonsoft.Json for
// deserialization, we need both JsonProperty and JsonPropertyName annotations.
Expand Down Expand Up @@ -265,6 +265,18 @@ private void ParseGroupProperty(ElementMetadata element, StringBuilder classBuil
}
}

private void AddXmlElementAnnotation(ElementMetadata element, StringBuilder classBuilder, int elementOrder)
{
if (element.OrderOblivious)
{
classBuilder.AppendLine($"""{Indent(2)}[XmlElement("{element.XName}")]""");
}
else
{
classBuilder.AppendLine($"""{Indent(2)}[XmlElement("{element.XName}", Order = {elementOrder})]""");
}
}

private void AddShouldSerializeForTagContent(ElementMetadata element, StringBuilder classBuilder, ModelMetadata modelMetadata)
{
var children = modelMetadata.Elements.Values.Where(metadata =>
Expand Down Expand Up @@ -502,6 +514,7 @@ or BaseValueType.GMonth
or BaseValueType.Time
or BaseValueType.TimePeriod
or BaseValueType.Date
or BaseValueType.AnyURI
or null => ("string", false),
BaseValueType.Int => ("int", true),
BaseValueType.Short => ("short", true),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,9 @@ private sealed class SchemaContext

public bool XmlText { get; set; }


public bool OrderOblivious { get; set; } = false;

public Dictionary<string, Restriction> Restrictions { get; set; } = new();
}

Expand Down Expand Up @@ -185,6 +188,10 @@ private void ProcessKeyword(JsonPointer path, IJsonSchemaKeyword keyword, Schema
ProcessPropertiesKeyword(path, k, context);
break;

case XsdStructureKeyword { Value: "all" }:
context.OrderOblivious = true;
break;

default:
throw new MetamodelConvertException($"Keyword {keyword.Keyword()} not processed!. It's not supported in the current version of the JsonSchemaToMetamodelConverter.");
}
Expand Down Expand Up @@ -267,7 +274,7 @@ private void ProcessPropertiesKeyword(JsonPointer path, PropertiesKeyword keywor
{
foreach (var (name, property) in keyword.Properties)
{
var currentContext = new SchemaContext() { Id = CombineId(context.Id, name), Name = name, ParentId = context.Id, XPath = CombineXPath(context.XPath, context.Name) };
var currentContext = new SchemaContext() { Id = CombineId(context.Id, name), Name = name, ParentId = context.Id, XPath = CombineXPath(context.XPath, context.Name), OrderOblivious = context.OrderOblivious };
var subSchemaPath = path.Combine(JsonPointer.Parse($"/{name}"));

if (property.TryGetKeyword(out XsdTextKeyword xsdTextKeyword))
Expand Down Expand Up @@ -364,7 +371,7 @@ private void ProcessNonPrimitiveType(JsonPointer path, JsonSchema subSchema, Sch
{
ProcessRegularType(path, subSchema, context);

foreach (var keyword in subSchema.Keywords)
foreach (var keyword in subSchema.Keywords.OrderByPriority())
{
var keywordPath = path.Combine(JsonPointer.Parse($"/{keyword.Keyword()}"));

Expand Down Expand Up @@ -478,7 +485,8 @@ private void ProcessRegularType(JsonPointer path, JsonSchema subSchema, SchemaCo
DataBindingName = GetDataBindingName(ElementType.Group, maxOccurs, id, null, xPath),
DisplayString = GetDisplayString(id, typeName, minOccurs, maxOccurs),
IsTagContent = context.XmlText,
Nillable = context.IsNillable
Nillable = context.IsNillable,
OrderOblivious = context.OrderOblivious
});
}

Expand Down Expand Up @@ -534,7 +542,8 @@ private void AddElement(JsonPointer path, JsonSchema subSchema, SchemaContext co
DataBindingName = GetDataBindingName(@type, maxOccurs, id, fixedValue, xPath),
DisplayString = GetDisplayString(id, context.SchemaValueType.ToString(), minOccurs, maxOccurs),
IsTagContent = context.XmlText,
Nillable = context.IsNillable
Nillable = context.IsNillable,
OrderOblivious = context.OrderOblivious
});
}

Expand Down
6 changes: 6 additions & 0 deletions backend/src/DataModeling/Metamodel/ElementMetadata.cs
Original file line number Diff line number Diff line change
Expand Up @@ -169,5 +169,11 @@ public ElementMetadata()
[JsonProperty(PropertyName = "nillable")]
[JsonPropertyName("nillable")]
public bool? Nillable { get; set; }

[Newtonsoft.Json.JsonIgnore]
[System.Text.Json.Serialization.JsonIgnore]
[JsonProperty(PropertyName = "orderOblivious")]
[JsonPropertyName("orderOblivious")]
public bool OrderOblivious { get; set; } = false;
}
}
12 changes: 12 additions & 0 deletions backend/src/DataModeling/Utils/JsonSchemaExtensions.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
using System.Linq;
using Altinn.Studio.DataModeling.Json.Keywords;
using Json.Schema;

namespace Altinn.Studio.DataModeling.Utils
Expand Down Expand Up @@ -185,5 +186,16 @@ public static JsonSchemaBuilder Type(this JsonSchemaBuilder builder, SchemaValue

return builder;
}

/// <summary>
/// Orders the keywords by priority.
/// Currently the only keyword that should be prioritized is <see cref="XsdStructureKeyword"/>.
/// </summary>
/// <param name="keywords"></param>
/// <returns></returns>
public static IEnumerable<IJsonSchemaKeyword> OrderByPriority(this IEnumerable<IJsonSchemaKeyword> keywords)
{
return keywords.OrderBy(item => item.GetType() != typeof(XsdStructureKeyword));
}
}
}
131 changes: 131 additions & 0 deletions backend/src/Designer/Controllers/Preview/DataController.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
using System;
using System.Collections.Generic;
using System.Text.Json.Nodes;
using System.Threading;
using System.Threading.Tasks;
using System.Web;
using Altinn.Platform.Storage.Interface.Models;
using Altinn.Studio.Designer.Filters;
using Altinn.Studio.Designer.Helpers;
using Altinn.Studio.Designer.Models;
using Altinn.Studio.Designer.Models.Preview;
using Altinn.Studio.Designer.Services.Implementation;
using Altinn.Studio.Designer.Services.Interfaces;
using Altinn.Studio.Designer.Services.Interfaces.Preview;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;

namespace Altinn.Studio.Designer.Controllers.Preview
{
[Authorize]
[AutoValidateAntiforgeryToken]
[Route("{org:regex(^(?!designer))}/{app:regex(^(?!datamodels$)[[a-z]][[a-z0-9-]]{{1,28}}[[a-z0-9]]$)}/instances/{partyId}/{instanceGuid}/data")]
public class DataController(IHttpContextAccessor httpContextAccessor,
IPreviewService previewService,
ISchemaModelService schemaModelService,
IDataService dataService
) : Controller
{
[HttpGet("{dataGuid}")]
public ActionResult Get([FromRoute] Guid dataGuid)
{
JsonNode dataItem = dataService.GetDataElement(dataGuid);
return Ok(dataItem);
}

[HttpPost]
public ActionResult Post(
[FromRoute] int partyId,
[FromRoute] Guid instanceGuid,
[FromQuery] string dataType
)
{
DataElement dataElement = dataService.CreateDataElement(partyId, instanceGuid, dataType);
return Created("link-to-app-placeholder", dataElement);
}

[HttpPatch("{dataGuid}")]
[UseSystemTextJson]
public ActionResult<DataPatchResponse> Patch(
[FromRoute] Guid dataGuid,
[FromBody] DataPatchRequest dataPatch
)
{
JsonNode dataItem = dataService.PatchDataElement(dataGuid, dataPatch.Patch);
return Ok(new DataPatchResponse()
{
ValidationIssues = [],
NewDataModel = dataItem,
});
}

[HttpDelete("{dataTypeId}")]
public ActionResult DeleteAttachment([FromRoute] Guid dataGuid)
{
return Ok();
}

[HttpGet("{dataGuid}/validate")]
public ActionResult ValidateInstanceForData([FromRoute] Guid dataGuid)
{
return Ok(new List<string>());
}

[HttpPost("{dataTypeId}/tags")]
public ActionResult UpdateTagsForAttachment([FromBody] string tag)
{
return Created("link-to-app-placeholder", tag);
}

[HttpGet(PreviewService.MockDataTaskId)]
public async Task<ActionResult> GetDefaultFormData(
[FromRoute] string org,
[FromRoute] string app,
[FromRoute] int partyId,
CancellationToken cancellationToken
)
{
string developer = AuthenticationHelper.GetDeveloperUserName(httpContextAccessor.HttpContext);
string refererHeader = Request.Headers.Referer;
string layoutSetName = GetSelectedLayoutSetInEditorFromRefererHeader(refererHeader);
DataType dataType = await previewService.GetDataTypeForLayoutSetName(org, app, developer, layoutSetName, cancellationToken);
// For apps that does not have a datamodel
if (dataType == null)
{
Instance mockInstance = await previewService.GetMockInstance(org, app, developer, partyId, layoutSetName, cancellationToken);
return Ok(mockInstance.Id);
}
string modelPath = $"/App/models/{dataType.Id}.schema.json";
string decodedPath = Uri.UnescapeDataString(modelPath);
string formData = await schemaModelService.GetSchema(AltinnRepoEditingContext.FromOrgRepoDeveloper(org, app, developer), decodedPath, cancellationToken);
return Ok(formData);
}

[HttpPut(PreviewService.MockDataTaskId)]
public async Task<ActionResult> UpdateFormData(
[FromRoute] string org,
[FromRoute] string app,
[FromRoute] int partyId,
CancellationToken cancellationToken
)
{
return await GetDefaultFormData(org, app, partyId, cancellationToken);
}

[HttpPatch(PreviewService.MockDataTaskId)]
public ActionResult PatchFormData()
{
return Ok();
}

private static string GetSelectedLayoutSetInEditorFromRefererHeader(string refererHeader)
{
Uri refererUri = new(refererHeader);
string layoutSetName = HttpUtility.ParseQueryString(refererUri.Query)["selectedLayoutSet"];

return string.IsNullOrEmpty(layoutSetName) ? null : layoutSetName;
}
}
}

Loading

0 comments on commit 192d489

Please sign in to comment.