• SAP传输请求自动发布


        最近公司服务器做迁移,原R3 PRE需要迁到另外的地方,迁移后一段时间内,需要两套PRE环境同时运行,过一段时间后才将传输路线切换到新的PRE。在切换前,要求新PRE环境也要正常同步发布请求,但传输路线只有一条,这需要在发原PRE时,同时手工发布新PRE,这样每次手工很麻烦(手工导入传输请求过程参考这篇文章)。本文就是来通过程序实现这种手工全过程,实现同步自动发布新PRE。实现过程也算简单,通过一台中间Java Web服务器进行传输请求的中转,将DEV上的传输请求文件下载后,上传到新PRE服务器上,然后在新PRE服务器上导入新的请求即可。这就需要在DEV上写个远程RFS接口,将需要传输的请求所对应的数据与配置文件下载下来;在新PRE上写个远程接口,将从DEV上下载下来的传输请求文件上传到新PRE服务器上,其后通过调用发布函数进行请求发布。代码涉及到三台机器:SAP DEV  ——>  Java Web中转服务器  ——>  SAP PRE,之间采用JCO进行连接。最新的SAP JCO包请点击这里下载,Linux上So动态链接库以及Windows的Dll部署请百度

    1、DEV远程接口:

     

     

    FUNCTION zxg_pre_fuc.
    *"----------------------------------------------------------------------
    *"*"Local interface:
    *" IMPORTING
    *" VALUE(REQUESTNO) TYPE STRING
    *" EXPORTING
    *" VALUE(FILES) TYPE ZXG_PRE_TABLE_TYPE
    *" VALUE(REQUESTNOS) TYPE STRING
    *"----------------------------------------------------------------------

    DATA: result_tab TYPE TABLE OF string WITH HEADER LINE.
    "多个请求以逗号分隔
    SPLIT requestno AT ',' INTO TABLE result_tab IN CHARACTER MODE.
    DATA: lt_data_binary TYPE TABLE OF sdokcntbin WITH HEADER LINE.
    DATA: lv_binary_len TYPE i,lv_lines TYPE i,lv_total_len TYPE i.
    DATA: v_filename TYPE string.
    DATA: lw_files LIKE LINE OF files.
    LOOP AT result_tab.
    DO 2 TIMES.
    CLEAR:lw_files,lv_total_len,lt_data_binary[].
    IF sy-index = 1.
    "传输请求所对应的数据文件
    CONCATENATE `/usr/sap/trans/data/R` result_tab+4 `.DEV` INTO v_filename.
    ELSE.
    "传输请求所对应的配置文件
    CONCATENATE `/usr/sap/trans/cofiles/K` result_tab+4 `.DEV` INTO v_filename.
    ENDIF.

    "从服务器上读取文件
    lw_files-filename = v_filename.
    OPEN DATASET v_filename FOR INPUT IN BINARY MODE.
    DO.
    CLEAR: lt_data_binary,lv_binary_len.
    READ DATASET v_filename INTO lt_data_binary ACTUAL LENGTH lv_binary_len.
    IF lv_binary_len > 0.
    lv_total_len = lv_total_len + lv_binary_len.
    APPEND lt_data_binary.
    lw_files-last_line_size = lv_binary_len.
    ELSE.
    lw_files-total_size = lv_total_len.
    EXIT.
    ENDIF.
    ENDDO.
    CLOSE DATASET v_filename.
    lw_files-data = lt_data_binary[].

    APPEND lw_files TO files.
    ENDDO.
    ENDLOOP.
    "返回给Java Web服务器
    requestnos = requestno.
    ENDFUNCTION.
     
    2、新PRE远程接口:
     此服务器上的ZXG_PRE_TABLE_TYPE类型与DEV上是一样的,这里就不再截图
    FUNCTION zxg_pre_fuc.
    *"----------------------------------------------------------------------
    *"*"Local interface:
    *"  IMPORTING
    *"     VALUE(FILES) TYPE  ZXG_PRE_TABLE_TYPE
    *"     VALUE(REQUESTNOS) TYPE  STRING
    *"----------------------------------------------------------------------

    DATAlw_files TYPE zxg_pre_strc_type.
    DATAlw_data TYPE sdokcntbin.
    DATAlines TYPE i.
    DATAindx TYPE .

    LOOP AT files INTO lw_files .
        indx 0.
    OPEN DATASET lw_files-filename FOR OUTPUT IN BINARY MODE.

    DESCRIBE TABLE lw_files-data LINES lines.
    LOOP AT lw_files-data INTO lw_data.
          indx indx + 1.
    IF indx <> lines.
    TRANSFER lw_data-line TO lw_files-filename.
    ELSE.
    TRANSFER lw_data-line+(lw_files-last_line_sizeTO lw_files-filename.
    ENDIF.
    ENDLOOP.
    CLOSE DATASET lw_files-filename.
    ENDLOOP.

    DATAresult_tab TYPE TABLE OF string WITH HEADER LINE.
    SPLIT requestnos AT ',' INTO TABLE  result_tab IN CHARACTER MODE.

    DATAreq TYPE tmsbuffer-trkorr.

    LOOP AT result_tab.
        req =  result_tab.
    PERFORM frm_stms USING req.
    ENDLOOP.
    ENDFUNCTION.

     
    FORM frm_stms USING requestno TYPE tmsbuffer-trkorr.
    CALL FUNCTION 'TMS_MGR_FORWARD_TR_REQUEST'
    EXPORTING
          iv_request requestno
          iv_target  'PRE'
          iv_tardom  'DOMAIN_PRE'.
    IF sy-subrc <> 0.
    MESSAGE ID sy-msgid TYPE sy-msgty NUMBER sy-msgno
    WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.
    ENDIF.

    CALL FUNCTION 'TMS_MGR_IMPORT_TR_REQUEST'
    EXPORTING
          iv_system  'PRE'
          iv_domain  'DOMAIN_PRE'
          iv_request requestno.
    IF sy-subrc <> 0.
    MESSAGE ID sy-msgid TYPE sy-msgty NUMBER sy-msgno
    WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.
    ENDIF.
    ENDFORM.  

    3、Java Web

     
    import java.io.File;
    import java.io.FileOutputStream;
    import java.util.Properties;
     
    import org.apache.commons.logging.Log;
    import org.apache.commons.logging.LogFactory;
     
    import com.sap.conn.jco.AbapException;
    import com.sap.conn.jco.JCoDestination;
    import com.sap.conn.jco.JCoDestinationManager;
    import com.sap.conn.jco.JCoException;
    import com.sap.conn.jco.JCoFunction;
    import com.sap.conn.jco.JCoParameterList;
    import com.sap.conn.jco.JCoTable;
    import com.sap.conn.jco.ext.DestinationDataProvider;
     
    public class ConnectPooled {// 连接池
        private static Log log = LogFactory.getLog(ConnectPooled.class);
     
        static String ABAP_AS_POOLED_XG_PRE = "ABAP_AS_POOLED_XG_PRE";
        static String ABAP_AS_POOLED_R3_DEV = "ABAP_AS_POOLED_R3_DEV";
        static {
            config("192.168.118.xx");// dev
            config("10.242.6.xxx");// pre
        }
     
        private static void config(String ip) {
            Properties connectProperties = new Properties();
            connectProperties.setProperty(DestinationDataProvider.JCO_ASHOSTip);
            connectProperties.setProperty(DestinationDataProvider.JCO_SYSNR"00");
            connectProperties
                    .setProperty(DestinationDataProvider.JCO_CLIENT"200");
            connectProperties.setProperty(DestinationDataProvider.JCO_USER,
                    "1504xxxx");
            // 注:密码是区分大小写的,要注意大小写
            connectProperties.setProperty(DestinationDataProvider.JCO_PASSWD,
                    "axxxxxx");
            connectProperties.setProperty(DestinationDataProvider.JCO_LANG"en");
     
            // *********连接池方式与直接不同的是设置了下面两个连接属性
            // JCO_PEAK_LIMIT - 同时可创建的最大活动连接数,0表示无限制,默认为JCO_POOL_CAPACITY的值
            // 如果小于JCO_POOL_CAPACITY的值,则自动设置为该值,在没有设置JCO_POOL_CAPACITY的情况下为0
            connectProperties.setProperty(DestinationDataProvider.JCO_PEAK_LIMIT,
                    "10");
            // JCO_POOL_CAPACITY - 空闲连接数,如果为0,则没有连接池效果,默认为1
            connectProperties.setProperty(
                    DestinationDataProvider.JCO_POOL_CAPACITY"3");
     
            createDataFile(ABAP_AS_POOLED_XG_PRE"jcoDestination",
                    connectProperties);
        }
     
        static void createDataFile(String name, String suffix, Properties properties) {
            File cfg = new File(name + "." + suffix);
            if (!cfg.exists()) {
                try {
                    FileOutputStream fos = new FileOutputStream(cfgfalse);
                    properties.store(fos"for tests only !");
                    fos.close();
                } catch (Exception e) {
                    log.error(""e);
                }
            }
        }
     
        /**
         * 根据输入的传输请求号,从DEV上获取传输请求所对应的传输文件
         * @param REQUESTNO
         * @return
         * @throws JCoException
         */
        public static JCoTable getTransRequestFiles(String REQUESTNO)
                throws JCoException {
            JCoDestination destination = JCoDestinationManager
                    .getDestination(ABAP_AS_POOLED_R3_DEV);
            JCoFunction function = destination.getRepository().getFunction(
                    "ZXG_PRE_FUC");// 从对象仓库中获取 RFM 函数
            if (function == null)
                throw new RuntimeException("ZXG_PRE_FUC not found in SAP.");
     
            JCoParameterList jpl = function.getImportParameterList();
            jpl.setValue("REQUESTNO"REQUESTNO);
            try {
                function.execute(destination);
            } catch (AbapException e) {
                log.error(""e);
                return null;
            }
     
            jpl = function.getExportParameterList();
            JCoTable jt = jpl.getTable("FILES");
     
            return jt;
        }
     
        /**
         * 将DEV上的传输请求文件上传到PRE上去,并实现后继的自动发布过程
         * @param jt
         * @param req
         * @throws JCoException
         */
        public static void sendTransReqFiles2xgpre(JCoTable jt, String req)
                throws JCoException {
            JCoDestination destination = JCoDestinationManager
                    .getDestination(ABAP_AS_POOLED_XG_PRE);
            JCoFunction function = destination.getRepository().getFunction(
                    "ZXG_PRE_FUC");// 从对象仓库中获取 RFM 函数
            if (function == null)
                throw new RuntimeException("ZXG_PRE_FUC not found in SAP.");
     
            function.getImportParameterList().setValue("FILES"jt);
            function.getImportParameterList().setValue("REQUESTNOS"req);
     
            try {
                function.execute(destination);
            } catch (AbapException e) {
                log.error(""e);
            }
        }
    }
    import org.apache.commons.logging.Log;
    import org.apache.commons.logging.LogFactory;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
     
    import org.springframework.stereotype.Controller;
    import org.springframework.web.bind.annotation.RequestMapping;
     
    import com.sap.conn.jco.JCoException;
     
    @Controller
    @RequestMapping("/xgpresync")
    public class XGPRECtrl {
     
        private static Log log = LogFactory.getLog(XGPRECtrl.class);
     
        @RequestMapping("/gettransreq")
        public void gettransreq(HttpServletRequest request,
                HttpServletResponse response, String transreqthrows JCoException {
            log.info("reqs:" + transreq);
            try {
                ConnectPooled.sendTransReqFiles2xgpre(
                        ConnectPooled.getTransRequestFiles(transreq), transreq);
                JsonPrintUtil.printJson(responsetrue"""");
            } catch (Exception e) {
                log.error(""e);
                JsonPrintUtil.printJson(responsefalsee.getMessage(), "");
            }
        }
    }
     
    然后再将该链接集成到我司发布平台上去,实现自动发布
     
     
     
     
     

    <wiz_tmp_tag id="wiz-table-range-border" contenteditable="false" style="display: none;">

    附件列表

  • 相关阅读:
    动态加载并执行Win32可执行程序
    二维码登录
    深度神经网络实现图像理解的原理
    NET Core Docker部署
    EventStore的设计思路
    NET Core,Ubuntu运行
    Tensorflow 神经网络
    System.Reflection.Emit学习
    泛型 "new的性能"
    蚁群算法
  • 原文地址:https://www.cnblogs.com/jiangzhengjun/p/8514732.html
Copyright © 2020-2023  润新知