Background
The company I work for has a sizeable and complex SAP estate with dozens of production SAP systems and therefore an equally complex development environment. Although development standards have been in place for a number of years, it is always a challenge to ‘encourage’ developers to adhere to them.
As well as development standards, the Transport Naming Standards are also important – especially for one particular business unit where they have developments moving to multiple QA systems and therefore knowing what goes where is paramount to ensure safe and reliable operations. Although reports had been built to provide statistics and details of transport adherence, this was all reactive and transports were routinely being released without ticket details and/or release schedule details. For audit purposes, ticket details are mandatory and for the Release Management team, the schedule details help to identify the scope for each release. The burden of correcting the transport name generally fell to a few build leads and due to the new DevOps structure and increased frequency of the releases, this was starting to consume up to 25% of their day. Not exactly an efficient use of time.
Benefits
The main benefit therefore was to move this burden onto individual developers and therefore the ‘pain’ was then felt at the source. This then relieved the build leads of this bottle neck and time drain, and (as it turned out) enabled them to concentrate of building more automation as a result of this implementation. The benefits can be summarised as:
1. Significant time saved to audit transports
2. Easier mechanism to validate all transports for the weekly release are included
3. Futher development based on change reference number now possible to generate the scope list automatically
Solution
Initially I considered whether it was appropriate to built a custom ATC check to house all the development in the Central ATC, but this was not the recommended approach and therefore I set about building my own solution.
The solution came in two parts:
Part One
Provide links and information to all the development standards and transport naming standards details from within SE80. This was to ensure that all the standards were in easy reach of all the developers, providing them will all the information required.
Part Two
Transports were to be blocked at both creation and release via the CTS_REQUEST_CHECK BAdI to force the correct format – which is:
<Programme/Region>:<Project/Release/Sprint>:<Change_Ref>:<Description>:<Delta No>
◉ <Programme/Region> = EPB, MOW, MDG, FSCM etc.
◉ <Project/Release/Sprint> = R5, 6, QR1, OOR, WR, QR01, ELS etc.
◉ <Change_Ref> = Service Now, Azure DevOps, SolMan or HPALM Ref Number
◉ <Description> = Self-explanatory
◉ <Delta No> = For subsequent transports for the same change ref 1, 2, 3, 4 etc.
Initial Scope
A single remote enabled function module within the Central ATC system was required. This was just a wrapper for a local class that was split into 3 sections. See below:
DATA: lv_ok TYPE abap_bool,
lo_transport_checks TYPE REF TO lcl_transport_checks. " Use the local class
CREATE OBJECT lo_transport_checks
exporting
request = request
type = type
sysid = sysid
text = text
owner = owner.
IF lo_transport_checks IS BOUND.
* Read the config, mapped from the system id
lv_ok = lo_transport_checks->get_config( ).
IF lv_ok = abap_false.
log = lo_transport_checks->get_log( ).
lo_transport_checks->update_statistics( 001 ).
RETURN.
ENDIF.
* Check the prefix against the config
lv_ok = lo_transport_checks->check_prefix( ).
IF lv_ok = abap_false.
lo_transport_checks->log_valid_prefixes( ).
log = lo_transport_checks->get_log( ).
lo_transport_checks->update_statistics( 002 ).
RETURN.
ENDIF.
* Check the transport title using regular expressions
lv_ok = lo_transport_checks->check_title( ).
IF lv_ok = abap_false.
lo_transport_checks->log_follow_structure( ).
log = lo_transport_checks->get_log( ).
lo_transport_checks->update_statistics( 003 ).
RETURN.
ENDIF.
ELSE.
log = lo_transport_checks->log_binding_error( ).
ENDIF.
* Also log the success
lo_transport_checks->update_statistics( 000 ).
The first section deals with ensuring the correct configuration was in place. Configuration tables are necessary to firstly ensure the linkage between the production systems to the respective development systems is in place.
* Read the config, mapped from the system id
lv_ok = lo_transport_checks->get_config( ).
IF lv_ok = abap_false.
log = lo_transport_checks->get_log( ).
lo_transport_checks->update_statistics( 001 ).
RETURN.
ENDIF.
Secondly, each production system can then have its own set of prefixes aligned to either a single or multiple development system scenario (in the case of dual track or more landscapes). If a valid prefix is not entered, the full set of valid prefixes is then sent back to the user, advising them of what they must do to proceed.
* Check the prefix against the config
lv_ok = lo_transport_checks->check_prefix( ).
IF lv_ok = abap_false.
lo_transport_checks->log_valid_prefixes( ).
log = lo_transport_checks->get_log( ).
lo_transport_checks->update_statistics( 002 ).
RETURN.
ENDIF.
Lastly, the rest of the title is then checked using regular expressions for conformity to the correct structure.
* Check the transport title using regular expressions
lv_ok = lo_transport_checks->check_title( ).
IF lv_ok = abap_false.
lo_transport_checks->log_follow_structure( ).
log = lo_transport_checks->get_log( ).
lo_transport_checks->update_statistics( 003 ).
RETURN.
ENDIF.
ELSE.
log = lo_transport_checks->log_binding_error( ).
ENDIF.
At each section, any errors were logged and then sent back to the user in the satellite system via the local POPUP_WITH_TABLE_DISPLAY function module and a statistics table is updated for later use.
On the satellite system side, the CTS_REQUEST_CHECK BAdI has a simple stub of code as below, again with a local class to house the call to the Central ATC system.
METHOD if_ex_cts_request_check~check_before_creation.
DATA: lv_result TYPE sysubrc,
lt_log TYPE tchar255,
lv_startpos_row TYPE sytabix,
lv_startpos_col TYPE sytabix,
lv_endpos_row TYPE sytabix,
lv_endpos_col TYPE sytabix,
lv_width TYPE sytabix,
lv_line TYPE sytabix.
FIELD-SYMBOLS: <lv_log> TYPE char255.
me->remote_naming_check(
EXPORTING
type = type
owner = sy-uname
IMPORTING
log = lt_log
CHANGING
text = text ).
* Initial top left corner of dialog box
lv_startpos_row = 5.
lv_startpos_col = 28.
IF lt_log IS NOT INITIAL.
* Set the necessary bottom right corner
lv_endpos_row = lines( lt_log ) + 3.
LOOP AT lt_log ASSIGNING <lv_log>.
lv_width = strlen( <lv_log> ).
IF lv_width > lv_endpos_col.
lv_endpos_col = lv_width.
ENDIF.
ENDLOOP.
lv_endpos_col = lv_endpos_col + lv_startpos_col.
CALL FUNCTION 'POPUP_WITH_TABLE_DISPLAY'
EXPORTING
endpos_col = lv_endpos_col
endpos_row = lv_endpos_row
startpos_col = lv_startpos_col
startpos_row = lv_startpos_row
titletext = 'Error Information'
TABLES
valuetab = lt_log
EXCEPTIONS
break_off = 1
OTHERS = 2.
RAISE cancel.
ENDIF.
ENDMETHOD.
It should also be noted that since the main logic is housed centrally and within a development system, it is always ‘live’ and therefore any changes made must be done with the greatest of care. For that reason, ABAP Unit has been employed to ensure that a test harness is in place to provide assurance that when adding new functionality, the old functionality is not broken.
Secondary Scope
After being live for several weeks, further improvements were identified and have been implemented:
1. Delta numbers were made mandatory and hence a colon number check was required
2. Refence number type check (allowed Service Now or ADO document types)
3. System specific additional requirements
Regardng point 3 above, catering for multiple production system requirements is not easy and although these are central standards, some systems require further checks for their own unique circumstances. In order to cater for these while keeping the core standards clean and not introducing a series of system specific IF’s or CASE statements into the central code, the multiple use functionality of the CTS_REQUEST_CHECK BAdI was taken advantage of, as well as ensuring the correct calling sequence i.e. central standards followed by local standards via the sort order option of the BAdI.
To illustrate this, the logical architecture is shown below
With the sequence of events as follows:
So far we have, five systems (2 landscapes) attached with another 4 systems imminent. As more systems come on board, feedback is positive and improvements suggested.
Future Improvements
Any suggestions that are believed to be ‘good for all’ will be built into the core logic in the Central ATC system which why we were keen to centralise this in the first place. System specific developments that ‘don’t make the grade’ will be developed and supported by the respectrive system teams.
Current improvements on the backlog are:
1. Provide a better UX than the POPUP_WITH_TABLE_DISPLAY FM. It is simple and functional but a better formatted HTML based UI would be more favourable
2. API calls to both Service Now and Azure DevOps to validate the change reference number added to the title
3. Configuration tables to be accessed via transactional CDS views/Fiori Elements rather than SM30 (nice to have but good excuse to develop experience in this area).
Also, I will be exploring whether it makes sense to move the functionality from the Central ATC to the SCP ABAP Environment (aka Steampunk). I’ll provide a blog on the experience when I get round to it.
No comments:
Post a Comment