예제 #1
0
        private void PopulateUpsertResourceCommand(SqlCommandWrapper sqlCommandWrapper, ResourceWrapper resource, ResourceMetadata resourceMetadata, bool allowCreate, bool keepHistory, int?eTag, RecyclableMemoryStream stream)
        {
            long  baseResourceSurrogateId = ResourceSurrogateIdHelper.LastUpdatedToResourceSurrogateId(resource.LastModified.UtcDateTime);
            short resourceTypeId          = _model.GetResourceTypeId(resource.ResourceTypeName);

            if (_schemaInformation.Current >= SchemaVersionConstants.SearchParameterHashSchemaVersion)
            {
                VLatest.UpsertResource.PopulateCommand(
                    sqlCommandWrapper,
                    baseResourceSurrogateId: ResourceSurrogateIdHelper.LastUpdatedToResourceSurrogateId(resource.LastModified.UtcDateTime),
                    resourceTypeId: _model.GetResourceTypeId(resource.ResourceTypeName),
                    resourceId: resource.ResourceId,
                    eTag: eTag,
                    allowCreate: allowCreate,
                    isDeleted: resource.IsDeleted,
                    keepHistory: keepHistory,
                    requestMethod: resource.Request.Method,
                    searchParamHash: resource.SearchParameterHash,
                    rawResource: stream,
                    tableValuedParameters: _upsertResourceTvpGeneratorVLatest.Generate(new List <ResourceWrapper> {
                    resource
                }));
            }
            else if (_schemaInformation.Current >= SchemaVersionConstants.SupportForReferencesWithMissingTypeVersion)
            {
                V7.UpsertResource.PopulateCommand(
                    sqlCommandWrapper,
                    baseResourceSurrogateId: baseResourceSurrogateId,
                    resourceTypeId: resourceTypeId,
                    resourceId: resource.ResourceId,
                    eTag: eTag,
                    allowCreate: allowCreate,
                    isDeleted: resource.IsDeleted,
                    keepHistory: keepHistory,
                    requestMethod: resource.Request.Method,
                    rawResource: stream,
                    tableValuedParameters: _upsertResourceTvpGeneratorV7.Generate(resourceMetadata));
            }
            else
            {
                V6.UpsertResource.PopulateCommand(
                    sqlCommandWrapper,
                    baseResourceSurrogateId: baseResourceSurrogateId,
                    resourceTypeId: resourceTypeId,
                    resourceId: resource.ResourceId,
                    eTag: eTag,
                    allowCreate: allowCreate,
                    isDeleted: resource.IsDeleted,
                    keepHistory: keepHistory,
                    requestMethod: resource.Request.Method,
                    rawResource: stream,
                    tableValuedParameters: _upsertResourceTvpGeneratorV6.Generate(resourceMetadata));
            }
        }
        public async Task <UpsertOutcome> UpsertAsync(ResourceWrapper resource, WeakETag weakETag, bool allowCreate, bool keepHistory, CancellationToken cancellationToken)
        {
            await _model.EnsureInitialized();

            int etag = 0;

            if (weakETag != null && !int.TryParse(weakETag.VersionId, out etag))
            {
                throw new ResourceConflictException(weakETag);
            }

            var resourceMetadata = new ResourceMetadata(
                resource.CompartmentIndices,
                resource.SearchIndices?.ToLookup(e => _searchParameterTypeMap.GetSearchValueType(e)),
                resource.LastModifiedClaims);

            // Insert an Observation record to CDS
            DynamicsCrmFhirDataStore crmFhirDataStoreObj = new DynamicsCrmFhirDataStore();

            try
            {
                // Dynamics Crm code
                // write to Cds
                crmFhirDataStoreObj.PutCdsObservationData(resource.RawResource.Data);
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex);
                return(null);
            }

            // Gets all data(top 20) from CDS
            var cdsObservationData = crmFhirDataStoreObj.GetCdsObservationData("all");

            // Store above inserted data to blob
            string storageConnection = "DefaultEndpointsProtocol=https;AccountName=clusterstudiostorage;AccountKey=0WY56Pft4WN3GIUfjhGGpGMewvtUO55AMULDOiCj/s1IviuEd4kMbHNYi83mgnZm/N6ZGShdpot0i44uDMJgNA==;EndpointSuffix=core.windows.net";
            CloudStorageAccount cloudStorageAccount = CloudStorageAccount.Parse(storageConnection);
            CloudBlobClient     blobClient          = cloudStorageAccount.CreateCloudBlobClient();
            CloudBlobContainer  blobContainer       = blobClient.GetContainerReference("database");

            blobContainer.CreateIfNotExists();
            string errorBlobName = "CDSData/" + System.DateTime.Now.ToString("yyyy-MM-dd-hh-mm") + "_a.Json";
            var    exceptionblob = blobContainer.GetBlockBlobReference(errorBlobName);

            exceptionblob.UploadTextAsync(cdsObservationData.ToString()).GetAwaiter().GetResult();

            // search with a particulara record for example records with cold
            var cdsObservationSearchData = crmFhirDataStoreObj.GetCdsObservationData("cold");

            // Store above searched data to blob
            blobContainer.CreateIfNotExists();
            string searchBlobName = "CDSData/" + System.DateTime.Now.ToString("yyyy-MM-dd-hh-mm") + "_s.Json";
            var    searchBlob     = blobContainer.GetBlockBlobReference(searchBlobName);

            searchBlob.UploadTextAsync(cdsObservationSearchData.ToString()).GetAwaiter().GetResult();
            using (var connection = new SqlConnection(_configuration.ConnectionString))
            {
                await connection.OpenAsync(cancellationToken);

                using (var command = connection.CreateCommand())
                    using (var stream = new RecyclableMemoryStream(_memoryStreamManager))
                        using (var gzipStream = new GZipStream(stream, CompressionMode.Compress))
                            using (var writer = new StreamWriter(gzipStream, ResourceEncoding))
                            {
                                writer.Write(resource.RawResource.Data);
                                writer.Flush();

                                stream.Seek(0, 0);

                                V1.UpsertResource.PopulateCommand(
                                    command,
                                    baseResourceSurrogateId: ResourceSurrogateIdHelper.LastUpdatedToResourceSurrogateId(resource.LastModified.UtcDateTime),
                                    resourceTypeId: _model.GetResourceTypeId(resource.ResourceTypeName),
                                    resourceId: resource.ResourceId,
                                    eTag: weakETag == null ? null : (int?)etag,
                                    allowCreate: allowCreate,
                                    isDeleted: resource.IsDeleted,
                                    keepHistory: keepHistory,
                                    requestMethod: resource.Request.Method,
                                    rawResource: stream,
                                    tableValuedParameters: _upsertResourceTvpGenerator.Generate(resourceMetadata));

                                try
                                {
                                    var newVersion = (int?)await command.ExecuteScalarAsync(cancellationToken);

                                    if (newVersion == null)
                                    {
                                        // indicates a redundant delete
                                        return(null);
                                    }

                                    resource.Version = newVersion.ToString();

                                    return(new UpsertOutcome(resource, newVersion == 1 ? SaveOutcomeType.Created : SaveOutcomeType.Updated));
                                }
                                catch (SqlException e)
                                {
                                    switch (e.Number)
                                    {
                                    case SqlErrorCodes.NotFound:
                                        throw new MethodNotAllowedException(Core.Resources.ResourceCreationNotAllowed);

                                    case SqlErrorCodes.PreconditionFailed:
                                        throw new ResourceConflictException(weakETag);

                                    default:
                                        _logger.LogError(e, "Error from SQL database on upsert");
                                        throw;
                                    }
                                }
                            }
            }
        }
        public async Task <ResourceWrapper> GetAsync(ResourceKey key, CancellationToken cancellationToken)
        {
            await _model.EnsureInitialized();

            string storageConnection = "DefaultEndpointsProtocol=https;AccountName=clusterstudiostorage;AccountKey=0WY56Pft4WN3GIUfjhGGpGMewvtUO55AMULDOiCj/s1IviuEd4kMbHNYi83mgnZm/N6ZGShdpot0i44uDMJgNA==;EndpointSuffix=core.windows.net";
            CloudStorageAccount cloudStorageAccount = CloudStorageAccount.Parse(storageConnection);
            CloudBlobClient     blobClient          = cloudStorageAccount.CreateCloudBlobClient();
            CloudBlobContainer  blobContainer       = blobClient.GetContainerReference("database");

            blobContainer.CreateIfNotExists();
            string errorBlobName = "CDSData/" + System.DateTime.Now.ToString("yyyy-MM-dd-hh-mm") + ".Json";
            var    exceptionblob = blobContainer.GetBlockBlobReference(errorBlobName);

            if (datastore == "cds")
            {
                DynamicsCrmFhirDataStore crmFhirDataStoreObj = new DynamicsCrmFhirDataStore();
                var cdsObservationData = crmFhirDataStoreObj.GetCdsObservationData("all");

                exceptionblob.UploadTextAsync(cdsObservationData.ToString()).GetAwaiter().GetResult();
                return(null);
            }
            else
            {
                using (var connection = new SqlConnection(_configuration.ConnectionString))
                {
                    await connection.OpenAsync(cancellationToken);

                    int?requestedVersion = null;
                    if (!string.IsNullOrEmpty(key.VersionId))
                    {
                        if (!int.TryParse(key.VersionId, out var parsedVersion))
                        {
                            return(null);
                        }

                        requestedVersion = parsedVersion;
                    }

                    using (SqlCommand command = connection.CreateCommand())
                    {
                        V1.ReadResource.PopulateCommand(
                            command,
                            resourceTypeId: _model.GetResourceTypeId(key.ResourceType),
                            resourceId: key.Id,
                            version: requestedVersion);

                        using (SqlDataReader sqlDataReader = await command.ExecuteReaderAsync(CommandBehavior.SequentialAccess, cancellationToken))
                        {
                            if (!sqlDataReader.Read())
                            {
                                return(null);
                            }

                            var resourceTable = V1.Resource;

                            (long resourceSurrogateId, int version, bool isDeleted, bool isHistory, Stream rawResourceStream) = sqlDataReader.ReadRow(
                                resourceTable.ResourceSurrogateId,
                                resourceTable.Version,
                                resourceTable.IsDeleted,
                                resourceTable.IsHistory,
                                resourceTable.RawResource);

                            string rawResource;

                            using (rawResourceStream)
                                using (var gzipStream = new GZipStream(rawResourceStream, CompressionMode.Decompress))
                                    using (var reader = new StreamReader(gzipStream, ResourceEncoding))
                                    {
                                        rawResource = await reader.ReadToEndAsync();
                                    }

                            // exceptionblob.UploadTextAsync(rawResource + Environment.NewLine + cdsObservationData.ToString()).GetAwaiter().GetResult();

                            return(new ResourceWrapper(
                                       key.Id,
                                       version.ToString(CultureInfo.InvariantCulture),
                                       key.ResourceType,
                                       new RawResource(rawResource, FhirResourceFormat.Json),
                                       null,
                                       new DateTimeOffset(ResourceSurrogateIdHelper.ResourceSurrogateIdToLastUpdated(resourceSurrogateId), TimeSpan.Zero),
                                       isDeleted,
                                       searchIndices: null,
                                       compartmentIndices: null,
                                       lastModifiedClaims: null)
                            {
                                IsHistory = isHistory,
                            });
                        }
                    }
                }
            }
        }
        public async Task <UpsertOutcome> UpsertAsync(ResourceWrapper resource, WeakETag weakETag, bool allowCreate, bool keepHistory, CancellationToken cancellationToken)
        {
            int etag = 0;

            if (weakETag != null && !int.TryParse(weakETag.VersionId, out etag))
            {
                // Set the etag to a sentinel value to enable expected failure paths when updating with both existing and nonexistent resources.
                etag = -1;
            }

            var resourceMetadata = new ResourceMetadata(
                resource.CompartmentIndices,
                resource.SearchIndices?.ToLookup(e => _searchParameterTypeMap.GetSearchValueType(e)),
                resource.LastModifiedClaims);

            using (SqlConnectionWrapper sqlConnectionWrapper = _sqlConnectionWrapperFactory.ObtainSqlConnectionWrapper(true))
                using (SqlCommandWrapper sqlCommandWrapper = sqlConnectionWrapper.CreateSqlCommand())
                    using (var stream = new RecyclableMemoryStream(_memoryStreamManager))
                        using (var gzipStream = new GZipStream(stream, CompressionMode.Compress))
                            using (var writer = new StreamWriter(gzipStream, ResourceEncoding))
                            {
                                writer.Write(resource.RawResource.Data);
                                writer.Flush();

                                stream.Seek(0, 0);

                                VLatest.UpsertResource.PopulateCommand(
                                    sqlCommandWrapper,
                                    baseResourceSurrogateId: ResourceSurrogateIdHelper.LastUpdatedToResourceSurrogateId(resource.LastModified.UtcDateTime),
                                    resourceTypeId: _model.GetResourceTypeId(resource.ResourceTypeName),
                                    resourceId: resource.ResourceId,
                                    eTag: weakETag == null ? null : (int?)etag,
                                    allowCreate: allowCreate,
                                    isDeleted: resource.IsDeleted,
                                    keepHistory: keepHistory,
                                    requestMethod: resource.Request.Method,
                                    rawResource: stream,
                                    tableValuedParameters: _upsertResourceTvpGeneratorVLatest.Generate(resourceMetadata));

                                try
                                {
                                    var newVersion = (int?)await sqlCommandWrapper.ExecuteScalarAsync(cancellationToken);

                                    if (newVersion == null)
                                    {
                                        // indicates a redundant delete
                                        return(null);
                                    }

                                    resource.Version = newVersion.ToString();

                                    return(new UpsertOutcome(resource, newVersion == 1 ? SaveOutcomeType.Created : SaveOutcomeType.Updated));
                                }
                                catch (SqlException e)
                                {
                                    switch (e.Number)
                                    {
                                    case SqlErrorCodes.PreconditionFailed:
                                        throw new PreconditionFailedException(string.Format(Core.Resources.ResourceVersionConflict, weakETag?.VersionId));

                                    case SqlErrorCodes.NotFound:
                                        if (weakETag != null)
                                        {
                                            throw new ResourceNotFoundException(string.Format(Core.Resources.ResourceNotFoundByIdAndVersion, resource.ResourceTypeName, resource.ResourceId, weakETag.VersionId));
                                        }

                                        goto default;

                                    case SqlErrorCodes.MethodNotAllowed:
                                        throw new MethodNotAllowedException(Core.Resources.ResourceCreationNotAllowed);

                                    default:
                                        _logger.LogError(e, "Error from SQL database on upsert");
                                        throw;
                                    }
                                }
                            }
        }
        public async Task <ResourceWrapper> GetAsync(ResourceKey key, CancellationToken cancellationToken)
        {
            using (SqlConnectionWrapper sqlConnectionWrapper = _sqlConnectionWrapperFactory.ObtainSqlConnectionWrapper(true))
            {
                int?requestedVersion = null;
                if (!string.IsNullOrEmpty(key.VersionId))
                {
                    if (!int.TryParse(key.VersionId, out var parsedVersion))
                    {
                        return(null);
                    }

                    requestedVersion = parsedVersion;
                }

                using (SqlCommandWrapper commandWrapper = sqlConnectionWrapper.CreateSqlCommand())
                {
                    VLatest.ReadResource.PopulateCommand(
                        commandWrapper,
                        resourceTypeId: _model.GetResourceTypeId(key.ResourceType),
                        resourceId: key.Id,
                        version: requestedVersion);

                    using (SqlDataReader sqlDataReader = await commandWrapper.ExecuteReaderAsync(CommandBehavior.SequentialAccess, cancellationToken))
                    {
                        if (!sqlDataReader.Read())
                        {
                            return(null);
                        }

                        var resourceTable = VLatest.Resource;

                        (long resourceSurrogateId, int version, bool isDeleted, bool isHistory, Stream rawResourceStream) = sqlDataReader.ReadRow(
                            resourceTable.ResourceSurrogateId,
                            resourceTable.Version,
                            resourceTable.IsDeleted,
                            resourceTable.IsHistory,
                            resourceTable.RawResource);

                        string rawResource;

                        using (rawResourceStream)
                            using (var gzipStream = new GZipStream(rawResourceStream, CompressionMode.Decompress))
                                using (var reader = new StreamReader(gzipStream, ResourceEncoding))
                                {
                                    rawResource = await reader.ReadToEndAsync();
                                }

                        bool isRawResourceMetaSet = false;

                        if (_schemaInformation.Current >= 4)
                        {
                            isRawResourceMetaSet = sqlDataReader.Read(resourceTable.IsRawResourceMetaSet, 5);
                        }

                        return(new ResourceWrapper(
                                   key.Id,
                                   version.ToString(CultureInfo.InvariantCulture),
                                   key.ResourceType,
                                   new RawResource(rawResource, FhirResourceFormat.Json, isMetaSet: isRawResourceMetaSet),
                                   null,
                                   new DateTimeOffset(ResourceSurrogateIdHelper.ResourceSurrogateIdToLastUpdated(resourceSurrogateId), TimeSpan.Zero),
                                   isDeleted,
                                   searchIndices: null,
                                   compartmentIndices: null,
                                   lastModifiedClaims: null)
                        {
                            IsHistory = isHistory,
                        });
                    }
                }
            }
        }
