feat: initial commit
This commit is contained in:
@@ -0,0 +1,10 @@
|
||||
.dockerignore
|
||||
.gitignore
|
||||
**/Dockerfile
|
||||
**/.env
|
||||
**/.vs
|
||||
**/.vscode
|
||||
**/bin
|
||||
**/obj
|
||||
**/.toolstarget
|
||||
**/node_modules
|
||||
+273
@@ -0,0 +1,273 @@
|
||||
## Ignore Visual Studio temporary files, build results, and
|
||||
## files generated by popular Visual Studio add-ons.
|
||||
|
||||
###################
|
||||
# compiled source #
|
||||
###################
|
||||
*.com
|
||||
*.class
|
||||
*.dll
|
||||
*.exe
|
||||
*.pdb
|
||||
*.dll.config
|
||||
*.cache
|
||||
*.suo
|
||||
# Include dlls if they’re in the NuGet packages directory
|
||||
!/packages/*/lib/*.dll
|
||||
# Include dlls if they're in the CommonReferences directory
|
||||
!*CommonReferences/*.dll
|
||||
####################
|
||||
# VS Upgrade stuff #
|
||||
####################
|
||||
_UpgradeReport_Files/
|
||||
###############
|
||||
# Directories #
|
||||
###############
|
||||
bin/
|
||||
obj/
|
||||
TestResults/
|
||||
###################
|
||||
# Web publish log #
|
||||
###################
|
||||
*.Publish.xml
|
||||
#############
|
||||
# Resharper #
|
||||
#############
|
||||
/_ReSharper.*
|
||||
*.ReSharper.*
|
||||
############
|
||||
# Packages #
|
||||
############
|
||||
# it’s better to unpack these files and commit the raw source
|
||||
# git has its own built in compression methods
|
||||
*.7z
|
||||
*.dmg
|
||||
*.gz
|
||||
*.iso
|
||||
*.jar
|
||||
*.rar
|
||||
*.tar
|
||||
*.zip
|
||||
######################
|
||||
# Logs and databases #
|
||||
######################
|
||||
*.log
|
||||
*.sqlite
|
||||
# OS generated files #
|
||||
######################
|
||||
.DS_Store?
|
||||
ehthumbs.db
|
||||
Icon?
|
||||
Thumbs.db
|
||||
|
||||
|
||||
# User-specific files
|
||||
*.user
|
||||
*.userosscache
|
||||
*.sln.docstates
|
||||
|
||||
# User-specific files (MonoDevelop/Xamarin Studio)
|
||||
*.userprefs
|
||||
|
||||
# Build results
|
||||
[Dd]ebug/
|
||||
[Dd]ebugPublic/
|
||||
[Rr]elease/
|
||||
[Rr]eleases/
|
||||
x64/
|
||||
x86/
|
||||
build/
|
||||
bld/
|
||||
[Bb]in/
|
||||
[Oo]bj/
|
||||
|
||||
# Visual Studo 2015 cache/options directory
|
||||
.vs/
|
||||
|
||||
# MSTest test Results
|
||||
[Tt]est[Rr]esult*/
|
||||
[Bb]uild[Ll]og.*
|
||||
|
||||
# NUNIT
|
||||
*.VisualState.xml
|
||||
TestResult.xml
|
||||
|
||||
# Build Results of an ATL Project
|
||||
[Dd]ebugPS/
|
||||
[Rr]eleasePS/
|
||||
dlldata.c
|
||||
|
||||
# DNX
|
||||
project.lock.json
|
||||
artifacts/
|
||||
|
||||
*_i.c
|
||||
*_p.c
|
||||
*_i.h
|
||||
*.ilk
|
||||
*.meta
|
||||
*.obj
|
||||
*.pch
|
||||
*.pgc
|
||||
*.pgd
|
||||
*.rsp
|
||||
*.sbr
|
||||
*.tlb
|
||||
*.tli
|
||||
*.tlh
|
||||
*.tmp
|
||||
*.tmp_proj
|
||||
*.vspscc
|
||||
*.vssscc
|
||||
.builds
|
||||
*.pidb
|
||||
*.svclog
|
||||
*.scc
|
||||
|
||||
# Chutzpah Test files
|
||||
_Chutzpah*
|
||||
|
||||
# Visual C++ cache files
|
||||
ipch/
|
||||
*.aps
|
||||
*.ncb
|
||||
*.opensdf
|
||||
*.sdf
|
||||
*.cachefile
|
||||
|
||||
# Visual Studio profiler
|
||||
*.psess
|
||||
*.vsp
|
||||
*.vspx
|
||||
|
||||
# TFS 2012 Local Workspace
|
||||
$tf/
|
||||
|
||||
# Guidance Automation Toolkit
|
||||
*.gpState
|
||||
|
||||
# ReSharper is a .NET coding add-in
|
||||
_ReSharper*/
|
||||
*.[Rr]e[Ss]harper
|
||||
*.DotSettings.user
|
||||
|
||||
# JustCode is a .NET coding add-in
|
||||
.JustCode
|
||||
|
||||
# TeamCity is a build add-in
|
||||
_TeamCity*
|
||||
|
||||
# DotCover is a Code Coverage Tool
|
||||
*.dotCover
|
||||
|
||||
# NCrunch
|
||||
_NCrunch_*
|
||||
.*crunch*.local.xml
|
||||
|
||||
# MightyMoose
|
||||
*.mm.*
|
||||
AutoTest.Net/
|
||||
|
||||
# Web workbench (sass)
|
||||
.sass-cache/
|
||||
|
||||
# Installshield output folder
|
||||
[Ee]xpress/
|
||||
|
||||
# DocProject is a documentation generator add-in
|
||||
DocProject/buildhelp/
|
||||
DocProject/Help/*.HxT
|
||||
DocProject/Help/*.HxC
|
||||
DocProject/Help/*.hhc
|
||||
DocProject/Help/*.hhk
|
||||
DocProject/Help/*.hhp
|
||||
DocProject/Help/Html2
|
||||
DocProject/Help/html
|
||||
|
||||
# Click-Once directory
|
||||
publish/
|
||||
ClickOnce/
|
||||
|
||||
# Publish Web Output
|
||||
*.[Pp]ublish.xml
|
||||
*.azurePubxml
|
||||
# TODO: Comment the next line if you want to checkin your web deploy settings
|
||||
# but database connection strings (with potential passwords) will be unencrypted
|
||||
*.publishproj
|
||||
|
||||
# NuGet Packages
|
||||
*.nupkg
|
||||
# The packages folder can be ignored because of Package Restore
|
||||
**/packages/*
|
||||
# except build/, which is used as an MSBuild target.
|
||||
!**/packages/build/
|
||||
# Uncomment if necessary however generally it will be regenerated when needed
|
||||
#!**/packages/repositories.config
|
||||
|
||||
# Windows Azure Build Output
|
||||
csx/
|
||||
*.build.csdef
|
||||
|
||||
# Windows Store app package directory
|
||||
AppPackages/
|
||||
|
||||
# Visual Studio cache files
|
||||
# files ending in .cache can be ignored
|
||||
*.[Cc]ache
|
||||
# but keep track of directories ending in .cache
|
||||
!*.[Cc]ache/
|
||||
|
||||
# Others
|
||||
ClientBin/
|
||||
[Ss]tyle[Cc]op.*
|
||||
~$*
|
||||
*~
|
||||
*.dbmdl
|
||||
*.dbproj.schemaview
|
||||
*.pfx
|
||||
*.publishsettings
|
||||
node_modules/
|
||||
bower_components/
|
||||
orleans.codegen.cs
|
||||
|
||||
# RIA/Silverlight projects
|
||||
Generated_Code/
|
||||
|
||||
# Backup & report files from converting an old project file
|
||||
# to a newer Visual Studio version. Backup files are not needed,
|
||||
# because we have git ;-)
|
||||
_UpgradeReport_Files/
|
||||
Backup*/
|
||||
UpgradeLog*.XML
|
||||
UpgradeLog*.htm
|
||||
|
||||
# SQL Server files
|
||||
*.mdf
|
||||
*.ldf
|
||||
**/node_modules/*
|
||||
# Business Intelligence projects
|
||||
*.rdl.data
|
||||
*.bim.layout
|
||||
*.bim_*.settings
|
||||
|
||||
# Microsoft Fakes
|
||||
FakesAssemblies/
|
||||
|
||||
# Node.js Tools for Visual Studio
|
||||
.ntvs_analysis.dat
|
||||
|
||||
# Visual Studio 6 build log
|
||||
*.plg
|
||||
|
||||
# Visual Studio 6 workspace options file
|
||||
*.opt
|
||||
|
||||
# SonarQube files
|
||||
sonarqube/
|
||||
|
||||
.vs/
|
||||
*.orig
|
||||
buildlogs/
|
||||
|
||||
# Jetbrains Rider IDE
|
||||
.idea/
|
||||
+156
@@ -0,0 +1,156 @@
|
||||
ARG PROJECT=Strata.Stratasphere
|
||||
ARG VERSION=0.0.0
|
||||
ARG SONARURL=''
|
||||
ARG SONARLOGIN=''
|
||||
ARG SONARBRANCH=''
|
||||
ARG STRATASPHERE_TESTS_AWS_ACCESS_KEY_ID=''
|
||||
ARG STRATASPHERE_TESTS_AWS_SECRET_ACCESS_KEY=''
|
||||
|
||||
##############
|
||||
# Base image #
|
||||
##############
|
||||
FROM ecr.ops.stratanetwork.net/strata.microsoft.dotnet.aspnet:6.0 AS base
|
||||
|
||||
# Add TMZ files for CST
|
||||
RUN cp /usr/share/zoneinfo/America/Los_Angeles "/usr/share/zoneinfo/Pacific Standard Time"
|
||||
RUN cp /usr/share/zoneinfo/America/Chicago "/usr/share/zoneinfo/Central Standard Time"
|
||||
|
||||
RUN sed -i'.bak' 's/$/ contrib/' /etc/apt/sources.list
|
||||
|
||||
RUN apt-get update --allow-releaseinfo-change \
|
||||
&& apt-get install -y \
|
||||
libc6-dev \
|
||||
libgdiplus \
|
||||
libx11-dev \
|
||||
ttf-mscorefonts-installer \
|
||||
fontconfig \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
###############
|
||||
# Build image #
|
||||
###############
|
||||
FROM ecr.ops.stratanetwork.net/strata.microsoft.dotnet.sdk:6.0 as build
|
||||
ARG PROJECT
|
||||
ARG VERSION
|
||||
ARG SONARURL
|
||||
ARG SONARLOGIN
|
||||
ARG SONARBRANCH
|
||||
ARG STRATASPHERE_TESTS_AWS_ACCESS_KEY_ID
|
||||
ARG STRATASPHERE_TESTS_AWS_SECRET_ACCESS_KEY
|
||||
|
||||
ENV AWS_ACCESS_KEY_ID=${STRATASPHERE_TESTS_AWS_ACCESS_KEY_ID}
|
||||
ENV AWS_SECRET_ACCESS_KEY=${STRATASPHERE_TESTS_AWS_SECRET_ACCESS_KEY}
|
||||
ENV AWS_DEFAULT_REGION=us-east-1
|
||||
|
||||
COPY ["awsconfig", "/root/.aws/config"]
|
||||
|
||||
# Add TMZ files for CST
|
||||
RUN cp /usr/share/zoneinfo/America/Los_Angeles "/usr/share/zoneinfo/Pacific Standard Time"
|
||||
RUN cp /usr/share/zoneinfo/America/Chicago "/usr/share/zoneinfo/Central Standard Time"
|
||||
|
||||
RUN apt-get update --allow-releaseinfo-change \
|
||||
&& apt-get install -y \
|
||||
libc6-dev \
|
||||
libgdiplus \
|
||||
libx11-dev \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
WORKDIR /src
|
||||
|
||||
# Copy project files and restore
|
||||
COPY ["${PROJECT}.sln", "${PROJECT}.sln"]
|
||||
COPY src/**/*.csproj ./
|
||||
RUN for file in $(ls *.csproj); do mkdir -p src/${file%.*}/ && mv $file src/${file%.*}/; done
|
||||
COPY tests/**/*.csproj ./
|
||||
RUN for file in $(ls *.csproj); do mkdir -p tests/${file%.*}/ && mv $file tests/${file%.*}/; done
|
||||
|
||||
RUN dotnet restore "${PROJECT}.sln" \
|
||||
--source https://api.nuget.org/v3/index.json \
|
||||
--source https://proget.sdt.local/nuget/nuget/v3/index.json
|
||||
|
||||
# Copy files and build
|
||||
COPY . .
|
||||
|
||||
RUN if [ "${SONARLOGIN}" != "" ] ; then dotnet sonarscanner begin \
|
||||
/k:"${PROJECT}" \
|
||||
/d:sonar.scm.provider=git \
|
||||
/d:sonar.host.url="${SONARURL}" \
|
||||
${SONARBRANCH} \
|
||||
/d:sonar.login="${SONARLOGIN}" \
|
||||
/d:sonar.cs.opencover.reportsPaths="/src/cover.xml" \
|
||||
/d:sonar.dependencyCheck.jsonReportPath=/src/buildlogs/dependency-check-report.json \
|
||||
/d:sonar.dependencyCheck.htmlReportPath=/src/buildlogs/dependency-check-report.html \
|
||||
/v:sonar.projectVersion="${VERSION}"; fi
|
||||
|
||||
RUN dotnet build "${PROJECT}.sln" \
|
||||
--configuration Release \
|
||||
--no-restore
|
||||
|
||||
# Run tests
|
||||
RUN dotnet test "tests/${PROJECT}.Api.APITests/${PROJECT}.Api.APITests.csproj" \
|
||||
--configuration Release \
|
||||
--no-restore \
|
||||
--no-build \
|
||||
--verbosity=normal \
|
||||
--logger "trx;LogFileName=/test-results/api-api-tests.trx" \
|
||||
-p:CollectCoverage=true \
|
||||
-p:CoverletOutputFormat="json" \
|
||||
-p:CoverletOutput=/test-results/cover.json \
|
||||
|| true
|
||||
|
||||
RUN dotnet test "tests/${PROJECT}.Api.UnitTests/${PROJECT}.Api.UnitTests.csproj" \
|
||||
--configuration Release \
|
||||
--no-restore \
|
||||
--no-build \
|
||||
--verbosity=normal \
|
||||
--logger "trx;LogFileName=/test-results/api-unit-tests.trx" \
|
||||
-p:CollectCoverage=true \
|
||||
-p:CoverletOutputFormat="json" \
|
||||
-p:CoverletOutput=/test-results/cover-apiUnit.json \
|
||||
-p:MergeWith=/test-results/cover.json \
|
||||
|| true
|
||||
|
||||
RUN dotnet test "tests/${PROJECT}.Biz.UnitTests/${PROJECT}.Biz.UnitTests.csproj" \
|
||||
--configuration Release \
|
||||
--no-restore \
|
||||
--no-build \
|
||||
--verbosity=normal \
|
||||
--logger "trx;LogFileName=/test-results/unit-tests.trx" \
|
||||
-p:CollectCoverage=true \
|
||||
-p:CoverletOutputFormat="opencover" \
|
||||
-p:CoverletOutput=/test-results/cover.xml \
|
||||
-p:MergeWith=/test-results/cover-apiUnit.json \
|
||||
|| true
|
||||
|
||||
# Publish project
|
||||
RUN dotnet publish "src/${PROJECT}.Api/${PROJECT}.Api.csproj" \
|
||||
--configuration Release \
|
||||
--no-restore \
|
||||
--no-build \
|
||||
--output /app
|
||||
|
||||
RUN if [ "${SONARLOGIN}" != "" ] ; then \
|
||||
(/dc/dependency-check/bin/dependency-check.sh -f JSON -f HTML -s . -o ./buildlogs \
|
||||
--suppression ./sonarsuppressions.xml \
|
||||
--noupdate --nodeAuditSkipDevDependencies --disableNodeJS \
|
||||
--dbDriverName "com.microsoft.sqlserver.jdbc.SQLServerDriver" \
|
||||
--connectionString "jdbc:sqlserver://ddensqldevops01.sdt.local;Database=DependencyCheck;encrypt=true;trustServerCertificate=true;" \
|
||||
--dbUser "dcuser" --dbPassword "${SONARLOGIN}" || true) && \
|
||||
dotnet sonarscanner end /d:sonar.login="${SONARLOGIN}"; \
|
||||
fi
|
||||
|
||||
###############
|
||||
# Final image #
|
||||
###############
|
||||
FROM base AS final
|
||||
ARG PROJECT
|
||||
WORKDIR /app
|
||||
ARG PROJECT
|
||||
ENV PROJECTDLL=${PROJECT}.Api.dll
|
||||
ENV DOTNET_ENVIRONMENT=Development
|
||||
ENV ASPNETCORE_ENVIRONMENT=Development
|
||||
|
||||
COPY --from=build /app /app
|
||||
COPY --from=build /test-results /test-results
|
||||
|
||||
ENTRYPOINT dotnet ${PROJECTDLL}
|
||||
@@ -0,0 +1,72 @@
|
||||
ARG PROJECT=Strata.Stratasphere
|
||||
ARG VERSION=0.0.0
|
||||
|
||||
|
||||
##############
|
||||
# Base image #
|
||||
##############
|
||||
FROM ecr.ops.stratanetwork.net/strata.microsoft.dotnet.aspnet:6.0 AS base
|
||||
# Add TMZ files for CST
|
||||
RUN cp /usr/share/zoneinfo/America/Chicago "/usr/share/zoneinfo/Central Standard Time"
|
||||
|
||||
RUN sed -i'.bak' 's/$/ contrib/' /etc/apt/sources.list
|
||||
|
||||
RUN apt-get update --allow-releaseinfo-change \
|
||||
&& apt-get install -y \
|
||||
libc6-dev \
|
||||
libgdiplus \
|
||||
libx11-dev \
|
||||
ttf-mscorefonts-installer \
|
||||
fontconfig \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
###############
|
||||
# Build image #
|
||||
###############
|
||||
FROM ecr.ops.stratanetwork.net/strata.microsoft.dotnet.sdk:6.0 as build
|
||||
ARG PROJECT
|
||||
ARG VERSION
|
||||
|
||||
# Add TMZ files for CST
|
||||
RUN cp /usr/share/zoneinfo/America/Chicago "/usr/share/zoneinfo/Central Standard Time"
|
||||
|
||||
WORKDIR /src
|
||||
|
||||
# Copy project files and restore
|
||||
COPY ["${PROJECT}.sln", "${PROJECT}.sln"]
|
||||
COPY src/**/*.csproj ./
|
||||
RUN for file in $(ls *.csproj); do mkdir -p src/${file%.*}/ && mv $file src/${file%.*}/; done
|
||||
COPY tests/**/*.csproj ./
|
||||
RUN for file in $(ls *.csproj); do mkdir -p tests/${file%.*}/ && mv $file tests/${file%.*}/; done
|
||||
|
||||
RUN dotnet restore "${PROJECT}.sln" \
|
||||
--source https://api.nuget.org/v3/index.json \
|
||||
--source https://proget.sdt.local/nuget/nuget/v3/index.json
|
||||
|
||||
# Copy files and build
|
||||
COPY . .
|
||||
|
||||
RUN dotnet build "${PROJECT}.sln" \
|
||||
--configuration Release \
|
||||
--no-restore
|
||||
|
||||
# Publish project
|
||||
RUN dotnet publish "src/${PROJECT}.Dashboard/${PROJECT}.Dashboard.csproj" \
|
||||
--configuration Release \
|
||||
--no-restore \
|
||||
--no-build \
|
||||
--output /app
|
||||
|
||||
###############
|
||||
# Final image #
|
||||
###############
|
||||
FROM base AS final
|
||||
ARG PROJECT
|
||||
WORKDIR /app
|
||||
ARG PROJECT
|
||||
ENV PROJECTDLL=${PROJECT}.Dashboard.dll
|
||||
ENV DOTNET_ENVIRONMENT=Development
|
||||
ENV ASPNETCORE_ENVIRONMENT=Development
|
||||
|
||||
COPY --from=build /app /app
|
||||
ENTRYPOINT dotnet ${PROJECTDLL}
|
||||
@@ -0,0 +1,72 @@
|
||||
ARG PROJECT=Strata.Stratasphere
|
||||
ARG VERSION=0.0.0
|
||||
|
||||
|
||||
##############
|
||||
# Base image #
|
||||
##############
|
||||
FROM ecr.ops.stratanetwork.net/strata.microsoft.dotnet.aspnet:6.0 AS base
|
||||
# Add TMZ files for CST
|
||||
RUN cp /usr/share/zoneinfo/America/Chicago "/usr/share/zoneinfo/Central Standard Time"
|
||||
|
||||
RUN sed -i'.bak' 's/$/ contrib/' /etc/apt/sources.list
|
||||
|
||||
RUN apt-get update --allow-releaseinfo-change \
|
||||
&& apt-get install -y \
|
||||
libc6-dev \
|
||||
libgdiplus \
|
||||
libx11-dev \
|
||||
ttf-mscorefonts-installer \
|
||||
fontconfig \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
###############
|
||||
# Build image #
|
||||
###############
|
||||
FROM ecr.ops.stratanetwork.net/strata.microsoft.dotnet.sdk:6.0 as build
|
||||
ARG PROJECT
|
||||
ARG VERSION
|
||||
|
||||
# Add TMZ files for CST
|
||||
RUN cp /usr/share/zoneinfo/America/Chicago "/usr/share/zoneinfo/Central Standard Time"
|
||||
|
||||
WORKDIR /src
|
||||
|
||||
# Copy project files and restore
|
||||
COPY ["${PROJECT}.sln", "${PROJECT}.sln"]
|
||||
COPY src/**/*.csproj ./
|
||||
RUN for file in $(ls *.csproj); do mkdir -p src/${file%.*}/ && mv $file src/${file%.*}/; done
|
||||
COPY tests/**/*.csproj ./
|
||||
RUN for file in $(ls *.csproj); do mkdir -p tests/${file%.*}/ && mv $file tests/${file%.*}/; done
|
||||
|
||||
RUN dotnet restore "${PROJECT}.sln" \
|
||||
--source https://api.nuget.org/v3/index.json \
|
||||
--source https://proget.sdt.local/nuget/nuget/v3/index.json
|
||||
|
||||
# Copy files and build
|
||||
COPY . .
|
||||
|
||||
RUN dotnet build "${PROJECT}.sln" \
|
||||
--configuration Release \
|
||||
--no-restore
|
||||
|
||||
# Publish project
|
||||
RUN dotnet publish "src/${PROJECT}.Service/${PROJECT}.Service.csproj" \
|
||||
--configuration Release \
|
||||
--no-restore \
|
||||
--no-build \
|
||||
--output /app
|
||||
|
||||
###############
|
||||
# Final image #
|
||||
###############
|
||||
FROM base AS final
|
||||
ARG PROJECT
|
||||
WORKDIR /app
|
||||
ARG PROJECT
|
||||
ENV PROJECTDLL=${PROJECT}.Service.dll
|
||||
ENV DOTNET_ENVIRONMENT=Development
|
||||
ENV ASPNETCORE_ENVIRONMENT=Development
|
||||
|
||||
COPY --from=build /app /app
|
||||
ENTRYPOINT dotnet ${PROJECTDLL}
|
||||
@@ -0,0 +1,28 @@
|
||||
FROM node:18.17.0 as build
|
||||
|
||||
# ENV CI=true
|
||||
|
||||
# Set working directory
|
||||
WORKDIR /app
|
||||
|
||||
# Install dependencies
|
||||
RUN npm config set @strata:registry http://proget.sdt.local/npm/npm
|
||||
RUN npm config set strict-ssl false
|
||||
COPY src/Strata.Stratasphere.Web/template/package*.json ./
|
||||
RUN npm cache verify
|
||||
RUN npm install --legacy-peer-deps
|
||||
RUN npm ci --legacy-peer-deps
|
||||
|
||||
RUN npx browserslist@latest --update-db
|
||||
|
||||
# Copy in rest of app and build
|
||||
COPY src/Strata.Stratasphere.Web/template/ .
|
||||
RUN npm run build
|
||||
|
||||
# Run tests
|
||||
#RUN npm run test
|
||||
|
||||
# Build release container
|
||||
FROM nginx:alpine
|
||||
COPY --from=build /app/build /usr/share/nginx/html
|
||||
COPY src/Strata.Stratasphere.Web/nginx.conf /etc/nginx/conf.d/default.conf
|
||||
@@ -1 +1,47 @@
|
||||
# strataspheredatamanagement
|
||||
# Strataspheredatamanagement
|
||||
|
||||
## First Time Setup Notes
|
||||
|
||||
For first time setting up AWS authentication you'll need to follow the steps here https://confluence.sdt.local/display/SWPRJ/IAM+Application+Role+Setup+for+AWS+applications#IAMApplicationRoleSetupforAWSapplications-AWSCredentialsSetup
|
||||
You will need the contents below in your AWS config file located here: %UserProfile%/.aws/config
|
||||
```
|
||||
[profile stratasphere-datawrangling]
|
||||
source_profile = 809820578507_SDT-Dev-Developers
|
||||
role_arn = arn:aws:iam::809820578507:role/SDT-data-wrangler-Service-Role
|
||||
region=us-east-1
|
||||
```
|
||||
|
||||
### SonarQube Metrics
|
||||
|
||||
[SonarQube](https://sonarqube.ops.stratanetwork.net/dashboard?id=Strata.StratasphereDataManagement)
|
||||
|
||||
### Build Status
|
||||
[](https://github.com/stratadecision/strataspheredatamanagement/actions/workflows/build.yaml)
|
||||
|
||||
|
||||
## Branching and Versioning
|
||||
|
||||
| branch | version format | example |
|
||||
| ---------- | --------------------- | --------------- |
|
||||
| master | #.#.# | 1.2.3 |
|
||||
| feature/\* | #.#+1.0-featureName.# | 1.3.0-newfeat.1 |
|
||||
| fix/\* | #.#.#+1-fixName.# | 1.2.4-bug.1 |
|
||||
|
||||
See our [confluence page](https://confluence.sdt.local/display/DOP/Branching+and+Versioning) for more information
|
||||
|
||||
## Usage
|
||||
|
||||
### Build and Run
|
||||
|
||||
```
|
||||
docker-compose up --build
|
||||
```
|
||||
API - https://localhost:8443
|
||||
Web - http://localhost:3000
|
||||
|
||||
### Extracting nuget package
|
||||
```
|
||||
docker create --name throwaway stratatemplate_template-api
|
||||
docker cp throwaway:/pack .
|
||||
docker rm throwaway
|
||||
```
|
||||
|
||||
@@ -0,0 +1,48 @@
|
||||
|
||||
--Sandbox Database
|
||||
|
||||
USE ROLE DATAADMIN;
|
||||
CREATE DATABASE IF NOT EXISTS DATALAKE_SANDBOX COMMENT = 'Sandbox environment for datalake';
|
||||
GRANT USAGE ON DATABASE DATALAKE_SANDBOX TO ROLE DATAANALYST;
|
||||
GRANT CREATE SCHEMA ON DATABASE DATALAKE_SANDBOX TO ROLE DATAANALYST;
|
||||
|
||||
USE ROLE DATAADMIN;
|
||||
USE DATABASE DATALAKE_SANDBOX;
|
||||
CREATE SCHEMA IF NOT EXISTS DATA WITH MANAGED ACCESS;
|
||||
ALTER SCHEMA IF EXISTS DATA ENABLE MANAGED ACCESS;
|
||||
GRANT USAGE ON SCHEMA DATA TO ROLE DATAANALYST;
|
||||
GRANT SELECT ON ALL TABLES IN SCHEMA DATA TO ROLE DATAANALYST;
|
||||
GRANT SELECT ON FUTURE TABLES IN SCHEMA DATA TO ROLE DATAANALYST;
|
||||
|
||||
|
||||
--Staging Database
|
||||
|
||||
USE ROLE DATAADMIN;
|
||||
CREATE DATABASE IF NOT EXISTS DATALAKE_STAGING COMMENT = 'Staging environment for datalake';
|
||||
GRANT USAGE ON DATABASE DATALAKE_STAGING TO ROLE DATAANALYST;
|
||||
GRANT CREATE SCHEMA ON DATABASE DATALAKE_STAGING TO ROLE DATAANALYST;
|
||||
|
||||
USE ROLE DATAADMIN;
|
||||
USE DATABASE DATALAKE_STAGING;
|
||||
CREATE SCHEMA IF NOT EXISTS DATA WITH MANAGED ACCESS;
|
||||
ALTER SCHEMA IF EXISTS DATA ENABLE MANAGED ACCESS;
|
||||
GRANT USAGE ON SCHEMA DATA TO ROLE DATAANALYST;
|
||||
GRANT SELECT ON ALL TABLES IN SCHEMA DATA TO ROLE DATAANALYST;
|
||||
GRANT SELECT ON FUTURE TABLES IN SCHEMA DATA TO ROLE DATAANALYST;
|
||||
|
||||
|
||||
--Production Database
|
||||
|
||||
USE ROLE DATAADMIN;
|
||||
CREATE DATABASE IF NOT EXISTS DATALAKE_PROD COMMENT = 'Production environment for datalake';
|
||||
GRANT USAGE ON DATABASE DATALAKE_PROD TO ROLE DATAANALYST;
|
||||
GRANT CREATE SCHEMA ON DATABASE DATALAKE_PROD TO ROLE DATAANALYST;
|
||||
|
||||
USE ROLE DATAADMIN;
|
||||
USE DATABASE DATALAKE_PROD;
|
||||
CREATE SCHEMA IF NOT EXISTS DATA WITH MANAGED ACCESS;
|
||||
ALTER SCHEMA IF EXISTS DATA ENABLE MANAGED ACCESS;
|
||||
GRANT USAGE ON SCHEMA DATA TO ROLE DATAANALYST;
|
||||
GRANT SELECT ON ALL TABLES IN SCHEMA DATA TO ROLE DATAANALYST;
|
||||
GRANT SELECT ON FUTURE TABLES IN SCHEMA DATA TO ROLE DATAANALYST;
|
||||
|
||||
@@ -0,0 +1,60 @@
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio Version 17
|
||||
VisualStudioVersion = 17.3.32922.545
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Strata.Stratasphere.Biz", "src\Strata.Stratasphere.Biz\Strata.Stratasphere.Biz.csproj", "{55550602-86C4-44DF-B2B0-1FCE65B3A8AF}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Strata.Stratasphere.Service", "src\Strata.Stratasphere.Service\Strata.Stratasphere.Service.csproj", "{C5F500D7-F5F9-4AE8-9EA6-5589E790AC9A}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Strata.Stratasphere.Dashboard", "src\Strata.Stratasphere.Dashboard\Strata.Stratasphere.Dashboard.csproj", "{503D5A6B-4B38-42DE-9066-57605B8BFBB5}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Strata.Stratasphere.Api", "src\Strata.Stratasphere.Api\Strata.Stratasphere.Api.csproj", "{95A28653-54C1-4C70-930E-652B126AEB9C}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Strata.Stratasphere.Biz.UnitTests", "tests\Strata.Stratasphere.Biz.UnitTests\Strata.Stratasphere.Biz.UnitTests.csproj", "{4A2BD57E-BAA9-4280-B189-2ED7D5CB2F28}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Strata.Stratasphere.Web", "src\Strata.Stratasphere.Web\Strata.Stratasphere.Web.csproj", "{2C4F6E6A-C220-49E7-99FD-B84B6AF5CBFF}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Strata.Stratasphere.Biz.IntegrationTests", "tests\Strata.Stratasphere.Biz.IntegrationTests\Strata.Stratasphere.Biz.IntegrationTests.csproj", "{550F3422-3FC7-45EF-A0B2-E3FCB84CAF35}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
Release|Any CPU = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{55550602-86C4-44DF-B2B0-1FCE65B3A8AF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{55550602-86C4-44DF-B2B0-1FCE65B3A8AF}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{55550602-86C4-44DF-B2B0-1FCE65B3A8AF}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{55550602-86C4-44DF-B2B0-1FCE65B3A8AF}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{C5F500D7-F5F9-4AE8-9EA6-5589E790AC9A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{C5F500D7-F5F9-4AE8-9EA6-5589E790AC9A}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{C5F500D7-F5F9-4AE8-9EA6-5589E790AC9A}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{C5F500D7-F5F9-4AE8-9EA6-5589E790AC9A}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{503D5A6B-4B38-42DE-9066-57605B8BFBB5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{503D5A6B-4B38-42DE-9066-57605B8BFBB5}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{503D5A6B-4B38-42DE-9066-57605B8BFBB5}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{503D5A6B-4B38-42DE-9066-57605B8BFBB5}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{95A28653-54C1-4C70-930E-652B126AEB9C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{95A28653-54C1-4C70-930E-652B126AEB9C}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{95A28653-54C1-4C70-930E-652B126AEB9C}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{95A28653-54C1-4C70-930E-652B126AEB9C}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{4A2BD57E-BAA9-4280-B189-2ED7D5CB2F28}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{4A2BD57E-BAA9-4280-B189-2ED7D5CB2F28}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{4A2BD57E-BAA9-4280-B189-2ED7D5CB2F28}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{4A2BD57E-BAA9-4280-B189-2ED7D5CB2F28}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{2C4F6E6A-C220-49E7-99FD-B84B6AF5CBFF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{2C4F6E6A-C220-49E7-99FD-B84B6AF5CBFF}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{2C4F6E6A-C220-49E7-99FD-B84B6AF5CBFF}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{2C4F6E6A-C220-49E7-99FD-B84B6AF5CBFF}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{550F3422-3FC7-45EF-A0B2-E3FCB84CAF35}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{550F3422-3FC7-45EF-A0B2-E3FCB84CAF35}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{550F3422-3FC7-45EF-A0B2-E3FCB84CAF35}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{550F3422-3FC7-45EF-A0B2-E3FCB84CAF35}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
SolutionGuid = {BE72BC18-62A4-42A7-9B88-08A667B35A19}
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
@@ -0,0 +1,3 @@
|
||||
<wpf:ResourceDictionary xml:space="preserve" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:ss="urn:shemas-jetbrains-com:settings-storage-xaml" xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
|
||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=Dtos/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=Stratasphere/@EntryIndexedValue">True</s:Boolean></wpf:ResourceDictionary>
|
||||
@@ -0,0 +1,4 @@
|
||||
[profile default]
|
||||
credential_source = Environment
|
||||
role_arn = arn:aws:iam::809820578507:role/SDT-data-wrangler-Service-Role
|
||||
region = us-east-1
|
||||
@@ -0,0 +1,16 @@
|
||||
version: "3"
|
||||
|
||||
services:
|
||||
template-web:
|
||||
build:
|
||||
context: .
|
||||
dockerfile: Web/Dockerfile
|
||||
ports:
|
||||
- "3000:80"
|
||||
template-api:
|
||||
build:
|
||||
context: .
|
||||
dockerfile: Api/Dockerfile
|
||||
ports:
|
||||
- "8080:80"
|
||||
- "8443:443"
|
||||
@@ -0,0 +1,151 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<suppressions xmlns="https://jeremylong.github.io/DependencyCheck/dependency-suppression.1.3.xsd">
|
||||
<suppress>
|
||||
<notes><![CDATA[
|
||||
file name: TeamCity.ServiceMessages.dll
|
||||
]]></notes>
|
||||
<packageUrl regex="true">^pkg:generic/TeamCity\.ServiceMessages@.*$</packageUrl>
|
||||
<cpe>cpe:/a:jetbrains:teamcity</cpe>
|
||||
<cve>CVE-2014-10002</cve>
|
||||
</suppress>
|
||||
<suppress>
|
||||
<notes><![CDATA[
|
||||
file name: Microsoft.AspNetCore.Authentication.JwtBearer.dll
|
||||
]]></notes>
|
||||
<packageUrl regex="true">^pkg:generic/Microsoft\.AspNetCore\.Authentication\.JwtBearer@.*$</packageUrl>
|
||||
<cve>CVE-2020-1108</cve>
|
||||
</suppress>
|
||||
<suppress>
|
||||
<notes><![CDATA[
|
||||
file name: Microsoft.VisualStudio.CodeCoverage.Shim.dll
|
||||
]]></notes>
|
||||
<packageUrl regex="true">^pkg:generic/Microsoft\.VisualStudio\.CodeCoverage\.Shim@.*$</packageUrl>
|
||||
<cve>CVE-2020-1171</cve>
|
||||
</suppress>
|
||||
<suppress>
|
||||
<notes><![CDATA[
|
||||
file name: Microsoft.VisualStudio.CodeCoverage.Shim.dll
|
||||
]]></notes>
|
||||
<packageUrl regex="true">^pkg:generic/Microsoft\.VisualStudio\.CodeCoverage\.Shim@.*$</packageUrl>
|
||||
<cve>CVE-2020-1192</cve>
|
||||
</suppress>
|
||||
<suppress>
|
||||
<notes><![CDATA[
|
||||
file name: SonarScanner.MSBuild.Tasks.dll
|
||||
]]></notes>
|
||||
<packageUrl regex="true">^pkg:generic/SonarScanner\.MSBuild\.Tasks@.*$</packageUrl>
|
||||
<cve>CVE-2020-22475</cve>
|
||||
</suppress>
|
||||
<suppress>
|
||||
<notes><![CDATA[
|
||||
file name: browserslist:4.14.2
|
||||
]]></notes>
|
||||
<packageUrl regex="true">^pkg:npm/browserslist@.*$</packageUrl>
|
||||
<vulnerabilityName>1747</vulnerabilityName>
|
||||
</suppress>
|
||||
<suppress>
|
||||
<notes><![CDATA[
|
||||
file name: css-what:3.4.2
|
||||
]]></notes>
|
||||
<packageUrl regex="true">^pkg:npm/css\-what@.*$</packageUrl>
|
||||
<vulnerabilityName>1754</vulnerabilityName>
|
||||
</suppress>
|
||||
<suppress>
|
||||
<notes><![CDATA[
|
||||
file name: dns-packet:1.3.1
|
||||
]]></notes>
|
||||
<packageUrl regex="true">^pkg:npm/dns\-packet@.*$</packageUrl>
|
||||
<vulnerabilityName>1745</vulnerabilityName>
|
||||
</suppress>
|
||||
<suppress>
|
||||
<notes><![CDATA[
|
||||
file name: normalize-url:3.3.0
|
||||
]]></notes>
|
||||
<packageUrl regex="true">^pkg:npm/normalize\-url@.*$</packageUrl>
|
||||
<vulnerabilityName>1755</vulnerabilityName>
|
||||
</suppress>
|
||||
<suppress>
|
||||
<notes><![CDATA[
|
||||
file name: trim-newlines:1.0.0
|
||||
]]></notes>
|
||||
<packageUrl regex="true">^pkg:npm/trim\-newlines@.*$</packageUrl>
|
||||
<vulnerabilityName>1753</vulnerabilityName>
|
||||
</suppress>
|
||||
<suppress>
|
||||
<notes><![CDATA[
|
||||
file name: TeamCity.ServiceMessages.dll
|
||||
]]></notes>
|
||||
<packageUrl regex="true">^pkg:generic/TeamCity\.ServiceMessages@.*$</packageUrl>
|
||||
<cve>CVE-2014-10036</cve>
|
||||
</suppress>
|
||||
<suppress>
|
||||
<notes><![CDATA[
|
||||
file name: TeamCity.ServiceMessages.dll
|
||||
]]></notes>
|
||||
<packageUrl regex="true">^pkg:generic/TeamCity\.ServiceMessages@.*$</packageUrl>
|
||||
<cve>CVE-2019-12156</cve>
|
||||
</suppress>
|
||||
<suppress>
|
||||
<notes><![CDATA[
|
||||
file name: TeamCity.ServiceMessages.dll
|
||||
]]></notes>
|
||||
<packageUrl regex="true">^pkg:generic/TeamCity\.ServiceMessages@.*$</packageUrl>
|
||||
<cve>CVE-2019-12157</cve>
|
||||
</suppress>
|
||||
<suppress>
|
||||
<notes><![CDATA[
|
||||
file name: TeamCity.ServiceMessages.dll
|
||||
]]></notes>
|
||||
<packageUrl regex="true">^pkg:generic/TeamCity\.ServiceMessages@.*$</packageUrl>
|
||||
<cve>CVE-2019-12841</cve>
|
||||
</suppress>
|
||||
<suppress>
|
||||
<notes><![CDATA[
|
||||
file name: TeamCity.ServiceMessages.dll
|
||||
]]></notes>
|
||||
<packageUrl regex="true">^pkg:generic/TeamCity\.ServiceMessages@.*$</packageUrl>
|
||||
<cve>CVE-2019-12842</cve>
|
||||
</suppress>
|
||||
<suppress>
|
||||
<notes><![CDATA[
|
||||
file name: TeamCity.ServiceMessages.dll
|
||||
]]></notes>
|
||||
<packageUrl regex="true">^pkg:generic/TeamCity\.ServiceMessages@.*$</packageUrl>
|
||||
<cve>CVE-2019-12843</cve>
|
||||
</suppress>
|
||||
<suppress>
|
||||
<notes><![CDATA[
|
||||
file name: TeamCity.ServiceMessages.dll
|
||||
]]></notes>
|
||||
<packageUrl regex="true">^pkg:generic/TeamCity\.ServiceMessages@.*$</packageUrl>
|
||||
<cve>CVE-2019-12844</cve>
|
||||
</suppress>
|
||||
<suppress>
|
||||
<notes><![CDATA[
|
||||
file name: TeamCity.ServiceMessages.dll
|
||||
]]></notes>
|
||||
<packageUrl regex="true">^pkg:generic/TeamCity\.ServiceMessages@.*$</packageUrl>
|
||||
<cve>CVE-2019-12845</cve>
|
||||
</suppress>
|
||||
<suppress>
|
||||
<notes><![CDATA[
|
||||
file name: TeamCity.VSTest.TestLogger.dll
|
||||
]]></notes>
|
||||
<packageUrl regex="true">^pkg:generic/TeamCity\.VSTest\.TestLogger@.*$</packageUrl>
|
||||
<cpe>cpe:/a:jetbrains:teamcity</cpe>
|
||||
</suppress>
|
||||
<suppress>
|
||||
<notes><![CDATA[
|
||||
file name: TeamCity.VSTest.TestAdapter.dll
|
||||
]]></notes>
|
||||
<packageUrl regex="true">^pkg:generic/TeamCity\.VSTest\.TestAdapter@.*$</packageUrl>
|
||||
<cpe>cpe:/a:jetbrains:teamcity</cpe>
|
||||
</suppress>
|
||||
<suppress>
|
||||
<notes><![CDATA[
|
||||
file name: dependency-check-core-5.3.2.jar: jquery-3.4.1.min.js
|
||||
]]></notes>
|
||||
<packageUrl regex="true">^pkg:javascript/jquery@.*$</packageUrl>
|
||||
<vulnerabilityName>Regex in its jQuery.htmlPrefilter sometimes may introduce XSS</vulnerabilityName>
|
||||
</suppress>
|
||||
</suppressions>
|
||||
@@ -0,0 +1,37 @@
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Strata.Stratasphere.Biz.Mappings.Accounts;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Strata.Stratasphere.Api.Controllers
|
||||
{
|
||||
[ApiController]
|
||||
[ApiVersion("1.0")]
|
||||
[Route("api/v{api-version:apiVersion}/[controller]")]
|
||||
public class AccountMappingController : ControllerBase
|
||||
{
|
||||
private readonly IAccountMappingService _accountMappingService;
|
||||
|
||||
public AccountMappingController(IAccountMappingService accountMappingService)
|
||||
{
|
||||
_accountMappingService = accountMappingService;
|
||||
}
|
||||
|
||||
[HttpPost("[action]")]
|
||||
[ProducesResponseType(StatusCodes.Status202Accepted)]
|
||||
public async Task<IActionResult> SetIsSPHCostModel(AccountMappingInfo mappingInfo, CancellationToken cancellationToken)
|
||||
{
|
||||
var userName = User?.Identity?.Name;
|
||||
await _accountMappingService.SetIsSPHCostModel(userName, mappingInfo.StrataId, mappingInfo.AccountCode, mappingInfo.IsSPHCostModel, cancellationToken);
|
||||
return new AcceptedResult();
|
||||
}
|
||||
}
|
||||
|
||||
public class AccountMappingInfo
|
||||
{
|
||||
public int StrataId { get; set; }
|
||||
public string AccountCode { get; set; }
|
||||
public bool IsSPHCostModel { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Strata.SqlTools.EntityFramework.Pagination;
|
||||
using Strata.Stratasphere.Biz.Mappings.Accounts;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Strata.Stratasphere.Api.Controllers
|
||||
{
|
||||
[ApiController]
|
||||
[ApiVersion("1.0")]
|
||||
[Route("api/v{api-version:apiVersion}/[controller]")]
|
||||
public class AccountMappingDetailsController : ControllerBase
|
||||
{
|
||||
private readonly IAccountMappingDetailService _accountMappingDetailService;
|
||||
|
||||
public AccountMappingDetailsController(IAccountMappingDetailService accountMappingDetailService)
|
||||
{
|
||||
_accountMappingDetailService = accountMappingDetailService;
|
||||
}
|
||||
|
||||
[HttpPost()]
|
||||
public async Task<PagedData<AccountMappingDetail>> GetAll(AccountMappingDetailLoadOptions loadOptions, CancellationToken cancellationToken)
|
||||
{
|
||||
return
|
||||
await _accountMappingDetailService.GetAccountMappingDetailsAsync(loadOptions.PagingOptions, loadOptions.FilterOptions, cancellationToken);
|
||||
}
|
||||
|
||||
[HttpPost("[action]")]
|
||||
[ProducesResponseType(StatusCodes.Status202Accepted)]
|
||||
public async Task<IActionResult> Export(AccountMappingDetailExportOptions exportOptions, CancellationToken cancellationToken)
|
||||
{
|
||||
await _accountMappingDetailService.ExportAsync(exportOptions.ExportAll, exportOptions.FilterOptions, User?.Identity?.Name ?? "", cancellationToken);
|
||||
return new AcceptedResult();
|
||||
}
|
||||
|
||||
[HttpPost("[action]")]
|
||||
public async Task<bool> Import(IFormFile file, CancellationToken cancellationToken)
|
||||
{
|
||||
return await _accountMappingDetailService.ImportAsync(file, User?.Identity?.Name ?? "", cancellationToken);
|
||||
}
|
||||
|
||||
[HttpGet("[action]")]
|
||||
public async Task<IEnumerable<string>> GetExports(CancellationToken cancellationToken)
|
||||
{
|
||||
return await _accountMappingDetailService.GetExports(User?.Identity?.Name ?? "", cancellationToken);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public class AccountMappingDetailLoadOptions
|
||||
{
|
||||
public PagingOptions PagingOptions { get; set; }
|
||||
public AccountMappingFilters FilterOptions { get; set; }
|
||||
}
|
||||
|
||||
public class AccountMappingDetailExportOptions
|
||||
{
|
||||
public bool ExportAll { get; set; }
|
||||
public AccountMappingFilters FilterOptions { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Strata.SqlTools.EntityFramework.Pagination;
|
||||
using Strata.Stratasphere.Biz.Mappings.AdmitType;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
using System.Threading;
|
||||
|
||||
namespace Strata.Stratasphere.Api.Controllers
|
||||
{
|
||||
[ApiController]
|
||||
[ApiVersion("1.0")]
|
||||
[Route("api/v{api-version:apiVersion}/[controller]")]
|
||||
public class AdmitTypeMappingDetailsController : ControllerBase
|
||||
{
|
||||
private readonly IAdmitTypeMappingDetailService _admitTypeMappingDetailService;
|
||||
|
||||
public AdmitTypeMappingDetailsController(IAdmitTypeMappingDetailService admitTypeMappingDetailService)
|
||||
{
|
||||
_admitTypeMappingDetailService = admitTypeMappingDetailService;
|
||||
}
|
||||
|
||||
[HttpPost()]
|
||||
public async Task<PagedData<AdmitTypeMappingDetail>> GetAll(AdmitTypeMappingDetailLoadOptions loadOptions, CancellationToken cancellationToken)
|
||||
{
|
||||
return await _admitTypeMappingDetailService.GetAdmitTypeMappingDetailsAsync(loadOptions.PagingOptions, loadOptions.FilterOptions, cancellationToken);
|
||||
}
|
||||
|
||||
[HttpPost("[action]")]
|
||||
[ProducesResponseType(StatusCodes.Status202Accepted)]
|
||||
public async Task<IActionResult> Export(AdmitTypeMappingDetailExportOptions exportOptions, CancellationToken cancellationToken)
|
||||
{
|
||||
await _admitTypeMappingDetailService.ExportAsync(exportOptions.ExportAll, exportOptions.FilterOptions, User?.Identity?.Name ?? "", cancellationToken);
|
||||
return new AcceptedResult();
|
||||
}
|
||||
|
||||
[HttpGet("[action]")]
|
||||
public async Task<IEnumerable<string>> GetExports(CancellationToken cancellationToken)
|
||||
{
|
||||
return await _admitTypeMappingDetailService.GetExports(User?.Identity?.Name ?? "", cancellationToken);
|
||||
}
|
||||
|
||||
[HttpPost("[action]")]
|
||||
public async Task<bool> Import(IFormFile file, CancellationToken cancellationToken)
|
||||
{
|
||||
return await _admitTypeMappingDetailService.ImportAsync(file, User?.Identity?.Name ?? "", cancellationToken);
|
||||
}
|
||||
}
|
||||
|
||||
public class AdmitTypeMappingDetailLoadOptions
|
||||
{
|
||||
public PagingOptions PagingOptions { get; set; }
|
||||
public AdmitTypeMappingFilters FilterOptions { get; set; }
|
||||
}
|
||||
|
||||
public class AdmitTypeMappingDetailExportOptions
|
||||
{
|
||||
public bool ExportAll { get; set; }
|
||||
public AdmitTypeMappingFilters FilterOptions { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,134 @@
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.JsonPatch;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Strata.Stratasphere.Biz.ClientQueries;
|
||||
using Strata.Stratasphere.Biz.DataManagement;
|
||||
using Strata.Stratasphere.Biz.DataManagement.Models;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Strata.Stratasphere.Api.Controllers
|
||||
{
|
||||
[ApiController]
|
||||
[ApiVersion("1.0")]
|
||||
[Route("api/v{api-version:apiVersion}/[controller]")]
|
||||
public class ClientQueriesController : ControllerBase
|
||||
{
|
||||
private readonly DataManagementContext _dataManagementContext;
|
||||
private readonly IClientQueryService _clientQueryService;
|
||||
|
||||
public ClientQueriesController(DataManagementContext dataManagementContext, IClientQueryService clientQueryService)
|
||||
{
|
||||
_dataManagementContext = dataManagementContext;
|
||||
_clientQueryService = clientQueryService;
|
||||
}
|
||||
|
||||
private bool ClientQueryExists(int clientQueryId) => _dataManagementContext.ClientQueries.Any(e => e.ClientQueryId == clientQueryId);
|
||||
|
||||
[ProducesResponseType(StatusCodes.Status200OK)]
|
||||
[HttpGet]
|
||||
public async Task<IEnumerable<ClientQuery>> GetClientQueries(CancellationToken cancellationToken)
|
||||
{
|
||||
var clientQueries = await _dataManagementContext.ClientQueries.ToListAsync(cancellationToken);
|
||||
|
||||
return clientQueries;
|
||||
}
|
||||
|
||||
[HttpGet("{clientQueryId}")]
|
||||
[ProducesResponseType(StatusCodes.Status200OK)]
|
||||
[ProducesResponseType(StatusCodes.Status404NotFound)]
|
||||
[ProducesDefaultResponseType]
|
||||
public async Task<ActionResult<ClientQuery>> GetById(int clientQueryId, CancellationToken cancellationToken)
|
||||
{
|
||||
var clientQuery = await _dataManagementContext.ClientQueries.SingleOrDefaultAsync(x => x.ClientQueryId == clientQueryId, cancellationToken);
|
||||
|
||||
if (clientQuery == null)
|
||||
{
|
||||
return NotFound();
|
||||
}
|
||||
|
||||
return clientQuery;
|
||||
}
|
||||
|
||||
[HttpPost]
|
||||
[ProducesResponseType(StatusCodes.Status200OK)]
|
||||
[ProducesResponseType(StatusCodes.Status400BadRequest)]
|
||||
[ProducesDefaultResponseType]
|
||||
public async Task<ActionResult<ClientQuery>> Create([FromBody] ClientQuery clientQuery, CancellationToken cancellationToken)
|
||||
{
|
||||
var user = User?.Identity?.Name ?? "";
|
||||
return await _clientQueryService.Create(clientQuery, user, cancellationToken);
|
||||
}
|
||||
|
||||
[HttpPut("{clientQueryId}")]
|
||||
[ProducesResponseType(StatusCodes.Status204NoContent)]
|
||||
[ProducesResponseType(StatusCodes.Status400BadRequest)]
|
||||
[ProducesResponseType(StatusCodes.Status404NotFound)]
|
||||
[ProducesDefaultResponseType]
|
||||
public async Task<IActionResult> Update(int clientQueryId, ClientQuery clientQueryDto, CancellationToken cancellationToken)
|
||||
{
|
||||
if (clientQueryId != clientQueryDto.ClientQueryId) { return BadRequest(); }
|
||||
|
||||
var user = User?.Identity?.Name ?? "";
|
||||
var updated = await _clientQueryService.Update(clientQueryDto, user, cancellationToken);
|
||||
if (!updated) { return NotFound(); }
|
||||
|
||||
return NoContent();
|
||||
}
|
||||
|
||||
[HttpPatch("{clientQueryId}")]
|
||||
[ProducesResponseType(StatusCodes.Status204NoContent)]
|
||||
[ProducesResponseType(StatusCodes.Status400BadRequest)]
|
||||
[ProducesResponseType(StatusCodes.Status404NotFound)]
|
||||
[ProducesDefaultResponseType]
|
||||
public async Task<IActionResult> Patch(int clientQueryId, [FromBody] JsonPatchDocument<ClientQuery> patchDoc,
|
||||
CancellationToken cancellationToken)
|
||||
{
|
||||
if (patchDoc == null) { return BadRequest(); }
|
||||
var user = User?.Identity?.Name ?? "";
|
||||
var clientQuery = await _clientQueryService.Patch(clientQueryId, patchDoc, user, cancellationToken);
|
||||
if (clientQuery == null) { return NotFound(); }
|
||||
|
||||
return new ObjectResult(clientQuery);
|
||||
}
|
||||
|
||||
[HttpGet("{clientQueryId}/[action]")]
|
||||
public async Task<bool> SaveToGithub(int clientQueryId, CancellationToken cancellationToken)
|
||||
{
|
||||
if (clientQueryId < 0) { return false; }
|
||||
var user = User?.Identity?.Name ?? "";
|
||||
return await _clientQueryService.SaveToGithub(clientQueryId, user, cancellationToken);
|
||||
}
|
||||
|
||||
[HttpDelete("{clientQueryId}")]
|
||||
[ProducesResponseType(StatusCodes.Status200OK)]
|
||||
[ProducesDefaultResponseType]
|
||||
[ProducesResponseType(StatusCodes.Status204NoContent)]
|
||||
public async Task<IActionResult> Delete(int clientQueryId, CancellationToken cancellationToken)
|
||||
{
|
||||
var clientQuery = await _dataManagementContext.ClientQueries.SingleOrDefaultAsync(p => p.ClientQueryId == clientQueryId, cancellationToken);
|
||||
|
||||
if (clientQuery == null)
|
||||
{
|
||||
return NotFound();
|
||||
}
|
||||
|
||||
_dataManagementContext.ClientQueries.Remove(clientQuery);
|
||||
await _dataManagementContext.SaveChangesAsync(cancellationToken);
|
||||
|
||||
return NoContent();
|
||||
}
|
||||
|
||||
[HttpGet("{clientQueryId}/[action]")]
|
||||
[ProducesResponseType(StatusCodes.Status200OK)]
|
||||
[ProducesResponseType(StatusCodes.Status404NotFound)]
|
||||
[ProducesDefaultResponseType]
|
||||
public async Task<IActionResult> History(int clientQueryId, CancellationToken cancellationToken)
|
||||
=> Ok(await _clientQueryService.History(clientQueryId, User?.Identity?.Name ?? ""));
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Strata.Stratasphere.Biz.Database;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Strata.Stratasphere.Api.Controllers
|
||||
{
|
||||
[ApiController]
|
||||
[ApiVersion("1.0")]
|
||||
[Route("api/v{api-version:apiVersion}/[controller]")]
|
||||
public class DatabasesController : ControllerBase
|
||||
{
|
||||
private readonly IDatabaseService _databaseService;
|
||||
|
||||
/// <summary>
|
||||
/// Provides an IEnumerable set of Database information
|
||||
/// </summary>
|
||||
/// <param name="databaseService"></param>
|
||||
public DatabasesController(IDatabaseService databaseService)
|
||||
{
|
||||
_databaseService = databaseService;
|
||||
}
|
||||
|
||||
[HttpGet]
|
||||
[ProducesResponseType(StatusCodes.Status200OK)]
|
||||
public async Task<IEnumerable<Database>> GetAll(CancellationToken cancellationToken)
|
||||
{
|
||||
return await _databaseService.GetDatabasesAsync(cancellationToken);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Strata.SqlTools.EntityFramework.Pagination;
|
||||
using Strata.Stratasphere.Biz.Mappings.Departments;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Strata.Stratasphere.Api.Controllers
|
||||
{
|
||||
[ApiController]
|
||||
[ApiVersion("1.0")]
|
||||
[Route("api/v{api-version:apiVersion}/[controller]")]
|
||||
public class DepartmentMappingDetailsController : ControllerBase
|
||||
{
|
||||
private readonly IDepartmentMappingDetailService _departmentMappingDetailService;
|
||||
|
||||
public DepartmentMappingDetailsController(IDepartmentMappingDetailService accountMappingDetailService)
|
||||
{
|
||||
_departmentMappingDetailService = accountMappingDetailService;
|
||||
}
|
||||
|
||||
[HttpPost()]
|
||||
public async Task<PagedData<DepartmentMappingDetail>> GetAll(DepartmentMappingDetailLoadOptions loadOptions, CancellationToken cancellationToken)
|
||||
{
|
||||
return await _departmentMappingDetailService.GetDepartmentMappingDetailsAsync(loadOptions.PagingOptions, loadOptions.FilterOptions, cancellationToken);
|
||||
}
|
||||
|
||||
[HttpPost("[action]")]
|
||||
[ProducesResponseType(StatusCodes.Status202Accepted)]
|
||||
public async Task<IActionResult> Export(DepartmentMappingDetailExportOptions exportOptions, CancellationToken cancellationToken)
|
||||
{
|
||||
await _departmentMappingDetailService.ExportAsync(exportOptions.ExportAll, exportOptions.FilterOptions, User?.Identity?.Name ?? "", cancellationToken);
|
||||
return new AcceptedResult();
|
||||
}
|
||||
|
||||
[HttpGet("[action]")]
|
||||
public async Task<IEnumerable<string>> GetExports(CancellationToken cancellationToken)
|
||||
{
|
||||
return await _departmentMappingDetailService.GetExports(User?.Identity?.Name ?? "", cancellationToken);
|
||||
}
|
||||
|
||||
[HttpPost("[action]")]
|
||||
public async Task<bool> Import(IFormFile file, CancellationToken cancellationToken)
|
||||
{
|
||||
return await _departmentMappingDetailService.ImportAsync(file, User?.Identity?.Name ?? "", cancellationToken);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public class DepartmentMappingDetailLoadOptions
|
||||
{
|
||||
public PagingOptions PagingOptions { get; set; }
|
||||
public DepartmentMappingFilters FilterOptions { get; set; }
|
||||
}
|
||||
|
||||
public class DepartmentMappingDetailExportOptions
|
||||
{
|
||||
public bool ExportAll { get; set; }
|
||||
public DepartmentMappingFilters FilterOptions { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Strata.SqlTools.EntityFramework.Pagination;
|
||||
using Strata.Stratasphere.Biz.Mappings.DischargeStatus;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Strata.Stratasphere.Api.Controllers
|
||||
{
|
||||
[ApiController]
|
||||
[ApiVersion("1.0")]
|
||||
[Route("api/v{api-version:apiVersion}/[controller]")]
|
||||
public class DischargeStatusMappingDetailsController : ControllerBase
|
||||
{
|
||||
private readonly IDischargeStatusMappingDetailService _dischargeStatusMappingDetailService;
|
||||
|
||||
public DischargeStatusMappingDetailsController(IDischargeStatusMappingDetailService dischargeStatusMappingDetailService)
|
||||
{
|
||||
_dischargeStatusMappingDetailService = dischargeStatusMappingDetailService;
|
||||
}
|
||||
|
||||
[HttpPost()]
|
||||
public async Task<PagedData<DischargeStatusMappingDetail>> GetAll(DischargeStatusMappingDetailLoadOptions loadOptions, CancellationToken cancellationToken)
|
||||
{
|
||||
return
|
||||
await _dischargeStatusMappingDetailService.GetDischargeStatusMappingDetailsAsync(loadOptions.PagingOptions, loadOptions.FilterOptions, cancellationToken);
|
||||
}
|
||||
|
||||
[HttpPost("[action]")]
|
||||
[ProducesResponseType(StatusCodes.Status202Accepted)]
|
||||
public async Task<IActionResult> Export(DischargeStatusMappingDetailExportOptions exportOptions, CancellationToken cancellationToken)
|
||||
{
|
||||
await _dischargeStatusMappingDetailService.ExportAsync(exportOptions.ExportAll, exportOptions.FilterOptions, User?.Identity?.Name ?? "", cancellationToken);
|
||||
return new AcceptedResult();
|
||||
}
|
||||
|
||||
[HttpPost("[action]")]
|
||||
public async Task<bool> Import(IFormFile file, CancellationToken cancellationToken)
|
||||
{
|
||||
return await _dischargeStatusMappingDetailService.ImportAsync(file, User?.Identity?.Name ?? "", cancellationToken);
|
||||
}
|
||||
}
|
||||
|
||||
public class DischargeStatusMappingDetailLoadOptions
|
||||
{
|
||||
public PagingOptions PagingOptions { get; set; }
|
||||
public DischargeStatusMappingFilters FilterOptions { get; set; }
|
||||
}
|
||||
|
||||
public class DischargeStatusMappingDetailExportOptions
|
||||
{
|
||||
public bool ExportAll { get; set; }
|
||||
public DischargeStatusMappingFilters FilterOptions { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Strata.Stratasphere.Biz.Mappings.Exports;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Strata.Stratasphere.Api.Controllers
|
||||
{
|
||||
[ApiController]
|
||||
[ApiVersion("1.0")]
|
||||
[Route("api/v{api-version:apiVersion}/[controller]")]
|
||||
public class ExportController : ControllerBase
|
||||
{
|
||||
private readonly IExportJobService _exportJobService;
|
||||
|
||||
public ExportController(IExportJobService exportJobService)
|
||||
{
|
||||
_exportJobService = exportJobService;
|
||||
}
|
||||
|
||||
[HttpGet("[action]")]
|
||||
[ProducesResponseType(StatusCodes.Status202Accepted)]
|
||||
[ProducesResponseType(StatusCodes.Status500InternalServerError)]
|
||||
[ProducesDefaultResponseType]
|
||||
public async Task<IActionResult> Download([FromQuery] string filename, CancellationToken cancellationToken)
|
||||
{
|
||||
var memoryStream = await _exportJobService.DownloadFile(filename, cancellationToken);
|
||||
|
||||
return new FileContentResult(memoryStream.ToArray(),
|
||||
"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet")
|
||||
{
|
||||
FileDownloadName = filename
|
||||
};
|
||||
}
|
||||
|
||||
[HttpGet("[action]")]
|
||||
public async Task<IEnumerable<string>> GetExports(CancellationToken cancellationToken)
|
||||
{
|
||||
return await _exportJobService.GetExports(cancellationToken);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Strata.Stratasphere.Biz.Github;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Strata.Stratasphere.Api.Controllers
|
||||
{
|
||||
[ApiController]
|
||||
[ApiVersion("1.0")]
|
||||
[Route("api/v{api-version:apiVersion}/[controller]")]
|
||||
public class GithubController : ControllerBase
|
||||
{
|
||||
private readonly IDataWranglerHistoryService _historyService;
|
||||
|
||||
public GithubController(
|
||||
IDataWranglerHistoryService historyService)
|
||||
{
|
||||
_historyService = historyService;
|
||||
}
|
||||
|
||||
[HttpGet("{processId}/[action]")]
|
||||
[ProducesResponseType(StatusCodes.Status200OK)]
|
||||
[ProducesResponseType(StatusCodes.Status404NotFound)]
|
||||
[ProducesDefaultResponseType]
|
||||
public async Task<IActionResult> ProcessHistory(int processId, CancellationToken cancellationToken)
|
||||
=> Ok(await _historyService.ProcessHistory(processId, User?.Identity?.Name ?? ""));
|
||||
|
||||
[HttpGet("{queryId}/[action]")]
|
||||
[ProducesResponseType(StatusCodes.Status200OK)]
|
||||
[ProducesResponseType(StatusCodes.Status404NotFound)]
|
||||
[ProducesDefaultResponseType]
|
||||
public async Task<IActionResult> QueryHistory(int queryId, CancellationToken cancellationToken)
|
||||
=> Ok(await _historyService.QueryHistory(queryId, User?.Identity?.Name ?? ""));
|
||||
|
||||
[HttpGet("{clientQueryId}/[action]")]
|
||||
[ProducesResponseType(StatusCodes.Status200OK)]
|
||||
[ProducesResponseType(StatusCodes.Status404NotFound)]
|
||||
[ProducesDefaultResponseType]
|
||||
public async Task<IActionResult> ClientQueryHistory(int clientQueryId, CancellationToken cancellationToken)
|
||||
=> Ok(await _historyService.ClientQueryHistory(clientQueryId, User?.Identity?.Name ?? ""));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Strata.SqlTools.EntityFramework.Pagination;
|
||||
using Strata.Stratasphere.Biz.Mappings.JobCodes;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Strata.Stratasphere.Api.Controllers
|
||||
{
|
||||
[ApiController]
|
||||
[ApiVersion("1.0")]
|
||||
[Route("api/v{api-version:apiVersion}/[controller]")]
|
||||
public class JobCodeMappingDetailsController : ControllerBase
|
||||
{
|
||||
private readonly IJobCodeMappingDetailService _jobCodeMappingDetailService;
|
||||
|
||||
public JobCodeMappingDetailsController(IJobCodeMappingDetailService jobCodeMappingDetailService)
|
||||
{
|
||||
_jobCodeMappingDetailService = jobCodeMappingDetailService;
|
||||
}
|
||||
|
||||
[HttpPost()]
|
||||
public async Task<PagedData<JobCodeMappingDetail>> GetAll(JobCodeMappingDetailLoadOptions loadOptions, CancellationToken cancellationToken)
|
||||
{
|
||||
return await _jobCodeMappingDetailService.GetJobCodeMappingDetailsAsync(loadOptions.PagingOptions, loadOptions.FilterOptions, cancellationToken);
|
||||
}
|
||||
|
||||
[HttpPost("[action]")]
|
||||
[ProducesResponseType(StatusCodes.Status202Accepted)]
|
||||
public async Task<IActionResult> Export(JobCodeMappingDetailExportOptions exportOptions, CancellationToken cancellationToken)
|
||||
{
|
||||
await _jobCodeMappingDetailService.ExportAsync(exportOptions.ExportAll, exportOptions.FilterOptions, User?.Identity?.Name ?? "", cancellationToken);
|
||||
return new AcceptedResult();
|
||||
}
|
||||
|
||||
[HttpGet("[action]")]
|
||||
public async Task<IEnumerable<string>> GetExports(CancellationToken cancellationToken)
|
||||
{
|
||||
return await _jobCodeMappingDetailService.GetExports(User?.Identity?.Name ?? "", cancellationToken);
|
||||
}
|
||||
|
||||
[HttpPost("[action]")]
|
||||
public async Task<bool> Import(IFormFile file, CancellationToken cancellationToken)
|
||||
{
|
||||
return await _jobCodeMappingDetailService.ImportAsync(file, User?.Identity?.Name ?? "", cancellationToken);
|
||||
}
|
||||
}
|
||||
|
||||
public class JobCodeMappingDetailLoadOptions
|
||||
{
|
||||
public PagingOptions PagingOptions { get; set; }
|
||||
public JobCodeMappingFilters FilterOptions { get; set; }
|
||||
}
|
||||
|
||||
public class JobCodeMappingDetailExportOptions
|
||||
{
|
||||
public bool ExportAll { get; set; }
|
||||
public JobCodeMappingFilters FilterOptions { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,70 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Strata.Stratasphere.Api.Dtos;
|
||||
using Strata.Stratasphere.Biz.DataManagement;
|
||||
using Strata.Stratasphere.Biz.DataManagement.Models;
|
||||
|
||||
namespace Strata.Stratasphere.Api.Controllers
|
||||
{
|
||||
|
||||
[ApiController]
|
||||
[ApiVersion("1.0")]
|
||||
[Route("api/v{api-version:apiVersion}/[controller]")]
|
||||
public class ParametersController: ControllerBase
|
||||
{
|
||||
private readonly DataManagementContext _dataManagementContext;
|
||||
private readonly ILogger<ParametersController> _logger;
|
||||
|
||||
public ParametersController(DataManagementContext dataManagementContext, ILogger<ParametersController> logger)
|
||||
{
|
||||
_dataManagementContext = dataManagementContext;
|
||||
_logger = logger;
|
||||
}
|
||||
|
||||
[HttpGet("{processId}")]
|
||||
[ProducesResponseType(StatusCodes.Status200OK)]
|
||||
public async Task<IEnumerable<Parameter>> GetById(int processId, CancellationToken cancellationToken)
|
||||
{
|
||||
var parameters = await _dataManagementContext.Parameters.Where(p => p.ProcessId == processId)
|
||||
.ToListAsync(cancellationToken);
|
||||
|
||||
return parameters;
|
||||
}
|
||||
|
||||
|
||||
// I don't love this method, we need to discuss if we are bulk saving or saving as they manipulate the grid
|
||||
[HttpPut()]
|
||||
[ProducesResponseType(StatusCodes.Status204NoContent)]
|
||||
[ProducesResponseType(StatusCodes.Status400BadRequest)]
|
||||
[ProducesDefaultResponseType]
|
||||
public async Task<IActionResult> SaveParameters([FromBody] List<ParameterDto> parameterDtos, CancellationToken cancellationToken)
|
||||
{
|
||||
foreach(var newParam in parameterDtos.Where(x => x.IsNew))
|
||||
{
|
||||
newParam.ParameterId = 0;
|
||||
}
|
||||
|
||||
_dataManagementContext.Parameters.AddRange(parameterDtos.Where(x => x.IsNew && !x.IsDeleted));
|
||||
|
||||
_dataManagementContext.Parameters.RemoveRange(parameterDtos.Where(x => x.IsDeleted && !x.IsNew));
|
||||
|
||||
foreach(var updatedParam in parameterDtos.Where(x => !x.IsNew && !x.IsDeleted))
|
||||
{
|
||||
var baseParam = await _dataManagementContext.Parameters.FindAsync(new object[] {updatedParam.ParameterId }, cancellationToken);
|
||||
|
||||
baseParam.Name = updatedParam.Name;
|
||||
baseParam.Value = updatedParam.Value;
|
||||
}
|
||||
|
||||
await _dataManagementContext.SaveChangesAsync(cancellationToken);
|
||||
|
||||
return NoContent();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Strata.SqlTools.EntityFramework.Pagination;
|
||||
using Strata.Stratasphere.Biz.Mappings.PayCodes;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Strata.Stratasphere.Api.Controllers
|
||||
{
|
||||
[ApiController]
|
||||
[ApiVersion("1.0")]
|
||||
[Route("api/v{api-version:apiVersion}/[controller]")]
|
||||
public class PayCodeMappingDetailsController : ControllerBase
|
||||
{
|
||||
private readonly IPayCodeMappingDetailService _payCodeMappingDetailService;
|
||||
|
||||
public PayCodeMappingDetailsController(IPayCodeMappingDetailService payCodeMappingDetailService)
|
||||
{
|
||||
_payCodeMappingDetailService = payCodeMappingDetailService;
|
||||
}
|
||||
|
||||
[HttpPost()]
|
||||
public async Task<PagedData<PayCodeMappingDetail>> GetAll(PayCodeMappingDetailLoadOptions loadOptions, CancellationToken cancellationToken)
|
||||
{
|
||||
return await _payCodeMappingDetailService.GetPayCodeMappingDetailsAsync(loadOptions.PagingOptions, loadOptions.FilterOptions, cancellationToken);
|
||||
}
|
||||
|
||||
[HttpPost("[action]")]
|
||||
[ProducesResponseType(StatusCodes.Status202Accepted)]
|
||||
public async Task<IActionResult> Export(PayCodeMappingDetailExportOptions exportOptions, CancellationToken cancellationToken)
|
||||
{
|
||||
await _payCodeMappingDetailService.ExportAsync(exportOptions.ExportAll, exportOptions.FilterOptions, User?.Identity?.Name ?? "", cancellationToken);
|
||||
return new AcceptedResult();
|
||||
}
|
||||
|
||||
[HttpGet("[action]")]
|
||||
public async Task<IEnumerable<string>> GetExports(CancellationToken cancellationToken)
|
||||
{
|
||||
return await _payCodeMappingDetailService.GetExports(User?.Identity?.Name ?? "", cancellationToken);
|
||||
}
|
||||
|
||||
[HttpPost("[action]")]
|
||||
public async Task<bool> Import(IFormFile file, CancellationToken cancellationToken)
|
||||
{
|
||||
return await _payCodeMappingDetailService.ImportAsync(file, User?.Identity?.Name ?? "", cancellationToken);
|
||||
}
|
||||
}
|
||||
|
||||
public class PayCodeMappingDetailLoadOptions
|
||||
{
|
||||
public PagingOptions PagingOptions { get; set; }
|
||||
public PayCodeMappingFilters FilterOptions { get; set; }
|
||||
}
|
||||
|
||||
public class PayCodeMappingDetailExportOptions
|
||||
{
|
||||
public bool ExportAll { get; set; }
|
||||
public PayCodeMappingFilters FilterOptions { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Strata.SqlTools.EntityFramework.Pagination;
|
||||
using Strata.Stratasphere.Biz.Mappings.PayorTypes;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Strata.Stratasphere.Api.Controllers
|
||||
{
|
||||
[ApiController]
|
||||
[ApiVersion("1.0")]
|
||||
[Route("api/v{api-version:apiVersion}/[controller]")]
|
||||
public class PayorTypeMappingDetailsController : ControllerBase
|
||||
{
|
||||
private readonly IPayorTypeMappingDetailService _payorTypeMappingDetailService;
|
||||
|
||||
public PayorTypeMappingDetailsController(IPayorTypeMappingDetailService payorTypeMappingDetailService)
|
||||
{
|
||||
_payorTypeMappingDetailService = payorTypeMappingDetailService;
|
||||
}
|
||||
|
||||
[HttpPost()]
|
||||
public async Task<PagedData<PayorTypeMappingDetail>> GetAll(PayorTypeMappingDetailLoadOptions loadOptions, CancellationToken cancellationToken)
|
||||
{
|
||||
return await _payorTypeMappingDetailService.GetPayorTypeMappingDetailsAsync(loadOptions.PagingOptions, loadOptions.FilterOptions, cancellationToken);
|
||||
}
|
||||
|
||||
|
||||
[HttpPost("[action]")]
|
||||
[ProducesResponseType(StatusCodes.Status202Accepted)]
|
||||
public async Task<IActionResult> Export(PayorTypeMappingDetailExportOptions exportOptions, CancellationToken cancellationToken)
|
||||
{
|
||||
await _payorTypeMappingDetailService.ExportAsync(exportOptions.ExportAll, exportOptions.FilterOptions, User?.Identity?.Name ?? "", cancellationToken);
|
||||
return new AcceptedResult();
|
||||
}
|
||||
|
||||
[HttpGet("[action]")]
|
||||
public async Task<IEnumerable<string>> GetExports(CancellationToken cancellationToken)
|
||||
{
|
||||
return await _payorTypeMappingDetailService.GetExports(User?.Identity?.Name ?? "", cancellationToken);
|
||||
}
|
||||
|
||||
[HttpPost("[action]")]
|
||||
public async Task<bool> Import(IFormFile file, CancellationToken cancellationToken)
|
||||
{
|
||||
return await _payorTypeMappingDetailService.ImportAsync(file, User?.Identity?.Name ?? "", cancellationToken);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public class PayorTypeMappingDetailLoadOptions
|
||||
{
|
||||
public PagingOptions PagingOptions { get; set; }
|
||||
public PayorTypeMappingFilters FilterOptions { get; set; }
|
||||
}
|
||||
|
||||
public class PayorTypeMappingDetailExportOptions
|
||||
{
|
||||
public bool ExportAll { get; set; }
|
||||
public PayorTypeMappingFilters FilterOptions { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Strata.SqlTools.EntityFramework.Pagination;
|
||||
using Strata.Stratasphere.Biz.Mappings.PresentOnAdmission;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Strata.Stratasphere.Api.Controllers
|
||||
{
|
||||
[ApiController]
|
||||
[ApiVersion("1.0")]
|
||||
[Route("api/v{api-version:apiVersion}/[controller]")]
|
||||
public class PresentOnAdmissionMappingDetailsController : ControllerBase
|
||||
{
|
||||
private readonly IPresentOnAdmissionMappingDetailService _presentOnAdmissionMappingDetailService;
|
||||
|
||||
public PresentOnAdmissionMappingDetailsController(IPresentOnAdmissionMappingDetailService presentOnAdmissionMappingDetailService)
|
||||
{
|
||||
_presentOnAdmissionMappingDetailService = presentOnAdmissionMappingDetailService;
|
||||
}
|
||||
|
||||
[HttpPost()]
|
||||
public async Task<PagedData<PresentOnAdmissionMappingDetail>> GetAll(PresentOnAdmissionMappingDetailLoadOptions loadOptions, CancellationToken cancellationToken)
|
||||
{
|
||||
return await _presentOnAdmissionMappingDetailService.GetPresentOnAdmissionMappingDetailsAsync(loadOptions.PagingOptions, loadOptions.FilterOptions, cancellationToken);
|
||||
}
|
||||
|
||||
[HttpPost("[action]")]
|
||||
[ProducesResponseType(StatusCodes.Status202Accepted)]
|
||||
public async Task<IActionResult> Export(PresentOnAdmissionMappingDetailExportOptions exportOptions, CancellationToken cancellationToken)
|
||||
{
|
||||
await _presentOnAdmissionMappingDetailService.ExportAsync(exportOptions.ExportAll, exportOptions.FilterOptions, User?.Identity?.Name ?? "", cancellationToken);
|
||||
return new AcceptedResult();
|
||||
}
|
||||
|
||||
[HttpGet("[action]")]
|
||||
public async Task<IEnumerable<string>> GetExports(CancellationToken cancellationToken)
|
||||
{
|
||||
return await _presentOnAdmissionMappingDetailService.GetExports(User?.Identity?.Name ?? "", cancellationToken);
|
||||
}
|
||||
|
||||
[HttpPost("[action]")]
|
||||
public async Task<bool> Import(IFormFile file, CancellationToken cancellationToken)
|
||||
{
|
||||
return await _presentOnAdmissionMappingDetailService.ImportAsync(file, User?.Identity?.Name ?? "", cancellationToken);
|
||||
}
|
||||
}
|
||||
|
||||
public class PresentOnAdmissionMappingDetailLoadOptions
|
||||
{
|
||||
public PagingOptions PagingOptions { get; set; }
|
||||
public PresentOnAdmissionMappingFilters FilterOptions { get; set; }
|
||||
}
|
||||
|
||||
public class PresentOnAdmissionMappingDetailExportOptions
|
||||
{
|
||||
public bool ExportAll { get; set; }
|
||||
public PresentOnAdmissionMappingFilters FilterOptions { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,60 @@
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Strata.Stratasphere.Api.DTOs;
|
||||
using Strata.Stratasphere.Biz.DataManagement;
|
||||
using Strata.Stratasphere.Biz.Parser;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using static Strata.Stratasphere.Biz.Parser.DirectedAcyclicGraph<Strata.Stratasphere.Biz.DataManagement.Models.Query>;
|
||||
|
||||
namespace Strata.Stratasphere.Api.Controllers
|
||||
{
|
||||
[ApiController]
|
||||
[ApiVersion("1.0")]
|
||||
[Route("api/v{api-version:apiVersion}/[controller]")]
|
||||
public class ProcessGraphsController : ControllerBase
|
||||
{
|
||||
private readonly DataManagementContext _dataManagementContext;
|
||||
private readonly ILogger<ProcessGraphsController> _logger;
|
||||
|
||||
public ProcessGraphsController(DataManagementContext dataManagementContext, ILogger<ProcessGraphsController> logger)
|
||||
{
|
||||
_dataManagementContext = dataManagementContext;
|
||||
_logger = logger;
|
||||
}
|
||||
|
||||
[HttpGet("{processId}/[action]")]
|
||||
[ProducesResponseType(StatusCodes.Status200OK)]
|
||||
[ProducesResponseType(StatusCodes.Status404NotFound)]
|
||||
[ProducesDefaultResponseType]
|
||||
public async Task<ActionResult<GraphDto>> GetEdgesAsync(int processId, CancellationToken cancellationToken)
|
||||
{
|
||||
var process = await _dataManagementContext.Processes.Include(x => x.Queries)
|
||||
.SingleOrDefaultAsync(x => x.ProcessId == processId, cancellationToken);
|
||||
|
||||
if (process == null)
|
||||
{
|
||||
return NotFound();
|
||||
}
|
||||
|
||||
var graph = process.Queries.ToDirectedAcyclicGraph();
|
||||
|
||||
var generationalLookup = graph.GetNodeGenerationLookup();
|
||||
|
||||
var edges = graph.Edges.ToList();
|
||||
|
||||
var queriesWithNoEdges = process.Queries.Where(q => edges.All(e => e.Source != q) && edges.All(e => e.Target != q));
|
||||
foreach (var orphan in queriesWithNoEdges)
|
||||
{
|
||||
edges.Add(new Edge(orphan, null));
|
||||
}
|
||||
|
||||
var graphDto = new GraphDto(edges, generationalLookup);
|
||||
|
||||
return Ok(graphDto);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Strata.Stratasphere.Biz.DataManagement;
|
||||
using Strata.Stratasphere.Biz.DataManagement.Models;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Strata.Stratasphere.Api.Controllers
|
||||
{
|
||||
[ApiController]
|
||||
[ApiVersion("1.0")]
|
||||
[Route("api/v{api-version:apiVersion}/[controller]")]
|
||||
public class ProcessHistoryController : ControllerBase
|
||||
{
|
||||
private readonly DataManagementContext _dataManagementContext;
|
||||
|
||||
public ProcessHistoryController(DataManagementContext dataManagementContext)
|
||||
{
|
||||
_dataManagementContext = dataManagementContext;
|
||||
}
|
||||
|
||||
[ProducesResponseType(StatusCodes.Status200OK)]
|
||||
[HttpGet("{processId}")]
|
||||
public async Task<IEnumerable<ProcessExecutionResult>> GetHistoryAsync(int processId, CancellationToken cancellationToken)
|
||||
{
|
||||
var history = await _dataManagementContext.ProcessExecutionResults.Where(x => x.ProcessId == processId)
|
||||
.Include(x => x.ProcessClientExecutionResults)
|
||||
.ToListAsync(cancellationToken);
|
||||
|
||||
return history.OrderByDescending(x => x.EndTime);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,131 @@
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Strata.Stratasphere.Biz.DataManagement.Models;
|
||||
using Strata.Stratasphere.Biz.Processes;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using ProcessJobRequest = Strata.Stratasphere.Biz.Processes.ProcessJobRequest;
|
||||
|
||||
namespace Strata.Stratasphere.Api.Controllers
|
||||
{
|
||||
[ApiController]
|
||||
[ApiVersion("1.0")]
|
||||
[Route("api/v{api-version:apiVersion}/[controller]")]
|
||||
public class ProcessesController : ControllerBase
|
||||
{
|
||||
private readonly IProcessService _processService;
|
||||
|
||||
public ProcessesController(IProcessService processesService)
|
||||
{
|
||||
_processService = processesService;
|
||||
}
|
||||
|
||||
[HttpGet]
|
||||
[ProducesResponseType(StatusCodes.Status200OK)]
|
||||
public async Task<IEnumerable<Process>> GetAll(CancellationToken cancellationToken)
|
||||
=> await _processService.GetAll(cancellationToken);
|
||||
|
||||
[HttpGet("{processId}/[action]")]
|
||||
[ProducesResponseType(StatusCodes.Status200OK)]
|
||||
[ProducesResponseType(StatusCodes.Status404NotFound)]
|
||||
[ProducesDefaultResponseType]
|
||||
public async Task<ActionResult<IEnumerable<Query>>> GetQueries(int processId, CancellationToken cancellationToken)
|
||||
{
|
||||
var queries = await _processService.GetQueries(processId, cancellationToken);
|
||||
|
||||
if (queries == null)
|
||||
{
|
||||
return NotFound();
|
||||
}
|
||||
|
||||
return Ok(queries);
|
||||
}
|
||||
|
||||
[HttpGet("{processId}")]
|
||||
[ProducesResponseType(StatusCodes.Status200OK)]
|
||||
[ProducesResponseType(StatusCodes.Status404NotFound)]
|
||||
[ProducesDefaultResponseType]
|
||||
public async Task<ActionResult<Process>> GetById(int processId, CancellationToken cancellationToken)
|
||||
{
|
||||
var process = await _processService.GetById(processId, cancellationToken);
|
||||
|
||||
if (process == null)
|
||||
{
|
||||
return NotFound();
|
||||
}
|
||||
|
||||
return process;
|
||||
}
|
||||
|
||||
[HttpPost]
|
||||
[ProducesResponseType(StatusCodes.Status200OK)]
|
||||
[ProducesDefaultResponseType]
|
||||
public async Task<ActionResult<Process>> Create([FromBody] ProcessData process, CancellationToken cancellationToken)
|
||||
=> await _processService.Create(process, User, cancellationToken);
|
||||
|
||||
[HttpGet("{processId}/[action]")]
|
||||
[ProducesResponseType(StatusCodes.Status200OK)]
|
||||
[ProducesResponseType(StatusCodes.Status404NotFound)]
|
||||
[ProducesDefaultResponseType]
|
||||
public async Task<ActionResult<Process>> Copy(int processId, CancellationToken cancellationToken)
|
||||
{
|
||||
var process = await _processService.Copy(processId, User, cancellationToken);
|
||||
if (process == null) { return NotFound(); }
|
||||
return process;
|
||||
}
|
||||
|
||||
[HttpPut("{processId}")]
|
||||
[ProducesResponseType(StatusCodes.Status200OK)]
|
||||
[ProducesResponseType(StatusCodes.Status400BadRequest)]
|
||||
[ProducesResponseType(StatusCodes.Status404NotFound)]
|
||||
[ProducesDefaultResponseType]
|
||||
public async Task<IActionResult> Update(int processId, ProcessData processDto, CancellationToken cancellationToken)
|
||||
{
|
||||
if (processId != processDto.ProcessId)
|
||||
{
|
||||
return BadRequest();
|
||||
}
|
||||
|
||||
var result = await _processService.Update(processDto, User, cancellationToken);
|
||||
if (result == StatusCodes.Status404NotFound) { return NotFound(); }
|
||||
return Ok(true);
|
||||
}
|
||||
|
||||
[HttpGet("{processId}/[action]")]
|
||||
public async Task<bool> SaveToGithub(int processId, CancellationToken cancellationToken)
|
||||
{
|
||||
if (processId < 0) { return false; }
|
||||
var user = User?.Identity?.Name ?? "";
|
||||
return await _processService.SaveToGithub(processId, user, cancellationToken);
|
||||
}
|
||||
|
||||
[HttpDelete("{processId}")]
|
||||
[ProducesResponseType(StatusCodes.Status200OK)]
|
||||
[ProducesDefaultResponseType]
|
||||
[ProducesResponseType(StatusCodes.Status204NoContent)]
|
||||
public async Task<IActionResult> Delete(int processId, CancellationToken cancellationToken)
|
||||
=> await _processService.Delete(processId, cancellationToken) ? NoContent() : NotFound();
|
||||
|
||||
[HttpGet("{processId}/[action]")]
|
||||
[ProducesResponseType(StatusCodes.Status200OK)]
|
||||
[ProducesResponseType(StatusCodes.Status404NotFound)]
|
||||
[ProducesDefaultResponseType]
|
||||
public async Task<IActionResult> History(int processId, CancellationToken cancellationToken)
|
||||
=> Ok(await _processService.History(processId, User));
|
||||
|
||||
[HttpPost("{processId}/[action]")]
|
||||
[ProducesResponseType(StatusCodes.Status200OK)]
|
||||
[ProducesDefaultResponseType]
|
||||
public async Task<IActionResult> Start(int processId, ProcessJobRequest processJobDto, CancellationToken cancellationToken)
|
||||
{
|
||||
var jobId = await _processService.Start(processId, processJobDto, User, cancellationToken);
|
||||
if (string.IsNullOrEmpty(jobId))
|
||||
{
|
||||
return NotFound();
|
||||
}
|
||||
return Ok(new { jobId });
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
using Hangfire;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Strata.Stratasphere.Biz;
|
||||
using Strata.Stratasphere.Biz.DataManagement;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Strata.Stratasphere.Api.Controllers
|
||||
{
|
||||
[ApiController]
|
||||
[ApiVersion("1.0")]
|
||||
[Route("api/v{api-version:apiVersion}/[controller]")]
|
||||
public class PromoteProcessController : ControllerBase
|
||||
{
|
||||
private readonly DataManagementContext _dataManagementContext;
|
||||
private readonly ILogger<PromoteProcessController> _logger;
|
||||
private readonly IBackgroundJobClient _backgroundJobClient;
|
||||
|
||||
public PromoteProcessController(DataManagementContext dataManagementContext, IBackgroundJobClient backgroundJobClient,
|
||||
ILogger<PromoteProcessController> logger)
|
||||
{
|
||||
_dataManagementContext = dataManagementContext;
|
||||
_backgroundJobClient = backgroundJobClient;
|
||||
_logger = logger;
|
||||
}
|
||||
|
||||
[HttpGet("{processId}/[action]")]
|
||||
[ProducesResponseType(StatusCodes.Status200OK)]
|
||||
[ProducesDefaultResponseType]
|
||||
public async Task<IActionResult> Promote(int processId, CancellationToken cancellationToken)
|
||||
{
|
||||
var process = await _dataManagementContext.Processes.SingleOrDefaultAsync(p => p.ProcessId == processId, cancellationToken);
|
||||
|
||||
if (process == null)
|
||||
{
|
||||
return NotFound();
|
||||
}
|
||||
|
||||
var executingUser = User?.Identity?.Name;
|
||||
|
||||
var jobId = _backgroundJobClient.Enqueue<PromoteJob>(p => p.PromoteProcessFromStagingToProd(process.ProcessId, process.Name, executingUser, CancellationToken.None));
|
||||
|
||||
return Ok(new { jobId });
|
||||
}
|
||||
|
||||
[HttpGet("{processId}/[action]")]
|
||||
[ProducesResponseType(StatusCodes.Status200OK)]
|
||||
[ProducesDefaultResponseType]
|
||||
public async Task<IActionResult> Rollback(int processId, CancellationToken cancellationToken)
|
||||
{
|
||||
var process = await _dataManagementContext.Processes.SingleOrDefaultAsync(p => p.ProcessId == processId, cancellationToken);
|
||||
|
||||
if (process == null)
|
||||
{
|
||||
return NotFound();
|
||||
}
|
||||
|
||||
var executingUser = User?.Identity?.Name;
|
||||
|
||||
var jobId = _backgroundJobClient.Enqueue<PromoteJob>(p => p.RollbackProcess(process.ProcessId, process.Name, executingUser, CancellationToken.None));
|
||||
|
||||
return Ok(new { jobId });
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,124 @@
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Strata.Stratasphere.Biz.DataManagement;
|
||||
using Strata.Stratasphere.Biz.DataManagement.Models;
|
||||
using Strata.Stratasphere.Biz.Queries;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Strata.Stratasphere.Api.Controllers
|
||||
{
|
||||
[ApiController]
|
||||
[ApiVersion("1.0")]
|
||||
[Route("api/v{api-version:apiVersion}/[controller]")]
|
||||
public class QueriesController : ControllerBase
|
||||
{
|
||||
private readonly DataManagementContext _dataManagementContext;
|
||||
private readonly IQueryService _queryService;
|
||||
|
||||
private bool QueryExists(int queryId) => _dataManagementContext.Queries.Any(e => e.QueryId == queryId);
|
||||
|
||||
public QueriesController(DataManagementContext dataManagementContext, IQueryService queryService)
|
||||
{
|
||||
_dataManagementContext = dataManagementContext;
|
||||
_queryService = queryService;
|
||||
}
|
||||
|
||||
[HttpGet]
|
||||
[ProducesResponseType(StatusCodes.Status200OK)]
|
||||
public async Task<IEnumerable<Query>> GetAll(CancellationToken cancellationToken)
|
||||
{
|
||||
var queries = await _dataManagementContext.Queries.ToListAsync(cancellationToken);
|
||||
|
||||
return queries;
|
||||
}
|
||||
|
||||
[HttpGet("{queryId}")]
|
||||
[ProducesResponseType(StatusCodes.Status200OK)]
|
||||
[ProducesResponseType(StatusCodes.Status404NotFound)]
|
||||
[ProducesDefaultResponseType]
|
||||
public async Task<ActionResult<Query>> GetById(int queryId, CancellationToken cancellationToken)
|
||||
{
|
||||
var query = await _dataManagementContext.Queries.SingleOrDefaultAsync(p => p.QueryId == queryId, cancellationToken);
|
||||
|
||||
if (query == null)
|
||||
{
|
||||
return NotFound();
|
||||
}
|
||||
|
||||
return query;
|
||||
}
|
||||
|
||||
[HttpGet("{queryId}/[action]")]
|
||||
[ProducesResponseType(StatusCodes.Status200OK)]
|
||||
[ProducesResponseType(StatusCodes.Status404NotFound)]
|
||||
[ProducesDefaultResponseType]
|
||||
public async Task<ActionResult<Query>> Copy(int queryId, CancellationToken cancellationToken)
|
||||
{
|
||||
return await _queryService.Copy(queryId, cancellationToken);
|
||||
}
|
||||
|
||||
[HttpPost]
|
||||
[ProducesResponseType(StatusCodes.Status200OK)]
|
||||
[ProducesDefaultResponseType]
|
||||
public async Task<ActionResult<Query>> Create([FromBody] Query query, CancellationToken cancellationToken)
|
||||
{
|
||||
return await _queryService.Create(query, cancellationToken);
|
||||
}
|
||||
|
||||
[HttpPut("{queryId}")]
|
||||
[ProducesResponseType(StatusCodes.Status204NoContent)]
|
||||
[ProducesResponseType(StatusCodes.Status400BadRequest)]
|
||||
[ProducesResponseType(StatusCodes.Status404NotFound)]
|
||||
[ProducesDefaultResponseType]
|
||||
public async Task<IActionResult> Update(int queryId, Query queryDto, CancellationToken cancellationToken)
|
||||
{
|
||||
if (queryId != queryDto.QueryId) { return BadRequest(); }
|
||||
|
||||
var updated = await _queryService.Update(queryDto, cancellationToken);
|
||||
if (!updated) { return NotFound(); }
|
||||
|
||||
return NoContent();
|
||||
}
|
||||
|
||||
[HttpGet("{queryId}/[action]")]
|
||||
public async Task<bool> SaveToGithub(int queryId, CancellationToken cancellationToken)
|
||||
{
|
||||
if (queryId < 0) { return false; }
|
||||
var user = User?.Identity?.Name ?? "";
|
||||
return await _queryService.SaveToGithub(queryId, user, cancellationToken);
|
||||
}
|
||||
|
||||
[HttpDelete("{queryId}")]
|
||||
[ProducesResponseType(StatusCodes.Status200OK)]
|
||||
[ProducesResponseType(StatusCodes.Status204NoContent)]
|
||||
[ProducesResponseType(StatusCodes.Status404NotFound)]
|
||||
[ProducesDefaultResponseType]
|
||||
public async Task<IActionResult> Delete(int queryId, CancellationToken token)
|
||||
{
|
||||
var query = await _dataManagementContext.Queries.SingleOrDefaultAsync(p => p.QueryId == queryId, token);
|
||||
|
||||
if (query == null)
|
||||
{
|
||||
return NotFound();
|
||||
}
|
||||
|
||||
_dataManagementContext.Remove(query);
|
||||
|
||||
await _dataManagementContext.SaveChangesAsync(token);
|
||||
|
||||
return NoContent();
|
||||
}
|
||||
|
||||
[HttpGet("{queryId}/[action]")]
|
||||
[ProducesResponseType(StatusCodes.Status200OK)]
|
||||
[ProducesResponseType(StatusCodes.Status404NotFound)]
|
||||
[ProducesDefaultResponseType]
|
||||
public async Task<IActionResult> History(int queryId, CancellationToken cancellationToken)
|
||||
=> Ok(await _queryService.History(queryId, User?.Identity?.Name ?? ""));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Strata.Stratasphere.Biz.RunnableClients;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Strata.Stratasphere.Api.Controllers
|
||||
{
|
||||
[ApiController]
|
||||
[ApiVersion("1.0")]
|
||||
[Route("api/v{api-version:apiVersion}/[controller]")]
|
||||
public class RunnableClientsController : ControllerBase
|
||||
{
|
||||
private readonly IRunnableClientsService _runnableClientsService;
|
||||
|
||||
public RunnableClientsController(
|
||||
IRunnableClientsService runnableClientsService)
|
||||
{
|
||||
_runnableClientsService = runnableClientsService;
|
||||
}
|
||||
|
||||
|
||||
[HttpGet("{processId}")]
|
||||
[ProducesResponseType(StatusCodes.Status200OK)]
|
||||
[ProducesResponseType(StatusCodes.Status404NotFound)]
|
||||
[ProducesDefaultResponseType]
|
||||
public async Task<ActionResult<IEnumerable<RunnableClientDto>>> GetRunnableClientsAsync(int processId, CancellationToken cancellationToken)
|
||||
{
|
||||
var result = await _runnableClientsService.GetRunnableClientsAsync(processId, cancellationToken);
|
||||
return Ok(result);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Strata.Stratasphere.Biz.DataManagement;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Strata.Stratasphere.Api.Controllers
|
||||
{
|
||||
[ApiController]
|
||||
[ApiVersion("1.0")]
|
||||
[Route("api/v{api-version:apiVersion}/[controller]")]
|
||||
public class SchemasController : ControllerBase
|
||||
{
|
||||
private readonly DataManagementContext _dataManagementContext;
|
||||
|
||||
public SchemasController(DataManagementContext dataManagementContext)
|
||||
{
|
||||
_dataManagementContext = dataManagementContext;
|
||||
}
|
||||
|
||||
[ProducesResponseType(StatusCodes.Status200OK)]
|
||||
[HttpGet]
|
||||
public async Task<IEnumerable<string>> GetAll(CancellationToken cancellationToken)
|
||||
{
|
||||
return await _dataManagementContext.Processes.Select(x => x.TargetSchema).Distinct().OrderBy(x => x).ToListAsync(cancellationToken);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Strata.SqlTools.EntityFramework.Pagination;
|
||||
using Strata.Stratasphere.Biz.Mappings.SourceSystem;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Strata.Stratasphere.Api.Controllers
|
||||
{
|
||||
[ApiController]
|
||||
[ApiVersion("1.0")]
|
||||
[Route("api/v{api-version:apiVersion}/[controller]")]
|
||||
public class SourceSystemMappingDetailsController : ControllerBase
|
||||
{
|
||||
private readonly ISourceSystemMappingDetailService _sourceSystemDetailService;
|
||||
|
||||
public SourceSystemMappingDetailsController(ISourceSystemMappingDetailService sourceSysemMappingDetailService)
|
||||
{
|
||||
_sourceSystemDetailService = sourceSysemMappingDetailService;
|
||||
}
|
||||
|
||||
[HttpPost()]
|
||||
public async Task<PagedData<SourceSystemMappingDetail>> GetAll(SourceSystemMappingDetailLoadOptions loadOptions, CancellationToken cancellationToken)
|
||||
{
|
||||
return await _sourceSystemDetailService.GetSourceSystemMappingDetailsAsync(loadOptions.PagingOptions, loadOptions.FilterOptions, cancellationToken);
|
||||
}
|
||||
|
||||
[HttpPost("[action]")]
|
||||
[ProducesResponseType(StatusCodes.Status202Accepted)]
|
||||
public async Task<IActionResult> Export(SourceSystemMappingDetailExportOptions exportOptions, CancellationToken cancellationToken)
|
||||
{
|
||||
await _sourceSystemDetailService.ExportAsync(exportOptions.ExportAll, exportOptions.FilterOptions, User?.Identity?.Name ?? "", cancellationToken);
|
||||
return new AcceptedResult();
|
||||
}
|
||||
|
||||
[HttpPost("[action]")]
|
||||
public async Task<bool> Import(IFormFile file, CancellationToken cancellationToken)
|
||||
{
|
||||
return await _sourceSystemDetailService.ImportAsync(file, User?.Identity?.Name ?? "", cancellationToken);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class SourceSystemMappingDetailLoadOptions
|
||||
{
|
||||
public PagingOptions PagingOptions { get; set; }
|
||||
public SourceSystemMappingFilters FilterOptions { get; set; }
|
||||
}
|
||||
|
||||
public class SourceSystemMappingDetailExportOptions
|
||||
{
|
||||
public bool ExportAll { get; set; }
|
||||
public SourceSystemMappingFilters FilterOptions { get; set; }
|
||||
}
|
||||
@@ -0,0 +1,149 @@
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Strata.Stratasphere.Api.Dtos;
|
||||
using Strata.Id.Client;
|
||||
using Strata.ApiCommunication.Http.Exceptions;
|
||||
using Strata.FeatureFlags.Client;
|
||||
using System;
|
||||
using Hangfire;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Strata.SMC.Client;
|
||||
using Strata.Stratasphere.Biz.Standards;
|
||||
using System.Threading;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace Strata.Stratasphere.Api.Controllers
|
||||
{
|
||||
/// <summary>
|
||||
/// The controller method for launching any jobs for standards to support data science activities
|
||||
/// </summary>
|
||||
[ApiController]
|
||||
[ApiVersion("1.0")]
|
||||
[Route("api/v{api-version:apiVersion}/[controller]")]
|
||||
public class StandardsController : ControllerBase
|
||||
{
|
||||
private readonly ILogger<StandardsController> _logger;
|
||||
private readonly IBackgroundJobClient _backgroundJobClient;
|
||||
private readonly ISMCServiceClient _smcServiceClient;
|
||||
/// <summary>
|
||||
/// C-tor
|
||||
/// </summary>
|
||||
/// <param name="logger">logger object</param>
|
||||
/// <param name="backgroundJobClient">Hangfire job client to enqueue work</param>
|
||||
/// <param name="smcServiceClient">SMC to look up client information</param>
|
||||
public StandardsController(ILogger<StandardsController> logger, IBackgroundJobClient backgroundJobClient, ISMCServiceClient smcServiceClient)
|
||||
{
|
||||
_logger = logger;
|
||||
_backgroundJobClient = backgroundJobClient;
|
||||
_smcServiceClient = smcServiceClient;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Refreshes patient type calculation for all encounters in the target database. The patient types defined by the data science team based on UB Revenue code
|
||||
/// </summary>
|
||||
/// <param name="databaseGuid">the client to process for</param>
|
||||
/// <returns></returns>
|
||||
[HttpPost("patienttypes/{databaseGuid}/")]
|
||||
[ProducesResponseType(StatusCodes.Status202Accepted)]
|
||||
[ProducesResponseType(StatusCodes.Status404NotFound)]
|
||||
public async Task<ActionResult> PatientTypeFullRefresh(Guid databaseGuid)
|
||||
{
|
||||
var dbInfo = await _smcServiceClient.GetDatabaseAsync(databaseGuid);
|
||||
if (dbInfo == null)
|
||||
{
|
||||
return new NotFoundResult();
|
||||
}
|
||||
_backgroundJobClient.Enqueue<PatientTypeJob>(j => j.ProcessPatientTypesForAllEncounters(databaseGuid, dbInfo.DatabaseName, null, CancellationToken.None));
|
||||
return new AcceptedResult();
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Refreshes encounter standards calculations in the client database for all encounters
|
||||
/// </summary>
|
||||
/// <param name="databaseGuid">the client to process encounter standards</param>
|
||||
/// <returns></returns>
|
||||
[HttpPost("encounterstandards/{databaseGuid}/")]
|
||||
[ProducesResponseType(StatusCodes.Status202Accepted)]
|
||||
[ProducesResponseType(StatusCodes.Status404NotFound)]
|
||||
public async Task<ActionResult> EncounterStandardsFullRefresh(Guid databaseGuid)
|
||||
{
|
||||
var dbInfo = await _smcServiceClient.GetDatabaseAsync(databaseGuid);
|
||||
if (dbInfo == null)
|
||||
{
|
||||
return new NotFoundResult();
|
||||
}
|
||||
|
||||
_backgroundJobClient.Enqueue<EncounterStandardsJob>(j => j.ProcessEncounterStandardsForAllEncounters(databaseGuid, dbInfo.DatabaseName, null, CancellationToken.None));
|
||||
return new AcceptedResult();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Refreshes readmission calculations in the client database for all encounters. Calculating the CMS rules for 30 day readmission
|
||||
/// </summary>
|
||||
/// <param name="databaseGuid">the client to process for</param>
|
||||
/// <returns></returns>
|
||||
[HttpPost("readmission/{databaseGuid}/")]
|
||||
[ProducesResponseType(StatusCodes.Status202Accepted)]
|
||||
[ProducesResponseType(StatusCodes.Status404NotFound)]
|
||||
public async Task<ActionResult> ReadmissionFullRefresh(Guid databaseGuid)
|
||||
{
|
||||
var dbInfo = await _smcServiceClient.GetDatabaseAsync(databaseGuid);
|
||||
if (dbInfo == null)
|
||||
{
|
||||
return new NotFoundResult();
|
||||
}
|
||||
|
||||
_backgroundJobClient.Enqueue<ReadmissionJob>(j => j.ProcessReadmissionsForAllEncounters(databaseGuid, dbInfo.DatabaseName, null, CancellationToken.None));
|
||||
return new AcceptedResult();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Refreshes the Hospital Acquired condition calculation for all encounters in a client. The HAC calc is defined by CMS
|
||||
/// </summary>
|
||||
/// <param name="databaseGuid"></param>
|
||||
/// <returns></returns>
|
||||
[HttpPost("hacs/{databaseGuid}/")]
|
||||
[ProducesResponseType(StatusCodes.Status202Accepted)]
|
||||
[ProducesResponseType(StatusCodes.Status404NotFound)]
|
||||
public async Task<ActionResult> HACsFullRefresh(Guid databaseGuid)
|
||||
{
|
||||
var dbInfo = await _smcServiceClient.GetDatabaseAsync(databaseGuid);
|
||||
if (dbInfo == null)
|
||||
{
|
||||
return new NotFoundResult();
|
||||
}
|
||||
|
||||
_backgroundJobClient.Enqueue<HACsJob>(j => j.ProcessHACsForAllEncounters(databaseGuid, dbInfo.DatabaseName, null));
|
||||
return new AcceptedResult();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Refreshes one of the 14 HAC calculations for all encounters in a client. The HAC calculation is defined by CMS
|
||||
/// </summary>
|
||||
/// <param name="databaseGuid">the client to process for</param>
|
||||
/// <param name="hacName">The name of the HAC in the format HACXX (i.e. 01,14)</param>
|
||||
/// <returns></returns>
|
||||
[HttpPost("hacs/{databaseGuid}/{hacName}")]
|
||||
[ProducesResponseType(StatusCodes.Status202Accepted)]
|
||||
[ProducesResponseType(StatusCodes.Status404NotFound)]
|
||||
public async Task<ActionResult> HACsFullRefresh(Guid databaseGuid, string hacName)
|
||||
{
|
||||
var dbInfo = await _smcServiceClient.GetDatabaseAsync(databaseGuid);
|
||||
if (dbInfo == null)
|
||||
{
|
||||
return new NotFoundResult();
|
||||
}
|
||||
|
||||
if (!Regex.IsMatch(hacName, @"HAC[\d][\d]\b", RegexOptions.IgnoreCase))
|
||||
{
|
||||
return new NotFoundResult();
|
||||
}
|
||||
_backgroundJobClient.Enqueue<HACsJob>(j => j.ProcessSingleHACForAllEncounters(databaseGuid, hacName.ToUpper(), null, CancellationToken.None));
|
||||
return new AcceptedResult();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,272 @@
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.JsonPatch;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Strata.Stratasphere.Biz.ClientTags;
|
||||
using Strata.Stratasphere.Biz.DataManagement;
|
||||
using Strata.Stratasphere.Biz.DataManagement.Models;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Strata.Stratasphere.Api.Controllers
|
||||
{
|
||||
[ApiController]
|
||||
[ApiVersion("1.0")]
|
||||
[Route("api/v{api-version:apiVersion}/[controller]")]
|
||||
public class TagsController : ControllerBase
|
||||
{
|
||||
private readonly DataManagementContext _dataManagementContext;
|
||||
private readonly IClientTagsService _clientTagsService;
|
||||
|
||||
private bool TagExists(int tagId) => _dataManagementContext.Tags.Any(e => e.TagId == tagId);
|
||||
|
||||
public TagsController(DataManagementContext dataManagementContext,
|
||||
IClientTagsService tagsService)
|
||||
{
|
||||
_dataManagementContext = dataManagementContext;
|
||||
_clientTagsService = tagsService;
|
||||
}
|
||||
|
||||
[ProducesResponseType(StatusCodes.Status200OK)]
|
||||
[HttpGet]
|
||||
public async Task<IEnumerable<Tag>> GetAll(CancellationToken cancellationToken)
|
||||
{
|
||||
var tag = await _dataManagementContext.Tags.Include(x => x.ClientTags)
|
||||
.ToListAsync(cancellationToken);
|
||||
|
||||
return tag;
|
||||
}
|
||||
|
||||
[HttpPost]
|
||||
[ProducesResponseType(StatusCodes.Status200OK)]
|
||||
[ProducesDefaultResponseType]
|
||||
public async Task<ActionResult<Tag>> Create([FromBody] Tag tag, CancellationToken cancellationToken)
|
||||
{
|
||||
//https://docs.microsoft.com/en-us/aspnet/core/tutorials/first-web-api?view=aspnetcore-3.1&tabs=visual-studio
|
||||
await _dataManagementContext.Tags.AddAsync(tag, cancellationToken);
|
||||
|
||||
await _dataManagementContext.SaveChangesAsync(cancellationToken);
|
||||
|
||||
return tag;
|
||||
}
|
||||
|
||||
[HttpGet("{tagId}")]
|
||||
[ProducesResponseType(StatusCodes.Status200OK)]
|
||||
[ProducesResponseType(StatusCodes.Status404NotFound)]
|
||||
[ProducesDefaultResponseType]
|
||||
public async Task<ActionResult<Tag>> GetById(int tagId, CancellationToken cancellationToken)
|
||||
{
|
||||
var tag = await _dataManagementContext.Tags.Include(x => x.ClientTags)
|
||||
.SingleOrDefaultAsync(x => x.TagId == tagId, cancellationToken);
|
||||
|
||||
if (tag == null)
|
||||
{
|
||||
return NotFound();
|
||||
}
|
||||
|
||||
return tag;
|
||||
}
|
||||
|
||||
[HttpGet("{tagId}/[action]")]
|
||||
[ProducesResponseType(StatusCodes.Status200OK)]
|
||||
[ProducesResponseType(StatusCodes.Status404NotFound)]
|
||||
[ProducesDefaultResponseType]
|
||||
public async Task<ActionResult<Tag>> Copy(int tagId, CancellationToken cancellationToken)
|
||||
{
|
||||
var tag = await _dataManagementContext.Tags.AsNoTracking()
|
||||
.Include(x => x.ClientTags)
|
||||
.SingleOrDefaultAsync(x => x.TagId == tagId, cancellationToken);
|
||||
|
||||
if (tag == null)
|
||||
{
|
||||
return NotFound();
|
||||
}
|
||||
|
||||
tag.TagName = $"{tag.TagName} Copy";
|
||||
tag.TagId = 0;
|
||||
foreach (var clientTag in tag.ClientTags)
|
||||
{
|
||||
clientTag.ClientTagId = 0;
|
||||
}
|
||||
|
||||
_dataManagementContext.Add(tag);
|
||||
|
||||
await _dataManagementContext.SaveChangesAsync(cancellationToken);
|
||||
|
||||
return tag;
|
||||
}
|
||||
|
||||
[HttpPatch("{tagId}")]
|
||||
[ProducesResponseType(StatusCodes.Status204NoContent)]
|
||||
[ProducesResponseType(StatusCodes.Status400BadRequest)]
|
||||
[ProducesResponseType(StatusCodes.Status404NotFound)]
|
||||
[ProducesDefaultResponseType]
|
||||
public async Task<IActionResult> Patch(int tagId, [FromBody] JsonPatchDocument<Tag> patchDoc,
|
||||
CancellationToken cancellationToken)
|
||||
{
|
||||
if (patchDoc == null)
|
||||
{
|
||||
return BadRequest();
|
||||
}
|
||||
|
||||
var tag = await _dataManagementContext.Tags.SingleOrDefaultAsync(p => p.TagId == tagId, cancellationToken);
|
||||
|
||||
if (tag == null)
|
||||
{
|
||||
return NotFound();
|
||||
}
|
||||
|
||||
patchDoc.ApplyTo(tag);
|
||||
|
||||
await _dataManagementContext.SaveChangesAsync(cancellationToken);
|
||||
|
||||
return new ObjectResult(tag);
|
||||
}
|
||||
|
||||
[HttpPut("{tagId}")]
|
||||
[ProducesResponseType(StatusCodes.Status204NoContent)]
|
||||
[ProducesResponseType(StatusCodes.Status400BadRequest)]
|
||||
[ProducesResponseType(StatusCodes.Status404NotFound)]
|
||||
[ProducesDefaultResponseType]
|
||||
public async Task<IActionResult> Update(int tagId, Tag tagDto, CancellationToken cancellationToken)
|
||||
{
|
||||
if (tagId != tagDto.TagId)
|
||||
{
|
||||
return BadRequest();
|
||||
}
|
||||
|
||||
var tag = await _dataManagementContext.Tags.Include(t => t.ClientTags)
|
||||
.SingleOrDefaultAsync(p => p.TagId == tagId, cancellationToken);
|
||||
if (tag == null)
|
||||
{
|
||||
return NotFound();
|
||||
}
|
||||
|
||||
tag.TagName = tagDto.TagName;
|
||||
if (tagDto.ClientTags != null)
|
||||
{
|
||||
foreach (var existingTag in tag.ClientTags)
|
||||
{
|
||||
var matching = tagDto.ClientTags.FirstOrDefault(x => x.StrataId == existingTag.StrataId && x.TagId == existingTag.TagId);
|
||||
if (matching == null)
|
||||
{
|
||||
_dataManagementContext.ClientTags.Remove(existingTag);
|
||||
}
|
||||
}
|
||||
foreach (var clientTag in tagDto.ClientTags)
|
||||
{
|
||||
var matching = tag.ClientTags.FirstOrDefault(x => x.StrataId == clientTag.StrataId && x.TagId == clientTag.TagId);
|
||||
if (matching == null)
|
||||
{
|
||||
_dataManagementContext.ClientTags.Add(clientTag);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
await _dataManagementContext.SaveChangesAsync(cancellationToken);
|
||||
}
|
||||
catch (DbUpdateConcurrencyException) when (!TagExists(tagId))
|
||||
{
|
||||
return NotFound();
|
||||
}
|
||||
|
||||
return NoContent();
|
||||
}
|
||||
|
||||
[HttpDelete("{tagId}")]
|
||||
[ProducesResponseType(StatusCodes.Status200OK)]
|
||||
[ProducesDefaultResponseType]
|
||||
[ProducesResponseType(StatusCodes.Status204NoContent)]
|
||||
public async Task<IActionResult> Delete(int tagId, CancellationToken cancellationToken)
|
||||
{
|
||||
var tag = await _dataManagementContext.Tags.SingleOrDefaultAsync(p => p.TagId == tagId, cancellationToken);
|
||||
|
||||
if (tag == null)
|
||||
{
|
||||
return NotFound();
|
||||
}
|
||||
|
||||
_dataManagementContext.Tags.Remove(tag);
|
||||
|
||||
await _dataManagementContext.SaveChangesAsync(cancellationToken);
|
||||
|
||||
return NoContent();
|
||||
}
|
||||
|
||||
[HttpPost("{tagName}/[action]/{databaseGuid}")]
|
||||
[ProducesResponseType(StatusCodes.Status200OK)]
|
||||
[ProducesDefaultResponseType]
|
||||
[ProducesResponseType(StatusCodes.Status204NoContent)]
|
||||
[ProducesResponseType(StatusCodes.Status409Conflict)]
|
||||
public async Task<IActionResult> AddByDatabase(string tagName, Guid databaseGuid, CancellationToken cancellationToken)
|
||||
{
|
||||
var clientTagId = await _clientTagsService.AddClientTag(tagName, databaseGuid, cancellationToken);
|
||||
if (clientTagId == 0) { return NotFound(); }
|
||||
else if (clientTagId > 0) { return NoContent(); }
|
||||
else { return Conflict(); }
|
||||
}
|
||||
|
||||
[HttpPost("{tagName}/[action]/{strataId}")]
|
||||
[ProducesResponseType(StatusCodes.Status200OK)]
|
||||
[ProducesDefaultResponseType]
|
||||
[ProducesResponseType(StatusCodes.Status204NoContent)]
|
||||
[ProducesResponseType(StatusCodes.Status409Conflict)]
|
||||
public async Task<IActionResult> AddByStrataId(string tagName, int strataId, CancellationToken cancellationToken)
|
||||
{
|
||||
var clientTagId = await _clientTagsService.AddClientTag(tagName, strataId, cancellationToken);
|
||||
if (clientTagId == 0) { return NotFound(); }
|
||||
else if (clientTagId > 0) { return NoContent(); }
|
||||
else { return Conflict(); }
|
||||
}
|
||||
|
||||
[HttpDelete("{tagName}/[action]/{databaseGuid}")]
|
||||
[ProducesResponseType(StatusCodes.Status200OK)]
|
||||
[ProducesDefaultResponseType]
|
||||
[ProducesResponseType(StatusCodes.Status204NoContent)]
|
||||
public async Task<IActionResult> DeleteByDatabase(string tagName, Guid databaseGuid, CancellationToken cancellationToken)
|
||||
{
|
||||
if (await _clientTagsService.RemoveTag(tagName, databaseGuid, cancellationToken))
|
||||
{ return NoContent(); }
|
||||
return NotFound();
|
||||
}
|
||||
|
||||
[HttpPost("{tagName}/[action]/{strataId}")]
|
||||
[ProducesResponseType(StatusCodes.Status200OK)]
|
||||
[ProducesDefaultResponseType]
|
||||
[ProducesResponseType(StatusCodes.Status204NoContent)]
|
||||
public async Task<IActionResult> DeleteByStrataId(string tagName, int strataId, CancellationToken cancellationToken)
|
||||
{
|
||||
if (await _clientTagsService.RemoveTag(tagName, strataId, cancellationToken))
|
||||
{ return NoContent(); }
|
||||
return NotFound();
|
||||
}
|
||||
|
||||
[HttpDelete("[action]/{databaseGuid}")]
|
||||
[ProducesResponseType(StatusCodes.Status200OK)]
|
||||
[ProducesDefaultResponseType]
|
||||
[ProducesResponseType(StatusCodes.Status204NoContent)]
|
||||
public async Task<IActionResult> DeleteByDatabase(Guid databaseGuid, CancellationToken cancellationToken)
|
||||
{
|
||||
if (await _clientTagsService.RemoveClientTags(databaseGuid, cancellationToken))
|
||||
{ return NoContent(); }
|
||||
return NotFound();
|
||||
}
|
||||
|
||||
[HttpPost("[action]/{strataId}")]
|
||||
[ProducesResponseType(StatusCodes.Status200OK)]
|
||||
[ProducesDefaultResponseType]
|
||||
[ProducesResponseType(StatusCodes.Status204NoContent)]
|
||||
public async Task<IActionResult> DeleteByStrataId(int strataId, CancellationToken cancellationToken)
|
||||
{
|
||||
if (await _clientTagsService.RemoveClientTags(strataId, cancellationToken))
|
||||
{ return NoContent(); }
|
||||
return NotFound();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,72 @@
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Strata.CoreLib.Claims.Extensions;
|
||||
using Strata.Stratasphere.Biz.DataManagement;
|
||||
using Strata.Stratasphere.Biz.DataManagement.Models;
|
||||
using Strata.Stratasphere.Biz.Users;
|
||||
using System;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Strata.Stratasphere.Api.Controllers
|
||||
{
|
||||
[ApiController]
|
||||
[ApiVersion("1.0")]
|
||||
[Route("api/v{api-version:apiVersion}/[controller]")]
|
||||
public class UsersController : ControllerBase
|
||||
{
|
||||
private readonly DataManagementContext _dataManagementContext;
|
||||
private readonly IUserService _userService;
|
||||
|
||||
public UsersController(DataManagementContext dataManagementContext, IUserService userService)
|
||||
{
|
||||
_dataManagementContext = dataManagementContext;
|
||||
_userService = userService;
|
||||
}
|
||||
|
||||
[ProducesResponseType(StatusCodes.Status200OK)]
|
||||
[HttpPost("")]
|
||||
public async Task EnsureUserExists(CancellationToken cancellationToken)
|
||||
{
|
||||
var userName = User?.Identity?.Name ?? "";
|
||||
if (userName == "") return;
|
||||
var userEmail = User?.GetEmail();
|
||||
if (userEmail == null) return;
|
||||
|
||||
var existingUser = await _dataManagementContext.Users.SingleOrDefaultAsync(u => u.UserName == userName);
|
||||
if (existingUser == null)
|
||||
{
|
||||
var user = new User()
|
||||
{
|
||||
UserName = userName,
|
||||
Email = userEmail,
|
||||
GithubToken = "",
|
||||
PreviousGithubToken = ""
|
||||
};
|
||||
await _dataManagementContext.Users.AddAsync(user);
|
||||
}
|
||||
|
||||
else if (string.IsNullOrEmpty(existingUser.Email) || !userEmail.Equals(existingUser.Email, StringComparison.CurrentCultureIgnoreCase))
|
||||
{
|
||||
existingUser.Email = userEmail;
|
||||
_dataManagementContext.Users.Update(existingUser);
|
||||
}
|
||||
|
||||
await _dataManagementContext.SaveChangesAsync();
|
||||
}
|
||||
|
||||
[HttpGet("[action]")]
|
||||
public async Task<string> GetUserName(CancellationToken cancellationToken)
|
||||
=> User?.Identity?.Name;
|
||||
|
||||
[HttpPost("[action]")]
|
||||
[ProducesResponseType(StatusCodes.Status202Accepted)]
|
||||
[ProducesResponseType(StatusCodes.Status400BadRequest)]
|
||||
public async Task<IActionResult> SetGithubToken([FromBody] string githubToken, CancellationToken cancellationToken)
|
||||
{
|
||||
await _userService.SaveUserGithubToken(User?.Identity?.Name, githubToken, cancellationToken);
|
||||
return new AcceptedResult();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
using Strata.Stratasphere.Biz.DataManagement.Models;
|
||||
using Strata.Stratasphere.Biz.Parser;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Strata.Stratasphere.Api.DTOs
|
||||
{
|
||||
public class GraphDto
|
||||
{
|
||||
public GraphDto(IEnumerable<DirectedAcyclicGraph<Query>.Edge> edges, IDictionary<Query, int> generationalLookup)
|
||||
{
|
||||
Edges = edges;
|
||||
GenerationalLookup = generationalLookup.GroupBy(x => x.Value).ToDictionary(x => x.Key, x => x.Select(x => x.Key.QueryId));
|
||||
MaxGeneration = GenerationalLookup.Any() ? GenerationalLookup.Max(x => x.Key) : 0;
|
||||
}
|
||||
|
||||
public IEnumerable<DirectedAcyclicGraph<Query>.Edge> Edges { get; }
|
||||
public IDictionary<int, IEnumerable<int>> GenerationalLookup { get; }
|
||||
public int MaxGeneration { get; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
using Strata.Stratasphere.Biz.DataManagement.Models;
|
||||
|
||||
namespace Strata.Stratasphere.Api.Dtos
|
||||
{
|
||||
public class ParameterDto : Parameter
|
||||
{
|
||||
public bool IsDeleted { get; set; }
|
||||
|
||||
public bool IsNew { get; set; }
|
||||
}
|
||||
}
|
||||
+57518
File diff suppressed because it is too large
Load Diff
+47762
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,14 @@
|
||||
using AutoMapper;
|
||||
using Strata.SMC.Client;
|
||||
using Strata.Stratasphere.Biz.Database;
|
||||
|
||||
namespace Strata.Stratasphere.Api
|
||||
{
|
||||
public class MappingProfile : Profile
|
||||
{
|
||||
public MappingProfile()
|
||||
{
|
||||
CreateMap<StrataSensitiveDatabaseDto, Database>();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,94 @@
|
||||
using Microsoft.AspNetCore;
|
||||
using Microsoft.AspNetCore.Hosting;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.Extensions.CommandLineUtils;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Hosting;
|
||||
using Serilog;
|
||||
using Strata.Configuration.Client.DependencyInjection;
|
||||
using Strata.Logging.DependencyInjection;
|
||||
using Strata.Stratasphere.Biz.DataManagement;
|
||||
using Strata.Stratasphere.Biz.Snowflake;
|
||||
using System;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
|
||||
namespace Strata.Stratasphere.Api
|
||||
{
|
||||
[ExcludeFromCodeCoverage]
|
||||
public class Program
|
||||
{
|
||||
public static void Main(string[] args)
|
||||
{
|
||||
try
|
||||
{
|
||||
var commandLineApplication = new CommandLineApplication(false);
|
||||
var doMigrate = commandLineApplication.Option(
|
||||
"--ef-migrate",
|
||||
"Apply entity framework migrations and exit",
|
||||
CommandOptionType.NoValue);
|
||||
|
||||
commandLineApplication.HelpOption("-? | -h | --help");
|
||||
commandLineApplication.OnExecute(() =>
|
||||
{
|
||||
ExecuteApp(args, doMigrate);
|
||||
return 0;
|
||||
});
|
||||
commandLineApplication.Execute(args);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Log.Error(ex, "There was an unhandled exception that caused the program to crash");
|
||||
|
||||
//This is for serilog to ensure that all of the cached logs are flushed when the app crashes
|
||||
//This is useful so we can capture logs when the application crashes during startup:
|
||||
Log.CloseAndFlush();
|
||||
Environment.Exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
public static void ExecuteApp(string[] args, CommandOption doMigrate)
|
||||
{
|
||||
var webHost = CreateWebHostBuilder(args).Build();
|
||||
|
||||
if (doMigrate.HasValue())
|
||||
{
|
||||
Log.Debug("Applying Entity Framework migrations");
|
||||
using var scope = webHost.Services.CreateScope();
|
||||
using var context = scope.ServiceProvider.GetService<DataManagementContext>();
|
||||
var snowflakeContext = scope.ServiceProvider.GetService<ISnowflakeMigrationContext>();
|
||||
var hostEnv = scope.ServiceProvider.GetService<IHostEnvironment>();
|
||||
try
|
||||
{
|
||||
context.Database.SetCommandTimeout(TimeSpan.FromMinutes(10));
|
||||
context.Database.Migrate();
|
||||
try
|
||||
{
|
||||
snowflakeContext.Migrate().GetAwaiter().GetResult();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Log.Error(e, "Unable to apply Snowflake migrations for environment {env}", hostEnv.EnvironmentName);
|
||||
}
|
||||
Log.Debug("All done, closing app");
|
||||
Log.CloseAndFlush();
|
||||
Environment.Exit(Environment.ExitCode);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Log.Error(ex, "There was an unhandled exception that caused the program to crash");
|
||||
Log.CloseAndFlush();
|
||||
Environment.Exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
// no flags provided, so just run the webhost
|
||||
webHost.Run();
|
||||
}
|
||||
|
||||
public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
|
||||
WebHost.CreateDefaultBuilder(args)
|
||||
.UseStrataConfiguration()
|
||||
.UseStrataLogging()
|
||||
.UseStartup<Startup>();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
{
|
||||
"profiles": {
|
||||
"IIS Express": {
|
||||
"commandName": "IISExpress",
|
||||
//"commandLineArgs": "--ef-migrate",
|
||||
"launchBrowser": true,
|
||||
"environmentVariables": {
|
||||
"Hangfire__RunLocally": "true",
|
||||
"AWS_Profile": "sdt-data-wrangler-Service-Role",
|
||||
"ASPNETCORE_ENVIRONMENT": "Development"
|
||||
}
|
||||
},
|
||||
"Strata.Stratasphere": {
|
||||
"commandName": "Project",
|
||||
"launchBrowser": true,
|
||||
"environmentVariables": {
|
||||
"Hangfire__RunLocally": "true",
|
||||
"AWS_S3_US_EAST_1_REGIONAL_ENDPOINT": "regional",
|
||||
"AWS_Profile": "sdt-data-wrangler-Service-Role",
|
||||
"ASPNETCORE_ENVIRONMENT": "Development"
|
||||
},
|
||||
"applicationUrl": "http://localhost:44302;https://localhost:44303"
|
||||
}
|
||||
},
|
||||
"iisSettings": {
|
||||
"windowsAuthentication": false,
|
||||
"anonymousAuthentication": true,
|
||||
"iisExpress": {
|
||||
"applicationUrl": "http://localhost:44302",
|
||||
"sslPort": 0
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,125 @@
|
||||
using FluentValidation.AspNetCore;
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
using Microsoft.AspNetCore.Hosting;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.AspNetCore.Mvc.ApiExplorer;
|
||||
using Microsoft.AspNetCore.Mvc.ApplicationModels;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Hosting;
|
||||
using Prometheus;
|
||||
using Strata.ApiLib.Core.Cors.Extensions;
|
||||
using Strata.ApiLib.Core.ExceptionHandling.DependencyInjection.Bootstrappers;
|
||||
using Strata.ApiLib.Core.StrataAuthentication.Bootstrappers;
|
||||
using Strata.ApiLib.Core.Transformers;
|
||||
using Strata.Identity.Client.Constants;
|
||||
using Strata.Stratasphere.Biz.Configuration;
|
||||
using Strata.Stratasphere.Biz.Configuration.SignalR;
|
||||
using Strata.Stratasphere.Biz.Hubs;
|
||||
using Strata.SwaggerExtensions;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Text.Json;
|
||||
|
||||
namespace Strata.Stratasphere.Api
|
||||
{
|
||||
[ExcludeFromCodeCoverage]
|
||||
public class Startup
|
||||
{
|
||||
public Startup(IConfiguration configuration)
|
||||
{
|
||||
Configuration = configuration;
|
||||
}
|
||||
|
||||
public IConfiguration Configuration { get; }
|
||||
|
||||
// This method gets called by the runtime. Use this method to add services to the container.
|
||||
// For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=398940
|
||||
public void ConfigureServices(IServiceCollection services)
|
||||
{
|
||||
|
||||
services.AddGlobalExceptionMiddleware(Configuration);
|
||||
services.AddControllers(options =>
|
||||
{
|
||||
//Prevent browsers from caching API responses (this addresses an IE11 issue):
|
||||
options.Filters.Add(
|
||||
new ResponseCacheAttribute
|
||||
{
|
||||
Location = ResponseCacheLocation.None,
|
||||
NoStore = false,
|
||||
Duration = -1
|
||||
});
|
||||
options.Conventions.Add(new RouteTokenTransformerConvention(new SlugifyParameterTransformer()));
|
||||
})
|
||||
.AddFluentValidation(fv => fv.RegisterValidatorsFromAssemblyContaining<Startup>())
|
||||
.AddJsonOptions(options =>
|
||||
{
|
||||
options.JsonSerializerOptions.PropertyNameCaseInsensitive = true;
|
||||
options.JsonSerializerOptions.PropertyNamingPolicy = JsonNamingPolicy.CamelCase;
|
||||
}).AddMvcOptions(options =>
|
||||
{
|
||||
options.ReturnHttpNotAcceptable = true;
|
||||
options.Filters.Add(new ProducesAttribute("application/json"));
|
||||
options.Filters.Add(new ConsumesAttribute("application/json"));
|
||||
});
|
||||
|
||||
services.AddCors(options =>
|
||||
{
|
||||
options.AddPolicy("CorsPolicy",
|
||||
builder =>
|
||||
{
|
||||
builder
|
||||
.WithOrigins("http://localhost:3000", "http://localhost:3001")
|
||||
.AllowAnyMethod()
|
||||
.AllowAnyHeader();
|
||||
});
|
||||
});
|
||||
|
||||
services.AddAutoMapper(typeof(Startup).Assembly);
|
||||
services.AddSwagger(Configuration);
|
||||
services.AddStrataAuthentication(Configuration);
|
||||
services.AddHealthChecks();
|
||||
services.AddStrataHangfire();
|
||||
services.AddStratasphere(Configuration);
|
||||
services.AddStrataSignalR();
|
||||
services.AddStrataCors(Configuration);
|
||||
|
||||
services.AddHttpContextAccessor();
|
||||
services.AddAuthorization(options =>
|
||||
{
|
||||
options.AddPolicy("StrataSphereDataManagementOnly", policy => policy.RequireRole(StrataRoles.StrataSphereDataManagement));
|
||||
});
|
||||
services.AddFluentEmail("noreply@notifications.stratanetwork.com");
|
||||
}
|
||||
|
||||
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
|
||||
public void Configure(IApplicationBuilder app, IWebHostEnvironment env, IApiVersionDescriptionProvider provider)
|
||||
{
|
||||
app.UseGlobalExceptionMiddleware();
|
||||
app.UseRouting();
|
||||
app.UseStrataAuthentication();
|
||||
app.UseStrataCorsPolicy(env);
|
||||
|
||||
if (env.IsDevelopment())
|
||||
{
|
||||
app.UseCors("CorsPolicy");
|
||||
app.UseEndpoints(endpoints => endpoints.MapControllers().RequireAuthorization());
|
||||
}
|
||||
else
|
||||
{
|
||||
app.UseHsts();
|
||||
app.UseHttpsRedirection();
|
||||
app.UseEndpoints(endpoints => endpoints.MapControllers().RequireAuthorization("StrataSphereDataManagementOnly"));
|
||||
}
|
||||
app.UseStaticFiles();
|
||||
|
||||
app.UseMetricServer();
|
||||
app.UseHttpMetrics();
|
||||
|
||||
app.ConfigureSwagger(env, provider);
|
||||
|
||||
app.UseHealthChecks("/health");
|
||||
app.UseEndpoints(endpoints => endpoints.MapHub<HangfireHub>(HangfireHub.HubURL));
|
||||
app.UseEndpoints(endpoints => endpoints.MapNotificationHub());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,67 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk.Web">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net6.0</TargetFramework>
|
||||
<AspNetCoreHostingModel>InProcess</AspNetCoreHostingModel>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup>
|
||||
<GenerateDocumentationFile>true</GenerateDocumentationFile>
|
||||
<IncludeOpenAPIAnalyzers>true</IncludeOpenAPIAnalyzers>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
|
||||
<TreatWarningsAsErrors>false</TreatWarningsAsErrors>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Compile Remove="DTOs\DatabaseDTO.cs" />
|
||||
<Compile Remove="XlsxContentResult.cs" />
|
||||
</ItemGroup>
|
||||
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="AutoMapper" Version="12.0.0" />
|
||||
<PackageReference Include="AutoMapper.Extensions.Microsoft.DependencyInjection" Version="12.0.0" />
|
||||
<PackageReference Include="AWSSDK.SecurityToken" Version="3.7.100.21" />
|
||||
<PackageReference Include="FluentEmail.Mailgun" Version="3.0.2" />
|
||||
<PackageReference Include="FluentValidation.AspNetCore" Version="11.2.2" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.JsonPatch" Version="6.0.10" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Mvc.Versioning.ApiExplorer" Version="5.0.0" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="6.0.11">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="6.0.10">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Microsoft.Extensions.CommandLineUtils" Version="1.1.1" />
|
||||
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="6.0.1" />
|
||||
<PackageReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Design" Version="6.0.10" />
|
||||
<PackageReference Include="Strata.ApiLib.Core" Version="5.2.0" />
|
||||
<PackageReference Include="Strata.Hangfire.AspNetCore" Version="3.0.0" />
|
||||
<PackageReference Include="Strata.Identity.Client" Version="2.80.0" />
|
||||
<PackageReference Include="Strata.Logging" Version="3.5.1" />
|
||||
<PackageReference Include="Strata.SignalR" Version="0.3.0" />
|
||||
<PackageReference Include="Strata.SwaggerExtensions" Version="2.3.0" />
|
||||
<PackageReference Include="Swashbuckle.AspNetCore" Version="6.4.0" />
|
||||
<PackageReference Include="prometheus-net" Version="7.0.0" />
|
||||
<PackageReference Include="prometheus-net.AspNetCore" Version="7.0.0" />
|
||||
<PackageReference Include="Swashbuckle.AspNetCore.Annotations" Version="6.4.0" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\Strata.Stratasphere.Biz\Strata.Stratasphere.Biz.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<None Update="DataMigrations\Standards_Readmission_PlannedExclusions.csv">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Update="DataMigrations\Standards_Readmission_ReadmissionExclusions.csv">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</None>
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
@@ -0,0 +1,14 @@
|
||||
using FluentValidation;
|
||||
using Strata.Stratasphere.Biz.DataManagement.Models;
|
||||
|
||||
namespace Strata.Stratasphere.Api.Validators
|
||||
{
|
||||
public class ProcessValidator : AbstractValidator<Process>
|
||||
{
|
||||
public ProcessValidator()
|
||||
{
|
||||
RuleFor(x => x.Name).NotEmpty().WithMessage("Please specify a name");
|
||||
RuleFor(x => x.Description).NotEmpty().WithMessage("Please specify a description");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
{
|
||||
"Logging": {
|
||||
"LogLevel": {
|
||||
"Default": "Debug",
|
||||
"System": "Information",
|
||||
"Microsoft": "Information"
|
||||
}
|
||||
},
|
||||
|
||||
"Snowflake": {
|
||||
"Url": "https://stratadev.us-east-1.privatelink.snowflakecomputing.com",
|
||||
"Account": "stratadev",
|
||||
"StandardsWarehouseSize": "XSMALL",
|
||||
"StandardsWarehouseMaxClusterSize": "1",
|
||||
"StandardsWarehouse": "STANDARDS_WH",
|
||||
"AdminRoleName": "DEVADMIN",
|
||||
"SphCoreRoleName": "SPHCORE"
|
||||
},
|
||||
|
||||
"s3": {
|
||||
"bucketName": "sdt-dev-data-wrangler"
|
||||
},
|
||||
|
||||
"configuration": {
|
||||
"basicAuthUsername": "BkQsRDdmdjkFNhKVuTI.TpujQJXuKhGDcV.F_hjADMRTaEUWMJnviaesoOrhhfnz",
|
||||
"basicAuthPassword": "GWPIIWECDqh.hjDNdpxVEfeFe-bYFwPSx-oBGFD_od_SUQVk-QqTIkZY_NXMeqeo"
|
||||
},
|
||||
|
||||
"StrataConfigServerBaseUrl": "https://configuration.dev.stratanetwork.net"
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
{
|
||||
"Logging": {
|
||||
"LogLevel": {
|
||||
"Default": "Debug",
|
||||
"System": "Information",
|
||||
"Microsoft": "Information"
|
||||
}
|
||||
},
|
||||
|
||||
"Snowflake": {
|
||||
"Url": "https://pda64574.us-east-1.privatelink.snowflakecomputing.com",
|
||||
"Account": "pda64574", //QA
|
||||
"StandardsWarehouseSize": "XSMALL",
|
||||
"StandardsWarehouseMaxClusterSize": "1",
|
||||
"StandardsWarehouse": "STANDARDS_WH",
|
||||
"AdminRoleName": "QAADMIN",
|
||||
"SphCoreRoleName": "SPHCORE"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
{
|
||||
"Logging": {
|
||||
"LogLevel": {
|
||||
"Default": "Warning"
|
||||
}
|
||||
},
|
||||
|
||||
"AllowedHosts": "*",
|
||||
|
||||
"Version": "0.0.0",
|
||||
|
||||
"Snowflake": {
|
||||
"Url": "https://strata.us-east-1.privatelink.snowflakecomputing.com",
|
||||
"Account": "strata",
|
||||
"RoleName": "DATAADMIN",
|
||||
"Warehouse": "DATA_ANALYSIS_WH",
|
||||
"StandardsWarehouseSize": "XSMALL",
|
||||
"StandardsWarehouseMaxClusterSize": "1",
|
||||
"StandardsWarehouse": "STANDARDS_WH",
|
||||
"SphCoreRoleName": "SPHCORE"
|
||||
},
|
||||
|
||||
"aws": {
|
||||
"masterEncounterListSQSQueueName": "sdt-masterencounterlist-queue",
|
||||
"snowflakeAdminSecretName": "stratareplication/snowflake/automation/connectionstring"
|
||||
},
|
||||
|
||||
"github": {
|
||||
"Repositories": [
|
||||
{
|
||||
"Path": "DataWrangler",
|
||||
"RepositoryId": 603055704,
|
||||
"RepositoryName": "data-wrangler",
|
||||
"AutoMerge": true,
|
||||
"Reviewers": [],
|
||||
"Assignees": []
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
namespace Strata.Stratasphere.Biz.Administration.Clients
|
||||
{
|
||||
public class ClientMappingSummary
|
||||
{
|
||||
public string Mapping { get; set; }
|
||||
public int StrataId { get; set; }
|
||||
public int WithoutRollup { get; set; }
|
||||
public int WithRollup { get; set; }
|
||||
public double RollupPct => 1d * WithRollup / TotalRollup;
|
||||
public int NotReviewed { get; set; }
|
||||
public int IsReviewed { get; set; }
|
||||
public double ReviewedPct => 1d * IsReviewed / TotalRollup;
|
||||
public int TotalRollup { get; set; }
|
||||
public int Duplicates { get; set; }
|
||||
public int Waiting { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
using ClosedXML.Excel;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Strata.Stratasphere.Biz.AwsS3
|
||||
{
|
||||
public interface IS3BucketService
|
||||
{
|
||||
Task<IEnumerable<string>> GetAll(CancellationToken cancellationToken);
|
||||
Task<Stream> DownloadFileAsync(string filename, CancellationToken cancellationToken);
|
||||
Task UploadFileAsync(MemoryStream memoryStream, string fileName, string groupName, CancellationToken cancellationToken);
|
||||
Task UploadFileAsync(IXLWorkbook workbook, string fileName, string groupName, CancellationToken cancellationToken);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,162 @@
|
||||
using Amazon.S3;
|
||||
using Amazon.S3.Model;
|
||||
using Amazon.S3.Transfer;
|
||||
using ClosedXML.Excel;
|
||||
using Microsoft.AspNetCore.SignalR;
|
||||
using Strata.Stratasphere.Biz.Configuration;
|
||||
using Strata.Stratasphere.Biz.Notification;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Strata.Stratasphere.Biz.AwsS3
|
||||
{
|
||||
public class S3BucketService : IS3BucketService
|
||||
{
|
||||
private readonly ITransferUtility _transferUtility;
|
||||
private readonly IAmazonS3 _amazonS3Client;
|
||||
private readonly IHubContext<NotificationHub, INotificationHub> _notificationHubContext;
|
||||
private readonly IStrataS3TransferConfiguration _s3TransferConfiguration;
|
||||
private readonly Regex _nameParser;
|
||||
|
||||
public S3BucketService(ITransferUtility transferUtility, IAmazonS3 amazonS3Client,
|
||||
IHubContext<NotificationHub, INotificationHub> notificationHubContext,
|
||||
IStrataS3TransferConfiguration s3TransferConfiguration)
|
||||
{
|
||||
_transferUtility = transferUtility;
|
||||
_amazonS3Client = amazonS3Client;
|
||||
_notificationHubContext = notificationHubContext;
|
||||
_s3TransferConfiguration = s3TransferConfiguration;
|
||||
// Example file names (AWS key) is in the format:
|
||||
// Account_Mapping_Export_All_{username}_2022_09_12_13_45_32_3333.xlsx, OR
|
||||
// Account_Mapping_Export_Not_Reviewed_{username}_2022_09_12_13_45_32_3333.xlsx
|
||||
// This regex gets two parts from this:
|
||||
// 1. Account_Mapping_Export
|
||||
// 2. All or Nor_Reviewed
|
||||
_nameParser = new Regex(@"(.*)\s+(All|Filtered List)\s+[^\d]*\s+[\d ]*(\..*)", RegexOptions.Compiled);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get the list of object keys from the S3 bucket
|
||||
/// </summary>
|
||||
/// <param name="cancellationToken"></param>
|
||||
/// <returns></returns>
|
||||
public async Task<IEnumerable<string>> GetAll(CancellationToken cancellationToken)
|
||||
{
|
||||
var objects = await _amazonS3Client.ListObjectsAsync(_s3TransferConfiguration.BucketName, cancellationToken).ConfigureAwait(false);
|
||||
return objects.S3Objects.Select(o => Path.GetFileName(o.Key));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get the response stream for a file download from S3 by key
|
||||
/// </summary>
|
||||
/// <param name="filename">The key (name) of the file to be downloaded from the bucket</param>
|
||||
/// <param name="cancellationToken"></param>
|
||||
/// <returns></returns>
|
||||
public async Task<Stream> DownloadFileAsync(string filename, CancellationToken cancellationToken)
|
||||
{
|
||||
var request = new GetObjectRequest
|
||||
{
|
||||
BucketName = _s3TransferConfiguration.BucketName,
|
||||
Key = filename
|
||||
};
|
||||
GetObjectResponse response = await _amazonS3Client.GetObjectAsync(request, cancellationToken);
|
||||
return response.ResponseStream;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Upload a file to the S3 bucket as a memoryStream
|
||||
/// </summary>
|
||||
/// <param name="memoryStream"></param>
|
||||
/// <param name="fileName"></param>
|
||||
/// <param name="cancellationToken"></param>
|
||||
/// <returns></returns>
|
||||
public async Task UploadFileAsync(MemoryStream memoryStream, string fileName, string groupName, CancellationToken cancellationToken)
|
||||
{
|
||||
var exportName = _nameParser.Replace(fileName.Replace("_", " "), "$1 $2");
|
||||
var fileType = _nameParser.Replace(fileName.Replace("_", " "), "$3");
|
||||
var hub = _notificationHubContext.Clients.Group(exportName);
|
||||
await hub.SendExportBuildingNotification(exportName, fileType, 100);
|
||||
|
||||
var fileTransferUtilityRequest = new TransferUtilityUploadRequest
|
||||
{
|
||||
BucketName = _s3TransferConfiguration.BucketName,
|
||||
StorageClass = S3StorageClass.Standard,
|
||||
InputStream = memoryStream,
|
||||
Key = fileName,
|
||||
ServerSideEncryptionMethod = ServerSideEncryptionMethod.AWSKMS
|
||||
};
|
||||
fileTransferUtilityRequest.Metadata.Add(nameof(groupName), groupName);
|
||||
fileTransferUtilityRequest.UploadProgressEvent += OnUploadProgressEvent;
|
||||
try
|
||||
{
|
||||
await _transferUtility.UploadAsync(fileTransferUtilityRequest, cancellationToken);
|
||||
}
|
||||
catch (System.Exception ex)
|
||||
{
|
||||
//
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Update an excel workbook to the S3 bucket to the filename (key)
|
||||
/// </summary>
|
||||
/// <param name="workbook"></param>
|
||||
/// <param name="fileName"></param>
|
||||
/// <param name="cancellationToken"></param>
|
||||
/// <returns></returns>
|
||||
public async Task UploadFileAsync(IXLWorkbook workbook, string fileName, string groupName, CancellationToken cancellationToken)
|
||||
{
|
||||
using var memoryStream = new MemoryStream();
|
||||
workbook.SaveAs(memoryStream);
|
||||
await UploadFileAsync(memoryStream, fileName, groupName, cancellationToken);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Provide a SignalR notification on the progress of the upload to the S3 bucket
|
||||
/// </summary>
|
||||
/// <param name="sender"></param>
|
||||
/// <param name="args"></param>
|
||||
public void OnUploadProgressEvent(object sender, UploadProgressArgs args)
|
||||
{
|
||||
var currentobject = sender as TransferUtilityUploadRequest;
|
||||
var groupName = currentobject.Metadata["groupName"];
|
||||
// Calculate a reporting reference for percentage
|
||||
var modBy = (args.TotalBytes / 10000000) switch
|
||||
{
|
||||
<= 3 => 50, // if less or equal to 30,000,000 then notify user every 50%, else
|
||||
<= 5 => 30, // if less or equal to 50,000,000 then notify user every 30%, else
|
||||
<= 7 => 25, // if less or equal to 70,000,000 then notify user every 25%, else
|
||||
<= 10 => 20, // if less or equal to 100,000,000 then notify user every 20%, else
|
||||
<= 20 => 15, // if less or equal to 200,000,000 then notify user every 15%, else
|
||||
<= 30 => 10, // if less or equal to 300,000,000 then notify user every 10%, else
|
||||
<= 40 => 7, // if less or equal to 400,000,000 then notify user every 7%, else
|
||||
<= 50 => 5, // if less or equal to 500,000,000 then notify user every 5%, else
|
||||
<= 60 => 3, // if less or equal to 600,000,000 then notify user every 3%, else
|
||||
_ => 1 // notify user every 1% of the upload
|
||||
};
|
||||
|
||||
// Get the notification group name from the file name (key)
|
||||
// Use Regex to parse the filename for the group name
|
||||
var exportName = _nameParser.Replace(currentobject.Key.Replace("_", " "), "$1 $2");
|
||||
var fileType = _nameParser.Replace(currentobject.Key.Replace("_", " "), "$3");
|
||||
var hub = _notificationHubContext.Clients.Group(groupName);
|
||||
if (args.PercentDone == 0)
|
||||
{
|
||||
hub.SendExportContinuesNotification(exportName, fileType, args.PercentDone);
|
||||
}
|
||||
else if (args.PercentDone != 100)
|
||||
{
|
||||
if (args.PercentDone % modBy != 0) { return; }
|
||||
hub.SendExportContinuesNotification(exportName, fileType, args.PercentDone);
|
||||
}
|
||||
else
|
||||
{
|
||||
hub.SendExportReadyNotification(exportName, fileType, currentobject.Key);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,79 @@
|
||||
using Microsoft.AspNetCore.JsonPatch;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Octokit;
|
||||
using Strata.Stratasphere.Biz.DataManagement;
|
||||
using Strata.Stratasphere.Biz.DataManagement.Models;
|
||||
using Strata.Stratasphere.Biz.Github;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Strata.Stratasphere.Biz.ClientQueries
|
||||
{
|
||||
public class ClientQueryService : IClientQueryService
|
||||
{
|
||||
private readonly DataManagementContext _dataManagementContext;
|
||||
private readonly IDataWranglerHistoryService _historyService;
|
||||
private readonly ISaveToGitHubService _saveToGitHubJob;
|
||||
|
||||
public ClientQueryService(DataManagementContext dataManagementContext,
|
||||
IDataWranglerHistoryService historyService,
|
||||
ISaveToGitHubService saveToGitHubJob)
|
||||
{
|
||||
_dataManagementContext = dataManagementContext;
|
||||
_historyService = historyService;
|
||||
_saveToGitHubJob = saveToGitHubJob;
|
||||
}
|
||||
|
||||
public async Task<ClientQuery> Create(ClientQuery clientQuery, string user, CancellationToken cancellationToken)
|
||||
{
|
||||
await _dataManagementContext.ClientQueries.AddAsync(clientQuery, cancellationToken);
|
||||
await _dataManagementContext.SaveChangesAsync(cancellationToken);
|
||||
return clientQuery;
|
||||
}
|
||||
|
||||
public async Task<bool> SaveToGithub(int clientQueryId, string user, CancellationToken cancellationToken)
|
||||
{
|
||||
await _saveToGitHubJob.SaveClientQueryToGithub(clientQueryId, user);
|
||||
return true;
|
||||
}
|
||||
|
||||
public async Task<bool> Update(ClientQuery clientQuery, string user, CancellationToken cancellationToken)
|
||||
{
|
||||
var ClientQueryEntity = await _dataManagementContext.ClientQueries
|
||||
.SingleOrDefaultAsync(p => p.ClientQueryId == clientQuery.ClientQueryId, cancellationToken);
|
||||
if (ClientQueryEntity == null) { return false; }
|
||||
|
||||
ClientQueryEntity.StrataId = clientQuery.StrataId;
|
||||
ClientQueryEntity.QueryText = clientQuery.QueryText;
|
||||
ClientQueryEntity.Description = clientQuery.Description;
|
||||
|
||||
try
|
||||
{
|
||||
await _dataManagementContext.SaveChangesAsync(cancellationToken);
|
||||
}
|
||||
catch (DbUpdateConcurrencyException)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public async Task<IEnumerable<GitHubCommit>> History(int clientQueryId, string user)
|
||||
=> await _historyService.ClientQueryHistory(clientQueryId, user);
|
||||
|
||||
public async Task<ClientQuery> Patch(int clientQueryId, [FromBody] JsonPatchDocument<ClientQuery> patchDoc, string user,
|
||||
CancellationToken cancellationToken)
|
||||
{
|
||||
var clientQuery = await _dataManagementContext.ClientQueries.SingleOrDefaultAsync(p => p.ClientQueryId == clientQueryId, cancellationToken);
|
||||
|
||||
if (clientQuery == null) { return null; }
|
||||
|
||||
patchDoc.ApplyTo(clientQuery);
|
||||
|
||||
await _dataManagementContext.SaveChangesAsync(cancellationToken);
|
||||
return clientQuery;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
using Microsoft.AspNetCore.JsonPatch;
|
||||
using Octokit;
|
||||
using Strata.Stratasphere.Biz.DataManagement.Models;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Strata.Stratasphere.Biz.ClientQueries
|
||||
{
|
||||
public interface IClientQueryService
|
||||
{
|
||||
Task<ClientQuery> Create(ClientQuery clientQuery, string user, CancellationToken cancellationToken);
|
||||
Task<bool> SaveToGithub(int clientQueryId, string user, CancellationToken cancellationToken);
|
||||
Task<bool> Update(ClientQuery clientQuery, string user, CancellationToken cancellationToken);
|
||||
Task<ClientQuery> Patch(int clientQueryId, JsonPatchDocument<ClientQuery> patchDoc, string user, CancellationToken cancellationToken);
|
||||
Task<IEnumerable<GitHubCommit>> History(int clientQueryId, string user);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,111 @@
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Strata.Stratasphere.Biz.Database;
|
||||
using Strata.Stratasphere.Biz.DataManagement;
|
||||
using Strata.Stratasphere.Biz.DataManagement.Models;
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Strata.Stratasphere.Biz.ClientTags
|
||||
{
|
||||
public class ClientTagsService : IClientTagsService
|
||||
{
|
||||
private readonly DataManagementContext _dataManagementContext;
|
||||
private readonly IDatabaseService _databaseService;
|
||||
|
||||
public ClientTagsService(
|
||||
DataManagementContext dataManagementContext,
|
||||
IDatabaseService databaseService)
|
||||
{
|
||||
_dataManagementContext = dataManagementContext;
|
||||
_databaseService = databaseService;
|
||||
}
|
||||
|
||||
public async Task<int> AddClientTag(string tagName, Guid databaseGuid, CancellationToken cancellationToken)
|
||||
{
|
||||
var db = await _databaseService.GetDatabaseByDatabaseGuid(databaseGuid, cancellationToken);
|
||||
if (db == null) { return 0; }
|
||||
|
||||
var tag = await _dataManagementContext.Tags.SingleOrDefaultAsync(p => p.TagName == tagName, cancellationToken);
|
||||
if (tag == null) { return 0; }
|
||||
return await AddClientTag(tag, db, cancellationToken);
|
||||
}
|
||||
|
||||
public async Task<int> AddClientTag(string tagName, int strataId, CancellationToken cancellationToken)
|
||||
{
|
||||
var db = await _databaseService.GetDatabaseByStrataId(strataId, cancellationToken);
|
||||
if (db == null) { return 0; }
|
||||
|
||||
var tag = await _dataManagementContext.Tags.SingleOrDefaultAsync(p => p.TagName == tagName, cancellationToken);
|
||||
if (tag == null) { return 0; }
|
||||
return await AddClientTag(tag, db, cancellationToken);
|
||||
}
|
||||
|
||||
private async Task<int> AddClientTag(Tag tag, Database.Database db, CancellationToken cancellationToken)
|
||||
{
|
||||
var clientTag = await _dataManagementContext.ClientTags
|
||||
.SingleOrDefaultAsync(p => p.TagId == tag.TagId && p.StrataId == db.StrataId, cancellationToken);
|
||||
|
||||
if (clientTag != null) { return -1; }
|
||||
|
||||
clientTag = _dataManagementContext.ClientTags.Add(new ClientTag { StrataId = db.StrataId, TagId = tag.TagId }).Entity;
|
||||
|
||||
await _dataManagementContext.SaveChangesAsync(cancellationToken);
|
||||
|
||||
return clientTag.ClientTagId;
|
||||
}
|
||||
|
||||
public async Task<bool> RemoveTag(string tagName, Guid databaseGuid, CancellationToken cancellationToken)
|
||||
{
|
||||
var db = await _databaseService.GetDatabaseByDatabaseGuid(databaseGuid, cancellationToken);
|
||||
if (db == null) { return false; }
|
||||
|
||||
var tag = await _dataManagementContext.Tags.SingleOrDefaultAsync(p => p.TagName == tagName, cancellationToken);
|
||||
if (tag == null) { return false; }
|
||||
return await RemoveTag(tag, db, cancellationToken);
|
||||
}
|
||||
|
||||
public async Task<bool> RemoveTag(string tagName, int strataId, CancellationToken cancellationToken)
|
||||
{
|
||||
var db = await _databaseService.GetDatabaseByStrataId(strataId, cancellationToken);
|
||||
if (db == null) { return false; }
|
||||
|
||||
var tag = await _dataManagementContext.Tags.SingleOrDefaultAsync(p => p.TagName == tagName, cancellationToken);
|
||||
if (tag == null) { return false; }
|
||||
return await RemoveTag(tag, db, cancellationToken);
|
||||
}
|
||||
|
||||
private async Task<bool> RemoveTag(Tag tag, Database.Database db, CancellationToken cancellationToken)
|
||||
{
|
||||
var clientTags = await _dataManagementContext.ClientTags
|
||||
.Where(ct => ct.TagId == tag.TagId && ct.StrataId == db.StrataId).ToListAsync();
|
||||
_dataManagementContext.ClientTags.RemoveRange(clientTags);
|
||||
await _dataManagementContext.SaveChangesAsync(cancellationToken);
|
||||
return true;
|
||||
}
|
||||
|
||||
public async Task<bool> RemoveClientTags(Guid databaseGuid, CancellationToken cancellationToken)
|
||||
{
|
||||
var db = await _databaseService.GetDatabaseByDatabaseGuid(databaseGuid, cancellationToken);
|
||||
if (db == null) { return false; }
|
||||
return await RemoveClientTags(db, cancellationToken);
|
||||
}
|
||||
|
||||
public async Task<bool> RemoveClientTags(int strataId, CancellationToken cancellationToken)
|
||||
{
|
||||
var db = await _databaseService.GetDatabaseByStrataId(strataId, cancellationToken);
|
||||
if (db == null) { return false; }
|
||||
return await RemoveClientTags(db, cancellationToken);
|
||||
}
|
||||
|
||||
private async Task<bool> RemoveClientTags(Database.Database db, CancellationToken cancellationToken)
|
||||
{
|
||||
var clientTags = await _dataManagementContext.ClientTags.Where(p => p.StrataId == db.StrataId).ToListAsync();
|
||||
if (!clientTags.Any()) { return false; }
|
||||
_dataManagementContext.ClientTags.RemoveRange(clientTags);
|
||||
await _dataManagementContext.SaveChangesAsync(cancellationToken);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
using System;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Strata.Stratasphere.Biz.ClientTags
|
||||
{
|
||||
public interface IClientTagsService
|
||||
{
|
||||
Task<int> AddClientTag(string tagName, Guid databaseGuid, CancellationToken cancellationToken);
|
||||
Task<int> AddClientTag(string tagName, int strataId, CancellationToken cancellationToken);
|
||||
Task<bool> RemoveTag(string tagName, Guid databaseGuid, CancellationToken cancellationToken);
|
||||
Task<bool> RemoveTag(string tagName, int strataId, CancellationToken cancellationToken);
|
||||
Task<bool> RemoveClientTags(Guid databaseGuid, CancellationToken cancellationToken);
|
||||
Task<bool> RemoveClientTags(int strataId, CancellationToken cancellationToken);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Strata.Stratasphere.Biz.Configuration
|
||||
{
|
||||
public class AWSOptions
|
||||
{
|
||||
[Required(ErrorMessage = "Missing the Sqs Queue Name for listening for new encounters")]
|
||||
public string MasterEncounterListSQSQueueName { get; set; }
|
||||
[Required(ErrorMessage = "Missing the Snowflake Admin Secret name")]
|
||||
public string SnowflakeAdminSecretName { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
namespace Strata.Stratasphere.Biz.Configuration
|
||||
{
|
||||
internal static class Constants
|
||||
{
|
||||
internal static readonly string ApplicationName = "stratasphere";
|
||||
|
||||
/// <summary>
|
||||
/// The name of the Stratasphere Sandbox database
|
||||
/// </summary>
|
||||
internal const string SandboxDatabaseName = "DATALAKE_SANDBOX";
|
||||
|
||||
/// <summary>
|
||||
/// The name of the Stratasphere Staging database
|
||||
/// </summary>
|
||||
internal const string StagingDatabaseName = "DATALAKE_STAGING";
|
||||
|
||||
/// <summary>
|
||||
/// The name of the Stratasphere Production database
|
||||
/// </summary>
|
||||
internal const string ProductionDatabaseName = "DATALAKE_PROD";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,60 @@
|
||||
using Hangfire.Common;
|
||||
using Hangfire.Server;
|
||||
using Strata.CoreLib.Claims;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using System.Security.Claims;
|
||||
using System.Threading;
|
||||
|
||||
namespace Strata.Stratasphere.Biz.Configuration.Hangfire
|
||||
{
|
||||
/// <summary>
|
||||
/// Captures Job parameters as Claims on the ThreadPrincipal running the job
|
||||
/// </summary>
|
||||
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Interface | AttributeTargets.Method)]
|
||||
public class CaptureJobParameterAttribute : JobFilterAttribute, IServerFilter
|
||||
{
|
||||
public int DatabaseGuidArgumentPosition { get; set; } = -1;
|
||||
public int StrataIdArgumentPosition { get; set; } = -1;
|
||||
|
||||
// server filters
|
||||
public void OnPerforming(PerformingContext filterContext)
|
||||
{
|
||||
var claims = new List<Claim>();
|
||||
var args = filterContext.BackgroundJob.Job.Args.ToArray();
|
||||
|
||||
if (StrataIdArgumentPosition >= 0)
|
||||
{
|
||||
var strataIdValue = string.Format(CultureInfo.CurrentCulture, $"{{{StrataIdArgumentPosition}}}", args);
|
||||
if (int.TryParse(strataIdValue, out var strataId))
|
||||
{
|
||||
claims.Add(new Claim(StrataClaims.StrataId, strataId.ToString()));
|
||||
}
|
||||
}
|
||||
|
||||
if (DatabaseGuidArgumentPosition >= 0)
|
||||
{
|
||||
var databaseGuidValue = string.Format(CultureInfo.CurrentCulture, $"{{{DatabaseGuidArgumentPosition}}}", args);
|
||||
if (Guid.TryParse(databaseGuidValue, out var databaseGuid))
|
||||
{
|
||||
claims.Add(new Claim(StrataClaims.DatabaseGuid, databaseGuid.ToString()));
|
||||
}
|
||||
}
|
||||
|
||||
if (claims.Count == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var principal = new ClaimsPrincipal(new ClaimsIdentity(claims, "hangfire_impersonation"));
|
||||
Thread.CurrentPrincipal = principal;
|
||||
}
|
||||
|
||||
public void OnPerformed(PerformedContext filterContext)
|
||||
{
|
||||
Thread.CurrentPrincipal = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
using Hangfire.Common;
|
||||
using Hangfire.States;
|
||||
|
||||
namespace Strata.Stratasphere.Biz.Configuration.Hangfire
|
||||
{
|
||||
public class DeleteOnSuccessAttribute : JobFilterAttribute, IElectStateFilter
|
||||
{
|
||||
public void OnStateElection(ElectStateContext context)
|
||||
{
|
||||
if (context.CandidateState.Name == SucceededState.StateName)
|
||||
{
|
||||
context.CandidateState = new DeletedState { Reason = "This job is deleted on success." };
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
using Microsoft.AspNetCore.Routing;
|
||||
using Strata.Stratasphere.Biz.Notification;
|
||||
|
||||
namespace Strata.Stratasphere.Biz.Configuration
|
||||
{
|
||||
public static class HubEndpointRouteBuilderExtensions
|
||||
{
|
||||
public static HubEndpointConventionBuilder MapNotificationHub(this IEndpointRouteBuilder endpoints)
|
||||
{
|
||||
return endpoints.MapHub<NotificationHub>("/api/NotificationHub", configureOptions: null);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
namespace Strata.Stratasphere.Biz.Configuration
|
||||
{
|
||||
/// <summary>
|
||||
/// This provides the setting in the json file for the S3 bucket name
|
||||
/// </summary>
|
||||
public interface IStrataS3TransferConfiguration
|
||||
{
|
||||
public string BucketName { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
using System;
|
||||
using Microsoft.AspNetCore.SignalR;
|
||||
using Microsoft.AspNetCore.SignalR.StackExchangeRedis;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Microsoft.Extensions.Options;
|
||||
using StackExchange.Redis;
|
||||
using Strata.ElastiCache.Redis;
|
||||
using Strata.Hangfire.Configuration;
|
||||
|
||||
namespace Strata.Stratasphere.Biz.Configuration.SignalR
|
||||
{
|
||||
internal class HangfireRedisHubLifetimeManager<THub> : RedisHubLifetimeManager<THub> where THub : Hub
|
||||
{
|
||||
public HangfireRedisHubLifetimeManager(ILogger<RedisHubLifetimeManager<THub>> logger, IAwsRedisConfigurationOptionsFactory awsRedisConfigurationOptionsFactory, IOptions<HangfireOptions> hangfireOptions, IHubProtocolResolver hubProtocolResolver)
|
||||
: base(logger,
|
||||
new OptionsWrapper<RedisOptions>(new RedisOptions { Configuration = GetConfigOptions(awsRedisConfigurationOptionsFactory, hangfireOptions) }),
|
||||
hubProtocolResolver)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public HangfireRedisHubLifetimeManager(ILogger<RedisHubLifetimeManager<THub>> logger, IAwsRedisConfigurationOptionsFactory awsRedisConfigurationOptionsFactory, IOptions<HangfireOptions> hangfireOptions, IHubProtocolResolver hubProtocolResolver, IOptions<HubOptions> globalHubOptions, IOptions<HubOptions<THub>> hubOptions)
|
||||
: base(logger,
|
||||
new OptionsWrapper<RedisOptions>(new RedisOptions { Configuration = GetConfigOptions(awsRedisConfigurationOptionsFactory, hangfireOptions) }),
|
||||
hubProtocolResolver , globalHubOptions, hubOptions)
|
||||
{
|
||||
}
|
||||
|
||||
private static ConfigurationOptions GetConfigOptions(IAwsRedisConfigurationOptionsFactory awsRedisConfigurationOptionsFactory, IOptions<HangfireOptions> hangfireOptions)
|
||||
{
|
||||
var configOptions = awsRedisConfigurationOptionsFactory
|
||||
.GetRedisConfigurationOptionsAsync("sdt-redis-hangfire-shared",
|
||||
AwsRedisConfigurationOptionsFactory.GetSecretIdByDefaultFormat("common",
|
||||
"sdt-redis-hangfire-shared")).GetAwaiter().GetResult();
|
||||
|
||||
// first set the redis prefix based on environment and if running locally
|
||||
var prefix = $"{Environment.MachineName}_{hangfireOptions.Value.Schema}";
|
||||
|
||||
if (hangfireOptions.Value.RunLocally)
|
||||
{
|
||||
prefix = $"{prefix}_{Environment.MachineName.ToLowerInvariant()}";
|
||||
}
|
||||
|
||||
configOptions.ChannelPrefix = $"{{{prefix}}}-signalr:";
|
||||
|
||||
return configOptions;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
|
||||
namespace Strata.Stratasphere.Biz.Configuration.SignalR
|
||||
{
|
||||
public static class ServiceCollectionExtensions
|
||||
{
|
||||
public static IServiceCollection AddStrataSignalR(this IServiceCollection services)
|
||||
{
|
||||
services.AddSignalR().AddStrataRedis();
|
||||
|
||||
return services;
|
||||
}
|
||||
}
|
||||
}
|
||||
+20
@@ -0,0 +1,20 @@
|
||||
using Microsoft.AspNetCore.SignalR;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
|
||||
namespace Strata.Stratasphere.Biz.Configuration.SignalR
|
||||
{
|
||||
public static class SignalROptionsServiceCollectionExtensions
|
||||
{
|
||||
/// <summary>
|
||||
/// Adds scale-out to a <see cref="ISignalRServerBuilder"/>, using a shared Redis server.
|
||||
/// </summary>
|
||||
/// <param name="signalrBuilder">The <see cref="ISignalRServerBuilder"/>.</param>
|
||||
/// <returns>The same instance of the <see cref="ISignalRServerBuilder"/> for chaining.</returns>
|
||||
public static ISignalRServerBuilder AddStrataRedis(this ISignalRServerBuilder signalrBuilder)
|
||||
{
|
||||
signalrBuilder.Services.AddSingleton(typeof(HubLifetimeManager<>), typeof(HangfireRedisHubLifetimeManager<>));
|
||||
|
||||
return signalrBuilder;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
using System;
|
||||
|
||||
namespace Strata.Stratasphere.Biz.Configuration
|
||||
{
|
||||
public class SnowflakeEnvironmentOptions : SnowflakeLib.Configuration.SnowflakeOptions
|
||||
{
|
||||
public string StandardsWarehouse { get; set; }
|
||||
public string StandardsWarehouseSize { get; set; }
|
||||
public string StandardsWarehouseMaxClusterSize { get; set; }
|
||||
public string Warehouse { get; set; }
|
||||
|
||||
public string RoleName { get; set; }
|
||||
public string AdminRoleName { get; set; }
|
||||
public string SphCoreRoleName { get; set; }
|
||||
|
||||
public string GetClientDatabaseName(string environmentName, Guid clientDbGuid) => $"{environmentName.Substring(0, 1)}_{clientDbGuid:N}".ToUpper();
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,250 @@
|
||||
using Amazon.S3;
|
||||
using Amazon.S3.Transfer;
|
||||
using Amazon.SQS;
|
||||
using Hangfire;
|
||||
using Hangfire.Annotations;
|
||||
using Hangfire.Throttling;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Strata.Hangfire.Configuration;
|
||||
using Strata.Id.Client;
|
||||
using Strata.SnowflakeLib.Configuration;
|
||||
using Strata.SqlTools.Configuration.Common.AsyncFactory;
|
||||
using Strata.SqlTools.Configuration.Postgres;
|
||||
using Strata.SqlTools.Configuration.SqlServer;
|
||||
using Strata.Stratasphere.Biz.AwsS3;
|
||||
using Strata.Stratasphere.Biz.ClientQueries;
|
||||
using Strata.Stratasphere.Biz.ClientTags;
|
||||
using Strata.Stratasphere.Biz.Configuration.SignalR;
|
||||
using Strata.Stratasphere.Biz.Database;
|
||||
using Strata.Stratasphere.Biz.DataManagement;
|
||||
using Strata.Stratasphere.Biz.DbContexts;
|
||||
using Strata.Stratasphere.Biz.Email;
|
||||
using Strata.Stratasphere.Biz.Encryption;
|
||||
using Strata.Stratasphere.Biz.FiscalTime;
|
||||
using Strata.Stratasphere.Biz.Github;
|
||||
using Strata.Stratasphere.Biz.Mappings;
|
||||
using Strata.Stratasphere.Biz.Mappings.Accounts;
|
||||
using Strata.Stratasphere.Biz.Mappings.Accounts.Predictions;
|
||||
using Strata.Stratasphere.Biz.Mappings.Accounts.SphAccountRollup;
|
||||
using Strata.Stratasphere.Biz.Mappings.AdmitType;
|
||||
using Strata.Stratasphere.Biz.Mappings.AdmitType.Predictions;
|
||||
using Strata.Stratasphere.Biz.Mappings.AdmitType.SphAdmitTypeRollup;
|
||||
using Strata.Stratasphere.Biz.Mappings.Departments;
|
||||
using Strata.Stratasphere.Biz.Mappings.Departments.Prediction;
|
||||
using Strata.Stratasphere.Biz.Mappings.Departments.Predictions;
|
||||
using Strata.Stratasphere.Biz.Mappings.Departments.SphDepartmentRollup;
|
||||
using Strata.Stratasphere.Biz.Mappings.DischargeStatus;
|
||||
using Strata.Stratasphere.Biz.Mappings.DischargeStatus.Predictions;
|
||||
using Strata.Stratasphere.Biz.Mappings.DischargeStatus.SphDischargeStatusRollup;
|
||||
using Strata.Stratasphere.Biz.Mappings.Exports;
|
||||
using Strata.Stratasphere.Biz.Mappings.JobCodes;
|
||||
using Strata.Stratasphere.Biz.Mappings.JobCodes.Predictions;
|
||||
using Strata.Stratasphere.Biz.Mappings.JobCodes.SphJobCodeRollup;
|
||||
using Strata.Stratasphere.Biz.Mappings.PayCodes;
|
||||
using Strata.Stratasphere.Biz.Mappings.PayCodes.Predictions;
|
||||
using Strata.Stratasphere.Biz.Mappings.PayCodes.SphPayCodeRollup;
|
||||
using Strata.Stratasphere.Biz.Mappings.PayorTypes;
|
||||
using Strata.Stratasphere.Biz.Mappings.PayorTypes.Predictions;
|
||||
using Strata.Stratasphere.Biz.Mappings.PayorTypes.SphPayorTypeRollup;
|
||||
using Strata.Stratasphere.Biz.Mappings.PresentOnAdmission;
|
||||
using Strata.Stratasphere.Biz.Mappings.PresentOnAdmission.Predictions;
|
||||
using Strata.Stratasphere.Biz.Mappings.PresentOnAdmission.SphPresentOnAdmissionCodeRollup;
|
||||
using Strata.Stratasphere.Biz.Mappings.SourceSystem;
|
||||
using Strata.Stratasphere.Biz.Mappings.SourceSystem.Predictions;
|
||||
using Strata.Stratasphere.Biz.Mappings.SourceSystem.SphSourceSystemCategory;
|
||||
using Strata.Stratasphere.Biz.Processes;
|
||||
using Strata.Stratasphere.Biz.Queries;
|
||||
using Strata.Stratasphere.Biz.RunnableClients;
|
||||
using Strata.Stratasphere.Biz.Snowflake;
|
||||
using Strata.Stratasphere.Biz.Standards;
|
||||
using Strata.Stratasphere.Biz.Standards.Commands.StartupCommands;
|
||||
using Strata.Stratasphere.Biz.Users;
|
||||
using System;
|
||||
using ConnectionStringBuilder = Strata.SqlTools.Configuration.Postgres.ConnectionStringBuilder;
|
||||
|
||||
namespace Strata.Stratasphere.Biz.Configuration
|
||||
{
|
||||
public static class StratasphereServiceExtensions
|
||||
{
|
||||
private const string CacheProviderName = "stratasphere_cache";
|
||||
|
||||
public static IServiceCollection AddStratasphere([NotNull] this IServiceCollection services,
|
||||
IConfiguration configuration)
|
||||
{
|
||||
if (services == null)
|
||||
throw new ArgumentNullException(nameof(services));
|
||||
|
||||
services.AddOptions<AWSOptions>().BindConfiguration("aws").ValidateDataAnnotations(); //bind the options for aws and validates for missing values
|
||||
services.AddOptions<SnowflakeEnvironmentOptions>().BindConfiguration("Snowflake").ValidateDataAnnotations(); //bind the options for aws and validates for missing values
|
||||
//Important step for In-Memory Caching
|
||||
services.AddEasyCaching(options =>
|
||||
{
|
||||
// use memory cache with your own configuration
|
||||
options.UseInMemory(config =>
|
||||
{
|
||||
config.EnableLogging = true;
|
||||
}, CacheProviderName);
|
||||
});
|
||||
|
||||
//hangfire
|
||||
services.AddTransient<IBatchJobClient, BatchJobClient>();
|
||||
services.AddTransient<IThrottlingManager, ThrottlingManager>();
|
||||
services.ConfigureHangfireOptionsFromAws(options =>
|
||||
{
|
||||
options.Schema = Constants.ApplicationName;
|
||||
});
|
||||
|
||||
//aws
|
||||
services.AddScoped<IStrataS3TransferConfiguration, StrataS3TransferConfiguration>();
|
||||
services.AddAWSService<IAmazonS3>();
|
||||
services.AddSingleton<ITransferUtility, TransferUtility>();
|
||||
|
||||
services.AddScoped<IS3BucketService, S3BucketService>();
|
||||
|
||||
services.AddStrataSignalR();
|
||||
services.AddTransient<IAmazonSQS, AmazonSQSClient>();
|
||||
|
||||
//Snowflake
|
||||
services.AddSnowflake(configuration);
|
||||
services.AddSingleton<SnowflakeDatalakeConnectionStringBuilderFactory>();
|
||||
services.AddTransient<ISnowflakeCommandHandler, SnowflakeCommandHandler>();
|
||||
services.AddTransient<ISnowflakeMigrationContext, SnowflakeMigrationContext>();
|
||||
services.AddTransient<IStandardsClientValidator, StandardsClientValidator>();
|
||||
services.AddScoped<IDatalakeConnection, DatalakeConnection>();
|
||||
|
||||
//Services
|
||||
services.AddScoped<IRunnableClientsService, RunnableClientsService>();
|
||||
services.AddScoped<IProcessService, ProcessService>();
|
||||
services.AddScoped<IExportJobService, ExportJobService>();
|
||||
services.AddScoped<IStrataS3TransferConfiguration, StrataS3TransferConfiguration>();
|
||||
services.AddScoped<IEmailService, EmailService>();
|
||||
|
||||
services.AddScoped<IAccountService, AccountService>();
|
||||
services.AddScoped<IAccountMappingService, AccountMappingService>();
|
||||
services.AddScoped<ISphAccountRollupService, SphAccountRollupService>();
|
||||
services.AddScoped<IAccountMappingDetailService, AccountMappingDetailService>();
|
||||
services.AddScoped<IAccountMappingPredictionService, AccountMappingPredictionService>();
|
||||
|
||||
services.AddScoped<IDepartmentService, DepartmentService>();
|
||||
services.AddScoped<IDepartmentMappingService, DepartmentMappingService>();
|
||||
services.AddScoped<ISphDepartmentRollupService, SphDepartmentRollupService>();
|
||||
services.AddScoped<IDepartmentMappingPredictionService, DepartmentMappingPredictionService>();
|
||||
services.AddScoped<IDepartmentMappingDetailService, DepartmentMappingDetailService>();
|
||||
|
||||
services.AddScoped<IFiscalTimeService, FiscalTimeService>();
|
||||
|
||||
services.AddScoped<IJobCodeService, JobCodeService>();
|
||||
services.AddScoped<IJobCodeMappingService, JobCodeMappingService>();
|
||||
services.AddScoped<ISphJobCodeRollupService, SphJobCodeRollupService>();
|
||||
services.AddScoped<IJobCodeMappingPredictionService, JobCodeMappingPredictionService>();
|
||||
services.AddScoped<IJobCodeMappingDetailService, JobCodeMappingDetailService>();
|
||||
|
||||
services.AddScoped<IPayCodeService, PayCodeService>();
|
||||
services.AddScoped<IPayCodeMappingService, PayCodeMappingService>();
|
||||
services.AddScoped<ISphPayCodeRollupService, SphPayCodeRollupService>();
|
||||
services.AddScoped<IPayCodeMappingPredictionService, PayCodeMappingPredictionService>();
|
||||
services.AddScoped<IPayCodeMappingDetailService, PayCodeMappingDetailService>();
|
||||
|
||||
services.AddScoped<IInsurancePlanService, InsurancePlanService>();
|
||||
services.AddScoped<IPayorTypeMappingService, PayorTypeMappingService>();
|
||||
services.AddScoped<ISphPayorTypeService, SphPayorTypeService>();
|
||||
services.AddScoped<IPayorTypeMappingPredictionService, PayorTypeMappingPredictionService>();
|
||||
services.AddScoped<IPayorTypeMappingDetailService, PayorTypeMappingDetailService>();
|
||||
|
||||
services.AddScoped<ISourceSystemService, SourceSystemService>();
|
||||
services.AddScoped<ISourceSystemMappingService, SourceSystemMappingService>();
|
||||
services.AddScoped<ISphSourceSystemCategoryService, SphSourceSystemCategoryService>();
|
||||
services.AddScoped<ISourceSystemMappingPredictionService, SourceSystemMappingPredictionService>();
|
||||
services.AddScoped<ISourceSystemMappingDetailService, SourceSystemMappingDetailService>();
|
||||
|
||||
services.AddScoped<IDischargeStatusService, DischargeStatusService>();
|
||||
services.AddScoped<IDischargeStatusMappingService, DischargeStatusMappingService>();
|
||||
services.AddScoped<ISphDischargeStatusRollupService, SphDischargeStatusRollupService>();
|
||||
services.AddScoped<IDischargeStatusMappingPredictionService, DischargeStatusMappingPredictionService>();
|
||||
services.AddScoped<IDischargeStatusMappingDetailService, DischargeStatusMappingDetailService>();
|
||||
|
||||
services.AddScoped<IPresentOnAdmissionService, PresentOnAdmissionService>();
|
||||
services.AddScoped<IPresentOnAdmissionMappingService, PresentOnAdmissionMappingService>();
|
||||
services.AddScoped<ISphPresentOnAdmissionService, SphPresentOnAdmissionService>();
|
||||
services.AddScoped<IPresentOnAdmissionMappingPredictionService, PresentOnAdmissionMappingPredictionService>();
|
||||
services.AddScoped<IPresentOnAdmissionMappingDetailService, PresentOnAdmissionMappingDetailService>();
|
||||
|
||||
services.AddScoped<IAdmitTypeService, AdmitTypeService>();
|
||||
services.AddScoped<IAdmitTypeMappingService, AdmitTypeMappingService>();
|
||||
services.AddScoped<ISphAdmitTypeRollupService, SphAdmitTypeRollupService>();
|
||||
services.AddScoped<IAdmitTypeMappingPredictionService, AdmitTypeMappingPredictionService>();
|
||||
services.AddScoped<IAdmitTypeMappingDetailService, AdmitTypeMappingDetailService>();
|
||||
services.AddScoped<IUserService, UserService>();
|
||||
services.AddScoped<IEncryptionService, EncryptionService>();
|
||||
|
||||
services.AddScoped<IDatabaseService, DatabaseService>();
|
||||
services.AddScoped<IClientTagsService, ClientTagsService>();
|
||||
|
||||
//Add the startup commands that will run when migration is run
|
||||
//Order matters and these will be executed on migrate in this order
|
||||
services.AddTransient<StartupCommandBase, EnsureStandardsWarehouseCommand>();
|
||||
services.AddTransient<StartupCommandBase, EnsureStandardsWarehouseGrantsCommand>();
|
||||
services.AddTransient<StartupDatalakeCommandBase, EnsureReadmissionDatalakeProdGrantsCommand>();
|
||||
services.AddTransient<StartupDatalakeCommandBase, EnsureReadmissionDatalakeSchemaGrantsCommand>();
|
||||
services.AddTransient<StartupDatalakeCommandBase, EnsureReadmissionPlannedExclusionTableCommand>();
|
||||
services.AddTransient<StartupDatalakeCommandBase, EnsureReadmissionPlannedExclusionTableGrantsCommand>();
|
||||
services.AddTransient<StartupDatalakeCommandBase, EnsureReadmissionTriggerExclusionTableCommand>();
|
||||
services.AddTransient<StartupDatalakeCommandBase, EnsureReadmissionTriggerExclusionTableGrantsCommand>();
|
||||
services.AddTransient<StartupDatalakeCommandBase, EnsureReadmissionPlannedExclusionDataCommand>();
|
||||
services.AddTransient<StartupDatalakeCommandBase, EnsureReadmissionTriggerExclusionDataCommand>();
|
||||
//Postgres
|
||||
var connectionString = ConnectionStringBuilder.Build(configuration, "dataOrchestration");
|
||||
|
||||
services.AddPostgres<DataManagementContext>((options, builder) =>
|
||||
{
|
||||
options.ConnectionString = connectionString;
|
||||
});
|
||||
|
||||
// Jazz databases
|
||||
services.AddScoped<IJazzDbContextFactory, JazzDbContextFactory>();
|
||||
|
||||
// Import Export Mapping Managers
|
||||
services.AddTransient<IImportManager, ImportManager>();
|
||||
services.AddTransient<IExportManager, ExportManager>();
|
||||
|
||||
//strata service clients
|
||||
services.AddIdServiceClient();
|
||||
services.AddCachedSmcServiceClient();
|
||||
|
||||
services.AddAsyncDbContextFactory<JazzDbContext>(options =>
|
||||
{
|
||||
options
|
||||
.UseSqlServer()
|
||||
.WithConnectionString((provider, cancellationToken) => provider.GetConnectionStringFromSmc(cancellationToken));
|
||||
});
|
||||
services.AddScoped(provider =>
|
||||
{
|
||||
var factory = provider.GetRequiredService<IAsyncDbContextFactory<JazzDbContext>>();
|
||||
try
|
||||
{
|
||||
//we should think about making a repository factory classes and getting the repositories in the controllers
|
||||
return factory.CreateDbContextAsync(default).GetAwaiter().GetResult();
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
return default;
|
||||
}
|
||||
});
|
||||
services.AddFeatureFlagServiceClient();
|
||||
|
||||
services.AddSchemaServiceClient();
|
||||
services.AddOptions<PredictionModelSection>().BindConfiguration("PredictionModel").ValidateDataAnnotations();
|
||||
|
||||
var githubSection = configuration.GetSection("github");
|
||||
services.Configure<GithubSection>(githubSection);
|
||||
services.AddScoped<ISaveToGitHubService, SaveToGitHubService>();
|
||||
|
||||
services.AddScoped<IDataWranglerHistoryService, DataWranglerHistoryService>();
|
||||
services.AddScoped<IQueryService, QueryService>();
|
||||
services.AddScoped<IClientQueryService, ClientQueryService>();
|
||||
|
||||
return services;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,332 @@
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Strata.Stratasphere.Biz.Administration.Clients;
|
||||
using Strata.Stratasphere.Biz.DataManagement.Models;
|
||||
using Strata.Stratasphere.Biz.Mappings.Accounts;
|
||||
using Strata.Stratasphere.Biz.Mappings.Accounts.SphAccountRollup;
|
||||
using Strata.Stratasphere.Biz.Mappings.AdmitType;
|
||||
using Strata.Stratasphere.Biz.Mappings.AdmitType.SphAdmitTypeRollup;
|
||||
using Strata.Stratasphere.Biz.Mappings.Departments;
|
||||
using Strata.Stratasphere.Biz.Mappings.Departments.SphDepartmentRollup;
|
||||
using Strata.Stratasphere.Biz.Mappings.DischargeStatus;
|
||||
using Strata.Stratasphere.Biz.Mappings.DischargeStatus.SphDischargeStatusRollup;
|
||||
using Strata.Stratasphere.Biz.Mappings.JobCodes;
|
||||
using Strata.Stratasphere.Biz.Mappings.JobCodes.SphJobCodeRollup;
|
||||
using Strata.Stratasphere.Biz.Mappings.PayCodes;
|
||||
using Strata.Stratasphere.Biz.Mappings.PayCodes.SphPayCodeRollup;
|
||||
using Strata.Stratasphere.Biz.Mappings.PayorTypes;
|
||||
using Strata.Stratasphere.Biz.Mappings.PayorTypes.SphPayorTypeRollup;
|
||||
using Strata.Stratasphere.Biz.Mappings.PresentOnAdmission;
|
||||
using Strata.Stratasphere.Biz.Mappings.PresentOnAdmission.SphPresentOnAdmissionCodeRollup;
|
||||
using Strata.Stratasphere.Biz.Mappings.SourceSystem;
|
||||
using Strata.Stratasphere.Biz.Mappings.SourceSystem.SphSourceSystemCategory;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Strata.Stratasphere.Biz.DataManagement
|
||||
{
|
||||
public class DataManagementContext : DbContext
|
||||
{
|
||||
|
||||
protected override void OnModelCreating(ModelBuilder modelBuilder)
|
||||
{
|
||||
modelBuilder.Entity<Query>()
|
||||
.HasIndex(p => new { p.TargetTable, p.ProcessId })
|
||||
.IsUnique();
|
||||
|
||||
modelBuilder.Entity<Query>()
|
||||
.Property(c => c.MaterializationType)
|
||||
.HasConversion<int>();
|
||||
|
||||
modelBuilder.Entity<Process>().Property(p => p.TargetSchema).HasDefaultValue(Process.DefaultSchema);
|
||||
|
||||
modelBuilder.Entity<Process>()
|
||||
.Property(p => p.IsGithubManaged)
|
||||
.HasDefaultValue(true);
|
||||
|
||||
modelBuilder.Entity<AccountMappingDetail>()
|
||||
.ToView("account_mapping_details")
|
||||
.HasKey(amr => amr.AccountMappingId);
|
||||
|
||||
modelBuilder.Entity<JobCodeMappingDetail>()
|
||||
.ToView("job_code_mapping_details")
|
||||
.HasKey(jc => jc.JobCodeMappingId);
|
||||
|
||||
modelBuilder.Entity<DepartmentMappingDetail>()
|
||||
.ToView("department_mapping_details")
|
||||
.HasKey(jc => jc.DepartmentMappingId);
|
||||
|
||||
modelBuilder.Entity<PayCodeMappingDetail>()
|
||||
.ToView("pay_code_mapping_details")
|
||||
.HasKey(pc => pc.PayCodeMappingId);
|
||||
|
||||
modelBuilder.Entity<PayorTypeMappingDetail>()
|
||||
.ToView("payor_type_mapping_details")
|
||||
.HasKey(pc => pc.PayorTypeMappingId);
|
||||
|
||||
modelBuilder.Entity<SourceSystemMappingDetail>()
|
||||
.ToView("source_system_mapping_details")
|
||||
.HasKey(ssm => ssm.SourceSystemMappingId);
|
||||
|
||||
modelBuilder.Entity<PresentOnAdmissionMappingDetail>()
|
||||
.ToView("present_on_admission_mapping_details")
|
||||
.HasKey(poam => poam.PresentOnAdmissionMappingId);
|
||||
|
||||
modelBuilder.Entity<DischargeStatusMappingDetail>()
|
||||
.ToView("discharge_status_mapping_details")
|
||||
.HasKey(ssm => ssm.DischargeStatusMappingId);
|
||||
|
||||
modelBuilder.Entity<AdmitTypeMappingDetail>()
|
||||
.ToView("admit_type_mapping_details")
|
||||
.HasKey(atm => atm.AdmitTypeMappingId);
|
||||
|
||||
modelBuilder.Entity<ClientMappingSummary>()
|
||||
.ToView("client_mapping_summary")
|
||||
.HasKey(key => new { key.StrataId, key.Mapping });
|
||||
|
||||
|
||||
modelBuilder.Entity<SphDischargeStatusRollup>()
|
||||
.HasData(new List<SphDischargeStatusRollup>()
|
||||
{
|
||||
new(){ SphDischargeStatusRollupId = 0, SphDischargeStatusRollupCode = "0" ,Description = "Not Specified", Name = "0 - Not Specified"},
|
||||
new(){ SphDischargeStatusRollupId = 1, SphDischargeStatusRollupCode = "ACH", Description = "Acute Care Hospital", Name = "ACH - Acute Care Hospital"},
|
||||
new(){ SphDischargeStatusRollupId = 2, SphDischargeStatusRollupCode = "Exp", Description = "Expired", Name = "Exp - Expired"},
|
||||
new(){ SphDischargeStatusRollupId = 3, SphDischargeStatusRollupCode = "Home", Description = "Home", Name = "Home - Home"},
|
||||
new(){ SphDischargeStatusRollupId = 4, SphDischargeStatusRollupCode = "Hospice", Description = "Hospice", Name = "Hospice - Hospice"},
|
||||
new(){ SphDischargeStatusRollupId = 5, SphDischargeStatusRollupCode = "Rehab", Description = "IP Rehab", Name = "Rehab - IP Rehab"},
|
||||
new(){ SphDischargeStatusRollupId = 6, SphDischargeStatusRollupCode = "LTAC", Description = "LTAC", Name = "LTAC - LTAC"},
|
||||
new(){ SphDischargeStatusRollupId = 7, SphDischargeStatusRollupCode = "Other", Description = "Other Healthcare Facility", Name = "Other - Other Healthcare Facility"},
|
||||
new(){ SphDischargeStatusRollupId = 8, SphDischargeStatusRollupCode = "PDC", Description = "Patient Discontinued Care", Name = "PDC - Patient Discontinued Care"},
|
||||
new(){ SphDischargeStatusRollupId = 9, SphDischargeStatusRollupCode = "Psych", Description = "Psych", Name = "Psych - Psych"},
|
||||
new(){ SphDischargeStatusRollupId = 10, SphDischargeStatusRollupCode = "SNF", Description = "SNF", Name = "SNF - SNF"},
|
||||
new(){ SphDischargeStatusRollupId = 11, SphDischargeStatusRollupCode = "UK", Description = "Unknown", Name = "UK - Unknown"}
|
||||
});
|
||||
|
||||
modelBuilder.Entity<Process>()
|
||||
.HasOne(p => p.Author)
|
||||
.WithMany(b => b.Processes)
|
||||
.HasForeignKey(b => b.AuthorId)
|
||||
.IsRequired(false);
|
||||
|
||||
modelBuilder.Entity<User>()
|
||||
.HasData(new List<User>()
|
||||
{
|
||||
new() {UserId = 1, UserName = "sdt\\xpei", Email = "xpei@stratadecision.com"},
|
||||
new() {UserId = 2, UserName = "sdt\\tcleary", Email = "tcleary@stratadecision.com"},
|
||||
new() {UserId = 3, UserName = "sdt\\slyons", Email = "slyons@stratadecision.com"},
|
||||
new() {UserId = 4, UserName = "sdt\\mlipps", Email = "mlipps@stratadecision.com"},
|
||||
new() {UserId = 5, UserName = "sdt\\ltruong", Email = "ltruong@stratadecision.com"},
|
||||
new() {UserId = 6, UserName = "sdt\\cburke", Email = "cburke@stratadecision.com"},
|
||||
new() {UserId = 7, UserName = "sdt\\bhu", Email = "bhu@stratadecision.com"},
|
||||
new() {UserId = 8, UserName = "sdt\\tdebolt", Email = "tdebolt@stratadecision.com"},
|
||||
new() {UserId = 9, UserName = "sdt\\mdraper", Email = "mdraper@stratadecision.com"},
|
||||
new() {UserId = 10, UserName = "sdt\\mleitch", Email = "mleitch@stratadecision.com"}
|
||||
});
|
||||
|
||||
modelBuilder.Entity<SphPresentOnAdmission>()
|
||||
.HasData(new List<SphPresentOnAdmission>()
|
||||
{
|
||||
new() {
|
||||
SphPresentOnAdmissionCodeRollupId = 0,
|
||||
SphPoaDescription = "Not Specified",
|
||||
MemberGUID = "7f745fc7-5b60-4cae-a1d1-0bd15d02e590",
|
||||
SphPoaCode = "0",
|
||||
SphPoaCodeRollup = "Not Specified",
|
||||
SortOrder = 0 },
|
||||
new() {
|
||||
SphPresentOnAdmissionCodeRollupId = 1,
|
||||
SphPoaDescription = "Unreported/exempt",
|
||||
MemberGUID = "e3902b5e-9b8e-4d4a-85e9-1270dfc6e07b",
|
||||
SphPoaCode = "1",
|
||||
SphPoaCodeRollup = "Unreported/Not used",
|
||||
SortOrder = 1
|
||||
},
|
||||
new() {
|
||||
SphPresentOnAdmissionCodeRollupId = 2,
|
||||
SphPoaDescription = "Yes",
|
||||
MemberGUID = "a0d3e992-7fec-49b7-912b-fa7500e93373",
|
||||
SphPoaCode = "Y",
|
||||
SphPoaCodeRollup = "DIagnosis was present",
|
||||
SortOrder = 2
|
||||
},
|
||||
new() {
|
||||
SphPresentOnAdmissionCodeRollupId = 3,
|
||||
SphPoaDescription = "No",
|
||||
MemberGUID = "96f26278-aac6-4b16-abaa-9a2d38d7c615",
|
||||
SphPoaCode = "N",
|
||||
SphPoaCodeRollup = "Diagnosis was not present",
|
||||
SortOrder = 3
|
||||
},
|
||||
new() {
|
||||
SphPresentOnAdmissionCodeRollupId = 4,
|
||||
SphPoaDescription = "Documentation undetermined",
|
||||
MemberGUID = "998c145b-bbbc-42b1-81c5-6e19f8091328",
|
||||
SphPoaCode = "U",
|
||||
SphPoaCodeRollup = "Documentation insufficient",
|
||||
SortOrder = 4
|
||||
},
|
||||
new() {
|
||||
SphPresentOnAdmissionCodeRollupId = 5,
|
||||
SphPoaDescription = "Clinically undetermined",
|
||||
MemberGUID = "8b936afd-85c4-435f-bfea-b5d033991996",
|
||||
SphPoaCode = "W",
|
||||
SphPoaCodeRollup = "Clinically undetermined",
|
||||
SortOrder = 5
|
||||
}
|
||||
});
|
||||
|
||||
modelBuilder.Entity<SphAdmitTypeRollup>()
|
||||
.HasData(new List<SphAdmitTypeRollup>()
|
||||
{
|
||||
new() {
|
||||
SphAdmitTypeRollupId = 0,
|
||||
SphAdmitTypeDescription = "Not Specified",
|
||||
MemberGUID = "c0ead3a0-bfc8-45ed-bae2-377954ff54dd",
|
||||
SphAdmitTypeCode = "0",
|
||||
SphAdmitTypeRollupName = "0 - Not Specified",
|
||||
SortOrder = 0
|
||||
},
|
||||
new() {
|
||||
SphAdmitTypeRollupId = 1,
|
||||
SphAdmitTypeDescription = "Inpatient",
|
||||
MemberGUID = "44A1F798-06CA-44C0-B58F-EDE981298922",
|
||||
SphAdmitTypeCode = "1",
|
||||
SphAdmitTypeRollupName = "1 - Inpatient",
|
||||
SortOrder = 1
|
||||
},
|
||||
new() {
|
||||
SphAdmitTypeRollupId = 2,
|
||||
SphAdmitTypeDescription = "Urgent",
|
||||
MemberGUID = "94c62434-c2b8-4ad3-b76f-5534912186c9",
|
||||
SphAdmitTypeCode = "2",
|
||||
SphAdmitTypeRollupName = "2 - Urgent",
|
||||
SortOrder = 2
|
||||
},
|
||||
new() {
|
||||
SphAdmitTypeRollupId = 3,
|
||||
SphAdmitTypeDescription = "Elective",
|
||||
MemberGUID = "12b13eee-fe8c-4ef8-a44f-e3a86e9adb37",
|
||||
SphAdmitTypeCode = "3",
|
||||
SphAdmitTypeRollupName = "3 - Elective",
|
||||
SortOrder = 3
|
||||
},
|
||||
new() {
|
||||
SphAdmitTypeRollupId = 4,
|
||||
SphAdmitTypeDescription = "Newborn",
|
||||
MemberGUID = "69e7c2de-bfcc-4ea9-8319-594709095201",
|
||||
SphAdmitTypeCode = "4",
|
||||
SphAdmitTypeRollupName = "4 - Newborn",
|
||||
SortOrder = 4
|
||||
},
|
||||
new() {
|
||||
SphAdmitTypeRollupId = 5,
|
||||
SphAdmitTypeDescription = "Trauma",
|
||||
MemberGUID = "D532F8BC-64E5-4301-A1C7-EA3A50FA1D90",
|
||||
SphAdmitTypeCode = "5",
|
||||
SphAdmitTypeRollupName = "5 - Trauma",
|
||||
SortOrder = 5
|
||||
},
|
||||
new() {
|
||||
SphAdmitTypeRollupId = 6,
|
||||
SphAdmitTypeDescription = "Reserved",
|
||||
MemberGUID = "047ebba4-313d-4922-8a1c-24076fb988ae",
|
||||
SphAdmitTypeCode = "6",
|
||||
SphAdmitTypeRollupName = "6 - Reserved",
|
||||
SortOrder = 6
|
||||
},
|
||||
new() {
|
||||
SphAdmitTypeRollupId = 7,
|
||||
SphAdmitTypeDescription = "Reserved",
|
||||
MemberGUID = "f7217436-7e33-49f7-bf00-44205877ee60",
|
||||
SphAdmitTypeCode = "7",
|
||||
SphAdmitTypeRollupName = "7 - Reserved",
|
||||
SortOrder = 7
|
||||
},
|
||||
new() {
|
||||
SphAdmitTypeRollupId = 8,
|
||||
SphAdmitTypeDescription = "Reserved",
|
||||
MemberGUID = "7a88491f-b472-46c3-b43a-52ad6b2ef43a",
|
||||
SphAdmitTypeCode = "8",
|
||||
SphAdmitTypeRollupName = "8 - Reserved",
|
||||
SortOrder = 8
|
||||
},
|
||||
new() {
|
||||
SphAdmitTypeRollupId = 9,
|
||||
SphAdmitTypeDescription = "Unknown",
|
||||
MemberGUID = "871e2044-a52b-489c-9710-9e71d005e75d",
|
||||
SphAdmitTypeCode = "9",
|
||||
SphAdmitTypeRollupName = "9 - Unknown",
|
||||
SortOrder = 9
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public DataManagementContext(DbContextOptions<DataManagementContext> options) : base(options)
|
||||
{
|
||||
}
|
||||
|
||||
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
|
||||
{
|
||||
// Intenionally left empty
|
||||
}
|
||||
|
||||
public virtual DbSet<Process> Processes { get; set; }
|
||||
|
||||
public virtual DbSet<User> Users { get; set; }
|
||||
|
||||
public virtual DbSet<Parameter> Parameters { get; set; }
|
||||
|
||||
public virtual DbSet<Query> Queries { get; set; }
|
||||
|
||||
public virtual DbSet<ClientQuery> ClientQueries { get; set; }
|
||||
|
||||
public virtual DbSet<Tag> Tags { get; set; }
|
||||
|
||||
public virtual DbSet<ClientTag> ClientTags { get; set; }
|
||||
|
||||
public virtual DbSet<QueryTag> QueryTags { get; set; }
|
||||
|
||||
public virtual DbSet<ProcessTag> ProcessTags { get; set; }
|
||||
|
||||
public virtual DbSet<ProcessExecutionResult> ProcessExecutionResults { get; set; }
|
||||
|
||||
public virtual DbSet<ProcessClientExecutionResult> ProcessClientExecutionResults { get; set; }
|
||||
|
||||
public virtual DbSet<AccountMapping> AccountMappings { get; set; }
|
||||
public virtual DbSet<SphAccountRollup> SphAccountRollups { get; set; }
|
||||
public virtual DbSet<AccountMappingDetail> AccountMappingDetails { get; set; }
|
||||
|
||||
public virtual DbSet<DepartmentMapping> DepartmentMappings { get; set; }
|
||||
public virtual DbSet<SphDepartmentRollup> SphDepartmentRollups { get; set; }
|
||||
public virtual DbSet<DepartmentMappingDetail> DepartmentMappingDetails { get; set; }
|
||||
|
||||
public virtual DbSet<JobCodeMapping> JobCodeMappings { get; set; }
|
||||
public virtual DbSet<SphJobCodeRollup> SphJobCodeRollups { get; set; }
|
||||
public virtual DbSet<JobCodeMappingDetail> JobCodeMappingDetails { get; set; }
|
||||
|
||||
public virtual DbSet<PayCodeMapping> PayCodeMappings { get; set; }
|
||||
public virtual DbSet<SphPayCodeRollup> SphPayCodeRollups { get; set; }
|
||||
public virtual DbSet<PayCodeMappingDetail> PayCodeMappingDetails { get; set; }
|
||||
|
||||
public virtual DbSet<PayorTypeMapping> PayorTypeMappings { get; set; }
|
||||
public virtual DbSet<SphPayorType> SphPayorTypes { get; set; }
|
||||
public virtual DbSet<PayorTypeMappingDetail> PayorTypeMappingDetails { get; set; }
|
||||
|
||||
public virtual DbSet<SourceSystemMapping> SourceSystemMappings { get; set; }
|
||||
public virtual DbSet<SphSourceSystemCategory> SphSourceSystemCategories { get; set; }
|
||||
public virtual DbSet<SourceSystemMappingDetail> SourceSystemMappingDetails { get; set; }
|
||||
|
||||
public virtual DbSet<PresentOnAdmissionMapping> PresentOnAdmissionMappings { get; set; }
|
||||
public virtual DbSet<SphPresentOnAdmission> SphPresentOnAdmissions { get; set; }
|
||||
public virtual DbSet<PresentOnAdmissionMappingDetail> PresentOnAdmissionMappingDetails { get; set; }
|
||||
|
||||
public virtual DbSet<DischargeStatusMapping> DischargeStatusMappings { get; set; }
|
||||
public virtual DbSet<SphDischargeStatusRollup> SphDischargeStatusRollups { get; set; }
|
||||
public virtual DbSet<DischargeStatusMappingDetail> DischargeStatusMappingDetails { get; set; }
|
||||
|
||||
public virtual DbSet<AdmitTypeMapping> AdmitTypeMappings { get; set; }
|
||||
public virtual DbSet<SphAdmitTypeRollup> SphAdmitTypeRollups { get; set; }
|
||||
public virtual DbSet<AdmitTypeMappingDetail> AdmitTypeMappingDetails { get; set; }
|
||||
|
||||
public virtual DbSet<ClientMappingSummary> ClientMappingSummaries { get; set; }
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
using Newtonsoft.Json;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
|
||||
namespace Strata.Stratasphere.Biz.DataManagement.Models
|
||||
{
|
||||
public class ClientQuery
|
||||
{
|
||||
public int ClientQueryId { get; set; }
|
||||
|
||||
public int QueryId { get; set; }
|
||||
|
||||
[Required(AllowEmptyStrings = false)]
|
||||
public string QueryText { get; set; }
|
||||
|
||||
public string Description { get; set; }
|
||||
|
||||
public int StrataId { get; set; }
|
||||
|
||||
internal string MetaData()
|
||||
{
|
||||
return JsonConvert.SerializeObject(new
|
||||
{
|
||||
description = Description,
|
||||
strataId = StrataId
|
||||
}, Formatting.Indented);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
namespace Strata.Stratasphere.Biz.DataManagement.Models
|
||||
{
|
||||
public class ClientTag
|
||||
{
|
||||
public int ClientTagId {get; set; }
|
||||
|
||||
public int TagId { get; set; }
|
||||
|
||||
public int StrataId { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
namespace Strata.Stratasphere.Biz.DataManagement.Models
|
||||
{
|
||||
public enum MaterializationType
|
||||
{
|
||||
Table,
|
||||
Ephemeral
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
using System;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
|
||||
namespace Strata.Stratasphere.Biz.DataManagement.Models
|
||||
{
|
||||
public class Parameter : IEquatable<Parameter>
|
||||
{
|
||||
public int ParameterId { get; set; }
|
||||
|
||||
[Required(AllowEmptyStrings = false)]
|
||||
public string Name { get; set; }
|
||||
|
||||
[Required(AllowEmptyStrings = false)]
|
||||
public string Value { get; set; }
|
||||
|
||||
public int ProcessId { get; set; }
|
||||
|
||||
[NotMapped]
|
||||
public string SqlName => Name.Replace(" ", string.Empty);
|
||||
|
||||
public bool Equals(Parameter other)
|
||||
{
|
||||
if (ReferenceEquals(null, other)) return false;
|
||||
if (ReferenceEquals(this, other)) return true;
|
||||
return ParameterId == other.ParameterId && Name == other.Name && ProcessId == other.ProcessId;
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return Name;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,146 @@
|
||||
using Newtonsoft.Json;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
using System.Linq;
|
||||
|
||||
namespace Strata.Stratasphere.Biz.DataManagement.Models
|
||||
{
|
||||
public enum ProcessEnvironment
|
||||
{
|
||||
Sandbox,
|
||||
Staging
|
||||
}
|
||||
|
||||
public enum ScheduleInterval
|
||||
{
|
||||
None,
|
||||
Daily,
|
||||
Weekly,
|
||||
Monthly
|
||||
}
|
||||
|
||||
public enum DayOfWeek
|
||||
{
|
||||
Sunday = 1,
|
||||
Monday,
|
||||
Tuesday,
|
||||
Wednesday,
|
||||
Thursday,
|
||||
Friday,
|
||||
Saturday
|
||||
}
|
||||
|
||||
public class Process
|
||||
{
|
||||
public Process() : this(1, DayOfWeek.Sunday)
|
||||
{
|
||||
}
|
||||
|
||||
public Process(int dayOfMonth, DayOfWeek dayOfWeek)
|
||||
{
|
||||
DayOfMonth = dayOfMonth;
|
||||
DayOfWeek = dayOfWeek;
|
||||
ScheduleInterval = ScheduleInterval.None;
|
||||
}
|
||||
|
||||
public const string DefaultSchema = "DATA";
|
||||
|
||||
public int ProcessId { get; set; }
|
||||
|
||||
[Required(AllowEmptyStrings = false)]
|
||||
public string Name { get; set; }
|
||||
|
||||
[Required(AllowEmptyStrings = false)]
|
||||
public string Description { get; set; }
|
||||
|
||||
public ICollection<Query> Queries { get; set; }
|
||||
|
||||
public ICollection<Parameter> Parameters { get; set; }
|
||||
|
||||
public ICollection<ProcessTag> ProcessTags { get; set; }
|
||||
|
||||
[NotMapped]
|
||||
public string Tags { get; set; }
|
||||
|
||||
public ProcessEnvironment Environment { get; set; }
|
||||
|
||||
[Required(AllowEmptyStrings = false)]
|
||||
public string TargetSchema { get; set; }
|
||||
|
||||
public ScheduleInterval ScheduleInterval { get; set; }
|
||||
|
||||
public int TimeOfDay { get; set; }
|
||||
|
||||
public DayOfWeek DayOfWeek { get; set; }
|
||||
|
||||
public int DayOfMonth { get; set; }
|
||||
public int? AuthorId { get; set; } = null!;
|
||||
#nullable enable
|
||||
[ForeignKey("AuthorId")]
|
||||
public virtual User? Author { get; set; }
|
||||
#nullable disable
|
||||
[NotMapped]
|
||||
public string AuthorName => Author?.UserName ?? "";
|
||||
|
||||
public bool IsGithubManaged { get; set; } = true;
|
||||
|
||||
public string GetCronExpression()
|
||||
{
|
||||
var cronTimeOfDayMinute = TimeOfDay % 2 * 30;
|
||||
var cronTimeOfDayHour = TimeOfDay / 2;
|
||||
string cronDayOfMonth = "*";
|
||||
string cronDayOfWeek = "*";
|
||||
|
||||
switch (ScheduleInterval)
|
||||
{
|
||||
case ScheduleInterval.None:
|
||||
return "";
|
||||
case ScheduleInterval.Daily:
|
||||
break;
|
||||
case ScheduleInterval.Weekly:
|
||||
cronDayOfWeek = System.Enum.GetName(typeof(Biz.DataManagement.Models.DayOfWeek), DayOfWeek).Substring(0, 3);
|
||||
break;
|
||||
case ScheduleInterval.Monthly:
|
||||
cronDayOfMonth = DayOfMonth != 0 ? $"{DayOfMonth}" : "*";
|
||||
break;
|
||||
}
|
||||
|
||||
return $"{cronTimeOfDayMinute} {cronTimeOfDayHour} {cronDayOfMonth} * {cronDayOfWeek}";
|
||||
}
|
||||
|
||||
internal string MetaData(IEnumerable<Tag> tags)
|
||||
{
|
||||
if (ScheduleInterval == ScheduleInterval.None)
|
||||
{
|
||||
return JsonConvert.SerializeObject(new
|
||||
{
|
||||
description = Description,
|
||||
defaultSchema = DefaultSchema,
|
||||
parameters = Parameters?.Select(p => new { name = p.Name, value = p.Value }),
|
||||
environment = Enum.GetName<ProcessEnvironment>(Environment),
|
||||
targetSchema = TargetSchema,
|
||||
scheduleInterval = Enum.GetName<ScheduleInterval>(ScheduleInterval),
|
||||
author = AuthorName,
|
||||
processTags = string.Join(", ", tags.Where(t => ProcessTags.Select(qt => qt.TagId).Contains(t.TagId)).Select(t => t.TagName)),
|
||||
}, Formatting.Indented);
|
||||
}
|
||||
return JsonConvert.SerializeObject(new
|
||||
{
|
||||
description = Description,
|
||||
defaultSchema = DefaultSchema,
|
||||
parameters = Parameters?.Select(p => new { name = p.Name, value = p.Value }),
|
||||
environment = Enum.GetName<ProcessEnvironment>(Environment),
|
||||
targetSchema = TargetSchema,
|
||||
scheduleInterval = Enum.GetName<ScheduleInterval>(ScheduleInterval),
|
||||
timeOfDay = TimeOfDay,
|
||||
dayofWeek = Enum.GetName<DayOfWeek>(DayOfWeek),
|
||||
dayOfMonth = DayOfMonth,
|
||||
author = AuthorName,
|
||||
processTags = string.Join(", ", tags.Where(t => ProcessTags.Select(qt => qt.TagId).Contains(t.TagId)).Select(t => t.TagName)),
|
||||
}, Formatting.Indented);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
using System;
|
||||
|
||||
namespace Strata.Stratasphere.Biz.DataManagement.Models
|
||||
{
|
||||
public class ProcessClientExecutionResult
|
||||
{
|
||||
public int ProcessExecutionResultId { get; set; }
|
||||
|
||||
public int ProcessClientExecutionResultId { get; set; }
|
||||
|
||||
public int ProcessId { get; set; }
|
||||
|
||||
public int StrataId { get; set; }
|
||||
|
||||
public string Error { get; set; }
|
||||
|
||||
public DateTime StartTime { get; set; }
|
||||
|
||||
public DateTime EndTime { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace Strata.Stratasphere.Biz.DataManagement.Models
|
||||
{
|
||||
public enum ProcessHistoryEnvironment
|
||||
{
|
||||
Sandbox,
|
||||
Staging,
|
||||
Production,
|
||||
Rollback
|
||||
}
|
||||
|
||||
public class ProcessExecutionResult
|
||||
{
|
||||
public int ProcessExecutionResultId { get; set; }
|
||||
|
||||
public int ProcessId { get; set; }
|
||||
|
||||
public ProcessHistoryEnvironment Environment { get; set; }
|
||||
|
||||
public string EnvironmentValue => Environment.ToString();
|
||||
|
||||
public string StartedByUserName { get; set; }
|
||||
|
||||
public string ParameterJson { get; set; }
|
||||
|
||||
public DateTime StartTime { get; set; }
|
||||
|
||||
public ICollection<ProcessClientExecutionResult> ProcessClientExecutionResults { get; set; }
|
||||
|
||||
public bool IsErrored
|
||||
{
|
||||
get
|
||||
{
|
||||
if (Environment == ProcessHistoryEnvironment.Production || Environment == ProcessHistoryEnvironment.Rollback)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return ProcessClientExecutionResults == null || ProcessClientExecutionResults.Any(x => !string.IsNullOrEmpty(x.Error));
|
||||
}
|
||||
}
|
||||
|
||||
public string Status => IsErrored ? "Error" : "Success";
|
||||
|
||||
public DateTime EndTime => ProcessClientExecutionResults != null && ProcessClientExecutionResults.Any() ? ProcessClientExecutionResults.Max(x => x.EndTime) : !IsErrored ? StartTime : default;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
namespace Strata.Stratasphere.Biz.DataManagement.Models
|
||||
{
|
||||
public class ProcessTag
|
||||
{
|
||||
public int ProcessTagId { get; set; }
|
||||
|
||||
public int TagId { get; set; }
|
||||
|
||||
public int ProcessId { get; set; }
|
||||
|
||||
public ProcessTag(int processId, int tagId)
|
||||
{
|
||||
ProcessId = processId;
|
||||
TagId = tagId;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,76 @@
|
||||
using Newtonsoft.Json;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
using System.Linq;
|
||||
|
||||
namespace Strata.Stratasphere.Biz.DataManagement.Models
|
||||
{
|
||||
public class Query : IEquatable<Query>
|
||||
{
|
||||
private readonly string RollbackTable_Suffix = "_last";
|
||||
public int QueryId { get; set; }
|
||||
|
||||
[Required(AllowEmptyStrings = false)]
|
||||
public string QueryText { get; set; }
|
||||
|
||||
[Required(AllowEmptyStrings = false)]
|
||||
public string TargetTable { get; set; }
|
||||
|
||||
[Required(AllowEmptyStrings = false)]
|
||||
public string Description { get; set; }
|
||||
|
||||
public MaterializationType MaterializationType { get; set; }
|
||||
|
||||
public int ProcessId { get; set; }
|
||||
|
||||
public int DisplayOrder { get; set; }
|
||||
|
||||
[NotMapped]
|
||||
internal string SessionTableName => TargetTable + "_temp";
|
||||
|
||||
public ICollection<ClientQuery> ClientQueries { get; set; }
|
||||
|
||||
public ICollection<QueryTag> QueryTags { get; set; }
|
||||
|
||||
public string GetQualifedTableName(Process process)
|
||||
{
|
||||
return $"{process.TargetSchema}.{TargetTable}";
|
||||
}
|
||||
|
||||
public string GetQualifedRollbackTableName(Process process)
|
||||
{
|
||||
return $"{process.TargetSchema}.{TargetTable}{RollbackTable_Suffix}";
|
||||
}
|
||||
|
||||
public string GetRollbackTableName()
|
||||
{
|
||||
return $"{TargetTable}{RollbackTable_Suffix}";
|
||||
}
|
||||
|
||||
public bool Equals(Query other)
|
||||
{
|
||||
return other != null && QueryId == other.QueryId &&
|
||||
QueryText == other.QueryText &&
|
||||
TargetTable == other.TargetTable &&
|
||||
MaterializationType == other.MaterializationType &&
|
||||
ProcessId == other.ProcessId;
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return TargetTable;
|
||||
}
|
||||
|
||||
internal string MetaData(IEnumerable<Tag> tags)
|
||||
{
|
||||
return JsonConvert.SerializeObject(new
|
||||
{
|
||||
description = Description,
|
||||
materializationType = MaterializationType.ToString(),
|
||||
queryTags = string.Join(", ", tags.Where(t => QueryTags.Select(qt => qt.TagId).Contains(t.TagId)).Select(t => t.TagName))
|
||||
}, Formatting.Indented);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
namespace Strata.Stratasphere.Biz.DataManagement.Models
|
||||
{
|
||||
public class QueryTag
|
||||
{
|
||||
public int QueryTagId { get; set; }
|
||||
|
||||
public int TagId { get; set; }
|
||||
|
||||
public int QueryId { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
|
||||
namespace Strata.Stratasphere.Biz.DataManagement.Models
|
||||
{
|
||||
public class Tag
|
||||
{
|
||||
public int TagId { get; set; }
|
||||
|
||||
[Required(AllowEmptyStrings = false)]
|
||||
public string TagName { get; set; }
|
||||
|
||||
public ICollection<ClientTag> ClientTags { get; set; }
|
||||
|
||||
public ICollection<QueryTag> QueryTags { get; set; }
|
||||
|
||||
public ICollection<ProcessTag> ProcessTags { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace Strata.Stratasphere.Biz.DataManagement.Models
|
||||
{
|
||||
public class User
|
||||
{
|
||||
[Key]
|
||||
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
|
||||
public int UserId { get; set; }
|
||||
public string UserName { get; set; }
|
||||
public string Email { get; set; }
|
||||
public string GithubToken { get; set; } = "";
|
||||
public string PreviousGithubToken { get; set; }
|
||||
public DateTimeOffset GithubTokenExpiry { get; set; }
|
||||
|
||||
[JsonIgnore]
|
||||
public virtual ICollection<Process> Processes { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
using System;
|
||||
|
||||
namespace Strata.Stratasphere.Biz.Database
|
||||
{
|
||||
public class Database
|
||||
{
|
||||
public string ServerName { get; set; }
|
||||
public string PhysicalName { get; set; }
|
||||
|
||||
public string DatabaseName { get; set; }
|
||||
|
||||
public Guid DatabaseGuid { get; set; }
|
||||
|
||||
public bool IsClientDb { get; set; }
|
||||
|
||||
public int StrataId { get; set; }
|
||||
|
||||
public string OrgPin { get; set; }
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,98 @@
|
||||
using EasyCaching.Core;
|
||||
using Strata.FeatureFlags.Client;
|
||||
using Strata.Id.Client;
|
||||
using Strata.SqlTools.EntityFramework;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Strata.Stratasphere.Biz.Database
|
||||
{
|
||||
public class DatabaseService : IDatabaseService
|
||||
{
|
||||
private readonly string _databaseListCacheKey = "databaseList";
|
||||
private readonly IEasyCachingProvider _easyCachingProvider;
|
||||
private readonly IFeatureFlagServiceClient _featureFlagServiceClient;
|
||||
private readonly IIdServiceClient _idServiceClient;
|
||||
|
||||
public DatabaseService(IEasyCachingProvider easyCachingProvider,
|
||||
IFeatureFlagServiceClient featureFlagServiceClient,
|
||||
IIdServiceClient idServiceClient)
|
||||
{
|
||||
_easyCachingProvider = easyCachingProvider;
|
||||
_featureFlagServiceClient = featureFlagServiceClient;
|
||||
_idServiceClient = idServiceClient;
|
||||
}
|
||||
|
||||
public async Task<IEnumerable<Database>> GetDatabasesAsync(CancellationToken cancellationToken)
|
||||
=> await GetDatabasesAsync(default, cancellationToken);
|
||||
|
||||
public async Task<Database> GetDatabaseByStrataId(int strataId, CancellationToken cancellationToken)
|
||||
{
|
||||
var databases = await GetDatabasesAsync(cancellationToken);
|
||||
return databases.FirstOrDefault(database => database.StrataId == strataId);
|
||||
}
|
||||
|
||||
public async Task<IEnumerable<Database>> GetDatabasesByStrataId(IEnumerable<int> strataIds, CancellationToken cancellationToken)
|
||||
{
|
||||
var databases = await GetDatabasesAsync(cancellationToken);
|
||||
return databases.Where(database => strataIds.Contains(database.StrataId));
|
||||
}
|
||||
|
||||
public async Task<Database> GetDatabaseByDatabaseGuid(Guid databaseGuid, CancellationToken cancellationToken)
|
||||
{
|
||||
var databases = await GetDatabasesAsync(cancellationToken);
|
||||
return databases.FirstOrDefault(database => database.DatabaseGuid == databaseGuid);
|
||||
}
|
||||
|
||||
public async Task<IEnumerable<Database>> GetDatabasesAsync(IDatabaseFilters filters, CancellationToken cancellationToken)
|
||||
{
|
||||
var cacheResult = await _easyCachingProvider.GetAsync(_databaseListCacheKey, async () =>
|
||||
{
|
||||
var dbStates = await _featureFlagServiceClient.GetClientStatesByFeatureFlagAsync("datauseaddendumexecuted");
|
||||
var dbInfo = await _idServiceClient.GetStrataIds(cancellationToken);
|
||||
|
||||
var validDtos = new List<Database>();
|
||||
|
||||
foreach (var db in dbStates.Where(x => x.Enabled))
|
||||
{
|
||||
var strata = dbInfo.FirstOrDefault(x => x.DatabaseGUID == db.DatabaseGuid);
|
||||
if (strata == null) continue;
|
||||
var dto = new Database
|
||||
{
|
||||
DatabaseGuid = db.DatabaseGuid,
|
||||
PhysicalName = strata?.PhysicalName ?? "",
|
||||
DatabaseName = strata?.DatabaseName ?? "",
|
||||
ServerName = strata?.ServerName ?? "",
|
||||
OrgPin = strata.OrgPin,
|
||||
StrataId = strata.StrataId
|
||||
};
|
||||
|
||||
validDtos.Add(dto);
|
||||
}
|
||||
|
||||
return validDtos;
|
||||
}, TimeSpan.FromMinutes(10));
|
||||
if (filters != null && cacheResult.HasValue)
|
||||
{
|
||||
var orgPins = filters.OrgPin?.ToLower().Split(',').Select(op => op.Trim()).Where(op => !string.IsNullOrEmpty(op)).ToList()
|
||||
?? new List<string>();
|
||||
var physicalName = filters.DatabaseName?.ToLower() ?? "";
|
||||
var databases = cacheResult.Value;
|
||||
if (orgPins.Any())
|
||||
{
|
||||
databases = databases.Where(db => orgPins.Contains(db.OrgPin)).ToList();
|
||||
}
|
||||
if (!string.IsNullOrEmpty(physicalName))
|
||||
{
|
||||
databases = databases.Where(db => db.PhysicalName.ToLower().Contains(physicalName)).ToList();
|
||||
}
|
||||
return databases;
|
||||
}
|
||||
return cacheResult.Value;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
namespace Strata.Stratasphere.Biz.Database
|
||||
{
|
||||
public interface IDatabaseFilters
|
||||
{
|
||||
public string OrgPin { get; set; }
|
||||
public string DatabaseName { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Strata.Stratasphere.Biz.Database
|
||||
{
|
||||
public interface IDatabaseService
|
||||
{
|
||||
Task<IEnumerable<Database>> GetDatabasesAsync(CancellationToken cancellationToken);
|
||||
Task<IEnumerable<Database>> GetDatabasesAsync(IDatabaseFilters filters, CancellationToken cancellationToken);
|
||||
Task<Database> GetDatabaseByStrataId(int strataId, CancellationToken cancellationToken);
|
||||
Task<IEnumerable<Database>> GetDatabasesByStrataId(IEnumerable<int> strataIds, CancellationToken cancellationToken);
|
||||
Task<Database> GetDatabaseByDatabaseGuid(Guid databaseGuid, CancellationToken cancellationToken);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
using Strata.Stratasphere.Biz.DbContexts;
|
||||
using System;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Strata.Stratasphere.Biz.Database
|
||||
{
|
||||
public interface IJazzDbContextFactory
|
||||
{
|
||||
Task<JazzDbContext> CreateContextFromDatabase(Guid databaseGuid, CancellationToken cancellationToken);
|
||||
Task<string> GetConnectionString(Guid databaseGuid, CancellationToken cancellationToken);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
using Strata.SMC.Client;
|
||||
using Strata.Stratasphere.Biz.DbContexts;
|
||||
using System;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Strata.Stratasphere.Biz.Database
|
||||
{
|
||||
public class JazzDbContextFactory : IJazzDbContextFactory
|
||||
{
|
||||
private readonly ISMCServiceClient _smcServiceClient;
|
||||
|
||||
public JazzDbContextFactory(ISMCServiceClient smcServiceClient)
|
||||
{
|
||||
_smcServiceClient = smcServiceClient;
|
||||
}
|
||||
|
||||
public async Task<JazzDbContext> CreateContextFromDatabase(Guid databaseGuid, CancellationToken cancellationToken = default(CancellationToken))
|
||||
{
|
||||
if (databaseGuid == Guid.Empty)
|
||||
{
|
||||
throw new ArgumentException(nameof(databaseGuid));
|
||||
}
|
||||
|
||||
return new JazzDbContext(await GetConnectionString(databaseGuid, cancellationToken));
|
||||
}
|
||||
|
||||
public async Task<string> GetConnectionString(Guid databaseGuid, CancellationToken cancellationToken = default(CancellationToken))
|
||||
{
|
||||
var db = await _smcServiceClient.GetDatabaseAsync(databaseGuid, cancellationToken);
|
||||
return db.ConnectionString;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
using System;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Strata.Stratasphere.Biz.DbContexts
|
||||
{
|
||||
public interface IJazzDbContext
|
||||
{
|
||||
Task<int> ScoreDimensionCacheRefresh(Guid dimensionGuid, CancellationToken cancellationToken);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,96 @@
|
||||
using Microsoft.Data.SqlClient;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Strata.Stratasphere.Biz.FiscalTime;
|
||||
using Strata.Stratasphere.Biz.Mappings;
|
||||
using Strata.Stratasphere.Biz.Mappings.Accounts;
|
||||
using Strata.Stratasphere.Biz.Mappings.AdmitType;
|
||||
using Strata.Stratasphere.Biz.Mappings.Departments;
|
||||
using Strata.Stratasphere.Biz.Mappings.DischargeStatus;
|
||||
using Strata.Stratasphere.Biz.Mappings.JobCodes;
|
||||
using Strata.Stratasphere.Biz.Mappings.PayCodes;
|
||||
using Strata.Stratasphere.Biz.Mappings.PayorTypes;
|
||||
using Strata.Stratasphere.Biz.Mappings.PresentOnAdmission;
|
||||
using Strata.Stratasphere.Biz.Mappings.SourceSystem;
|
||||
using Strata.Stratasphere.Biz.Mappings.SourceSystem.SphSourceSystemCategory;
|
||||
using System;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Strata.Stratasphere.Biz.DbContexts
|
||||
{
|
||||
public class JazzDbContext : DbContext, IJazzDbContext
|
||||
{
|
||||
|
||||
public JazzDbContext(DbContextOptions<JazzDbContext> options) : base(options)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public JazzDbContext(string connectionString) : base(GetOptions(connectionString)) { }
|
||||
|
||||
private static DbContextOptions GetOptions(string connectionString)
|
||||
=> SqlServerDbContextOptionsExtensions.UseSqlServer(new DbContextOptionsBuilder(), connectionString).Options;
|
||||
|
||||
|
||||
public DbSet<ICD10DXCount> ICD10DXCounts { get; set; }
|
||||
public DbSet<UBRevVolume> UbRevVolumes { get; set; }
|
||||
public DbSet<GLAccountDollars> GLAccountDollars { get; set; }
|
||||
public DbSet<JobCodeCount> JobCodeCounts { get; set; }
|
||||
public DbSet<Accounting> Accounting { get; set; }
|
||||
public DbSet<FiscalMonth> FiscalMonths { get; set; }
|
||||
public DbSet<Account> Accounts { get; set; }
|
||||
public DbSet<Department> Departments { get; set; }
|
||||
public DbSet<JobCode> JobCodes { get; set; }
|
||||
public DbSet<PayrollData> PayrollData { get; set; }
|
||||
public DbSet<PayCode> PayCodes { get; set; }
|
||||
public DbSet<InsurancePlan> InsurancePlans { get; set; }
|
||||
public DbSet<SPHPayorType> SPHPayorTypes { get; set; }
|
||||
public DbSet<SourceSystem> SourceSystem { get; set; }
|
||||
public DbSet<SphSourceSystemCategory> SphSourceSystemCategories { get; set; }
|
||||
public DbSet<PresentOnAdmission> PresentOnAdmissions { get; set; }
|
||||
public DbSet<DischargeStatus> DischargeStatus { get; set; }
|
||||
public DbSet<AdmitType> AdmitTypes { get; set; }
|
||||
|
||||
protected override void OnModelCreating(ModelBuilder modelBuilder)
|
||||
{
|
||||
base.OnModelCreating(modelBuilder);
|
||||
modelBuilder.Entity<Account>().HasAlternateKey(key => new { key.AccountId, key.AccountCode });
|
||||
modelBuilder.Entity<Department>().HasAlternateKey(key => new { key.DepartmentId, key.DepartmentCode });
|
||||
modelBuilder.Entity<JobCode>().HasAlternateKey(key => new { key.JobCodeId, key.JobCodeCode });
|
||||
modelBuilder.Entity<PayrollData>().HasNoKey();
|
||||
modelBuilder.Entity<PayCode>().HasAlternateKey(key => new { key.PayCodeId, key.Paycode });
|
||||
modelBuilder.Entity<InsurancePlan>().HasAlternateKey(key => new { key.InsurancePlanId, key.InsurancePlanCode });
|
||||
modelBuilder.Entity<UBRevVolume>().HasNoKey();
|
||||
modelBuilder.Entity<ICD10DXCount>().HasNoKey();
|
||||
modelBuilder.Entity<GLAccountDollars>().HasNoKey();
|
||||
modelBuilder.Entity<JobCodeCount>().HasNoKey();
|
||||
modelBuilder.Entity<Accounting>().HasNoKey();
|
||||
|
||||
}
|
||||
|
||||
public async Task<int> ScoreDimensionCacheRefresh(Guid dimensionGuid, CancellationToken cancellationToken)
|
||||
{
|
||||
var dimensionGuidParam = new SqlParameter("@dimensionGuid", dimensionGuid);
|
||||
var isSecurityDirty = new SqlParameter("@isSecurityDirty", true);
|
||||
return await Database.ExecuteSqlRawAsync("EXEC dbo.procScoreDimensionCacheRefresh @dimensionGuid=@dimensionGuid, @isSecurityDirty=@isSecurityDirty",
|
||||
new[] { dimensionGuidParam, isSecurityDirty }, cancellationToken);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Validate that this Jazz Context and the Strata Database are the same client
|
||||
/// </summary>
|
||||
/// <param name="db">The Database <see cref="Database.Database"/>that is being updated from</param>
|
||||
/// <param name="timeoutMinutes">The timeout in minutes for the jazz context</param>
|
||||
/// <exception cref="DatabaseContextException"></exception>
|
||||
public void ValidateContextWithDb(Database.Database db, int timeoutMinutes)
|
||||
{
|
||||
var connection = Database.GetConnectionString();
|
||||
if (!connection.Contains($"\"{db.PhysicalName}\""))
|
||||
{
|
||||
throw new DatabaseContextException(db.PhysicalName, connection);
|
||||
}
|
||||
Database.SetCommandTimeout(TimeSpan.FromMinutes(timeoutMinutes));
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
using System;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
|
||||
namespace Strata.Stratasphere.Biz.DbContexts
|
||||
{
|
||||
[Table("DimSPHPayorType", Schema = "DSS")]
|
||||
public class SPHPayorType
|
||||
{
|
||||
[Key]
|
||||
public Guid MemberGuid { get; set; }
|
||||
public int SphPayorTypeId { get; set; }
|
||||
public string SphPayorTypeCode { get; set; }
|
||||
public string SphPayorGroup { get; set; }
|
||||
public string SphPayorType { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,78 @@
|
||||
using System;
|
||||
using FluentEmail.Mailgun;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Strata.Stratasphere.Biz.DataManagement;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Strata.Stratasphere.Biz.Email
|
||||
{
|
||||
public class EmailService : IEmailService
|
||||
{
|
||||
private readonly DataManagementContext _dataManagementContext;
|
||||
|
||||
public EmailService([NotNull] DataManagementContext dataManagementContext)
|
||||
{
|
||||
_dataManagementContext = dataManagementContext;
|
||||
}
|
||||
|
||||
public async Task ProcessEmail(string processName, IEnumerable<string> recipients, int logId, string batchGuid)
|
||||
{
|
||||
var result = await _dataManagementContext.ProcessExecutionResults
|
||||
.Include(r => r.ProcessClientExecutionResults)
|
||||
.SingleAsync(r => r.ProcessExecutionResultId == logId);
|
||||
|
||||
var hasErrors = result.IsErrored;
|
||||
var batchJobPage = Guid.TryParse(batchGuid, out _) ? batchGuid : "started";
|
||||
var diff = result.EndTime.Subtract(result.StartTime);
|
||||
|
||||
var totalMinutes = diff.TotalMinutes;
|
||||
if (totalMinutes > 1.0d)
|
||||
{
|
||||
if (hasErrors)
|
||||
{
|
||||
await SendPostProcessJobFailedEmail(processName, recipients, batchJobPage);
|
||||
}
|
||||
else
|
||||
{
|
||||
await SendPostProcessJobEmail(processName, recipients, batchJobPage);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public async Task SendPostProcessJobFailedEmail(string processName, IEnumerable<string> recipients, string batchJobPage)
|
||||
{
|
||||
await SendEmail(recipients,
|
||||
$"Data Wrangler - {processName} failed. Please check hangfire.",
|
||||
@$"<p>The process {processName} has failed. Please log into hangfire to view the result.</p>
|
||||
<a href = ""https://stratasphere.prod.stratanetwork.net/dashboard/batches/{batchJobPage}""> Hangfire Job {processName} </a>");
|
||||
}
|
||||
|
||||
public async Task SendPostProcessJobEmail(string processName, IEnumerable<string> recipients, string batchJobPage)
|
||||
{
|
||||
await SendEmail(recipients,
|
||||
$"Data Wrangler - {processName} successfully completed.",
|
||||
@$"<p>The process {processName} has successfully completed. Please log into hangfire to view the result.</p>
|
||||
<a href = ""https://stratasphere.prod.stratanetwork.net/dashboard/batches/{batchJobPage}""> Hangfire Job {processName} </a>");
|
||||
}
|
||||
|
||||
internal static async Task SendEmail(IEnumerable<string> recipients, string subject, string body)
|
||||
{
|
||||
var sender = new MailgunSender(
|
||||
"notifications-dev.stratanetwork.com",
|
||||
"key-12ea6389d906cef290ad8a0557a3a8c4"
|
||||
);
|
||||
FluentEmail.Core.Email.DefaultSender = sender;
|
||||
|
||||
var email = new FluentEmail.Core.Email()
|
||||
.SetFrom("noreply@notifications.stratanetwork.com")
|
||||
.To(string.Join(';', recipients.Where(r => !string.IsNullOrEmpty(r))))
|
||||
.Subject(subject)
|
||||
.Body(body, true);
|
||||
|
||||
await email.SendAsync();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Strata.Stratasphere.Biz.Email
|
||||
{
|
||||
public interface IEmailService
|
||||
{
|
||||
Task ProcessEmail(string processName, IEnumerable<string> recipients, int logId, string batchGuid);
|
||||
Task SendPostProcessJobFailedEmail(string processName, IEnumerable<string> recipients, string batchJobPage);
|
||||
Task SendPostProcessJobEmail(string processName, IEnumerable<string> recipients, string batchJobPage);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,67 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Security.Cryptography;
|
||||
using System.Text;
|
||||
|
||||
namespace Strata.Stratasphere.Biz.Encryption
|
||||
{
|
||||
public class EncryptionService : IEncryptionService
|
||||
{
|
||||
private readonly string _key = "babel encrypting";
|
||||
|
||||
public string EncryptString(string plainText)
|
||||
{
|
||||
if (string.IsNullOrEmpty(plainText)) { return plainText; }
|
||||
byte[] iv = new byte[16];
|
||||
byte[] array;
|
||||
|
||||
using (Aes aes = Aes.Create())
|
||||
{
|
||||
aes.Key = Encoding.UTF8.GetBytes(_key);
|
||||
aes.IV = iv;
|
||||
|
||||
ICryptoTransform encryptor = aes.CreateEncryptor(aes.Key, aes.IV);
|
||||
|
||||
using (MemoryStream memoryStream = new MemoryStream())
|
||||
{
|
||||
using (CryptoStream cryptoStream = new CryptoStream((Stream)memoryStream, encryptor, CryptoStreamMode.Write))
|
||||
{
|
||||
using (StreamWriter streamWriter = new StreamWriter((Stream)cryptoStream))
|
||||
{
|
||||
streamWriter.Write(plainText);
|
||||
}
|
||||
|
||||
array = memoryStream.ToArray();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return Convert.ToBase64String(array);
|
||||
}
|
||||
|
||||
public string DecryptString(string cipherText)
|
||||
{
|
||||
if (string.IsNullOrEmpty(cipherText)) { return cipherText; }
|
||||
byte[] iv = new byte[16];
|
||||
byte[] buffer = Convert.FromBase64String(cipherText);
|
||||
|
||||
using (Aes aes = Aes.Create())
|
||||
{
|
||||
aes.Key = Encoding.UTF8.GetBytes(_key);
|
||||
aes.IV = iv;
|
||||
ICryptoTransform decryptor = aes.CreateDecryptor(aes.Key, aes.IV);
|
||||
|
||||
using (MemoryStream memoryStream = new MemoryStream(buffer))
|
||||
{
|
||||
using (CryptoStream cryptoStream = new CryptoStream((Stream)memoryStream, decryptor, CryptoStreamMode.Read))
|
||||
{
|
||||
using (StreamReader streamReader = new StreamReader((Stream)cryptoStream))
|
||||
{
|
||||
return streamReader.ReadToEnd();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
namespace Strata.Stratasphere.Biz.Encryption
|
||||
{
|
||||
public interface IEncryptionService
|
||||
{
|
||||
string DecryptString(string cipherText);
|
||||
string EncryptString(string plainText);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
namespace Strata.Stratasphere.Biz.Extensions
|
||||
{
|
||||
public static class BooleanExtensions
|
||||
{
|
||||
public static string ToYesNoString(this bool value)
|
||||
=> value ? "Yes" : "No";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
using Strata.SqlTools.EntityFramework.Pagination;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Strata.Stratasphere.Biz.Extensions
|
||||
{
|
||||
public static class EmptyPageDataExtensions
|
||||
{
|
||||
public static PagedData<T> EmptyPageData<T>(this IEnumerable<Database.Database> databases)
|
||||
=> new PagedData<T>
|
||||
{
|
||||
Data = new List<T>(),
|
||||
Total = 0
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace Strata.Stratasphere.Biz.Extensions
|
||||
{
|
||||
public static class FilterExtensions
|
||||
{
|
||||
public static IEnumerable<string> CSVValues(this string csv)
|
||||
=> csv.ToLower().Split(',').Select(csv => csv.Trim());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,101 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Linq;
|
||||
|
||||
namespace Strata.Stratasphere.Biz.Extensions
|
||||
{
|
||||
[ExcludeFromCodeCoverage]
|
||||
public static class ListExtensions
|
||||
{
|
||||
/// <summary>
|
||||
/// Batches the source sequence into sized buckets.
|
||||
/// </summary>
|
||||
/// <typeparam name="TSource">Type of elements in <paramref name="source"/> sequence.</typeparam>
|
||||
/// <param name="source">The source sequence.</param>
|
||||
/// <param name="size">Size of buckets.</param>
|
||||
/// <returns>A sequence of equally sized buckets containing elements of the source collection.</returns>
|
||||
/// <remarks>
|
||||
/// This operator uses deferred execution and streams its results (buckets and bucket content).
|
||||
/// It is also identical to <see cref="Partition{TSource}(System.Collections.Generic.IEnumerable{TSource},int)"/>.
|
||||
/// </remarks>
|
||||
//https://code.google.com/p/morelinq/source/browse/MoreLinq/Batch.cs
|
||||
public static IEnumerable<IEnumerable<TSource>> Batch<TSource>(this IEnumerable<TSource> source, int size)
|
||||
{
|
||||
return Batch(source, size, x =>
|
||||
{
|
||||
var enumerable = x as IList<TSource> ?? x.ToList();
|
||||
return enumerable;
|
||||
});
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Batches the source sequence into sized buckets and applies a projection to each bucket.
|
||||
/// </summary>
|
||||
/// <typeparam name="TSource">Type of elements in <paramref name="source"/> sequence.</typeparam>
|
||||
/// <typeparam name="TResult">Type of result returned by <paramref name="resultSelector"/>.</typeparam>
|
||||
/// <param name="source">The source sequence.</param>
|
||||
/// <param name="size">Size of buckets.</param>
|
||||
/// <param name="resultSelector">The projection to apply to each bucket.</param>
|
||||
/// <returns>A sequence of projections on equally sized buckets containing elements of the source collection.</returns>
|
||||
/// <remarks>
|
||||
/// This operator uses deferred execution and streams its results (buckets and bucket content).
|
||||
/// It is also identical to <see cref="Partition{TSource}(System.Collections.Generic.IEnumerable{TSource},int)"/>.
|
||||
/// </remarks>
|
||||
|
||||
public static IEnumerable<TResult> Batch<TSource, TResult>(this IEnumerable<TSource> source, int size,
|
||||
Func<IEnumerable<TSource>, TResult> resultSelector)
|
||||
{
|
||||
if (source == null) throw new ArgumentNullException(nameof(source));
|
||||
if (size <= 0) throw new ArgumentOutOfRangeException(nameof(size));
|
||||
if (resultSelector == null) throw new ArgumentNullException(nameof(resultSelector));
|
||||
return BatchImpl(source, size, resultSelector);
|
||||
}
|
||||
|
||||
private static IEnumerable<TResult> BatchImpl<TSource, TResult>(this IEnumerable<TSource> source, int size,
|
||||
Func<IEnumerable<TSource>, TResult> resultSelector)
|
||||
{
|
||||
TSource[] bucket = null;
|
||||
var count = 0;
|
||||
|
||||
foreach (var item in source)
|
||||
{
|
||||
if (bucket == null)
|
||||
{
|
||||
bucket = new TSource[size];
|
||||
}
|
||||
|
||||
bucket[count++] = item;
|
||||
|
||||
// The bucket is fully buffered before it's yielded
|
||||
if (count != size)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// Select is necessary so bucket contents are streamed too
|
||||
yield return resultSelector(bucket.Select(x => x));
|
||||
|
||||
bucket = null;
|
||||
count = 0;
|
||||
}
|
||||
|
||||
// Return the last bucket with all remaining elements
|
||||
if (bucket != null && count > 0)
|
||||
{
|
||||
yield return resultSelector(bucket.Take(count));
|
||||
}
|
||||
}
|
||||
|
||||
public static Dictionary<string, int> ColumnDictionary<T>(this IEnumerable<T> data)
|
||||
{
|
||||
return data.FirstOrDefault()?.GetType().GetProperties()
|
||||
.Select((p, i) => new { i, p.Name }).ToDictionary(key => key.Name, value => value.i + 1)
|
||||
?? new Dictionary<string, int>();
|
||||
}
|
||||
|
||||
public static bool IsAny<T>(this IEnumerable<T> data)
|
||||
=> data != null && data.Any();
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,394 @@
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.Infrastructure;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Newtonsoft.Json;
|
||||
using Strata.Stratasphere.Biz.DbContexts;
|
||||
using Strata.Stratasphere.Biz.Mappings;
|
||||
using Strata.Stratasphere.Biz.Mappings.Accounts.Predictions;
|
||||
using Strata.Stratasphere.Biz.RunnableClients;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Process = Strata.Stratasphere.Biz.DataManagement.Models.Process;
|
||||
using Query = Strata.Stratasphere.Biz.DataManagement.Models.Query;
|
||||
|
||||
namespace Strata.Stratasphere.Biz.Extensions
|
||||
{
|
||||
internal static class LogUtilsExtensions
|
||||
{
|
||||
public static Dictionary<string, object> DatabaseDictionary(this Database.Database database, string service)
|
||||
{
|
||||
var dictionary = new Dictionary<string, object> { { "service", service } };
|
||||
if (database != null)
|
||||
{
|
||||
dictionary.Add("db", new Dictionary<string, object> {
|
||||
{ "guid", database.DatabaseGuid },
|
||||
{ "instance", database.PhysicalName },
|
||||
{ "server", database.ServerName },
|
||||
{ "strata_id", database.StrataId },
|
||||
{ "org_pin", database.OrgPin },
|
||||
{ "name", database.DatabaseName }
|
||||
});
|
||||
}
|
||||
return dictionary;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// <para>
|
||||
/// This turns the dbContext connction string into a dictionary of elements.
|
||||
/// </para>
|
||||
/// <para>
|
||||
/// It splits the string by semi-colons, then splits each of those by the equal symbol.
|
||||
/// </para>
|
||||
/// <para>
|
||||
/// The left side is the dictionary key, the right side is the dictionary value, ignoring the Password (if present).
|
||||
/// </para>
|
||||
/// </summary>
|
||||
/// <param name="dbContext"></param>
|
||||
/// <returns></returns>
|
||||
public static Dictionary<string, object> DbContextDictionary(this DatabaseFacade dbContext)
|
||||
{
|
||||
var dictionary = dbContext?.GetConnectionString().Split(';')
|
||||
.Select(x => x.Split('='))
|
||||
.Select(y => new { key = y[0].Replace(" ", ""), value = y[1] })
|
||||
.Where(x => !new[] { "password" }.Contains(x.key.ToLowerInvariant()))
|
||||
.ToDictionary(x => x.key, x => x.value) ?? new Dictionary<string, string>();
|
||||
return new Dictionary<string, object> { { "dbContext", dictionary } };
|
||||
}
|
||||
|
||||
public static void LogMappingJobError<T>(this ILogger<T> _logger, Exception ex, Database.Database database, string jobName)
|
||||
=> _logger.LogMappingError<T>(ex, database, $"{jobName} Job Failed");
|
||||
|
||||
public static void LogMappingCodesRemoved<T>(this ILogger<T> _logger, Database.Database database, IEnumerable<string> codes)
|
||||
=> _logger.LogMappingJobInfo(database, codes, "Codes were removed from the client");
|
||||
|
||||
public static void LogMappingMissingRollups<T>(this ILogger<T> _logger, Database.Database database, IEnumerable<string> codes)
|
||||
=> _logger.LogMappingJobInfo(database, codes, "Rollups not found for these codes");
|
||||
|
||||
public static void LogMappingUpdatedCodes<T>(this ILogger<T> _logger, Database.Database database, IEnumerable<string> codes)
|
||||
=> _logger.LogMappingJobInfo(database, codes, "Codes to update in Jazz");
|
||||
|
||||
private static void LogMappingJobInfo<T>(this ILogger<T> _logger, Database.Database database, IEnumerable<string> codes, string message)
|
||||
{
|
||||
message = $"{codes?.Count() ?? 0} {message} on {database.DatabaseName}";
|
||||
var scopeDictionary = database.DatabaseDictionary(typeof(T).Name)
|
||||
.Union(new Dictionary<string, object> { { "message", message }, { "codes", codes?.OrderBy(code => code) } });
|
||||
using (_logger.BeginScope(scopeDictionary))
|
||||
_logger.LogInformation(message);
|
||||
}
|
||||
|
||||
public static void LogPredictionWithNoMatchingRollup<T>(this ILogger<T> _logger, Database.Database database, IEnumerable<GLAccountClassification> predictions)
|
||||
=> _logger.LogMappingJobPredictionInfo(database, predictions, "Prediction(s) had no matching rollups, cannot assign a rollup id.");
|
||||
|
||||
private static void LogMappingJobPredictionInfo<T>(this ILogger<T> _logger, Database.Database database, IEnumerable<GLAccountClassification> predictions, string message)
|
||||
{
|
||||
message = $"{predictions?.Count() ?? 0} {message} on {database.DatabaseName}";
|
||||
var predictionJson = predictions?.OrderBy(prediction => prediction.AccountId).Select(prediction => JsonConvert.SerializeObject(prediction));
|
||||
var scopeDictionary = database.DatabaseDictionary(typeof(T).Name)
|
||||
.Union(new Dictionary<string, object> {
|
||||
{ "message", message },
|
||||
{ "predictions", predictions?.OrderBy(prediction => prediction.AccountId)
|
||||
.Select(prediction => new Dictionary<string, object> {
|
||||
{ "AccountId", prediction.AccountId },
|
||||
{ "Description", prediction.Description },
|
||||
{ "Prediction", prediction.Prediction },
|
||||
{ "Probability", prediction.Probability }
|
||||
}
|
||||
)}
|
||||
});
|
||||
using (_logger.BeginScope(scopeDictionary))
|
||||
_logger.LogInformation(message);
|
||||
}
|
||||
|
||||
public static void LogMappingMetaDataError<T>(this ILogger<T> _logger, Exception ex, Database.Database database, string sql, string query)
|
||||
{
|
||||
var meta = new Dictionary<string, object> { { "query", sql } };
|
||||
using (_logger.BeginScope(database.DatabaseDictionary(typeof(T).Name).Union(meta)))
|
||||
_logger.LogError(ex, query);
|
||||
}
|
||||
|
||||
public static void LogMappingError<T>(this ILogger<T> _logger, Exception ex, Database.Database database, string jobName)
|
||||
{
|
||||
using (_logger.BeginScope(database.DatabaseDictionary(typeof(T).Name)))
|
||||
_logger.LogError(ex, jobName);
|
||||
}
|
||||
|
||||
public static void LogJazzUpdateError<T>(this ILogger<T> _logger, Exception ex, Database.Database database, DatabaseFacade dbContext, string jobName)
|
||||
{
|
||||
var dictionary = database.DatabaseDictionary(typeof(T).Name);
|
||||
dictionary.Union(dbContext.DbContextDictionary());
|
||||
using (_logger.BeginScope(dictionary))
|
||||
_logger.LogError(ex, jobName);
|
||||
}
|
||||
|
||||
public static void LogJazzUpdateInfo<T>(this ILogger<T> _logger, Database.Database database, JazzDbContext dbContext, string message)
|
||||
=> _logger.LogJazzUpdateInfo(database, dbContext.Database, message);
|
||||
|
||||
public static void LogJazzUpdateInfo<T>(this ILogger<T> _logger, Database.Database database, DatabaseFacade dbContext, string message)
|
||||
{
|
||||
var dictionary = database.DatabaseDictionary(typeof(T).Name);
|
||||
dictionary.Union(dbContext.DbContextDictionary());
|
||||
using (_logger.BeginScope(dictionary))
|
||||
_logger.LogInformation(message);
|
||||
}
|
||||
|
||||
public static void LogJazzUpdateAwaitingUpdate<T>(this ILogger<T> _logger, Database.Database database, IEnumerable<string> codes)
|
||||
=> _logger.LogJazzUpdateDetails(database, codes, "Items awaiting jazz update");
|
||||
|
||||
public static void LogJazzUpdateAwaitingUpdate<T>(this ILogger<T> _logger, Database.Database database, IEnumerable<int> ids)
|
||||
=> _logger.LogJazzUpdateDetails(database, ids, "Items awaiting jazz update");
|
||||
|
||||
public static void LogJazzUpdateAwaitingReset<T>(this ILogger<T> _logger, Database.Database database, IEnumerable<string> codes)
|
||||
=> _logger.LogJazzUpdateDetails(database, codes, "Items awaiting jazz update, reset to false");
|
||||
|
||||
public static void LogJazzUpdateCodesNotFound<T>(this ILogger<T> _logger, Database.Database database, JazzDbContext dbContext,
|
||||
IEnumerable<string> codes)
|
||||
=> _logger.LogJazzUpdateDetails(database, dbContext, codes, "Codes not found");
|
||||
|
||||
public static void LogJazzUpdateNotChanged<T>(this ILogger<T> _logger, Database.Database database, JazzDbContext dbContext,
|
||||
IEnumerable<LogInfo> items)
|
||||
=> _logger.LogJazzUpdateDetails(database, dbContext, items, "Not Changed");
|
||||
|
||||
public static void LogJazzUpdateIdChanged<T>(this ILogger<T> _logger, Database.Database database, JazzDbContext dbContext,
|
||||
IEnumerable<LogInfo> items)
|
||||
=> _logger.LogJazzUpdateDetails(database, dbContext, items, "Id Changed");
|
||||
|
||||
public static void LogJazzUpdateUpdated<T>(this ILogger<T> _logger, Database.Database database, JazzDbContext dbContext,
|
||||
IEnumerable<LogInfo> items)
|
||||
=> _logger.LogJazzUpdateDetails(database, dbContext, items, "Updated");
|
||||
|
||||
private static void LogJazzUpdateDetails<T>(this ILogger<T> _logger, Database.Database database,
|
||||
IEnumerable<LogInfo> items, string context)
|
||||
{
|
||||
var dictionary = database.DatabaseDictionary(typeof(T).Name);
|
||||
dictionary.Add(context.Replace(" ", "_").ToLower(),
|
||||
items.OrderBy(item => item.Code).Select(item => item.KeyValuePairs));
|
||||
var message = $"{items.Count()} Items {context} on {database.DatabaseName}";
|
||||
using (_logger.BeginScope(dictionary))
|
||||
_logger.LogInformation(message);
|
||||
}
|
||||
|
||||
private static void LogJazzUpdateDetails<T>(this ILogger<T> _logger, Database.Database database, JazzDbContext dbContext,
|
||||
IEnumerable<LogInfo> items, string context)
|
||||
{
|
||||
var dictionary = database.DatabaseDictionary(typeof(T).Name);
|
||||
dictionary.Union(dbContext.Database.DbContextDictionary());
|
||||
dictionary.Add(context.Replace(" ", "_").ToLower(),
|
||||
items.OrderBy(item => item.Code).Select(item => item.KeyValuePairs));
|
||||
var message = $"{items.Count()} Items {context} on {database.DatabaseName}";
|
||||
using (_logger.BeginScope(dictionary))
|
||||
_logger.LogInformation(message);
|
||||
}
|
||||
|
||||
private static void LogJazzUpdateDetails<T>(this ILogger<T> _logger, Database.Database database, JazzDbContext dbContext,
|
||||
IEnumerable<string> codes, string context)
|
||||
{
|
||||
var dictionary = database.DatabaseDictionary(typeof(T).Name);
|
||||
dictionary.Union(dbContext.Database.DbContextDictionary());
|
||||
dictionary.Add(context.Replace(" ", "_").ToLower(),
|
||||
codes.OrderBy(code => code).Select(item => item));
|
||||
using (_logger.BeginScope(dictionary))
|
||||
_logger.LogInformation($"{codes.Count()} Items {context} on {database.DatabaseName}");
|
||||
}
|
||||
|
||||
private static void LogJazzUpdateDetails<T>(this ILogger<T> _logger, Database.Database database,
|
||||
IEnumerable<string> codes, string context)
|
||||
{
|
||||
var dictionary = database.DatabaseDictionary(typeof(T).Name);
|
||||
dictionary.Add(context.Replace(" ", "_").ToLower(),
|
||||
codes.OrderBy(code => code).Select(item => item));
|
||||
using (_logger.BeginScope(dictionary))
|
||||
_logger.LogInformation($"{codes.Count()} Items {context} on {database.DatabaseName}");
|
||||
}
|
||||
|
||||
private static void LogJazzUpdateDetails<T>(this ILogger<T> _logger, Database.Database database,
|
||||
IEnumerable<int> ids, string context)
|
||||
{
|
||||
var dictionary = database.DatabaseDictionary(typeof(T).Name);
|
||||
dictionary.Add(context.Replace(" ", "_").ToLower(),
|
||||
ids.OrderBy(id => id).Select(item => item));
|
||||
using (_logger.BeginScope(dictionary))
|
||||
_logger.LogInformation($"{ids.Count()} Items {context} on {database.DatabaseName}");
|
||||
}
|
||||
|
||||
public static void LogProcessInfo<T>(this ILogger<T> _logger, Process process, string message)
|
||||
{
|
||||
var dictionary = new Dictionary<string, object> { { "service", typeof(T).Name },
|
||||
{ "process", new Dictionary<string, object>{
|
||||
{ "id", process.ProcessId },
|
||||
{ "name", process.Name } }
|
||||
} };
|
||||
using (_logger.BeginScope(dictionary))
|
||||
_logger.LogInformation(message);
|
||||
}
|
||||
|
||||
public static void LogProcessRunnables<T>(this ILogger<T> _logger, Process process, IEnumerable<RunnableClientDto> runnables, string message)
|
||||
{
|
||||
var dictionary = new Dictionary<string, object> { { "service", typeof(T).Name },
|
||||
{ "process", new Dictionary<string, object>{
|
||||
{ "id", process.ProcessId },
|
||||
{ "name", process.Name } }
|
||||
},
|
||||
{ "runnables", runnables.OrderBy(r => r.Index).Select(r => r.KeyValuePairs) } };
|
||||
using (_logger.BeginScope(dictionary))
|
||||
_logger.LogInformation(message);
|
||||
}
|
||||
|
||||
public static void LogProcessRunnables<T>(this ILogger<T> _logger, int processId, string processName, IEnumerable<RunnableClientDto> runnables, string message)
|
||||
{
|
||||
var dictionary = new Dictionary<string, object> { { "service", typeof(T).Name },
|
||||
{ "process", new Dictionary<string, object>{
|
||||
{ "id", processId },
|
||||
{ "name", processName } }
|
||||
},
|
||||
{ "runnables", runnables.OrderBy(r => r.Index).Select(r => r.KeyValuePairs) } };
|
||||
using (_logger.BeginScope(dictionary))
|
||||
_logger.LogInformation(message);
|
||||
}
|
||||
|
||||
public static void LogUnrunnableIds<T>(this ILogger<T> _logger, Process process, IEnumerable<int> strataIds, string message)
|
||||
{
|
||||
var dictionary = new Dictionary<string, object> { { "service", typeof(T).Name },
|
||||
{ "process", new Dictionary<string, object>{
|
||||
{ "id", process.ProcessId },
|
||||
{ "name", process.Name } }
|
||||
},
|
||||
{ "strataIds", strataIds } };
|
||||
using (_logger.BeginScope(dictionary))
|
||||
_logger.LogInformation(message);
|
||||
}
|
||||
|
||||
public static void LogServiceError<T>(this ILogger<T> _logger, Exception ex, string message)
|
||||
{
|
||||
using (_logger.BeginScope(new Dictionary<string, object> { { "service", typeof(T).Name } }))
|
||||
_logger.LogError(ex, message);
|
||||
}
|
||||
|
||||
public static void LogServiceError<T>(this ILogger<T> _logger, Exception ex, string query, string message)
|
||||
{
|
||||
using (_logger.BeginScope(new Dictionary<string, object>
|
||||
{
|
||||
{ "service", typeof(T).Name },
|
||||
{ "query", query }
|
||||
}))
|
||||
_logger.LogError(ex, message);
|
||||
}
|
||||
|
||||
public static void LogDebugInfo<T>(this ILogger<T> _logger, Database.Database db, string fileName, string message)
|
||||
{
|
||||
var dbDictionary = db.DatabaseDictionary(typeof(T).Name);
|
||||
dbDictionary.Add("fileName", fileName);
|
||||
using (_logger.BeginScope(dbDictionary))
|
||||
_logger.LogInformation(message);
|
||||
}
|
||||
|
||||
public static void LogDebugInfo<T>(this ILogger<T> _logger, string fileName, string message)
|
||||
=> _logger.LogDebugInfo(null, fileName, message);
|
||||
|
||||
public static void LogImportError<T>(this ILogger<T> _logger, Exception ex, Database.Database db, string fileName, string message)
|
||||
{
|
||||
var dbDictionary = db.DatabaseDictionary(typeof(T).Name);
|
||||
dbDictionary.Add("fileName", fileName);
|
||||
using (_logger.BeginScope(dbDictionary))
|
||||
_logger.LogError(ex, message);
|
||||
}
|
||||
|
||||
public static void LogImportError<T>(this ILogger<T> _logger, Exception ex, string fileName, string message)
|
||||
=> _logger.LogImportError(ex, null, fileName, message);
|
||||
|
||||
public static void LogImportError<T>(this ILogger<T> _logger, string fileName, IEnumerable<IMapping> batch, Database.Database db, string message)
|
||||
{
|
||||
var dictionary = db.DatabaseDictionary(typeof(T).Name);
|
||||
dictionary.GetBatchDictionary(batch)
|
||||
.Add("fileName", fileName);
|
||||
using (_logger.BeginScope(dictionary))
|
||||
_logger.LogError(message);
|
||||
}
|
||||
|
||||
public static void LogImportError<T>(this ILogger<T> _logger, Exception ex, string fileName, IEnumerable<object> batch, Database.Database db, string message)
|
||||
{
|
||||
var dictionary = db.DatabaseDictionary(typeof(T).Name);
|
||||
dictionary.GetBatchDictionary(batch)
|
||||
.Add("fileName", fileName);
|
||||
using (_logger.BeginScope(dictionary))
|
||||
_logger.LogError(ex, message);
|
||||
}
|
||||
|
||||
private static Dictionary<string, object> GetBatchDictionary(this Dictionary<string, object> dictionary, IEnumerable<object> batch)
|
||||
{
|
||||
dictionary.Add("batch", JsonConvert.SerializeObject(batch, Formatting.Indented,
|
||||
new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore }));
|
||||
return dictionary;
|
||||
}
|
||||
|
||||
public static void LogPredictionServiceError<T>(this ILogger<T> _logger, Exception ex, string prediction, string orgPin, int strataId)
|
||||
{
|
||||
var dictionary = new Dictionary<string, object>
|
||||
{
|
||||
{ "strataId", strataId },
|
||||
{ "orgPin", orgPin }
|
||||
};
|
||||
using (_logger.BeginScope(new Dictionary<string, object> { { "service", typeof(T).Name }, { "db", dictionary } }))
|
||||
_logger.LogError(ex, "{prediction} Prediction failed.", new[] { prediction });
|
||||
}
|
||||
|
||||
public static void LogGithubUserTokenMissing<T>(this ILogger<T> _logger, string user, Process process)
|
||||
{
|
||||
using (_logger.BeginScope(new Dictionary<string, object>
|
||||
{
|
||||
{ "service", typeof(T).Name },
|
||||
{ "user", user },
|
||||
{ "process", JsonConvert.SerializeObject(process) }
|
||||
}))
|
||||
_logger.LogInformation("User '{user}' doesn't have a github token.", new[] { user });
|
||||
}
|
||||
|
||||
public static void LogGithubUserTokenMissing<T>(this ILogger<T> _logger, string user, Query query)
|
||||
{
|
||||
using (_logger.BeginScope(new Dictionary<string, object>
|
||||
{
|
||||
{ "service", typeof(T).Name },
|
||||
{ "user", user },
|
||||
{ "query", JsonConvert.SerializeObject(query) }
|
||||
}))
|
||||
_logger.LogInformation("User '{user}' doesn't have a github token.", new[] { user });
|
||||
}
|
||||
}
|
||||
|
||||
public class LogInfo
|
||||
{
|
||||
public string Code { get; set; }
|
||||
public int RollupId { get; set; }
|
||||
public string RollupCode { get; set; }
|
||||
public string Name { get; set; }
|
||||
public bool IsValidated { get; set; }
|
||||
public LogInfo(string code, int rollupId, string name, bool isValidated)
|
||||
{
|
||||
Code = code;
|
||||
RollupId = rollupId;
|
||||
Name = name;
|
||||
IsValidated = isValidated;
|
||||
}
|
||||
public LogInfo(string code, string rollupCode, string name, bool isValidated)
|
||||
{
|
||||
Code = code;
|
||||
RollupCode = rollupCode;
|
||||
Name = name;
|
||||
IsValidated = isValidated;
|
||||
}
|
||||
public Dictionary<string, object> KeyValuePairs
|
||||
=> RollupCode == null ? new()
|
||||
{
|
||||
{ "code", Code } ,
|
||||
{ "rollupId", RollupId},
|
||||
{ "name", Name },
|
||||
{ "isValidated", IsValidated }
|
||||
} : new()
|
||||
{
|
||||
{ "code", Code } ,
|
||||
{ "rollupCode", RollupCode},
|
||||
{ "name", Name },
|
||||
{ "isValidated", IsValidated }
|
||||
};
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user