Sunday, June 19, 2011
Developing and Testing in Android Against Local Web Services
http://denimgroup.posterous.com/android-dns-setup-for-developing-and-testing
Thursday, November 18, 2010
Recommend using Fluent Nhibernate
It is definitely helpful in preventing configuration typos.
There other contrib projects for Nhibernate that I have found extremely useful
including Nhibernate Validator and NHibernate Spatial.
Nhibernate is independent from Hibernate and it doesn't benefit from a large corporate backer. Due to this Nhibernate and contrib projects are spread across multiple websites.
Main Site:
Fluent Nhibernate:
Friday, January 22, 2010
Unit Testing Restful Web Services using Restlet and Jaxb
Here is link to javadoc that discuss this: http://java.sun.com/javase/6/docs/api/javax/xml/bind/JAXBContext.html
@XmlRootElement
public class Sample {
@XmlElement(name = "value")
private String val;
public Sample() {
}
public Sample(String val) {
this.val = val;
}
public String getVal() {
return val;
}
public void setVal(String val) {
this.val = val;
}
@Override
public String toString() {
return "Sample [val=" + val + "]";
}
}
{
JAXBContext context1 = JAXBContext.newInstance(Sample.class);
JAXBContext context2 = JAXBContext.newInstance("com.acme.businessobjects");
Marshaller m = context1.createMarshaller();
m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
Sample sample = new Sample();
sample.setVal("Hello");
final File f = new File("src/test/java/com/endurotracker/gwt/test/rest/api/sample.xml");
m.marshal(sample, new FileOutputStream(f));
Unmarshaller um = context2.createUnmarshaller();
um.setSchema(getSchema("Sample.xsd"));
Object bce = um.unmarshal(f);
m.marshal(bce, System.out);
}
Friday, January 1, 2010
Restful Web Services using Asp.net MVC
Microsoft's new Asp.net MVC framework can also easily support Restful Web Services.
Controller actions can be called from Ajax based based websites using Javascript.
For example if you create a controller named APIController with a method:GetUsers,
then a Restful url would be /API/GetUsers. To implement your Restful Web Services using Asp.net MVC, take a look at these excellent write ups,
create-rest-api-using-asp-net-mvc-that-speaks-both-json-and-plain-xml, and
Creating-a-RESTful-Web-Service-Using-ASPNet-MVC-Part-1-Introduction
Thursday, December 31, 2009
Restful Web Services using Restlet Framework
However, Microsoft has worked with the team behind Restlet and has enabled interoperability between Azure ADO.net and Restlet.
microsoft-selects-restlet-to-show-rest-interoperabilityOther big companies like Google also use the Restlet framework for writing Web Services in a Restful way. I always lean towards projects that are well documented and the Restlet framework has some good documentation including examples, tutorials, and api documents. In addition, if you want to integrate a Spring Web project with Restlet, here is a good write up,
restlet-with-springIf your website leverages ajax via javascript, one of the nice things with Restlets is that you can easily call your Restful Web Services using javascript.
Restlets has implemented lots of extensions, for example if you want to write a smartphone app in android to call Restful Web Services, Restlets has an extension for this.
Restlet is extremely flexible and can be called from either a Web client or Web server code.
Thursday, December 17, 2009
Spring MVC with SiteMesh Decoration Framework and Velocity Templates
Most developers hate to repeat themselves, so they like to reuse as much code as possible. The folks at OpenSymphony.org who also brought you Quartz developed Sitemesh to utilize the Gang of Four pattern composition.
In short, SiteMesh is a web-page layout and decoration framework. It allows you to
reuse your layouts (header and footer for example) throughout your site, so that
you site has a consistent look and feel.
The general documentation at the SiteMesh Site site is quite good but I needed to utilize Sitemesh in the following specific scenario, I am using Spring MVC and Velocity Templates.
Since the general install documentation, installation instructions is very good, I will not repeat it here. Once you have downloaded and setup your web project, you will have 3 xml config that you will be dealing with, web.xml, sitemesh.xml, and decorators.xml. In my case I am using Spring MVC and Velocity, so I need to customize my web.xml configuration to handle this setup. Here is how my web.xml is configured:
<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">
<display-name>EnduroTracker</display-name>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/applicationContext.xml
</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<!--SiteMesh-->
<filter>
<filter-name>sitemesh</filter-name>
<filter-class>com.opensymphony.sitemesh.webapp.SiteMeshFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>sitemesh</filter-name>
<url-pattern>*.html</url-pattern>
<dispatcher>REQUEST</dispatcher>
<dispatcher>FORWARD</dispatcher>
</filter-mapping>
<!--Used to Enable Spring MVC -->
<servlet>
<servlet-name>dispatcher</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>dispatcher</servlet-name>
<url-pattern>*.html</url-pattern>
</servlet-mapping>
<!--Sitemesh-->
<servlet>
<servlet-name>sitemesh-velocity</servlet-name>
<servlet-class>com.opensymphony.module.sitemesh.velocity.VelocityDecoratorServlet</servlet-class>
<load-on-startup>2</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>sitemesh-velocity</servlet-name>
<url-pattern>*.vm</url-pattern>
</servlet-mapping>
<welcome-file-list>
<welcome-file>homeIndex.html</welcome-file>
</welcome-file-list>
<error-page>
<error-code>500</error-code>
<location>/error.html</location>
</error-page>
</web-app>
If you followed the SiteMesh Install steps at their site and then customized your
web.xml for your Spring MVC web project, you should now have SiteMesh configured correctly to use with Spring MVC and Velocity.
Important to note in your decorators.xml since you are using Velocity,
you will be using *.vm decorator files, here is an example decorators.xml file:
<decorators defaultdir="/decorators">
<!-- Any urls that are excluded will never be decorated by Sitemesh -->
<!--<excludes>
<pattern>/exclude.vm</pattern>
<pattern>/exclude/*</pattern>
</excludes>-->
<decorator name="default" page="default.vm">
<pattern>/*</pattern>
</decorator>
</decorators>
Tuesday, November 24, 2009
Using CAS 4 within a Load Balanced Environment
I'm not crazy about acronyms because given the variety of words in the english language they can mean any combination of things.
I have 2 main requirements/constraints when running my website:
1) Always be load balanced for High Availability,redundancy and also allow easy scalability.
2) Allow use Hibernate across multiple databases. I have a separate database for users (user db), and a separate database for the core of the web application.
My website is load balanced using Apache, I have a single load balance server , and 2 web servers also running Apache.
They get load balanced via Apache ProxyReverse or mod_proxy module.
I added a third requirement to my web application, always allow the users to sign in once and sign in with one set of credentials (username/password).
Another words, don't have separate sign up, sign in processes for third party applications like forums that you have tacked onto to your site.
This third requirement is straight forward and may appear easy to some, but it can be complicated and time consuming to implement.
Luckily, the folks at jasig.org , created CAS , Central Authentication Service, which can be implemented into one's website.
It is Java based, but can be integrated with lots of different website technology stacks like .Net, PHP, Perl, ColdFusion, Ruby on Rails, etc.
Combining these 3 requirements means that I need to be able to have CAS load balanced across multiple servers and multiple databases.
The standard implementation of CAS stores a user's credentials in the session. However, when CAS is implemented this way, the web site
ends up losing the credentials on redirects, etc.
To solve this issue CAS 4 (Cas version 4) introduced the concept of Database Session Storage named JpaSessionStorage in CAS.
Due to requirement #2, I had to implement my own Session Storage class that utilizes Spring's JtaTransactionManager rather EntityManager.
This allows for managing transactions over multiple databases.
Here is my code:
import org.springframework.test.context.transaction.TransactionConfiguration;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Repository;
import org.javalid.annotations.validation.CollectionSize;
import org.javalid.annotations.validation.NotNull;
import org.javalid.annotations.validation.MinValue;
import org.jasig.cas.server.authentication.Authentication;
import org.jasig.cas.server.login.LoginRequest;
import org.jasig.cas.server.util.Cleanable;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import javax.annotation.Resource;
import javax.persistence.*;
import java.util.ArrayList;
import java.util.List;
/***
* Session Storage Implementation that uses Spring's a JtaTransactionManager rather
* than EntityManager. Allows for managing transactions over multiple databases which
* is required in some web application implementations.
* @author David Driscoll
*
*/
@TransactionConfiguration(transactionManager="jtaTransactionManager", defaultRollback=false)
@Transactional
@Repository
/*public class JpaSessionStorageUsingJtaImpl extends AbstractSessionStorageImpl implements Cleanable{*/
public class JpaSessionStorageUsingJtaImpl implements SessionStorage, Cleanable{
@Resource(name="sessionFactory3")
private org.hibernate.SessionFactory sessionFactory;
@NotNull
@CollectionSize(mode=CollectionSize.MODE_MINIMUM, minimumSize = 1)
@Autowired(required=false)
private List
/*@Override
@Autowired
protected void setSessionFactories(List
{
this.sessionFactories = sessionFactories;
}*/
@MinValue(1)
private long purgeTimeOut = 21600000;
@MinValue(1)
private int purgeMaxCount = Integer.MAX_VALUE;
public JpaSessionStorageUsingJtaImpl(){}
@Autowired(required=true)
public JpaSessionStorageUsingJtaImpl(List
this.sessionFactories = sessionFactories;
}
public org.jasig.cas.server.session.Session createSession(
LoginRequest loginRequest, Authentication authentication)
throws InvalidatedSessionException {
try{
if (loginRequest.getOriginalAccess() != null && loginRequest.getOriginalAccess().getParentSession() != null) {
org.jasig.cas.server.session.Session parentSession = loginRequest.getOriginalAccess().getParentSession();
org.jasig.cas.server.session.Session childSession = parentSession.createDelegatedSession(authentication);
addSession(childSession);
return childSession;
}
if(this.sessionFactories != null){
for ( org.jasig.cas.server.session.SessionFactory sessionFactory : this.sessionFactories) {
org.jasig.cas.server.session.Session session = sessionFactory.getSession(authentication);
if (session != null) {
addSession(session);
return session;
}
}
}
throw new IllegalStateException("No SessionFactory configured that can handle this type of Authentication.");
}
catch(Exception ex){
System.out.println("exception in createSession, exception message:" + ex.getMessage());
throw new IllegalStateException("No SessionFactory configured that can handle this type of Authentication.");
}
}
protected void addSession(org.jasig.cas.server.session.Session session) {
Assert.isInstanceOf(JpaSessionImpl.class, session);
this.sessionFactory.getCurrentSession().persist(session);
}
public org.jasig.cas.server.session.Session destroySession(String sessionId) {
try {
Query query = this.sessionFactory.getCurrentSession().createQuery("select s from session s where s.sessionId = :sessionId").setParameter("sessionId", sessionId);
org.jasig.cas.server.session.Session session = (org.jasig.cas.server.session.Session) query.uniqueResult();
this.sessionFactory.getCurrentSession().delete(session);
return session;
} catch (Exception e) {
return null;
}
}
public org.jasig.cas.server.session.Session findSessionBySessionId(String sessionId) {
try {
Query query = this.sessionFactory.getCurrentSession().createQuery("select s from session s where s.sessionId = :sessionId").setParameter("sessionId", sessionId);
org.jasig.cas.server.session.Session session = (org.jasig.cas.server.session.Session) query.uniqueResult();
return session;
} catch ( Exception e) {
return null;
}
}
public org.jasig.cas.server.session.Session updateSession(org.jasig.cas.server.session.Session session) {
this.sessionFactory.getCurrentSession().update(session);
return session;
}
public org.jasig.cas.server.session.Session findSessionByAccessId(String accessId) {
try {
Query query = this.sessionFactory.getCurrentSession().
createQuery("select s from session s, IN(s.casProtocolAccesses) c where c.id = :accessId").setParameter("accessId", accessId);
org.jasig.cas.server.session.Session session = (org.jasig.cas.server.session.Session) query.uniqueResult();
return session;
} catch ( Exception e) {
return null;
}
}
public void purge() {
Query query = this.sessionFactory.getCurrentSession().
createQuery("delete from session s");
query.executeUpdate();
}
public void prune() {
Query query = this.sessionFactory.getCurrentSession().
createQuery("Delete From session s where (s.state.creationTime + :timeOut) >= :currentTime or s.state.count > :maxCount").
setParameter("timeOut", this.purgeTimeOut).setParameter("currentTime", System.currentTimeMillis()).setParameter("maxCount", this.purgeMaxCount);
query.executeUpdate();
}
public void setPurgeTimeOut(long purgeTimeOut) {
this.purgeTimeOut = purgeTimeOut;
}
public void setPurgeMaxCount(int purgeMaxCount) {
this.purgeMaxCount = purgeMaxCount;
}
See my series of blog posts on setting up Spring with Multiple Databases to setup JTA appropriately, here : http://endurotracker.blogspot.com/2009/08/using-spring-with-multiple-databases.html
CAS 4 uses utilizes autowiring annotations, so you only need to reference this new class in your pom.xml for it to be found and used as the session storage mechanism.
Here is a xml snippet from the pom.xml file:
<groupId>org.jasig.cas</groupId>
<artifactId>cas-server-sessionstorage-jpa</artifactId>
<version>${project.version}</version>
<scope>runtime</scope>
<type>jar</type>
</dependency>