[saiku] olap数据源管理
一、应用场景
系统初始化的时候
如果没有创建olap数据源需要先创建olap数据源
否则直接获取所有的数据源存放在全局变量datasources里面以便于后续步骤中获取plap-connections
二、代码详细解析
1、olap数据源对象结构
(1) SaikuDatasource - org.saiku.datasources.datasource.SaikuDatasource
public SaikuDatasource( String name, Type type, Properties properties ) {
this.name = name;//数据源名称
this.type = type;//数据源类型
this.properties = properties;//数据源属性
}
public enum Type {
OLAP
}
(2) DataSource - org.saiku.datasources.datasource.SaikuDatasource.DataSource
public DataSource(SaikuDatasource datasource) {
this.type = datasource.getType().toString();
this.name = datasource.getName();
this.driver = datasource.getProperties().getProperty("driver");
this.location = datasource.getProperties().getProperty("location");
this.username = datasource.getProperties().getProperty("username");
this.password = datasource.getProperties().getProperty("password");
this.id = datasource.getProperties().getProperty("id");
this.encryptpassword =datasource.getProperties().getProperty("encrypt.password");
this.securityenabled =datasource.getProperties().getProperty("security.enabled");
this.securitytype = datasource.getProperties().getProperty("security.type");
this.securitymapping =datasource.getProperties().getProperty("security.mapping");
this.advanced = datasource.getProperties().getProperty("advanced");
}
2、新增OLAP数据源
(1)判断是否需要新增此OLAP数据源的代码如下:
代码结构
|-Database.loadLegacyDatasources()
|- LegacyImporterImpl.importDatasources()
详细代码LegacyImporterImpl.importDatasources()
关键代码:
1) 获取数据源配置文件所在文件夹
String repoURL = "";
FileSystemManager fileSystemManager = VFS.getManager();
fileObject fileObject = fileSystemManager.resolveFile("res:saiku-datasources");
repoURL = fileObject.getURL();
2)遍历该文件夹下所有文件
File[] files = new File(repoURL.getFile()).listFiles();
3)获取OLAP数据源的配置构造saiku-ds对象并判断是否存在,不存在才添加
for (File file : files) {
Properties props = new Properties();
props.load(new FileInputStream(file));
稍微处理下props的location属性之后创建saikuDs
SaikuDatasource ds = new SaikuDatasource(name, t, props);
//获取已加入JCR的ds
List<DataSource> dsList = irm.getAllDataSources();
//比对待添加的OLAP_DS和已存在的OLAP_DS的名字,如果不存在,才添加
boolean isExists = false;
for (DataSource dataSource : dsList) {
if(dataSource.getName().equals(ds.getName())){
isExists = true;
break;
}
}
if(!isExists){
dsm.addDatasource(ds);
}
}
(2)新增数据源具体步骤
第一步将ds加入JCR节点
第二步将ds加入全局datasources
RepositoryDatasourceManager.addDatasource(SaikuDatasource datasource)
//源代码
private Map<String, SaikuDatasource> datasources =
Collections.synchronizedMap(new HashMap<String, SaikuDatasource>());
IRepositoryManager irm = JackRabbitRepositoryManager.getJackRabbitRepositoryManager(configurationpath, datadir, repopassword,oldpassword); public SaikuDatasource addDatasource(SaikuDatasource datasource){
DataSource ds = new DataSource(datasource);
irm.saveDataSource(ds, "/datasources/" + ds.getName() + ".sds", "fixme");
datasources.put(datasource.getName(), datasource);
return datasource;
}
(3)详解第一步:将ds加入JCR节点
JackRabbitRepositoryManager.saveDataSource(DataSource ds, String path, String user)
//源代码
public void saveDataSource(DataSource ds, String path, String user) throws RepositoryException {
//定义字节输出流
ByteArrayOutputStream baos = new ByteArrayOutputStream();
//将DataSource对象转换成XML文件,存入baos中
try {
JAXBContext jaxbContext = JAXBContext.newInstance(DataSource.class);
Marshaller jaxbMarshaller = jaxbContext.createMarshaller();
jaxbMarshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
jaxbMarshaller.marshal(ds, baos);
} catch (JAXBException e) {
log.error("Could not read XML", e);
}
//获取文件名
int pos = path.lastIndexOf("/");
String filename = "./" + path.substring(pos + 1, path.length());//结果为./schema名
//获取数据源根节点/datadatasources
Node n = getFolder(path.substring(0, pos));
//在根节点下添加文件节点resNode: path = /datadatasources/filename
//指定node名字为filename,类型为file,属性为olap_ds,以便后续查询olap数据源能查询到
Node resNode = n.addNode(filename, "nt:file");
resNode.addMixin("nt:olapdatasource");
//在新创建的resNode节点下添加文件内容节点contentNode:
//path = /datadatasources/filename/jcr:content
//设置该内容节点的内容为转换的XML的内容
Node contentNode = resNode.addNode("jcr:content", "nt:resource");
contentNode.setProperty("jcr:data", baos.toString());
//至此,数据源属性节点和配置内容节点就加入到JCR结构中了
//最后,别忘了保存新增的节点
resNode.getSession().save();
}
3、获取所有OLAP数据源
(1) 初始化内容仓库管理器
private String configurationXml = projectPath + "saiku-repository/configuration.xml";
private String datadir = projectPath + "saiku-repository/data";
private String repopassword = "sa!kuanalyt!cs";
private String oldpassword = ""; IRepositoryManager irm = JackRabbitRepositoryManager.getJackRabbitRepositoryManager(configurationpath, datadir, repopassword,oldpassword);\
(2) 初始化JCR基本结构
irm.start(userService);
关键代码:
1)获得内容根节点
//根据configurationXml文件配置在datadir路径下创建JCR文件夹基本结构
//相当于创建MyRepo
RepositoryConfig config = RepositoryConfig.create(configurationXml, datadir);
//根据JCR文件夹基本结构生成repository对象
repository = RepositoryImpl.create(config);
//获取操作JCR的权限[也叫Ticket]
session = repository.login(
new SimpleCredentials("admin", password.toCharArray()));
//根据session获取JCR的根节点
JackrabbitSession js = (JackrabbitSession) session;
session = js;
root = session.getRootNode();
root.getSession().save();
2)为workspace注册Node的类型。四种类型:File/Folder/Schema/DataSource
createFiles();
createFolders();
createSchemas();
createDataSources();
//创建的大致步骤
NodeTypeManager manager = session.getWorkspace().getNodeTypeManager();//相同的代码
NodeTypeTemplate ntt = manager.createNodeTypeTemplate();//相同的代码
ntt.setName("nt:saikufiles");//依次nt:saikufiles/nt:saikufolders/nt:mondrianschema/nt:olapdatasource
String[] str = new String[]{"nt:file"};//依次nt:saikufiles/nt:folder/nt:file/nt:file
ntt.setDeclaredSuperTypeNames(str);
ntt.setMixin(true);
//创建pdt对象 name有几个值就创建几个
//File 创建五个:name分别为owner/type/roles/users/jcr:data
//Folder 创建四个:name分别为owner/type/roles/users
//Schema 创建四个:name分别为owner/schemaname/cubenames/jcr:data
///DataSource 创建三个:name分别为owner/enabled/jcr:data
PropertyDefinitionTemplate pdt = manager.createPropertyDefinitionTemplate();//相同的代码
pdt.setName("owner");
pdt.setRequiredType(PropertyType.STRING);//相同的代码
ntt.getPropertyDefinitionTemplates().add(创建pdt对象);//有几个pdt就添加几次
manager.registerNodeType(ntt, false);//注册新建的节点类型//相同的代码
3)为workspace注册命名空间
createNamespace();
NamespaceRegistry ns = session.getWorkspace().getNamespaceRegistry();
if (!Arrays.asList(ns.getPrefixes()).contains("home")) {
ns.registerNamespace("home", "http://www.meteorite.bi/namespaces/home");
}
4)构建repository结构
在root节点下新增如下文件夹节点结构,并赋予一定的ACL权限<略>
结构:
/homes
/datasources
/etc
/etc/legacyreports
/etc/theme
/etc/theme/legacyreports
Node n = JcrUtils.getOrAddFolder(root, "homes");
n.addMixin("nt:saikufolders");
n = JcrUtils.getOrAddFolder(root, "datasources");
n.addMixin("nt:saikufolders");
n = JcrUtils.getOrAddFolder(root, "etc");
n.addMixin("nt:saikufolders");
n = JcrUtils.getOrAddFolder(n, "legacyreports");
n.addMixin("nt:saikufolders");
n = JcrUtils.getOrAddFolder(root, "etc/theme");
n.addMixin("nt:saikufolders");
n = JcrUtils.getOrAddFolder(n, "legacyreports");
n.addMixin("nt:saikufolders");
session.save();
(3) 获取JCR结构中存在的数据源
List<DataSource> dslist = irm.getAllDataSources();
关键代码:
1)获取MDX查询管理器
QueryManager qm = session.getWorkspace().getQueryManager();
2)查询执行属性的数据,获得所有类型为Cube数据源的节点
//创建Cube数据源时dsNode.addMixin("nt:olapdatasource");
String sql = "SELECT * FROM [nt:olapdatasource]";
Query query = qm.createQuery(sql, Query.JCR_SQL2);
QueryResult res = query.execute();
NodeIterator node = res.getNodes();
3)遍历NodeIterator,解析获取每一个node的属性构造Datasource对象
Node n = node.nextNode();//结果为:node_path = /datadatasources/filename
4)获取cube数据源的schema配置
String schemaContent = n.getNodes("jcr:content").nextNode().getProperty("jcr:data").getString();
5)将XML文件内容数据流转换为DataSource对象
Unmarshaller jaxbMarshaller = jaxbContext != null ? jaxbContext.createUnmarshaller() : null;
JAXBContext jaxbContext = JAXBContext.newInstance(DataSource.class);
InputStream stream = new ByteArrayInputStream(schemaContent.getBytes());
DataSource d = (DataSource) (jaxbMarshaller != null ? jaxbMarshaller.unmarshal(stream) : null);
6)设置数据源的路径
d.setPath(n.getPath());
7)遍历完所有olapds_node以后,返回dsList
(4) 根据dsList拼凑saikuDsList
for (DataSource file : dslist) {
Properties props = new Properties();
根据file构建props
SaikuDatasource.Type t = SaikuDatasource.Type.valueOf(file.getType().toUpperCase());//OLAP
SaikuDatasource ds = new SaikuDatasource(file.getName(),t,props);
datasources.put(file.getName(), ds);//将saikuDs加入到全局变量datasources中
}
[saiku] olap数据源管理的更多相关文章
- 数据源管理 | OLAP查询引擎,ClickHouse集群化管理
本文源码:GitHub·点这里 || GitEE·点这里 一.列式库简介 ClickHouse是俄罗斯的Yandex公司于2016年开源的列式存储数据库(DBMS),主要用于OLAP在线分析处理查询, ...
- 数据源管理 | Kafka集群环境搭建,消息存储机制详解
本文源码:GitHub·点这里 || GitEE·点这里 一.Kafka集群环境 1.环境版本 版本:kafka2.11,zookeeper3.4 注意:这里zookeeper3.4也是基于集群模式部 ...
- 数据源管理 | 搜索引擎框架,ElasticSearch集群模式
本文源码:GitHub·点这里 || GitEE·点这里 一.集群环境搭建 1.环境概览 ES版本6.3.2,集群名称esmaster,虚拟机centos7. 服务群 角色划分 说明 en-maste ...
- 数据源管理 | 分布式NoSQL系统,Cassandra集群管理
本文源码:GitHub·点这里 || GitEE·点这里 一.Cassandra简介 1.基础描述 Cassandra是一套开源分布式NoSQL数据库系统.它最初由Facebook开发,用于储存收件箱 ...
- Spring AOP /代理模式/事务管理/读写分离/多数据源管理
参考文章: http://www.cnblogs.com/MOBIN/p/5597215.html http://www.cnblogs.com/fenglie/articles/4097759.ht ...
- ODBC数据源管理器-》系统DSN-》没有....Microsoft Access Driver(*mdb,*,accdb)
问题如标题: 解决方法:打开目录:“C:\Windows\SysWOW64”,双击该目录下的“odbcad32.exe”文件,就进去ODBC数据源管理界面了,现在这个界面中就有access的驱动了!
- 数据源管理 | 主从库动态路由,AOP模式读写分离
本文源码:GitHub·点这里 || GitEE·点这里 一.多数据源应用 1.基础描述 在相对复杂的应用服务中,配置多个数据源是常见现象,例如常见的:配置主从数据库用来写数据,再配置一个从库读数据, ...
- 数据源管理 | 基于JDBC模式,适配和管理动态数据源
本文源码:GitHub·点这里 || GitEE·点这里 一.关系型数据源 1.动态数据源 动态管理数据源的基本功能:数据源加载,容器维护,持久化管理. 2.关系型数据库 不同厂商的关系型数据库,提供 ...
- 数据源管理 | PostgreSQL环境整合,JSON类型应用
本文源码:GitHub·点这里 || GitEE·点这里 一.PostgreSQL简介 1.和MySQL的比较 PostgreSQL是一个功能强大的且开源关系型数据库系统,在网上PostgreSQL和 ...
随机推荐
- js九宫格的碰撞检测
说来惭愧,我一直以为四四方方的拖拽碰撞检测是一个比较容易的事情,后来试过一次,真是让我耗费了无数的脑细胞,原理其实不难,但是具体做起来可就让我很恶心,这可能跟我驾驭的代码数量有关系,我一般也就写半屏幕 ...
- 【转载】COM:IUnknown、IClassFactory、IDispatch
原文:COM:IUnknown.IClassFactory.IDispatch COM组件有三个最基本的接口类,分别是IUnknown.IClassFactory.IDispatch. COM规范规定 ...
- 怎样在mysql里面修改数据库名称
怎样在mysql里面修改数据库名称 提供三种方法:1. RENAME DATABASE db_name TO new_db_name这个..这个语法在mysql 5.1.7中被添加进来,到 ...
- LINUX DIFF命令详解
刚才在和公司做离线IP对比,最后手工了,感觉还是比较麻烦的,遇到数据很大的时候不能手工进行了 本想用linux下的DIFF来进行对比,发现结果很乱.时间很紧最后还是手工了. 现在忙完要认认真真学习一下 ...
- 7.Constants and Fields
1.Constants is a symbol that has a never-changing value. its value must be determinable at compile ...
- C# WinForm程序添加引用后调用静态方法时报“Interfaces_Helper.Global”的类型初始值设定项引发异常。---> System.NullReferenceException: 未将对象引用设置到对象的实例。
出现原因: 因为Global类初始化某个静态变量时没有成功则会抛 System.NullReferenceException 异常,具体代码: public static string connstr ...
- SQL - 批量修改表中所有行数据某字段的部分内容
UPDATE 表名 SET 字段名 = REPLACE (字段名, 'old', 'new');
- C#正则表达式编程(四):正则表达式
正则表达式提供了功能强大.灵活而又高效的方法来处理文本.正则表达式的全面模式匹配表示法使您可以快速分析大量文本以找到特定的字符模式:提取.编辑.替换或删除文本子字符串:或将提取的字符串添加到集合以生成 ...
- placeholder在不同浏览器下的表现及兼容方法(转)
1.什么是placeholder? placeholder是html5新增的一个属性,当input或者textarea设置了该属性后,该值的内容将作为灰字提示显示在文本框中,当文本框获得焦点(或 ...
- mysql 特殊字符
1.倒引号,比如表中有一个字段为desc,在mysql中desc是关键字,如何表明desc是字段呢? 有两种办法:desc使用倒引号引起来,或者在desc前面加上表名,如下:mysql> sel ...