How to output cache files and do custom logging - jboss/java project - java

I am a .Net developer who is starting to do more and more Java development at work. I have a specific question about caching that I hope you guys can solve or offer suggestions. We are starting a java project that will be deployed on a Linux box running JBoss. We are planning ahead and try to think about our caching strategy. One thing we would like to do is to output cache the pages since our content will likely be cacheable for 8 hours or so. I started looking at mod_cache and this does what we want to do. The one other requirement that I need to meet is that for every request, I need to do some custom logging. I need the basic request URL and then some other business logic stuff and stuff it into a database. My questions are these:
1) How can i put code at the mod_cache level to kick off the custom logging process?
2) I want to queue these logging messages up somehow since i don't want to go to the db with every request. What would be the best way to tackle this?
I would appreciate any suggestions or solutions if you got 'em!

I assume your planned setup is Apache httpd -> mod_cache -> mod_proxy/mod_jk -> JBoss
1) You can't, since mod_cache at the Apache level does not even get down to calling Java. Hence, you would need to check if mod_cache itself has some logging facility which you can hook something in, or you would need to modify mod_cache and recompile it. This has nothing to do with Java and I don't think you can do it in Java.
2) Again, this is not a Java question when mod_cache is handling the response on its own without calling JBoss.
JBoss/Catalina/Tomcat are pretty fast when it comes down to delivering pages rendered by JSPs or other web frameworks. Set the cache expiration date and let the browser handle the cache.

You might look into using memcached instead. I don't know if there is a Tomcat/JBoss wrapper module for this program or not. It will let you cache just about any data that you can serialize and make a string key value for.
You have to write an accessor for what you need, which tries to pull stuff out of the memcached process, and/or calls a generator function upon cache miss (as well as caching the generator's result). Within this accessor, you could log cache hits and misses.
The memcached daemon is written in C, of course, so it won't "mark and sweep" itself to death holding onto data, unlike java (or most of the other "modern" language runtimes).
On the other hand, maybe mod_cache has some logging hooks. Maybe you should look into that, as this will lighten the load on your java process.
Is this close to the sort of thing you are looking for?

Related

Isolate Liferay access to frontend and REST URL's

I have a Liferay instance running on a URL like example.org/app. This instance does have a REST API that would normally be running under example.org/app/o/restpath.
The way the server running this instance is that the frontend is accessible without restrictions from the outside, however the REST API is only accessible from the inside the network under a URL like example.org/rest.
I need to make sure that it is impossible to access the REST API with example.org/app. I should also be impossible to access the frontend with example.org/rest. Does anybody have any suggestions?
There are tons of ways of doing that, the best one will depend on your stack, preferences and abilities.
A reverse proxy is the first that comes to mind, bearing in mind that is is normally better if your app has control of who can access it. So a wrapper or a filter checking who is accessing would help. But even then, is the filter to be put on the main application or on your module? That is an evaluation that needs to come from you.
You can also combine the proxy strategy, with a filter, just in case one day you are tuning up your proxy and let something through. You can also decide change your proxy server too..
Or your company already have a proxy that enables traffic going out, and would be easier if that proxy was to have access...
Your servlet contained might also be able to provide such control, so you do not actually need a proxy.
Although I would feel more comfortable if that kind of feature was in the application layer itself, like a wrapper for your component and that wrapper provides the service, a filter, or even a method in in the entry-point, while the others are just extra and to reduce load.
Some companies have networks devices that go up several layers of the network stack, those have lots of potential to help here too, IDS would be able to provide alarms, triggers and such...
As it stands, one would need more information to help you more, even in what you mean by "ensure" ( how far this assurance need to go, like are you thinking about passwords, certificates, IDS, or a simple approach like the mentioned ones ), but I guess that covers it.

Play framework concepts

Could someone explain how the web apps work on play framework example? The things I misunderstand:
1)Which part of the code(I mean code from examples listed on play framework site) allows many users to use the same app at same time?
2)For example I have a program : a textField, button and list. Write in textfield, press button and the text is added to the list. Every user should have own list, but where should I store the data if it's objects, in memory? In DB? In session/cookies? And how this data should be recognized, by session of? Are there any good examples?
I think you should read the documentation and search the web a bit more about Play to be honest. Here are a few pointers:-
Play will use a default thread pool to serve requests. All actions are asynchronous - meaning (as long as you do not block a thread in the action) a Play app should be able to serve a large volume of requests (depending on your machine resources), as these threads get quickly reused to serve other requests
Play is designed to be stateless so no Session (in context of Java servlet session that is). Play does not use Java servlet spec. (actually one of the original drivers Play was created was of limitations of Servlet spec)
In terms of your own application, what are you going to do with that data you have collected later? What do you need it for? That should help you determine where to store it (if at all). If you want it just for session scope then you could use session cookie - see the docs). If you want it later (ie. when user comes back to site) then you could put it in a store of some kind. Again, see the docs.
There are loads of articles on Play's architecture. And the official docs are quite good at pointing you in the right direction for most use cases.
The Lightbend has some good resources and there are loads of Activator templates to provide codes samples.
Here is the simple CRUD template which might help you.

Multi Threading vs JMS Queue for Asynchronous Logging

