Skip to content
This repository has been archived by the owner on Aug 29, 2024. It is now read-only.

Commit

Permalink
Http header size cosmosdb fix (#466)
Browse files Browse the repository at this point in the history
* Added auto create collection annotation field

* Fixed find by id APIs to return empty optional on not found
  • Loading branch information
kushagraThapar authored Dec 27, 2019
1 parent 672876f commit 6ea8892
Show file tree
Hide file tree
Showing 11 changed files with 84 additions and 13 deletions.
4 changes: 2 additions & 2 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@

<spring.springframework.version>5.2.0.RELEASE</spring.springframework.version>
<spring.data.version>2.2.0.RELEASE</spring.data.version>
<fasterxml.jackson.version>2.9.5</fasterxml.jackson.version>
<fasterxml.jackson.version>2.10.0</fasterxml.jackson.version>

<mockito.core.version>2.8.9</mockito.core.version>
<powermock.version>1.7.1</powermock.version>
Expand All @@ -58,7 +58,7 @@
<gson.version>2.8.4</gson.version>
<project.reactor.test.version>3.3.0.RELEASE</project.reactor.test.version>

<azure.cosmos.version>3.4.0</azure.cosmos.version>
<azure.cosmos.version>3.5.0</azure.cosmos.version>
<azure.test.resourcegroup>spring-data-cosmosdb-test</azure.test.resourcegroup>
<azure.test.dbname>testdb-${maven.build.timestamp}</azure.test.dbname>
<skip.integration.tests>true</skip.integration.tests>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ public class Constants {
public static final IndexingMode DEFAULT_INDEXINGPOLICY_MODE = IndexingMode.CONSISTENT;
public static final String DEFAULT_REPOSITORY_IMPLEMENT_POSTFIX = "Impl";
public static final int DEFAULT_TIME_TO_LIVE = -1; // Indicates never expire
public static final boolean DEFAULT_AUTO_CREATE_COLLECTION = true;

public static final String ID_PROPERTY_NAME = "id";

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import com.azure.data.cosmos.AccessCondition;
import com.azure.data.cosmos.AccessConditionType;
import com.azure.data.cosmos.CosmosClient;
import com.azure.data.cosmos.CosmosClientException;
import com.azure.data.cosmos.CosmosContainerProperties;
import com.azure.data.cosmos.CosmosContainerResponse;
import com.azure.data.cosmos.CosmosItemProperties;
Expand All @@ -18,6 +19,7 @@
import com.azure.data.cosmos.FeedResponse;
import com.azure.data.cosmos.PartitionKey;
import com.azure.data.cosmos.SqlQuerySpec;
import com.azure.data.cosmos.internal.HttpConstants;
import com.microsoft.azure.spring.data.cosmosdb.CosmosDbFactory;
import com.microsoft.azure.spring.data.cosmosdb.common.Memoizer;
import com.microsoft.azure.spring.data.cosmosdb.core.convert.MappingCosmosConverter;
Expand Down Expand Up @@ -147,7 +149,15 @@ public <T> T findById(Object id, Class<T> entityClass, PartitionKey partitionKey
return Mono.justOrEmpty(toDomainObject(entityClass,
cosmosItemResponse.properties()));
})
.onErrorResume(Mono::error)
.onErrorResume(e -> {
if (e instanceof CosmosClientException) {
final CosmosClientException cosmosClientException = (CosmosClientException) e;
if (cosmosClientException.statusCode() == HttpConstants.StatusCodes.NOTFOUND) {
return Mono.empty();
}
}
return Mono.error(e);
})
.block();

} catch (Exception e) {
Expand Down Expand Up @@ -179,7 +189,15 @@ public <T> T findById(String collectionName, Object id, Class<T> domainClass) {
.map(cosmosItem -> mappingCosmosConverter.read(domainClass, cosmosItem))
.findFirst());
})
.onErrorResume(Mono::error)
.onErrorResume(e -> {
if (e instanceof CosmosClientException) {
final CosmosClientException cosmosClientException = (CosmosClientException) e;
if (cosmosClientException.statusCode() == HttpConstants.StatusCodes.NOTFOUND) {
return Mono.empty();
}
}
return Mono.error(e);
})
.blockFirst();

} catch (Exception e) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,4 +21,6 @@
String ru() default Constants.DEFAULT_REQUEST_UNIT;

int timeToLive() default Constants.DEFAULT_TIME_TO_LIVE;

boolean autoCreateCollection() default Constants.DEFAULT_AUTO_CREATE_COLLECTION;
}
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ public class CosmosEntityInformation<T, ID> extends AbstractEntityInformation<T,
private Integer timeToLive;
private IndexingPolicy indexingPolicy;
private boolean isVersioned;
private boolean autoCreateCollection;

