class /HEC1/CL_BOPF_CONFIG_VALIDAT_H definition
  public
  final
  create public .

public section.

  class-methods CHECK_MASTER_NODE_IS_COMPLETE
    importing
      !IV_IS_APP_SERVER type BOOLE_D optional
      !IV_CHECK_RULE type INT1
      !IS_CTX type /BOBF/S_FRW_CTX_DET
      !IT_KEY type /BOBF/T_FRW_KEY
      !IO_READ type ref to /BOBF/IF_FRW_READ
    exporting
      !EO_MESSAGE type ref to /BOBF/IF_FRW_MESSAGE
      !ET_FAILED_KEY type /BOBF/T_FRW_KEY
    returning
      value(RV_VALUE) type BOOLE_D
    raising
      /BOBF/CX_FRW .
  class-methods CHECK_STANDBY_NODE_IS_RELEASED
    importing
      !IV_IS_APP_SERVER type BOOLE_D optional
      !IV_CHECK_RULE type INT1
      !IS_CTX type /BOBF/S_FRW_CTX_DET
      !IT_KEY type /BOBF/T_FRW_KEY
      !IO_READ type ref to /BOBF/IF_FRW_READ
    exporting
      !ET_NODE_KEY type /BOBF/T_FRW_KEY
      !EO_MESSAGE type ref to /BOBF/IF_FRW_MESSAGE
      !ET_FAILED_KEY type /BOBF/T_FRW_KEY
    returning
      value(RV_VALUE) type BOOLE_D
    raising
      /BOBF/CX_FRW .
protected section.
private section.
ENDCLASS.



