TT Bigdata TT Bigdata
首页
  • 部署专题

    • 常规安装
    • 一键部署
  • 组件安装

    • 常规&高可用
  • 版本专题

    • 更新说明
  • Ambari-Env

    • 环境准备
    • 开始使用
  • 组件编译

    • 专区—Ambari
    • 专区—Bigtop
  • 报错解决

    • 专区—Ambari
    • 专区—Bigtop
  • 其他技巧

    • Maven镜像加速
    • Gradle镜像加速
    • Bower镜像加速
    • 虚拟环境思路
    • R环境安装+一键安装脚本
    • Ivy配置私有镜像仓库
    • Node.js 多版本共存方案
    • Ambari Web本地启动
    • Npm镜像加速
    • PostgreSQL快速安装
    • Temurin JDK 23快速安装
  • 成神之路

    • 专区—Ambari
    • 专区—Bigtop
  • 集成案例

    • Redis集成教学
    • Dolphin集成教学
    • Doris集成教学
    • 持续整理...
  • 模板代码

    • 各类组件
    • 通用模板
  • 国产化&其他系统

    • Centos系列
    • Kylin系列
    • OpenEuler系列
    • Rocky系列
    • Ubuntu系列
  • 生产调优

    • 组件调优指南
    • 1v1指导调优
  • 定制开发

    • 组件版本定制
    • 样式风格定制
  • 蓝图愿景
  • 技术支持
  • 合作共建
GitHub (opens new window)

JaneTTR

数据酿造智慧,每一滴都是沉淀!
首页
  • 部署专题

    • 常规安装
    • 一键部署
  • 组件安装

    • 常规&高可用
  • 版本专题

    • 更新说明
  • Ambari-Env

    • 环境准备
    • 开始使用
  • 组件编译

    • 专区—Ambari
    • 专区—Bigtop
  • 报错解决

    • 专区—Ambari
    • 专区—Bigtop
  • 其他技巧

    • Maven镜像加速
    • Gradle镜像加速
    • Bower镜像加速
    • 虚拟环境思路
    • R环境安装+一键安装脚本
    • Ivy配置私有镜像仓库
    • Node.js 多版本共存方案
    • Ambari Web本地启动
    • Npm镜像加速
    • PostgreSQL快速安装
    • Temurin JDK 23快速安装
  • 成神之路

    • 专区—Ambari
    • 专区—Bigtop
  • 集成案例

    • Redis集成教学
    • Dolphin集成教学
    • Doris集成教学
    • 持续整理...
  • 模板代码

    • 各类组件
    • 通用模板
  • 国产化&其他系统

    • Centos系列
    • Kylin系列
    • OpenEuler系列
    • Rocky系列
    • Ubuntu系列
  • 生产调优

    • 组件调优指南
    • 1v1指导调优
  • 定制开发

    • 组件版本定制
    • 样式风格定制
  • 蓝图愿景
  • 技术支持
  • 合作共建
GitHub (opens new window)
  • 方法论

  • 代码生命周期-metainfo

    • 加载原理深度剖析[一]
    • 加载原理深度剖析[二]
    • 加载原理深度剖析[三]
    • 结构与层级深入解读
    • configFile详解[一]
    • configFile详解[二]
    • cardinality详解[一]
    • cardinality详解[二]
    • cardinality详解[三]
    • category详解[一]
    • category详解[二]
    • category详解[三]
    • theme详解[一]
    • theme详解[二]
    • theme详解[三]
    • commandScript详解[二]
    • commandScript详解[一]
    • commandScript详解[三]
    • customCommand详解[一]
    • customCommand详解[二]
    • customCommand详解[三]
    • requiredServices详解[一]
    • requiredServices详解[二]
    • osSpecifics详解[一]
    • osSpecifics详解[二]
    • osSpecifics详解[三]
    • quicklinks详解[一]
    • quicklinks详解[二]
    • quicklinks详解[三]
    • quicklinks详解[四]
      • 4. 自定义超链接方式
        • 4.1 QuickLinks 配置模板
        • 4.2 配置说明
        • 4.3 配置文件参考
        • 配置文件关键点
        • 4.4 配置的运行流程
  • 架构剖析

  • UI样式

  • GOD-Ambari
  • 代码生命周期-metainfo
JaneTTR
2025-06-03
目录

quicklinks详解[四]

