refactor(all): 初始化项目
迁移项目到独立的 service 进行集中开发 包含以下组件的查询 API 服务 flink hudi database(info) pulsar yarn 包含前端服务和 UI web 包含公共代码 configuration
This commit is contained in:
@@ -0,0 +1,50 @@
|
||||
package com.lanyuanxiaoyao.service.yarn;
|
||||
|
||||
import com.lanyuanxiaoyao.service.yarn.configuration.YarnConfiguration;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.boot.ApplicationArguments;
|
||||
import org.springframework.boot.ApplicationRunner;
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
import org.springframework.boot.autoconfigure.gson.GsonAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
|
||||
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
||||
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
|
||||
import org.springframework.context.annotation.ComponentScan;
|
||||
import org.springframework.context.annotation.ComponentScans;
|
||||
import org.springframework.retry.annotation.EnableRetry;
|
||||
import org.springframework.scheduling.annotation.EnableScheduling;
|
||||
|
||||
/**
|
||||
* 启动类
|
||||
*
|
||||
* @author lanyuanxiaoyao
|
||||
* @date 2023-04-17
|
||||
*/
|
||||
@EnableDiscoveryClient
|
||||
@SpringBootApplication(exclude = {GsonAutoConfiguration.class, DataSourceAutoConfiguration.class})
|
||||
@ComponentScans({
|
||||
@ComponentScan("com.lanyuanxiaoyao.service")
|
||||
})
|
||||
@EnableConfigurationProperties
|
||||
@EnableRetry
|
||||
@EnableScheduling
|
||||
public class YarnQueryApplication implements ApplicationRunner {
|
||||
private static final Logger logger = LoggerFactory.getLogger(YarnQueryApplication.class);
|
||||
|
||||
public YarnQueryApplication(YarnConfiguration yarnConfiguration) {
|
||||
this.yarnConfiguration = yarnConfiguration;
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
SpringApplication.run(YarnQueryApplication.class, args);
|
||||
}
|
||||
|
||||
private final YarnConfiguration yarnConfiguration;
|
||||
|
||||
@Override
|
||||
public void run(ApplicationArguments args) throws Exception {
|
||||
logger.info("Yarn configuration: {}", yarnConfiguration);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
package com.lanyuanxiaoyao.service.yarn.configuration;
|
||||
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
/**
|
||||
* Yarn 配置
|
||||
*
|
||||
* @author lanyuanxiaoyao
|
||||
* @date 2023-04-23
|
||||
*/
|
||||
@Component
|
||||
@ConfigurationProperties("yarn")
|
||||
public class YarnConfiguration {
|
||||
private String webUrl;
|
||||
|
||||
public String getWebUrl() {
|
||||
return webUrl;
|
||||
}
|
||||
|
||||
public void setWebUrl(String webUrl) {
|
||||
this.webUrl = webUrl;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "YarnConfiguration{" +
|
||||
"webUrl='" + webUrl + '\'' +
|
||||
'}';
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
package com.lanyuanxiaoyao.service.yarn.controller;
|
||||
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
import com.lanyuanxiaoyao.service.configuration.entity.yarn.YarnRootQueue;
|
||||
import com.lanyuanxiaoyao.service.yarn.service.ClusterService;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
/**
|
||||
* Cluster
|
||||
*
|
||||
* @author lanyuanxiaoyao
|
||||
* @date 2023-04-23
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("cluster")
|
||||
public class ClusterController {
|
||||
private static final Logger logger = LoggerFactory.getLogger(ClusterController.class);
|
||||
|
||||
private final ClusterService clusterService;
|
||||
|
||||
public ClusterController(ClusterService clusterService) {
|
||||
this.clusterService = clusterService;
|
||||
}
|
||||
|
||||
@GetMapping("info")
|
||||
public YarnRootQueue info() throws JsonProcessingException {
|
||||
return clusterService.info();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
package com.lanyuanxiaoyao.service.yarn.controller;
|
||||
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
import com.lanyuanxiaoyao.service.configuration.entity.yarn.YarnApplication;
|
||||
import com.lanyuanxiaoyao.service.yarn.service.JobService;
|
||||
import org.eclipse.collections.api.list.ImmutableList;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Qualifier;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
/**
|
||||
* Job
|
||||
*
|
||||
* @author lanyuanxiaoyao
|
||||
* @date 2023-04-23
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("job")
|
||||
public class JobController {
|
||||
private static final Logger logger = LoggerFactory.getLogger(JobController.class);
|
||||
|
||||
private final JobService jobService;
|
||||
|
||||
public JobController(@Qualifier("JobService") JobService jobService) {
|
||||
this.jobService = jobService;
|
||||
}
|
||||
|
||||
@GetMapping("list")
|
||||
public ImmutableList<YarnApplication> list() throws JsonProcessingException {
|
||||
return jobService.list();
|
||||
}
|
||||
|
||||
@GetMapping("list_equals")
|
||||
public ImmutableList<YarnApplication> listEquals(@RequestParam("name") String name) throws JsonProcessingException {
|
||||
return jobService.listEquals(name);
|
||||
}
|
||||
|
||||
@GetMapping("list_like")
|
||||
public ImmutableList<YarnApplication> listLike(@RequestParam("text") String text) throws JsonProcessingException {
|
||||
return jobService.listLike(text);
|
||||
}
|
||||
|
||||
@GetMapping("kill")
|
||||
public void kill(@RequestParam("application_id") String applicationId) {
|
||||
jobService.kill(applicationId);
|
||||
}
|
||||
|
||||
@GetMapping("detail")
|
||||
public YarnApplication detail(@RequestParam("application_id") String applicationId) throws Exception {
|
||||
return jobService.detail(applicationId);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
package com.lanyuanxiaoyao.service.yarn.controller;
|
||||
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
import com.lanyuanxiaoyao.service.configuration.entity.yarn.YarnQueue;
|
||||
import com.lanyuanxiaoyao.service.yarn.service.QueueService;
|
||||
import org.eclipse.collections.api.list.ImmutableList;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Qualifier;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
/**
|
||||
* Queue
|
||||
*
|
||||
* @author lanyuanxiaoyao
|
||||
* @date 2023-04-23
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("queue")
|
||||
public class QueueController {
|
||||
private static final Logger logger = LoggerFactory.getLogger(QueueController.class);
|
||||
|
||||
private final QueueService queueService;
|
||||
|
||||
public QueueController(@Qualifier("QueueService") QueueService queueService) {
|
||||
this.queueService = queueService;
|
||||
}
|
||||
|
||||
@GetMapping("list")
|
||||
public ImmutableList<YarnQueue> list() throws JsonProcessingException {
|
||||
return queueService.list();
|
||||
}
|
||||
|
||||
@GetMapping("detail")
|
||||
public YarnQueue detail(@RequestParam("name") String name) throws Exception {
|
||||
return queueService.detail(name);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
package com.lanyuanxiaoyao.service.yarn.response;
|
||||
|
||||
import com.lanyuanxiaoyao.service.configuration.entity.yarn.YarnApplication;
|
||||
|
||||
/**
|
||||
* 接收类
|
||||
*
|
||||
* @author lanyuanxiaoyao
|
||||
* @date 2023-04-23
|
||||
*/
|
||||
public final class ApplicationDetailResponse {
|
||||
private YarnApplication app;
|
||||
|
||||
public YarnApplication getApp() {
|
||||
return app;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "ApplicationDetailResponse{" +
|
||||
"app=" + app +
|
||||
'}';
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
package com.lanyuanxiaoyao.service.yarn.response;
|
||||
|
||||
import com.lanyuanxiaoyao.service.configuration.entity.yarn.YarnApplication;
|
||||
import org.eclipse.collections.api.list.ImmutableList;
|
||||
|
||||
/**
|
||||
* 接收类
|
||||
*
|
||||
* @author lanyuanxiaoyao
|
||||
* @date 2023-04-23
|
||||
*/
|
||||
public final class ApplicationsListResponse {
|
||||
private Apps apps;
|
||||
|
||||
public Apps getApps() {
|
||||
return apps;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "ApplicationsResponse{" +
|
||||
"apps=" + apps +
|
||||
'}';
|
||||
}
|
||||
|
||||
public static final class Apps {
|
||||
private ImmutableList<YarnApplication> app;
|
||||
|
||||
public ImmutableList<YarnApplication> getApp() {
|
||||
return app;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Apps{" +
|
||||
"app=" + app +
|
||||
'}';
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
package com.lanyuanxiaoyao.service.yarn.response;
|
||||
|
||||
import com.lanyuanxiaoyao.service.configuration.entity.yarn.YarnRootQueue;
|
||||
|
||||
/**
|
||||
* 队列
|
||||
*
|
||||
* @author lanyuanxiaoyao
|
||||
* @date 2023-04-23
|
||||
*/
|
||||
public final class ClusterInfoResponse {
|
||||
private Scheduler scheduler;
|
||||
|
||||
public Scheduler getScheduler() {
|
||||
return scheduler;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "QueueListResponse{" +
|
||||
"scheduler=" + scheduler +
|
||||
'}';
|
||||
}
|
||||
|
||||
public static final class Scheduler {
|
||||
private YarnRootQueue schedulerInfo;
|
||||
|
||||
public YarnRootQueue getSchedulerInfo() {
|
||||
return schedulerInfo;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Scheduler{" +
|
||||
"schedulerInfo=" + schedulerInfo +
|
||||
'}';
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,70 @@
|
||||
package com.lanyuanxiaoyao.service.yarn.response;
|
||||
|
||||
import com.lanyuanxiaoyao.service.configuration.entity.yarn.YarnQueue;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 队列
|
||||
*
|
||||
* @author lanyuanxiaoyao
|
||||
* @date 2023-04-23
|
||||
*/
|
||||
public final class QueueListResponse {
|
||||
private Scheduler scheduler;
|
||||
|
||||
public Scheduler getScheduler() {
|
||||
return scheduler;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "QueueListResponse{" +
|
||||
"scheduler=" + scheduler +
|
||||
'}';
|
||||
}
|
||||
|
||||
public static final class Scheduler {
|
||||
private RootQueue schedulerInfo;
|
||||
|
||||
public RootQueue getSchedulerInfo() {
|
||||
return schedulerInfo;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Scheduler{" +
|
||||
"schedulerInfo=" + schedulerInfo +
|
||||
'}';
|
||||
}
|
||||
}
|
||||
|
||||
public static final class RootQueue {
|
||||
private Queues queues;
|
||||
|
||||
public Queues getQueues() {
|
||||
return queues;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "RootQueue{" +
|
||||
"queues=" + queues +
|
||||
'}';
|
||||
}
|
||||
}
|
||||
|
||||
public static final class Queues {
|
||||
private List<YarnQueue> queue;
|
||||
|
||||
public List<YarnQueue> getQueue() {
|
||||
return queue;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Queues{" +
|
||||
"queue=" + queue +
|
||||
'}';
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
package com.lanyuanxiaoyao.service.yarn.service;
|
||||
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
import com.lanyuanxiaoyao.service.configuration.entity.yarn.YarnRootQueue;
|
||||
|
||||
/**
|
||||
* Cluster
|
||||
*
|
||||
* @author lanyuanxiaoyao
|
||||
* @date 2023-04-23
|
||||
*/
|
||||
public interface ClusterService {
|
||||
YarnRootQueue info() throws JsonProcessingException;
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
package com.lanyuanxiaoyao.service.yarn.service;
|
||||
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
import com.lanyuanxiaoyao.service.configuration.entity.yarn.YarnApplication;
|
||||
import org.eclipse.collections.api.list.ImmutableList;
|
||||
|
||||
/**
|
||||
* Job
|
||||
*
|
||||
* @author lanyuanxiaoyao
|
||||
* @date 2023-04-23
|
||||
*/
|
||||
public interface JobService {
|
||||
ImmutableList<YarnApplication> list() throws JsonProcessingException;
|
||||
|
||||
ImmutableList<YarnApplication> listEquals(String name) throws JsonProcessingException;
|
||||
|
||||
ImmutableList<YarnApplication> listLike(String text) throws JsonProcessingException;
|
||||
|
||||
void kill(String applicationId);
|
||||
|
||||
YarnApplication detail(String applicationId) throws Exception;
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
package com.lanyuanxiaoyao.service.yarn.service;
|
||||
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
import com.lanyuanxiaoyao.service.configuration.entity.yarn.YarnQueue;
|
||||
import org.eclipse.collections.api.list.ImmutableList;
|
||||
|
||||
/**
|
||||
* Queue
|
||||
*
|
||||
* @author lanyuanxiaoyao
|
||||
* @date 2023-04-23
|
||||
*/
|
||||
public interface QueueService {
|
||||
ImmutableList<YarnQueue> list() throws JsonProcessingException;
|
||||
|
||||
YarnQueue detail(String name) throws Exception;
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
package com.lanyuanxiaoyao.service.yarn.service.impl;
|
||||
|
||||
import cn.hutool.core.util.URLUtil;
|
||||
import cn.hutool.http.HttpUtil;
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.lanyuanxiaoyao.service.configuration.entity.yarn.YarnRootQueue;
|
||||
import com.lanyuanxiaoyao.service.yarn.configuration.YarnConfiguration;
|
||||
import com.lanyuanxiaoyao.service.yarn.response.ClusterInfoResponse;
|
||||
import com.lanyuanxiaoyao.service.yarn.service.ClusterService;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.cache.annotation.CacheConfig;
|
||||
import org.springframework.cache.annotation.Cacheable;
|
||||
import org.springframework.retry.annotation.Retryable;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
/**
|
||||
* Cluster
|
||||
*
|
||||
* @author lanyuanxiaoyao
|
||||
* @date 2023-04-23
|
||||
*/
|
||||
@Service
|
||||
@CacheConfig(cacheManager = "normal-cache")
|
||||
public class ClusterServiceImpl implements ClusterService {
|
||||
private static final Logger logger = LoggerFactory.getLogger(ClusterServiceImpl.class);
|
||||
|
||||
private final ObjectMapper mapper;
|
||||
private final YarnConfiguration yarnConfiguration;
|
||||
|
||||
public ClusterServiceImpl(ObjectMapper mapper, YarnConfiguration yarnConfiguration) {
|
||||
this.mapper = mapper;
|
||||
this.yarnConfiguration = yarnConfiguration;
|
||||
}
|
||||
|
||||
@Cacheable(value = "cluster-info", sync = true)
|
||||
@Retryable(Throwable.class)
|
||||
@Override
|
||||
public YarnRootQueue info() throws JsonProcessingException {
|
||||
String queryUrl = URLUtil.completeUrl(yarnConfiguration.getWebUrl(), "/ws/v1/cluster/scheduler");
|
||||
String body = HttpUtil.createGet(queryUrl).setMaxRedirectCount(10).execute().body();
|
||||
return mapper.readValue(body, ClusterInfoResponse.class).getScheduler().getSchedulerInfo();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,72 @@
|
||||
package com.lanyuanxiaoyao.service.yarn.service.impl;
|
||||
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import cn.hutool.core.util.URLUtil;
|
||||
import cn.hutool.http.HttpUtil;
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.lanyuanxiaoyao.service.configuration.entity.yarn.YarnApplication;
|
||||
import com.lanyuanxiaoyao.service.yarn.configuration.YarnConfiguration;
|
||||
import com.lanyuanxiaoyao.service.yarn.response.ApplicationsListResponse;
|
||||
import com.lanyuanxiaoyao.service.yarn.service.JobService;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
import org.eclipse.collections.api.factory.Lists;
|
||||
import org.eclipse.collections.api.list.ImmutableList;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.scheduling.annotation.Scheduled;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
/**
|
||||
* Job
|
||||
*
|
||||
* @author lanyuanxiaoyao
|
||||
* @date 2023-04-23
|
||||
*/
|
||||
@Service("JobAutoRefreshService")
|
||||
public class JobAutoRefreshServiceImpl implements JobService {
|
||||
private static final Logger logger = LoggerFactory.getLogger(JobAutoRefreshServiceImpl.class);
|
||||
|
||||
private final ObjectMapper mapper;
|
||||
private final YarnConfiguration yarnConfiguration;
|
||||
|
||||
public JobAutoRefreshServiceImpl(ObjectMapper mapper, YarnConfiguration yarnConfiguration) {
|
||||
this.mapper = mapper;
|
||||
this.yarnConfiguration = yarnConfiguration;
|
||||
}
|
||||
|
||||
private static final AtomicReference<ImmutableList<YarnApplication>> CACHE = new AtomicReference<>(Lists.immutable.empty());
|
||||
|
||||
@Scheduled(fixedRate = 50000)
|
||||
public void refresh() throws JsonProcessingException {
|
||||
String queryUrl = URLUtil.completeUrl(yarnConfiguration.getWebUrl(), "/ws/v1/cluster/apps");
|
||||
String body = HttpUtil.createGet(queryUrl).setMaxRedirectCount(10).execute().body();
|
||||
ImmutableList<YarnApplication> apps = mapper.readValue(body, ApplicationsListResponse.class).getApps().getApp();
|
||||
CACHE.set(apps);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ImmutableList<YarnApplication> list() {
|
||||
return CACHE.get();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ImmutableList<YarnApplication> listEquals(String name) {
|
||||
return list().select(app -> StrUtil.equals(app.getName(), name));
|
||||
}
|
||||
|
||||
@Override
|
||||
public ImmutableList<YarnApplication> listLike(String name) {
|
||||
return list().select(app -> StrUtil.contains(app.getName(), name));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void kill(String applicationId) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public YarnApplication detail(String applicationId) throws Exception {
|
||||
return list().select(app -> StrUtil.equals(app.getId(), applicationId))
|
||||
.getFirstOptional().orElseThrow(() -> new Exception("cannot found " + applicationId));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,75 @@
|
||||
package com.lanyuanxiaoyao.service.yarn.service.impl;
|
||||
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import cn.hutool.core.util.URLUtil;
|
||||
import cn.hutool.http.HttpUtil;
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.lanyuanxiaoyao.service.configuration.entity.yarn.YarnApplication;
|
||||
import com.lanyuanxiaoyao.service.yarn.configuration.YarnConfiguration;
|
||||
import com.lanyuanxiaoyao.service.yarn.response.ApplicationDetailResponse;
|
||||
import com.lanyuanxiaoyao.service.yarn.response.ApplicationsListResponse;
|
||||
import com.lanyuanxiaoyao.service.yarn.service.JobService;
|
||||
import org.eclipse.collections.api.list.ImmutableList;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.cache.annotation.CacheConfig;
|
||||
import org.springframework.cache.annotation.Cacheable;
|
||||
import org.springframework.retry.annotation.Retryable;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
/**
|
||||
* Job
|
||||
*
|
||||
* @author lanyuanxiaoyao
|
||||
* @date 2023-04-23
|
||||
*/
|
||||
@CacheConfig(cacheManager = "normal-cache")
|
||||
@Service("JobService")
|
||||
public class JobServiceImpl implements JobService {
|
||||
private static final Logger logger = LoggerFactory.getLogger(JobServiceImpl.class);
|
||||
|
||||
private final ObjectMapper mapper;
|
||||
private final YarnConfiguration yarnConfiguration;
|
||||
|
||||
public JobServiceImpl(ObjectMapper mapper, YarnConfiguration yarnConfiguration) {
|
||||
this.mapper = mapper;
|
||||
this.yarnConfiguration = yarnConfiguration;
|
||||
}
|
||||
|
||||
@Cacheable(value = "job-list", sync = true)
|
||||
@Retryable(Throwable.class)
|
||||
@Override
|
||||
public ImmutableList<YarnApplication> list() throws JsonProcessingException {
|
||||
String queryUrl = URLUtil.completeUrl(yarnConfiguration.getWebUrl(), "/ws/v1/cluster/apps");
|
||||
String body = HttpUtil.createGet(queryUrl).setMaxRedirectCount(10).execute().body();
|
||||
return mapper.readValue(body, ApplicationsListResponse.class).getApps().getApp();
|
||||
}
|
||||
|
||||
@Cacheable(value = "job-list", sync = true, key = "#{methodName+name}")
|
||||
@Retryable(Throwable.class)
|
||||
@Override
|
||||
public ImmutableList<YarnApplication> listEquals(String name) throws JsonProcessingException {
|
||||
return list().select(app -> StrUtil.equals(app.getName(), name));
|
||||
}
|
||||
|
||||
@Cacheable(value = "job-list", sync = true, key = "#{methodName+name}")
|
||||
@Retryable(Throwable.class)
|
||||
@Override
|
||||
public ImmutableList<YarnApplication> listLike(String name) throws JsonProcessingException {
|
||||
return list().select(app -> StrUtil.contains(app.getName(), name));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void kill(String applicationId) {
|
||||
}
|
||||
|
||||
@Cacheable(value = "job-detail", sync = true, key = "#applicationId")
|
||||
@Retryable(Throwable.class)
|
||||
@Override
|
||||
public YarnApplication detail(String applicationId) throws JsonProcessingException {
|
||||
String queryUrl = URLUtil.completeUrl(yarnConfiguration.getWebUrl(), "/ws/v1/cluster/apps/" + applicationId);
|
||||
String body = HttpUtil.createGet(queryUrl).setMaxRedirectCount(10).execute().body();
|
||||
return mapper.readValue(body, ApplicationDetailResponse.class).getApp();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
package com.lanyuanxiaoyao.service.yarn.service.impl;
|
||||
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import cn.hutool.core.util.URLUtil;
|
||||
import cn.hutool.http.HttpUtil;
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.lanyuanxiaoyao.service.configuration.entity.yarn.YarnQueue;
|
||||
import com.lanyuanxiaoyao.service.yarn.configuration.YarnConfiguration;
|
||||
import com.lanyuanxiaoyao.service.yarn.response.QueueListResponse;
|
||||
import com.lanyuanxiaoyao.service.yarn.service.QueueService;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
import org.eclipse.collections.api.factory.Lists;
|
||||
import org.eclipse.collections.api.list.ImmutableList;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.scheduling.annotation.Scheduled;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
/**
|
||||
* Queue
|
||||
*
|
||||
* @author lanyuanxiaoyao
|
||||
* @date 2023-04-23
|
||||
*/
|
||||
@Service("QueueAutoRefreshService")
|
||||
public class QueueAutoRefreshServiceImpl implements QueueService {
|
||||
private static final Logger logger = LoggerFactory.getLogger(QueueAutoRefreshServiceImpl.class);
|
||||
|
||||
private final ObjectMapper mapper;
|
||||
private final YarnConfiguration yarnConfiguration;
|
||||
|
||||
public QueueAutoRefreshServiceImpl(ObjectMapper mapper, YarnConfiguration yarnConfiguration) {
|
||||
this.mapper = mapper;
|
||||
this.yarnConfiguration = yarnConfiguration;
|
||||
}
|
||||
|
||||
private static final AtomicReference<ImmutableList<YarnQueue>> CACHE = new AtomicReference<>(Lists.immutable.empty());
|
||||
|
||||
@Scheduled(fixedRate = 50000)
|
||||
public void refresh() throws JsonProcessingException {
|
||||
String queryUrl = URLUtil.completeUrl(yarnConfiguration.getWebUrl(), "/ws/v1/cluster/scheduler");
|
||||
String body = HttpUtil.createGet(queryUrl).setMaxRedirectCount(10).execute().body();
|
||||
QueueListResponse response = mapper.readValue(body, QueueListResponse.class);
|
||||
ImmutableList<YarnQueue> queues = Lists.immutable.ofAll(response.getScheduler().getSchedulerInfo().getQueues().getQueue());
|
||||
CACHE.set(queues);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ImmutableList<YarnQueue> list() throws JsonProcessingException {
|
||||
return CACHE.get();
|
||||
}
|
||||
|
||||
@Override
|
||||
public YarnQueue detail(String name) throws Exception {
|
||||
return list()
|
||||
.select(q -> StrUtil.equals(q.getQueueName(), name))
|
||||
.getFirstOptional()
|
||||
.orElseThrow(() -> new Exception("cannot found " + name));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
package com.lanyuanxiaoyao.service.yarn.service.impl;
|
||||
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import cn.hutool.core.util.URLUtil;
|
||||
import cn.hutool.http.HttpUtil;
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.lanyuanxiaoyao.service.configuration.entity.yarn.YarnQueue;
|
||||
import com.lanyuanxiaoyao.service.yarn.configuration.YarnConfiguration;
|
||||
import com.lanyuanxiaoyao.service.yarn.response.QueueListResponse;
|
||||
import com.lanyuanxiaoyao.service.yarn.service.QueueService;
|
||||
import org.eclipse.collections.api.factory.Lists;
|
||||
import org.eclipse.collections.api.list.ImmutableList;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.cache.annotation.CacheConfig;
|
||||
import org.springframework.cache.annotation.Cacheable;
|
||||
import org.springframework.retry.annotation.Retryable;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
/**
|
||||
* Queue
|
||||
*
|
||||
* @author lanyuanxiaoyao
|
||||
* @date 2023-04-23
|
||||
*/
|
||||
@CacheConfig(cacheManager = "normal-cache")
|
||||
@Service("QueueService")
|
||||
public class QueueServiceImpl implements QueueService {
|
||||
private static final Logger logger = LoggerFactory.getLogger(QueueServiceImpl.class);
|
||||
|
||||
private final ObjectMapper mapper;
|
||||
private final YarnConfiguration yarnConfiguration;
|
||||
|
||||
public QueueServiceImpl(ObjectMapper mapper, YarnConfiguration yarnConfiguration) {
|
||||
this.mapper = mapper;
|
||||
this.yarnConfiguration = yarnConfiguration;
|
||||
}
|
||||
|
||||
@Cacheable(value = "queue-list", sync = true)
|
||||
@Retryable(Throwable.class)
|
||||
@Override
|
||||
public ImmutableList<YarnQueue> list() throws JsonProcessingException {
|
||||
String queryUrl = URLUtil.completeUrl(yarnConfiguration.getWebUrl(), "/ws/v1/cluster/scheduler");
|
||||
String body = HttpUtil.createGet(queryUrl).setMaxRedirectCount(10).execute().body();
|
||||
QueueListResponse response = mapper.readValue(body, QueueListResponse.class);
|
||||
return Lists.immutable.ofAll(response.getScheduler().getSchedulerInfo().getQueues().getQueue());
|
||||
}
|
||||
|
||||
@Cacheable(value = "queue-detail", sync = true, key = "#name")
|
||||
@Retryable(Throwable.class)
|
||||
@Override
|
||||
public YarnQueue detail(String name) throws Exception {
|
||||
return list()
|
||||
.select(q -> StrUtil.equals(q.getQueueName(), name))
|
||||
.getFirstOptional()
|
||||
.orElseThrow(() -> new Exception("cannot found " + name));
|
||||
}
|
||||
}
|
||||
30
service-yarn-query/src/main/resources/application.yml
Normal file
30
service-yarn-query/src/main/resources/application.yml
Normal file
@@ -0,0 +1,30 @@
|
||||
server:
|
||||
port: 0
|
||||
spring:
|
||||
application:
|
||||
name: service-yarn-query
|
||||
main:
|
||||
banner-mode: off
|
||||
jackson:
|
||||
serialization:
|
||||
fail-on-empty-beans: false
|
||||
management:
|
||||
endpoints:
|
||||
web:
|
||||
exposure:
|
||||
include: "*"
|
||||
endpoint:
|
||||
prometheus:
|
||||
enabled: true
|
||||
metrics:
|
||||
export:
|
||||
jmx:
|
||||
enabled: false
|
||||
eureka:
|
||||
instance:
|
||||
hostname: localhost
|
||||
prefer-ip-address: true
|
||||
instance-id: ${spring.application.name}-${eureka.instance.hostname}-${random.uuid}-${datetime}
|
||||
client:
|
||||
service-url:
|
||||
defaultZone: http://localhost:35670/eureka/
|
||||
50
service-yarn-query/src/main/resources/logback-spring.xml
Normal file
50
service-yarn-query/src/main/resources/logback-spring.xml
Normal file
@@ -0,0 +1,50 @@
|
||||
<configuration>
|
||||
<conversionRule conversionWord="clr" converterClass="org.springframework.boot.logging.logback.ColorConverter" />
|
||||
<conversionRule conversionWord="wex" converterClass="org.springframework.boot.logging.logback.WhitespaceThrowableProxyConverter" />
|
||||
<conversionRule conversionWord="wEx" converterClass="org.springframework.boot.logging.logback.ExtendedWhitespaceThrowableProxyConverter" />
|
||||
|
||||
<springProperty scope="context" name="LOKI_PUSH_URL" source="loki.url"/>
|
||||
<springProperty scope="context" name="LOGGING_PARENT" source="logging.parent"/>
|
||||
<springProperty scope="context" name="APP_NAME" source="spring.application.name"/>
|
||||
|
||||
<appender name="Loki" class="com.github.loki4j.logback.Loki4jAppender">
|
||||
<metricsEnabled>true</metricsEnabled>
|
||||
<http class="com.github.loki4j.logback.ApacheHttpSender">
|
||||
<url>${LOKI_PUSH_URL:-http://localhost/loki/api/v1/push}</url>
|
||||
</http>
|
||||
<format>
|
||||
<label>
|
||||
<pattern>app=${APP_NAME:- },host=${HOSTNAME},level=%level</pattern>
|
||||
</label>
|
||||
<message>
|
||||
<pattern>${FILE_LOG_PATTERN:-%d{${LOG_DATEFORMAT_PATTERN:-yyyy-MM-dd HH:mm:ss.SSS}} [${HOSTNAME}] ${LOG_LEVEL_PATTERN:-%5p} ${PID:- } --- [%t] %-40.40logger{39} : %m%n${LOG_EXCEPTION_CONVERSION_WORD:-%wEx}}</pattern>
|
||||
</message>
|
||||
<sortByTime>true</sortByTime>
|
||||
</format>
|
||||
</appender>
|
||||
|
||||
<appender name="Console" class="ch.qos.logback.core.ConsoleAppender">
|
||||
<encoder>
|
||||
<pattern>${CONSOLE_LOG_PATTERN:-%clr(%d{${LOG_DATEFORMAT_PATTERN:-yyyy-MM-dd HH:mm:ss.SSS}}){faint} %clr(${LOG_LEVEL_PATTERN:-%5p}) %clr(${PID:- }){magenta} %clr(---){faint} %clr([%15.15t]){faint} %clr(%-40.40logger{39}){cyan} %clr(:){faint} %m%n${LOG_EXCEPTION_CONVERSION_WORD:-%wEx}}</pattern>
|
||||
</encoder>
|
||||
</appender>
|
||||
|
||||
<appender name="RollingFile" class="ch.qos.logback.core.rolling.RollingFileAppender">
|
||||
<file>${LOGGING_PARENT:-.}/${APP_NAME:-run}.log</file>
|
||||
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
|
||||
<fileNamePattern>${LOGGING_PARENT:-.}/archive/${APP_NAME:-run}-%d{yyyy-MM-dd}.gz</fileNamePattern>
|
||||
<MaxHistory>7</MaxHistory>
|
||||
</rollingPolicy>
|
||||
<encoder>
|
||||
<pattern>${FILE_LOG_PATTERN:-%d{${LOG_DATEFORMAT_PATTERN:-yyyy-MM-dd HH:mm:ss.SSS}} [${HOSTNAME}] ${LOG_LEVEL_PATTERN:-%5p} ${PID:- } --- [%t] %-40.40logger{39} : %m%n${LOG_EXCEPTION_CONVERSION_WORD:-%wEx}}</pattern>
|
||||
</encoder>
|
||||
</appender>
|
||||
|
||||
<logger name="com.zaxxer.hikari" level="ERROR"/>
|
||||
|
||||
<root level="INFO">
|
||||
<appender-ref ref="Loki"/>
|
||||
<appender-ref ref="Console"/>
|
||||
<appender-ref ref="RollingFile"/>
|
||||
</root>
|
||||
</configuration>
|
||||
Reference in New Issue
Block a user