class ZMSImpl implements Authorizer, KeyStore, ZMSHandler {

    @Override
    public void putPolicy(ResourceContext ctx, String domainName, String policyName, String auditRef, Policy policy) {

        final String caller = ctx.getApiName();
        logPrincipal(ctx);

        if (readOnlyMode) {
            throw ZMSUtils.requestError(SERVER_READ_ONLY_MESSAGE, caller);
        }

        validateRequest(ctx.request(), caller);

        validate(domainName, TYPE_DOMAIN_NAME, caller);
        validate(policyName, TYPE_COMPOUND_NAME, caller);
        validate(policy, TYPE_POLICY, caller);

        // verify that request is properly authenticated for this request

        verifyAuthorizedServiceOperation(((RsrcCtxWrapper) ctx).principal().getAuthorizedService(), caller);

        // for consistent handling of all requests, we're going to convert
        // all incoming object values into lower case (e.g. domain, role,
        // policy, service, etc name)

        domainName = domainName.toLowerCase();
        setRequestDomain(ctx, domainName);
        policyName = policyName.toLowerCase();
        AthenzObject.POLICY.convertToLowerCase(policy);

        // we are not going to allow any user to update
        // the admin policy since that is required
        // for standard domain operations */

        if (policyName.equalsIgnoreCase(ADMIN_POLICY_NAME)) {
            throw ZMSUtils.requestError("putPolicy: admin policy cannot be modified", caller);
        }

        // verify the policy name in the URI and request are consistent

        if (!isConsistentPolicyName(domainName, policyName, policy)) {
            throw ZMSUtils.requestError("putPolicy: Inconsistent policy names - expected: "
                    + ZMSUtils.policyResourceName(domainName, policyName) + ", actual: "
                    + policy.getName(), caller);
        }

        // validate to make sure we have expected values for assertion fields

        validatePolicyAssertions(policy.getAssertions(), caller);

        dbService.executePutPolicy(ctx, domainName, policyName, policy, auditRef, caller);
    }

    public  ZMSImpl();

}