SAP BC/SAP

# [SAP] Import Queue Clear Script ( 임포트 큐 정리 스크립트 )

leehi0110 2024. 9. 23. 08:00
반응형

0. 이해를 위한 사전 지식

# [SAP] CTS ( Change and Transport System )

0. CTS를 알기 위한 사전 지식 일반적으로 SAP System은 개발 ( DEV ) - 검증 ( QAS ) - 운영 ( PROD )의 형태로 구성된다. ( 상황에 따라서는 개발/검증을 하나의 서버에 Client로 구분하여 사용하기도 하지만

leehi0110.tistory.com

# [SAP] Transport Request - STMS

0. 이해를 위한 사전 지식2024.08.05 - [SAP/BC] - # [SAP] Import options2023.08.23 - [SAP/BC] - # [SAP] CTS ( Change and Transport System )  # [SAP] CTS ( Change and Transport System )0. CTS를 알기 위한 사전 지식 일반적으로 SAP Syste

leehi0110.tistory.com

# [SAP] Import Queue ( Import Queue 정리 )

0. 이해를 위한 사전 지식CTS 란 ? 2023.08.23 - [SAP/BC] - # [SAP] CTS ( Change and Transport System ) # [SAP] CTS ( Change and Transport System )0. CTS를 알기 위한 사전 지식 일반적으로 SAP System은 개발 ( DEV ) - 검증 ( QAS ) -

leehi0110.tistory.com

1. 스크립트 컨셉

  • tp cleanbuffer 명령어를 수행할 경우, Import Buffer의 이력이 아예 삭제되기 때문에 이력을 유지하며 Import Queue 정리가 필요함
  • tp showbuffer 명령어를 수행하여 이관 된, Request number ( 성공, 실패, 경고 포함 )을 확인
  • /usr/sap/trans/buffer/<SID> 파일을 읽은 뒤, 각 라인 ( Request )을 확인하여 특정 날짜보다 오래 전에 이관된 Request를 주석 처리

2. 스크립트 작성

  • tp showbuffer 수행 결과 파일과 스크립트 파일을 넣을 경로 생성
  • <Path> 는 해당 쉘을 저장하고자 하는 각자의 경로를 설정하면 됨
sidap01:/<Path>/ > mkdir import_queue_clear
sidap01:/<Path>/ > cd import_queue_clear
sidap01:/<Path>/import_queue_clear > mkdir data script
sidap01:/<Path>/import_queue_clear > ll
  • import_queue_clear.sh 작성
  • tp show buffer 수행 결과를 /<Path>/import_queue_clear/data 경로에 생성
  • 또한, 데이터 파일에 대한 권한, 소유권을 변경 한 뒤, Import Queue Clear를 수행하는 파이썬 파일 실행
sidap01:/<Path>/import_queue_clear > cd script
sidap01:/<Path>/import_queue_clear/script > vi import_queue_clear.sh

#!/bin/bash

# current date for backup file name
# 오늘 날짜를 저장하는 변수
current_date=$(date +%y%m%d)

# hostname check
# 해당 쉘이 실행되는 서버의 호스트네임을 저장하는 변수
hostname=$(hostname)

# sid (Lower case) check
# 제 케이스의 경우 <sid>ap01가 호스트네임이기 때문에 이를 이용해 sid를 구해서 변수에 저장
sid=${hostname:0:3}

# SID (Upper case ) check
# sid를 대문자로 변환하여 변수에 저장
sid_upper=$(echo $sid | tr '[:lower:]' '[:upper:]')

# original Queue file ( /usr/sap/trans/buffer/SID ) backup
# import queue data를 가지고 있는 /usr/sap/trans/buffer/<SID> 파일을 <sid>_<오늘 날짜> 이름으로 백업
cp -rp /usr/sap/trans/buffer/$sid_upper /<Path>/import_queue_clear/data/${sid_upper}_${current_date}

# execute tp showbuffer command and save the result to file /monitoring/import_queue_clear/data/~
# tp showbuffer 명령어를 수행할 경우 import queue 상의 모든 request의 정보를 확인할 수 있고, 이를 파일로 생성
sudo -i -u "${sid}adm" tp showbuffer $sid_upper pf=/usr/sap/trans/bin/TP_DOMAIN_${sid_upper}.PFL > /<Path>/import_queue_clear/data/tp_showbuffer_${sid_upper}.txt

# change file authorization
# 보안을 위해 파일 권한, 소유자, 소유 그룹 변경
chmod 744 /<Path>/import_queue_clear/data/tp_showbuffer_${sid_upper}.txt
sudo chown ${sid}adm:sapsys /<Path>/import_queue_clear/data/tp_showbuffer_${sid_upper}.txt

# execute import queue clear python
# 실질적으로 /usr/sap/trans/buffer/<SID> 파일을 조작하는 파이썬 프로그램 실행
python3 /<Path>/import_queue_clear/script/import_queue_clear.py
  • import_queue_clear.py 작성
  • /<Path>/import_queue_data/tp_showbuffer_SID.txt 파일과 /usr/sap/trans/buffer/SID 파일을 읽은 뒤, 현재 시점보다 6개월 전에 반영된 request는 주석처리 하는 파이썬 코드
#!/usr/bin/python3

import os
import socket
from datetime import datetime
import calendar
imported_list = []

def getDate():

    # 오늘 날짜를 가져오기
   today = datetime.today()
    year = today.year
    month = today.month
    
    # 오늘 날짜 기준으로 6개월 전 날짜 구하기
    if month <= 6:
        year -= 1
        month += 6
    else: # month > 6
        month -= 6
    
    # 캘린더 상으로 유효한 날짜인지 확인
    last_day_of_month = calendar.monthrange(year, month)[1]
    day = min(today.day, last_day_of_month)
    
    # yyyymmdd 형식으로 포맷
    target_date = datetime(year,month,day).strftime('%Y%m%d')
    
    return target_date

def get_reqeust_info(input_string):

	indices = []
    line = input_string.replace("\n","")
    
    # tp showbuffer 데이터는 "|" 로 정보들이 분리되기 때문에,
    # "|" 위치에 대한 index를 indices list에 저장
    for index, char in enumerate(input_string):
        if char == '|':
            indices.append(index)
    
    # 라인의 0번째 인덱스부터 첫번째로 "|"가 나오는 부분까지가 request number
    request_number = line[:indices[0]].replace(" ","")
    
    # 라인의 51 ~ 55번째 자리까지가 RC (Request import status) 값을 나타냄
    return_code = line[51:56].replace(" ","")
    
    return [request_number, return_code]

def read_showbuffer_file():
    
    # 프로그램을 실행하는 hosname, sid (대소문자) 확인
    hostname = socket.gethostname()
    lower_sid = hostname[0:3]
    upper_sid = lower_sid.upper()
    
    # 이전에 tp showbuffer 명령어로 생성한 파일 오픈
    f = open("/<Path>/import_queue_clear/data/tp_showbuffer_{upper_sid}.txt", "r")
    
    # 파일의 모든 데이터를 읽음
    lines = f.readlines()
    
    # 데이터를 라인별로 확인
    for line in lines:
    
        # request의 경우 <SID>K<NUMBER> 이기 때문에 읽은 정보의 첫 4글자가 <SID>K 인지 확인
        if line[0:4] != "KEDK":
            
            continue
        
        # get_request_info() 함수 수행
        request_info = get_reqeust_info(line)
    
    	# RC값이 "*4000"인 경우 아직 반영되지 않은 상태이기 떄문에
        # 이 외의 값을 가지면서, None 값이 아닌것을 imported_list에 추가
        # 결론적으로 imported_list에는 이관이 된 request number가 저장됨
        # 이관된 상태는 정상,경고,에러를 모두 포함함 (이관이 안된 것만 제외)
        if request_info is not None and request_info[1] != "*4000":
            imported_list.append(request_info[0])

def change_SID_file():

	# 프로그램을 실행하는 hosname, sid (대소문자) 확인
    hostname = socket.gethostname()
    lower_sid = hostname[0:3]
    upper_sid = lower_sid.upper()
    
    # import queue 상의 request 정보가 있는 /usr/sap/trans/buffer/<SID> 파일 경로 설정
    file_path = "/usr/sap/trans/buffer/{upper_sid}"
    
    # getDate() 수행하여 오늘날짜 기준 6개월 전 날짜 가져옴
    target_date = datetime.strptime(getDate(),"%Y%m%d")
    
    # /usr/sap/trans/buffer/<SID> 파일 읽기
    with open(file_path, 'r') as f:
        lines = f.readlines()
    
    # request에 대한 정보는 3번째 줄부터 시작하기 때문에 2번째 부터 반복하여 line 읽기
    for i in range(2,len(lines)):
    
    	# 각 line 별로 하나의 request 정보를 가지고 있음
        line = lines[i]
        
        # request 정보를 공백 기준으로 분리
        request_info = line.split()
        
        # 분리된 데이터의 첫번째의 1번째 글자가 이미 주석처리 (#) 되어 있는 경우 다음 request 확인
        if request_info[0][0] == '#':
            continue
        
        # 분리된 데이터의 첫번째의 4번째 글자부터 마지막까지의 글자가 request number
        # ex) request_info[0][3:] = <SID>K<NUMBER>
        # 해당 request가 imported_list (이미 이관된 리퀘스트)에 있는 경우
        if request_info[0][3:] in imported_list:
        
        	# requst_info의 마지막 데이터의 5번째 ~ 11번째까지는 이관된 날짜 데이터
            # ex) request_info[-1][4:12] = 20240101
            # 이관된 날짜를 yyyymmdd 형식으로 포맷
            reference_date = datetime.strptime(request_info[-1][4:12], "%Y%m%d")
            
            # 이관 날짜가 6개월보다 오래된 경우
            if reference_date < target_date :
                # 해당 라인의 첫번째 글자를 변경하여 주석 처리 (#)
                lines[i] = "#" + line[1:]
    
    # 모든 라인을 확인 한 뒤, 변경 내역을 write
    with open(file_path, 'w') as f:
        f.writelines(lines)

def main():

	read_showbuffer_file()
    change_SID_file()

# 프로그램 시작
main()

3. 스크립트 실행

sidap01:/ > cd /<Path>/import_queue_clear/script
sidap01:/<Path>/import_queue_clear/script > ./import_queue_clear.sh

 
 

🙋‍♂️ 궁금한 점이나 잘못된 내용을 댓글로 적어주시면 감사하겠습니다 !!

반응형

'SAP BC > SAP' 카테고리의 다른 글

# [SAP] Import Queue ( Import Queue 정리 )  (2) 2024.09.03
# [SAP] Transport Request - STMS  (0) 2024.08.08
# [SAP] Import options  (0) 2024.08.06
# [SAP] Lock Entries - SM12  (0) 2024.07.25
# [SAP] CTS Import history  (0) 2024.06.28