mirror of
https://github.com/Sudo-JHare/FHIRFLARE-IG-Toolkit.git
synced 2025-11-05 17:45:14 +00:00
Compare commits
3 Commits
f1478561c1
...
85f980be0a
| Author | SHA1 | Date | |
|---|---|---|---|
| 85f980be0a | |||
| d37af01b3a | |||
| 6ae0e56118 |
@ -2,57 +2,130 @@
|
||||
setlocal enabledelayedexpansion
|
||||
|
||||
REM --- Configuration ---
|
||||
set REPO_URL=https://github.com/hapifhir/hapi-fhir-jpaserver-starter.git
|
||||
set CLONE_DIR=hapi-fhir-jpaserver
|
||||
set REPO_URL_HAPI=https://github.com/hapifhir/hapi-fhir-jpaserver-starter.git
|
||||
set REPO_URL_CANDLE=https://github.com/FHIR/fhir-candle.git
|
||||
set CLONE_DIR_HAPI=hapi-fhir-jpaserver
|
||||
set CLONE_DIR_CANDLE=fhir-candle
|
||||
set SOURCE_CONFIG_DIR=hapi-fhir-setup
|
||||
set CONFIG_FILE=application.yaml
|
||||
|
||||
REM --- Define Paths ---
|
||||
set SOURCE_CONFIG_PATH=..\%SOURCE_CONFIG_DIR%\target\classes\%CONFIG_FILE%
|
||||
set DEST_CONFIG_PATH=%CLONE_DIR%\target\classes\%CONFIG_FILE%
|
||||
set DEST_CONFIG_PATH=%CLONE_DIR_HAPI%\target\classes\%CONFIG_FILE%
|
||||
|
||||
REM === CORRECTED: Prompt for Version ===
|
||||
REM --- NEW: Define a variable for the custom FHIR URL and server type ---
|
||||
set "CUSTOM_FHIR_URL_VAL="
|
||||
set "SERVER_TYPE="
|
||||
set "CANDLE_FHIR_VERSION="
|
||||
|
||||
REM === MODIFIED: Prompt for Installation Mode ===
|
||||
:GetModeChoice
|
||||
SET "APP_MODE=" REM Clear the variable first
|
||||
echo.
|
||||
echo Select Installation Mode:
|
||||
echo 1. Standalone (Includes local HAPI FHIR Server - Requires Git & Maven)
|
||||
echo 2. Lite (Excludes local HAPI FHIR Server - No Git/Maven needed)
|
||||
CHOICE /C 12 /N /M "Enter your choice (1 or 2):"
|
||||
echo 1. Lite (Excludes local HAPI FHIR Server - No Git/Maven/Dotnet needed)
|
||||
echo 2. Custom URL (Uses a custom FHIR Server - No Git/Maven/Dotnet needed)
|
||||
echo 3. Hapi (Includes local HAPI FHIR Server - Requires Git & Maven)
|
||||
echo 4. Candle (Includes local FHIR Candle Server - Requires Git & Dotnet)
|
||||
CHOICE /C 1234 /N /M "Enter your choice (1, 2, 3, or 4):"
|
||||
|
||||
IF ERRORLEVEL 4 (
|
||||
SET APP_MODE=standalone
|
||||
SET SERVER_TYPE=candle
|
||||
goto :GetCandleFhirVersion
|
||||
)
|
||||
IF ERRORLEVEL 3 (
|
||||
SET APP_MODE=standalone
|
||||
SET SERVER_TYPE=hapi
|
||||
goto :ModeSet
|
||||
)
|
||||
IF ERRORLEVEL 2 (
|
||||
SET APP_MODE=standalone
|
||||
goto :GetCustomUrl
|
||||
)
|
||||
IF ERRORLEVEL 1 (
|
||||
SET APP_MODE=lite
|
||||
goto :ModeSet
|
||||
)
|
||||
IF ERRORLEVEL 1 (
|
||||
SET APP_MODE=standalone
|
||||
goto :ModeSet
|
||||
)
|
||||
|
||||
REM If somehow neither was chosen (e.g., Ctrl+C), loop back
|
||||
echo Invalid input. Please try again.
|
||||
goto :GetModeChoice
|
||||
|
||||
:GetCustomUrl
|
||||
set "CONFIRMED_URL="
|
||||
:PromptUrlLoop
|
||||
echo.
|
||||
set /p "CUSTOM_URL_INPUT=Please enter the custom FHIR server URL: "
|
||||
echo.
|
||||
echo You entered: !CUSTOM_URL_INPUT!
|
||||
set /p "CONFIRM_URL=Is this URL correct? (Y/N): "
|
||||
if /i "!CONFIRM_URL!" EQU "Y" (
|
||||
set "CONFIRMED_URL=!CUSTOM_URL_INPUT!"
|
||||
goto :ConfirmUrlLoop
|
||||
) else (
|
||||
goto :PromptUrlLoop
|
||||
)
|
||||
:ConfirmUrlLoop
|
||||
echo.
|
||||
echo Please re-enter the URL to confirm it is correct:
|
||||
set /p "CUSTOM_URL_INPUT=Re-enter URL: "
|
||||
if /i "!CUSTOM_URL_INPUT!" EQU "!CONFIRMED_URL!" (
|
||||
set "CUSTOM_FHIR_URL_VAL=!CUSTOM_URL_INPUT!"
|
||||
echo.
|
||||
echo Custom URL confirmed: !CUSTOM_FHIR_URL_VAL!
|
||||
goto :ModeSet
|
||||
) else (
|
||||
echo.
|
||||
echo URLs do not match. Please try again.
|
||||
goto :PromptUrlLoop
|
||||
)
|
||||
|
||||
:GetCandleFhirVersion
|
||||
echo.
|
||||
echo Select the FHIR version for the Candle server:
|
||||
echo 1. R4 (4.0)
|
||||
echo 2. R4B (4.3)
|
||||
echo 3. R5 (5.0)
|
||||
CHOICE /C 123 /N /M "Enter your choice (1, 2, or 3):"
|
||||
IF ERRORLEVEL 3 (
|
||||
SET CANDLE_FHIR_VERSION=r5
|
||||
goto :ModeSet
|
||||
)
|
||||
IF ERRORLEVEL 2 (
|
||||
SET CANDLE_FHIR_VERSION=r4b
|
||||
goto :ModeSet
|
||||
)
|
||||
IF ERRORLEVEL 1 (
|
||||
SET CANDLE_FHIR_VERSION=r4
|
||||
goto :ModeSet
|
||||
)
|
||||
echo Invalid input. Please try again.
|
||||
goto :GetCandleFhirVersion
|
||||
|
||||
:ModeSet
|
||||
IF "%APP_MODE%"=="" (
|
||||
echo Invalid choice detected after checks. Exiting.
|
||||
goto :eof
|
||||
)
|
||||
echo Selected Mode: %APP_MODE%
|
||||
echo Server Type: %SERVER_TYPE%
|
||||
echo.
|
||||
REM === END CORRECTION ===
|
||||
REM === END MODIFICATION ===
|
||||
|
||||
|
||||
REM === Conditionally Execute HAPI Setup ===
|
||||
IF "%APP_MODE%"=="standalone" (
|
||||
echo Running Standalone setup including HAPI FHIR...
|
||||
REM === Conditionally Execute Server Setup ===
|
||||
IF "%SERVER_TYPE%"=="hapi" (
|
||||
echo Running Hapi server setup...
|
||||
echo.
|
||||
|
||||
|
||||
REM --- Step 0: Clean up previous clone (optional) ---
|
||||
echo Checking for existing directory: %CLONE_DIR%
|
||||
if exist "%CLONE_DIR%" (
|
||||
echo Checking for existing directory: %CLONE_DIR_HAPI%
|
||||
if exist "%CLONE_DIR_HAPI%" (
|
||||
echo Found existing directory, removing it...
|
||||
rmdir /s /q "%CLONE_DIR%"
|
||||
rmdir /s /q "%CLONE_DIR_HAPI%"
|
||||
if errorlevel 1 (
|
||||
echo ERROR: Failed to remove existing directory: %CLONE_DIR%
|
||||
echo ERROR: Failed to remove existing directory: %CLONE_DIR_HAPI%
|
||||
goto :error
|
||||
)
|
||||
echo Existing directory removed.
|
||||
@ -62,8 +135,8 @@ IF "%APP_MODE%"=="standalone" (
|
||||
echo.
|
||||
|
||||
REM --- Step 1: Clone the HAPI FHIR server repository ---
|
||||
echo Cloning repository: %REPO_URL% into %CLONE_DIR%...
|
||||
git clone "%REPO_URL%" "%CLONE_DIR%"
|
||||
echo Cloning repository: %REPO_URL_HAPI% into %CLONE_DIR_HAPI%...
|
||||
git clone "%REPO_URL_HAPI%" "%CLONE_DIR_HAPI%"
|
||||
if errorlevel 1 (
|
||||
echo ERROR: Failed to clone repository. Check Git installation and network connection.
|
||||
goto :error
|
||||
@ -72,10 +145,10 @@ IF "%APP_MODE%"=="standalone" (
|
||||
echo.
|
||||
|
||||
REM --- Step 2: Navigate into the cloned directory ---
|
||||
echo Changing directory to %CLONE_DIR%...
|
||||
cd "%CLONE_DIR%"
|
||||
echo Changing directory to %CLONE_DIR_HAPI%...
|
||||
cd "%CLONE_DIR_HAPI%"
|
||||
if errorlevel 1 (
|
||||
echo ERROR: Failed to change directory to %CLONE_DIR%.
|
||||
echo ERROR: Failed to change directory to %CLONE_DIR_HAPI%.
|
||||
goto :error
|
||||
)
|
||||
echo Current directory: %CD%
|
||||
@ -92,7 +165,7 @@ IF "%APP_MODE%"=="standalone" (
|
||||
)
|
||||
echo Maven build completed successfully. ErrorLevel: %errorlevel%
|
||||
echo.
|
||||
|
||||
|
||||
REM --- Step 4: Copy the configuration file ---
|
||||
echo ===> "Starting file copy (Step 4)..."
|
||||
echo Copying configuration file...
|
||||
@ -118,47 +191,141 @@ IF "%APP_MODE%"=="standalone" (
|
||||
echo Current directory: %CD%
|
||||
echo.
|
||||
|
||||
) ELSE (
|
||||
echo Running Lite setup, skipping HAPI FHIR build...
|
||||
REM Ensure the hapi-fhir-jpaserver directory doesn't exist or is empty if Lite mode is chosen after a standalone attempt
|
||||
if exist "%CLONE_DIR%" (
|
||||
echo Found existing HAPI directory in Lite mode. Removing it to avoid build issues...
|
||||
rmdir /s /q "%CLONE_DIR%"
|
||||
) ELSE IF "%SERVER_TYPE%"=="candle" (
|
||||
echo Running FHIR Candle server setup...
|
||||
echo.
|
||||
|
||||
REM --- Step 0: Clean up previous clone (optional) ---
|
||||
echo Checking for existing directory: %CLONE_DIR_CANDLE%
|
||||
if exist "%CLONE_DIR_CANDLE%" (
|
||||
echo Found existing directory, removing it...
|
||||
rmdir /s /q "%CLONE_DIR_CANDLE%"
|
||||
if errorlevel 1 (
|
||||
echo ERROR: Failed to remove existing directory: %CLONE_DIR_CANDLE%
|
||||
goto :error
|
||||
)
|
||||
echo Existing directory removed.
|
||||
) else (
|
||||
echo Directory does not exist, proceeding with clone.
|
||||
)
|
||||
REM Create empty target directories expected by Dockerfile COPY, even if not used
|
||||
mkdir "%CLONE_DIR%\target\classes" 2> nul
|
||||
mkdir "%CLONE_DIR%\custom" 2> nul
|
||||
REM Create a placeholder empty WAR file to satisfy Dockerfile COPY
|
||||
echo. > "%CLONE_DIR%\target\ROOT.war"
|
||||
echo. > "%CLONE_DIR%\target\classes\application.yaml"
|
||||
echo.
|
||||
|
||||
REM --- Step 1: Clone the FHIR Candle server repository ---
|
||||
echo Cloning repository: %REPO_URL_CANDLE% into %CLONE_DIR_CANDLE%...
|
||||
git clone "%REPO_URL_CANDLE%" "%CLONE_DIR_CANDLE%"
|
||||
if errorlevel 1 (
|
||||
echo ERROR: Failed to clone repository. Check Git and Dotnet installation and network connection.
|
||||
goto :error
|
||||
)
|
||||
echo Repository cloned successfully.
|
||||
echo.
|
||||
|
||||
REM --- Step 2: Navigate into the cloned directory ---
|
||||
echo Changing directory to %CLONE_DIR_CANDLE%...
|
||||
cd "%CLONE_DIR_CANDLE%"
|
||||
if errorlevel 1 (
|
||||
echo ERROR: Failed to change directory to %CLONE_DIR_CANDLE%.
|
||||
goto :error
|
||||
)
|
||||
echo Current directory: %CD%
|
||||
echo.
|
||||
|
||||
REM --- Step 3: Build the FHIR Candle server using Dotnet ---
|
||||
echo ===> "Starting Dotnet build (Step 3)...""
|
||||
dotnet publish -c Release -f net9.0 -o publish
|
||||
echo ===> Dotnet command finished. Checking error level...
|
||||
if errorlevel 1 (
|
||||
echo ERROR: Dotnet build failed. Check Dotnet SDK installation.
|
||||
cd ..
|
||||
goto :error
|
||||
)
|
||||
echo Dotnet build completed successfully. ErrorLevel: %errorlevel%
|
||||
echo.
|
||||
|
||||
REM --- Step 4: Navigate back to the parent directory ---
|
||||
echo ===> "Changing directory back (Step 4)..."
|
||||
cd ..
|
||||
if errorlevel 1 (
|
||||
echo ERROR: Failed to change back to the parent directory. ErrorLevel: %errorlevel%
|
||||
goto :error
|
||||
)
|
||||
echo Current directory: %CD%
|
||||
echo.
|
||||
|
||||
) ELSE (
|
||||
echo Running Lite setup, skipping server build...
|
||||
REM Ensure the server directories don't exist in Lite mode
|
||||
if exist "%CLONE_DIR_HAPI%" (
|
||||
echo Found existing HAPI directory in Lite mode. Removing it to avoid build issues...
|
||||
rmdir /s /q "%CLONE_DIR_HAPI%"
|
||||
)
|
||||
if exist "%CLONE_DIR_CANDLE%" (
|
||||
echo Found existing Candle directory in Lite mode. Removing it to avoid build issues...
|
||||
rmdir /s /q "%CLONE_DIR_CANDLE%"
|
||||
)
|
||||
REM Create empty placeholder files to satisfy Dockerfile COPY commands in Lite mode.
|
||||
mkdir "%CLONE_DIR_HAPI%\target\classes" 2> nul
|
||||
mkdir "%CLONE_DIR_HAPI%\custom" 2> nul
|
||||
echo. > "%CLONE_DIR_HAPI%\target\ROOT.war"
|
||||
echo. > "%CLONE_DIR_HAPI%\target\classes\application.yaml"
|
||||
mkdir "%CLONE_DIR_CANDLE%\publish" 2> nul
|
||||
echo. > "%CLONE_DIR_CANDLE%\publish\fhir-candle.dll"
|
||||
echo Placeholder files created for Lite mode build.
|
||||
echo.
|
||||
)
|
||||
|
||||
REM === Modify docker-compose.yml to set APP_MODE ===
|
||||
echo Updating docker-compose.yml with APP_MODE=%APP_MODE%...
|
||||
REM === MODIFIED: Update docker-compose.yml to set APP_MODE and HAPI_FHIR_URL ===
|
||||
echo Updating docker-compose.yml with APP_MODE=%APP_MODE% and HAPI_FHIR_URL...
|
||||
(
|
||||
echo version: '3.8'
|
||||
echo services:
|
||||
echo fhirflare:
|
||||
echo build:
|
||||
echo context: .
|
||||
echo dockerfile: Dockerfile
|
||||
IF "%SERVER_TYPE%"=="hapi" (
|
||||
echo dockerfile: Dockerfile.hapi
|
||||
) ELSE IF "%SERVER_TYPE%"=="candle" (
|
||||
echo dockerfile: Dockerfile.candle
|
||||
) ELSE (
|
||||
echo dockerfile: Dockerfile.lite
|
||||
)
|
||||
echo ports:
|
||||
echo - "5000:5000"
|
||||
echo - "8080:8080" # Keep port exposed, even if Tomcat isn't running useful stuff in Lite
|
||||
IF "%SERVER_TYPE%"=="candle" (
|
||||
echo - "5000:5000"
|
||||
echo - "5001:5826"
|
||||
) ELSE (
|
||||
echo - "5000:5000"
|
||||
echo - "8080:8080"
|
||||
)
|
||||
echo volumes:
|
||||
echo - ./instance:/app/instance
|
||||
echo - ./static/uploads:/app/static/uploads
|
||||
echo - ./instance/hapi-h2-data/:/app/h2-data # Keep volume mounts consistent
|
||||
IF "%SERVER_TYPE%"=="hapi" (
|
||||
echo - ./instance/hapi-h2-data/:/app/h2-data # Keep volume mounts consistent
|
||||
)
|
||||
echo - ./logs:/app/logs
|
||||
IF "%SERVER_TYPE%"=="hapi" (
|
||||
echo - ./hapi-fhir-jpaserver/target/ROOT.war:/usr/local/tomcat/webapps/ROOT.war
|
||||
echo - ./hapi-fhir-jpaserver/target/classes/application.yaml:/usr/local/tomcat/conf/application.yaml
|
||||
) ELSE IF "%SERVER_TYPE%"=="candle" (
|
||||
echo - ./fhir-candle/publish/:/app/fhir-candle-publish/
|
||||
)
|
||||
echo environment:
|
||||
echo - FLASK_APP=app.py
|
||||
echo - FLASK_ENV=development
|
||||
echo - NODE_PATH=/usr/lib/node_modules
|
||||
echo - APP_MODE=%APP_MODE%
|
||||
echo - APP_BASE_URL=http://localhost:5000
|
||||
echo - HAPI_FHIR_URL=http://localhost:8080/fhir
|
||||
IF DEFINED CUSTOM_FHIR_URL_VAL (
|
||||
echo - HAPI_FHIR_URL=!CUSTOM_FHIR_URL_VAL!
|
||||
) ELSE (
|
||||
IF "%SERVER_TYPE%"=="candle" (
|
||||
echo - HAPI_FHIR_URL=http://localhost:5826/fhir/%CANDLE_FHIR_VERSION%
|
||||
echo - ASPNETCORE_URLS=http://0.0.0.0:5826
|
||||
) ELSE (
|
||||
echo - HAPI_FHIR_URL=http://localhost:8080/fhir
|
||||
)
|
||||
)
|
||||
echo command: supervisord -c /etc/supervisord.conf
|
||||
) > docker-compose.yml.tmp
|
||||
|
||||
@ -208,4 +375,4 @@ exit /b 1
|
||||
|
||||
:eof
|
||||
echo Script execution finished.
|
||||
pause
|
||||
pause
|
||||
|
||||
15
Dockerfile
15
Dockerfile
@ -3,13 +3,16 @@ FROM tomcat:10.1-jdk17
|
||||
|
||||
# Install build dependencies, Node.js 18, and coreutils (for stdbuf)
|
||||
RUN apt-get update && apt-get install -y --no-install-recommends \
|
||||
python3 python3-pip python3-venv curl coreutils \
|
||||
python3 python3-pip python3-venv curl coreutils git \
|
||||
&& curl -fsSL https://deb.nodesource.com/setup_18.x | bash - \
|
||||
&& apt-get install -y --no-install-recommends nodejs \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
# ADDED: Install the Dotnet SDK for the FHIR Candle server
|
||||
# This makes the image a universal base for either server type
|
||||
RUN apt-get update && apt-get install -y dotnet-sdk-6.0
|
||||
|
||||
# Install specific versions of GoFSH and SUSHI
|
||||
# REMOVED pip install fhirpath from this line
|
||||
RUN npm install -g gofsh fsh-sushi
|
||||
|
||||
# ADDED: Download the latest HL7 FHIR Validator CLI
|
||||
@ -24,7 +27,6 @@ RUN chmod 755 validator_cli.jar
|
||||
# Change back to the main app directory for the next steps
|
||||
WORKDIR /app
|
||||
# Set up Python environment
|
||||
WORKDIR /app
|
||||
RUN python3 -m venv /app/venv
|
||||
ENV PATH="/app/venv/bin:$PATH"
|
||||
|
||||
@ -55,6 +57,9 @@ COPY hapi-fhir-jpaserver/target/classes/application.yaml /app/config/application
|
||||
COPY hapi-fhir-jpaserver/target/classes/application.yaml /usr/local/tomcat/webapps/app/config/application.yaml
|
||||
COPY hapi-fhir-jpaserver/custom/ /usr/local/tomcat/webapps/custom/
|
||||
|
||||
# ADDED: Copy pre-built Candle DLL files
|
||||
COPY fhir-candle/publish/ /app/fhir-candle-publish/
|
||||
|
||||
# Install supervisord
|
||||
RUN pip install supervisor
|
||||
|
||||
@ -62,7 +67,7 @@ RUN pip install supervisor
|
||||
COPY supervisord.conf /etc/supervisord.conf
|
||||
|
||||
# Expose ports
|
||||
EXPOSE 5000 8080
|
||||
EXPOSE 5000 8080 5001
|
||||
|
||||
# Start supervisord
|
||||
CMD ["supervisord", "-c", "/etc/supervisord.conf"]
|
||||
CMD ["supervisord", "-c", "/etc/supervisord.conf"]
|
||||
|
||||
62
Dockerfile.candle
Normal file
62
Dockerfile.candle
Normal file
@ -0,0 +1,62 @@
|
||||
# Base image with Python and Dotnet
|
||||
FROM mcr.microsoft.com/dotnet/sdk:9.0
|
||||
|
||||
# Install build dependencies, Node.js 18, and coreutils (for stdbuf)
|
||||
RUN apt-get update && apt-get install -y --no-install-recommends \
|
||||
python3 python3-pip python3-venv curl coreutils git \
|
||||
&& curl -fsSL https://deb.nodesource.com/setup_18.x | bash - \
|
||||
&& apt-get install -y --no-install-recommends nodejs \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
# Install specific versions of GoFSH and SUSHI
|
||||
RUN npm install -g gofsh fsh-sushi
|
||||
|
||||
# ADDED: Download the latest HL7 FHIR Validator CLI
|
||||
RUN mkdir -p /app/validator_cli
|
||||
WORKDIR /app/validator_cli
|
||||
# Download the validator JAR and a separate checksum file for verification
|
||||
RUN curl -L -o validator_cli.jar "https://github.com/hapifhir/org.hl7.fhir.core/releases/latest/download/validator_cli.jar"
|
||||
|
||||
# Set permissions for the downloaded file
|
||||
RUN chmod 755 validator_cli.jar
|
||||
|
||||
# Change back to the main app directory for the next steps
|
||||
WORKDIR /app
|
||||
# Set up Python environment
|
||||
RUN python3 -m venv /app/venv
|
||||
ENV PATH="/app/venv/bin:$PATH"
|
||||
|
||||
# ADDED: Uninstall old fhirpath just in case it's in requirements.txt
|
||||
RUN pip uninstall -y fhirpath || true
|
||||
# ADDED: Install the new fhirpathpy library
|
||||
RUN pip install --no-cache-dir fhirpathpy
|
||||
|
||||
# Copy Flask files
|
||||
COPY requirements.txt .
|
||||
# Install requirements (including Pydantic - check version compatibility if needed)
|
||||
RUN pip install --no-cache-dir -r requirements.txt
|
||||
COPY app.py .
|
||||
COPY services.py .
|
||||
COPY forms.py .
|
||||
COPY package.py .
|
||||
COPY templates/ templates/
|
||||
COPY static/ static/
|
||||
COPY tests/ tests/
|
||||
|
||||
# Ensure /tmp, /app/h2-data, /app/static/uploads, and /app/logs are writable
|
||||
RUN mkdir -p /tmp /app/h2-data /app/static/uploads /app/logs && chmod 777 /tmp /app/h2-data /app/static/uploads /app/logs
|
||||
|
||||
# Copy pre-built Candle DLL files
|
||||
COPY fhir-candle/publish/ /app/fhir-candle-publish/
|
||||
|
||||
# Install supervisord
|
||||
RUN pip install supervisor
|
||||
|
||||
# Configure supervisord
|
||||
COPY supervisord.conf /etc/supervisord.conf
|
||||
|
||||
# Expose ports
|
||||
EXPOSE 5000 5001
|
||||
|
||||
# Start supervisord
|
||||
CMD ["supervisord", "-c", "/etc/supervisord.conf"]
|
||||
66
Dockerfile.hapi
Normal file
66
Dockerfile.hapi
Normal file
@ -0,0 +1,66 @@
|
||||
# Base image with Python, Java, and Maven
|
||||
FROM tomcat:10.1-jdk17
|
||||
|
||||
# Install build dependencies, Node.js 18, and coreutils (for stdbuf)
|
||||
RUN apt-get update && apt-get install -y --no-install-recommends \
|
||||
python3 python3-pip python3-venv curl coreutils git maven \
|
||||
&& curl -fsSL https://deb.nodesource.com/setup_18.x | bash - \
|
||||
&& apt-get install -y --no-install-recommends nodejs \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
# Install specific versions of GoFSH and SUSHI
|
||||
RUN npm install -g gofsh fsh-sushi
|
||||
|
||||
# ADDED: Download the latest HL7 FHIR Validator CLI
|
||||
RUN mkdir -p /app/validator_cli
|
||||
WORKDIR /app/validator_cli
|
||||
# Download the validator JAR and a separate checksum file for verification
|
||||
RUN curl -L -o validator_cli.jar "https://github.com/hapifhir/org.hl7.fhir.core/releases/latest/download/validator_cli.jar"
|
||||
|
||||
# Set permissions for the downloaded file
|
||||
RUN chmod 755 validator_cli.jar
|
||||
|
||||
# Change back to the main app directory for the next steps
|
||||
WORKDIR /app
|
||||
# Set up Python environment
|
||||
RUN python3 -m venv /app/venv
|
||||
ENV PATH="/app/venv/bin:$PATH"
|
||||
|
||||
# ADDED: Uninstall old fhirpath just in case it's in requirements.txt
|
||||
RUN pip uninstall -y fhirpath || true
|
||||
# ADDED: Install the new fhirpathpy library
|
||||
RUN pip install --no-cache-dir fhirpathpy
|
||||
|
||||
# Copy Flask files
|
||||
COPY requirements.txt .
|
||||
# Install requirements (including Pydantic - check version compatibility if needed)
|
||||
RUN pip install --no-cache-dir -r requirements.txt
|
||||
COPY app.py .
|
||||
COPY services.py .
|
||||
COPY forms.py .
|
||||
COPY package.py .
|
||||
COPY templates/ templates/
|
||||
COPY static/ static/
|
||||
COPY tests/ tests/
|
||||
|
||||
# Ensure /tmp, /app/h2-data, /app/static/uploads, and /app/logs are writable
|
||||
RUN mkdir -p /tmp /app/h2-data /app/static/uploads /app/logs && chmod 777 /tmp /app/h2-data /app/static/uploads /app/logs
|
||||
|
||||
# Copy pre-built HAPI WAR and configuration
|
||||
COPY hapi-fhir-jpaserver/target/ROOT.war /usr/local/tomcat/webapps/
|
||||
COPY hapi-fhir-jpaserver/target/classes/application.yaml /usr/local/tomcat/conf/
|
||||
COPY hapi-fhir-jpaserver/target/classes/application.yaml /app/config/application.yaml
|
||||
COPY hapi-fhir-jpaserver/target/classes/application.yaml /usr/local/tomcat/webapps/app/config/application.yaml
|
||||
COPY hapi-fhir-jpaserver/custom/ /usr/local/tomcat/webapps/custom/
|
||||
|
||||
# Install supervisord
|
||||
RUN pip install supervisor
|
||||
|
||||
# Configure supervisord
|
||||
COPY supervisord.conf /etc/supervisord.conf
|
||||
|
||||
# Expose ports
|
||||
EXPOSE 5000 8080
|
||||
|
||||
# Start supervisord
|
||||
CMD ["supervisord", "-c", "/etc/supervisord.conf"]
|
||||
58
Dockerfile.lite
Normal file
58
Dockerfile.lite
Normal file
@ -0,0 +1,58 @@
|
||||
# Base image with Python and Node.js
|
||||
FROM python:3.9-slim
|
||||
|
||||
# Install Node.js 18 and npm
|
||||
RUN apt-get update && apt-get install -y --no-install-recommends \
|
||||
curl coreutils git \
|
||||
&& curl -fsSL https://deb.nodesource.com/setup_18.x | bash - \
|
||||
&& apt-get install -y --no-install-recommends nodejs \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
# Install specific versions of GoFSH and SUSHI
|
||||
RUN npm install -g gofsh fsh-sushi
|
||||
|
||||
# ADDED: Download the latest HL7 FHIR Validator CLI
|
||||
RUN mkdir -p /app/validator_cli
|
||||
WORKDIR /app/validator_cli
|
||||
# Download the validator JAR and a separate checksum file for verification
|
||||
RUN curl -L -o validator_cli.jar "https://github.com/hapifhir/org.hl7.fhir.core/releases/latest/download/validator_cli.jar"
|
||||
|
||||
# Set permissions for the downloaded file
|
||||
RUN chmod 755 validator_cli.jar
|
||||
|
||||
# Change back to the main app directory for the next steps
|
||||
WORKDIR /app
|
||||
# Set up Python environment
|
||||
RUN python3 -m venv /app/venv
|
||||
ENV PATH="/app/venv/bin:$PATH"
|
||||
|
||||
# ADDED: Uninstall old fhirpath just in case it's in requirements.txt
|
||||
RUN pip uninstall -y fhirpath || true
|
||||
# ADDED: Install the new fhirpathpy library
|
||||
RUN pip install --no-cache-dir fhirpathpy
|
||||
|
||||
# Copy Flask files
|
||||
COPY requirements.txt .
|
||||
RUN pip install --no-cache-dir -r requirements.txt
|
||||
COPY app.py .
|
||||
COPY services.py .
|
||||
COPY forms.py .
|
||||
COPY package.py .
|
||||
COPY templates/ templates/
|
||||
COPY static/ static/
|
||||
COPY tests/ tests/
|
||||
|
||||
# Ensure necessary directories are writable
|
||||
RUN mkdir -p /app/static/uploads /app/logs && chmod 777 /app/static/uploads /app/logs
|
||||
|
||||
# Install supervisord
|
||||
RUN pip install supervisor
|
||||
|
||||
# Configure supervisord
|
||||
COPY supervisord.conf /etc/supervisord.conf
|
||||
|
||||
# Expose ports
|
||||
EXPOSE 5000
|
||||
|
||||
# Start supervisord
|
||||
CMD ["supervisord", "-c", "/etc/supervisord.conf"]
|
||||
51
README.md
51
README.md
@ -5,22 +5,65 @@
|
||||
|
||||
The FHIRFLARE IG Toolkit is a Flask-based web application designed to streamline the management, processing, validation, and deployment of FHIR Implementation Guides (IGs) and test data. It offers a user-friendly interface for importing IG packages, extracting metadata, validating FHIR resources or bundles, pushing IGs to FHIR servers, converting FHIR resources to FHIR Shorthand (FSH), uploading complex test data sets with dependency management, and retrieving/splitting FHIR bundles. The toolkit includes live consoles for real-time feedback, making it an essential tool for FHIR developers and implementers.
|
||||
|
||||
The application can run in two modes:
|
||||
The application can run in four modes:
|
||||
|
||||
* **Standalone:** Includes a Dockerized Flask frontend, SQLite database, and an embedded HAPI FHIR server for local validation and interaction.
|
||||
* **Lite:** Includes only the Dockerized Flask frontend and SQLite database, excluding the local HAPI FHIR server. Requires connection to external FHIR servers for certain features.
|
||||
|
||||
* Installation Modes (Lite, Custom URL, Hapi, and Candle)
|
||||
This toolkit now offers four primary installation modes, configured via a simple command-line prompt during setup:
|
||||
|
||||
Lite Mode
|
||||
|
||||
Includes the Flask frontend, SQLite database, and core tooling (GoFSH, SUSHI) without an embedded FHIR server.
|
||||
|
||||
Requires you to provide a URL for an external FHIR server when using features like the FHIR API Explorer and validation.
|
||||
|
||||
Does not require Git, Maven, or .NET for setup.
|
||||
|
||||
Ideal for users who will always connect to an existing external FHIR server.
|
||||
|
||||
Custom URL Mode
|
||||
|
||||
Similar to Lite Mode, but prompts you for a specific external FHIR server URL to use as the default for the toolkit.
|
||||
|
||||
The application will be pre-configured to use your custom URL for all FHIR-related operations.
|
||||
|
||||
Does not require Git, Maven, or .NET for setup.
|
||||
|
||||
Hapi Mode
|
||||
|
||||
Includes the full FHIRFLARE toolkit and an embedded HAPI FHIR server.
|
||||
|
||||
The docker-compose configuration will proxy requests to the internal HAPI server, which is accessible via http://localhost:8080/fhir.
|
||||
|
||||
Requires Git and Maven during the initial build process to compile the HAPI FHIR server.
|
||||
|
||||
Ideal for users who want a self-contained, offline development and testing environment.
|
||||
|
||||
Candle Mode
|
||||
|
||||
Includes the full FHIRFLARE toolkit and an embedded FHIR Candle server.
|
||||
|
||||
The docker-compose configuration will proxy requests to the internal Candle server, which is accessible via http://localhost:5001/fhir/<version>.
|
||||
|
||||
Requires Git and the .NET SDK during the initial build process.
|
||||
|
||||
Ideal for users who want to use the .NET-based FHIR server for development and testing.
|
||||
|
||||
## Installation Modes (Lite vs. Standalone)
|
||||
|
||||
This toolkit offers two primary installation modes to suit different needs:
|
||||
|
||||
* **Standalone Version:**
|
||||
* **Standalone Version - Hapi / Candle:**
|
||||
* Includes the full FHIRFLARE Toolkit application **and** an embedded HAPI FHIR server running locally within the Docker environment.
|
||||
* Allows for local FHIR resource validation using HAPI FHIR's capabilities.
|
||||
* Enables the "Use Local HAPI" option in the FHIR API Explorer and FHIR UI Operations pages, proxying requests to the internal HAPI server (`http://localhost:8080/fhir`).
|
||||
* Requires Git and Maven during the initial build process (via the `.bat` script or manual steps) to prepare the HAPI FHIR server.
|
||||
* Ideal for users who want a self-contained environment for development and testing or who don't have readily available external FHIR servers.
|
||||
|
||||
* **Standalone Version - Custom Mode:**
|
||||
* Includes the full FHIRFLARE Toolkit application **and** point the Environmet variable at your chosen custom fhir url endpoint allowing for Custom setups
|
||||
|
||||
|
||||
* **Lite Version:**
|
||||
* Includes the FHIRFLARE Toolkit application **without** the embedded HAPI FHIR server.
|
||||
* Requires users to provide URLs for external FHIR servers when using features like the FHIR API Explorer and FHIR UI Operations pages. The "Use Local HAPI" option will be disabled in the UI.
|
||||
|
||||
54
app.py
54
app.py
@ -1780,59 +1780,41 @@ def fhir_ui_operations():
|
||||
|
||||
# Use a single route to capture everything after /fhir/
|
||||
# The 'path' converter handles slashes. 'subpath' can be empty.
|
||||
@app.route('/fhir', defaults={'subpath': ''}, methods=['GET', 'POST', 'PUT', 'DELETE'])
|
||||
@app.route('/fhir/', defaults={'subpath': ''}, methods=['GET', 'POST', 'PUT', 'DELETE'])
|
||||
@app.route('/fhir/<path:subpath>', methods=['GET', 'POST', 'PUT', 'DELETE'])
|
||||
@app.route('/fhir', defaults={'subpath': ''}, methods=['GET', 'POST', 'PUT', 'DELETE', 'PATCH'])
|
||||
@app.route('/fhir/', defaults={'subpath': ''}, methods=['GET', 'POST', 'PUT', 'DELETE', 'PATCH'])
|
||||
@app.route('/fhir/<path:subpath>', methods=['GET', 'POST', 'PUT', 'DELETE', 'PATCH'])
|
||||
def proxy_hapi(subpath):
|
||||
"""
|
||||
Proxies FHIR requests to either the local HAPI server or a custom
|
||||
target server specified by the 'X-Target-FHIR-Server' header.
|
||||
Handles requests to /fhir/ (base, subpath='') and /fhir/<subpath>.
|
||||
The route '/fhir' (no trailing slash) is handled separately for the UI.
|
||||
target server specified by the 'X-Target-FHIR-Server' header or a query parameter.
|
||||
"""
|
||||
# Clean subpath just in case prefixes were somehow included
|
||||
clean_subpath = subpath.replace('r4/', '', 1).replace('fhir/', '', 1).strip('/')
|
||||
logger.debug(f"Proxy received request for path: '/fhir/{subpath}', cleaned subpath: '{clean_subpath}'")
|
||||
logger.debug(f"Proxy received request for path: '/fhir/{subpath}'")
|
||||
|
||||
# Determine the target FHIR server base URL
|
||||
# NEW: Check for proxy-target query parameter first
|
||||
target_server_query = request.args.get('proxy-target')
|
||||
target_server_header = request.headers.get('X-Target-FHIR-Server')
|
||||
final_base_url = None
|
||||
is_custom_target = False
|
||||
|
||||
if target_server_query:
|
||||
try:
|
||||
parsed_url = urlparse(target_server_query)
|
||||
if not parsed_url.scheme or not parsed_url.netloc:
|
||||
raise ValueError("Invalid URL format in proxy-target query parameter")
|
||||
final_base_url = target_server_query.rstrip('/')
|
||||
is_custom_target = True
|
||||
logger.info(f"Proxy target identified from query parameter: {final_base_url}")
|
||||
except ValueError as e:
|
||||
logger.warning(f"Invalid URL in proxy-target query parameter: '{target_server_query}'. Falling back. Error: {e}")
|
||||
final_base_url = current_app.config['HAPI_FHIR_URL'].rstrip('/')
|
||||
logger.debug(f"Falling back to default local HAPI due to invalid query: {final_base_url}")
|
||||
final_base_url = target_server_query.rstrip('/')
|
||||
is_custom_target = True
|
||||
logger.info(f"Proxy target identified from query parameter: {final_base_url}")
|
||||
elif target_server_header:
|
||||
try:
|
||||
parsed_url = urlparse(target_server_header)
|
||||
if not parsed_url.scheme or not parsed_url.netloc:
|
||||
raise ValueError("Invalid URL format in X-Target-FHIR-Server header")
|
||||
final_base_url = target_server_header.rstrip('/')
|
||||
is_custom_target = True
|
||||
logger.info(f"Proxy target identified from header: {final_base_url}")
|
||||
except ValueError as e:
|
||||
logger.warning(f"Invalid URL in X-Target-FHIR-Server header: '{target_server_header}'. Falling back. Error: {e}")
|
||||
final_base_url = current_app.config['HAPI_FHIR_URL'].rstrip('/')
|
||||
logger.debug(f"Falling back to default local HAPI due to invalid header: {final_base_url}")
|
||||
final_base_url = target_server_header.rstrip('/')
|
||||
is_custom_target = True
|
||||
logger.info(f"Proxy target identified from header: {final_base_url}")
|
||||
else:
|
||||
final_base_url = current_app.config['HAPI_FHIR_URL'].rstrip('/')
|
||||
logger.debug(f"No target info found, proxying to default local HAPI: {final_base_url}")
|
||||
|
||||
# Construct the final URL for the target server request
|
||||
# Append the cleaned subpath only if it's not empty
|
||||
final_url = f"{final_base_url}/{clean_subpath}" if clean_subpath else final_base_url
|
||||
|
||||
# Construct the final URL for the target server request. This is the core logical change.
|
||||
# The subpath variable now correctly captures the remaining part of the URL after '/fhir/'.
|
||||
# We construct the final URL by joining the base URL and the subpath.
|
||||
final_url = f"{final_base_url}/{subpath}" if subpath else final_base_url
|
||||
|
||||
logger.debug(f"Final URL for target server: {final_url}")
|
||||
|
||||
# Prepare headers to forward
|
||||
headers_to_forward = {
|
||||
k: v for k, v in request.headers.items()
|
||||
|
||||
@ -3,14 +3,13 @@ services:
|
||||
fhirflare:
|
||||
build:
|
||||
context: .
|
||||
dockerfile: Dockerfile
|
||||
dockerfile: Dockerfile.lite
|
||||
ports:
|
||||
- "5000:5000"
|
||||
- "8080:8080" # Keep port exposed, even if Tomcat isn't running useful stuff in Lite
|
||||
- "8080:8080"
|
||||
volumes:
|
||||
- ./instance:/app/instance
|
||||
- ./static/uploads:/app/static/uploads
|
||||
- ./instance/hapi-h2-data/:/app/h2-data # Keep volume mounts consistent
|
||||
- ./logs:/app/logs
|
||||
environment:
|
||||
- FLASK_APP=app.py
|
||||
@ -18,5 +17,5 @@ services:
|
||||
- NODE_PATH=/usr/lib/node_modules
|
||||
- APP_MODE=standalone
|
||||
- APP_BASE_URL=http://localhost:5000
|
||||
- HAPI_FHIR_URL=https://fhir.hl7.org.au/aucore/fhir/DEFAULT/
|
||||
- HAPI_FHIR_URL=https://fhir.hl7.org.au/aucore/fhir/DEFAULT/
|
||||
command: supervisord -c /etc/supervisord.conf
|
||||
|
||||
414
setup_linux.sh
414
setup_linux.sh
@ -1,18 +1,21 @@
|
||||
#!/bin/bash
|
||||
|
||||
# --- Configuration ---
|
||||
REPO_URL="https://github.com/hapifhir/hapi-fhir-jpaserver-starter.git"
|
||||
CLONE_DIR="hapi-fhir-jpaserver"
|
||||
SOURCE_CONFIG_DIR="hapi-fhir-Setup" # Assuming this is relative to the script's parent
|
||||
REPO_URL_HAPI="https://github.com/hapifhir/hapi-fhir-jpaserver-starter.git"
|
||||
REPO_URL_CANDLE="https://github.com/FHIR/fhir-candle.git"
|
||||
CLONE_DIR_HAPI="hapi-fhir-jpaserver"
|
||||
CLONE_DIR_CANDLE="fhir-candle"
|
||||
SOURCE_CONFIG_DIR="hapi-fhir-Setup"
|
||||
CONFIG_FILE="application.yaml"
|
||||
|
||||
# --- Define Paths ---
|
||||
# Note: Adjust SOURCE_CONFIG_PATH if SOURCE_CONFIG_DIR is not a sibling directory
|
||||
# This assumes the script is run from a directory, and hapi-fhir-setup is at the same level
|
||||
SOURCE_CONFIG_PATH="../${SOURCE_CONFIG_DIR}/target/classes/${CONFIG_FILE}"
|
||||
DEST_CONFIG_PATH="${CLONE_DIR}/target/classes/${CONFIG_FILE}"
|
||||
DEST_CONFIG_PATH="${CLONE_DIR_HAPI}/target/classes/${CONFIG_FILE}"
|
||||
|
||||
APP_MODE=""
|
||||
CUSTOM_FHIR_URL_VAL=""
|
||||
SERVER_TYPE=""
|
||||
CANDLE_FHIR_VERSION=""
|
||||
|
||||
# --- Error Handling Function ---
|
||||
handle_error() {
|
||||
@ -20,25 +23,39 @@ handle_error() {
|
||||
echo "An error occurred: $1"
|
||||
echo "Script aborted."
|
||||
echo "------------------------------------"
|
||||
# Removed 'read -p "Press Enter to exit..."' as it's not typical for non-interactive CI/CD
|
||||
exit 1
|
||||
}
|
||||
|
||||
# === Prompt for Installation Mode ===
|
||||
# === MODIFIED: Prompt for Installation Mode ===
|
||||
get_mode_choice() {
|
||||
echo ""
|
||||
echo "Select Installation Mode:"
|
||||
echo "1. Standalone (Includes local HAPI FHIR Server - Requires Git & Maven)"
|
||||
echo "2. Lite (Excludes local HAPI FHIR Server - No Git/Maven needed)"
|
||||
echo "1. Lite (Excludes local HAPI FHIR Server - No Git/Maven/Dotnet needed)"
|
||||
echo "2. Custom URL (Uses a custom FHIR Server - No Git/Maven/Dotnet needed)"
|
||||
echo "3. Hapi (Includes local HAPI FHIR Server - Requires Git & Maven)"
|
||||
echo "4. Candle (Includes local FHIR Candle Server - Requires Git & Dotnet)"
|
||||
|
||||
while true; do
|
||||
read -r -p "Enter your choice (1 or 2): " choice
|
||||
read -r -p "Enter your choice (1, 2, 3, or 4): " choice
|
||||
case "$choice" in
|
||||
1)
|
||||
APP_MODE="standalone"
|
||||
APP_MODE="lite"
|
||||
break
|
||||
;;
|
||||
2)
|
||||
APP_MODE="lite"
|
||||
APP_MODE="standalone"
|
||||
get_custom_url_prompt
|
||||
break
|
||||
;;
|
||||
3)
|
||||
APP_MODE="standalone"
|
||||
SERVER_TYPE="hapi"
|
||||
break
|
||||
;;
|
||||
4)
|
||||
APP_MODE="standalone"
|
||||
SERVER_TYPE="candle"
|
||||
get_candle_fhir_version
|
||||
break
|
||||
;;
|
||||
*)
|
||||
@ -47,156 +64,301 @@ get_mode_choice() {
|
||||
esac
|
||||
done
|
||||
echo "Selected Mode: $APP_MODE"
|
||||
echo "Server Type: $SERVER_TYPE"
|
||||
echo
|
||||
}
|
||||
|
||||
# === NEW: Prompt for Custom URL ===
|
||||
get_custom_url_prompt() {
|
||||
local confirmed_url=""
|
||||
while true; do
|
||||
echo
|
||||
read -r -p "Please enter the custom FHIR server URL: " custom_url_input
|
||||
echo
|
||||
echo "You entered: $custom_url_input"
|
||||
read -r -p "Is this URL correct? (Y/N): " confirm_url
|
||||
if [[ "$confirm_url" =~ ^[Yy]$ ]]; then
|
||||
confirmed_url="$custom_url_input"
|
||||
break
|
||||
else
|
||||
echo "URL not confirmed. Please re-enter."
|
||||
fi
|
||||
done
|
||||
|
||||
while true; do
|
||||
echo
|
||||
read -r -p "Please re-enter the URL to confirm it is correct: " custom_url_input
|
||||
if [ "$custom_url_input" = "$confirmed_url" ]; then
|
||||
CUSTOM_FHIR_URL_VAL="$custom_url_input"
|
||||
echo
|
||||
echo "Custom URL confirmed: $CUSTOM_FHIR_URL_VAL"
|
||||
break
|
||||
else
|
||||
echo
|
||||
echo "URLs do not match. Please try again."
|
||||
confirmed_url="$custom_url_input"
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
# === NEW: Prompt for Candle FHIR version ===
|
||||
get_candle_fhir_version() {
|
||||
echo ""
|
||||
echo "Select the FHIR version for the Candle server:"
|
||||
echo "1. R4 (4.0)"
|
||||
echo "2. R4B (4.3)"
|
||||
echo "3. R5 (5.0)"
|
||||
while true; do
|
||||
read -r -p "Enter your choice (1, 2, or 3): " choice
|
||||
case "$choice" in
|
||||
1)
|
||||
CANDLE_FHIR_VERSION=r4
|
||||
break
|
||||
;;
|
||||
2)
|
||||
CANDLE_FHIR_VERSION=r4b
|
||||
break
|
||||
;;
|
||||
3)
|
||||
CANDLE_FHIR_VERSION=r5
|
||||
break
|
||||
;;
|
||||
*)
|
||||
echo "Invalid input. Please try again."
|
||||
;;
|
||||
esac
|
||||
done
|
||||
}
|
||||
|
||||
|
||||
# Call the function to get mode choice
|
||||
get_mode_choice
|
||||
|
||||
# === Conditionally Execute HAPI Setup ===
|
||||
if [ "$APP_MODE" = "standalone" ]; then
|
||||
echo "Running Standalone setup including HAPI FHIR..."
|
||||
echo
|
||||
# === Conditionally Execute Server Setup ===
|
||||
case "$SERVER_TYPE" in
|
||||
"hapi")
|
||||
echo "Running Hapi server setup..."
|
||||
echo
|
||||
|
||||
# --- Step 0: Clean up previous clone (optional) ---
|
||||
echo "Checking for existing directory: $CLONE_DIR"
|
||||
if [ -d "$CLONE_DIR" ]; then
|
||||
echo "Found existing directory, removing it..."
|
||||
rm -rf "$CLONE_DIR"
|
||||
if [ $? -ne 0 ]; then
|
||||
handle_error "Failed to remove existing directory: $CLONE_DIR"
|
||||
# --- Step 0: Clean up previous clone (optional) ---
|
||||
echo "Checking for existing directory: $CLONE_DIR_HAPI"
|
||||
if [ -d "$CLONE_DIR_HAPI" ]; then
|
||||
echo "Found existing directory, removing it..."
|
||||
rm -rf "$CLONE_DIR_HAPI"
|
||||
if [ $? -ne 0 ]; then
|
||||
handle_error "Failed to remove existing directory: $CLONE_DIR_HAPI"
|
||||
fi
|
||||
echo "Existing directory removed."
|
||||
else
|
||||
echo "Directory does not exist, proceeding with clone."
|
||||
fi
|
||||
echo "Existing directory removed."
|
||||
else
|
||||
echo "Directory does not exist, proceeding with clone."
|
||||
fi
|
||||
echo
|
||||
echo
|
||||
|
||||
# --- Step 1: Clone the HAPI FHIR server repository ---
|
||||
echo "Cloning repository: $REPO_URL into $CLONE_DIR..."
|
||||
git clone "$REPO_URL" "$CLONE_DIR"
|
||||
if [ $? -ne 0 ]; then
|
||||
handle_error "Failed to clone repository. Check Git installation and network connection."
|
||||
fi
|
||||
echo "Repository cloned successfully."
|
||||
echo
|
||||
|
||||
# --- Step 2: Navigate into the cloned directory ---
|
||||
echo "Changing directory to $CLONE_DIR..."
|
||||
cd "$CLONE_DIR" || handle_error "Failed to change directory to $CLONE_DIR."
|
||||
echo "Current directory: $(pwd)"
|
||||
echo
|
||||
|
||||
# --- Step 3: Build the HAPI server using Maven ---
|
||||
echo "===> Starting Maven build (Step 3)..."
|
||||
mvn clean package -DskipTests=true -Pboot
|
||||
if [ $? -ne 0 ]; then
|
||||
echo "ERROR: Maven build failed."
|
||||
cd ..
|
||||
handle_error "Maven build process resulted in an error."
|
||||
fi
|
||||
echo "Maven build completed successfully."
|
||||
echo
|
||||
|
||||
# --- Step 4: Copy the configuration file ---
|
||||
echo "===> Starting file copy (Step 4)..."
|
||||
echo "Copying configuration file..."
|
||||
# Corrected SOURCE_CONFIG_PATH to be relative to the new current directory ($CLONE_DIR)
|
||||
# This assumes the original script's SOURCE_CONFIG_PATH was relative to its execution location
|
||||
# If SOURCE_CONFIG_DIR is ../hapi-fhir-setup relative to script's original location:
|
||||
# Then from within CLONE_DIR, it becomes ../../hapi-fhir-setup
|
||||
# We defined SOURCE_CONFIG_PATH earlier relative to the script start.
|
||||
# So, when inside CLONE_DIR, the path from original script location should be used.
|
||||
# The original script had: set SOURCE_CONFIG_PATH=..\%SOURCE_CONFIG_DIR%\target\classes\%CONFIG_FILE%
|
||||
# And then: xcopy "%SOURCE_CONFIG_PATH%" "target\classes\"
|
||||
# This implies SOURCE_CONFIG_PATH is relative to the original script's location, not the $CLONE_DIR
|
||||
# Therefore, we need to construct the correct relative path from *within* $CLONE_DIR back to the source.
|
||||
# Assuming the script is in dir X, and SOURCE_CONFIG_DIR is ../hapi-fhir-setup from X.
|
||||
# So, hapi-fhir-setup is a sibling of X's parent.
|
||||
# If CLONE_DIR is also in X, then from within CLONE_DIR, the path is ../ + original SOURCE_CONFIG_PATH
|
||||
# For simplicity and robustness, let's use an absolute path or a more clearly defined relative path from the start.
|
||||
# The original `SOURCE_CONFIG_PATH=..\%SOURCE_CONFIG_DIR%\target\classes\%CONFIG_FILE%` implies
|
||||
# that `hapi-fhir-setup` is a sibling of the directory where the script *is being run from*.
|
||||
|
||||
# Let's assume the script is run from the root of FHIRFLARE-IG-Toolkit.
|
||||
# And hapi-fhir-setup is also in the root, next to this script.
|
||||
# Then SOURCE_CONFIG_PATH would be ./hapi-fhir-setup/target/classes/application.yaml
|
||||
# And from within ./hapi-fhir-jpaserver/, the path would be ../hapi-fhir-setup/target/classes/application.yaml
|
||||
|
||||
# The original batch file sets SOURCE_CONFIG_PATH as "..\%SOURCE_CONFIG_DIR%\target\classes\%CONFIG_FILE%"
|
||||
# And COPIES it to "target\classes\" *while inside CLONE_DIR*.
|
||||
# This means the source path is relative to where the *cd %CLONE_DIR%* happened from.
|
||||
# Let's make it relative to the script's initial execution directory.
|
||||
INITIAL_SCRIPT_DIR=$(pwd)
|
||||
ABSOLUTE_SOURCE_CONFIG_PATH="${INITIAL_SCRIPT_DIR}/../${SOURCE_CONFIG_DIR}/target/classes/${CONFIG_FILE}" # This matches the ..\ logic
|
||||
|
||||
echo "Source: $ABSOLUTE_SOURCE_CONFIG_PATH"
|
||||
echo "Destination: target/classes/$CONFIG_FILE"
|
||||
|
||||
if [ ! -f "$ABSOLUTE_SOURCE_CONFIG_PATH" ]; then
|
||||
echo "WARNING: Source configuration file not found at $ABSOLUTE_SOURCE_CONFIG_PATH."
|
||||
echo "The script will continue, but the server might use default configuration."
|
||||
else
|
||||
cp "$ABSOLUTE_SOURCE_CONFIG_PATH" "target/classes/"
|
||||
# --- Step 1: Clone the HAPI FHIR server repository ---
|
||||
echo "Cloning repository: $REPO_URL_HAPI into $CLONE_DIR_HAPI..."
|
||||
git clone "$REPO_URL_HAPI" "$CLONE_DIR_HAPI"
|
||||
if [ $? -ne 0 ]; then
|
||||
echo "WARNING: Failed to copy configuration file. Check if the source file exists and permissions."
|
||||
handle_error "Failed to clone repository. Check Git installation and network connection."
|
||||
fi
|
||||
echo "Repository cloned successfully."
|
||||
echo
|
||||
|
||||
# --- Step 2: Navigate into the cloned directory ---
|
||||
echo "Changing directory to $CLONE_DIR_HAPI..."
|
||||
cd "$CLONE_DIR_HAPI" || handle_error "Failed to change directory to $CLONE_DIR_HAPI."
|
||||
echo "Current directory: $(pwd)"
|
||||
echo
|
||||
|
||||
# --- Step 3: Build the HAPI server using Maven ---
|
||||
echo "===> Starting Maven build (Step 3)..."
|
||||
mvn clean package -DskipTests=true -Pboot
|
||||
if [ $? -ne 0 ]; then
|
||||
echo "ERROR: Maven build failed."
|
||||
cd ..
|
||||
handle_error "Maven build process resulted in an error."
|
||||
fi
|
||||
echo "Maven build completed successfully."
|
||||
echo
|
||||
|
||||
# --- Step 4: Copy the configuration file ---
|
||||
echo "===> Starting file copy (Step 4)..."
|
||||
echo "Copying configuration file..."
|
||||
INITIAL_SCRIPT_DIR=$(pwd)
|
||||
ABSOLUTE_SOURCE_CONFIG_PATH="${INITIAL_SCRIPT_DIR}/../${SOURCE_CONFIG_DIR}/target/classes/${CONFIG_FILE}"
|
||||
|
||||
echo "Source: $ABSOLUTE_SOURCE_CONFIG_PATH"
|
||||
echo "Destination: target/classes/$CONFIG_FILE"
|
||||
|
||||
if [ ! -f "$ABSOLUTE_SOURCE_CONFIG_PATH" ]; then
|
||||
echo "WARNING: Source configuration file not found at $ABSOLUTE_SOURCE_CONFIG_PATH."
|
||||
echo "The script will continue, but the server might use default configuration."
|
||||
else
|
||||
echo "Configuration file copied successfully."
|
||||
cp "$ABSOLUTE_SOURCE_CONFIG_PATH" "target/classes/"
|
||||
if [ $? -ne 0 ]; then
|
||||
echo "WARNING: Failed to copy configuration file. Check if the source file exists and permissions."
|
||||
echo "The script will continue, but the server might use default configuration."
|
||||
else
|
||||
echo "Configuration file copied successfully."
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
echo
|
||||
echo
|
||||
|
||||
# --- Step 5: Navigate back to the parent directory ---
|
||||
echo "===> Changing directory back (Step 5)..."
|
||||
cd .. || handle_error "Failed to change back to the parent directory."
|
||||
echo "Current directory: $(pwd)"
|
||||
echo
|
||||
# --- Step 5: Navigate back to the parent directory ---
|
||||
echo "===> Changing directory back (Step 5)..."
|
||||
cd .. || handle_error "Failed to change back to the parent directory."
|
||||
echo "Current directory: $(pwd)"
|
||||
echo
|
||||
;;
|
||||
|
||||
else # APP_MODE is "lite"
|
||||
echo "Running Lite setup, skipping HAPI FHIR build..."
|
||||
# Ensure the hapi-fhir-jpaserver directory doesn't exist or is empty if Lite mode is chosen
|
||||
if [ -d "$CLONE_DIR" ]; then
|
||||
echo "Found existing HAPI directory ($CLONE_DIR) in Lite mode. Removing it..."
|
||||
rm -rf "$CLONE_DIR"
|
||||
fi
|
||||
# Create empty target directories expected by Dockerfile COPY, even if not used
|
||||
mkdir -p "${CLONE_DIR}/target/classes"
|
||||
mkdir -p "${CLONE_DIR}/custom" # This was in the original batch, ensure it's here
|
||||
# Create a placeholder empty WAR file and application.yaml to satisfy Dockerfile COPY
|
||||
touch "${CLONE_DIR}/target/ROOT.war"
|
||||
touch "${CLONE_DIR}/target/classes/application.yaml"
|
||||
echo "Placeholder files and directories created for Lite mode build in $CLONE_DIR."
|
||||
echo
|
||||
fi
|
||||
"candle")
|
||||
echo "Running FHIR Candle server setup..."
|
||||
echo
|
||||
|
||||
# --- Step 0: Clean up previous clone (optional) ---
|
||||
echo "Checking for existing directory: $CLONE_DIR_CANDLE"
|
||||
if [ -d "$CLONE_DIR_CANDLE" ]; then
|
||||
echo "Found existing directory, removing it..."
|
||||
rm -rf "$CLONE_DIR_CANDLE"
|
||||
if [ $? -ne 0 ]; then
|
||||
handle_error "Failed to remove existing directory: $CLONE_DIR_CANDLE"
|
||||
fi
|
||||
echo "Existing directory removed."
|
||||
else
|
||||
echo "Directory does not exist, proceeding with clone."
|
||||
fi
|
||||
echo
|
||||
|
||||
# === Modify docker-compose.yml to set APP_MODE ===
|
||||
echo "Updating docker-compose.yml with APP_MODE=$APP_MODE..."
|
||||
# --- Step 1: Clone the FHIR Candle server repository ---
|
||||
echo "Cloning repository: $REPO_URL_CANDLE into $CLONE_DIR_CANDLE..."
|
||||
git clone "$REPO_URL_CANDLE" "$CLONE_DIR_CANDLE"
|
||||
if [ $? -ne 0 ]; then
|
||||
handle_error "Failed to clone repository. Check Git and Dotnet SDK installation and network connection."
|
||||
fi
|
||||
echo "Repository cloned successfully."
|
||||
echo
|
||||
|
||||
# --- Step 2: Navigate into the cloned directory ---
|
||||
echo "Changing directory to $CLONE_DIR_CANDLE..."
|
||||
cd "$CLONE_DIR_CANDLE" || handle_error "Failed to change directory to $CLONE_DIR_CANDLE."
|
||||
echo "Current directory: $(pwd)"
|
||||
echo
|
||||
|
||||
# --- Step 3: Build the FHIR Candle server using Dotnet ---
|
||||
echo "===> Starting Dotnet build (Step 3)..."
|
||||
dotnet publish -c Release -f net9.0 -o publish
|
||||
if [ $? -ne 0 ]; then
|
||||
handle_error "Dotnet build failed. Check Dotnet SDK installation."
|
||||
fi
|
||||
echo "Dotnet build completed successfully."
|
||||
echo
|
||||
|
||||
# --- Step 4: Navigate back to the parent directory ---
|
||||
echo "===> Changing directory back (Step 4)..."
|
||||
cd .. || handle_error "Failed to change back to the parent directory."
|
||||
echo "Current directory: $(pwd)"
|
||||
echo
|
||||
;;
|
||||
|
||||
*) # APP_MODE is Lite, no SERVER_TYPE
|
||||
echo "Running Lite setup, skipping server build..."
|
||||
if [ -d "$CLONE_DIR_HAPI" ]; then
|
||||
echo "Found existing HAPI directory in Lite mode. Removing it to avoid build issues..."
|
||||
rm -rf "$CLONE_DIR_HAPI"
|
||||
fi
|
||||
if [ -d "$CLONE_DIR_CANDLE" ]; then
|
||||
echo "Found existing Candle directory in Lite mode. Removing it to avoid build issues..."
|
||||
rm -rf "$CLONE_DIR_CANDLE"
|
||||
fi
|
||||
mkdir -p "${CLONE_DIR_HAPI}/target/classes"
|
||||
mkdir -p "${CLONE_DIR_HAPI}/custom"
|
||||
touch "${CLONE_DIR_HAPI}/target/ROOT.war"
|
||||
touch "${CLONE_DIR_HAPI}/target/classes/application.yaml"
|
||||
mkdir -p "${CLONE_DIR_CANDLE}/publish"
|
||||
touch "${CLONE_DIR_CANDLE}/publish/fhir-candle.dll"
|
||||
echo "Placeholder files and directories created for Lite mode build."
|
||||
echo
|
||||
;;
|
||||
esac
|
||||
|
||||
# === MODIFIED: Update docker-compose.yml to set APP_MODE and HAPI_FHIR_URL and DOCKERFILE ===
|
||||
echo "Updating docker-compose.yml with APP_MODE=$APP_MODE and HAPI_FHIR_URL..."
|
||||
DOCKER_COMPOSE_TMP="docker-compose.yml.tmp"
|
||||
DOCKER_COMPOSE_ORIG="docker-compose.yml"
|
||||
|
||||
HAPI_URL_TO_USE="https://fhir.hl7.org.au/aucore/fhir/DEFAULT/"
|
||||
if [ -n "$CUSTOM_FHIR_URL_VAL" ]; then
|
||||
HAPI_URL_TO_USE="$CUSTOM_FHIR_URL_VAL"
|
||||
elif [ "$SERVER_TYPE" = "candle" ]; then
|
||||
HAPI_URL_TO_USE="http://localhost:5826/fhir/${CANDLE_FHIR_VERSION}"
|
||||
else
|
||||
HAPI_URL_TO_USE="http://localhost:8080/fhir"
|
||||
fi
|
||||
|
||||
DOCKERFILE_TO_USE="Dockerfile.lite"
|
||||
if [ "$SERVER_TYPE" = "hapi" ]; then
|
||||
DOCKERFILE_TO_USE="Dockerfile.hapi"
|
||||
elif [ "$SERVER_TYPE" = "candle" ]; then
|
||||
DOCKERFILE_TO_USE="Dockerfile.candle"
|
||||
fi
|
||||
|
||||
cat << EOF > "$DOCKER_COMPOSE_TMP"
|
||||
version: '3.8'
|
||||
services:
|
||||
fhirflare:
|
||||
build:
|
||||
context: .
|
||||
dockerfile: Dockerfile
|
||||
dockerfile: ${DOCKERFILE_TO_USE}
|
||||
ports:
|
||||
EOF
|
||||
|
||||
if [ "$SERVER_TYPE" = "candle" ]; then
|
||||
cat << EOF >> "$DOCKER_COMPOSE_TMP"
|
||||
- "5000:5000"
|
||||
- "8080:8080" # Keep port exposed, even if Tomcat isn't running useful stuff in Lite
|
||||
- "5001:5826"
|
||||
EOF
|
||||
else
|
||||
cat << EOF >> "$DOCKER_COMPOSE_TMP"
|
||||
- "5000:5000"
|
||||
- "8080:8080"
|
||||
EOF
|
||||
fi
|
||||
|
||||
cat << EOF >> "$DOCKER_COMPOSE_TMP"
|
||||
volumes:
|
||||
- ./instance:/app/instance
|
||||
- ./static/uploads:/app/static/uploads
|
||||
- ./instance/hapi-h2-data/:/app/h2-data # Keep volume mounts consistent
|
||||
- ./logs:/app/logs
|
||||
EOF
|
||||
|
||||
if [ "$SERVER_TYPE" = "hapi" ]; then
|
||||
cat << EOF >> "$DOCKER_COMPOSE_TMP"
|
||||
- ./instance/hapi-h2-data/:/app/h2-data # Keep volume mounts consistent
|
||||
- ./hapi-fhir-jpaserver/target/ROOT.war:/usr/local/tomcat/webapps/ROOT.war
|
||||
- ./hapi-fhir-jpaserver/target/classes/application.yaml:/usr/local/tomcat/conf/application.yaml
|
||||
EOF
|
||||
elif [ "$SERVER_TYPE" = "candle" ]; then
|
||||
cat << EOF >> "$DOCKER_COMPOSE_TMP"
|
||||
- ./fhir-candle/publish/:/app/fhir-candle-publish/
|
||||
EOF
|
||||
fi
|
||||
|
||||
cat << EOF >> "$DOCKER_COMPOSE_TMP"
|
||||
environment:
|
||||
- FLASK_APP=app.py
|
||||
- FLASK_ENV=development
|
||||
- NODE_PATH=/usr/lib/node_modules
|
||||
- APP_MODE=${APP_MODE}
|
||||
- APP_BASE_URL=http://localhost:5000
|
||||
- HAPI_FHIR_URL=http://localhost:8080/fhir
|
||||
- HAPI_FHIR_URL=${HAPI_URL_TO_USE}
|
||||
EOF
|
||||
|
||||
if [ "$SERVER_TYPE" = "candle" ]; then
|
||||
cat << EOF >> "$DOCKER_COMPOSE_TMP"
|
||||
- ASPNETCORE_URLS=http://0.0.0.0:5826
|
||||
EOF
|
||||
fi
|
||||
|
||||
cat << EOF >> "$DOCKER_COMPOSE_TMP"
|
||||
command: supervisord -c /etc/supervisord.conf
|
||||
EOF
|
||||
|
||||
|
||||
@ -33,4 +33,18 @@ stdout_logfile_maxbytes=10MB
|
||||
stdout_logfile_backups=5
|
||||
stderr_logfile=/app/logs/tomcat_err.log
|
||||
stderr_logfile_maxbytes=10MB
|
||||
stderr_logfile_backups=5
|
||||
stderr_logfile_backups=5
|
||||
|
||||
[program:candle]
|
||||
command=dotnet /app/fhir-candle-publish/fhir-candle.dll
|
||||
directory=/app/fhir-candle-publish
|
||||
autostart=true
|
||||
autorestart=true
|
||||
startsecs=10
|
||||
stopwaitsecs=10
|
||||
stdout_logfile=/app/logs/candle.log
|
||||
stdout_logfile_maxbytes=10MB
|
||||
stdout_logfile_backups=5
|
||||
stderr_logfile=/app/logs/candle_err.log
|
||||
stderr_logfile_maxbytes=10MB
|
||||
stderr_logfile_backups=5
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user