public async Task <UpsertResourceResponse> Handle(UpsertResourceRequest request, CancellationToken cancellationToken)
        {
            EnsureArg.IsNotNull(request, nameof(request));

            if (await AuthorizationService.CheckAccess(DataActions.Write, cancellationToken) != DataActions.Write)
            {
                throw new UnauthorizedFhirActionException();
            }

            Resource resource = request.Resource.ToPoco <Resource>();

            bool allowCreate = await ConformanceProvider.Value.CanUpdateCreate(resource.TypeName, cancellationToken);

            bool keepHistory = await ConformanceProvider.Value.CanKeepHistory(resource.TypeName, cancellationToken);

            bool requireETagOnUpdate = await ConformanceProvider.Value.RequireETag(resource.TypeName, cancellationToken);

            ResourceWrapper resourceWrapper = CreateResourceWrapper(resource, deleted: false, keepMeta: allowCreate);

            UpsertOutcome result = await FhirDataStore.UpsertAsync(resourceWrapper, request.WeakETag, allowCreate, keepHistory, cancellationToken, requireETagOnUpdate);

            resource.VersionId = result.Wrapper.Version;

            return(new UpsertResourceResponse(new SaveOutcome(new RawResourceElement(result.Wrapper), result.OutcomeType)));
        }
Пример #2
0
 public async Task <UpsertOutcome> UpsertAsync(
     ResourceWrapper resource,
     WeakETag weakETag,
     bool allowCreate,
     bool keepHistory,
     CancellationToken cancellationToken = default(CancellationToken))
 {
     return(await _dataStore.UpsertAsync(resource, weakETag, allowCreate, keepHistory, cancellationToken));
 }
Пример #3
0
        public async Task <DeleteResourceResponse> Handle(DeleteResourceRequest request, CancellationToken cancellationToken)
        {
            EnsureArg.IsNotNull(request, nameof(request));

            DataActions requiredDataAction = request.DeleteOperation == DeleteOperation.SoftDelete ? DataActions.Delete : DataActions.HardDelete | DataActions.Delete;

            if (await AuthorizationService.CheckAccess(requiredDataAction, cancellationToken) != requiredDataAction)
            {
                throw new UnauthorizedFhirActionException();
            }

            var key = request.ResourceKey;

            if (!string.IsNullOrEmpty(key.VersionId))
            {
                throw new MethodNotAllowedException(Core.Resources.DeleteVersionNotAllowed);
            }

            string version = null;

            switch (request.DeleteOperation)
            {
            case DeleteOperation.SoftDelete:
                var emptyInstance = (Resource)Activator.CreateInstance(ModelInfo.GetTypeForFhirType(request.ResourceKey.ResourceType));
                emptyInstance.Id = request.ResourceKey.Id;

                ResourceWrapper deletedWrapper = CreateResourceWrapper(emptyInstance, deleted: true, keepMeta: false);

                bool keepHistory = await ConformanceProvider.Value.CanKeepHistory(key.ResourceType, cancellationToken);

                UpsertOutcome result = await FhirDataStore.UpsertAsync(
                    deletedWrapper,
                    weakETag : null,
                    allowCreate : true,
                    keepHistory : keepHistory,
                    cancellationToken : cancellationToken);

                version = result?.Wrapper.Version;
                break;

            case DeleteOperation.HardDelete:
            case DeleteOperation.PurgeHistory:
                await FhirDataStore.HardDeleteAsync(key, request.DeleteOperation == DeleteOperation.PurgeHistory, cancellationToken);

                break;

            default:
                throw new ArgumentOutOfRangeException(nameof(request));
            }

            if (string.IsNullOrWhiteSpace(version))
            {
                return(new DeleteResourceResponse(new ResourceKey(key.ResourceType, key.Id)));
            }

            return(new DeleteResourceResponse(new ResourceKey(key.ResourceType, key.Id, version), weakETag: WeakETag.FromVersionId(version)));
        }
        public async Task <DeleteResourceResponse> Handle(DeleteResourceRequest message, CancellationToken cancellationToken)
        {
            EnsureArg.IsNotNull(message, nameof(message));

            var key = message.ResourceKey;

            if (!string.IsNullOrEmpty(key.VersionId))
            {
                throw new MethodNotAllowedException(Core.Resources.DeleteVersionNotAllowed);
            }

            string version = null;

            if (message.HardDelete)
            {
                await FhirDataStore.HardDeleteAsync(key, cancellationToken);
            }
            else
            {
                ResourceWrapper existing = await FhirDataStore.GetAsync(key, cancellationToken);

                version = existing?.Version;

                if (existing?.IsDeleted == false)
                {
                    var emptyInstance = (Resource)Activator.CreateInstance(ModelInfo.GetTypeForFhirType(existing.ResourceTypeName));
                    emptyInstance.Id = existing.ResourceId;

                    ResourceWrapper deletedWrapper = CreateResourceWrapper(emptyInstance, deleted: true);

                    bool keepHistory = await ConformanceProvider.Value.CanKeepHistory(key.ResourceType, cancellationToken);

                    UpsertOutcome result = await FhirDataStore.UpsertAsync(
                        deletedWrapper,
                        WeakETag.FromVersionId(existing.Version),
                        allowCreate : true,
                        keepHistory : keepHistory,
                        cancellationToken : cancellationToken);

                    version = result.Wrapper.Version;
                }
            }

            if (string.IsNullOrWhiteSpace(version))
            {
                return(new DeleteResourceResponse(new ResourceKey(key.ResourceType, key.Id)));
            }

            return(new DeleteResourceResponse(new ResourceKey(key.ResourceType, key.Id, version), WeakETag.FromVersionId(version)));
        }
