Ejemplo n.º 1
0
        public async Task <IActionResult> Submit([FromBody] Models.MeasureSubmissionViewModel data)
        {
            if (User.Identity.IsAuthenticated == false)
            {
                return(BadRequest(new Models.ApiErrorResult("User must be authenticated to view measures.")));
            }

            if (data == null)
            {
                return(BadRequest(new Models.ApiErrorResult("Invalid measure data.")));
            }

            if (!User.Claims.Any(cl => cl.Type == Identity.Claims.SubmitMeasure_Key))
            {
                return(BadRequest(new Models.ApiErrorResult("The user does not have permission to submit measures.")));
            }

            List <string> errors = new List <string>();

            if (!ValidateSubmission(data, errors))
            {
                return(BadRequest(new { errors }));
            }

            var user = await _modelDB.Users.FindAsync(Guid.Parse(User.Claims.Where(x => x.Type == ClaimTypes.NameIdentifier).Select(x => x.Value).FirstOrDefault()));

            MeasurementMeta measure = new MeasurementMeta
            {
                CommonDataModel        = data.CommonDataModel,
                DatabaseSystem         = data.DatabaseSystem,
                DataSource             = data.DataSource,
                DataSourceID           = data.DataSourceID,
                DateRangeEnd           = data.DateRangeEnd.Value,
                DateRangeStart         = data.DateRangeStart.Value,
                MetricID               = data.MetricID.Value,
                Network                = data.Network,
                Organization           = data.Organization,
                OrganizationID         = data.OrganizationID,
                RunDate                = data.RunDate.Value,
                SubmittedByID          = user.ID,
                SubmittedOn            = DateTime.UtcNow,
                CommonDataModelVersion = data.CommonDataModelVersion,
                ResultsDelimiter       = data.ResultsDelimiter,
                ResultsTypeID          = await _modelDB.MetricResultTypes.Where(rt => rt.Metrics.Any(m => m.ID == data.MetricID.Value)).Select(rt => rt.ID).FirstOrDefaultAsync(),
                SupportingResources    = data.SupportingResources
            };

            measure.Measurements = new HashSet <Measurement>(data.Measures.Select(i => new Measurement {
                MetadataID = measure.ID, RawValue = i.RawValue, Definition = string.IsNullOrEmpty(i.Definition) ? i.RawValue : i.Definition, Measure = i.Measure.HasValue ? i.Measure.Value : 0f, Total = i.Total
            }).ToArray());

            _modelDB.MeasurementMeta.Add(measure);

            await _modelDB.SaveChangesAsync();

            return(Ok());
        }
        public Models.MeasureSubmissionViewModel Convert(IList <string> errors)
        {
            var measure = new Models.MeasureSubmissionViewModel();

            foreach (var row in GetMetadataRows())
            {
                var cells = row.Descendants <Cell>().ToArray();

                if (cells.Length == 0)
                {
                    continue;
                }

                //check if the first cell is in column A, if not skip
                string cellReference = cells[0].CellReference.Value;
                if (!cellReference.StartsWith("A", StringComparison.OrdinalIgnoreCase))
                {
                    continue;
                }

                string metadataHeader = GetCellValue(cells[0]);

                string value = string.Empty;

                if (cells.Length > 1)
                {
                    cellReference = cells[1].CellReference.Value;
                    if (cellReference.StartsWith("B", StringComparison.OrdinalIgnoreCase))
                    {
                        value = GetCellValue(cells[1]);
                    }
                }

                SetMeasureValue(measure, metadataHeader, value);
            }

            var measurementRows = GetValuesRows().ToArray();

            if (measurementRows.Length > 1)
            {
                var measurements = new List <Models.MeasurementSubmissionViewModel>();

                //going to assume for a valid document that the first four cells of the first row will always have a value
                //assume that the cell reference for each header will be A1-D1.
                var headers = measurementRows.First().Descendants <Cell>().Take(4).Select(c => GetCellValue(c)).ToArray();

                foreach (var row in measurementRows.Skip(1))
                {
                    var cells       = row.Descendants <Cell>().ToArray();
                    var measurement = new Models.MeasurementSubmissionViewModel();

                    foreach (var cell in cells)
                    {
                        switch (cell.CellReference.Value[0].ToStringEx().ToUpper())
                        {
                        case "A":
                            SetMeasurementValue(measurement, headers[0], GetCellValue(cell));
                            break;

                        case "B":
                            SetMeasurementValue(measurement, headers[1], GetCellValue(cell));
                            break;

                        case "C":
                            SetMeasurementValue(measurement, headers[2], GetCellValue(cell));
                            break;

                        case "D":
                            SetMeasurementValue(measurement, headers[3], GetCellValue(cell));
                            break;
                        }
                    }

                    if (measurement.IsNotNull())
                    {
                        measurements.Add(measurement);
                    }
                }

                measure.Measures = measurements;
            }

            return(measure);
        }
        void SetMeasureValue(Models.MeasureSubmissionViewModel measure, string property, object value)
        {
            if (value == null)
            {
                return;
            }

            Guid id;

            switch (property.TrimEnd(' ', '*').ToLower())
            {
            case "metricid":
                if (Guid.TryParse(value.ToStringEx(), out id))
                {
                    measure.MetricID = id;
                }
                break;

            case "organizationid":
                if (Guid.TryParse(value.ToStringEx(), out id))
                {
                    measure.OrganizationID = id;
                }
                break;

            case "organization":
                measure.Organization = value.ToStringEx();
                break;

            case "datasourceid":
                if (Guid.TryParse(value.ToStringEx(), out id))
                {
                    measure.DataSourceID = id;
                }
                break;

            case "datasource":
                measure.DataSource = value.ToStringEx();
                break;

            case "rundate":
                measure.RunDate = ConvertToDate(value);
                break;

            case "network":
                measure.Network = value.ToStringEx();
                break;

            case "resultstype":
            case "datatype":
            case "results type":
            case "data type":
                measure.ResultsType = value.ToStringEx();
                break;
            }

            if (property.StartsWith("common", StringComparison.OrdinalIgnoreCase))
            {
                if (property.EndsWith("version", StringComparison.OrdinalIgnoreCase))
                {
                    measure.CommonDataModelVersion = value.ToStringEx();
                }
                else
                {
                    measure.CommonDataModel = value.ToStringEx();
                }
            }
            if (property.Contains("Results Delimiter", StringComparison.OrdinalIgnoreCase))
            {
                measure.ResultsDelimiter = value.ToStringEx();
            }
            if (property.StartsWith("database", StringComparison.OrdinalIgnoreCase))
            {
                measure.DatabaseSystem = value.ToStringEx();
            }
            if (property.Contains("range start", StringComparison.OrdinalIgnoreCase))
            {
                measure.DateRangeStart = ConvertToDate(value);
            }
            if (property.Contains("range end", StringComparison.OrdinalIgnoreCase))
            {
                measure.DateRangeEnd = ConvertToDate(value);
            }
            if (property.Contains("supporting resources", StringComparison.OrdinalIgnoreCase))
            {
                measure.SupportingResources = value.ToStringEx();
            }
        }