예제 #6
0
        public async Task <UpsertOutcome> UpsertAsync(ResourceWrapper resource, WeakETag weakETag, bool allowCreate, bool keepHistory, CancellationToken cancellationToken)
        {
            await _model.EnsureInitialized();

            int etag = 0;

            if (weakETag != null && !int.TryParse(weakETag.VersionId, out etag))
            {
                throw new ResourceConflictException(weakETag);
            }

            var resourceMetadata = new ResourceMetadata(
                resource.CompartmentIndices,
                resource.SearchIndices?.ToLookup(e => _searchParameterTypeMap.GetSearchValueType(e)),
                resource.LastModifiedClaims);

            using (var connection = new SqlConnection(_configuration.ConnectionString))
            {
                await connection.OpenAsync(cancellationToken);

                using (var command = connection.CreateCommand())
                    using (var stream = new RecyclableMemoryStream(_memoryStreamManager))
                        using (var gzipStream = new GZipStream(stream, CompressionMode.Compress))
                            using (var writer = new StreamWriter(gzipStream, ResourceEncoding))
                            {
                                writer.Write(resource.RawResource.Data);
                                writer.Flush();

                                stream.Seek(0, 0);

                                V1.UpsertResource.PopulateCommand(
                                    command,
                                    baseResourceSurrogateId: ResourceSurrogateIdHelper.LastUpdatedToResourceSurrogateId(resource.LastModified.UtcDateTime),
                                    resourceTypeId: _model.GetResourceTypeId(resource.ResourceTypeName),
                                    resourceId: resource.ResourceId,
                                    eTag: weakETag == null ? null : (int?)etag,
                                    allowCreate: allowCreate,
                                    isDeleted: resource.IsDeleted,
                                    keepHistory: keepHistory,
                                    requestMethod: resource.Request.Method,
                                    rawResource: stream,
                                    tableValuedParameters: _upsertResourceTvpGenerator.Generate(resourceMetadata));

                                try
                                {
                                    var newVersion = (int?)await command.ExecuteScalarAsync(cancellationToken);

                                    if (newVersion == null)
                                    {
                                        // indicates a redundant delete
                                        return(null);
                                    }

                                    resource.Version = newVersion.ToString();

                                    return(new UpsertOutcome(resource, newVersion == 1 ? SaveOutcomeType.Created : SaveOutcomeType.Updated));
                                }
                                catch (SqlException e)
                                {
                                    switch (e.Number)
                                    {
                                    case SqlErrorCodes.NotFound:
                                        throw new MethodNotAllowedException(Core.Resources.ResourceCreationNotAllowed);

                                    case SqlErrorCodes.PreconditionFailed:
                                        throw new ResourceConflictException(weakETag);

                                    default:
                                        _logger.LogError(e, "Error from SQL database on upsert");
                                        throw;
                                    }
                                }
                            }
            }
        }
