diff --git a/aspnetcore/openshift/indexer/rahti2/template-indexer-cronjob-devel.yml b/aspnetcore/openshift/indexer/rahti2/template-indexer-cronjob-devel.yml
index 63feb83..908a4a7 100644
--- a/aspnetcore/openshift/indexer/rahti2/template-indexer-cronjob-devel.yml
+++ b/aspnetcore/openshift/indexer/rahti2/template-indexer-cronjob-devel.yml
@@ -30,7 +30,7 @@ objects:
failedJobsHistoryLimit: 2
jobTemplate:
spec:
- activeDeadlineSeconds: 2400 # Can run for 40 minutes
+ activeDeadlineSeconds: 5400 # Can run for 90 minutes
template:
spec:
restartPolicy: Never
diff --git a/aspnetcore/openshift/indexer/rahti2/template-indexer-cronjob-production.yml b/aspnetcore/openshift/indexer/rahti2/template-indexer-cronjob-production.yml
index 84c9733..0dc112e 100644
--- a/aspnetcore/openshift/indexer/rahti2/template-indexer-cronjob-production.yml
+++ b/aspnetcore/openshift/indexer/rahti2/template-indexer-cronjob-production.yml
@@ -30,7 +30,7 @@ objects:
failedJobsHistoryLimit: 2
jobTemplate:
spec:
- activeDeadlineSeconds: 2400 # Can run for 40 minutes
+ activeDeadlineSeconds: 5400 # Can run for 90 minutes
template:
spec:
restartPolicy: Never
diff --git a/aspnetcore/openshift/indexer/rahti2/template-indexer-cronjob-qa.yml b/aspnetcore/openshift/indexer/rahti2/template-indexer-cronjob-qa.yml
index 5d124ae..d3ff438 100644
--- a/aspnetcore/openshift/indexer/rahti2/template-indexer-cronjob-qa.yml
+++ b/aspnetcore/openshift/indexer/rahti2/template-indexer-cronjob-qa.yml
@@ -30,7 +30,7 @@ objects:
failedJobsHistoryLimit: 2
jobTemplate:
spec:
- activeDeadlineSeconds: 2400 # Can run for 40 minutes
+ activeDeadlineSeconds: 5400 # Can run for 90 minutes
template:
spec:
restartPolicy: Never
diff --git a/aspnetcore/src/ApiModels/Query/GetFundingCallQueryParameters.cs b/aspnetcore/src/ApiModels/Query/GetFundingCallQueryParameters.cs
index c0bd9ea..73203d2 100644
--- a/aspnetcore/src/ApiModels/Query/GetFundingCallQueryParameters.cs
+++ b/aspnetcore/src/ApiModels/Query/GetFundingCallQueryParameters.cs
@@ -6,7 +6,7 @@ namespace ResearchFi.Query;
/// Query parameters for searching funding calls.
///
///
-public class GetFundingCallQueryParameters : PaginationQueryParameters
+public class GetFundingCallQueryParameters
{
///
/// One of the fields nameFi, nameSV, nameEn contains the full text.
diff --git a/aspnetcore/src/ApiModels/Query/GetFundingDecisionQueryParameters.cs b/aspnetcore/src/ApiModels/Query/GetFundingDecisionQueryParameters.cs
index 2213ae0..18c3f0c 100644
--- a/aspnetcore/src/ApiModels/Query/GetFundingDecisionQueryParameters.cs
+++ b/aspnetcore/src/ApiModels/Query/GetFundingDecisionQueryParameters.cs
@@ -6,7 +6,7 @@ namespace ResearchFi.Query;
/// Query parameters for searching funding decisions.
///
///
-public class GetFundingDecisionQueryParameters : PaginationQueryParameters
+public class GetFundingDecisionQueryParameters
{
///
/// One of the fields nameFi, nameSV, nameEn contains the full text.
diff --git a/aspnetcore/src/ApiModels/Query/GetInfrastructuresQueryParameters.cs b/aspnetcore/src/ApiModels/Query/GetInfrastructuresQueryParameters.cs
index 0e9afbf..a29000e 100644
--- a/aspnetcore/src/ApiModels/Query/GetInfrastructuresQueryParameters.cs
+++ b/aspnetcore/src/ApiModels/Query/GetInfrastructuresQueryParameters.cs
@@ -3,7 +3,7 @@
///
/// Hakuparametrit infrastruktuurien hakemiseen.
///
-public class GetInfrastructuresQueryParameters : PaginationQueryParameters
+public class GetInfrastructuresQueryParameters
{
///
/// Infrastruktuurin nimi.
diff --git a/aspnetcore/src/ApiModels/Query/GetPublicationsQueryParameters.cs b/aspnetcore/src/ApiModels/Query/GetPublicationsQueryParameters.cs
index 48e46c1..d170712 100644
--- a/aspnetcore/src/ApiModels/Query/GetPublicationsQueryParameters.cs
+++ b/aspnetcore/src/ApiModels/Query/GetPublicationsQueryParameters.cs
@@ -6,7 +6,7 @@ namespace ResearchFi.Query;
/// Query parameters for searching publications.
///
///
-public class GetPublicationsQueryParameters : PaginationQueryParameters
+public class GetPublicationsQueryParameters
{
///
/// The field name contains text.
diff --git a/aspnetcore/src/ApiModels/Query/PaginationQueryParameters.cs b/aspnetcore/src/ApiModels/Query/PaginationQueryParameters.cs
index 8fbd10c..cbd8742 100644
--- a/aspnetcore/src/ApiModels/Query/PaginationQueryParameters.cs
+++ b/aspnetcore/src/ApiModels/Query/PaginationQueryParameters.cs
@@ -19,7 +19,7 @@ public int PageNumber
}
///
- /// Number of results on page. Optional. Default value 20. Maximum permissible value 100. Maximum possible result set of 10,000 results.
+ /// Number of results on page. Optional. Default value 20. Maximum permissible value 100. Maximum possible result set of 10000 results.
///
public int PageSize
{
diff --git a/aspnetcore/src/ApiModels/Query/SearchAfterQueryParameters.cs b/aspnetcore/src/ApiModels/Query/SearchAfterQueryParameters.cs
new file mode 100644
index 0000000..9ca8fab
--- /dev/null
+++ b/aspnetcore/src/ApiModels/Query/SearchAfterQueryParameters.cs
@@ -0,0 +1,30 @@
+namespace ResearchFi.Query;
+
+///
+/// Vientiin liittyvät tiedot.
+///
+public class SearchAfterQueryParameters
+{
+ private const int DefaultPageSize = 50;
+ private const int MaximumPageSize = 1000;
+ private int _pageSize = DefaultPageSize;
+ private long? _nextPageToken = null;
+
+ ///
+ /// Number of results on page. Optional. Default value 50. Maximum permissible value 1000.
+ ///
+ public int PageSize
+ {
+ get => _pageSize;
+ set => _pageSize = value < 1 ? DefaultPageSize : (value > MaximumPageSize ? MaximumPageSize : value);
+ }
+
+ ///
+ /// Value from previous query response header "x-next-page-token". Leave empty in the first query.
+ ///
+ public long? NextPageToken
+ {
+ get => _nextPageToken;
+ set => _nextPageToken = value;
+ }
+}
\ No newline at end of file
diff --git a/aspnetcore/src/ElasticService/ElasticSearchIndexService.cs b/aspnetcore/src/ElasticService/ElasticSearchIndexService.cs
index d1d0d01..0ff095f 100644
--- a/aspnetcore/src/ElasticService/ElasticSearchIndexService.cs
+++ b/aspnetcore/src/ElasticService/ElasticSearchIndexService.cs
@@ -32,7 +32,7 @@ public async Task IndexAsync(string indexName, List entities, Type model
await IndexEntities(indexToCreate, entities, modelType);
// Switch indexes
- await SwitchIndexes(indexName, indexToCreate, indexToDelete);
+ await SwitchIndexes(indexName, indexToCreate, indexToDelete, modelType.Name);
_logger.LogDebug("{EntityType:l}: Indexing to {IndexName:l} complete", modelType.Name, indexName);
}
@@ -43,8 +43,9 @@ public async Task IndexChunkAsync(string indexToCreate, List entities, T
await IndexEntities(indexToCreate, entities, modelType);
}
- public async Task SwitchIndexes(string indexName, string indexToCreate, string indexToDelete)
+ public async Task SwitchIndexes(string indexName, string indexToCreate, string indexToDelete, string modelTypeName)
{
+ _logger.LogInformation($"{modelTypeName}: Switch indexes start: indexName={indexName}, indexToCreate={indexToCreate}, indexToDelete={indexToDelete}");
// Wait for new index to be operational.
await _elasticClient.Cluster
.HealthAsync(selector: s => s
@@ -61,6 +62,7 @@ await _elasticClient.Indices.BulkAliasAsync(r => r
// Delete the old index if it exists.
await _elasticClient.Indices.DeleteAsync(indexToDelete, d => d.RequestConfiguration(x => x.AllowedStatusCodes(404)));
+ _logger.LogInformation($"{modelTypeName}: Switch indexes complete");
}
public async Task<(string indexToCreate, string indexToDelete)> GetIndexNames(string indexName)
diff --git a/aspnetcore/src/ElasticService/ElasticSearchQueryGenerators/IQueryGenerator.cs b/aspnetcore/src/ElasticService/ElasticSearchQueryGenerators/IQueryGenerator.cs
index 701cf3b..e39a5d7 100644
--- a/aspnetcore/src/ElasticService/ElasticSearchQueryGenerators/IQueryGenerator.cs
+++ b/aspnetcore/src/ElasticService/ElasticSearchQueryGenerators/IQueryGenerator.cs
@@ -5,5 +5,6 @@ namespace CSC.PublicApi.ElasticService.ElasticSearchQueryGenerators;
public interface IQueryGenerator where TOut : class
{
Func, ISearchRequest> GenerateQuery(TIn searchParameters, int pageNumber, int pageSize);
+ Func, ISearchRequest> GenerateQuerySearchAfter(TIn searchParameters, int pageSize, long? searchAfter);
Func, ISearchRequest> GenerateSingleQuery(string id);
}
\ No newline at end of file
diff --git a/aspnetcore/src/ElasticService/ElasticSearchQueryGenerators/QueryGeneratorBase.cs b/aspnetcore/src/ElasticService/ElasticSearchQueryGenerators/QueryGeneratorBase.cs
index 8afc1a8..ffb31d7 100644
--- a/aspnetcore/src/ElasticService/ElasticSearchQueryGenerators/QueryGeneratorBase.cs
+++ b/aspnetcore/src/ElasticService/ElasticSearchQueryGenerators/QueryGeneratorBase.cs
@@ -22,6 +22,27 @@ public Func, ISearchRequest> GenerateQuery(TIn searchPara
.Query(GenerateQueryForSearch(searchParameters));
}
+ public Func, ISearchRequest> GenerateQuerySearchAfter(TIn searchParameters, int pageSize, long? searchAfter)
+ {
+ var indexName = _configuration.GetIndexNameForType(typeof(TOut));
+
+ if (searchAfter == null) {
+ return descriptor => descriptor
+ .Index(indexName)
+ .Take(pageSize)
+ .Sort(sort => sort.Ascending(SortSpecialField.DocumentIndexOrder))
+ .Query(GenerateQueryForSearch(searchParameters));
+ }
+ else {
+ return descriptor => descriptor
+ .Index(indexName)
+ .Take(pageSize)
+ .Sort(sort => sort.Ascending(SortSpecialField.DocumentIndexOrder))
+ .Query(GenerateQueryForSearch(searchParameters))
+ .SearchAfter(searchAfter);
+ }
+ }
+
public Func, ISearchRequest> GenerateSingleQuery(string id)
{
var indexName = _configuration.GetIndexNameForType(typeof(TOut));
diff --git a/aspnetcore/src/ElasticService/ElasticSearchService.cs b/aspnetcore/src/ElasticService/ElasticSearchService.cs
index 7193d7e..b5d3f58 100644
--- a/aspnetcore/src/ElasticService/ElasticSearchService.cs
+++ b/aspnetcore/src/ElasticService/ElasticSearchService.cs
@@ -32,6 +32,27 @@ public ElasticSearchService(
return (searchResult.Documents, new SearchResult(pageNumber, pageSize, searchResult.HitsMetadata?.Total.Value));
}
+ public async Task<(IEnumerable, SearchAfterResult)> SearchAfter(TIn parameters, int pageSize, long? searchAfter)
+ {
+ var query = _queryGenerator.GenerateQuerySearchAfter(parameters, pageSize, searchAfter);
+
+ var searchResult = await _elasticClient.SearchAsync(query);
+
+ if (Debugger.IsAttached)
+ {
+ // Enables seeing the query sent to elastic and the response in the log when debugging.
+ Console.WriteLine(searchResult.DebugInformation);
+ }
+
+ long? searchAfterValue = null;
+
+ if (searchResult.Hits.Count > 0) {
+ searchAfterValue = (long)searchResult.Hits.Last().Sorts.First();
+ }
+
+ return (searchResult.Documents, new SearchAfterResult(searchAfterValue, pageSize));
+ }
+
public async Task GetSingle(string id)
{
var query = _queryGenerator.GenerateSingleQuery(id);
diff --git a/aspnetcore/src/ElasticService/IElasticSearchIndexService.cs b/aspnetcore/src/ElasticService/IElasticSearchIndexService.cs
index 960b848..f949344 100644
--- a/aspnetcore/src/ElasticService/IElasticSearchIndexService.cs
+++ b/aspnetcore/src/ElasticService/IElasticSearchIndexService.cs
@@ -48,6 +48,7 @@ public interface IElasticSearchIndexService
///
///
///
+ ///
///
- Task SwitchIndexes(string indexName, string indexToCreate, string indexToDelete);
+ Task SwitchIndexes(string indexName, string indexToCreate, string indexToDelete, string modelTypeName);
}
\ No newline at end of file
diff --git a/aspnetcore/src/ElasticService/ISearchService.cs b/aspnetcore/src/ElasticService/ISearchService.cs
index 5242e1e..43992b8 100644
--- a/aspnetcore/src/ElasticService/ISearchService.cs
+++ b/aspnetcore/src/ElasticService/ISearchService.cs
@@ -3,6 +3,6 @@
public interface ISearchService where TOut : class
{
Task<(IEnumerable, SearchResult)> Search(TIn searchParameters, int pageNumber, int pageSize);
-
+ Task<(IEnumerable, SearchAfterResult)> SearchAfter(TIn searchParameters, int pageSize, long? searchAfter);
Task GetSingle(string id);
}
\ No newline at end of file
diff --git a/aspnetcore/src/ElasticService/SearchAfterResult.cs b/aspnetcore/src/ElasticService/SearchAfterResult.cs
new file mode 100644
index 0000000..5fa6a51
--- /dev/null
+++ b/aspnetcore/src/ElasticService/SearchAfterResult.cs
@@ -0,0 +1,12 @@
+namespace CSC.PublicApi.ElasticService;
+
+public class SearchAfterResult
+{
+ public long? SearchAfter { get; }
+ public int PageSize { get; }
+ public SearchAfterResult(long? searchAfter, int pageSize)
+ {
+ SearchAfter = searchAfter;
+ PageSize = pageSize;
+ }
+}
\ No newline at end of file
diff --git a/aspnetcore/src/Indexer/Indexer.cs b/aspnetcore/src/Indexer/Indexer.cs
index 5c8ed9c..7da2a99 100644
--- a/aspnetcore/src/Indexer/Indexer.cs
+++ b/aspnetcore/src/Indexer/Indexer.cs
@@ -177,7 +177,7 @@ private async Task IndexEntities(string indexName, IIndexRepository repository,
} while (numOfResults >= takeAmount - 1);
// Activate new index and delete old
- await _indexService.SwitchIndexes(indexName, indexToCreate, indexToDelete);
+ await _indexService.SwitchIndexes(indexName, indexToCreate, indexToDelete, type.Name);
_logger.LogInformation("{EntityType:l}: Recreated index {IndexName:l}, {ElasticsearchDocumentCount} documents", type.Name, indexName, processedCount);
}
else
diff --git a/aspnetcore/src/Interface/Configuration/SwaggerExtensions.cs b/aspnetcore/src/Interface/Configuration/SwaggerExtensions.cs
index 3ca855e..c841237 100644
--- a/aspnetcore/src/Interface/Configuration/SwaggerExtensions.cs
+++ b/aspnetcore/src/Interface/Configuration/SwaggerExtensions.cs
@@ -76,6 +76,7 @@ public static void UseSwaggerAndSwaggerUI(this WebApplication app)
foreach (var description in app.Services.GetRequiredService().ApiVersionDescriptions)
{
options.SwaggerEndpoint($"{description.GroupName}/swagger.json", description.GroupName.ToUpperInvariant());
+ options.ConfigObject.AdditionalItems.Add("syntaxHighlight", false); // disable to improve performance with large responses
}
});
}
diff --git a/aspnetcore/src/Interface/Controllers/FundingCallController.cs b/aspnetcore/src/Interface/Controllers/FundingCallController.cs
index c3da5b9..f9621e7 100644
--- a/aspnetcore/src/Interface/Controllers/FundingCallController.cs
+++ b/aspnetcore/src/Interface/Controllers/FundingCallController.cs
@@ -30,7 +30,7 @@ public FundingCallController(
///
/// Endpoint for filtering funding calls using the specified query parameters.
///
- /// The query parameters for filtering the results.
+ /// The query parameters for filtering the results.
/// Paged search result as a collection of objects.
/// Ok.
/// Unauthorized.
@@ -43,9 +43,9 @@ public FundingCallController(
[ProducesResponseType(typeof(IEnumerable), StatusCodes.Status200OK)]
[ProducesResponseType(typeof(void), StatusCodes.Status401Unauthorized)]
[ProducesResponseType(typeof(void),StatusCodes.Status403Forbidden)]
- public async Task> Get([FromQuery] GetFundingCallQueryParameters queryParameters)
+ public async Task> Get([FromQuery] GetFundingCallQueryParameters fundingCallQueryParameters, [FromQuery] PaginationQueryParameters paginationQueryParameters)
{
- var (fundingCalls, searchResult) = await _service.GetFundingCalls(queryParameters);
+ var (fundingCalls, searchResult) = await _service.GetFundingCalls(fundingCallQueryParameters, paginationQueryParameters);
ResponseHelper.AddPaginationResponseHeaders(HttpContext, searchResult);
diff --git a/aspnetcore/src/Interface/Controllers/FundingCallExportController.cs b/aspnetcore/src/Interface/Controllers/FundingCallExportController.cs
new file mode 100644
index 0000000..6753875
--- /dev/null
+++ b/aspnetcore/src/Interface/Controllers/FundingCallExportController.cs
@@ -0,0 +1,54 @@
+using CSC.PublicApi.Interface.Services;
+using Microsoft.AspNetCore.Authorization;
+using Microsoft.AspNetCore.Mvc;
+using ResearchFi.FundingCall;
+using ResearchFi.Query;
+using Serilog;
+
+namespace CSC.PublicApi.Interface.Controllers;
+
+[ApiController]
+[ApiVersion(ApiConstants.ApiVersion1)]
+[Route("v{version:apiVersion}/funding-calls-export")]
+public class FundingCallExportController : ControllerBase
+{
+ private readonly ILogger _logger;
+ private readonly IFundingCallService _service;
+ private readonly IDiagnosticContext _diagnosticContext;
+
+ public FundingCallExportController(
+ ILogger logger,
+ IFundingCallService service,
+ IDiagnosticContext diagnosticContext)
+ {
+ _logger = logger;
+ _service = service;
+ _diagnosticContext = diagnosticContext;
+ _diagnosticContext.Set(ApiConstants.LogResourceType_PropertyName, ApiConstants.LogResourceType_FundingCall);
+ }
+
+ ///
+ /// Endpoint for bypassing the limit of 10000 records for funding calls.
+ ///
+ /// The query parameters for filtering the results.
+ /// Paged search result as a collection of objects.
+ /// Ok.
+ /// Unauthorized.
+ /// Forbidden.
+ [HttpGet(Name = "GetFundingCallExport")]
+ [MapToApiVersion(ApiConstants.ApiVersion1)]
+ [Authorize(Policy = ApiPolicies.FundingCall.Read)]
+ [Produces(ApiConstants.ContentTypeJson)]
+ [Consumes(ApiConstants.ContentTypeJson)]
+ [ProducesResponseType(typeof(IEnumerable), StatusCodes.Status200OK)]
+ [ProducesResponseType(typeof(void), StatusCodes.Status401Unauthorized)]
+ [ProducesResponseType(typeof(void),StatusCodes.Status403Forbidden)]
+ public async Task> Get([FromQuery] GetFundingCallQueryParameters fundingCallQueryParameters, [FromQuery] SearchAfterQueryParameters searchAfterQueryParameters)
+ {
+ var (fundingCalls, searchAfterResult) = await _service.GetFundingCallsSearchAfter(fundingCallQueryParameters, searchAfterQueryParameters);
+
+ ResponseHelper.AddPaginationResponseHeadersSearchAfter(HttpContext, searchAfterResult);
+
+ return fundingCalls;
+ }
+}
\ No newline at end of file
diff --git a/aspnetcore/src/Interface/Controllers/FundingDecisionController.cs b/aspnetcore/src/Interface/Controllers/FundingDecisionController.cs
index 1f250a3..cad980b 100644
--- a/aspnetcore/src/Interface/Controllers/FundingDecisionController.cs
+++ b/aspnetcore/src/Interface/Controllers/FundingDecisionController.cs
@@ -32,6 +32,7 @@ public FundingDecisionController(
///
/// Endpoint for filtering funding decisions using the specified query parameters.
///
+ /// The query parameters for filtering the results.
/// Paged search result as a collection of objects.
/// Ok.
/// Unauthorized.
@@ -44,9 +45,9 @@ public FundingDecisionController(
[ProducesResponseType(typeof(IEnumerable), StatusCodes.Status200OK)]
[ProducesResponseType(typeof(void), StatusCodes.Status401Unauthorized)]
[ProducesResponseType(typeof(void),StatusCodes.Status403Forbidden)]
- public async Task> Get([FromQuery] GetFundingDecisionQueryParameters queryParameters)
+ public async Task> Get([FromQuery] GetFundingDecisionQueryParameters fundingDecisionQueryParameters, [FromQuery] PaginationQueryParameters paginationQueryParameters)
{
- var (fundingDecisions, searchResult) = await _service.GetFundingDecisions(queryParameters);
+ var (fundingDecisions, searchResult) = await _service.GetFundingDecisions(fundingDecisionQueryParameters, paginationQueryParameters);
ResponseHelper.AddPaginationResponseHeaders(HttpContext, searchResult);
diff --git a/aspnetcore/src/Interface/Controllers/FundingDecisionExportController.cs b/aspnetcore/src/Interface/Controllers/FundingDecisionExportController.cs
new file mode 100644
index 0000000..798c1a2
--- /dev/null
+++ b/aspnetcore/src/Interface/Controllers/FundingDecisionExportController.cs
@@ -0,0 +1,56 @@
+using CSC.PublicApi.Interface.Services;
+using Microsoft.AspNetCore.Authorization;
+using Microsoft.AspNetCore.Mvc;
+using ResearchFi.FundingDecision;
+using ResearchFi.Query;
+using Serilog;
+
+namespace CSC.PublicApi.Interface.Controllers;
+
+[ApiController]
+[ApiVersion(ApiVersion)]
+[Route("v{version:apiVersion}/funding-decisions-export")]
+
+public class FundingDecisionExportController : ControllerBase
+{
+ private const string ApiVersion = "1.0";
+ private readonly ILogger _logger;
+ private readonly IFundingDecisionService _service;
+ private readonly IDiagnosticContext _diagnosticContext;
+
+ public FundingDecisionExportController(
+ ILogger logger,
+ IFundingDecisionService service,
+ IDiagnosticContext diagnosticContext)
+ {
+ _logger = logger;
+ _service = service;
+ _diagnosticContext = diagnosticContext;
+ _diagnosticContext.Set(ApiConstants.LogResourceType_PropertyName, ApiConstants.LogResourceType_FundingDecision);
+ }
+
+ ///
+ /// Endpoint for bypassing the limit of 10000 records for funding decisions.
+ ///
+ /// The query parameters for filtering the results.
+ /// Paged search result as a collection of objects.
+ /// Ok.
+ /// Unauthorized.
+ /// Forbidden.
+ [HttpGet(Name = "GetFundingDecisionExport")]
+ [MapToApiVersion(ApiVersion)]
+ [Authorize(Policy = ApiPolicies.FundingDecision.Read)]
+ [Produces(ApiConstants.ContentTypeJson)]
+ [Consumes(ApiConstants.ContentTypeJson)]
+ [ProducesResponseType(typeof(IEnumerable), StatusCodes.Status200OK)]
+ [ProducesResponseType(typeof(void), StatusCodes.Status401Unauthorized)]
+ [ProducesResponseType(typeof(void),StatusCodes.Status403Forbidden)]
+ public async Task> Get([FromQuery] GetFundingDecisionQueryParameters fundingDecisionQueryParameters, [FromQuery] SearchAfterQueryParameters searchAfterQueryParameters)
+ {
+ var (fundingDecisions, searchAfterResult) = await _service.GetFundingDecisionsSearchAfter(fundingDecisionQueryParameters, searchAfterQueryParameters);
+
+ ResponseHelper.AddPaginationResponseHeadersSearchAfter(HttpContext, searchAfterResult);
+
+ return fundingDecisions;
+ }
+}
\ No newline at end of file
diff --git a/aspnetcore/src/Interface/Controllers/InfrastructureController.cs b/aspnetcore/src/Interface/Controllers/InfrastructureController.cs
index d228721..122fc3a 100644
--- a/aspnetcore/src/Interface/Controllers/InfrastructureController.cs
+++ b/aspnetcore/src/Interface/Controllers/InfrastructureController.cs
@@ -32,17 +32,26 @@ public InfrastructureController(
///
/// Search Infrastructures
///
- /// Query parameters for filtering the results.
- ///
- /*[HttpGet(Name = "GetInfrastructure")]
+ /// The query parameters for filtering the results.
+ /// Paged search result as a collection of objects.
+ /// Ok.
+ /// Unauthorized.
+ /// Forbidden.
+ [HttpGet(Name = "GetInfrastructure")]
[MapToApiVersion(ApiVersion)]
[Authorize(Policy = ApiPolicies.Infrastructure.Read)]
- public async Task> Get([FromQuery] GetInfrastructuresQueryParameters queryParameters)
+ [Produces(ApiConstants.ContentTypeJson)]
+ [Consumes(ApiConstants.ContentTypeJson)]
+ [ProducesResponseType(typeof(IEnumerable), StatusCodes.Status200OK)]
+ [ProducesResponseType(typeof(void), StatusCodes.Status401Unauthorized)]
+ [ProducesResponseType(typeof(void),StatusCodes.Status403Forbidden)]
+ [ApiExplorerSettings(IgnoreApi = true)] // Hidden
+ public async Task> Get([FromQuery] GetInfrastructuresQueryParameters infrastructuresQueryParameters, [FromQuery] PaginationQueryParameters paginationQueryParameters)
{
- var (infrastructures, searchResult) = await _service.GetInfrastructures(queryParameters);
+ var (infrastructures, searchResult) = await _service.GetInfrastructures(infrastructuresQueryParameters, paginationQueryParameters);
ResponseHelper.AddPaginationResponseHeaders(HttpContext, searchResult);
return infrastructures;
- }*/
+ }
}
\ No newline at end of file
diff --git a/aspnetcore/src/Interface/Controllers/OrganizationController.cs b/aspnetcore/src/Interface/Controllers/OrganizationController.cs
index 62025f6..513226a 100644
--- a/aspnetcore/src/Interface/Controllers/OrganizationController.cs
+++ b/aspnetcore/src/Interface/Controllers/OrganizationController.cs
@@ -32,17 +32,26 @@ public OrganizationController(
///
/// Hae organisaatioita
///
- ///
- ///
- /*[HttpGet(Name = "GetOrganization")]
+ /// The query parameters for filtering the results.
+ /// Paged search result as a collection of objects.
+ /// Ok.
+ /// Unauthorized.
+ /// Forbidden.
+ [HttpGet(Name = "GetOrganization")]
[MapToApiVersion(ApiVersion)]
[Authorize(Policy = ApiPolicies.Organization.Read)]
- public async Task> Get([FromQuery] GetOrganizationsQueryParameters queryParameters)
+ [Produces(ApiConstants.ContentTypeJson)]
+ [Consumes(ApiConstants.ContentTypeJson)]
+ [ProducesResponseType(typeof(IEnumerable), StatusCodes.Status200OK)]
+ [ProducesResponseType(typeof(void), StatusCodes.Status401Unauthorized)]
+ [ProducesResponseType(typeof(void),StatusCodes.Status403Forbidden)]
+ [ApiExplorerSettings(IgnoreApi = true)] // Hidden
+ public async Task> Get([FromQuery] GetOrganizationsQueryParameters organizationsQueryParameters, [FromQuery] PaginationQueryParameters paginationQueryParameters)
{
- var (organizations, searchResult) = await _service.GetOrganizations(queryParameters);
+ var (organizations, searchResult) = await _service.GetOrganizations(organizationsQueryParameters, paginationQueryParameters);
ResponseHelper.AddPaginationResponseHeaders(HttpContext, searchResult);
return organizations;
- }*/
+ }
}
\ No newline at end of file
diff --git a/aspnetcore/src/Interface/Controllers/PublicationController.cs b/aspnetcore/src/Interface/Controllers/PublicationController.cs
index baebcfe..d6cf501 100644
--- a/aspnetcore/src/Interface/Controllers/PublicationController.cs
+++ b/aspnetcore/src/Interface/Controllers/PublicationController.cs
@@ -31,20 +31,21 @@ public PublicationController(
///
/// Endpoint for filtering publications using the specified query parameters.
///
+ /// The query parameters for filtering the results.
/// Paged search result as a collection of objects.
/// Ok.
/// Unauthorized.
/// Forbidden.
- [HttpGet(Name = "SearchPublications")]
+ [HttpGet(Name = "GetPublications")]
[Authorize(Policy = ApiPolicies.Publication.Read)]
[Produces(ApiConstants.ContentTypeJson)]
[Consumes(ApiConstants.ContentTypeJson)]
[ProducesResponseType(typeof(IEnumerable), StatusCodes.Status200OK)]
[ProducesResponseType(typeof(void), StatusCodes.Status401Unauthorized)]
[ProducesResponseType(typeof(void), StatusCodes.Status403Forbidden)]
- public async Task> Get([FromQuery] GetPublicationsQueryParameters queryParameters)
+ public async Task> Get([FromQuery] GetPublicationsQueryParameters publicationsQueryParameters, [FromQuery] PaginationQueryParameters paginationQueryParameters)
{
- var (publications, searchResult) = await _service.GetPublications(queryParameters);
+ var (publications, searchResult) = await _service.GetPublications(publicationsQueryParameters, paginationQueryParameters);
ResponseHelper.AddPaginationResponseHeaders(HttpContext, searchResult);
diff --git a/aspnetcore/src/Interface/Controllers/PublicationExportController.cs b/aspnetcore/src/Interface/Controllers/PublicationExportController.cs
new file mode 100644
index 0000000..62c076f
--- /dev/null
+++ b/aspnetcore/src/Interface/Controllers/PublicationExportController.cs
@@ -0,0 +1,54 @@
+using ResearchFi.Publication;
+using CSC.PublicApi.Interface.Services;
+using Microsoft.AspNetCore.Authorization;
+using Microsoft.AspNetCore.Mvc;
+using ResearchFi.Query;
+using Serilog;
+
+namespace CSC.PublicApi.Interface.Controllers;
+
+[ApiController]
+[ApiVersion(ApiConstants.ApiVersion1)]
+[Route("v{version:apiVersion}/publications-export")]
+
+public class PublicationExportController : ControllerBase
+{
+ private readonly ILogger _logger;
+ private IPublicationService _service;
+ private readonly IDiagnosticContext _diagnosticContext;
+
+ public PublicationExportController(
+ ILogger logger,
+ IPublicationService service,
+ IDiagnosticContext diagnosticContext)
+ {
+ _logger = logger;
+ _service = service;
+ _diagnosticContext = diagnosticContext;
+ _diagnosticContext.Set(ApiConstants.LogResourceType_PropertyName, ApiConstants.LogResourceType_Publication);
+ }
+
+ ///
+ /// Endpoint for bypassing the limit of 10000 records for publications.
+ ///
+ /// The query parameters for filtering the results.
+ /// Paged search result as a collection of objects.
+ /// Ok.
+ /// Unauthorized.
+ /// Forbidden.
+ [HttpGet(Name = "GetPublicationsExport")]
+ [Authorize(Policy = ApiPolicies.Publication.Read)]
+ [Produces(ApiConstants.ContentTypeJson)]
+ [Consumes(ApiConstants.ContentTypeJson)]
+ [ProducesResponseType(typeof(IEnumerable), StatusCodes.Status200OK)]
+ [ProducesResponseType(typeof(void), StatusCodes.Status401Unauthorized)]
+ [ProducesResponseType(typeof(void), StatusCodes.Status403Forbidden)]
+ public async Task> Get([FromQuery] GetPublicationsQueryParameters publicationsQueryParameters, [FromQuery] SearchAfterQueryParameters searchAfterQueryParameters)
+ {
+ var (publications, searchAfterResult) = await _service.GetPublicationsSearchAfter(publicationsQueryParameters, searchAfterQueryParameters);
+
+ ResponseHelper.AddPaginationResponseHeadersSearchAfter(HttpContext, searchAfterResult);
+
+ return publications;
+ }
+}
\ No newline at end of file
diff --git a/aspnetcore/src/Interface/Controllers/ResearchDatasetController.cs b/aspnetcore/src/Interface/Controllers/ResearchDatasetController.cs
index 02661b2..ca82403 100644
--- a/aspnetcore/src/Interface/Controllers/ResearchDatasetController.cs
+++ b/aspnetcore/src/Interface/Controllers/ResearchDatasetController.cs
@@ -32,6 +32,7 @@ public ResearchDatasetController(
///
/// Endpoint for filtering research datasets using the specified query parameters.
///
+ /// The query parameters for filtering the results.
/// Paged search result as a collection of objects.
/// Ok.
/// Unauthorized.
@@ -44,9 +45,9 @@ public ResearchDatasetController(
[ProducesResponseType(typeof(IEnumerable), StatusCodes.Status200OK)]
[ProducesResponseType(typeof(void), StatusCodes.Status401Unauthorized)]
[ProducesResponseType(typeof(void),StatusCodes.Status403Forbidden)]
- public async Task> Get([FromQuery] GetResearchDatasetsQueryParameters queryParameters)
+ public async Task> Get([FromQuery] GetResearchDatasetsQueryParameters researchDatasetsQueryParameters, [FromQuery] PaginationQueryParameters paginationQueryParameters)
{
- var (researchDatasets, searchResult) = await _service.GetResearchDatasets(queryParameters);
+ var (researchDatasets, searchResult) = await _service.GetResearchDatasets(researchDatasetsQueryParameters, paginationQueryParameters);
ResponseHelper.AddPaginationResponseHeaders(HttpContext, searchResult);
diff --git a/aspnetcore/src/Interface/Controllers/ResearchDatasetExportController.cs b/aspnetcore/src/Interface/Controllers/ResearchDatasetExportController.cs
new file mode 100644
index 0000000..7debb5c
--- /dev/null
+++ b/aspnetcore/src/Interface/Controllers/ResearchDatasetExportController.cs
@@ -0,0 +1,56 @@
+using CSC.PublicApi.Interface.Services;
+using Microsoft.AspNetCore.Authorization;
+using Microsoft.AspNetCore.Mvc;
+using ResearchFi.Query;
+using ResearchDataset = ResearchFi.ResearchDataset.ResearchDataset;
+using Serilog;
+
+namespace CSC.PublicApi.Interface.Controllers;
+
+[ApiController]
+[ApiVersion(ApiVersion)]
+[Route("v{version:apiVersion}/research-datasets-export")]
+public class ResearchDatasetExportController : ControllerBase
+{
+ private const string ApiVersion = "1.0";
+
+ private readonly ILogger _logger;
+ private IResearchDatasetService _service;
+ private readonly IDiagnosticContext _diagnosticContext;
+
+ public ResearchDatasetExportController(
+ ILogger logger,
+ IResearchDatasetService service,
+ IDiagnosticContext diagnosticContext)
+ {
+ _logger = logger;
+ _service = service;
+ _diagnosticContext = diagnosticContext;
+ _diagnosticContext.Set(ApiConstants.LogResourceType_PropertyName, ApiConstants.LogResourceType_ResearchDataset);
+ }
+
+ ///
+ /// Endpoint for bypassing the limit of 10000 records for research datasets.
+ ///
+ /// The query parameters for filtering the results.
+ /// Paged search result as a collection of objects.
+ /// Ok.
+ /// Unauthorized.
+ /// Forbidden.
+ [HttpGet(Name = "GetResearchDatasetExport")]
+ [MapToApiVersion(ApiVersion)]
+ [Authorize(Policy = ApiPolicies.ResearchDataset.Read)]
+ [Produces(ApiConstants.ContentTypeJson)]
+ [Consumes(ApiConstants.ContentTypeJson)]
+ [ProducesResponseType(typeof(IEnumerable), StatusCodes.Status200OK)]
+ [ProducesResponseType(typeof(void), StatusCodes.Status401Unauthorized)]
+ [ProducesResponseType(typeof(void),StatusCodes.Status403Forbidden)]
+ public async Task> Get([FromQuery] GetResearchDatasetsQueryParameters researchDatasetsQueryParameters, [FromQuery] SearchAfterQueryParameters searchAfterQueryParameters)
+ {
+ var (researchDatasets, searchAfterResult) = await _service.GetResearchDatasetsSearchAfter(researchDatasetsQueryParameters, searchAfterQueryParameters);
+
+ ResponseHelper.AddPaginationResponseHeadersSearchAfter(HttpContext, searchAfterResult);
+
+ return researchDatasets;
+ }
+}
\ No newline at end of file
diff --git a/aspnetcore/src/Interface/Controllers/ResponseHelper.cs b/aspnetcore/src/Interface/Controllers/ResponseHelper.cs
index cd19204..87b4f81 100644
--- a/aspnetcore/src/Interface/Controllers/ResponseHelper.cs
+++ b/aspnetcore/src/Interface/Controllers/ResponseHelper.cs
@@ -25,33 +25,51 @@ public static void AddPaginationResponseHeaders(HttpContext httpContext, SearchR
httpContext.Response.Headers.Add("link", GetLinks(httpContext.Request, results.PageNumber, results.TotalPages));
}
+ public static void AddPaginationResponseHeadersSearchAfter(HttpContext httpContext, SearchAfterResult searchAfterResult)
+ {
+ httpContext.Response.Headers.Add("x-page-size", searchAfterResult.PageSize.ToString());
+ if (searchAfterResult.SearchAfter != null)
+ {
+ httpContext.Response.Headers.Add("x-next-page-token", searchAfterResult.SearchAfter.ToString());
+ httpContext.Response.Headers.Add("link", GetLinksSearchAfter(httpContext.Request, searchAfterResult.SearchAfter));
+ }
+ }
+
private static string GetLinks(HttpRequest httpRequest, int pageNumber, int totalPages)
{
var url = $"{httpRequest.Scheme}://{httpRequest.Host}{httpRequest.Path}";
-
var queryValues = QueryHelpers.ParseQuery(httpRequest.QueryString.Value);
-
var result = string.Empty;
-
if (pageNumber < totalPages)
{
result += $"{CreateLink(url, queryValues, pageNumber + 1, Next)}, ";
}
-
result += $"{CreateLink(url, queryValues, totalPages, Last)}, {CreateLink(url, queryValues, 1, First)}";
-
if (pageNumber > 1)
{
result += $", {CreateLink(url, queryValues, pageNumber - 1, Previous)}";
}
-
+ return result;
+ }
+ private static string GetLinksSearchAfter(HttpRequest httpRequest, long? searchAfter)
+ {
+ var url = $"{httpRequest.Scheme}://{httpRequest.Host}{httpRequest.Path}";
+ var queryValues = QueryHelpers.ParseQuery(httpRequest.QueryString.Value);
+ var result = string.Empty;
+ if (searchAfter != null) {
+ result += $"{CreateLinkSearchAfter(url, queryValues, searchAfter, Next)}";
+ }
return result;
}
private static string CreateLink(string url, Dictionary query, int pageNumber, string rel)
{
query["pageNumber"] = pageNumber.ToString();
-
+ return $"<{QueryHelpers.AddQueryString(url, query)}>; rel=\"{rel}\"";
+ }
+ private static string CreateLinkSearchAfter(string url, Dictionary query, long? searchAfter, string rel)
+ {
+ query["NextPageToken"] = searchAfter.ToString();
return $"<{QueryHelpers.AddQueryString(url, query)}>; rel=\"{rel}\"";
}
}
\ No newline at end of file
diff --git a/aspnetcore/src/Interface/Interface.csproj b/aspnetcore/src/Interface/Interface.csproj
index 7b028f6..dee5fe3 100644
--- a/aspnetcore/src/Interface/Interface.csproj
+++ b/aspnetcore/src/Interface/Interface.csproj
@@ -39,7 +39,7 @@
-
+
diff --git a/aspnetcore/src/Interface/Services/FundingCallService.cs b/aspnetcore/src/Interface/Services/FundingCallService.cs
index 628f1e6..2df487a 100644
--- a/aspnetcore/src/Interface/Services/FundingCallService.cs
+++ b/aspnetcore/src/Interface/Services/FundingCallService.cs
@@ -21,15 +21,24 @@ public FundingCallService(ILogger logger,
_searchService = searchService;
}
- public async Task<(IEnumerable, SearchResult)> GetFundingCalls(GetFundingCallQueryParameters queryParameters)
+ public async Task<(IEnumerable, SearchResult)> GetFundingCalls(GetFundingCallQueryParameters fundingCallQueryParameters, PaginationQueryParameters paginationQueryParameters)
{
- var searchParameters = _mapper.Map(queryParameters);
+ var searchParameters = _mapper.Map(fundingCallQueryParameters);
- var (result, searchResult) = await _searchService.Search(searchParameters, queryParameters.PageNumber, queryParameters.PageSize);
+ var (result, searchResult) = await _searchService.Search(searchParameters, paginationQueryParameters.PageNumber, paginationQueryParameters.PageSize);
return (_mapper.Map>(result), searchResult);
}
+ public async Task<(IEnumerable, SearchAfterResult)> GetFundingCallsSearchAfter(GetFundingCallQueryParameters fundingCallQueryParameters, SearchAfterQueryParameters searchAfterQueryParameters)
+ {
+ var searchParameters = _mapper.Map(fundingCallQueryParameters);
+
+ var (result, searchAfterResult) = await _searchService.SearchAfter(searchParameters, searchAfterQueryParameters.PageSize, searchAfterQueryParameters.NextPageToken);
+
+ return (_mapper.Map>(result), searchAfterResult);
+ }
+
public async Task PostFundCall(FundingCall fundingCall)
{
// TODO: only NameFi mapped to entity. Not using final models yet.
diff --git a/aspnetcore/src/Interface/Services/FundingDecisionService.cs b/aspnetcore/src/Interface/Services/FundingDecisionService.cs
index 136e5bc..1851ddd 100644
--- a/aspnetcore/src/Interface/Services/FundingDecisionService.cs
+++ b/aspnetcore/src/Interface/Services/FundingDecisionService.cs
@@ -19,12 +19,21 @@ public FundingDecisionService(ILogger logger, IMapper ma
_searchService = searchService;
}
- public async Task<(IEnumerable, SearchResult)> GetFundingDecisions(GetFundingDecisionQueryParameters queryParameters)
+ public async Task<(IEnumerable, SearchResult)> GetFundingDecisions(GetFundingDecisionQueryParameters fundingDecisionQueryParameters, PaginationQueryParameters paginationQueryParameters)
{
- var searchParameters = _mapper.Map(queryParameters);
+ var searchParameters = _mapper.Map(fundingDecisionQueryParameters);
- var (result, searchResult) = await _searchService.Search(searchParameters, queryParameters.PageNumber, queryParameters.PageSize);
+ var (result, searchResult) = await _searchService.Search(searchParameters, paginationQueryParameters.PageNumber, paginationQueryParameters.PageSize);
return (_mapper.Map>(result), searchResult);
}
+
+ public async Task<(IEnumerable, SearchAfterResult)> GetFundingDecisionsSearchAfter(GetFundingDecisionQueryParameters fundingDecisionQueryParameters, SearchAfterQueryParameters searchAfterQueryParameters)
+ {
+ var searchParameters = _mapper.Map(fundingDecisionQueryParameters);
+
+ var (result, searchAfterResult) = await _searchService.SearchAfter(searchParameters, searchAfterQueryParameters.PageSize, searchAfterQueryParameters.NextPageToken);
+
+ return (_mapper.Map>(result), searchAfterResult);
+ }
}
\ No newline at end of file
diff --git a/aspnetcore/src/Interface/Services/IFundingCallService.cs b/aspnetcore/src/Interface/Services/IFundingCallService.cs
index 3974858..469bd45 100644
--- a/aspnetcore/src/Interface/Services/IFundingCallService.cs
+++ b/aspnetcore/src/Interface/Services/IFundingCallService.cs
@@ -6,6 +6,7 @@ namespace CSC.PublicApi.Interface.Services;
public interface IFundingCallService
{
- Task<(IEnumerable, SearchResult)> GetFundingCalls(GetFundingCallQueryParameters queryParameters);
+ Task<(IEnumerable, SearchResult)> GetFundingCalls(GetFundingCallQueryParameters fundingCallQueryParameters, PaginationQueryParameters paginationQueryParameters);
+ Task<(IEnumerable, SearchAfterResult)> GetFundingCallsSearchAfter(GetFundingCallQueryParameters fundingCallQueryParameters, SearchAfterQueryParameters searchAfterQueryParameters);
Task PostFundCall(FundingCall fundingCall);
}
\ No newline at end of file
diff --git a/aspnetcore/src/Interface/Services/IFundingDecisionService.cs b/aspnetcore/src/Interface/Services/IFundingDecisionService.cs
index bcfe4c1..6ee3a21 100644
--- a/aspnetcore/src/Interface/Services/IFundingDecisionService.cs
+++ b/aspnetcore/src/Interface/Services/IFundingDecisionService.cs
@@ -6,5 +6,6 @@ namespace CSC.PublicApi.Interface.Services;
public interface IFundingDecisionService
{
- Task<(IEnumerable, SearchResult)> GetFundingDecisions(GetFundingDecisionQueryParameters queryParameters);
+ Task<(IEnumerable, SearchResult)> GetFundingDecisions(GetFundingDecisionQueryParameters fundingDecisionQueryParameters, PaginationQueryParameters paginationQueryParameters);
+ Task<(IEnumerable, SearchAfterResult)> GetFundingDecisionsSearchAfter(GetFundingDecisionQueryParameters fundingDecisionQueryParameters, SearchAfterQueryParameters searchAfterQueryParameters);
}
\ No newline at end of file
diff --git a/aspnetcore/src/Interface/Services/IInfrastructureService.cs b/aspnetcore/src/Interface/Services/IInfrastructureService.cs
index fb9e2ff..f5263be 100644
--- a/aspnetcore/src/Interface/Services/IInfrastructureService.cs
+++ b/aspnetcore/src/Interface/Services/IInfrastructureService.cs
@@ -6,5 +6,6 @@ namespace CSC.PublicApi.Interface.Services;
public interface IInfrastructureService
{
- Task<(IEnumerable, SearchResult)> GetInfrastructures(GetInfrastructuresQueryParameters queryParameters);
+ Task<(IEnumerable, SearchResult)> GetInfrastructures(GetInfrastructuresQueryParameters infrastructuresQueryParameters, PaginationQueryParameters paginationQueryParameters);
+ Task<(IEnumerable, SearchAfterResult)> GetInfrastructuresSearchAfter(GetInfrastructuresQueryParameters infrastructuresQueryParameters, SearchAfterQueryParameters searchAfterQueryParameters);
}
\ No newline at end of file
diff --git a/aspnetcore/src/Interface/Services/IOrganizationService.cs b/aspnetcore/src/Interface/Services/IOrganizationService.cs
index c9e3cc0..a10330a 100644
--- a/aspnetcore/src/Interface/Services/IOrganizationService.cs
+++ b/aspnetcore/src/Interface/Services/IOrganizationService.cs
@@ -6,5 +6,6 @@ namespace CSC.PublicApi.Interface.Services;
public interface IOrganizationService
{
- Task<(IEnumerable, SearchResult)> GetOrganizations(GetOrganizationsQueryParameters queryParameters);
+ Task<(IEnumerable, SearchResult)> GetOrganizations(GetOrganizationsQueryParameters organizationsQueryParameters, PaginationQueryParameters paginationQueryParameters);
+ Task<(IEnumerable, SearchAfterResult)> GetOrganizationsSearchAfter(GetOrganizationsQueryParameters organizationsQueryParameters, SearchAfterQueryParameters searchAfterQueryParameters);
}
\ No newline at end of file
diff --git a/aspnetcore/src/Interface/Services/IPublicationService.cs b/aspnetcore/src/Interface/Services/IPublicationService.cs
index 93d9adb..bdb0c16 100644
--- a/aspnetcore/src/Interface/Services/IPublicationService.cs
+++ b/aspnetcore/src/Interface/Services/IPublicationService.cs
@@ -6,7 +6,8 @@ namespace CSC.PublicApi.Interface.Services;
public interface IPublicationService
{
- Task<(IEnumerable, SearchResult)> GetPublications(GetPublicationsQueryParameters queryParameters);
+ Task<(IEnumerable, SearchResult)> GetPublications(GetPublicationsQueryParameters publicationsQueryParameters, PaginationQueryParameters paginationQueryParameters);
+ Task<(IEnumerable, SearchAfterResult)> GetPublicationsSearchAfter(GetPublicationsQueryParameters publicationsQueryParameters, SearchAfterQueryParameters searchAfterQueryParameters);
Task GetPublication(string publicationId);
}
\ No newline at end of file
diff --git a/aspnetcore/src/Interface/Services/IResearchDataSetService.cs b/aspnetcore/src/Interface/Services/IResearchDataSetService.cs
index 90ef97e..920417c 100644
--- a/aspnetcore/src/Interface/Services/IResearchDataSetService.cs
+++ b/aspnetcore/src/Interface/Services/IResearchDataSetService.cs
@@ -6,5 +6,6 @@ namespace CSC.PublicApi.Interface.Services;
public interface IResearchDatasetService
{
- Task<(IEnumerable, SearchResult)> GetResearchDatasets(GetResearchDatasetsQueryParameters queryParameters);
+ Task<(IEnumerable, SearchResult)> GetResearchDatasets(GetResearchDatasetsQueryParameters researchDatasetsQueryParameters, PaginationQueryParameters paginationQueryParameters);
+ Task<(IEnumerable, SearchAfterResult)> GetResearchDatasetsSearchAfter(GetResearchDatasetsQueryParameters researchDatasetsQueryParameters, SearchAfterQueryParameters searchAfterQueryParameters);
}
\ No newline at end of file
diff --git a/aspnetcore/src/Interface/Services/InfrastructureService.cs b/aspnetcore/src/Interface/Services/InfrastructureService.cs
index 8975882..9f1e4eb 100644
--- a/aspnetcore/src/Interface/Services/InfrastructureService.cs
+++ b/aspnetcore/src/Interface/Services/InfrastructureService.cs
@@ -19,12 +19,22 @@ public InfrastructureService(ILogger logger, IMapper mapp
_searchService = searchService;
}
- public async Task<(IEnumerable, SearchResult)> GetInfrastructures(GetInfrastructuresQueryParameters queryParameters)
+ public async Task<(IEnumerable, SearchResult)> GetInfrastructures(GetInfrastructuresQueryParameters infrastructuresQueryParameters, PaginationQueryParameters paginationQueryParameters)
{
- var searchParameters = _mapper.Map(queryParameters);
+ var searchParameters = _mapper.Map(infrastructuresQueryParameters);
- var (result, searchResult) = await _searchService.Search(searchParameters, queryParameters.PageNumber, queryParameters.PageSize);
+ var (result, searchResult) = await _searchService.Search(searchParameters, paginationQueryParameters.PageNumber, paginationQueryParameters.PageSize);
return (_mapper.Map>(result), searchResult);
}
+
+
+ public async Task<(IEnumerable, SearchAfterResult)> GetInfrastructuresSearchAfter(GetInfrastructuresQueryParameters infrastructuresQueryParameters, SearchAfterQueryParameters searchAfterQueryParameters)
+ {
+ var searchParameters = _mapper.Map(infrastructuresQueryParameters);
+
+ var (result, searchAfterResult) = await _searchService.SearchAfter(searchParameters, searchAfterQueryParameters.PageSize, searchAfterQueryParameters.NextPageToken);
+
+ return (_mapper.Map>(result), searchAfterResult);
+ }
}
\ No newline at end of file
diff --git a/aspnetcore/src/Interface/Services/OrganizationService.cs b/aspnetcore/src/Interface/Services/OrganizationService.cs
index c026e52..ee81691 100644
--- a/aspnetcore/src/Interface/Services/OrganizationService.cs
+++ b/aspnetcore/src/Interface/Services/OrganizationService.cs
@@ -19,12 +19,22 @@ public OrganizationService(ILogger logger, IMapper mapper,
_searchService = searchService;
}
- public async Task<(IEnumerable, SearchResult)> GetOrganizations(GetOrganizationsQueryParameters queryParameters)
+ public async Task<(IEnumerable, SearchResult)> GetOrganizations(GetOrganizationsQueryParameters organizationsQueryParameters, PaginationQueryParameters paginationQueryParameters)
{
- var searchParameters = _mapper.Map(queryParameters);
+ var searchParameters = _mapper.Map(organizationsQueryParameters);
- var (result, searchResult) = await _searchService.Search(searchParameters, queryParameters.PageNumber, queryParameters.PageSize);
+ var (result, searchResult) = await _searchService.Search(searchParameters, paginationQueryParameters.PageNumber, paginationQueryParameters.PageSize);
return (_mapper.Map>(result), searchResult);
}
+
+
+ public async Task<(IEnumerable, SearchAfterResult)> GetOrganizationsSearchAfter(GetOrganizationsQueryParameters organizationsQueryParameters, SearchAfterQueryParameters searchAfterQueryParameters)
+ {
+ var searchParameters = _mapper.Map(organizationsQueryParameters);
+
+ var (result, searchAfterResult) = await _searchService.SearchAfter(searchParameters, searchAfterQueryParameters.PageSize, searchAfterQueryParameters.NextPageToken);
+
+ return (_mapper.Map>(result), searchAfterResult);
+ }
}
\ No newline at end of file
diff --git a/aspnetcore/src/Interface/Services/PublicationService.cs b/aspnetcore/src/Interface/Services/PublicationService.cs
index e8532d4..2033b58 100644
--- a/aspnetcore/src/Interface/Services/PublicationService.cs
+++ b/aspnetcore/src/Interface/Services/PublicationService.cs
@@ -17,15 +17,24 @@ public PublicationService(IMapper mapper, ISearchService, SearchResult)> GetPublications(GetPublicationsQueryParameters queryParameters)
+ public async Task<(IEnumerable, SearchResult)> GetPublications(GetPublicationsQueryParameters publicationsQueryParameters, PaginationQueryParameters paginationQueryParameters)
{
- var searchParameters = _mapper.Map(queryParameters);
+ var searchParameters = _mapper.Map(publicationsQueryParameters);
- var (result, searchResult) = await _searchService.Search(searchParameters, queryParameters.PageNumber, queryParameters.PageSize);
+ var (result, searchResult) = await _searchService.Search(searchParameters, paginationQueryParameters.PageNumber, paginationQueryParameters.PageSize);
return (_mapper.Map>(result), searchResult);
}
+ public async Task<(IEnumerable, SearchAfterResult)> GetPublicationsSearchAfter(GetPublicationsQueryParameters publicationsQueryParameters, SearchAfterQueryParameters searchAfterQueryParameters)
+ {
+ var searchParameters = _mapper.Map(publicationsQueryParameters);
+
+ var (result, searchAfterResult) = await _searchService.SearchAfter(searchParameters, searchAfterQueryParameters.PageSize, searchAfterQueryParameters.NextPageToken);
+
+ return (_mapper.Map>(result), searchAfterResult);
+ }
+
public async Task GetPublication(string publicationId)
{
var result = await _searchService.GetSingle(publicationId);
diff --git a/aspnetcore/src/Interface/Services/ResearchDatasetService.cs b/aspnetcore/src/Interface/Services/ResearchDatasetService.cs
index deb7c2a..42a30ec 100644
--- a/aspnetcore/src/Interface/Services/ResearchDatasetService.cs
+++ b/aspnetcore/src/Interface/Services/ResearchDatasetService.cs
@@ -19,12 +19,21 @@ public ResearchDatasetService(ILogger logger, IMapper ma
_searchService = searchService;
}
- public async Task<(IEnumerable, SearchResult)> GetResearchDatasets(GetResearchDatasetsQueryParameters queryParameters)
+ public async Task<(IEnumerable, SearchResult)> GetResearchDatasets(GetResearchDatasetsQueryParameters researchDatasetsQueryParameters, PaginationQueryParameters paginationQueryParameters)
{
- var searchParameters = _mapper.Map(queryParameters);
+ var searchParameters = _mapper.Map(researchDatasetsQueryParameters);
- var (result, searchResult) = await _searchService.Search(searchParameters, queryParameters.PageNumber, queryParameters.PageSize);
+ var (result, searchResult) = await _searchService.Search(searchParameters, paginationQueryParameters.PageNumber, paginationQueryParameters.PageSize);
return (_mapper.Map>(result), searchResult);
}
+
+ public async Task<(IEnumerable, SearchAfterResult)> GetResearchDatasetsSearchAfter(GetResearchDatasetsQueryParameters queryParameters, SearchAfterQueryParameters searchAfterQueryParameters)
+ {
+ var searchParameters = _mapper.Map(queryParameters);
+
+ var (result, searchAfterResult) = await _searchService.SearchAfter(searchParameters, searchAfterQueryParameters.PageSize, searchAfterQueryParameters.NextPageToken);
+
+ return (_mapper.Map>(result), searchAfterResult);
+ }
}
\ No newline at end of file
diff --git a/aspnetcore/test/Interface.Tests/Configuration/IndexNameSettingsTest.cs b/aspnetcore/test/Interface.Tests/Configuration/IndexNameSettingsTest.cs
index 9fc6710..d506a03 100644
--- a/aspnetcore/test/Interface.Tests/Configuration/IndexNameSettingsTest.cs
+++ b/aspnetcore/test/Interface.Tests/Configuration/IndexNameSettingsTest.cs
@@ -2,6 +2,9 @@
using CSC.PublicApi.Service.Models.FundingCall;
using CSC.PublicApi.Service.Models.FundingDecision;
using CSC.PublicApi.Service.Models.ResearchDataset;
+using CSC.PublicApi.Service.Models.Publication;
+using CSC.PublicApi.Service.Models.Infrastructure;
+using CSC.PublicApi.Service.Models.Organization;
using FluentAssertions;
using Xunit;
@@ -16,32 +19,43 @@ public IndexNameSettingsTest()
_settings = new IndexNameSettings();
}
+ [Fact]
+ public void GetIndexNameForType_Publication_ShouldReturnIndexName()
+ {
+ // Arrange
+ _settings["CSC.PublicApi.Service.Models.Publication.Publication"] = "publication index name";
+
+ // Act
+ var actual = _settings.GetIndexNameForType(typeof(Publication));
+
+ // Assert
+ actual.Should().Be("publication index name");
+ }
+
[Fact]
public void GetIndexNameForType_FundingDecision_ShouldReturnIndexName()
{
// Arrange
- _settings["CSC.PublicApi.Service.Models.FundingDecision.FundingDecision"] = "some index name";
+ _settings["CSC.PublicApi.Service.Models.FundingDecision.FundingDecision"] = "funding decision index name";
// Act
var actual = _settings.GetIndexNameForType(typeof(FundingDecision));
// Assert
- actual.Should().Be("some index name");
-
+ actual.Should().Be("funding decision index name");
}
[Fact]
public void GetIndexNameForType_FundingCall_ShouldReturnIndexName()
{
// Arrange
- _settings["CSC.PublicApi.Service.Models.FundingCall.FundingCall"] = "some index name";
+ _settings["CSC.PublicApi.Service.Models.FundingCall.FundingCall"] = "funding call index name";
// Act
var actual = _settings.GetIndexNameForType(typeof(FundingCall));
// Assert
- actual.Should().Be("some index name");
-
+ actual.Should().Be("funding call index name");
}
[Fact]
@@ -55,6 +69,31 @@ public void GetIndexNameForType_ResearchDataset_ShouldReturnIndexName()
// Assert
actual.Should().Be("some index name");
+ }
+
+ [Fact]
+ public void GetIndexNameForType_Infrastructure_ShouldReturnIndexName()
+ {
+ // Arrange
+ _settings["CSC.PublicApi.Service.Models.Infrastructure.Infrastructure"] = "infrastructure index name";
+
+ // Act
+ var actual = _settings.GetIndexNameForType(typeof(Infrastructure));
+
+ // Assert
+ actual.Should().Be("infrastructure index name");
+ }
+ [Fact]
+ public void GetIndexNameForType_Organization_ShouldReturnIndexName()
+ {
+ // Arrange
+ _settings["CSC.PublicApi.Service.Models.Organization.Organization"] = "organization index name";
+
+ // Act
+ var actual = _settings.GetIndexNameForType(typeof(Service.Models.Organization.Organization));
+
+ // Assert
+ actual.Should().Be("organization index name");
}
}
\ No newline at end of file
diff --git a/aspnetcore/test/Interface.Tests/FundingCallControllerTest.cs b/aspnetcore/test/Interface.Tests/FundingCallControllerTest.cs
index 8392df7..ee65603 100644
--- a/aspnetcore/test/Interface.Tests/FundingCallControllerTest.cs
+++ b/aspnetcore/test/Interface.Tests/FundingCallControllerTest.cs
@@ -42,10 +42,11 @@ public void Get_PaginationWithSpecifiedParameters_IsSuccessful()
// Arrange
const int pageNumber = 7;
const int pageSize = 50;
- var queryParameters = new GetFundingCallQueryParameters { PageSize = pageSize, PageNumber = pageNumber };
+ var queryParameters = new GetFundingCallQueryParameters {};
+ var paginationQueryParameters = new PaginationQueryParameters { PageSize = pageSize, PageNumber = pageNumber };
// Act
- var result = _controller.Get(queryParameters);
+ var result = _controller.Get(queryParameters, paginationQueryParameters);
// Assert
result.Should().NotBeNull();
@@ -58,10 +59,11 @@ public void Get_PaginationWithNegativeValues_UseOneInstead()
// Arrange
const int pageNumber = -1;
const int pageSize = -5;
- var queryParameters = new GetFundingCallQueryParameters { PageSize = pageSize, PageNumber = pageNumber };
+ var queryParameters = new GetFundingCallQueryParameters {};
+ var paginationQueryParameters = new PaginationQueryParameters { PageSize = pageSize, PageNumber = pageNumber };
// Act
- var result = _controller.Get(queryParameters);
+ var result = _controller.Get(queryParameters, paginationQueryParameters);
// Assert
result.Should().NotBeNull();
@@ -76,7 +78,9 @@ public void Get_PaginationWithNoSpecifiedParameters_UsesDefaultValues()
const int defaultSize = 20;
// Act
- var result = _controller.Get(new GetFundingCallQueryParameters());
+ var result = _controller.Get(
+ new GetFundingCallQueryParameters(),
+ new PaginationQueryParameters());
// Assert
result.Should().NotBeNull();
@@ -90,10 +94,11 @@ public void Get_PaginationWithTooLargePageSize_SetsPageSizeToMaximum()
const int maximumPageSize = 100;
const int pageNumber = 7;
const int pageSize = 150;
- var queryParameters = new GetFundingCallQueryParameters { PageSize = pageSize, PageNumber = pageNumber };
+ var queryParameters = new GetFundingCallQueryParameters {};
+ var paginationQueryParameters = new PaginationQueryParameters { PageSize = pageSize, PageNumber = pageNumber };
// Act
- var result = _controller.Get(queryParameters);
+ var result = _controller.Get(queryParameters, paginationQueryParameters);
// Assert
result.Should().NotBeNull();