All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.hazelcast.azure.AzureClient Maven / Gradle / Ivy

There is a newer version: 5.0-BETA-1
Show newest version
/*
 * Copyright 2020 Hazelcast Inc.
 *
 * Licensed under the Hazelcast Community License (the "License"); you may not use
 * this file except in compliance with the License. You may obtain a copy of the
 * License at
 *
 * http://hazelcast.com/hazelcast-community-license
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OF ANY KIND, either express or implied. See the License for the
 * specific language governing permissions and limitations under the License.
 */

package com.hazelcast.azure;


import java.util.Collection;
import java.util.logging.Logger;

import static com.hazelcast.azure.Utils.isEmpty;

/**
 * Responsible for fetching the discovery information from Azure APIs.
 */
class AzureClient {
    private static final Logger LOGGER = Logger.getLogger(AzureClient.class.getSimpleName());

    private static final int RETRIES = 2;

    private final AzureMetadataApi azureMetadataApi;
    private final AzureComputeApi azureComputeApi;
    private final AzureAuthenticator azureAuthenticator;

    private final AzureConfig azureConfig;
    private final Tag tag;

    private String subscriptionId;
    private String resourceGroup;
    private String scaleSet;

    AzureClient(AzureMetadataApi azureMetadataApi, AzureComputeApi azureComputeApi,
                AzureAuthenticator azureAuthenticator, AzureConfig azureConfig) {
        this.azureMetadataApi = azureMetadataApi;
        this.azureComputeApi = azureComputeApi;
        this.azureAuthenticator = azureAuthenticator;
        this.azureConfig = azureConfig;

        this.subscriptionId = subscriptionIdFromConfigOrMetadataApi();
        this.resourceGroup = resourceGroupFromConfigOrMetadataApi();
        this.scaleSet = scaleSetFromConfigOrMetadataApi();
        this.tag = azureConfig.getTag();
    }

    private String subscriptionIdFromConfigOrMetadataApi() {
        if (!isEmpty(azureConfig.getSubscriptionId())) {
            return azureConfig.getSubscriptionId();
        }
        LOGGER.finest("Property 'subscriptionId' not configured, fetching from the VM metadata service");
        return RetryUtils.retry(() -> azureMetadataApi.subscriptionId(), RETRIES);
    }

    private String resourceGroupFromConfigOrMetadataApi() {
        if (!azureConfig.isInstanceMetadataAvailable()) {
            return azureConfig.getResourceGroup();
        }
        LOGGER.finest("Property 'resourceGroup' not configured, fetching from the VM metadata service");
        return RetryUtils.retry(() -> azureMetadataApi.resourceGroupName(), RETRIES);
    }

    private String scaleSetFromConfigOrMetadataApi() {
        if (!azureConfig.isInstanceMetadataAvailable()) {
            return azureConfig.getScaleSet();
        }
        LOGGER.finest("Property 'scaleSet' not configured, fetching from the VM metadata service");
        return RetryUtils.retry(() -> azureMetadataApi.scaleSet(), RETRIES);
    }

    Collection getAddresses() {
        LOGGER.finest("Fetching OAuth Access Token");
        final String accessToken = fetchAccessToken();
        LOGGER.finest(String.format("Fetching instances for subscription '%s' and resourceGroup '%s'",
                subscriptionId, resourceGroup));
        Collection addresses = azureComputeApi.instances(subscriptionId, resourceGroup,
                scaleSet, tag, accessToken);
        LOGGER.finest(String.format("Found the following instances for project '%s' and zone '%s': %s",
                subscriptionId, resourceGroup,
                addresses));
        return addresses;
    }

    private String fetchAccessToken() {
        if (azureConfig.isInstanceMetadataAvailable()) {
            return azureMetadataApi.accessToken();
        } else {
            return azureAuthenticator.refreshAccessToken(azureConfig.getTenantId(), azureConfig.getClientId(),
                    azureConfig.getClientSecret());
        }
    }

    /**
     * This method creates an availability zone string by joining Azure Location and Zone properties because availability zones
     * are defined in locations in Azure environment.
     *
     * @see Availability Zones in Azure
     *
     * @return Availability zone string in "LOCATION-ZONE" format
     */
    String getAvailabilityZone() {
        String zone = azureMetadataApi.availabilityZone();
        if (isEmpty(zone)) {
            return azureMetadataApi.faultDomain();
        } else {
            return String.format("%s-%s", azureMetadataApi.location(), zone);
        }
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy