public override IReadOnlyDictionary <long, HandlingStatus> Execute( StandardGetHandlingStatusOp operation) { operation.MustForArg(nameof(operation)).NotBeNull(); var sqlServerLocator = this.TryGetLocator(operation); var sqlProtocol = this.BuildSqlOperationsProtocol(sqlServerLocator); var convertedRecordFilter = this.ConvertRecordFilter(operation.RecordFilter, sqlServerLocator); var op = StreamSchema.Sprocs.GetHandlingStatuses.BuildExecuteStoredProcedureOp( this.Name, operation.Concern, convertedRecordFilter); var sprocResult = sqlProtocol.Execute(op); var outputParameter = sprocResult .OutputParameters[StreamSchema.Sprocs.GetHandlingStatuses.OutputParamName.RecordIdHandlingStatusXml.ToString()]; var recordIdStatusXml = outputParameter.GetValueOfType <string>(); var tags = recordIdStatusXml.GetTagsFromXmlString(); var result = tags.ToDictionary( k => long.Parse(k.Name, CultureInfo.InvariantCulture), v => v.Value?.ToEnum <HandlingStatus>() ?? HandlingStatus.AvailableByDefault); return(result); }
public override IReadOnlyDictionary <string, IReadOnlyDictionary <long, HandlingStatus> > Execute( GetReactionRegistrationDependenciesStatusOp operation) { operation.MustForArg(nameof(operation)).NotBeNull(); var reactionRegistration = operation.ReactionRegistration; if (reactionRegistration.Dependencies.Count != 1) { throw new NotSupportedException( Invariant( $"Only 1 single {typeof(RecordFilterReactorDependency)} is supported, {reactionRegistration.Dependencies.Count} were supplied.")); } var dependency = reactionRegistration.Dependencies.Single(); var recordFilterDependency = dependency as RecordFilterReactorDependency; if (recordFilterDependency == null) { throw new NotSupportedException( Invariant($"Only {typeof(RecordFilterReactorDependency)} is supported, {dependency?.GetType().ToStringReadable()}.")); } var result = new Dictionary <string, IReadOnlyDictionary <long, HandlingStatus> >(); foreach (var recordFilterEntry in recordFilterDependency.Entries) { var concern = EvaluateReactionRegistrationOp.BuildHandlingConcern(reactionRegistration, recordFilterEntry); var getHandlingStatusOp = new StandardGetHandlingStatusOp( concern, recordFilterEntry.RecordFilter, new HandlingFilter()); var stream = (IStandardStream)reactionOperationStreamFactory.Execute(new GetStreamFromRepresentationOp(recordFilterEntry.StreamRepresentation)); stream.MustForOp(nameof(stream)) .BeAssignableToType <ISyncReturningProtocol <StandardGetHandlingStatusOp, IReadOnlyDictionary <long, HandlingStatus> > >(); var streamProtocol = (ISyncReturningProtocol <StandardGetHandlingStatusOp, IReadOnlyDictionary <long, HandlingStatus> >)stream; var handlingStatusesForDependency = streamProtocol.Execute(getHandlingStatusOp); result.Add(recordFilterEntry.Id, handlingStatusesForDependency); } return(result); }
/// <inheritdoc /> public override CheckRecordHandlingResult Execute( CheckRecordHandlingOp operation) { operation.MustForArg(nameof(operation)).NotBeNull(); var stream = this.streamFactory.Execute(new GetStreamFromRepresentationOp(operation.StreamRepresentation)); stream.MustForOp(nameof(stream)) .BeAssignableToType <ISyncReturningProtocol <StandardGetHandlingStatusOp, IReadOnlyDictionary <long, HandlingStatus> > >(); var streamProtocol = (ISyncReturningProtocol <StandardGetHandlingStatusOp, IReadOnlyDictionary <long, HandlingStatus> >)stream; var getStatusOp = new StandardGetHandlingStatusOp( operation.Concern, operation.RecordFilter, operation.HandlingFilter); var statuses = streamProtocol.Execute(getStatusOp); var result = new CheckRecordHandlingResult(operation.StreamRepresentation, statuses); return(result); }
public override void Execute( CompleteHandlingOnReactionRegistrationDependenciesOp operation) { operation.MustForArg(nameof(operation)).NotBeNull(); var reactionRegistration = operation.ReactionRegistration; var tags = reactionRegistration.Tags?.Any() ?? false ? reactionRegistration.Tags.DeepClone().Concat(this.handlingTags?.DeepClone() ?? new NamedValue <string> [0]).ToList() : this.handlingTags; if (reactionRegistration.Dependencies.Count != 1) { throw new NotSupportedException( Invariant( $"Only 1 single {typeof(RecordFilterReactorDependency)} is supported, {reactionRegistration.Dependencies.Count} were supplied.")); } var dependency = reactionRegistration.Dependencies.Single(); var recordFilterDependency = dependency as RecordFilterReactorDependency; if (recordFilterDependency == null) { throw new NotSupportedException( Invariant($"Only {typeof(RecordFilterReactorDependency)} is supported, {dependency?.GetType().ToStringReadable()}.")); } foreach (var recordFilterEntry in recordFilterDependency.Entries) { var concern = EvaluateReactionRegistrationOp.BuildHandlingConcern(reactionRegistration, recordFilterEntry); var getHandlingStatusOp = new StandardGetHandlingStatusOp( concern, recordFilterEntry.RecordFilter, new HandlingFilter(CompleteHandlingOnReactionRegistrationDependenciesOp.AvailableStatuses)); var stream = (IStandardStream)reactionOperationStreamFactory.Execute(new GetStreamFromRepresentationOp(recordFilterEntry.StreamRepresentation)); stream.MustForOp(nameof(stream)) .BeAssignableToType <ISyncReturningProtocol <StandardGetHandlingStatusOp, IReadOnlyDictionary <long, HandlingStatus> > >(); var streamProtocol = (ISyncReturningProtocol <StandardGetHandlingStatusOp, IReadOnlyDictionary <long, HandlingStatus> >)stream; var handlingStatusesForDependency = streamProtocol.Execute(getHandlingStatusOp); var missingHandlingMap = handlingStatusesForDependency .Where( _ => CompleteHandlingOnReactionRegistrationDependenciesOp .HandlingStatusesToRegardAsIncomplete.Contains(_.Value)) .ToDictionary(k => k.Key, v => v.Value); if (missingHandlingMap.Any()) { foreach (var item in missingHandlingMap) { if (!operation.AcceptableHandlingStatuses.Contains(item.Value)) { var acceptableStatusesString = operation.AcceptableHandlingStatuses.Select(_ => _.ToString()).ToCsv(); throw new InvalidOperationException(Invariant($"Record '{item.Key}' in stream '{stream.Name}' has status '{item.Value}' which is not in the acceptable status list from the operation: {acceptableStatusesString}.")); } var completeOp = new StandardUpdateHandlingStatusForRecordOp( item.Key, concern, HandlingStatus.Completed, new[] { HandlingStatus.Running, }, operation.Details, tags); var runningOp = new StandardUpdateHandlingStatusForRecordOp( item.Key, concern, HandlingStatus.Running, CompleteHandlingOnReactionRegistrationDependenciesOp.AvailableStatuses, operation.Details, tags); if (CompleteHandlingOnReactionRegistrationDependenciesOp.AvailableStatuses.Contains(item.Value)) { stream.Execute(runningOp); stream.Execute(completeOp); } else if (item.Value == HandlingStatus.Running) { stream.Execute(completeOp); } else { throw new NotSupportedException(Invariant($"Record '{item.Key}' in stream '{stream.Name}' has status '{item.Value}' which cannot be reset.")); } } } } }
public void HandlingTests() { var stream = this.GetCreatedSqlStream(); var x = stream.GetNextUniqueLong(); x.MustForTest().BeGreaterThan(0L); var start = DateTime.UtcNow; for (int idx = 0; idx < 10; idx++) { var key = Invariant($"{stream.Name}Key{idx}"); var firstValue = "Testing again."; var firstObject = new MyObject(key, firstValue); var firstConcern = "CanceledPickedBackUpScenario"; var firstTags = new List <NamedValue <string> > { new NamedValue <string>("Record", Guid.NewGuid().ToString().ToUpper(CultureInfo.InvariantCulture)), }; var handleTags = new List <NamedValue <string> > { new NamedValue <string>("Handle", Guid.NewGuid().ToString().ToUpper(CultureInfo.InvariantCulture)), }; var firstRecordAndHandleTags = firstTags.Concat(handleTags).ToList(); stream.PutWithId(firstObject.Id, firstObject, firstTags); var metadata = stream.GetLatestRecordMetadataById("monkeyAintThere"); metadata.MustForTest().BeNull(); var first = stream.Execute( new StandardTryHandleRecordOp( firstConcern, new RecordFilter( idTypes: new[] { typeof(string).ToRepresentation(), }, objectTypes: new[] { typeof(MyObject).ToRepresentation(), }), inheritRecordTags: true, tags: handleTags)); first.RecordToHandle.MustForTest().NotBeNull(); var getFirstStatusByTagsOp = new StandardGetHandlingStatusOp( firstConcern, new RecordFilter(tags: firstTags)); stream.Execute(getFirstStatusByTagsOp).OrderByDescending(_ => _.Key).First().Value.MustForTest().BeEqualTo(HandlingStatus.Running); var firstInternalRecordId = first.RecordToHandle.InternalRecordId; stream.Execute( new CancelRunningHandleRecordOp( firstInternalRecordId, firstConcern, "Resources unavailable; node out of disk space.", tags: firstRecordAndHandleTags).Standardize()); stream.Execute(getFirstStatusByTagsOp).OrderByDescending(_ => _.Key).First().Value.MustForTest().BeEqualTo(HandlingStatus.AvailableAfterExternalCancellation); stream.Execute(new DisableHandlingForStreamOp("Stop processing, fixing resource issue.").Standardize()); stream.Execute(getFirstStatusByTagsOp).OrderByDescending(_ => _.Key).First().Value.MustForTest().BeEqualTo(HandlingStatus.DisabledForStream); first = stream.Execute(new StandardTryHandleRecordOp( firstConcern, new RecordFilter( idTypes: new[] { typeof(string).ToRepresentation(), }, objectTypes: new[] { typeof(MyObject).ToRepresentation(), }), inheritRecordTags: true, tags: firstTags)); first.RecordToHandle.MustForTest().BeNull(); first.IsBlocked.MustForTest().BeTrue(); stream.Execute(getFirstStatusByTagsOp).OrderByDescending(_ => _.Key).First().Value.MustForTest().BeEqualTo(HandlingStatus.DisabledForStream); stream.Execute(new EnableHandlingForStreamOp("Resume processing, fixed resource issue.").Standardize()); stream.Execute(getFirstStatusByTagsOp).OrderByDescending(_ => _.Key).First().Value.MustForTest().BeEqualTo(HandlingStatus.AvailableAfterExternalCancellation); first = stream.Execute(new StandardTryHandleRecordOp( firstConcern, new RecordFilter( idTypes: new[] { typeof(string).ToRepresentation(), }, objectTypes: new[] { typeof(MyObject).ToRepresentation(), }), inheritRecordTags: true, tags: handleTags)); first.RecordToHandle.MustForTest().NotBeNull(); stream.Execute(getFirstStatusByTagsOp).OrderByDescending(_ => _.Key).First().Value.MustForTest().BeEqualTo(HandlingStatus.Running); stream.Execute( new SelfCancelRunningHandleRecordOp( firstInternalRecordId, firstConcern, "Processing not finished, check later.", tags: firstRecordAndHandleTags).Standardize()); stream.Execute(getFirstStatusByTagsOp).OrderByDescending(_ => _.Key).First().Value.MustForTest().BeEqualTo(HandlingStatus.AvailableAfterSelfCancellation); first = stream.Execute(new StandardTryHandleRecordOp( firstConcern, new RecordFilter( idTypes: new[] { typeof(string).ToRepresentation(), }, objectTypes: new[] { typeof(MyObject).ToRepresentation(), }), inheritRecordTags: true, tags: handleTags)); first.RecordToHandle.MustForTest().NotBeNull(); stream.Execute(getFirstStatusByTagsOp).OrderByDescending(_ => _.Key).First().Value.MustForTest().BeEqualTo(HandlingStatus.Running); stream.Execute( new CompleteRunningHandleRecordOp( firstInternalRecordId, firstConcern, "Processing not finished, check later.", tags: firstRecordAndHandleTags).Standardize()); stream.Execute(getFirstStatusByTagsOp).OrderByDescending(_ => _.Key).First().Value.MustForTest().BeEqualTo(HandlingStatus.Completed); first = stream.Execute(new StandardTryHandleRecordOp( firstConcern, new RecordFilter( idTypes: new[] { typeof(string).ToRepresentation(), }, objectTypes: new[] { typeof(MyObject).ToRepresentation(), }), inheritRecordTags: true, tags: handleTags)); first.RecordToHandle.MustForTest().BeNull(); stream.Execute(getFirstStatusByTagsOp).OrderByDescending(_ => _.Key).First().Value.MustForTest().BeEqualTo(HandlingStatus.Completed); //var firstHistory = stream.Execute(new StandardGetHandlingHistoryOp(firstInternalRecordId, firstConcern)); //firstHistory.MustForTest().HaveCount(7); //foreach (var history in firstHistory) // { // this.testOutputHelper.WriteLine( // Invariant( // $"{history.Metadata.Concern}: {history.InternalHandlingEntryId}:{history.Metadata.InternalRecordId} - {history.Metadata.Status} - {history.Payload.DeserializePayloadUsingSpecificFactory<IHaveDetails>(stream.SerializerFactory).Details ?? "<no details specified>"}")); //} var secondConcern = "FailedRetriedScenario"; var second = stream.Execute( new StandardTryHandleRecordOp( secondConcern, new RecordFilter( idTypes: new[] { typeof(string).ToRepresentation(), }, objectTypes: new[] { typeof(MyObject).ToRepresentation(), }), inheritRecordTags: true, tags: handleTags)); second.RecordToHandle.MustForTest().NotBeNull(); var secondInternalRecordId = second.RecordToHandle.InternalRecordId; var getSecondStatusByIdOp = new StandardGetHandlingStatusOp( secondConcern, new RecordFilter( ids: new[] { new StringSerializedIdentifier( second.RecordToHandle.Metadata.StringSerializedId, second.RecordToHandle.Metadata.TypeRepresentationOfId.WithVersion), })); stream.Execute(getSecondStatusByIdOp).OrderByDescending(_ => _.Key).First().Value.MustForTest().BeEqualTo(HandlingStatus.Running); stream.Execute( new FailRunningHandleRecordOp( secondInternalRecordId, secondConcern, "NullReferenceException: Bot v1.0.1 doesn't work.", tags: firstRecordAndHandleTags).Standardize()); stream.Execute(getSecondStatusByIdOp).OrderByDescending(_ => _.Key).First().Value.MustForTest().BeEqualTo(HandlingStatus.Failed); second = stream.Execute(new StandardTryHandleRecordOp( secondConcern, new RecordFilter( idTypes: new[] { typeof(string).ToRepresentation(), }, objectTypes: new[] { typeof(MyObject).ToRepresentation(), }), inheritRecordTags: true, tags: handleTags)); second.RecordToHandle.MustForTest().BeNull(); stream.Execute(getSecondStatusByIdOp).OrderByDescending(_ => _.Key).First().Value.MustForTest().BeEqualTo(HandlingStatus.Failed); stream.Execute( new ResetFailedHandleRecordOp(secondInternalRecordId, secondConcern, "Redeployed Bot v1.0.1-hotfix, re-run.", tags: firstRecordAndHandleTags).Standardize()); stream.Execute(getSecondStatusByIdOp).OrderByDescending(_ => _.Key).First().Value.MustForTest().BeEqualTo(HandlingStatus.AvailableAfterFailure); stream.GetStreamRecordHandlingProtocols().Execute(new DisableHandlingForStreamOp("Stop processing, need to confirm deployment.")); stream.Execute(getSecondStatusByIdOp).OrderByDescending(_ => _.Key).First().Value.MustForTest().BeEqualTo(HandlingStatus.DisabledForStream); second = stream.Execute( new StandardTryHandleRecordOp( secondConcern, new RecordFilter( idTypes: new[] { typeof(string).ToRepresentation(), }, objectTypes: new[] { typeof(MyObject).ToRepresentation(), }))); second.RecordToHandle.MustForTest().BeNull(); stream.Execute(getSecondStatusByIdOp).OrderByDescending(_ => _.Key).First().Value.MustForTest().BeEqualTo(HandlingStatus.DisabledForStream); stream.GetStreamRecordHandlingProtocols().Execute(new EnableHandlingForStreamOp("Resume processing, confirmed deployment.")); stream.Execute(getSecondStatusByIdOp).OrderByDescending(_ => _.Key).First().Value.MustForTest().BeEqualTo(HandlingStatus.AvailableAfterFailure); second = stream.Execute(new StandardTryHandleRecordOp( secondConcern, new RecordFilter( idTypes: new[] { typeof(string).ToRepresentation(), }, objectTypes: new[] { typeof(MyObject).ToRepresentation(), }), inheritRecordTags: true, tags: handleTags)); second.RecordToHandle.MustForTest().NotBeNull(); stream.Execute(getSecondStatusByIdOp).OrderByDescending(_ => _.Key).First().Value.MustForTest().BeEqualTo(HandlingStatus.Running); stream.Execute( new FailRunningHandleRecordOp( secondInternalRecordId, secondConcern, "NullReferenceException: Bot v1.0.1-hotfix doesn't work.", tags: firstRecordAndHandleTags).Standardize()); stream.Execute(getSecondStatusByIdOp).OrderByDescending(_ => _.Key).First().Value.MustForTest().BeEqualTo(HandlingStatus.Failed); stream.Execute(new DisableHandlingForRecordOp(firstInternalRecordId, "Giving up.", tags: firstRecordAndHandleTags).Standardize()); stream.Execute(getSecondStatusByIdOp).OrderByDescending(_ => _.Key).First().Value.MustForTest().BeEqualTo(HandlingStatus.DisabledForRecord); second = stream.Execute(new StandardTryHandleRecordOp( secondConcern, new RecordFilter( idTypes: new[] { typeof(string).ToRepresentation(), }, objectTypes: new[] { typeof(MyObject).ToRepresentation(), }), inheritRecordTags: true, tags: handleTags)); stream.Execute(getSecondStatusByIdOp).OrderByDescending(_ => _.Key).First().Value.MustForTest().BeEqualTo(HandlingStatus.DisabledForRecord); second.RecordToHandle.MustForTest().BeNull(); //var secondHistory = stream.Execute(new StandardGetHandlingHistoryOp(secondInternalRecordId, secondConcern)); //secondHistory.MustForTest().HaveCount(7); //foreach (var history in secondHistory) //{ // this.testOutputHelper.WriteLine( // Invariant( // $"{history.Metadata.Concern}: {history.InternalHandlingEntryId}:{history.Metadata.InternalRecordId} - {history.Metadata.Status} - {history.Payload.DeserializePayloadUsingSpecificFactory<IHaveDetails>(stream.SerializerFactory).Details ?? "<no details specified>"}")); //} //var blockingHistory = stream.Execute(new StandardGetHandlingHistoryOp(0, Concerns.StreamHandlingDisabledConcern)); //foreach (var history in blockingHistory) //{ // this.testOutputHelper.WriteLine( // Invariant( // $"{history.Metadata.Concern}: {history.InternalHandlingEntryId}:{history.Metadata.InternalRecordId} - {history.Metadata.Status} - {history.Payload.DeserializePayloadUsingSpecificFactory<IHaveDetails>(stream.SerializerFactory).Details ?? "<no details specified>"}")); //} } var stop = DateTime.UtcNow; this.testOutputHelper.WriteLine(Invariant($"TotalSeconds: {(stop - start).TotalSeconds}.")); /* * var allLocators = stream.ResourceLocatorProtocols.Execute(new GetAllResourceLocatorsOp()).ToList(); * var pruneDate = start.AddMilliseconds((stop - start).TotalMilliseconds / 2); * allLocators.ForEach(_ => stream.Execute(new StandardPruneStreamOp(pruneDate, "Pruning by date.", _))); * allLocators.ForEach(_ => stream.Execute(new PruneBeforeInternalRecordIdOp(7, "Pruning by id.", _))); */ }