Uncategorized

Hibernate, Spring Security and list paging

Of the dangers of using Spring Security, Hibernate and paging

Here’s a tricky one; we need to do paging on one of our listing pages. The obvious solution was the following, which is a common pattern:

@Secured(value={Roles.PERSON_READ})
public List<Person> getPeople(int offset, int max) {
   Criteria criteria = getSession().createCriteria(Person.class);
   criteria.setFirstResult(offset;
   criteria.setMaxResults(max);
   return criteria.list();
}

Can you see it? The bug I mean? See it? How about now? Now?

The problem lies in the @Secured annotation. This little guy is SOOOOOO useful for us, but it will burn you once in a while. This annotation will proxy the method and remove any objects which you aren’t allowed to get back. i.e.: It will filter the returned list.

I guess you see it now: If I ask Hibernate to give me rows from 20 to 50, I am in no way garanteed to get back 30 results since Spring will remove items from my list AFTER the query has run and Hibernate has created the list.

The solution? I guess that really depends on your own requirements. Given our own volume and requirements, pulling out all the data on each page request is acceptable (we have a query cache enabled, so it’s not as bad as it may sound).

Testing http calls with NanoHTTPD

Well, we finally got tired of over engineering 2 lines of code just to make it testable. I’m talking about those classes which have some http calls done throughout some code; intermingled with maybe some error handling, some conditional logic, etc ..

In other words, you want to test everything around the http call, but don’t care about the call actually being made or not. Yes, yes, yes. I know; just abstract out the call to another class, then mock that … pain in the ass! Use Spring rest template. Pain in the ass and overkill and doesn’t work well in multi threaded setups.

The solution we now use here is called NanoHTTPD which is a tiny, tiny, miniscule http server which can easily run inside a suite of tests. It can easily be extended to intercept calls. For example, we have:

  • A HitCountingNanoHTTPD implementation which counts how many times the server was hit (good for testing that a multi-threaded class actually does the amount of call outs you need)
  • Another implementation that given a file with key value pairs, will set the response headers using that file.
We use it in the following way:
class HttpHitTest {
     private NanoHTTPD nano;

     @Before
     public void setup() throws Exception {
          nano = new Nano(9999);
     }

     @After
     public void tearDown() throws Exception {
          nano.stop();
     }

     @Test(expected=NoSuchFileException.class)
     public void testHttpHit() {
           HttpGetClass hgc = new HttpGetClass();
           hgc.doGet("http://localhost:9999/resources/myfile.mp3");
      }
}

See the beauty! NanoHTTPD simply exposes all files found in it’s working directory. So all test resources simply go into a folder inside the project and the CI server runs it without a hitch. Bonus: test performance and speeds are not affected (this thing is just so tiny).

As well, here’s what an extension to NanoHTTPD would look like. This example is a very simple something I whipped up to count how many times a server is hit (I needed the counter to be thread safe)

public class HitCountingNanoHttpd extends NanoHTTPD {
	private AtomicLong hits = new AtomicLong(0);

	public HitCountingNanoHttpd(int port) throws IOException {
		super(port);
	}

	@Override
	public Response serve(String uri, String method, Properties header, Properties parms, Properties files) {
		hits.incrementAndGet();
		return super.serve(uri, method, header, parms, files);
	}

	public long getHitCount() {
		return hits.longValue();
	}
}

ActiveMQ issues update

This is a follow up to a previous entry I made about problems experienced with ActiveMQ 5.

First, let’s get this out of the way: I get what open source is; I get that there are a LOT of people who invest a LOT of their personal time; I get that while these people are working hard, I’m climbing cliffs instead of helping them even though I have the capacity and knowledge to do so; I get that criticism isn’t cool, especially when voiced publicly; and I get that I can be abrasive :).

With that said, in the last couple of months, we’ve worked hard to give ActiveMQ an nth chance. Unfortunately to no avail. The good folks at ActiveMQ have mentioned that we may be the first to use ActiveMQ the way we are. There has been a lot of effort into debugging the problem and there may be light at the end of the tunnel, but a fix is most likely a ways off.

The good news (for us that is), is that we have decided to keep ActiveMQ but in single broker configurations. Obviously, this is far from ideal, but all our products are currently programmed and architected around the possibility of a broker being unavailable, so we’ll keep on programming in the safeguards. I repeat: ActiveMQ is awesome in a single broker or embedded scenario.

ActiveMQ – not what it used to be?

I’ve posted a quick update to this here.

When I started this job a couple years ago, we were mildly invested in ActiveMQ with a single queue for some mission critical work. Since I’d had good experience with ActiveMQ 4.x in previous jobs, I didn’t hesitate to push forward and suggest we invest more in ActiveMQ and architect solutions around it’s usage.  After all, I had experienced flawless performance and up time with 4.x.

Forward 2 years: We now have 30 or so topics and queues with moderate usage and it’s incapable of staying up more than a few minutes when configured as a network of brokers.

We’ve gone so far as paying the big bucks to get consulting from the folks at FuseSource. Unfortunately, the suggestions and help have been … uh … expensive with no results at all.

The setup

The setup is relatively straightforward:

  • 3 brokers in different cities in different countries which need to work as a network of brokers.
  • Latency can be high (80ms)
  • Java clients using the client libraries over the tcp protocol
  • C++ clients using the ActiveCPP library
  • A few dozen topics and queues
  • No big messages (5MB max with the average being closer to a few hundred k)
  • Moderate traffic (a few hundred thousand messages per day overall)

Everything performs well enough in a single broker setup, but that’s un-acceptable for us.

What was done

Pretty much everything :)

Our expert had us upgrade to the latest version (5.4.2) with horrendous results; the KahaDB would continuously corrupt. Let me say this about trying to fix a basic problem with a minor upgrade: It’s bullshit. If version 5.4.1 can’t do something as straightforward as we’re trying to do, some suggestion about upgrading a point release isn’t going to do anything.(edit: The language was harsh. As it turns out, the minor upgrade was to adress another issue and not the network of brokers issue). And don’t be mistaken; our usage is basic and reasonable and definitely falls into the advertised set of features touted by ActiveMQ.

What’s next

We’re throwing all our weight behind JBoss HornetQ right now. The team is pretty psyched because they’re all fed up and disillusioned with the ActiveMQ product. Obviously, the migration path will not be easy, but at least we should no more be prisoner to a buggy product. (edit: Again, harsh: I’d say ‘prisoner to a product that doesn’t work in our configuration’)

Reading ‘The 21 Irrefutable Laws of Leadership’

Firstly, the use of the word ‘Irrefutable’ given a subject mater that is so subjective seems a bit odd.

Second, the atheist in me gets easily annoyed at a book that uses pastors and churches in examples …

But I’ll stick to it until the end :)