Hot questions for Using Azure in api

Question:

I have been searching the web for hours now for a working sample in Android or java of the Microsoft Translator Text API since its the only API with free 2m character translation everymonth. But to no avail, none works since most of what I find are already deprecated since this march 2017 and had been migrated to the azure cognitive services now. Anyone knows how to do it?. I found a working code in c# which outputs the translation in console, but I can't convert it myself to Java since I'm not into C#. TIA.

Below is the working code in C#.

using System;
using System.Net.Http;
using System.Threading.Tasks;

namespace AzureSubscriptionKeySample
{
    class Program
    {
        /// Header name used to pass the subscription key to translation service
        private const string OcpApimSubscriptionKeyHeader = "Ocp-Apim-Subscription-Key";

    /// Url template to make translate call
    private const string TranslateUrlTemplate = "http://api.microsofttranslator.com/v2/http.svc/translate?text={0}&from={1}&to={2}&category={3}";

    private const string AzureSubscriptionKey = "MyAzureSubscriptionKey";   //Enter here the Key from your Microsoft Translator Text subscription on http://portal.azure.com

    static void Main(string[] args)
    {
        TranslateAsync().Wait();
        Console.ReadKey();
    }

    /// Demonstrates Translate API call using Azure Subscription key authentication.
    private static async Task TranslateAsync()
    {
        try
        {
            var translateResponse = await TranslateRequest(string.Format(TranslateUrlTemplate, "안녕하세요 친구", "ko", "en", "general"), AzureSubscriptionKey);
            var translateResponseContent = await translateResponse.Content.ReadAsStringAsync();
            if (translateResponse.IsSuccessStatusCode)
            {
                Console.WriteLine("Translation result: {0}", translateResponseContent);
            }
            else
            {
                Console.Error.WriteLine("Failed to translate. Response: {0}", translateResponseContent);
            }
        }
        catch (Exception ex)
        {
            Console.Error.WriteLine("Failed to translate. Exception: {0}", ex.Message);
        }
    }

    public static async Task<HttpResponseMessage> TranslateRequest(string url, string azureSubscriptionKey)
    {
        using (HttpClient client = new HttpClient())
        { 
            client.DefaultRequestHeaders.Add(OcpApimSubscriptionKeyHeader, azureSubscriptionKey);
            return await client.GetAsync(url);
        }
    }
}
}

Details about Deprecation: https://datamarket.azure.com/dataset/bing/microsofttranslatorspeech


Answer:

You could use the Microsoft Translator Text API via REST API.

Please refer to this official doc for more details.

Here, I offer snippet code of GetTranslations request with java code for your reference.

import org.apache.commons.io.IOUtils;

import javax.net.ssl.HttpsURLConnection;
import java.net.URL;
import java.net.URLEncoder;

public class Test1 {
    private static String key = "<your translator account key>";

    public static void main(String[] args) {
        try {
            // Get the access token
            // The key got from Azure portal, please see https://docs.microsoft.com/en-us/azure/cognitive-services/cognitive-services-apis-create-account
            String authenticationUrl = "https://api.cognitive.microsoft.com/sts/v1.0/issueToken";
            HttpsURLConnection authConn = (HttpsURLConnection) new URL(authenticationUrl).openConnection();
            authConn.setRequestMethod("POST");
            authConn.setDoOutput(true);
            authConn.setRequestProperty("Ocp-Apim-Subscription-Key", key);
            IOUtils.write("", authConn.getOutputStream(), "UTF-8");
            String token = IOUtils.toString(authConn.getInputStream(), "UTF-8");
            System.out.println(token);

//          Using the access token to build the appid for the request url
            String appId = URLEncoder.encode("Bearer " + token, "UTF-8");
            String text = URLEncoder.encode("Hello", "UTF-8");
            String from = "en";
            String to = "fr";
            String translatorTextApiUrl = String.format("https://api.microsofttranslator.com/v2/http.svc/GetTranslations?appid=%s&text=%s&from=%s&to=%s&maxTranslations=5", appId, text, from, to);
            HttpsURLConnection translateConn = (HttpsURLConnection) new URL(translatorTextApiUrl).openConnection();
            translateConn.setRequestMethod("POST");
            translateConn.setRequestProperty("Accept", "application/xml");
            translateConn.setRequestProperty("Content-Type", "text/xml");
            translateConn.setDoOutput(true);
            String TranslationOptions = "<TranslateOptions xmlns=\"http://schemas.datacontract.org/2004/07/Microsoft.MT.Web.Service.V2\">" +
                    "<Category>general</Category>" +
                    "<ContentType>text/plain</ContentType>" +
                    "<IncludeMultipleMTAlternatives>True</IncludeMultipleMTAlternatives>" +
                    "<ReservedFlags></ReservedFlags>" +
                    "<State>contact with each other</State>" +
                    "</TranslateOptions>";
            translateConn.setRequestProperty("TranslationOptions", TranslationOptions);
            IOUtils.write("", translateConn.getOutputStream(), "UTF-8");
            String resp = IOUtils.toString(translateConn.getInputStream(), "UTF-8");
            System.out.println(resp);
        } catch (Exception e) {
            e.printStackTrace();
        }


    }
}

Hope it helps you.

Question:

I am looking for something similar to this but using JAVA rest API calls. I want to get the list of all the resources (including virtual machines, storage disks, network devices etc) and their basic properties(like ip address, disk space etc) I have tried making API calls following this link.

When I make an http request to this url

"https://management.azure.com/subscriptions/"+subscriptionId+"/resourceGroups/"+resourceGroupName+"/providers/Microsoft.Compute/virtualMachines?api-version="+apiVersion

But I am getting a 401 error. Am I calling the right URL ? if not which URL I should be calling ?


Answer:

But I am getting a 401 error. Am I calling the right URL ? if not which URL I should be calling ?

You're calling the right URL however you're providing incorrect parameters to the API call. The link you mentioned is for making Azure Service Management API calls however what you need to dod is make Azure Resource Manager (ARM) API calls.

Like Azure Service Management API, ARM API requests need to be authenticated. In case of former, the requests are authenticated by using a management certificate. In case of latter, you would need to use a token that you get by authenticating the user against an Azure AD.

Please see this link for more details on authenticating/authorizing ARM API requests: https://azure.microsoft.com/en-us/documentation/articles/resource-manager-api-authentication/.

In order to list all resources in a resource group, you can definitely make use of ARM REST API. However now SDKs are available for you that you can consume directly. To learn more about these SDKs, please see this link: https://azure.microsoft.com/en-in/blog/azure-resource-manager-preview-sdks/.

Question:

I added all the jar files of application insight sdk for java in java web project and included the code for sending custom telemetry in servlet but when i try to run the servlet it shows classnotfound error for TelemetryConfiguration and TelemetryClient.


Answer:

Per my experience, I think you can try to check the jar files of Application Insight SDK for Java whether be added the Libraries of Java Build Path, please right click the prject name and select the Properties in the menu.

