Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,7 @@
}
else if (ViewModel.Id?.Type is OtlpApplicationType.Instance)
{
<div style="width: 20px;"></div>
<span aria-label="@string.Format(@Loc[nameof(ControlsStrings.ResourceDropdownReplicaAccessibleTitle)], ViewModel.Name, ViewModel.Id.ReplicaSetName)">@ViewModel.Name</span>
<span style="padding-left: 20px;" aria-label="@string.Format(@Loc[nameof(ControlsStrings.ResourceDropdownReplicaAccessibleTitle)], ViewModel.Name, ViewModel.Id.ReplicaSetName)">@ViewModel.Name</span>
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I noticed the div+width was compressed when the display name is long. padding is always applied.

}
else
{
Expand Down
5 changes: 2 additions & 3 deletions src/Aspire.Dashboard/Components/Pages/ConsoleLogs.razor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -717,9 +717,8 @@ public string GetUrlFromSerializableViewModel(ConsoleLogsPageState serializable)

public ConsoleLogsPageState ConvertViewModelToSerializable()
{
var selectedResourceName = PageViewModel.SelectedOption.Id is not null
? PageViewModel.SelectedOption.Name
// _noSelection, which doesn't have a resource attached to it
var selectedResourceName = PageViewModel.SelectedResource is { } selectedResource
? GetResourceName(selectedResource)
: null;
return new ConsoleLogsPageState(selectedResourceName);
}
Expand Down
37 changes: 30 additions & 7 deletions src/Aspire.Dashboard/Model/Otlp/ApplicationsSelectHelpers.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,16 +14,39 @@ public static SelectViewModel<ResourceTypeDetails> GetApplication(this ICollecti
return fallback;
}

var matches = applications.Where(e => SupportType(e.Id?.Type, canSelectGrouping) && string.Equals(name, e.Name, StringComparisons.ResourceName)).ToList();
if (matches.Count == 1)
var allowedMatches = applications.Where(e => SupportType(e.Id?.Type, canSelectGrouping)).ToList();

// First attempt an exact match on the instance id.
var instanceIdMatches = allowedMatches.Where(e => string.Equals(name, e.Id?.InstanceId, StringComparisons.ResourceName)).ToList();
if (instanceIdMatches.Count == 1)
{
return matches[0];
return instanceIdMatches[0];
}
else if (matches.Count == 0)
else if (instanceIdMatches.Count == 0)
{
return fallback;
// Fallback to matching on app name. This is commonly used when there is only one instance of the app.
var replicaSetMatches = allowedMatches.Where(e => e.Id?.Type != OtlpApplicationType.Instance && string.Equals(name, e.Id?.ReplicaSetName, StringComparisons.ResourceName)).ToList();

if (replicaSetMatches.Count == 1)
{
return replicaSetMatches[0];
}
else if (replicaSetMatches.Count == 0)
{
// No matches found so return the passed in fallback.
return fallback;
}
else
{
return MultipleMatches(allowedMatches, logger, name, replicaSetMatches);
}
}
else
{
return MultipleMatches(allowedMatches, logger, name, instanceIdMatches);
}

static SelectViewModel<ResourceTypeDetails> MultipleMatches(ICollection<SelectViewModel<ResourceTypeDetails>> applications, ILogger logger, string name, List<SelectViewModel<ResourceTypeDetails>> matches)
{
// There are multiple matches. Log as much information as possible about applications.
logger.LogWarning(
Expand Down Expand Up @@ -54,7 +77,7 @@ public static List<SelectViewModel<ResourceTypeDetails>> CreateApplications(List
var app = replicas.Single();
selectViewModels.Add(new SelectViewModel<ResourceTypeDetails>
{
Id = ResourceTypeDetails.CreateSingleton(app.InstanceId, applicationName),
Id = ResourceTypeDetails.CreateSingleton($"{applicationName}-{app.InstanceId}", applicationName),
Name = applicationName
});

Expand All @@ -72,7 +95,7 @@ public static List<SelectViewModel<ResourceTypeDetails>> CreateApplications(List
selectViewModels.AddRange(replicas.Select(replica =>
new SelectViewModel<ResourceTypeDetails>
{
Id = ResourceTypeDetails.CreateReplicaInstance(replica.InstanceId, applicationName),
Id = ResourceTypeDetails.CreateReplicaInstance($"{applicationName}-{replica.InstanceId}", applicationName),
Name = OtlpApplication.GetResourceName(replica, applications)
}));
}
Expand Down
4 changes: 4 additions & 0 deletions src/Aspire.Dashboard/Model/ResourceTypeDetails.cs
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,10 @@ public ApplicationKey GetApplicationKey()
{
throw new InvalidOperationException($"Can't get ApplicationKey from resource type details '{ToString()}' because {nameof(ReplicaSetName)} is null.");
}
if (InstanceId != null)
{
return ApplicationKey.Create(InstanceId);
}

return new ApplicationKey(ReplicaSetName, InstanceId);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,42 +22,42 @@ public void GetApplication_SameNameAsReplica_GetInstance()
// Arrange
var appVMs = ApplicationsSelectHelpers.CreateApplications(new List<OtlpApplication>
{
CreateOtlpApplication(name: "app", instanceId: "app"),
CreateOtlpApplication(name: "app", instanceId: "app-abc"),
CreateOtlpApplication(name: "singleton", instanceId: "singleton-abc")
CreateOtlpApplication(name: "multiple", instanceId: "instance"),
CreateOtlpApplication(name: "multiple", instanceId: "instanceabc"),
CreateOtlpApplication(name: "singleton", instanceId: "instanceabc")
});

Assert.Collection(appVMs,
app =>
{
Assert.Equal("app", app.Name);
Assert.Equal("multiple", app.Name);
Assert.Equal(OtlpApplicationType.ResourceGrouping, app.Id!.Type);
Assert.Null(app.Id!.InstanceId);
},
app =>
{
Assert.Equal("app-app", app.Name);
Assert.Equal("multiple-instance", app.Name);
Assert.Equal(OtlpApplicationType.Instance, app.Id!.Type);
Assert.Equal("app", app.Id!.InstanceId);
Assert.Equal("multiple-instance", app.Id!.InstanceId);
},
app =>
{
Assert.Equal("app-app-abc", app.Name);
Assert.Equal("multiple-instanceabc", app.Name);
Assert.Equal(OtlpApplicationType.Instance, app.Id!.Type);
Assert.Equal("app-abc", app.Id!.InstanceId);
Assert.Equal("multiple-instanceabc", app.Id!.InstanceId);
},
app =>
{
Assert.Equal("singleton", app.Name);
Assert.Equal(OtlpApplicationType.Singleton, app.Id!.Type);
Assert.Equal("singleton-abc", app.Id!.InstanceId);
Assert.Equal("singleton-instanceabc", app.Id!.InstanceId);
});

// Act
var app = appVMs.GetApplication(NullLogger.Instance, "app-app-abc", canSelectGrouping: false, null!);
var app = appVMs.GetApplication(NullLogger.Instance, "multiple-instanceabc", canSelectGrouping: false, null!);

// Assert
Assert.Equal("app-abc", app.Id!.InstanceId);
Assert.Equal("multiple-instanceabc", app.Id!.InstanceId);
Assert.Equal(OtlpApplicationType.Instance, app.Id!.Type);
}

Expand All @@ -67,38 +67,38 @@ public void GetApplication_NameDifferentByCase_Merge()
// Arrange
var appVMs = ApplicationsSelectHelpers.CreateApplications(new List<OtlpApplication>
{
CreateOtlpApplication(name: "app", instanceId: "app"),
CreateOtlpApplication(name: "APP", instanceId: "app-abc")
CreateOtlpApplication(name: "name", instanceId: "instance"),
CreateOtlpApplication(name: "NAME", instanceId: "instanceabc")
});

Assert.Collection(appVMs,
app =>
{
Assert.Equal("app", app.Name);
Assert.Equal("name", app.Name);
Assert.Equal(OtlpApplicationType.ResourceGrouping, app.Id!.Type);
Assert.Null(app.Id!.InstanceId);
},
app =>
{
Assert.Equal("APP-app", app.Name);
Assert.Equal("NAME-instance", app.Name);
Assert.Equal(OtlpApplicationType.Instance, app.Id!.Type);
Assert.Equal("app", app.Id!.InstanceId);
Assert.Equal("name-instance", app.Id!.InstanceId);
},
app =>
{
Assert.Equal("APP-app-abc", app.Name);
Assert.Equal("NAME-instanceabc", app.Name);
Assert.Equal(OtlpApplicationType.Instance, app.Id!.Type);
Assert.Equal("app-abc", app.Id!.InstanceId);
Assert.Equal("name-instanceabc", app.Id!.InstanceId);
});

var testSink = new TestSink();
var factory = LoggerFactory.Create(b => b.AddProvider(new TestLoggerProvider(testSink)));

// Act
var app = appVMs.GetApplication(factory.CreateLogger("Test"), "app-app", canSelectGrouping: false, null!);
var app = appVMs.GetApplication(factory.CreateLogger("Test"), "name-instance", canSelectGrouping: false, null!);

// Assert
Assert.Equal("app", app.Id!.InstanceId);
Assert.Equal("name-instance", app.Id!.InstanceId);
Assert.Equal(OtlpApplicationType.Instance, app.Id!.Type);
Assert.Empty(testSink.Writes);
}
Expand Down Expand Up @@ -148,13 +148,13 @@ public void GetApplication_SelectGroup_NotEnabled_ReturnNull()
{
Assert.Equal("app-123", app.Name);
Assert.Equal(OtlpApplicationType.Instance, app.Id!.Type);
Assert.Equal("123", app.Id!.InstanceId);
Assert.Equal("app-123", app.Id!.InstanceId);
},
app =>
{
Assert.Equal("app-456", app.Name);
Assert.Equal(OtlpApplicationType.Instance, app.Id!.Type);
Assert.Equal("456", app.Id!.InstanceId);
Assert.Equal("app-456", app.Id!.InstanceId);
});

// Act
Expand Down Expand Up @@ -185,13 +185,13 @@ public void GetApplication_SelectGroup_Enabled_ReturnGroup()
{
Assert.Equal("app-123", app.Name);
Assert.Equal(OtlpApplicationType.Instance, app.Id!.Type);
Assert.Equal("123", app.Id!.InstanceId);
Assert.Equal("app-123", app.Id!.InstanceId);
},
app =>
{
Assert.Equal("app-456", app.Name);
Assert.Equal(OtlpApplicationType.Instance, app.Id!.Type);
Assert.Equal("456", app.Id!.InstanceId);
Assert.Equal("app-456", app.Id!.InstanceId);
});

// Act
Expand Down