专栏首页编码小白ofbiz实体引擎(九) 多租户

ofbiz实体引擎(九) 多租户

多租户在平台中是根据delegator不同操作不同的数据库

  /**
     * @author 郑小康
     * 设置完整的delegator  其可能形式有 default 或者defalut#tenantDelegatorName
     * 针对于第一种情况 delegatorBaseName =="default" delegatorTenantId=null
     * 针对第二种情况 delegatorBaseName =="default"  delegatorTenantId="tenantDelegatorName"
     * 为什么存在第二种情况,是因为在多租户中要实现数据独立,所以获取基础delagtor 和租户delegator,注意这时并未创建实例更没有建立数据库连接
     * 其再获取了默认的delegator中的信息之后,如果存在delegatorBaseName 则将 uri username password进行覆盖
     * */
    protected void setDelegatorNames(String delegatorFullName) {
        this.delegatorFullName = delegatorFullName;

        int hashSymbolIndex = delegatorFullName.indexOf('#');
        if (hashSymbolIndex == -1) {
            this.delegatorBaseName = delegatorFullName;
        } else {
            this.delegatorBaseName = delegatorFullName.substring(0, hashSymbolIndex);
            this.delegatorTenantId = delegatorFullName.substring(hashSymbolIndex + 1);
        }
    }
//多租户 根据默认baseDelegator获取域名对应TenantId 拼接DelegatorName获取其实例
if (useMultitenant) {
            // get tenant delegator by domain name,获取服务名
            String serverName = httpRequest.getServerName();
            try {
            	
                // if tenant was specified, replace delegator with the new per-tenant delegator and set tenantId to session attribute
                Delegator delegator = getDelegator(config.getServletContext());

                //Use base delegator for fetching data from entity of entityGroup com.hanlin.fadp.tenant 
                Delegator baseDelegator = DelegatorFactory.getDelegator(delegator.getDelegatorBaseName());
                GenericValue tenantDomainName = EntityQuery.use(baseDelegator).from("TenantDomainName").where("domainName", serverName).queryOne();
                String tenantId = null;
                if(UtilValidate.isNotEmpty(tenantDomainName)) {
                    tenantId = tenantDomainName.getString("tenantId");
                }
                
                if(UtilValidate.isEmpty(tenantId)) {
                    tenantId = (String) httpRequest.getAttribute("userTenantId");
                }
                if(UtilValidate.isEmpty(tenantId)) {
                    tenantId = (String) httpRequest.getParameter("userTenantId");
                }
                if (UtilValidate.isNotEmpty(tenantId)) {
                    // if the request path is a root mount then redirect to the initial path
                    if (UtilValidate.isNotEmpty(requestPath) && requestPath.equals(contextUri)) {
                        GenericValue tenant = EntityQuery.use(baseDelegator).from("Tenant").where("tenantId", tenantId).queryOne();
                        String initialPath = tenant.getString("initialPath");
                        if (UtilValidate.isNotEmpty(initialPath) && !"/".equals(initialPath)) {
                            ((HttpServletResponse)response).sendRedirect(initialPath);
                            return;
                        }
                    }

                    // make that tenant active, setup a new delegator and a new dispatcher
                    String tenantDelegatorName = delegator.getDelegatorBaseName() + "#" + tenantId;
                    httpRequest.getSession().setAttribute("delegatorName", tenantDelegatorName);

                    // after this line the delegator is replaced with the new per-tenant delegator
                    delegator = DelegatorFactory.getDelegator(tenantDelegatorName);
                    config.getServletContext().setAttribute("delegator", delegator);

                    // clear web context objects
                    config.getServletContext().setAttribute("security", null);
                    config.getServletContext().setAttribute("dispatcher", null);

                    /**
                     * 初始化security,根据delegatorName先从缓存中获取,如果缓存中不存在对应的security,则实例化一个
                     * 由于该过滤器是每次请求都会经过,所以根据域名不同,获取的security就有所不同,这样就可以实现共用一套用户表在不同租户中权限不同
                     */
                    Security security = getSecurity();
                    // initialize the services dispatcher
                    LocalDispatcher dispatcher = getDispatcher(config.getServletContext());

                    // set web context objects
                    request.setAttribute("dispatcher", dispatcher);
                    request.setAttribute("security", security);
                    
                    request.setAttribute("userTenantId", tenantId);
                }

                // NOTE DEJ20101130: do NOT always put the delegator name in the user's session because the user may 
                // have logged in and specified a tenant, and even if no Tenant record with a matching domainName field 
                // is found this will change the user's delegator back to the base one instead of the one for the 
                // tenant specified on login 
                // httpRequest.getSession().setAttribute("delegatorName", delegator.getDelegatorName());
            } catch (GenericEntityException e) {
                Debug.logWarning(e, "Unable to get Tenant没有获取这个租户", module);
            }
        }

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • ofbiz实体引擎(二) delegator实例化具体方式

    /** * @author 郑小康 * 采用spi创建对应实例DelegatorFactoryImpl * */ publ...

    cfs
  • cordova学习二 项目创建

    2.1简单创建          Cmd在指定的自己所想创建项目的路径下执行命令:cordova create MyApp 2.2指定应用名与应用id     ...

    cfs
  • tomcat请求处理分析(四) 监听请求轮询处理

    1.1.1.1  startInternal方法 这个方法是核心的启动方法,目前理解主要做了两件事情,第一件是创建轮询线程,即具体的读取线程,它是进行具体的处理...

    cfs
  • 吴恩达机器学习 Coursera 笔记(二) - 单变量线性回归

    To establish notation for future use, we’ll use

    JavaEdge
  • python资料汇总

    摘要:重新整理汇总,内容包括长期必备、入门教程、练手项目、学习视频。 ? 一、长期必备。 1. StackOverflow,是疑难解答、bug排除必备网站,任何...

    企鹅号小编
  • python3安装解决ssl问题

    使用yum命令报错File "/usr/bin/yum", line 30 except KeyboardInterrupt, e: 问题出现原因:

    py3study
  • 【玩转腾讯云】python reload函数

    1.module 必须是已经成功导入的模块,使用 reload函数的前提,是reload函数重新导入的模块在之前已经使用import或者from导入成功了,否则...

    猿说编程[Python和C]
  • 人工智能系列之智能家居——来自勤奋的锐锐的投稿

    今天我在玩小度智能屏的时候,突然意识到,小度智能屏的语音识别功能,很强大,于是我打算做一个人工智能项目——智能家居。我买了一块语音识别版,图片如下:

    勤奋的思远
  • peak注释信息揭秘

    在chip_seq数据分析中,peak calling是核心,得到peak区间之后,我们首先需要对peak进行注释。所谓的注释其实是一个比较宽泛的概念,其中包含...

    生信修炼手册
  • Git - git push origin master 报错的解决方法

    KangVcar

扫码关注云+社区

领取腾讯云代金券