Check MongoDB authentication with Java 3.0 driver - java

I am currently trying to connect to a MongoDB replica set using the (relatively) new 3.0 Java driver. However I can't seem to catch the MongoSecurityExceptions that occur when the user provides bad credentials. This is my current code.
try {
MongoClientURI mongoClientURI = new MongoClientURI("mongodb://<user>:<password>#member1.com:27017/?authSource=db"
this.mongoClient = new MongoClient(mongoClientURI);
}
catch(Exception e) {
// TODO: some proper exception handling
System.err.println(e.toLocalizedMessage());
}
This code works fine when run with correct credentials, but an exception is thrown outside of the try-catch when bad credentials are provided.
com.mongodb.MongoSecurityException: Exception authenticating MongoCredential{mechanism=null, userName='<user>', source='<source>', password=<hidden>, mechanismProperties={}}
at com.mongodb.connection.SaslAuthenticator.authenticate(SaslAuthenticator.java:61)
at com.mongodb.connection.DefaultAuthenticator.authenticate(DefaultAuthenticator.java:32)
at com.mongodb.connection.InternalStreamConnectionInitializer.authenticateAll(InternalStreamConnectionInitializer.java:99)
at com.mongodb.connection.InternalStreamConnectionInitializer.initialize(InternalStreamConnectionInitializer.java:44)
at com.mongodb.connection.InternalStreamConnection.open(InternalStreamConnection.java:115)
at com.mongodb.connection.DefaultServerMonitor$ServerMonitorRunnable.run(DefaultServerMonitor.java:127)
at java.lang.Thread.run(Thread.java:745)
Any idea where to handle authentication exceptions?

The MongoClient constructors do not throw any connectivity-related exceptions. Rather, they return immediately after starting one or more background threads that attempt to establish a connection and authenticate based on the provided credentials.
It's only when an application uses the MongoClient to perform some operation on the MongoDB server that an exception will be thrown. However, that exception is a generic timeout exception indicating that the driver failed to find a suitable server for the operation before the server selection timeout expires. For example:
MongoClient client = new MongoClient(asList(new ServerAddress("localhost"), new ServerAddress("localhost:27018")),
singletonList(MongoCredential.createCredential("username",
"admin",
"bad".toCharArray())),
MongoClientOptions.builder().serverSelectionTimeout(1000).build());
try {
client.getDB("admin").command("ping");
} catch (MongoTimeoutException e) {
// do something
}
will throw a MongoTimeoutException after 1 second. While no MongoSecurityException is thrown, the message of the MongoTimeoutException will contain relevant details. For example, when connecting to a three member replica set when one of the servers is down, and authentication failed on the remaining two, the message field of the MongoTimeoutException will be something like:
Timed out after 1000 ms while waiting for a server that matches
ReadPreferenceServerSelector{readPreference=primary}. Client view of
cluster state is {type=UNKNOWN, servers=[{address=localhost:27017,
type=UNKNOWN, state=CONNECTING,
exception={com.mongodb.MongoSocketOpenException: Exception opening
socket}, caused by {java.net.ConnectException: Connection refused}},
{address=localhost:27018, type=UNKNOWN, state=CONNECTING,
exception={com.mongodb.MongoSecurityException: Exception
authenticating MongoCredential{mechanism=null, userName='username',
source='admin', password=, mechanismProperties={}}}, caused by
{com.mongodb.MongoCommandException: Command failed with error 18:
'Authentication failed.' on server localhost:27018. The full response
is { "ok" : 0.0, "code" : 18, "errmsg" : "Authentication failed." }}}]

Related

java.net.ConnectException: Connection refused timeout

I saw a lot of "java.net.ConnectException: Connection refused" questions but none referring to timeout of this error. My problem is I have to connect to a server that, in some cases, is blocked (connected by another software to the same port). So, I'm doing a loop with some max retries to try to connect:
My current code (of course, is depending on a lot of configurations for my software, but is working fine):
public TCPConnector(TCPDefinition tcpDefinition) throws IAException {
ivTcpDefinition = tcpDefinition;
// Initialize the socket
boolean retry = false;
int counter = 1;
do {
try {
ivSocket = new Socket();
ivSocket.connect(new InetSocketAddress(tcpDefinition.getHostname(), tcpDefinition.getPort()), tcpDefinition.getConnectTimeOut());
ivSocket.setSoTimeout(tcpDefinition.getAckTimeOut());
retry = false;
}
catch (UnknownHostException uhe) {
throw new IAException(null, new StringBuffer("Can't find host: ").append(tcpDefinition.getHostname()).toString(), uhe);
}
catch (SocketException see) {
StringBuilder sb = new StringBuilder("Connection refused to host ").append(tcpDefinition.getHostname()).
append(" port ").append(tcpDefinition.getPort()).append(". Connection Attempt Nr. ").append(counter);
logger.error(sb.toString(), see);
retry = true;
if (counter++ > tcpDefinition.getConnectRetries())
throw new IAException(null, sb.toString(), see);
else
logger.error("will retry to connect");
}
catch (IOException ioe) {
StringBuilder sb = new StringBuilder("I/O error while connecting to host ").append(tcpDefinition.getHostname()).
append(" port ").append(tcpDefinition.getPort()).append(". Connection Attempt Nr. ").append(counter);
logger.error(sb.toString(), ioe);
retry = true;
if (counter++ > tcpDefinition.getConnectRetries())
throw new IAException(null, sb.toString(), ioe);
else
logger.error("will retry to connect");
}
}
while (retry);
}
Well, the problem is this:
On Windows, every second, the SocketException is thrown, instead the IOException, while I have configured a timeout of 5000 msec to ivSocket.connect
On Linux, this is thrown every millisecond!!
Windows:
2019-12-05 12:40:47,609 ERROR DefaultQuartzScheduler_Worker-1 TCPConnector - Connection refused to host localhost port 13002. Connection Attempt Nr. 1
java.net.ConnectException: Connection refused: connect
at java.net.PlainSocketImpl.socketConnect(Native Method)
2019-12-05 12:40:48,703 ERROR DefaultQuartzScheduler_Worker-1 TCPConnector - Connection refused to host localhost port 13002. Connection Attempt Nr. 2
java.net.ConnectException: Connection refused: connect
Linux:
2019-12-05 12:45:47,609 ERROR DefaultQuartzScheduler_Worker-1 TCPConnector - Connection refused to host localhost port 13002. Connection Attempt Nr. 1
java.net.ConnectException: Connection refused: connect
at java.net.PlainSocketImpl.socketConnect(Native Method)
2019-12-05 12:45:47,610 ERROR DefaultQuartzScheduler_Worker-1 TCPConnector - Connection refused to host localhost port 13002. Connection Attempt Nr. 2
java.net.ConnectException: Connection refused: connect
Why the timeout is not executed? Well this is not exactly right. If I configure a timeout less than 1 second on Windows, then the timeout is executed. 500 msec:
2019-12-05 11:47:07,375 ERROR DefaultQuartzScheduler_Worker-1 TCPConnector - I/O error while connecting to host localhost port 13002. Connection Attempt Nr. 1
java.net.SocketTimeoutException: connect timed out
at java.net.PlainSocketImpl.socketConnect(Native Method)
2019-12-05 11:47:07,875 ERROR DefaultQuartzScheduler_Worker-1 TCPConnector - I/O error while connecting to host localhost port 13002. Connection Attempt Nr. 2
java.net.SocketTimeoutException: connect timed out
at java.net.PlainSocketImpl.socketConnect(Native Method)
It is possible to configure a "connect refuse" timeout?
There is no such thing as a "connection refused timeout".
"Connection refused" happens when the server sees the connection request, but there is no service listening for connections on the IP + port that the request is directed to. The server then "refuses" the connection. This typically happens instantly, so so no timeout is triggered.
"Connection timed out" happens (typically) when something stops the connection request from reaching the server1, 2. So the client-side will wait for the response from the server, and then resend / wait a few times. And eventually the time allotted for establishing a connection will expire ... and the connection times out.
As you can see these are different scenarios. And they are reported back to the Java client-side differently.
So the reason you are not getting timeouts is that the "connection refused" responses are coming back quick enough that your configured timeout is not exceeded.
That might also explain why setting the connect timeout small might have changed the behavior. There may also be issues with the granularity of the timeout that the OS allows Java to set.
To investigate this further, I think we would need a minimal reproducible example. For example, we need to see how you have implemented the code that manages the server-socket and accepts connections on the server side.
1 - The blockage could be on the server's reply packets.
2 - There are various possible causes for this kind of thing. The most likely are a firewall blocking traffic somewhere, a network routing problem, or using a private IP address on the wrong network.

Why does this error occur? An established connection was aborted by the software in your host machine

Stack:AngularJS v1.6.5, java 8, spring boot, tomcat.
After about 1 week of work , the application not response with such an error. Why this happening?
Frontend:
$http({
url: 'find',
method: "post",
data: { 'month' : $scope.month,'year' : $scope.year, 'payTime' : $scope.payTime,'waitTime' : $scope.waitTime,'scanTime' : $scope.scanTime,'gbNumber' : $scope.hyper}
})
.then(function(response) {
..
});
}
Backend:
#RequestMapping(path = "/find", method = RequestMethod.POST)
public ReportResponse find(#RequestBody RequestSearch params,
HttpServletResponse response) throws DataNotFoundException {
...
}
Stacktrace:
2018-04-02 09:37:44.738 ERROR 14912 --- [p-nio-80-exec-9] o.s.boot.web.support.ErrorPageFilter : Cannot forward to error page for request [/excel/ExceReport.xls] as the response has already been committed. As a result, the response may have the wrong status code. If your application is running on WebSphere Application Server you may be able to resolve this problem by setting com.ibm.ws.webcontainer.invokeFlushAfterService to false
org.apache.catalina.connector.ClientAbortException: java.io.IOException: An established connection was aborted by the software in your host machine
at org.apache.catalina.connector.OutputBuffer.realWriteBytes(OutputBuffer.java:356) ~[catalina.jar:8.5.24]
at org.apache.catalina.connector.OutputBuffer.flushByteBuffer(OutputBuffer.java:815) ~[catalina.jar:8.5.24]
at org.apache.catalina.connector.OutputBuffer.append(OutputBuffer.java:720) ~[catalina.jar:8.5.24]
at org.apache.catalina.connector.OutputBuffer.writeBytes(OutputBuffer.java:391) ~[catalina.jar:8.5.24]
at org.apache.catalina.connector.OutputBuffer.write(OutputBuffer.java:369) ~[catalina.jar:8.5.24]
at org.apache.catalina.connector.CoyoteOutputStream.write(CoyoteOutputStream.java:96) ~[catalina.jar:8.5.24]
at org.springframework.util.StreamUtils.copy(StreamUtils.java:138) ~[spring-core-4.3.9.RELEASE.jar:4.3.9.RELEASE]
at org.springframework.http.converter.ResourceHttpMessageConverter.writeContent(ResourceHttpMessageConverter.java:110) ~[spring-web-4.3.9.RELEASE.jar:4.3.9.RELEASE]
at org.springframework.http.converter.ResourceHttpMessageConverter.writeInternal(ResourceHttpMessageConverter.java:102) ~[spring-web-4.3.9.RELEASE.jar:4.3.9.RELEASE]
...
Cause
This exception can mean that the connection to the client browser was
aborted before the response is fully transferred. It is a harmless
warning as it can be due to transient network problems or the user
aborts/refreshes the page before it loaded.
A list of other causes are:
The user closed the browser before the page loaded.
Their Internet connection failed during loading.
They went to another page before the page loaded.
The browser timed the connection out before the page loaded (would
have to be a large page).
Resolution
This can be ignored, unless there are other issues that are currently
occurring. For example, if the your application server is throwing a
lot of these, it might be a sign of a performance problem.

Self-Connect to Websocket Spring server from JUnit test

I have an app that exposes Websocket/SockJS/Stomp server endpoints and would like to run a JUnit tests that runs client (Java STOMP client, also from Spring) against it, to test "sending" features.
I have a test like
public void measureSpeedWithWebsocket() throws Exception {
final Waiter subscribeWaiter = new Waiter();
new Thread(() -> {
// Prepare connection
WebsocketClient listener = new WebsocketClient("/mytopic/stomp");
try {
listener.connectAndSubscribe();
subscribeWaiter.resume();
} catch (Exception e) {
e.printStackTrace();
}
}).start();
subscribeWaiter.await(); // Wait for connection.
Here I made use of Waiter from https://github.com/jhalterman/concurrentunit, which effect is basically to delay main thread of the test till secondary thread call resume(). This is likely wrong, because Spring server that is running in the context has to react
I am getting the following error
[INFO ] 2017-02-03 12:36:12.402 [Thread-19] WebsocketClient - Listening
[INFO ] 2017-02-03 12:36:12.403 [Thread-19] WebsocketClient - Connecting to ws://localhost:8083/user...
2017-02-03 12:36:14.097 ERROR 9956 --- [ Thread-19] o.s.w.socket.sockjs.client.SockJsClient : Initial SockJS "Info" request to server failed, url=ws://localhost:8083/user
org.springframework.web.client.ResourceAccessException: I/O error on GET request for "http://localhost:8083/user/info": Connection refused: connect; nested exception is java.net.ConnectException: Connection refused: connect
at org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:633) ~[spring-web-4.3.3.RELEASE.jar:4.3.3.RELEASE]
at org.springframework.web.client.RestTemplate.execute(RestTemplate.java:595) ~[spring-web-4.3.3.RELEASE.jar:4.3.3.RELEASE]
at org.springframework.web.socket.sockjs.client.RestTemplateXhrTransport.executeInfoRequestInternal(RestTemplateXhrTransport.java:138) ~[spring-websocket-4.3.3.RELEASE.jar:4.3.3.RELEASE]
at org.springframework.web.socket.sockjs.client.AbstractXhrTransport.executeInfoRequest(AbstractXhrTransport.java:155) ~[spring-websocket-4.3.3.RELEASE.jar:4.3.3.RELEASE]
at org.springframework.web.socket.sockjs.client.SockJsClient.getServerInfo(SockJsClient.java:286) ~[spring-websocket-4.3.3.RELEASE.jar:4.3.3.RELEASE]
at org.springframework.web.socket.sockjs.client.SockJsClient.doHandshake(SockJsClient.java:254) ~[spring-websocket-4.3.3.RELEASE.jar:4.3.3.RELEASE]
at org.springframework.web.socket.messaging.WebSocketStompClient.connect(WebSocketStompClient.java:274) [spring-websocket-4.3.3.RELEASE.jar:4.3.3.RELEASE]
at org.springframework.web.socket.messaging.WebSocketStompClient.connect(WebSocketStompClient.java:255) [spring-websocket-4.3.3.RELEASE.jar:4.3.3.RELEASE]
(...)
at java.lang.Thread.run(Thread.java:745) ~[na:1.8.0_74]
Caused by: java.net.ConnectException: Connection refused: connect
How I can possibly make a proper test that "self-connects" to the websocket offered by my Spring Boot application?
If you are using Spring Boot than you are a lucky one :).
Here is an example http://rafaelhz.github.io/testing-websockets/ how you can test the web sockets, which perfectly works in Spring Boot and can helps you a lot. I am trying to do the same in Spring MVC but unfortunately that doesn't work in Spring MVC.

