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
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 地球OL攻略 —— 某应届生求职总结
· 提示词工程——AI应用必不可少的技术
· Open-Sora 2.0 重磅开源!
· 字符编码:从基础到乱码解决
2015-06-21 深入浅出 nginx lua 为什么高性能
2013-06-21 一致性哈希算法——PHP实现代码
2013-06-21 TCP三次握手详解
2012-06-21 Yahoo14条前端优化规则
2012-06-21 ubuntu系统WEB配置文件
2012-06-21 php数组中删除元素
2012-06-21 linux下开启mysql慢查询,分析查询语句