Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 43 additions & 0 deletions services/painting-process-data-simulator-service/.env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
# .env.example
# 이 파일을 .env 로 복사한 후, 로컬 개발 환경에 맞게 값을 수정하여 사용하세요.

#==============================
# Azure Storage 설정
#==============================

# Azure Storage 계정의 연결 문자열 (필수)
AZURE_CONNECTION_STRING=

# 데이터를 읽어올 컨테이너 이름
AZURE_CONTAINER_NAME=simulator-data

# 컨테이너 내에서 데이터가 저장된 폴더 경로
PAINTING_DATA_FOLDER=painting-process-equipment


#==============================
# 스케줄러 설정
#==============================

# 데이터 전송 작업의 실행 주기 (초 단위)
SCHEDULER_INTERVAL_SECONDS=30

# 한 번에 전송할 데이터의 묶음 크기
BATCH_SIZE=10


#==============================
# 백엔드 서비스 설정
#==============================


# 도커 사용시 시뮬레이터가 데이터를 전송할 Spring Boot 백엔드 서비스의 전체 URL
BACKEND_SERVICE_URL=http://localhost:8091/equipment-data


#==============================
# HTTP 클라이언트 설정
#==============================

# 백엔드 API 호출 시 타임아웃 시간 (초 단위)
HTTP_TIMEOUT=30
101 changes: 30 additions & 71 deletions services/painting-process-data-simulator-service/README.md
Original file line number Diff line number Diff line change
@@ -1,35 +1,30 @@
# Painting Process Equipment Simulator Service
# Painting Process Backend Simulator Service
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

문서 타이틀을 서비스 명칭과 일치시키세요.

PR/디렉토리명은 "painting-process-data-simulator-service"인데, 제목은 "Backend Simulator"로 되어 있습니다. 명칭 혼용은 혼란을 유발합니다.

적용 제안(diff):

-# Painting Process Backend Simulator Service
+# Painting Process Data Simulator Service
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
# Painting Process Backend Simulator Service
# Painting Process Data Simulator Service
🤖 Prompt for AI Agents
services/painting-process-data-simulator-service/README.md lines 1-1: README 제목이
디렉토리 및 서비스명과 일치하지 않아 혼동을 유발합니다; 파일 상단의 제목을 현재 디렉토리명/서비스명인
"painting-process-data-simulator-service" 또는 더 읽기 쉬운 서비스명(예: "Painting Process
Data Simulator Service")로 변경하여 PR 및 디렉토리명과 일치시키세요.


## 1. 서비스 소개
이 서비스는 **Painting Process Equipment Defect Detection Model Service**를 테스트하고 모니터링하기 위한 시뮬레이터입니다.
이 서비스는 Spring Boot 백엔드 애플리케이션으로 공정 데이터를 전송하는 시뮬레이터입니다.

주기적으로 Azure Blob Storage에 저장된 CSV 데이터를 읽어와 실시간 공정 데이터처럼 모델 서비스의 예측 API를 호출합니다. 그 후, 모델 서비스로부터 받은 결과(정상 또는 이상 감지)를 콘솔과 로그 파일에 기록하여 시스템의 동작을 검증하는 역할을 합니다.
주기적으로 Azure Blob Storage에 저장된 CSV 데이터를 읽어와, Spring Boot 백엔드의 API를 호출하여 데이터를 전송하는 역할을 합니다.

## 2. 주요 기능
- **주기적 데이터 시뮬레이션**: `APScheduler`를 사용하여 설정된 시간 간격마다 자동으로 데이터를 생성하고 예측을 요청합니다.
- **Azure Blob Storage 연동**: Azure Blob Storage에 저장된 실제 공정 데이터 기반의 CSV 파일을 읽어 시뮬레이션에 사용합니다.
- **모델 서비스 연동**: `HTTPX` 클라이언트를 사용하여 `painting-process-equipment-defect-detection-model-service`의 API를 비동기적으로 호출합니다.
- **상태 로깅**: 모델의 예측 결과를 `anomaly_logger`를 통해 이상(anomaly) 또는 정상(normal) 상태로 구분하여 로그를 기록합니다.
- **Docker 지원**: Dockerfile을 통해 컨테이너 환경에서 쉽게 서비스를 빌드하고 실행할 수 있으며, Docker Compose를 통한 통합 관리에도 용이합니다.
- **주기적 데이터 전송**: `APScheduler`를 사용하여 설정된 시간 간격마다 Azure의 데이터를 백엔드로 전송합니다.
- **Azure Blob Storage 연동**: Azure Blob Storage에 저장된 CSV 파일을 읽어 시뮬레이션에 사용합니다.
- **Spring Boot 백엔드 연동**: `HTTPX` 클라이언트를 사용하여 Spring Boot 백엔드의 API를 비동기적으로 호출합니다.

## 3. 프로젝트 구조

```text
painting-process-equipment-simulator-service/
painting-process-data-simulator-service/
├── app/
│ ├── main.py # FastAPI 애플리케이션의 메인 진입점
│ ├── config/
│ │ └── settings.py # Pydantic-settings를 이용한 환경 변수 및 설정 관리
│ │ ├── settings.py # Pydantic-settings를 이용한 환경 변수 및 설정 관리
│ │ └── logging_config.py # 서비스 로깅 설정
│ ├── routers/
│ │ ├── simulator_router.py # 시뮬레이터 시작/중지/상태 확인 API
│ │ └── test_connection_router.py # 외부 서비스(Azure, 모델) 연결 테스트 API
│ ├── services/
│ │ ├── scheduler_service.py # APScheduler를 사용한 핵심 스케줄링 로직
│ │ ├── model_client.py # 모델 예측 서비스 API 호출 클라이언트
│ │ └── azure_storage.py # Azure Blob Storage 데이터 처리 서비스
│ └── utils/
│ └── logger.py # 이상 및 정상 로그 기록 유틸리티
├── logs/ # 시뮬레이션 결과 로그가 저장되는 디렉토리
│ │ └── simulator_router.py # 시뮬레이터 시작/중지/상태 확인 API
│ └── services/
│ ├── scheduler_service.py # APScheduler를 사용한 핵심 스케줄링 로직
│ ├── backend_client.py # Spring Boot 백엔드 API 호출 클라이언트
│ └── azure_storage.py # Azure Blob Storage 데이터 처리 서비스
Comment on lines +20 to +27
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

설정 항목(환경 변수) 문서화 보강 제안.

settings.py에서 관리하는 주요 설정값(예: scheduler_interval_seconds, backend_service_url, log_directory 등)의 키명/기본값/유효성 제약을 README에 명시해 주세요. 운영/도커 배포 시 필수 정보입니다.

원하는 경우, .env 섹션 아래에 "환경 변수 요약" 표를 추가하는 패치를 제안할 수 있습니다.

🤖 Prompt for AI Agents
In services/painting-process-data-simulator-service/README.md around lines 20 to
27, add documentation for the key environment settings managed in settings.py:
list each env var name (e.g., scheduler_interval_seconds, backend_service_url,
log_directory, azure_blob_connection_string, storage_container,
scheduler_max_workers), their default values, expected types/validation rules
(ranges, required formats, URL pattern, integer min/max), and whether they are
mandatory for production/docker; include an ".env" subsection with a concise "환경
변수 요약" table showing key, default, required, and brief description so operators
can copy into Docker or deployment manifests.

├── .env # Azure 연결 문자열 등 민감한 환경 변수 파일
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Verification agent

🧩 Analysis chain

보안/운영 혼동 방지: .env 대신 .env.example 표시 권장.

프로젝트 트리에 .env를 직접 표기하면 커밋 오해를 유발합니다. 예시 파일(.env.example)을 트리에 노출하고, .env는 gitignore 대상임을 명시하세요.

적용 제안(diff):

-├── .env                             # Azure 연결 문자열 등 민감한 환경 변수 파일
+├── .env.example                     # 환경 변수 예시 파일 (.env는 git에 커밋하지 않음)

또한 .gitignore에 .env가 포함되어 있는지 확인 부탁드립니다.


🏁 Script executed:

#!/bin/bash
# Locate all .gitignore files and check for .env entries
find . -type f -name ".gitignore" | while read gitignore; do
  echo "Checking $gitignore"
  if grep -qE '(^|/)\.env($|[[:space:]])' "$gitignore"; then
    echo "  ✅ .env is already listed in $gitignore"
  else
    echo "  ❌ .env is NOT listed in $gitignore"
  fi
done

Length of output: 267


🏁 Script executed:

#!/bin/bash
# Locate the README for the painting-process-data-simulator-service
target=$(find . -type f -name README.md | grep painting-process-data-simulator-service)
echo "Found README at: $target"
echo "Lines with '.env':"
grep -n "├── .env" "$target" || echo "No matches found"

Length of output: 521


Replace .env entry in service README with .env.example

The .env file is already listed in .gitignore, so please update the tree diagram in the service’s README to refer to an example file instead:

• File: services/painting-process-data-simulator-service/README.md
– Line 28: change the .env entry to .env.example

Suggested patch:

--- a/services/painting-process-data-simulator-service/README.md
+++ b/services/painting-process-data-simulator-service/README.md
@@ -28,1 +28,1 @@
-├── .env                             # Azure 연결 문자열 등 민감한 환경 변수 파일
+├── .env.example                     # 환경 변수 예시 파일 (.env는 git에 커밋하지 않음)

Ensure you also include a real services/painting-process-data-simulator-service/.env.example with placeholder values.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
├── .env # Azure 연결 문자열 등 민감한 환경 변수 파일
├── .env.example # 환경 변수 예시 파일 (.env는 git에 커밋하지 않음)
🤖 Prompt for AI Agents
In services/painting-process-data-simulator-service/README.md around line 28,
the tree diagram currently shows a private `.env` file; change that entry to
`.env.example` and update the README accordingly, and add a new
services/painting-process-data-simulator-service/.env.example file containing
placeholder values for each required environment variable (do not include real
secrets), ensuring the example matches the variables used by the service and
that `.env` remains gitignored.

├── Dockerfile # Docker 이미지 빌드 설정
├── requirements.txt # Python 라이브러리 의존성 목록
Expand All @@ -38,9 +33,7 @@ painting-process-equipment-simulator-service/

## 4. 설치 및 실행 방법

### 4.1. 로컬 환경에서 실행

**사전 준비:** `painting-process-equipment-defect-detection-model-service`가 로컬 환경(`http://localhost:8001`)에서 먼저 실행 중이어야 합니다.
### 로컬 환경에서 실행

1. **Python 가상 환경 설정**:
```bash
Expand All @@ -57,66 +50,32 @@ painting-process-equipment-simulator-service/
```

3. **.env 파일 설정**:
프로젝트 루트에 `.env` 파일을 생성하고, Azure Storage 연결 문자열을 추가합니다.
프로젝트 루트에 `.env` 파일을 생성하고, Azure Storage 연결 문자열과 백엔드 서비스 URL을 추가합니다.
```env
AZURE_CONNECTION_STRING="<Your_Azure_Storage_Connection_String>"
BACKEND_SERVICE_URL="<Your_Backend_Service_URL>"
```
Comment on lines 52 to 57
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Verification agent

🧩 Analysis chain

.env 예시에 필수/권장 변수 추가.

스케줄러 주기와 로그 디렉토리 등 핵심 설정을 함께 예시로 제공하세요. 운영 시 초기 장애를 줄여줍니다.

적용 제안(diff):

     AZURE_CONNECTION_STRING="<Your_Azure_Storage_Connection_String>"
     BACKEND_SERVICE_URL="<Your_Backend_Service_URL>"
+    # 전송 주기(초). 예: 5
+    SCHEDULER_INTERVAL_SECONDS=5
+    # 로그 디렉토리(컨테이너/호스트 모두 쓰기 가능 경로)
+    LOG_DIRECTORY="logs"
+    # (선택) Azure Blob 선택을 위한 컨테이너/경로 설정이 필요한 경우 아래 키 사용
+    # AZURE_BLOB_CONTAINER="your-container"
+    # AZURE_BLOB_PREFIX="path/prefix/"

확인 요청:

  • settings.py에서 실제 사용하는 키명이 위와 동일한지 검증 필요합니다. 불일치 시 README를 settings와 동일하게 맞춰주세요.

🏁 Script executed:

#!/bin/bash
# Locate all settings.py files in the repo
echo "=== settings.py files ==="
fd --hidden --glob settings.py

# Search for environment variable accesses in the simulator service
echo "=== getenv and environ usage in service folder ==="
grep -R --color=always -nE "os\.getenv|os\.environ" services/painting-process-data-simulator-service

# Search specifically for scheduler and log-related keys
echo "=== Scheduler & Log keys ==="
grep -R -nE "SCHEDULER|LOG_DIRECTORY|BLOB_CONTAINER|BLOB_PREFIX" -n services/painting-process-data-simulator-service

Length of output: 731


🏁 Script executed:

#!/bin/bash
# Display the settings.py for painting-process-data-simulator-service
sed -n '1,200p' services/painting-process-data-simulator-service/app/config/settings.py

Length of output: 1066


.env 예시: 필수/권장 변수 추가 및 settings.py 키 이름 동기화

README의 .env 예시에 services/painting-process-data-simulator-service/app/config/settings.py에서 사용하는 모든 환경 변수 키를 반영해주세요. 주요 변경 사항:

  • AZURE_CONTAINER_NAME, PAINTING_DATA_FOLDER, BATCH_SIZE, HTTP_TIMEOUT 항목을 추가하여 기본값과 함께 예시 제공
  • 기존 제안된 AZURE_BLOB_CONTAINER/AZURE_BLOB_PREFIX 대신, 실제 사용하는 AZURE_CONTAINER_NAME으로 맞춤
  • SCHEDULER_INTERVAL_SECONDSLOG_DIRECTORY는 기본값 30초/“logs”로 유지

적용할 diff 예시 (파일: services/painting-process-data-simulator-service/README.md, 해당 섹션 교체):

  AZURE_CONNECTION_STRING="<Your_Azure_Storage_Connection_String>"
  BACKEND_SERVICE_URL="<Your_Backend_Service_URL>"
+# Azure Blob 컨테이너 이름 (기본: "simulator-data")
+AZURE_CONTAINER_NAME="simulator-data"
+# 페인팅 프로세스 데이터 저장 폴더 (기본: "painting-process-equipment")
+PAINTING_DATA_FOLDER="painting-process-equipment"
+# 스케줄러 주기(초) (기본: 30)
+SCHEDULER_INTERVAL_SECONDS=30
+# 배치 사이즈 (기본: 10)
+BATCH_SIZE=10
+# HTTP 타임아웃(초) (기본: 30)
+HTTP_TIMEOUT=30
+# 로그 디렉토리 (기본: "logs")
+LOG_DIRECTORY="logs"
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
3. **.env 파일 설정**:
프로젝트 루트에 `.env` 파일을 생성하고, Azure Storage 연결 문자열을 추가합니다.
프로젝트 루트에 `.env` 파일을 생성하고, Azure Storage 연결 문자열과 백엔드 서비스 URL을 추가합니다.
```env
AZURE_CONNECTION_STRING="<Your_Azure_Storage_Connection_String>"
BACKEND_SERVICE_URL="<Your_Backend_Service_URL>"
```
3. **.env 파일 설정**:
프로젝트 루트에 `.env` 파일을 생성하고, Azure Storage 연결 문자열과 백엔드 서비스 URL을 추가합니다.
🤖 Prompt for AI Agents
In services/painting-process-data-simulator-service/README.md around lines 52 to
57, the .env example is missing several variables used by
app/config/settings.py; update the example to replace
AZURE_BLOB_CONTAINER/AZURE_BLOB_PREFIX with AZURE_CONTAINER_NAME and add
AZURE_CONTAINER_NAME, PAINTING_DATA_FOLDER, BATCH_SIZE, HTTP_TIMEOUT (with
sensible defaults), and keep SCHEDULER_INTERVAL_SECONDS=30 and
LOG_DIRECTORY="logs"; ensure the README .env sample keys exactly match the names
used in settings.py and include brief default values for each variable.


4. **애플리케이션 실행**:
```bash
# 포트 8011에서 실행
uvicorn app.main:app --reload --port 8011
```
실행 후 `http://localhost:8011/docs`에서 API 문서를 확인할 수 있습니다.

### 4.2. Docker를 이용한 실행

**사전 준비:** `painting-process-equipment-defect-detection-model-service`가 `model-service`라는 컨테이너 이름으로 동일한 Docker 네트워크(`smart-fast-net`)에서 실행 중이어야 합니다.

1. **Docker 네트워크 생성** (이미 생성했다면 생략):
```bash
docker network create smart-fast-net
```

2. **모델 서비스 실행** (이미 실행 중이라면 생략):
```bash
# 모델 서비스 디렉토리에서 실행
docker build -t model-service .
docker run --name model-service --network smart-fast-net -p 8001:8001 model-service
```

Comment on lines 61 to 63
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Docker 실행 가이드 추가 제안.

PR 요약에 “Docker 환경(포트 8011)”이 강조되었으나, README에는 Docker 빌드/실행 예시가 없습니다. 도커 사용자 가이드가 필요합니다.

추가 제안(diff; 섹션 하단에 삽입):

  uvicorn app.main:app --reload --port 8011 
 }
 