Пример #5
0
        public async Task <DeleteResourceResponse> Handle(DeleteResourceRequest message, CancellationToken cancellationToken)
        {
            EnsureArg.IsNotNull(message, nameof(message));

            DataActions requiredDataAction = message.HardDelete ? DataActions.Delete | DataActions.HardDelete : DataActions.Delete;

            if (AuthorizationService.CheckAccess(requiredDataAction) != requiredDataAction)
            {
                throw new UnauthorizedFhirActionException();
            }

            var key = message.ResourceKey;

            if (!string.IsNullOrEmpty(key.VersionId))
            {
                throw new MethodNotAllowedException(Core.Resources.DeleteVersionNotAllowed);
            }

            string version = null;

            if (message.HardDelete)
            {
                await FhirDataStore.HardDeleteAsync(key, cancellationToken);
            }
            else
            {
                var emptyInstance = (Resource)Activator.CreateInstance(ModelInfo.GetTypeForFhirType(message.ResourceKey.ResourceType));
                emptyInstance.Id = message.ResourceKey.Id;

                ResourceWrapper deletedWrapper = CreateResourceWrapper(emptyInstance, deleted: true);

                bool keepHistory = await ConformanceProvider.Value.CanKeepHistory(key.ResourceType, cancellationToken);

                UpsertOutcome result = await FhirDataStore.UpsertAsync(
                    deletedWrapper,
                    weakETag : null,
                    allowCreate : true,
                    keepHistory : keepHistory,
                    cancellationToken : cancellationToken);

                version = result?.Wrapper.Version;
            }

            if (string.IsNullOrWhiteSpace(version))
            {
                return(new DeleteResourceResponse(new ResourceKey(key.ResourceType, key.Id)));
            }

            return(new DeleteResourceResponse(new ResourceKey(key.ResourceType, key.Id, version), WeakETag.FromVersionId(version)));
        }
        private async Task <UpsertOutcome> UpsertAsync(UpsertResourceRequest message, ResourceWrapper resourceWrapper, bool allowCreate, bool keepHistory, CancellationToken cancellationToken)
        {
            UpsertOutcome result;

            try
            {
                result = await FhirDataStore.UpsertAsync(resourceWrapper, message.WeakETag, allowCreate, keepHistory, cancellationToken);
            }
            catch (PreconditionFailedException)
            {
                throw new ResourceConflictException(message.WeakETag);
            }

            return(result);
        }
        private async Task <UpsertOutcome> UpsertAsync(UpsertResourceRequest message, ResourceWrapper resourceWrapper, bool allowCreate, bool keepHistory, CancellationToken cancellationToken)
        {
            UpsertOutcome result;

            try
            {
                result = await FhirDataStore.UpsertAsync(resourceWrapper, message.WeakETag, allowCreate, keepHistory, cancellationToken);
            }
            catch (PreconditionFailedException) when(_modelInfoProvider.Version == FhirSpecification.Stu3)
            {
                // The backwards compatibility behavior of Stu3 is to return a Conflict instead of Precondition fail
                throw new ResourceConflictException(message.WeakETag);
            }

            return(result);
        }
