MongoDB and Play! Framework Inconsistent Behaviour - mongodb

I have some code in a test as follows:
#Test
public void testRetrieveMongoDBFailUnkownHost()
{
//Set up test port and host on DSMongo
MyMongo mongoTest = new MyMongo();
mongoTest.setHost("failure");
mongoTest.setPort("0");
//attempt to make the connection
try
{
mongoTest.attemptMongoConnection();
assertTrue(false);
}
catch (Exception e)
{
assertEquals("Incorrect error message received: " + e.getMessage(),"Error (3013) : Unknown database host.", e.getMessage());
}
}
And the attempt MongoConnection() method runs the new Mongo(host, port) method which should fail with an unknown host exception. It isn't failing on my machine (no matter what string I put in instead of failure) but it is failing on my colleagues machine. So the test fails on my machine and passes on his (i.e. he gets the exception). Any ideas cause I am stumped!
Thanks
Paul
EDIT: The code in the attempt Connection Method is
*/
public static void attemptMongoConnection() throws MYException
{
try {
singleMongo = new Mongo(getHost(), getPort());
Logger.debug("Retrieved Mongo database from " + host);
} catch (UnknownHostException e) {
Logger.error("Unknown Host Exception", e);
throw new MYException(MYMessage.MY_UNKNOWN_HOST);
} catch (MongoException e) {
Logger.error("Mongo error", e);
throw new MYException(MYMessage.DS_MONGO_ERROR);
}
}
where singleMOngo is a Mongo variable and the getHost and getPort are the ones we have set (.e. failure and 0).

I have found this was a problem with the DNS somewhere. When I ran it at home (from where I originally made the post) it failed and seems to hav been resolving the name of "failure" so when I instead entered something like "localhost_123" it works perfectly.
I have come into the office this morning and it works with "failure" again. Doing some further digging it seems therefore that my router or something at home is resolving "failure" to an address it is aware of which is not present on the network here in the office.
Thanks for all those who looked at this. Very bizarre.

Related

Server restart results in never ending Bad_ServiceUnsupported errors, onSubscriptionTransferFailed not called

