class DBService implements RolesProvider {

    void executePutTenantRoles(ResourceContext ctx, String provSvcDomain, String provSvcName, String tenantDomain,
            String resourceGroup, List<TenantRoleAction> roles, String auditRef, String caller) {

        // our exception handling code does the check for retry count
        // and throws the exception it had received when the retry
        // count reaches 0

        for (int retryCount = defaultRetryCount; ; retryCount--) {

            try (ObjectStoreConnection con = store.getConnection(false, true)) {

                // first verify that auditing requirements are met

                checkDomainAuditEnabled(con, provSvcDomain, auditRef, caller, getPrincipalName(ctx), AUDIT_TYPE_TENANCY);

                String trustedRolePrefix = ZMSUtils.getTrustedResourceGroupRolePrefix(provSvcDomain,
                        provSvcName, tenantDomain, resourceGroup);

                StringBuilder auditDetails = new StringBuilder(ZMSConsts.STRING_BLDR_SIZE_DEFAULT);
                auditDetails.append("{\"put-tenant-roles\": [");
                boolean firstEntry = true;

                for (TenantRoleAction ra : roles) {

                    String tenantRole = ra.getRole();
                    String tenantAction = ra.getAction();
                    String trustedRole = trustedRolePrefix + tenantRole;
                    String trustedName = trustedRole.substring((provSvcDomain + AuthorityConsts.ROLE_SEP).length());

                    Role role = new Role().setName(trustedRole).setTrust(tenantDomain);

                    if (LOG.isInfoEnabled()) {
                        LOG.info(caller + ": add trusted Role to domain " + provSvcDomain +
                                ": " + trustedRole + " -> " + role);
                    }

                    // retrieve our original role in case one exists

                    Role originalRole = getRole(con, provSvcDomain, trustedName, false, false, false);

                    // now process the request

                    firstEntry = auditLogSeparator(auditDetails, firstEntry);

                    auditDetails.append("{\"role\": ");
                    if (!processRole(con, originalRole, provSvcDomain, trustedName, role,
                            getPrincipalName(ctx), auditRef, false, auditDetails)) {
                        con.rollbackChanges();
                        throw ZMSUtils.internalServerError("unable to put role: " + trustedRole, caller);
                    }

                    String policyResourceName = ZMSUtils.policyResourceName(provSvcDomain, trustedName);
                    final String resourceName = provSvcDomain + ":service." +
                            ZMSUtils.getTenantResourceGroupRolePrefix(provSvcName, tenantDomain, resourceGroup) + '*';
                    List<Assertion> assertions = Collections.singletonList(
                            new Assertion().setRole(trustedRole)
                                    .setResource(resourceName)
                                    .setAction(tenantAction));

                    Policy policy = new Policy().setName(policyResourceName).setAssertions(assertions);

                    if (LOG.isInfoEnabled()) {
                        LOG.info(caller + ": add trust policy to domain " + provSvcDomain +
                                ": " + trustedRole + " -> " + policy);
                    }

                    // retrieve our original policy

                    Policy originalPolicy = getPolicy(con, provSvcDomain, trustedName);

                    // now process the request

                    auditDetails.append(", \"policy\": ");
                    if (!processPolicy(con, originalPolicy, provSvcDomain, trustedName, policy, false, auditDetails)) {
                        con.rollbackChanges();
                        throw ZMSUtils.internalServerError("unable to put policy: " + policy.getName(), caller);
                    }
                    auditDetails.append('}');
                }

                // update our domain time-stamp and save changes

                saveChanges(con, provSvcDomain);

                // audit log the request

                auditLogRequest(ctx, provSvcDomain, auditRef, caller, ZMSConsts.HTTP_PUT,
                        tenantDomain, auditDetails.toString());

                return;

            } catch (ResourceException ex) {
                if (!shouldRetryOperation(ex, retryCount)) {
                    throw ex;
                }
            }
        }
    }

    public  DBService(ObjectStore store, AuditLogger auditLogger, ZMSConfig zmsConfig, AuditReferenceValidator auditReferenceValidator);

}