REPORT zmikne_higasket_test. *----------------------------------------------------------------------* * MIKNE × Higasket — Prueba de conectividad de la API * MIKNE × Higasket — API connectivity test * MIKNE × Higasket — 接口连通性测试 * * Flujo / Flow / 流程: * 1) POST /api/login -> obtiene token Bearer (24 h) / get Bearer token / 获取令牌 * 2) POST /api/test -> envía JSON con "Authorization: Bearer " * y muestra el ID de confirmación / shows the * confirmation ID / 显示确认编号 * * Requisitos / Requirements / 前提条件: * - STRUST: importar la raíz de Let's Encrypt "ISRG Root X1" (y el * intermedio R10/R11) en "SSL Client (Anonymous)" y reiniciar el * ICM en SMICM. * Import Let's Encrypt "ISRG Root X1" root (and R10/R11 * intermediate) into "SSL Client (Anonymous)" and restart ICM. * 在 STRUST 中将 Let's Encrypt 根证书 "ISRG Root X1" 导入 * "SSL Client (Anonymous)",然后在 SMICM 中重启 ICM。 * - Si el SAP sale a internet por proxy, ver el bloque "PROXY" en la * rutina HTTP_POST. / If SAP uses a corporate proxy, see the * "PROXY" block in HTTP_POST. / 如经公司代理上网,请参见 * HTTP_POST 中的 "PROXY" 部分。 * * Documentación completa / Full documentation / 完整文档: * https://higasket-api-test.mikne.com.mx/docs *----------------------------------------------------------------------* CONSTANTS: gc_host TYPE string VALUE 'https://higasket-api-test.mikne.com.mx', gc_user TYPE string VALUE 'higasket', gc_pass TYPE string VALUE 'AQUI-LA-CONTRASENA-DE-MIKNE', * 'ANONYM' = SSL Client (Anonymous). Usar 'DFAULT' si el certificado se * importó en SSL Client (Standard). / Use 'DFAULT' if the certificate * was imported into SSL Client (Standard). / 若证书导入在 Standard * 节点,请改为 'DFAULT'。 gc_ssl_id TYPE ssfapplssl VALUE 'ANONYM'. DATA: gv_body TYPE string, gv_resp TYPE string, gv_code TYPE i, gv_token TYPE string, gv_id TYPE string, gv_ts TYPE string. START-OF-SELECTION. WRITE: / 'MIKNE × Higasket — Prueba de API / API test / 接口测试'. ULINE. *----------------------------------------------------------------------* * 1. LOGIN *----------------------------------------------------------------------* CONCATENATE '{"username":"' gc_user '","password":"' gc_pass '"}' INTO gv_body. PERFORM http_post USING gc_host '/api/login' gv_body '' CHANGING gv_resp gv_code. IF gv_code <> 200. WRITE: / '1) LOGIN FALLÓ / LOGIN FAILED / 登录失败 — HTTP', gv_code. WRITE: / gv_resp. RETURN. ENDIF. FIND REGEX '"token"[[:space:]]*:[[:space:]]*"([^"]+)"' IN gv_resp SUBMATCHES gv_token. IF gv_token IS INITIAL. WRITE: / '1) No se encontró el token en la respuesta / Token not', 'found in response / 响应中未找到令牌:'. WRITE: / gv_resp. RETURN. ENDIF. WRITE: / '1) Login OK — token recibido / token received / 已获取令牌'. *----------------------------------------------------------------------* * 2. POST /api/test con el token / with the token / 携带令牌 *----------------------------------------------------------------------* CONCATENATE sy-datum sy-uzeit INTO gv_ts SEPARATED BY '-'. CONCATENATE '{"origen":"SAP S/4HANA DS4","programa":"ZMIKNE_HIGASKET_TEST",' '"cliente":"Higasket","proveedor":"MIKNE","timestamp":"' gv_ts '"}' INTO gv_body. PERFORM http_post USING gc_host '/api/test' gv_body gv_token CHANGING gv_resp gv_code. IF gv_code = 200. FIND REGEX '"id"[[:space:]]*:[[:space:]]*"([^"]+)"' IN gv_resp SUBMATCHES gv_id. WRITE: / '2) JSON enviado y registrado / JSON sent and logged /', 'JSON 已发送并记录 — HTTP 200'. WRITE: / ' ID de confirmación / Confirmation ID / 确认编号:', gv_id. ELSE. WRITE: / '2) ENVÍO FALLÓ / SEND FAILED / 发送失败 — HTTP', gv_code. ENDIF. ULINE. WRITE: / 'Respuesta completa / Full response / 完整响应:'. WRITE: / gv_resp. *----------------------------------------------------------------------* * Rutina genérica de POST HTTP / Generic HTTP POST routine / 通用 POST *----------------------------------------------------------------------* FORM http_post USING iv_host TYPE string iv_path TYPE string iv_body TYPE string iv_token TYPE string CHANGING cv_resp TYPE string cv_code TYPE i. DATA: lo_client TYPE REF TO if_http_client, lv_url TYPE string, lv_auth TYPE string, lv_msg TYPE string. CLEAR: cv_resp, cv_code. CONCATENATE iv_host iv_path INTO lv_url. CALL METHOD cl_http_client=>create_by_url EXPORTING url = lv_url ssl_id = gc_ssl_id IMPORTING client = lo_client EXCEPTIONS argument_not_found = 1 plugin_not_active = 2 internal_error = 3 OTHERS = 4. * --- PROXY corporativo: si aplica, sustituir la llamada de arriba por * --- esta (con sus datos) / If a corporate proxy applies, replace the * --- call above with this one / 如需代理,请改用以下调用: * CALL METHOD cl_http_client=>create_by_url * EXPORTING * url = lv_url * ssl_id = gc_ssl_id * proxy_host = 'proxy.su-empresa.com' * proxy_service = '8080' * IMPORTING * client = lo_client * EXCEPTIONS * OTHERS = 4. IF sy-subrc <> 0. cv_code = -1. cv_resp = 'Error en CREATE_BY_URL. Verifique la URL y el plugin HTTPS del ICM.'. RETURN. ENDIF. * Evitar popup de logon en respuestas 401 / avoid logon popup on 401 lo_client->propertytype_logon_popup = lo_client->co_disabled. lo_client->request->set_method( if_http_request=>co_request_method_post ). lo_client->request->set_content_type( 'application/json; charset=utf-8' ). IF iv_token IS NOT INITIAL. CONCATENATE 'Bearer' iv_token INTO lv_auth SEPARATED BY space. lo_client->request->set_header_field( name = 'Authorization' value = lv_auth ). ENDIF. lo_client->request->set_cdata( iv_body ). CALL METHOD lo_client->send EXCEPTIONS http_communication_failure = 1 http_invalid_state = 2 http_processing_failed = 3 http_invalid_timeout = 4 OTHERS = 5. IF sy-subrc <> 0. lo_client->get_last_error( IMPORTING message = lv_msg ). cv_code = -2. CONCATENATE 'Error en SEND:' lv_msg INTO cv_resp SEPARATED BY space. IF lv_msg CS 'SSL' OR lv_msg CS 'ssl'. CONCATENATE cv_resp '>>> Pista / Hint / 提示: importar "ISRG Root X1" en STRUST' '(SSL Client Anonymous o Standard) y reiniciar ICM en SMICM.' INTO cv_resp SEPARATED BY space. ENDIF. lo_client->close( ). RETURN. ENDIF. CALL METHOD lo_client->receive EXCEPTIONS http_communication_failure = 1 http_invalid_state = 2 http_processing_failed = 3 OTHERS = 4. IF sy-subrc <> 0. lo_client->get_last_error( IMPORTING message = lv_msg ). cv_code = -3. CONCATENATE 'Error en RECEIVE:' lv_msg INTO cv_resp SEPARATED BY space. lo_client->close( ). RETURN. ENDIF. lo_client->response->get_status( IMPORTING code = cv_code ). cv_resp = lo_client->response->get_cdata( ). lo_client->close( ). ENDFORM.