+### Docker로 실행
+
+```bash
+# 이미지 빌드
+docker build -t painting-process-data-simulator:latest .
+
+# (권장) .env 사용 시
+docker run --rm -p 8011:8011 --env-file ./.env \
+  -v $(pwd)/logs:/app/logs \
+  --name painting-data-simulator \
+  painting-process-data-simulator:latest
+
+# (대안) 개별 환경변수 전달
+# docker run --rm -p 8011:8011 \
+#   -e AZURE_CONNECTION_STRING="..." \
+#   -e BACKEND_SERVICE_URL="..." \
+#   -e SCHEDULER_INTERVAL_SECONDS=5 \
+#   -e LOG_DIRECTORY="logs" \
+#   -v $(pwd)/logs:/app/logs \
+#   painting-process-data-simulator:latest
+```
🤖 Prompt for AI Agents
In services/painting-process-data-simulator-service/README.md around lines
61-63, the README lacks the Docker build and run examples referenced in the PR;
add a new subsection at the bottom showing how to build the image and run it
with port 8011 mapped, an example using --env-file and mounting ./logs to
/app/logs, and an alternative showing individual -e environment variables for
AZURE_CONNECTION_STRING, BACKEND_SERVICE_URL, SCHEDULER_INTERVAL_SECONDS and
LOG_DIRECTORY; ensure commands include docker build -t
painting-process-data-simulator:latest ., docker run --rm -p 8011:8011
--env-file ./.env -v $(pwd)/logs:/app/logs --name painting-data-simulator
painting-process-data-simulator:latest and commented example of docker run with
explicit -e variables.

