• saiku 元数据存储分析


    一、介绍

    使用saiku的人一定对他的元数据存储都特别感兴趣,特别是有分布式管理需求的项目,更是迫切需要了解。其实它是使用Apache的开源项目Jackrabbit管理文件的!

    二、代码跟踪

    我也是使用了一段时间,希望深入了解它的元数据存储,下面是代码跟踪:

    2.1 ajax

    首先还是从ajax入手:ajax请求:/saiku/rest/saiku/admin/datasources?_=1466478165922

    对应的脚本:org.saiku.web.rest.resources.AdminResource,方法如下:
        @GET
        @Produces( {"application/json"})
        @Path("/datasources")
        @ReturnType("java.lang.List<SaikuDatasource>")
        public Response getAvailableDataSources() 
    发现核心代码是:datasourceService.getDatasources().values() 不过看不出来什么,于是从代码注入开始查起!

    2.2 代码注入

    AdminResource对象注入:
        <bean id="adminBean" class="org.saiku.web.rest.resources.AdminResource">
            <property name="userService" ref="userServiceBean"/>
            <property name="datasourceService" ref="datasourceServiceBean"/>
            <property name="olapDiscoverService" ref="olapDiscoverServiceBean"/>
            <property name="repositoryDatasourceManager" ref="repositoryDsManager"/>
            <property name="logExtractor" ref="logwriterbean"/>
        </bean>
    UserService对象注入:
        <bean id="userServiceBean" class="org.saiku.service.user.UserService">
            <property name="jdbcUserDAO" ref="userDAO"/>
            <property name="datasourceService" ref="datasourceServiceBean"/>
            <property name="iDatasourceManager" ref="repositoryDsManager"/>
            <property name="adminRoles">
                <list>
                    <value>ROLE_ADMIN</value>
                </list>
            </property>
            <property name="sessionService" ref="sessionService"/>
        </bean>
    DatasourceService对象注入:
        <bean id="datasourceServiceBean" class="org.saiku.service.datasource.DatasourceService">
            <property name="connectionManager" ref="connectionManager"/>
        </bean>

    发现部分核心代码:

      private void readObject(ObjectInputStream stream)
          throws IOException, ClassNotFoundException {
        stream.defaultReadObject();
        datasources = connectionManager.getDataSourceManager();
      }

    继续跟踪: 

    connectionManager对象注入:
        <bean id="connectionManager" class="org.saiku.web.core.SecurityAwareConnectionManager" init-method="init"
              destroy-method="destroy" depends-on="mondrianVFS">
            <property name="dataSourceManager" ref="repositoryDsManager"/> --这是注入执行setDataSourceManager方法,传入repositoryDsManager对象
            <property name="sessionService" ref="sessionService"/>
        </bean>
    repositoryDsManager对象注入:
        <bean id="repositoryDsManager" class="org.saiku.service.datasource.RepositoryDatasourceManager" init-method="load" destroy-method="unload">
            <property name="userService" ref="userServiceBean"/>
            <property name="configurationpath" value="../../repository/configuration.xml"/>
            <property name="datadir" value="../../repository/data"/>
            <property name="foodmartdir" value="../../data"/>
            <property name="foodmartschema" value="../../data/FoodMart4.xml"/>
            <property name="foodmarturl" value="jdbc:h2:../../data/foodmart;MODE=MySQL"/>
            <property name="earthquakeDir" value="../../data"/>
            <property name="earthquakeSchema" value="../../data/Earthquakes.xml"/>
            <property name="earthquakeUrl" value="jdbc:h2:../../data/earthquakes;MODE=MySQL"/>
            <property name="repoPasswordProvider" ref ="repoPasswordProviderBean"/>
            <property name="defaultRole" value="ROLE_USER"/>
            <!-- If you change the repoPassword set this property for at least 1 restart to update the old repo password-->
            <!--<property name="oldRepoPassword" value="sa!kuanalyt!cs"/>-->
        </bean>

    获取所有的元数据,就是获取RepositoryDatasourceManager对象的datasources对象,这个对象是由下面的代码生成的: 

       public void load() {
            irm = JackRabbitRepositoryManager.getJackRabbitRepositoryManager(configurationpath, datadir, repopasswordprovider.getPassword(),
                oldpassword, defaultRole);
            try {
                irm.start(userService);
                this.saveInternalFile("/etc/.repo_version", "d20f0bea-681a-11e5-9d70-feff819cdc9f", null);
            } catch (RepositoryException e) {
                log.error("Could not start repo", e);
            }
            datasources.clear();
            try {
     
                List<DataSource> exporteddatasources = null;
                try {
                    exporteddatasources = irm.getAllDataSources();
                } catch (RepositoryException e1) {
                    log.error("Could not export data sources", e1);
                }
     
                if (exporteddatasources != null) {
                    for (DataSource file : exporteddatasources) {
                        if (file.getName() != null && file.getType() != null) {
                            Properties props = new Properties();
                            SaikuDatasource.Type t = SaikuDatasource.Type.valueOf(file.getType().toUpperCase());
                            SaikuDatasource ds = new SaikuDatasource(file.getName(), t, props);
                            datasources.put(file.getName(), ds);
                        }
                    }
                } 
            } catch (Exception e) {
                throw new SaikuServiceException(e.getMessage(), e);
            }
        }

    三、终极发现

    saiku是使用JackRabbit管理树状元数据的,如果想要扩展,只能在JackRabbit基础上进行扩展,同志们继续努力!
    JackRabbitIBM文档:http://www.ibm.com/developerworks/cn/java/j-jcr/  
    JackRabbit入门文档: http://suigara.iteye.com/blog/1454765 
  • 相关阅读:
    (转)运维角度浅谈MySQL数据库优化
    关于MySQL的null值
    MySQL优化——or条件优化
    MySQL优化原理
    Xcode Archive打包失败问题
    ionic3 对android包进行签名
    ios 审核未通过 相机相册权限问题
    js计算两个日期相差天数
    截取URL链接中字段的方法
    ionic3 自定义组件 滑动选择器 ion-multi-picker
  • 原文地址:https://www.cnblogs.com/liqiu/p/JackRabbit.html
Copyright © 2020-2023  润新知