use of info.xiancloud.core.Unit in project xian by happyyangyuan.
the class DaoUnit method execute.
/**
* @param request the request object.
* @param handler the unit response consumer, this handler must be executed asynchronously.
*/
@Override
public final void execute(UnitRequest request, Handler<UnitResponse> handler) {
final SqlAction[] sqlActions = getActions();
for (SqlAction sqlAction : sqlActions) {
if (sqlAction instanceof ISingleTableAction) {
TableMetaCache.makeSureCache(((ISingleTableAction) sqlAction).getTableName());
}
}
bareError(request);
final boolean readOnly = readOnly(sqlActions, request) || request.getContext().isReadyOnly();
final AtomicBoolean transactional = new AtomicBoolean(false);
final UnitResponse[] tempUnitResponse = new UnitResponse[] { null };
final XianTransaction[] tempTransaction = new XianTransaction[] { null };
TransactionFactory.getTransaction(request.getContext().getMsgId(), readOnly).flatMap(transaction -> {
tempTransaction[0] = transaction;
transactional.set(isTransactional(sqlActions, transaction));
if (transactional.get()) {
// business layer has begun the transaction, here we reentrant it.
return transaction.begin().toSingle(() -> transaction);
} else {
// if transaction is not begun by business layer, here we do not begin the transaction
return Single.just(transaction);
}
}).flatMap(transaction -> Flowable.fromArray(sqlActions).concatMapSingle(action -> action.execute(this, request.getArgMap(), transaction.getConnection(), request.getContext().getMsgId())).reduce(UnitResponse.succeededSingleton(), (unitResponse, unitResponse2) -> {
if (unitResponse2.succeeded()) {
return unitResponse2;
} else {
throw new ExceptionWithUnitResponse(unitResponse2);
}
}).flatMapCompletable(unitResponse -> {
tempUnitResponse[0] = unitResponse;
if (transactional.get()) {
return transaction.commit();
} else {
return Completable.complete();
}
}).toSingle(() -> tempUnitResponse[0]).onErrorResumeNext(error -> {
ExceptionWithUnitResponse exceptionWithUnitResponse;
if (error instanceof ExceptionWithUnitResponse) {
exceptionWithUnitResponse = (ExceptionWithUnitResponse) error;
} else {
LOG.error(error);
exceptionWithUnitResponse = new ExceptionWithUnitResponse(UnitResponse.createException(error));
}
if (transactional.get()) {
// if transaction is begun then rollback here
return transaction.rollback().andThen(Single.just(exceptionWithUnitResponse.getUnitResponse()));
} else {
// if no transaction is begun, no need transaction rollback.
return Single.just(exceptionWithUnitResponse.getUnitResponse());
}
})).doFinally(() -> tempTransaction[0].close().subscribe()).subscribe(unitResponse -> {
unitResponse.getContext().setMsgId(request.getContext().getMsgId());
handler.handle(unitResponse);
}, error -> {
LOG.error(error);
UnitResponse errorResponse = UnitResponse.createException(error);
errorResponse.getContext().setMsgId(request.getContext().getMsgId());
handler.handle(errorResponse);
});
}
use of info.xiancloud.core.Unit in project xian by happyyangyuan.
the class DaoUnitProvider method provideExtraUnits.
@Override
public List<Unit> provideExtraUnits() {
List<Unit> baseDaoUnits = new ArrayList<>();
for (DaoGroup daoGroup : DaoGroup.GROUP_LIST) {
baseDaoUnits.add(new BaseAddDB() {
@Override
public Group getGroup() {
return daoGroup;
}
});
baseDaoUnits.add(new BaseDeleteByIdDB() {
@Override
public Group getGroup() {
return daoGroup;
}
});
baseDaoUnits.add(new BaseDeleteDB() {
@Override
public Group getGroup() {
return daoGroup;
}
});
baseDaoUnits.add(new BasePaginateDB() {
@Override
public Group getGroup() {
return daoGroup;
}
});
baseDaoUnits.add(new BaseQueryByIdDB() {
@Override
public Group getGroup() {
return daoGroup;
}
});
baseDaoUnits.add(new BaseQueryDB() {
@Override
public Group getGroup() {
return daoGroup;
}
});
baseDaoUnits.add(new BaseUpdateByIdDB() {
@Override
public Group getGroup() {
return daoGroup;
}
});
baseDaoUnits.add(new BaseUpdateDB() {
@Override
public Group getGroup() {
return daoGroup;
}
});
baseDaoUnits.add(new CommitTransaction() {
@Override
public Group getGroup() {
return daoGroup;
}
});
baseDaoUnits.add(new RollbackTransaction() {
@Override
public Group getGroup() {
return daoGroup;
}
});
baseDaoUnits.add(new BeginTransaction() {
@Override
public Group getGroup() {
return daoGroup;
}
});
}
return baseDaoUnits;
}
use of info.xiancloud.core.Unit in project xian by happyyangyuan.
the class IUnitAop method intercept.
/**
* intercept
*/
default void intercept() {
Collection<Unit> units = getUnitCollection();
if (units == null || units.isEmpty()) {
LOG.info("nothing to intercept at all.");
return;
}
final IUnitAop thiz = this;
for (final Unit originUnit : units) {
LOG.debug(originUnit.getName() + " 代理对象:" + Proxy.isProxyClass(originUnit.getClass()));
final Unit nakedUnit;
if (Proxy.isProxyClass(originUnit.getClass())) {
nakedUnit = (Unit) ProxyBuilder.getProxyBuilder(originUnit.hashCode()).getMostOriginalObject();
} else {
nakedUnit = originUnit;
}
Unit proxy = new ProxyBuilder<Unit>(originUnit, true) {
@Override
public Object before(Method method, Object[] args) throws UnitResponseReplacement {
if (METHOD_EXECUTE.equals(method.getName())) {
if (!asyncBefore()) {
return thiz.before(nakedUnit, (UnitRequest) args[0]);
} else {
Runnable runnableForBefore = () -> {
try {
Object beforeReturnIgnored = thiz.before(nakedUnit, (UnitRequest) args[0]);
LOG.info("异步AOP的前置拦截方法before返回的内容被忽略:" + beforeReturnIgnored);
} catch (UnitResponseReplacement outputReplacement) {
throw new RuntimeException("异步aop不允许打断被拦截的方法!", outputReplacement);
}
};
if (trackMsgIdIfAsync()) {
ThreadPoolManager.execute(runnableForBefore, MsgIdHolder.get());
} else {
ThreadPoolManager.executeWithoutTrackingMsgId(runnableForBefore);
}
return "";
}
}
return "";
}
@Override
public void after(Method method, Object[] args, Object unitReturn, Object beforeReturn) throws UnitResponseReplacement {
if (METHOD_EXECUTE.equals(method.getName())) /*&& !beforeReturn.toString().equals(AOP_FILTER_PLAG)*/
{
final UnitResponse finalMethodReturn;
if (unitReturn instanceof Throwable) {
// 有异常抛出,则需要回滚
finalMethodReturn = UnitResponse.createException((Throwable) unitReturn);
} else {
finalMethodReturn = (UnitResponse) unitReturn;
}
if (!asyncAfter()) {
// 同步
thiz.after(originUnit, (UnitRequest) args[0], finalMethodReturn, beforeReturn);
} else {
Runnable runnableAfter = () -> {
try {
thiz.after(originUnit, (UnitRequest) args[0], finalMethodReturn, beforeReturn);
} catch (UnitResponseReplacement outputReplacement) {
throw new RuntimeException("异步aop不允许执行此操作!", outputReplacement);
}
};
if (trackMsgIdIfAsync()) {
ThreadPoolManager.execute(runnableAfter, MsgIdHolder.get());
} else {
ThreadPoolManager.executeWithoutTrackingMsgId(runnableAfter);
}
}
}
}
}.getProxy();
LocalUnitsManager.replaceUnit(proxy);
}
}
use of info.xiancloud.core.Unit in project xian by happyyangyuan.
the class ApidocServlet method invoke.
private void invoke(HttpServletRequest req, HttpServletResponse resp) throws IOException {
resp.setHeader("Content-type", "text/plain; charset=UTF-8");
resp.setCharacterEncoding("UTF-8");
String docType = req.getRequestURI().substring(PATH_PREFIX.length());
Class<? extends Unit> apidocUnitClass;
switch(docType) {
case DOC_TYPE_CUSTOM:
apidocUnitClass = CustomizedMdApidocUnit.class;
break;
case DOC_TYPE_FULL:
apidocUnitClass = FullMdApidocUnit.class;
break;
case DOC_TYPE_GROUP:
apidocUnitClass = GroupMdApidocUnit.class;
break;
default:
apidocUnitClass = FullMdApidocUnit.class;
}
JSONObject params = HttpUtil.parseQueryString(req.getQueryString(), false);
PrintWriter out = resp.getWriter();
try {
Unit apidocUnit = apidocUnitClass.newInstance();
out.print(SingleRxXian.call(apidocUnit.getGroup().getName(), apidocUnit.getName(), params).blockingGet().throwExceptionIfNotSuccess().dataToStr());
} catch (InstantiationException | IllegalAccessException e) {
throw new RuntimeException(e);
}
}
use of info.xiancloud.core.Unit in project xian by happyyangyuan.
the class ISequencer method build.
static ISequencer build(String group, String unit, JSONObject argMap) {
Unit unit1 = LocalUnitsManager.getLocalUnit(group, unit);
Input input = unit1.getInput();
if (input != null && input.isSequential()) {
LOG.info("sequential: " + group + "." + unit);
return new AsyncSequencer(group, unit, argMap);
} else {
return new NoSequenceGuaranteeSequencer();
}
}
Aggregations