Azure Cosmos DB-错误的请求-http:400 [英] Azure Cosmos DB - bad request - http:400

查看:47
本文介绍了Azure Cosmos DB-错误的请求-http:400的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

问候我的同伴开发人员,

Greetings my fellow developers,

已经3天,我一直无法连接到Cosmos DB.

It is already 3 days I'm struggling with a connection to the Cosmos DB without success.

我正在使用翻新作为我的REST客户端,并使用GsonConverterFactory进行序列化/反序列化.

I'm using retrofit as my REST client and GsonConverterFactory for serialization/deserialization.

当前状态是我从Cosmos DB REST API获得HTTP:400(错误请求).我尝试采用此SO答案

Current status is that I get HTTP:400 (bad request) from Cosmos DB REST API. I have tried to adopt the authentication header generation from this SO answer

这是我的代码(此单元测试可在您的开发环境中运行.请参见gradle.build行以在本文的底部运行它):

So here is my code (this unit test is runnable from your development environment. please see gradle.build lines to run it in the bottom of this post):

@RunWith(AndroidJUnit4.class)
@MediumTest
public class AzureDbConnectionTests {
    public static final int COSMOS_PORT_NUM = 443;
    public static final String COSMOS_DB_URL = "https://mazedb.documents.azure.com";
    public static final String CONNECTION_STR = 
            COSMOS_DB_URL + ":" + COSMOS_PORT_NUM;
    public static final String PRIMARY_KEY = 
"<Private Key>";

    // Entity to serialize into Cosmos DB
    public static class Building {
        public Building() {}

        private String mName;
        private String mAddress;
        private String id;
    }

    public interface FirstAzureService {
        @POST("/dbs/mazedb/colls/buildings/docs")
        Call<Building> addDocument(
            @Header("authorization") String authorization, 
            @Header("x-ms-date") String date, 
            @Body Building building);
    }

    @Test
    public void serverConnectionTest() throws Exception {
        String headerDate = getDateString();

        Building building = new Building();
        building.mName = "UUID";
        building.id = UUID.randomUUID().toString();

        Retrofit retrofit = new Retrofit.Builder().baseUrl(CONNECTION_STR)
            .addConverterFactory(GsonConverterFactory.create()).build();

        FirstAzureService azureService = retrofit.create(FirstAzureService.class);

        Call<Building> buildingCall = azureService.addDocument(
            generateAuthHeader("post", "docs", "dbs/mazedb/colls/buildings",
            headerDate, PRIMARY_KEY), headerDate, building);

        Response<Building> response = buildingCall.execute();
        Log.d("AzureDbConnectionTest", "HTTP status code: " + response.code());
        Log.d("AzureDbConnectionTest", "HTTP message: " + response.message());
        Log.d("AzureDbConnectionTest", headerDate);
        assertTrue(response.isSuccessful());
    }

    private String generateAuthHeader(String verb, String resourceType, String resourceId, String headerDate, String masterKeyBase64) throws Exception
    {
        //Decode the master key, and setup the MAC object for signing.
        byte[] masterKeyBytes = Base64.decode(PRIMARY_KEY, Base64.NO_WRAP);
        Mac mac = Mac.getInstance("HMACSHA256");
        mac.init(new SecretKeySpec(masterKeyBytes, "HMACSHA256"));

        //Build the unsigned auth string.
        String stringToSign = verb.toLowerCase() + "\n"
                + resourceType.toLowerCase() + "\n"
                + resourceId.toLowerCase() + "\n"
                + headerDate.toLowerCase() + "\n"
                + "\n";

        //Sign and encode the auth string.
        String signature = Base64.encodeToString(
            mac.doFinal(stringToSign.toLowerCase().getBytes("UTF8")), Base64.NO_WRAP);

        //Generate the auth header.
        String authHeader = 
            URLEncoder.encode("type=master&ver=1.0&sig=" + signature, "UTF8");

        return authHeader;
    }

    @NonNull
    public static String getDateString() {
        SimpleDateFormat formatter = 
            new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss 'GMT'", Locale.US);
        formatter.setTimeZone(TimeZone.getTimeZone("GMT"));
        return formatter.format(new Date()).toLowerCase();
    }
}

API是SQL API.数据库数据显示在Azure仪表板上: 数据库结构

The API is SQL API. The DB data as appears on Azure Dashboard: db structure

我还试图为Android找到一些可用的Cosmos DB客户端,以节省时间进行身份验证和其他工作.但是只能找到以下内容: https://github.com/Azure/Azure.Android .这正是我在寻找的东西,但是它仍在开发中,并且缺少MongoDB API(我想使用MongoDB API来进行更轻松的切换).

I have also tried to find some available Cosmos DB client for android to save time on fiddling with the authentication and the rest. But could find only this: https://github.com/Azure/Azure.Android. Which is exactly what I'm looking for but it is still under development and lacks MongoDB API (I thought to use MongoDB API for easier switch if it will come).

非常感谢您的帮助!我对此感到非常厌倦.

Many thanks for any help! I'm so tired of this.

P.S.可以找到在官方网站上.从那里开始,代码为400的原因是:

P.S. List of HTTP Status Codes for Azure Cosmos DB could be found on official website. From there reasons for code 400 are:

  • 请求正文中的JSON,SQL或JavaScript无效.
  • 此外,当资源的POST或PUT主体中不存在或未设置资源的必需属性时,也可以返回400.
  • 当GET操作的一致性级别被该帐户的一组更强的一致性所取代时,也会返回
  • 400.
  • 当需要x-ms-documentdb-partitionkey的请求中不包含
  • 400时,也会返回
  • .
  • The JSON, SQL, or JavaScript in the request body is invalid.
  • In addition, a 400 can also be returned when the required properties of a resource are not present or set in the body of the POST or PUT on the resource.
  • 400 is also returned when the consistent level for a GET operation is overridden by a stronger consistency from the one set for the account.
  • 400 is also returned when a request that requires an x-ms-documentdb-partitionkey does not include it.

我认为最可能的是错误的JSON,但是在另一个单元测试中序列化了相同的对象之后,我发现它确定: {"id":"cceb3f5d-8d9c-44cd-85ee-599cd2f58783","mName":"UUID"}

I think most probable is wrong JSON, but after serialization of the same object in another unit test I find it OK: {"id":"cceb3f5d-8d9c-44cd-85ee-599cd2f58783","mName":"UUID"}

最诚挚的问候,格雷格.

Kindest regards, Greg.

build.gradle来运行它:

dependencies {
    androidTestCompile "junit:junit:4.12"
    androidTestCompile "com.android.support:support-annotations:25.3.1"
    androidTestCompile "com.android.support.test:runner:0.5"
    androidTestCompile "com.android.support.test:rules:0.5"
    androidTestCompile "com.google.code.gson:gson:2.8.2"
    androidTestCompile "com.squareup.retrofit2:retrofit:2.4.0"
    androidTestCompile "com.squareup.retrofit2:converter-gson:2.4.0"
}

推荐答案

generateAuthHeader方法中,您提供dbs/mazedb/colls/buildings作为String resourceId作为集合ID. 这是错误的.

At the generateAuthHeader method you are providing dbs/mazedb/colls/buildings as the String resourceId which is the collection id. This is wrong.

您应该将其更改为buildings.

这篇关于Azure Cosmos DB-错误的请求-http:400的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