public void ShouldPutInCacheWhenNotInCache()
        {
            var vacancyStatusSummary = new VacancyStatusSummary {
                LegacyVacancyId = 123, ClosingDate = DateTime.Now.AddMonths(-3), VacancyStatus = VacancyStatuses.Expired
            };

            _applicationStatusProcessor.Setup(x => x.ProcessApplicationStatuses(It.IsAny <VacancyStatusSummary>()));
            _cacheServiceMock.Setup(x => x.PutObject(It.IsAny <string>(), It.IsAny <object>(), It.IsAny <CacheDuration>()));
            _configurationManagerMock.Setup(x => x.GetCloudAppSetting <bool>(It.Is <string>(s => s == "EnableVacancyStatusPropagation"))).Returns(true);
            _vacancyStatusSummaryConsumerAsync = new VacancyStatusSummaryConsumerAsync(_cacheServiceMock.Object, _applicationStatusProcessor.Object, _configurationManagerMock.Object);

            var task = _vacancyStatusSummaryConsumerAsync.Consume(vacancyStatusSummary);

            task.Wait();

            _cacheServiceMock.Verify(
                x =>
                x.PutObject(
                    It.Is <string>(c => c == vacancyStatusSummary.CacheKey()),
                    It.Is <object>(vss => vss == vacancyStatusSummary),
                    It.Is <CacheDuration>(c => c == vacancyStatusSummary.CacheDuration())), Times.Once);

            _applicationStatusProcessor.Verify(
                x =>
                x.ProcessApplicationStatuses(
                    It.Is <VacancyStatusSummary>(i => i == vacancyStatusSummary)), Times.Once);
        }
 public static string CacheKey(this VacancyStatusSummary vacancyStatusSummary)
 {
     return(vacancyStatusSummary != null
         ? string.Format("VacancyStatusSummary_CacheKey_{0}_{1}_{2}",
                         vacancyStatusSummary.LegacyVacancyId, vacancyStatusSummary.VacancyStatus, vacancyStatusSummary.ClosingDate.ToString("yyyy-MM-dd"))
         : null);
 }
        public void ProcessApplicationStatuses(VacancyStatusSummary vacancyStatusSummary)
        {
            // propagate current vacancy state to all draft applications for the vacancy
            var applicationSummaries = _apprenticeshipApplicationReadRepository.GetApplicationSummaries(vacancyStatusSummary.LegacyVacancyId);

            var applicationStatusSummaries = applicationSummaries
                                             .Where(applicationSummary => applicationSummary.Status == ApplicationStatuses.Draft)
                                             .Select(applicationSummary =>
                                                     new ApplicationStatusSummary
            {
                ApplicationId        = applicationSummary.ApplicationId,
                ApplicationStatus    = applicationSummary.Status,
                LegacyApplicationId  = applicationSummary.LegacyApplicationId,
                LegacyVacancyId      = applicationSummary.LegacyVacancyId,
                VacancyStatus        = vacancyStatusSummary.VacancyStatus,
                ClosingDate          = vacancyStatusSummary.ClosingDate,
                UnsuccessfulReason   = applicationSummary.UnsuccessfulReason,
                UnsuccessfulDateTime = applicationSummary.UnsuccessfulDateTime
            });

            Parallel.ForEach(
                applicationStatusSummaries,
                new ParallelOptions {
                MaxDegreeOfParallelism = 5
            },
                applicationStatusSummary => _serviceBus.PublishMessage(applicationStatusSummary));
        }
        public TVacancyDetail GetVacancyDetails(Guid candidateId, int vacancyId)
        {
            _logger.Debug("Calling LegacyGetCandidateVacancyDetailStrategy to get vacancy details for vacancy ID {0} and candidate ID {1}.", vacancyId, candidateId);

            try
            {
                var vacancyDetails = _vacancyDataProvider.GetVacancyDetails(vacancyId);

                if (vacancyDetails != null)
                {
                    // update the application for this candidate (if they have one) with latest info from legacy
                    _applicationVacancyUpdater.Update(candidateId, vacancyId, vacancyDetails);

                    // propagate the current vacancy status for other consumers
                    var vacancyStatusSummary = new VacancyStatusSummary
                    {
                        LegacyVacancyId = vacancyId,
                        VacancyStatus   = vacancyDetails.VacancyStatus,
                        ClosingDate     = vacancyDetails.ClosingDate
                    };

                    _bus.PublishMessage(vacancyStatusSummary);
                }

                return(vacancyDetails);
            }
            catch (Exception e)
            {
                var message = string.Format("Get vacancy failed for vacancy ID {0} and candidate ID {1}.", vacancyId, candidateId);

                _logger.Debug(message, e);

                throw new CustomException(message, e, ErrorCodes.GetVacancyDetailsFailed);
            }
        }
        public void ShouldPutInCacheWhenNotInCache()
        {
            // Arrange.
            var vacancyStatusSummary = new VacancyStatusSummary
            {
                LegacyVacancyId = 123,
                ClosingDate     = DateTime.UtcNow.AddMonths(-3),
                VacancyStatus   = VacancyStatuses.Expired
            };

            _applicationStatusProcessor.Setup(x => x.ProcessApplicationStatuses(It.IsAny <VacancyStatusSummary>()));
            _cacheServiceMock.Setup(x => x.PutObject(It.IsAny <string>(), It.IsAny <object>(), It.IsAny <CacheDuration>()));

            _configurationServiceMock.Setup(x => x.Get <ProcessConfiguration>())
            .Returns(new ProcessConfiguration
            {
                EnableVacancyStatusPropagation = true
            });

            _subscriber = new VacancyStatusSummarySubscriber(
                _configurationServiceMock.Object,
                _cacheServiceMock.Object,
                _applicationStatusProcessor.Object);

            // Act.
            var state = _subscriber.Consume(vacancyStatusSummary);

            // Assert.
            state.Should().NotBeNull();
            state.Should().Be(ServiceBusMessageStates.Complete);

            _cacheServiceMock.Verify(
                x =>
                x.PutObject(
                    It.Is <string>(c => c == vacancyStatusSummary.CacheKey()),
                    It.Is <object>(vss => vss == vacancyStatusSummary),
                    It.Is <CacheDuration>(c => c == vacancyStatusSummary.CacheDuration())), Times.Once);

            _applicationStatusProcessor.Verify(
                x =>
                x.ProcessApplicationStatuses(
                    It.Is <VacancyStatusSummary>(i => i == vacancyStatusSummary)), Times.Once);
        }
        public ServiceBusMessageStates Consume(ApplicationStatusSummary applicationStatusSummary)
        {
            _applicationStatusProcessor.ProcessApplicationStatuses(applicationStatusSummary, _strictEtlValidation);

            // determine whether this message is from an already propagated vacancy status summary
            var isReprocessing = applicationStatusSummary.ApplicationId != Guid.Empty;

            if (!isReprocessing)
            {
                var vacancyStatusSummary = new VacancyStatusSummary
                {
                    LegacyVacancyId = applicationStatusSummary.LegacyVacancyId,
                    VacancyStatus   = applicationStatusSummary.VacancyStatus,
                    ClosingDate     = applicationStatusSummary.ClosingDate
                };

                _serviceBus.PublishMessage(vacancyStatusSummary);
            }

            return(ServiceBusMessageStates.Complete);
        }
        public Task Consume(ApplicationStatusSummary applicationStatusSummaryToProcess)
        {
            return(Task.Run(() =>
            {
                if (CancellationToken.IsCancellationRequested)
                {
                    _applicationStatusSummaryConsumerResetEvent.Set();
                    Thread.Sleep(Timeout.Infinite);
                }

                _applicationStatusSummaryConsumerResetEvent.Reset();

                try
                {
                    _applicationStatusProcessor.ProcessApplicationStatuses(applicationStatusSummaryToProcess);

                    // determine whether this message is from an already propagated vacancy status summary
                    var isReprocessing = applicationStatusSummaryToProcess.ApplicationId != Guid.Empty;

                    if (!isReprocessing)
                    {
                        var vacancyStatusSummary = new VacancyStatusSummary
                        {
                            LegacyVacancyId = applicationStatusSummaryToProcess.LegacyVacancyId,
                            VacancyStatus = applicationStatusSummaryToProcess.VacancyStatus,
                            ClosingDate = applicationStatusSummaryToProcess.ClosingDate
                        };

                        _bus.PublishMessage(vacancyStatusSummary);
                    }
                }
                finally
                {
                    _applicationStatusSummaryConsumerResetEvent.Set();
                }
            }));
        }
 public static CacheDuration CacheDuration(this VacancyStatusSummary vacancyStatusSummary)
 {
     //todo: 1.6: move to config setting
     return(Domain.Interfaces.Caching.CacheDuration.ThirtyMinutes);
 }