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
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@


class Settings(BaseSettings):
# ✅ 환경 구분 (기본값을 local로 변경)
environment: str = "production" # 기본값을 다시 local로 변경

Comment on lines +7 to +9
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

Default env should be 'local' (not 'production') to avoid accidental prod traffic

Comment and value conflict. Use a safe default.

-    environment: str = "production"  # 기본값을 다시 local로 변경
+    environment: str = "local"  # 안전한 기본값 (개발)
📝 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
# ✅ 환경 구분 (기본값을 local로 변경)
environment: str = "production" # 기본값을 다시 local로 변경
# ✅ 환경 구분 (기본값을 local로 변경)
environment: str = "local" # 안전한 기본값 (개발)
🤖 Prompt for AI Agents
In services/welding-machine-data-simulator-service/app/config/settings.py around
lines 7 to 9, the environment default is set to "production" while the comment
indicates it should be "local"; change the hardcoded default value to "local" so
the line reads environment: str = "local" (or adjust the configuration source to
default to "local") to ensure a safe non-production default and keep the comment
and value consistent.

# Azure Storage 설정
azure_connection_string: str
azure_container_name: str = "simulator-data"
Expand All @@ -15,25 +18,109 @@ class Settings(BaseSettings):
scheduler_interval_minutes: int = 1
batch_size: int = 10

# Welding Machine 모델 서비스 설정
# ✅ 기존 호환성을 위한 필드 (deprecated but needed)
welding_machine_url: str = "http://localhost:8006"

# ✅ 환경별 서비스 URL 설정
# 로컬 개발
local_gateway_url: str = "http://localhost:8088"
local_model_service_url: str = "http://localhost:8006"

# Docker Compose
docker_gateway_url: str = "http://gateway:8088"
docker_model_service_url: str = "http://welding-model-service:8006"

# AKS Kubernetes (내부 서비스 통신)
kubernetes_gateway_url: str = "http://gateway.smart-be.svc.cluster.local:8088"
kubernetes_model_service_url: str = "http://sf-welding-machine-defect-detection-model-service.sf-welding-machine-defect-detection-model-service.svc.cluster.local:80"

# ✅ Production (현재 실제 배포된 URL) - 기본값으로 설정
production_gateway_url: str = "http://20.249.138.42:8088" # 배포시 기본값
production_model_service_url: str = "http://20.249.138.42:8088/api/v1/welding/defect"

# HTTP 설정
spring_boot_timeout: int = 30
spring_boot_max_retries: int = 3
http_timeout: int = 30
max_retries: int = 3

# 로그 설정
log_directory: str = "logs"
log_filename: str = "welding_anomaly_detections.json"
error_log_filename: str = "welding_errors.json"

# HTTP 클라이언트 설정
http_timeout: int = 30
max_retries: int = 3
def __init__(self, **kwargs):
super().__init__(**kwargs)
# ✅ 명시적으로 environment가 설정되지 않은 경우에만 자동 감지
if not kwargs.get('environment') and not os.getenv('ENVIRONMENT'):
# 특정 조건에서만 production으로 감지 (더 엄격한 조건)
if (hasattr(self, 'azure_connection_string') and
self.azure_connection_string and
self.azure_connection_string != "your_azure_connection_string" and
"localhost" not in self.azure_connection_string and
# 추가 조건: Kubernetes 환경 변수 존재 여부
(os.getenv('KUBERNETES_SERVICE_HOST') or os.getenv('WEBSITE_HOSTNAME'))):
self.environment = "production"
else:
self.environment = "local"

Comment on lines +52 to +66
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

Kubernetes auto-detection currently sets environment='production' → wrong URL map

When KUBERNETES_SERVICE_HOST is present, you should select 'kubernetes' to use in-cluster URLs. Today this will route pods to the external prod IP.

-        if not kwargs.get('environment') and not os.getenv('ENVIRONMENT'):
-            # 특정 조건에서만 production으로 감지 (더 엄격한 조건)
-            if (hasattr(self, 'azure_connection_string') and
-                self.azure_connection_string and
-                self.azure_connection_string != "your_azure_connection_string" and
-                "localhost" not in self.azure_connection_string and
-                # 추가 조건: Kubernetes 환경 변수 존재 여부
-                    (os.getenv('KUBERNETES_SERVICE_HOST') or os.getenv('WEBSITE_HOSTNAME'))):
-                self.environment = "production"
-            else:
-                self.environment = "local"
+        if not kwargs.get('environment') and not os.getenv('ENVIRONMENT'):
+            # 우선순위: Kubernetes → Production(웹앱 등) → Local
+            if os.getenv('KUBERNETES_SERVICE_HOST'):
+                self.environment = "kubernetes"
+            elif (
+                self.azure_connection_string
+                and self.azure_connection_string != "your_azure_connection_string"
+                and "localhost" not in self.azure_connection_string
+            ) or os.getenv('WEBSITE_HOSTNAME'):
+                self.environment = "production"
+            else:
+                self.environment = "local"
📝 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
def __init__(self, **kwargs):
super().__init__(**kwargs)
# ✅ 명시적으로 environment가 설정되지 않은 경우에만 자동 감지
if not kwargs.get('environment') and not os.getenv('ENVIRONMENT'):
# 특정 조건에서만 production으로 감지 (더 엄격한 조건)
if (hasattr(self, 'azure_connection_string') and
self.azure_connection_string and
self.azure_connection_string != "your_azure_connection_string" and
"localhost" not in self.azure_connection_string and
# 추가 조건: Kubernetes 환경 변수 존재 여부
(os.getenv('KUBERNETES_SERVICE_HOST') or os.getenv('WEBSITE_HOSTNAME'))):
self.environment = "production"
else:
self.environment = "local"
def __init__(self, **kwargs):
super().__init__(**kwargs)
# ✅ 명시적으로 environment가 설정되지 않은 경우에만 자동 감지
if not kwargs.get('environment') and not os.getenv('ENVIRONMENT'):
# 우선순위: Kubernetes → Production(웹앱 등) → Local
if os.getenv('KUBERNETES_SERVICE_HOST'):
self.environment = "kubernetes"
elif (
self.azure_connection_string
and self.azure_connection_string != "your_azure_connection_string"
and "localhost" not in self.azure_connection_string
) or os.getenv('WEBSITE_HOSTNAME'):
self.environment = "production"
else:
self.environment = "local"
🤖 Prompt for AI Agents
In services/welding-machine-data-simulator-service/app/config/settings.py around
lines 52 to 66, the auto-detection sets environment="production" whenever
KUBERNETES_SERVICE_HOST is present which causes pods to use external prod URLs;
change the logic so that if KUBERNETES_SERVICE_HOST is set you assign
environment="kubernetes" (to use in-cluster URLs) before falling back to
production (e.g. when WEBSITE_HOSTNAME indicates an App Service) and finally to
"local"; keep the guard so this auto-detection only runs when no explicit
kwargs['environment'] or ENVIRONMENT is set.

