private void ExpiredAiringDelieryTest() { IAiringService airingService = _fixture.Container.GetInstance <IAiringService>(); foreach (var expiredAiring in _processedAirings) { if (!expiredAiring.UnExpectedQueues.Any()) { continue; } var airing = airingService.GetBy(expiredAiring.AiringId, expiredAiring.IsDeleted ? AiringCollection.DeletedCollection : AiringCollection.CurrentOrExpiredCollection); foreach (var queueName in expiredAiring.UnExpectedQueues) { if (airing.DeliveredTo.Contains(queueName)) { var failureMessage = string.Format("{0}. Airing {1} should not delivered to queue {2}", expiredAiring.TestName, expiredAiring.AiringId, queueName); expiredAiring.AddMessage(failureMessage, true); expiredAiring.HasQueueDeliveryError = true; Assert.True(false, failureMessage); } else { expiredAiring.AddMessage(string.Format("Airing not delivered to Queue {0}", queueName)); } } } }
private void ProhibitResendMediaIdTest() { IAiringService airingService = _fixture.Container.GetInstance <IAiringService>(); foreach (var activeAiring in _processedAirings) { if (!activeAiring.IgnoredQueues.Any()) { continue; } var airing = airingService.GetBy(activeAiring.AiringId, activeAiring.IsDeleted ? AiringCollection.DeletedCollection : AiringCollection.CurrentOrExpiredCollection); foreach (var ignoredQueue in activeAiring.IgnoredQueues) { if (!airing.IgnoredQueues.Contains(ignoredQueue)) { var failureMessage = string.Format("{0}. Airing {1} not added to ignored queue {2}", activeAiring.TestName, activeAiring.AiringId, ignoredQueue); activeAiring.HasQueueDeliveryError = true; Assert.True(false, failureMessage); } else { activeAiring.AddMessage(string.Format("Airing successfully delivered to Ignored Queue {0}", ignoredQueue)); } } } }
public Mailbox(AppSettings appsettings, Serilog.ILogger logger, IAiringService _airingSvc) { this.appsettings = appsettings; this.logger = logger; airingSvc = _airingSvc; TimeZoneInfo = TimeZoneInfo.FindSystemTimeZoneById(appsettings.JobSchedules.TimeZone); }
public EnvelopeDistributor( IQueueReporterService queueReporter, IQueueService queueService, IAiringService airingService) { _reporter = queueReporter; _queueService = queueService; _airingService = airingService; }
public EncodingFileContentValidator(IAiringService airingSvc) { _airingSvc = airingSvc; // Verify if the main field: media-id is provided RuleFor(request => request.MediaId). NotEmpty().WithMessage("media-id required"); // Verify that airing id is provided // Verify that the given AiringId exist Func <String, bool> airingIdExistRule = new Func <String, bool>((airingId) => { if (String.IsNullOrEmpty(airingId)) { return(false); } return((_airingSvc.GetBy(airingId) == null) ? false : true); }); RuleFor(c => c.AiringId) .Must(airingIdExistRule) .WithMessage("AiringId {0} doesn't exist", c => c.AiringId); //Verify that required data points are provided RuleFor(request => request.RootId).NotEmpty().WithMessage("root-id required"); // Only apply the remaining validation if mediaid is provided When(x => !String.IsNullOrWhiteSpace(x.MediaId), () => { // Verify that the given MediaId exist Func <String, bool> mediaIdExistRule = new Func <String, bool>((mediaId) => { return((_airingSvc.GetByMediaId(mediaId).IsNullOrEmpty()) ? false : true); }); RuleFor(c => c.MediaId) .Must(mediaIdExistRule) .WithMessage("MediaId {0} doesn't exist", c => c.MediaId); // Verify that outputs property is provided RuleFor(c => c.MediaCollection) .NotEmpty() .WithMessage("Output property required and cannot be empty"); // Apply content segment validation if output is provided When(x => !x.MediaCollection.IsNullOrEmpty(), () => { // Apply content segment validation rule SetContentSegmentsRule(); }); }); }
public DeliveryQueueController(IQueueService queueSvc, AppSettings appsettings, IRemoteQueueHandler remoteQueueHandler, IAiringService airingSvc, IHangfireRecurringJobCommand hangfireCommand ) { this.appsettings = appsettings; _queueSvc = queueSvc; _airingService = airingSvc; this.remoteQueueHandler = remoteQueueHandler; this.hangfireCommand = hangfireCommand; }
private void ActiveAiringDeliveryTest() { IAiringService airingService = _fixture.Container.GetInstance <IAiringService>(); foreach (var activeAiring in _processedAirings) { if (!activeAiring.ExpectedQueues.Any()) { continue; } var airing = airingService.GetBy(activeAiring.AiringId, activeAiring.IsDeleted ? AiringCollection.DeletedCollection : AiringCollection.CurrentOrExpiredCollection); if (!_dfStatusService.HasMessages(activeAiring.AiringId, !activeAiring.IsDeleted)) { activeAiring.HasQueueDeliveryError = true; Assert.True(false, activeAiring.IsDeleted ? string.Format( "Airing {0}, DF messages added to current collection instead of Expired/Deleted collection", activeAiring.AiringId) : string.Format( "Airing {0}, DF messages added to expired collection instead of active collection", activeAiring.AiringId)); } foreach (var expectedQueue in activeAiring.ExpectedQueues) { if (!airing.DeliveredTo.Contains(expectedQueue)) { var failureMessage = string.Format("{0}. Airing {1} not delivered to queue {2}", activeAiring.TestName, activeAiring.AiringId, expectedQueue); activeAiring.AddMessage(failureMessage, true); activeAiring.HasQueueDeliveryError = true; Assert.True(false, failureMessage); } else { activeAiring.AddMessage(string.Format("Airing successfully delivered to Queue {0}", expectedQueue)); } } } }
public void GetAiringwithOptionChange_InitialReleaseTest() { //Prepare IAiringService airingService = fixture.container.GetInstance <IAiringService>(); var airingPost = JObject.Parse(Resources.AiringBusinessResource.ResourceManager.GetString("TBSEHistoryInitial")).ToObject <Modules.Airing.Model.Airing>(); var savedAiringObj = airingService.Save(airingPost, false, true); JObject jsonObject = JObject.Parse(Resources.AiringBusinessResource.ResourceManager.GetString("TBSEAiring")); jsonObject.Add("AiringId", savedAiringObj.AssetId); var businessAiring = jsonObject.ToObject <Modules.Airing.Model.Alternate.Long.Airing>(); //Act airingService.AppendChanges(ref businessAiring); //Assert Assert.True(businessAiring.Options.Changes.Count > 0, string.Format("The value returned for change should be 'New Release' but it is returned as {0}", businessAiring.Options.Changes[0].TheChange)); }
public void GetAiringwithOptionChange_FlightEndDateModifiedTest() { //Prepare IAiringService airingService = fixture.container.GetInstance <IAiringService>(); var airingPost = JObject.Parse(Resources.AiringBusinessResource.ResourceManager.GetString("TBSEHistoryWithFightDateModified")).ToObject <Modules.Airing.Model.Airing>(); var savedAiringObj = airingService.Save(airingPost, false, true); JObject jsonObject = JObject.Parse(Resources.AiringBusinessResource.ResourceManager.GetString("TBSEAiring")); jsonObject.Add("AiringId", savedAiringObj.AssetId); var businessAiring = jsonObject.ToObject <Modules.Airing.Model.Alternate.Long.Airing>(); //Act airingService.AppendChanges(ref businessAiring); //Assert Assert.True(businessAiring.Options.Changes.Any(e => e.TheChange == "Flights's End"), "Flight End change not found."); }
private bool IsAiringIdDelvieredToQueue() { IQueueService queueService = _fixture.Container.GetInstance <IQueueService>(); var deliveryQueue = queueService.GetByApiKey(_tbsQueueKey); if (deliveryQueue == null) { Assert.True(false, string.Format("Unit test delivery queue not found: API Key {0}", _tbsQueueKey)); } queueService.Unlock(deliveryQueue.Name); _publisher.Execute(deliveryQueue.Name); IAiringService airingService = _fixture.Container.GetInstance <IAiringService>(); var airing = airingService.GetBy(_airingId); return(airing.DeliveredTo.Contains(_tbsQueueKey)); }
public void VerifyDeporterJobTest() { //Prepare IAiringService airingService = fixture.Container.GetInstance <IAiringService>(); IAiringUnitTestService airingUnitTestService = fixture.Container.GetInstance <IAiringUnitTestService>(); var dfStatusService = fixture.Container.GetInstance <IDfStatusService>(); JObject airingJson = JObject.Parse(Resources.Resources.ResourceManager.GetString("TBSAiringWithSingleFlight")); JObject response = new JObject(); var request = new RestRequest("/v1/airing/TBSE", Method.POST); request.AddParameter("application/json", UpdateAiringDates(airingJson), ParameterType.RequestBody); Task.Run(async() => { response = await _client.RetrieveRecord(request); }).Wait(); string airingId = response.Value <string>(@"airingId"); airingUnitTestService.UpdateAiringRelasedDateAndFlightEndDate(airingId, DateTime.UtcNow.AddDays(-3)); //Act airingService.Deport(int.Parse(fixture.Configuration["AiringDeportGraceDays"])); //Assert BLModel.Airing expiredairingModel = airingService.GetBy(airingId, AiringCollection.ExpiredCollection); if (expiredairingModel == null) { Assert.True(false, "Deporter Airing test Failed : Airing is not returned from Expired Collection : " + expiredairingModel.AssetId); } if (dfStatusService.HasMessages(airingId, true)) { Assert.True(false, string.Format("Deporter Airing test Failed : Airing {0} DF messages not moved to Expired Collection.", expiredairingModel.AssetId)); } }
public Publisher( Serilog.ILogger logger, AppSettings appsettings, IQueueService queueService, IAiringService airingService, IEnvelopeDistributor envelopeDistributor, IEnvelopeStuffer envelopeStuffer, IQueueReporterService reportStatusCommand, IMessageDeliveryValidator messageDeliveryValidator, BimContentValidator bimContentValidator, MediaIdValidator mediaIdValidator) { this.logger = logger; this.queueService = queueService; this.airingService = airingService; processId = GetProcessId(); this.envelopeDistributor = envelopeDistributor; this.envelopeStuffer = envelopeStuffer; this.reportStatusCommand = reportStatusCommand; this.messageDeliveryValidator = messageDeliveryValidator; this.bimContentValidator = bimContentValidator; this.mediaIdValidator = mediaIdValidator; this.appsettings = appsettings; }
public FileRoutes( IQueueService queueSvc, IFileService fileSvc, FileValidator fileValidator, IReportingService reporter, IAiringService airingSvc) : base("v1") { this.RequiresAuthentication(); this.queueSvc = queueSvc; this.fileSvc = fileSvc; this.fileValidator = fileValidator; this.reporter = reporter; this.airingSvc = airingSvc; Get("/files/title/{titleId}", _ => { this.RequiresClaims(c => c.Type == HttpMethod.Get.Verb()); var files = fileSvc.GetByTitleId((int)_.titleId); return(files.ToViewModel <List <BLFileModel.File>, List <Models.Airing.Long.File> >()); }); Get("/files/airing/{airingId}", _ => { this.RequiresClaims(c => c.Type == HttpMethod.Get.Verb()); var files = fileSvc.GetByAiringId((string)_.airingId); return(files.ToViewModel <List <BLFileModel.File>, List <Models.Airing.Long.File> >()); }); Post("/files", _ => { // Verify if the user has post permission this.RequiresClaims(c => c.Type == HttpMethod.Post.Verb()); var k = this.Request.Body.ToString(); // Bind POST request to data contract var newFiles = this.Bind <List <RQModel.FileViewModel> >(); // Validate files List <ValidationResult> results = ValidateFiles(newFiles); // Verify if there are any validation errors. If so, return error if (results.Where(c => (!c.IsValid)).Count() > 0) { // Report status to monitoring system ReportStatusToMonitoringSystem(newFiles, "Ingestion of file data failed due to validation errors in payload"); // Return status return(Negotiate.WithModel(results.Where(c => (!c.IsValid)).Select(c => c.Errors.Select(d => d.ErrorMessage))) .WithStatusCode(HttpStatusCode.BadRequest)); } // Translate data contract to file business model var files = Mapper.Map <List <RQModel.FileViewModel>, List <BLFileModel.File> >(newFiles); // Persist the files fileSvc.Save(files); // Inform subscriber queues that are listening // for file notification changes ResetFileQueues(files); // Report status to monitoring system ReportStatusToMonitoringSystem(newFiles, "Successfully ingested file data"); // Return Status return(Response.AsJson(new { result = "success" }, HttpStatusCode.OK)); }); }
public HandlerRoutes( IAiringService airingSvc, IDestinationService destinationSvc, IPathingService pathingSvc, IFileService fileSvc, IHandlerHistoryService handlerHistorySvc, IQueueService queueSvc, IReportingService reporterSvc, EncodingFileContentValidator encodingFileValidator, Serilog.ILogger logger ) : base("v1") { _airingSvc = airingSvc; _destinationSvc = destinationSvc; _pathingSvc = pathingSvc; _fileSvc = fileSvc; _handlerHistorySvc = handlerHistorySvc; _queueSvc = queueSvc; _encodingFileValidator = encodingFileValidator; _reporterSvc = reporterSvc; _logger = logger; /// Persist Encoding related data through POST operation. /// The correlation between an existing airing and the provided payload /// is performed using the provided odt-media-id data point. As a result, /// odt-media-id is a required field in the payload. Post("/handler/encoding", _ => { BLFileModel.File file = default(BLFileModel.File); try { // Perform preliminary authorization this.RequiresAuthentication(); this.RequiresClaims(c => c.Type == HttpMethod.Post.Verb()); // Deserealize JSON request to DataContracts. EncodingFileContentViewModel encodingPayLoad = this.Bind <EncodingFileContentViewModel>(); // Retrieve encoding destination details DF_ENCOM_DESTINATION_CODE = _destinationSvc.GetByDestinationNames(new List <String> { "ENCOM" }).First().ExternalId; // Persist encoding raw JSON data before proceeding this.Request.Body.Seek(0, SeekOrigin.Begin); _handlerHistorySvc.Save(this.Request.Body.AsString(), encodingPayLoad.MediaId); // Validate provided data contract. If validation errors are found // then inform user, else continue var validationResult = _encodingFileValidator.Validate(encodingPayLoad); if (!validationResult.IsValid) { // Report error status (for encoding destination) to monitoring system ReportStatusToMonitoringSystem(encodingPayLoad.MediaId, "Ingestion of encoding data failed due to validation errors in payload", DF_ERROR_STATUS_CODE, DF_ENCOM_DESTINATION_CODE); // Return status return(Negotiate.WithModel(validationResult.Errors.Select(c => c.ErrorMessage)) .WithStatusCode(HttpStatusCode.BadRequest)); } ApplyPathTranslationInformation(encodingPayLoad); // Translate DataContracts to Business Models file = encodingPayLoad.ToBusinessModel <EncodingFileContentViewModel, BLFileModel.File>(); // Perform CRUD _fileSvc.PersistVideoFile(file); // Send notification to all subscribed consumers SendNotification(file); // Report completed status (for Encoding destination) to monitoring system ReportStatusToMonitoringSystem(file.MediaId, "Successfully ingested encoding data", DF_COMPLETED_STATUS_CODE, DF_ENCOM_DESTINATION_CODE); // Return return(Response.AsJson(new { result = "success" }, HttpStatusCode.OK)); } catch (Exception ex) { // Log error logger.Error(ex, ex.Message); throw; } }); }
public FileValidator(IAiringService airingSvc) { this.airingSvc = airingSvc; // Apply video specific file validation RuleSet("Video", () => { /// <summary> /// This validation checks if content segment(s) specified /// in the payload (# of entries in 'contents' array) should match that of the airing. /// That is, # of elements in 'contents' array should match with the # of elements in ‘version’ array for the airing /// </summary> int contentSegmentsCount = default(int); Func <FileViewModel, List <FileContentViewModel>, bool> contentSegmentsMatchRule = new Func <FileViewModel, List <FileContentViewModel>, bool>((request, filec) => { // If the mediaid is provided then do content segment validation using that. If the provided mediaid doesn't exist // then set content segment count to 0 if (!request.MediaId.IsNullOrEmpty()) { var query = this.airingSvc.GetByMediaId(request.MediaId); contentSegmentsCount = (query.IsNullOrEmpty()) ? 0 : query.FirstOrDefault().Versions.Count(); return((filec.Count() != contentSegmentsCount) ? false : true); } else if (!request.AiringId.IsNullOrEmpty()) { try { var airing = this.airingSvc.GetBy(request.AiringId); contentSegmentsCount = (airing == null) ? 0 : airing.Versions.Count(); return((filec.Count() != contentSegmentsCount) ? false : true); } catch (Exception) { //if it throws and exception during Get, throw a validation error return(false); } } else if (request.TitleId.HasValue) { //var airing = airingSvc.GetNonExpiredBy(request.TitleId.Value, DateTime.MinValue); //contentSegmentsCount = (airing == null) ? 0 : airing.FirstOrDefault().Versions.Count(); //return ((filec.Count() != contentSegmentsCount) ? false : true); return(true); } // return false if none of the above criteria matches return(false); }); Func <FileViewModel, List <FileContentViewModel>, object> contentCount = new Func <FileViewModel, List <FileContentViewModel>, object>((request, filec) => { return(contentSegmentsCount); }); // Verify that required data points are provided RuleFor(c => c) .Cascade(CascadeMode.StopOnFirstFailure) .Must(c => !(string.IsNullOrEmpty(c.AiringId) && string.IsNullOrEmpty(c.MediaId) && !c.TitleId.HasValue)) .WithMessage("AiringId, MediaId or TitleId is required") .Must(c => OnlyOneTrue(new bool[] { !string.IsNullOrEmpty(c.AiringId), !string.IsNullOrEmpty(c.MediaId), c.TitleId.HasValue })) .WithMessage("Either provide AiringId, MediaId or TitleId but not more than one") .DependentRules(dr => { // Apply the following validation if AiringId is not empty and MediaId is empty dr.When(x => (!String.IsNullOrWhiteSpace(x.AiringId) && String.IsNullOrWhiteSpace(x.MediaId)), () => { // Verify that the given AiringId exist Func <String, bool> airingIdExistRule = new Func <String, bool>((airingId) => { return(this.airingSvc.IsAiringExists(airingId)); }); dr.RuleFor(c => c.AiringId) .Cascade(CascadeMode.StopOnFirstFailure) .Must(airingIdExistRule) .WithMessage("AiringId {0} doesn't exist/expired.", c => c.MediaId) .DependentRules(o => { o.RuleFor(ox => ox.Contents) .Cascade(CascadeMode.StopOnFirstFailure) .NotEmpty() .WithMessage("Contents property required and cannot be empty when posting video payload by airing-id") .Must(contentSegmentsMatchRule) .WithMessage("Content segments provided in payload doesn't match with that of media/airing. Payload contains {0} content segments (# of items in 'contents' array), while media/airing contains {1} content segments", (request, mediac) => mediac.Count(), contentCount) .DependentRules(ox => { ox.RuleForEach(xo => xo.Contents) .SetValidator(new FileContentValidator()); }); }); }); // Apply the following validation if MediaId is provided dr.When(x => !String.IsNullOrWhiteSpace(x.MediaId), () => { // Verify that the given MediaId exist Func <String, bool> mediaIdExistRule = new Func <String, bool>((mediaId) => { return((airingSvc.GetByMediaId(mediaId).IsNullOrEmpty()) ? false : true); }); dr.RuleFor(c => c.MediaId) .Cascade(CascadeMode.StopOnFirstFailure) .Must(mediaIdExistRule) .WithMessage("MediaId {0} doesn't exist", c => c.MediaId) .DependentRules(oxx => { oxx.RuleFor(ox => ox.Contents) .Cascade(CascadeMode.StopOnFirstFailure) .NotEmpty() .WithMessage("Contents property required and cannot be empty when posting video payload by media-id") .Must(contentSegmentsMatchRule) .WithMessage("Content segments provided in payload doesn't match with that of media/airing. Payload contains {0} content segments (# of items in 'contents' array), while media/airing contains {1} content segments", (request, mediac) => mediac.Count(), contentCount) .DependentRules(o => { o.RuleForEach(xo => xo.Contents) .SetValidator(new FileContentValidator()); }); }); }); // Apply the following validation if TitleId is provided dr.When(x => x.TitleId.HasValue, () => { // Verify that the given MediaId exist Func <int, bool> titleIdExistRule = new Func <int, bool>((titleId) => { //return (airingSvc.GetNonExpiredBy(titleId, DateTime.MinValue).IsNullOrEmpty()) ? false : true; return(true); }); dr.RuleFor(c => c.TitleId.Value) .Cascade(CascadeMode.StopOnFirstFailure) .Must(titleIdExistRule) .WithMessage("TitleId {0} doesn't exist", c => c.TitleId.Value) .DependentRules(oxx => { oxx.RuleFor(ox => ox.Contents) .Cascade(CascadeMode.StopOnFirstFailure) .NotEmpty() .WithMessage("Contents property required and cannot be empty when posting video payload by title-id") .Must(contentSegmentsMatchRule) .WithMessage("Content segments provided in payload doesn't match with that of media/airing. Payload contains {0} content segments (# of items in 'contents' array), while media/airing contains {1} content segments", (request, mediac) => mediac.Count(), contentCount) .DependentRules(o => { o.RuleForEach(xo => xo.Contents) .SetValidator(new FileContentValidator()); }); }); }); }); }); // Apply non-video specific file validation RuleSet("NonVideo", () => { // Verify that TitleId is provided RuleFor(c => c) .Cascade(CascadeMode.StopOnFirstFailure) .Must(c => c.TitleId.HasValue) .WithMessage("Title Id Required") .Must(c => c.TitleId > 0) .WithMessage("Title Id must be greater than zero"); RuleFor(c => c) .Must(c => String.IsNullOrEmpty(c.AiringId) && String.IsNullOrEmpty(c.MediaId)) .WithMessage("Registering non video assets by Airing Id or Media Id not currently supported"); // Verify that other required fileds are provided RuleFor(c => c) .Must(c => !String.IsNullOrEmpty(c.Path)) .WithMessage("Path required"); RuleFor(c => c) .Must(c => !String.IsNullOrEmpty(c.Name)) .WithMessage("Name required"); RuleFor(c => c) .Must(c => !String.IsNullOrEmpty(c.Type)) .WithMessage("Type required"); RuleFor(c => c) .Must(c => !String.IsNullOrEmpty(c.Domain)) .WithMessage("Domain required"); RuleFor(c => c) .Must(c => !String.IsNullOrEmpty(c.AspectRatio)) .WithMessage("Aspect ratio required"); RuleFor(c => c) .Must(c => !String.IsNullOrEmpty(c.Category)) .WithMessage("Category required"); RuleFor(c => c) .Must(c => !String.IsNullOrEmpty(c.Match)) .WithMessage("Match required"); }); }
public PurgeUnitTestAirings(IAiringService service) { _service = service; }
public AiringStatusRoutes( IAiringService airingSvc, IStatusSerivce statusService, IQueueService queueService, Serilog.ILogger logger ) : base("v1") { this.RequiresAuthentication(); _statusService = statusService; #region "POST Operations" Post("/airingstatus/{airingid}", _ => { // Verify that the user has permission to POST this.RequiresClaims(c => c.Type == HttpMethod.Post.Verb()); var airingId = (string)_.airingid; try { if (!airingSvc.IsAiringExists(airingId)) { var airingErrorMessage = string.IsNullOrWhiteSpace(airingId) ? "AiringId is required." : "Provided AiringId does not exists or expired."; // Return's NOT found status if airing not exists in current collection. return(Negotiate.WithModel(airingErrorMessage) .WithStatusCode(!string.IsNullOrWhiteSpace(airingId) ? HttpStatusCode.NotFound : HttpStatusCode.BadRequest)); } // Bind POST request to data contract var request = this.Bind <VMAiringRequestModel.AiringStatusRequest>(); //Validates the airing status request var validationResults = ValidateRequest(request); if (validationResults.Any()) { //returns validation results if there is any return(Negotiate.WithModel(validationResults) .WithStatusCode(HttpStatusCode.BadRequest)); } var airing = airingSvc.GetBy(airingId, AiringCollection.CurrentCollection); //Updates the airing status with the POST request foreach (var status in request.Status) { airing.Status[status.Key] = status.Value; } //Set the user name who updates the status airing.UserName = Context.User().UserName; // get all active queues var statusQueues = queueService.GetByStatus(true); // Finally, persist the airing data airingSvc.Save(airing, false, true); //update the status notification airingSvc.CreateNotificationForStatusChange(airing.AssetId, ResetDeliveryQueue(statusQueues, airing)); return(new { Result = "Successfully updated the airing status." }); } catch (Exception e) { logger.Error(e, "Failure ingesting status to airing. Airingid:{@airingId}", airingId); throw; } }); Post("/airingstatus/mediaId/{mediaid}", _ => { // Verify that the user has permission to POST this.RequiresClaims(c => c.Type == HttpMethod.Post.Verb()); var mediaId = (string)_.mediaid; if (string.IsNullOrWhiteSpace(mediaId)) { return(Negotiate.WithModel("MediaId is required.") .WithStatusCode(HttpStatusCode.BadRequest)); } var airingsByMediaId = airingSvc.GetByMediaId(mediaId); try { // Bind POST request to data contract var request = this.Bind <VMAiringRequestModel.AiringStatusRequest>(); //Validates the airing status request var validationResults = ValidateRequest(request); if (validationResults.Any()) { //returns validation results if there is any return(Negotiate.WithModel(validationResults) .WithStatusCode(HttpStatusCode.BadRequest)); } //Updates the airing status with the POST request foreach (var airing in airingsByMediaId) { foreach (var status in request.Status) { airing.Status[status.Key] = status.Value; } //Set the user name who updates the status airing.UserName = Context.User().UserName; // get all active queues var statusQueues = queueService.GetByStatus(true); // Finally, persist the airing data airingSvc.Save(airing, false, true); //update the status notification airingSvc.CreateNotificationForStatusChange(airing.AssetId, ResetDeliveryQueue(statusQueues, airing)); logger.Information("Successfully updated the airing status. AiringId : {AiringId}", airing.AssetId); } return(new { Result = "Successfully updated the airings status." }); } catch (Exception e) { logger.Error(e, "Failure ingesting status to airings by mediaid. Mediaid:{@mediaId}", mediaId); throw; } }); #endregion }
public AiringRoutes( IIdDistributor airingIdDistributorSvc, IAiringIdService airingIdSvc, IAiringService airingSvc, IReportingService reporterSvc, IProductService productSvc, AiringValidator _validator, IQueueService queueSvc, Serilog.ILogger logger, IDestinationService destinationSvc ) : base("v1") { this.RequiresAuthentication(); #region "GET Operations" Get("/airing/{airingId}", _ => { this.RequiresClaims(c => c.Type == HttpMethod.Get.Verb()); var options = GetOptionsFromQueryString(); // These timers are added for instrumentation and will be removed // in the future Dictionary <string, object> routeStats = new Dictionary <string, object>(); long start = Stopwatch.GetTimestamp(); var airing = airingSvc.GetBy((string)_.airingId); routeStats.Add("rtAiring_ElapsedMS", GetElapsedMilliseconds(start, Stopwatch.GetTimestamp())); var user = Context.User(); FilterDestinations(airing, user.Destinations.ToList()); ValidateRequest(airing, user.Brands); var airingLong = airing.ToBusinessModel <BLAiringModel.Airing, BLAiringLongModel.Airing>(); start = Stopwatch.GetTimestamp(); if (options.Contains(Appenders.File.ToString().ToLower())) { airingSvc.AppendFile(ref airingLong); } routeStats.Add("appendFile_ElapsedMS", GetElapsedMilliseconds(start, Stopwatch.GetTimestamp())); start = Stopwatch.GetTimestamp(); if (options.Contains(Appenders.Title.ToString().ToLower())) { airingSvc.AppendTitle(ref airingLong); } routeStats.Add("appendTitle_ElapsedMS", GetElapsedMilliseconds(start, Stopwatch.GetTimestamp())); if (options.Contains(Appenders.Series.ToString().ToLower()) && (options.Contains(Appenders.File.ToString().ToLower()))) { airingSvc.AppendSeries(ref airingLong); } else if (options.Contains(Appenders.Series.ToString().ToLower())) { airingSvc.AppendSeries(ref airingLong); airingSvc.AppendFileBySeriesId(ref airingLong); } start = Stopwatch.GetTimestamp(); if (options.Contains(Appenders.Destination.ToString().ToLower())) { airingSvc.AppendDestinations(ref airingLong); } routeStats.Add("appendDestination_ElapsedMS", GetElapsedMilliseconds(start, Stopwatch.GetTimestamp())); start = Stopwatch.GetTimestamp(); if (options.Contains(Appenders.Change.ToString().ToLower())) { airingSvc.AppendChanges(ref airingLong); } routeStats.Add("appendChanges_ElapsedMS", GetElapsedMilliseconds(start, Stopwatch.GetTimestamp())); // Append status information if requested start = Stopwatch.GetTimestamp(); if (options.Contains(Appenders.Status.ToString().ToLower())) { airingSvc.AppendStatus(ref airingLong); } routeStats.Add("appendStatus_ElapsedMS", GetElapsedMilliseconds(start, Stopwatch.GetTimestamp())); start = Stopwatch.GetTimestamp(); if (options.Contains(Appenders.Package.ToString().ToLower())) { airingSvc.AppendPackage(ref airingLong, Request.Headers.Accept); } routeStats.Add("appendPackage_ElapsedMS", GetElapsedMilliseconds(start, Stopwatch.GetTimestamp())); start = Stopwatch.GetTimestamp(); if (options.Contains(Appenders.Premiere.ToString().ToLower())) { airingSvc.AppendPremiere(ref airingLong); } routeStats.Add("appendPremiere_ElapsedMS", GetElapsedMilliseconds(start, Stopwatch.GetTimestamp())); start = Stopwatch.GetTimestamp(); if (options.Contains(Appenders.Version.ToString().ToLower())) { airingSvc.AppendVersion(ref airingLong); } routeStats.Add("appendVersion_ElapsedMS", GetElapsedMilliseconds(start, Stopwatch.GetTimestamp())); start = Stopwatch.GetTimestamp(); var model = airingLong.ToViewModel <BLAiringLongModel.Airing, VMAiringLongModel.Airing>(); routeStats.Add("BLtoVM_ElapsedMS", GetElapsedMilliseconds(start, Stopwatch.GetTimestamp())); if (!options.Contains(Appenders.Package.ToString().ToLower())) { model.Options.Packages = null; } routeStats.Add("context", "Instrumentation-GET-Airing-Route"); routeStats.Add("requestMethod", this.Request.Method); routeStats.Add("path", this.Request.Path); logger.Information("Request -" + this.Request.Path + "{@info}", routeStats); return(model); }); Get("/airings/titleId/{titleId}", _ => { this.RequiresClaims(c => c.Type == HttpMethod.Get.Verb()); var airings = airingSvc .GetNonExpiredBy((int)_.titleId, DateTime.UtcNow) .ToList(); var user = Context.User(); airings = FilterDestinations(airings, user.Destinations.ToList()); airings = FilterBrands(airings, user.Brands.ToList()); var viewModels = airings.Select(a => a.ToViewModel <BLAiringModel.Airing, VMAiringShortModel.Airing>()).ToList(); return(viewModels); }); Get("/airings/seriesId/{seriesId}", _ => { this.RequiresClaims(c => c.Type == HttpMethod.Get.Verb()); var airings = airingSvc .GetNonExpiredBy((int)_.seriesId, DateTime.UtcNow, true) .ToList(); var user = Context.User(); airings = FilterDestinations(airings, user.Destinations.ToList()); airings = FilterBrands(airings, user.Brands.ToList()); var viewModels = airings.Select(a => a.ToViewModel <BLAiringModel.Airing, VMAiringShortModel.Airing>()).ToList(); return(viewModels); }); Get("/airings/mediaId/{mediaId}", _ => { this.RequiresClaims(c => c.Type == HttpMethod.Get.Verb()); List <BLAiringModel.Airing> airings; DateTime startDate; DateTime endDate; if ((Request.Query.ContainsKey("startDate")) && (Request.Query.ContainsKey("endDate"))) { // validate ValidationResult results = new ValidationResult(); results = validateRequestDate(Request.Query["startDate"], Request.Query["endDate"]); if (results.Errors.Any()) // Verify if there are any validation errors. If so, return error { return(Negotiate.WithModel(results.Errors.Select(c => c.ErrorMessage)) .WithStatusCode(HttpStatusCode.BadRequest)); // Return status } startDate = getDate(Request.Query["startDate"]); endDate = getDate(Request.Query["endDate"]); if (startDate > endDate) { return(Negotiate.WithModel("Start date should be smaller than the end date") .WithStatusCode(HttpStatusCode.PreconditionFailed)); } airings = airingSvc.GetAiringsByMediaId((string)_.mediaId, startDate, endDate); } else { airings = new List <BLAiringModel.Airing>(airingSvc.GetByMediaId((string)_.mediaId)); } var user = Context.User(); airings = FilterDestinations(airings, user.Destinations.ToList()); airings = FilterBrands(airings, user.Brands.ToList()); var viewModels = airings.Select(a => a.ToViewModel <BLAiringModel.Airing, VMAiringShortModel.Airing>()).ToList(); return(viewModels); }); Get("/airings/destination/{destination}", _ => { this.RequiresClaims(c => c.Type == HttpMethod.Get.Verb()); var airings = airingSvc .GetNonExpiredBy((string)_.destination, DateTime.UtcNow) .ToList(); var user = Context.User(); airings = FilterDestinations(airings, user.Destinations.ToList()); airings = FilterBrands(airings, user.Brands.ToList()); var viewModels = airings.Select(a => a.ToViewModel <BLAiringModel.Airing, VMAiringShortModel.Airing>()).ToList(); return(viewModels); }); Get("/airings/brand/{brand}/destination/{destination}", _ => { this.RequiresClaims(c => c.Type == HttpMethod.Get.Verb()); List <BLAiringModel.Airing> airings = airingSvc .GetBy((string)_.brand, (string)_.destination, (DateTime)Request.Query["startDate"], (DateTime)Request.Query["endDate"], Request.Query["airingStatus"]); var user = Context.User(); airings = FilterDestinations(airings, user.Destinations.ToList()); airings = FilterBrands(airings, user.Brands.ToList()); var viewModels = airings.Select(a => a.ToViewModel <BLAiringModel.Airing, VMAiringShortModel.Airing>()).ToList(); return(viewModels); }); #endregion #region "POST Operations" Post("/airing/task", _ => { this.RequiresClaims(c => c.Type == HttpMethod.Post.Verb()); var request = this.Bind <TaskViewModel>(); airingSvc.UpdateTask(request.AiringIds, request.Tasks); return(new { request.AiringIds, Message = "updated successfully" }); }); Post("/airing/send/{airingId}", _ => { this.RequiresClaims(c => c.Type == HttpMethod.Post.Verb()); if (!airingSvc.IsAiringExists((string)_.airingId)) { return(Negotiate.WithModel("airingId not found") .WithStatusCode(HttpStatusCode.NotFound)); } airingSvc.PushToQueues(new List <string> { (string)_.airingId }); return(new { AiringId = (string)_.airingId, Message = "AiringId flagged for delivery for valid queues" }); }); Post("/airing/deliver/{airingId}", _ => { this.RequiresClaims(c => c.Type == HttpMethod.Post.Verb()); if (!airingSvc.IsAiringExists((string)_.airingId)) { return(Negotiate.WithModel("airingId not found") .WithStatusCode(HttpStatusCode.NotFound)); } airingSvc.PushToQueues(new List <string> { (string)_.airingId }); return(new { AiringId = (string)_.airingId, Message = "AiringId flagged for delivery for valid queues" }); }); Post("/airing/send", _ => { this.RequiresClaims(c => c.Type == HttpMethod.Post.Verb()); var request = this.Bind <QueuePushViewModel>(); var queueName = queueSvc.GetByApiKey(request.QueueName); if (queueName == null) { return(Negotiate.WithModel("Queue not found") .WithStatusCode(HttpStatusCode.NotFound)); } if (!queueName.Active) { return(Negotiate.WithModel("Inactive queue") .WithStatusCode(HttpStatusCode.PreconditionFailed)); } var invalidAirings = new List <string>(); var validAiringIds = new List <string>(); foreach (string airingId in request.AiringIds) { if (!airingSvc.IsAiringExists(airingId)) { invalidAirings.Add(airingId); } else { validAiringIds.Add(airingId); } } if (validAiringIds.Any()) { airingSvc.PushToQueue(request.QueueName, request.AiringIds); } return(new { validAiringIds = validAiringIds, invalidAiringsIds = invalidAirings, Message = "validAiringIds are flagged for delivery and delivered based on enabled options of the queue" }); }); Post("/airing/deliver", _ => { this.RequiresClaims(c => c.Type == HttpMethod.Post.Verb()); var request = this.Bind <QueuePushViewModel>(); var queueName = queueSvc.GetByApiKey(request.QueueName); if (queueName == null) { return(Negotiate.WithModel("Queue not found") .WithStatusCode(HttpStatusCode.NotFound)); } if (!queueName.Active) { return(Negotiate.WithModel("Inactive queue") .WithStatusCode(HttpStatusCode.PreconditionFailed)); } var invalidAirings = new List <string>(); var validAiringIds = new List <string>(); foreach (string airingId in request.AiringIds) { if (!airingSvc.IsAiringExists(airingId)) { invalidAirings.Add(airingId); } else { validAiringIds.Add(airingId); } } if (validAiringIds.Any()) { airingSvc.PushToQueue(request.QueueName, request.AiringIds); } return(new { AiringIds = validAiringIds, invalidAiringsIds = invalidAirings, Message = "AiringIds are flagged for delivery and delivered based on enabled options of the queue" }); }); Post("/airing/{prefix}", _ => { // Verify that the user has permission to POST this.RequiresClaims(c => c.Type == HttpMethod.Post.Verb()); var user = Context.User(); // Bind POST request to data contract var request = this.Bind <VMAiringRequestModel.AiringRequest>(); try { // If the Airing provided in the request doesn't have an // AiringId, create new one. CurrentAiringId currentAiringId = null; if (string.IsNullOrEmpty(request.AiringId)) { currentAiringId = airingIdDistributorSvc.Distribute((string)_.prefix); request.AiringId = currentAiringId.AiringId; } else { try { var assetDetails = airingSvc.GetBy(request.AiringId); if (assetDetails.SequenceNumber != 0) { currentAiringId = new CurrentAiringId { SequenceNumber = assetDetails.SequenceNumber, BillingNumber = new BillingNumber { Current = assetDetails.BillingNumber.Current, Lower = assetDetails.BillingNumber.Lower, Upper = assetDetails.BillingNumber.Upper } }; } } catch (AiringNotFoundException e) { logger.Information("Airing released from other systems like turniverse"); } } // Translate data contract to airing business model var airing = Mapper.Map <BLAiringModel.Airing>(request); // validate List <ValidationResult> results = new List <ValidationResult>(); results.Add(_validator.Validate(airing, ruleSet: AiringValidationRuleSet.PostAiring.ToString())); // Verify if there are any validation errors. If so, return error if (results.Where(c => (!c.IsValid)).Count() > 0) { var message = results.Where(c => (!c.IsValid)) .Select(c => c.Errors.Select(d => d.ErrorMessage)); logger.Error("Failure ingesting released asset: {AssetId}", new Dictionary <string, object>() { { "airingid", request.AiringId }, { "mediaid", airing.MediaId }, { "error", message } }); // Return status return(Negotiate.WithModel(message) .WithStatusCode(HttpStatusCode.BadRequest)); } // Now that the validation is succesful, proceed to // persisting the data. But first, populate remaining // properties for the airing business model. if (currentAiringId != null) { airing.SequenceNumber = currentAiringId.SequenceNumber; airing.BillingNumber.Lower = currentAiringId.BillingNumber.Lower; airing.BillingNumber.Current = currentAiringId.BillingNumber.Current; airing.BillingNumber.Upper = currentAiringId.BillingNumber.Upper; } else { airing.BillingNumber = null; } airing.ReleaseOn = DateTime.UtcNow; airing.UserName = user.UserName; //Get the username // If flight information is provided in the airing, create // the corresponding product to destination mapping as defined // in ODT if (airing.Flights.SelectMany(f => f.Products).Any()) { productSvc.ProductDestinationConverter(ref airing); destinationSvc.FilterDestinationPropertiesDeliverablesAndCategoriesAndTransformTokens(ref airing); } else { // Retrieve destination related data - properties, deliverables and categories - lsand // augment it to airing destinationSvc.GetAiringDestinationRelatedData(ref airing); destinationSvc.FilterDestinationPropertiesDeliverablesAndCategoriesAndTransformTokens(ref airing); } // If the versions exist, create a mediaid based on the // provided version informtion,playlists and the network to which this // asset/airing belongs if (airing.Versions.Any()) { airingSvc.AugmentMediaId(ref airing); } // Finally, persist the airing data var savedAiring = airingSvc.Save(airing, request.Instructions.DeliverImmediately, true); // If immediate deliver requested, force push the airing to the // respective queues (based on: product=>destination=>queue relationship) if (request.Instructions.DeliverImmediately) { airingSvc.PushToQueues(new List <string> { savedAiring.AssetId }); } // Report status of this airing to monitoring system (digital fulfillment/logzio) reporterSvc.Report(savedAiring, airingSvc.IsAiringExists(savedAiring.AssetId)); logger.Information("Successfully ingested released asset: {Asset}", GeneratePostAiringpropertiesForLogzIO(savedAiring, user)); // Return airing model return(savedAiring.ToViewModel <BLAiringModel.Airing, VMAiringPostResponseModel.PostResponseAiring>()); } catch (Exception e) { logger.Error(e, "Failure ingesting released asset. AssetId:{@assetId}", request.AiringId); throw e; } }); #endregion #region "DELETE Operations" Delete("/airing", _ => { this.RequiresClaims(c => c.Type == HttpMethod.Delete.Verb()); var request = this.Bind <VMAiringRequestModel.AiringRequest>(); var airing = Mapper.Map <BLAiringModel.Airing>(request); // validate List <ValidationResult> results = new List <ValidationResult>(); results.Add(_validator.Validate(airing, ruleSet: AiringValidationRuleSet.DeleteAiring.ToString())); // Verify if there are any validation errors. If so, return error if (results.Where(c => (!c.IsValid)).Count() > 0) { // Return status return(Negotiate.WithModel(results.Where(c => (!c.IsValid)) .Select(c => c.Errors.Select(d => d.ErrorMessage))) .WithStatusCode(HttpStatusCode.BadRequest)); } var existingAiring = airingSvc.GetBy(airing.AssetId); ValidateRequest(existingAiring, Context.User().Brands); existingAiring.ReleaseBy = airing.ReleaseBy; existingAiring.ReleaseOn = DateTime.UtcNow; existingAiring.UserName = Context.User().UserName; existingAiring.DeliveredTo.Clear(); airingSvc.Delete(existingAiring); //Delete related packages of airing airingSvc.DeleteAiringMappedPackages(airing.AssetId); if (request.Instructions.DeliverImmediately) { airingSvc.PushToQueues(new List <string> { existingAiring.AssetId }); } reporterSvc.Report(existingAiring, false); return(new VMAiringLongModel.AiringMessage { AiringId = airing.AssetId, Message = "deleted successfully" }); }); #endregion }
public Deporter(Serilog.ILogger logger, IAiringService airingService, AppSettings appsettings) { this.appsettings = appsettings; this.logger = logger; this.airingServiceHelper = airingService; }
public PlaylistRoutes( IAiringService airingSvc, AiringValidator validator, Serilog.ILogger logger ) : base("v1") { this.RequiresAuthentication(); #region "POST Operations" Post("/playlist/{airingid}", _ => { // Verify that the user has permission to POST this.RequiresClaims(c => c.Type == HttpMethod.Post.Verb()); var airingId = (string)_.airingid; // Bind POST request to data contract var request = this.Bind <VMAiringRequestModel.PlayListRequest>(); try { BLAiringModel.Airing airing; if (airingSvc.IsAiringExists(airingId)) { airing = airingSvc.GetBy(airingId, AiringCollection.CurrentCollection); //Updates the airing with the given Playlist payload airing.PlayList = Mapper.Map <List <BLAiringModel.PlayItem> >(request.PlayList); airing.ReleaseBy = request.ReleasedBy; //Clears the existing delivery details airing.IgnoredQueues = new List <string>(); airing.DeliveredTo = new List <string>(); //Sets the date with the current date time airing.ReleaseOn = DateTime.UtcNow; //Sets the user name airing.UserName = Context.User().UserName; } else { var airingErrorMessage = string.IsNullOrWhiteSpace(airingId) ? "AiringId is required." : "Provided AiringId does not exists or expired."; // Return status return(Negotiate.WithModel(airingErrorMessage) .WithStatusCode(string.IsNullOrWhiteSpace(airingId) ? HttpStatusCode.BadRequest : HttpStatusCode.NotFound)); } // validate var results = new List <ValidationResult> { validator.Validate(airing, ruleSet: AiringValidationRuleSet.PostPlaylist.ToString()) }; // Verify if there are any validation errors. If so, return error if (results.Any(c => (!c.IsValid))) { var message = results.Where(c => (!c.IsValid)) .Select(c => c.Errors.Select(d => d.ErrorMessage)).ToList(); logger.Error("Failure ingesting playlist released asset: {AssetId}", new Dictionary <string, object>() { { "airingid", airingId }, { "mediaid", airing.MediaId }, { "error", message } }); // Return status return(Negotiate.WithModel(message) .WithStatusCode(HttpStatusCode.BadRequest)); } // If the versions exist, create a mediaid based on the // provided version informtion,playlists and the network to which this // asset/airing belongs if (airing.Versions.Any()) { airingSvc.AugmentMediaId(ref airing); } // Finally, persist the airing data airingSvc.Save(airing, false, true); return("Successfully updated the playlist."); } catch (Exception e) { logger.Error(e, "Failure ingesting playlist to airing. Airingid:{@airingId}", airingId); throw; } }); #endregion }