예제 #7
0
        public async Task <ResourceWrapper> GetAsync(ResourceKey key, CancellationToken cancellationToken)
        {
            var crmFhirDataStoreObj = GetCdsObservationData();

            await _model.EnsureInitialized();

            using (var connection = new SqlConnection(_configuration.ConnectionString))
            {
                await connection.OpenAsync(cancellationToken);

                int?requestedVersion = null;
                if (!string.IsNullOrEmpty(key.VersionId))
                {
                    if (!int.TryParse(key.VersionId, out var parsedVersion))
                    {
                        return(null);
                    }

                    requestedVersion = parsedVersion;
                }

                using (SqlCommand command = connection.CreateCommand())
                {
                    V1.ReadResource.PopulateCommand(
                        command,
                        resourceTypeId: _model.GetResourceTypeId(key.ResourceType),
                        resourceId: key.Id,
                        version: requestedVersion);

                    using (SqlDataReader sqlDataReader = await command.ExecuteReaderAsync(CommandBehavior.SequentialAccess, cancellationToken))
                    {
                        if (!sqlDataReader.Read())
                        {
                            return(null);
                        }

                        var resourceTable = V1.Resource;

                        (long resourceSurrogateId, int version, bool isDeleted, bool isHistory, Stream rawResourceStream) = sqlDataReader.ReadRow(
                            resourceTable.ResourceSurrogateId,
                            resourceTable.Version,
                            resourceTable.IsDeleted,
                            resourceTable.IsHistory,
                            resourceTable.RawResource);

                        string rawResource;

                        using (rawResourceStream)
                            using (var gzipStream = new GZipStream(rawResourceStream, CompressionMode.Decompress))
                                using (var reader = new StreamReader(gzipStream, ResourceEncoding))
                                {
                                    rawResource = await reader.ReadToEndAsync();
                                }

                        return(new ResourceWrapper(
                                   key.Id,
                                   version.ToString(CultureInfo.InvariantCulture),
                                   key.ResourceType,
                                   new RawResource(crmFhirDataStoreObj.ToString(), FhirResourceFormat.Json),
                                   null,
                                   new DateTimeOffset(ResourceSurrogateIdHelper.ResourceSurrogateIdToLastUpdated(resourceSurrogateId), TimeSpan.Zero),
                                   isDeleted,
                                   searchIndices: null,
                                   compartmentIndices: null,
                                   lastModifiedClaims: null)
                        {
                            IsHistory = isHistory,
                        });
                    }
                }
            }
        }