Vertx : cannot read SQLConnection from fillReport - jasper-reports

I want to use vertx and JasperReports, I create my connection and I test it, everything is ok, but when I want to fill jasper report by using fillReport method (where the last one is Connection) it shows error :
The method fillReport(JasperReport, Map< String,Object >, Connection) in the type JasperFillManager is not applicable for the arguments (JasperReport, null, Class < connection>).
Any idea how should I cast my SQLConnect to connect ?
Here is my code :
AsyncSQLClient client = MySQLClient.createShared(vertx, mySQLClientConfig);
client.getConnection(res -> {
if (res.succeeded()) {
SQLConnection connection = res.result();
try{
String report = "C:\\Users\\paths\\Test1.jrxml";
JasperReport Jasp = JasperCompileManager.compileReport(report);
JasperPrint JASP_PRINT = JasperFillManager.fillReport(Jasp, null, connection);
JasperViewer.viewReport(JASP_PRINT);
}
catch(Exception ex){System.out.println(ex);}
Regards.

The answer is simple. You can't cast a Vert.x io.vertx.ext.sql.SQLConnection to a JDBC java.sql.Connection.
Vert.x heavily relies upon asynchronous calls. JDBC is blocking and so Vert.x wraps it with an asynchronous interface (and a bit more). There is no way to get to the real java.sql.Connection as there is no getter or something like that in the JDBCConnectionImpl or in the SQLConnection interface.
That doesn't mean you can't use Jasper with Vert.x. You need to open you own JDBC connection – but don't block the Event loop! So I suggest you have a look at the Worker Verticles, which don't block the Event loop because they spin up a separat thread.

Related

Issue with HttpClient in AEM

I have an HttpClient code written that is from org.apache.commons.httpclient package.
In that I am setting connection time and socket time out this way.
final HttpClient http = new HttpClient(this.connectionManager);
http.getParams().setParameter("http.connection.timeout", this.connectionTimeout);
http.getParams().setParameter("http.socket.timeout", this.socketTimeout);
Now the Adobe Cloud has raised issue that timeout is not being set(which is not true).
They suggested to set timeouts using
#Reference
private HttpClientBuilderFactory httpClientBuilderFactory;
public void doThis() {
HttpClientBuilder builder = httpClientBuilderFactory.newBuilder();
RequestConfig requestConfig = RequestConfig.custom()
.setConnectTimeout(5000)
.setSocketTimeout(5000)
.build();
builder.setDefaultRequestConfig(requestConfig);
HttpClient httpClient = builder.build();
// do something with the client
}
Refer Link
But HttpClientBuilderFactory does not belong to **org.apache.commons.httpclient it belongs to org.apache.http.client**
And always returns Closable Http client.
How do I resolve this security issue? Can I add an annotation for exception? Or will I have to rewrite all my code?
This issue is with Adobe Experience Manager 6.5 instance.
Is it probably because you are not setting the right timeout parameter?
You are setting the property http.connection.timeout which is not available in the class org.apache.commons.httpclient.params.HttpClientParams.
http.getParams() returns an instance of HttpClientParams which has the socket timeout and connection manager timeout but not a connection timeout. You could probably use the constant HttpClientParams.CONNECTION_MANAGER_TIMEOUT to set a timeout for the connection manager?
On the other hand, the property http.connection.timeout is available for the class HttpConnectionParams.
Constant field values reference
The problem is Adobe has two versions of HttpClient the old 3.x that has package structure org.apache.commons.httpclient.HttpClient and the one that HttpClientBuilderFactory gives out that is 4.x org.apache.http.Httpclient.
I was breaking my head around this. Finally we were left with two options...
1) Rewrite all our commons http api(3.x) to the newer version of apache.http (4.x) that has the methods setTimeout and setConnectionTimeout
OR
2)#SuppressWarnings("CQRules:ConnectionTimeoutMechanism")
We chose Option number 2 as the effort arround this was huge and we are planning to go live soon.

How to handle PostgreSQL timeout in groovy

In my Groovy script, I have following structure:
def sql = Sql.newInstance(connString, "user", "password",
"org.postgresql.Driver")
sql.withTransaction {
sql.withBatch(){}
sql.withBatch(){}
sql.withBatch(){}
.........
}
sql.close()
I want to take care of timeout issues here.
But Sql API doesn't have any method for it.
So how can I do it? I am using PostgreSQL driver.
I came across this. But I get error:
java.sql.SQLFeatureNotSupportedException: Method org.postgresql.jdbc4.Jdbc4Connection.setNetworkTimeout(Executor, int) is not yet implemented.
PS:
int[] modifyCount = sql.withBatch(batchSize, updateQuery) { ps ->
keyValue.each { k,v ->
ps.addBatch(keyvalue:k, newvalue:v)
}
}
In above code, when I try to add ps.setQueryTimeout(), error message says no such method defined.
Low-level timeouts could be defined through connection properties:
https://jdbc.postgresql.org/documentation/head/connect.html
loginTimeout Specify how long to wait for establishment of a database connection.
connectTimeout The timeout value used for socket connect operations.
socketTimeout The timeout value used for socket read operations.
These properties may be specified in either the connection URL or an additional Properties object parameter.
Query timeout. After connecting to the database you could define closure to be executed for each statement:
sql.withStatement{java.sql.Statement stmt->
stmt.setQueryTimeout( MY_SQL_TIMEOUT )
}

C# MVC5 classic ADO.NET when to open connection

I'm using MVC5 with classic ADO.NET objects such as sqldatareader and sqldataadapter and sqlconnection and so on....
My controllers are creating a connection while initializing because I need to send the request object to the class holding the sqlconnection for something irrelevant to the question so my controller has an override void
protected override void Initialize(RequestContext requestContext)
{
base.Initialize(requestContext);
db = new db(Request);
db.Connect();
}
Where db is my class and the method (connect) will create the sqlconnection object and open a connection...
and to close the connection I used the controller's dispose method as follows
protected override void Dispose(bool disposing)
{
base.Dispose(disposing);
if (db != null)
{
db.Close();
db = null;
}
}
and everything works fine then at one moment I got a weird server error (can't connect to db) please notice that my host is smarterasp.net
I can connect to database remotely using my home computer and I can connect to the web host as well so the problem is between my webhost and my database host, or between my application and my database host...
or it could be something related to the connection pooling even though the server error doesn't give me any details or stack trace(hens error is not inside my app thread)....
and I've fixed the problem by opening (remote iis) tab of smarterasp.net's control panel and clicked on (fix ACL) which I have no idea what it does but it fixed my problem.... temporarily :( unfortunately the problem reoccurred many times after that
so my question is in short format
is it good practice to open the connection while I'm initializing the controller and close it while the controller disposing???
and what do you think the error reason is??
finally I want to apologize if the question wasn't clear enough because English is not my first language (obviously)....
thanks a lot
so my question is in short format is it good practice to open the
connection while I'm initializing the controller and close it while
the controller disposing???
I do not think that is a good approach. You shouldn't open / close database connections and / or access the database from your controller. The controller should be as "thin" as possible. Additionally - the connection should be kept open for as short a period of time as possible and let ADO.NET connection pooling handle the details for you.
I also recommend wrapping your connection in a using block as it will implicitly call the close method:
using (SqlConnection connection = new SqlConnection(
connectionString))
{
SqlCommand command = new SqlCommand(queryString, connection);
command.Connection.Open();
command.ExecuteNonQuery();
}
You did not say what the exact error is. At first glance, you aren't even checking to see if the connection is open before you try closing it. You should check the connection state before you try to explicitly close it and this should happen outside of the controller. Though I recommend that you wrap your SqlConnection in a using block (mentioned above).
EDIT
I read your comment. You are trying to manage the connection within the context of the controller's lifecycle and I suspect this is your issue.
If you were using Entity Framework (or possibly an another ORM), an IoC with "per-request lifestyle" - then the IoC container would properly dispose your context (connection) at the end of each request, and serve a new instance at each new one.
Perhaps this an option you can explore if you want to manage your database connection this way.

Jena API with REST webservice using Jersey

I am using Jena API to get RDF data from Allegrograph Server. I have written a REST webservice using Jersey jar to get this data.
My java code for the webservice is as shown below:
#GET
#Path("/JENA")
#Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
public String getData() throws RepositoryException {
AGGraphMaker maker = new AGGraphMaker(conn);
AGGraph graph = maker.getGraph();
AGModel model = new AGModel(graph);
AGQuery agQuery = AGQueryFactory.create(query);
QueryExecution qe = AGQueryExecutionFactory.create(agQuery, model);
String result = null;
ByteArrayOutputStream byteArrayOutputStream = null;
try {
ResultSet rs = qe.execSelect();
While(rs.hasNext()){
byteArrayOutputStream = new ByteArrayOutputStream();
if("JSON".equalsIgnoreCase(outputFormat)){
ResultSetFormatter.outputAsJSON(byteArrayOutputStream, rs);
result = byteArrayOutputStream.toString();
System.out.println("Result is "+result);
} else if("XML".equalsIgnoreCase(outputFormat)){
ResultSetFormatter.outputAsXML(byteArrayOutputStream, rs);
result = byteArrayOutputStream.toString();
}else if("CSV".equalsIgnoreCase(outputFormat)){
ResultSetFormatter.outputAsCSV(byteArrayOutputStream, rs);
result = byteArrayOutputStream.toString();
}
}
} catch (Exception e) {
System.out.println(e.getMessage());
}
}
I get no results for the SPARQL query when I deploy this web service on Tomcat server and test it using REST client app on Chrome and firefox.
But the same code(absolutely no difference in webservice code and this main method code) if I write in a plain java class and run its main method, i am getting 36 results. I am not sure what the issue is.
Please help me in this regard.
You need to separate the concerns:
Move the service logic - the bit that actually queries Allegro graph - to a separate class so that it's properly encapsulated. The API for the class should reflect its responsibilities in your application, not the way that it happens to be working at the moment.
Write JUnit tests for the service class. This is important - it gives you confidence that your service is performing its job correctly, and keeps on doing so as you develop your application.
Write your Jersey method to invoke any service object that conforms to the API of your service class.
Write one or more HTTPUnit (or similar) tests to invoke your REST API. Ideally, you'll use a mock or test double instead of the actual service. What you want to test is whether the HTTP request reaches the right method, and that method delegates to the service object with the right arguments. You're then testing (and debugging!) a smaller number of concerns.
It's much better to work with small units of functionality with a clear idea of what their responsibilities are. And you should definitely learn to work with tests - it's a big win in the medium term, even if it means a bit more learning up front!

How to cache a Memcached connection using the java spymemcached client

I am learning how to cache objects using memcached with the spymemcached client from spymemcached examples
MemcachedClient c=new MemcachedClient(new InetSocketAddress("hostname", portNum));
// Store a value (async) for one hour
c.set("someKey", 3600, someObject);
// Retrieve a value (synchronously).
Object myObject=c.get("someKey");
I have noted that each time I want to cache or retrieve an object I create a new memcached client which am assuming is a new connection and that memcached has no connection pooling mechanism therefore users are advised to cache the connections to decrease overhead for reconnecting from this question opening closing and reusing connections.
My question is how do I cache this connection? Can someone please give me an example I can start from.
If you are wondering what I have tried, I tried to put my connection in the memcached but then I realized that I have to create a connection to get it. :)
Thanks in advance.
I have noted that each time I want to cache or retrieve an object I
create a new memcached client which am assuming is a new connection
Don't do this; spymemcache uses a single connection for ALL I/O to and from memcache; it's all done asychronously; from spymemcache docs...
Each MemcachedClient instance establishes and maintains a single
connection to each server in your cluster.
Just do the following once in your app; make sure the client is available to other services in your app so they can access it.
MemcachedClient memClient = new MemcachedClient(new InetSocketAddress(host, port));
Use memClient for I/O with memcache; no need to create a new instance of MemcachedClient each time; done. The link you provided answers all of your questions.
What is your deployment? web-app or standalone?
This just means that you should use reuse the connections that you open as opposed to opening a connection for each request. It doesn't make sense to store a connection instance in memcached.
Cacheing the connection in the case means caching it in your application (keeping it in memory and open), not actually storing the connection in memcached.
I did a little more research and stumbled on this question
Then I came up with my solution as,
first created a contextlistener
public class ContextListener implements ServletContextListener {
#Override
public void contextInitialized(ServletContextEvent sce) {
Memcached.createClient();
}
#Override
public void contextDestroyed(ServletContextEvent sce) {
}
}
then i added the listener to the deployment discriptor by adding these lines to web.xml
<listener>
<description>Used with memcached to initialize connection</description>
<listener-class>com.qualebs.managers.ContextListener</listener-class>
</listener>
I created a class Memcached and added these methods
static void createClient() {
try {
client = new MemcachedClient(new InetSocketAddress("localhost", 11211));
} catch (IOException ex) {
Logger.getLogger(Memcached.class.getName()).log(Level.SEVERE, ex.getMessage(), ex);
}
}
static MemcachedClient getClient() throws IOException {
return client;
}
Now anywhere I need to use memcached connection just call Memcached.getClient()
I hope that will help anybody else out there with the same question.