# 3.2 后台参数解读

本节将通过源码+配置+接口三位一体,梳理 Ambari QuickLinks 的后台请求、Provider 调用、配置文件加载以及多样化自定义机制。适合运维/二开开发者深入理解底层原理和排查思路。

# 3.2.1 API 请求定义

从浏览器发送的 QuickLinks 请求,可以通过路径匹配,直接定位到 StacksService.java 文件中的如下代码:

image-20241231161704707

路径定义代码:

 @GET
  @Path("{stackName}/versions/{stackVersion}/services/{serviceName}/quicklinks")
  @Produces(MediaType.TEXT_PLAIN)
  @ApiOperation(value = "Get all quicklinks configurations for a stack service",
      nickname = "StacksService#getStackServiceQuickLinksConfigurations",
      notes = "Returns all quicklinks configurations for a stack service.",
      response = QuickLinksResponse.class,
      responseContainer = RESPONSE_CONTAINER_LIST)
  @ApiImplicitParams({
      @ApiImplicitParam(name = QUERY_FIELDS, value = "Filter returned attributes",
          defaultValue = "QuickLinkInfo/file_name," +
              "QuickLinkInfo/service_name," +
              "QuickLinkInfo/stack_name," +
              "QuickLinkInfo/stack_version",
          dataType = DATA_TYPE_STRING, paramType = PARAM_TYPE_QUERY),
      @ApiImplicitParam(name = QUERY_SORT, value = "Sort quick links (asc | desc)",
          defaultValue = "QuickLinkInfo/file_name.asc," +
              "QuickLinkInfo/service_name.asc," +
              "QuickLinkInfo/stack_name.asc," +
              "QuickLinkInfo/stack_version.asc",
          dataType = DATA_TYPE_STRING, paramType = PARAM_TYPE_QUERY),
      @ApiImplicitParam(name = QUERY_PAGE_SIZE, value = QUERY_PAGE_SIZE_DESCRIPTION, defaultValue = DEFAULT_PAGE_SIZE, dataType = DATA_TYPE_INT, paramType = PARAM_TYPE_QUERY),
      @ApiImplicitParam(name = QUERY_FROM, value = QUERY_FROM_DESCRIPTION, defaultValue = DEFAULT_FROM, dataType = DATA_TYPE_STRING, paramType = PARAM_TYPE_QUERY),
      @ApiImplicitParam(name = QUERY_TO, value = QUERY_TO_DESCRIPTION, dataType = DATA_TYPE_STRING, paramType = PARAM_TYPE_QUERY)
  })
  @ApiResponses(value = {
      @ApiResponse(code = HttpStatus.SC_OK, message = MSG_SUCCESSFUL_OPERATION),
      @ApiResponse(code = HttpStatus.SC_NOT_FOUND, message = MSG_RESOURCE_NOT_FOUND),
      @ApiResponse(code = HttpStatus.SC_INTERNAL_SERVER_ERROR, message = MSG_SERVER_ERROR)
  })
  public Response getStackServiceQuickLinksConfigurations(String body, @Context HttpHeaders headers,
                                           @Context UriInfo ui,
                                           @ApiParam @PathParam("stackName") String stackName,
                                           @ApiParam @PathParam("stackVersion") String stackVersion,
                                           @ApiParam @PathParam("serviceName") String serviceName) {

    return handleRequest(headers, body, ui, Request.Type.GET,
      createStackServiceQuickLinksResource(stackName, stackVersion, serviceName, null));
  }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39

解析:

  1. API 路径匹配
    • 请求路径为 /{stackName}/versions/{stackVersion}/services/{serviceName}/quicklinks,三参数动态适配多栈、多版本、多服务。
  2. 处理逻辑
    • 统一调用 handleRequest,再进入 Provider 和资源创建流程。
  3. 返回类型
    • 返回 QuickLinksResponse,封装所有 JSON 配置数据。

# 3.2.2 Provider 逻辑解析

Resource.Type.QuickLink 对应的 Provider 是 QuickLinkArtifactResourceProvider,其核心方法为 getResources。

