Skip to content

Commit

Permalink
First commit
Browse files Browse the repository at this point in the history
  • Loading branch information
Mohammad Derakhshani committed Mar 22, 2017
1 parent d8e64de commit 75429d1
Show file tree
Hide file tree
Showing 38 changed files with 10,052 additions and 0 deletions.
97 changes: 97 additions & 0 deletions azure-documentdb-examples/pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>

<groupId>com.microsoft.azure</groupId>
<artifactId>azure-documentdb-examples</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>

<name>azure-documentdb-examples</name>
<url>http://azure.microsoft.com/en-us/services/documentdb/</url>
<licenses>
<license>
<name>MIT License</name>
<url>http://www.opensource.org/licenses/mit-license.php</url>
</license>
</licenses>

<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<slf4j.version>1.7.6</slf4j.version>
<log4j.version>1.2.17</log4j.version>
</properties>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.6.0</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-eclipse-plugin</artifactId>
<version>2.8</version>
<configuration>
<classpathContainers>
<classpathContainer>
org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8
</classpathContainer>
</classpathContainers>
</configuration>
</plugin>
</plugins>
</build>
<dependencies>
<dependency>
<groupId>com.microsoft.azure</groupId>
<artifactId>azure-documentdb-rx</artifactId>
<version>0.9.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>io.reactivex</groupId>
<artifactId>rxjava-guava</artifactId>
<version>1.0.3</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<version>1.10.19</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.hamcrest</groupId>
<artifactId>hamcrest-all</artifactId>
<version>1.3</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>${slf4j.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>${slf4j.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>${log4j.version}</version>
<scope>test</scope>
</dependency>
</dependencies>
</project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,256 @@
/**
* The MIT License (MIT)
* Copyright (c) 2016 Microsoft Corporation
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package com.microsoft.azure.documentdb.rx.examples;

import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.greaterThan;

import java.util.List;
import java.util.UUID;
import java.util.concurrent.CountDownLatch;

import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.google.common.util.concurrent.ListenableFuture;
import com.microsoft.azure.documentdb.ConnectionPolicy;
import com.microsoft.azure.documentdb.ConsistencyLevel;
import com.microsoft.azure.documentdb.Database;
import com.microsoft.azure.documentdb.DocumentClientException;
import com.microsoft.azure.documentdb.DocumentCollection;
import com.microsoft.azure.documentdb.FeedResponsePage;
import com.microsoft.azure.documentdb.ResourceResponse;
import com.microsoft.azure.documentdb.SqlParameter;
import com.microsoft.azure.documentdb.SqlParameterCollection;
import com.microsoft.azure.documentdb.SqlQuerySpec;
import com.microsoft.azure.documentdb.rx.AsyncDocumentClient;
import com.microsoft.azure.documentdb.rx.examples.TestConfigurations;

import rx.Observable;
import rx.functions.Action1;
import rx.observable.ListenableFutureObservable;

/**
* This integration test class demonstrates how to use Async API to create,
* delete, replace, and update.
*
* NOTE: you can use rxJava based async api with java8 lambda expression. Using of
* rxJava based async APIs with java8 lambda expressions is much prettier.
*
* You can also use the async API without java8 lambda expression support.
*
* For example
* <ul>
* <li>{@link #testCreateDatabase_Async()} demonstrates how to use async api with
* java8 lambda expression.
*
* <li>{@link #testCreateDatabase_Async_withoutLambda()} demonstrates how to the same
* thing without lambda expression.
* </ul>
*
* Also if you need to work with Future or ListenableFuture it is possible to transform
* an observable to ListenableFuture. Please see {@link #testTransformObservableToGoogleGuavaListenableFuture()}
*
*/
public class DatabaseAndCollectionCreationAsyncAPITest {

private static final Logger LOGGER = LoggerFactory.getLogger(DatabaseAndCollectionCreationAsyncAPITest.class);

private static final String DATABASE_ID = "async-test-db";
private DocumentCollection collectionDefinition;
private Database databaseDefinition;

private AsyncDocumentClient asyncClient;

@Before
public void setUp() throws DocumentClientException {

asyncClient = new AsyncDocumentClient.Builder()
.withServiceEndpoint(TestConfigurations.HOST)
.withMasterKey(TestConfigurations.MASTER_KEY)
.withConnectionPolicy(ConnectionPolicy.GetDefault())
.withConsistencyLevel(ConsistencyLevel.Session)
.build();

// Clean up before setting up
this.cleanUpGeneratedDatabases();

databaseDefinition = new Database();
databaseDefinition.setId(DATABASE_ID);

collectionDefinition = new DocumentCollection();
collectionDefinition.setId(UUID.randomUUID().toString());
}

@After
public void shutdown() throws DocumentClientException {
asyncClient.close();
}

@Test
public void testCreateDatabase_Async() throws Exception {

// create a database using async api
// this test uses java8 lambda expression see testCreateDatabase_Async_withoutLambda

Observable<ResourceResponse<Database>> createDatabaseObservable = asyncClient
.createDatabase(databaseDefinition, null);

final CountDownLatch doneLatch = new CountDownLatch(1);

createDatabaseObservable
.single() // we know there is only single result
.subscribe(
databaseResourceResponse -> {
System.out.println(databaseResourceResponse.getActivityId());
doneLatch.countDown();
},

error -> {
System.err.println("an error happened in database creation: actual cause: " + error.getMessage());
}
);

// wait till database creation completes
doneLatch.await();
}

@Test
public void testCreateDatabase_Async_withoutLambda() throws Exception {

// create a database using async api

Observable<ResourceResponse<Database>> createDatabaseObservable = asyncClient
.createDatabase(databaseDefinition, null);

final CountDownLatch successfulCompletionLatch = new CountDownLatch(1);
Action1<ResourceResponse<Database>> onDatabaseCreationAction = new Action1<ResourceResponse<Database>>() {

@Override
public void call(ResourceResponse<Database> resourceResponse) {
// Database is created
System.out.println(resourceResponse.getActivityId());
successfulCompletionLatch.countDown();
}
};

Action1<Throwable> onError = new Action1<Throwable>() {
@Override
public void call(Throwable error) {
System.err.println("an error happened in database creation: actual cause: " + error.getMessage());
}
};

createDatabaseObservable
.single() //we know there is only a single event
.subscribe(onDatabaseCreationAction, onError);

// wait till database creation completes
successfulCompletionLatch.await();
}


@Test
public void testCreateDatabase_toBlocking() throws DocumentClientException {

// create a database
// toBlocking() converts the observable to a blocking observable

Observable<ResourceResponse<Database>> createDatabaseObservable = asyncClient
.createDatabase(databaseDefinition, null);

// toBlocking() converts to a blocking observable
// single() gets the only result
createDatabaseObservable.toBlocking().single();
}

@Test
public void testCreateDatabase_toBlocking_DatabaseAlreadyExists_Fails() throws DocumentClientException {

// attempt to create a database which already exists
// - first create a database
// - Using the async api generate an async database creation observable
// - Converts the Observable to blocking using Observable.toBlocking() api
// - catch already exist failure (409)

asyncClient.createDatabase(databaseDefinition, null).toBlocking().single();

// Create the database for test.
Observable<ResourceResponse<Database>> databaseForTestObservable = asyncClient
.createDatabase(databaseDefinition, null);

try {
databaseForTestObservable
.toBlocking() //blocks
.single(); //gets the single result
assertThat("Should not reach here", false);
} catch (Exception e) {
assertThat("Database already exists.",
((DocumentClientException) e.getCause()).getStatusCode(), equalTo(409));
}
}

@Test
public void testTransformObservableToGoogleGuavaListenableFuture() throws Exception {

// You can convert an Observable to a ListenableFuture.
// ListenableFuture (part of google guava library) is a popular extension
// of Java's Future which allows registering listener callbacks:
// https://github.com/google/guava/wiki/ListenableFutureExplained

Observable<ResourceResponse<Database>> createDatabaseObservable = asyncClient.createDatabase(databaseDefinition, null);
ListenableFuture<ResourceResponse<Database>> future = ListenableFutureObservable.to(createDatabaseObservable);

ResourceResponse<Database> rrd = future.get();

assertThat(rrd.getRequestCharge(), greaterThan((double) 0));
System.out.print(rrd.getRequestCharge());
}

private void cleanUpGeneratedDatabases() throws DocumentClientException {
LOGGER.info("cleanup databases invoked");

String[] allDatabaseIds = { DATABASE_ID };

for (String id : allDatabaseIds) {
try {
List<FeedResponsePage<Database>> feedResponsePages = asyncClient
.queryDatabases(new SqlQuerySpec("SELECT * FROM root r WHERE r.id=@id",
new SqlParameterCollection(new SqlParameter("@id", id))), null).toList().toBlocking().single();


if (!feedResponsePages.get(0).getResults().isEmpty()) {
Database res = feedResponsePages.get(0).getResults().get(0);
LOGGER.info("deleting a database " + feedResponsePages.get(0));
asyncClient.deleteDatabase(res.getSelfLink(), null).toBlocking().single();
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
Loading

0 comments on commit 75429d1

Please sign in to comment.