CLASS /HEC1/CL_BOPF_CONFIG_VALIDAT_H IMPLEMENTATION.


  METHOD check_master_node_is_complete.

    DATA: lr_serv_inst     TYPE REF TO data,
          lr_node          TYPE REF TO data,
          lr_serv_perf_cat TYPE REF TO data,
          lr_storage_qty   TYPE REF TO data.

    FIELD-SYMBOLS: <lt_serv_inst>     TYPE INDEX TABLE,
                   <lt_node>          TYPE INDEX TABLE,
                   <lt_serv_perf_cat> TYPE INDEX TABLE,
                   <lt_storage_qty>   TYPE INDEX TABLE.



    IF iv_is_app_server = abap_true.
      lr_serv_inst     = NEW /hec1/t_data_app_serv_inst_ct( ).
      lr_node          = NEW /hec1/t_data_app_node_ct( ).
      lr_serv_perf_cat = NEW /hec1/t_data_app_serv_pc_ct( ).
      lr_storage_qty   = NEW /hec1/t_data_app_storageqty_ct( ).
    ELSE.
      lr_serv_inst     = NEW /hec1/t_data_db_inst_ct( ).
      lr_node          = NEW /hec1/t_data_db_node_ct( ).
      lr_serv_perf_cat = NEW /hec1/t_data_db_serv_pc_ct( ).
      lr_storage_qty   = NEW /hec1/t_data_db_storage_qty_ct( ).
    ENDIF.

    ASSIGN lr_serv_inst->*     TO <lt_serv_inst>.
    ASSIGN lr_node->*          TO <lt_node>.
    ASSIGN lr_serv_perf_cat->* TO <lt_serv_perf_cat>.
    ASSIGN lr_storage_qty->*   TO <lt_storage_qty>.


    CASE iv_check_rule.
        " ******************************************
        " Start node to storage amount
        " ******************************************
      WHEN /hec1/if_bopf_constants=>gc_check_rule-node.
        " Get default master node
        io_read->retrieve_by_association( EXPORTING iv_node        = is_ctx-node_key
                                                    it_key         = it_key
                                                    iv_fill_data   = abap_false
                                                    iv_association = COND #( WHEN iv_is_app_server = abap_true
                                                                             THEN /hec1/if_configuration_c=>sc_association-app_node-def_master_node
                                                                             ELSE /hec1/if_configuration_c=>sc_association-db_node-to_def_master_node )
                                          IMPORTING et_target_key  = DATA(lt_key)                                                                       ).

        " ******************************************
        " Start from server performance
        " category to storage amount
        " ******************************************
      WHEN /hec1/if_bopf_constants=>gc_check_rule-perfomance_cat.
        " Get node master(parent)
        io_read->retrieve_by_association( EXPORTING iv_node        = is_ctx-node_key
                                                    it_key         = it_key
                                                    iv_fill_data   = abap_false
                                                    iv_association = COND #( WHEN iv_is_app_server = abap_true
                                                                             THEN /hec1/if_configuration_c=>sc_association-app_server_perform_cat-to_parent
                                                                             ELSE /hec1/if_configuration_c=>sc_association-db_server_perform_cat-to_parent  )
                                          IMPORTING et_target_key  = lt_key                                                                                   ).

        " ******************************************
        " Start from storage amount to node
        " ******************************************
      WHEN /hec1/if_bopf_constants=>gc_check_rule-storage_amount.
        " Get app server node
        io_read->retrieve_by_association( EXPORTING iv_node        = is_ctx-node_key
                                                    it_key         = it_key
                                                    iv_fill_data   = abap_false
                                                    iv_association = COND #( WHEN iv_is_app_server = abap_true
                                                                             THEN /hec1/if_configuration_c=>sc_association-app_storage_amount-to_def_master_node
                                                                             ELSE /hec1/if_configuration_c=>sc_association-db_storage_amount-to_def_master_node  )
                                          IMPORTING et_target_key  = lt_key                                                                                        ).

    ENDCASE.


    " ******************************************
    " Check if master node is complete
    " configured
    " ******************************************
    io_read->retrieve( EXPORTING iv_node = COND #( WHEN iv_is_app_server = abap_true
                                                   THEN /hec1/if_configuration_c=>sc_node-app_node
                                                   ELSE /hec1/if_configuration_c=>sc_node-db_node  )
                                 it_key  = lt_key
                       IMPORTING et_data = <lt_node>                                                 ).


    " Get all server performance categories
    " of master node
    io_read->retrieve_by_association( EXPORTING iv_node        = COND #( WHEN iv_is_app_server = abap_true
                                                                         THEN /hec1/if_configuration_c=>sc_node-app_node
                                                                         ELSE /hec1/if_configuration_c=>sc_node-db_node  )
                                                it_key         = lt_key
                                                iv_fill_data   = abap_true
                                                iv_association = COND #( WHEN iv_is_app_server = abap_true
                                                                         THEN /hec1/if_configuration_c=>sc_association-app_node-app_server_perform_cat
                                                                         ELSE /hec1/if_configuration_c=>sc_association-db_node-db_server_perform_cat   )

                                      IMPORTING et_data        = <lt_serv_perf_cat>                                                                      ).

    " Set key for retrieve storage amount
    CLEAR lt_key.
    LOOP AT <lt_serv_perf_cat> ASSIGNING FIELD-SYMBOL(<fs_serv_perf_cat>).
      ASSIGN COMPONENT 'KEY'
          OF STRUCTURE <fs_serv_perf_cat>
       TO FIELD-SYMBOL(<fs_key>).

      IF <fs_key> IS ASSIGNED.
        INSERT VALUE #( key = <fs_key> ) INTO TABLE lt_key.
        UNASSIGN <fs_key>.
      ENDIF.
    ENDLOOP.

    " Get all storage amounts of master node
    io_read->retrieve_by_association( EXPORTING iv_node        = COND #( WHEN iv_is_app_server = abap_true
                                                                         THEN /hec1/if_configuration_c=>sc_node-app_server_perform_cat
                                                                         ELSE /hec1/if_configuration_c=>sc_node-db_server_perform_cat  )
                                                it_key         = lt_key
                                                iv_fill_data   = abap_true
                                                iv_association = COND #( WHEN iv_is_app_server = abap_true
                                                                         THEN /hec1/if_configuration_c=>sc_association-app_server_perform_cat-app_storage_amount
                                                                         ELSE /hec1/if_configuration_c=>sc_association-db_server_perform_cat-db_storage_amount   )
                                      IMPORTING et_data        = <lt_storage_qty>                                                                                  ).


    rv_value = abap_true.
    " Check first all storage amounts
    LOOP AT <lt_storage_qty> ASSIGNING FIELD-SYMBOL(<fs_storage_qty>).
      " Get instance status
      ASSIGN COMPONENT /hec1/if_configuration_c=>sc_node_attribute-db_node-hec_instance_status
         OF STRUCTURE <fs_storage_qty>
      TO FIELD-SYMBOL(<fs_status>).

      IF <fs_status> IS ASSIGNED                                                 AND
         <fs_status> = /hec1/if_config_constants=>gc_instance_status-incomplete.
        CLEAR rv_value.
        RETURN. " >>>>>>>>
      ENDIF.
      UNASSIGN <fs_status>.
    ENDLOOP.


    " Check all server performance categories
    LOOP AT <lt_serv_perf_cat> ASSIGNING <fs_serv_perf_cat>.
      " Get instance status
      ASSIGN COMPONENT /hec1/if_configuration_c=>sc_node_attribute-db_node-hec_instance_status
         OF STRUCTURE <fs_serv_perf_cat>
                   TO <fs_status>.

      IF <fs_status> IS ASSIGNED                                                 AND
         <fs_status> = /hec1/if_config_constants=>gc_instance_status-incomplete.
        CLEAR rv_value.
        RETURN. " >>>>>>>>
      ENDIF.
      UNASSIGN <fs_status>.
    ENDLOOP.


    " Check default master node
    LOOP AT <lt_node> ASSIGNING FIELD-SYMBOL(<fs_node>).
      " Get instance status
      ASSIGN COMPONENT /hec1/if_configuration_c=>sc_node_attribute-db_node-hec_instance_status
         OF STRUCTURE <fs_node>
                   TO <fs_status>.

      IF <fs_status> IS ASSIGNED                                                 AND
         <fs_status> = /hec1/if_config_constants=>gc_instance_status-incomplete.
        CLEAR rv_value.
        RETURN. " >>>>>>>>
      ENDIF.
      UNASSIGN <fs_status>.
    ENDLOOP.


  ENDMETHOD.


  METHOD check_standby_node_is_released.

    DATA: lr_node TYPE REF TO data.

    FIELD-SYMBOLS: <lt_node> TYPE INDEX TABLE.




    IF iv_is_app_server = abap_true.
      lr_node = NEW /hec1/t_data_app_node_ct( ).
    ELSE.
      lr_node = NEW /hec1/t_data_db_node_ct( ).
    ENDIF.
    ASSIGN lr_node->* TO <lt_node>.


    CASE iv_check_rule.
        " ******************************************
        " Start from node to standby/worker node
        " ******************************************
      WHEN /hec1/if_bopf_constants=>gc_check_rule-node.
        io_read->retrieve_by_association( EXPORTING iv_node        = is_ctx-node_key
                                                    it_key         = it_key
                                                    iv_fill_data   = abap_false
                                                    iv_association = COND #( WHEN iv_is_app_server = abap_true
                                                                             THEN /hec1/if_configuration_c=>sc_association-app_node-to_standby_node
                                                                             ELSE /hec1/if_configuration_c=>sc_association-db_node-to_none_master_node )
                                          IMPORTING et_target_key  = DATA(lt_key)                                                                        ).

        " ******************************************
        " Start from server performance category
        " to standby/worker node
        " ******************************************
      WHEN /hec1/if_bopf_constants=>gc_check_rule-perfomance_cat.
        io_read->retrieve_by_association( EXPORTING iv_node        = is_ctx-node_key
                                                    it_key         = it_key
                                                    iv_fill_data   = abap_false
                                                    iv_association = COND #( WHEN iv_is_app_server = abap_true
                                                                             THEN /hec1/if_configuration_c=>sc_association-app_server_perform_cat-to_standby_node
                                                                             ELSE /hec1/if_configuration_c=>sc_association-db_server_perform_cat-to_none_master_node )
                                          IMPORTING et_target_key  = lt_key                                                                                            ).

        " ******************************************
        " Start from storage amount
        " to standby/worker node
        " ******************************************
      WHEN /hec1/if_bopf_constants=>gc_check_rule-storage_amount.
        io_read->retrieve_by_association( EXPORTING iv_node        = is_ctx-node_key
                                                    it_key         = it_key
                                                    iv_fill_data   = abap_false
                                                    iv_association = COND #( WHEN iv_is_app_server = abap_true
                                                                             THEN /hec1/if_configuration_c=>sc_association-app_storage_amount-to_standby_node
                                                                             ELSE /hec1/if_configuration_c=>sc_association-db_storage_amount-to_none_master_node )
                                          IMPORTING et_target_key  = lt_key                                                                                        ).
    ENDCASE.


    " ******************************************
    " Check if standby/worker node is released
    " ******************************************
    io_read->retrieve( EXPORTING iv_node = COND #( WHEN iv_is_app_server = abap_true
                                                   THEN /hec1/if_configuration_c=>sc_node-app_node
                                                   ELSE /hec1/if_configuration_c=>sc_node-db_node  )
                                 it_key  = lt_key
                       IMPORTING et_data = <lt_node>                                                ).

    rv_value = abap_true.

    LOOP AT <lt_node> ASSIGNING FIELD-SYMBOL(<fs_node>).
      ASSIGN COMPONENT 'KEY'
          OF STRUCTURE <fs_node>
       TO FIELD-SYMBOL(<fs_key>).

      IF <fs_key> IS ASSIGNED.
        INSERT VALUE #( key = <fs_key> ) INTO TABLE et_node_key.
      ENDIF.

      IF rv_value = abap_true.
        ASSIGN COMPONENT /hec1/if_configuration_c=>sc_node_attribute-db_node-hec_row_selectable
           OF STRUCTURE <fs_node>
        TO FIELD-SYMBOL(<fs_row_selectable>).

        IF <fs_row_selectable> IS ASSIGNED.
          TRY.
              IF <fs_row_selectable> = abap_false.
                CLEAR rv_value.
                CONTINUE. " >>>>>>>
              ELSE.
                rv_value = <fs_row_selectable>.
              ENDIF.
            CATCH cx_root.
          ENDTRY.
        ENDIF. " IF <fs_row_selectable> IS ASSIGNED.
      ENDIF.  " IF rv_value = abap_true.

      UNASSIGN: <fs_key>,
                <fs_row_selectable>.
    ENDLOOP.


  ENDMETHOD.
ENDCLASS.
