# For Bio-OS开发者

## 架构

特点：高可扩展，包括接口、存储层等；深度集成生信领域流行的开源工具，Cromwell、JupyterHub等；

下图展示了运行依赖的网络和存储，及内部各组件间的调用关系；

文件存储存放生信分析作业的输入输出和Notebook，DB存放各类实体控制信息，包括工作流脚本。

<figure><img src="/files/AkLM6jbNEv3GB7MrLpYz" alt=""><figcaption></figcaption></figure>

## 领域设计

整个项目深度实践了领域驱动设计；图中仅示意了API Server所代表的核心域设计，Cromwell、JupyterHub处于支撑域未做体现；限界上下文划分基于动静分离原则，出于轻量化的考虑，所有限界上下文被集中实现于单个服务中。

<figure><img src="/files/XpaQ92YNTsZvE6JwpHVG" alt=""><figcaption></figcaption></figure>

| 限界上下文           | 职责                                 |
| --------------- | ---------------------------------- |
| Workspace       | 用于归档和呈现生信分析过程和结果资料，同时也是划分人员权责的基本单元 |
| Notebook Server | 用于管理Notebook编辑环境，即环境设置和环境生命周期      |
| Submission      | 用于管理工作流运行及其历史                      |

## 代码

### 框架

[Hertz](https://www.cloudwego.io/zh/docs/hertz/) 字节跳动CloudWeGo团队开源的HTTP服务框架[GRPC](https://github.com/grpc/grpc-go) GRPC主要被用于CLI接入及内部各限界上下文间的接口调用[Casbin](https://casbin.org/zh/) 基于其RBAC能力支持访问控制[GORM](https://gorm.io/zh_CN/docs/index.html) Go生态中最流行的ORM框架，所有关系型数据库都借助它进行连接

### 目录

代码部分

```Shell
.
├── cmd # 各组件的main入口，以cobra command形式运行
│   ├── apiserver
│   └── bioctl
├── internal # 组件内部逻辑
│   ├── apiserver
│   ├── bioctl
│   ├── context # 各限界上下文实现
│   │   ├── notebookserver
│   │   ├── submission
│   │   └── workspace
│   │       ├── application
│   │       ├── domain
│   │       ├── infrastructure
│   │       └── interface
├── pkg # 后端公共库部分，被cmd和ineternal引用
│   ├── auth # 身份校验和权限检查配置
│   ├── client
│   ├── consts
│   ├── db # 数据库配置
│   ├── errors
│   ├── eventbus # 事件总线配置
│   ├── jupyterhub
│   ├── log
│   ├── middlewares # 处理API接入的身份校验和权限检查
│   ├── notebook # notebook配置
│   ├── schema
│   ├── server # server框架配置
│   ├── storage # 文件存储配置
│   ├── utils
│   ├── validator # API入参检查方法
│   └── version
└── web # 前端部分
    ├── public # 页面入口相关静态资源
    ├── src # TS代码
    └── swagger-gen.js # 从swagger生成API调用代码
```

其他

```Shell
.
├── build # 各组件Dockerfile
│   ├── apiserver
│   ├── bioctl
│   └── web
├── conf # apiserver和ctl启动配置示例
├── docs # API文档 swagger形式
├── hack
│   ├── boilerplate # LICENSE头
│   └── make-rules # Makefile各target实现
└── githooks # Git提交检查
```

### DDD实践

项目采用经典四层结构：

1. **Interface层** 用于借助各种server框架实现不同的种类的接口，与Hertz和GRPC的对接就在该层实现，在层内会对不同的协议类型分别定义View Object，并实现从View Object到Data Transfer Object的转换
2. **Application层** 按[CQRS原则](https://learn.microsoft.com/zh-cn/azure/architecture/patterns/cqrs)分command和query，其中query中带有Read Model抽象定义，由Infrastructure层实现，用于与Interface层传递的数据Data Transfer Object定义于此
3. **Domain层** 最核心的部分，其对外部的依赖也由其进行抽象定义，抽象的实现由外部完成，比如典型的Repository，表现为依赖倒置
4. **Infrastructure层** 负责对包括存储在内的各种外部设施的对接，表现为各种抽象的实现

<figure><img src="/files/QZYeiUETTvVRlmnNymzS" alt=""><figcaption></figcaption></figure>

### 开发环境

所需工具（未涉及前端）：

1. Git
2. GNU Make
3. Go 1.19或以上
4. Docker

其余的工具（例如swagger、womtool、protoc等）可以通过`make tools`一键安装

## 运行

对于集群部署，推荐使用官方提供的[helm charts](https://github.com/Bio-OS/helm-charts)，原文档中以Minikube为运行环境，但更推荐使用公有云kubernetes托管服务，能一键安装网络、存储组件，另外公有云也有NFS、MySQL产品

### 附：单机运行Cromwell

1. 准备一个工作目录，在目录中创建application.conf，并将以下内容进行粘贴

```Bash
include required(classpath("application"))
webservice {
  port = 8000
}
workflow-options {
  workflow-log-dir = /nfs/bioos-storage/cromwell-workflow-logs
  workflow-log-temporary = false
}
call-caching {
  enabled = true
  invalidate-bad-cache-results = true
}
database {
  profile = "slick.jdbc.MySQLProfile$"
  db {
    driver = "com.mysql.cj.jdbc.Driver"
    url = "jdbc:mysql://${db_endpoint}:3306/${db_name}?rewriteBatchedStatements=true&useSSL=false"
    port = 3306
    user = "${db_username}"
    password = "${db_password}"
    connectionTimeout = 5000
  }
}
backend {
  default = "Local"
  providers {
    Local {
      config {
        root = "/nfs/bioos-storage/cromwell-executions"
        filesystem {
          local {
           localization: [
                  "hard-link", "soft-link", "copy"
           ]

            caching {
              duplication-strategy: [
                "hard-link", "soft-link", "copy"
              ]
              hashing-strategy: "md5"
              check-sibling-md5: false
            }
          }
        }
      }
    }
  }
}
```

2. 下载程序文件cromwell.jar

从下面的链接下载cromwell-85.jar：<https://github.com/broadinstitute/cromwell/releases/tag/85>

3. 运行`bash ./run.sh`

```Bash
#!/bin/bash
set -e
echo 'starting cromwell'
nohup java -jar -Dconfig.file=${application.conf} -DLOG_LEVEL=INFO -DLOG_MODE=standard ${cromwell_path} server >log1 2>logerr &
echo 'started cromwell'
```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://bio-os.gitbook.io/userguide/zui-jia-shi-jian/for-bioos-kai-fa-zhe.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
