Mongo client {Mongo-Java-driver} creation hangs duration . No exception thrown - java

I have a cron-job running at a Linux machine running after every 5 minutes. The job executes a Java class.
private MongoClient createConnection(int retry,List<ServerAddress> host){
try {
System.out.println("Retrying----------"+retry);
MongoClient client = new MongoClient(host, MongoClientOptions.builder()
.connectionsPerHost(10)
.threadsAllowedToBlockForConnectionMultiplier(5)
.connectTimeout(5000).writeConcern(WriteConcern.NORMAL).build());
client.getDB("admin").command("ping").throwOnError();
retry = 0;
return client;
} catch (Exception e) {
retry++;
if (retry < retryLimit) {
createConnection(retry,host);
} else {
System.out.println("Connection could not be established to host-"+host);
}
return null;
}
}
retry is the integer value denoting how many times client creation can be tried in case host is unreachable.
The host list that i am passing is -
public static List<ServerAddress> HOST_SCRIPT = new ArrayList<ServerAddress>() {
private static final long serialVersionUID = 1L;
{
try {
add(new ServerAddress("PrimaryHost23", 27017));
} catch (UnknownHostException e) {
e.printStackTrace();
}
}
};
Code is Stuck when i MongoClient is being created. It does not happen always. Code works fine and NEVER hangs when i run on my local machine. There is no exception thrown.
I recently upgraded Linux machine OS (from CentOS 5 to CentOS 6). Can this be responsible for this because this script was working fine earlier.
Please help.
Regards,
Vibhav

The thing what you can do is you can throw mongo exception try out that of mongo client is stuck you will get to know try out this https://api.mongodb.org/java/2.6/com/mongodb/MongoException.html

Yes of course, actually i was creating crawler in java which fetch all the links of any particular website and validate the css and html structure Using the Jsoup and jcabi api but when i used to store links to the database it was not throwing any exception and even not storing the data also. so i did this
catch (MongoException e){
System.err.print(e.getClass().getName()+": "+e.getMessage());
}

Have you checked the compatibility like of jar that you have uploaded for your project like before it was like Mongo mongo = new Mongo(host,port); but That is deprecated. Try to check that and even your MongoDb jar.

Related

how can i handle multiple server MongoDB

Hi all i am new to spring maven project, and i am using MongoDB. I want to use two tomcats/ MongoDB both of theri IP address are different. when first DB is down i need to connect with second one how it is possible
I am using following code
public boolean mongoRunningAt(String uri) {
try {
Mongo mongo = new Mongo(new MongoURI(uri));
try {
Socket socket = mongo.getMongoOptions().socketFactory.createSocket();
socket.connect(mongo.getAddress().getSocketAddress());
socket.close();
} catch (IOException ex) {
mongo = new Mongo(new MongoURI(uri_second));
Socket socket = mongo.getMongoOptions().socketFactory.createSocket();
socket.connect(mongo.getAddress().getSocketAddress());
socket.close();
//return false;
}
mongo.close();
return true;
} catch (UnknownHostException e) {
return false;
}
}
Using this code i tried with first one successfully connected, now stoped first DB now restarted server it is connected with second db.
But if i didn't restart server it is always pointing to First only... how should i work on this
Thanks in advance
You deployed 2 servers, are they in a replica set. If not you can follow the link.
When they are already in a replica set you can use a connectionstring containing the 2 servers.
Like this:
mongodb://db1.example.net,db2.example.net:2500/?replicaSet=test

Couchbase java.util.concurrent.TimeoutException while getting multiple documents

