For while now, I haven't written any music. Not a bean. Not even a one line ditty to be stored away under some suitably irrelevant name, and referenced at some point in the distant future. Nothing.
Sure, I've done music. PeopleAreThings are currently recording an album ( please, download 'Games'. For me) - we've been 'currently' recording an album for nearly 2 years now - and I've done bits and pieces for the Hot Donkey boys, including a couple of remixes. But I haven't sat down and actually concentrated on writing something, from scratch, and finishing it off to a state that I'm happy with. It just hasn't happened.
This disturbs me on a number of levels. I've always been able to sit down for a few minutes, record something I'm happy with, and use it as the basis for something bigger, even if I'm not able to progress the idea further at that moment in time.
It's not like I don't have the time. I have plenty of time. I get into work at about 0830hrs, and I'm usually done by 1730hrs on most days. This means I have a good 4 or 5 usable hours before I have to start the whole cycle all over again.
No, the thing that scares me the most is that for a while now, I just haven't been excited by anything I've written. I've sat down, tried things out, shrugged my shoulders and gone and done something else. I took a brief foray into piano-based songs, rather than guitars, and that worked well for a little bit. But now I need something new to keep me occupied.
I just have no idea what it's going to be.
Oh, and P.s. Shameless Plug
Benemon
A selection of musings, whether technical, musical, or general to keep you occupied when you should be doing something productive.
Wednesday, 22 August 2012
Wednesday, 13 June 2012
Dates and Timestamps
Just a quick one today folks. Had a stupid little problem pop up when converting some HQL to native SQL. Even though I was still executing the SQL via the Hibernate session, the query wasn't returning any results.
Hmmm. Suspicious. Query which used to work perfectly now broken.
Obviously, something had gone awry during the conversion. Turns out that when executing the query as HQL, the java.util.Date object being passed in as a bind would convert to an Oracle time stamp quite happily. This would allow some cheeky Date/Time arithmetic to take place, and we'd get a result. When passing the same Date object in as a parameter to a native SQL query, Hibernate seems to effectively call toString() on the object, simply giving us the Date, without any hours, minutes, or seconds. Which is entirely not useful.
To solve this irritating little issue, I did this:
You can then just pass the TimeStamp object into your SQL query as a parameter as you normally would when executing native SQL via the Hibernate Session.
I guess this is due to the fact that when executing SQL queries through the Hibernate session, you lose all the implicit intelligence that Hibernate brings to the table. When you start talking native SQL, the type conversions that would usually take place behind the scenes just don't happen, as I assume Hibernate is electing to trust your judgement as the developer, rather than automatically assume you want your parameters converted. There are clearly going to be other ways to address this issue, but doing it in code like this was the most appropriate to me.
Hmmm. Suspicious. Query which used to work perfectly now broken.
Obviously, something had gone awry during the conversion. Turns out that when executing the query as HQL, the java.util.Date object being passed in as a bind would convert to an Oracle time stamp quite happily. This would allow some cheeky Date/Time arithmetic to take place, and we'd get a result. When passing the same Date object in as a parameter to a native SQL query, Hibernate seems to effectively call toString() on the object, simply giving us the Date, without any hours, minutes, or seconds. Which is entirely not useful.
To solve this irritating little issue, I did this:
Date myDate = new Date(); // in reality, this is a date retrieved from the underlying database using a custom util, so as to avoid any timing issues
java.sql.Timestamp timestamp = new java.sql.Timestamp(myDate.getTime());
You can then just pass the TimeStamp object into your SQL query as a parameter as you normally would when executing native SQL via the Hibernate Session.
I guess this is due to the fact that when executing SQL queries through the Hibernate session, you lose all the implicit intelligence that Hibernate brings to the table. When you start talking native SQL, the type conversions that would usually take place behind the scenes just don't happen, as I assume Hibernate is electing to trust your judgement as the developer, rather than automatically assume you want your parameters converted. There are clearly going to be other ways to address this issue, but doing it in code like this was the most appropriate to me.
Friday, 1 June 2012
Hibernate and State Pattern Persistence
Yesterday, I started looking at implementing a State Pattern using Hibernate as the persistence mechanism. For the most part, I was following Joe Kelley's excellent blog post on the subject here, in which he outlines two possible implementations using both an Integer, and the org.apache.commons Enum type.
Both of these implementations are good solutions to the problem - they get the job done with minimal fuss.
However, I thought it might be useful to write about a third possible implementation, hinted at in Mr. Kelley's post - still based on his work, but tweaked to use a standard Java Enum as its main currency of change. It has the advantages of the described Enum implementation, but without bringing in extra libraries, or adding more complication than is strictly necessary.
To get this to work, realistically you only need to alter your implementation of the custom UserType. There are 4 things we need to change:
Both of these implementations are good solutions to the problem - they get the job done with minimal fuss.
However, I thought it might be useful to write about a third possible implementation, hinted at in Mr. Kelley's post - still based on his work, but tweaked to use a standard Java Enum as its main currency of change. It has the advantages of the described Enum implementation, but without bringing in extra libraries, or adding more complication than is strictly necessary.
To get this to work, realistically you only need to alter your implementation of the custom UserType. There are 4 things we need to change:
- Remove any static ints from your custom UserType. You won't need them.
- Alter the public int[] sqlTypes method to return a Types.VARCHAR.
- Alter the public Object nullSafeGet to convert the returned String value into your Java Enum value.
- Alter the public void nullSafeSet method to convert the concrete implementation of your State object to the String value required for persistence.
The first change is simple enough. We're moving responsibility for the actual values we're storing out of our UserType implementation, and into an Enum.
The second is to change the sqlTypes method. Here, we're merely telling Hibernate that what we expect our transactions with the data layer to be of type VARCHAR.
The second is to change the sqlTypes method. Here, we're merely telling Hibernate that what we expect our transactions with the data layer to be of type VARCHAR.
public int[] sqlTypes()
{
return new int[] {Types.VARCHAR};
}
The most interesting changes are the ones for nullSafeGet and nullSafeSet. We're using the GenericStateEnum to hold possible state values to be persisted. Using this method, you can manage explicitly what is being persisted, and enforce data-level constraints if you want.
nullSafeGet is fairly easy to understand - all we're doing here is taking our String value out of the ResultSet, attempting to convert it to an Enum value, and running a switch / case over it to determine which implementation of AbstractGenericState we should be returning to the calling class.
public Object nullSafeGet(ResultSet rs, String[] names, Object owner) throws HibernateException, SQLException
{
final String stateStr = rs.getString(names[0]);
if (rs.wasNull())
{
return null;
}
GenericState state = null;
GenericStateEnum stateValue = GenericStateEnum.valueOf(stateStr);
switch(stateValue)
{
case STATEONE:
state = AbstractGenericState.STATEONE;
break;
case STATETWO:
state = AbstractGenericState.STATETWO;
break;
default:
throw new RuntimeException("Could not find GenericState for value " + stateStr);
}
return state;
}
The method nullSafeSet is the interesting one:
public void nullSafeSet(PreparedStatement ps, Object value, int index) throws HibernateException, SQLException
{
if (value== null)
{
ps.setNull(index, Types.VARCHAR);
}
else
{
GenericState state = (GenericState) value;
GenereicStateEnum stateEnum = null;
if (state.isStateOne())
{
stateEnum = GenericStateEnum.STATEONE;
}
if (state.isStateTwo())
{
stateEnum = GenericStateEnum.STATETWO;
}
ps.setString(index, stateEnum.toString());
}
}
Now, I'm not particularly happy with this method at the moment in the way it's not particularly flexible, and I'm currently pondering ways to improve this. For example, what if we need to add another state? It's a relatively small change for sure, but is it one we can avoid?
Personally, I think the way forward with this is to use Reflection to work out the relationship between the implementation of GenericState used in the method, and the GenericStateEnum value. Certainly, it's not beyond the realms of possibility to solve. But as a starting point for using bog-standard Java Enums for State Pattern persistence using Hibernate, I've found it pretty effective.
Personally, I think the way forward with this is to use Reflection to work out the relationship between the implementation of GenericState used in the method, and the GenericStateEnum value. Certainly, it's not beyond the realms of possibility to solve. But as a starting point for using bog-standard Java Enums for State Pattern persistence using Hibernate, I've found it pretty effective.
Have a go, see what you think.
Tuesday, 29 May 2012
Mocking Basic HTTP Authentication in SoapUI
Working on a project this week, I came across an interesting little problem; namely, a web service we need to talk to in a production environment mandates basic HTTP authentication. Here's the kicker - we don't have ready access to a reference version of that web service within our development environment.
So what do we do?
Well, like many projects, we use the excellent SoapUI to exercise our published endpoints, and drive the functionality within our system. We make heavy use of SoapUI's Mock Service functionality to generate endpoints, and send our SOAP messages to these mocks during developer testing. The ability to send back different Responses based on the data we chuck out is invaluable to us, as it allows us to test the internal workings of our system under many different use cases, giving us a lot of confidence in what we've written.
Back to the problem at hand, I quickly discovered that whilst Basic HTTP Authentication is supported as an option sending SOAP messages out of SoapUI, Mock Services do not currently (as of version 4.0.1) support decoding and validation of user credentials passed over in the HTTP Request header. To get around this, I ended up writing a small piece of Groovy that sits in the OnRequest Script tab on the Mock Service you want to wrap.
Essentially, what we want to do is pull apart the Request headers, extract the header marked 'Authorization' (note Americanised spelling), parse it to remove excess padding and useless data, then decode it back into a String object to be interrogated.
import com.eviware.soapui.support.types.StringToStringsMap;
// Get the global properties
def globalProperties = com.eviware.soapui.model.propertyexpansion.PropertyExpansionUtils.globalProperties;
String httpUsername = globalProperties['httpUsername'].value;
String httpPassword = globalProperties['httpPassword'].value;
// Get the Request Headers
StringToStringsMap headers = mockRequest.getRequestHeaders();
headers.each
{
if (it.key.equals("Authorization"))
{
// Pull the Auth string out of the request, and tidy it up
String content = it.value;
String [] contentArray = content.split();
if (contentArray.length == 2)
{
// Decode the authorisation String
String base64Enc = contentArray[1].minues("]");
byte [] decoded = base64Enc.decodeBase64();
String s = new String(decoded);
if (httpUsername != null && httpPassword != null)
{
def credentials = s.split(":");
assert credentials[0].equals(httpUsername);
assert credentials[1].equals(httpPassword);
log.info("Mock Service authenticated request for credentials: " + s);
}
}
}
}
And that's it really. As long as you're setting up your HTTP Requests to use Basic Authentication, and you place properties (listed above as 'httpUsername' and 'httpPassword') into the Global Property store containing your expected credentials, then you should be good to go.
Hopefully this will help someone else out. If all you want to do is validate the fact your code is sending out the right user credentials, this should do the trick.
Subscribe to:
Posts (Atom)