If using Maven project, you can see the jar files in the Maven Dependencies.

If using the normal Dynamic Web Project, you can see them in the Web App Libraries or a User Library with custom name.

Then you need to try to manually build the project, and run the servlet again.

Question:

I've been trying to send an image from my computer to this API but I only get the following error: {"error":{"code":"InvalidImageSize","message":"Image size is too small."}}

My code is the following. I have a PostRequestClass with this method:

public void sendImageRequest(String imagePath) {
    try {
        HttpClient httpClient = new DefaultHttpClient();
        File file = new File(imagePath);
        FileEntity reqEntity = new FileEntity(file, ContentType.APPLICATION_OCTET_STREAM);
        reqEntity.setChunked(false);
        HttpResponse response = httpClient.execute(request);
        HttpEntity entity = response.getEntity();
        if (entity != null) {
            this.responseResult = EntityUtils.toString(entity);
        }
    } catch(Exception e) {
        System.out.println(e.getMessage());
    }   
}

And on my Main is this one:

public class Test {
    public static void main(String[] args) throws URISyntaxException {
        PostRequest p = new PostRequest(
          "https://westcentralus.api.cognitive.microsoft.com/face/v1.0/detect?returnFaceAttributes=emotion"
        );
        p.addHeader("Content-Type", "application/octet-stream");
        p.addHeader("Ocp-Apim-Subscription-Key", "my-api-key");
        p.sendImageRequest("/Users/user/Desktop/image.jpg");
        System.out.println(p.getResponseResult());           
    }
}

Answer:

I solved it with the following code:

public void sendImageRequest(String imagePath) {
    try {
        HttpClient httpClient = new DefaultHttpClient();

        File file = new File(imagePath);
        FileInputStream fileInputStreamReader = new FileInputStream(file);
        byte[] bytes = new byte[(int)file.length()];
        fileInputStreamReader.read(bytes);            
        ByteArrayEntity reqEntity = new ByteArrayEntity(bytes, ContentType.APPLICATION_OCTET_STREAM);
        request.setEntity(reqEntity);

        HttpResponse response = httpClient.execute(request);
        HttpEntity entity = response.getEntity();
        if (entity != null) {
            this.responseResult = EntityUtils.toString(entity);
        }
    } catch(Exception e) {
        System.out.println(e.getMessage());
    }   
}

Question:

I am creating application where I want to store folder from local storage(from PC) to directory created under any share of azure. I am working under 'file' of azure's storage account.

Here is my code :

@Override
    public String uploadDirectory(JSONObject jsonInput) throws IOException {
        CloudFileClient fileClient = null;
        try{
        fileClient = FileClientProvider.getFileClientReference();
        String directoryLocation = jsonInput.get("directoryLocation").toString();
        File f = new File(directoryLocation);
        listFilesForFolder(f);

        CloudFileShare share = fileClient.getShareReference(f.getName().toLowerCase().replace(".", "").replace("_", ""));
        if (share.createIfNotExists()) {
            System.out.println("New share created");
        }
        CloudFileDirectory rootDir = share.getRootDirectoryReference();
        CloudFileDirectory sampleDir = rootDir.getDirectoryReference(f.getName().toLowerCase().replace(".", "").replace("_", ""));
        if (sampleDir.createIfNotExists()) {
            System.out.println("new directory created");
        } 
        for ( ListFileItem fileItem : rootDir.listFilesAndDirectories() ) {
            System.out.println(fileItem.getUri());
        }

        }catch(Exception e)
        {
            System.out.println("Exception "+e);
        }
        return "Check";
    } 

How can I store all folder 'f' and it's contents to directory 'sampleDir' ?


Answer:

You can use the following sample code to upload your local folder and its contents to Azure file storage in your application.

@Override
public String uploadDirectory(JSONObject jsonInput) throws IOException {
    CloudFileClient fileClient = null;
    try {
        fileClient = FileClientProvider.getFileClientReference();
        String directoryLocation = jsonInput.get("directoryLocation").toString();
        File f = new File(directoryLocation);

        CloudFileShare share = 
        fileClient.getShareReference(f.getName().toLowerCase().replace(".", "").replace("_", ""));
        if (share.createIfNotExists()) {
            System.out.println("New share created");
        }
        CloudFileDirectory rootDir = share.getRootDirectoryReference();

        listFilesAndUploadToCloud(f.getAbsolutePath(), rootDir);

    } catch(Exception e) {
        System.out.println("Exception " + e);
    }
    return "Check";
} 

public void listFilesAndUploadToCloud(String filePath, CloudFileDirectory storageDir) throws Exception {

    File f = new File(filePath);
    ArrayList<File> files = new ArrayList<File>(Arrays.asList(f.listFiles()));

    for (File file : files) {
        if (file.isFile()) {
            CloudFile cloudFile = storageDir.getFileReference(file.getName());
            cloudFile.uploadFromFile(file.getAbsolutePath());
        } else {
            CloudFileDirectory cloudDir = storageDir.getDirectoryReference(file.getName());
            if (cloudDir.createIfNotExists()) {
                listFilesAndUploadToCloud(file.getAbsolutePath(), cloudDir);
            }
        }
    }

}

Question:

I am trying to invoke the REST API to view the content of Azure Storage table. Hope I have properly formed Authorization header value and I am getting below error. Please correct me where I am missing in below request (From REST Client app).

{
  "method": "GET",
  "transformRequest": [
    null
  ],
  "transformResponse": [
    null
  ],
  "url": "https://#####.table.core.windows.net/testDB",
  "headers": {
    "x-ms-date": "Thu, 28 Jun 2018 08:39:05 GMT",
    "x-ms-version": "2018-06-28",
    "Accept": "application/json;odata=nometadata",
    "Authorization": "SharedKeyLite #####:########"
  },
  "data": "",
  "timeout": {}
}

And Here is my response Headers:

{
  "x-ms-request-id": "3fc23b14-2002-0037-04bc-0e9e56000000",
  "date": "Thu, 28 Jun 2018 08:46:39 GMT",
  "server": "Microsoft-HTTPAPI/2.0",
  "content-length": "371",
  "content-type": "application/xml",
  "status": 400
}

and Response Body

<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<error xmlns="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata">
  <code>InvalidHeaderValue</code>
  <message xml:lang="en-US">The value for one of the HTTP headers is not in the correct format.
RequestId:3fc23b14-2002-0037-04bc-0e9e56000000
Time:2018-06-28T08:46:40.1148690Z</message>
</error>

