Connection to Azure Cosmos DB

Hi all,

I have been trying to connect and interact with a Cosmos DB instance on Azure to log sensor values, and I did struggle a bit, so thought the outcome may be interesting to others. This is just a snippet of the code, but may save you some time, especially around the authentication and building of the request.

Cheers
Pedro

// this function encrypts a message using SHA-256 and a provided key. The key is Base64 encoded as provided by Azure
private String encrypt(String secret, String message) {

    byte[] secretByteArray =secret.decodeBase64(); //decode secret to byte array

    Mac sha256_HMAC = Mac.getInstance("HmacSHA256");
    SecretKeySpec secret_key = new SecretKeySpec(secretByteArray, "HmacSHA256");
    sha256_HMAC.init(secret_key);

    byte[] hash = sha256_HMAC.doFinal(message.getBytes()); // generate hash

    return hash.encodeBase64().toString();

}

// this function inserts an entry in a collection in Cosmos DB, using a timestamp as id and partition key
private CosmosDBInsertAvg(String tstamp, BigDecimal avgVal) {

// generate request time stamp
java.text.SimpleDateFormat rfcFormat = new java.text.SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss zzz");
rfcFormat?.setTimeZone(TimeZone.getTimeZone("GMT"));
String rfcDate=rfcFormat.format(new Date());

// generate request text - this must match the URL and HTTP request type		
String text = "post"+"\n"; // http request type
text+= "docs"+"\n"; // resource type
text+= "dbs/*#DATABASE_NAME#*/colls/*#CONTAINER_NAME#*"+"\n"; // resource path
text+= rfcDate.toLowerCase()+"\n"; // request date time
text+= "\n";

String key = "*#MASTER KEY#*"; // enter the primary key from my Cosmos DB

String auth = java.net.URLEncoder.encode("type=master&ver=1.0&sig=" + encrypt(key,text));

// POST
def methods= [
'req':
[
uri: 'https://#YOUR URI#.documents.azure.com',
path: 'dbs/#DATABASE_NAME#/colls/#CONTAINER_NAME#/docs', // must match the request text used for authorization
body: [id: tstamp, value: avgVal], // in my case i am just logging one value for each timestamp, you can create your own documents
requestContentType: "application/json",
headers: [Authorization: auth, Accept: "application/json", "x-ms-version": "2018-12-31", "x-ms-date": rfcDate, "x-ms-documentdb-is-upsert": "true", "x-ms-documentdb-partitionkey": "["${tstamp}"]"]
]
]

def request=methods.getAt('req')

log.trace "${request}"

try {httpPost(request) {resp -> parseResponse(resp)}}
catch (Exception e) {log.debug("___exception: " + e)}

}