1、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。
2、Ambari-Server目录
目录 | 描述 |
---|---|
org.apache.ambari.server.api.services | 对web接口的入口方法,处理/api/v1/* 的请求 |
org.apache.ambari.server.controller | 对Ambari中cluster的管理处理,如新增host,更service、删除component等 |
org.apache.ambari.server.controller.internal | 主要存放ResourceProvider和PropertyProvider; |
org.apache.ambari.service.orm.* | 对数据库的操作 |
org.apache.ambari.server.agent.rest | 处理与Agent的接口的入口方法 |
org.apache.ambari.security | 使用Spring Security来做权限管理 |
其中,每一种Resource都对应一个ResourceProvider,对应关系如下
3、RestApi调用过程剖析
下面以查看集群中主机列表API为例,说明Ambari-Server处理Rest API的基本处理框架。
该API的具体形式为:
get: api/v1/clusters/mycluster/hosts。
Ambari-Server中嵌入Jetty,使用Jetty为容器处理Web请求
Ambari-Server在收到Web请求后,转入到Jetty Hander逻辑中,由Jetty Hander进行处理
每个Rest API有对应的处理Handler,可直接进行Rest API的URI进行标注对比。
对于get:api/v1/clusters/mycluster/hosts URI请求的Handler,可直接找标注了@path(/clusters/)的类,该类为ClusterService。
并找到URI路径全匹配的Get方法,最终找到getHostHandler方法。
该方法返回一个JAX-RS子资源,表明对该Get请求由HostService的相应方法进行处理响应。具体下文有详细配图介绍
3.1 源代码调用跟踪
3.1.1、 api->service层
ambari-server module 对web接口的入口方法中处理形如/api/v1/* 的请求,由上文2中可知,需要在service层找对应的服务处理类
get: api/v1/clusters/mycluster/hosts。
对应的就是ClustersService.java了
在Ambari-Server中,几个常用的Service列表如下:
Ambari-Server使用Jersey框架作为JAX-RS标准的实现。
具体的资源及资源方法通过JAX-RS标注进行标识。
Ambari-Server将org.apache.ambari.server.api.services包下所有类都通过Jersey注册成Jetty Handler。
3.1.2、Service->Handler
找到URI路径全匹配的Get方法,最终找到getHostHandler方法
该方法返回一个JAX-RS子资源,表明对该Get请求由HostService的相应方法进行处理响应。
说明是拿HostService这个服务对应的Handler调度的
同理,在HostService中按照路径匹配规则找到响应的处理方法,方法为:getHosts。
public Response getHosts(String body, @Context HttpHeaders headers, @Context UriInfo ui) {
return handleRequest(headers, body, ui, Request.Type.GET,
createHostResource(m_clusterName, null));
}
3.1.3、Handler->Request
将Rest API请求进行转发时,首先转发给一级JAX-RS资源的相关方法。
如果该JAX-RS资源能直接处理,则直接调用BaseSevrvice类的handleRequest方法进行请求处理。
否则转发给二级JAX-RS资源,由该JAX-RS资源处理,处理方式相同(要么直接调用BaseService.handleRequest方法或是继续转给下一级资源)。
getHosts()–>BaseService.handleRequest()
protected Response handleRequest(HttpHeaders headers, String body, UriInfo uriInfo,
Request.Type requestType, ResourceInstance resource) {
return handleRequest(headers, body, uriInfo, requestType, null, resource);
}
protected Response handleRequest(HttpHeaders headers, String body,
UriInfo uriInfo, Request.Type requestType,
MediaType mediaType, ResourceInstance resource) {
// original request and initial result
RequestBody rb = new RequestBody();
rb.setBody(body);
Request request = getRequestFactory().createRequest(headers, rb, uriInfo, requestType, resource);
Result result = new ResultImpl(new ResultStatus(ResultStatus.STATUS.OK));
try {
Set<RequestBody> requestBodySet = getBodyParser().parse(body);
Iterator<RequestBody> iterator = requestBodySet.iterator();
while (iterator.hasNext() && result.getStatus().getStatus().equals(ResultStatus.STATUS.OK)) {
RequestBody requestBody = iterator.next();//获取列表中下一个RequestBody元素,创建一个request对象(下面)
request = getRequestFactory().createRequest(
headers, requestBody, uriInfo, requestType, resource);//Request对象类型有GetRequest、PostRequest、PutRequest
result = request.process();//调用request.process函数处理请求
// if it is not OK, then it is logged below
if(ResultStatus.STATUS.OK.equals(result.getStatus().getStatus())) {
requestAuditLogger.log(request, result);//获取请求的原始处理结果,并写日志
}
}
if(requestBodySet.isEmpty() || !ResultStatus.STATUS.OK.equals(result.getStatus().getStatus())) {
requestAuditLogger.log(request, result);//获取请求的原始处理结果,并写日志
}
} catch (BodyParseException e) {
result = new ResultImpl(new ResultStatus(ResultStatus.STATUS.BAD_REQUEST, e.getMessage()));
LOG.error("Bad request received: " + e.getMessage());
requestAuditLogger.log(request, result);
} catch (Throwable t) {
requestAuditLogger.log(request, new ResultImpl(new ResultStatus(ResultStatus.STATUS.SERVER_ERROR, t.getMessage())));
throw t;
}
ResultSerializer serializer = mediaType == null ? getResultSerializer() : getResultSerializer(mediaType);
Response.ResponseBuilder builder = Response.status(result.getStatus().getStatusCode()).entity(
serializer.serialize(result));
if (mediaType != null) {
builder.type(mediaType);
}
RetryHelper.clearAffectedClusters();
return builder.build();
}
3.1.4、Request.process()->Result
/**
BaseRequest类实现了这个接口,返回一个Result结果集
process实现里调用了result = getRequestHandler().handleRequest(this)
其中 getRequestHandler()是确定哪种类型的请求,这里是GetRequest
GetRequest调用自己的RequestHandler返回一个ReadHandler()实例
*
*/
@Override
public Result process() {
if (LOG.isDebugEnabled()) {
LOG.debug("Handling API Request: '{}'", getURI());
}
Result result;
try {
parseRenderer();
parseQueryPredicate();
result = getRequestHandler().handleRequest(this);//用一种Request来调用handleRequest()
} catch (InvalidQueryException e) {
String message = "Unable to compile query predicate: " + e.getMessage();
LOG.error(message, e);
result = new ResultImpl(new ResultStatus(ResultStatus.STATUS.BAD_REQUEST, message));
} catch (IllegalArgumentException e) {
String message = "Invalid Request: " + e.getMessage();
LOG.error(message, e);
result = new ResultImpl(new ResultStatus(ResultStatus.STATUS.BAD_REQUEST, message));
}
if (! result.getStatus().isErrorState()) {
getResultPostProcessor().process(result);
}
return result;
}
如下图、GetRequest调用自己的RequestHandler返回一个ReadHandler()实例
如下图、ReadHandler实例
其中的handleRequest(Request)方法
如下图、handleRequest()做真正请求处理的工作,通过这个方法使Request转化为Result结果集
其中的query对象执行execute操作,返回result结果,核心方法
@Override
public Result handleRequest(Request request) {//此方法做真正请求处理的工作,通过这个方法使Request转化为Result结果集
Query query = request.getResource().getQuery();
query.setPageRequest(request.getPageRequest());//根据Rquest参数设置Query参数
query.setSortRequest(request.getSortRequest());
query.setRenderer(request.getRenderer());
// If the request body exists, copy the requstInfoProperties from it. This map should contain
// the _directives_ specified in the request.
RequestBody body = request.getBody();
if(body != null) {
query.setRequestInfoProps(body.getRequestInfoProperties());
}
try {
addFieldsToQuery(request, query);//向提供的查询query里添加部分响应字段。
} catch (IllegalArgumentException e) {
return new ResultImpl(new ResultStatus(ResultStatus.STATUS.BAD_REQUEST, e.getMessage()));
}
Result result;
Predicate p = null;
try {
p = request.getQueryPredicate();
query.setUserPredicate(p);
result = query.execute();//query进行execute执行操作,返回result结果,核心方法
result.setResultStatus(new ResultStatus(ResultStatus.STATUS.OK));
} catch (AuthorizationException e) {
result = new ResultImpl(new ResultStatus(ResultStatus.STATUS.FORBIDDEN, e.getMessage()));
} catch (SystemException e) {
result = new ResultImpl(new ResultStatus(ResultStatus.STATUS.SERVER_ERROR, e));
} catch (NoSuchParentResourceException e) {
result = new ResultImpl(new ResultStatus(ResultStatus.STATUS.NOT_FOUND, e.getMessage()));
} catch (UnsupportedPropertyException e) {
result = new ResultImpl(new ResultStatus(ResultStatus.STATUS.BAD_REQUEST, e.getMessage()));
} catch (NoSuchResourceException e) {
if (p == null) {
// no predicate specified, resource requested by id
result = new ResultImpl(new ResultStatus(ResultStatus.STATUS.NOT_FOUND, e.getMessage()));
} else {
// resource(s) requested using predicate
result = new ResultImpl(new ResultStatus(ResultStatus.STATUS.OK, e));
result.getResultTree().setProperty("isCollection", "true");
}
} catch (IllegalArgumentException e) {
result = new ResultImpl(new ResultStatus(ResultStatus.STATUS.BAD_REQUEST,
"Invalid Request: " + e.getMessage()));
LOG.error("Bad request: ", e);
} catch (RuntimeException e) {
if (LOG.isErrorEnabled()) {
LOG.error("Caught a runtime exception executing a query", e);
}
//result = new ResultImpl(new ResultStatus(ResultStatus.STATUS.SERVER_ERROR, e));
throw e;
}
return result;
}
Request如何到Result?
handleReques()中的query.execute()为核心方法
此方法为Query接口方法,QueryImpl实现了它
@Override
public Result execute()
throws UnsupportedPropertyException,
SystemException,
NoSuchResourceException,
NoSuchParentResourceException {
queryForResources();
return getResult(null);
}
3.1.4.1、QueryImpl.queryForResources()
如下图、由此看出,是queryForResources()查询出的资源列表才最终拼接成Result对象
queryForResources()中,核心方法为doQuery()方法
/**
* Query the cluster controller for the top level resources.
*/
private void queryForResources()
throws UnsupportedPropertyException,
SystemException,
NoSuchResourceException,
NoSuchParentResourceException {
Resource.Type resourceType = getResourceDefinition().getType();
Predicate queryPredicate = createPredicate(getKeyValueMap(), processUserPredicate(userPredicate));
// must occur after processing user predicate and prior to creating request
finalizeProperties();
Request request = createRequest();
// use linked hash sets so that we maintain insertion and traversal order
// in the event that the resource provider already gave us a sorted set
// back
Set<Resource> resourceSet = new LinkedHashSet<>();
Set<Resource> providerResourceSet = new LinkedHashSet<>();
//doQuery方法向Clustercontroller查询Request所指定的一级资源列表
QueryResponse queryResponse = doQuery(resourceType, request, queryPredicate, true);
// If there is a page request and the predicate does not contain properties
// that need to be set
if ((pageRequest != null || sortRequest != null ) &&
!populateResourceRequired(resourceType)) {
PageResponse pageResponse = clusterController.getPage(resourceType,
queryResponse, request, queryPredicate, pageRequest, sortRequest);
// build a new set
for (Resource r : pageResponse.getIterable()) {
resourceSet.add(r);
providerResourceSet.add(r);
}
} else {
resourceSet.addAll(queryResponse.getResources());
providerResourceSet.addAll(queryResponse.getResources());
}
populatedQueryResults.put(null, new QueryResult(
request, queryPredicate, userPredicate, getKeyValueMap(), new QueryResponseImpl(resourceSet)));
queryResults.put(null, new QueryResult(
request, queryPredicate, userPredicate, getKeyValueMap(), queryResponse));
if (renderer.requiresPropertyProviderInput()) {
clusterController.populateResources(resourceType, providerResourceSet, request, queryPredicate);
}
// Optimization:
// Currently the steps executed when sub-resources are requested are:
// (1) Get *all* top-level resources
// (2) Populate all top-level resources
// (3) Query for and populate sub-resources of *all* top-level resources
// (4) Apply pagination and predicate on resources from above
//
// Though this works, it is very inefficient when either:
// (a) Predicate does not apply to sub-resources
// (b) Page request is present
// It is inefficient because we needlessly populate sub-resources that might not get
// used due to their top-level resources being filtered out by the predicate and paging
//
// The optimization is to apply the predicate and paging request on the top-level resources
// directly if there are no sub-resources predicates.
if ((pageRequest != null || userPredicate != null) && !hasSubResourcePredicate() && populateResourceRequired(resourceType)) {
QueryResponse newResponse = new QueryResponseImpl(resourceSet, queryResponse.isSortedResponse(), queryResponse.isPagedResponse(),
queryResponse.getTotalResourceCount());
PageResponse pageResponse = clusterController.getPage(resourceType, newResponse, request, queryPredicate, pageRequest, sortRequest);
// build a new set
Set<Resource> newResourceSet = new LinkedHashSet<>();
for (Resource r : pageResponse.getIterable()) {
newResourceSet.add(r);
}
populatedQueryResults.put(null, new QueryResult(request, queryPredicate, userPredicate, getKeyValueMap(), new QueryResponseImpl(newResourceSet)));
}
queryForSubResources();
}
↓
3.1.4.2、QueryImpl.doQuery()
用ClusterController去查询资源列表
/**
* Query the cluster controller for the resources.
*
* @param type the resource type
* @param request the request information
* @param predicate the predicate
* @param checkEmptyResponse true if an empty query response can trigger a NoSuchResourceException
*
* @return the result of the cluster controller query
*
* @throws NoSuchResourceException if a specific resource was asked for and not found and checkEmptyResponse == true
*/
private QueryResponse doQuery(Resource.Type type, Request request, Predicate predicate, boolean checkEmptyResponse)
throws UnsupportedPropertyException,
SystemException,
NoSuchResourceException,
NoSuchParentResourceException {
if (LOG.isDebugEnabled()) {
LOG.debug("Executing resource query: {} where {}", request, predicate);
}
//用ClusterController去查询资源列表
QueryResponse queryResponse = clusterController.getResources(type, request, predicate);
if (checkEmptyResponse && queryResponse.getResources().isEmpty()) {
// If this is not a collection request then we must throw
// NoSuchResourceException (404 response) for an empty query result
if(!isCollectionResource()) {
throw new NoSuchResourceException(
"The requested resource doesn't exist: " + type + " not found where " + predicate + ".");
}
}
return queryResponse;
}
↓
query -> controller层
↓
3.1.4.3、clusterControllerImpl.getResources()
如下图、getResources()中2个核心功能点为
- 封装资源的privider对象
- privider对象去查询资源,然后返回一个QueryResponse对象
@Override
public QueryResponse getResources(Type type, Request request, Predicate predicate)
throws UnsupportedPropertyException, NoSuchResourceException,
NoSuchParentResourceException, SystemException {
QueryResponse queryResponse = null;
// 1、封装资源的ExtendedResourceProviderWrapper对象 provider
ExtendedResourceProviderWrapper provider = ensureResourceProviderWrapper(type);
ensurePropertyProviders(type);
if (provider != null) {
if (LOG.isDebugEnabled()) {
LOG.debug("Using resource provider {} for request type {}", provider.getClass().getName(), type);
}
// make sure that the providers can satisfy the request
checkProperties(type, request, predicate);
//2、privider对象去查询资源
//queryForResources方法是provider调用的,ExtendedResourceProviderWrapper是一个内部类。
// get the resources---》
queryResponse = provider.queryForResources(request, predicate);
}
return queryResponse == null ? new QueryResponseImpl(Collections.emptySet()) : queryResponse;
}
↓
3.1.4.4、clusterControllerImpl.queryForResources()
如下图、queryForResources()中getResources()是ResourceProvider接口的一个方法
@Override
public QueryResponse queryForResources(Request request, Predicate predicate)
throws SystemException, UnsupportedPropertyException, NoSuchResourceException, NoSuchParentResourceException {
return extendedResourceProvider == null ?
new QueryResponseImpl(resourceProvider.getResources(request, predicate)) ://(resourceProvider)去获取资源列表
extendedResourceProvider.queryForResources(request, predicate);
}
↓
controller层->provider
↓
ResourceProvider接口,顾名思义,资源提供者接口,将controller层的资源请求调用通过各个ResourceProvider的实现类来实现getResources的动作事件
3.1.4.5、HostComponentResourceProvider.getResources()
HostComponentResourceProvider类是进行hostcomponent资源的获取
如下图、HostComponentResourceProvider类中的getResources()方法,通过调用findResources()返回一个Set
@Override
public Set<Resource> getResources(Request request, Predicate predicate)
throws SystemException, UnsupportedPropertyException, NoSuchResourceException, NoSuchParentResourceException {
final Set<ServiceComponentHostRequest> requests = new HashSet<>();
for (Map<String, Object> propertyMap : getPropertyMaps(predicate)) {
requests.add(getRequest(propertyMap));
}
//获取资源列表---》
return findResources(request, predicate, requests);
}
3.1.4.6、HostComponentResourceProvider.findResources()
private Set<Resource> findResources(Request request, final Predicate predicate,
final Set<ServiceComponentHostRequest> requests)
throws SystemException, NoSuchResourceException, NoSuchParentResourceException {
Set<Resource> resources = new HashSet<>();
Set<String> requestedIds = getRequestPropertyIds(request, predicate);
// We always need host_name for sch
requestedIds.add(HOST_NAME);
//AmbariManagementController获取Request对应的集群CLuster,Cluster在Ambari-server启动是初始化,其储存了相应host列表
Set<ServiceComponentHostResponse> responses = getResources(new Command<Set<ServiceComponentHostResponse>>() {
@Override
public Set<ServiceComponentHostResponse> invoke() throws AmbariException {
return getManagementController().getHostComponents(requests);//获取HostComponents--》》
}
});
for (ServiceComponentHostResponse response : responses) {
Resource resource = new ResourceImpl(Resource.Type.HostComponent);
setResourceProperty(resource, CLUSTER_NAME,
response.getClusterName(), requestedIds);
setResourceProperty(resource, SERVICE_NAME,
response.getServiceName(), requestedIds);
setResourceProperty(resource, COMPONENT_NAME,
response.getComponentName(), requestedIds);
setResourceProperty(resource, DISPLAY_NAME,
response.getDisplayName(), requestedIds);
setResourceProperty(resource, HOST_NAME,
response.getHostname(), requestedIds);
setResourceProperty(resource, PUBLIC_HOST_NAME,
response.getPublicHostname(), requestedIds);
setResourceProperty(resource, STATE,
response.getLiveState(), requestedIds);
setResourceProperty(resource, DESIRED_STATE,
response.getDesiredState(), requestedIds);
setResourceProperty(resource, VERSION, response.getVersion(),
requestedIds);
setResourceProperty(resource, DESIRED_STACK_ID,
response.getDesiredStackVersion(), requestedIds);
setResourceProperty(resource, ACTUAL_CONFIGS,
response.getActualConfigs(), requestedIds);
setResourceProperty(resource, STALE_CONFIGS,
response.isStaleConfig(), requestedIds);
setResourceProperty(resource, RELOAD_CONFIGS,
response.isReloadConfig(), requestedIds);
setResourceProperty(resource, UPGRADE_STATE,
response.getUpgradeState(), requestedIds);
setResourceProperty(resource, DESIRED_REPOSITORY_VERSION,
response.getDesiredRepositoryVersion(), requestedIds);
if (response.getAdminState() != null) {
setResourceProperty(resource, DESIRED_ADMIN_STATE,
response.getAdminState(), requestedIds);
}
if (null != response.getMaintenanceState()) {
setResourceProperty(resource, MAINTENANCE_STATE,
response.getMaintenanceState(), requestedIds);
}
resources.add(resource);
}
return resources;
}
↓
provider层->controller实现层
↓
3.1.4.7、AmbariManagementControllerImpl.getHostComponents()
@Override
public Set<ServiceComponentHostResponse> getHostComponents(
Set<ServiceComponentHostRequest> requests, boolean statusOnly) throws AmbariException {
LOG.debug("Processing requests: {}", requests);
Set<ServiceComponentHostResponse> response =
new HashSet<>();
for (ServiceComponentHostRequest request : requests) {
try {
response.addAll(getHostComponents(request, statusOnly));//getHostComponents---》获取HostComponents资源
} catch (ServiceComponentHostNotFoundException | ServiceComponentNotFoundException |
。。。。。
↓
↓
private Set<ServiceComponentHostResponse> getHostComponents(
ServiceComponentHostRequest request, boolean statusOnly) throws AmbariException {
LOG.debug("Processing request {}", request);
if (request.getClusterName() == null
|| request.getClusterName().isEmpty()) {
IllegalArgumentException e = new IllegalArgumentException("Invalid arguments, cluster name should not be null");
LOG.debug("Cluster not specified in request", e);
throw e;
}
final Cluster cluster;
try {
cluster = clusters.getCluster(request.getClusterName());//这里就调用Cluster实现类了
} catch (ClusterNotFoundException e) {
LOG.error("Cluster not found ", e);
throw new ParentObjectNotFoundException("Parent Cluster resource doesn't exist", e);
}
if (request.getHostname() != null) {
try {
if (!clusters.getClustersForHost(request.getHostname()).contains(cluster)) {
// case where host exists but not associated with given cluster
。。。。。。。。
↓
3.1.4.8、ClusterImpl.getClustersForHost()
如下图、ClusterImpl.getClustersForHost()方法返回Set
其中的getHostClustersMap()初始化时会从库中获取
@Override
public Set<Cluster> getClustersForHost(String hostname)
throws AmbariException {
Set<Cluster> clusters = getHostClustersMap().get(hostname);//getHostClustersMap()初始化时会从库中获取
if(clusters == null){
throw new HostNotFoundException(hostname);
}
if (LOG.isDebugEnabled()) {
LOG.debug("Looking up clusters for hostname, hostname={}, mappedClusters={}", hostname, clusters.size());
}
return Collections.unmodifiableSet(clusters);
}
loadClustersAndHosts()中为实体类的逻辑处理
↓
controller实现层->Dao层
↓
3.1.4.9、ClusterImpl调用链
getHostClustersMap() ->safelyLoadClustersAndHosts()->loadClustersAndHosts()
/**
* Gets the internal host/clusters map, ensuring that the relevant data has been previously initialized.
*
* @return a map of the requested data
*/
private ConcurrentHashMap<String, Set<Cluster>> getHostClustersMap() {
if (hostClustersMap == null) {
safelyLoadClustersAndHosts();
}
return hostClustersMap;
}
synchronized private void safelyLoadClustersAndHosts() {
if (clustersByName == null || clustersById == null ||
hostsByName == null || hostsById == null ||
hostClustersMap == null || clusterHostsMap1 == null) {
loadClustersAndHosts();
}
}
private void loadClustersAndHosts() {
LOG.info("Initializing cluster and host data.");
ConcurrentHashMap<String, Cluster> clustersByNameTemp = new ConcurrentHashMap<>();
ConcurrentHashMap<Long, Cluster> clustersByIdTemp = new ConcurrentHashMap<>();
ConcurrentHashMap<String, Host> hostsByNameTemp = new ConcurrentHashMap<>();
ConcurrentHashMap<Long, Host> hostsByIdTemp = new ConcurrentHashMap<>();
ConcurrentHashMap<String, Set<Cluster>> hostClustersMapTemp = new ConcurrentHashMap<>();
ConcurrentHashMap<String, Set<Host>> clusterHostsMap1Temp = new ConcurrentHashMap<>();
List<HostEntity> hostEntities = hostDAO.findAll();
for (HostEntity hostEntity : hostEntities) {
Host host = hostFactory.create(hostEntity);
hostsByNameTemp.put(hostEntity.getHostName(), host);
hostsByIdTemp.put(hostEntity.getHostId(), host);
}
hostsByName = hostsByNameTemp;
hostsById = hostsByIdTemp;
for (ClusterEntity clusterEntity : clusterDAO.findAll()) {
Cluster currentCluster = clusterFactory.create(clusterEntity);
clustersByNameTemp.put(clusterEntity.getClusterName(), currentCluster);
clustersByIdTemp.put(currentCluster.getClusterId(), currentCluster);
clusterHostsMap1Temp.put(currentCluster.getClusterName(), Collections.newSetFromMap(new ConcurrentHashMap<>()));
}
clustersByName = clustersByNameTemp;
clustersById = clustersByIdTemp;
for (HostEntity hostEntity : hostEntities) {
Set<Cluster> cSet = Collections.newSetFromMap(new ConcurrentHashMap<Cluster, Boolean>());
hostClustersMapTemp.put(hostEntity.getHostName(), cSet);
Host host = getHostsByName().get(hostEntity.getHostName());
for (ClusterEntity clusterEntity : hostEntity.getClusterEntities()) {
clusterHostsMap1Temp.get(clusterEntity.getClusterName()).add(host);
cSet.add(clustersByName.get(clusterEntity.getClusterName()));
}
}
hostClustersMap = hostClustersMapTemp;
clusterHostsMap1 = clusterHostsMap1Temp;
// init host configs
for (Long hostId : hostsById.keySet()) {
try {
m_agentConfigsHolder.get().initializeDataIfNeeded(hostId, true);
} catch (AmbariException e) {
LOG.error("Agent configs initialization was failed", e);
}
}
}
如上图、
例如clusterEntity.getClusterName()等API即为从数据库中查询对应sql(基于JPA框架,Guice注解方式)
↓
Dao层->Entity层->DB
↓
3.1.4.10、HostDAO.findAll()
@RequiresSession
public List<HostEntity> findAll() {
TypedQuery<HostEntity> query = entityManagerProvider.get().createQuery("SELECT host FROM HostEntity host", HostEntity.class);
try {
return query.getResultList();
} catch (NoResultException e) {
return Collections.emptyList();
}
}
至此,就将host列表查出来了,会进行一个page分页,返回前端
具体的调用流程比较复杂,建议看目录,我已经都调好格式了