Skip to content

Commit

Permalink
Add support for variables
Browse files Browse the repository at this point in the history
  • Loading branch information
Vincent Wilms committed Jan 14, 2025
1 parent 99a0408 commit 2d6b543
Show file tree
Hide file tree
Showing 4 changed files with 105 additions and 4 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
## v2.0.0-beta.45 - 2025-01-14

- Added variable support.

## v2.0.0-beta.45 - 2025-01-14

- Execute transform id after transform property.

## v2.0.0-beta.44 - 2025-01-14
Expand Down
45 changes: 42 additions & 3 deletions src/Nexus.Sources.Transform/TransformDataSource.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,10 @@ internal record PropertyTransform(
string? TargetProperty,
string? TargetTemplate,
string? Separator
);
)
{
public bool NeedsVariableExpansion { get; set; }
}

internal record IdTransform(
// TransformTarget target, /* (catalog vs. resource - maybe required later) */
Expand All @@ -41,7 +44,7 @@ internal record TransformSettings(
"A data source to transform catalog properties like resources names and group memberships",
"https://github.com/nexus-main/nexus-sources-transform",
"https://github.com/nexus-main/nexus-sources-transform")]
public class Transform : IDataSource
public partial class Transform : IDataSource
{
private const string DEFAULT_TARGET_TEMPLATE = "$1";

Expand All @@ -51,13 +54,25 @@ public class Transform : IDataSource

private ILogger _logger = default!;

[GeneratedRegex(@"\${(.*?)}")]
private partial Regex VariableExpansionRegex { get; }

/// <inheritdoc/>
public Task SetContextAsync(DataSourceContext context, ILogger logger, CancellationToken cancellationToken)
{
// TODO: this is not so nice
_settings = JsonSerializer
.Deserialize<TransformSettings>(JsonSerializer.Serialize(context.SourceConfiguration));

if (_settings is not null && _settings.PropertyTransforms is not null)
{
foreach (var propertyTransform in _settings.PropertyTransforms)
{
if (propertyTransform.TargetTemplate is not null)
propertyTransform.NeedsVariableExpansion = VariableExpansionRegex.IsMatch(propertyTransform.TargetTemplate);
}
}

_logger = logger;

return Task.CompletedTask;
Expand Down Expand Up @@ -130,11 +145,17 @@ public Task<ResourceCatalog> EnrichCatalogAsync(ResourceCatalog catalog, Cancell
if (!isMatch)
continue;

var targetTemplate = transform.TargetTemplate is null
? DEFAULT_TARGET_TEMPLATE
: transform.NeedsVariableExpansion
? ExpandVariables(transform.TargetTemplate, resourceProperties)
: transform.TargetTemplate;

var targetValue = Regex
.Replace(
input: sourceValue,
pattern: transform.SourcePattern,
replacement: transform.TargetTemplate ?? DEFAULT_TARGET_TEMPLATE
replacement: targetTemplate
);

// apply value
Expand Down Expand Up @@ -217,4 +238,22 @@ public Task ReadAsync(DateTime begin, DateTime end, ReadRequest[] requests, Read
{
return Task.CompletedTask;
}

private string ExpandVariables(string targetTemplate, IReadOnlyDictionary<string, JsonElement>? resourceProperties)
{
return VariableExpansionRegex.Replace(targetTemplate, match =>
{
var path = match.Groups[1].Value;

if (!_pathCache.TryGetValue(path, out var pathSegments))
{
pathSegments = path.Split('/');
_pathCache[path] = pathSegments;
}

return resourceProperties is null
? ""
: resourceProperties.GetStringValue(pathSegments) ?? "";
});
}
}
58 changes: 58 additions & 0 deletions tests/Nexus.Sources.Transform.Tests/TransformDataSourceTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -393,6 +393,64 @@ string expected
Assert.Equal(expected, actual);
}

[Fact]
public async Task CanExpandVariables()
{
// Arrange
var expected = "my_file_source_id_foo_something_else";
var originalName = "foo in meters per second";

/* data source setup */
var transform = new PropertyTransform(
Operation: default,
SourcePath: DataModelExtensions.OriginalNameKey,
SourcePattern: "(.*) in.*",
TargetProperty: "id",
TargetTemplate: "${file-source-id}_$1_${something-else}",
Separator: default
);

var settings = new TransformSettings(
IdTransforms: [],
PropertyTransforms: [transform]
);

var sourceConfiguration = JsonSerializer
.Deserialize<IReadOnlyDictionary<string, JsonElement>>(JsonSerializer.SerializeToElement(settings));

var context = new DataSourceContext(
ResourceLocator: default,
SystemConfiguration: default,
SourceConfiguration: sourceConfiguration,
RequestConfiguration: default
);

var dataSource = new Transform();

await dataSource.SetContextAsync(context, NullLogger.Instance, CancellationToken.None);

/* catalog setup */
var resource = new ResourceBuilder(id: "foo")
.WithOriginalName(originalName)
.WithProperty("file-source-id", "my_file_source_id")
.WithProperty("something-else", "something_else")
.Build();

var catalog = new ResourceCatalogBuilder(id: "/bar")
.AddResource(resource)
.Build();

// Act
var actualCatalog = await dataSource
.EnrichCatalogAsync(catalog, CancellationToken.None);

// Assert
var actual = actualCatalog.Resources![0].Properties!
.GetStringValue(["id"]);

Assert.Equal(expected, actual);
}

[Fact]
public async Task DoesNotModifyPropertiesIfNoMatch()
{
Expand Down
2 changes: 1 addition & 1 deletion version.json
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
{
"version": "2.0.0",
"suffix": "beta.45"
"suffix": "beta.46"
}

0 comments on commit 2d6b543

Please sign in to comment.