using System.Threading.Tasks; using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Routing; using Microsoft.Extensions.Logging; using Microsoft.AspNetCore.Authorization; using Sockeye.Models; using Sockeye.Api.ControllerHelpers; using Sockeye.Biz; using Newtonsoft.Json.Linq; namespace Sockeye.Api.Controllers { /// /// /// [ApiController] [ApiVersion("8.0")] [Route("api/v{version:apiVersion}/tag-list")] [Produces("application/json")] [Authorize] public class TagController : ControllerBase { private readonly AyContext ct; private readonly ILogger log; private readonly ApiServerState serverState; /// /// ctor /// /// /// /// public TagController(AyContext dbcontext, ILogger logger, ApiServerState apiServerState) { ct = dbcontext; log = logger; serverState = apiServerState; } /// /// Get tag list /// /// The query to filter the returned list by /// Filtered list (maximum 25 items are returned for any query) [HttpGet("list")] public async Task GetList([FromQuery] string query) { if (serverState.IsClosed) return StatusCode(503, new ApiErrorResponse(serverState.ApiErrorCode, null, serverState.Reason)); return Ok(ApiOkResponse.Response(await TagBiz.TagListFilteredAsync(ct, query))); } /// /// Get tag cloud list /// /// The query to filter the returned list by /// List [HttpGet("cloudlist")] public async Task GetCloudList([FromQuery] string query) { if (serverState.IsClosed) return StatusCode(503, new ApiErrorResponse(serverState.ApiErrorCode, null, serverState.Reason)); return Ok(ApiOkResponse.Response(await TagBiz.CloudListFilteredAsync(ct, query))); } ///////////////////////////////////////////////////////////// //BATCH OPS // // /// /// Batch add tags to list of object id's specified /// /// /// /// Job Id [HttpPost("batch-add/{tag}")] public async Task BatchAdd([FromRoute] string tag, [FromBody] DataListSelectedRequest selectedRequest) { if (!serverState.IsOpen) return StatusCode(503, new ApiErrorResponse(serverState.ApiErrorCode, null, serverState.Reason)); if (!ModelState.IsValid) return BadRequest(new ApiErrorResponse(ModelState)); if (!selectedRequest.SockType.HasAttribute(typeof(CoreBizObjectAttribute))) return BadRequest(new ApiErrorResponse(ApiErrorCode.INVALID_OPERATION, null, "Not a taggable object type")); if (!Authorized.HasModifyRole(HttpContext.Items, selectedRequest.SockType)) return StatusCode(403, new ApiNotAuthorizedResponse()); tag = TagBiz.NormalizeTag(tag); if (string.IsNullOrWhiteSpace(tag)) return BadRequest(new ApiErrorResponse(ApiErrorCode.VALIDATION_REQUIRED, null, "tag required")); //Rehydrate id list if necessary if (selectedRequest.SelectedRowIds.Length == 0) selectedRequest.SelectedRowIds = await DataListSelectedProcessingOptions.RehydrateIdList( selectedRequest, ct, UserRolesFromContext.Roles(HttpContext.Items), log, UserIdFromContext.Id(HttpContext.Items), UserTranslationIdFromContext.Id(HttpContext.Items)); var JobName = $"LT:BatchJob LT:Add LT:Tag \"{tag}\" LT:{selectedRequest.SockType} ({selectedRequest.SelectedRowIds.LongLength}) LT:User {UserNameFromContext.Name(HttpContext.Items)}"; JObject o = JObject.FromObject(new { idList = selectedRequest.SelectedRowIds, tag = tag }); OpsJob j = new OpsJob(); j.Name = JobName; j.SockType = selectedRequest.SockType; j.JobType = JobType.BatchCoreObjectOperation; j.SubType = JobSubType.TagAdd; j.Exclusive = false; j.JobInfo = o.ToString(); await JobsBiz.AddJobAsync(j); await EventLogProcessor.LogEventToDatabaseAsync(new Event(UserIdFromContext.Id(HttpContext.Items), 0, SockType.ServerJob, SockEvent.Created, JobName), ct); return Accepted(new { JobId = j.GId }); } /// /// Batch add tags to all objects of type specified /// /// /// /// Job Id [HttpPost("batch-add-any/{sockType}/{tag}")] public async Task BatchAddAny([FromRoute] SockType sockType, [FromRoute] string tag) { if (!serverState.IsOpen) return StatusCode(503, new ApiErrorResponse(serverState.ApiErrorCode, null, serverState.Reason)); if (!ModelState.IsValid) return BadRequest(new ApiErrorResponse(ModelState)); if (!sockType.HasAttribute(typeof(CoreBizObjectAttribute))) return BadRequest(new ApiErrorResponse(ApiErrorCode.INVALID_OPERATION, null, "Not a taggable object type")); if (!Authorized.HasModifyRole(HttpContext.Items, sockType)) return StatusCode(403, new ApiNotAuthorizedResponse()); tag = TagBiz.NormalizeTag(tag); if (string.IsNullOrWhiteSpace(tag)) return BadRequest(new ApiErrorResponse(ApiErrorCode.VALIDATION_REQUIRED, null, "tag")); var JobName = $"LT:BatchJob LT:Add LT:Tag \"{tag}\" LT:{sockType.ToString()} (LT:GridRowFilterDropDownAllItem) LT:User {UserNameFromContext.Name(HttpContext.Items)}"; JObject o = JObject.FromObject(new { tag = tag }); OpsJob j = new OpsJob(); j.Name = JobName; j.SockType = sockType; j.JobType = JobType.BatchCoreObjectOperation; j.SubType = JobSubType.TagAddAny; j.Exclusive = false; j.JobInfo = o.ToString(); await JobsBiz.AddJobAsync(j); await EventLogProcessor.LogEventToDatabaseAsync(new Event(UserIdFromContext.Id(HttpContext.Items), 0, SockType.ServerJob, SockEvent.Created, JobName), ct); return Accepted(new { JobId = j.GId }); } /// /// Batch remove tags to list of object id's specified /// /// /// /// Job Id [HttpPost("batch-remove/{tag}")] public async Task BatchRemove([FromRoute] string tag, [FromBody] DataListSelectedRequest selectedRequest) { if (!serverState.IsOpen) return StatusCode(503, new ApiErrorResponse(serverState.ApiErrorCode, null, serverState.Reason)); if (!ModelState.IsValid) return BadRequest(new ApiErrorResponse(ModelState)); if (!selectedRequest.SockType.HasAttribute(typeof(CoreBizObjectAttribute))) return BadRequest(new ApiErrorResponse(ApiErrorCode.INVALID_OPERATION, null, "Not a taggable object type")); if (!Authorized.HasModifyRole(HttpContext.Items, selectedRequest.SockType)) return StatusCode(403, new ApiNotAuthorizedResponse()); tag = TagBiz.NormalizeTag(tag); if (string.IsNullOrWhiteSpace(tag)) return BadRequest(new ApiErrorResponse(ApiErrorCode.VALIDATION_REQUIRED, null, "tag")); //Rehydrate id list if necessary if (selectedRequest.SelectedRowIds.Length == 0) selectedRequest.SelectedRowIds = await DataListSelectedProcessingOptions.RehydrateIdList( selectedRequest, ct, UserRolesFromContext.Roles(HttpContext.Items), log, UserIdFromContext.Id(HttpContext.Items), UserTranslationIdFromContext.Id(HttpContext.Items)); var JobName = $"LT:BatchJob LT:Remove LT:Tag \"{tag}\" LT:{selectedRequest.SockType} ({selectedRequest.SelectedRowIds.LongLength}) LT:User {UserNameFromContext.Name(HttpContext.Items)}"; JObject o = JObject.FromObject(new { idList = selectedRequest.SelectedRowIds, tag = tag }); OpsJob j = new OpsJob(); j.Name = JobName; j.SockType = selectedRequest.SockType; j.JobType = JobType.BatchCoreObjectOperation; j.SubType = JobSubType.TagRemove; j.Exclusive = false; j.JobInfo = o.ToString(); await JobsBiz.AddJobAsync(j); await EventLogProcessor.LogEventToDatabaseAsync(new Event(UserIdFromContext.Id(HttpContext.Items), 0, SockType.ServerJob, SockEvent.Created, JobName), ct); return Accepted(new { JobId = j.GId }); } /// /// Batch remove tags to all objects of type specified /// /// /// /// Job Id [HttpPost("batch-remove-any/{sockType}/{tag}")] public async Task BatchRemoveAny([FromRoute] SockType sockType, [FromRoute] string tag) { if (!serverState.IsOpen) return StatusCode(503, new ApiErrorResponse(serverState.ApiErrorCode, null, serverState.Reason)); if (!ModelState.IsValid) return BadRequest(new ApiErrorResponse(ModelState)); if (!sockType.HasAttribute(typeof(CoreBizObjectAttribute))) return BadRequest(new ApiErrorResponse(ApiErrorCode.INVALID_OPERATION, null, "Not a taggable object type")); if (!Authorized.HasModifyRole(HttpContext.Items, sockType)) return StatusCode(403, new ApiNotAuthorizedResponse()); tag = TagBiz.NormalizeTag(tag); if (string.IsNullOrWhiteSpace(tag)) return BadRequest(new ApiErrorResponse(ApiErrorCode.VALIDATION_REQUIRED, null, "tag")); var JobName = $"LT:BatchJob LT:Remove LT:Tag \"{tag}\" LT:{sockType.ToString()} (LT:GridRowFilterDropDownAllItem) LT:User {UserNameFromContext.Name(HttpContext.Items)}"; JObject o = JObject.FromObject(new { tag = tag }); OpsJob j = new OpsJob(); j.Name = JobName; j.SockType = sockType; j.SubType = JobSubType.TagRemoveAny; j.JobType = JobType.BatchCoreObjectOperation; j.Exclusive = false; j.JobInfo = o.ToString(); await JobsBiz.AddJobAsync(j); await EventLogProcessor.LogEventToDatabaseAsync(new Event(UserIdFromContext.Id(HttpContext.Items), 0, SockType.ServerJob, SockEvent.Created, JobName), ct); return Accepted(new { JobId = j.GId }); } /// /// Batch replace tags to list of object id's specified /// /// /// /// /// Job Id [HttpPost("batch-replace/{fromTag}")] public async Task BatchReplace([FromRoute] string fromTag, [FromQuery] string toTag, [FromBody] DataListSelectedRequest selectedRequest) { if (!serverState.IsOpen) return StatusCode(503, new ApiErrorResponse(serverState.ApiErrorCode, null, serverState.Reason)); if (!ModelState.IsValid) return BadRequest(new ApiErrorResponse(ModelState)); if (!selectedRequest.SockType.HasAttribute(typeof(CoreBizObjectAttribute))) return BadRequest(new ApiErrorResponse(ApiErrorCode.INVALID_OPERATION, null, "Not a taggable object type")); if (!Authorized.HasModifyRole(HttpContext.Items, selectedRequest.SockType)) return StatusCode(403, new ApiNotAuthorizedResponse()); fromTag = TagBiz.NormalizeTag(fromTag); if (string.IsNullOrWhiteSpace(fromTag)) return BadRequest(new ApiErrorResponse(ApiErrorCode.VALIDATION_REQUIRED, null, "fromTag")); toTag = TagBiz.NormalizeTag(toTag); if (string.IsNullOrWhiteSpace(toTag)) return BadRequest(new ApiErrorResponse(ApiErrorCode.VALIDATION_REQUIRED, null, "toTag")); //Rehydrate id list if necessary if (selectedRequest.SelectedRowIds.Length == 0) selectedRequest.SelectedRowIds = await DataListSelectedProcessingOptions.RehydrateIdList( selectedRequest, ct, UserRolesFromContext.Roles(HttpContext.Items), log, UserIdFromContext.Id(HttpContext.Items), UserTranslationIdFromContext.Id(HttpContext.Items)); var JobName = $"LT:BatchJob LT:Replace LT:Tag \"{fromTag}\" -> LT:Tag \"{toTag}\" LT:{selectedRequest.SockType} ({selectedRequest.SelectedRowIds.LongLength}) LT:User {UserNameFromContext.Name(HttpContext.Items)}"; JObject o = JObject.FromObject(new { idList = selectedRequest.SelectedRowIds, tag = fromTag, toTag = toTag }); OpsJob j = new OpsJob(); j.SockType = selectedRequest.SockType; j.Name = JobName; j.JobType = JobType.BatchCoreObjectOperation; j.SubType = JobSubType.TagReplace; j.Exclusive = false; j.JobInfo = o.ToString(); await JobsBiz.AddJobAsync(j); await EventLogProcessor.LogEventToDatabaseAsync(new Event(UserIdFromContext.Id(HttpContext.Items), 0, SockType.ServerJob, SockEvent.Created, JobName), ct); return Accepted(new { JobId = j.GId }); } /// /// Batch replace tags to all objects of type specified /// /// /// /// /// Job Id [HttpPost("batch-replace-any/{sockType}/{fromTag}")] public async Task BatchReplaceAny([FromRoute] SockType sockType, [FromRoute] string fromTag, [FromQuery] string toTag) { if (!serverState.IsOpen) return StatusCode(503, new ApiErrorResponse(serverState.ApiErrorCode, null, serverState.Reason)); if (!ModelState.IsValid) return BadRequest(new ApiErrorResponse(ModelState)); if (!sockType.HasAttribute(typeof(CoreBizObjectAttribute))) return BadRequest(new ApiErrorResponse(ApiErrorCode.INVALID_OPERATION, null, "Not a taggable object type")); if (!Authorized.HasModifyRole(HttpContext.Items, sockType)) return StatusCode(403, new ApiNotAuthorizedResponse()); fromTag = TagBiz.NormalizeTag(fromTag); if (string.IsNullOrWhiteSpace(fromTag)) return BadRequest(new ApiErrorResponse(ApiErrorCode.VALIDATION_REQUIRED, null, "fromTag")); toTag = TagBiz.NormalizeTag(toTag); if (string.IsNullOrWhiteSpace(toTag)) return BadRequest(new ApiErrorResponse(ApiErrorCode.VALIDATION_REQUIRED, null, "toTag")); var JobName = $"LT:BatchJob LT:Replace LT:Tag \"{fromTag}\" -> LT:Tag \"{toTag}\" LT:{sockType.ToString()} (LT:GridRowFilterDropDownAllItem) LT:User {UserNameFromContext.Name(HttpContext.Items)}"; JObject o = JObject.FromObject(new { tag = fromTag, toTag = toTag }); OpsJob j = new OpsJob(); j.Name = JobName; j.SockType = sockType; j.JobType = JobType.BatchCoreObjectOperation; j.SubType = JobSubType.TagReplaceAny; j.Exclusive = false; j.JobInfo = o.ToString(); await JobsBiz.AddJobAsync(j); await EventLogProcessor.LogEventToDatabaseAsync(new Event(UserIdFromContext.Id(HttpContext.Items), 0, SockType.ServerJob, SockEvent.Created, JobName), ct); return Accepted(new { JobId = j.GId }); } }//eoc }//ens