class RevokeAccessServiceTask implements JavaDelegate {

    public void execute(DelegateExecution execution) throws Exception{
        Job job = managementService.createJobQuery().processInstanceId(execution.getProcessInstanceId()).singleResult();
        AccessRequest accessRequest = (AccessRequest)execution.getVariable("accessRequest");
        try {
            AWSEnvironment awsEnvironment = new AWSEnvironment(accessRequest.getAccount(), accessRequest.getRegion(), accessRequest.getAccountSdlc());
            logger.info("Revoking access for Users, Attempts remaining: " + job.getRetries());
            for(User user : accessRequest.getUsers()) {
                AWSRdsDatabase database = accessRequest.getAwsRdsInstances().get(0);
                for (UserRole role : accessRequest.getRoles()) {
                    if (accessRequestService.getLiveRequestsForUserOnDatabase(user.getUserId(), accessRequest.getAccount(), database.getName(), role).isEmpty()) {
                        // if the db was actually an aurora global cluster then we should re-fetch the primary cluster
                        // as that could have changed
                        if (database.getDatabaseType() != null && database.getDatabaseType() == DatabaseType.AURORA_GLOBAL) {
                            logger.info("Re-fetching the Primary Cluster for this global cluster since it could have changed over time.");
                            DBCluster primaryCluster = rdsLookupService.getPrimaryClusterForGlobalCluster(awsEnvironment, database.getName()).get();
                            database.setEndpoint(String.format("%s:%s", primaryCluster.getEndpoint(), primaryCluster.getPort()));
                        }
                        databaseConnectionService.revokeAccess(database, awsEnvironment, RoleType.valueOf(role.getRole().toUpperCase()), user.getUserId());
                    } else {
                        logger.info("Skipping revocation of user " + user.getUserId() + " with role " + role.toString() + " as they have another active access request for this instance.");
                    }
                }
            }

        }catch(Exception e){
            if(job.getRetries() - 1 == 0){
                logger.error("Maximum attempt limit reached. Notify Ops team for manual removal");
                emailServiceWrapper.notifyOps(accessRequest);
                emailServiceWrapper.notifyAdminsOfFailure(accessRequest,e);
            }else{
                throw e;
            }
        }
    }

    @Autowired public  RevokeAccessServiceTask(EmailServiceWrapper emailServiceWrapper,
                                   DatabaseConnectionService databaseConnectionService,
                                   ManagementService managementService,
                                   RdsLookupService rdsLookupService,
                                   AccessRequestService accessRequestService);

}