An important part of most projects is managing a list of open issues. Chances are, your project is using an issue tracker for this. If this happens to be
Mozilla's
Bugzilla, read on.
If your project revolves around the Change and Transport System using customizing transports and workbench transports, you may have found it useful to tie transports to entries in Bugzilla. This post gives a kickstarter on how to make Netweaver add a comment to a Bugzilla entry (a "bug") whenever a CTS transport is released or imported. This might be a good place to start from if you envision other means of interaction between Netweaver and Bugzilla.
Preconditions
Bugzilla added a REST API with version 5.0. We will be using this. Your Bugzilla's version will therefore need to be at least 5.0.
Environment
As this post focuses on the connection to Bugzilla, details on the integration into the CTS will be skipped. Here are some hints, though:
- Use the Transport Organizer Tools (transaction SE03) to add an attribute which holds bug numbers, so that you can tie transports to bugs (m:n)
- Use BAdI CTS_REQUEST_CHECK to allow release of a transport only if it has at least one bug number attribute
- Use BAdI CTS_EXPORT_FEEDBACK to trigger your Bugzilla connection on release of a transport
- Use BAdI CTS_IMPORT_FEEDBACK to trigger your Bugzilla connection on import of a transport
Preparing Netweaver
Using transaction
SM59, et up a HTTP RFC destination (type G) to your Bugzilla. Here are the cornerposts:
- Give it a name (BUGZILLA might come to mind and will be used in the following code snippets)
- Fill target host and service no. according to your Bugzilla (will be along the lines of bugzilla.example.org and 80 or 443)
- Give the path prefix to your Bugzilla's rest.cgi script, with a trailing slash (maybe /rest.cgi/ or /bugzilla/rest.cgi/)
- If your Bugzilla is using SSL (as it should), switch SSL on and set the SSL Certificate to "Anonymous", as we won't be using SSL for authentication
- Leave the defaults "Do Not Use a User" and "Do Not Send Logon Ticket"
- Set HTTP version to 1.1 (unless your Bugzilla's server does not support it) so that you have the option to profit from compression
If you test this connection, a response code 404 is the expected result. The response body should contain some JSON content. Part of this is a message stating that there is no REST API resource at "
GET /". This is fine; we will specify the exact resource when making the HTTP call later.
Hello World: Retrieving the Bugzilla version
Let's start with asking Bugzilla for its version. We don't send data to Bugzilla, and we don't need to log in, so it's easier than adding a comment, which we will cover in the next chapter.
Here's the code snippet, core error handling stripped:
DATA: lr_cx_transformation TYPE REF TO cx_transformation_error,
lr_client TYPE REF TO if_http_client,
lv_result TYPE string,
lv_rest_errcode TYPE string,
lv_rest_errmsg TYPE string,
lv_version TYPE string.
cl_http_client=>create_by_destination( EXPORTING destination = 'BUGZILLA'
IMPORTING client = lr_client
EXCEPTIONS OTHERS = 99 ).
lr_client->request->set_content_type( 'application/json' ).
lr_client->request->set_header_field( name = 'Accept'
value = 'application/json' ).
lr_client->request->set_method( if_http_entity=>co_request_method_get ).
lr_client->request->set_header_field( name = '~request_uri'
value = 'version' ).
http_client_wrapper_send( lr_client ).
http_client_wrapper_receive( lr_client ).
lv_result = lr_client->response->get_cdata( ).
TRY.
CALL TRANSFORMATION z_bz_version SOURCE XML lv_result
RESULT version = lv_version.
CATCH cx_transformation_error INTO lr_cx_transformation.
TRY.
CALL TRANSFORMATION z_bz_error SOURCE XML lv_result
RESULT code = lv_rest_errcode
message = lv_rest_errmsg.
CATCH cx_transformation_error.
RAISE EXCEPTION lr_cx_transformation.
ENDTRY.
ENDTRY.
Transformation
z_bz_version should look like this:
<?sap.transform simple?>
<tt:transform xmlns:tt="http://www.sap.com/transformation-templates">
<tt:root name="VERSION"/>
<tt:template>
<object>
<str name="version">
<tt:value ref="VERSION"/>
</str>
</object>
</tt:template>
</tt:transform>
And this is transformation
z_bz_error:
<?sap.transform simple?>
<tt:transform xmlns:tt="http://www.sap.com/transformation-templates">
<tt:root name="CODE"/>
<tt:root name="MESSAGE"/>
<tt:template>
<object>
<tt:group>
<tt:d-cond frq="1">
<bool name="error">
<tt:text>true</tt:text>
</bool>
</tt:d-cond>
<tt:d-cond frq="1">
<num name="code">
<tt:value ref="CODE"/>
</num>
</tt:d-cond>
<tt:d-cond frq="1">
<str name="message">
<tt:value ref="MESSAGE"/>
</str>
</tt:d-cond>
<tt:d-cond frq="*">
<tt:skip count="1"/>
</tt:d-cond>
</tt:group>
</object>
</tt:template>
</tt:transform>
You will find the Bugzilla version in
lv_version afterwards, if all went well. If Bugzilla was unhappy with your request,
lv_rest_errcode and
lv_rest_errmsg will contain information about the error. If something on the way to or from Bugzilla went awry, you'll most likely be faced with a
cx_transformation_error exception.
Adding a comment to a bug
Now let's add a comment. We'll need to get an API key from Bugzilla to identify the user we want to add our comment as. To get the API key, log in to Bugzilla, go to the API keys page (Preferences → API keys), and have Bugzilla generate a new API key for you.
Here's the code snippet, again core error handling stripped. We'll be adding a confidential comment "Test" (
lv_comment) to bug 1234 (
lv_bugid_as_string), using the API key we generated (
lv_bz_api_key).
DATA: lr_cx_transformation TYPE REF TO cx_transformation_error,
lr_client TYPE REF TO if_http_client,
lv_bz_api_key TYPE string VALUE 'iuTTvtOBnGG...oOPZN8d',
lv_bugid_as_string TYPE string VALUE '1234',
lv_comment TYPE string VALUE 'Test',
lv_confidential TYPE abap_bool VALUE abap_true,
lv_path_info TYPE string
lr_json_writer TYPE REF TO cl_sxml_string_writer,
lv_result TYPE string,
lv_comment_id TYPE string,
lv_rest_errcode TYPE string,
lv_rest_errmsg TYPE string.
cl_http_client=>create_by_destination( EXPORTING destination = 'BUGZILLA'
IMPORTING client = lr_client
EXCEPTIONS OTHERS = 99 ).
lr_client->request->set_content_type( 'application/json' ).
lr_client->request->set_header_field( name = 'Accept'
value = 'application/json' ).
lr_client->request->set_method( if_http_entity=>co_request_method_post ).
CONCATENATE 'bug' lv_bugid_as_string 'comment' INTO lv_path_info SEPARATED BY '/'.
lr_client->request->set_header_field( name = '~request_uri'
value = lv_path_info ).
lr_json_writer = cl_sxml_string_writer=>create( type = if_sxml=>co_xt_json ).
CALL TRANSFORMATION z_bz_add_comment SOURCE bugzilla_api_key
= lv_bz_api_key
comment = lv_comment
confidential
= lv_confidential
RESULT XML lr_json_writer
.
lr_client->request->set_data( data = lr_json_writer->get_output( ) ).
http_client_wrapper_send( lr_client ).
http_client_wrapper_receive( lr_client ).
lv_result = lr_client->response->get_cdata( ).
TRY.
CALL TRANSFORMATION z_bz_add_comment SOURCE XML lv_result
RESULT id_comment = lv_id_comment.
CATCH cx_transformation_error INTO lr_cx_transformation.
TRY.
CALL TRANSFORMATION z_bz_error SOURCE XML lv_result
RESULT code = lv_rest_errcode
message = lv_rest_errmsg.
CATCH cx_transformation_error.
RAISE EXCEPTION lr_cx_transformation.
ENDTRY.
ENDTRY.
Transformation
z_bz_add_comment should look like this:
<?sap.transform simple?>
<tt:transform xmlns:tt="http://www.sap.com/transformation-templates">
<tt:root name="BUGZILLA_API_KEY"/>
<tt:root name="COMMENT"/>
<tt:root name="CONFIDENTIAL"/>
<tt:root name="ID_COMMENT"/>
<tt:template>
<tt:serialize>
<object>
<str name="Bugzilla_api_key">
<tt:value ref="BUGZILLA_API_KEY"/>
</str>
<str name="comment">
<tt:value ref="COMMENT"/>
</str>
<tt:cond data="CONFIDENTIAL='X'">
<bool name="private">
<tt:text>true</tt:text>
</bool>
</tt:cond>
</object>
</tt:serialize>
<tt:deserialize>
<object>
<num name="id">
<tt:value ref="ID_COMMENT"/>
</num>
</object>
</tt:deserialize>
</tt:template>
</tt:transform>
This will add the comment to the bug and place the id of the new comment into
lv_comment_id.
Further Reading
Bugzilla's REST API is very well documented at
https://bugzilla.readthedocs.org/en/latest/api/index.html. This can help you build upon the above simple examples; maybe you'll want to login using email and password, or you want to change a bug status.