Creating an index causes unauthorized error

Viewed 266

I'm working on a project using Go microservices connecting to an Azure CosmosDB. On the dev / stage environment I'm using the MongoDB API 3.6, for production 4.0.

The microservices creating indices on the collections. For the dev / stage environment all work's fine. But on production I'm retrieving the following error:

(Unauthorized) Error=13, Details='Response status code does not indicate success, Number of regions attempted:1

I've checked the connection string twice and currently there are no firewall rules for the production db.

My code looks familiar to this:

package repository

import (
    "go.mongodb.org/mongo-driver/mongo"
    "log"
)

func Collection(db *mongo.Database, c string, indices ...mongo.IndexModel) *mongo.Collection {
    col := db.Collection(c)

    if indices != nil {
        _, err := col.Indexes().CreateMany(ctx, indices)
        if err != nil {
            log.Fatal(err)
        }
    }

    return col
}

// .....

package service

import (
    "go.mongodb.org/mongo-driver/bson"
    "go.mongodb.org/mongo-driver/mongo"
    "go.mongodb.org/mongo-driver/mongo/options"
    "repository"
)

col := repository.Collection(db, "my_col", []mongo.IndexModel{
    {
        Keys:    bson.M{"uuid": 1},
        Options: options.Index().SetUnique(true),
    },
}...)

Anyone an idea what causes this error?

1 Answers

I've contacted the Microsoft support and this is what they replied:

This is a limitation of accounts with Point in Time Restore. The collection must be created with a unique index.

https://docs.microsoft.com/en-us/azure/cosmos-db/continuous-backup-restore-introduction

You can use a command such as this to create the collection with the unique index already present (from the Mongo shell, or Robo3T, or another client)

MongoDB extension commands to manage data in Azure Cosmos DB’s API for MongoDB | Microsoft Docs

For example:

db.runCommand({
  customAction: "CreateCollection",
  collection: "my_collection",
  shardKey: "my_shard_key",
  offerThroughput: 100,
  indexes: [{key: {_id: 1}, name: "_id_1"}, {key: {a: 1, b: 1}, name:"a_1_b_1", unique: true} ]
})

So now my code looks like this:

func Collection(db *mongo.Database, c string, indices []bson.M) *mongo.Collection {
    ctx, cls := context.WithTimeout(context.Background(), time.Second * 15)
    defer cls()

    if cursor, _ := db.ListCollectionNames(ctx, bson.M{"name": c}); len(cursor) < 1 {
        cmd := bson.D{{"customAction", "CreateCollection"}, {"collection", c}}
        if indices != nil {
            cmd = append(cmd, bson.E{Key: "indexes", Value: indices})
        }

        res := db.RunCommand(ctx, cmd)

        if res.Err() != nil {
            log.Fatal(res.Err())
        }
    }

    return db.Collection(c)
}
Related