SAP BTP Java DAY5. 자동화 + 마무리

이우철·2026년 5월 5일

SAP_BTP

목록 보기
11/11

[5일차] 자동화 + 마무리 + 다음 단계 — Java 버전

목표: 승인 워크플로우를 자동화하고, 5일간의 학습을 완성된 엔드-투-엔드 시나리오로 통합한다.
시나리오: SAP Build Process Automation으로 자동 승인 워크플로우 생성 → Java 앱과 REST 통합 → 전체 데모.
런타임: CAP Java (Spring Boot) + SAP Build PA
소요 시간: 이론 1.5시간 + 실습 2.5시간 + 발표 1시간


5일차 학습 목표

이론:
  자동화의 정의와 BTP에서의 위치를 이해한다
  SAP Build Process Automation (RPA + BPM)의 개념을 안다
  Workflow vs Integration Automation을 구분한다
  BTP 4대 기둥을 모두 경험한다

실습:
  SAP Build Process Automation 테넌트 활성화
  간단한 승인 워크플로우 생성 (UI 기반)
  Java 앱과 API 통합 (RestTemplate 사용) ← Java 특화
  5일 동안 만든 앱의 완전한 E2E 데모 시나리오 구성
  동료 앞에서 발표 (선택)
  최종 Git 커밋 및 다음 단계 가이드

이론 세션 (1.5시간)


이론 1. 자동화의 필요성

수동 프로세스의 문제점

출장비 승인 프로세스 (Traditional):

1. 신청자: 이메일로 신청서 작성
2. 신청자: PDF로 변환 후 매니저에게 이메일
3. 매니저: 이메일 확인, 스프레드시트에 기록
4. 매니저: 회계팀에 이메일 전달
5. 회계팀: 또 다른 시스템에 재입력
6. 회계팀: 지출 처리 및 송금
7. 신청자: "언제 나오나?" 추적 불가

→ 4-5일 소요, 에러 발생 확률 높음

자동화된 프로세스 (이 강좌 후)

1. [신청자] 앱에서 신청
   ↓
2. [시스템] 자동으로 매니저에게 알림 (메일)
   ↓
3. [매니저] 앱에서 승인/반려 (1-2시간 내)
   ↓
4. [시스템] 자동으로 회계팀에 전달
   ↓
5. [회계팀] 다른 시스템 수동 입력 (또는 API 자동화로 제거)
   ↓
6. [신청자] 앱에서 실시간 상태 조회 가능

→ 2-3시간 소요, 에러 0%, 추적 가능

이론 2. BTP의 자동화 포지셔닝

┌─────────────────────────────────────────────────────┐
│              SAP Business Technology Platform       │
│                                                     │
│  ┌─────────────┐  ┌────────────┐  ┌─────────────┐  │
│  │ 데이터&분석 │  │   통합     │  │ 앱 개발     │  │
│  │(Analytics)  │  │(Integration)  │ (CAP Java)  │  │
│  └─────────────┘  └────────────┘  └─────────────┘  │
│         ↓               ↓                ↓          │
│      분석            시스템간           개발         │
│                     데이터 흐름         (DAY1-4)    │
│                                                     │
│  ┌───────────────────────────────────────────────┐  │
│  │     AI & Automation (자동화) ← 오늘 배우는 것  │  │
│  │                                               │  │
│  │  SAP Build Process Automation (BPA)           │  │
│  │  ├─ RPA: 사람의 반복 작업 자동화              │  │
│  │  │  (마우스, 키보드 자동 조작)                 │  │
│  │  │                                            │  │
│  │  └─ BPM: 비즈니스 프로세스 자동화 ← 오늘       │  │
│  │     (의사결정, 워크플로우)                    │  │
│  └───────────────────────────────────────────────┘  │
│                                                     │
└─────────────────────────────────────────────────────┘

이론 3. SAP Build Process Automation (BPA)

RPA vs BPM

구분RPABPM
대상사람의 반복 작업비즈니스 프로세스
웹 양식 자동 입력승인 워크플로우
기술화면 조작 자동화프로세스 흐름 정의
개발자불필요비즈니스 애널리스트
이 강좌10분 시연집중 실습

이론 4. Java와 BPA의 통신

출장비 신청 앱 (Java CAP)
    ↓ (신청 제출)
[Java Handler] triggerApprovalWorkflow()
    ↓ (HTTP POST + RestTemplate)
SAP Build PA API
    ↓ (워크플로우 시작)
[의사결정] 금액 확인 → 매니저/CFO 할당
    ↓ (사용자 승인)
[REST Call] CAP Java API 호출
    ↓ (PATCH /travel/TravelRequests)
[Java Handler] handleApprovalCallback()
    ↓ (상태 업데이트)
Database (HANA)
    ↓
[신청자] 앱에서 상태 조회

실습 세션 (2.5시간)


실습 1. SAP Build Process Automation 활성화

1-1. 테넌트 생성 (Node.js와 동일)

BTP Cockpit:

