class ExecuteBuildingBlockRainyDay {

    public void queryRainyDayTable(DelegateExecution execution, boolean primaryPolicy) {
        try {
            ExecuteBuildingBlock ebb = (ExecuteBuildingBlock) execution.getVariable("buildingBlock");
            String bbName = ebb.getBuildingBlock().getBpmnFlowName();
            GeneralBuildingBlock gBBInput = (GeneralBuildingBlock) execution.getVariable("gBBInput");
            String requestId = (String) execution.getVariable("mso-request-id");
            Map<ResourceKey, String> lookupKeyMap = (Map<ResourceKey, String>) execution.getVariable("lookupKeyMap");
            String serviceType = ASTERISK;
            boolean aLaCarte = (boolean) execution.getVariable("aLaCarte");
            boolean suppressRollback = (boolean) execution.getVariable("suppressRollback");
            WorkflowException workflowException = (WorkflowException) execution.getVariable("WorkflowException");
            if (workflowException != null) {
                execution.setVariable("WorkflowExceptionErrorMessage", workflowException.getErrorMessage());
            } else {
                logger.debug("WorkflowException is null, unable to set WorkflowExceptionErrorMessage");
            }
            String handlingCode = "";

            if (suppressRollback) {
                handlingCode = "Abort";
            } else {
                try {
                    if (gBBInput.getCustomer() != null && gBBInput.getCustomer().getServiceSubscription() != null) {
                        serviceType = gBBInput.getCustomer().getServiceSubscription().getServiceInstances().get(0)
                                .getModelInfoServiceInstance().getServiceType();
                    }
                    if (serviceType == null || serviceType.isEmpty()) {
                        serviceType = ASTERISK;
                    }
                } catch (Exception ex) {
                    // keep default serviceType value
                    logger.error("Exception in serviceType retrieval", ex);
                }
                execution.setVariable(RAINY_DAY_SERVICE_TYPE, serviceType);
                String vnfType = ASTERISK;
                String vnfName = ASTERISK;
                try {
                    if (gBBInput.getCustomer() != null && gBBInput.getCustomer().getServiceSubscription() != null) {
                        for (GenericVnf vnf : gBBInput.getCustomer().getServiceSubscription().getServiceInstances()
                                .get(0).getVnfs()) {
                            if (vnf.getVnfId().equalsIgnoreCase(lookupKeyMap.get(ResourceKey.GENERIC_VNF_ID))) {
                                vnfType = vnf.getVnfType();
                                vnfName = vnf.getVnfName();
                            }
                        }
                    } else {
                        for (GenericVnf vnf : gBBInput.getServiceInstance().getVnfs()) {
                            if (vnf.getVnfId().equalsIgnoreCase(lookupKeyMap.get(ResourceKey.GENERIC_VNF_ID))) {
                                vnfType = vnf.getVnfType();
                                vnfName = vnf.getVnfName();
                            }
                        }
                    }
                } catch (Exception ex) {
                    // keep default vnfType value
                    logger.error("Exception in vnfType retrieval", ex);
                }
                execution.setVariable(RAINY_DAY_VNF_TYPE, vnfType);
                execution.setVariable(RAINY_DAY_VNF_NAME, vnfName);
                String errorCode = ASTERISK;
                if (workflowException != null) {
                    errorCode = "" + workflowException.getErrorCode();
                } else {
                    logger.debug("WorkflowException is null, unable to get error code");
                }

                try {
                    errorCode = "" + (String) execution.getVariable("WorkflowExceptionCode");
                } catch (Exception ex) {
                    // keep default errorCode value
                    logger.error("Exception in errorCode retrieval", ex);
                }

                String workStep = ASTERISK;
                try {
                    workStep = workflowException.getWorkStep();
                } catch (Exception ex) {
                    // keep default workStep value
                    logger.error("Exception in workStep retrieval", ex);
                }

                String errorMessage = ASTERISK;
                try {
                    errorMessage = workflowException.getErrorMessage();
                } catch (Exception ex) {
                    // keep default workStep value
                    logger.error("Exception in errorMessage retrieval", ex);
                }

                String serviceRole = ASTERISK;
                try {
                    if (gBBInput.getCustomer() != null && gBBInput.getCustomer().getServiceSubscription() != null) {
                        serviceRole = gBBInput.getCustomer().getServiceSubscription().getServiceInstances().get(0)
                                .getModelInfoServiceInstance().getServiceRole();
                    }
                    if (serviceRole == null || serviceRole.isEmpty()) {
                        serviceRole = ASTERISK;
                    }
                } catch (Exception ex) {
                    // keep default serviceRole value
                }

                RainyDayHandlerStatus rainyDayHandlerStatus;
                rainyDayHandlerStatus = catalogDbClient.getRainyDayHandlerStatus(bbName, serviceType, vnfType,
                        errorCode, workStep, errorMessage, serviceRole);

                if (rainyDayHandlerStatus == null) {
                    handlingCode = "Abort";
                } else {
                    if (primaryPolicy) {
                        handlingCode = rainyDayHandlerStatus.getPolicy();
                    } else {
                        handlingCode = rainyDayHandlerStatus.getSecondaryPolicy();
                    }
                }
                if (!primaryPolicy) {
                    try {
                        InfraActiveRequests request = requestDbclient.getInfraActiveRequestbyRequestId(requestId);
                        request.setRetryStatusMessage("Retries have been exhausted.");
                        requestDbclient.updateInfraActiveRequests(request);
                    } catch (Exception ex) {
                        logger.error("Failed to update Request Db Infra Active Requests with Retry Status", ex);
                    }
                }
                if ("RollbackToAssigned".equals(handlingCode) && !aLaCarte) {
                    handlingCode = "Rollback";
                }
                if (handlingCode.startsWith("Rollback")) {
                    String targetState = "";
                    if ("RollbackToAssigned".equalsIgnoreCase(handlingCode)) {
                        targetState = Status.ROLLED_BACK_TO_ASSIGNED.toString();
                    } else if ("RollbackToCreated".equalsIgnoreCase(handlingCode)) {
                        targetState = Status.ROLLED_BACK_TO_CREATED.toString();
                    } else {
                        targetState = Status.ROLLED_BACK.toString();
                    }
                    execution.setVariable(ROLLBACK_TARGET_STATE, targetState);
                    logger.debug("Rollback target state is: {}", targetState);
                }
            }
            logger.debug("RainyDayHandler Status Code is: {}", handlingCode);
            execution.setVariable(HANDLING_CODE, handlingCode);
        } catch (Exception e) {
            String code = this.environment.getProperty(defaultCode);
            logger.error("Failed to determine RainyDayHandler Status. Seting handlingCode = {}", code, e);
            execution.setVariable(HANDLING_CODE, code);
        }
        try {
            int envMaxRetries = Integer.parseInt(this.environment.getProperty(maxRetries));
            execution.setVariable("maxRetries", envMaxRetries);
        } catch (Exception ex) {
            logger.error("Could not read maxRetries from config file. Setting max to 5 retries", ex);
            execution.setVariable("maxRetries", 5);
        }
    }

}