001: /*
002: * This file is part of the WfMOpen project.
003: * Copyright (C) 2001-2005 Danet GmbH (www.danet.de), GS-AN.
004: * All rights reserved.
005: *
006: * This program is free software; you can redistribute it and/or modify
007: * it under the terms of the GNU General Public License as published by
008: * the Free Software Foundation; either version 2 of the License, or
009: * (at your option) any later version.
010: *
011: * This program is distributed in the hope that it will be useful,
012: * but WITHOUT ANY WARRANTY; without even the implied warranty of
013: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
014: * GNU General Public License for more details.
015: *
016: * You should have received a copy of the GNU General Public License
017: * along with this program; if not, write to the Free Software
018: * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
019: *
020: * $Id: EisRmsService.java,v 1.5 2006/12/12 10:03:10 drmlipp Exp $
021: *
022: * $Log: EisRmsService.java,v $
023: * Revision 1.5 2006/12/12 10:03:10 drmlipp
024: * Fixed authorizers.
025: *
026: * Revision 1.4 2006/10/15 19:29:51 mlipp
027: * Merged changes from 1.4.x up to 1.4ea3pre1.
028: *
029: * Revision 1.3.2.1 2006/10/14 21:34:06 mlipp
030: * Simplified resource assignment service implementation.
031: *
032: * Revision 1.3 2006/10/03 17:05:52 mlipp
033: * Using new default resource classes.
034: *
035: * Revision 1.2 2006/09/29 12:32:13 drmlipp
036: * Consistently using WfMOpen as projct name now.
037: *
038: * Revision 1.1 2006/09/24 20:57:17 mlipp
039: * Moved RMS implementations in own sub-package.
040: *
041: * Revision 1.7 2006/07/11 11:48:29 drmlipp
042: * Fixed message.
043: *
044: * Revision 1.6 2006/07/11 11:13:13 drmlipp
045: * Props RMS running.
046: *
047: * Revision 1.5 2006/07/11 09:19:10 drmlipp
048: * Fixed exception categorization.
049: *
050: * Revision 1.4 2006/07/10 13:47:09 drmlipp
051: * Implemented EisRmsService.
052: *
053: * Revision 1.3 2006/07/10 10:34:49 drmlipp
054: * Added resource adaptor lookup.
055: *
056: * Revision 1.2 2006/07/05 10:58:28 drmlipp
057: * Fixed package names.
058: *
059: * Revision 1.1 2006/07/05 10:53:27 drmlipp
060: * Separated generic RMS adapter client from properties based adapter.
061: *
062: * Revision 1.1 2006/07/04 13:49:57 drmlipp
063: * Started.
064: *
065: */
066: package de.danet.an.workflow.rmsimpls.eisrms;
067:
068: import java.rmi.RemoteException;
069: import java.security.Principal;
070: import java.util.ArrayList;
071: import java.util.Collection;
072: import java.util.Iterator;
073:
074: import javax.naming.NameNotFoundException;
075: import javax.resource.ResourceException;
076: import javax.resource.spi.ApplicationServerInternalException;
077: import javax.resource.spi.CommException;
078: import javax.resource.spi.EISSystemException;
079: import javax.resource.spi.LocalTransactionException;
080: import javax.resource.spi.ResourceAllocationException;
081:
082: import de.danet.an.workflow.omgcore.WfResource;
083: import de.danet.an.workflow.rmsimpls.eisrms.aci.RmsConnection;
084: import de.danet.an.workflow.rmsimpls.eisrms.aci.RmsConnectionFactory;
085: import de.danet.an.workflow.rmsimpls.eisrms.aci.RmsEntry;
086: import de.danet.an.workflow.spis.rms.DefaultGroupResource;
087: import de.danet.an.workflow.spis.rms.DefaultResource;
088: import de.danet.an.workflow.spis.rms.DefaultRoleResource;
089: import de.danet.an.workflow.spis.rms.DefaultUserResource;
090: import de.danet.an.workflow.spis.rms.FactoryConfigurationError;
091: import de.danet.an.workflow.spis.rms.ResourceAssignmentContext;
092: import de.danet.an.workflow.spis.rms.ResourceManagementService;
093: import de.danet.an.workflow.spis.rms.ResourceNotFoundException;
094:
095: /**
096: * Implements the {@link
097: * de.danet.an.workflow.spis.rms.ResourceManagementService resource
098: * management service} based on an LDAP server.
099: *
100: * @author <a href="mailto:lipp@danet.de">Michael Lipp</a>
101: * @version $Revision: 1.5 $
102: */
103:
104: public class EisRmsService implements ResourceManagementService {
105:
106: private static final org.apache.commons.logging.Log logger = org.apache.commons.logging.LogFactory
107: .getLog(EisRmsService.class);
108:
109: private RmsConnectionFactory conFac = null;
110: private ResourceAssignmentContext rasCtx = null;
111:
112: /**
113: * Constructs a new resource management service.
114: *
115: * @param props the configuration properties
116: * @param rasvc the resource assignment service
117: * @throws FactoryConfigurationError if the required resources
118: * cannot be obtained
119: */
120: public EisRmsService(RmsConnectionFactory conFac,
121: ResourceAssignmentContext rasCtx)
122: throws FactoryConfigurationError {
123: this .conFac = conFac;
124: this .rasCtx = rasCtx;
125: }
126:
127: /**
128: * Given a {@link java.security.Principal principal}, return the
129: * workflow resource associated with this principal by the
130: * resource management facility.<P>
131: *
132: * @param principal the principal.
133: * @return a <code>WfResource</code> object corresponding to the
134: * given principal.
135: * @throws ResourceNotFoundException if the StaffMember with the given key
136: * can't be found or the key is not associate with an StaffMember object.
137: * @throws RemoteException if a system-level error occurs.
138: */
139: public WfResource asResource(Principal principal)
140: throws ResourceNotFoundException, RemoteException {
141: RmsConnection con = null;
142: try {
143: con = conFac.getConnection();
144: RmsEntry e = con.lookupUserByAccountName(principal
145: .getName());
146: return new DefaultUserResource(rasCtx, e.getKey(), e
147: .getDisplayName());
148: } catch (ResourceException e) {
149: maybeMapToRemoteException(e);
150: throw new ResourceNotFoundException("Not found: "
151: + e.getMessage());
152: } catch (NameNotFoundException e) {
153: throw new ResourceNotFoundException("No user \""
154: + principal.getName() + "\" found: "
155: + e.getMessage());
156: } finally {
157: closeConnection(con);
158: }
159: }
160:
161: /* Comment copied from interface */
162: public Collection authorizers(WfResource wfResource)
163: throws RemoteException {
164: RmsConnection con = null;
165: try {
166: Collection res = new ArrayList();
167: if (!(wfResource instanceof DefaultUserResource)) {
168: return res;
169: }
170: con = conFac.getConnection();
171: Collection resRaw = con
172: .authorizers(((DefaultUserResource) wfResource)
173: .getId());
174: for (Iterator i = resRaw.iterator(); i.hasNext();) {
175: RmsEntry e = (RmsEntry) i.next();
176: addAsTyped(res, e);
177: }
178: return res;
179: } catch (ResourceException e) {
180: maybeMapToRemoteException(e);
181: throw new IllegalStateException("Cannot get authorizers: "
182: + e.getMessage());
183: } finally {
184: closeConnection(con);
185: }
186: }
187:
188: /* Comment copied from interface */
189: public WfResource resourceByKey(String key)
190: throws ResourceNotFoundException, RemoteException {
191: RmsConnection con = null;
192: try {
193: con = conFac.getConnection();
194: if (DefaultUserResource.isValidKey(key)) {
195: RmsEntry e = con.lookupResource(DefaultUserResource
196: .getId(key));
197: return new DefaultUserResource(rasCtx, e.getKey(), e
198: .getDisplayName());
199: } else if (DefaultRoleResource.isValidKey(key)) {
200: RmsEntry e = con.lookupResource(DefaultRoleResource
201: .getId(key));
202: return new DefaultRoleResource(rasCtx, e.getKey(), e
203: .getDisplayName());
204: } else if (DefaultGroupResource.isValidKey(key)) {
205: RmsEntry e = con.lookupResource(DefaultGroupResource
206: .getId(key));
207: return new DefaultGroupResource(rasCtx, e.getKey(), e
208: .getDisplayName());
209: } else {
210: RmsEntry e = con.lookupResource(key);
211: return new DefaultResource(rasCtx, e.getKey(), e
212: .getDisplayName());
213: }
214: } catch (ResourceException e) {
215: maybeMapToRemoteException(e);
216: throw new ResourceNotFoundException("Not found: "
217: + e.getMessage());
218: } catch (NameNotFoundException e) {
219: throw new ResourceNotFoundException("No entry with key \""
220: + key + "\" found: " + e.getMessage());
221: } finally {
222: closeConnection(con);
223: }
224: }
225:
226: /* Comment copied from interface. */
227: public Collection listResources() throws RemoteException {
228: RmsConnection con = null;
229: try {
230: con = conFac.getConnection();
231: Collection resRaw = con.listResources();
232: Collection res = new ArrayList();
233: for (Iterator i = resRaw.iterator(); i.hasNext();) {
234: RmsEntry e = (RmsEntry) i.next();
235: addAsTyped(res, e);
236: }
237: return res;
238: } catch (ResourceException e) {
239: maybeMapToRemoteException(e);
240: throw new IllegalStateException("Cannot list resources: "
241: + e.getMessage());
242: } finally {
243: closeConnection(con);
244: }
245: }
246:
247: /**
248: * The <code>resSel</code> paramter is poassed to the resource adapter.
249: * See the description of the configured resource adapter to find out
250: * about its interpretation.
251: *
252: * @param resSel an object that describes resource selection criteria
253: * @return collection of <code>WfResource</code> objects
254: * @throws RemoteException if a system-level error occurs
255: * @throws UnsupportedOperationException if the resource management
256: * service does not support this feature.
257: */
258: public Collection selectResources(Object resSel)
259: throws RemoteException, UnsupportedOperationException {
260: RmsConnection con = null;
261: try {
262: con = conFac.getConnection();
263: Collection resRaw = con.selectResources(resSel);
264: Collection res = new ArrayList();
265: for (Iterator i = resRaw.iterator(); i.hasNext();) {
266: RmsEntry e = (RmsEntry) i.next();
267: addAsTyped(res, e);
268: }
269: return res;
270: } catch (ResourceException e) {
271: maybeMapToRemoteException(e);
272: throw new IllegalStateException("Cannot select resources: "
273: + e.getMessage());
274: } finally {
275: closeConnection(con);
276: }
277: }
278:
279: /**
280: * @param res
281: * @param e
282: */
283: private void addAsTyped(Collection res, RmsEntry e) {
284: if (e.getType() == RmsEntry.RESOURCE_TYPE_USER) {
285: res.add(new DefaultUserResource(rasCtx, e.getKey(), e
286: .getDisplayName()));
287: } else if (e.getType() == RmsEntry.RESOURCE_TYPE_ROLE) {
288: res.add(new DefaultRoleResource(rasCtx, e.getKey(), e
289: .getDisplayName()));
290: } else if (e.getType() == RmsEntry.RESOURCE_TYPE_GROUP) {
291: res.add(new DefaultGroupResource(rasCtx, e.getKey(), e
292: .getDisplayName()));
293: } else {
294: res.add(new DefaultResource(rasCtx, e.getKey(), e
295: .getDisplayName()));
296: }
297: }
298:
299: private void maybeMapToRemoteException(ResourceException e)
300: throws RemoteException {
301: // Will repeating the operation help? Depends...
302: if (e instanceof ApplicationServerInternalException
303: || e instanceof CommException
304: || e instanceof EISSystemException
305: || e instanceof javax.resource.spi.IllegalStateException
306: || e instanceof LocalTransactionException
307: || e instanceof ResourceAllocationException) {
308: throw (RemoteException) (new RemoteException(
309: "Problem accessing resource: " + e.getMessage()))
310: .initCause(e);
311: }
312: }
313:
314: private void closeConnection(RmsConnection con) {
315: if (con != null) {
316: try {
317: con.close();
318: } catch (ResourceException e) {
319: logger.warn("Problem closing connection (ignored): "
320: + e.getMessage());
321: }
322: }
323: }
324: }
|