How to detect SCTP connection failuer

I am using mobicents CAP implementation to build a CAP application for CAMEL charging; my application is working fine and I can send and receive messages between SSF and SCF.
What I am looking for is: how to detect it the SCTP link between client and server has been broken? Because when I deliberately stop the server and keep the client running, on sending CAPDialog doesn't raise any error.
When I stop the server, on console I see following exception:
2015-04-14 13:15:29,669 [Thread-0 ] ERROR org.mobicents.protocols.sctp.SelectorThread - Exception while finishing connection for Association=clientAsscoiation
java.net.ConnectException: Connection refused: no further information
at sun.nio.ch.SocketChannelImpl.checkConnect(Native Method)
at sun.nio.ch.SocketChannelImpl.finishConnect(Unknown Source)
at org.mobicents.protocols.sctp.SelectorThread.finishConnectionTcp(SelectorThread.java:407)
at org.mobicents.protocols.sctp.SelectorThread.finishConnection(SelectorThread.java:368)
at org.mobicents.protocols.sctp.SelectorThread.run(SelectorThread.java:151)
at java.lang.Thread.run(Unknown Source)
And during this if I try to send a CAPDialog e.g. send an oAnswer event, it simple doesn't tell if the request was successful or not (which ideally should return a failure in my case)
OAnswerSpecificInfo oAnswerSpecificInfo = this.getCapProvider().getCAPParameterFactory().createOAnswerSpecificInfo(null,
false, false, null, null, null);
ReceivingSideID legID = this.getCapProvider().getCAPParameterFactory().createReceivingSideID(LegType.leg2);
MiscCallInfo miscCallInfo = this.getCapProvider().getINAPParameterFactory().createMiscCallInfo(MiscCallInfoMessageType.notification, null);
EventSpecificInformationBCSM eventSpecificInformationBCSM = this.getCapProvider()
.getCAPParameterFactory()
.createEventSpecificInformationBCSM(oAnswerSpecificInfo);
CAPDialogCircuitSwitchedCall capDialog = (CAPDialogCircuitSwitchedCall) getCapProvider().getCAPDialog(localDialogId);
capDialog.addEventReportBCSMRequest(EventTypeBCSM.oAnswer, eventSpecificInformationBCSM, legID, miscCallInfo, null);
capDialog.setUserObject(getParamAsString("referenceId"));
capDialog.setReturnMessageOnError(true);
capDialog.send();
"capDialog.send();" code does not return back an error even when any underlying SS7 link is down.
If you have access to SCTP stack you can check if SCTP connection is up or down:
Association association = ...;
association.isConnected();