@property
def gateway_service_url(self) -> str:
"""환경에 따른 게이트웨이 서비스 URL"""
url_map = {
"local": self.local_gateway_url,
"development": self.local_gateway_url,
"docker": self.docker_gateway_url,
"kubernetes": self.kubernetes_gateway_url,
"production": self.production_gateway_url,
}
return url_map.get(self.environment, self.local_gateway_url)

@property
def model_service_url(self) -> str:
"""환경에 따른 모델 서빙 서비스 URL"""
url_map = {
"local": self.local_model_service_url,
"development": self.local_model_service_url,
"docker": self.docker_model_service_url,
"kubernetes": self.kubernetes_model_service_url,
"production": self.production_model_service_url,
}
return url_map.get(self.environment, self.local_model_service_url)

@property
def model_services(self) -> Dict[str, str]:
"""Welding Machine 모델 서비스 URL"""
"""Welding Machine 모델 서비스 URL (기존 호환성 유지)"""
return {
"welding-machine": self.welding_machine_url
"welding-machine": self.welding_machine_url # 기존 필드 사용
}

@property
def spring_boot_service_url(self) -> str:
"""기존 호환성을 위한 별칭"""
return self.gateway_service_url

@property
def spring_boot_endpoints(self) -> Dict[str, str]:
"""스프링부트 서비스 엔드포인트 (게이트웨이 경유)"""
base_url = self.gateway_service_url

return {
"welding_data": f"{base_url}/weldingMachineDefectDetectionLogs",
"health": f"{base_url}/actuator/health",
"status": f"{base_url}/weldingMachineDefectDetectionLogs"
}

@property
def is_local_environment(self) -> bool:
"""로컬 환경 여부 확인"""
return self.environment in ["local", "development"]

@property
def is_production_environment(self) -> bool:
"""프로덕션 환경 여부 확인"""
return self.environment in ["production", "kubernetes"]

model_config = {
"env_file": ".env",
"env_file_encoding": "utf-8"
Expand Down
29 changes: 16 additions & 13 deletions services/welding-machine-data-simulator-service/app/main.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
from fastapi import FastAPI
from fastapi.middleware.cors import CORSMiddleware
from contextlib import asynccontextmanager
from app.config.settings import settings
from app.services.scheduler_service import simulator_scheduler
Expand All @@ -9,16 +10,12 @@

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

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

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

print(f"📁 로그 디렉토리: {settings.log_directory}")
Expand All @@ -27,30 +24,37 @@ async def lifespan(app: FastAPI):

yield

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

# FastAPI 앱 생성

app = FastAPI(
title="Welding Machine Data Simulator Service",
description="용접기 결함 탐지 모델을 위한 실시간 데이터 시뮬레이터",
version="1.0.0",
lifespan=lifespan
)

# 라우터 설정
# 시뮬레이터 활성화/비활성화/상태확인 API 모음
# ✅ CORS (개발 환경)
origins = ["http://localhost:3000"]
app.add_middleware(
CORSMiddleware,
allow_origins=origins, # 프론트 도메인 명시
allow_credentials=True, # 쿠키/인증 헤더 사용 시 True
allow_methods=["*"], # 또는 ["GET","POST","OPTIONS",...]
allow_headers=["*"],
)

# ✅ 라우터: 여기에서만 최종 prefix 부여
# simulator_router 내부는 @router.get("/status")처럼 상대 경로만 있어야 함
app.include_router(simulator_router.router, prefix="/simulator")
# azure storage 연결, model serving 서비스 연결 확인 API 모음
app.include_router(test_connection_router.router, prefix="/test")
app.include_router(test_connection_router.router,
prefix="/test")


# 아래는 서비스 기본 정보 확인과 서비스 헬스 체크 api 정의
@app.get("/")
async def root():
"""서비스 정보"""
return {
"service": "Welding Machine Data Simulator Service",
"version": "1.0.0",
Expand All @@ -62,5 +66,4 @@ async def root():

@app.get("/health")
async def health_check():
"""헬스 체크"""
return {"status": "healthy"}
Loading
Loading