Skip to content

Commit

Permalink
Merge branch 'main' into chore/warning-supression-cleanup
Browse files Browse the repository at this point in the history
  • Loading branch information
oskogstad authored Dec 13, 2024
2 parents 18990d9 + 2e8b3e6 commit a538d8e
Show file tree
Hide file tree
Showing 27 changed files with 468 additions and 92 deletions.
8 changes: 4 additions & 4 deletions .azure/infrastructure/staging.bicepparam
Original file line number Diff line number Diff line change
Expand Up @@ -31,15 +31,15 @@ param slackNotifierSku = {
}
param postgresConfiguration = {
sku: {
name: 'Standard_B1ms'
tier: 'Burstable'
name: 'Standard_D4ads_v5'
tier: 'GeneralPurpose'
}
storage: {
storageSizeGB: 32
storageSizeGB: 256
autoGrow: 'Enabled'
type: 'Premium_LRS'
}
enableIndexTuning: false
enableIndexTuning: true
enableQueryPerformanceInsight: true
}

Expand Down
3 changes: 0 additions & 3 deletions .azure/modules/redis/main.bicep
Original file line number Diff line number Diff line change
Expand Up @@ -97,9 +97,6 @@ module privateDnsZone '../privateDnsZone/main.bicep' = {

module privateDnsZoneGroup '../privateDnsZoneGroup/main.bicep' = {
name: '${namePrefix}-redis-privateDnsZoneGroup'
dependsOn: [
privateDnsZone
]
params: {
name: 'default'
dnsZoneGroupName: 'privatelink-redis-cache-windows-net'
Expand Down
3 changes: 0 additions & 3 deletions .azure/modules/serviceBus/main.bicep
Original file line number Diff line number Diff line change
Expand Up @@ -83,9 +83,6 @@ module privateDnsZone '../privateDnsZone/main.bicep' = {

module privateDnsZoneGroup '../privateDnsZoneGroup/main.bicep' = {
name: '${namePrefix}-service-bus-privateDnsZoneGroup'
dependsOn: [
privateDnsZone
]
params: {
name: 'default'
dnsZoneGroupName: 'privatelink-servicebus-windows-net'
Expand Down
28 changes: 28 additions & 0 deletions .github/actions/azure-login/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
name: 'Azure Login with Bicep Upgrade'
description: 'Login to Azure and upgrade Bicep CLI'

inputs:
client-id:
description: 'Azure Client ID'
required: true
tenant-id:
description: 'Azure Tenant ID'
required: true
subscription-id:
description: 'Azure Subscription ID'
required: true
env:
AZ_CLI_VERSION: 2.67.0
runs:
using: "composite"
steps:
- name: OIDC Login to Azure Public Cloud
uses: azure/login@v2
with:
client-id: ${{ inputs.client-id }}
tenant-id: ${{ inputs.tenant-id }}
subscription-id: ${{ inputs.subscription-id }}

- name: Upgrade Azure Bicep
shell: bash
run: az bicep upgrade
2 changes: 1 addition & 1 deletion .github/slack-templates/pipeline-failed.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
"type": "section",
"text": {
"type": "mrkdwn",
"text": "*Job Status:*\n• Infrastructure: ${{ env.INFRA_STATUS }}\n• Apps: ${{ env.APPS_STATUS }}\n• Slack Notifier: ${{ env.SLACK_NOTIFIER_STATUS }}\n• E2E Tests: ${{ env.E2E_TESTS_STATUS }}\n• Schema NPM: ${{ env.SCHEMA_NPM_STATUS }}\n• Publish: ${{ env.PUBLISH_STATUS }}"
"text": "*Job Status:*\n• Infrastructure: ${{ env.INFRA_STATUS }}\n• Apps: ${{ env.APPS_STATUS }}\n• Slack Notifier: ${{ env.SLACK_NOTIFIER_STATUS }}\n• E2E Tests: ${{ env.E2E_TESTS_STATUS }}\nPerformance Tests: ${{ env.PERFORMANCE_TESTS_STATUS }}\nSchema NPM: ${{ env.SCHEMA_NPM_STATUS }}\n• Publish: ${{ env.PUBLISH_STATUS }}"
}
},
{
Expand Down
36 changes: 35 additions & 1 deletion .github/workflows/ci-cd-yt01.yml
Original file line number Diff line number Diff line change
Expand Up @@ -140,9 +140,42 @@ jobs:
checks: write
pull-requests: write

run-performance-tests:
name: "Run K6 performance tests"
# we want the performance tests to be dependent on deployment of infrastructure and apps, but if infrastructure is skipped, we still want to run the tests
if: ${{ always() && !failure() && !cancelled() && (github.event_name == 'workflow_dispatch' || needs.check-for-changes.outputs.hasBackendChanges == 'true' || needs.check-for-changes.outputs.hasInfraChanges == 'true') }}
needs: [deploy-apps, deploy-infra, check-for-changes]
#needs: [deploy-apps, check-for-changes]
uses: ./.github/workflows/workflow-run-k6-performance.yml
secrets:
TOKEN_GENERATOR_USERNAME: ${{ secrets.TOKEN_GENERATOR_USERNAME }}
TOKEN_GENERATOR_PASSWORD: ${{ secrets.TOKEN_GENERATOR_PASSWORD }}
K6_CLOUD_TOKEN: ${{ secrets.K6_CLOUD_TOKEN }}
K6_CLOUD_PROJECT_ID: ${{ secrets.K6_CLOUD_PROJECT_ID }}

strategy:
max-parallel: 1
matrix:
files:
- tests/k6/tests/serviceowner/serviceOwnerSearchWithThresholds.js
- tests/k6/tests/serviceowner/createDialogWithThresholds.js
- tests/k6/tests/enduser/enduserSearchWithThresholds.js
fail-fast: false
with:
environment: yt01
apiVersion: v1
vus: 1
duration: 30s
tokens: both
numberOfTokens: 100
testSuitePath: ${{ matrix.files }}
permissions:
checks: write
pull-requests: write

send-slack-message-on-failure:
name: Send Slack message on failure
needs: [deploy-infra, deploy-apps, deploy-slack-notifier, run-e2e-tests, publish]
needs: [deploy-infra, deploy-apps, deploy-slack-notifier, run-e2e-tests, publish, run-performance-tests]
if: ${{ always() && failure() && !cancelled() }}
uses: ./.github/workflows/workflow-send-ci-cd-status-slack-message.yml
with:
Expand All @@ -151,6 +184,7 @@ jobs:
apps_status: ${{ needs.deploy-apps.result }}
slack_notifier_status: ${{ needs.deploy-slack-notifier.result }}
e2e_tests_status: ${{ needs.run-e2e-tests.result }}
performance_tests_status: ${{ needs.run-performance-tests.result }}
publish_status: ${{ needs.publish.result }}
secrets:
SLACK_BOT_TOKEN: ${{ secrets.SLACK_BOT_TOKEN }}
Expand Down
18 changes: 7 additions & 11 deletions .github/workflows/workflow-deploy-apps.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
name: Deploy apps
env:
AZ_CLI_VERSION: 2.67.0
on:
workflow_call:
outputs:
Expand Down Expand Up @@ -67,8 +65,8 @@ jobs:
- name: "Checkout GitHub Action"
uses: actions/checkout@v4

- name: OIDC Login to Azure Public Cloud
uses: azure/login@v2
- name: Azure Login
uses: ./.github/actions/azure-login
with:
client-id: ${{ secrets.AZURE_CLIENT_ID }}
tenant-id: ${{ secrets.AZURE_TENANT_ID }}
Expand Down Expand Up @@ -119,7 +117,6 @@ jobs:
uses: azure/CLI@v2
if: ${{!inputs.dryRun}}
with:
azcliversion: ${{ env.AZ_CLI_VERSION }}
inlineScript: |
az containerapp job start -n ${{ steps.deploy.outputs.name }} -g ${{ secrets.AZURE_RESOURCE_GROUP_NAME }}
Expand All @@ -129,7 +126,6 @@ jobs:
id: verify-migration
timeout-minutes: 3
with:
azcliversion: ${{ env.AZ_CLI_VERSION }}
inlineScript: |
./.github/tools/containerAppJobVerifier.sh ${{ steps.deploy.outputs.name }} ${{ secrets.AZURE_RESOURCE_GROUP_NAME }} ${{ inputs.version }}
Expand Down Expand Up @@ -162,12 +158,13 @@ jobs:
- name: "Checkout GitHub Action"
uses: actions/checkout@v4

- name: OIDC Login to Azure Public Cloud
uses: azure/login@v2
- name: Azure Login
uses: ./.github/actions/azure-login
with:
client-id: ${{ secrets.AZURE_CLIENT_ID }}
tenant-id: ${{ secrets.AZURE_TENANT_ID }}
subscription-id: ${{ secrets.AZURE_SUBSCRIPTION_ID }}

- name: Dryrun Deploy app ${{ matrix.name }}(${{ inputs.environment }})
uses: azure/arm-deploy@v2
if: ${{ inputs.dryRun }}
Expand Down Expand Up @@ -223,7 +220,6 @@ jobs:
id: verify-deployment
timeout-minutes: 3
with:
azcliversion: ${{ env.AZ_CLI_VERSION }}
inlineScript: |
./.github/tools/revisionVerifier.sh ${{ steps.deploy.outputs.revisionName }} ${{ secrets.AZURE_RESOURCE_GROUP_NAME }}
Expand Down Expand Up @@ -252,8 +248,8 @@ jobs:
- name: "Checkout GitHub Action"
uses: actions/checkout@v4

- name: OIDC Login to Azure Public Cloud
uses: azure/login@v2
- name: Azure Login
uses: ./.github/actions/azure-login
with:
client-id: ${{ secrets.AZURE_CLIENT_ID }}
tenant-id: ${{ secrets.AZURE_TENANT_ID }}
Expand Down
9 changes: 2 additions & 7 deletions .github/workflows/workflow-deploy-infra.yml
Original file line number Diff line number Diff line change
@@ -1,8 +1,4 @@
name: Deploy infrastructure

env:
AZ_CLI_VERSION: 2.67.0

on:
workflow_call:
secrets:
Expand Down Expand Up @@ -63,8 +59,8 @@ jobs:
with:
ref: ${{ inputs.ref }}

- name: OIDC Login to Azure Public Cloud
uses: azure/login@v2
- name: Azure Login
uses: ./.github/actions/azure-login
with:
client-id: ${{ secrets.AZURE_CLIENT_ID }}
tenant-id: ${{ secrets.AZURE_TENANT_ID }}
Expand All @@ -74,7 +70,6 @@ jobs:
uses: azure/CLI@v2
id: keyvault-keys
with:
azcliversion: ${{ env.AZ_CLI_VERSION }}
inlineScript: |
KEY_VAULT_KEYS=$(az keyvault secret list --vault-name ${{ secrets.AZURE_SOURCE_KEY_VAULT_NAME }} --subscription ${{ secrets.AZURE_SOURCE_KEY_VAULT_SUBSCRIPTION_ID }} --query "[].name" -o json | tr -d '\n')
echo "::set-output name=key-vault-keys::$KEY_VAULT_KEYS"
Expand Down
13 changes: 11 additions & 2 deletions .github/workflows/workflow-run-k6-performance.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,14 @@ on:
tokens:
required: true
type: string
numberOfTokens:
required: false
type: number
default: 0
ttl:
required: false
type: number
default: 3600
secrets:
TOKEN_GENERATOR_USERNAME:
required: true
Expand All @@ -45,9 +53,10 @@ jobs:
uses: grafana/setup-k6-action@v1
- name: Run K6 tests (${{ inputs.testSuitePath }})
run: |
./tests/k6/tests/scripts/generate_tokens.sh ./tests/k6/tests/performancetest_data ${{ inputs.tokens }}
./tests/k6/tests/scripts/generate_tokens.sh ./tests/k6/tests/performancetest_data ${{ inputs.tokens }} ${{ inputs.numberOfTokens }} ${{ inputs.ttl }}
echo "Running k6 test suite ${{ inputs.testSuitePath }} with ${{ inputs.vus }} VUs for ${{ inputs.duration }}"
k6 run ${{ inputs.testSuitePath }} --quiet --log-output=stdout --include-system-env-vars \
--vus=${{ inputs.vus }} --duration=${{ inputs.duration }} --out=cloud --out csv=./results.csv
--vus=${{ inputs.vus }} --duration=${{ inputs.duration }} --out csv=./results.csv
grep http_req_duration ./results.csv | sort --field-separator=',' --key=3 -nr | head -10
env:
API_ENVIRONMENT: ${{ inputs.environment }}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,10 @@ on:
type: string
description: "Status of the end-to-end tests job"
default: "skipped"
performance_tests_status:
type: string
description: "Status of the performance tests job"
default: "skipped"
schema_npm_status:
type: string
description: "Status of the schema npm publishing job"
Expand Down Expand Up @@ -69,6 +73,7 @@ jobs:
echo "SCHEMA_NPM_EMOJI=$(determine_emoji "${{ inputs.schema_npm_status }}")"
echo "PUBLISH_EMOJI=$(determine_emoji "${{ inputs.publish_status }}")"
echo "BUILD_AND_TEST_EMOJI=$(determine_emoji "${{ inputs.build_and_test_status }}")"
echo "PERFORMANCE_TESTS_EMOJI=$(determine_emoji "${{ inputs.performance_tests_status }}")"
} >> "$GITHUB_OUTPUT"
- name: Send GitHub slack message
Expand All @@ -85,6 +90,7 @@ jobs:
SCHEMA_NPM_STATUS: "${{ steps.status-emojis.outputs.SCHEMA_NPM_EMOJI }}"
PUBLISH_STATUS: "${{ steps.status-emojis.outputs.PUBLISH_EMOJI }}"
BUILD_AND_TEST_STATUS: "${{ steps.status-emojis.outputs.BUILD_AND_TEST_EMOJI }}"
PERFORMANCE_TESTS_STATUS: "${{ steps.status-emojis.outputs.PERFORMANCE_TESTS_EMOJI }}"
uses: slackapi/slack-github-action@v2.0.0
with:
errors: true
Expand Down
7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
# Changelog

## [1.41.2](https://github.com/digdir/dialogporten/compare/v1.41.1...v1.41.2) (2024-12-12)


### Bug Fixes

* **webapi:** Set correct swagger return type for transmission list ([#1590](https://github.com/digdir/dialogporten/issues/1590)) ([6e88e0c](https://github.com/digdir/dialogporten/commit/6e88e0c13c089d0f4871be2ee95a7f74fb21a51c))

## [1.41.1](https://github.com/digdir/dialogporten/compare/v1.41.0...v1.41.1) (2024-12-09)


Expand Down
4 changes: 2 additions & 2 deletions sonar-project.properties
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# Disable code duplication detection for C# files
sonar.cpd.exclusions=**/*.cs
# Disable code duplication detection for C# and k6 files
sonar.cpd.exclusions=**/*.cs,**/k6/**/*

# Disable all rules for auto-generated migration files
sonar.exclusions=**/Migrations/**/*
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,15 @@
using System.Text;
using Digdir.Domain.Dialogporten.Application.Externals.AltinnAuthorization;
using Digdir.Domain.Dialogporten.Domain.Dialogs.Entities;
using Digdir.Domain.Dialogporten.Domain.SubjectResources;
using Microsoft.EntityFrameworkCore;

namespace Digdir.Domain.Dialogporten.Application.Common.Extensions;

public static class DbSetExtensions
{
public static IQueryable<DialogEntity> PrefilterAuthorizedDialogs(this DbSet<DialogEntity> dialogs, DialogSearchAuthorizationResult authorizedResources)
public static (string sql, object[] parameters) GeneratePrefilterAuthorizedDialogsSql(DialogSearchAuthorizationResult authorizedResources)
{
var parameters = new List<object>();

// lang=sql
var sb = new StringBuilder()
.AppendLine(CultureInfo.InvariantCulture, $"""
SELECT *
Expand All @@ -22,36 +19,50 @@ public static IQueryable<DialogEntity> PrefilterAuthorizedDialogs(this DbSet<Dia
""");
parameters.Add(authorizedResources.DialogIds);

foreach (var (party, resources) in authorizedResources.ResourcesByParties)
// Group parties that have the same resources
var groupedResult = authorizedResources.ResourcesByParties
.GroupBy(kv => kv.Value, new HashSetEqualityComparer<string>())
.ToDictionary(
g => g.Key,
g => new HashSet<string>(g.Select(kv => kv.Key))
);

foreach (var (resources, parties) in groupedResult)
{
// lang=sql
sb.AppendLine(CultureInfo.InvariantCulture, $"""
OR (
"{nameof(DialogEntity.Party)}" = @p{parameters.Count}
"{nameof(DialogEntity.Party)}" = ANY(@p{parameters.Count})
AND "{nameof(DialogEntity.ServiceResource)}" = ANY(@p{parameters.Count + 1})
)
""");
parameters.Add(party);
parameters.Add(parties);
parameters.Add(resources);
}

foreach (var (party, subjects) in authorizedResources.SubjectsByParties)
return (sb.ToString(), parameters.ToArray());
}

public static IQueryable<DialogEntity> PrefilterAuthorizedDialogs(this DbSet<DialogEntity> dialogs, DialogSearchAuthorizationResult authorizedResources)
{
var (sql, parameters) = GeneratePrefilterAuthorizedDialogsSql(authorizedResources);
return dialogs.FromSqlRaw(sql, parameters);
}
}


public sealed class HashSetEqualityComparer<T> : IEqualityComparer<HashSet<T>>
{
public bool Equals(HashSet<T>? x, HashSet<T>? y)
{
return ReferenceEquals(x, y) || (x is not null && y is not null && x.SetEquals(y));
}

public int GetHashCode(HashSet<T> obj)
{
ArgumentNullException.ThrowIfNull(obj);
unchecked
{
// lang=sql
sb.AppendLine(CultureInfo.InvariantCulture, $"""
OR (
"{nameof(DialogEntity.Party)}" = @p{parameters.Count}
AND "{nameof(DialogEntity.ServiceResource)}" = ANY(
SELECT "{nameof(SubjectResource.Resource)}"
FROM "{nameof(SubjectResource)}"
WHERE "{nameof(SubjectResource.Subject)}" = ANY(@p{parameters.Count + 1})
)
)
""");
parameters.Add(party);
parameters.Add(subjects);
return obj.Aggregate(0, (hash, item) => hash ^ (item?.GetHashCode() ?? 0));
}

return dialogs.FromSqlRaw(sb.ToString(), parameters.ToArray());
}
}
Loading

0 comments on commit a538d8e

Please sign in to comment.