trial Subaccount
  → Service Marketplace
    → "SAP Build Process Automation" 검색
      → Create Instance
         Plan: "Standard"
         Instance Name: "travel-automation"
         → Create

1-2. 테넌트 접근

완료 후:

Service Instances and Subscriptions
  → "SAP Build Process Automation"
    → "Go to Application"

실습 2. 승인 워크플로우 생성 (Node.js와 동일)

2-1. 새 프로세스 생성

SAP Build Tenant
  → Build Processes
    → Create
       Name: "Travel Approval Workflow"
       Project: "Travel Expense App"
       → Create

2-2. 워크플로우 단계 설계

Step 1: 트리거

Trigger: "Travel Request Created"
├─ request_id (UUID)
├─ title (String)
├─ amount (Decimal)
└─ requester_email (String)

Step 2: 의사결정

Decision: "Check Amount"
├─ IF amount >= 1000000 → CFO 승인 필요
└─ ELSE → 매니저 승인

Step 3: 사용자 태스크

Task: "Manager/CFO Approval"
├─ Assigned To: [매니저 또는 CFO]
├─ Title: "{{ title }} 승인 필요"
├─ Actions: Approve / Reject
└─ Due Date: Today + 1 Day

Step 4: REST API 호출 (Java와 동일하게 BPA에서 설정)

REST Call: "Update CAP Backend"
├─ Method: PATCH
├─ URL: {{ environment.backendUrl }}/travel/TravelRequests({{ requestId }})
├─ Body: { "status": "{{ approvalDecision }}" }
├─ Auth: OAuth 2.0
└─ Output: Response

Step 5: 알림

Email: "Send Result"
├─ To: {{ requester_email }}
├─ Subject: "출장비 신청 {{ approvalDecision }}"
└─ Body: 결과 메시지

Step 6: 완료

End: "Process Complete"

2-3. 테스트 및 저장

Save → Test
  ├─ 입력값 제공
  │  request_id: "xxxxx"
  │  title: "도쿄 출장"
  │  amount: 850000
  │  requester_email: "user@example.com"
  └─ Run

실습 3. Java 앱과 통합 (Java 특화)

3-1. pom.xml에 RestTemplate 의존성 확인

이미 Spring Web에 포함되어 있으므로 추가 작업 불필요:

<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-web</artifactId>
</dependency>

3-2. Java Handler에 BPA 통합 코드 추가

TravelServiceHandler.java 에 추가:

import org.springframework.web.client.RestTemplate;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.beans.factory.annotation.Value;

@Component
@ServiceName("TravelService")
public class TravelServiceHandler {
  
  @Value("${bpa.endpoint:}")
  private String bpaEndpoint;
  
  @Value("${bpa.auth-token:}")
  private String bpaAuthToken;
  
  private final RestTemplate restTemplate;
  
  // 생성자 주입
  public TravelServiceHandler(RestTemplate restTemplate) {
    this.restTemplate = restTemplate;
  }

  /**
   * 신청 제출 시 BPA 워크플로우 트리거
   */
  @On(event = "submit", entity = "TravelRequests")
  public void onSubmitTravelRequest(TravelRequests request) {
    // 상태 업데이트
    request.setStatus("Submitted");
    db.update(request).execute();

    // BPA 워크플로우 트리거 (로컬에서는 스킵)
    if (bpaEndpoint != null && !bpaEndpoint.isEmpty()) {
      triggerApprovalWorkflow(request);
    }
  }

  /**
   * BPA 워크플로우 트리거
   * RestTemplate를 사용한 HTTP POST
   */
  private void triggerApprovalWorkflow(TravelRequests request) {
    try {
      // 페이로드 구성
      Map<String, Object> payload = new HashMap<>();
      payload.put("request_id", request.getId());
      payload.put("title", request.getTitle());
      payload.put("amount", request.getTotalAmount());
      payload.put("requester_email", request.getRequesterEmail());

      // HTTP 헤더 설정
      HttpHeaders headers = new HttpHeaders();
      headers.setContentType(MediaType.APPLICATION_JSON);
      headers.setBearerAuth(bpaAuthToken);

      // HTTP 요청 생성
      HttpEntity<Map<String, Object>> httpRequest = 
        new HttpEntity<>(payload, headers);

      // BPA API 호출
      String bpaUrl = bpaEndpoint + "/workflows/Travel%20Approval%20Workflow";
      Map<String, Object> response = restTemplate.postForObject(
        bpaUrl,
        httpRequest,
        Map.class
      );

      log.info("BPA 워크플로우 트리거: {}", request.getId());

    } catch (Exception e) {
      // 워크플로우 실패해도 신청은 계속 진행 (로그만 기록)
      log.warn("BPA 트리거 실패: {}", e.getMessage());
    }
  }

