class ZTSImpl implements KeyStore, ZTSHandler {

    @Override
    public DomainMetrics postDomainMetrics(ResourceContext ctx, String domainName,
            DomainMetrics domainMetrics) {

        final String caller = ctx.getApiName();
        final String principalDomain = logPrincipalAndGetDomain(ctx);

        if (readOnlyMode) {
            throw requestError("Server in Maintenance Read-Only mode. Please try your request later",
                    caller, ZTSConsts.ZTS_UNKNOWN_DOMAIN, principalDomain);
        }
        
        validateRequest(ctx.request(), principalDomain, caller);
        validate(domainName, TYPE_DOMAIN_NAME, principalDomain, caller);
        validate(domainMetrics, TYPE_DOMAIN_METRICS, principalDomain, caller);
        domainName = domainName.toLowerCase();
        setRequestDomain(ctx, domainName);
 
        // 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)
        
        AthenzObject.DOMAIN_METRICS.convertToLowerCase(domainMetrics);

        // verify valid domain specified
        DataCache data = dataStore.getDataCache(domainName);
        if (data == null) {
            metric.increment(HTTP_REQUEST, ZTSConsts.ZTS_UNKNOWN_DOMAIN, principalDomain);
            metric.increment(caller, ZTSConsts.ZTS_UNKNOWN_DOMAIN, principalDomain);
            throw notFoundError("postDomainMetrics: No such domain: " + domainName,
                    caller, ZTSConsts.ZTS_UNKNOWN_DOMAIN, principalDomain);
        }

        // verify domain name matches domain name in request object
        
        final String metricDomain = domainMetrics.getDomainName();
        if (!metricDomain.equals(domainName)) {
            final String errMsg = "postDomainMetrics: mismatched domain names: uri domain: "
                    + domainName + " : metric domain: " + metricDomain;
            throw requestError(errMsg, caller, domainName, principalDomain);
        }

        List<DomainMetric> dmList = domainMetrics.getMetricList();
        if (dmList == null || dmList.size() == 0) {
            // no metrics were sent - log error
            final String errMsg = "postDomainMetrics: received no metrics for domain: " + domainName;
            throw requestError(errMsg, caller, domainName, principalDomain);
        }

        // process the DomainMetrics request in order to increment each of its attrs
        
        for (DomainMetric dm: dmList) {
            final String dmt = dm.getMetricType().toString().toLowerCase();
            int count = dm.getMetricVal();
            if (count <= 0) {
                LOGGER.error("postDomainMetrics: ignore metric: {} invalid counter {} received for domain {}",
                        dmt, count, domainName);
                continue;
            }
            String metricName = DOM_METRIX_PREFIX + dmt;
            metric.increment(metricName, domainName, principalDomain, count);
        }

        return domainMetrics;
    }

    public  ZTSImpl();
    public  ZTSImpl(CloudStore implCloudStore, DataStore implDataStore);

}