Requirement: Log events like Page Views and form Submits. Each page has ~1 second SLA. The application can have 100's of concurrent users at a time.
Log events are stored into the Database.
Solution: My initial thought was to use an async logging approach where the control returns back to the application and the logging happens in a different thread (via Spring's Thread pool task executor).
However someone suggested using JMS would be a more robust approach. Is the added work(Setting-up queue(s), writing to the queue(s), reading from the queue(s)) required when using this approach worthwhile?
What are some of the best practices / things to look out for (in a production environment) when implementing something like this?
Both approaches are valid, but one is vulnerable if you app unexpectedly stops. In your first scenario, events yet to be written to the database will be lost. Using a persistent JMS queue will mean that those events will be read from the queue and persisted to the database upon restart.
Of course, if your DB writes are so much slower than placing a message of similar size on to a JMS queue, you may be solving the wrong problem?
Using JMS for logging is a complete mismatch. JMS is a Java Abstraction for a Middleware Tool like MQ Series. That is complete overkill, and will let you go through a setup and configuration hell. JMS also lets you place messages in a transactional context, so you already get quickly the idea that JMS might be not much better than Database writes as #rjsang suggested.
This is not that JMS is not a nice technolgy. It is a good technology where it is applied properly.
For Assynchronous logging, you better just depend on a Logging API that directly supports it like Log4j2. In your case, you might be looking to configure a AsyncAppender with a JDBCAppender. Log4j2 has many more appenders as additional options, including one for JMS. However, by at least using a Logging abstraction, you make that all configurable and will make it possible to change your mind at a later time.
In the future we might have something similar to Asynchronous CDI Events, which should work similar to JMS, but would be much more lightweight. Maybe you can get something similar to work by combining CDI Events with EJB Asynchronous Methods. As long as you don't use EJB's with a remote interface, it should also be pretty lightweight.
You could give it a try using fully async and external tooling if you want to. If you have to stick to your SLA at any price and resilience is important for you, you could try using either logstash or process your logs offline. With doing so, you decouple your application from the database and you are no longer depending on the database performance. If the database is slow and you're using async loggers, queues might run full.
With logstash using GELF the whole log processing is handled within a different (or even remote) JVM. Offline processing (e.g. you write CSV logs) allows you to load the log data afterwards into the database.

Recommendations on providing integration api

Are there any recommendations, best practices or good articles on providing integration hooks ?
Let's say I'm developing a web based ordering system. Eventually I'd like my client to be able to write some code, packaged it into a jar, dump it into the classpath, and it would change the way the software behaves.
For example, if an order comes in, the code
1. may send an email or sms
2. may write some additional data into the database
3. may change data in the database, or decide that the order should not be saved into the database (cancel the data save)
Point 3 is quite dangerous since it interferes too much with data integrity, but if we want integration to be that flexible, is it doable ?
Options so far
1. provide hooks for specific actions, e.g. if this and that occurs, call this method, client will write implementation for that method, this is too rigid though
2. mechanism similar to servlet filters, there is code before the actual action is executed and code after, not quite sure how this could be designed though
We're using Struts2 if that matters.
This integration must be able to detect a "state change", not just the "end state" after the core action executes.
For example if an order changes state from In Progress to Paid, then it will do something, but if it changes from Draft to Paid, it should not do anything.The core action in this case would be loading the order object from the database, changing the state to Paid, and saving it again (or doing an sql update).
Many options, including:
Workflow tool
AOP
Messaging
DB-layer hooks
The easiest (for me at the time) was a message-based approach. I did a sort-of ad-hoc thing using Struts 2 interceptors, but a cleaner approach would use Spring and/or JMS.
As long as the relevant information is contained in the message, it's pretty much completely open-ended. Having a system accessible via services/etc. means the messages can tap back in to the main app in ways you haven't anticipated.
If you want this to work without system restarts, another option would be to implement handlers in a dynamic language (e.g., Groovy). Functionality can be stored in a DB. Using a Spring factory makes this pretty fun and reduces some of the complexity of a message-based approach.
One issue with a synchronous approach, however, is if a handler deadlocks or takes a long time; it can impact that thread at the least, or the system as a whole under some circumstances.

Good way to make Authentication and Authorization information available between application layers

I have a web application running on Google App Engine (GAE) for JAVA. I'm authenticating the client at the Servlet layer but would like to make the client information available to my business and data layers without having to pass the client object through the arguments of every single function.
I'm considering setting up a "session" type object using ThreadLocal. That way any function can just say something like:
CurrentUser.getRoles();
Is this a good way to do this or is there something else that is a more accepted solution?
Thanks!
This will probably work and will be utterly convenient, but usually I try to avoid ThreadLocals for similar use cases as much as I can. Reasons:
You code just suddenly starts to depend on the fact that underlying container uses different threads for different users. If the container will start using NIO, different type of threads (e.g. green threads which would not be mapped into java.lang.Thread on some exotic JVM), etc. you will be out of luck.
ThreadLocals tend to be forgotten to be cleaned up after using them. So if your server will spike in usage and one of the users will put lots of stuff into 'cache', you might run out of RAM.
As a consequence of not cleaning up after a request, ThreadLocal can expose security vulnerability assuming the other user would jump unto the same thread.
Finally, I believe ThreadLocals were designed for environments where you have an absolute control over threads in your context, and this use case is just so far beyond.
Unfortunately I don't know much about GAE to suggest a viable alternative, sorry about that!
ThreadLocals are a completely accepted way to store such information. Besides us I also know from Alfresco that they do it.
If using Spring and Spring Security works for you then you can use the code I've built as part of jappstart for your authentication/authorization. This information is then available via Spring Security.

Categories

Resources