I am trying to get a document from Couchbase using the below code:
public synchronized void initialize() {
CouchbaseEnvironment env =
DefaultCouchbaseEnvironment
.builder()
.connectTimeout(10000)
.build();
setBucket(proper
.getCluster()
.openBucket(proper.getBucket(),proper.getBucketPassword())
}
public JsonDocument findByDocumentId(String id) {
try {
return getBucket.get(id);
} catch (Exception e) {
e.printStackTrace(System.out);
}
}
I am able to retrieve 3 or 4 documents successfully, but then I receive a TimeoutException:
java.lang.RuntimeException: java.util.concurrent.TimeoutException
at com.couchbase.client.java.util.Blocking.blockForSingle(Blocking.java:93)
at com.couchbase.client.java.CouchbaseBucket.get(CouchbaseBucket.java:100)
at com.couchbase.client.java.CouchbaseBucket.get(CouchbaseBucket.java:95)
Why am I getting a timeout and how can I avoid it?
You can increase the Key / Value operation timeout using the kvTimeout(long) parameter when configuring your environment.
EG
CouchbaseEnvironment env =
DefaultCouchbaseEnvironment
.builder()
.kvTimeout(5000) //in ms
.build();
But I'd be concerned if you need to increase this and you're not stressing your system. This might point to poorly configured setup somewhere.
For a list of configurable options see http://developer.couchbase.com/documentation/server/4.0/sdks/java-2.2/env-config.html
Thread.sleep would help to avoid this issue.
We have to implement the wait time to next document read. This is not an solution but a work around.

try-catch-finally block in java

As per my understanding, I want to follow the best practice for releasing the resources at the end to prevent any connection leaks. Here is my code in HelperClass.
public static DynamoDB getDynamoDBConnection()
{
try
{
dynamoDB = new DynamoDB(new AmazonDynamoDBClient(new ProfileCredentialsProvider()));
}
catch(AmazonServiceException ase)
{
//ase.printStackTrace();
slf4jLogger.error(ase.getMessage());
slf4jLogger.error(ase.getStackTrace());
slf4jLogger.error(ase);
}
catch (Exception e)
{
slf4jLogger.error(e);
slf4jLogger.error(e.getStackTrace());
slf4jLogger.error(e.getMessage());
}
finally
{
dynamoDB.shutdown();
}
return dynamoDB;
}
My doubt is, since the finally block will be executed no matter what, will the dynamoDB returns empty connection because it will be closed in finally block and then execute the return statement? TIA.
Your understanding is correct. dynamoBD.shutdown() will always execute before return dynamoDB.
I'm not familiar with the framework you're working with, but I would probably organize the code as follows:
public static DynamoDB getDynamoDBConnection()
throws ApplicationSpecificException {
try {
return new DynamoDB(new AmazonDynamoDBClient(
new ProfileCredentialsProvider()));
} catch(AmazonServiceException ase) {
slf4jLogger.error(ase.getMessage());
slf4jLogger.error(ase.getStackTrace());
slf4jLogger.error(ase);
throw new ApplicationSpecificException("some good message", ase);
}
}
and use it as
DynamoDB con = null;
try {
con = getDynamoDBConnection();
// Do whatever you need to do with con
} catch (ApplicationSpecificException e) {
// deal with it gracefully
} finally {
if (con != null)
con.shutdown();
}
You could also create an AutoCloseable wrapper for your dynamoDB connection (that calls shutdown inside close) and do
try (DynamoDB con = getDynamoDBConnection()) {
// Do whatever you need to do with con
} catch (ApplicationSpecificException e) {
// deal with it gracefully
}
Yes,dynamoDB will return an empty connection as dynamoBD.shutdow() will be executed before return statement, Always.
Although I am not answering your question about the finally block being executed always (there are several answers to that question already), I would like to share some information about how DynamoDB clients are expected to be used.
The DynamoDB client is a thread-safe object and is intended to be shared between multiple threads - you can create a global one for your application and re-use the object where ever you need it. Generally, the client creation is managed by some sort of IoC container (Spring IoC container for example) and then provided by the container to whatever code needs it through dependency injection.
Underneath the hood, the DynamoDB client maintains a pool of HTTP connections for communicating the DynamoDB endpoint and uses connections from within this pool. The various parameters of the pool can be configured by passing an instance of the ClientConfiguration object when constructing the client. For example, one of the parameters is the maximum number of open HTTP connections allowed.
With the above understanding, I would say that since the DynamoDB client manages the lifecycle of HTTP connections, resource leaks shouldn't really be concern of code that uses the DynamoDB client.
How about we "imitate" the error and see what happens ? This is what I mean:
___Case 1___
try{
// dynamoDB = new DynamoDB(new AmazonDynamoDBClient(new ProfileCredentialsProvider()));
throw new AmazonServiceException("Whatever parameters required to instantiate this exception");
} catch(AmazonServiceException ase)
{
//ase.printStackTrace();
slf4jLogger.error(ase.getMessage());
slf4jLogger.error(ase.getStackTrace());
slf4jLogger.error(ase);
}
catch (Exception e)
{
slf4jLogger.error(e);
slf4jLogger.error(e.getStackTrace());
slf4jLogger.error(e.getMessage());
}
finally
{
//dynamoDB.shutdown();
slf4jLogger.info("Database gracefully shutdowned");
}
___Case 2___
try{
// dynamoDB = new DynamoDB(new AmazonDynamoDBClient(new ProfileCredentialsProvider()));
throw new Exception("Whatever parameters required to instantiate this exception");
} catch(AmazonServiceException ase)
{
//ase.printStackTrace();
slf4jLogger.error(ase.getMessage());
slf4jLogger.error(ase.getStackTrace());
slf4jLogger.error(ase);
}
catch (Exception e)
{
slf4jLogger.error(e);
slf4jLogger.error(e.getStackTrace());
slf4jLogger.error(e.getMessage());
}
finally
{
//dynamoDB.shutdown();
slf4jLogger.info("Database gracefully shutdowned");
}
These exercise could be a perfect place to use unit tests and more specifically mock tests. I suggest you to take a close look at JMockit, which will help you write such tests much more easily.

How can 1 catch the exceptions thrown by the executable run using Java code?

I have written a Java code that must run only after successful shutting down of weblogic server.
The code shuts down the weblogic server and performs the required operations and then restarts the servers.
My question now is .. Is there a way by which 1 can keep a tab on the weblogic console to see if the shutdown proceess is over or not or if there were some exceptions thrown by the server during startup or shut down(not manually but programmatically)??
In my local machine I had made the thread to sleep until the server was shutdown completely by keeping the average time to shut (manually).
The code goes as under:
static final String DOMAIN_NAMES = "domainNames";
static final String DOMAIN_HOME="domainHome";
public static void main(String[] argss)
{
AbstractApplicationContext context=new FileSystemXmlApplicationContext(new String[]{"src/main/resources/redeployconfig.xml"});
StepOneRedeploy stepOne=(StepOneRedeploy) context.getBean("stepOneRedeploy");
stepOne.setProperties();
Properties prop=stepOne.getProperties();
String domainNames = prop.getProperty(DOMAIN_NAMES);
System.out.println(domainNames);
String domainHome = prop.getProperty(DOMAIN_HOME);
StringTokenizer domainNamesTokens= new StringTokenizer(domainNames,",");
StringTokenizer domainNamesTokens2=domainNamesTokens;
ArrayList<String> serverIPListArray = new ArrayList<String>();
while (domainNamesTokens.hasMoreElements())
{
String domainName=domainNamesTokens.nextToken();
System.out.println(domainName);
serverIPListArray.add(domainName);
}
while(domainNamesTokens2.hasMoreElements())
{
String domainName=domainNamesTokens2.nextToken();
/** Stopping weblogicserver **/
String domainPathToShutServer = domainHome + domainName+"/stopWebLogic.cmd";
String commandToShutServer="cmd /C start "+domainPathToShutServer;
try
{
Process p = Runtime.getRuntime().exec(commandToShutServer,null);
}
catch (Exception e)
{
e.printStackTrace();
}
/**Putting thread to sleep for 1 minute**/
try {
Thread.sleep(20000);
} catch (InterruptedException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
/** Deleting temp folder **/
try
{
File delTmpFile=new File("");
boolean isTmpDelete=delTmpFile.delete();
System.out.println(isTmpDelete);
if(!isTmpDelete)
{
throw new TempDeleteFailedException("Could not delete Tmp folder for "+domainName);
}
}
catch(TempDeleteFailedException tdfe)
{
tdfe.printStackTrace();
}
catch(Exception e)
{
e.printStackTrace();
}
/** Deleting stage folder **/
try
{
File delStgFile=new File("");
boolean isStgDelete=delStgFile.delete();
System.out.println(isStgDelete);
if(isStgDelete)
{
throw new StageDeleteFailedException();
}
}
catch (StageDeleteFailedException stgDelEileException)
{
stgDelEileException.printStackTrace();
}
catch(Exception e)
{
e.printStackTrace();
}
/** Starting weblogicserver **/
String domainPath = domainHome + domainName+"/startWebLogic.cmd";
String command="cmd /C start "+domainPath;
try
{
Process p = Runtime.getRuntime().exec(command,null);
}
catch (Exception e)
{
e.printStackTrace();
}
}
}
I have tried ProcessBuilder to start weblogic server.
But it says that
java.io.IOException: Cannot run program "startWebLogic.cmd" (in directory "D:\Oracle\Middleware\user_projects\domains\ass1"): CreateProcess error=2, The system cannot find the file specified
at java.lang.ProcessBuilder.start(ProcessBuilder.java:470)
at TestMain.main(TestMain.java:35)
Caused by: java.io.IOException: CreateProcess error=2, The system cannot find the file specified
at java.lang.ProcessImpl.create(Native Method)
at java.lang.ProcessImpl.(ProcessImpl.java:177)
at java.lang.ProcessImpl.start(ProcessImpl.java:28)
at java.lang.ProcessBuilder.start(ProcessBuilder.java:452)
... 1 more
So if I were to refactor the Question...
How can 1 catch the exceptions thrown by the executable run using Java code?
Is there a way by which 1 can keep a tab on the weblogic console to see if the shutdown proceess is over or not or if there were some exceptions thrown by the server during startup or shut down(not manually but programmatically)??
Weblogic logs are written to disk. By default they ae in DOMAIN_NAME\servers\SERVER_NAME\logs\SERVER_NAME.log(see: Understanding WebLogic logging files).
Just monitor the server log for exceptions. Take a look at Commons IO - Tailer.
By the way, you can use WLST and JMX to stop, start, restart and monitor the health of Weblogic (see ServerRuntimeMBean and ServerLifeCycleRuntimeMBean), no need to fire standalone processes.
You can either:
Use MBeanServerConnection (see: This Example)
Use an Embbeded WLST interpreter to Manage the server Life Cycle.
"Waiting enough" is a bad idea as it will easily break when the situation changes, and using a process builder is very limiting (not to mention that, these startup scripts typically spawn the main process as a separate process so you don't get to watch them to start with).
I'd look into hooks that the WebLogic server provides. WebLogic has lots of hooks so I don't know which one would be appropriate for you, but for example if it's a servlet you could do your shutdown process from a ServletContextListener.

MongoDB: check connection to DB

I'm looking for best way to check connection to Mongo DB.
Situation: client makes request (api) to server. And server returns status of all databases.
What the best way to do it?
I use this:
Builder o = MongoClientOptions.builder().connectTimeout(3000);
MongoClient mongo = new MongoClient(new ServerAddress("192.168.0.1", 3001), o.build());
try {
mongo.getAddress();
} catch (Exception e) {
System.out.println("Mongo is down");
mongo.close();
return;
}
In Java MongoDriver 3.3.0 use ServerMonitorListener to determine whether server is up and connected or not.
Here is the example code,
public class ServerConnection implements ServerMonitorListener {
private MongoClient client;
public ServerConnection(){
try {
MongoClientOptions clientOptions = new MongoClientOptions.Builder()
.addServerMonitorListener(this)
.build();
client = new MongoClient(new ServerAddress("localhost", 27017), clientOptions);
} catch (Exception ex) {
}
}
#Override
public void serverHearbeatStarted(ServerHeartbeatStartedEvent serverHeartbeatStartedEvent) {
// Ping Started
}
#Override
public void serverHeartbeatSucceeded(ServerHeartbeatSucceededEvent serverHeartbeatSucceededEvent) {
// Ping Succeed, Connected to server
}
#Override
public void serverHeartbeatFailed(ServerHeartbeatFailedEvent serverHeartbeatFailedEvent) {
// Ping failed, server down or connection lost
}
}
The ping command is a no-op used to test whether a server is responding to commands. This command will return immediately even if the server is write-locked:
try{
DBObject ping = new BasicDBObject("ping", "1");
mongoTemplate.getDb().getMongo().getDB("DATABASE NAME"").command(ping);
} catch (Exception exp){
// MongoDb is down..
}
Use MongoClient for Java, all the info you need is here...
http://docs.mongodb.org/ecosystem/tutorial/getting-started-with-java-driver/
If I understand your question correctly you want to get state returned via a web service call. You can write a function that invokes db.serverStatus() and have it return the data. Check out the documentation here:
Monitoring for MongoDB

Categories