Support of Azure Cosmos DB for Spring Data
CAST supports Azure Cosmos DB via its com.castsoftware.nosqljava extension. Details about how this support is provided for Spring Data source code is discussed below.
Supported Client Libraries
Library | Version | Supported |
---|---|---|
Azure spring data cosmos | Up to: 3.10.0 | ✔️ |
Supported Operations
Operations | Method Supported |
---|---|
Insert | org.springframework.data.repository.CrudRepository.save org.springframework.data.repository.CrudRepository.saveAll org.springframework.data.repository.reactive.ReactiveCrudRepository.save org.springframework.data.repository.reactive.ReactiveCrudRepository.saveAll com.microsoft.azure.spring.data.cosmosdb.repository.DocumentDbRepository.save com.microsoft.azure.spring.data.cosmosdb.repository.DocumentDbRepository.saveAll com.microsoft.azure.spring.data.cosmosdb.repository.CosmosRepository.save com.microsoft.azure.spring.data.cosmosdb.repository.CosmosRepository.saveAll com.microsoft.azure.spring.data.cosmosdb.repository.ReactiveCosmosRepository.save com.microsoft.azure.spring.data.cosmosdb.repository.ReactiveCosmosRepository.saveAll com.azure.spring.data.cosmos.repository.CosmosRepository.save com.azure.spring.data.cosmos.repository.CosmosRepository.saveAll com.azure.spring.data.cosmos.repository.ReactiveCosmosRepository.save com.azure.spring.data.cosmos.repository.ReactiveCosmosRepository.saveAll com.microsoft.azure.spring.data.cosmosdb.core.CosmosTemplate.insert com.microsoft.azure.spring.data.cosmosdb.core.ReactiveCosmosTemplate.insert |
Select | org.springframework.data.repository.CrudRepository.existsById org.springframework.data.repository.CrudRepository.findAll org.springframework.data.repository.CrudRepository.findById org.springframework.data.repository.PagingAndSortingRepository.findAll org.springframework.data.repository.reactive.ReactiveCrudRepository.existsById org.springframework.data.repository.reactive.ReactiveCrudRepository.findAll org.springframework.data.repository.reactive.ReactiveCrudRepository.findAllById org.springframework.data.repository.reactive.ReactiveCrudRepository.findById org.springframework.data.repository.reactive.ReactiveSortingRepository.findAll com.azure.spring.data.cosmos.repository.CosmosRepository.findById com.azure.spring.data.cosmos.repository.CosmosRepository.findAll com.azure.spring.data.cosmos.repository.CosmosRepository.existsById com.azure.spring.data.cosmos.repository.CosmosRepository.count com.azure.spring.data.cosmos.repository.CosmosRepository.findAllById com.azure.spring.data.cosmos.repository.ReactiveCosmosRepository.findbyId com.azure.spring.data.cosmos.repository.ReactiveCosmosRepository.findAll com.azure.spring.data.cosmos.repository.ReactiveCosmosRepository.existsById com.azure.spring.data.cosmos.repository.ReactiveCosmosRepository.count com.azure.spring.data.cosmos.repository.ReactiveCosmosRepository.findAllById com.microsoft.azure.spring.data.cosmosdb.repository.CosmosRepository.findById com.microsoft.azure.spring.data.cosmosdb.repository.CosmosRepository.findAll com.microsoft.azure.spring.data.cosmosdb.repository.CosmosRepository.existsById com.microsoft.azure.spring.data.cosmosdb.repository.CosmosRepository.findAllById com.microsoft.azure.spring.data.cosmosdb.repository.CosmosRepository.count com.microsoft.azure.spring.data.cosmosdb.repository.DocumentDbRepository.findAll com.microsoft.azure.spring.data.cosmosdb.repository.DocumentDbRepository.existsById com.microsoft.azure.spring.data.cosmosdb.repository.DocumentDbRepository.findAllById com.microsoft.azure.spring.data.cosmosdb.repository.DocumentDbRepository.count com.microsoft.azure.spring.data.cosmosdb.repository.ReactiveSortingRepository.findAll com.microsoft.azure.spring.data.cosmosdb.core.CosmosOperations.findAll com.microsoft.azure.spring.data.cosmosdb.core.CosmosOperations.find com.microsoft.azure.spring.data.cosmosdb.core.CosmosOperations.findByIds com.microsoft.azure.spring.data.cosmosdb.core.CosmosOperations.exists com.microsoft.azure.spring.data.cosmosdb.core.CosmosOperations.count com.microsoft.azure.spring.data.cosmosdb.core.CosmosOperations.findById com.microsoft.azure.spring.data.cosmosdb.core.CosmosTemplate.findById com.microsoft.azure.spring.data.cosmosdb.core.ReactiveCosmosOperations.findAll com.microsoft.azure.spring.data.cosmosdb.core.ReactiveCosmosOperations.find com.microsoft.azure.spring.data.cosmosdb.core.ReactiveCosmosOperations.findByIds com.microsoft.azure.spring.data.cosmosdb.core.ReactiveCosmosOperations.exists com.microsoft.azure.spring.data.cosmosdb.core.ReactiveCosmosOperations.count com.microsoft.azure.spring.data.cosmosdb.core.ReactiveCosmosOperations.findById com.microsoft.azure.spring.data.cosmosdb.core.ReactiveCosmosTemplate.findById com.microsoft.azure.spring.data.cosmosdb.repository.ReactiveCosmosRepository.findById com.microsoft.azure.spring.data.cosmosdb.repository.ReactiveCosmosRepository.findAll com.microsoft.azure.spring.data.cosmosdb.repository.ReactiveCosmosRepository.count com.microsoft.azure.spring.data.cosmosdb.repository.ReactiveCosmosRepository.findAllById com.microsoft.azure.spring.data.cosmosdb.repository.ReactiveCosmosRepository.existsById |
Delete | org.springframework.data.repository.CrudRepository.delete org.springframework.data.repository.CrudRepository.deleteById org.springframework.data.repository.CrudRepository.deleteAllById org.springframework.data.repository.CrudRepository.deleteAll org.springframework.data.repository.reactive.ReactiveCrudRepository.delete org.springframework.data.repository.reactive.ReactiveCrudRepository.deleteAll org.springframework.data.repository.reactive.ReactiveCrudRepository.deleteAllById org.springframework.data.repository.reactive.ReactiveCrudRepository.deleteById com.azure.spring.data.cosmos.repository.CosmosRepository.deleteById com.azure.spring.data.cosmos.repository.CosmosRepository.delete com.azure.spring.data.cosmos.repository.CosmosRepository.deleteAll com.azure.spring.data.cosmos.repository.ReactiveCosmosRepository.deletebyId com.azure.spring.data.cosmos.repository.ReactiveCosmosRepository.deleteAll com.azure.spring.data.cosmos.repository.ReactiveCosmosRepository.delete com.microsoft.azure.spring.data.cosmosdb.core.CosmosOperations.deleteAll com.microsoft.azure.spring.data.cosmosdb.core.CosmosOperations.delete com.microsoft.azure.spring.data.cosmosdb.core.CosmosOperations.deleteCollection com.microsoft.azure.spring.data.cosmosdb.core.ReactiveCosmosOperations.deleteAll com.microsoft.azure.spring.data.cosmosdb.core.ReactiveCosmosOperations.delete com.microsoft.azure.spring.data.cosmosdb.core.ReactiveCosmosOperations.deleteCollection com.microsoft.azure.spring.data.cosmosdb.repository.ReactiveCosmosRepository.deleteById com.microsoft.azure.spring.data.cosmosdb.repository.ReactiveCosmosRepository.deleteAll com.microsoft.azure.spring.data.cosmosdb.repository.ReactiveCosmosRepository.delete com.microsoft.azure.spring.data.cosmosdb.repository.CosmosRepository.deleteById com.microsoft.azure.spring.data.cosmosdb.repository.DocumentDbRepository.deletebyId com.microsoft.azure.spring.data.cosmosdb.repository.DocumentDbRepository.deleteAll com.microsoft.azure.spring.data.cosmosdb.repository.DocumentDbRepository.delete |
Above mentioned methods are supported for both Synchronous and Asynchronous clients.
Objects
Icon | Description |
---|---|
Java CosmosDB Database | |
Java CosmosDB Collection | |
Java Unknown CosmosDB Database | |
Java Unknown CosmosDB Collection |
Links
Link type | Source and destination of link | Methods Supported |
---|---|---|
parentLink | Between CosmosDB Database object and CosmosDB Collection | - |
useInsertLink | Between the caller Java Method objects and CosmosDB Collection | save saveAll |
useSelectLink | Between the caller Java Method objects and CosmosDB Collection | existsById findById findAll findAllById count |
useDeleteLink | Between the caller Java Method objects and CosmosDB Collection | delete deleteAll deleteById deleteAllById |
What results can you expect?
Some example scenarios are shown below:
CosmosDB Database Connection from Properties File
application.properties
application.properties
azure.cosmosdb.uri=https://cosmoswithspring.documents.azure.com:443/
azure.cosmosdb.key=2VanbwRYNeJKCUjb5StsnBKaatDcKGRUckHnlSUVSJXifWL3exjwjP2o6rJpt8fY24MRmtnctzcE8hWAlBsRZw==
azure.cosmosdb.database=cosmoswithspring
Cosmos DB Client Creation
@Configuration
@EnableDocumentDbRepositories
public class AppConfig extends AbstractDocumentDbConfiguration {
@Value("${azure.documentdb.uri}")
private String uri;
@Value("${azure.documentdb.key}")
private String key;
@Value("${azure.documentdb.database}")
private String dbName;
public DocumentClient documentClient() {
return new DocumentClient(uri, key, ConnectionPolicy.GetDefault(), ConsistencyLevel.Session);
}
public String getDatabase() {
return dbName;
}
}
Select Operation
CreateDocument
@Autowired
private AlertRepository alertRepository;
@GetMapping("/all")
public Iterable getAllAlerts() {
if (StreamSupport.stream(alertRepository.findAll().spliterator(), false).count() > 0) {
return alertRepository.findAll();
} else {
throw new ValidationException("No records found.");
}
}
@GetMapping("/count")
public long countAlert() {
if (StreamSupport.stream(alertRepository.findAll().spliterator(), false).count() > 0) {
return alertRepository.count();
} else {
throw new ValidationException("No records found.");
}
}
Insert Operation
QueryDocuments
@PostMapping("/add")
public StatusMessage addAlert(@Valid @RequestBody Alert alert) {
Alert returnedAlert = alertRepository.save(alert);
if (returnedAlert.getAlertId().isEmpty()) {
throw new ValidationException("Error accessing Cosmos database.");
}
return new StatusMessage("200", "Alert Added");
}
Delete Operation
DeleteDocument
@GetMapping("/deleteall")
public StatusMessage deleteAllAlert() {
alertRepository.deleteAll();
return new StatusMessage("200", "Alert Deleted");
}
@DeleteMapping("/delete/{id}")
public StatusMessage deleteAlert(@PathVariable String id) throws NotFoundException {
//Optional<Alert> returnedAlert = alertRepository.findById(id);
if (!alertRepository.existsById(id)) {
throw new NotFoundException("No alert found with id: " + id);
}
alertRepository.deleteById(id);
return new StatusMessage("200", "alert deleted.");
}
Query Method Support
Repo with query method
@Repository
public interface AlertRepository extends CosmosRepository<Alert, String> {
// repo for alert
List<Alert> findById(String priority);
}
Controller
@GetMapping("find/{id}")
public Alert findAlert(@PathVariable String id) throws NotFoundException {
return alertRepository.findById(id).orElseThrow(
() -> new NotFoundException("No alert found with id: " + id)
);
}
Query Methods with @Query annotation
Repository with @query methods
@Repository
public interface AddressRepository extends CosmosRepository<Address, String> {
void deleteByPostalCodeAndCity(String postalCode, String city);
void deleteByCity(String city);
Iterable<Address> findByPostalCodeAndCity(String postalCode, String city);
Iterable<Address> findByCity(String city);
Iterable<Address> findByCityIn(List<String> cities);
Iterable<Address> findByPostalCode(String postalCode);
Iterable<Address> findByPostalCodeInAndCity(List<String> postalCodes, String city);
Iterable<Address> findByStreetOrCity(String street, String city);
@Query("select * from a where a.city = @city")
List<Address> annotatedFindListByCity(@Param("city") String city);
@Query("select * from a where a.city = @city")
Page<Address> annotatedFindByCity(@Param("city") String city, Pageable pageable);
}
public void testAnnotatedQuery() {
addressRepository.saveAll(Arrays.asList(Address.TEST_ADDRESS1_PARTITION1, Address.TEST_ADDRESS1_PARTITION2));
final List<Address> result = addressRepository.annotatedFindListByCity(Address.TEST_ADDRESS1_PARTITION1.getCity());
assertThat(result).isNotNull();
assertThat(result.size()).isEqualTo(1);
assertThat(result.get(0)).isEqualTo(Address.TEST_ADDRESS1_PARTITION1);
}
Asynchronous API
All corresponding methods are represented and results are very similar to its Synchronous counterpart. Async Client creation:
import com.microsoft.azure.spring.data.cosmosdb.repository.ReactiveCosmosRepository;
import info.hayslip.AlertHoarder.models.Alert;
import org.springframework.stereotype.Repository;
@Repository
public interface AlertReactRepository extends ReactiveCosmosRepository<Alert, String> {
// repo for alert
}
Known Limitations
- Database/Collection is created as unknown, if the name is not retrieved from the properties file or if the name could not be resolved.