my Milo client (sdk 0.4.1) subscribes on server events by use of UaSubscription and can receive events sucessfully. But once I restart the server, the clients only logs errors in an endless loop in the form of:
[ERROR] 2021-06-11 17:29:11.467 [milo-netty-event-loop-0]
UascClientMessageHandler -
errorMessage=ErrorMessage{error=StatusCode{name=Bad_ServiceUnsupported,
value=0x800B0000, quality=bad}, reason=null}
Unfortunately implementing the onSubscriptionTransferFailed method does not help because it is never called.
client.getSubscriptionManager().addSubscriptionListener(new UaSubscriptionManager.SubscriptionListener() {
#Override
public void onSubscriptionTransferFailed(UaSubscription subscription, StatusCode statusCode) {
try {
LOGGER.info("onSubscriptionTransferFailed");
client.getSubscriptionManager().clearSubscriptions();
client.disconnect().get();
run(client, serverAddress, biConsumer, requestedPublishingInterval);
} catch (InterruptedException | ExecutionException e) {
LOGGER.error("Failed re-subscription: {}", e.getMessage(), e);
}
}
}
Any idea how I can get the client to detect its current problem and resubscribe on server events?
Thank you in advance.
Update:
Found this commit https://github.com/eclipse/milo/commit/e854374845e6c5f46a7b033c2c62cee2ee10622a and was able to fix the problem by just increasing the Milo client sdk version to 0.6.1. Version 0.5.3 should probably also fix it but I did not test it.

Why can not I read bytes from the TcpClient in C#?

Why can not I read bytes from the TcpClient in C#?
Here is the error I am getting:
Unable to read data from the transport connection: An established connection was aborted by the software in your host machine.
Here is how I start my TcpClient:
public static async void Start()
{
TcpListener server = null;
try
{
server = new TcpListener(IPAddress.Loopback, 13000);
server.Start();
var client = await server.AcceptTcpClientAsync();
var stream = client.GetStream();
var bytes = Convert.FromBase64String("ABCD");
await stream.WriteAsync(bytes, 0, bytes.Length);
client.Close();
}
catch (Exception e)
{
throw;
}
finally
{
if(server != null)
{
server.Stop();
}
}
}
Here is how I run a request to the TcpClient:
try {
var response = (new HttpClient()).GetByteArrayAsync("http://localhost:13000").Result;
return Convert.ToBase64String(response);
} catch(Exception e) {
throw;
}
The return Convert.ToBase64String(response); line is never reached. While I see the quoted above error message inside the Exception e if I hit a breakpoint on the throw line.
Also, during debug the Start() method completes just fine. I.e. it starts, then wait for a request, gets a request, writes to the TclClient and at the end runs the server.Stop(); command.
I am expecting my code to work, because I took it and modified from the official documentation over here.
I tried to check out a few resources which would tackle my exception, but none of them did help.
E.g. I tried to use the question.
First answer tells nothing useful actually, but just plays around with words and at the end states that one can do nothing about the exception (please, correct me if I am missing a point in the answer).
And the second answer tells an impossible in my case problem. Because, I am sure there is nothing running on the 13000 port.
Your client code is using HttpClient, which sends an HTTP request and expects an HTTP response. But your server is not an HTTP server, it is just a plain TCP server, so the client is likely to fail and forcibly close the connection when it doesn't receive a properly formatted HTTP response.
The "official documentation" whose example you modified is not using HttpClient at all, it is using TcpClient instead.
If you want to use HttpClient in your client, then you should use HttpListener instead of TcpListener in your server.

Trying to connect XMPP server by Smack and getting error

I have got an requirement to connect XMPP server using Java API Smack and further make send message/receive message.
I tried with Smack API (4.1.8) and I am getting errors (find errors below).
Note: both host and port are opened.
Code:`public class Sender {
public static void main(String a[]) throws NoResponseException,XMPPException,
InterruptedException, SmackException, IOException
{
// Create the configuration for this new connection
XMPPTCPConnectionConfiguration.Builder configBuilder = XMPPTCPConnectionConfiguration.builder();
configBuilder.setUsernameAndPassword("user", "******");
configBuilder.setResource("work");
configBuilder.setServiceName("HOstname");
configBuilder.setSocketFactory(SSLSocketFactory.getDefault());
configBuilder.setSecurityMode(SecurityMode.required);
configBuilder.setCompressionEnabled(true);
configBuilder.setHost("thingsociety.im");
configBuilder.setDebuggerEnabled(true);
configBuilder.setPort(5222);
System.out.println("Connected1..............");
XMPPTCPConnection connection = new XMPPTCPConnection(configBuilder.build());
// Connect to the server
try {
System.out.println("Connected2..............");
connection.setPacketReplyTimeout(100000);
connection.connect();
System.out.println("Connected3..............");
// Log into the server
connection.isConnected();
connection.login();
System.out.println("Connected4..............");
}
catch (XMPPException | SmackException | IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
System.out.println(e.getMessage());
}
}
}
Error: No response received within reply timeout. Timeout was 100000ms (~100s). Used filter: No filter used or filter was 'null'.
org.jivesoftware.smack.SmackException$NoResponseException: No response received within reply timeout. Timeout was 100000ms (~100s). Used filter: No filter used or filter was 'null'
So basicly something (local firewall or on your gateway) is blocking outgouing communications OR configBuilder.setServiceName("HOstname"); service name (aka XMPP Domain) is wrong, maybe mispelled - especialy capital O looks like misspell to me.
I have just probe thingsociety.im:5222 and it is open so most probably it is a firewall issue.
Another one could be unhandeld, low level error on server side.

Why can't I catch this EJBTransactionRolledbackException

Server: WildFly10
JPA with eclipseLink 2.6.3-M1
JavaEE7
I have the following EJB:
#Stateless
#LocalBean
public class HandleRollbackComponent {
private static Logger logger = Logger.getLogger(HandleRollbackComponent.class);
#EJB
private Tws14WSBatchChRequestsFacade tws14wsBatchChRequestsFacade;
public void doSomething() {
// first off go and fetch an instance of tws14 from the db
logger.debug("*************************************************");
logger.debug("1. First off go and fetch an instance of tws14 from the db");
String batchChReqId = "103";
Tws14WSBatchChRequests tws14wsBatchChRequests = tws14wsBatchChRequestsFacade.find(new BigDecimal(batchChReqId));
logger.debug("2. Found instance of tws14: " + tws14wsBatchChRequests);
logger.debug("2.1 CARD PLASTIC : " + tws14wsBatchChRequests.getCardPlastic());
try {
logger.debug("3. Now call a method that throws the EJBTrxnRollBackException....");
doSomethingThatThrowsEJBTransactionRolledbackException(tws14wsBatchChRequests);
logger.debug("---> This line should not be logged if exception was thrown....");
} catch (Exception e) {
logger.debug("5. Caught the exception....");
} finally {
logger.debug("6. Finally try and get a fresh instance from the db again...");
tws14wsBatchChRequests = tws14wsBatchChRequestsFacade.find(new BigDecimal(batchChReqId));
logger.debug("7. Was able to get instance from db: " + tws14wsBatchChRequests);
logger.debug("8. Try and update the instance of tws again...");
tws14wsBatchChRequestsFacade.edit(tws14wsBatchChRequests);
logger.debug("9. Could update the instance without problems.....");
logger.debug("10. Check the OrderCards value: " + tws14wsBatchChRequests.getOrderCards() );
}
logger.debug("11. Done...");
}
public void doSomethingThatThrowsEJBTransactionRolledbackException(Tws14WSBatchChRequests tws14wsBatchChRequests) {
logger.debug("4. Set some invalid values on tws14 in an attempt to get exception thrown...");
tws14wsBatchChRequests.setOrderCards("N");
tws14wsBatchChRequests.setOrderCards("");
tws14wsBatchChRequests.setCardPlastic(null);
tws14wsBatchChRequestsFacade.edit(tws14wsBatchChRequests);
}
}
When I call doSomething() this is what I see:
First off go and fetch an instance of tws14 from the db
Found instance of tws14: za.co.fnds.persistence.entities.Tws14WSBatchChRequests[ batchChRequestId=103 ]
2.1 CARD PLASTIC : NBCRFLI_PIN
Now call a method that throws the EJBTrxnRollBackException....
Set some invalid values on tws14 in an attempt to get exception thrown...
---> This line should not be logged if exception was thrown....
Finally trying to get a fresh instance from the db again...
Was able to get instance from db: za.co.fnds.persistence.entities.Tws14WSBatchChRequests[ batchChRequestId=103 ]
Try and update the instance of tws again...
Could update the instance without problems.....
Check the OrderCards value:
Done...
My question is why is the program not going into the catch clause because my logs indicates that a javax.validation.ConstraintViolationException was thrown. Why is the bold log above still show? What am I missing? Is there a way I'm supposed to be handling this program structure in an EJB?
To verify that the implementation is wrong is the method doSomethingThatThrowsEJBTransactionRolledbackException. You can explicitly throw the exception and see if the cath works.
public void doSomething() {
try {
doSomethingThatThrowsEJBTransactionRolledbackException(new Tws14WSBatchChRequests());
} catch (Exception e) {
logger.warn(e.getMessage(), e);
}
}
public void doSomethingThatThrowsEJBTransactionRolledbackException(Tws14WSBatchChRequests tws14wsBatchChRequests) {
throw new EJBTransactionRolledbackException();
}
If the exception is catching, then your code is not throwing anything

Handle JDBC exception in BIRT API

I have a scheduler job which is based on a standalone RunAndRenderTask. The report design connects to a remote mysql database to fetch data. The scheduler generates a PDF and emails the report as attachment to a set of people. This works as long as the database is available.
But when the database is unavailable, then I can see the error in the logs, but the RunAndRenderTask still generates a PDF report which is blank and useless, and this gets emailed by the scheduler. I need to be able to catch this exception and instead email another set of people who can fix the DB issue. I tried various things but couldn't figure out how to do it.
In the code below, I expect the API to return an exception, and hence print "BirtException" or "Exception", but this code prints "Success" even when there is a JDBC exception.
Any help is appreciated.
Here's the code I have.
IReportEngine engine = null;
IRunAndRenderTask runAndRenderTask = null;
try {
EngineConfig config = new EngineConfig();
config.setEngineHome("birt-runtime-4_4_0/RuntimeEngine");
Platform.startup(config);
IReportEngineFactory factory = (IReportEngineFactory) Platform
.createFactoryObject(IReportEngineFactory.EXTENSION_REPORT_ENGINE_FACTORY);
engine = factory.createReportEngine(config);
IReportRunnable reportRunnable = engine.openReportDesign(DATA_PATH + "sample.rptdesign");
runAndRenderTask = engine.createRunAndRenderTask(reportRunnable);
PDFRenderOption option = new PDFRenderOption();
option.setOutputFileName(DATA_PATH + "output.pdf");
option.setOutputFormat("pdf");
runAndRenderTask.setRenderOption(option);
runAndRenderTask.run();
System.out.println("Success!");
} catch (BirtException e) {
System.out.println("BirtException");
e.printStackTrace();
} catch (Throwable e) {
System.out.println("Exception");
e.printStackTrace();
} finally {
if (runAndRenderTask != null) {
runAndRenderTask.close();
}
if (engine != null) {
engine.destroy();
}
Platform.shutdown();
RegistryProviderFactory.releaseDefault();
}
This is the exception stacktrace, which never gets propagated back by RunAndRenderTask.run()
INFO: Loaded JDBC driver class in class path: com.mysql.jdbc.Driver
Jun 26, 2014 9:26:43 PM org.eclipse.birt.data.engine.odaconsumer.ConnectionManager openConnection
SEVERE: Unable to open connection.
org.eclipse.birt.report.data.oda.jdbc.JDBCException: There is an error in get connection, Communications link failure
The last packet sent successfully to the server was 0 milliseconds ago. The driver has not received any packets from the server..
at org.eclipse.birt.report.data.oda.jdbc.JDBCDriverManager.doConnect(JDBCDriverManager.java:336)
at org.eclipse.birt.report.data.oda.jdbc.JDBCDriverManager.getConnection(JDBCDriverManager.java:235)
at org.eclipse.birt.report.data.oda.jdbc.Connection.connectByUrl(Connection.java:252)
at org.eclipse.birt.report.data.oda.jdbc.Connection.open(Connection.java:162)
at org.eclipse.datatools.connectivity.oda.consumer.helper.OdaConnection.open(OdaConnection.java:250)
at org.eclipse.birt.data.engine.odaconsumer.ConnectionManager.openConnection(ConnectionManager.java:165)
at org.eclipse.birt.data.engine.executor.DataSource.newConnection(DataSource.java:224)
at org.eclipse.birt.data.engine.executor.DataSource.open(DataSource.java:212)
at org.eclipse.birt.data.engine.impl.DataSourceRuntime.openOdiDataSource(DataSourceRuntime.java:217)
at org.eclipse.birt.data.engine.impl.QueryExecutor.openDataSource(QueryExecutor.java:435)
at org.eclipse.birt.data.engine.impl.QueryExecutor.prepareExecution(QueryExecutor.java:322)
at org.eclipse.birt.data.engine.impl.PreparedQuery.doPrepare(PreparedQuery.java:463)
at org.eclipse.birt.data.engine.impl.PreparedDataSourceQuery.produceQueryResults(PreparedDataSourceQuery.java:190)
at org.eclipse.birt.data.engine.impl.PreparedDataSourceQuery.execute(PreparedDataSourceQuery.java:178)
at org.eclipse.birt.data.engine.impl.PreparedOdaDSQuery.execute(PreparedOdaDSQuery.java:178)
at org.eclipse.birt.report.data.adapter.impl.DataRequestSessionImpl.execute(DataRequestSessionImpl.java:637)
at org.eclipse.birt.report.engine.data.dte.DteDataEngine.doExecuteQuery(DteDataEngine.java:152)
at org.eclipse.birt.report.engine.data.dte.AbstractDataEngine.execute(AbstractDataEngine.java:275)
at org.eclipse.birt.report.engine.executor.ExtendedGenerateExecutor.executeQueries(ExtendedGenerateExecutor.java:205)
at org.eclipse.birt.report.engine.executor.ExtendedGenerateExecutor.execute(ExtendedGenerateExecutor.java:65)
at org.eclipse.birt.report.engine.executor.ExtendedItemExecutor.execute(ExtendedItemExecutor.java:62)
at org.eclipse.birt.report.engine.internal.executor.dup.SuppressDuplicateItemExecutor.execute(SuppressDuplicateItemExecutor.java:43)
at org.eclipse.birt.report.engine.internal.executor.wrap.WrappedReportItemExecutor.execute(WrappedReportItemExecutor.java:46)
at org.eclipse.birt.report.engine.internal.executor.l18n.LocalizedReportItemExecutor.execute(LocalizedReportItemExecutor.java:34)
at org.eclipse.birt.report.engine.layout.html.HTMLBlockStackingLM.layoutNodes(HTMLBlockStackingLM.java:65)
at org.eclipse.birt.report.engine.layout.html.HTMLPageLM.layout(HTMLPageLM.java:92)
at org.eclipse.birt.report.engine.layout.html.HTMLReportLayoutEngine.layout(HTMLReportLayoutEngine.java:100)
at org.eclipse.birt.report.engine.api.impl.RunAndRenderTask.doRun(RunAndRenderTask.java:181)
at org.eclipse.birt.report.engine.api.impl.RunAndRenderTask.run(RunAndRenderTask.java:77)
at test.ReportTester.test(ReportTester.java:50)
at test.ReportTester.main(ReportTester.java:19)
In addition to catching BirtException, you should be aware that the way BIRT handles Javascript errors is - by default - browser-like. That is, BIRT tries to continue generating the report.
There are different ways to handle this for production-quality code (where task is a RunAndRenderTask or RunTask or RenderTask):
Use task.setErrorHandlingOption(CANCEL_ON_ERROR) (see BIRT docs). Personally, I have never tried this.
After task.run(...), but before task.close(), call task.getErrors(). If this list is not empty, your code should output these messages and throw an exception.
You need to add catch block that catches EngineException, not JDBC exception.
You can find javadocs at link.