Пример #8
0
        public async Task <PatchResourceResponse> Handle(PatchResourceRequest message, CancellationToken cancellationToken)
        {
            EnsureArg.IsNotNull(message, nameof(message));

            if (await AuthorizationService.CheckAccess(DataActions.Write, cancellationToken) != DataActions.Write)
            {
                throw new UnauthorizedFhirActionException();
            }

            var key = message.ResourceKey;

            if (!string.IsNullOrEmpty(key.VersionId))
            {
                throw new MethodNotAllowedException(Core.Resources.DeleteVersionNotAllowed);
            }

            ResourceWrapper currentDoc = await FhirDataStore.GetAsync(key, cancellationToken);

            if (currentDoc == null)
            {
                throw new ResourceNotFoundException(string.Format(Core.Resources.ResourceNotFoundById, key.ResourceType, key.Id));
            }

            ResourceElement resource         = _resourceDeserializer.Deserialize(currentDoc);
            Resource        resourceInstance = resource.Instance.ToPoco <Resource>();

            message.PatchDocument.ApplyTo(resourceInstance);

            ResourceWrapper resourceWrapper = CreateResourceWrapper(resourceInstance, deleted: false, keepMeta: true);
            bool            keepHistory     = await ConformanceProvider.Value.CanKeepHistory(currentDoc.ResourceTypeName, cancellationToken);

            UpsertOutcome result = await FhirDataStore.UpsertAsync(
                resourceWrapper,
                weakETag : message.WeakETag,
                allowCreate : false,
                keepHistory : keepHistory,
                cancellationToken : cancellationToken);

            resourceInstance.VersionId = result.Wrapper.Version;

            return(new PatchResourceResponse(new SaveOutcome(new RawResourceElement(result.Wrapper), result.OutcomeType)));
        }
Пример #9
0
        public async Task <UpsertResourceResponse> Handle(UpsertResourceRequest message, CancellationToken cancellationToken)
        {
            EnsureArg.IsNotNull(message, nameof(message));

            Resource resource = message.Resource;

            if (await ConformanceProvider.Value.RequireETag(resource.TypeName, cancellationToken) && message.WeakETag == null)
            {
                throw new PreconditionFailedException(string.Format(Core.Resources.IfMatchHeaderRequiredForResource, resource.TypeName));
            }

            bool allowCreate = await ConformanceProvider.Value.CanUpdateCreate(resource.TypeName, cancellationToken);

            bool keepHistory = await ConformanceProvider.Value.CanKeepHistory(resource.TypeName, cancellationToken);

            ResourceWrapper resourceWrapper = CreateResourceWrapper(resource, deleted: false);
            UpsertOutcome   result          = await FhirDataStore.UpsertAsync(resourceWrapper, message.WeakETag, allowCreate, keepHistory, cancellationToken);

            resource.VersionId = result.Wrapper.Version;

            return(new UpsertResourceResponse(new SaveOutcome(resource, result.OutcomeType)));
        }
        public async Task <UpsertResourceResponse> Handle(CreateResourceRequest message, CancellationToken cancellationToken)
        {
            EnsureArg.IsNotNull(message, nameof(message));

            var resource = message.Resource.Instance.ToPoco <Resource>();

            // If an Id is supplied on create it should be removed/ignored
            resource.Id = null;

            ResourceWrapper resourceWrapper = CreateResourceWrapper(resource, deleted: false);

            bool keepHistory = await ConformanceProvider.Value.CanKeepHistory(resource.TypeName, cancellationToken);

            UpsertOutcome result = await FhirDataStore.UpsertAsync(
                resourceWrapper,
                weakETag : null,
                allowCreate : true,
                keepHistory : keepHistory,
                cancellationToken : cancellationToken);

            resource.VersionId = result.Wrapper.Version;

            return(new UpsertResourceResponse(new SaveOutcome(resource.ToResourceElement(), SaveOutcomeType.Created)));
        }
Пример #11
0
 private async Task <UpsertOutcome> UpsertAsync(UpsertResourceRequest message, ResourceWrapper resourceWrapper, bool allowCreate, bool keepHistory, CancellationToken cancellationToken)
 {
     return(await FhirDataStore.UpsertAsync(resourceWrapper, message.WeakETag, allowCreate, keepHistory, cancellationToken));
 }