📄 servicedispatcher.java
字号:
}
// needed for events
DispatchContext ctx = (DispatchContext) localContext.get(localName);
try {
// get eventMap once for all calls for speed, don't do event calls if it is null
Map eventMap = ServiceEcaUtil.getServiceEventMap(modelService.name);
// setup global transaction ECA listeners
if (eventMap != null) ServiceEcaUtil.evalRules(modelService.name, eventMap, "global-rollback", ctx, context, null, false);
if (eventMap != null) ServiceEcaUtil.evalRules(modelService.name, eventMap, "global-commit", ctx, context, null, false);
// pre-auth ECA
if (eventMap != null) ServiceEcaUtil.evalRules(modelService.name, eventMap, "auth", ctx, context, null, false);
context = checkAuth(localName, context, modelService);
Object userLogin = context.get("userLogin");
if (modelService.auth && userLogin == null) {
throw new ServiceAuthException("User authorization is required for this service: " + modelService.name + modelService.debugInfo());
}
// setup the engine
GenericEngine engine = getGenericEngine(modelService.engineName);
// pre-validate ECA
if (eventMap != null) ServiceEcaUtil.evalRules(modelService.name, eventMap, "in-validate", ctx, context, null, false);
// validate the context
if (modelService.validate) {
try {
modelService.validate(context, ModelService.IN_PARAM);
} catch (ServiceValidationException e) {
Debug.logError(e, "Incoming context (in runSync : " + modelService.name + ") does not match expected requirements", module);
throw e;
}
}
// pre-invoke ECA
if (eventMap != null) ServiceEcaUtil.evalRules(modelService.name, eventMap, "invoke", ctx, context, null, false);
// ===== invoke the service =====
Map result = engine.runSync(localName, modelService, context);
// if anything but the error response, is not an error
boolean isError = ModelService.RESPOND_ERROR.equals(result.get(ModelService.RESPONSE_MESSAGE));
// create a new context with the results to pass to ECA services; necessary because caller may reuse this context
Map ecaContext = new HashMap(context);
// copy all results: don't worry parameters that aren't allowed won't be passed to the ECA services
ecaContext.putAll(result);
// validate the result
if (modelService.validate && validateOut) {
// pre-out-validate ECA
if (eventMap != null) ServiceEcaUtil.evalRules(modelService.name, eventMap, "out-validate", ctx, ecaContext, result, isError);
try {
modelService.validate(result, ModelService.OUT_PARAM);
} catch (ServiceValidationException e) {
Debug.logError(e, "Outgoing result (in runSync : " + modelService.name + ") does not match expected requirements", module);
throw e;
}
}
// pre-commit ECA
if (eventMap != null) ServiceEcaUtil.evalRules(modelService.name, eventMap, "commit", ctx, ecaContext, result, isError);
// if there was an error, rollback transaction, otherwise commit
if (isError) {
// try to log the error
Debug.logError("Service Error [" + modelService.name + "]: " + result.get(ModelService.ERROR_MESSAGE), module);
// rollback the transaction
try {
TransactionUtil.rollback(beganTrans);
} catch (GenericTransactionException e) {
Debug.logError(e, "Could not rollback transaction", module);
}
} else {
// commit the transaction
try {
TransactionUtil.commit(beganTrans);
} catch (GenericTransactionException e) {
Debug.logError(e, "Could not commit transaction", module);
throw new GenericServiceException("Commit transaction failed");
}
}
// resume the parent transaction
if (parentTransaction != null) {
try {
tm.resume(parentTransaction);
} catch (InvalidTransactionException ite) {
Debug.logWarning(ite, "Invalid transaction, not resumed", module);
} catch (IllegalStateException ise) {
Debug.logError(ise, "Trouble resuming parent transaction", module);
throw new GenericServiceException("Resume transaction exception, see logs");
} catch (SystemException se) {
Debug.logError(se, "Trouble resuming parent transaction", module);
throw new GenericServiceException("Resume transaction exception, see logs");
}
}
// pre-return ECA
if (eventMap != null) ServiceEcaUtil.evalRules(modelService.name, eventMap, "return", ctx, ecaContext, result, isError);
checkDebug(modelService, 0, debugging);
return result;
} catch (Throwable t) {
Debug.logError(t, "Service [" + modelService.name + "] threw an unexpected exception/error", module);
try {
TransactionUtil.rollback(beganTrans);
} catch (GenericTransactionException te) {
Debug.logError(te, "Cannot rollback transaction", module);
}
checkDebug(modelService, 0, debugging);
if (t instanceof ServiceAuthException) {
throw (ServiceAuthException) t;
} else if (t instanceof ServiceValidationException) {
throw (ServiceValidationException) t;
} else if (t instanceof GenericServiceException) {
throw (GenericServiceException) t;
} else {
throw new GenericServiceException("Service [" + modelService.name + "] Failed" + modelService.debugInfo() , t);
}
}
}
/**
* Run the service asynchronously, passing an instance of GenericRequester that will receive the result.
* @param localName Name of the context to use.
* @param service Service model object.
* @param context Map of name, value pairs composing the context.
* @param requester Object implementing GenericRequester interface which will receive the result.
* @param persist True for store/run; False for run.
* @throws ServiceAuthException
* @throws ServiceValidationException
* @throws GenericServiceException
*/
public void runAsync(String localName, ModelService service, Map context, GenericRequester requester, boolean persist) throws ServiceAuthException, ServiceValidationException, GenericServiceException {
boolean debugging = checkDebug(service, 1, true);
if (Debug.verboseOn()) {
Debug.logVerbose("[ServiceDispatcher.runAsync] : prepareing service " + service.name + " [" + service.location + "/" + service.invoke +
"] (" + service.engineName + ")", module);
}
// check the locale
this.checkLocale(context);
// for isolated transactions
TransactionManager tm = TransactionFactory.getTransactionManager();
Transaction parentTransaction = null;
// start the transaction
boolean beganTrans = false;
if (service.useTransaction) {
try {
beganTrans = TransactionUtil.begin(service.transactionTimeout);
} catch (GenericTransactionException te) {
throw new GenericServiceException("Cannot start the transaction.", te.getNested());
}
// isolate the transaction if defined
if (service.requireNewTransaction && !beganTrans) {
try {
parentTransaction = tm.suspend();
} catch (SystemException se) {
Debug.logError(se, "Problems suspending current transaction", module);
throw new GenericServiceException("Problems suspending transaction, see logs");
}
// now start a new transaction
try {
beganTrans = TransactionUtil.begin(service.transactionTimeout);
} catch (GenericTransactionException gte) {
throw new GenericServiceException("Cannot start the transaction.", gte.getNested());
}
}
}
// needed for events
DispatchContext ctx = (DispatchContext) localContext.get(localName);
try {
// get eventMap once for all calls for speed, don't do event calls if it is null
Map eventMap = ServiceEcaUtil.getServiceEventMap(service.name);
// pre-auth ECA
if (eventMap != null) ServiceEcaUtil.evalRules(service.name, eventMap, "auth", ctx, context, null, false);
context = checkAuth(localName, context, service);
Object userLogin = context.get("userLogin");
if (service.auth && userLogin == null)
throw new ServiceAuthException("User authorization is required for this service: " + service.name + service.debugInfo());
// setup the engine
GenericEngine engine = getGenericEngine(service.engineName);
// pre-validate ECA
if (eventMap != null) ServiceEcaUtil.evalRules(service.name, eventMap, "in-validate", ctx, context, null, false);
// validate the context
if (service.validate) {
try {
service.validate(context, ModelService.IN_PARAM);
} catch (ServiceValidationException e) {
Debug.logError(e, "Incoming service context (in runAsync: " + service.name + ") does not match expected requirements", module);
throw e;
}
}
// run the service
if (requester != null) {
engine.runAsync(localName, service, context, requester, persist);
} else {
engine.runAsync(localName, service, context, persist);
}
// always try to commit the transaction since we don't know in this case if its was an error or not
try {
TransactionUtil.commit(beganTrans);
} catch (GenericTransactionException e) {
Debug.logError(e, "Could not commit transaction", module);
throw new GenericServiceException("Commit transaction failed");
}
// resume the parent transaction
if (parentTransaction != null) {
try {
tm.resume(parentTransaction);
} catch (InvalidTransactionException ite) {
Debug.logWarning(ite, "Invalid transaction, not resumed", module);
} catch (IllegalStateException ise) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -