class MsoKeystoneUtils extends MsoTenantUtils {

    public MsoTenant queryTenant(String tenantId, String cloudSiteId) throws MsoException {
        // Obtain the cloud site information where we will query the tenant
        CloudSite cloudSite =
                cloudConfig.getCloudSite(cloudSiteId).orElseThrow(() -> new MsoCloudSiteNotFound(cloudSiteId));

        Keystone keystoneAdminClient = getKeystoneAdminClient(cloudSite);

        // Check if the tenant exists and return its Tenant Id
        try {
            Tenant tenant = findTenantById(keystoneAdminClient, tenantId);
            if (tenant == null) {
                return null;
            }

            Map<String, String> metadata = new HashMap<>();
            if (cloudSite.getIdentityService().getTenantMetadata()) {
                OpenStackRequest<Metadata> request = keystoneAdminClient.tenants().showMetadata(tenant.getId());
                Metadata tenantMetadata = executeAndRecordOpenstackRequest(request);
                if (tenantMetadata != null) {
                    metadata = tenantMetadata.getMetadata();
                }
            }
            return new MsoTenant(tenant.getId(), tenant.getName(), metadata);
        } catch (OpenStackBaseException e) {
            // Convert Keystone OpenStackResponseException to MsoOpenstackException
            throw keystoneErrorToMsoException(e, "QueryTenant");
        } catch (RuntimeException e) {
            // Catch-all
            throw runtimeExceptionToMsoException(e, "QueryTenant");
        }
    }

}