본문으로 건너뛰기

command

command는 XML 계약을 기준으로 서버 측 CLI 프로세스와 Web URL 호출을 실행하는 모듈입니다. transact 계약에서 CommandType을 C로 지정하면 RoutingCommandUri 규칙에 따라 /command/api/execution으로 라우팅됩니다.

책임 범위​

  • 계약에 등록된 실행 파일, 인자, 작업 디렉터리를 해석해 shell 없이 프로세스를 실행합니다.
  • HTTP 요청 계약을 읽어 URL, query string, header, authorization, body를 구성합니다.
  • { @Parameter }, { #Parameter } 치환 규칙으로 요청 값을 실행 명령이나 Web 요청에 주입합니다.
  • 실행 결과를 HandStack의 표준 응답 형식으로 반환하고, 필요 시 logger 모듈로 거래 로그를 전송합니다.

주요 API​

메서드경로용도
GET/command/api/execution/has계약 캐시에 실행 ID가 있는지 확인합니다.
GET/command/api/execution/refresh계약 파일을 다시 읽어 캐시를 갱신합니다.
GET/command/api/execution/retrieve실행 계약 원문 또는 메타 정보를 조회합니다.
GET/command/api/execution/meta실행 계약의 입력/출력 메타 정보를 반환합니다.
POST/command/api/executionCLI 또는 Web 요청 계약을 실행합니다.

has, refresh, retrieve, meta의 파라미터와 인증 규칙(실패 시 400)은 transact 모듈의 계약 관리 API 공통 규칙을 보세요.

핵심 구현​

  • Areas/command/Controllers/ExecutionController.cs: 외부 API 진입점입니다.
  • DataClient/CommandDataClient.cs: 계약 검색, 파라미터 바인딩, CLI/Web 실행을 담당합니다.
  • Extensions/CommandMapper.cs: XML 계약을 메모리 매핑으로 로드하고 refresh를 처리합니다.
  • Entity/ModuleConfigJson.cs: module.json의 설정 스키마입니다.

계약과 식별자​

계약은 기본적으로 다음 위치에 둡니다.

contracts/command/{ApplicationID}/{ProjectID}/{TransactionID}.xml

실행 ID는 다음 형식으로 조회됩니다.

ApplicationID|ProjectID|TransactionID|CommandID

계약의 <commands>는 CLI 실행을, <requests>는 Web URL 호출을 정의합니다. CommandID는 계약의 id와 seq 조합으로 관리되므로, 같은 거래 파일 안에서 중복되지 않아야 합니다.

계약 파일 형식 (.bas)​

한 계약에 CLI 프로세스(<commands>)와 외부 HTTP 호출(<requests>)을 정의합니다. 확장자는 .xml 또는 .bas입니다(계약 확장자).

<mapper xmlns="contract.xsd">
<header>
<application>HDS</application><project>ABC</project><transaction>ABC030</transaction>
<use>Y</use><timeout>30</timeout><maxOutputBytes>1048576</maxOutputBytes><desc>설명</desc>
</header>
<commands>
<command id="GC01" seq="0" use="Y" timeout="30" desc="버전 조회">
<executable>dotnet</executable>
<arguments>--info</arguments>
<workingDirectory>../</workingDirectory>
<environment><variable id="APP_USER">{@UserID}</variable></environment>
<successExitCodes>0</successExitCodes>
<param id="@UserID" type="String" length="255" value="NULL" />
</command>
</commands>
<requests>
<request id="GW01" seq="0" use="Y" timeout="30" desc="사용자 조회">
<method>POST</method>
<url>https://api.example.com/users</url>
<headers><header id="Accept">application/json</header></headers>
<querystrings><value id="userID">{@UserID}</value></querystrings>
<authorization type="Bearer">{@AccessToken}</authorization>
<body type="raw" contentType="application/json">{ "userID": {#UserID} }</body>
<param id="@UserID" type="String" length="255" value="NULL" />
<param id="@AccessToken" type="String" length="4000" value="NULL" />
<outputmeta value="Result:string" />
</request>
</requests>
</mapper>
항목의미
{@이름}파라미터 값을 그대로 치환합니다
{#이름}값을 JSON 문자열 리터럴(따옴표 포함, 역슬래시·큰따옴표·개행 이스케이프)로 치환합니다. JSON 본문과 인자에 넣는 사용자 입력에 쓰세요
없는 파라미터빈 문자열이 됩니다
authorization typeBearer, JwtBearer, Basic(username·password 속성), ApiKey(name, in은 Header 또는 Query)
body typeraw, form-data(<part type>은 text 또는 file)
timeout, successExitCodes, maxOutputBytes제한 시간, 성공으로 보는 종료 코드, 출력 최대 크기(초과분은 잘림)

계약을 쓸 때 확인할 것:

  • 실행 파일과 인자를 셸 없이 분리해 선언하고 문자열을 이어 붙여 명령줄을 만들지 않습니다. 실행 파일은 Security.AllowedExecutableBasePaths 허용 경로 안에 있어야 합니다.
  • 인증 키와 토큰은 계약에 고정하지 말고 파라미터나 서버 설정으로 주입합니다. 외부 URL과 계정은 환경별 값이므로 예제 도메인을 운영 값으로 바꿔 커밋하지 마세요.
  • 테스트에서 패키지 설치, 메일 발송, 운영 명령을 실행하지 않습니다. 실제 외부 API 호출이 필요하면 모의 서버나 승인된 대상으로 제한하세요.

주요 설정​

설정설명
ContractBasePathcommand XML 계약 루트 목록입니다.
IsContractFileWatching계약 파일 변경 감시 여부입니다. 개발 환경에서는 편리하지만 운영에서는 변경 통제와 함께 사용합니다.
DefaultCommandTimeout계약에 timeout이 없을 때 적용되는 기본 실행 제한 시간입니다.
DefaultMaxOutputBytesCLI 실행 결과로 수집할 최대 출력 크기입니다.
Security.AllowedExecutableBasePathsCLI 실행 파일을 허용할 기준 경로 목록입니다. 비어 있으면 운영 정책상 허용 범위를 별도로 검토해야 합니다.
Security.BlockedForwardHeadersWeb 요청으로 전달하지 않을 HTTP 헤더 목록입니다.
LogServerUrl거래 로그를 전송할 logger API입니다.

transact 연동​

transact 거래 계약에서는 CommandType을 C로 둡니다.

{
"ServiceID": "CMD010",
"CommandType": "C",
"ReturnType": "Json"
}

transact/module.json의 라우팅은 환경별로 다음 형태를 사용합니다.

{
"HDS|*|C|D": "http://localhost:8421/command/api/execution",
"HDS|*|C|P": "http://localhost:8421/command/api/execution",
"HDS|*|C|T": "http://localhost:8421/command/api/execution"
}

운영 주의사항​

  • command는 서버 권한으로 외부 프로세스를 실행할 수 있으므로 계약 리뷰와 실행 파일 allowlist가 필수입니다.
  • shell 문자열을 조립하는 방식이 아니라 실행 파일과 인자를 분리해 선언해야 합니다.
  • Web 요청 계약에서 인증 헤더와 API Key를 사용할 때는 값 자체를 계약에 고정하지 말고 환경별 설정이나 요청 파라미터로 주입합니다.
  • 운영 환경에서는 DefaultCommandTimeout, DefaultMaxOutputBytes, 로그 저장 정책을 서비스별로 검토합니다.