<commit_before>/**
 * Copyright (C) 2012 enStratus Networks Inc
 *
 * ====================================================================
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 * ====================================================================
 */

package org.dasein.cloud.azure;

import org.apache.commons.codec.binary.Base64;
import org.apache.log4j.Logger;
import org.dasein.cloud.AbstractCloud;
import org.dasein.cloud.CloudException;
import org.dasein.cloud.InternalException;
import org.dasein.cloud.ProviderContext;
import org.dasein.cloud.azure.compute.AzureComputeServices;
import org.dasein.cloud.azure.network.AzureNetworkServices;
import org.dasein.cloud.azure.storage.AzureStorageServices;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathExpression;
import javax.xml.xpath.XPathExpressionException;
import javax.xml.xpath.XPathFactory;
import java.io.UnsupportedEncodingException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Random;

/**
 * Core cloud provider implementation for the Microsoft Azure cloud.
 * @author <NAME> (<EMAIL>)
 * @since 2012.04.1
 * @version 2012.04.1
 */
public class Azure extends AbstractCloud {
    static private final Logger logger = Azure.getLogger(Azure.class);
	
    static private @Nonnull String getLastItem(@Nonnull String name) {
        int idx = name.lastIndexOf('.');

        if( idx < 0 ) {
            return name;
        }
        else if( idx == (name.length()-1) ) {
            return "";
        }
        return name.substring(idx + 1);
    }

    static public @Nonnull Logger getLogger(@Nonnull Class<?> cls) {
        String pkg = getLastItem(cls.getPackage().getName());

        if( pkg.equals("azure") ) {
            pkg = "";
        }
        else {
            pkg = pkg + ".";
        }
        return Logger.getLogger("dasein.cloud.azure.std." + pkg + getLastItem(cls.getName()));
    }

    static public @Nonnull Logger getWireLogger(@Nonnull Class<?> cls) {
        return Logger.getLogger("dasein.cloud.azure.wire." + getLastItem(cls.getPackage().getName()) + "." + getLastItem(cls.getName()));
    }


    public Azure() { }


    static private final Random random = new Random();
    
    public @Nonnull String generateToken(int minLength, int maxLength) {
        if( minLength < 0 ) {
            minLength = 0;
        }
        if( maxLength < minLength ) {
            if( minLength == 0 ) {
                return "";
            }
            maxLength = minLength;
        }

        //generate token that meets most password complexity requirements - Uppercase and lowercase letters, digits and special chars
        String token = new String(RandomPasswordGenerator.generatePassword(minLength, maxLength, 2, 2, 2));
        return token;
    }
  
    @Override
    public @Nonnull String getCloudName() {
        return "Azure";
    }

    public String getDataCenterId(String regionId){
    	return regionId;
    }


    @Override
    public @Nonnull AzureComputeServices getComputeServices() {
        return new AzureComputeServices(this);
    }

    @Override
    public @Nonnull AzureLocation getDataCenterServices() {
        return new AzureLocation(this);
    }
    
    @Override
    public @Nonnull AzureNetworkServices getNetworkServices() {
    	//return null;
    	//Not ready yet
    	return new AzureNetworkServices(this);
    }

    private transient String storageEndpoint;

    public @Nonnull String getStorageEndpoint() throws CloudException, InternalException {
        if( storageEndpoint == null ) {
            ProviderContext ctx = getContext();

            if( ctx == null ) {
                throw new AzureConfigException("No configuration was set for this request");
            }
            AzureMethod method = new AzureMethod(this);

            Document xml = method.getAsXML(ctx.getAccountNumber(), "/services/storageservices");

            if( xml == null ) {
                throw new CloudException("Unable to identify the blob endpoint");
            }
            XPathFactory xPathfactory = XPathFactory.newInstance();
            XPath xpath = xPathfactory.newXPath();

            try {
                XPathExpression expr = xpath.compile("(/StorageServices/StorageService/StorageServiceProperties[GeoPrimaryRegion='"+ctx.getRegionId()+"']/Endpoints/Endpoint[contains(.,'.blob.')])[1]");
                storageEndpoint = expr.evaluate(xml).trim();
            } catch (XPathExpressionException e) {
                throw new CloudException("Invalid blob endpoint search expression");
            }

            if( storageEndpoint == null || storageEndpoint.isEmpty()) {
                throw new CloudException("Cannot find blob storage endpoint in the current region");
            }
        }
        return storageEndpoint;
    }

    private transient String storageService;