3. **시뮬레이터 서비스 Docker 이미지 빌드**:
```bash
docker build -t simulator-service .
```
## 5. API 엔드포인트

4. **시뮬레이터 서비스 Docker 컨테이너 실행**:
`--env-file` 옵션을 사용하여 호스트의 `.env` 파일을 컨테이너의 환경 변수로 안전하게 주입합니다.
혹시 Azure storage가 잘 불러와지지 않는다면 -e AZURE_CONNECTION_STRING="Access-Key"를 직접 추가해주세요.
```bash
docker run --name simulator-service --network smart-fast-net \
-p 8011:8011 \
--env-file ./.env \
-e PAINTING_SERVICE_URL="http://model-service:8001" \
simulator-service
```
서비스가 시작되면 다음 URL로 API 문서(Swagger UI)에 접근할 수 있습니다: `http://localhost:8011/docs`

5. **로그 확인**:
```bash
# 시뮬레이터 로그 확인
docker logs -f simulator-service
```
| HTTP Method | Endpoint | Description |
| :---------- | :----------------- | :--------------------------- |
| `POST` | `/simulator/start` | 데이터 전송 시뮬레이션을 시작합니다. |
| `POST` | `/simulator/stop` | 실행 중인 시뮬레이션을 중지합니다. |
| `GET` | `/simulator/status`| 현재 스케줄러의 상태를 확인합니다. |

## 5. API 엔드포인트
## 6. 로깅 (Logging)

서비스가 시작되면 `http://localhost:8011/docs` (또는 Docker IP)에서 API 문서를 통해 아래 엔드포인트를 테스트할 수 있습니다.
이 서비스는 `app/config/logging_config.py` 파일을 통해 중앙에서 로깅 설정을 관리합니다.

| HTTP Method | Endpoint | Description |
| :---------- | :-------------------------------- | :----------------------------------------- |
| `POST` | `/simulator/start` | 데이터 시뮬레이션을 시작합니다. |
| `POST` | `/simulator/stop` | 실행 중인 시뮬레이션을 중지합니다. |
| `GET` | `/simulator/status` | 현재 스케줄러의 상태를 확인합니다. |
| `POST` | `/test/azure-storage-connection` | Azure Blob Storage 연결을 테스트합니다. |
| `POST` | `/test/models-connection` | 모델 서비스와의 연결을 테스트합니다. |
```text
```
- **로그 형식**: 모든 로그는 `시간 - 모듈 - 로그 레벨 - 메시지` 형식으로 기록됩니다.
- **로그 출력**:
- **콘솔**: 실시간으로 로그가 콘솔에 출력됩니다.
- **파일**: 로그는 `logs/service.log` 파일에도 저장되어, 서비스 실행 이력을 확인할 수 있습니다.
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import os
import logging
import sys
from app.config.settings import settings

