blog.broncotoxique.com

Just another geek website

Spring-Framework, JavaMelody and MongoTemplate

Let say you use Spring-Framework (without Spring-Boot), MongoTemplate and JavaMelody in the same app. I guess you will need to see the mongo request statistics in the Melody dashboard, like you see the SQL statistics.

First you might have followed the JavaMelody documentation to setup Melody into you app.

Let say you create your MongoTemplate Bean like that :

@Bean
public MongoTemplate template() {
  return new MongoTemplate(...);
}

If you wanna have the same type of bean creation with JavaMelody monitoring, you can do it like that following.

First you will need to Override the org.springframework.data.mongodb.MongoDatabaseFactory :

public class JavaMelodyMongoClientDatabaseFactory extends SimpleMongoClientDatabaseFactory {

  public JavaMelodyMongoClientDatabaseFactory(MongoClient mongoClient, String databaseName) {
    super(mongoClient, databaseName);
  }

  @Override
  public MongoDatabase getMongoDatabase() throws DataAccessException {
    MongoDatabase db = getMongoDatabase(getDefaultDatabaseName());
    return MongoWrapper.createDatabaseProxy(db); // JavaMelody Monitoring
  }
}

Then you modify your app configuration to wrap the mongo connection before creating the MongoTemplate :

@Bean
public MongoTemplate template() {
  String dbName = "dbName"; // Name of the DB linked to the Template
  return buildTemplate(dbName);
}

private MongoTemplate buildTemplate(String dbName) {
  MongoClient client = getMongoClient();
  JavaMelodyMongoClientDatabaseFactory dbf = new JavaMelodyMongoClientDatabaseFactory(client, dbName);
  return new MongoTemplate(dbf);
}

private MongoClient getMongoClient() {
  MongoCredential credential = MongoCredential.createScramSha256Credential(user, source, pass);
  ConnectionString uri = new ConnectionString("mongodb://[HOST]:[PORT]");
  MongoClientSettings settings = MongoClientSettings.builder().credential(credential).applyConnectionString(uri).build();
  return MongoClients.create(settings);
}

Posted

in

, ,

by

Comments

2 responses to “Spring-Framework, JavaMelody and MongoTemplate”

  1. emeric Avatar
    emeric

    Hello
    If you have created and declared your org.springframework.data.mongodb.MongoDatabaseFactory (or SimpleMongoClientDatabaseFactory) as a method with the @Bean annotation in your application, then net.bull.javamelody.SpringMongoDbFactoryBeanPostProcessor should automatically wrap the MongoDatabaseFactory and its MongoDatabase using net.bull.javamelody.MongoWrapper.createDatabaseProxy(db). See https://github.com/javamelody/javamelody/blob/master/javamelody-core/src/main/java/net/bull/javamelody/SpringMongoDbFactoryBeanPostProcessor.java
    Note that the SpringMongoDbFactoryBeanPostProcessor is automatically configured when using javamelody-spring-boot-starter or javamelody-spring-boot4-starter.

    In your case, you have a dbName when creating the template, but you can still have @Bean for each MongoDatabaseFactory and MongoTemplate you create.

    Then all the above is not supposed to be needed.
    That means that the following should be enough to have the mongodatabase monitored:

    private MongoClient getMongoClient() {
    MongoCredential credential = MongoCredential.createScramSha256Credential(user, source, pass);
    ConnectionString uri = new ConnectionString(“mongodb://[HOST]:[PORT]”);
    MongoClientSettings settings = MongoClientSettings.builder().credential(credential).applyConnectionString(uri).build();
    return MongoClients.create(settings);
    }

    // SpringMongoDbFactoryBeanPostProcessor will post-process the factory bean to create a javamelody proxy of the factory
    @Bean
    public MongoDatabaseFactory mongoDatabaseFactory() {
    MongoClient client = getMongoClient();
    String dbName = “dbName”; // Name of the DB linked to the Factory
    return new SimpleMongoClientDatabaseFactory(client, dbName);
    }

    // inject MongoDatabaseFactory as an interface in this method and not the class SimpleMongoClientDatabaseFactory which can’t be the javamelody proxy
    @Bean
    public MongoTemplate template(MongoDatabaseFactory mongoDatabaseFactory) {
    return new MongoTemplate(mongoDatabaseFactory);
    }

    Emeric from JavaMelody

    1. zorglube Avatar

      First of all, thank you Emeric for tacking time to write a long an detailed response.

      I don’t work on this project anymore, still I remember reading the net.bull.javamelody.SpringMongoDbFactoryBeanPostProcessor and don’t really understating why the MongoTemplate wasn’t processed and wraped into a JavaMelody proxy. That’s why I writed the code you saw in the post.

      Maybe it’s related to the fact in my situation I don’t use Spring-Boot, only Spring-Framework.

Leave a Reply to emeric Cancel reply

Your email address will not be published. Required fields are marked *