    public @Nullable String getStorageService() throws CloudException, InternalException {
        if( storageService == null ) {
            ProviderContext ctx = getContext();

            if( ctx == null ) {
                throw new AzureConfigException("No configuration was set for this request");
            }
            AzureMethod method = new AzureMethod(this);

            Document xml = method.getAsXML(ctx.getAccountNumber(), "/services/storageservices");

            if( xml == null ) {
                throw new CloudException("Unable to identify the storage service");
            }<commit_msg>Prevent possible Azure error if storageEndpoint is empty<commit_after>/**
 * Copyright (C) 2012 enStratus Networks Inc
 *
 * ====================================================================
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 * ====================================================================
 */

package org.dasein.cloud.azure;

import org.apache.commons.codec.binary.Base64;
import org.apache.log4j.Logger;
import org.dasein.cloud.AbstractCloud;
import org.dasein.cloud.CloudException;
import org.dasein.cloud.InternalException;
import org.dasein.cloud.ProviderContext;
import org.dasein.cloud.azure.compute.AzureComputeServices;
import org.dasein.cloud.azure.network.AzureNetworkServices;
import org.dasein.cloud.azure.storage.AzureStorageServices;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathExpression;
import javax.xml.xpath.XPathExpressionException;
import javax.xml.xpath.XPathFactory;
import java.io.UnsupportedEncodingException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Random;

/**
 * Core cloud provider implementation for the Microsoft Azure cloud.
 * @author <NAME> (<EMAIL>)
 * @since 2012.04.1
 * @version 2012.04.1
 */
public class Azure extends AbstractCloud {
    static private final Logger logger = Azure.getLogger(Azure.class);
	
    static private @Nonnull String getLastItem(@Nonnull String name) {
        int idx = name.lastIndexOf('.');

        if( idx < 0 ) {
            return name;
        }
        else if( idx == (name.length()-1) ) {
            return "";
        }
        return name.substring(idx + 1);
    }

    static public @Nonnull Logger getLogger(@Nonnull Class<?> cls) {
        String pkg = getLastItem(cls.getPackage().getName());

        if( pkg.equals("azure") ) {
            pkg = "";
        }
        else {
            pkg = pkg + ".";
        }
        return Logger.getLogger("dasein.cloud.azure.std." + pkg + getLastItem(cls.getName()));
    }

    static public @Nonnull Logger getWireLogger(@Nonnull Class<?> cls) {
        return Logger.getLogger("dasein.cloud.azure.wire." + getLastItem(cls.getPackage().getName()) + "." + getLastItem(cls.getName()));
    }


    public Azure() { }


    static private final Random random = new Random();
    
    public @Nonnull String generateToken(int minLength, int maxLength) {
        if( minLength < 0 ) {
            minLength = 0;
        }
        if( maxLength < minLength ) {
            if( minLength == 0 ) {
                return "";
            }
            maxLength = minLength;
        }

        //generate token that meets most password complexity requirements - Uppercase and lowercase letters, digits and special chars
        String token = new String(RandomPasswordGenerator.generatePassword(minLength, maxLength, 2, 2, 2));
        return token;
    }
  
    @Override
    public @Nonnull String getCloudName() {
        return "Azure";
    }

    public String getDataCenterId(String regionId){
    	return regionId;
    }


    @Override
    public @Nonnull AzureComputeServices getComputeServices() {
        return new AzureComputeServices(this);
    }

    @Override
    public @Nonnull AzureLocation getDataCenterServices() {
        return new AzureLocation(this);
    }
    
    @Override
    public @Nonnull AzureNetworkServices getNetworkServices() {
    	//return null;
    	//Not ready yet
    	return new AzureNetworkServices(this);
    }

    private transient String storageEndpoint;

    public @Nonnull String getStorageEndpoint() throws CloudException, InternalException {
        if( storageEndpoint == null ) {
            ProviderContext ctx = getContext();

            if( ctx == null ) {
                throw new AzureConfigException("No configuration was set for this request");
            }
            AzureMethod method = new AzureMethod(this);

            Document xml = method.getAsXML(ctx.getAccountNumber(), "/services/storageservices");

            if( xml == null ) {
                throw new CloudException("Unable to identify the blob endpoint");
            }
            XPathFactory xPathfactory = XPathFactory.newInstance();
            XPath xpath = xPathfactory.newXPath();

            try {
                XPathExpression expr = xpath.compile("(/StorageServices/StorageService/StorageServiceProperties[GeoPrimaryRegion='"+ctx.getRegionId()+"']/Endpoints/Endpoint[contains(.,'.blob.')])[1]");
                storageEndpoint = expr.evaluate(xml).trim();
            } catch (XPathExpressionException e) {
                throw new CloudException("Invalid blob endpoint search expression");
            }

            if( storageEndpoint == null || storageEndpoint.isEmpty()) {
                storageEndpoint = null;
                throw new CloudException("Cannot find blob storage endpoint in the current region");
            }
        }
        return storageEndpoint;
    }

    private transient String storageService;

    public @Nullable String getStorageService() throws CloudException, InternalException {
        if( storageService == null ) {
            ProviderContext ctx = getContext();

            if( ctx == null ) {
                throw new AzureConfigException("No configuration was set for this request");
            }
            AzureMethod method = new AzureMethod(this);

            Document xml = method.getAsXML(ctx.getAccountNumber(), "/services/storageservices");

            if( xml == null ) {
                throw new CloudException("Unable to identify the storage service");
            }
{'fraction_non_alphanumeric': 0.11906106316044204, 'fraction_numerical': 0.0061305154472856335, 'mean_word_length': 2.7467512843759443, 'pattern_counts': {'":': 0, '<': 17, '<?xml version=': 0, '>': 11, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 18}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6639236', 'n_tokens_mistral': 3262, 'n_tokens_neox': 3115, 'n_words': 899}