当前位置: 首页 > news >正文

[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中
    }

 

相关文章:

  • uniapp开发:瀑布流 灵活配置 简单易用 兼容vue2vue3小程序、H5、app等多端
  • Chrome浏览器使用Overrides调试线上代码的技巧
  • js查找json数据中的最大值和最小值方法集结
  • CSS3 Border-color
  • uniapp+unicloud开发微信小程序流程
  • 微信小程序解决saveImageToPhotosAlbum:fail invalid file type
  • Cacti 不出图像的解决办法(完整版)
  • 我的CSDN博客、UNI技术成长之路
  • websoket封装版 参数配置化 开箱即用
  • h5页面js监听页面失去焦点、获取焦点
  • uniapp之vuex在vue2和vue3两种模式下前端工程化动态导入文件
  • css实现三角形的最简单方式原理剖析
  • android4.4.2内核移植3.4.1
  • js正则提取字符串中http等地址
  • 解决 多列 布局 左右等高问题
  • CSS 三角实现
  • github从入门到放弃(1)
  • Git同步原始仓库到Fork仓库中
  • Linux下的乱码问题
  • PyCharm搭建GO开发环境(GO语言学习第1课)
  • spring-boot List转Page
  • spring学习第二天
  • Synchronized 关键字使用、底层原理、JDK1.6 之后的底层优化以及 和ReenTrantLock 的对比...
  • vue 配置sass、scss全局变量
  • 产品三维模型在线预览
  • 程序员最讨厌的9句话,你可有补充?
  • 初识 webpack
  • 基于Android乐音识别(2)
  • 利用DataURL技术在网页上显示图片
  • 马上搞懂 GeoJSON
  • 前端每日实战:70# 视频演示如何用纯 CSS 创作一只徘徊的果冻怪兽
  • 为物联网而生:高性能时间序列数据库HiTSDB商业化首发!
  • 一道闭包题引发的思考
  • 怎么把视频里的音乐提取出来
  • 仓管云——企业云erp功能有哪些?
  • 带你开发类似Pokemon Go的AR游戏
  • 好程序员大数据教程Hadoop全分布安装(非HA)
  • #pragma pack(1)
  • (¥1011)-(一千零一拾一元整)输出
  • (2)MFC+openGL单文档框架glFrame
  • (Matalb时序预测)WOA-BP鲸鱼算法优化BP神经网络的多维时序回归预测
  • (Redis使用系列) SpringBoot 中对应2.0.x版本的Redis配置 一
  • (附源码)python房屋租赁管理系统 毕业设计 745613
  • (附源码)springboot人体健康检测微信小程序 毕业设计 012142
  • (附源码)基于ssm的模具配件账单管理系统 毕业设计 081848
  • (论文阅读笔记)Network planning with deep reinforcement learning
  • (七)MySQL是如何将LRU链表的使用性能优化到极致的?
  • (三)Hyperledger Fabric 1.1安装部署-chaincode测试
  • (小白学Java)Java简介和基本配置
  • (原)Matlab的svmtrain和svmclassify
  • (转)Linq学习笔记
  • (转)大型网站的系统架构
  • (轉貼) 蒼井そら挑戰筋肉擂台 (Misc)
  • .net Application的目录
  • .NET Compact Framework 3.5 支持 WCF 的子集