Ejemplo n.º 4
0
        bool ValidateSubmission(Models.MeasureSubmissionViewModel measure, IList <string> errors)
        {
            if (!measure.MetricID.HasValue)
            {
                errors.Add("Unable to determine MetricID.");
                return(false);
            }
            else
            {
                if (!_modelDB.Metrics.Any(m => m.ID == measure.MetricID.Value))
                {
                    errors.Add("Invalid MetricID, metric not found.");
                    return(false);
                }
            }

            if (string.IsNullOrEmpty(measure.Organization))
            {
                errors.Add("Missing the Organization name.");
            }

            if (string.IsNullOrEmpty(measure.DataSource))
            {
                errors.Add("Missing the DataSource name.");
            }

            if (!measure.RunDate.HasValue)
            {
                errors.Add("Missing the Run Date.");
            }

            if (!measure.DateRangeStart.HasValue)
            {
                errors.Add("Missing the Date Range Start value.");
            }

            if (!measure.DateRangeStart.HasValue)
            {
                errors.Add("Missing the Date Range End value.");
            }

            if (measure.DateRangeStart.HasValue && measure.DateRangeEnd.HasValue && measure.DateRangeStart.Value > measure.DateRangeEnd.Value)
            {
                errors.Add("The Date Range Start value should occure before the Date Range End value.");
            }

            if (string.IsNullOrEmpty(measure.ResultsType))
            {
                errors.Add("Missing the Results Type value.");
            }
            else
            {
                var validResultType = _modelDB.MetricResultTypes.Where(rt => rt.Metrics.Any(m => m.ID == measure.MetricID.Value)).Select(rt => rt.Value).FirstOrDefault();
                if (string.IsNullOrEmpty(validResultType))
                {
                    errors.Add("Unable to determine the Results Type for the specified metric.");
                }
                else if (!validResultType.Equals(measure.ResultsType, StringComparison.OrdinalIgnoreCase))
                {
                    errors.Add("Invalid Results Type value. The expected value of '" + validResultType + "' was expected for the specified Metric.");
                }
            }

            if (measure.Measures == null || measure.Measures.Any() == false)
            {
                errors.Add("At least one measurement is required.");
                return(false);
            }

            if (measure.Measures.Any(m => string.IsNullOrEmpty(m.RawValue)))
            {
                errors.Add("All measurements require a value for Raw Value.");
            }

            if (measure.Measures.Any(m => m.Measure.HasValue == false))
            {
                errors.Add("All measurements require a value for Measure.");
            }

            return(errors.Count == 0);
        }
        public async Task <IActionResult> DownloadMeasureTemplate(Guid metricID, string format)
        {
            var metric = await _db.Metrics.Where(m => m.ID == metricID).Select(m => new { m.Title, ResultsType = m.ResultsType.Value }).FirstOrDefaultAsync();

            if (metric == null)
            {
                return(NotFound());
            }

            if (string.Equals("json", format, StringComparison.OrdinalIgnoreCase))
            {
                var measure = new Models.MeasureSubmissionViewModel {
                    MetricID    = metricID,
                    ResultsType = metric.ResultsType,
                    Measures    = new HashSet <Models.MeasurementSubmissionViewModel> {
                        new Models.MeasurementSubmissionViewModel {
                            Definition = string.Empty, RawValue = string.Empty, Measure = 0, Total = 0
                        }
                    }
                };

                var serializerSettings = new Newtonsoft.Json.JsonSerializerSettings {
                    Formatting = Formatting.Indented, DateFormatString = "'yyyy-MM-dd'"
                };
                var result = new FileContentResult(System.Text.Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(measure, serializerSettings)), Microsoft.Net.Http.Headers.MediaTypeHeaderValue.Parse("application/json"))
                {
                    FileDownloadName = CleanFilename("MeasureSubmission_" + metric.Title) + ".json"
                };

                return(result);
            }
            else if (string.Equals("xlsx", format, StringComparison.OrdinalIgnoreCase))
            {
                using (var scope = _serviceProvider.CreateScope())
                {
                    var hostingEnvironment = scope.ServiceProvider.GetService <IWebHostEnvironment>();

                    System.IO.MemoryStream ms = new System.IO.MemoryStream();

                    using (var fs = new System.IO.FileStream(System.IO.Path.Combine(hostingEnvironment.WebRootPath, "assets", "MeasureSubmission_template.xlsx"), System.IO.FileMode.Open, System.IO.FileAccess.Read))
                    {
                        await fs.CopyToAsync(ms);

                        await fs.FlushAsync();
                    }

                    ms.Position = 0;

                    using (var document = DocumentFormat.OpenXml.Packaging.SpreadsheetDocument.Open(ms, true))
                    {
                        var helper = new Utils.MeasuresExcelReader(document);
                        helper.UpdateMetricInformation(metricID, metric.ResultsType);
                        helper.Document.Save();
                        document.Close();
                    }

                    ms.Position = 0;

                    var result = new FileStreamResult(ms, Microsoft.Net.Http.Headers.MediaTypeHeaderValue.Parse("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"))
                    {
                        FileDownloadName = CleanFilename("MeasureSubmission_" + metric.Title + ".xlsx")
                    };

                    return(result);
                }
            }

            return(BadRequest("Invalid document format, must be either 'json' or 'xlsx'."));
        }
        public async Task UploadJsonMeasure()
        {
            var app = new ApplicationFactory();

            using (var scope = app.CreateScope())
                using (var db = scope.ServiceProvider.GetRequiredService <Model.ModelDataContext>())
                {
                    //get the first count metric
                    var metric = db.Metrics.Include(m => m.ResultsType).Where(m => m.ResultsType.Value == "Count" && m.Statuses.OrderByDescending(s => s.CreateOn).First().MetricStatusID == Model.MetricStatus.PublishedID).FirstOrDefault();

                    if (metric == null)
                    {
                        Assert.Fail("There is no published metric to create measures for.");
                    }

                    var rnd = new Random();


                    var measureMeta = new Models.MeasureSubmissionViewModel {
                        MetricID            = metric.ID,
                        ResultsType         = metric.ResultsType.Value,
                        DataSource          = "Unit Test DataSource",
                        Organization        = "Unit Test Organization",
                        Network             = "Developerland",
                        RunDate             = DateTime.Now.Date,
                        DateRangeStart      = DateTime.Now.AddYears(Convert.ToInt32(-100 * rnd.NextDouble())).Date,
                        DateRangeEnd        = DateTime.Now.AddMonths(Convert.ToInt32(-12 * rnd.NextDouble())).Date,
                        SupportingResources = "https://github.com/some-organization/repositoryurl"
                    };

                    List <Models.MeasurementSubmissionViewModel> measurements = new List <Models.MeasurementSubmissionViewModel>();
                    int totalRows = Convert.ToInt32(20 * rnd.NextDouble()) + 1;
                    for (int i = 0; i < totalRows; i++)
                    {
                        measurements.Add(new Models.MeasurementSubmissionViewModel {
                            RawValue = i.ToString(), Definition = i.ToString(), Measure = Convert.ToSingle(100 * rnd.NextDouble())
                        });
                    }
                    float sum = measurements.Sum(m => m.Measure.Value);
                    foreach (var measure in measurements)
                    {
                        measure.Total = sum;
                    }

                    measureMeta.Measures = measurements;

                    using (var ms = new System.IO.MemoryStream())
                    {
                        using (var sw = new System.IO.StreamWriter(ms, Encoding.Default, 1024, true))
                            using (var jw = new Newtonsoft.Json.JsonTextWriter(sw))
                            {
                                var serializer = new Newtonsoft.Json.JsonSerializer();
                                serializer.DateFormatString = "yyyy'-'MM'-'dd";
                                serializer.Formatting       = Newtonsoft.Json.Formatting.None;

                                serializer.Serialize(jw, measureMeta);
                                await jw.FlushAsync();
                            }

                        ms.Seek(0, SeekOrigin.Begin);

                        using (var http = new System.Net.Http.HttpClient())
                        {
                            http.DefaultRequestHeaders.Accept.Add(System.Net.Http.Headers.MediaTypeWithQualityHeaderValue.Parse("application/json"));
                            http.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Basic", Convert.ToBase64String(Encoding.Default.GetBytes("dqm1:Password1!")));

                            try
                            {
                                var content = new System.Net.Http.StreamContent(ms);
                                content.Headers.Add("Content-Type", "application/json");

                                var result = await http.PostAsync("https://localhost:44317/api/measures/submit", content);

                                if (result.IsSuccessStatusCode)
                                {
                                    var responseContent = await result.Content.ReadAsStringAsync();
                                }
                                else
                                {
                                    string error = await result.Content.ReadAsStringAsync();

                                    Assert.Fail(error);
                                }
                            }
                            catch (System.Net.WebException webex)
                            {
                                using (var reader = new StreamReader(webex.Response.GetResponseStream()))
                                {
                                    Assert.Fail(await reader.ReadToEndAsync());
                                }
                            }
                        }
                    }
                }
        }