Search in sources :

Example 6 with Unit

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);
    });
}
Also used : XianConnection(info.xiancloud.dao.core.connection.XianConnection) TableMetaCache(info.xiancloud.dao.core.utils.TableMetaCache) TransactionFactory(info.xiancloud.dao.core.transaction.TransactionFactory) Unit(info.xiancloud.core.Unit) UnitRequest(info.xiancloud.core.message.UnitRequest) StringUtil(info.xiancloud.core.util.StringUtil) AbstractSqlAction(info.xiancloud.dao.core.action.AbstractSqlAction) Completable(io.reactivex.Completable) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) UnitResponse(info.xiancloud.core.message.UnitResponse) SqlAction(info.xiancloud.dao.core.action.SqlAction) Handler(info.xiancloud.core.Handler) Single(io.reactivex.Single) ISingleTableAction(info.xiancloud.dao.core.action.ISingleTableAction) Input(info.xiancloud.core.Input) ISelect(info.xiancloud.dao.core.action.select.ISelect) Flowable(io.reactivex.Flowable) PoolFactory(info.xiancloud.dao.core.pool.PoolFactory) Map(java.util.Map) LOG(info.xiancloud.core.util.LOG) XianTransaction(info.xiancloud.dao.core.transaction.XianTransaction) ExceptionWithUnitResponse(info.xiancloud.core.message.ExceptionWithUnitResponse) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) UnitResponse(info.xiancloud.core.message.UnitResponse) ExceptionWithUnitResponse(info.xiancloud.core.message.ExceptionWithUnitResponse) ISingleTableAction(info.xiancloud.dao.core.action.ISingleTableAction) XianTransaction(info.xiancloud.dao.core.transaction.XianTransaction) ExceptionWithUnitResponse(info.xiancloud.core.message.ExceptionWithUnitResponse) AbstractSqlAction(info.xiancloud.dao.core.action.AbstractSqlAction) SqlAction(info.xiancloud.dao.core.action.SqlAction)

Example 7 with Unit

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;
}
Also used : Group(info.xiancloud.core.Group) DaoGroup(info.xiancloud.dao.core.DaoGroup) ArrayList(java.util.ArrayList) Unit(info.xiancloud.core.Unit) DaoGroup(info.xiancloud.dao.core.DaoGroup)

Example 8 with Unit

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);
    }
}
Also used : Method(java.lang.reflect.Method) Unit(info.xiancloud.core.Unit) UnitRequest(info.xiancloud.core.message.UnitRequest) UnitResponse(info.xiancloud.core.message.UnitResponse) JSONObject(com.alibaba.fastjson.JSONObject)

Example 9 with Unit

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);
    }
}
Also used : JSONObject(com.alibaba.fastjson.JSONObject) CustomizedMdApidocUnit(info.xiancloud.apidoc.unit.md.CustomizedMdApidocUnit) Unit(info.xiancloud.core.Unit) GroupMdApidocUnit(info.xiancloud.apidoc.unit.md.GroupMdApidocUnit) FullMdApidocUnit(info.xiancloud.apidoc.unit.md.FullMdApidocUnit) PrintWriter(java.io.PrintWriter)

Example 10 with Unit

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();
    }
}
Also used : Input(info.xiancloud.core.Input) NoSequenceGuaranteeSequencer(info.xiancloud.core.sequence.sequence_no_garantee.NoSequenceGuaranteeSequencer) AsyncSequencer(info.xiancloud.core.sequence.default_sequencer.AsyncSequencer) Unit(info.xiancloud.core.Unit)

Aggregations

Unit (info.xiancloud.core.Unit)12 JSONObject (com.alibaba.fastjson.JSONObject)4 UnitRequest (info.xiancloud.core.message.UnitRequest)3 UnitResponse (info.xiancloud.core.message.UnitResponse)3 Input (info.xiancloud.core.Input)2 LOG (info.xiancloud.core.util.LOG)2 XianConnection (info.xiancloud.dao.core.connection.XianConnection)2 Single (io.reactivex.Single)2 Map (java.util.Map)2 CustomizedMdApidocUnit (info.xiancloud.apidoc.unit.md.CustomizedMdApidocUnit)1 FullMdApidocUnit (info.xiancloud.apidoc.unit.md.FullMdApidocUnit)1 GroupMdApidocUnit (info.xiancloud.apidoc.unit.md.GroupMdApidocUnit)1 Group (info.xiancloud.core.Group)1 Handler (info.xiancloud.core.Handler)1 XianConfig (info.xiancloud.core.conf.XianConfig)1 UnitProxy (info.xiancloud.core.distribution.UnitProxy)1 UnitInstance (info.xiancloud.core.distribution.service_discovery.UnitInstance)1 UnitInstanceIdBean (info.xiancloud.core.distribution.service_discovery.UnitInstanceIdBean)1 ExceptionWithUnitResponse (info.xiancloud.core.message.ExceptionWithUnitResponse)1 AsyncSequencer (info.xiancloud.core.sequence.default_sequencer.AsyncSequencer)1