Here is the JAVA code, I used to generate SignatureString

    private void printHash()
    {
//        https://mytestaccount.table.core.windows.net/testDB: this is the url form Azure portal displaying next to table
        String secret = "I Updated my key here";
// Date for string to sign
        Calendar calendar = Calendar.getInstance();
        SimpleDateFormat sdf = new SimpleDateFormat("EEE, d MMM yyyy HH:mm:ss 'GMT'", Locale.US);
        sdf.setTimeZone(TimeZone.getTimeZone("GMT"));
        String date = sdf.format(calendar.getTime());
// canonicalizedResource, such as "/testaccount1/Tables"
        String canonicalizedResource = "/testDB";
        String stringToSign = date + "\n" + canonicalizedResource;
        System.out.println(stringToSign);
// HMAC-SHA@%^
        Mac sha256HMAC = null;
        try {
            sha256HMAC = Mac.getInstance("HmacSHA256");
            SecretKeySpec secretKey = new SecretKeySpec(secret.getBytes(), "HmacSHA256");
            sha256HMAC.init(secretKey);
            String hash = Base64.encodeToString(sha256HMAC.doFinal(stringToSign.getBytes()), Base64.DEFAULT);
            System.out.println(hash);
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (InvalidKeyException e) {
            e.printStackTrace();
        }
}

Answer:

Four points to fix:

  1. x-ms-version is not optional if you want get content as application/json;odata=nometadata. x-ms-version should be set explicitly to 2013-08-15 or later(The latest is 2018-03-28) to support this format. See Json format in table service.
  2. Date Format should be EEE, dd MMM yyyy HH:mm:ss 'GMT'. Two digits to express Day.
  3. canonicalizedResource should be storageAccountName\tableName like your code remark.
  4. To generate SecretKeySpec, SecretKeySpec secretKey = new SecretKeySpec(Base64.decode(secret), "HmacSHA256"); Because the secret is encoded as Base64.

Question:

I need to list all snapshots for each blob in Azure, using the Java SDK if possible or the Azure REST API otherwise. For both options, I know how to list all storage accounts, but I have not found a way to retrieve a list of snapshots associated with a single storage account.


Answer:

Acording to the javadocs of Azure Storage SDK for Java, using the method listBlobs(String prefix, boolean useFlatBlobListing, EnumSet<BlobListingDetails> listingDetails, BlobRequestOptions options, OperationContext opContext) with BlobListingDetails.SNAPSHOTS for a container to list all blobs which include snapshot blob to filter by the method isSnapshot().

Here is my sample code below.

String accountName = "<your-storage-account-name>";
String accountKey = "<your-storage-account-key>";
String storageConnectionString = "DefaultEndpointsProtocol=https;AccountName=%s;AccountKey=%s";
String connectionString = String.format(storageConnectionString, accountName, accountKey);
CloudStorageAccount account = CloudStorageAccount.parse(connectionString);
CloudBlobClient client = account.createCloudBlobClient();
// List all containers of a storage account
Iterable<CloudBlobContainer> containers = client.listContainers();
String prefix = null;
boolean useFlatBlobListing = true;
// Specify the blob list which include snapshot blob
EnumSet<BlobListingDetails> listingDetails = EnumSet.of(BlobListingDetails.SNAPSHOTS);
BlobRequestOptions options = null;
OperationContext opContext = null;
for (CloudBlobContainer container : containers) {
    Iterable<ListBlobItem> blobItems = container.listBlobs(prefix, useFlatBlobListing, listingDetails, options,
                    opContext);
    for (ListBlobItem blobItem : blobItems) {
        if (blobItem instanceof CloudBlob) {
            CloudBlob blob = (CloudBlob) blobItem;
            // Check a blob whether be a snapshot blob
            if (blob.isSnapshot()) {
                System.out.println(blobItem.getStorageUri());
            }
        }
    }
}   

If you want to use REST API for implementing this needs, the steps as below.

  1. Using List Containers for a storage account to list all containers.
  2. Using List Blobs with the url parameter include={snapshots} as the subsection Blob and Snapshot List of the reference said to list all blobs of a container which include snapshot blob, then to filter all snapshot blobs.

Question:

@azuresupport #azTechHelp Rest API : -https://management.azure.com/subscriptions/{subscriptionId}/resources?api-version=2018-02-01 giving me one of the DataDisk id as /subscriptions/{subscription-id}/resourceGroups/test/providers/Microsoft.Compute/disks/datadisk1

while Rest API : - https://management.azure.com/{id-of-that-vm-to-which-that-dataDisk is attached}?api-version=2018-10-01 giving me dataDisk id as : /subscriptions/{subscription-id}/resourceGroups/TEST/providers/Microsoft.Compute/disks/datadisk1.

Is this expected? why different resource group id?


Answer:

In Azure, the resource group name in the resource id is case insensitive, no need to care about it.

The resource id /subscriptions/{subscription-id}/resourceGroups/test/providers/Microsoft.Compute/disks/datadisk1 and /subscriptions/{subscription-id}/resourceGroups/TEST/providers/Microsoft.Compute/disks/datadisk1 are the same.

Refer to : Naming rules and restrictions

Question:

I'm trying to call the Microsoft Translator API from Java using the new Azure Cloud methods that were introduced in May 2017.

I had been using this API from Java very successfully before then, but now with this new change something seems to be broken. I see that something has changed with the authentication and it must be recoded.

I'm sure someone has a good working example of test code. Can anyone help out here?


Answer:

Please see my answers for other similar SO threads, which include the explaination for these changes and Java sample codes for new MS Translator API version, as below.

  1. Bing translator exception while integrating with java application
  2. MS Translator returns empty response when used with Azure token
  3. Microsoft Translator API Java, How to get client new ID with Azure

Hope it helps.

Question:

The following code uses com.google.code.gson.gson:2.8.5 and org.asynchttpclient.async-http-client:2.5.2 to send JSONs to Azure's Log Analytics. It worked fine until yesterday midnight, but then suddenly started returning HTTP 403 responses. What went wrong?

public class LogAnalyticsSender {

    private static final Charset    UTF8            = Charset.forName("UTF-8");
    private static final String     HMAC_SHA256_ALG = "HmacSHA256";

    static String createAuthorization(String workspaceId, String key, int contentLength, String rfc1123Date) {
        try {
            // Documentation: https://docs.microsoft.com/en-us/rest/api/loganalytics/create-request
            String signature = String.format("POST\n%d\napplication/json\nx-ms-date:%s\n/api/logs", contentLength, rfc1123Date);
            Mac mac = Mac.getInstance(HMAC_SHA256_ALG);
            mac.init(new SecretKeySpec(DatatypeConverter.parseBase64Binary(key), HMAC_SHA256_ALG));
            String hmac = DatatypeConverter.printBase64Binary(mac.doFinal(signature.getBytes(UTF8)));
            return String.format("SharedKey %s:%s", workspaceId, hmac);
        } catch (NoSuchAlgorithmException | InvalidKeyException e) {
            throw new RuntimeException(e);
        }
    }

    final SslEngineFactory          defaultSslEngineFactory = (configuration, peerHost, peerPort) -> {
                                                                try {
                                                                    SSLContext sslCtx = SSLContext.getDefault();
                                                                    SSLEngine sslEngine = sslCtx.createSSLEngine(peerHost, peerPort);
                                                                    sslEngine.setUseClientMode(true);
                                                                    return sslEngine;
                                                                } catch (NoSuchAlgorithmException e) {
                                                                    throw new RuntimeException(e);
                                                                }
                                                            };
    final String                    key;
    final String                    workspace;
    final Gson                      gson;
    final DefaultAsyncHttpClient    httpClient;

    public LogAnalyticsSender(String workspaceId, String base64Key, int maxConnections) {
        DefaultAsyncHttpClientConfig config = new DefaultAsyncHttpClientConfig.Builder().setMaxConnections(maxConnections)
                .setThreadPoolName("LogAnalyticsSender").setSslEngineFactory(this.defaultSslEngineFactory).build();
        this.key = base64Key;
        this.workspace = workspaceId;
        this.gson = new GsonBuilder().create();
        this.httpClient = new DefaultAsyncHttpClient(config);
    }

    public CompletableFuture<Response> sendPojo(Object o, String logType) {
        String json = this.gson.toJson(o);
        return sendRawJson(json, logType);
    }

    public CompletableFuture<Response> sendPojo(JsonElement element, String logType) {
        String json = this.gson.toJson(element);
        return sendRawJson(json, logType);
    }

    public CompletableFuture<Response> sendRawJson(String rawJson, String logType) {
        int bodyLength = rawJson.getBytes(UTF8).length;
        String nowRfc1123 = DateTimeFormatter.RFC_1123_DATE_TIME.format(ZonedDateTime.now(ZoneOffset.UTC));
        String createAuthorization = createAuthorization(this.workspace, this.key, bodyLength, nowRfc1123);
        return this.httpClient.preparePost("https://" + this.workspace + ".ods.opinsights.azure.com/api/logs?api-version=2016-04-01").setBody(rawJson)
                .addHeader("Authorization", createAuthorization).addHeader("Content-Type", "application/json").addHeader("Log-Type", logType)
                .addHeader("x-ms-date", nowRfc1123).execute().toCompletableFuture();
    }

    public void shutdown() {
        this.httpClient.close();
    }
}

Answer:

(answering my own question)

The issue occurred when the date switched from Jul 31 to Aug 1. It turns out that Java's DateTimeFormatter.RFC_1123_DATE_TIME writes the day-of-month as a single digit, and the Log Analytics API doesn't like that.

The solution was to replace the regular RFC 1123 DateTimeFormatter with a pattern that uses two digits:

DateTimeFormatter.ofPattern("EEE, dd MMM yyyy HH:mm:ss O")

Question:

I need to get the contents of files available in a File Share in Azure File Storage using REST API using JAVA. There are official documents available but I got confused as there is no clear explanation. So, if some one could provide a sample then it will be really helpful for me.


Answer:

I was getting problem in generating the Authentication String properly, and it was giving Error : 403, Message : Forbidden. But Using the below code I successfully managed to do that.

public class FileStorageServiceWithRest {
private static final String account = "<your_account_name>";
private static final String key = "<your_access_key>";

public static void main(String args[]) throws Exception{
    String urlString = "http://" + account + ".file.core.windows.net/myshare/<your_file_name>";
    HttpURLConnection connection = (HttpURLConnection)(new URL(urlString)).openConnection();
    getFileRequest(connection, account, key);
    connection.connect();
    System.out.println("Response message : "+connection.getResponseMessage());
    System.out.println("Response code : "+connection.getResponseCode());

    BufferedReader br = null;
    if(connection.getResponseCode() != 200){
        br = new BufferedReader(new InputStreamReader((connection.getErrorStream())));
    }else{
         br = new BufferedReader(new InputStreamReader((connection.getInputStream())));
    }
    System.out.println("Response body : "+br.readLine());
}

public static void getFileRequest(HttpURLConnection request, String account, String key) throws Exception{
    SimpleDateFormat fmt = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss");
    fmt.setTimeZone(TimeZone.getTimeZone("GMT"));
    String date = fmt.format(Calendar.getInstance().getTime()) + " GMT";
    String stringToSign =  "GET\n"
            + "\n" // content encoding
            + "\n" // content language
            + "\n" // content length
            + "\n" // content md5
            + "\n" // content type
            + "\n" // date
            + "\n" // if modified since
            + "\n" // if match
            + "\n" // if none match
            + "\n" // if unmodified since
            + "\n" // range
            + "x-ms-date:" + date + "\nx-ms-version:2014-02-14\n" //headers
            + "/"+account + request.getURL().getPath(); // resources
    System.out.println("stringToSign : "+stringToSign);
    String auth = getAuthenticationString(stringToSign);
    request.setRequestMethod("GET");
    request.setRequestProperty("x-ms-date", date);
    request.setRequestProperty("x-ms-version", "2014-02-14");
    request.setRequestProperty("Authorization", auth);
}

private static String getAuthenticationString(String stringToSign) throws Exception{
    Mac mac = Mac.getInstance("HmacSHA256");
    mac.init(new SecretKeySpec(Base64.decode(key), "HmacSHA256"));
    String authKey = new String(Base64.encode(mac.doFinal(stringToSign.getBytes("UTF-8"))));
    String auth = "SharedKey " + account + ":" + authKey;
    return auth;
}}

Question:

How can we create zone dns and records on azure server using Azure web services API with latest "MSAL" library not ADAL based? However dns libarary support https://github.com/Azure-Samples/dns-java-host-and-manage-your-domains does not mentioned any way to utilized using MSAL access token. e.g

    ApplicationTokenCredentials credentials = new ApplicationTokenCredentials(client, tenant, key, AzureEnvironment.AZURE);
azure = Azure.authenticate(credentials).withSubscription(subscriptionId);
ResourceGroup resourceGroup = azure.resourceGroups().define(rgName)
        .withRegion(Region.US_EAST2)
        .create();

System.out.println("Creating root DNS zone " + customDomainName + "...");
DnsZone rootDnsZone = azure.dnsZones().define(customDomainName)
        .withExistingResourceGroup(resourceGroup)
        .create();

But it is using with keys instead of access tokens provided by msal. this can be already achieved in old ways which is using ADAL internally by azure.


Answer:

If you want to use Azure java management SDK to manage Azure DNS with AD access token, please refer to the following code

a. create a service principal (I use Azure CLI to do that)

az login
az account set --subscription "<your subscription id>"
# the sp will have Azure Contributor role
az ad sp create-for-rbac -n "readMetric" 

  1. Code
 public void test() throws MalformedURLException, ExecutionException, InterruptedException {



        AzureTokenCredentials tokenCredentials = new AzureTokenCredentials(AzureEnvironment.AZURE,ADProperty.tenantId) {
            @Override
            public String getToken(String resource) throws IOException {
                String token =null;
                // use msal to get Azure AD access token
                ConfidentialClientApplication app = ConfidentialClientApplication.builder(
                        ADProperty.clientId,  // sp appid
                        ClientCredentialFactory.createFromSecret(ADProperty.clientKey)) // sp password
                        .authority(ADProperty.authority) // "https://login.microsoftonline.com/" + sp tenant id
                        .build();
                ClientCredentialParameters clientCredentialParam = ClientCredentialParameters.builder(
                        Collections.singleton("https://management.azure.com/.default"))
                        .build();
                CompletableFuture<IAuthenticationResult> future = app.acquireToken(clientCredentialParam);
                try {
                    token =future.get().accessToken();

                } catch (InterruptedException e) {
                    e.printStackTrace();
                } catch (ExecutionException e) {
                    e.printStackTrace();
                }
                return  token;
            }
        };


        Azure azure = Azure.authenticate(tokenCredentials)
                .withSubscription(ADProperty.subscriptionId); // sp subscription id
        DnsZone rootDnsZone = azure.dnsZones().define("mydevchat.com")
                .withExistingResourceGroup("jimtest")
                .create();
        System.out.println("create DNSZone " + rootDnsZone.name() + " successfully");
}

Question:

I want to get a Azure RateCard Json response via Billing REST Api. For this I use the following code in eclipse:

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;

import com.fasterxml.jackson.core.JsonFactory;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonToken;

public class RateCardRest {

public static String getAccessToken(String tenantId, String clientId, String clientSecret)
        throws MalformedURLException, IOException {
    String endpoint = String.format("https://login.microsoftonline.com/%s/oauth2/token", tenantId);
    String postBody = String.format("grant_type=client_credentials&client_id=%s&client_secret=%s&resource=%s",
            clientId, clientSecret, "https://management.azure.com/");
    HttpURLConnection conn = (HttpURLConnection) new URL(endpoint).openConnection();
    conn.setRequestMethod("POST");
    conn.addRequestProperty("Content-Type", "application/x-www-form-urlencoded");
    conn.setDoOutput(true);
    conn.getOutputStream().write(postBody.getBytes());
    conn.connect();
//      If you want to see the response content, please use the commented code below.
//      BufferedReader reader = new BufferedReader(new InputStreamReader(conn.getInputStream()));
//      StringBuilder builder = new StringBuilder();
//      String line = null;
//      while ((line = reader.readLine()) != null) {
//          builder.append(line);
//      }
//      reader.close();
//      System.out.println(builder.toString());
//      The output for access token is {"token_type":"Bearer","expires_in":"3600","ext_expires_in":"3600","expires_on":"1550660092","not_before":"1550656192","resource":"https://management.azure.com/","access_token":"eyJ0eXAiOiJKV1QiL...."}
    JsonFactory factory = new JsonFactory();
    JsonParser parser = factory.createParser(conn.getInputStream());
    String accessToken = null;
    while (parser.nextToken() != JsonToken.END_OBJECT) {
        String name = parser.getCurrentName();
        if ("access_token".equals(name)) {
            parser.nextToken();
            accessToken = parser.getText();
        }
    }
    return accessToken;
}

public static String getRateCard(String subscriptionId, String apiVersion, String offerId, String currency,
        String locale, String region, String accessToken) throws MalformedURLException, IOException {
    String endpoint = String.format(
            "https://management.azure.com/subscriptions/%s/providers/Microsoft.Commerce/RateCard?api-version=%s&$filter=OfferDurableId eq '%s' and Currency eq '%s' and Locale eq '%s' and RegionInfo eq '%s'",
            subscriptionId, apiVersion, offerId, currency, locale, region).replaceAll(" ", "%20");
    HttpURLConnection conn = (HttpURLConnection) new URL(endpoint).openConnection();
    conn.setRequestMethod("GET");
    conn.addRequestProperty("Authorization", "Bearer " + accessToken);
    conn.addRequestProperty("Content-Type", "application/json");
    conn.connect();
    BufferedReader reader = new BufferedReader(new InputStreamReader(conn.getInputStream()));
    StringBuilder builder = new StringBuilder();
    String line = null;
    while ((line = reader.readLine()) != null) {
        builder.append(line);
    }
    reader.close();
    return builder.toString();
}

public static void main(String[] args) throws MalformedURLException, IOException {
    String tenantId = "<your tenant id like xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxxx";
    String clientId = "<your client id registed in AAD like xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxxx";
    String clientSecret = "<your client secret key generated in AAD>";
    String accessToken = getAccessToken(tenantId, clientId, clientSecret);
    System.out.println(accessToken);
    String subscriptionId = "<your subscription id like xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxxx";
    String apiVersion = "2015-06-01-preview";
    String offerId = "<your offer id like XX-AZR-XXXXX";
    String currency = "USD";
    String locale = "en-US";
    String region = "US";
    String rateCardResp = getRateCard(subscriptionId, apiVersion, offerId, currency, locale, region, accessToken);
    System.out.println(rateCardResp);
}

 }

This causes the following error:

Exception in thread "main" java.io.IOException: Server returned HTTP response code: 401 for URL: https://login.microsoftonline.com/"myTenantID"/oauth2/token
    at sun.net.www.protocol.http.HttpURLConnection.getInputStream0(Unknown Source)
    at sun.net.www.protocol.http.HttpURLConnection.getInputStream(Unknown Source)
    at sun.net.www.protocol.https.HttpsURLConnectionImpl.getInputStream(Unknown Source)
    at com.nttdata.altemista.RateCardRest.getAccessToken(RateCardRest.java:38)
    at com.nttdata.altemista.RateCardRest.main(RateCardRest.java:74)

When I search the URL, I get the following message:

AADSTS900561: The endpoint only accepts POST, OPTIONS requests. Received a GET request.

Hopefully somebody can help me. Thanks in advanced!


Answer:

You need to UrlEncode your client secret key generated in AAD.

add

clientSecret=java.net.URLEncoder.encode(clientSecret,"UTF-8");

below to

String clientSecret = "<your client secret key generated in AAD>";

Question:

for my Java program I need an Azure pricelist. For this Azure has an API which you can use for a AzureRateCard (you can see this here: https://docs.microsoft.com/en-us/azure/cloud-solution-provider/integration/manage-billing/get-azure-prices). Unfortunately I never worked with an API and I don't know what to do with this informations.

I hope I find somebody who already worked with this API :D Thank you!


Answer:

I have a sample code to get Azure RateCard Json response via Billing REST API Get price and metadata information for resources used in an Azure subscription, not SDK for Java because I don't know where the SDK is. It works fine for me.

Here is my sample code.

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;

import com.fasterxml.jackson.core.JsonFactory;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonToken;

public class RateCardRest {

    public static String getAccessToken(String tenantId, String clientId, String clientSecret)
            throws MalformedURLException, IOException {
        String endpoint = String.format("https://login.microsoftonline.com/%s/oauth2/token", tenantId);
        String postBody = String.format("grant_type=client_credentials&client_id=%s&client_secret=%s&resource=%s",
                clientId, clientSecret, "https://management.azure.com/");
        HttpURLConnection conn = (HttpURLConnection) new URL(endpoint).openConnection();
        conn.setRequestMethod("POST");
        conn.addRequestProperty("Content-Type", "application/x-www-form-urlencoded");
        conn.setDoOutput(true);
        conn.getOutputStream().write(postBody.getBytes());
        conn.connect();
//      If you want to see the response content, please use the commented code below.
//      BufferedReader reader = new BufferedReader(new InputStreamReader(conn.getInputStream()));
//      StringBuilder builder = new StringBuilder();
//      String line = null;
//      while ((line = reader.readLine()) != null) {
//          builder.append(line);
//      }
//      reader.close();
//      System.out.println(builder.toString());
//      The output for access token is {"token_type":"Bearer","expires_in":"3600","ext_expires_in":"3600","expires_on":"1550660092","not_before":"1550656192","resource":"https://management.azure.com/","access_token":"eyJ0eXAiOiJKV1QiL...."}
        JsonFactory factory = new JsonFactory();
        JsonParser parser = factory.createParser(conn.getInputStream());
        String accessToken = null;
        while (parser.nextToken() != JsonToken.END_OBJECT) {
            String name = parser.getCurrentName();
            if ("access_token".equals(name)) {
                parser.nextToken();
                accessToken = parser.getText();
            }
        }
        return accessToken;
    }

    public static String getRateCard(String subscriptionId, String apiVersion, String offerId, String currency,
            String locale, String region, String accessToken) throws MalformedURLException, IOException {
        String endpoint = String.format(
                "https://management.azure.com/subscriptions/%s/providers/Microsoft.Commerce/RateCard?api-version=%s&$filter=OfferDurableId eq '%s' and Currency eq '%s' and Locale eq '%s' and RegionInfo eq '%s'",
                subscriptionId, apiVersion, offerId, currency, locale, region).replaceAll(" ", "%20");
        HttpURLConnection conn = (HttpURLConnection) new URL(endpoint).openConnection();
        conn.setRequestMethod("GET");
        conn.addRequestProperty("Authorization", "Bearer " + accessToken);
        conn.addRequestProperty("Content-Type", "application/json");
        conn.connect();
        BufferedReader reader = new BufferedReader(new InputStreamReader(conn.getInputStream()));
        StringBuilder builder = new StringBuilder();
        String line = null;
        while ((line = reader.readLine()) != null) {
            builder.append(line);
        }
        reader.close();
        return builder.toString();
    }

    public static void main(String[] args) throws MalformedURLException, IOException {
        String tenantId = "<your tenant id like xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxxx";
        String clientId = "<your client id registed in AAD like xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxxx";
        String clientSecret = "<your client secret key generated in AAD>";
        String accessToken = getAccessToken(tenantId, clientId, clientSecret);
        System.out.println(accessToken);
        String subscriptionId = "<your subscription id like xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxxx";
        String apiVersion = "2015-06-01-preview";
        String offerId = "<your offer id like XX-AZR-XXXXX";
        String currency = "USD";
        String locale = "en-US";
        String region = "US";
        String rateCardResp = getRateCard(subscriptionId, apiVersion, offerId, currency, locale, region, accessToken);
        System.out.println(rateCardResp);
    }

}

Note: The size of rateCardResp content is about 7 MB, so it will cost more time for downloading. Please store it to a file as data cache.

Note: for using the code below, you have to collect these parameters on Azure portal as below.

  1. Follow the section Register your client application with Azure AD of the offical document Azure REST API Reference to regist an application to get the clientId and clientSecret and grant the Owner role with its required permission to your application in Azure AD.

  1. Move to your subscription to get the subscription id & offer id.

If you have any concern, please feel free to let me know and I will update my post in detail.

Question:

How can I download pdf file from azure file storage. I know that there is a method downloadText() but it corrupts the pdf file. I have written code to download a uploaded file on azure and I have used downloadText() method but it's not working here.

However it downloads the pdf file but it says file corrupted or damaged.

Code sample which I am trying to do:

CloudFileDirectory sampleDir = rootDir.getDirectoryReference(path);
                        //Get a reference to the file you want to download
                        CloudFile file = sampleDir.getFileReference(fileStorageBean.getUniqueFileIdentifier());
                        //get file contents from azure file.
                        String fileContent = file.downloadText();
                        ESAPI.httpUtilities().setHeader(response, "Content-Disposition","attachment;");

                        response.setContentType(fileStorageBean.getMimeType());
                        response.setContentLength(file.getStreamWriteSizeInBytes());
                InputStream in = new ByteArrayInputStream(fileContent.getBytes());

Answer:

You could use file.downloadToFile method to download your pdf file from Azure File Storage to local.

Sample Code:

CloudStorageAccount storageAccount = CloudStorageAccount.parse(storageConnectionString);

CloudFileClient fileClient = storageAccount.createCloudFileClient();

CloudFileShare share = fileClient.getShareReference("test");

CloudFileDirectory rootDir = share.getRootDirectoryReference();

CloudFile file = rootDir.getFileReference("testFile.pdf");

File sourceFile = new File("E:\\AzureFile\\f.pdf");

file.downloadToFile(sourceFile.getAbsolutePath());

Or you could use file.download method to download file to a stream.

OutputStream outs=response.getOutputStream();

file.download(outs);

Hope it helps you.

Question:

I'm simply trying to run this sample code below:

import com.memetix.mst.language.Language;
import com.memetix.mst.translate.Translate;
public class Translator {
public static void main(String[] args) throws Exception {

    Translate.setClientId("ID GOES HERE");

    Translate.setClientSecret("SECRET GOES HERE");

    String translatedText = Translate.execute("Bonjour le monde", 
    Language.FRENCH, Language.ENGLISH);

    System.out.println(translatedText);
  }

}

and I'm getting the following Exception:

Exception in thread "main" java.lang.Exception: [microsoft-translator-api] Error retrieving translation : datamarket.accesscontrol.windows.net
at com.memetix.mst.MicrosoftTranslatorAPI.retrieveString(MicrosoftTranslatorAPI.java:202)
at com.memetix.mst.translate.Translate.execute(Translate.java:61)
at Translator.main(Translator.java:10)

Caused by: java.net.UnknownHostException: datamarket.accesscontrol.windows.net
at java.net.AbstractPlainSocketImpl.connect(Unknown Source)
at java.net.PlainSocketImpl.connect(Unknown Source)
at java.net.SocksSocketImpl.connect(Unknown Source)
at java.net.Socket.connect(Unknown Source)
at sun.security.ssl.SSLSocketImpl.connect(Unknown Source)
at sun.security.ssl.BaseSSLSocketImpl.connect(Unknown Source)
at sun.net.NetworkClient.doConnect(Unknown Source)
at sun.net.www.http.HttpClient.openServer(Unknown Source)
at sun.net.www.http.HttpClient.openServer(Unknown Source)
at sun.net.www.protocol.https.HttpsClient.<init>(Unknown Source)
at sun.net.www.protocol.https.HttpsClient.New(Unknown Source)
at sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.getNewHttpClient(Unknown Source)
at sun.net.www.protocol.http.HttpURLConnection.plainConnect0(Unknown Source)
at sun.net.www.protocol.http.HttpURLConnection.plainConnect(Unknown Source)
at sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.connect(Unknown Source)
at sun.net.www.protocol.http.HttpURLConnection.getOutputStream0(Unknown Source)
at sun.net.www.protocol.http.HttpURLConnection.getOutputStream(Unknown Source)
at sun.net.www.protocol.https.HttpsURLConnectionImpl.getOutputStream(Unknown Source)
at com.memetix.mst.MicrosoftTranslatorAPI.getToken(MicrosoftTranslatorAPI.java:133)
at com.memetix.mst.MicrosoftTranslatorAPI.retrieveResponse(MicrosoftTranslatorAPI.java:160)
at com.memetix.mst.MicrosoftTranslatorAPI.retrieveString(MicrosoftTranslatorAPI.java:199)
... 2 more

I know it seems like I'm not even trying to figure this out on my own but I'm a complete beginner and can't really understand the Exception trace at all by myself. I'm pretty sure I got the right client Secret. In my azure account I only see an application ID and an Object ID. I'm using the application ID as the client ID.

Does anyone have any ideas on what might be causing this? Any help is greatly appreciated.

Thank you!


Answer:

The third party Java wrapper boatmeme/microsoft-translator-java-api for MS Azure Translator API is too old & unavailable, because it wrappered the old Microsoft Translator - Text Translation which is old & unavailable now. There is a notice at the page top of the site Azure datamarket.

DataMarket and Data Services are being retired and will stop accepting new orders after 12/31/2016. Existing subscriptions will be retired and cancelled starting 3/31/2017. Please reach out to your service provider for options if you want to continue service.

For using the new Azure Translator API on Azure portal, you need to refer to the document Announcements: Microsoft Translator Moves to the Azure portal to know how to create the new one on Azure portal and use it via the new REST APIs. Meanwhile, just as reference, you can see my answer in Java for the other SO thread Microsoft Translator API Java, How to get client new ID with Azure.

Hope it helps.

Question:

I have a Java Application running on Tomcat. I want to get the details of all machines installed in Microsoft Azure portal by taking user's subscription details as input. Preferably a REST API. I am expecting response same like what we get in azure resource explorer. I made a request with this url "https://management.core.windows.net/"+subscriptionId+"/services/disks" following this method. It gives me result like this

<Disks xmlns="http://schemas.microsoft.com/windowsazure" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
   <Disk>
     <AttachedTo>
       <DeploymentName>TEST1</DeploymentName> 
       <HostedServiceName>TEST1</HostedServiceName>
       <RoleName>TEST1</RoleName>
       </AttachedTo><OS>Linux</OS>
       <Location>South Central US</Location>
       <LogicalDiskSizeInGB>30</LogicalDiskSizeInGB>   
       <MediaLink>link.vhd</MediaLink>
       <Name>TEST1-TEST1-0-20</Name>
       <SourceImageName>imageName</SourceImageName>

When I call the same method with

"https://management.azure.com/subscriptions/"+subscriptionid+"/providers/Microsoft.Compute/virtualMachines?api-version=2016-03-30" I am getting 401 error.

I even tried downloading the SDK , ListVirtualMachines.java is listing some 600 images, not the one under my subscription.

How Can I achieve it using JAVA REST API?


Answer:

Per my experience, this issue is due to the authentication method. I do all the requests that you have made and I get the same results with you. The 401 error code means "Unauthorized". Your authentication method is right for the old REST API request, but not for new. The new authentication is handled by Azure Active Directory(AD).

The followings may be useful for you.

  1. You could figure out Virtual Machines Rest API by this URL https://msdn.microsoft.com/en-us/library/mt163647.aspx.
  2. You could understand how to authenticate Azure Resource Manager Request by Azure Active Directory by this URL https://msdn.microsoft.com/en-us/library/dn790557.aspx.

Hope it helps. Any concerns, please feel free to let me know.

Question:

I'd like to get the customer search results from the custom API in the Azure Mobile Service. When I check the custome API using the Fiddler, it returns multiple search results. But my Invoke API only get the one result. How I can get the all results? My Azure-Mobile-Android SDK is 3.1.0

ListenableFuture<jsonelement> response = mClient.invokeApi("customersearch", request, JsonElement.class);

Futures.addCallback(response, new FutureCallback<jsonelement>() {
@Override
   public void onSuccess(JsonElement response) {
   Log.d("Debug","Response received!!! " + response.toString());

}

@Override
public void onFailure(Throwable throwable) {

   createAndShowDialog((Exception) throwable, "Wakeup Error");

}
});

Answer:

@KevinKo, I viewed the source code MobileServiceClient.java, then I found the function invokeApi return multiple entities or only one entity via the function Class.isArray() for the parameter final Class<E> clazz.

So please use JsonElement[].class instead of JsonElement.class to try again.

Question:

I'm testing the API using the Rest tool Chrome client to validate that the POST request I make is right in order to use it in a Java application. My request is in the following format:

POST /androidhub/publishers/android/messages?timeout=60&api-version=2014-01 
HTTP/1.1 HOST: androidhub-124.servicebus.windows.net 
authorization: SharedAccessSignature sr=androidhub-124.servicebus.windows.net&sig=mykeySAS=&se=146480684&skn=RootManageSharedAccessKey 
content-type: application/json, application/atom+xml;type=entry;charset=utf-8 
content-length: 45  { "DeviceId":"dev-01", "Temperature":"37.0" }

But I have the following error.

<Error>
<Code>401</Code>
<Detail>ExpiredToken: . TrackingId:2f6d284e-d7d2-4c9c-81a5-79c542ce8eee_G7, SystemTracker:androidhub-124.servicebus.windows.net:androidhub/publishers/android/messages, Timestamp:5/25/2016 7:13:33 PM</Detail>
</Error>

The key was regenerated before I used it. How I can I not get that error or make the request without putting the time of expiration of the key?

Thank you


Answer:

Per my experience, if the se value 146480684 was correctly post here, I think the issue was caused by the expiry time as the se key which is measured in seconds between the current time and midnight, January 1, 1970 UTC.

So the expiry time as the value of the se key should be got using Java code below.

long now = System.currentTimeMillis();
int expiry = (int)(now/1000) + 3600;

As reference, you can refer to the offical document for C#, please see https://msdn.microsoft.com/en-us/library/azure/mt652140.aspx.

Question:

Tring to use search api of bing azure marketpalce with java I have this code :

import org.apache.commons.codec.binary.Base64;
import org.apache.http.client.ResponseHandler;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.BasicResponseHandler;
import org.apache.http.impl.client.DefaultHttpClient;

public class BingAPI2 {
    public static void main(String[] args) throws Exception{
        BingAPI2 b = null;
        b.getBing();

    }

public static void getBing() throws Exception {

        HttpClient httpclient = new DefaultHttpClient();

        try {
            String accountKey = "myAccountKey=";
            byte[] accountKeyBytes = Base64.encodeBase64((":" + accountKey).getBytes());
            String accountKeyEnc = new String(accountKeyBytes);

            HttpGet httpget = new HttpGet("https://api.datamarket.azure.com/Data.ashx/Bing/Search/Web?$Query=%27Datamarket%27&$format=json");
            httpget.setHeader("Authorization", "Basic <"+accountKeyEnc+">");

            System.out.println("executing request " + httpget.getURI());

            // Create a response handler
            ResponseHandler<String> responseHandler = new BasicResponseHandler();
            String responseBody = httpclient.execute(httpget, responseHandler);
            System.out.println("----------------------------------------");
            System.out.println(responseBody);
            System.out.println("----------------------------------------");

        } finally {
            // When HttpClient instance is no longer needed,
            // shut down the connection manager to ensure
            // immediate deallocation of all system resources
            httpclient.getConnectionManager().shutdown();
        }
    }

}

I get an error :

Exception in thread "main" org.apache.http.client.HttpResponseException: The authorization type you provided is not supported. Only Basic and OAuth are supported


Answer:

first thing I see is that your line

byte[] accountKeyBytes = Base64.encodeBase64((":" + accountKey).getBytes());

should read :

byte[] accountKeyBytes = Base64.encodeBase64((accountKey + ":" + accountKey).getBytes());

also is there a reason you're using the apache libraries for this? the code I use for getting json objects from bing uses java.net and looks like this:

import java.net.URLConnection;
import java.net.URL;
import java.io.InputStreamReader;

class BingJson{

  JSONObject getJSONfromBing(String term){
  try{
    URLConnection c = new URL(term).openConnection();
    String key = (DatatypeConverter.printBase64Binary(("XXX" + ":" + "XXX").getBytes("UTF-8")));
    c.setRequestProperty("Authorization", String.format("Basic %s",key));
    c.connect();
    //etc.
  }
}

to build the json object I would say follow this code: Convert InputStream to JSONObject

Question:

I tried to setup a bing visual search API REST-Call from my java program. It works partly, i get an answer but not the answer i want. The goal is to do a POST REST-Call with an image and then get the information about the image as JSON.

I setup everything in the azure portal: firstly bing-search v7 with an resource group and a resource. After that i got my API-Key which seems to work. I also followed the quickstart guide https://docs.microsoft.com/en-us/azure/cognitive-services/bing-visual-search/quickstarts/java, but nonetheless i still don't get the expected response.

My code is exactly the same as in the quickstarts guide except for the image path.

I tested my API-Key here, which is a site for testing the API call, there is also an example of an Response i would expect, for example pages including that images and so on https://dev.cognitive.microsoft.com/docs/services/878c38e705b84442845e22c7bff8c9ac/operations/124f9090e80447b1985f881e.

My Response looks like this:

{
  "_type": "ImageKnowledge",
  "instrumentation": {
    "_type": "ResponseInstrumentation",
    "pingUrlBase": "https:\/\/www.bingapis.com\/api\/ping?IG=CB7D2E4D02B7453CA95C71AB55548271&CID=33CBAFA2BC1D6CF829C9A2DDBD516D7A&ID=",
    "pageLoadPingUrl": "https:\/\/www.bingapis.com\/api\/ping\/pageload?IG=CB7D2E4D02B7453CA95C71AB55548271&CID=33CBAFA2BC1D6CF829C9A2DDBD516D7A&Type=Event.CPT&DATA=0"
  },
  "tags": [{
    "displayName": "",
    "actions": [{
      "actionType": "MoreSizes"
    }, {
      "actionType": "ImageById"
    }]
  }],
  "image": {
    "imageInsightsToken": "bcid_COGc070ee574e85498c8b0b6cec557121cd*ccid_9619671840e76c8e5b5c33e002742ac7*thid_OSBI.COGc070ee574e85498c8b0b6cec557121cd"
  }
}

Answer:

I found an ugly workaround. I upload the image to a filehoster and get a URL. The URL returns a result via the Bing Vision API. I'm also using the Bing Java SDK for azure, which can be found on github.

Question:

I can create my VMSS with CLI with skutype : STANDARD_D2S_V3 but it's not possible on JAVA because i didn't have this type of sku. There are not V3 on Java but i use Java and i use virtualization so i need a skutype allowing virtualization. I didn't found an option for this.

I try to use another function but i didn't find any function, any type in this function allowing virtualization.

public static void creationVMSS(){
  VirtualMachineScaleSet vmss = azure.virtualMachineScaleSets()
    .define("name")
    .withregion(SOUTHEAST_ASIA)
    .withExistingResourceGroup(MyRG)
    .withSku(VirtualMachineScaleSetSkuTypes.STANDARD_..._v2
}

I want a type of VM allowing virtualization


Answer:

For your issue, there truly is no STANDARD_D2S_V3 SKU list in Java SDK. But it's actually supported in Azure for VMSS. So you can use the method that provides in the Azure Java SDK VirtualMachineScaleSetSkuTypes(String skuName, String skuTier) to create a custom SKU named STANDARD_D2S_V3, just like it shows in the Github:

public static final VirtualMachineScaleSetSkuTypes STANDARD_A0 = new VirtualMachineScaleSetSkuTypes("Standard_A0", "Standard");

Question:

That Might be a trivial question for many, but I am pretty new to azure environment and I am looking forward to access data underlying azure subscriptions and resource groups, so regarding that I Know I have to hit the REST endpoints in order to obtain result, but before that, in order to connect what is the API that I should look into, if any help could be provided in order to start writing code to obtain data from underlying Subscriptions. So can anyone help with the API I should look into, and how to start with them. Also if there are resources where I can look into in order to obtain a start working with Azure API, that would also be really helpful That will be a great help.


Answer:

I recommend you can use Azure SDK for Java to check whether meet your requirement. https://github.com/Azure/azure-sdk-for-java. Also, you can see this document about azure for java development(https://azure.microsoft.com/en-us/develop/java/ ).

Because the SDK encapsulates lots of REST endpoints and you can use it easily. Meanwhile, could you please describe the more details about your requirement about access what's data?

Question:

I'm trying to develop a stand alone java process which will look into a dedicated email inbox hosted by Azure Active Directory. The purpose is to retrieve a specific set of emails and perform operation. Azure AD is providing REST API to perform the same using Auth2.0 authorization. However, access token expires in 60 mins. or so. I want to use private/public key certification to perform the same. Is it achievable? If so, how to achieve the same.

Thanks in advance.


Answer:

There is a code sample for C# which seems to be similar with your needs, please see https://azure.microsoft.com/en-us/documentation/samples/active-directory-dotnet-daemon-certificate-credential/. I think you can try to refer to the sample above to perform the needs in Java.

Hope it helps. Any concern, please feel free to let me know.