View Javadoc

1   /**
2    * Copyright 2005-2006 the original author or authors.
3    *
4    * Licensed under the Gnu General Pubic License, Version 2.0 (the
5    * "License"); you may not use this file except in compliance with
6    * the License. You may obtain a copy of the License at
7    *
8    *      http://www.opensource.org/licenses/gpl-license.php
9    *
10   * This program is distributed in the hope that it will be useful,
11   * but WITHOUT ANY WARRANTY; without even the implied warranty of
12   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
13   * See the Gnu General Public License for more details.
14   */
15  package org.figure8.join.services.scripting.ant.tasks;
16  
17  import org.figure8.join.services.remoting.AuthenticatedService;
18  import org.figure8.join.services.security.InvalidLoginException;
19  
20  import com.caucho.hessian.client.HessianProxyFactory;
21  
22  import org.apache.tools.ant.Task;
23  import org.apache.tools.ant.Project;
24  import org.apache.tools.ant.BuildException;
25  
26  import java.rmi.RemoteException;
27  /**
28   * This is an abstract Ant task providing utility methods for accessing
29   * Join remote service. This task provides 3 optional attributes : <br/>
30   * <ul>
31   * <li><b>url</b> : The url for connecting to Join remote service (in
32   * case ot no url in context),</li>
33   * <li><b>user</b> : The user for connecting to Join remote service (in
34   * case of no security token in context),</li>
35   * <li><b>password</b> : The password for connecting to Join remote service
36   * (in case of no security token in context).</li>
37   * </ul>
38   * @author <a href="mailto:laurent.broudoux@free.fr">Laurent Broudoux</a>
39   * @version $Revision: 1.2 $
40   */
41  public abstract class RemoteServiceTask extends Task{
42  
43     // Static -------------------------------------------------------------------
44  
45     /** Constant representing the subcontext url whithin Join web site for accessing remote services. */
46     public static final String REMOTE_URL_SUBCONTEXT = "/remoting/hessian/";
47  
48  
49     // Attributes ---------------------------------------------------------------
50  
51     /** The url for connecting to Join remote service (in case ot no url in context) */
52     private String url;
53     /** The user for connecting to Join remote service (in case of no security token in context) */
54     private String user;
55     /** The password for connecting to Join remote service (in case of no security token in context) */
56     private String password;
57  
58  
59     // Public -------------------------------------------------------------------
60  
61     /** @return The url for connecting to Join remote service */
62     public String getUrl(){
63        return url;
64     }
65     /** @param url The url for connecting to Join remote service */
66     public void setUrl(String url){
67        this.url = url;
68     }
69     /** @return The user for connecting to Join remote service */
70     public String getUser(){
71        return user;
72     }
73     /** @param user The user for connecting to Join remote service */
74     public void setUser(String user){
75        this.user = user;
76     }
77     /** @return The password for connecting to Join remote service */
78     public String getPassword(){
79        return password;
80     }
81     /** @param password The password for connecting to Join remote service */
82     public void setPassword(String password){
83        this.password = password;
84     }
85  
86  
87     // Protected ----------------------------------------------------------------
88  
89     /**
90      * Retrieve a remote {@link AuthenticatedService} using a connection url. The
91      * connection url retrieval strategy is the following : first check if there's an
92      * url into project user properties (join.url property), if not present check if
93      * it is defined as a global system property, finally use the <b>url</b> attribute
94      * of this Task.
95      * @param name The name of the AuthenticatedService
96      * @param serviceClass The class representing the service interface
97      * @throws BuildException if remote service cannot be acquired (connection problem, etc...)
98      * @return A handler onto remote service needing authentication
99      */
100    protected AuthenticatedService retrieveRemoteService(String name, Class serviceClass) throws BuildException{
101       // Retrieve url from project properties, from system property or from task attributes.
102       String connectionUrl = getProject().getUserProperty(JoinTask.URL_PROPERTY);
103       if (connectionUrl == null) connectionUrl = System.getProperty(JoinTask.URL_PROPERTY);
104       if (connectionUrl == null) connectionUrl = url;
105       // Check we really have an url.
106       if (connectionUrl == null || connectionUrl.length() == 0)
107          throw new BuildException("No url found for connecting to remote " + name + " service", getLocation());
108 
109       // Retrieve the authenticated service.
110       AuthenticatedService service = null;
111       connectionUrl += (REMOTE_URL_SUBCONTEXT + name);
112       try{
113          // Connect and retrieve Hessian proxy.
114          HessianProxyFactory proxyFactory = new HessianProxyFactory();
115          log("Connecting to remote AuthenticatedService (" + name + ") using url: " + connectionUrl, Project.MSG_DEBUG);
116          service = (AuthenticatedService)proxyFactory.create(serviceClass, connectionUrl);
117       }
118       catch (Exception e){
119          // Log disgnostic messages and wrap into a BuildException.
120          log("Exception while connecting to remote service using " + connectionUrl, Project.MSG_ERR);
121          log("Exception detailed message is: " + e.getMessage(), Project.MSG_ERR);
122          throw new BuildException("Exception while connecting to remote service", e, getLocation());
123       }
124       return service;
125    }
126 
127    /**
128     * Log to remote service if necessary before starting working with it. This method returns the
129     * security token associated with session. It is retrieved with the following strategy :
130     * <ul>
131     * <li>first check if such a token is in project context (join.security.token user property).
132     * It assumes the login has already been done,</li>
133     * <li>if not present try getting user and password first from global system properties
134     * (join.security.user and join.security.password) and login to the service,</li>
135     * <li>get user and password from this task attributes and login to the service.</li>
136     * </ul>
137     * @param service The remote service to retrieve a security token for
138     * @return The security token for the established session
139     */
140    protected String loginToRemoteService(AuthenticatedService service) throws InvalidLoginException, RemoteException{
141       // First check if there's a secutiry token.
142       String token = getProject().getUserProperty(JoinTask.SECURITY_TOKEN);
143 
144       if (token == null){
145          // Else, try system property for getting user/password ....
146          String connectionUser = System.getProperty(JoinTask.SECURITY_USER);
147          String connectionPwd = System.getProperty(JoinTask.SECURITY_PASSWORD);
148          // Else, try user/password specified by task.
149          if (connectionUser == null){
150             connectionUser = user;
151             connectionPwd = password;
152          }
153          // Check we really have user/password pair.
154          if (connectionUser == null || connectionPwd == null)
155             throw new BuildException("No user or password for login to the remote AuthenticatedService", getLocation());
156 
157          // Login onto remote service.
158          log("Login to remote ProcessControlService using user/password: " + connectionUser + "/" + connectionPwd, Project.MSG_DEBUG);
159          token = service.login(connectionUser, connectionPwd);
160       }
161       log("Retrieve a security token: " + token, Project.MSG_DEBUG);
162       return token;
163    }
164 
165    /**
166     * Release the connection onto remote authenticated service. The logout operation
167     * is only called if the token is not first retrieved from context (context tokens
168     * are permanent).
169     * @param service The remote service to logout from
170     * @param token The security token to use for logging out.
171     */
172    protected void releaseRemoteService(AuthenticatedService service, String token){
173       // First check if there's a secutiry token in context.
174       String ctxToken = getProject().getUserProperty(JoinTask.SECURITY_TOKEN);
175 
176       if (ctxToken == null || !ctxToken.equals(token)){
177          log("Logout from remote AuthenticatedService using token: " + token, Project.MSG_DEBUG);
178          try {service.logout(token);}
179          catch (RemoteException re){
180             // Log a non lethal disgnostic message.
181             log("RemoteException while logout from remote AuthenticatedService: " + re.getMessage(), Project.MSG_WARN);
182          }
183       }
184    }
185 }