/* *------------------------------------------------------------------------------ * Copyright (C) 2006-2015 University of Dundee & Open Microscopy Environment. * All rights reserved. * * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * *------------------------------------------------------------------------------ */ package omero.gateway; import java.beans.PropertyChangeListener; import java.beans.PropertyChangeSupport; import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Set; import java.util.concurrent.Callable; import java.util.concurrent.atomic.AtomicLong; import org.apache.commons.collections.CollectionUtils; import org.apache.commons.lang.StringUtils; import com.google.common.cache.Cache; import com.google.common.cache.CacheBuilder; import com.google.common.collect.HashMultimap; import com.google.common.collect.MapMaker; import com.google.common.collect.Multimap; import com.google.common.collect.Multimaps; import com.google.common.collect.Sets; import ome.formats.OMEROMetadataStoreClient; import omero.ServerError; import omero.client; import omero.api.ExporterPrx; import omero.api.ExporterPrxHelper; import omero.api.IAdminPrx; import omero.api.IAdminPrxHelper; import omero.api.IConfigPrx; import omero.api.IConfigPrxHelper; import omero.api.IContainerPrx; import omero.api.IContainerPrxHelper; import omero.api.IMetadataPrx; import omero.api.IMetadataPrxHelper; import omero.api.IPixelsPrx; import omero.api.IPixelsPrxHelper; import omero.api.IProjectionPrx; import omero.api.IProjectionPrxHelper; import omero.api.IQueryPrx; import omero.api.IQueryPrxHelper; import omero.api.IRenderingSettingsPrx; import omero.api.IRenderingSettingsPrxHelper; import omero.api.IRepositoryInfoPrx; import omero.api.IRepositoryInfoPrxHelper; import omero.api.IRoiPrx; import omero.api.IRoiPrxHelper; import omero.api.IScriptPrx; import omero.api.IScriptPrxHelper; import omero.api.ISessionPrx; import omero.api.IUpdatePrx; import omero.api.IUpdatePrxHelper; import omero.api.RawFileStorePrx; import omero.api.RawFileStorePrxHelper; import omero.api.RawPixelsStorePrx; import omero.api.RawPixelsStorePrxHelper; import omero.api.RenderingEnginePrx; import omero.api.SearchPrx; import omero.api.SearchPrxHelper; import omero.api.ServiceFactoryPrx; import omero.api.ServiceInterfacePrx; import omero.api.StatefulServiceInterfacePrx; import omero.api.ThumbnailStorePrx; import omero.api.ThumbnailStorePrxHelper; import omero.cmd.CmdCallbackI; import omero.cmd.DoAll; import omero.cmd.Request; import omero.gateway.exception.DSOutOfServiceException; import omero.grid.SharedResourcesPrx; import omero.grid.SharedResourcesPrxHelper; import omero.log.LogMessage; import omero.log.Logger; import omero.model.ExperimenterGroup; import omero.model.Session; import omero.sys.Principal; /** * Manages the various services and entry points. * * @author Jean-Marie Burel      * <a href="mailto:j.burel@dundee.ac.uk">j.burel@dundee.ac.uk</a> * @since Beta4.4 */ class Connector { /** * The elapsed time before checking if the services need to be * kept alive. */ private final int ELAPSED_TIME = 30000; /** Keeps track of the last keep alive action.*/ private final AtomicLong lastKeepAlive = new AtomicLong(System.currentTimeMillis()); /** * The Blitz client object, this is the entry point to the * OMERO Server using a secure connection. */ private final client secureClient; /** * The client object, this is the entry point to the * OMERO Server using non secure data transfer */ private client unsecureClient; /** * The entry point provided by the connection library to access the various * <i>OMERO</i> services. */ private ServiceFactoryPrx entryEncrypted; /** * The entry point provided by the connection library to access the various * <i>OMERO</i> services. */ private ServiceFactoryPrx entryUnencrypted; /** Collection of stateless services to prevent re-lookup */ private final Map<String, ServiceInterfacePrx> statelessServices; /** Collection of stateful services to prevent re-lookup. * {@link RenderingEnginePrx} and {@link OMEROMetadataStoreClient} * instances are stored separately */ private final Multimap<String, StatefulServiceInterfacePrx> statefulServices; private final Map<OMEROMetadataStoreClient, String> importStores; /** Collection of services to keep alive. */ private final Multimap<Long, RenderingEnginePrx> reServices; /** The security context for that connector.*/ private final SecurityContext context; /** * The map of derived connector. This will be only used when * performing action for other users e.g. import as. */ //TODO: this should be reviewed, since if getConnector(String) is used //outside of the import process there could be a race condition. private final Cache<String, Connector> derived; /** The name of the group. To be removed when we can use groupId.*/ private String groupName; /** Reference to the logger.*/ private final Logger logger; /** The username if this is a derived connector */ private String username = null; /** The PropertyChangeSupport */ private final PropertyChangeSupport pcs = new PropertyChangeSupport(this); /** * Creates a new instance. * * @param context The context hosting information about the user. * @param secureClient The entry point to server. * @param entryEncrypted The entry point to access the various services. * @param encrypted Pass <code>false</code> to use an unencrypted connection * for data transfers * @param logger Reference to the logger. * @param elapseTime The time between network check. * @throws Exception Thrown if entry points cannot be initialized. */ Connector(SecurityContext context, client client, ServiceFactoryPrx entryEncrypted, boolean encrypted, Logger logger) throws Exception { this(context, client, entryEncrypted, encrypted, null, logger); } /** * Creates a new instance. * * @param context The context hosting information about the user. * @param secureClient The entry point to server. * @param entryEncrypted The entry point to access the various services. * @param encrypted Pass <code>false</code> to use an unencrypted connection * for data transfers * @param username The username if this is a derived connector * @param logger Reference to the logger. * @param elapseTime The time between network check. * @throws Exception Thrown if entry points cannot be initialized. */ Connector(SecurityContext context, client client, ServiceFactoryPrx entryEncrypted, boolean encrypted, String username, Logger logger) throws Exception { if (context == null) throw new IllegalArgumentException("No Security context."); if (client == null) throw new IllegalArgumentException("No Server entry point."); if (entryEncrypted == null) throw new IllegalArgumentException("No Services entry point."); if (!encrypted) { unsecureClient = client.createClient(false); entryUnencrypted = unsecureClient.getSession(); } else { unsecureClient = null; entryUnencrypted = null; } this.username = username; this.logger = logger; this.secureClient = client; this.entryEncrypted = entryEncrypted; this.context = context; final MapMaker mapMaker = new MapMaker(); statelessServices = mapMaker.makeMap(); importStores = mapMaker.makeMap(); statefulServices = Multimaps.<String, StatefulServiceInterfacePrx> synchronizedMultimap( HashMultimap.<String, StatefulServiceInterfacePrx>create()); reServices = Multimaps.<Long, RenderingEnginePrx> synchronizedMultimap( HashMultimap.<Long, RenderingEnginePrx>create()); derived = CacheBuilder.newBuilder().build(); } /** * Adds a {@link PropertyChangeListener} * @param listener The listener */ public void addPropertyChangeListener(PropertyChangeListener listener) { this.pcs.addPropertyChangeListener(listener); } /** * Removes a {@link PropertyChangeListener} * @param listener The listener */ public void removePropertyChangeListener(PropertyChangeListener listener) { this.pcs.removePropertyChangeListener(listener); } /** * Get the {@link PropertyChangeListener}s * @return See above */ public PropertyChangeListener[] getPropertyChangeListeners() { return this.pcs.getPropertyChangeListeners(); } // // Regular service lookups // /** * Returns the {@link SharedResourcesPrx} service. * * @return See above. * @throws Throwable Thrown if the service cannot be initialized. */ SharedResourcesPrx getSharedResources() throws DSOutOfServiceException { return SharedResourcesPrxHelper.uncheckedCast( get(omero.constants.SHAREDRESOURCES.value, true)); } /** * Returns the {@link IRenderingSettingsPrx} service. * * @return See above. * @throws Throwable Thrown if the service cannot be initialized. */ IRenderingSettingsPrx getRenderingSettingsService() throws DSOutOfServiceException { return IRenderingSettingsPrxHelper.uncheckedCast( get(omero.constants.RENDERINGSETTINGS.value, unsecureClient == null)); } /** * Returns the {@link IRepositoryInfoPrx} service. * * @return See above. * @throws Throwable Thrown if the service cannot be initialized. */ IRepositoryInfoPrx getRepositoryService() throws DSOutOfServiceException { return IRepositoryInfoPrxHelper.uncheckedCast( get(omero.constants.REPOSITORYINFO.value, unsecureClient == null)); } /** * Returns the {@link IScriptPrx} service. * * @return See above. * @throws Throwable Thrown if the service cannot be initialized. */ IScriptPrx getScriptService() throws DSOutOfServiceException { return IScriptPrxHelper.uncheckedCast( get(omero.constants.SCRIPTSERVICE.value, unsecureClient == null)); } /** * Returns the {@link IContainerPrx} service. * * @return See above. * @throws Throwable Thrown if the service cannot be initialized. */ IContainerPrx getPojosService() throws DSOutOfServiceException { return IContainerPrxHelper.uncheckedCast( get(omero.constants.CONTAINERSERVICE.value, unsecureClient == null)); } /** * Returns the {@link IQueryPrx} service. * * @return See above. * @throws Throwable Thrown if the service cannot be initialized. */ IQueryPrx getQueryService() throws DSOutOfServiceException { return IQueryPrxHelper.uncheckedCast( get(omero.constants.QUERYSERVICE.value, unsecureClient == null)); } /** * Returns the {@link IUpdatePrx} service. * * @return See above. * @throws Throwable Thrown if the service cannot be initialized. */ IUpdatePrx getUpdateService() throws DSOutOfServiceException { return IUpdatePrxHelper.uncheckedCast( get(omero.constants.UPDATESERVICE.value, unsecureClient == null)); } /** * Returns the {@link IMetadataPrx} service. * * @return See above. * @throws Throwable Thrown if the service cannot be initialized. */ IMetadataPrx getMetadataService() throws DSOutOfServiceException { return IMetadataPrxHelper.uncheckedCast( get(omero.constants.METADATASERVICE.value, unsecureClient == null)); } /** * Returns the {@link IRoiPrx} service. * * @return See above. * @throws Throwable Thrown if the service cannot be initialized. */ IRoiPrx getROIService() throws DSOutOfServiceException { return IRoiPrxHelper.uncheckedCast( get(omero.constants.ROISERVICE.value, unsecureClient == null)); } /** * Returns the {@link IConfigPrx} service. * * @return See above. * @throws Throwable Thrown if the service cannot be initialized. */ IConfigPrx getConfigService() throws DSOutOfServiceException { return IConfigPrxHelper.uncheckedCast( get(omero.constants.CONFIGSERVICE.value, unsecureClient == null)); } /** * Returns the {@link ThumbnailStorePrx} service. * * @return See above. * @throws Throwable Thrown if the service cannot be initialized. */ ThumbnailStorePrx getThumbnailService() throws DSOutOfServiceException { return ThumbnailStorePrxHelper.uncheckedCast( create(omero.constants.THUMBNAILSTORE.value, unsecureClient == null)); } /** * Returns the {@link ExporterPrx} service. * * @return See above. * @throws @throws Throwable Thrown if the service cannot be initialized. */ ExporterPrx getExporterService() throws DSOutOfServiceException { return ExporterPrxHelper.uncheckedCast( create(omero.constants.EXPORTERSERVICE.value, unsecureClient == null)); } /** * Returns the {@link RawFileStorePrx} service. * * @return See above. * @throws @throws Throwable Thrown if the service cannot be initialized. */ RawFileStorePrx getRawFileService() throws DSOutOfServiceException { return RawFileStorePrxHelper.uncheckedCast( create(omero.constants.RAWFILESTORE.value, unsecureClient == null)); } /** * Returns the {@link RawPixelsStorePrx} service. * * @return See above. * @throws Throwable Thrown if the service cannot be initialized. */ RawPixelsStorePrx getPixelsStore() throws DSOutOfServiceException { return RawPixelsStorePrxHelper.uncheckedCast( create(omero.constants.RAWPIXELSSTORE.value, unsecureClient == null)); } /** * Returns the {@link IPixelsPrx} service. * * @return See above. * @throws Throwable Thrown if the service cannot be initialized. */ IPixelsPrx getPixelsService() throws DSOutOfServiceException { return IPixelsPrxHelper.uncheckedCast( get(omero.constants.PIXELSSERVICE.value, unsecureClient == null)); } /** * Returns the {@link SearchPrx} service. * * @return See above. * @throws Throwable Thrown if the service cannot be initialized. */ SearchPrx getSearchService() throws DSOutOfServiceException { return SearchPrxHelper.uncheckedCast( create(omero.constants.SEARCH.value, unsecureClient == null)); } /** * Returns the {@link IProjectionPrx} service. * * @return See above. * @throws Throwable Thrown if the service cannot be initialized. */ IProjectionPrx getProjectionService() throws DSOutOfServiceException { return IProjectionPrxHelper.uncheckedCast( get(omero.constants.PROJECTIONSERVICE.value, unsecureClient == null)); } /** * Returns the {@link IAdminPrx} service. * * @return See above. * @throws Throwable Thrown if the service cannot be initialized. */ IAdminPrx getAdminService() throws DSOutOfServiceException { return getAdminService(unsecureClient == null); } /** * Returns the {@link IAdminPrx} service. * * @param secure Pass <code>true</code> to have a secure admin service, * <code>false</code> otherwise. * @return See above. * @throws Throwable Thrown if the service cannot be initialized. */ IAdminPrx getAdminService(boolean secure) throws DSOutOfServiceException { return IAdminPrxHelper.uncheckedCast( get(omero.constants.ADMINSERVICE.value, secure)); } // // Irregular service lookups // /** * Creates or recycles the import store. * * @return See above. * @throws Throwable Thrown if the service cannot be initialized. */ OMEROMetadataStoreClient getImportStore() throws DSOutOfServiceException { OMEROMetadataStoreClient importStore = new OMEROMetadataStoreClient(); try { if (entryUnencrypted != null) { // Note: this is a change. Now permit unencrypted import! importStore.initialize(entryUnencrypted); } else { importStore.initialize(entryEncrypted); } this.pcs.firePropertyChange(Gateway.PROP_IMPORTSTORE_CREATED, null, importStore); importStores.put(importStore, ""); return importStore; } catch (Exception e) { throw new DSOutOfServiceException("Failed to create import store", e); } } /** * Returns the {@link RenderingEnginePrx Rendering service}. * * @return See above. * @throws Throwable Thrown if the service cannot be initialized. */ RenderingEnginePrx getRenderingService(long pixelsID, float compression) throws DSOutOfServiceException, ServerError { RenderingEnginePrx prx = null; try { if (entryUnencrypted != null) { prx = entryUnencrypted.createRenderingEngine(); } else { prx = entryEncrypted.createRenderingEngine(); } this.pcs.firePropertyChange(Gateway.PROP_RENDERINGENGINE_CREATED, null, prx); } catch (Exception e) { throw new DSOutOfServiceException("Could not get rendering engine", e); } prx.setCompressionLevel(compression); reServices.put(pixelsID, prx); return prx; } /** * Rejoins the session. * * @throws Throwable Thrown if an error occurred while rejoining the session. */ void joinSession() throws Throwable { String uuid = secureClient.getSessionId(); statelessServices.clear(); reServices.clear(); statefulServices.clear(); secureClient.closeSession(); if (unsecureClient != null) { unsecureClient.closeSession(); } entryEncrypted = secureClient.joinSession(uuid); if (unsecureClient != null) { //we are in unsecured mode unsecureClient = null; entryUnencrypted = null; unsecureClient = secureClient.createClient(false); entryUnencrypted = unsecureClient.getSession(); } } /** * Helper returning the group id, to be used after reconnect. * * @return See above. */ long getGroupID() { return context.getGroupID(); } // // Cleanup // /** * Closes the session. * * @param networkup Pass <code>true</code> if the network is up, * <code>false</code> otherwise. */ void close(boolean networkup) throws Throwable { secureClient.setFastShutdown(!networkup); if (unsecureClient != null) unsecureClient.setFastShutdown(!networkup); if (networkup) { shutDownServices(true); } String id = secureClient.getSessionId(); secureClient.__del__(); // Won't throw. this.pcs.firePropertyChange(Gateway.PROP_SESSION_CLOSED, null, id); if (unsecureClient != null) { id = unsecureClient.getSessionId(); unsecureClient.__del__(); this.pcs.firePropertyChange(Gateway.PROP_SESSION_CLOSED, null, id); } if (username == null) this.pcs.firePropertyChange(Gateway.PROP_CONNECTOR_CLOSED, null, id); else this.pcs.firePropertyChange(Gateway.PROP_CONNECTOR_CLOSED, null, id + "_" + username); closeDerived(networkup); } /** * Closes the services initialized by the importer. */ //TODO: along with the TODO on derived, this will need to be reviewed //for race conditions. void closeImport() { shutdownImports(); try { closeDerived(false); } catch (Throwable e) { logger.warn(this, new LogMessage("Exception on closeDerived: ", e)); } } /** * Closes the connectors associated to the master connector. * * @param networkup Pass <code>true</code> if the network is up, * <code>false</code> otherwise. */ void closeDerived(boolean networkup) throws Throwable { for (final Connector c : derived.asMap().values()) { try { c.close(networkup); } catch (Throwable e) { logger.warn(this, String.format("Failed to close(%s) service: %s", networkup, c)); } } derived.invalidateAll(); } /** * Shuts downs the stateful services. * * @param rendering Pass <code>true</code> to shut down the rendering * services, <code>false</code> otherwise. */ void shutDownServices(boolean rendering) { shutdownStateful(); shutdownImports(); if (!rendering) return; Set<Long> tmp = new HashSet<Long>(reServices.keySet()); for (Long pixelsId : tmp) { shutDownRenderingEngine(pixelsId); } } /** * Keeps the services alive. * Returns <code>true</code> if success, <code>false</code> otherwise. * * @return See above. */ boolean keepSessionAlive() { boolean success = true; try { entryEncrypted.keepAllAlive(null); } catch (Exception e) { success = false; logger.warn(this, new LogMessage("Failed encrypted keep alive: " ,e)); } try { if (entryUnencrypted != null && success) entryUnencrypted.keepAllAlive(null); } catch (Exception e) { success = false; logger.warn(this, new LogMessage("failed unencrypted keep alive: ", e)); } if (success) { lastKeepAlive.set(System.currentTimeMillis()); } return success; } /** * Closes the specified proxy. * * @param proxy The proxy to close. */ void close(StatefulServiceInterfacePrx proxy) { if (proxy == null) { return; } try { proxy.close(); } catch (Ice.ObjectNotExistException e) { // ignore } catch (Exception e) { logger.warn(this, new LogMessage("Failed to close " + proxy, e)); } finally { if (proxy instanceof RenderingEnginePrx) { this.pcs.firePropertyChange(Gateway.PROP_RENDERINGENGINE_CLOSED, null, proxy); Set<Long> keys = reServices.keySet(); keys = Sets.newHashSet(keys); for (Long key : keys) { reServices.remove(key, proxy); } } else { this.pcs.firePropertyChange(Gateway.PROP_STATEFUL_SERVICE_CLOSED, null, proxy); Set<String> keys = statefulServices.keySet(); keys = Sets.newHashSet(keys); for (String key : keys) { statefulServices.remove(key, proxy); } } } } /** * Shuts downs the rendering engine. * * @param pixelsId The id of the pixels set. */ void shutDownRenderingEngine(long pixelsId) { Collection<RenderingEnginePrx> proxies = reServices.removeAll(pixelsId); for (RenderingEnginePrx prx : proxies) { close(prx); } } /** Shuts down the import services.*/ void shutdownImports() { List<OMEROMetadataStoreClient> imports = new ArrayList<OMEROMetadataStoreClient>(); synchronized (importStores) { imports.addAll(importStores.keySet()); importStores.clear(); } for (OMEROMetadataStoreClient store : imports) { try { store.closeServices(); this.pcs.firePropertyChange(Gateway.PROP_IMPORTSTORE_CLOSED, null, store); } catch (Exception e) { logger.warn(this, new LogMessage("Failed to close import store:", e)); } } } /** Shuts down the stateful services.*/ void shutdownStateful() { Collection<StatefulServiceInterfacePrx> proxies = null; synchronized (statefulServices) { proxies = statefulServices.values(); statefulServices.clear(); } for (StatefulServiceInterfacePrx prx : proxies) { close(prx); this.pcs.firePropertyChange(Gateway.PROP_STATEFUL_SERVICE_CLOSED, null, prx); } } /** * Returns the unsecured client if not <code>null</code> otherwise * returns the secured client. * * @return See above. */ client getClient() { if (unsecureClient != null) return unsecureClient; return secureClient; } /** * Executes the commands. * * @param commands The commands to execute. * @param target The target context is any. * @return See above. */ CmdCallbackI submit(List<Request> commands, SecurityContext target) throws Throwable { if (CollectionUtils.isEmpty(commands)) return null; DoAll all = new DoAll(); all.requests = commands; Map<String, String> callContext = new HashMap<String, String>(); if (target != null) { callContext.put("omero.group", ""+target.getGroupID()); } if (entryUnencrypted != null) { return new CmdCallbackI(getClient(), entryUnencrypted.submit(all, callContext)); } return new CmdCallbackI(getClient(), entryEncrypted.submit(all, callContext)); } /** * Returns the rendering engines that are currently active. * * @return See above. */ Map<SecurityContext, Set<Long>> getRenderingEngines() { Map<SecurityContext, Set<Long>> map = new HashMap<SecurityContext, Set<Long>>(); Set<Long> list = new HashSet<Long>(); Iterator<Long> i = reServices.keySet().iterator(); while (i.hasNext()) list.add(i.next()); map.put(context, list); return map; } /** * Returns the connector associated to the specified user. If none exists, * creates a connector. * * @param userName * The name of the user. To be replaced by user's id. * @return See above. */ Connector getConnector(final String userName) throws Throwable { if (StringUtils.isBlank(userName)) return this; return derived.get(userName, new Callable<Connector>() { @Override public Connector call() throws Exception { if (groupName == null) { ExperimenterGroup g = getAdminService().getGroup( context.getGroupID()); groupName = g.getName().getValue(); } // Create a connector. Principal p = new Principal(); p.group = groupName; p.name = userName; p.eventType = "Sessions"; ISessionPrx prx = entryEncrypted.getSessionService(); Session session = prx.getSession(secureClient.getSessionId()); long timeout = session.getTimeToIdle().getValue(); session = prx.createSessionWithTimeouts(p, 0, timeout); // Create the userSession omero.client client = new omero.client(context .getServerInformation().getHostname(), context .getServerInformation().getPort()); ServiceFactoryPrx userSession = client.createSession(session .getUuid().getValue(), session.getUuid().getValue()); Connector.this.pcs.firePropertyChange(Gateway.PROP_SESSION_CREATED, null, client.getSessionId()); final Connector c = new Connector(context.copy(), client, userSession, unsecureClient == null, userName, logger); for (PropertyChangeListener l : Connector.this.pcs .getPropertyChangeListeners()) c.addPropertyChangeListener(l); Connector.this.pcs.firePropertyChange(Gateway.PROP_CONNECTOR_CREATED, null, client.getSessionId()+"_"+userName); logger.debug(this, "Created derived connector: " + userName); return c; } }); } // // HELPERS // /** * Returns <code>true</code> if the services need to be kept alive, * <code>false</code> otherwise. * * @return See above. */ boolean needsKeepAlive() { long last = lastKeepAlive.get(); long elapsed = System.currentTimeMillis() - last; return elapsed > ELAPSED_TIME; } /** * Recycles the specified service. * * @param name The name of the service to create or recycle. * @param secure Pass <code>true</code> to create a secure object, * <code>false</code> otherwise. * @return See above. * @throws DSOutOfServiceException Thrown if an error occurred. */ private ServiceInterfacePrx get(String name, boolean secure) throws DSOutOfServiceException { try { ServiceInterfacePrx prx = statelessServices.get(name); if (!secure && prx != null) { // Reload if secure is true. //TODO: Why? return prx; } if (!secure && entryUnencrypted != null) { prx = entryUnencrypted.getByName(name); } else { prx = entryEncrypted.getByName(name); } statelessServices.put(name, prx); this.pcs.firePropertyChange(Gateway.PROP_STATELESS_SERVICE_CREATED, null, prx); return prx; } catch (Exception e) { throw new DSOutOfServiceException("Could not load " + name, e); } } /** * Creates the specified service. * * @param name The name of the service to create or recycle. * @param secure Pass <code>true</code> to create a secure object, * <code>false</code> otherwise. * @return See above. * @throws DSOutOfServiceException Thrown if an error occurred. */ private StatefulServiceInterfacePrx create(String name, boolean secure) throws DSOutOfServiceException { try { StatefulServiceInterfacePrx prx = null; if (!secure && entryUnencrypted != null) { prx = entryUnencrypted.createByName(name); } else { prx = entryEncrypted.createByName(name); } statefulServices.put(name, prx); this.pcs.firePropertyChange(Gateway.PROP_STATEFUL_SERVICE_CREATED, null, prx); return prx; } catch (Exception e) { throw new DSOutOfServiceException("Could not create " + name, e); } } }