Wednesday, December 30, 2009

A Little Too Ambitious

I have not blogged in a while because of finals and work. I may have been a little too ambitious with this whole blogging thing while I'm going to school full time and working overtime. I am going to try to keep on trucking though.

I think I did really well my first semester of graduate school. I received an 'A' in Software Architecture, and 'A' in Multiparadigmatic Programming, and a 'B+' in Computational Geometry. I learned a lot this semester. Multiparadigmatic programming had to be my favorite. We learned about functional programming with scheme, and process-oriented programming in occam. We also did presentations on a language we had never programmed in before. I did my presentation on Objective-C , though I did not care for it much. The presentations definitely got me interested in erlang, go, and scala. I enjoy these newer languages that have concurrency built into the language.

Work has set me to a Spring MVC project that also involves Drools, and I have been putting in a lot of hours. I am psyched that I get to work on all these awesome technologies that I have wanted to work with. I convinced the powers that be, to use this as a pilot project to start centralizing business logic in the Guvnor Business Rules Management System. As I progress, I will try to post some Spring and Drools/Guvnor gotchas.

Monday, November 9, 2009

Authentication in Jersey

I recently added authentication to unidata-rest by walking through the examples provided by Marc Hadley, and I thought I would share my experience. If you have never had to implement authentication in Jersey before, I hope this will help. I have shortened it for brevity, but you can check it out if you like.


@Path("{account}")
public class AccountResource {
private static final String USER_ROLE = "UNIDATA_REST_USER";

@GET
@Produces("application/atom+xml")
public Response getAtomFeed(
@Context SecurityContext sc,
@DefaultValue("")
@PathParam("account") String account) {
Response response;
if(!sc.isUserInRole(USER_ROLE)){
throw new WebApplicationException(Response.Status.FORBIDDEN);
}
...
return response;
}
...
}


Ok, this is where things get a little confusing. In the web.xml file you need to define a security-constraint where you define the resources you would like to secure as well as their associated roles. You also need to define a login-config and a security role.

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:applicationContext.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<listener>
<listener-class>org.springframework.web.context.request.RequestContextListener</listener-class>
</listener>
<servlet>
<servlet-name>ServletAdaptor</servlet-name>
<servlet-class>com.sun.jersey.spi.spring.container.servlet.SpringServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>ServletAdaptor</servlet-name>
<url-pattern>/resources/*</url-pattern>
</servlet-mapping>
<security-constraint>
<display-name>UniDataResources</display-name>
<web-resource-collection>
<web-resource-name>UniDataResources</web-resource-name>
<description>UniData RESTful Resources</description>
<url-pattern>/resources/*</url-pattern>
<http-method>GET</http-method>
<http-method>POST</http-method>
<http-method>HEAD</http-method>
<http-method>PUT</http-method>
<http-method>OPTIONS</http-method>
<http-method>TRACE</http-method>
<http-method>DELETE</http-method>
</web-resource-collection>
<auth-constraint>
<description>Have to be a UNIDATA_REST_USER</description>
<role-name>UNIDATA_REST_USER</role-name>
</auth-constraint>
</security-constraint>
<login-config>
<auth-method>BASIC</auth-method>
<realm-name>file</realm-name>
</login-config>
<security-role>
<description/>
<role-name>UNIDATA_REST_USER</role-name>
</security-role>
</web-app>


I am using GlassFish, but I am sure there is a similar step for most app servers.
Now for the default configuration, I just used the file realm to keep things simple and added a user in there called "restuser" and assigned the UNIDATA_REST_USER group to it. In order to map from the role-name to a group you need to define a mapping. I added a sun-web.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE sun-web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Application Server 9.0 Servlet 2.5//EN" "http://www.sun.com/software/appserver/dtds/sun-web-app_2_5-0.dtd">
<sun-web-app error-url="">
<security-role-mapping>
<role-name>UNIDATA_REST_USER</role-name>
<group-name>UNIDATA_REST_USER</group-name>
</security-role-mapping>
<class-loader delegate="true"/>
<jsp-config>
<property name="keepgenerated" value="true">
<description>Keep a copy of the generated servlet class' java code.</description>
</property>
</jsp-config>
</sun-web-app>


I think eventually I would like to refactor the security check into an AOP Aspect, as well as have different roles for GET, PUT, POST, and DELETE. In my next post, I'll talk about using Rome to connect to this service.

Saturday, November 7, 2009

UniData REST

I am currently working on a generic RESTful web service for UniData. For those unfamiliar with UniData, let me explain. UniData is a multivalued database. For a programmer, that means everything you know about SQL, relational calculus, normal forms, referential integrity, data type integrity, ORM and pretty much any cool new modern technology goes right out the window.

However, the system does have a Java API, which you can use to query and get XML back. My idea is to abstract away the more gruesome details of this API and expose the data in a uniform manner through HTTP. When querying a collection, you get an Atom feed back with each entity containing a link to the actual resource. The project is implemented using Java, Jersey, Spring, and the UniObjects for Java API. I have only implemented GET so far, but I am working on PUT, POST, and DELETE. If you are interested, I have open sourced the code through google code the project name is unidata-rest.

Thursday, November 5, 2009

NOP

I want to make a conscience effort to be part of the software development community, and I believe the best way to utilize what I have learned is to post what I have learned -> make a fool of myself -> learn -> repeat. Please be gentle, it's my first time.