Skip to content

Commit dcf5e1a

Browse files
committed
create endpoint to get attribute values
1 parent 04253fe commit dcf5e1a

File tree

11 files changed

+307
-1
lines changed

11 files changed

+307
-1
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
// Copyright (c) Microsoft Corporation.
2+
// Licensed under the MIT license.
3+
4+
using Services.Messages.Contracts.Requests;
5+
6+
namespace Services.Messages.Requests
7+
{
8+
public class GetDefaultSqlMembershipSourceAttributeValuesRequest : RequestBase
9+
{
10+
public GetDefaultSqlMembershipSourceAttributeValuesRequest(string attribute)
11+
{
12+
Attribute = attribute;
13+
}
14+
15+
public string Attribute { get; }
16+
}
17+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
// Copyright (c) Microsoft Corporation.
2+
// Licensed under the MIT license.
3+
4+
using Services.Messages.Contracts.Responses;
5+
using WebApi.Models.Responses;
6+
7+
namespace Services.Messages.Responses
8+
{
9+
public class GetDefaultSqlMembershipSourceAttributeValuesResponse : ResponseBase
10+
{
11+
public GetAttributeValuesModel Model { get; set; } = new GetAttributeValuesModel();
12+
}
13+
}
Lines changed: 120 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,120 @@
1+
// Copyright (c) Microsoft Corporation.
2+
// Licensed under the MIT license.
3+
4+
using Microsoft.Data.SqlClient;
5+
using Models;
6+
using Repositories.Contracts;
7+
using Services.Contracts;
8+
using Services.Messages.Requests;
9+
using Services.Messages.Responses;
10+
using SqlMembershipAttributeValueDTO = WebApi.Models.DTOs.SqlMembershipAttributeValue;
11+
12+
namespace Services
13+
{
14+
public class GetDefaultSqlMembershipSourceAttributeValuesHandler : RequestHandlerBase<GetDefaultSqlMembershipSourceAttributeValuesRequest, GetDefaultSqlMembershipSourceAttributeValuesResponse>
15+
{
16+
private readonly ILoggingRepository _loggingRepository;
17+
private readonly IDataFactoryRepository _dataFactoryRepository;
18+
private readonly ISqlMembershipRepository _sqlMembershipRepository;
19+
20+
private SemaphoreSlim _adfRunIdSemaphore = new SemaphoreSlim(1, 1);
21+
22+
public GetDefaultSqlMembershipSourceAttributeValuesHandler(ILoggingRepository loggingRepository,
23+
IDataFactoryRepository dataFactoryRepository,
24+
ISqlMembershipRepository sqlMembershipRepository) : base(loggingRepository)
25+
{
26+
_loggingRepository = loggingRepository ?? throw new ArgumentNullException(nameof(loggingRepository));
27+
_dataFactoryRepository = dataFactoryRepository ?? throw new ArgumentNullException(nameof(dataFactoryRepository));
28+
_sqlMembershipRepository = sqlMembershipRepository ?? throw new ArgumentNullException(nameof(sqlMembershipRepository));
29+
}
30+
31+
protected override async Task<GetDefaultSqlMembershipSourceAttributeValuesResponse> ExecuteCoreAsync(GetDefaultSqlMembershipSourceAttributeValuesRequest request)
32+
{
33+
try
34+
{
35+
var response = new GetDefaultSqlMembershipSourceAttributeValuesResponse();
36+
var attributeValues = await GetSqlAttributeValues(request.Attribute);
37+
foreach (var attributeValue in attributeValues)
38+
{
39+
var dto = new SqlMembershipAttributeValueDTO(attributeValue.Code, attributeValue.Description);
40+
41+
response.Model.Add(dto);
42+
}
43+
return response;
44+
}
45+
catch (Exception ex)
46+
{
47+
await _loggingRepository.LogMessageAsync(new LogMessage { Message = $"Unable to retrieve Sql Filter Attribute Values: {ex.Message}" });
48+
throw ex;
49+
}
50+
}
51+
52+
private async Task<List<(string Code, string Description)>> GetSqlAttributeValues(string attribute)
53+
{
54+
var tableName = await GetTableNameAsync();
55+
var attributes = await GetAttributeValuesAsync(attribute, tableName);
56+
return attributes;
57+
}
58+
59+
private async Task<List<(string Code, string Description)>> GetAttributeValuesAsync(string attribute, string tableName)
60+
{
61+
var attributeValues = new List<(string Code, string Description)>();
62+
63+
try
64+
{
65+
attributeValues = await _sqlMembershipRepository.GetAttributeValuesAsync(attribute, tableName);
66+
}
67+
catch (SqlException ex)
68+
{
69+
await _loggingRepository.LogMessageAsync(new LogMessage { Message = $"An exception was thrown while attempting to get Sql Filter Attribute Values from mappings table '{tableName}': {ex.Message}" });
70+
throw ex;
71+
}
72+
73+
return attributeValues;
74+
}
75+
76+
private async Task<string> GetTableNameAsync()
77+
{
78+
var adfRunId = await GetADFRunIdAsync();
79+
var tableName = adfRunId.Replace("-", "");
80+
var tableExists = await CheckIfMappingsTableExistsAsync(tableName);
81+
82+
return tableExists ? tableName : "";
83+
}
84+
85+
private async Task<bool> CheckIfMappingsTableExistsAsync(string tableName)
86+
{
87+
bool tableExists = false;
88+
89+
try
90+
{
91+
tableExists = await _sqlMembershipRepository.CheckIfMappingsTableExistsAsync(tableName);
92+
}
93+
catch (SqlException ex)
94+
{
95+
await _loggingRepository.LogMessageAsync(new LogMessage { Message = $"An exception was thrown while checking if table '{tableName}' exists: {ex.Message}" });
96+
throw ex;
97+
}
98+
99+
return tableExists;
100+
}
101+
102+
private async Task<string> GetADFRunIdAsync()
103+
{
104+
await _adfRunIdSemaphore.WaitAsync();
105+
106+
var lastSqlMembershipRunId = await _dataFactoryRepository.GetMostRecentSucceededRunIdAsync();
107+
108+
_adfRunIdSemaphore.Release();
109+
110+
if (string.IsNullOrWhiteSpace(lastSqlMembershipRunId))
111+
{
112+
var message = $"No SqlMembershipObtainer pipeline run has been found";
113+
await _loggingRepository.LogMessageAsync(new LogMessage { Message = $"An exception was thrown while attempting to get the latest ADF pipeline run: {message}" });
114+
throw new ArgumentException(message);
115+
}
116+
117+
return lastSqlMembershipRunId;
118+
}
119+
}
120+
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
// Copyright (c) Microsoft Corporation.
2+
// Licensed under the MIT license.
3+
4+
namespace WebApi.Models.DTOs
5+
{
6+
public class SqlMembershipAttributeValue
7+
{
8+
public SqlMembershipAttributeValue(string code, string description)
9+
{
10+
Code = code;
11+
Description = description;
12+
}
13+
14+
public string Code { get; set; }
15+
public string Description { get; set; }
16+
}
17+
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
// Copyright (c) Microsoft Corporation.
2+
// Licensed under the MIT license.
3+
4+
namespace WebApi.Models.Responses
5+
{
6+
public class GetAttributeValuesModel : List<DTOs.SqlMembershipAttributeValue>
7+
{
8+
public GetAttributeValuesModel()
9+
{
10+
11+
}
12+
}
13+
}

Service/GroupMembershipManagement/Hosts/WebApi/WebApi.Tests/SqlMembershipSourcesControllerTests.cs

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
using WebApi.Controllers.v1.Settings;
1212
using WebApi.Controllers.v1.SqlMembershipSources;
1313
using WebApi.Models;
14+
using WebApi.Models.Responses;
1415

1516
namespace Services.Tests
1617
{
@@ -24,6 +25,7 @@ public class SqlMembershipSourcesControllerTests
2425

2526
private GetDefaultSqlMembershipSourceHandler _getDefaultSqlMembershipSourceHandler = null!;
2627
private GetDefaultSqlMembershipSourceAttributesHandler _getDefaultSqlMembershipSourceAttributesHandler = null!;
28+
private GetDefaultSqlMembershipSourceAttributeValuesHandler _getDefaultSqlMembershipSourceAttributeValuesHandler = null!;
2729
private PatchDefaultSqlMembershipSourceCustomLabelHandler _patchDefaultSqlMembershipSourceCustomLabelHandler = null!;
2830
private PatchDefaultSqlMembershipSourceAttributesHandler _patchDefaultSqlMembershipSourceAttributesHandler = null!;
2931
private SqlMembershipSourcesController _sqlMembershipSourcesController = null!;
@@ -38,10 +40,11 @@ public void Initialize()
3840

3941
_getDefaultSqlMembershipSourceHandler = new GetDefaultSqlMembershipSourceHandler(_loggingRepository.Object, _databaseSqlMembershipSourcesRepository.Object);
4042
_getDefaultSqlMembershipSourceAttributesHandler = new GetDefaultSqlMembershipSourceAttributesHandler(_loggingRepository.Object, _databaseSqlMembershipSourcesRepository.Object, _dataFactoryRepository.Object, _sqlMembershipRepository.Object);
43+
_getDefaultSqlMembershipSourceAttributeValuesHandler = new GetDefaultSqlMembershipSourceAttributeValuesHandler(_loggingRepository.Object, _dataFactoryRepository.Object, _sqlMembershipRepository.Object);
4144
_patchDefaultSqlMembershipSourceCustomLabelHandler = new PatchDefaultSqlMembershipSourceCustomLabelHandler(_loggingRepository.Object, _databaseSqlMembershipSourcesRepository.Object);
4245
_patchDefaultSqlMembershipSourceAttributesHandler = new PatchDefaultSqlMembershipSourceAttributesHandler(_loggingRepository.Object, _databaseSqlMembershipSourcesRepository.Object);
4346

44-
_sqlMembershipSourcesController = new SqlMembershipSourcesController(_getDefaultSqlMembershipSourceHandler, _getDefaultSqlMembershipSourceAttributesHandler, _patchDefaultSqlMembershipSourceCustomLabelHandler, _patchDefaultSqlMembershipSourceAttributesHandler)
47+
_sqlMembershipSourcesController = new SqlMembershipSourcesController(_getDefaultSqlMembershipSourceHandler, _getDefaultSqlMembershipSourceAttributesHandler, _getDefaultSqlMembershipSourceAttributeValuesHandler, _patchDefaultSqlMembershipSourceCustomLabelHandler, _patchDefaultSqlMembershipSourceAttributesHandler)
4548
{
4649
ControllerContext = CreateControllerContext(new List<Claim>
4750
{
@@ -69,7 +72,9 @@ public void Initialize()
6972
_databaseSqlMembershipSourcesRepository.Setup(x => x.GetDefaultSourceAsync()).ReturnsAsync(() => _defaultSource);
7073
_databaseSqlMembershipSourcesRepository.Setup(x => x.GetDefaultSourceAttributesAsync()).ReturnsAsync(() => _storedAttributeSettings);
7174
_sqlMembershipRepository.Setup(x => x.GetColumnDetailsAsync(It.IsAny<string>())).ReturnsAsync(new List<(string Name, string Type)> { ("Name1", "nvarchar"), ("Name2", "int"), ("Name3", "nvarchar") });
75+
_sqlMembershipRepository.Setup(x => x.GetAttributeValuesAsync(It.IsAny<string>(), It.IsAny<string>())).ReturnsAsync(new List<(string Code, string Description)> { ("Code1", "Description1"), ("Code2", "Description2"), ("Code3", "Description3") });
7276
_sqlMembershipRepository.Setup(x => x.CheckIfTableExistsAsync(It.IsAny<string>())).ReturnsAsync(true);
77+
_sqlMembershipRepository.Setup(x => x.CheckIfMappingsTableExistsAsync(It.IsAny<string>())).ReturnsAsync(true);
7378
_dataFactoryRepository.Setup(x => x.GetMostRecentSucceededRunIdAsync()).ReturnsAsync("RUN ID");
7479
}
7580

@@ -229,6 +234,23 @@ public async Task PatchDefaultSourceAttributesWhenCustomMembershipProviderAdminT
229234
_databaseSqlMembershipSourcesRepository.Verify(x => x.UpdateDefaultSourceAttributesAsync(It.Is<List<SqlMembershipAttribute>>(list => list[0].Name == "Name4" && list[0].CustomLabel == "CustomLabel4")), Times.Once());
230235
}
231236

237+
[TestMethod]
238+
public async Task SuccessfulGetHRFilterattributeValuesTestAsync()
239+
{
240+
var response = await _sqlMembershipSourcesController.GetDefaultSourceAttributeValuesAsync("attribute");
241+
Assert.IsNotNull(response);
242+
var okResult = response as OkObjectResult;
243+
244+
Assert.IsNotNull(okResult);
245+
Assert.IsNotNull(okResult.Value);
246+
247+
var attributeValues = okResult.Value as GetAttributeValuesModel;
248+
Assert.IsNotNull(attributeValues);
249+
Assert.AreEqual(attributeValues.Count, 3);
250+
Assert.AreEqual(attributeValues[0].Code, "Code1");
251+
Assert.AreEqual(attributeValues[1].Description, "Description1");
252+
}
253+
232254
private ControllerContext CreateControllerContext(List<Claim> claims)
233255
{
234256
return new ControllerContext { HttpContext = CreateHttpContext(claims) };

Service/GroupMembershipManagement/Hosts/WebApi/WebApi/Configuration/MessageHandlerInjector.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ public static IServiceCollection InjectMessageHandlers(this IServiceCollection s
2323

2424
services.AddTransient<IRequestHandler<GetDefaultSqlMembershipSourceRequest, GetDefaultSqlMembershipSourceResponse>, GetDefaultSqlMembershipSourceHandler>();
2525
services.AddTransient<IRequestHandler<GetDefaultSqlMembershipSourceAttributesRequest, GetDefaultSqlMembershipSourceAttributesResponse>, GetDefaultSqlMembershipSourceAttributesHandler>();
26+
services.AddTransient<IRequestHandler<GetDefaultSqlMembershipSourceAttributeValuesRequest, GetDefaultSqlMembershipSourceAttributeValuesResponse>, GetDefaultSqlMembershipSourceAttributeValuesHandler>();
2627
services.AddTransient<IRequestHandler<PatchDefaultSqlMembershipSourceCustomLabelRequest, NullResponse>, PatchDefaultSqlMembershipSourceCustomLabelHandler>();
2728
services.AddTransient<IRequestHandler<PatchDefaultSqlMembershipSourceAttributesRequest, NullResponse>, PatchDefaultSqlMembershipSourceAttributesHandler>();
2829

Service/GroupMembershipManagement/Hosts/WebApi/WebApi/Controllers/v1/SqlMembershipSources/SqlMembershipSourcesController.cs

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,17 +17,20 @@ public class SqlMembershipSourcesController : ControllerBase
1717
{
1818
private readonly IRequestHandler<GetDefaultSqlMembershipSourceRequest, GetDefaultSqlMembershipSourceResponse> _getDefaultSqlMembershipSourceHandler;
1919
private readonly IRequestHandler<GetDefaultSqlMembershipSourceAttributesRequest, GetDefaultSqlMembershipSourceAttributesResponse> _getDefaultSqlMembershipSourceAttributesHandler;
20+
private readonly IRequestHandler<GetDefaultSqlMembershipSourceAttributeValuesRequest, GetDefaultSqlMembershipSourceAttributeValuesResponse> _getDefaultSqlMembershipSourceAttributeValuesHandler;
2021
private readonly IRequestHandler<PatchDefaultSqlMembershipSourceCustomLabelRequest, NullResponse> _patchDefaultSqlMembershipSourceCustomLabelHandler;
2122
private readonly IRequestHandler<PatchDefaultSqlMembershipSourceAttributesRequest, NullResponse> _patchDefaultSqlMembershipSourceAttributesHandler;
2223

2324
public SqlMembershipSourcesController(
2425
IRequestHandler<GetDefaultSqlMembershipSourceRequest, GetDefaultSqlMembershipSourceResponse> getDefaultSqlMembershipSourceHandler,
2526
IRequestHandler<GetDefaultSqlMembershipSourceAttributesRequest, GetDefaultSqlMembershipSourceAttributesResponse> getDefaultSqlMembershipSourceAttributesHandler,
27+
IRequestHandler<GetDefaultSqlMembershipSourceAttributeValuesRequest, GetDefaultSqlMembershipSourceAttributeValuesResponse> getDefaultSqlMembershipSourceAttributeValuesHandler,
2628
IRequestHandler<PatchDefaultSqlMembershipSourceCustomLabelRequest, NullResponse> patchDefaultSqlMembershipSourceCustomLabelHandler,
2729
IRequestHandler<PatchDefaultSqlMembershipSourceAttributesRequest, NullResponse> patchDefaultSqlMembershipSourceAttributesHandler)
2830
{
2931
_getDefaultSqlMembershipSourceHandler = getDefaultSqlMembershipSourceHandler ?? throw new ArgumentNullException(nameof(getDefaultSqlMembershipSourceHandler));
3032
_getDefaultSqlMembershipSourceAttributesHandler = getDefaultSqlMembershipSourceAttributesHandler ?? throw new ArgumentNullException(nameof(getDefaultSqlMembershipSourceAttributesHandler));
33+
_getDefaultSqlMembershipSourceAttributeValuesHandler = getDefaultSqlMembershipSourceAttributeValuesHandler ?? throw new ArgumentNullException(nameof(getDefaultSqlMembershipSourceAttributeValuesHandler));
3134
_patchDefaultSqlMembershipSourceCustomLabelHandler = patchDefaultSqlMembershipSourceCustomLabelHandler ?? throw new ArgumentNullException(nameof(patchDefaultSqlMembershipSourceCustomLabelHandler));
3235
_patchDefaultSqlMembershipSourceAttributesHandler = patchDefaultSqlMembershipSourceAttributesHandler ?? throw new ArgumentNullException(nameof(patchDefaultSqlMembershipSourceAttributesHandler));
3336
}
@@ -62,6 +65,21 @@ public async Task<IActionResult> GetDefaultSourceAttributesAsync()
6265
}
6366
}
6467

68+
[Authorize()]
69+
[HttpGet("defaultAttributeValues")]
70+
public async Task<IActionResult> GetDefaultSourceAttributeValuesAsync(string attribute)
71+
{
72+
try
73+
{
74+
var response = await _getDefaultSqlMembershipSourceAttributeValuesHandler.ExecuteAsync(new GetDefaultSqlMembershipSourceAttributeValuesRequest(attribute));
75+
return Ok(response.Model);
76+
}
77+
catch (Exception ex)
78+
{
79+
return StatusCode((int)HttpStatusCode.InternalServerError);
80+
}
81+
}
82+
6583
[Authorize(Roles = Models.Roles.CUSTOM_MEMBERSHIP_PROVIDER_ADMINISTRATOR)]
6684
[HttpPatch("default")]
6785
public async Task<IActionResult> PatchDefaultSourceCustomLabelAsync([FromBody] string customLabel)
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
// Copyright (c) Microsoft Corporation.
2+
// Licensed under the MIT license.
3+
4+
namespace Models
5+
{
6+
public class SqlMembershipAttributeValue
7+
{
8+
public string Code { get; set; }
9+
public string Description { get; set; }
10+
}
11+
}

Service/GroupMembershipManagement/Repositories.Contracts/ISqlMembershipRepository.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,5 +16,7 @@ public interface ISqlMembershipRepository
1616
Task<List<string>> GetColumnNamesAsync(string tableName);
1717
Task<(int maxDepth, string azureObjectId)> GetOrgLeaderAsync(int employeeId, string tableName);
1818
Task<List<(string Name, string Type)>> GetColumnDetailsAsync(string tableName);
19+
Task<bool> CheckIfMappingsTableExistsAsync(string tableName);
20+
Task<List<(string Code, string Description)>> GetAttributeValuesAsync(string attribute, string tableName);
1921
}
2022
}

0 commit comments

Comments
 (0)