def setup_logging():
"""Sets up centralized logging."""
# Ensure log directory exists
os.makedirs(settings.log_directory, exist_ok=True)
handlers = [logging.StreamHandler(sys.stdout)]
try:
handlers.append(logging.FileHandler(f"{settings.log_directory}/service.log"))
except OSError as e:
# fallback to stdout-only logging if file handler can't be created
logging.warning("FileHandler creation failed; using stdout-only logging. (%s)", e)

logging.basicConfig(
level=logging.INFO,
format="%(asctime)s - %(name)s - %(levelname)s - %(message)s",
handlers=handlers,
)
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
import os
from typing import Dict
from pydantic_settings import BaseSettings

from pydantic import AnyHttpUrl, field_validator

class Settings(BaseSettings):
# Azure Storage 설정
Expand All @@ -12,27 +10,32 @@ class Settings(BaseSettings):
painting_data_folder: str = "painting-process-equipment"

# 스케줄러 설정
scheduler_interval_minutes: int = 1
scheduler_interval_seconds: int = 30
batch_size: int = 10

# Painting Process Equipment 모델 서비스 설정
painting_service_url: str = os.getenv("PAINTING_SERVICE_URL", "http://localhost:8001")

# 로그 설정
log_directory: str = "logs"
log_filename: str = "painting_issue_logs.json"
error_log_filename: str = "painting_errors.json"
# Backend 서비스 설정
backend_service_url: AnyHttpUrl = "http://localhost:8088/equipment-data"

# HTTP 클라이언트 설정
http_timeout: int = 30
max_retries: int = 3

@property
def model_services(self) -> Dict[str, str]:
"""Painting Process Equipment 모델 서비스 URL"""
return {
"painting-process-equipment": self.painting_service_url
}

# 로그 디렉토리
log_directory: str = "logs"

# Validators
@field_validator("scheduler_interval_seconds")
@classmethod
def _positive_interval(cls, v: int) -> int:
if v <= 0:
raise ValueError("scheduler_interval_seconds must be > 0")
return v

Comment on lines +25 to +32
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Add Azure container name validation to fail fast

A malformed container name will cause runtime errors with Azure. Validate per Azure rules (3–63 chars; lowercase letters, numbers, hyphens; no leading/trailing hyphen; no consecutive hyphens).