@Override
public Set<Resource> getResources(Request request, Predicate predicate) throws SystemException, UnsupportedPropertyException, NoSuchResourceException, NoSuchParentResourceException {

    Set<Resource> resources = new LinkedHashSet<>();

    resources.addAll(getQuickLinks(request, predicate));
    // Add other artifacts types here

    if (resources.isEmpty()) {
      throw new NoSuchResourceException("The requested resource doesn't exist: QuickLink not found, " + predicate);
    }

    return resources;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
  • 负责拉取所有 QuickLinks 配置对象,失败时抛出异常,便于前端捕获和用户报错提示。

getQuickLinks 方法补全(未省略任何原文片段):

private Set<Resource> getQuickLinks(Request request, Predicate predicate) throws NoSuchParentResourceException,
    NoSuchResourceException, UnsupportedPropertyException, SystemException {
         //	此处省略不必要的代码 
        for (QuickLinksConfigurationInfo quickLinksConfigurationInfo : serviceQuickLinks) {
          Resource resource = new ResourceImpl(Resource.Type.QuickLink);
          Set<String> requestedIds = getRequestPropertyIds(request, predicate);
          setResourceProperty(resource, QUICKLINK_FILE_NAME_PROPERTY_ID, quickLinksConfigurationInfo.getFileName(), requestedIds);
          setResourceProperty(resource, QUICKLINK_DATA_PROPERTY_ID, quickLinksConfigurationInfo.getQuickLinksConfigurationMap(), requestedIds);
          setResourceProperty(resource, QUICKLINK_DEFAULT_PROPERTY_ID, quickLinksConfigurationInfo.getIsDefault(), requestedIds);
          setResourceProperty(resource, STACK_NAME_PROPERTY_ID, stackName, requestedIds);
          setResourceProperty(resource, STACK_VERSION_PROPERTY_ID, stackVersion, requestedIds);
          setResourceProperty(resource, STACK_SERVICE_NAME_PROPERTY_ID, serviceInfo.getName(), requestedIds);
          serviceResources.add(resource);
        }

        resources.addAll(serviceResources);

      }
    }
    return resources;
  }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21

# 3.2.3 配置加载逻辑

# QuickLinks 配置读取流程

完整代码片段:

public QuickLinksConfigurationModule(File quickLinksConfigurationFile, QuickLinksConfigurationInfo moduleInfo) {
    this.moduleInfo = moduleInfo;
    if (!moduleInfo.isDeleted() && quickLinksConfigurationFile != null) {
      LOG.debug("Looking for quicklinks in {}", quickLinksConfigurationFile.getAbsolutePath());
      FileReader reader = null;
      try {
        reader = new FileReader(quickLinksConfigurationFile);
      } catch (FileNotFoundException e) {
        LOG.error("Quick links file not found");
      }
      try {
        QuickLinks quickLinksConfig = mapper.readValue(reader, QuickLinks.class);
        Map<String, QuickLinks> map = new HashMap<>();
        map.put(QUICKLINKS_CONFIGURATION_KEY, quickLinksConfig);
        moduleInfo.setQuickLinksConfigurationMap(map);
        LOG.debug("Loaded quicklinks configuration: {}", moduleInfo);
      } catch (IOException e) {
        String errorMessage = String.format("Unable to parse quicklinks configuration file %s", quickLinksConfigurationFile.getAbsolutePath());
        LOG.error(errorMessage,  e);
        setValid(false);
        addError(errorMessage);
      }
    }
  }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
# 配置文件路径解析

ServiceModule 路径拼接方法补全:

private void populateQuickLinksConfigurationModules(){
    if (serviceInfo.getQuickLinksConfigurationsDir() == null) {
      serviceInfo.setQuickLinksConfigurationsDir(StackDirectory.SERVICE_QUICKLINKS_CONFIGURATIONS_FOLDER_NAME);
    }

    String quickLinksConfigurationsDir = serviceDirectory.getAbsolutePath() + File.separator + serviceInfo.getQuickLinksConfigurationsDir();

    if (serviceInfo.getQuickLinksConfigurations() != null) {
      for (QuickLinksConfigurationInfo quickLinksConfigurationInfo: serviceInfo.getQuickLinksConfigurations()) {
        File file = new File(quickLinksConfigurationsDir + File.separator + quickLinksConfigurationInfo.getFileName());
        QuickLinksConfigurationModule module = new QuickLinksConfigurationModule(file, quickLinksConfigurationInfo);
        quickLinksConfigurationModules.put(module.getId(), module);
      }
    }    //Not fail if quicklinks.json file contains errors
  }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# 文件路径覆盖逻辑

image-20241231170529048

