|
Modified: ofbiz/branches/20120329_portletWidget/framework/service/src/org/ofbiz/service/DispatchContext.java
URL: http://svn.apache.org/viewvc/ofbiz/branches/20120329_portletWidget/framework/service/src/org/ofbiz/service/DispatchContext.java?rev=1369382&r1=1369381&r2=1369382&view=diff ============================================================================== --- ofbiz/branches/20120329_portletWidget/framework/service/src/org/ofbiz/service/DispatchContext.java (original) +++ ofbiz/branches/20120329_portletWidget/framework/service/src/org/ofbiz/service/DispatchContext.java Sat Aug 4 18:11:00 2012 @@ -19,9 +19,6 @@ package org.ofbiz.service; import java.io.Serializable; -import java.net.URL; -import java.util.Collection; -import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Set; @@ -43,8 +40,9 @@ import org.ofbiz.base.util.Debug; import org.ofbiz.base.util.UtilXml; import org.ofbiz.base.util.cache.UtilCache; import org.ofbiz.entity.Delegator; +import org.ofbiz.entity.config.DelegatorInfo; +import org.ofbiz.entity.config.EntityConfigUtil; import org.ofbiz.security.Security; -import org.ofbiz.security.authz.Authorization; import org.ofbiz.service.config.ServiceConfigUtil; import org.ofbiz.service.eca.ServiceEcaUtil; import org.w3c.dom.Document; @@ -58,77 +56,94 @@ public class DispatchContext implements public static final String module = DispatchContext.class.getName(); - protected static final String GLOBAL_KEY = "global.services"; - private static final UtilCache<String, Map<String, ModelService>> modelServiceMapByDispatcher = UtilCache.createUtilCache("service.ModelServiceMapByDispatcher", 0, 0, false); + private static final UtilCache<String, Map<String, ModelService>> modelServiceMapByModel = UtilCache.createUtilCache("service.ModelServiceMapByModel", 0, 0, false); - protected transient LocalDispatcher dispatcher; - protected transient ClassLoader loader; - protected Collection<URL> localReaders; - protected Map<String, Object> attributes; - protected String name; - - /** - * Creates new DispatchContext - * @param localReaders a collection of reader URLs - * @param loader the classloader to use for dispatched services + // these four fields represent the immutable state of a DispatchContext object + private final String name; + private final transient ClassLoader loader; + private final transient LocalDispatcher dispatcher; + private final String model; + + /** + * Creates new DispatchContext as an immutable object. + * The "dispatcher" argument can be null if the "name" argument matches the name of a valid entity model reader. + * The thread safety of a DispatchContext object is a consequence of its immutability. + * + * @param name The immutable name of the DispatchContext + * @param loader The immutable class loader + * @param dispatcher The immutable dispatcher associated to the DispatchContext + * */ - public DispatchContext(String name, Collection<URL> localReaders, ClassLoader loader, LocalDispatcher dispatcher) { + public DispatchContext(String name, ClassLoader loader, LocalDispatcher dispatcher) { this.name = name; - this.localReaders = localReaders; this.loader = loader; this.dispatcher = dispatcher; - this.attributes = FastMap.newInstance(); - } - - public void loadReaders() { - this.getLocalServiceMap(); - this.getGlobalServiceMap(); + String modelName = null; + if (this.dispatcher != null) { + Delegator delegator = dispatcher.getDelegator(); + if (delegator != null) { + DelegatorInfo delegatorInfo = EntityConfigUtil.getDelegatorInfo(delegator.getDelegatorBaseName()); + if (delegatorInfo != null) { + modelName = delegatorInfo.entityModelReader; + } + } + } + if (modelName == null) { + // if a modelName is not associated to the dispatcher (e.g. dispatcher is null) then use the name + // of the DispatchContext as the model reader name + modelName = name; + } + this.model = modelName; + getGlobalServiceMap(); } /** - * Returns the service attribute for the given name, or null if there is no attribute by that name. - * @param name a String specifying the name of the attribute - * @return an Object containing the value of the attribute, or null if there is no attribute by that name. + * Gets the classloader of this context + * @return ClassLoader of the context */ - public Object getAttribute(String name) { - if (attributes.containsKey(name)) - return attributes.get(name); - return null; + public ClassLoader getClassLoader() { + return this.loader; } /** - * Binds an object to a given attribute name in this context. - * @param name a String specifying the name of the attribute - * @param object an Object representing the attribute to be bound. + * Gets the name of the local dispatcher + * @return String name of the LocalDispatcher object */ - public void setAttribute(String name, Object object) { - attributes.put(name, object); + public String getName() { + return name; } /** - * Gets the classloader of this context - * @return ClassLoader of the context + * Gets the LocalDispatcher used with this context + * @return LocalDispatcher that was used to create this context */ - public ClassLoader getClassLoader() { - return this.loader; + public LocalDispatcher getDispatcher() { + return this.dispatcher; } /** - * Gets the collection of readers associated with this context - * @return Collection of reader URLs + * Gets the Delegator associated with this context/dispatcher + * @return Delegator associated with this context */ - public Collection<URL> getReaders() { - return localReaders; + public Delegator getDelegator() { + return dispatcher.getDelegator(); } /** - * Gets the name of the local dispatcher - * @return String name of the LocalDispatcher object + * Gets the Security object associated with this dispatcher + * @return Security object associated with this dispatcher */ - public String getName() { - return name; + public Security getSecurity() { + return dispatcher.getSecurity(); } + // All the methods that follow are helper methods to retrieve service model information from cache (and manage the cache) + // The cache object is static but most of these methods are not because the same service definition, is used with different + // DispatchContext objects may result in different in/out attributes: this happens because the DispatchContext is associated to + // a LocalDispatcher that is associated to a Delegator that is associated to a ModelReader; different ModelReaders could load the + // same entity name from different files with different fields, and the service definition could automatically get the input/output + // attributes from an entity. + /** * Uses an existing map of name value pairs and extracts the keys which are used in serviceName * Note: This goes not guarantee the context will be 100% valid, there may be missing fields @@ -139,9 +154,8 @@ public class DispatchContext implements * @throws GenericServiceException */ public Map<String, Object> makeValidContext(String serviceName, String mode, Map<String, ? extends Object> context) throws GenericServiceException { - ModelService model = this.getModelService(serviceName); + ModelService model = getModelService(serviceName); return makeValidContext(model, mode, context); - } /** @@ -153,7 +167,7 @@ public class DispatchContext implements * @return Map contains any valid values * @throws GenericServiceException */ - public Map<String, Object> makeValidContext(ModelService model, String mode, Map<String, ? extends Object> context) throws GenericServiceException { + public static Map<String, Object> makeValidContext(ModelService model, String mode, Map<String, ? extends Object> context) throws GenericServiceException { Map<String, Object> newContext; int modeInt = 0; @@ -186,23 +200,7 @@ public class DispatchContext implements * @return GenericServiceModel that corresponds to the serviceName */ public ModelService getModelService(String serviceName) throws GenericServiceException { - //long timeStart = System.currentTimeMillis(); - ModelService retVal = getLocalModelService(serviceName); - if (retVal == null) { - retVal = getGlobalModelService(serviceName); - } - - if (retVal == null) { - throw new GenericServiceException("Cannot locate service by name (" + serviceName + ")"); - } - - //Debug.logTiming("Got ModelService for name [" + serviceName + "] in [" + (System.currentTimeMillis() - timeStart) + "] milliseconds", module); - return retVal; - } - - private ModelService getLocalModelService(String serviceName) throws GenericServiceException { - Map<String, ModelService> serviceMap = this.getLocalServiceMap(); - + Map<String, ModelService> serviceMap = getGlobalServiceMap(); ModelService retVal = null; if (serviceMap != null) { retVal = serviceMap.get(serviceName); @@ -210,84 +208,25 @@ public class DispatchContext implements retVal.interfaceUpdate(this); } } - - return retVal; - } - - private ModelService getGlobalModelService(String serviceName) throws GenericServiceException { - Map<String, ModelService> serviceMap = this.getGlobalServiceMap(); - - ModelService retVal = null; - if (serviceMap != null) { - retVal = serviceMap.get(serviceName); - if (retVal != null && !retVal.inheritedParameters()) { - retVal.interfaceUpdate(this); - } + if (retVal == null) { + throw new GenericServiceException("Cannot locate service by name (" + serviceName + ")"); } - return retVal; } - /** - * Gets the LocalDispatcher used with this context - * @return LocalDispatcher that was used to create this context - */ - public LocalDispatcher getDispatcher() { - return this.dispatcher; - } - - /** - * Sets the LocalDispatcher used with this context - * @param dispatcher The LocalDispatcher to re-assign to this context - */ - public void setDispatcher(LocalDispatcher dispatcher) { - this.dispatcher = dispatcher; - } - - /** - * Gets the Delegator associated with this context/dispatcher - * @return Delegator associated with this context - */ - public Delegator getDelegator() { - return dispatcher.getDelegator(); - } - - /** - * Gets the Authorization object associated with this dispatcher - * @return Authorization object associated with this dispatcher - */ - public Authorization getAuthorization() { - return dispatcher.getAuthorization(); - } - - /** - * Gets the Security object associated with this dispatcher - * @return Security object associated with this dispatcher - */ - public Security getSecurity() { - return dispatcher.getSecurity(); - } + public Set<String> getAllServiceNames() { + Set<String> serviceNames = new TreeSet<String>(); - private Map<String, ModelService> getLocalServiceMap() { - Map<String, ModelService> serviceMap = modelServiceMapByDispatcher.get(name); - if (serviceMap == null) { - if (this.localReaders != null) { - serviceMap = FastMap.newInstance(); - for (URL readerURL: this.localReaders) { - Map<String, ModelService> readerServiceMap = ModelServiceReader.getModelServiceMap(readerURL, this); - if (readerServiceMap != null) { - serviceMap.putAll(readerServiceMap); - } - } - serviceMap = new HashMap<String, ModelService>(serviceMap); - } - if (serviceMap != null) { - serviceMap = modelServiceMapByDispatcher.putIfAbsentAndGet(name, serviceMap); - // NOTE: the current ECA per dispatcher for local services stuff is a bit broken, so now just doing this on the global def load: ServiceEcaUtil.reloadConfig(); - } + Map<String, ModelService> globalServices = modelServiceMapByModel.get(this.model); + if (globalServices != null) { + serviceNames.addAll(globalServices.keySet()); } + return serviceNames; + } - return serviceMap; + public Document getWSDL(String serviceName, String locationURI) throws GenericServiceException, WSDLException { + ModelService model = this.getModelService(serviceName); + return model.toWSDL(locationURI); } private Callable<Map<String, ModelService>> createServiceReaderCallable(final ResourceHandler handler) { @@ -299,7 +238,7 @@ public class DispatchContext implements } private Map<String, ModelService> getGlobalServiceMap() { - Map<String, ModelService> serviceMap = modelServiceMapByDispatcher.get(GLOBAL_KEY); + Map<String, ModelService> serviceMap = modelServiceMapByModel.get(this.model); if (serviceMap == null) { serviceMap = FastMap.newInstance(); @@ -331,32 +270,12 @@ public class DispatchContext implements } if (serviceMap != null) { - Map<String, ModelService> cachedServiceMap = modelServiceMapByDispatcher.putIfAbsentAndGet(GLOBAL_KEY, serviceMap); + Map<String, ModelService> cachedServiceMap = modelServiceMapByModel.putIfAbsentAndGet(this.model, serviceMap); if (cachedServiceMap == serviceMap) { // same object: this means that the object created by this thread was actually added to the cache ServiceEcaUtil.reloadConfig(); } } } - return serviceMap; } - - public Set<String> getAllServiceNames() { - Set<String> serviceNames = new TreeSet<String>(); - - Map<String, ModelService> globalServices = modelServiceMapByDispatcher.get(GLOBAL_KEY); - Map<String, ModelService> localServices = modelServiceMapByDispatcher.get(name); - if (globalServices != null) { - serviceNames.addAll(globalServices.keySet()); - } - if (localServices != null) { - serviceNames.addAll(localServices.keySet()); - } - return serviceNames; - } - - public Document getWSDL(String serviceName, String locationURI) throws GenericServiceException, WSDLException { - ModelService model = this.getModelService(serviceName); - return model.toWSDL(locationURI); - } } Modified: ofbiz/branches/20120329_portletWidget/framework/service/src/org/ofbiz/service/GenericAbstractDispatcher.java URL: http://svn.apache.org/viewvc/ofbiz/branches/20120329_portletWidget/framework/service/src/org/ofbiz/service/GenericAbstractDispatcher.java?rev=1369382&r1=1369381&r2=1369382&view=diff ============================================================================== --- ofbiz/branches/20120329_portletWidget/framework/service/src/org/ofbiz/service/GenericAbstractDispatcher.java (original) +++ ofbiz/branches/20120329_portletWidget/framework/service/src/org/ofbiz/service/GenericAbstractDispatcher.java Sat Aug 4 18:11:00 2012 @@ -29,7 +29,6 @@ import org.ofbiz.entity.Delegator; import org.ofbiz.entity.transaction.GenericTransactionException; import org.ofbiz.entity.transaction.TransactionUtil; import org.ofbiz.security.Security; -import org.ofbiz.security.authz.Authorization; import org.ofbiz.service.jms.JmsListenerFactory; import org.ofbiz.service.job.JobManager; import org.ofbiz.service.job.JobManagerException; @@ -214,16 +213,8 @@ public abstract class GenericAbstractDis } /** - * @see org.ofbiz.service.LocalDispatcher#getAuthorization() - */ - public Authorization getAuthorization() { - return dispatcher.getAuthorization(); - } - - /** * @see org.ofbiz.service.LocalDispatcher#getSecurity() */ - @Deprecated public Security getSecurity() { return dispatcher.getSecurity(); } @@ -246,6 +237,7 @@ public abstract class GenericAbstractDis * @see org.ofbiz.service.LocalDispatcher#deregister() */ public void deregister() { + ServiceContainer.removeFromCache(getName()); dispatcher.deregister(this); } Modified: ofbiz/branches/20120329_portletWidget/framework/service/src/org/ofbiz/service/LocalDispatcher.java URL: http://svn.apache.org/viewvc/ofbiz/branches/20120329_portletWidget/framework/service/src/org/ofbiz/service/LocalDispatcher.java?rev=1369382&r1=1369381&r2=1369382&view=diff ============================================================================== --- ofbiz/branches/20120329_portletWidget/framework/service/src/org/ofbiz/service/LocalDispatcher.java (original) +++ ofbiz/branches/20120329_portletWidget/framework/service/src/org/ofbiz/service/LocalDispatcher.java Sat Aug 4 18:11:00 2012 @@ -22,7 +22,6 @@ import java.util.Map; import org.ofbiz.entity.Delegator; import org.ofbiz.security.Security; -import org.ofbiz.security.authz.Authorization; import org.ofbiz.service.jms.JmsListenerFactory; import org.ofbiz.service.job.JobManager; @@ -319,11 +318,6 @@ public interface LocalDispatcher { */ public Delegator getDelegator(); - /** - * Gets the Authorization object associated with this dispatcher - * @return Authorization object associated with this dispatcher - */ - public Authorization getAuthorization(); /** * Gets the Security object associated with this dispatcher @@ -344,7 +338,7 @@ public interface LocalDispatcher { public DispatchContext getDispatchContext(); /** - * De-Registers this LocalDispatcher with the ServiceDispatcher + * De-Registers this LocalDispatcher */ public void deregister(); } Modified: ofbiz/branches/20120329_portletWidget/framework/service/src/org/ofbiz/service/ModelPermission.java URL: http://svn.apache.org/viewvc/ofbiz/branches/20120329_portletWidget/framework/service/src/org/ofbiz/service/ModelPermission.java?rev=1369382&r1=1369381&r2=1369382&view=diff ============================================================================== --- ofbiz/branches/20120329_portletWidget/framework/service/src/org/ofbiz/service/ModelPermission.java (original) +++ ofbiz/branches/20120329_portletWidget/framework/service/src/org/ofbiz/service/ModelPermission.java Sat Aug 4 18:11:00 2012 @@ -27,7 +27,6 @@ import org.ofbiz.base.util.UtilValidate; import org.ofbiz.entity.GenericValue; import org.ofbiz.entity.util.EntityUtil; import org.ofbiz.security.Security; -import org.ofbiz.security.authz.Authorization; /** * Service Permission Model Class @@ -53,7 +52,6 @@ public class ModelPermission implements public boolean evalPermission(DispatchContext dctx, Map<String, ? extends Object> context) { GenericValue userLogin = (GenericValue) context.get("userLogin"); - Authorization authz = dctx.getAuthorization(); Security security = dctx.getSecurity(); if (userLogin == null) { Debug.logInfo("Secure service requested with no userLogin object", module); @@ -61,7 +59,7 @@ public class ModelPermission implements } switch (permissionType) { case PERMISSION: - return evalAuthzPermission(authz, userLogin, context); + return evalSimplePermission(security, userLogin); case ENTITY_PERMISSION: return evalEntityPermission(security, userLogin); case ROLE_MEMBER: @@ -74,12 +72,12 @@ public class ModelPermission implements } } - private boolean evalAuthzPermission(Authorization authz, GenericValue userLogin, Map<String, ? extends Object> context) { + private boolean evalSimplePermission(Security security, GenericValue userLogin) { if (nameOrRole == null) { Debug.logWarning("Null permission name passed for evaluation", module); return false; } - return authz.hasPermission(userLogin.getString("userLoginId"), nameOrRole, context); + return security.hasPermission(nameOrRole, userLogin); } private boolean evalEntityPermission(Security security, GenericValue userLogin) { Modified: ofbiz/branches/20120329_portletWidget/framework/service/src/org/ofbiz/service/ModelService.java URL: http://svn.apache.org/viewvc/ofbiz/branches/20120329_portletWidget/framework/service/src/org/ofbiz/service/ModelService.java?rev=1369382&r1=1369381&r2=1369382&view=diff ============================================================================== --- ofbiz/branches/20120329_portletWidget/framework/service/src/org/ofbiz/service/ModelService.java (original) +++ ofbiz/branches/20120329_portletWidget/framework/service/src/org/ofbiz/service/ModelService.java Sat Aug 4 18:11:00 2012 @@ -59,6 +59,7 @@ import javax.xml.parsers.DocumentBuilder import javolution.util.FastList; import javolution.util.FastMap; +import org.ofbiz.base.metrics.Metrics; import org.ofbiz.base.util.Debug; import org.ofbiz.base.util.GeneralException; import org.ofbiz.base.util.ObjectType; @@ -205,6 +206,11 @@ public class ModelService extends Abstra /** Flag to say if we have pulled in our addition parameters from our implemented service(s) */ protected boolean inheritedParameters = false; + /** + * Service metrics. + */ + public Metrics metrics = null; + public ModelService() {} public ModelService(ModelService model) { @@ -231,7 +237,7 @@ public class ModelService extends Abstra this.inheritedParameters = model.inheritedParameters(); this.internalGroup = model.internalGroup; this.hideResultInLog = model.hideResultInLog; - + this.metrics = model.metrics; List<ModelParam> modelParamList = model.getModelParamList(); for (ModelParam param: modelParamList) { this.addParamClone(param); @@ -1625,7 +1631,7 @@ public class ModelService extends Abstra cusObjElement.appendChild(cusObjElement0); Element cusObjElement1 = document.createElement("xsd:documentation"); cusObjElement0.appendChild(cusObjElement1); - cusObjElement1.setTextContent("Object content need to be in CDATA such as <cus-obj><![CDATA[--byteHex--]]></cus-obj>"); + cusObjElement1.setTextContent("Object content is hex encoded so does not need to be in a CDATA block."); schema.appendChild(cusObjElement); /*-----------------------------------*/ Modified: ofbiz/branches/20120329_portletWidget/framework/service/src/org/ofbiz/service/ModelServiceReader.java URL: http://svn.apache.org/viewvc/ofbiz/branches/20120329_portletWidget/framework/service/src/org/ofbiz/service/ModelServiceReader.java?rev=1369382&r1=1369381&r2=1369382&view=diff ============================================================================== --- ofbiz/branches/20120329_portletWidget/framework/service/src/org/ofbiz/service/ModelServiceReader.java (original) +++ ofbiz/branches/20120329_portletWidget/framework/service/src/org/ofbiz/service/ModelServiceReader.java Sat Aug 4 18:11:00 2012 @@ -20,8 +20,6 @@ package org.ofbiz.service; import java.io.IOException; import java.io.Serializable; -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; import java.net.URL; import java.util.Iterator; import java.util.LinkedHashMap; @@ -35,9 +33,9 @@ import javolution.util.FastMap; import org.ofbiz.base.config.GenericConfigException; import org.ofbiz.base.config.ResourceHandler; +import org.ofbiz.base.metrics.MetricsFactory; import org.ofbiz.base.util.Debug; import org.ofbiz.base.util.GeneralException; -import org.ofbiz.base.util.UtilProperties; import org.ofbiz.base.util.UtilTimer; import org.ofbiz.base.util.UtilValidate; import org.ofbiz.base.util.UtilXml; @@ -46,7 +44,6 @@ import org.ofbiz.entity.GenericEntityExc import org.ofbiz.entity.model.ModelEntity; import org.ofbiz.entity.model.ModelField; import org.ofbiz.entity.model.ModelFieldType; -import org.ofbiz.service.engine.GenericEngine; import org.ofbiz.service.group.GroupModel; import org.w3c.dom.Document; import org.w3c.dom.Element; @@ -68,7 +65,6 @@ public class ModelServiceReader implemen protected boolean isFromURL; protected URL readerURL = null; protected ResourceHandler handler = null; - protected Map<String, ModelService> modelServices = null; protected DispatchContext dctx = null; public static Map<String, ModelService> getModelServiceMap(URL readerURL, DispatchContext dctx) { @@ -283,7 +279,11 @@ public class ModelServiceReader implemen this.createAutoAttrDefs(serviceElement, service); this.createAttrDefs(serviceElement, service); this.createOverrideDefs(serviceElement, service); - + // Get metrics. + Element metricsElement = UtilXml.firstChildElement(serviceElement, "metric"); + if (metricsElement != null) { + service.metrics = MetricsFactory.getInstance(metricsElement); + } return service; } Modified: ofbiz/branches/20120329_portletWidget/framework/service/src/org/ofbiz/service/ServiceDispatcher.java URL: http://svn.apache.org/viewvc/ofbiz/branches/20120329_portletWidget/framework/service/src/org/ofbiz/service/ServiceDispatcher.java?rev=1369382&r1=1369381&r2=1369382&view=diff ============================================================================== --- ofbiz/branches/20120329_portletWidget/framework/service/src/org/ofbiz/service/ServiceDispatcher.java (original) +++ ofbiz/branches/20120329_portletWidget/framework/service/src/org/ofbiz/service/ServiceDispatcher.java Sat Aug 4 18:11:00 2012 @@ -21,6 +21,7 @@ package org.ofbiz.service; import java.util.List; import java.util.Locale; import java.util.Map; + import javax.transaction.Transaction; import javolution.util.FastList; @@ -30,7 +31,6 @@ import org.ofbiz.base.config.GenericConf import org.ofbiz.base.util.Debug; import org.ofbiz.base.util.GeneralRuntimeException; import org.ofbiz.base.util.UtilMisc; -import org.ofbiz.base.util.UtilProperties; import org.ofbiz.base.util.UtilTimer; import org.ofbiz.base.util.UtilValidate; import org.ofbiz.base.util.UtilXml; @@ -45,8 +45,6 @@ import org.ofbiz.entity.transaction.Tran import org.ofbiz.security.Security; import org.ofbiz.security.SecurityConfigurationException; import org.ofbiz.security.SecurityFactory; -import org.ofbiz.security.authz.Authorization; -import org.ofbiz.security.authz.AuthorizationFactory; import org.ofbiz.service.config.ServiceConfigUtil; import org.ofbiz.service.eca.ServiceEcaRule; import org.ofbiz.service.eca.ServiceEcaUtil; @@ -60,7 +58,6 @@ import org.ofbiz.service.semaphore.Servi import org.w3c.dom.Element; import com.googlecode.concurrentlinkedhashmap.ConcurrentLinkedHashMap; -import com.googlecode.concurrentlinkedhashmap.ConcurrentLinkedHashMap.Builder; /** * Global Service Dispatcher @@ -79,7 +76,6 @@ public class ServiceDispatcher { protected Delegator delegator = null; protected GenericEngineFactory factory = null; - protected Authorization authz = null; protected Security security = null; protected Map<String, DispatchContext> localContext = null; protected Map<String, List<GenericServiceCallback>> callbacks = null; @@ -98,7 +94,6 @@ public class ServiceDispatcher { if (delegator != null) { try { - this.authz = AuthorizationFactory.getInstance(delegator); this.security = SecurityFactory.getInstance(delegator); } catch (SecurityConfigurationException e) { Debug.logError(e, "[ServiceDispatcher.init] : No instance of security implementation found.", module); @@ -118,7 +113,7 @@ public class ServiceDispatcher { // make sure we haven't disabled these features from running if (enableJMS) { - this.jlf = JmsListenerFactory.getInstance(this); + this.jlf = JmsListenerFactory.getInstance(delegator); } if (enableSvcs) { @@ -132,28 +127,28 @@ public class ServiceDispatcher { /** * Returns a pre-registered instance of the ServiceDispatcher associated with this delegator. + * @param name the name of the DispatchContext * @param delegator the local delegator - * @return A reference to this global ServiceDispatcher + * @return A reference to the LocalDispatcher associated with the DispatchContext */ - public static ServiceDispatcher getInstance(String name, Delegator delegator) { - ServiceDispatcher sd = getInstance(null, null, delegator); - - if (!sd.containsContext(name)) { - return null; + public static LocalDispatcher getLocalDispatcher(String name, Delegator delegator) { + // get the ServiceDispatcher associated to the delegator (if not found in the cache, it will be created and added to the cache) + ServiceDispatcher sd = getInstance(delegator); + // if a DispatchContext has already been already registered as "name" then return the LocalDispatcher associated with it + if (sd.containsContext(name)) { + return sd.getLocalDispatcher(name); } - return sd; + // otherwise return null + return null; } /** - * Returns an instance of the ServiceDispatcher associated with this delegator and registers the loader. - * @param name the local dispatcher - * @param context the context of the local dispatcher + * Returns an instance of the ServiceDispatcher associated with this delegator. * @param delegator the local delegator * @return A reference to this global ServiceDispatcher */ - public static ServiceDispatcher getInstance(String name, DispatchContext context, Delegator delegator) { + public static ServiceDispatcher getInstance(Delegator delegator) { ServiceDispatcher sd; - String dispatcherKey = delegator != null ? delegator.getDelegatorName() : "null"; sd = dispatchers.get(dispatcherKey); if (sd == null) { @@ -166,10 +161,6 @@ public class ServiceDispatcher { } } } - - if (name != null && context != null) { - sd.register(name, context); - } return sd; } @@ -178,11 +169,10 @@ public class ServiceDispatcher { * @param name the local dispatcher * @param context the context of the local dispatcher */ - public void register(String name, DispatchContext context) { - if (Debug.verboseOn()) Debug.logVerbose("Registered dispatcher: " + context.getName(), module); - this.localContext.put(name, context); + public void register(DispatchContext context) { + if (Debug.infoOn()) Debug.logInfo("Registering dispatcher: " + context.getName(), module); + this.localContext.put(context.getName(), context); } - /** * De-Registers the loader with this ServiceDispatcher * @param local the LocalDispatcher to de-register @@ -190,13 +180,13 @@ public class ServiceDispatcher { public void deregister(LocalDispatcher local) { if (Debug.infoOn()) Debug.logInfo("De-Registering dispatcher: " + local.getName(), module); localContext.remove(local.getName()); - if (localContext.size() == 1) { // 1 == the JMSDispatcher - try { + if (localContext.size() == 0) { + try { this.shutdown(); } catch (GenericServiceException e) { Debug.logError(e, "Trouble shutting down ServiceDispatcher!", module); } - } + } } public synchronized void registerCallback(String serviceName, GenericServiceCallback cb) { @@ -251,54 +241,47 @@ public class ServiceDispatcher { * @throws GenericServiceException */ public Map<String, Object> runSync(String localName, ModelService modelService, Map<String, ? extends Object> params, boolean validateOut) throws ServiceAuthException, ServiceValidationException, GenericServiceException { - // check for semaphore and aquire a lock - ServiceSemaphore lock = null; - if ("wait".equals(modelService.semaphore) || "fail".equals(modelService.semaphore)) { - lock = new ServiceSemaphore(delegator, modelService); - lock.acquire(); - } - long serviceStartTime = System.currentTimeMillis(); - boolean debugging = checkDebug(modelService, 1, true); - if (Debug.verboseOn()) { - Debug.logVerbose("[ServiceDispatcher.runSync] : invoking service " + modelService.name + " [" + modelService.location + - "/" + modelService.invoke + "] (" + modelService.engineName + ")", module); - } - - Map<String, Object> context = FastMap.newInstance(); - if (params != null) { - context.putAll(params); - } - - // setup the result map and other initial settings Map<String, Object> result = FastMap.newInstance(); + ServiceSemaphore lock = null; + Map<String, List<ServiceEcaRule>> eventMap = null; + Map<String, Object> ecaContext = null; + RunningService rs = null; + DispatchContext ctx = localContext.get(localName); + GenericEngine engine = null; + Transaction parentTransaction = null; boolean isFailure = false; boolean isError = false; + boolean beganTrans = false; + try { + // check for semaphore and aquire a lock + if ("wait".equals(modelService.semaphore) || "fail".equals(modelService.semaphore)) { + lock = new ServiceSemaphore(delegator, modelService); + lock.acquire(); + } - // set up the running service log - RunningService rs = this.logService(localName, modelService, GenericEngine.SYNC_MODE); - - // get eventMap once for all calls for speed, don't do event calls if it is null - Map<String, List<ServiceEcaRule>> eventMap = ServiceEcaUtil.getServiceEventMap(modelService.name); - - // check the locale - Locale locale = this.checkLocale(context); + if (Debug.verboseOn() || modelService.debug) { + Debug.logVerbose("[ServiceDispatcher.runSync] : invoking service " + modelService.name + " [" + modelService.location + + "/" + modelService.invoke + "] (" + modelService.engineName + ")", module); + } - // setup the engine and context - DispatchContext ctx = localContext.get(localName); - GenericEngine engine = this.getGenericEngine(modelService.engineName); + Map<String, Object> context = FastMap.newInstance(); + if (params != null) { + context.putAll(params); + } + // check the locale + Locale locale = this.checkLocale(context); - // set IN attributes with default-value as applicable - modelService.updateDefaultValues(context, ModelService.IN_PARAM); + // set up the running service log + rs = this.logService(localName, modelService, GenericEngine.SYNC_MODE); - Map<String, Object> ecaContext = null; + // get eventMap once for all calls for speed, don't do event calls if it is null + eventMap = ServiceEcaUtil.getServiceEventMap(modelService.name); + engine = this.getGenericEngine(modelService.engineName); - // for isolated transactions - Transaction parentTransaction = null; - // start the transaction - boolean beganTrans = false; - try { + // set IN attributes with default-value as applicable + modelService.updateDefaultValues(context, ModelService.IN_PARAM); //Debug.logInfo("=========================== " + modelService.name + " 1 tx status =" + TransactionUtil.getStatusString() + ", modelService.requireNewTransaction=" + modelService.requireNewTransaction + ", modelService.useTransaction=" + modelService.useTransaction + ", TransactionUtil.isTransactionInPlace()=" + TransactionUtil.isTransactionInPlace(), module); if (modelService.useTransaction) { if (TransactionUtil.isTransactionInPlace()) { @@ -516,7 +499,6 @@ public class ServiceDispatcher { } catch (GenericTransactionException te) { Debug.logError(te, "Cannot rollback transaction", module); } - checkDebug(modelService, 0, debugging); rs.setEndStamp(); if (t instanceof ServiceAuthException) { throw (ServiceAuthException) t; @@ -544,6 +526,7 @@ public class ServiceDispatcher { try { TransactionUtil.commit(beganTrans); } catch (GenericTransactionException e) { + GenericDelegator.popUserIdentifier(); String errMsg = "Could not commit transaction for service [" + modelService.name + "] call"; Debug.logError(e, errMsg, module); if (e.getMessage() != null) { @@ -563,9 +546,13 @@ public class ServiceDispatcher { Debug.logError(te, "Problems with the transaction", module); throw new GenericServiceException("Problems with the transaction.", te.getNested()); } finally { - // release the semaphore lock if (lock != null) { - lock.release(); + // release the semaphore lock + try { + lock.release(); + } catch (GenericServiceException e) { + Debug.logWarning(e, "Exception thrown while unlocking semaphore: ", module); + } } // resume the parent transaction @@ -582,7 +569,6 @@ public class ServiceDispatcher { // pre-return ECA if (eventMap != null) ServiceEcaUtil.evalRules(modelService.name, eventMap, "return", ctx, ecaContext, result, isError, isFailure); - checkDebug(modelService, 0, debugging); rs.setEndStamp(); long timeToRun = System.currentTimeMillis() - serviceStartTime; @@ -591,7 +577,7 @@ public class ServiceDispatcher { } else if (Debug.infoOn() && timeToRun > 200) { Debug.logInfo("Very slow sync service execution detected: service [" + localName + "/" + modelService.name + "] finished in [" + timeToRun + "] milliseconds", module); } - if (Debug.verboseOn() && timeToRun > 50 && !modelService.hideResultInLog) { + if ((Debug.verboseOn() || modelService.debug) && timeToRun > 50 && !modelService.hideResultInLog) { // Sanity check - some service results can be multiple MB in size. Limit message size to 10K. String resultStr = result.toString(); if (resultStr.length() > 10240) { @@ -599,6 +585,9 @@ public class ServiceDispatcher { } Debug.logVerbose("Sync service [" + localName + "/" + modelService.name + "] finished with response [" + resultStr + "]", module); } + if (modelService.metrics != null) { + modelService.metrics.recordServiceRate(1, timeToRun); + } return result; } @@ -617,8 +606,7 @@ public class ServiceDispatcher { if (Debug.timingOn()) { UtilTimer.timerLog(localName + " / " + service.name, "ASync service started...", module); } - boolean debugging = checkDebug(service, 1, true); - if (Debug.verboseOn()) { + if (Debug.verboseOn() || service.debug) { Debug.logVerbose("[ServiceDispatcher.runAsync] : preparing service " + service.name + " [" + service.location + "/" + service.invoke + "] (" + service.engineName + ")", module); } @@ -714,7 +702,6 @@ public class ServiceDispatcher { if (Debug.timingOn()) { UtilTimer.closeTimer(localName + " / " + service.name, "ASync service finished...", module); } - checkDebug(service, 0, debugging); } catch (Throwable t) { if (Debug.timingOn()) { UtilTimer.closeTimer(localName + " / " + service.name, "ASync service failed...", module); @@ -727,7 +714,6 @@ public class ServiceDispatcher { } catch (GenericTransactionException te) { Debug.logError(te, "Cannot rollback transaction", module); } - checkDebug(service, 0, debugging); if (t instanceof ServiceAuthException) { throw (ServiceAuthException) t; } else if (t instanceof ServiceValidationException) { @@ -810,18 +796,9 @@ public class ServiceDispatcher { } /** - * Gets the Authorization object associated with this dispatcher - * @return Authorization object associated with this dispatcher - */ - public Authorization getAuthorization() { - return this.authz; - } - - /** * Gets the Security object associated with this dispatcher * @return Security object associated with this dispatcher */ - @Deprecated public Security getSecurity() { return this.security; } @@ -854,8 +831,10 @@ public class ServiceDispatcher { protected void shutdown() throws GenericServiceException { Debug.logImportant("Shutting down the service engine...", module); - // shutdown JMS listeners - jlf.closeListeners(); + if (jlf != null) { + // shutdown JMS listeners + jlf.closeListeners(); + } // shutdown the job scheduler jm.shutdown(); } @@ -984,32 +963,6 @@ public class ServiceDispatcher { return newLocale; } - // mode 1 = beginning (turn on) mode 0 = end (turn off) - private boolean checkDebug(ModelService model, int mode, boolean enable) { - boolean debugOn = Debug.verboseOn(); - switch (mode) { - case 0: - if (model.debug && enable && debugOn) { - // turn it off - Debug.set(Debug.VERBOSE, false); - Debug.logInfo("Verbose logging turned OFF", module); - return true; - } - break; - case 1: - if (model.debug && enable && !debugOn) { - // turn it on - Debug.set(Debug.VERBOSE, true); - Debug.logInfo("Verbose logging turned ON", module); - return true; - } - break; - default: - Debug.logError("Invalid mode for checkDebug should be (0 or 1)", module); - } - return false; - } - // run startup services private synchronized int runStartupServices() { if (jm == null) return 0; Modified: ofbiz/branches/20120329_portletWidget/framework/service/src/org/ofbiz/service/engine/AbstractEngine.java URL: http://svn.apache.org/viewvc/ofbiz/branches/20120329_portletWidget/framework/service/src/org/ofbiz/service/engine/AbstractEngine.java?rev=1369382&r1=1369381&r2=1369382&view=diff ============================================================================== --- ofbiz/branches/20120329_portletWidget/framework/service/src/org/ofbiz/service/engine/AbstractEngine.java (original) +++ ofbiz/branches/20120329_portletWidget/framework/service/src/org/ofbiz/service/engine/AbstractEngine.java Sat Aug 4 18:11:00 2012 @@ -18,12 +18,12 @@ *******************************************************************************/ package org.ofbiz.service.engine; +import java.util.Collections; +import java.util.HashMap; import java.util.Map; import java.util.List; import java.util.Iterator; -import javolution.util.FastMap; - import org.ofbiz.service.ServiceDispatcher; import org.ofbiz.service.ModelService; import org.ofbiz.service.GenericServiceException; @@ -41,40 +41,38 @@ import org.w3c.dom.Element; public abstract class AbstractEngine implements GenericEngine { public static final String module = AbstractEngine.class.getName(); - protected static Map<String, String> locationMap = null; + protected static final Map<String, String> locationMap = createLocationMap(); protected ServiceDispatcher dispatcher = null; protected AbstractEngine(ServiceDispatcher dispatcher) { this.dispatcher = dispatcher; - initLocations(); } // creates the location alias map - protected synchronized void initLocations() { - if (locationMap == null) { - locationMap = FastMap.newInstance(); - - Element root = null; - try { - root = ServiceConfigUtil.getXmlRootElement(); - } catch (GenericConfigException e) { - Debug.logError(e, module); - } + protected static Map<String, String> createLocationMap() { + Map<String, String> tmpMap = new HashMap<String, String>(); + + Element root = null; + try { + root = ServiceConfigUtil.getXmlRootElement(); + } catch (GenericConfigException e) { + Debug.logError(e, module); + } - if (root != null) { - List<? extends Element> locationElements = UtilXml.childElementList(root, "service-location"); - if (locationElements != null) { - for (Element e: locationElements) { - locationMap.put(e.getAttribute("name"), e.getAttribute("location")); - } + if (root != null) { + List<? extends Element> locationElements = UtilXml.childElementList(root, "service-location"); + if (locationElements != null) { + for (Element e: locationElements) { + tmpMap.put(e.getAttribute("name"), e.getAttribute("location")); } } - Debug.logInfo("Loaded Service Locations : " + locationMap, module); } + Debug.logInfo("Loaded Service Locations: " + tmpMap, module); + return Collections.unmodifiableMap(tmpMap); } - // uses the lookup map to determin if the location has been aliased in serviceconfig.xml + // uses the lookup map to determine if the location has been aliased by a service-location element in serviceengine.xml protected String getLocation(ModelService model) { if (locationMap.containsKey(model.location)) { return locationMap.get(model.location); Modified: ofbiz/branches/20120329_portletWidget/framework/service/src/org/ofbiz/service/jms/AbstractJmsListener.java URL: http://svn.apache.org/viewvc/ofbiz/branches/20120329_portletWidget/framework/service/src/org/ofbiz/service/jms/AbstractJmsListener.java?rev=1369382&r1=1369381&r2=1369382&view=diff ============================================================================== --- ofbiz/branches/20120329_portletWidget/framework/service/src/org/ofbiz/service/jms/AbstractJmsListener.java (original) +++ ofbiz/branches/20120329_portletWidget/framework/service/src/org/ofbiz/service/jms/AbstractJmsListener.java Sat Aug 4 18:11:00 2012 @@ -28,12 +28,12 @@ import javax.jms.Message; import org.ofbiz.base.util.Debug; import org.ofbiz.base.util.ObjectType; import org.ofbiz.base.util.UtilGenerics; +import org.ofbiz.entity.Delegator; import org.ofbiz.entity.serialize.XmlSerializer; -import org.ofbiz.service.GenericDispatcher; import org.ofbiz.service.GenericServiceException; import org.ofbiz.service.LocalDispatcher; import org.ofbiz.service.ModelService; -import org.ofbiz.service.ServiceDispatcher; +import org.ofbiz.service.ServiceContainer; /** * AbstractJmsListener @@ -47,10 +47,10 @@ public abstract class AbstractJmsListene /** * Initializes the LocalDispatcher for this service listener. - * @param serviceDispatcher the service dispatcher + * @param delegator the delegator associated to the dispatcher */ - protected AbstractJmsListener(ServiceDispatcher serviceDispatcher) { - this.dispatcher = GenericDispatcher.getLocalDispatcher("entity-default", null, null, this.getClass().getClassLoader(), serviceDispatcher); + protected AbstractJmsListener(Delegator delegator) { + this.dispatcher = ServiceContainer.getLocalDispatcher("JMSDispatcher", delegator); } /** Modified: ofbiz/branches/20120329_portletWidget/framework/service/src/org/ofbiz/service/jms/JmsListenerFactory.java URL: http://svn.apache.org/viewvc/ofbiz/branches/20120329_portletWidget/framework/service/src/org/ofbiz/service/jms/JmsListenerFactory.java?rev=1369382&r1=1369381&r2=1369382&view=diff ============================================================================== --- ofbiz/branches/20120329_portletWidget/framework/service/src/org/ofbiz/service/jms/JmsListenerFactory.java (original) +++ ofbiz/branches/20120329_portletWidget/framework/service/src/org/ofbiz/service/jms/JmsListenerFactory.java Sat Aug 4 18:11:00 2012 @@ -28,8 +28,8 @@ import org.ofbiz.base.util.UtilGenerics; import org.ofbiz.base.util.UtilMisc; import org.ofbiz.base.util.UtilValidate; import org.ofbiz.base.util.UtilXml; +import org.ofbiz.entity.Delegator; import org.ofbiz.service.GenericServiceException; -import org.ofbiz.service.ServiceDispatcher; import org.ofbiz.service.config.ServiceConfigUtil; import org.w3c.dom.Element; import org.w3c.dom.NodeList; @@ -49,18 +49,18 @@ public class JmsListenerFactory implemen protected static JmsListenerFactory jlf = null; - protected ServiceDispatcher dispatcher; + protected Delegator delegator; protected boolean firstPass = true; protected int loadable = 0; protected int connected = 0; protected Thread thread; - public static JmsListenerFactory getInstance(ServiceDispatcher dispatcher){ + public static JmsListenerFactory getInstance(Delegator delegator){ if (jlf == null) { synchronized (JmsListenerFactory.class) { if (jlf == null) { - jlf = new JmsListenerFactory(dispatcher); + jlf = new JmsListenerFactory(delegator); } } } @@ -68,8 +68,8 @@ public class JmsListenerFactory implemen return jlf; } - public JmsListenerFactory(ServiceDispatcher dispatcher) { - this.dispatcher = dispatcher; + public JmsListenerFactory(Delegator delegator) { + this.delegator = delegator; thread = new Thread(this, this.toString()); thread.setDaemon(false); thread.start(); @@ -80,6 +80,10 @@ public class JmsListenerFactory implemen while (firstPass || connected < loadable) { if (Debug.verboseOn()) Debug.logVerbose("First Pass: " + firstPass + " Connected: " + connected + " Available: " + loadable, module); this.loadListeners(); + if (loadable == 0) { + // if there is nothing to do then we can break without sleeping + break; + } firstPass = false; try { Thread.sleep(20000); @@ -95,7 +99,7 @@ public class JmsListenerFactory implemen Element rootElement = ServiceConfigUtil.getXmlRootElement(); NodeList nodeList = rootElement.getElementsByTagName("jms-service"); - if (Debug.verboseOn()) Debug.logVerbose("[ServiceDispatcher] : Loading JMS Listeners.", module); + if (Debug.verboseOn()) Debug.logVerbose("Loading JMS Listeners.", module); for (int i = 0; i < nodeList.getLength(); i++) { Element element = (Element) nodeList.item(i); StringBuilder serverKey = new StringBuilder(); @@ -158,9 +162,9 @@ public class JmsListenerFactory implemen try { Class<?> c = cl.loadClass(className); - Constructor<GenericMessageListener> cn = UtilGenerics.cast(c.getConstructor(ServiceDispatcher.class, String.class, String.class, String.class, String.class, String.class)); + Constructor<GenericMessageListener> cn = UtilGenerics.cast(c.getConstructor(Delegator.class, String.class, String.class, String.class, String.class, String.class)); - listener = cn.newInstance(dispatcher, serverName, jndiName, queueName, userName, password); + listener = cn.newInstance(delegator, serverName, jndiName, queueName, userName, password); } catch (Exception e) { throw new GenericServiceException(e.getMessage(), e); } Modified: ofbiz/branches/20120329_portletWidget/framework/service/src/org/ofbiz/service/jms/JmsQueueListener.java URL: http://svn.apache.org/viewvc/ofbiz/branches/20120329_portletWidget/framework/service/src/org/ofbiz/service/jms/JmsQueueListener.java?rev=1369382&r1=1369381&r2=1369382&view=diff ============================================================================== --- ofbiz/branches/20120329_portletWidget/framework/service/src/org/ofbiz/service/jms/JmsQueueListener.java (original) +++ ofbiz/branches/20120329_portletWidget/framework/service/src/org/ofbiz/service/jms/JmsQueueListener.java Sat Aug 4 18:11:00 2012 @@ -29,10 +29,10 @@ import javax.naming.InitialContext; import javax.naming.NamingException; import org.ofbiz.service.GenericServiceException; -import org.ofbiz.service.ServiceDispatcher; import org.ofbiz.base.util.Debug; import org.ofbiz.base.util.GeneralException; import org.ofbiz.base.util.JNDIContextFactory; +import org.ofbiz.entity.Delegator; /** * JmsQueueListener - Queue (P2P) Message Listener. @@ -50,8 +50,8 @@ public class JmsQueueListener extends Ab /** * Creates a new JmsQueueListener - Should only be called by the JmsListenerFactory. */ - public JmsQueueListener(ServiceDispatcher dispatcher, String jndiServer, String jndiName, String queueName, String userName, String password) { - super(dispatcher); + public JmsQueueListener(Delegator delegator, String jndiServer, String jndiName, String queueName, String userName, String password) { + super(delegator); this.jndiServer = jndiServer; this.jndiName = jndiName; this.queueName = queueName; Modified: ofbiz/branches/20120329_portletWidget/framework/service/src/org/ofbiz/service/jms/JmsTopicListener.java URL: http://svn.apache.org/viewvc/ofbiz/branches/20120329_portletWidget/framework/service/src/org/ofbiz/service/jms/JmsTopicListener.java?rev=1369382&r1=1369381&r2=1369382&view=diff ============================================================================== --- ofbiz/branches/20120329_portletWidget/framework/service/src/org/ofbiz/service/jms/JmsTopicListener.java (original) +++ ofbiz/branches/20120329_portletWidget/framework/service/src/org/ofbiz/service/jms/JmsTopicListener.java Sat Aug 4 18:11:00 2012 @@ -29,10 +29,10 @@ import javax.naming.InitialContext; import javax.naming.NamingException; import org.ofbiz.service.GenericServiceException; -import org.ofbiz.service.ServiceDispatcher; import org.ofbiz.base.util.Debug; import org.ofbiz.base.util.GeneralException; import org.ofbiz.base.util.JNDIContextFactory; +import org.ofbiz.entity.Delegator; /** * JmsTopicListener - Topic (Pub/Sub) Message Listener. @@ -50,8 +50,8 @@ public class JmsTopicListener extends Ab /** * Creates a new JmsTopicListener - Should only be called by the JmsListenerFactory. */ - public JmsTopicListener(ServiceDispatcher dispatcher, String jndiServer, String jndiName, String topicName, String userName, String password) { - super(dispatcher); + public JmsTopicListener(Delegator delegator, String jndiServer, String jndiName, String topicName, String userName, String password) { + super(delegator); this.jndiServer = jndiServer; this.jndiName = jndiName; this.topicName = topicName; Modified: ofbiz/branches/20120329_portletWidget/framework/service/src/org/ofbiz/service/job/JobInvoker.java URL: http://svn.apache.org/viewvc/ofbiz/branches/20120329_portletWidget/framework/service/src/org/ofbiz/service/job/JobInvoker.java?rev=1369382&r1=1369381&r2=1369382&view=diff ============================================================================== --- ofbiz/branches/20120329_portletWidget/framework/service/src/org/ofbiz/service/job/JobInvoker.java (original) +++ ofbiz/branches/20120329_portletWidget/framework/service/src/org/ofbiz/service/job/JobInvoker.java Sat Aug 4 18:11:00 2012 @@ -20,13 +20,9 @@ package org.ofbiz.service.job; import java.util.Date; -import org.apache.commons.lang.math.NumberUtils; import org.ofbiz.base.util.Debug; -import org.ofbiz.base.util.UtilDateTime; import org.ofbiz.entity.transaction.GenericTransactionException; import org.ofbiz.entity.transaction.TransactionUtil; -import org.ofbiz.security.authz.AbstractAuthorization; -import org.ofbiz.service.config.ServiceConfigUtil; /** * JobInvoker @@ -34,82 +30,20 @@ import org.ofbiz.service.config.ServiceC public class JobInvoker implements Runnable { public static final String module = JobInvoker.class.getName(); - public static final long THREAD_TTL = 18000000; - public static final int WAIT_TIME = 750; - private JobPoller jp = null; - private Thread thread = null; private Date created = null; - private String name = null; - private int count = 0; - private int wait = 0; - - private volatile boolean run = false; - private volatile Job currentJob = null; - private volatile int statusCode = 0; - private volatile long jobStart = 0; + private long jobStart; - public JobInvoker(JobPoller jp) { - this(jp, WAIT_TIME); - } + private Job currentJob = null; - public JobInvoker(JobPoller jp, int wait) { + public JobInvoker(Job job) { this.created = new Date(); - this.run = true; - this.count = 0; - this.jp = jp; - this.wait = wait; - - // service dispatcher delegator name (for thread name) - String delegatorName = jp.getManager().getDelegator().getDelegatorName(); - - // get a new thread - this.thread = new Thread(this); - this.name = delegatorName + "-invoker-" + this.thread.getName(); - - this.thread.setDaemon(false); - this.thread.setName(this.name); - - if (Debug.verboseOn()) Debug.logVerbose("JobInvoker: Starting Invoker Thread -- " + thread.getName(), module); - this.thread.start(); + this.currentJob = job; } protected JobInvoker() {} /** - * Tells the thread to stop after the next job. - */ - public void stop() { - run = false; - } - - /** - * Wakes up this thread. - */ - public void wakeUp() { - notifyAll(); - } - - /** - * Gets the number of times this thread was used. - * @return The number of times used. - */ - public int getUsage() { - return count; - } - - /** - * Gets the remaining time this thread has before it is killed - * @return Time in millis remaining - */ - public long getTimeRemaining() { - long now = UtilDateTime.nowTimestamp().getTime(); - long time = getTime(); - long ttl = getTTL(); - return (time + ttl) - now; - } - - /** * Gets the time when this thread was created. * @return Time in milliseconds when this was created. */ @@ -118,24 +52,8 @@ public class JobInvoker implements Runna } /** - * Gets the name of this JobInvoker. - * @return Name of the invoker. - */ - public String getName() { - return this.name; - } - - /** - * Gets the status code for this thread (0 = sleeping, 1 = running job) - * @return 0 for sleeping or 1 when running a job. - */ - public int getCurrentStatus() { - return this.statusCode; - } - - /** * Gets the total time the current job has been running or 0 when sleeping. - * @return Total time the curent job has been running. + * @return Total time the current job has been running. */ public long getCurrentRuntime() { if (this.jobStart > 0) { @@ -146,27 +64,15 @@ public class JobInvoker implements Runna } } - public Long getThreadId() { - if (this.thread != null) { - return this.thread.getId(); - } else { - return null; - } - } - /** * Get the current running job's ID. * @return String ID of the current running job. */ public String getJobId() { - if (this.statusCode == 1) { - if (this.currentJob != null) { - return this.currentJob.getJobId(); - } else { - return "WARNING: Invalid Job!"; - } + if (this.currentJob != null) { + return this.currentJob.getJobId(); } else { - return null; + return "WARNING: Invalid Job!"; } } @@ -175,14 +81,10 @@ public class JobInvoker implements Runna * @return String name of the current running job. */ public String getJobName() { - if (this.statusCode == 1) { - if (this.currentJob != null) { - return this.currentJob.getJobName(); - } else { - return "WARNING: Invalid Job!"; - } + if (this.currentJob != null) { + return this.currentJob.getJobName(); } else { - return null; + return "WARNING: Invalid Job!"; } } @@ -192,104 +94,45 @@ public class JobInvoker implements Runna */ public String getServiceName() { String serviceName = null; - if (this.statusCode == 1) { - if (this.currentJob != null) { - if (this.currentJob instanceof GenericServiceJob) { - GenericServiceJob gsj = (GenericServiceJob) this.currentJob; - try { - serviceName = gsj.getServiceName(); - } catch (InvalidJobException e) { - Debug.logError(e, module); - } + if (this.currentJob != null) { + if (this.currentJob instanceof GenericServiceJob) { + GenericServiceJob gsj = (GenericServiceJob) this.currentJob; + try { + serviceName = gsj.getServiceName(); + } catch (InvalidJobException e) { + Debug.logError(e, module); } } } return serviceName; } - /** - * Kill this invoker thread.s - */ - public void kill() { - this.stop(); - this.statusCode = -1; - this.thread.interrupt(); - this.thread = null; - } - - public synchronized void run() { - while (run) { - Job job = jp.next(); - - if (job == null) { - try { - java.lang.Thread.sleep(wait); - } catch (InterruptedException ie) { - Debug.logError(ie, "JobInvoker.run() : InterruptedException", module); - stop(); - } - } else { - Debug.logInfo("Invoker [" + thread.getName() + "] received job [" + job.getJobName() + "] from poller [" + jp.toString() + "]", module); - - // setup the current job settings - this.currentJob = job; - this.statusCode = 1; - this.jobStart = System.currentTimeMillis(); - - // execute the job - if (Debug.verboseOn()) Debug.logVerbose("Invoker: " + thread.getName() + " executing job -- " + job.getJobName(), module); - try { - job.exec(); - } catch (InvalidJobException e) { - Debug.logWarning(e.getMessage(), module); - } - if (Debug.verboseOn()) Debug.logVerbose("Invoker: " + thread.getName() + " finished executing job -- " + job.getJobName(), module); - - // clear the current job settings - this.currentJob = null; - this.statusCode = 0; - this.jobStart = 0; - - // sanity check; make sure we don't have any transactions in place - try { - // roll back current TX first - if (TransactionUtil.isTransactionInPlace()) { - Debug.logWarning("*** NOTICE: JobInvoker finished w/ a transaction in place! Rolling back.", module); - TransactionUtil.rollback(); - } - - // now resume/rollback any suspended txs - if (TransactionUtil.suspendedTransactionsHeld()) { - int suspended = TransactionUtil.cleanSuspendedTransactions(); - Debug.logWarning("Resumed/Rolled Back [" + suspended + "] transactions.", module); - } - } catch (GenericTransactionException e) { - Debug.logWarning(e, module); - } + public void run() { + // setup the current job settings + this.jobStart = System.currentTimeMillis(); - // increment the count - count++; - if (Debug.verboseOn()) Debug.logVerbose("Invoker: " + thread.getName() + " (" + count + ") total.", module); - - // reset thread local security - AbstractAuthorization.clearThreadLocal(); - } - long diff = (new Date().getTime() - this.getTime()); - - if (getTTL() > 0 && diff > getTTL()) - jp.removeThread(this); + // execute the job + try { + this.currentJob.exec(); + } catch (InvalidJobException e) { + Debug.logWarning(e.getMessage(), module); } - if (Debug.verboseOn()) Debug.logVerbose("Invoker: " + thread.getName() + " dead -- " + UtilDateTime.nowTimestamp(), module); - } - - private long getTTL() { - long ttl = THREAD_TTL; + // sanity check; make sure we don't have any transactions in place try { - ttl = NumberUtils.toLong(ServiceConfigUtil.getElementAttr("thread-pool", "ttl")); - } catch (NumberFormatException nfe) { - Debug.logError("Problems reading value from attribute [ttl] of element [thread-pool] in serviceengine.xml file [" + nfe.toString() + "]. Using default (" + THREAD_TTL + ").", module); + // roll back current TX first + if (TransactionUtil.isTransactionInPlace()) { + Debug.logWarning("*** NOTICE: JobInvoker finished w/ a transaction in place! Rolling back.", module); + TransactionUtil.rollback(); + } + + // now resume/rollback any suspended txs + if (TransactionUtil.suspendedTransactionsHeld()) { + int suspended = TransactionUtil.cleanSuspendedTransactions(); + Debug.logWarning("Resumed/Rolled Back [" + suspended + "] transactions.", module); + } + } catch (GenericTransactionException e) { + Debug.logWarning(e, module); } - return ttl; } } |
| Free forum by Nabble | Edit this page |