  /**
   * BPA 워크플로우 콜백 (BPA에서 호출)
   */
  @PostMapping("/callbacks/approvalResult")
  public Map<String, Object> handleApprovalCallback(
    @RequestBody Map<String, Object> result
  ) {
    log.info("BPA 콜백 수신: {}", result);

    try {
      String requestId = (String) result.get("request_id");
      String decision = (String) result.get("approvalDecision");

      // DB 업데이트
      TravelRequests request = db.selectOne(TravelRequests.class)
        .byKey(requestId)
        .execute();

      if (request != null) {
        request.setStatus(decision); // "Approved" 또는 "Rejected"
        db.update(request).execute();
      }

      return Map.of("status", "success");
    } catch (Exception e) {
      return Map.of("status", "error", "message", e.getMessage());
    }
  }
}

3-3. application.yaml 설정

src/main/resources/application.yaml:

# BPA 통합 설정 (클라우드에서 환경 변수로 제공)
bpa:
  endpoint: ${BPA_ENDPOINT:}
  auth-token: ${BPA_AUTH_TOKEN:}

클라우드 배포 시:

cf set-env travel-api BPA_ENDPOINT "https://your-bpa-tenant..."
cf set-env travel-api BPA_AUTH_TOKEN "your-token"
cf restage travel-api

실습 4. E2E (End-to-End) 데모 시나리오

4-1. 로컬에서 테스트

# 터미널 1: Java 서버
mvn spring-boot:run

# 터미널 2: Fiori UI
cd app/travel-expense-ui
npm start

브라우저에서:

http://localhost:3000
  → [신청서 작성]
  → 제목: "도쿄 출장"
  → 금액: 850,000
  → [Create] 클릭
    ↓
  [목록에 추가됨 (Draft)]
  → 해당 항목 클릭
    ↓
  [Object Page 열기]
  → [Submit] 클릭
    ↓
  상태 → "Submitted"
  → (로컬: BPA 트리거 안 됨 — 정상)

4-2. 클라우드에서 E2E 데모

1. 신청자: 앱 접속 → 신청 생성 → 제출
   ↓
2. Java CAP: triggerApprovalWorkflow() 자동 호출
   ↓
3. SAP Build PA: 워크플로우 시작
   ↓
4. 매니저: BPA의 "My Tasks"에서 승인 버튼 클릭
   ↓
5. SAP Build PA: REST Call 실행
   ↓
6. Java CAP: /callbacks/approvalResult 수신
   ↓
7. 신청자: 앱에서 상태 "Approved" 확인

실습 5. 최종 Git 커밋

cd /home/user/projects/sap-btp-travel-expense

# 최종 파일 추가
git add .

# 커밋
git commit -m "day5: SAP Build PA 워크플로우 + Java RestTemplate 통합 + E2E 완성"

# 태그 추가 (버전 관리)
git tag -a v1.0.0-complete -m "5일 강좌 완성 (Java CAP)"

# 푸시
git push origin main
git push origin v1.0.0-complete

실습 6. 최종 README 작성

프로젝트 루트에 README.md:

# 출장비 승인 앱 (Travel Expense App) — Java 버전

SAP BTP에서 구축한 완전한 엔드-투-엔드 애플리케이션입니다.

## 기술 스택

- **Backend:** CAP Java (Spring Boot 3.x)
- **Frontend:** Fiori Elements (SAPUI5)
- **Database:** SQLite (로컬) / HANA Cloud (클라우드)
- **Security:** XSUAA + Spring Security
- **Automation:** SAP Build Process Automation
- **Deployment:** Cloud Foundry (MTA)

## 빠른 시작 (로컬)

```bash
# 1. Java 서버 시작
mvn spring-boot:run

# 2. Fiori UI 시작 (다른 터미널)
cd app/travel-expense-ui
npm start

# 3. 접속
http://localhost:3000

강좌 결과물

DAY1: BTP 개념 + CAP Java 시작
DAY2: CDS 모델링 + Java Handler
DAY3: Fiori Elements UI
DAY4: 클라우드 보안 & 배포
DAY5: 자동화 + E2E 완성

주요 기능

  • 신청 관리 (Create → Submit → Approve/Reject)
  • 자동 승인 워크플로우
  • 실시간 상태 추적
  • 역할 기반 접근 제어

자세한 내용은 강의 자료 참조.


---

## 5일차 마무리 체크

[ ] SAP Build PA 테넌트 활성화
[ ] 워크플로우 설계 완료
[ ] Java RestTemplate으로 BPA 트리거
[ ] BPA 콜백 핸들러 구현
[ ] 로컬 E2E 테스트 성공
[ ] 클라우드 배포 완료
[ ] 최종 README 작성
[ ] Git 커밋 + 태그


---

## 5일 강좌 최종 성과

SAP BTP의 4대 기둥 이해
CAP Java로 엔터프라이즈 백엔드 구축
Fiori Elements로 엔터프라이즈 UI 자동 생성
XSUAA + Spring Security로 클라우드 보안
MTA로 Cloud Foundry 배포
SAP Build PA로 자동화 통합
완전한 E2E 애플리케이션 완성

이제 혼자 비슷한 앱을 만들 수 있습니다!


---

> **다음:** 심화 학습 경로 (Integration Suite, Analytics Cloud, Kyma)
profile
개발 정리 공간 - 업무일때도 있고, 공부일때도 있고...

0개의 댓글