Ambari-Server Rest API处理1(基础知识准备+从Server到Handler)

本文梳理的Rest API主要是针对Web端的Rest API,暂不包括处理Agent 请求的API.该部分的处理以后会补充。

目录

  1. 基础知识准备
    1.1. IDEA远程调试Ambari-Server
    1.1.1. 在IDEA中配置远程服务器
    1.1.2. 以Debug模式启动Ambari-Server
    1.1.3. 在IDEA中连接Ambari-Server
    1.2. Rest API 说明
    1.2.1. 使用curl发送Rest API请求
    1.2.2. Ambari-Server中基本的Rest API请求举例
    1.3. Ambari-Server目录
    1.4. Ambari-Server中基本资源对象与Provider
  2. Ambari-Server 处理Rest API基本流程说明
    2.1. 从Server到Handler
    2.2. Hander分派
    2.3. 具体Handler处理
    2.4. 基本流程总结
  3. Ambari-Server通过Rest API进行服务安装、部署、操作流程
    3.1. 服务部署安装流程
    3.2. 关于配置
    3.2.1. 配置相关的Rest API
    3.3. 安装部署时可能遇到的问题
    3.3.1. 安装失败,提示缺少配置
    3.3.2. 重启时,数据库检查不通过,Ambari-Server重启失败
    3.4. 服务操作
    3.4.1. 创建服务
    3.4.2. 启动服务
    3.4.3. 停止服务
    3.4.4. 卸载服务
  4. Ambari-Server通过Rest API进行服务安装、部署、操作源码分析
    4.1. 创建服务资源
    4.2. 为服务添加服务组件
    4.3. 创建配置
    4.4. 应用配置
    4.5. 指定服务组件部署的主机
    4.6. 开始服务组件的安装
    4.6.1. 关于Stage与Stage DAG
    4.6.2. Stage DAG构建逻辑
    4.7. 服务操作
  5. 用户鉴权、操作权限检查管理
    5.1. HTTP基本认证
    5.2. 从Ambari-Server用户基本认证之Servlet Filter
    5.2.1. 关于spring-security.xml
    5.2.2. AmbariUserAuthorizationFilter
    5.2.3. AmbariDelegatingAuthenticationFilter
    5.2.4. AmbariAuthorizationFilter
    5.3. 操作权限检查
    5.4. 用户鉴权检查总结
    5.5. 用户登录
    5.6. 用户登出

1.基础知识准备

1.1.IDEA远程调试Ambari-Server

为了查看追踪Ambari-Server对Rest API的处理过程,可以采用Debug方式启动Ambari-Server,然后使用本地IDEA环境连接Ambari-Server,对Ambari-Server进行远程调试,追踪Ambari-Server的运行流程。
主要操作步骤如下:
① 在IDEA中配置远程服务器;
② 以Debug模式启动Ambari-Server;
③ 在IDEA中连接Ambari-Server,开始追踪Server运行流程。
下面对各个步骤进行详细说明。

1.1.1.在IDEA中配置远程服务器

操作步骤:
① 在工具栏中,点击“Select Run/Debug Configuration”按钮;
这里写图片描述

② 在弹出菜单中点击“Edit Configurations…”,弹出“Run/Debug Configurations”对话框;
这里写图片描述

③ 在弹出“Run/Debug Configurations”对话框中选择点击添加按钮,添加类型为”Remote”;
这里写图片描述

④ 配置Remote Server,然后点击”OK”,保存配置Remote Server;
这里写图片描述

配置完成后,IDEA工具栏会显示刚才配置的Server

这里写图片描述

1.1.2.以Debug模式启动Ambari-Server

Ambari-Server后端使用postgreSQL数据库时,启动命令为:

/usr/lib/jvm/java-1.7.0-openjdk-1.7.0.91-2.6.2.3.el7.x86_64/bin/java -server -Xdebug  -Xrunjdwp:transport=dt_socket,suspend=n,server=y,address=5005 -XX:NewRatio=3 -XX:+UseConcMarkSweepGC -XX:-UseGCOverheadLimit -XX:CMSInitiatingOccupancyFraction=60 -XX:+CMSClassUnloadingEnabled -Dsun.zip.disableMemoryMapping=true -Xms512m -Xmx2048m -XX:MaxPermSize=128m -Djava.security.auth.login.config=/etc/ambari-server/conf/krb5JAASLogin.conf -Djava.security.krb5.conf=/etc/krb5.conf -Djavax.security.auth.useSubjectCredsOnly=false -cp /etc/ambari-server/conf:/usr/lib/ambari-server/*:/usr/share/java/postgresql-jdbc.jar org.apache.ambari.server.controller.AmbariServer

Ambari-Server后端使用Mysql数据库时,还需要进一步配置。
操作步骤如下:
① 拷贝mysql驱动,执行命令:cp /usr/share/java/mysql-connector-java.jar /var/lib/ambari-server/resources/
② 编辑vim /etc/ambari-server/conf/ambari.properties文件,增加属性:server.jdbc.driver.path=/usr/share/java/mysql-connector-java.jar
③ 使用如下命令启动Ambari-Server。

/usr/lib/jvm/java-1.7.0-openjdk-1.7.0.91-2.6.2.3.el7.x86_64/bin/java -server -Xdebug  -Xrunjdwp:transport=dt_socket,suspend=n,server=y,address=5005 -XX:NewRatio=3 -XX:+UseConcMarkSweepGC -XX:-UseGCOverheadLimit -XX:CMSInitiatingOccupancyFraction=60 -XX:+CMSClassUnloadingEnabled -Dsun.zip.disableMemoryMapping=true -Xms1012m -Xmx3048m -XX:MaxPermSize=256m -Djava.security.auth.login.config=/etc/ambari-server/conf/krb5JAASLogin.conf -Djava.security.krb5.conf=/etc/krb5.conf -Djavax.security.auth.useSubjectCredsOnly=false -cp /etc/ambari-server/conf:/usr/lib/ambari-server/*:/usr/share/java/mysql-connector-java.jar       org.apache.ambari.server.controller.AmbariServer

1.1.3.在IDEA中连接Ambari-Server

操作步骤:
① 在程序中相应位置填上断点;
② 服务器启动后,立马在IDEA中开启调试:
这里写图片描述

正常连接服务器,进入调试后,在控制输出台输出信息如下:
这里写图片描述

③ 进入调试,正常调试。
这里写图片描述

1.2.Rest API 说明

所谓Rest,就是用URL定位资源,用HTTP动词(GET,POST,DELETE,DETC)描述操作,主要特点有:
① REST描述的是在网络中client和server的一种交互形式;REST本身不实用,实用的是如何设计 RESTful API(REST风格的网络接口);
② Server提供的RESTful API中,URL中只使用名词来指定资源,原则上不使用动词。“资源”是REST架构或者说整个网络处理的核心。如:
a)http://api.qc.com/v1/friends: 获取某人的好友表;
b)http://api.qc.com/v1/profile: 获取某人的详细信息;
③ 用HTTP协议里的动词来实现资源的添加,修改,删除等操作。即通过HTTP动词来实现资源的状态扭转:
a)GET 用来获取资源;
b)POST 用来新建资源(也可以用于更新资源);
c)PUT 用来更新资源,DELETE 用来删除资源。
比如:DELETE http://api.qc.com/v1/friends: 删除某人的好友 (在http parameter指定好友id)
POST http://api.qc.com/v1/friends: 添加好友
④ Server提供的RESTful API中,URL中只使用名词来指定资源,原则上不使用动词。“资源”是REST架构或者说整个网络处理的核心。
⑤ Server和Client之间传递某资源的一个表现形式,比如用JSON,XML传输文本,或者用JPG,WebP传输图片等。当然还可以压缩HTTP传输时的数据(on-wire data compression)。
用 HTTP Status Code传递Server的状态信息。比如最常用的 200 表示成功,500 表示Server内部错误等。

1.2.1.使用curl发送Rest API请求

curl是很方便的Rest客戶端,可以很方便的完成许多Rest API测试的需求,甚至,如果是需要先登入或认证的rest api,也可以进行测试,利用curl指令,可以送出HTTP GET, POST, PUT, DELETE, 也可以改变 HTTP header來满足使用REST API需要的特定条件。
curl参数很多,这里仅列出测试Rest时需要用到的。
这里写图片描述

curl后面加的url加引号也可以,不加引号也可以,如果有非纯英文字或数字外的字元,不加引号可能会有问题,如果是经过编码的url,也要加上引号。
(2)HEADER
在http header加入信息,如:curl -v -i -H “Content-Type: application/json” http://www.example.com/users
(3)HTTP Parameter
http參數可以直接加在url的query string,也可以用-d帶入參數間用&串接,或使用多個-d,例如:

# 使用`&`串接多个参数
curl -X POST -d   "param1=value1&param2=value2"

# 也可使用多個`-d`,效果同上
curl -X POST -d "param1=value1" -d "param2=value2"

(4)post json 格式的资料
如同时需要传送request parameter和json,request parameter可以加在url后面,json数据则放入-d的参数,然後利用单引号將json资料含起來(如果json內容是用单引号,-d的参数則改用单引号包裹),header要加入”Content-Type:application/json”跟”Accept:application/json”

curl http://www.example.com?modifier=kent -X PUT -i -H "Content-Type:application/json" -H "Accept:application/json" -d '{"boolean" : false, "foo" : "bar"}'
# 不加"Accept:application/json"也可以

curl http://www.example.com?modifier=kent -X PUT -i -H "Content-Type:application/json" -d '{"boolean" : false, "foo" : "bar"}'

(5)HTTP Basic Authentication
如果网站是采用HTTP基本认证, 可以使用 –user username:password 登入,例如:curl -i –user kent:secret http://www.rest.com/api/foo

1.2.2.Ambari-Server中基本的Rest API请求举例

(1)认证
对Ambari API操作需要认证,在Ambari中采用的HTTP基本认证,该认证可使用-u或是–user参数指定,例如:curl –user name:password http://{your.ambari.server}/api/v1/clusters
(2)监控
Ambari API提供监控Hadoop集群运行状况和metrics信息的接口。例子:获取c1集群中HDFS服务的DataNode组件资源信息。
请求:GET /clusters/c1/services/HDFS/components/DATANODE
响应:

200 OK
{
    "href" : "http://your.ambari.server/api/v1/clusters/c1/services/HDFS/components/DATANODE",
    "metrics" : {
        "process" : { "proc_total" : 697.75, "proc_run" : 0.875},
        "rpc" : {...},
        "ugi" : {...},
        "dfs" : {"datanode" : {...}},
        "disk" : {...},
        "cpu" : {...}
        ...
    },
    "ServiceComponentInfo" : {
        "cluster_name" : "c1",
        "component_name" : "DATANODE",
        "service_name" : "HDFS"
        "state" : "STARTED"
    },
    "host_components" : [
        {
            "href" : "http://your.ambari.server/api/v1/clusters/c1/hosts/host1/host_components/DATANODE",
            "HostRoles" : {"cluster_name" : "c1","component_name" : "DATANODE","host_name" : "host1"}
        }
    ]
}

(3)管理
Ambari API提供了对Hadoop集群资源管理的方法,包括资源创建、删除和更新。例如
创建HDFS服务,请求:POST /clusters/c1/services/HDFS;响应:201 Created。
启动服务,请求:PUT /clusters/c1/services/HDFS/,传入body: {“serviceInfo”:{”state”:”STARTED”} };
响应:202 Accepted。

1.3.Ambari-Server目录
这里写图片描述

1.4.Ambari-Server中基本资源对象与Provider
这里写图片描述

2.Ambari-Server 处理Rest API基本流程说明

下面以查看集群中主机列表API为例,说明Ambari-Server处理Rest API的基本处理框架。该API的具体形式为:get: api/v1/clusters/mycluster/hosts。
说明:Ambari-Server中嵌入Jetty,使用Jetty处理Web请求,关于Jetty对请求的处理及Jetty原理框架背景知识见文档“Jetty框架调研报告”。

2.1.从Server到Handler

Ambari-Server在收到Web请求后,转入到Jetty Hander逻辑中,由Jetty Hander进行处理。这个过程可以用标准的Jetty Server处理图表示。

这里写图片描述

Ambari-Server注册的处理Rest API请求的Hander为HandlerCollection类型,实际子类为AmbariHandlerList,该Hander的处理逻辑为:不断遍历注册的子Handler,直到找到一个可以处理该请求的子Hander,该Handler处理该请求,重置请求的处理位,如果遍历完毕还没有找到,则抛出异常,表示无法处理该请求。

该Handler的handler方法处理逻辑如下:

这里写图片描述

其中processHandlers处理过程如下:

2.2.Hander分派

Ambari-Server使用Jersey框架作为JAX-RS标准的实现。具体的资源及资源方法通过JAX-RS标注进行标识。Ambari-Server将org.apache.ambari.server.api.services包下所有类都通过Jersey注册成Jetty Handler。

ServletHolder sh = new ServletHolder(ServletContainer.class);
sh.setInitParameter("com.sun.jersey.config.property.resourceConfigClass",
        "com.sun.jersey.api.core.PackagesResourceConfig");

sh.setInitParameter("com.sun.jersey.config.property.packages",
        "org.apache.ambari.server.api.rest;" +
                "org.apache.ambari.server.api.services;" +
                "org.apache.ambari.eventdb.webservice;" +
                "org.apache.ambari.server.api");

sh.setInitParameter("com.sun.jersey.api.json.POJOMappingFeature", "true");
root.addServlet(sh, "/api/v1/*");

因此,在找某个Rest API的处理Handler时,可直接进行Rest API的URI进行标注对比。对于get:api/v1/clusters/mycluster/hosts URI请求的Handler,可直接找标注了@path(/clusters/)的类,该类为ClusterService,并找到URI路径全匹配的Get方法,最终找到getHostHandler方法,该方法返回一个JAX-RS子资源,表明对该Get请求由HostService的相应方法进行处理响应。

@Path("{clusterName}/hosts")
public HostService getHostHandler(@Context javax.ws.rs.core.Request request, @PathParam("clusterName") String clusterName) {
  return new HostService(clusterName);
}

同理,在HostService中按照路径匹配规则找到响应的处理方法,方法为:getHosts。

@GET
@Produces("text/plain")
public Response getHosts(String body, @Context HttpHeaders headers, @Context UriInfo ui) {
  return handleRequest(headers, body, ui, Request.Type.GET,
      createHostResource(m_clusterName, null, ui));
}

在Ambari-Server中,几个常用的Service列表如下:

这里写图片描述

2.3.具体Handler处理
AmbariHandlerList在将Rest API请求进行转发时,首先转发给一级JAX-RS资源的相关方法,如果该JAX-RS资源能直接处理,则直接调用BaseSevrvice类的handleRequest方法进行请求处理,否则转发给二级JAX-RS资源,由该JAX-RS资源处理,处理方式相同(要么直接调用BaseService.handleRequest方法或是继续转给下一级资源)。
BaseService对请求的处理逻辑过程如下:
这里写图片描述

在Ambari中,Request(org.apache.ambari.server.api.services)分为:GetRequest,PostRequest,PutRequest,DeleteRequest,QueryPostRequest 5中Request。5中Request的类关系如下:
这里写图片描述

Request.process方法调用的是BaseRequest类中的process方法,该方法的主要处理步骤如下所示:
① 调用函数parseRenderer();//不知道具体干什么的
② 调用函数parseQueryPredicate();//不知道具体干什么的
③ 调用Request的Hander的handleRequest函数继续处理请求并返回结果;
④ 如果处理结果不为Error,这对结果进行初步解析,并返回处理结果。

不同的Request的实现代码基本相同,也都比较简单,对Request的主要处理逻辑都在BaseRequest里。但是不同的Request的Handler不同,如GetRequest的Handler为ReadHandler(org.apache.ambari.server.api.handlers)。GetRequest的类实现代码如下:

public class GetRequest extends BaseRequest {
  public GetRequest(HttpHeaders headers, RequestBody body, UriInfo uriInfo, ResourceInstance resource) {
    super(headers, body, uriInfo, resource);
  }
  @Override
  public Type getRequestType() {
    return Type.GET;
  }
  @Override
  protected RequestHandler getRequestHandler() {
    return new ReadHandler();
  }
}

ReadHandler的handleRequest函数做真正的请求处理工作,ReadHandler.handlerRequest的主要处理步骤如下:

这里写图片描述

Clustercontroler查选资源列表的方式为向资源Provider进行查询。对于查询Host列表请求,对应的资源Provider为HostResourceProvider。HostResourceProvider在获取资源列表时,首先通过AmbarManagementController(org.apache.server.controller.AmbariManagementControllerImp)获取Request对应的集群Clusters(org.apache.ambari.server.state.cluster.ClustersImpl),Clusters实例在Ambari-Server启动时初始化,其中存储了相应的host列表;

2.4.基本流程总结

Ambari-Server在收到外部Rest API请求后的总体处理流程如下:
这里写图片描述

Handler对请求处理的流程如下:
这里写图片描述

对于ReadHander的处理过程如下:
这里写图片描述

猜你喜欢

转载自blog.csdn.net/youyou1543724847/article/details/78377914