Connecting Mongodb Atlas from Spring boot - mongodb

I i am new to the Mongodb with Spring Boot.And i have MONGODB ATLAS URI Connection String
mongodb://userName:<PASSWORD>#icarat-shard-00-00-7lopx.mongodb.net:27017,icarat-shard-00-01-7lopx.mongodb.net:27017,icarat-shard-00-02-7lopx.mongodb.net:27017/<DATABASE>?ssl=true&replicaSet=icarat-shard-0&authSource=admin
Then in my Spring Boot Application i set uri in application.properties like
spring.data.mongodb.uri: mongodb://userName:*****#icarat-shard-00-00-7lopx.mongodb.net:27017,icarat-shard-00-01-7lopx.mongodb.net:27017,icarat-shard-00-02-7lopx.mongodb.net:27017/vehicleplatform?ssl=true&replicaSet=icarat-shard-0&authSource=admin
This Repository intefface
public interface OrganizationRepository extends MongoRepository<Organization, String> {
}
when i Inject OrganizationRepository interface Its showing error like this
Failed to instantiate [com.mongodb.MongoClient]: Factory method 'mongo' threw exception; nested exception is java.lang.IllegalArgumentException: The connection string contains invalid user information. If the username or password contains a colon (:) or an at-sign (#) then it must be urlencoded
And this my Document class
#Document(collection="Organization")
public class Organization {
#Id
String id;
String orgName;
String orgAddress;
String pinCode;
//getter
//setter
}
This is my pom.xml
<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.icarat</groupId>
<artifactId>vehicleplatform</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>war</packaging>
<name>vehicleplatform</name>
<url>http://maven.apache.org</url>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.4.0.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-mongodb</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- mongodb java driver -->
<dependency>
<groupId>org.mongodb</groupId>
<artifactId>mongo-java-driver</artifactId>
<version>2.11.0</version>
</dependency>
<!-- swagger2 dependency -->
<dependency>
<groupId>io.springfox</groupId>
<artifactId> springfox-swagger2</artifactId>
<version>2.6.1</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>2.6.1</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
How we can fix this? Thanks

I find the actual problem. In my pevious Atlas password contain # (symbol) so its not supoort. I follwed document HERE
IMPORTANT If the password contains reserved URI characters, you must
escape the characters per RFC 2396. For example, if your password is
#bc123, you must escape the # character when specifying the password
in the connection string; i.e. %40bc123.

Failed to instantiate [com.mongodb.MongoClient]: Factory method
'mongo' threw exception; nested exception is
java.lang.IllegalArgumentException: The connection string contains
invalid user information. If the username or password contains a colon
(:) or an at-sign (#) then it must be urlencoded
The problem is crystal clear, if you are trying to connect with MongoDB Atlas with SpringBoot, your password must be URL Encoded which is more secure.
Here you can see how to URL encode password in MongoDB Atlas.

You can use the Mongodb SRV record to define all nodes associated to the cluster
# Mongo Connection
spring.data.mongodb.uri=mongodb+srv://myuser:mypassword#mycluster.azure.mongodb.net/mydb?retryWrites=true&w=majority
where
myuser: Mongodb user
mypassword: password of the user above
mycluster.azure.mongodb.net: host of your cluster
mydb: Mongodb database of your application
It is important to use the correct SRV assigned to you by Atlas (in your example you have combined all three shards), which you can get in the "Connect Your Application" screen, together with a code example (if needed).
Copy the connection string, replace password and dbname, set this in the SpringBoot property file.

I think best escape is to follow this pattern:
spring.data.mongodb.authentication-database= # Authentication database name.
spring.data.mongodb.database=db_name.
spring.data.mongodb.host=127.0.0.1
spring.data.mongodb.password=passwrd
spring.data.mongodb.port=27017
spring.data.mongodb.repositories.enabled=true # Enable Mongo repositories.
spring.data.mongodb.username= # Login user of the mongo server.

In my case I'm added {} surrounded with the documentDb url

I faced same issue when connecting to Mongo DB Atlas from spring boot:
'If the username or password contains a colon (:) or an at-sign (#) then it must be urlencoded'
This occurs if the password contains above mentioned special characters,
I was able to solve the issue by using the encoded password.
Go to https://www.urlencoder.io/ -> type the password to be encoded, Example: 'sample#password' , encoded string will be 'sample%40password'. Now use this in your connection uri by replacing the password
the password value will look something like
mongodb://userName:sample%40password#icarat-shard-00-00-7lopx.mongodb.net:27017,icarat-shard-00-01-7lopx.mongodb.net:27017,icarat-shard-00-02-7lopx.mongodb.net:27017/testdb?ssl=true&replicaSet=icarat-shard-0&authSource=admin

Related

The background display of the startup project is as follows

Spring integrates jwt to realize login.
pom.xml configuration
<!--security-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<!--JWT-->
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt</artifactId>
<version>0.9.0</version>
</dependency>
<dependency>
<groupId>org.jetbrains</groupId>
<artifactId>annotations</artifactId>
<version>RELEASE</version>
<scope>compile</scope>
</dependency>
</dependencies>
application.yml configuration
logging:
level:
com.xxxx.server.mapper: debug
jwt:
tokenHeader: Authorization
secret: yeb-secret
expiration: 604800
tokenHead: Bearer
Running the project background prompts the following information.
Description:
Failed to bind properties under 'logging.level.jwt.tokenheader' to org.springframework.boot.logging.LogLevel:
Property: logging.level.jwt.tokenheader
Value: "Authorization"
Origin: class path resource [config/application.yml] - 52:20
Reason: failed to convert java.lang.String to org.springframework.boot.logging.LogLevel (caused by java.lang.IllegalArgumentException: No enum constant org.springframework.boot.logging.LogLevel.Authorization)
Why it can't works?
thanks!!

Getting Error when trying to connect AWS Aurora Postgre cluster from spring boot app

I am trying to connect to AWS Aurora (Postgre) cluster from spring boot app using following properties
spring.datasource.driver.class.name = org.postgre.jdbc.Driver
spring.datasource.url=jdbc:postgresql://a2-xxxxx.cluster-xxxxxxxxxx.us-east-1.rds.amazonaws.com:5432
spring.datasource.username=username
spring.datasource.password=password
but I am getting following error -
*Caused by: java.lang.RuntimeException: Driver org.postgresql.Driver claims to not accept jdbcUrl, jdbc:postgresql://a2-xxxxx.cluster-xxxxxxxxxx.us-east-1.rds.amazonaws.com:5432
at com.zaxxer.hikari.util.DriverDataSource.<init>(DriverDataSource.java:110) ~[HikariCP-4.0.3.jar:na]
at com.zaxxer.hikari.pool.PoolBase.initializeDataSource(PoolBase.java:331) ~[HikariCP-4.0.3.jar:na]
at com.zaxxer.hikari.pool.PoolBase.<init>(PoolBase.java:114) ~[HikariCP-4.0.3.jar:na]*
Following are my maven pom.xml contents -
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jdbc</artifactId>
</dependency>
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
</dependency>
You should read the jdbc documentation.
If the host is specified, the url needs a / at the end. If the database you are connecting to has a different name than the user, you also have to put the name of the database after the /. Even if they are the same, it's a good idea to include the db name because that default behavior is a bit confusing.

Failed connection when trying for Heroku PostgreSQL with Spring

I am trying to set up a Spring Boot application. Currently I am working in a local environment and I have a Heroku PostgreSQL db. When I start my application it starts with error:
HikariPool-1 - Exception during pool initialization.
org.postgresql.util.PSQLException: El intento de conexión falló.
...
Caused by: java.net.UnknownHostException: #host
...
HHH000342: Could not obtain connection to query metadata
Where I have added the correct hostname and hideen it for security. I know this hostname is right since I've managed to connect using an Express app.
My POM.xml has the following dependencies:}
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
And my application.properties file is:
spring.datasource.url=jdbc:postgresql://#host:5432/dal2fiqv9or5eg?user=----&password=----&sslmode=require
spring.datasource.username=----
spring.datasource.password=----
spring.datasource.driver-class-name=org.postgresql.Driver
spring.jpa-hibernate.ddl-auto=create-drop
spring.jpa.show=true
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.PostgreSQLDialect
spring.jpa.properties.hibernate.format_sql=true
Whre once again I hid the host, username and pwd.
After this the application starts.
The spring.datasource.url property in your application.properties seems to be incorrect.
This file has worked for me:
#postgres parameters
spring.datasource.url=jdbc:postgresql://<host>:<port>/<database>
spring.datasource.username=<user>
spring.datasource.password=<password>
spring.jpa.show-sql=true
## Hibernate Properties
# The SQL dialect makes Hibernate generate better SQL for the chosen database
spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.PostgreSQLDialect
# Hibernate ddl auto (create, create-drop, validate, update)
spring.jpa.hibernate.ddl-auto = update
logging.level.org.springframework=TRACE
logging.level.org.hibernate.type=TRACE
server.port=${PORT:8080}
The values for port, host, database, user, and password can be derived from the HerokuPostgres addon you add to your Heroku app
Do not add # or any special symobols. Simply replace the values with the values you see in Heroku.
eg: spring.datasource.url=jdbc:postgresql://myhostname:5432/mydbname

MongoTemplate.getCollectionNames and MongoTemplate,collectionExists method throws StringIndexOutOfBoundsException when connected to Azure Cosmos DB

I am trying to get the list of collections on a database. My application uses spring-boot 2.4.1 and Azure Cosmos DB. Below is the code block.
String uri= "mongodb://<username>:<password>#<hostname.documents.azure.com>:<port>/?ssl=true";
String dbName= "databaseName";
MongoClient mongoClient = MongoClients.create(uri);
SimpleMongoClientDatabaseFactory mongoDbFactory =
new SimpleMongoClientDatabaseFactory(mongoClient, dbName);
MongoTemplate mongoTemplate = new MongoTemplate(mongoDbFactory);
System.out.println(mongoTemplate.getCollectionNames());
The code throws a very strange StringIndexOutOfBoundsException.
Stacktrace:
Exception in thread "main" java.lang.StringIndexOutOfBoundsException: String index out of range: -4
at java.lang.String.substring(String.java:1931)
at com.mongodb.internal.operation.ListCollectionsOperation.projectFromFullNamespaceToCollectionName(ListCollectionsOperation.java:512)
at com.mongodb.internal.operation.ListCollectionsOperation.access$1500(ListCollectionsOperation.java:86)
at com.mongodb.internal.operation.ListCollectionsOperation$ProjectingBatchCursor.next(ListCollectionsOperation.java:418)
at com.mongodb.client.internal.MongoBatchCursorAdapter.next(MongoBatchCursorAdapter.java:64)
at com.mongodb.client.internal.MongoMappingCursor.next(MongoMappingCursor.java:48)
at org.springframework.data.mongodb.core.MongoTemplate.lambda$getCollectionNames$28(MongoTemplate.java:2314)
at org.springframework.data.mongodb.core.MongoTemplate.execute(MongoTemplate.java:535)
at org.springframework.data.mongodb.core.MongoTemplate.getCollectionNames(MongoTemplate.java:2312)
at TestApp.main(TestApp.java:20)
When I am connecting to a mongo instance that is running on my local with the connection string "mongodb://localhost:27017" the above code works fine.
And my relevant part of the pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<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>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.4.1</version>
</parent>
<groupId>org.example</groupId>
<artifactId>test-mongo</artifactId>
<version>1.0-SNAPSHOT</version>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-mongodb</artifactId>
</dependency>
</dependencies>
</project>
Any thoughts about this error?
Are you sure your connection uri correctness?
i cant see password part your uri
Add the password section uri like this
String uri= "mongodb://<username>:<password>#...

Restlet client resource "not modified" condition

I've got a Restlet based application, and I'm trying to use Restlet client resources to test certain parts of it.
Since upgrading from Restlet 2.2.3 to 2.3.4, my ETag verification tests have started failing. Here's how I was adding the header in the old version:
Series<Header> headers = (Series<Header>) currentClientResource.getRequest().getAttributes().get("org.restlet.http.headers");
if (headers == null) {
headers = new Series<Header>(Header.class);
}
headers.add("If-None-Match", "\"" + eTag + "\"");
currentClientResource.getRequestAttributes().put("org.restlet.http.headers", headers);
Then when calling represent() again on the wrapped clientResource I was getting a 304 Not Modified response (which is what I want).
In 2.3.4 this started returning a 200 OK instead, and I noticed a log message about not setting the If-None-Match header directly.
Instead I'm now trying this:
currentClientResource.getRequest().getConditions().getNoneMatch().add(new Tag(eTag));
However this is still giving me a 200 OK. If I do the request manually through a REST client I can get a 304 Not Modified, so the server is still doing the right behavior. What do I need to do in the tests to see what I want to see?
I made a try and it works for me with version 2.3.4 of Restlet.
Here is what I did:
The Maven dependencies for my test
<project>
<modelVersion>4.0.0</modelVersion>
(...)
<properties>
<java-version>1.7</java-version>
<restlet-version>2.3.4</restlet-version>
</properties>
<dependencies>
<dependency>
<groupId>org.restlet.jse</groupId>
<artifactId>org.restlet</artifactId>
<version>${restlet-version}</version>
</dependency>
<dependency>
<groupId>org.restlet.jse</groupId>
<artifactId>org.restlet.ext.jetty</artifactId>
<version>${restlet-version}</version>
</dependency>
<dependency>
<groupId>org.restlet.jse</groupId>
<artifactId>org.restlet.ext.jackson</artifactId>
<version>${restlet-version}</version>
</dependency>
<dependency>
<groupId>org.restlet.jse</groupId>
<artifactId>org.restlet.ext.crypto</artifactId>
<version>${restlet-version}</version>
</dependency>
</dependencies>
<repositories>
<repository>
<id>maven-restlet</id>
<name>Public online Restlet repository</name>
<url>http://maven.restlet.com</url>
</repository>
</repositories>
</project>
A server resource that sets the etag on the returned representation:
public class ETagServerResource extends ServerResource {
#Get
public Representation test() {
String test = "test";
String md5 = DigestUtils.toMd5(test);
StringRepresentation repr = new StringRepresentation(test);
repr.setTag(new Tag(md5));
return repr;
}
}
The client that makes two calls: a first one without the etag and a second one with the etag that should return a 304 status code.
// First call
ClientResource cr
= new ClientResource("http://localhost:8182/test");
Representation repr = cr.get();
Tag tag = repr.getTag();
System.out.println(">> cr = "+cr); // Status code: 200
// Second call
cr.getRequest().getConditions().getNoneMatch().add(tag);
cr.get();
System.out.println(">> cr = "+cr); // Status code: 304
I don't know what you use within the server resource. Feel free to tell me.
Hope it helps you,
Thierry