QuickLinks 默认配置路径为 quicklinks,可通过 metainfo.xml 灵活覆盖。

image-20241231170431640


<quickLinksConfigurations-dir>custom-quicklinks</quickLinksConfigurations-dir>
<quickLinksConfigurations>
<quickLinksConfiguration>
    <fileName>quicklinks.json</fileName>
    <default>true</default>
</quickLinksConfiguration>
</quickLinksConfigurations>
1
2
3
4
5
6
7
8

# 4. 自定义超链接方式

# 4.1 QuickLinks 配置模板

{
  "name": "default",
  "description": "default quick links configuration",
  "configuration": {
    "protocol": {
      "type": "http"
    },
    "links": [
      {
        "name": "dolphin_application_ui",
        "label": "DolphinApplication UI",
        "requires_user_name": "false",
        "component_name": "DOLPHIN_API",
        "url": "%@://%@:%@/dolphinscheduler/",
        "port": {
          "http_property": "server.port",
          "http_default_port": "12345",
          "regex": "^(\\d+)$",
          "site": "dolphin-api-server-application"
        }
      }
    ]
  }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24

# 4.2 配置说明

字段 说明 示例值
name 配置文件的名称,用于标识当前 QuickLinks 配置。 "default"
description 配置文件的描述信息,便于识别和管理。 "default quick links configuration"
protocol 定义协议类型,可选 http 或 https。 "http"
links 超链接数组,定义多个链接时需添加多个对象。 [{...}]
name 链接的唯一标识符,在内部使用,不显示在页面上。 "dolphin_application_ui"
label 页面上显示的超链接名称。 "DolphinApplication UI"
requires_user_name 是否需要附加登录用户参数到链接中,false 表示不需要,true 表示需要。 "false"
component_name 对应组件的名称,必须与 metainfo.xml 中 <component> 的 name 值保持一致。 "DOLPHIN_API"
url 链接的模板,包含占位符 %@,依次替换为协议、主机名、端口号等内容。 "%@://%@:%@/dolphinscheduler/"
port 定义端口号的来源及默认值。 {...}
- http_property 在配置文件中用于指定端口号的属性名称。 "server.port"
- http_default_port 如果未找到端口号,则使用的默认值。 "12345"
- regex 用于从属性值中提取端口号的正则表达式。 "^(\\d+)$"
- site 指定配置文件的名称,用于获取 http_property 的值。 "dolphin-api-server-application"

# 4.3 配置文件参考

  • dolphin-api-server-application.xml(对应上方 site 的定义)

image-20241231171553436

services/DOLPHINSCHEDULER/configuration/dolphin-api-server-application.xml
1

<configuration>
    <property>
        <name>server.port</name>
        <value>12345</value>
        <on-ambari-upgrade add="true"/>
    </property>
    <property>
        <name>content</name>
        <display-name>Dolphinscheduler api-server application.yaml</display-name>
        <description>Dolphinscheduler api-server application.yaml</description>
        <value>#</value>
    </property>
</configuration>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
# 配置文件关键点
  1. server.port:核心端口号映射,必须和 JSON 里的 site、property 保持一致。
  2. on-ambari-upgrade:升级流程中是否添加/更新此配置。
  3. 路径要求:文件路径、文件名、site字段三者严格一一对应,否则不会被自动加载。

# 4.4 配置的运行流程

  1. QuickLinks 请求触发
    • 用户访问页面时自动由前端/后端协作请求拉取对应 quicklinks 配置。
  2. 配置文件加载
    • 后端自动加载 JSON 模板和 site 指定的 XML 配置,支持多环境和多实例拓扑。
  3. 占位符替换
    • 按顺序替换 %@ 为协议、主机、端口,实现高度动态适配。
  4. 超链接生成
    • 最终渲染到页面,供用户直达服务 UI。
#Ambari#QuickLinks#后端解析#Provider机制#配置加载#自定义超链接
quicklinks详解[三]
server与agent协作详解[一]

← quicklinks详解[三] server与agent协作详解[一]→

最近更新
01
Pandoc 缺失导致 SparkR 构建失败
06-08
02
Cyrus SASL/GSASL 缺失解决
06-07
03
Hadoop_3.3.4 编译实战 1.0.0+
06-06
更多文章>
Theme by Vdoing | Copyright © 2017-2025 JaneTTR | MIT License
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式