Add a validator (and import re) alongside the existing validators:

import re

@field_validator("azure_container_name")
@classmethod
def _valid_container_name(cls, v: str) -> str:
    # must be 3-63 chars, lowercase letters/numbers/hyphens, no leading/trailing hyphen, no consecutive hyphens
    if not re.match(r'^(?!-)(?!.*--)[a-z0-9-]{3,63}(?<!-)$', v):
        raise ValueError("azure_container_name must be 3-63 chars, use lowercase letters/numbers/hyphens, no leading/trailing '-' or consecutive '-'")
    return v

Optionally, alias the connection string to the common Azure env name for convenience:

# Example (requires pydantic Field):
# azure_connection_string: str = Field(validation_alias="AZURE_STORAGE_CONNECTION_STRING")
🤖 Prompt for AI Agents
In services/painting-process-data-simulator-service/app/config/settings.py
around lines 25 to 32, there is no validation for azure_container_name which can
lead to runtime Azure errors; add an import for re at the top and implement a
field_validator for "azure_container_name" that uses a regex to enforce 3–63
characters, only lowercase letters/numbers/hyphens, no leading/trailing hyphen
and no consecutive hyphens (raise ValueError with a clear message on failure),
and optionally add a Field with
validation_alias="AZURE_STORAGE_CONNECTION_STRING" for the connection string if
you want the env var alias.

@field_validator("batch_size", "http_timeout")
@classmethod
def _positive_ints(cls, v: int) -> int:
if v <= 0:
raise ValueError("batch_size and http_timeout must be > 0")
return v

model_config = {
"env_file": ".env",
Expand Down
24 changes: 13 additions & 11 deletions services/painting-process-data-simulator-service/app/main.py
Original file line number Diff line number Diff line change
@@ -1,33 +1,37 @@
import logging
from fastapi import FastAPI
from contextlib import asynccontextmanager
from app.config.settings import settings
from app.services.scheduler_service import simulator_scheduler
from app.routers import simulator_router
from app.routers import connection_test_router
from app.config.logging_config import setup_logging

import os

# 로깅 설정
# Ensure log directory exists before creating FileHandler(s)
os.makedirs(settings.log_directory, exist_ok=True)
setup_logging()
logger = logging.getLogger(__name__)

@asynccontextmanager
async def lifespan(app: FastAPI):
"""애플리케이션 생명주기 관리"""
# 시작 시
print("🚀 Data Simulator Service 시작 중...")
logger.info("🚀 Data Simulator Service 시작 중...")

# 환경 변수 체크
if not settings.azure_connection_string:
logger.error("AZURE_CONNECTION_STRING 환경 변수가 설정되지 않았습니다.")
raise ValueError("AZURE_CONNECTION_STRING 환경 변수가 설정되지 않았습니다. .env 파일을 생성하거나 환경 변수를 설정해주세요.")

# 로그 디렉토리 생성
os.makedirs(settings.log_directory, exist_ok=True)

print(f"📁 로그 디렉토리: {settings.log_directory}")
print(f"🔧 스케줄러 간격: {settings.scheduler_interval_minutes}분")
print(f"🎯 대상 서비스 수: {len(settings.model_services)}")
logger.info(f"📁 로그 디렉토리: {settings.log_directory}")
logger.info(f"🔧 스케줄러 간격: {settings.scheduler_interval_seconds}초")

yield

# 종료 시
print("🛑 Data Simulator Service 종료 중...")
logger.info("🛑 Data Simulator Service 종료 중...")
if simulator_scheduler.is_running:
await simulator_scheduler.stop()

Expand All @@ -42,8 +46,6 @@ async def lifespan(app: FastAPI):
# 라우터 설정
# 시뮬레이터 활성화/비활성화/상태확인 API 모음
app.include_router(simulator_router.router, prefix="/simulator")
# azure storage 연결, model serving 서비스 연결 확인 API 모음
app.include_router(connection_test_router.router, prefix="/test")


# 아래는 서비스 기본 정보 확인과 서비스 헬스 체크 api 정의
Expand Down

This file was deleted.

Loading