microsoft / spring-data-cosmosdb

Access data with Azure Cosmos DB
MIT License
93 stars 68 forks source link

Unknown protocol: MongoDB #478

Closed rmeyer20 closed 4 years ago

rmeyer20 commented 4 years ago

[UPDATE] I have now tried simply adding my Azure properties to your sample application and am still getting the error. As such, is this project completely broken in its current state? Can someone else try it and confirm?

[ORIGINAL] I have followed the example code closely. Unfortunately when I run my Spring Boot application I get the following error:

Caused by: org.springframework.beans.BeanInstantiationException: Failed to instantiate [com.microsoft.azure.spring.data.cosmosdb.core.CosmosTemplate]: Factory method 'cosmosTemplate' threw exception; nested exception is java.lang.IllegalArgumentException: java.net.MalformedURLException: unknown protocol: mongodb
    at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:185) ~[spring-beans-5.2.0.RELEASE.jar:5.2.0.RELEASE]
    at org.springframework.beans.factory.support.ConstructorResolver.instantiate(ConstructorResolver.java:640) ~[spring-beans-5.2.0.RELEASE.jar:5.2.0.RELEASE]
    ... 59 common frames omitted
Caused by: java.lang.IllegalArgumentException: java.net.MalformedURLException: unknown protocol: mongodb
    at com.azure.data.cosmos.internal.GlobalEndpointManager.<init>(GlobalEndpointManager.java:70) ~[azure-cosmos-3.6.0.jar:na]
    at com.azure.data.cosmos.internal.RxDocumentClientImpl.<init>(RxDocumentClientImpl.java:223) ~[azure-cosmos-3.6.0.jar:na]
    at com.azure.data.cosmos.internal.RxDocumentClientImpl.<init>(RxDocumentClientImpl.java:135) ~[azure-cosmos-3.6.0.jar:na]
    at com.azure.data.cosmos.internal.RxDocumentClientImpl.<init>(RxDocumentClientImpl.java:124) ~[azure-cosmos-3.6.0.jar:na]
    at com.azure.data.cosmos.internal.AsyncDocumentClient$Builder.build(AsyncDocumentClient.java:177) ~[azure-cosmos-3.6.0.jar:na]
    at com.azure.data.cosmos.CosmosClient.<init>(CosmosClient.java:54) ~[azure-cosmos-3.6.0.jar:na]
...
Caused by: java.net.MalformedURLException: unknown protocol: mongodb
    at java.net.URL.<init>(URL.java:600) ~[na:1.8.0_111]
    at java.net.URL.<init>(URL.java:490) ~[na:1.8.0_111]
    at java.net.URL.<init>(URL.java:439) ~[na:1.8.0_111]
    at java.net.URI.toURL(URI.java:1089) ~[na:1.8.0_111]
    at com.azure.data.cosmos.internal.GlobalEndpointManager.<init>(GlobalEndpointManager.java:57) ~[azure-cosmos-3.6.0.jar:na]
    ... 79 common frames omitted

I've delved into it a bit and it seems to stem from the fact that when it calls getServiceEndpoint().getURL(), there are no handlers for the MongoDB protocol. This is an incredibly simple setup using:

@Configuration
@EnableCosmosRepositories(basePackageClasses={MyRepository.class})
public class CosmosConfig extends AbstractCosmosConfiguration {

    @Value("${azure.cosmosdb.uri}")
    private String uri;

    @Value("${azure.cosmosdb.key}")
    private String key;

    @Value("${azure.cosmosdb.database}")
    private String dbName;

    @Bean
    public CosmosDBConfig getConfig() {
        CosmosKeyCredential cosmosKeyCredential = new CosmosKeyCredential(key);
        return CosmosDBConfig.builder(uri, cosmosKeyCredential,
                dbName).build();
    }
}

The URI is the connection string I've got from Azure e.g.

mongodb://account:key@url:port/?ssl=true&replicaSet=globaldb

This same URI works with MongoRepository and Spring Data setup, but unfortunately due to incompatibilities with regards to shard keys and CosmoDB, II've opted to use this library. I've made sure I'm using the same versions as the example. As one last thing, here are the dependencies:

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.2.0.RELEASE</version>
    </parent>

   ...

    <dependencies>
        <!-- Spring Dependencies -->
        <dependency>
            <groupId>com.microsoft.azure</groupId>
            <artifactId>spring-data-cosmosdb</artifactId>
            <version>2.2.2</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.data</groupId>
            <artifactId>spring-data-jpa</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-autoconfigure</artifactId>
        </dependency>

I have raised this as an issue rather than a question as I haven't done anything beyond what the example project does which can only mean there's something not quite right. I've tried using other builds (other than 2.2.2) but it gives the same result. The only version that doesn't error and successfully connects to CosmoDB is 2.1.x (and below). Unfortunately that errors with a "Sql is not supported on this account" when trying to post documents. As an FYI, I'm using MacOSX though I doubt this would affect things.

rmeyer20 commented 4 years ago

Ok, this issue has been resolved. Although this isn't made clear since all the other documentation points you to using the connection string, there's a separate URI listed under Azure (beginning https://). When I replaced it with that, it now gets passed that stage and fails with Caused by: com.azure.data.cosmos.CosmosClientException: Sql api is not supported for this database account. I will therefore close this issue.