<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Bowlinguru</title>
	<atom:link href="http://bowlinguru.com/?feed=rss2" rel="self" type="application/rss+xml" />
	<link>http://bowlinguru.com</link>
	<description>Learn, Grow, Thrive</description>
	<lastBuildDate>Mon, 20 Jul 2009 15:33:45 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Grails Domain Objects Over Webservices</title>
		<link>http://bowlinguru.com/?p=40</link>
		<comments>http://bowlinguru.com/?p=40#comments</comments>
		<pubDate>Mon, 20 Jul 2009 15:33:45 +0000</pubDate>
		<dc:creator>alex</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[CXF]]></category>
		<category><![CDATA[grails]]></category>
		<category><![CDATA[groovy]]></category>
		<category><![CDATA[JAXB]]></category>
		<category><![CDATA[web services]]></category>

		<guid isPermaLink="false">http://www.bowlinguru.com/?p=40</guid>
		<description><![CDATA[groovy.lang.MetaClass is an interface, and JAXB can&#8217;t handle interfaces
Nope.  Sure can&#8217;t.  And that sucks.  But how do I get my Grails domain objects to pass over web services.
I&#8217;m SOOOO happy I finally figured this out.  It made our web services almost unreadable and unusable.  
Anyway, if you are struggling with [...]]]></description>
			<content:encoded><![CDATA[<p>groovy.lang.MetaClass is an interface, and JAXB can&#8217;t handle interfaces</p>
<p>Nope.  Sure can&#8217;t.  And that sucks.  But how do I get my Grails domain objects to pass over web services.</p>
<p>I&#8217;m SOOOO happy I finally figured this out.  It made our web services almost unreadable and unusable.  </p>
<p>Anyway, if you are struggling with this, my solution is to use the XML annotation @XmlAccessorType(XmlAccessType.FIELD) in the domain class.   This will limit JAXB&#8217;s exploration of the object to only the declared members.  Awesome.</p>
<p>(remember to &#8220;import javax.xml.bind.annotation.*;&#8221;)</p>
]]></content:encoded>
			<wfw:commentRss>http://bowlinguru.com/?feed=rss2&amp;p=40</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Protecting Webservices with Acegi in Grails</title>
		<link>http://bowlinguru.com/?p=32</link>
		<comments>http://bowlinguru.com/?p=32#comments</comments>
		<pubDate>Tue, 07 Jul 2009 15:04:32 +0000</pubDate>
		<dc:creator>alex</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://www.bowlinguru.com/?p=32</guid>
		<description><![CDATA[This is a continuation of my previous post &#8220;Publishing and Consuming Webservices with Grails&#8220;.
Lets suppose you already have experience in your favorite Authentication provider and want to ensure that your webservices use the same users and authentication engine.  For my purposes, Acegi (Spring Security) is that engine.  I&#8217;m going to assume we&#8217;ll start from where [...]]]></description>
			<content:encoded><![CDATA[<p>This is a continuation of my previous post &#8220;<a href="http://www.bowlinguru.com/?p=29">Publishing and Consuming Webservices with Grails</a>&#8220;.</p>
<p>Lets suppose you already have experience in your favorite Authentication provider and want to ensure that your webservices use the same users and authentication engine.  For my purposes, Acegi (Spring Security) is that engine.  I&#8217;m going to assume we&#8217;ll start from where the last post left off, (<a href="/testApp.zip">here&#8217;s the zip</a> if you would like to follow along).</p>
<p>So first, install the plugin for Acegi with</p>
<pre>grails install-plugin acegi</pre>
<p>And then run</p>
<pre>grails create-auth-domains</pre>
<p>Before we get to far, I want to be sure to setup the Bootstrap so I can be sure that Acegi is doing its job (/grails-app/conf/BootStrap.groovy).</p>
<pre>class BootStrap {

     def init = { servletContext -&gt;
    //Protect everything
        new Requestmap(url:"/**",configAttribute:"ROLE_ADMIN").save()
    //Allow a user to login
        new Requestmap(url:"/login/auth**",configAttribute:"IS_AUTHENTICATED_ANONYMOUSLY").save()
    //And have a nice looking login page
        new Requestmap(url:"/images/**",configAttribute:"IS_AUTHENTICATED_ANONYMOUSLY").save()
        new Requestmap(url:"/css/**",configAttribute:"IS_AUTHENTICATED_ANONYMOUSLY").save()
    //Our Webservices can be seen publicly, but require an authentication header
      new Requestmap(url:"/ws/**",configAttribute:"IS_AUTHENTICATED_ANONYMOUSLY").save()

      //Credentials Information
      def pass = DU.shaHex("passw0rd")

    //Create some users
      def person1 = new Person(username:"user1", userRealName:"user", passwd:pass, email:"admin@site.com",emailShow:true, enabled:true, description:"a user")
        def person2 = new Person(username:"user2", userRealName:"user two", passwd:pass, email:"user@user.com",emailShow:true, enabled:true, description:"user")

        def clientAuth = new Authority(description:"Users",authority:"ROLE_USER")
                                        .addToPeople(person1)
                                        .addToPeople(person2)
                                        .save()
     }
     def destroy = {
     }
}</pre>
<p>This will give us users and permissions when we run.</p>
<p>Alright, nothing too intense yet.  But now we have to worry about securing our CXF web services with Acegi as an authentication provider.  The first step involves getting dirty in the Spring xml config again.  We need to add some in interceptors to the server.  Pretty straight forward if you know what you are doing (I still don&#8217;t understand it great). Edit /web-app/WEB-INF/cxf-servlet.xml to look like the following:</p>
<pre>&lt;?xml version="1.0" encoding="UTF-8"?&gt;
&lt;beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:simple="http://cxf.apache.org/simple"
    xmlns:soap="http://cxf.apache.org/bindings/soap"
    xsi:schemaLocation="

http://www.springframework.org/schema/beans

http://www.springframework.org/schema/beans/spring-beans.xsd

http://cxf.apache.org/bindings/soap

http://cxf.apache.org/schemas/configuration/soap.xsd

http://cxf.apache.org/simple

http://cxf.apache.org/schemas/simple.xsd"&gt;
    &lt;!--create CXF service--&gt;
    &lt;simple:server id="samplePublishedService" serviceClass="com.domain.services.Sample" address="/sample"&gt;
        &lt;simple:serviceBean&gt;
          &lt;bean class="SampleService" /&gt;
        &lt;/simple:serviceBean&gt;
        &lt;simple:inInterceptors&gt;
          &lt;bean class="org.apache.cxf.binding.soap.saaj.SAAJInInterceptor"/&gt;
          &lt;bean class="org.apache.cxf.ws.security.wss4j.WSS4JInInterceptor"&gt;
            &lt;constructor-arg&gt;
                &lt;map&gt;
                       &lt;entry key="action" value="UsernameToken"/&gt;
                       &lt;entry key="passwordType" value="PasswordText"/&gt;
                       &lt;entry key="passwordCallbackRef"&gt;
                          &lt;bean class="com.domain.security.PasswordHandler"/&gt;
                       &lt;/entry&gt;
                   &lt;/map&gt;
            &lt;/constructor-arg&gt;
            &lt;/bean&gt;
          &lt;bean class="com.domain.security.ValidateUserTokenInterceptor" /&gt;
        &lt;/simple:inInterceptors&gt;
    &lt;/simple:server&gt;
&lt;/beans&gt;</pre>
<p>I just referenced a couple classes that don&#8217;t exist, so I get you know whats next.  Add those classes to /src/groovy/ with the following code:</p>
<h3>PasswordHandler.groovy</h3>
<pre>package com.domain.security;

import java.io.IOException;

import javax.security.auth.callback.Callback;
import javax.security.auth.callback.CallbackHandler;
import javax.security.auth.callback.UnsupportedCallbackException;
import org.codehaus.groovy.grails.commons.GrailsApplication;
import org.codehaus.groovy.grails.plugins.springsecurity.GrailsDaoAuthenticationProvider;
import org.springframework.security.AuthenticationManager;
import org.springframework.context.ApplicationContext;
import org.springframework.security.context.SecurityContextHolder;
import org.springframework.security.providers.UsernamePasswordAuthenticationToken;

import org.apache.ws.security.WSPasswordCallback;
/**
 * This is passed to the WSS4JInHandler in the server configuration.
 *
 * @author bowlinguru based on XFire implementation by Michael Vorburger, based on XFire sample by &lt;a href="mailto:tsztelak@gmail.com"&gt;Tomasz Sztelak&lt;/a&gt;
 */
public class PasswordHandler implements CallbackHandler {

    public PasswordHandler() {
    }

    public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException {

        // There is nothing we could actually do here...

        WSPasswordCallback pc = (WSPasswordCallback) callbacks[0];
        String uid = pc.getIdentifer();
        System.out.println(uid);
        System.out.println(pc.getPassword());
        // No pc.setPassword(password); - we don't have a pwd (and don't need one)
    }
}</pre>
<h3>ValidateUserTokenInterceptor.groovy</h3>
<pre>package com.stewie.security

import org.apache.cxf.phase.AbstractPhaseInterceptor;
import org.apache.cxf.phase.Phase;
import org.apache.cxf.message.*;
import org.apache.cxf.interceptor.Fault;
import org.springframework.security.context.SecurityContextHolder;
import org.springframework.security.providers.UsernamePasswordAuthenticationToken;
import org.springframework.security.AuthenticationManager;
import org.apache.ws.security.WSConstants;
import org.apache.ws.security.WSSecurityEngineResult;
import org.apache.ws.security.WSUsernameTokenPrincipal;
import org.apache.ws.security.handler.WSHandlerConstants;
import org.apache.ws.security.handler.WSHandlerResult;
import org.codehaus.groovy.grails.plugins.springsecurity.GrailsDaoAuthenticationProvider;
import org.springframework.security.AuthenticationManager;
import org.springframework.context.ApplicationContext;

class ValidateUserTokenInterceptor extends AbstractPhaseInterceptor {
    public ValidateUserTokenInterceptor(){
        super(Phase.UNMARSHAL);
    }
    public ValidateUserTokenInterceptor(java.lang.String phase){
        super(Phase.UNMARSHAL);
    }
    public ValidateUserTokenInterceptor(java.lang.String phase, boolean uniqueId){
        super(Phase.UNMARSHAL);
    }
    public ValidateUserTokenInterceptor(java.lang.String i, java.lang.String p){
        super(Phase.UNMARSHAL);
    }
    public ValidateUserTokenInterceptor(java.lang.String i, java.lang.String p, boolean uniqueId){
        super(Phase.UNMARSHAL);
    }
    void handleMessage(Message message) throws Fault{
        println message
        Vector result = (Vector) message.getContextualProperty(WSHandlerConstants.RECV_RESULTS);
        if (result==null) {
            throw new IllegalArgumentException(WSHandlerConstants.RECV_RESULTS + " Property not found in MessageContext?!");
        }
        for (int i = 0; i &lt; result.size(); i++) {
            WSHandlerResult res = (WSHandlerResult) result.get(i);
            for (int j = 0; j &lt; res.getResults().size(); j++) {
                WSSecurityEngineResult secRes = (WSSecurityEngineResult) res.getResults().get(j);
                int action = secRes.getAction();

                // USER TOKEN
                if ((action &amp; WSConstants.UT) &gt; 0) {
                    WSUsernameTokenPrincipal principal = (WSUsernameTokenPrincipal) secRes.getPrincipal();
                    // "Set user property to user from UT to allow response encryption" (probably not needed at this point at Visana)
                    //context.setProperty(WSHandlerConstants.ENCRYPTION_USER, principal.getName());

                    org.codehaus.groovy.grails.commons.GrailsApplication dga = org.codehaus.groovy.grails.commons.ApplicationHolder.getApplication();
                    //grails.spring.BeanBuilder bb = new grails.spring.BeanBuilder();
                    ApplicationContext appContext = dga.getMainContext();//bb.createApplicationContext();
                    appContext.getBeanDefinitionNames().each{println it};
                    def sessionFactory = appContext.getBean("sessionFactory");
                    //Make sure we have a session
                    def session = sessionFactory.openSession();
                    get the authenticationManager
                    AuthenticationManager manager = (AuthenticationManager)appContext.getBean("authenticationManager");
                    // Set the Acegi Security Context
                    SecurityContextHolder.getContext().setAuthentication(
                                    manager.authenticate(new UsernamePasswordAuthenticationToken(principal.getName(),principal.getPassword())));
                }
            }
        }
    }
}</pre>
<p>Now we call the PasswordHandler, which makes sure there is a username and password, and then the authenticator, which calls our Acegi to create the session.  We can get the user principal from the same way we would if it was a manual (webpage) log-in.</p>
<p>The beauty of this solution is that security is all handled discretely.  All a user needs to do is call the web method with their SOAP envelope with an authentication header.</p>
<p>Here is a sample soap envelope (I use soapUI to test):</p>
<pre>POST http://localhost:8080/testApp/ws/sample HTTP/1.1
Content-Type: text/xml;charset=UTF-8
SOAPAction: ""
User-Agent: Jakarta Commons-HttpClient/3.1
Host: localhost:8080
Content-Length: 892

&lt;soapenv:Envelope xmlns:ser="http://services.domain.com/" xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"&gt;
   &lt;soapenv:Header&gt;&lt;wsse:Security xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"&gt;&lt;wsse:UsernameToken wsu:Id="UsernameToken-14535355" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"&gt;&lt;wsse:Username&gt;user1&lt;/wsse:Username&gt;&lt;wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText"&gt;passw0rd&lt;/wsse:Password&gt;&lt;wsse:Nonce&gt;083LNLHB9OW2YKc85/TbhA==&lt;/wsse:Nonce&gt;&lt;wsu:Created&gt;2009-07-07T15:03:26.218Z&lt;/wsu:Created&gt;&lt;/wsse:UsernameToken&gt;&lt;/wsse:Security&gt;&lt;/soapenv:Header&gt;
   &lt;soapenv:Body&gt;
      &lt;ser:methOne&gt;
         &lt;ser:arg0&gt;0&lt;/ser:arg0&gt;
         &lt;ser:arg1&gt;"whit"&lt;/ser:arg1&gt;
      &lt;/ser:methOne&gt;
   &lt;/soapenv:Body&gt;
&lt;/soapenv:Envelope&gt;</pre>
<p><a href="http://bowlinguru.com/testAppWithAcegi.zip">Final source here</a></p>
]]></content:encoded>
			<wfw:commentRss>http://bowlinguru.com/?feed=rss2&amp;p=32</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Publishing and Consuming Webservices with Grails</title>
		<link>http://bowlinguru.com/?p=29</link>
		<comments>http://bowlinguru.com/?p=29#comments</comments>
		<pubDate>Tue, 07 Jul 2009 13:49:37 +0000</pubDate>
		<dc:creator>alex</dc:creator>
				<category><![CDATA[Coding]]></category>
		<category><![CDATA[Grails]]></category>
		<category><![CDATA[Webservices]]></category>

		<guid isPermaLink="false">http://www.bowlinguru.com/?p=29</guid>
		<description><![CDATA[We&#8217;ve been working on a middle layer application that needs to translate a generic API to a proprietary API which uses our business logic to drive our local hardware.  The hardest part has been developing the webservices on an MVC framework.  Grails isn&#8217;t designed to natively consume or publish web services, but of course, there [...]]]></description>
			<content:encoded><![CDATA[<p>We&#8217;ve been working on a middle layer application that needs to translate a generic API to a proprietary API which uses our business logic to drive our local hardware.  The hardest part has been developing the webservices on an MVC framework.  Grails isn&#8217;t designed to natively consume or publish web services, but of course, there are plugins and jars available which can add that functionality.</p>
<h2>Grails and Xfire</h2>
<p>I was assigned to figure out how to do the top level exposing of our methods, while my teammates were working on consuming from the other service.  It was easy enough to get to work.  The Xfire plugin works quite simply.  Just install, add expose = true, and your exposing your webservices.  To everyone.  With no security.  To add security, add a couple of Spring transactional layers (wow, I trivialized, but its not easy at all when you don&#8217;t have Spring experience).  All was good, every thing was working the way I wanted.  I was interacting with Xfire and securing with Acegi.</p>
<p>Then we merged our branches.  My stuff broke the consuming part (done with jaxws, not sure how, I didn&#8217;t do it).</p>
<p>What on earth?  Why won&#8217;t this work together?</p>
<p>Xfire is using jaxws too.  Oh, but its a different version.  And its REALLY old.  Development on Xfire stopped before Grails was born.  Why the hell is there a plugin that uses such out of date code?  Damnit.  And there&#8217;s no simple upgrade from the Grails Xfire plugin to Apache CXF (it&#8217;s replacement).  Oh well, throw all this work out and start over.</p>
<h2>Grails and CXF</h2>
<p>CXF is a completely different beast in terms of what I have to do to get it to work with Grails.  No simple &#8220;grails install-plugin&#8221;.   No &#8220;add one line to expose&#8221;.  No good (Grails and CXF) tutorial.  Nobody doing what I&#8217;m trying to do.  (Well, I guess there is someone trying to do it because I find plenty of questions, similar stack traces, and a bunch of hints on where to go, but none of it was assembled together)  Hopefully, my experience can help others, and maybe someone who knows a little more about Spring, Grails, or CXF will be able to improve this solution.</p>
<p>Before we get too far, this solution is VERY touchy.  It requires you to recompile everytime you make a change to the source.  It gives horrible stack traces (but you&#8217;re used to that if you&#8217;re using grails).  Use it at your own risk.</p>
<p>First grab the jars from the <a href="http://cxf.apache.org/download.html">CXF Apache site</a>. There are a bunch of jars, and I don&#8217;t really know which ones are needed and which ones are not, but I found the following list and it works.  Examine WHICH_JARS if you want to be sure it works.</p>
<pre>asm-2.2.3.jar
commons-lang-2.4.jar
commons-logging-1.1.1.jar
cxf-2.2.2.jar
cxf-manifest.jar
FastInfoset-1.2.3.jar
geronimo-activation_1.1_spec-1.0.2.jar
geronimo-annotation_1.0_spec-1.1.1.jar
geronimo-javamail_1.4_spec-1.6.jar
geronimo-jaxws_2.1_spec-1.0.jar
geronimo-jms_1.1_spec-1.1.1.jar
geronimo-servlet_2.5_spec-1.2.jar
geronimo-stax-api_1.0_spec-1.0.1.jar
geronimo-ws-metadata_2.0_spec-1.1.2.jar
jaxb-api-2.1.jar
jaxb-impl-2.1.9.jar
jaxb-xjc-2.1.9.jar
jaxen-1.1.jar
jaxws-2_1-mrel2-api.jar
jaxws-rt-2.0EA3.jar
jetty-6.1.18.jar
jetty-util-6.1.18.jar
jsr181-api.jar
neethi-2.0.4.jar
saaj-api-1.3.jar
saaj-impl-1.3.2.jar
saaj-impl-1.3.jar
velocity-1.5.jar
wsdl4j-1.6.2.jar
wss4j-1.5.7.jar
wstx-asl-3.2.8.jar
xml-resolver-1.2.jar
XmlSchema-1.4.5.jar</pre>
<p>Once the jars are in the lib folder, an interface for the exposed class needs to be made in the /src/groovy.</p>
<pre>package com.domain.services;

import com.domain.*;

interface Sample{
    int methOne(int arg1, String arg2)
}</pre>
<p>Then the interface needs to be implemented by a service (well, it doesn&#8217;t have to be a service, just the class you want to expose).</p>
<pre>import com.domain.*;

class SampleService implements com.domain.services.Sample {
    boolean transactional = true

    int methOne( int arg1, String arg2){</pre>
<pre>          return 3;</pre>
<pre>    }</pre>
<p>Now we have the service all ready to expose, and we just need to tell Spring to do it.  We can do this with some xml in the right places.  In order to be able to find where I added the XML (so when I need to add another service interface) I created cxf-servlet.xml (don&#8217;t try to rename it. It won&#8217;t work) in web-app/WEB-INF with the following content:</p>
<pre>&lt;?xml version="1.0" encoding="UTF-8"?&gt;
&lt;beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:simple="http://cxf.apache.org/simple"
    xmlns:soap="http://cxf.apache.org/bindings/soap"
    xsi:schemaLocation="

http://www.springframework.org/schema/beans

http://www.springframework.org/schema/beans/spring-beans.xsd

http://cxf.apache.org/bindings/soap

http://cxf.apache.org/schemas/configuration/soap.xsd

http://cxf.apache.org/simple

http://cxf.apache.org/schemas/simple.xsd"&gt;
    &lt;!--create CXF service--&gt;
    &lt;simple:server id="samplePublishedService"
                   serviceClass="com.domain.services.Sample"
                   address="/sample"&gt;
        &lt;simple:serviceBean&gt;
          &lt;bean class="SampleService" /&gt;
        &lt;/simple:serviceBean&gt;
    &lt;/simple:server&gt;
&lt;/beans&gt;</pre>
<p>This will setup the basic servlet, but doesn&#8217;t put it any where.  If desired, &#8220;address&#8221; can be a complete URL, with a different port number, and your app would serve this service there. (i.e. address=&#8221;http://localhost:523/services&#8221; would allow your SOAP calls over port 523)  However, I want to aggregate my services so a user can find the wsdl for any of my services easily.</p>
<p>Next, if you haven&#8217;t already, run</p>
<pre>grails install-templates</pre>
<p>This will create /src/templates/war/web.xml.  Add the following to that file (inside the &lt;web-app&gt; tags):</p>
<pre>&lt;servlet&gt;
        &lt;servlet-name&gt;CXFServlet&lt;/servlet-name&gt;
        &lt;display-name&gt;CXF Servlet&lt;/display-name&gt;
        &lt;servlet-class&gt;
            org.apache.cxf.transport.servlet.CXFServlet
        &lt;/servlet-class&gt;
        &lt;load-on-startup&gt;1&lt;/load-on-startup&gt;
    &lt;/servlet&gt;

    &lt;servlet-mapping&gt;
        &lt;servlet-name&gt;CXFServlet&lt;/servlet-name&gt;
        &lt;url-pattern&gt;/ws/*&lt;/url-pattern&gt;
    &lt;/servlet-mapping&gt;</pre>
<p>Then to /grails-app/conf/spring/resources.xml (or rewrite this to match the .groovy way) add</p>
<pre>&lt;beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:simple="http://cxf.apache.org/simple"
    xmlns:lang="http://www.springframework.org/schema/lang"
    xmlns:jaxws="http://cxf.apache.org/jaxws"
    xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/lang http://www.springframework.org/schema/lang/spring-lang-2.0.xsd
http://cxf.apache.org/simple http://cxf.apache.org/schemas/simple.xsd
http://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsd"&gt;

    &lt;import resource="classpath:META-INF/cxf/cxf.xml" /&gt;
    &lt;import resource="classpath:META-INF/cxf/cxf-extension-soap.xml" /&gt;
    &lt;import resource="classpath:META-INF/cxf/cxf-servlet.xml" /&gt;
    &lt;import resource="classpath:WEB-INF/cxf-servlet.xml" /&gt;
&lt;/beans&gt;</pre>
<p>At this point, you should be able to run.  (You probably have to run with -Ddisable.auto.recompile=true.  Also &#8220;grails clean&#8221;ing helps solve some of the errors.) So that is where I will end.  I will post soon about Acegi integration.</p>
<p>Point your browser to &#8220;http://localhost:8080/testApp/ws/&#8221; (for example) to see the list of services.  Links will give the wsdls.</p>
<p><a href="http://bowlinguru.com/testApp.zip">Here</a> is a copy of the source.</p>
]]></content:encoded>
			<wfw:commentRss>http://bowlinguru.com/?feed=rss2&amp;p=29</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>I&#8217;m a BOSS (Alumni)</title>
		<link>http://bowlinguru.com/?p=24</link>
		<comments>http://bowlinguru.com/?p=24#comments</comments>
		<pubDate>Wed, 24 Jun 2009 01:41:44 +0000</pubDate>
		<dc:creator>alex</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://www.bowlinguru.com/?p=24</guid>
		<description><![CDATA[Sunday night completed the most miserable week of my life.   But it was also the best week of my life.  I gained some valuable skills, 19 life-long friends, and a renewed faith in my fraternity.
I spent the last week on the True Pike Challenge, a specialized course through Boulder Outdoor Survival School for 20 [...]]]></description>
			<content:encoded><![CDATA[<p>Sunday night completed the most miserable week of my life.   But it was also the best week of my life.  I gained some valuable skills, 19 life-long friends, and a renewed faith in my fraternity.<span id="more-24"></span></p>
<p>I spent the last week on the True Pike Challenge, a specialized course through Boulder Outdoor Survival School for 20 Pi Kappa Alpha brothers.  We spent a week in the Utah desert; hiking for miles, eating little food, and pushing our limits in ways I could hardly imagine before I arrived.  The nights were as cold as the day was hot. A strong brotherhood was forged while cuddling for warmth during the wee hours of the morning.  The rain came as we were moving,  but stopped when we made camp.  After a night alone, our journey to find eachother found hail crushing our spirits.  None of us were successfull at making fire, so many dinners were wasted and we were left hungry.  We covered nearly fourty miles and a 4000 foot elevation change in five days of hiking.  Last week was the most miserable week of my life.</p>
<p>But that makes this week awesome.</p>
<p>One of the philosphies of BOSS is to compare down.  All week we told ourselves we could be naked, sleeping on dirt, with sunburns on top of our blisters.  It made the week more managable. It helped us humble ourselves.</p>
<p>My week in Utah gave me a low to compare the rest of my life to.  It pushed my limits, and showed me how far beyond them I could go.</p>
]]></content:encoded>
			<wfw:commentRss>http://bowlinguru.com/?feed=rss2&amp;p=24</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Guacamole Bacon Burger</title>
		<link>http://bowlinguru.com/?p=23</link>
		<comments>http://bowlinguru.com/?p=23#comments</comments>
		<pubDate>Wed, 10 Jun 2009 13:13:12 +0000</pubDate>
		<dc:creator>alex</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://www.bowlinguru.com/?p=23</guid>
		<description><![CDATA[These guys are amazing.  Even better than they sound, and they are really easy to make.  First, make guacamole by mixing 2 parts mashed avocado, 1 part diced onion, and 1 part diced roma tomato.  (Normally, I use 4 avocados, 1 onion the size of a tennis ball, and 2 tomatoes)  [...]]]></description>
			<content:encoded><![CDATA[<p>These guys are amazing.  Even better than they sound, and they are really easy to make.  First, make guacamole by mixing 2 parts mashed avocado, 1 part diced onion, and 1 part diced roma tomato.  (Normally, I use 4 avocados, 1 onion the size of a tennis ball, and 2 tomatoes)  Then, make the bacon in your favorite way.  I have a microwave bacon maker that I like to use.  Finally, grill a burger in your favorite way. I sprinkle with Lowery&#8217;s seasoning salt, then grill. Combine all three on a bun, and its magical.</p>
<p>I don&#8217;t like to use cheese because there are already a lot of flavors going on.  Also, when normally making guacamole, I would add salt and lime juice, but these burgers already have enough salt and I used all of my batch of guacamole (the main purpose of the lime juice is to preserve the green color the guac). </p>
]]></content:encoded>
			<wfw:commentRss>http://bowlinguru.com/?feed=rss2&amp;p=23</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>I was the Best Man</title>
		<link>http://bowlinguru.com/?p=21</link>
		<comments>http://bowlinguru.com/?p=21#comments</comments>
		<pubDate>Tue, 09 Jun 2009 15:30:42 +0000</pubDate>
		<dc:creator>alex</dc:creator>
				<category><![CDATA[Random]]></category>

		<guid isPermaLink="false">http://www.bowlinguru.com/?p=21</guid>
		<description><![CDATA[My brother had his wedding this week and I was the best man.  Of course, the thing that made me most nervous was the toast I was to offer the newly weds.  After all, this was the first wedding I&#8217;ve been to since my mom&#8217;s nearly six years ago, and I can barely remember that.  [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://photos.bowlinguru.com/index.php?album=alexs-first-picture-upload"><img class="alignright" title="Jay and Lauras Invite" src="http://photos.bowlinguru.com/index.php?album=alexs-first-picture-upload&amp;image=EFW_042.jpg&amp;p=*full-image" alt="" width="167" height="250" /></a>My brother had his wedding this week and I was the best man.  Of course, the thing that made me most nervous was the toast I was to offer the newly weds.  After all, this was the first wedding I&#8217;ve been to since my mom&#8217;s nearly six years ago, and I can barely remember that.  I prepared by browsing a few different sites that offered advice on how to give the speech, what to say, the parts the speech should have, and a variety of toasts. After a lot of searching and reading, I was much better informed, and had picked up a few one liners I could use as best man, but I didn&#8217;t have any content to my toast.  So I sat down and just wrote.  Everything came to me and it was nearly perfect.  Even though as I spoke the content changed a little, I thought that I would share my toast here as I wrote it.</p>
<p style="padding-left: 30px;">I&#8217;d like take a few moments to congratulate Jay and Laura on their marriage, but first, for those who do not know me, I&#8217;m Alex, Jay&#8217;s Brother, and until a few hours ago, the only person here, other than Jay, with &#8220;Weingarten&#8221; for a last name. I am absolutely honored to be the first to toast Jay and Laura here today because, after all these years, Jay has finally admitted that I am the best man</p>
<p style="padding-left: 30px;">I&#8217;d like to thank Mr and Mrs Foley for coordinating such a wonderful reception, and for providing my brother the love of his life. I can remember when Jay and Laura met.  Nights when we would hang out together bullshitting about sports or video games, or whatever, quickly deteriorated to him locked in his room on the phone with some mystery woman.  Then I met her.  It was the night of his prom, so she was all dolled up looking almost as beautiful as she does now.  And I understood why he didn&#8217;t care about watching sports or playing video games with me any more.</p>
<p style="padding-left: 30px;">It&#8217;s always been a little hard to be Jay&#8217;s little brother.  He left some huge shoes to fill. And I&#8217;ve tried my hardest to fill them, but if I am able to be half as lucky with love as he has been and find a wife half as amazing as Laura, I will consider myself blessed.  So let us raise our glasses to Jay and Laura, may love permeate their souls, and bind them together in eternal happiness.</p>
<p>I took a lot of pic with Dan&#8217;s camera, most of which are uploaded to my <a title="photos!" href="http://photos.bowlinguru.com/index.php?album=jayandlaurawedding">photo site</a>.  If you have any photos, let me know so I can get you a log in so you can upload them and to share them with everyone else!</p>
]]></content:encoded>
			<wfw:commentRss>http://bowlinguru.com/?feed=rss2&amp;p=21</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Grails and Google Calendar</title>
		<link>http://bowlinguru.com/?p=5</link>
		<comments>http://bowlinguru.com/?p=5#comments</comments>
		<pubDate>Thu, 28 May 2009 14:50:54 +0000</pubDate>
		<dc:creator>alex</dc:creator>
				<category><![CDATA[Coding]]></category>
		<category><![CDATA[Grails]]></category>
		<category><![CDATA[google AuthSub]]></category>
		<category><![CDATA[google calendar]]></category>
		<category><![CDATA[google data]]></category>
		<category><![CDATA[google data services]]></category>
		<category><![CDATA[grails plugins]]></category>
		<category><![CDATA[grails services]]></category>

		<guid isPermaLink="false">http://www.bowlinguru.com/?p=5</guid>
		<description><![CDATA[I wanted to integrate Google Calendar into our project to allow our users to sync the appointments they make in our system with their Google Calendar.  Doing this will allow us to focus on creating the core of our site while allowing Google to make our more useful to our users.
The biggest obstacle in connecting [...]]]></description>
			<content:encoded><![CDATA[<p>I wanted to integrate Google Calendar into our project to allow our users to sync the appointments they make in our system with their Google Calendar.  Doing this will allow us to focus on creating the core of our site while allowing Google to make our more useful to our users.</p>
<p>The biggest obstacle in connecting to Google with Grails was the lack of a good resource.  I even struggled to find a good Java resource, so I knew there was no way Grails had one.</p>
<p>There are two parts essential to connecting to Google Calendar.  First, you need to create a connection to google using one of their APIs.  The two available are OAuth and AuthSub.  Because of the nature of how we want users connecting to Google, I choose to use AuthSub (and because it seemed to have more reasources).   The second part of the integration is using the CalendarService API.  This is fairly straight forward after getting the authentication piece working.</p>
<h2>Getting Started</h2>
<p>With grails, the easiest way to get any of Google&#8217;s data services is to install the google-data plugin</p>
<pre>grails install-plugin google-data</pre>
<p>This installs several jars that are the Java adaptation of the Google Data API.  The JavaDocs can be found <a href="http://code.google.com/apis/gdata/javadoc/" target="_blank">here</a>.</p>
<h2>AuthSub</h2>
<p>The AuthSub is pretty well documented.  I&#8217;m just going to throw out some code, and if you can&#8217;t understand it, ask.</p>
<p>First the Imports:</p>
<pre>import com.google.gdata.client.*;
import com.google.gdata.client.calendar.*;
import com.google.gdata.data.*;
import com.google.gdata.data.acl.*;
import com.google.gdata.data.calendar.*;
import com.google.gdata.data.extensions.*;
import com.google.gdata.util.*;
import com.google.gdata.client.http.AuthSubUtil;

import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;</pre>
<p>Now some AuthSub Code:</p>
<pre>    //This will return a URL.  The user will have to be redirect()ed to it to get the security token
     def sendRequestURL() {
        //we don't have access for one reason or another. So re-up with google.
	String nextUrl = "http://localhost:8080/returnHandler";
	String scope = "http://www.google.com/calendar/feeds/";
	boolean secure = false;  // set secure=true to request AuthSub tokens
	boolean session = true;

	String authSubUrl = AuthSubUtil.getRequestUrl(nextUrl, scope, secure, session);
	return authSubUrl;
    }

    def returnHandler = {
    	if (params.token){
    		session['googleToken'] = getSessionToken(params.token)
	}
	redirect(action:"weHaveApproval")
    }

    //getting a session token will allow us to interact for a while
    def getSessionToken(token) {
    	return AuthSubUtil.exchangeForSessionToken(token, null);
    }</pre>
<p>Basically, installing the plugin did all the legwork of us. We just have to assemble how to handle our situation.</p>
<h2>Google Services</h2>
<p>Again, the installed plugin will handle most of the work, and it is well documented.  I again will just give code, and let you experiment.</p>
<p>Here are couple of methods for creating a calendar and creating events for that calendar:</p>
<pre>    def calendarUser = {
	//create the service
    	CalendarService service = new CalendarService("evodox-appointmentsDemo-v1.0");
	service.setAuthSubToken(googleToken, null);

	//Find the proper calendar
	CalendarFeed resultFeed = service.getFeed(owncalendarsFeedUrl, CalendarFeed.class);
	def calendar;
	resultFeed.getEntries().each {
		println it.getTitle().getPlainText()
		if (it.getTitle().getPlainText() == calName){
			println "matched calName"
			calendar = it;
		}
	}
	//see if we found the calendar. if not, make it.
	if (!calendar){
		calendar = createCalendar(service, calName);
	}
	//Add an event to that calendar
	jobList.each{
		if (it.nextContact &gt; new Date()){
	  			calendar = addJobAppointment(calendar,service,it);
		}
	}
    }

    private static CalendarEntry createCalendar(CalendarService service, String title) throws IOException, ServiceException {
      // Create the calendar
      CalendarEntry calendar = new CalendarEntry();
      calendar.setTitle(new PlainTextConstruct(title));
      calendar.setSummary(new PlainTextConstruct("This calendar contains you appointments made in Evodox."));
      calendar.setHidden(HiddenProperty.FALSE);
      calendar.setColor(new ColorProperty(GREEN));

      // Insert the calendar
      return service.insert(owncalendarsFeedUrl, calendar);
    }

    private static CalendarEntry addJobAppointment(CalendarEntry calendar,CalendarService service, job) throws IOException, ServiceException {
      def list = calendar.getEditLink().getHref().split("/")
      URL postURL = new URL("http://www.google.com/calendar/feeds/" + list[list.length-1].replace("%40","@") + "/private/full");

      CalendarEventEntry myEvent = new CalendarEventEntry();
      myEvent.setTitle(new PlainTextConstruct(job.contact.toString() + " - " + job.nextAction));
      myEvent.setContent(new PlainTextConstruct("Event in evodox:n" + job.contact.toString() + " - " + job.nextAction));
      def googleFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss")
      DateTime startTime = DateTime.parseDateTime(googleFormat.format(job.nextContact)+ "-05:00")//DateTime.parseDateTime("2009-05-19T15:00:00-08:00");
      DateTime endTime = DateTime.parseDateTime(googleFormat.format(job.nextContact)+ "-05:00") //DateTime.parseDateTime("2009-05-19T17:00:00-08:00");
      When eventTimes = new When();
      eventTimes.setStartTime(startTime);
      eventTimes.setEndTime(endTime);
      myEvent.addTime(eventTimes);

      CalendarEventEntry insertedEntry = service.insert(postURL, myEvent);
      return calendar.update();</pre>
<p>}</p>
<p>Of course , these aren&#8217;t perfect solutions, but they wil help you get started with interacting with Google Calendar, and probably some other services.</p>
<p>Resources:</p>
<ul>
<li><a href="http://code.google.com/p/gdata-java-client/">Google&#8217;s Java Tutorial</a></li>
<li><a href="http://code.google.com/p/gdata-java-client/">Google Data Java Client Home</a></li>
<li><a href="http://code.google.com/apis/gdata/javadoc/">Google Data Java Client Javadoc</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://bowlinguru.com/?feed=rss2&amp;p=5</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>The Bake of Monte Cristo</title>
		<link>http://bowlinguru.com/?p=6</link>
		<comments>http://bowlinguru.com/?p=6#comments</comments>
		<pubDate>Thu, 28 May 2009 14:07:18 +0000</pubDate>
		<dc:creator>alex</dc:creator>
				<category><![CDATA[Food]]></category>
		<category><![CDATA[Recipes]]></category>
		<category><![CDATA[bake]]></category>
		<category><![CDATA[ham]]></category>
		<category><![CDATA[sandwich]]></category>
		<category><![CDATA[turkey]]></category>

		<guid isPermaLink="false">http://www.bowlinguru.com/?p=6</guid>
		<description><![CDATA[Nick just told me he is going to start blogging recipes for the food he makes.  I thought that would be a great way for me to get started with my own blogging.  After all, a fat kid always loves food.
Last night I made a recipe I first made in my high school foods class.  [...]]]></description>
			<content:encoded><![CDATA[<p>Nick just told me he is going to start blogging recipes for the food he makes.  I thought that would be a great way for me to get started with my own blogging.  After all, a fat kid always loves food.</p>
<p>Last night I made a recipe I first made in my high school foods class.  It is a sandwich that the teacher referred to as <em>something </em>Monte Cristo.  I will henceforth call it &#8220;The Bake of Monte Cristo&#8221;, because its fun to say.   The recipe is so easy that, after the first time I made it, it just comes back to me every time I want to make it.</p>
<p>Ingredients:</p>
<p style="padding-left: 30px;">2 tubes of 8 Crescent Rolls<br />
1 Tbl. butter<br />
1 Tbl. honey<br />
8 oz Deli sliced Ham<br />
8 oz. Deli sliced Turkey<br />
4 oz Munster Cheese<br />
2 Tbl. Raspberry Perserves<br />
Sesame Seeds (optional)</p>
<p>Required Materials:</p>
<p style="padding-left: 30px;">2 baking sheets or 13&#215;9 pans<br />
Sauce bowl<br />
Brush (optional)</p>
<p>Bread Prep:</p>
<ol>
<li>Open and unroll the Crescent Rolls.  Each roll comes as 2 rolls of 4 triangles.  Keep them like this.  Press the seems together, so that from the 2 tubes, you make 4 rectanglur pieces.  Place on 2 baking sheets</li>
<li>Melt the butter and honey together in the microwave.  Don&#8217;t worry about being exact with 1 Tbl. of each, just get close to even amounts.</li>
<li>Brush (or use your fingers to spread) the melted honey-butter over the 4 crescent roll pieces (just the &#8216;up&#8217; side)</li>
<li>Bake for 10 minutes at 325°F, or until golden brown.</li>
</ol>
<p>Sandwich Assembly:</p>
<ol>
<li>Create the sandwich on a baking pan as follows:</li>
<p>Bread<br />
Raspberry Perserves<br />
Bread<br />
Munster Cheese<br />
Ham<br />
Bread<br />
Turkey<br />
Bread</p>
<li>Top with a drizzle of honey and ornamentation of sesame seeds.</li>
<li>Bake at 325°F until warm throughout.  (You can tell when the Munster  is all melty)</li>
</ol>
<p>Enjoy!</p>
<p>Well, there it is finally.  My first somewhat good post.  I&#8217;d love to hear from anyone subscribed or anyone who follows the recipe!</p>
]]></content:encoded>
			<wfw:commentRss>http://bowlinguru.com/?feed=rss2&amp;p=6</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Back Up!</title>
		<link>http://bowlinguru.com/?p=3</link>
		<comments>http://bowlinguru.com/?p=3#comments</comments>
		<pubDate>Fri, 24 Apr 2009 03:52:56 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Random]]></category>
		<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://www.bowlinguru.com/?p=3</guid>
		<description><![CDATA[I, again, am hoping to start blogging.  I still don&#8217;t think anything I have to say will help any one, but maybe will help me focus my ideas.
]]></description>
			<content:encoded><![CDATA[<p>I, again, am hoping to start blogging.  I still don&#8217;t think anything I have to say will help any one, but maybe will help me focus my ideas.</p>
]]></content:encoded>
			<wfw:commentRss>http://bowlinguru.com/?feed=rss2&amp;p=3</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>