public CosmosEntityInformation(Class<T> domainClass) {
super(domainClass);
Expand All @@ -57,6 +58,7 @@ public CosmosEntityInformation(Class<T> domainClass) {
this.timeToLive = getTimeToLive(domainClass);
this.indexingPolicy = getIndexingPolicy(domainClass);
this.isVersioned = getIsVersioned(domainClass);
this.autoCreateCollection = getIsAutoCreateCollection(domainClass);
}

@SuppressWarnings("unchecked")
Expand Down Expand Up @@ -107,6 +109,10 @@ public String getPartitionKeyFieldValue(T entity) {
return partitionKeyField == null ? null : (String) ReflectionUtils.getField(partitionKeyField, entity);
}

public boolean isAutoCreateCollection() {
return autoCreateCollection;
}

private IndexingPolicy getIndexingPolicy(Class<?> domainClass) {
final IndexingPolicy policy = new IndexingPolicy();

Expand Down Expand Up @@ -255,5 +261,16 @@ private boolean getIsVersioned(Class<T> domainClass) {
&& findField.isAnnotationPresent(Version.class);
}

private boolean getIsAutoCreateCollection(Class<T> domainClass) {
final Document annotation = domainClass.getAnnotation(Document.class);

boolean autoCreateCollection = Constants.DEFAULT_AUTO_CREATE_COLLECTION;
if (annotation != null) {
autoCreateCollection = annotation.autoCreateCollection();
}

return autoCreateCollection;
}

}

Original file line number Diff line number Diff line change
Expand Up @@ -36,15 +36,19 @@ public SimpleCosmosRepository(CosmosEntityInformation<T, ID> metadata,
this.operation = applicationContext.getBean(CosmosOperations.class);
this.information = metadata;

createCollectionIfNotExists();
if (this.information.isAutoCreateCollection()) {
createCollectionIfNotExists();
}
}

public SimpleCosmosRepository(CosmosEntityInformation<T, ID> metadata,
CosmosOperations dbOperations) {
this.operation = dbOperations;
this.information = metadata;

createCollectionIfNotExists();
if (this.information.isAutoCreateCollection()) {
createCollectionIfNotExists();
}
}

private CosmosContainerProperties createCollectionIfNotExists() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,9 @@
TestConstants.EXCLUDEDPATH_0,
TestConstants.EXCLUDEDPATH_1,
})
@Document(collection = TestConstants.ROLE_COLLECTION_NAME, ru = TestConstants.REQUEST_UNIT_STRING)
@Document(collection = TestConstants.ROLE_COLLECTION_NAME,
ru = TestConstants.REQUEST_UNIT_STRING,
autoCreateCollection = false)
public class Role {
@Id
String id;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,15 @@ public void testIndexingPolicyAnnotation() {
TestUtils.testIndexingPolicyPathsEquals(policy.excludedPaths(), TestConstants.EXCLUDEDPATHS);
}

@Test
public void testAutoCreateCollectionAnnotation() {
final boolean autoCreateCollectionRoleInfo = roleInfo.isAutoCreateCollection();
final boolean autoCreateCollectionPersonInfo = personInfo.isAutoCreateCollection();

Assert.isTrue(!autoCreateCollectionRoleInfo, "autoCreateCollection in role should be false");
Assert.isTrue(autoCreateCollectionPersonInfo, "autoCreateCollection in person should be true");
}

@Test
public void testDefaultDocumentAnnotationTimeToLive() {
final Integer timeToLive = personInfo.getTimeToLive();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -166,12 +166,12 @@ public void canDeleteByPartitionedCity() {
assertThat(result.get(0).getCity()).isNotEqualTo(TEST_ADDRESS1_PARTITION1.getCity());
}

@Test(expected = CosmosDBAccessException.class)
@Test
public void testDeleteByIdAndPartitionKey() {
final long count = repository.count();
assertThat(count).isEqualTo(4);

final Optional<Address> addressById = repository.findById(TEST_ADDRESS1_PARTITION1.getPostalCode(),
Optional<Address> addressById = repository.findById(TEST_ADDRESS1_PARTITION1.getPostalCode(),
new PartitionKey(TEST_ADDRESS1_PARTITION1.getCity()));
assertThat(addressById.isPresent()).isTrue();

Expand All @@ -181,8 +181,10 @@ public void testDeleteByIdAndPartitionKey() {
final List<Address> result = TestUtils.toList(repository.findAll());
assertThat(result.size()).isEqualTo(3);

repository.findById(TEST_ADDRESS1_PARTITION1.getPostalCode(),
addressById = repository.findById(TEST_ADDRESS1_PARTITION1.getPostalCode(),
new PartitionKey(TEST_ADDRESS1_PARTITION1.getCity()));

assertThat(addressById.isPresent()).isFalse();
}

@Test
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -160,18 +160,25 @@ public void testCustomQuery() {
@Ignore // TODO(kuthapar): v3 doesn't support creation of items without id.
public void testNullIdContact() {
final Contact nullIdContact = new Contact(null, "testTitile");
final Contact savedContact = this.repository.save(nullIdContact);
final Contact savedContact = repository.save(nullIdContact);

Assert.assertNotNull(savedContact.getLogicId());
Assert.assertEquals(nullIdContact.getTitle(), savedContact.getTitle());
}

@Test
public void testFindById() {
final Optional<Contact> optional = this.repository.findById(TEST_CONTACT.getLogicId());
final Optional<Contact> optional = repository.findById(TEST_CONTACT.getLogicId());

Assert.assertTrue(optional.isPresent());
Assert.assertEquals(TEST_CONTACT, optional.get());
Assert.assertFalse(this.repository.findById("").isPresent());
Assert.assertFalse(repository.findById("").isPresent());
}

@Test
public void testFindByIdNotFound() {
final Optional<Contact> optional = repository.findById("unknown-id");

Assert.assertFalse(optional.isPresent());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -358,6 +358,15 @@ public void findByIdWithPartitionKey() {
Assert.assertEquals(project.get(), PROJECT_0);
}

@Test
public void findByIdWithPartitionKeyNotFound() {
final Optional<Project> project = repository.findById("unknown-id",
new PartitionKey("unknown-partition-key"));

Assert.assertFalse(project.isPresent());
}


@Test
public void testFindByIn() {
List<Project> projects = repository.findByCreatorIn(Collections.singleton(FAKE_CREATOR));
Expand Down

0 comments on commit 6ea8892

Please sign in to comment.