Problem with remote JMX connection and Notifications

I'm trying to follow one example from the Java API documentation (http://download.oracle.com/javase/1.5.0/docs/api/java/lang/management/MemoryPoolMXBean.html#Notification) related to the UsageThreshold property of the Memory Pool Beans and notifications. My intention is to do something every time the pool overcomes the threshold. This is the sample code:
MemoryPoolMXBean remoteOldGenMemoryPool =
ManagementFactory.newPlatformMXBeanProxy(
jmxServer,
"java.lang:type=MemoryPool,name=PS Old Gen",
MemoryPoolMXBean.class);
class MyListener implements javax.management.NotificationListener {
public void handleNotification(Notification notification, Object handback) {
String notifType = notification.getType();
if (notifType.equals(MemoryNotificationInfo.MEMORY_THRESHOLD_EXCEEDED)) {
// Do Something
println "Threshold passed";
}
}
}
// Register MyListener with MemoryMXBean
MemoryMXBean remoteMemory =
ManagementFactory.newPlatformMXBeanProxy(
jmxServer,
ManagementFactory.MEMORY_MXBEAN_NAME,
MemoryMXBean.class);
NotificationEmitter emitter = remoteMemory as NotificationEmitter;
MyListener listener = new MyListener();
emitter.addNotificationListener(listener, null, null);
remoteOldGenMemoryPool.setUsageThreshold 500000000;
When I execute the code and connect to my JVM I can see the following:
Threshold passed
02-Feb-2011 16:30:00 ClientCommunicatorAdmin restart
WARNING: Failed to restart: java.io.IOException: Failed to get a RMI stub: javax.naming.CommunicationException [Root exception is java.rmi.ConnectIOException: error during JRMP connection establishment; nested exception is:
java.net.SocketException: Connection reset]
02-Feb-2011 16:30:03 RMIConnector RMIClientCommunicatorAdmin-doStop
WARNING: Failed to call the method close():java.rmi.ConnectIOException: error during JRMP connection establishment; nested exception is:
java.net.SocketException: Connection reset
02-Feb-2011 16:30:03 ClientCommunicatorAdmin Checker-run
WARNING: Failed to check connection: java.net.SocketException: Connection reset
02-Feb-2011 16:30:03 ClientCommunicatorAdmin Checker-run
WARNING: stopping
For some reason (that I don't understand yet) the code is trying to restart the connection to JVM. Any ideas why this can be happening or how to prevent it? Am I doing somehing wrong?
Thanks
May be you can add a variable to the jmx enviroment, like this:
m.put("jmx.remote.x.client.connection.check.period", 0L);
But, what i have encountered is little different from this.
you can see : http://chainhou.iteye.com/blog/1906688.

Categories

Resources