paramValues, long readTimeoutMs) {
- return null;
- }
-
- private String buildUrl(String path) {
- return serverListManager.getCurrentServerAddr() + path;
- }
-
-}
diff --git a/dynamic-threadpool-spring-boot-starter/src/main/java/com/github/dynamic/threadpool/starter/toolkit/thread/AbstractBuildThreadPoolTemplate.java b/dynamic-threadpool-spring-boot-starter/src/main/java/com/github/dynamic/threadpool/starter/toolkit/thread/AbstractBuildThreadPoolTemplate.java
deleted file mode 100644
index 38a775ff..00000000
--- a/dynamic-threadpool-spring-boot-starter/src/main/java/com/github/dynamic/threadpool/starter/toolkit/thread/AbstractBuildThreadPoolTemplate.java
+++ /dev/null
@@ -1,174 +0,0 @@
-package com.github.dynamic.threadpool.starter.toolkit.thread;
-
-import com.github.dynamic.threadpool.common.toolkit.Assert;
-import com.github.dynamic.threadpool.starter.alarm.ThreadPoolAlarm;
-import lombok.Data;
-import lombok.experimental.Accessors;
-import lombok.extern.slf4j.Slf4j;
-
-import java.util.concurrent.*;
-import java.util.concurrent.locks.AbstractQueuedSynchronizer;
-
-/**
- * Abstract build threadPool template.
- *
- * @author chen.ma
- * @date 2021/7/5 21:45
- */
-@Slf4j
-public class AbstractBuildThreadPoolTemplate {
-
- /**
- * 线程池构建初始化参数
- *
- * 此处本身是模版设计方法, 但是考虑创建简洁性, 移除 abstract
- * 异常参考 {@link AbstractQueuedSynchronizer#tryAcquire}
- *
- * @return
- */
- protected static ThreadPoolInitParam initParam() {
- throw new UnsupportedOperationException();
- }
-
- /**
- * 构建线程池
- *
- * @return
- */
- public static ThreadPoolExecutor buildPool() {
- ThreadPoolInitParam initParam = initParam();
- return buildPool(initParam);
- }
-
- /**
- * 构建线程池
- *
- * @return
- */
- public static ThreadPoolExecutor buildPool(ThreadPoolInitParam initParam) {
- Assert.notNull(initParam);
- ThreadPoolExecutor executorService =
- new ThreadPoolExecutorTemplate(initParam.getCorePoolNum(),
- initParam.getMaxPoolNum(),
- initParam.getKeepAliveTime(),
- initParam.getTimeUnit(),
- initParam.getWorkQueue(),
- initParam.getThreadFactory(),
- initParam.rejectedExecutionHandler);
- return executorService;
- }
-
- /**
- * 构建快速执行线程池
- *
- * @return
- */
- public static ThreadPoolExecutor buildFastPool() {
- ThreadPoolInitParam initParam = initParam();
- return buildFastPool(initParam);
- }
-
- /**
- * 构建快速执行线程池
- *
- * @return
- */
- public static ThreadPoolExecutor buildFastPool(ThreadPoolInitParam initParam) {
- TaskQueue taskQueue = new TaskQueue(initParam.getCapacity());
- FastThreadPoolExecutor fastThreadPoolExecutor =
- new FastThreadPoolExecutor(initParam.getCorePoolNum(),
- initParam.getMaxPoolNum(),
- initParam.getKeepAliveTime(),
- initParam.getTimeUnit(),
- taskQueue,
- initParam.getThreadFactory(),
- initParam.rejectedExecutionHandler);
- taskQueue.setExecutor(fastThreadPoolExecutor);
- return fastThreadPoolExecutor;
- }
-
- /**
- * 构建自定义线程池
- *
- * @param initParam
- * @return
- */
- public static CustomThreadPoolExecutor buildCustomPool(ThreadPoolInitParam initParam) {
- Assert.notNull(initParam);
- CustomThreadPoolExecutor executorService =
- new CustomThreadPoolExecutor(initParam.getCorePoolNum(),
- initParam.getMaxPoolNum(),
- initParam.getKeepAliveTime(),
- initParam.getTimeUnit(),
- initParam.getWorkQueue(),
- initParam.getThreadPoolId(),
- initParam.getThreadFactory(),
- initParam.getThreadPoolAlarm(),
- initParam.getRejectedExecutionHandler());
- return executorService;
- }
-
- @Data
- @Accessors(chain = true)
- public static class ThreadPoolInitParam {
-
- /**
- * 核心线程数量
- */
- private Integer corePoolNum;
-
- /**
- * 最大线程数量
- */
- private Integer maxPoolNum;
-
- /**
- * 线程存活时间
- */
- private Long keepAliveTime;
-
- /**
- * 线程存活时间单位
- */
- private TimeUnit timeUnit;
-
- /**
- * 队列最大容量
- */
- private Integer capacity;
-
- /**
- * 阻塞队列
- */
- private BlockingQueue workQueue;
-
- /**
- * 线程池任务满时拒绝任务策略
- */
- private RejectedExecutionHandler rejectedExecutionHandler;
-
- /**
- * 创建线程工厂
- */
- private ThreadFactory threadFactory;
-
- /**
- * 线程 ID
- */
- private String threadPoolId;
-
- /**
- * 报警策略
- */
- private ThreadPoolAlarm threadPoolAlarm;
-
- public ThreadPoolInitParam(String threadNamePrefix, boolean isDaemon) {
- this.threadPoolId = threadNamePrefix;
- this.threadFactory = ThreadFactoryBuilder.builder()
- .prefix(threadNamePrefix)
- .daemon(isDaemon)
- .build();
- }
- }
-
-}
diff --git a/dynamic-threadpool-spring-boot-starter/src/main/java/com/github/dynamic/threadpool/starter/toolkit/thread/CustomThreadPoolExecutor.java b/dynamic-threadpool-spring-boot-starter/src/main/java/com/github/dynamic/threadpool/starter/toolkit/thread/CustomThreadPoolExecutor.java
deleted file mode 100644
index a770c361..00000000
--- a/dynamic-threadpool-spring-boot-starter/src/main/java/com/github/dynamic/threadpool/starter/toolkit/thread/CustomThreadPoolExecutor.java
+++ /dev/null
@@ -1,954 +0,0 @@
-package com.github.dynamic.threadpool.starter.toolkit.thread;
-
-import com.github.dynamic.threadpool.starter.alarm.ThreadPoolAlarm;
-import com.github.dynamic.threadpool.starter.alarm.ThreadPoolAlarmManage;
-import lombok.NoArgsConstructor;
-import lombok.NonNull;
-
-import java.security.AccessControlContext;
-import java.security.AccessController;
-import java.security.PrivilegedAction;
-import java.util.*;
-import java.util.concurrent.*;
-import java.util.concurrent.atomic.AtomicInteger;
-import java.util.concurrent.locks.AbstractQueuedSynchronizer;
-import java.util.concurrent.locks.Condition;
-import java.util.concurrent.locks.ReentrantLock;
-
-import static com.github.dynamic.threadpool.common.constant.Constants.MAP_INITIAL_CAPACITY;
-
-/**
- * Custom threadPool wrap.
- *
- * @author chen.ma
- * @date 2021/7/8 21:47
- */
-public final class CustomThreadPoolExecutor extends ThreadPoolExecutor {
-
- private final AtomicInteger rejectCount = new AtomicInteger();
- private final AtomicInteger ctl = new AtomicInteger(ctlOf(RUNNING, 0));
-
- private static final int COUNT_BITS = Integer.SIZE - 3;
- private static final int CAPACITY = (1 << COUNT_BITS) - 1;
-
- private static final int RUNNING = -1 << COUNT_BITS;
- private static final int SHUTDOWN = 0 << COUNT_BITS;
- private static final int STOP = 1 << COUNT_BITS;
- private static final int TIDYING = 2 << COUNT_BITS;
- private static final int TERMINATED = 3 << COUNT_BITS;
-
- private final BlockingQueue workQueue;
- private final ReentrantLock mainLock = new ReentrantLock();
- private final HashSet workers = new HashSet();
- private final Condition termination = mainLock.newCondition();
-
- private int largestPoolSize;
- private long completedTaskCount;
- private volatile long keepAliveTime;
- private volatile boolean allowCoreThreadTimeOut;
- private volatile int corePoolSize;
- private volatile int maximumPoolSize;
- private String threadPoolId;
-
- private final AccessControlContext acc;
- private volatile ThreadPoolAlarm threadPoolAlarm;
- private volatile ThreadFactory threadFactory;
- private volatile RejectedExecutionHandler handler;
-
- private static final RejectedExecutionHandler DEFAULT_HANDLER = new ThreadPoolExecutor.AbortPolicy();
- private static final RuntimePermission SHUTDOWN_PERM = new RuntimePermission("modifyThread");
-
- public CustomThreadPoolExecutor(int corePoolSize,
- int maximumPoolSize,
- long keepAliveTime,
- TimeUnit unit,
- @NonNull BlockingQueue workQueue,
- @NonNull String threadPoolId,
- @NonNull ThreadFactory threadFactory,
- @NonNull ThreadPoolAlarm threadPoolAlarm,
- @NonNull RejectedExecutionHandler handler) {
- super(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue, threadFactory, handler);
-
- if (corePoolSize < 0 ||
- maximumPoolSize <= 0 ||
- maximumPoolSize < corePoolSize ||
- keepAliveTime < 0) {
- throw new IllegalArgumentException();
- }
-
- this.corePoolSize = corePoolSize;
- this.maximumPoolSize = maximumPoolSize;
- this.workQueue = workQueue;
- this.threadPoolId = threadPoolId;
- this.keepAliveTime = unit.toNanos(keepAliveTime);
- this.threadFactory = threadFactory;
- this.handler = handler;
- this.threadPoolAlarm = threadPoolAlarm;
- this.acc = System.getSecurityManager() == null ? null : AccessController.getContext();
- }
-
- private static int runStateOf(int c) {
- return c & ~CAPACITY;
- }
-
- private static int workerCountOf(int c) {
- return c & CAPACITY;
- }
-
- private static int ctlOf(int rs, int wc) {
- return rs | wc;
- }
-
- private static boolean runStateLessThan(int c, int s) {
- return c < s;
- }
-
- private static boolean runStateAtLeast(int c, int s) {
- return c >= s;
- }
-
- private static boolean isRunning(int c) {
- return c < SHUTDOWN;
- }
-
- private boolean compareAndIncrementWorkerCount(int expect) {
- return ctl.compareAndSet(expect, expect + 1);
- }
-
- private boolean compareAndDecrementWorkerCount(int expect) {
- return ctl.compareAndSet(expect, expect - 1);
- }
-
- private void decrementWorkerCount() {
- do {
- } while (!compareAndDecrementWorkerCount(ctl.get()));
- }
-
- public Integer getRejectCount() {
- return rejectCount.get();
- }
-
- public ThreadPoolAlarm getThreadPoolAlarm() {
- return this.threadPoolAlarm;
- }
-
- public void setThreadPoolAlarm(ThreadPoolAlarm threadPoolAlarm) {
- this.threadPoolAlarm = threadPoolAlarm;
- }
-
- public String getThreadPoolId() {
- return this.threadPoolId;
- }
-
- private final class Worker
- extends AbstractQueuedSynchronizer
- implements Runnable {
-
- private static final long serialVersionUID = 6138294804551838833L;
-
- final Thread thread;
- Runnable firstTask;
- volatile long completedTasks;
-
- Worker(Runnable firstTask) {
- setState(-1);
- this.firstTask = firstTask;
- this.thread = getThreadFactory().newThread(this);
- }
-
- @Override
- public void run() {
- runWorker(this);
- }
-
- @Override
- protected boolean isHeldExclusively() {
- return getState() != 0;
- }
-
- @Override
- protected boolean tryAcquire(int unused) {
- if (compareAndSetState(0, 1)) {
- setExclusiveOwnerThread(Thread.currentThread());
- return true;
- }
- return false;
- }
-
- @Override
- protected boolean tryRelease(int unused) {
- setExclusiveOwnerThread(null);
- setState(0);
- return true;
- }
-
- public void lock() {
- acquire(1);
- }
-
- public boolean tryLock() {
- return tryAcquire(1);
- }
-
- public void unlock() {
- release(1);
- }
-
- public boolean isLocked() {
- return isHeldExclusively();
- }
-
- void interruptIfStarted() {
- Thread t;
- if (getState() >= 0 && (t = thread) != null && !t.isInterrupted()) {
- try {
- t.interrupt();
- } catch (SecurityException ignore) {
- }
- }
- }
- }
-
- private void advanceRunState(int targetState) {
- for (; ; ) {
- int c = ctl.get();
- if (runStateAtLeast(c, targetState) ||
- ctl.compareAndSet(c, ctlOf(targetState, workerCountOf(c)))) {
- break;
- }
- }
- }
-
- final void tryTerminate() {
- for (; ; ) {
- int c = ctl.get();
- if (isRunning(c)
- || runStateAtLeast(c, TIDYING)
- || (runStateOf(c) == SHUTDOWN && !workQueue.isEmpty())) {
- return;
- }
- if (workerCountOf(c) != 0) {
- interruptIdleWorkers(ONLY_ONE);
- return;
- }
-
- final ReentrantLock mainLock = this.mainLock;
- mainLock.lock();
- try {
- if (ctl.compareAndSet(c, ctlOf(TIDYING, 0))) {
- try {
- terminated();
- } finally {
- ctl.set(ctlOf(TERMINATED, 0));
- termination.signalAll();
- }
- return;
- }
- } finally {
- mainLock.unlock();
- }
- }
- }
-
- private void checkShutdownAccess() {
- SecurityManager security = System.getSecurityManager();
- if (security != null) {
- security.checkPermission(SHUTDOWN_PERM);
- final ReentrantLock mainLock = this.mainLock;
- mainLock.lock();
- try {
- for (Worker w : workers) {
- security.checkAccess(w.thread);
- }
- } finally {
- mainLock.unlock();
- }
- }
- }
-
- private void interruptWorkers() {
- final ReentrantLock mainLock = this.mainLock;
- mainLock.lock();
- try {
- for (Worker w : workers) {
- w.interruptIfStarted();
- }
- } finally {
- mainLock.unlock();
- }
- }
-
- private void interruptIdleWorkers(boolean onlyOne) {
- final ReentrantLock mainLock = this.mainLock;
- mainLock.lock();
- try {
- for (Worker w : workers) {
- Thread t = w.thread;
- if (!t.isInterrupted() && w.tryLock()) {
- try {
- t.interrupt();
- } catch (SecurityException ignore) {
- } finally {
- w.unlock();
- }
- }
- if (onlyOne) {
- break;
- }
- }
- } finally {
- mainLock.unlock();
- }
- }
-
- private void interruptIdleWorkers() {
- interruptIdleWorkers(false);
- }
-
- private static final boolean ONLY_ONE = true;
-
- final void reject(Runnable command) {
- rejectCount.incrementAndGet();
- ThreadPoolAlarmManage.checkPoolRejectAlarm(this);
- handler.rejectedExecution(command, this);
- }
-
- void onShutdown() {
- }
-
- final boolean isRunningOrShutdown(boolean shutdownOk) {
- int rs = runStateOf(ctl.get());
- return rs == RUNNING || (rs == SHUTDOWN && shutdownOk);
- }
-
- private List drainQueue() {
- BlockingQueue q = workQueue;
- ArrayList taskList = new ArrayList();
- q.drainTo(taskList);
- if (!q.isEmpty()) {
- for (Runnable r : q.toArray(new Runnable[0])) {
- if (q.remove(r)) {
- taskList.add(r);
- }
- }
- }
- return taskList;
- }
-
- private boolean addWorker(Runnable firstTask, boolean core) {
- retry:
- for (; ; ) {
- int c = ctl.get();
- int rs = runStateOf(c);
-
- // Check if queue empty only if necessary.
- if (rs >= SHUTDOWN && !(rs == SHUTDOWN && firstTask == null && !workQueue.isEmpty())) {
- return false;
- }
-
- for (; ; ) {
- int wc = workerCountOf(c);
- if (wc >= CAPACITY ||
- wc >= (core ? corePoolSize : maximumPoolSize)) {
- return false;
- }
- if (compareAndIncrementWorkerCount(c)) {
- break retry;
- }
- c = ctl.get();
- if (runStateOf(c) != rs) {
- continue retry;
- }
- }
- }
-
- ThreadPoolAlarmManage.checkPoolLivenessAlarm(core, this);
-
- boolean workerStarted = false;
- boolean workerAdded = false;
- Worker w = null;
- try {
- w = new Worker(firstTask);
- final Thread t = w.thread;
- if (t != null) {
- final ReentrantLock mainLock = this.mainLock;
- mainLock.lock();
- try {
- int rs = runStateOf(ctl.get());
-
- if (rs < SHUTDOWN || (rs == SHUTDOWN && firstTask == null)) {
- if (t.isAlive()) {
- throw new IllegalThreadStateException();
- }
- workers.add(w);
- int s = workers.size();
- if (s > largestPoolSize) {
- largestPoolSize = s;
- }
- workerAdded = true;
- }
- } finally {
- mainLock.unlock();
- }
- if (workerAdded) {
- t.start();
- workerStarted = true;
- }
- }
- } finally {
- if (!workerStarted) {
- addWorkerFailed(w);
- }
- }
- return workerStarted;
- }
-
- private void addWorkerFailed(Worker w) {
- final ReentrantLock mainLock = this.mainLock;
- mainLock.lock();
- try {
- if (w != null) {
- workers.remove(w);
- }
- decrementWorkerCount();
- tryTerminate();
- } finally {
- mainLock.unlock();
- }
- }
-
- private void processWorkerExit(Worker w, boolean completedAbruptly) {
- if (completedAbruptly) {
- decrementWorkerCount();
- }
-
- final ReentrantLock mainLock = this.mainLock;
- mainLock.lock();
- try {
- completedTaskCount += w.completedTasks;
- workers.remove(w);
- } finally {
- mainLock.unlock();
- }
-
- tryTerminate();
-
- int c = ctl.get();
- if (runStateLessThan(c, STOP)) {
- if (!completedAbruptly) {
- int min = allowCoreThreadTimeOut ? 0 : corePoolSize;
- if (min == 0 && !workQueue.isEmpty()) {
- min = 1;
- }
- if (workerCountOf(c) >= min) {
- return;
- }
- }
- addWorker(null, false);
- }
- }
-
- private Runnable getTask() {
- boolean timedOut = false;
-
- for (; ; ) {
- int c = ctl.get();
- int rs = runStateOf(c);
-
- if (rs >= SHUTDOWN && (rs >= STOP || workQueue.isEmpty())) {
- decrementWorkerCount();
- return null;
- }
-
- int wc = workerCountOf(c);
-
- boolean timed = allowCoreThreadTimeOut || wc > corePoolSize;
-
- if ((wc > maximumPoolSize || (timed && timedOut)) && (wc > 1 || workQueue.isEmpty())) {
- if (compareAndDecrementWorkerCount(c)) {
- return null;
- }
- continue;
- }
-
- try {
- Runnable r = timed ?
- workQueue.poll(keepAliveTime, TimeUnit.NANOSECONDS) :
- workQueue.take();
- if (r != null) {
- return r;
- }
- timedOut = true;
- } catch (InterruptedException retry) {
- timedOut = false;
- }
- }
- }
-
- final void runWorker(Worker w) {
- Thread wt = Thread.currentThread();
- Runnable task = w.firstTask;
- w.firstTask = null;
- w.unlock();
- boolean completedAbruptly = true;
- try {
- while (task != null || (task = getTask()) != null) {
- w.lock();
- if ((runStateAtLeast(ctl.get(), STOP)
- || (Thread.interrupted() && runStateAtLeast(ctl.get(), STOP)))
- && !wt.isInterrupted()) {
- wt.interrupt();
- }
- try {
- beforeExecute(wt, task);
- Throwable thrown = null;
- try {
- task.run();
- } catch (RuntimeException x) {
- thrown = x;
- throw x;
- } catch (Error x) {
- thrown = x;
- throw x;
- } catch (Throwable x) {
- thrown = x;
- throw new Error(x);
- } finally {
- afterExecute(task, thrown);
- }
- } finally {
- task = null;
- w.completedTasks++;
- w.unlock();
- }
- }
- completedAbruptly = false;
- } finally {
- processWorkerExit(w, completedAbruptly);
- }
- }
-
- @Override
- public void execute(@NonNull Runnable command) {
- int c = ctl.get();
- if (workerCountOf(c) < corePoolSize) {
- if (addWorker(command, true)) {
- return;
- }
- c = ctl.get();
- }
- if (isRunning(c) && workQueue.offer(command)) {
- ThreadPoolAlarmManage.checkPoolCapacityAlarm(this);
- int recheck = ctl.get();
- if (!isRunning(recheck) && remove(command)) {
- reject(command);
- } else if (workerCountOf(recheck) == 0) {
- addWorker(null, false);
- }
- } else if (!addWorker(command, false)) {
- reject(command);
- }
- }
-
- @Override
- public void shutdown() {
- final ReentrantLock mainLock = this.mainLock;
- mainLock.lock();
- try {
- checkShutdownAccess();
- advanceRunState(SHUTDOWN);
- interruptIdleWorkers();
- onShutdown();
- } finally {
- mainLock.unlock();
- }
- tryTerminate();
- }
-
- @Override
- public List shutdownNow() {
- List tasks;
- final ReentrantLock mainLock = this.mainLock;
- mainLock.lock();
- try {
- checkShutdownAccess();
- advanceRunState(STOP);
- interruptWorkers();
- tasks = drainQueue();
- } finally {
- mainLock.unlock();
- }
- tryTerminate();
- return tasks;
- }
-
- @Override
- public boolean isShutdown() {
- return !isRunning(ctl.get());
- }
-
- @Override
- public boolean isTerminating() {
- int c = ctl.get();
- return !isRunning(c) && runStateLessThan(c, TERMINATED);
- }
-
- @Override
- public boolean isTerminated() {
- return runStateAtLeast(ctl.get(), TERMINATED);
- }
-
- @Override
- public boolean awaitTermination(long timeout, TimeUnit unit)
- throws InterruptedException {
- long nanos = unit.toNanos(timeout);
- final ReentrantLock mainLock = this.mainLock;
- mainLock.lock();
- try {
- for (; ; ) {
- if (runStateAtLeast(ctl.get(), TERMINATED)) {
- return true;
- }
- if (nanos <= 0) {
- return false;
- }
- nanos = termination.awaitNanos(nanos);
- }
- } finally {
- mainLock.unlock();
- }
- }
-
- @Override
- protected void finalize() {
- SecurityManager sm = System.getSecurityManager();
- if (sm == null || acc == null) {
- shutdown();
- } else {
- PrivilegedAction pa = () -> {
- shutdown();
- return null;
- };
- AccessController.doPrivileged(pa, acc);
- }
- }
-
- @Override
- public void setThreadFactory(@NonNull ThreadFactory threadFactory) {
- this.threadFactory = threadFactory;
- }
-
- @Override
- public ThreadFactory getThreadFactory() {
- return threadFactory;
- }
-
- @Override
- public void setRejectedExecutionHandler(@NonNull RejectedExecutionHandler handler) {
- this.handler = handler;
- }
-
- @Override
- public RejectedExecutionHandler getRejectedExecutionHandler() {
- return handler;
- }
-
- @Override
- public void setCorePoolSize(int corePoolSize) {
- if (corePoolSize < 0) {
- throw new IllegalArgumentException();
- }
- int delta = corePoolSize - this.corePoolSize;
- this.corePoolSize = corePoolSize;
- if (workerCountOf(ctl.get()) > corePoolSize) {
- interruptIdleWorkers();
- } else if (delta > 0) {
- int k = Math.min(delta, workQueue.size());
- while (k-- > 0 && addWorker(null, true)) {
- if (workQueue.isEmpty()) {
- break;
- }
- }
- }
- }
-
- @Override
- public int getCorePoolSize() {
- return corePoolSize;
- }
-
- @Override
- public boolean prestartCoreThread() {
- return workerCountOf(ctl.get()) < corePoolSize &&
- addWorker(null, true);
- }
-
- void ensurePrestart() {
- int wc = workerCountOf(ctl.get());
- if (wc < corePoolSize) {
- addWorker(null, true);
- } else if (wc == 0) {
- addWorker(null, false);
- }
- }
-
- @Override
- public int prestartAllCoreThreads() {
- int n = 0;
- while (addWorker(null, true)) {
- ++n;
- }
- return n;
- }
-
- @Override
- public boolean allowsCoreThreadTimeOut() {
- return allowCoreThreadTimeOut;
- }
-
- @Override
- public void allowCoreThreadTimeOut(boolean value) {
- if (value && keepAliveTime <= 0) {
- throw new IllegalArgumentException("Core threads must have nonzero keep alive times");
- }
- if (value != allowCoreThreadTimeOut) {
- allowCoreThreadTimeOut = value;
- if (value) {
- interruptIdleWorkers();
- }
- }
- }
-
- @Override
- public void setMaximumPoolSize(int maximumPoolSize) {
- if (maximumPoolSize <= 0 || maximumPoolSize < corePoolSize) {
- throw new IllegalArgumentException();
- }
- this.maximumPoolSize = maximumPoolSize;
- if (workerCountOf(ctl.get()) > maximumPoolSize) {
- interruptIdleWorkers();
- }
- }
-
- @Override
- public int getMaximumPoolSize() {
- return maximumPoolSize;
- }
-
- @Override
- public void setKeepAliveTime(long time, TimeUnit unit) {
- if (time < 0) {
- throw new IllegalArgumentException();
- }
- if (time == 0 && allowsCoreThreadTimeOut()) {
- throw new IllegalArgumentException("Core threads must have nonzero keep alive times");
- }
- long keepAliveTime = unit.toNanos(time);
- long delta = keepAliveTime - this.keepAliveTime;
- this.keepAliveTime = keepAliveTime;
- if (delta < 0) {
- interruptIdleWorkers();
- }
- }
-
- @Override
- public long getKeepAliveTime(TimeUnit unit) {
- return unit.convert(keepAliveTime, TimeUnit.NANOSECONDS);
- }
-
- @Override
- public BlockingQueue getQueue() {
- return workQueue;
- }
-
- @Override
- public boolean remove(Runnable task) {
- boolean removed = workQueue.remove(task);
- tryTerminate();
- return removed;
- }
-
- @Override
- public void purge() {
- final BlockingQueue q = workQueue;
- try {
- Iterator it = q.iterator();
- while (it.hasNext()) {
- Runnable r = it.next();
- if (r instanceof Future> && ((Future>) r).isCancelled()) {
- it.remove();
- }
- }
- } catch (ConcurrentModificationException fallThrough) {
- for (Object r : q.toArray()) {
- if (r instanceof Future> && ((Future>) r).isCancelled()) {
- q.remove(r);
- }
- }
- }
-
- tryTerminate();
- }
-
- @Override
- public int getPoolSize() {
- final ReentrantLock mainLock = this.mainLock;
- mainLock.lock();
- try {
- return runStateAtLeast(ctl.get(), TIDYING) ? 0 : workers.size();
- } finally {
- mainLock.unlock();
- }
- }
-
- @Override
- public int getActiveCount() {
- final ReentrantLock mainLock = this.mainLock;
- mainLock.lock();
- try {
- int n = 0;
- for (Worker w : workers) {
- if (w.isLocked()) {
- ++n;
- }
- }
- return n;
- } finally {
- mainLock.unlock();
- }
- }
-
- @Override
- public int getLargestPoolSize() {
- final ReentrantLock mainLock = this.mainLock;
- mainLock.lock();
- try {
- return largestPoolSize;
- } finally {
- mainLock.unlock();
- }
- }
-
- @Override
- public long getTaskCount() {
- final ReentrantLock mainLock = this.mainLock;
- mainLock.lock();
- try {
- long n = completedTaskCount;
- for (Worker w : workers) {
- n += w.completedTasks;
- if (w.isLocked()) {
- ++n;
- }
- }
- return n + workQueue.size();
- } finally {
- mainLock.unlock();
- }
- }
-
- @Override
- public long getCompletedTaskCount() {
- final ReentrantLock mainLock = this.mainLock;
- mainLock.lock();
- try {
- long n = completedTaskCount;
- for (Worker w : workers) {
- n += w.completedTasks;
- }
- return n;
- } finally {
- mainLock.unlock();
- }
- }
-
- @Override
- public String toString() {
- long ncompleted;
- int nworkers, nactive;
- final ReentrantLock mainLock = this.mainLock;
- mainLock.lock();
- try {
- ncompleted = completedTaskCount;
- nactive = 0;
- nworkers = workers.size();
- for (Worker w : workers) {
- ncompleted += w.completedTasks;
- if (w.isLocked()) {
- ++nactive;
- }
- }
- } finally {
- mainLock.unlock();
- }
- int c = ctl.get();
- String rs = (runStateLessThan(c, SHUTDOWN) ? "Running" :
- (runStateAtLeast(c, TERMINATED) ? "Terminated" :
- "Shutting down"));
- return super.toString() +
- "[" + rs +
- ", pool size = " + nworkers +
- ", active threads = " + nactive +
- ", queued tasks = " + workQueue.size() +
- ", completed tasks = " + ncompleted +
- "]";
- }
-
- private ConcurrentHashMap statisticsTime = new ConcurrentHashMap(MAP_INITIAL_CAPACITY);
-
- @Override
- protected void beforeExecute(Thread t, Runnable r) {
- statisticsTime.put(String.valueOf(r.hashCode()), new Date());
- }
-
- @Override
- protected void afterExecute(Runnable r, Throwable t) {
- Date startDate = statisticsTime.remove(String.valueOf(r.hashCode()));
- Date finishDate = new Date();
- long diff = finishDate.getTime() - startDate.getTime();
-
- }
-
- @Override
- protected void terminated() {
- }
-
- @NoArgsConstructor
- public static class CallerRunsPolicy implements RejectedExecutionHandler {
- @Override
- public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {
- if (!e.isShutdown()) {
- r.run();
- }
- }
- }
-
- @NoArgsConstructor
- public static class AbortPolicy implements RejectedExecutionHandler {
- @Override
- public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {
- throw new RejectedExecutionException("Task " + r.toString() +
- " rejected from " +
- e.toString());
- }
- }
-
- @NoArgsConstructor
- public static class DiscardPolicy implements RejectedExecutionHandler {
- @Override
- public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {
- }
- }
-
- @NoArgsConstructor
- public static class DiscardOldestPolicy implements RejectedExecutionHandler {
- @Override
- public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {
- if (!e.isShutdown()) {
- e.getQueue().poll();
- e.execute(r);
- }
- }
- }
-
-}
diff --git a/dynamic-threadpool-spring-boot-starter/src/main/java/com/github/dynamic/threadpool/starter/toolkit/thread/RejectedTypeEnum.java b/dynamic-threadpool-spring-boot-starter/src/main/java/com/github/dynamic/threadpool/starter/toolkit/thread/RejectedTypeEnum.java
deleted file mode 100644
index 2781c98c..00000000
--- a/dynamic-threadpool-spring-boot-starter/src/main/java/com/github/dynamic/threadpool/starter/toolkit/thread/RejectedTypeEnum.java
+++ /dev/null
@@ -1,99 +0,0 @@
-package com.github.dynamic.threadpool.starter.toolkit.thread;
-
-import com.github.dynamic.threadpool.starter.spi.CustomRejectedExecutionHandler;
-import com.github.dynamic.threadpool.starter.spi.DynamicTpServiceLoader;
-
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Objects;
-import java.util.Optional;
-import java.util.concurrent.RejectedExecutionHandler;
-import java.util.concurrent.ThreadPoolExecutor;
-import java.util.stream.Stream;
-
-/**
- * Reject policy type Enum.
- *
- * @author chen.ma
- * @date 2021/7/10 23:16
- */
-public enum RejectedTypeEnum {
-
- /**
- * 被拒绝任务的程序由主线程执行
- */
- CALLER_RUNS_POLICY(1, new ThreadPoolExecutor.CallerRunsPolicy()),
-
- /**
- * 被拒绝任务的处理程序, 抛出异常
- */
- ABORT_POLICY(2, new ThreadPoolExecutor.AbortPolicy()),
-
- /**
- * 被拒绝任务的处理程序, 默默地丢弃被拒绝的任务。
- */
- DISCARD_POLICY(3, new ThreadPoolExecutor.DiscardPolicy()),
-
- /**
- * 被拒绝任务的处理程序, 它丢弃最早的未处理请求, 然后重试
- */
- DISCARD_OLDEST_POLICY(4, new ThreadPoolExecutor.DiscardOldestPolicy()),
-
- /**
- * 发生拒绝事件时, 添加新任务并运行最早的任务
- */
- RUNS_OLDEST_TASK_POLICY(5, RejectedPolicies.runsOldestTaskPolicy()),
-
- /**
- * 使用阻塞方法将拒绝任务添加队列, 可保证任务不丢失
- */
- SYNC_PUT_QUEUE_POLICY(6, RejectedPolicies.syncPutQueuePolicy());
-
- /**
- * 类型
- */
- public Integer type;
-
- /**
- * 线程池拒绝策略
- */
- public RejectedExecutionHandler rejectedHandler;
-
- RejectedTypeEnum(Integer type, RejectedExecutionHandler rejectedHandler) {
- this.type = type;
- this.rejectedHandler = rejectedHandler;
- }
-
- static {
- DynamicTpServiceLoader.register(CustomRejectedExecutionHandler.class);
- }
-
- public static RejectedExecutionHandler createPolicy(int type) {
- Optional rejectedTypeEnum = Stream.of(RejectedTypeEnum.values())
- .filter(each -> Objects.equals(type, each.type))
- .map(each -> each.rejectedHandler)
- .findFirst();
-
- // 使用 SPI 匹配拒绝策略
- RejectedExecutionHandler resultRejected = rejectedTypeEnum.orElseGet(() -> {
- Collection customRejectedExecutionHandlers = DynamicTpServiceLoader
- .getSingletonServiceInstances(CustomRejectedExecutionHandler.class);
- Optional customRejected = customRejectedExecutionHandlers.stream()
- .filter(each -> Objects.equals(type, each.getType()))
- .map(each -> each.generateRejected())
- .findFirst();
-
- return customRejected.orElse(ABORT_POLICY.rejectedHandler);
- });
-
- return resultRejected;
- }
-
- public static String getRejectedNameByType(int type) {
- Optional rejectedTypeEnum = Arrays.stream(RejectedTypeEnum.values())
- .filter(each -> each.type == type).findFirst();
-
- return rejectedTypeEnum.map(each -> each.rejectedHandler.getClass().getSimpleName()).orElse("");
- }
-
-}
diff --git a/dynamic-threadpool-spring-boot-starter/src/main/java/com/github/dynamic/threadpool/starter/wrap/DynamicThreadPoolWrap.java b/dynamic-threadpool-spring-boot-starter/src/main/java/com/github/dynamic/threadpool/starter/wrap/DynamicThreadPoolWrap.java
deleted file mode 100644
index 571b4679..00000000
--- a/dynamic-threadpool-spring-boot-starter/src/main/java/com/github/dynamic/threadpool/starter/wrap/DynamicThreadPoolWrap.java
+++ /dev/null
@@ -1,79 +0,0 @@
-package com.github.dynamic.threadpool.starter.wrap;
-
-import com.github.dynamic.threadpool.starter.common.CommonThreadPool;
-import com.github.dynamic.threadpool.starter.toolkit.thread.CustomThreadPoolExecutor;
-import lombok.Data;
-
-import java.util.concurrent.Callable;
-import java.util.concurrent.Future;
-
-/**
- * Dynamic threadPool wrap.
- *
- * @author chen.ma
- * @date 2021/6/20 16:55
- */
-@Data
-public class DynamicThreadPoolWrap {
-
- private String tenantId;
-
- private String itemId;
-
- private String tpId;
-
- private boolean subscribeFlag;
-
- private CustomThreadPoolExecutor pool;
-
- /**
- * 首选服务端线程池, 为空使用默认线程池 {@link CommonThreadPool#getInstance(String)}
- *
- * @param threadPoolId
- */
- public DynamicThreadPoolWrap(String threadPoolId) {
- this(threadPoolId, CommonThreadPool.getInstance(threadPoolId));
- }
-
- /**
- * 首选服务端线程池, 为空使用 threadPoolExecutor
- *
- * @param threadPoolId
- * @param threadPoolExecutor
- */
- public DynamicThreadPoolWrap(String threadPoolId, CustomThreadPoolExecutor threadPoolExecutor) {
- this.tpId = threadPoolId;
- this.pool = threadPoolExecutor;
- }
-
- /**
- * 提交任务
- *
- * @param command
- */
- public void execute(Runnable command) {
- pool.execute(command);
- }
-
- /**
- * 提交任务
- *
- * @param task
- * @return
- */
- public Future> submit(Runnable task) {
- return pool.submit(task);
- }
-
- /**
- * 提交任务
- *
- * @param task
- * @param
- * @return
- */
- public Future submit(Callable task) {
- return pool.submit(task);
- }
-
-}
diff --git a/dynamic-threadpool-spring-boot-starter/src/main/java/com/github/dynamic/threadpool/starter/wrap/ManagerListenerWrap.java b/dynamic-threadpool-spring-boot-starter/src/main/java/com/github/dynamic/threadpool/starter/wrap/ManagerListenerWrap.java
deleted file mode 100644
index 2b35b07d..00000000
--- a/dynamic-threadpool-spring-boot-starter/src/main/java/com/github/dynamic/threadpool/starter/wrap/ManagerListenerWrap.java
+++ /dev/null
@@ -1,26 +0,0 @@
-package com.github.dynamic.threadpool.starter.wrap;
-
-import com.github.dynamic.threadpool.starter.core.Listener;
-import lombok.Getter;
-import lombok.Setter;
-
-/**
- * Manager listener wrap.
- *
- * @author chen.ma
- * @date 2021/6/22 17:47
- */
-@Getter
-@Setter
-public class ManagerListenerWrap {
-
- private String lastCallMd5;
-
- final Listener listener;
-
- public ManagerListenerWrap(String md5, Listener listener) {
- this.lastCallMd5 = md5;
- this.listener = listener;
- }
-
-}
diff --git a/dynamic-threadpool-spring-boot-starter/src/main/resources/META-INF/spring.factories b/dynamic-threadpool-spring-boot-starter/src/main/resources/META-INF/spring.factories
deleted file mode 100644
index 797fc7f9..00000000
--- a/dynamic-threadpool-spring-boot-starter/src/main/resources/META-INF/spring.factories
+++ /dev/null
@@ -1,2 +0,0 @@
-org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
- com.github.dynamic.threadpool.starter.config.DynamicThreadPoolAutoConfiguration
diff --git a/example/src/main/java/com/github/dynamic/threadpool/example/ExampleApplication.java b/example/src/main/java/com/github/dynamic/threadpool/example/ExampleApplication.java
deleted file mode 100644
index 57e79924..00000000
--- a/example/src/main/java/com/github/dynamic/threadpool/example/ExampleApplication.java
+++ /dev/null
@@ -1,15 +0,0 @@
-package com.github.dynamic.threadpool.example;
-
-import com.github.dynamic.threadpool.starter.enable.EnableDynamicThreadPool;
-import org.springframework.boot.SpringApplication;
-import org.springframework.boot.autoconfigure.SpringBootApplication;
-
-@SpringBootApplication
-@EnableDynamicThreadPool
-public class ExampleApplication {
-
- public static void main(String[] args) {
- SpringApplication.run(ExampleApplication.class, args);
- }
-
-}
diff --git a/example/src/main/java/com/github/dynamic/threadpool/example/config/ThreadPoolConfig.java b/example/src/main/java/com/github/dynamic/threadpool/example/config/ThreadPoolConfig.java
deleted file mode 100644
index 6d3ec6c6..00000000
--- a/example/src/main/java/com/github/dynamic/threadpool/example/config/ThreadPoolConfig.java
+++ /dev/null
@@ -1,48 +0,0 @@
-package com.github.dynamic.threadpool.example.config;
-
-import com.github.dynamic.threadpool.starter.core.DynamicThreadPool;
-import com.github.dynamic.threadpool.starter.toolkit.thread.CustomThreadPoolExecutor;
-import com.github.dynamic.threadpool.starter.toolkit.thread.ThreadPoolBuilder;
-import com.github.dynamic.threadpool.starter.wrap.DynamicThreadPoolWrap;
-import lombok.extern.slf4j.Slf4j;
-import org.springframework.context.annotation.Bean;
-import org.springframework.context.annotation.Configuration;
-
-import java.util.concurrent.ThreadPoolExecutor;
-
-import static com.github.dynamic.threadpool.example.constant.GlobalTestConstant.*;
-
-/**
- * Thread pool config.
- *
- * @author chen.ma
- * @date 2021/6/20 17:16
- */
-@Slf4j
-@Configuration
-public class ThreadPoolConfig {
-
- /**
- * {@link DynamicThreadPoolWrap} 完成 Server 端订阅配置功能.
- *
- * @return
- */
- @Bean
- public DynamicThreadPoolWrap messageCenterConsumeThreadPool() {
- return new DynamicThreadPoolWrap(MESSAGE_CONSUME);
- }
-
- /**
- * 通过 {@link DynamicThreadPool} 修饰 {@link CustomThreadPoolExecutor} 完成 Server 端订阅配置功能.
- *
- * 由动态线程池注解修饰后, IOC 容器中保存的是 {@link CustomThreadPoolExecutor}
- *
- * @return
- */
- @Bean
- @DynamicThreadPool
- public ThreadPoolExecutor customThreadPoolExecutor() {
- return ThreadPoolBuilder.builder().threadFactory(MESSAGE_PRODUCE).isCustomPool(true).build();
- }
-
-}
diff --git a/example/src/main/java/com/github/dynamic/threadpool/example/inittest/RunStateHandlerTest.java b/example/src/main/java/com/github/dynamic/threadpool/example/inittest/RunStateHandlerTest.java
deleted file mode 100644
index 85d49c9b..00000000
--- a/example/src/main/java/com/github/dynamic/threadpool/example/inittest/RunStateHandlerTest.java
+++ /dev/null
@@ -1,59 +0,0 @@
-package com.github.dynamic.threadpool.example.inittest;
-
-import com.github.dynamic.threadpool.starter.core.GlobalThreadPoolManage;
-import com.github.dynamic.threadpool.starter.wrap.DynamicThreadPoolWrap;
-import lombok.extern.slf4j.Slf4j;
-import org.springframework.stereotype.Component;
-
-import java.util.Random;
-import java.util.concurrent.Executors;
-import java.util.concurrent.ScheduledExecutorService;
-import java.util.concurrent.ThreadPoolExecutor;
-import java.util.concurrent.TimeUnit;
-
-import static com.github.dynamic.threadpool.example.constant.GlobalTestConstant.MESSAGE_PRODUCE;
-
-/**
- * Test run time metrics.
- *
- * @author chen.ma
- * @date 2021/8/15 21:00
- */
-@Slf4j
-@Component
-public class RunStateHandlerTest {
-
- // @PostConstruct
- @SuppressWarnings("all")
- public void runStateHandlerTest() {
- log.info("Test thread pool runtime state interface, The rejection policy will be triggered after 30s...");
-
- ScheduledExecutorService scheduledThreadPool = Executors.newSingleThreadScheduledExecutor();
- scheduledThreadPool.scheduleAtFixedRate(() -> {
- DynamicThreadPoolWrap executorService = GlobalThreadPoolManage.getExecutorService(MESSAGE_PRODUCE);
- ThreadPoolExecutor pool = executorService.getPool();
- try {
- pool.execute(() -> {
- log.info("Thread pool name :: {}, Executing incoming blocking...", Thread.currentThread().getName());
- try {
- int maxRandom = 10;
- int temp = 2;
- Random random = new Random();
- // Assignment thread pool completedTaskCount
- if (random.nextInt(maxRandom) % temp == 0) {
- Thread.sleep(10241024);
- } else {
- Thread.sleep(3000);
- }
- } catch (InterruptedException e) {
- // ignore
- }
- });
- } catch (Exception ex) {
- // ignore
- }
-
- }, 5, 2, TimeUnit.SECONDS);
- }
-
-}
diff --git a/example/src/main/resources/application.yaml b/example/src/main/resources/application.yaml
deleted file mode 100644
index aa2f581a..00000000
--- a/example/src/main/resources/application.yaml
+++ /dev/null
@@ -1,21 +0,0 @@
-server:
- port: 8088
- servlet:
- context-path: /example
-
-spring:
- profiles:
- active: dev
- application:
- name: dynamic-threadpool-example
- dynamic:
- thread-pool:
- notifys:
- - type: DING
- url: https://oapi.dingtalk.com/robot/send?access_token=
- token: 4a582a588a161d6e3a1bd1de7eea9ee9f562cdfcbe56b6e72029e7fd512b2eae
- receives: '15601166691'
- alarm-interval: 5
- server-addr: http://localhost:6691
- namespace: prescription
- item-id: ${spring.application.name}
diff --git a/auth/.gitignore b/hippo4j-auth/.gitignore
similarity index 100%
rename from auth/.gitignore
rename to hippo4j-auth/.gitignore
diff --git a/auth/pom.xml b/hippo4j-auth/pom.xml
similarity index 68%
rename from auth/pom.xml
rename to hippo4j-auth/pom.xml
index 354daee7..69d59712 100644
--- a/auth/pom.xml
+++ b/hippo4j-auth/pom.xml
@@ -4,14 +4,18 @@
4.0.0
- com.github.dynamic-threadpool
- parent
+ cn.hippo4j
+ hippo4j-all
${revision}
- auth
+ hippo4j-auth
jar
+
+ true
+
+
org.springframework.boot
@@ -49,6 +53,22 @@
cn.hutool
hutool-all
+
+
+ org.springframework.boot
+ spring-boot-starter-security
+
+
+
+ io.jsonwebtoken
+ jjwt
+ ${jjwt.version}
+
+
+
+ cn.hippo4j
+ hippo4j-common
+
diff --git a/hippo4j-auth/src/main/java/cn/hippo4j/auth/config/GlobalSecurityConfig.java b/hippo4j-auth/src/main/java/cn/hippo4j/auth/config/GlobalSecurityConfig.java
new file mode 100644
index 00000000..25b364a1
--- /dev/null
+++ b/hippo4j-auth/src/main/java/cn/hippo4j/auth/config/GlobalSecurityConfig.java
@@ -0,0 +1,95 @@
+package cn.hippo4j.auth.config;
+
+import cn.hippo4j.auth.constant.Constants;
+import cn.hippo4j.auth.filter.JWTAuthenticationFilter;
+import cn.hippo4j.auth.filter.JWTAuthorizationFilter;
+import cn.hippo4j.auth.security.JwtTokenManager;
+import cn.hippo4j.auth.service.impl.UserDetailsServiceImpl;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.security.authentication.AuthenticationManager;
+import org.springframework.security.config.BeanIds;
+import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
+import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
+import org.springframework.security.config.annotation.web.builders.HttpSecurity;
+import org.springframework.security.config.annotation.web.builders.WebSecurity;
+import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
+import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
+import org.springframework.security.config.http.SessionCreationPolicy;
+import org.springframework.security.core.userdetails.UserDetailsService;
+import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
+import org.springframework.web.cors.CorsConfiguration;
+import org.springframework.web.cors.CorsConfigurationSource;
+import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
+
+import javax.annotation.Resource;
+import java.util.stream.Stream;
+
+/**
+ * 安全配置.
+ *
+ * @author chen.ma
+ * @date 2021/11/9 21:10
+ */
+@Configuration
+@EnableWebSecurity
+@EnableGlobalMethodSecurity(prePostEnabled = true)
+public class GlobalSecurityConfig extends WebSecurityConfigurerAdapter {
+
+ @Resource
+ private UserDetailsService userDetailsService;
+
+ @Resource
+ private JwtTokenManager tokenManager;
+
+ @Bean
+ public UserDetailsService customUserService() {
+ return new UserDetailsServiceImpl();
+ }
+
+ @Bean
+ public BCryptPasswordEncoder bCryptPasswordEncoder() {
+ return new BCryptPasswordEncoder();
+ }
+
+ @Bean(name = BeanIds.AUTHENTICATION_MANAGER)
+ @Override
+ public AuthenticationManager authenticationManagerBean() throws Exception {
+ return super.authenticationManagerBean();
+ }
+
+ @Bean
+ public CorsConfigurationSource corsConfigurationSource() {
+ UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
+ CorsConfiguration config = new CorsConfiguration();
+ config.addAllowedMethod(Constants.SPLIT_STAR);
+ config.applyPermitDefaultValues();
+ source.registerCorsConfiguration("/**", config);
+ return source;
+ }
+
+ @Override
+ protected void configure(AuthenticationManagerBuilder auth) throws Exception {
+ auth.userDetailsService(userDetailsService).passwordEncoder(bCryptPasswordEncoder());
+ }
+
+ @Override
+ protected void configure(HttpSecurity http) throws Exception {
+ http.cors().and().csrf().disable()
+ .authorizeRequests()
+ .antMatchers("/static/**", "/index.html", "/favicon.ico", "/avatar.jpg").permitAll()
+ .antMatchers("/doc.html", "/swagger-resources/**", "/webjars/**", "/*/api-docs").anonymous()
+ .anyRequest().authenticated()
+ .and()
+ .addFilter(new JWTAuthenticationFilter(authenticationManager()))
+ .addFilter(new JWTAuthorizationFilter(tokenManager, authenticationManager()))
+ .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
+ }
+
+ @Override
+ public void configure(WebSecurity web) throws Exception {
+ String[] ignores = Stream.of("/hippo4j/v1/cs/auth/users/apply/token/**", "/hippo4j/v1/cs/configs/**").toArray(String[]::new);
+ web.ignoring().antMatchers(ignores);
+ }
+
+}
diff --git a/hippo4j-auth/src/main/java/cn/hippo4j/auth/constant/Constants.java b/hippo4j-auth/src/main/java/cn/hippo4j/auth/constant/Constants.java
new file mode 100644
index 00000000..739752d0
--- /dev/null
+++ b/hippo4j-auth/src/main/java/cn/hippo4j/auth/constant/Constants.java
@@ -0,0 +1,17 @@
+package cn.hippo4j.auth.constant;
+
+/**
+ * Constants.
+ *
+ * @author chen.ma
+ * @date 2021/11/9 22:24
+ */
+public class Constants {
+
+ public static final String SPLIT_STAR = "*";
+
+ public static final String SPLIT_COMMA = ",";
+
+ public static final long TOKEN_VALIDITY_IN_SECONDS = 18000L;
+
+}
diff --git a/hippo4j-auth/src/main/java/cn/hippo4j/auth/filter/JWTAuthenticationFilter.java b/hippo4j-auth/src/main/java/cn/hippo4j/auth/filter/JWTAuthenticationFilter.java
new file mode 100644
index 00000000..b7d52472
--- /dev/null
+++ b/hippo4j-auth/src/main/java/cn/hippo4j/auth/filter/JWTAuthenticationFilter.java
@@ -0,0 +1,99 @@
+package cn.hippo4j.auth.filter;
+
+import cn.hippo4j.auth.model.biz.user.JwtUser;
+import cn.hippo4j.auth.model.biz.user.LoginUser;
+import cn.hippo4j.auth.toolkit.JwtTokenUtil;
+import cn.hippo4j.auth.toolkit.ReturnT;
+import cn.hippo4j.common.web.base.Results;
+import cn.hutool.json.JSONUtil;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.security.authentication.AuthenticationManager;
+import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
+import org.springframework.security.core.Authentication;
+import org.springframework.security.core.AuthenticationException;
+import org.springframework.security.core.GrantedAuthority;
+import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
+
+import javax.servlet.FilterChain;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Map;
+
+import static cn.hippo4j.auth.constant.Constants.SPLIT_COMMA;
+import static cn.hippo4j.common.constant.Constants.BASE_PATH;
+import static cn.hippo4j.common.constant.Constants.MAP_INITIAL_CAPACITY;
+
+/**
+ * JWT authentication filter.
+ *
+ * @author chen.ma
+ * @date 2021/11/9 22:21
+ */
+@Slf4j
+public class JWTAuthenticationFilter extends UsernamePasswordAuthenticationFilter {
+
+ private final AuthenticationManager authenticationManager;
+
+ private final ThreadLocal rememberMe = new ThreadLocal();
+
+ public JWTAuthenticationFilter(AuthenticationManager authenticationManager) {
+ this.authenticationManager = authenticationManager;
+ super.setFilterProcessesUrl(BASE_PATH + "/auth/login");
+ }
+
+ @Override
+ public Authentication attemptAuthentication(HttpServletRequest request,
+ HttpServletResponse response) throws AuthenticationException {
+ // 从输入流中获取到登录的信息
+ try {
+ LoginUser loginUser = new ObjectMapper().readValue(request.getInputStream(), LoginUser.class);
+ rememberMe.set(loginUser.getRememberMe());
+ return authenticationManager.authenticate(
+ new UsernamePasswordAuthenticationToken(loginUser.getUsername(), loginUser.getPassword(), new ArrayList())
+ );
+ } catch (IOException e) {
+ logger.error("attemptAuthentication error :{}", e);
+ return null;
+ }
+ }
+
+ @Override
+ protected void successfulAuthentication(HttpServletRequest request,
+ HttpServletResponse response,
+ FilterChain chain,
+ Authentication authResult) throws IOException {
+ try {
+ JwtUser jwtUser = (JwtUser) authResult.getPrincipal();
+ boolean isRemember = rememberMe.get() == 1;
+
+ String role = "";
+ Collection extends GrantedAuthority> authorities = jwtUser.getAuthorities();
+ for (GrantedAuthority authority : authorities) {
+ role = authority.getAuthority();
+ }
+
+ String token = JwtTokenUtil.createToken(jwtUser.getId(), jwtUser.getUsername(), role, isRemember);
+ response.setHeader("token", JwtTokenUtil.TOKEN_PREFIX + token);
+ response.setCharacterEncoding("UTF-8");
+ Map maps = new HashMap(MAP_INITIAL_CAPACITY);
+ maps.put("data", JwtTokenUtil.TOKEN_PREFIX + token);
+ maps.put("roles", role.split(SPLIT_COMMA));
+ response.getWriter().write(JSONUtil.toJsonStr(Results.success(maps)));
+ } finally {
+ rememberMe.remove();
+ }
+ }
+
+ @Override
+ protected void unsuccessfulAuthentication(HttpServletRequest request, HttpServletResponse response, AuthenticationException failed) throws IOException, ServletException {
+ response.setCharacterEncoding("UTF-8");
+ response.getWriter().write(JSONUtil.toJsonStr(new ReturnT(-1, "Server Error")));
+ }
+
+}
diff --git a/hippo4j-auth/src/main/java/cn/hippo4j/auth/filter/JWTAuthorizationFilter.java b/hippo4j-auth/src/main/java/cn/hippo4j/auth/filter/JWTAuthorizationFilter.java
new file mode 100644
index 00000000..a303ab6a
--- /dev/null
+++ b/hippo4j-auth/src/main/java/cn/hippo4j/auth/filter/JWTAuthorizationFilter.java
@@ -0,0 +1,118 @@
+package cn.hippo4j.auth.filter;
+
+import cn.hippo4j.auth.security.JwtTokenManager;
+import cn.hippo4j.auth.toolkit.JwtTokenUtil;
+import cn.hippo4j.common.toolkit.JSONUtil;
+import cn.hippo4j.common.toolkit.UserContext;
+import cn.hippo4j.common.web.base.Results;
+import cn.hippo4j.common.web.exception.ServiceException;
+import cn.hutool.core.util.StrUtil;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.security.authentication.AuthenticationManager;
+import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
+import org.springframework.security.core.Authentication;
+import org.springframework.security.core.authority.SimpleGrantedAuthority;
+import org.springframework.security.core.context.SecurityContextHolder;
+import org.springframework.security.web.authentication.www.BasicAuthenticationFilter;
+
+import javax.servlet.FilterChain;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
+import java.util.Collections;
+
+import static cn.hippo4j.common.constant.Constants.ACCESS_TOKEN;
+import static cn.hippo4j.common.web.exception.ErrorCodeEnum.LOGIN_TIMEOUT;
+
+/**
+ * JWT authorization filter.
+ *
+ * @author chen.ma
+ * @date 2021/11/9 22:21
+ */
+@Slf4j
+public class JWTAuthorizationFilter extends BasicAuthenticationFilter {
+
+ private final JwtTokenManager tokenManager;
+
+ public JWTAuthorizationFilter(JwtTokenManager tokenManager, AuthenticationManager authenticationManager) {
+ super(authenticationManager);
+ this.tokenManager = tokenManager;
+ }
+
+ @Override
+ protected void doFilterInternal(HttpServletRequest request,
+ HttpServletResponse response,
+ FilterChain chain) throws IOException, ServletException {
+ // 验证客户端交互时 Token
+ String accessToken = request.getParameter(ACCESS_TOKEN);
+ if (StrUtil.isNotBlank(accessToken)) {
+ tokenManager.validateToken(accessToken);
+
+ Authentication authentication = this.tokenManager.getAuthentication(accessToken);
+ SecurityContextHolder.getContext().setAuthentication(authentication);
+
+ chain.doFilter(request, response);
+ return;
+ }
+
+ // 如果请求头中没有 Authorization 信息则直接放行
+ String tokenHeader = request.getHeader(JwtTokenUtil.TOKEN_HEADER);
+ if (tokenHeader == null || !tokenHeader.startsWith(JwtTokenUtil.TOKEN_PREFIX)) {
+ chain.doFilter(request, response);
+ return;
+ }
+
+ // 如果请求头中有 Token, 则进行解析, 并且设置认证信息
+ try {
+ SecurityContextHolder.getContext().setAuthentication(getAuthentication(tokenHeader));
+ } catch (Exception ex) {
+ // 返回 Json 形式的错误信息
+ response.setCharacterEncoding("UTF-8");
+ response.setContentType("application/json; charset=utf-8");
+ String resultStatus = "-1";
+ if (ex instanceof ServiceException) {
+ ServiceException serviceException = (ServiceException) ex;
+ resultStatus = serviceException.errorCode.getCode();
+ }
+ response.getWriter().write(JSONUtil.toJSONString(Results.failure(resultStatus, ex.getMessage())));
+ response.getWriter().flush();
+ return;
+ }
+
+ try {
+ super.doFilterInternal(request, response, chain);
+ } finally {
+ UserContext.clear();
+ }
+ }
+
+ /**
+ * Token 中获取用户信息并新建一个 Token.
+ *
+ * @param tokenHeader
+ * @return
+ */
+ private UsernamePasswordAuthenticationToken getAuthentication(String tokenHeader) {
+ String token = tokenHeader.replace(JwtTokenUtil.TOKEN_PREFIX, "");
+ boolean expiration = JwtTokenUtil.isExpiration(token);
+ if (expiration) {
+ throw new ServiceException(LOGIN_TIMEOUT);
+ }
+
+ String username = JwtTokenUtil.getUsername(token);
+ String userRole = JwtTokenUtil.getUserRole(token);
+ UserContext.setUserInfo(username, userRole);
+
+ String role = JwtTokenUtil.getUserRole(token);
+ if (username != null) {
+ return new UsernamePasswordAuthenticationToken(username, null,
+ Collections.singleton(new SimpleGrantedAuthority(role))
+ );
+ }
+
+ return null;
+ }
+
+}
diff --git a/auth/src/main/java/com/github/dynamic/threadpool/auth/mapper/PermissionMapper.java b/hippo4j-auth/src/main/java/cn/hippo4j/auth/mapper/PermissionMapper.java
similarity index 69%
rename from auth/src/main/java/com/github/dynamic/threadpool/auth/mapper/PermissionMapper.java
rename to hippo4j-auth/src/main/java/cn/hippo4j/auth/mapper/PermissionMapper.java
index 67fb2c59..f0977313 100644
--- a/auth/src/main/java/com/github/dynamic/threadpool/auth/mapper/PermissionMapper.java
+++ b/hippo4j-auth/src/main/java/cn/hippo4j/auth/mapper/PermissionMapper.java
@@ -1,7 +1,7 @@
-package com.github.dynamic.threadpool.auth.mapper;
+package cn.hippo4j.auth.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
-import com.github.dynamic.threadpool.auth.model.PermissionInfo;
+import cn.hippo4j.auth.model.PermissionInfo;
import org.apache.ibatis.annotations.Mapper;
/**
diff --git a/auth/src/main/java/com/github/dynamic/threadpool/auth/mapper/RoleMapper.java b/hippo4j-auth/src/main/java/cn/hippo4j/auth/mapper/RoleMapper.java
similarity index 69%
rename from auth/src/main/java/com/github/dynamic/threadpool/auth/mapper/RoleMapper.java
rename to hippo4j-auth/src/main/java/cn/hippo4j/auth/mapper/RoleMapper.java
index bed36fe7..0286d0cc 100644
--- a/auth/src/main/java/com/github/dynamic/threadpool/auth/mapper/RoleMapper.java
+++ b/hippo4j-auth/src/main/java/cn/hippo4j/auth/mapper/RoleMapper.java
@@ -1,7 +1,7 @@
-package com.github.dynamic.threadpool.auth.mapper;
+package cn.hippo4j.auth.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
-import com.github.dynamic.threadpool.auth.model.RoleInfo;
+import cn.hippo4j.auth.model.RoleInfo;
import org.apache.ibatis.annotations.Mapper;
/**
diff --git a/auth/src/main/java/com/github/dynamic/threadpool/auth/mapper/UserMapper.java b/hippo4j-auth/src/main/java/cn/hippo4j/auth/mapper/UserMapper.java
similarity index 69%
rename from auth/src/main/java/com/github/dynamic/threadpool/auth/mapper/UserMapper.java
rename to hippo4j-auth/src/main/java/cn/hippo4j/auth/mapper/UserMapper.java
index 28dc0361..317c6023 100644
--- a/auth/src/main/java/com/github/dynamic/threadpool/auth/mapper/UserMapper.java
+++ b/hippo4j-auth/src/main/java/cn/hippo4j/auth/mapper/UserMapper.java
@@ -1,7 +1,7 @@
-package com.github.dynamic.threadpool.auth.mapper;
+package cn.hippo4j.auth.mapper;
+import cn.hippo4j.auth.model.UserInfo;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
-import com.github.dynamic.threadpool.auth.model.UserInfo;
import org.apache.ibatis.annotations.Mapper;
/**
diff --git a/auth/src/main/java/com/github/dynamic/threadpool/auth/model/PermissionInfo.java b/hippo4j-auth/src/main/java/cn/hippo4j/auth/model/PermissionInfo.java
similarity index 92%
rename from auth/src/main/java/com/github/dynamic/threadpool/auth/model/PermissionInfo.java
rename to hippo4j-auth/src/main/java/cn/hippo4j/auth/model/PermissionInfo.java
index f938e18e..2c8faaaa 100644
--- a/auth/src/main/java/com/github/dynamic/threadpool/auth/model/PermissionInfo.java
+++ b/hippo4j-auth/src/main/java/cn/hippo4j/auth/model/PermissionInfo.java
@@ -1,4 +1,4 @@
-package com.github.dynamic.threadpool.auth.model;
+package cn.hippo4j.auth.model;
import com.baomidou.mybatisplus.annotation.*;
import lombok.Data;
@@ -18,7 +18,7 @@ public class PermissionInfo {
/**
* id
*/
- @TableId
+ @TableId(type = IdType.AUTO)
private Long id;
/**
diff --git a/auth/src/main/java/com/github/dynamic/threadpool/auth/model/RoleInfo.java b/hippo4j-auth/src/main/java/cn/hippo4j/auth/model/RoleInfo.java
similarity index 91%
rename from auth/src/main/java/com/github/dynamic/threadpool/auth/model/RoleInfo.java
rename to hippo4j-auth/src/main/java/cn/hippo4j/auth/model/RoleInfo.java
index b1f7ff46..f3bca4a4 100644
--- a/auth/src/main/java/com/github/dynamic/threadpool/auth/model/RoleInfo.java
+++ b/hippo4j-auth/src/main/java/cn/hippo4j/auth/model/RoleInfo.java
@@ -1,4 +1,4 @@
-package com.github.dynamic.threadpool.auth.model;
+package cn.hippo4j.auth.model;
import com.baomidou.mybatisplus.annotation.*;
import lombok.Data;
@@ -18,7 +18,7 @@ public class RoleInfo {
/**
* id
*/
- @TableId
+ @TableId(type = IdType.AUTO)
private Long id;
/**
diff --git a/auth/src/main/java/com/github/dynamic/threadpool/auth/model/UserInfo.java b/hippo4j-auth/src/main/java/cn/hippo4j/auth/model/UserInfo.java
similarity index 85%
rename from auth/src/main/java/com/github/dynamic/threadpool/auth/model/UserInfo.java
rename to hippo4j-auth/src/main/java/cn/hippo4j/auth/model/UserInfo.java
index a472849d..0c4cba74 100644
--- a/auth/src/main/java/com/github/dynamic/threadpool/auth/model/UserInfo.java
+++ b/hippo4j-auth/src/main/java/cn/hippo4j/auth/model/UserInfo.java
@@ -1,4 +1,4 @@
-package com.github.dynamic.threadpool.auth.model;
+package cn.hippo4j.auth.model;
import com.baomidou.mybatisplus.annotation.*;
import lombok.Data;
@@ -18,7 +18,7 @@ public class UserInfo {
/**
* id
*/
- @TableId
+ @TableId(type = IdType.AUTO)
private Long id;
/**
@@ -31,6 +31,11 @@ public class UserInfo {
*/
private String password;
+ /**
+ * role
+ */
+ private String role;
+
/**
* gmtCreate
*/
diff --git a/auth/src/main/java/com/github/dynamic/threadpool/auth/model/biz/permission/PermissionQueryPageReqDTO.java b/hippo4j-auth/src/main/java/cn/hippo4j/auth/model/biz/permission/PermissionQueryPageReqDTO.java
similarity index 83%
rename from auth/src/main/java/com/github/dynamic/threadpool/auth/model/biz/permission/PermissionQueryPageReqDTO.java
rename to hippo4j-auth/src/main/java/cn/hippo4j/auth/model/biz/permission/PermissionQueryPageReqDTO.java
index c87d65b8..30e0b42c 100644
--- a/auth/src/main/java/com/github/dynamic/threadpool/auth/model/biz/permission/PermissionQueryPageReqDTO.java
+++ b/hippo4j-auth/src/main/java/cn/hippo4j/auth/model/biz/permission/PermissionQueryPageReqDTO.java
@@ -1,4 +1,4 @@
-package com.github.dynamic.threadpool.auth.model.biz.permission;
+package cn.hippo4j.auth.model.biz.permission;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import lombok.Data;
diff --git a/auth/src/main/java/com/github/dynamic/threadpool/auth/model/biz/permission/PermissionRespDTO.java b/hippo4j-auth/src/main/java/cn/hippo4j/auth/model/biz/permission/PermissionRespDTO.java
similarity index 82%
rename from auth/src/main/java/com/github/dynamic/threadpool/auth/model/biz/permission/PermissionRespDTO.java
rename to hippo4j-auth/src/main/java/cn/hippo4j/auth/model/biz/permission/PermissionRespDTO.java
index 67d9a930..4d0bc92b 100644
--- a/auth/src/main/java/com/github/dynamic/threadpool/auth/model/biz/permission/PermissionRespDTO.java
+++ b/hippo4j-auth/src/main/java/cn/hippo4j/auth/model/biz/permission/PermissionRespDTO.java
@@ -1,4 +1,4 @@
-package com.github.dynamic.threadpool.auth.model.biz.permission;
+package cn.hippo4j.auth.model.biz.permission;
import lombok.Data;
diff --git a/auth/src/main/java/com/github/dynamic/threadpool/auth/model/biz/role/RoleQueryPageReqDTO.java b/hippo4j-auth/src/main/java/cn/hippo4j/auth/model/biz/role/RoleQueryPageReqDTO.java
similarity index 84%
rename from auth/src/main/java/com/github/dynamic/threadpool/auth/model/biz/role/RoleQueryPageReqDTO.java
rename to hippo4j-auth/src/main/java/cn/hippo4j/auth/model/biz/role/RoleQueryPageReqDTO.java
index 783ecf80..ae93f7e1 100644
--- a/auth/src/main/java/com/github/dynamic/threadpool/auth/model/biz/role/RoleQueryPageReqDTO.java
+++ b/hippo4j-auth/src/main/java/cn/hippo4j/auth/model/biz/role/RoleQueryPageReqDTO.java
@@ -1,4 +1,4 @@
-package com.github.dynamic.threadpool.auth.model.biz.role;
+package cn.hippo4j.auth.model.biz.role;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import lombok.Data;
diff --git a/auth/src/main/java/com/github/dynamic/threadpool/auth/model/biz/role/RoleRespDTO.java b/hippo4j-auth/src/main/java/cn/hippo4j/auth/model/biz/role/RoleRespDTO.java
similarity index 80%
rename from auth/src/main/java/com/github/dynamic/threadpool/auth/model/biz/role/RoleRespDTO.java
rename to hippo4j-auth/src/main/java/cn/hippo4j/auth/model/biz/role/RoleRespDTO.java
index e6269a5d..2adffbcb 100644
--- a/auth/src/main/java/com/github/dynamic/threadpool/auth/model/biz/role/RoleRespDTO.java
+++ b/hippo4j-auth/src/main/java/cn/hippo4j/auth/model/biz/role/RoleRespDTO.java
@@ -1,4 +1,4 @@
-package com.github.dynamic.threadpool.auth.model.biz.role;
+package cn.hippo4j.auth.model.biz.role;
import lombok.Data;
diff --git a/hippo4j-auth/src/main/java/cn/hippo4j/auth/model/biz/user/JwtUser.java b/hippo4j-auth/src/main/java/cn/hippo4j/auth/model/biz/user/JwtUser.java
new file mode 100644
index 00000000..d2b655d2
--- /dev/null
+++ b/hippo4j-auth/src/main/java/cn/hippo4j/auth/model/biz/user/JwtUser.java
@@ -0,0 +1,58 @@
+package cn.hippo4j.auth.model.biz.user;
+
+import lombok.Data;
+import org.springframework.security.core.GrantedAuthority;
+import org.springframework.security.core.userdetails.UserDetails;
+
+import java.util.Collection;
+
+/**
+ * Jwt user.
+ *
+ * @author chen.ma
+ * @date 2021/11/9 22:34
+ */
+@Data
+public class JwtUser implements UserDetails {
+
+ /**
+ * id
+ */
+ private Long id;
+
+ /**
+ * userName
+ */
+ private String username;
+
+ /**
+ * password
+ */
+ private String password;
+
+ /**
+ * authorities
+ */
+ private Collection extends GrantedAuthority> authorities;
+
+ @Override
+ public boolean isAccountNonExpired() {
+ return true;
+ }
+
+ @Override
+ public boolean isAccountNonLocked() {
+ return true;
+ }
+
+ @Override
+ public boolean isCredentialsNonExpired() {
+ return true;
+ }
+
+ @Override
+ public boolean isEnabled() {
+ return true;
+ }
+
+}
diff --git a/hippo4j-auth/src/main/java/cn/hippo4j/auth/model/biz/user/LoginUser.java b/hippo4j-auth/src/main/java/cn/hippo4j/auth/model/biz/user/LoginUser.java
new file mode 100644
index 00000000..ad2184a8
--- /dev/null
+++ b/hippo4j-auth/src/main/java/cn/hippo4j/auth/model/biz/user/LoginUser.java
@@ -0,0 +1,29 @@
+package cn.hippo4j.auth.model.biz.user;
+
+import lombok.Data;
+
+/**
+ * Login user.
+ *
+ * @author chen.ma
+ * @date 2021/11/9 22:41
+ */
+@Data
+public class LoginUser {
+
+ /**
+ * username
+ */
+ private String username;
+
+ /**
+ * password
+ */
+ private String password;
+
+ /**
+ * rememberMe
+ */
+ private Integer rememberMe;
+
+}
diff --git a/auth/src/main/java/com/github/dynamic/threadpool/auth/model/biz/user/UserQueryPageReqDTO.java b/hippo4j-auth/src/main/java/cn/hippo4j/auth/model/biz/user/UserQueryPageReqDTO.java
similarity index 57%
rename from auth/src/main/java/com/github/dynamic/threadpool/auth/model/biz/user/UserQueryPageReqDTO.java
rename to hippo4j-auth/src/main/java/cn/hippo4j/auth/model/biz/user/UserQueryPageReqDTO.java
index 50c708bf..472e5b36 100644
--- a/auth/src/main/java/com/github/dynamic/threadpool/auth/model/biz/user/UserQueryPageReqDTO.java
+++ b/hippo4j-auth/src/main/java/cn/hippo4j/auth/model/biz/user/UserQueryPageReqDTO.java
@@ -1,7 +1,8 @@
-package com.github.dynamic.threadpool.auth.model.biz.user;
+package cn.hippo4j.auth.model.biz.user;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import lombok.Data;
+import lombok.experimental.Accessors;
/**
* User query page.
@@ -10,10 +11,12 @@ import lombok.Data;
* @date 2021/10/30 21:47
*/
@Data
+@Accessors(chain = true)
public class UserQueryPageReqDTO extends Page {
- public UserQueryPageReqDTO(long current, long size) {
- super(current, size);
- }
+ /**
+ * userName
+ */
+ private String userName;
}
diff --git a/hippo4j-auth/src/main/java/cn/hippo4j/auth/model/biz/user/UserReqDTO.java b/hippo4j-auth/src/main/java/cn/hippo4j/auth/model/biz/user/UserReqDTO.java
new file mode 100644
index 00000000..b84529d7
--- /dev/null
+++ b/hippo4j-auth/src/main/java/cn/hippo4j/auth/model/biz/user/UserReqDTO.java
@@ -0,0 +1,32 @@
+package cn.hippo4j.auth.model.biz.user;
+
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import lombok.Data;
+import lombok.experimental.Accessors;
+
+/**
+ * User req dto.
+ *
+ * @author chen.ma
+ * @date 2021/11/11 20:30
+ */
+@Data
+@Accessors(chain = true)
+public class UserReqDTO extends Page {
+
+ /**
+ * userName
+ */
+ private String userName;
+
+ /**
+ * password
+ */
+ private String password;
+
+ /**
+ * role
+ */
+ private String role;
+
+}
diff --git a/auth/src/main/java/com/github/dynamic/threadpool/auth/model/biz/user/UserRespDTO.java b/hippo4j-auth/src/main/java/cn/hippo4j/auth/model/biz/user/UserRespDTO.java
similarity index 84%
rename from auth/src/main/java/com/github/dynamic/threadpool/auth/model/biz/user/UserRespDTO.java
rename to hippo4j-auth/src/main/java/cn/hippo4j/auth/model/biz/user/UserRespDTO.java
index 790cdadd..a82f68f3 100644
--- a/auth/src/main/java/com/github/dynamic/threadpool/auth/model/biz/user/UserRespDTO.java
+++ b/hippo4j-auth/src/main/java/cn/hippo4j/auth/model/biz/user/UserRespDTO.java
@@ -1,4 +1,4 @@
-package com.github.dynamic.threadpool.auth.model.biz.user;
+package cn.hippo4j.auth.model.biz.user;
import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.Data;
@@ -20,9 +20,9 @@ public class UserRespDTO {
private String userName;
/**
- * password
+ * role
*/
- private String password;
+ private String role;
/**
* gmtCreate
diff --git a/hippo4j-auth/src/main/java/cn/hippo4j/auth/security/AuthManager.java b/hippo4j-auth/src/main/java/cn/hippo4j/auth/security/AuthManager.java
new file mode 100644
index 00000000..fdfbcdd1
--- /dev/null
+++ b/hippo4j-auth/src/main/java/cn/hippo4j/auth/security/AuthManager.java
@@ -0,0 +1,46 @@
+package cn.hippo4j.auth.security;
+
+import lombok.AllArgsConstructor;
+import lombok.SneakyThrows;
+import org.springframework.expression.AccessException;
+import org.springframework.security.authentication.AuthenticationManager;
+import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
+import org.springframework.security.core.AuthenticationException;
+import org.springframework.stereotype.Component;
+
+/**
+ * Auth manager
+ *
+ * @author chen.ma
+ * @date 2021/12/20 20:34
+ */
+@Component
+@AllArgsConstructor
+public class AuthManager {
+
+ private final JwtTokenManager jwtTokenManager;
+
+ private final AuthenticationManager authenticationManager;
+
+ /**
+ * Resolve token from user.
+ *
+ * @param userName
+ * @param rawPassword
+ * @return
+ * @throws AccessException
+ */
+ @SneakyThrows
+ public String resolveTokenFromUser(String userName, String rawPassword) {
+ try {
+ UsernamePasswordAuthenticationToken authenticationToken =
+ new UsernamePasswordAuthenticationToken(userName, rawPassword);
+ authenticationManager.authenticate(authenticationToken);
+ } catch (AuthenticationException e) {
+ throw new AccessException("Unknown user.");
+ }
+
+ return jwtTokenManager.createToken(userName);
+ }
+
+}
diff --git a/hippo4j-auth/src/main/java/cn/hippo4j/auth/security/JwtTokenManager.java b/hippo4j-auth/src/main/java/cn/hippo4j/auth/security/JwtTokenManager.java
new file mode 100644
index 00000000..157a9f66
--- /dev/null
+++ b/hippo4j-auth/src/main/java/cn/hippo4j/auth/security/JwtTokenManager.java
@@ -0,0 +1,61 @@
+package cn.hippo4j.auth.security;
+
+import cn.hutool.core.util.StrUtil;
+import io.jsonwebtoken.Claims;
+import io.jsonwebtoken.Jwts;
+import io.jsonwebtoken.SignatureAlgorithm;
+import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
+import org.springframework.security.core.Authentication;
+import org.springframework.security.core.GrantedAuthority;
+import org.springframework.security.core.authority.AuthorityUtils;
+import org.springframework.security.core.userdetails.User;
+import org.springframework.stereotype.Component;
+
+import java.util.Date;
+import java.util.List;
+
+import static cn.hippo4j.auth.constant.Constants.TOKEN_VALIDITY_IN_SECONDS;
+import static cn.hippo4j.auth.toolkit.JwtTokenUtil.SECRET;
+import static cn.hippo4j.common.constant.Constants.AUTHORITIES_KEY;
+
+/**
+ * Jwt token manager.
+ *
+ * @author chen.ma
+ * @date 2021/12/20 20:36
+ */
+@Component
+public class JwtTokenManager {
+
+ public String createToken(String userName) {
+ long now = System.currentTimeMillis();
+
+ Date validity;
+ validity = new Date(now + TOKEN_VALIDITY_IN_SECONDS * 1000L);
+
+ Claims claims = Jwts.claims().setSubject(userName);
+ return Jwts.builder().setClaims(claims).setExpiration(validity)
+ .signWith(SignatureAlgorithm.HS512, SECRET).compact();
+ }
+
+ public void validateToken(String token) {
+ Jwts.parser().setSigningKey(SECRET).parseClaimsJws(token);
+ }
+
+ /**
+ * Get auth Info.
+ *
+ * @param token token
+ * @return auth info
+ */
+ public Authentication getAuthentication(String token) {
+ Claims claims = Jwts.parser().setSigningKey(SECRET).parseClaimsJws(token).getBody();
+
+ List authorities = AuthorityUtils
+ .commaSeparatedStringToAuthorityList((String) claims.get(AUTHORITIES_KEY));
+
+ User principal = new User(claims.getSubject(), StrUtil.EMPTY, authorities);
+ return new UsernamePasswordAuthenticationToken(principal, StrUtil.EMPTY, authorities);
+ }
+
+}
diff --git a/auth/src/main/java/com/github/dynamic/threadpool/auth/service/PermissionService.java b/hippo4j-auth/src/main/java/cn/hippo4j/auth/service/PermissionService.java
similarity index 84%
rename from auth/src/main/java/com/github/dynamic/threadpool/auth/service/PermissionService.java
rename to hippo4j-auth/src/main/java/cn/hippo4j/auth/service/PermissionService.java
index eec92f4e..922c0576 100644
--- a/auth/src/main/java/com/github/dynamic/threadpool/auth/service/PermissionService.java
+++ b/hippo4j-auth/src/main/java/cn/hippo4j/auth/service/PermissionService.java
@@ -1,7 +1,7 @@
-package com.github.dynamic.threadpool.auth.service;
+package cn.hippo4j.auth.service;
+import cn.hippo4j.auth.model.biz.permission.PermissionRespDTO;
import com.baomidou.mybatisplus.core.metadata.IPage;
-import com.github.dynamic.threadpool.auth.model.biz.permission.PermissionRespDTO;
/**
* Permission service.
diff --git a/auth/src/main/java/com/github/dynamic/threadpool/auth/service/RoleService.java b/hippo4j-auth/src/main/java/cn/hippo4j/auth/service/RoleService.java
similarity index 86%
rename from auth/src/main/java/com/github/dynamic/threadpool/auth/service/RoleService.java
rename to hippo4j-auth/src/main/java/cn/hippo4j/auth/service/RoleService.java
index 399e8fff..2b212e4c 100644
--- a/auth/src/main/java/com/github/dynamic/threadpool/auth/service/RoleService.java
+++ b/hippo4j-auth/src/main/java/cn/hippo4j/auth/service/RoleService.java
@@ -1,7 +1,7 @@
-package com.github.dynamic.threadpool.auth.service;
+package cn.hippo4j.auth.service;
import com.baomidou.mybatisplus.core.metadata.IPage;
-import com.github.dynamic.threadpool.auth.model.biz.role.RoleRespDTO;
+import cn.hippo4j.auth.model.biz.role.RoleRespDTO;
import java.util.List;
diff --git a/auth/src/main/java/com/github/dynamic/threadpool/auth/service/UserService.java b/hippo4j-auth/src/main/java/cn/hippo4j/auth/service/UserService.java
similarity index 53%
rename from auth/src/main/java/com/github/dynamic/threadpool/auth/service/UserService.java
rename to hippo4j-auth/src/main/java/cn/hippo4j/auth/service/UserService.java
index d98a294b..bbbffba5 100644
--- a/auth/src/main/java/com/github/dynamic/threadpool/auth/service/UserService.java
+++ b/hippo4j-auth/src/main/java/cn/hippo4j/auth/service/UserService.java
@@ -1,7 +1,9 @@
-package com.github.dynamic.threadpool.auth.service;
+package cn.hippo4j.auth.service;
+import cn.hippo4j.auth.model.biz.user.UserQueryPageReqDTO;
+import cn.hippo4j.auth.model.biz.user.UserRespDTO;
import com.baomidou.mybatisplus.core.metadata.IPage;
-import com.github.dynamic.threadpool.auth.model.biz.user.UserRespDTO;
+import cn.hippo4j.auth.model.biz.user.UserReqDTO;
import java.util.List;
@@ -16,27 +18,24 @@ public interface UserService {
/**
* 分页查询用户列表.
*
- * @param pageNo
- * @param pageSize
+ * @param reqDTO
* @return
*/
- IPage listUser(int pageNo, int pageSize);
+ IPage listUser(UserQueryPageReqDTO reqDTO);
/**
* 新增用户.
*
- * @param userName
- * @param password
+ * @param reqDTO
*/
- void addUser(String userName, String password);
+ void addUser(UserReqDTO reqDTO);
/**
* 修改用户.
*
- * @param userName
- * @param password
+ * @param reqDTO
*/
- void updateUser(String userName, String password);
+ void updateUser(UserReqDTO reqDTO);
/**
* 删除用户.
@@ -53,4 +52,12 @@ public interface UserService {
*/
List getUserLikeUsername(String userName);
+ /**
+ * 获取用户详情.
+ *
+ * @param reqDTO
+ * @return
+ */
+ UserRespDTO getUser(UserReqDTO reqDTO);
+
}
diff --git a/auth/src/main/java/com/github/dynamic/threadpool/auth/service/impl/PermissionServiceImpl.java b/hippo4j-auth/src/main/java/cn/hippo4j/auth/service/impl/PermissionServiceImpl.java
similarity index 77%
rename from auth/src/main/java/com/github/dynamic/threadpool/auth/service/impl/PermissionServiceImpl.java
rename to hippo4j-auth/src/main/java/cn/hippo4j/auth/service/impl/PermissionServiceImpl.java
index 2a7bd176..ddbf36f4 100644
--- a/auth/src/main/java/com/github/dynamic/threadpool/auth/service/impl/PermissionServiceImpl.java
+++ b/hippo4j-auth/src/main/java/cn/hippo4j/auth/service/impl/PermissionServiceImpl.java
@@ -1,15 +1,16 @@
-package com.github.dynamic.threadpool.auth.service.impl;
+package cn.hippo4j.auth.service.impl;
+import cn.hippo4j.auth.mapper.PermissionMapper;
+import cn.hippo4j.auth.model.biz.permission.PermissionQueryPageReqDTO;
+import cn.hippo4j.auth.model.biz.permission.PermissionRespDTO;
+import cn.hippo4j.auth.service.PermissionService;
import cn.hutool.core.bean.BeanUtil;
+import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
-import com.github.dynamic.threadpool.auth.mapper.PermissionMapper;
-import com.github.dynamic.threadpool.auth.model.PermissionInfo;
-import com.github.dynamic.threadpool.auth.model.biz.permission.PermissionQueryPageReqDTO;
-import com.github.dynamic.threadpool.auth.model.biz.permission.PermissionRespDTO;
-import com.github.dynamic.threadpool.auth.service.PermissionService;
+import cn.hippo4j.auth.model.PermissionInfo;
import lombok.AllArgsConstructor;
import org.springframework.stereotype.Service;
@@ -54,9 +55,9 @@ public class PermissionServiceImpl implements PermissionService {
@Override
public void deletePermission(String role, String resource, String action) {
LambdaUpdateWrapper updateWrapper = Wrappers.lambdaUpdate(PermissionInfo.class)
- .eq(PermissionInfo::getRole, role)
- .eq(PermissionInfo::getResource, resource)
- .eq(PermissionInfo::getAction, action);
+ .eq(StrUtil.isNotBlank(role), PermissionInfo::getRole, role)
+ .eq(StrUtil.isNotBlank(resource), PermissionInfo::getResource, resource)
+ .eq(StrUtil.isNotBlank(action), PermissionInfo::getAction, action);
permissionMapper.delete(updateWrapper);
}
diff --git a/auth/src/main/java/com/github/dynamic/threadpool/auth/service/impl/RoleServiceImpl.java b/hippo4j-auth/src/main/java/cn/hippo4j/auth/service/impl/RoleServiceImpl.java
similarity index 67%
rename from auth/src/main/java/com/github/dynamic/threadpool/auth/service/impl/RoleServiceImpl.java
rename to hippo4j-auth/src/main/java/cn/hippo4j/auth/service/impl/RoleServiceImpl.java
index 4f15664b..04b7b59a 100644
--- a/auth/src/main/java/com/github/dynamic/threadpool/auth/service/impl/RoleServiceImpl.java
+++ b/hippo4j-auth/src/main/java/cn/hippo4j/auth/service/impl/RoleServiceImpl.java
@@ -1,15 +1,18 @@
-package com.github.dynamic.threadpool.auth.service.impl;
+package cn.hippo4j.auth.service.impl;
+import cn.hippo4j.auth.mapper.RoleMapper;
+import cn.hippo4j.auth.model.biz.role.RoleQueryPageReqDTO;
+import cn.hippo4j.auth.model.biz.role.RoleRespDTO;
+import cn.hippo4j.auth.service.PermissionService;
+import cn.hippo4j.auth.service.RoleService;
import cn.hutool.core.bean.BeanUtil;
+import cn.hutool.core.collection.CollUtil;
+import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
-import com.github.dynamic.threadpool.auth.mapper.RoleMapper;
-import com.github.dynamic.threadpool.auth.model.RoleInfo;
-import com.github.dynamic.threadpool.auth.model.biz.role.RoleQueryPageReqDTO;
-import com.github.dynamic.threadpool.auth.model.biz.role.RoleRespDTO;
-import com.github.dynamic.threadpool.auth.service.RoleService;
+import cn.hippo4j.auth.model.RoleInfo;
import lombok.AllArgsConstructor;
import org.springframework.stereotype.Service;
@@ -28,6 +31,8 @@ public class RoleServiceImpl implements RoleService {
private final RoleMapper roleMapper;
+ private final PermissionService permissionService;
+
@Override
public IPage listRole(int pageNo, int pageSize) {
RoleQueryPageReqDTO queryPage = new RoleQueryPageReqDTO(pageNo, pageSize);
@@ -53,10 +58,18 @@ public class RoleServiceImpl implements RoleService {
@Override
public void deleteRole(String role, String userName) {
+ List roleStrList = CollUtil.toList(role);
+ if (StrUtil.isBlank(role)) {
+ LambdaQueryWrapper queryWrapper = Wrappers.lambdaQuery(RoleInfo.class).eq(RoleInfo::getUserName, userName);
+ roleStrList = roleMapper.selectList(queryWrapper).stream().map(RoleInfo::getRole).collect(Collectors.toList());
+ }
+
LambdaUpdateWrapper updateWrapper = Wrappers.lambdaUpdate(RoleInfo.class)
- .eq(RoleInfo::getRole, role)
- .eq(RoleInfo::getUserName, userName);
+ .eq(StrUtil.isNotBlank(role), RoleInfo::getRole, role)
+ .eq(StrUtil.isNotBlank(userName), RoleInfo::getUserName, userName);
roleMapper.delete(updateWrapper);
+
+ roleStrList.forEach(each -> permissionService.deletePermission(each, "", ""));
}
@Override
diff --git a/hippo4j-auth/src/main/java/cn/hippo4j/auth/service/impl/UserDetailsServiceImpl.java b/hippo4j-auth/src/main/java/cn/hippo4j/auth/service/impl/UserDetailsServiceImpl.java
new file mode 100644
index 00000000..5a1c1fc9
--- /dev/null
+++ b/hippo4j-auth/src/main/java/cn/hippo4j/auth/service/impl/UserDetailsServiceImpl.java
@@ -0,0 +1,42 @@
+package cn.hippo4j.auth.service.impl;
+
+import cn.hippo4j.auth.mapper.UserMapper;
+import cn.hippo4j.auth.model.UserInfo;
+import cn.hippo4j.auth.model.biz.user.JwtUser;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import org.springframework.security.core.authority.SimpleGrantedAuthority;
+import org.springframework.security.core.userdetails.UserDetails;
+import org.springframework.security.core.userdetails.UserDetailsService;
+import org.springframework.security.core.userdetails.UsernameNotFoundException;
+
+import javax.annotation.Resource;
+import java.util.Collections;
+import java.util.Set;
+
+/**
+ * User details service impl.
+ *
+ * @author chen.ma
+ * @date 2021/11/9 22:26
+ */
+public class UserDetailsServiceImpl implements UserDetailsService {
+
+ @Resource
+ private UserMapper userMapper;
+
+ @Override
+ public UserDetails loadUserByUsername(String userName) throws UsernameNotFoundException {
+ UserInfo userInfo = userMapper.selectOne(Wrappers.lambdaQuery(UserInfo.class).eq(UserInfo::getUserName, userName));
+
+ JwtUser jwtUser = new JwtUser();
+ jwtUser.setId(userInfo.getId());
+ jwtUser.setUsername(userName);
+ jwtUser.setPassword(userInfo.getPassword());
+
+ Set authorities = Collections.singleton(new SimpleGrantedAuthority(userInfo.getRole() + ""));
+ jwtUser.setAuthorities(authorities);
+
+ return jwtUser;
+ }
+
+}
diff --git a/hippo4j-auth/src/main/java/cn/hippo4j/auth/service/impl/UserServiceImpl.java b/hippo4j-auth/src/main/java/cn/hippo4j/auth/service/impl/UserServiceImpl.java
new file mode 100644
index 00000000..6b0470fa
--- /dev/null
+++ b/hippo4j-auth/src/main/java/cn/hippo4j/auth/service/impl/UserServiceImpl.java
@@ -0,0 +1,109 @@
+package cn.hippo4j.auth.service.impl;
+
+import cn.hippo4j.auth.mapper.UserMapper;
+import cn.hippo4j.auth.model.UserInfo;
+import cn.hippo4j.auth.model.biz.user.UserQueryPageReqDTO;
+import cn.hippo4j.auth.model.biz.user.UserReqDTO;
+import cn.hippo4j.auth.model.biz.user.UserRespDTO;
+import cn.hippo4j.auth.service.RoleService;
+import cn.hippo4j.auth.service.UserService;
+import cn.hippo4j.common.toolkit.StringUtil;
+import cn.hippo4j.common.web.exception.ServiceException;
+import cn.hutool.core.bean.BeanUtil;
+import cn.hutool.core.util.StrUtil;
+import com.baomidou.mybatisplus.core.conditions.Wrapper;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import lombok.AllArgsConstructor;
+import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
+import org.springframework.stereotype.Service;
+
+import java.util.List;
+import java.util.Optional;
+import java.util.stream.Collectors;
+
+/**
+ * User service impl.
+ *
+ * @author chen.ma
+ * @date 2021/10/30 21:40
+ */
+@Service
+@AllArgsConstructor
+public class UserServiceImpl implements UserService {
+
+ private final UserMapper userMapper;
+
+ private final RoleService roleService;
+
+ private final BCryptPasswordEncoder bCryptPasswordEncoder;
+
+ @Override
+ public IPage listUser(UserQueryPageReqDTO reqDTO) {
+ LambdaQueryWrapper queryWrapper = Wrappers.lambdaQuery(UserInfo.class)
+ .eq(StringUtil.isNotBlank(reqDTO.getUserName()), UserInfo::getUserName, reqDTO.getUserName());
+ IPage selectPage = userMapper.selectPage(reqDTO, queryWrapper);
+
+ return selectPage.convert(each -> BeanUtil.toBean(each, UserRespDTO.class));
+ }
+
+ @Override
+ public void addUser(UserReqDTO reqDTO) {
+ LambdaQueryWrapper queryWrapper = Wrappers.lambdaQuery(UserInfo.class)
+ .eq(UserInfo::getUserName, reqDTO.getUserName());
+ UserInfo existUserInfo = userMapper.selectOne(queryWrapper);
+ if (existUserInfo != null) {
+ throw new RuntimeException("用户名重复");
+ }
+
+ reqDTO.setPassword(bCryptPasswordEncoder.encode(reqDTO.getPassword()));
+ UserInfo insertUser = BeanUtil.toBean(reqDTO, UserInfo.class);
+ userMapper.insert(insertUser);
+ }
+
+ @Override
+ public void updateUser(UserReqDTO reqDTO) {
+ if (StrUtil.isNotBlank(reqDTO.getPassword())) {
+ reqDTO.setPassword(bCryptPasswordEncoder.encode(reqDTO.getPassword()));
+ }
+ UserInfo updateUser = BeanUtil.toBean(reqDTO, UserInfo.class);
+
+ LambdaUpdateWrapper updateWrapper = Wrappers.lambdaUpdate(UserInfo.class)
+ .eq(UserInfo::getUserName, reqDTO.getUserName());
+ userMapper.update(updateUser, updateWrapper);
+ }
+
+ @Override
+ public void deleteUser(String userName) {
+ LambdaUpdateWrapper updateWrapper = Wrappers.lambdaUpdate(UserInfo.class)
+ .eq(UserInfo::getUserName, userName);
+ userMapper.delete(updateWrapper);
+ // roleService.deleteRole("", userName);
+ }
+
+ @Override
+ public List getUserLikeUsername(String userName) {
+ LambdaQueryWrapper queryWrapper = Wrappers.lambdaQuery(UserInfo.class)
+ .like(UserInfo::getUserName, userName)
+ .select(UserInfo::getUserName);
+
+ List userInfos = userMapper.selectList(queryWrapper);
+ List userNames = userInfos.stream().map(UserInfo::getUserName).collect(Collectors.toList());
+
+ return userNames;
+ }
+
+ @Override
+ public UserRespDTO getUser(UserReqDTO reqDTO) {
+ Wrapper queryWrapper = Wrappers.lambdaQuery(UserInfo.class).eq(UserInfo::getUserName, reqDTO.getUserName());
+ UserInfo userInfo = userMapper.selectOne(queryWrapper);
+
+ UserRespDTO respUser = Optional.ofNullable(userInfo)
+ .map(each -> BeanUtil.toBean(each, UserRespDTO.class))
+ .orElseThrow(() -> new ServiceException("查询无此用户, 可以尝试清空缓存或退出登录."));
+ return respUser;
+ }
+
+}
diff --git a/hippo4j-auth/src/main/java/cn/hippo4j/auth/toolkit/JwtTokenUtil.java b/hippo4j-auth/src/main/java/cn/hippo4j/auth/toolkit/JwtTokenUtil.java
new file mode 100644
index 00000000..bdcaa95d
--- /dev/null
+++ b/hippo4j-auth/src/main/java/cn/hippo4j/auth/toolkit/JwtTokenUtil.java
@@ -0,0 +1,118 @@
+package cn.hippo4j.auth.toolkit;
+
+import cn.hippo4j.auth.constant.Constants;
+import io.jsonwebtoken.Claims;
+import io.jsonwebtoken.ExpiredJwtException;
+import io.jsonwebtoken.Jwts;
+import io.jsonwebtoken.SignatureAlgorithm;
+
+import java.util.Arrays;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.List;
+
+import static cn.hippo4j.common.constant.Constants.MAP_INITIAL_CAPACITY;
+
+/**
+ * Jwt token util.
+ *
+ * @author chen.ma
+ * @date 2021/11/9 22:43
+ */
+public class JwtTokenUtil {
+
+ public static final String TOKEN_HEADER = "Authorization";
+ public static final String TOKEN_PREFIX = "Bearer ";
+
+ public static final String SECRET = "SecretKey039245678901232039487623456783092349288901402967890140939827";
+ public static final String ISS = "admin";
+
+ /**
+ * 角色的 Key
+ */
+ private static final String ROLE_CLAIMS = "rol";
+
+ /**
+ * 过期时间是 3600 秒, 既 24 小时
+ */
+ private static final long EXPIRATION = 86400L;
+
+ /**
+ * 选择了记住我之后的过期时间为 7 天
+ */
+ private static final long EXPIRATION_REMEMBER = 7 * EXPIRATION;
+
+ /**
+ * 创建 Token.
+ *
+ * @param id
+ * @param username
+ * @param role
+ * @param isRememberMe
+ * @return
+ */
+ public static String createToken(Long id, String username, String role, boolean isRememberMe) {
+ long expiration = isRememberMe ? EXPIRATION_REMEMBER : EXPIRATION;
+ HashMap map = new HashMap(MAP_INITIAL_CAPACITY);
+ map.put(ROLE_CLAIMS, role);
+ return Jwts.builder()
+ .signWith(SignatureAlgorithm.HS512, SECRET)
+ .setClaims(map)
+ .setIssuer(ISS)
+ .setSubject(id + Constants.SPLIT_COMMA + username)
+ .setIssuedAt(new Date())
+ .setExpiration(new Date(System.currentTimeMillis() + expiration * 1000))
+ .compact();
+ }
+
+ /**
+ * Token 中获取用户名.
+ *
+ * @param token
+ * @return
+ */
+ public static String getUsername(String token) {
+ List userInfo = Arrays.asList(getTokenBody(token).getSubject().split(Constants.SPLIT_COMMA));
+ return userInfo.get(1);
+ }
+
+ /**
+ * Token 中获取用户名.
+ *
+ * @param token
+ * @return
+ */
+ public static Integer getUserId(String token) {
+ List userInfo = Arrays.asList(getTokenBody(token).getSubject().split(Constants.SPLIT_COMMA));
+ return Integer.parseInt(userInfo.get(0));
+ }
+
+ /**
+ * 获取用户角色.
+ *
+ * @param token
+ * @return
+ */
+ public static String getUserRole(String token) {
+ return (String) getTokenBody(token).get(ROLE_CLAIMS);
+ }
+
+ /**
+ * 是否已过期.
+ *
+ * @param token
+ * @return
+ */
+ public static boolean isExpiration(String token) {
+ try {
+ return getTokenBody(token).getExpiration().before(new Date());
+ } catch (ExpiredJwtException e) {
+ return true;
+ }
+ }
+
+ private static Claims getTokenBody(String token) {
+ return Jwts.parser().setSigningKey(SECRET).parseClaimsJws(token).getBody();
+ }
+
+}
diff --git a/hippo4j-auth/src/main/java/cn/hippo4j/auth/toolkit/ReturnT.java b/hippo4j-auth/src/main/java/cn/hippo4j/auth/toolkit/ReturnT.java
new file mode 100644
index 00000000..f46e4de8
--- /dev/null
+++ b/hippo4j-auth/src/main/java/cn/hippo4j/auth/toolkit/ReturnT.java
@@ -0,0 +1,40 @@
+package cn.hippo4j.auth.toolkit;
+
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.io.Serializable;
+
+/**
+ * ReturnT.
+ *
+ * @author chen.ma
+ * @date 2021/11/10 00:00
+ */
+@Data
+@NoArgsConstructor
+public class ReturnT implements Serializable {
+
+ public static final long serialVersionUID = 42L;
+
+ public static final int SUCCESS_CODE = 200;
+ public static final int FAIL_CODE = 500;
+
+ public static final ReturnT SUCCESS = new ReturnT<>(null);
+ public static final ReturnT FAIL = new ReturnT<>(FAIL_CODE, null);
+
+ private int code;
+ private String msg;
+ private T content;
+
+ public ReturnT(int code, String msg) {
+ this.code = code;
+ this.msg = msg;
+ }
+
+ public ReturnT(T content) {
+ this.code = SUCCESS_CODE;
+ this.content = content;
+ }
+
+}
diff --git a/common/.gitignore b/hippo4j-common/.gitignore
similarity index 100%
rename from common/.gitignore
rename to hippo4j-common/.gitignore
diff --git a/dynamic-threadpool-spring-boot-starter/pom.xml b/hippo4j-common/pom.xml
similarity index 67%
rename from dynamic-threadpool-spring-boot-starter/pom.xml
rename to hippo4j-common/pom.xml
index a5bef1b2..2564b9e0 100644
--- a/dynamic-threadpool-spring-boot-starter/pom.xml
+++ b/hippo4j-common/pom.xml
@@ -4,16 +4,16 @@
4.0.0
- com.github.dynamic-threadpool
- parent
+ cn.hippo4j
+ hippo4j-all
${revision}
- dynamic-threadpool-spring-boot-starter
+ hippo4j-common
jar
${project.artifactId}
- ${project.artifactId}
+ HIPPO4J、HIPPO4J-CORE 公共代码库.
@@ -22,49 +22,36 @@
- org.springframework.boot
- spring-boot-starter-web
-
-
-
- cn.hutool
- hutool-all
-
-
-
- com.squareup.okhttp3
- logging-interceptor
-
-
-
- com.alibaba
- fastjson
+ org.projectlombok
+ lombok
- com.github.dynamic-threadpool
- common
+ org.springframework.boot
+ spring-boot-starter-json
- org.springframework.boot
- spring-boot-configuration-processor
- true
+ com.google.guava
+ guava
- org.projectlombok
- lombok
+ cn.hutool
+ hutool-all
com.aliyun
alibaba-dingtalk-service-sdk
-
-
-
- com.google.guava
- guava
+
+
+
+ log4j
+ log4j
+
+
+ true
@@ -84,6 +71,19 @@
+
+
+ org.apache.maven.plugins
+ maven-javadoc-plugin
+ 2.10.3
+
+
+
+ jar
+
+
+
+
diff --git a/hippo4j-common/src/main/java/cn/hippo4j/common/api/ClientCloseHookExecute.java b/hippo4j-common/src/main/java/cn/hippo4j/common/api/ClientCloseHookExecute.java
new file mode 100644
index 00000000..05746360
--- /dev/null
+++ b/hippo4j-common/src/main/java/cn/hippo4j/common/api/ClientCloseHookExecute.java
@@ -0,0 +1,42 @@
+package cn.hippo4j.common.api;
+
+import lombok.Data;
+import lombok.experimental.Accessors;
+
+/**
+ * Client close hook execute.
+ *
+ * @author chen.ma
+ * @date 2022/1/6 22:14
+ */
+public interface ClientCloseHookExecute {
+
+ /**
+ * Client close hook function execution.
+ *
+ * @param req
+ */
+ void closeHook(ClientCloseHookReq req);
+
+ @Data
+ @Accessors(chain = true)
+ class ClientCloseHookReq {
+
+ /**
+ * appName
+ */
+ private String appName;
+
+ /**
+ * instanceId
+ */
+ private String instanceId;
+
+ /**
+ * groupKey
+ */
+ private String groupKey;
+
+ }
+
+}
diff --git a/hippo4j-common/src/main/java/cn/hippo4j/common/api/JsonFacade.java b/hippo4j-common/src/main/java/cn/hippo4j/common/api/JsonFacade.java
new file mode 100644
index 00000000..566bbb71
--- /dev/null
+++ b/hippo4j-common/src/main/java/cn/hippo4j/common/api/JsonFacade.java
@@ -0,0 +1,41 @@
+package cn.hippo4j.common.api;
+
+import java.util.List;
+
+/**
+ * Json facade.
+ *
+ * @author chen.ma
+ * @date 2021/12/13 20:01
+ */
+public interface JsonFacade {
+
+ /**
+ * To JSON string.
+ *
+ * @param object
+ * @return
+ */
+ String toJSONString(Object object);
+
+ /**
+ * Parse object.
+ *
+ * @param text
+ * @param clazz
+ * @param
+ * @return
+ */
+ T parseObject(String text, Class clazz);
+
+ /**
+ * Parse array.
+ *
+ * @param text
+ * @param clazz
+ * @param
+ * @return
+ */
+ List parseArray(String text, Class clazz);
+
+}
diff --git a/hippo4j-common/src/main/java/cn/hippo4j/common/api/NotifyConfigBuilder.java b/hippo4j-common/src/main/java/cn/hippo4j/common/api/NotifyConfigBuilder.java
new file mode 100644
index 00000000..951b91b0
--- /dev/null
+++ b/hippo4j-common/src/main/java/cn/hippo4j/common/api/NotifyConfigBuilder.java
@@ -0,0 +1,23 @@
+package cn.hippo4j.common.api;
+
+import cn.hippo4j.common.notify.NotifyConfigDTO;
+
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Notify config builder.
+ *
+ * @author chen.ma
+ * @date 2022/2/24 19:50
+ */
+public interface NotifyConfigBuilder {
+
+ /**
+ * Build notify.
+ *
+ * @return
+ */
+ Map> buildNotify();
+
+}
diff --git a/hippo4j-common/src/main/java/cn/hippo4j/common/api/ThreadDetailState.java b/hippo4j-common/src/main/java/cn/hippo4j/common/api/ThreadDetailState.java
new file mode 100644
index 00000000..a6bb2523
--- /dev/null
+++ b/hippo4j-common/src/main/java/cn/hippo4j/common/api/ThreadDetailState.java
@@ -0,0 +1,32 @@
+package cn.hippo4j.common.api;
+
+import cn.hippo4j.common.model.ThreadDetailStateInfo;
+
+import java.util.List;
+import java.util.concurrent.ThreadPoolExecutor;
+
+/**
+ * Get thread status in thread pool.
+ *
+ * @author chen.ma
+ * @date 2022/1/9 12:47
+ */
+public interface ThreadDetailState {
+
+ /**
+ * Get thread status in thread pool.
+ *
+ * @param threadPoolId
+ * @return
+ */
+ List getThreadDetailStateInfo(String threadPoolId);
+
+ /**
+ * Get thread status in thread pool.
+ *
+ * @param threadPoolExecutor
+ * @return
+ */
+ List getThreadDetailStateInfo(ThreadPoolExecutor threadPoolExecutor);
+
+}
diff --git a/hippo4j-common/src/main/java/cn/hippo4j/common/api/ThreadPoolDynamicRefresh.java b/hippo4j-common/src/main/java/cn/hippo4j/common/api/ThreadPoolDynamicRefresh.java
new file mode 100644
index 00000000..0f2733da
--- /dev/null
+++ b/hippo4j-common/src/main/java/cn/hippo4j/common/api/ThreadPoolDynamicRefresh.java
@@ -0,0 +1,18 @@
+package cn.hippo4j.common.api;
+
+/**
+ * Thread pool dynamic refresh.
+ *
+ * @author chen.ma
+ * @date 2022/2/26 12:26
+ */
+public interface ThreadPoolDynamicRefresh {
+
+ /**
+ * Dynamic refresh.
+ *
+ * @param content
+ */
+ void dynamicRefresh(String content);
+
+}
diff --git a/common/src/main/java/com/github/dynamic/threadpool/common/config/ApplicationContextHolder.java b/hippo4j-common/src/main/java/cn/hippo4j/common/config/ApplicationContextHolder.java
similarity index 97%
rename from common/src/main/java/com/github/dynamic/threadpool/common/config/ApplicationContextHolder.java
rename to hippo4j-common/src/main/java/cn/hippo4j/common/config/ApplicationContextHolder.java
index f12df7e4..574366ec 100644
--- a/common/src/main/java/com/github/dynamic/threadpool/common/config/ApplicationContextHolder.java
+++ b/hippo4j-common/src/main/java/cn/hippo4j/common/config/ApplicationContextHolder.java
@@ -1,4 +1,4 @@
-package com.github.dynamic.threadpool.common.config;
+package cn.hippo4j.common.config;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
diff --git a/common/src/main/java/com/github/dynamic/threadpool/common/constant/Constants.java b/hippo4j-common/src/main/java/cn/hippo4j/common/constant/Constants.java
similarity index 54%
rename from common/src/main/java/com/github/dynamic/threadpool/common/constant/Constants.java
rename to hippo4j-common/src/main/java/cn/hippo4j/common/constant/Constants.java
index cc40c294..1b482c4e 100644
--- a/common/src/main/java/com/github/dynamic/threadpool/common/constant/Constants.java
+++ b/hippo4j-common/src/main/java/cn/hippo4j/common/constant/Constants.java
@@ -1,4 +1,4 @@
-package com.github.dynamic.threadpool.common.constant;
+package cn.hippo4j.common.constant;
/**
* Constants.
@@ -14,10 +14,20 @@ public class Constants {
public static final String NAMESPACE = "namespace";
+ public static final String GROUP_KEY = "groupKey";
+
+ public static final String AUTHORITIES_KEY = "auth";
+
+ public static final String ACCESS_TOKEN = "accessToken";
+
+ public static final String TOKEN_TTL = "tokenTtl";
+
public static final String DEFAULT_NAMESPACE_ID = "public";
public static final String NULL = "";
+ public static final String UP = "UP";
+
public static final String ENCODE = "UTF-8";
public static final int CONFIG_LONG_POLL_TIMEOUT = 30000;
@@ -28,28 +38,52 @@ public class Constants {
public static final String GENERAL_SPLIT_SYMBOL = ",";
+ public static final String IDENTIFY_SLICER_SYMBOL = "_";
+
public static final String LONG_POLLING_LINE_SEPARATOR = "\r\n";
- public static final String BASE_PATH = "/v1/cs";
+ public static final String BASE_PATH = "/hippo4j/v1/cs";
public static final String CONFIG_CONTROLLER_PATH = BASE_PATH + "/configs";
public static final String LISTENER_PATH = CONFIG_CONTROLLER_PATH + "/listener";
+ public static final String MONITOR_PATH = BASE_PATH + "/monitor";
+
+ public static final String HEALTH_CHECK_PATH = BASE_PATH + "/health/check";
+
public static final String PROBE_MODIFY_REQUEST = "Listening-Configs";
public static final String LONG_PULLING_TIMEOUT = "Long-Pulling-Timeout";
public static final String LONG_PULLING_TIMEOUT_NO_HANGUP = "Long-Pulling-Timeout-No-Hangup";
+ public static final String LONG_PULLING_CLIENT_IDENTIFICATION = "Long-Pulling-Client-Identification";
+
public static final String LISTENING_CONFIGS = "Listening-Configs";
+ public static final String WEIGHT_CONFIGS = "Weight-Configs";
+
public static final String GROUP_KEY_DELIMITER = "+";
+ public static final String GROUP_KEY_DELIMITER_TRANSLATION = "\\+";
+
public static final long EVICTION_INTERVAL_TIMER_IN_MS = 60 * 1000;
public static final int SCHEDULED_THREAD_CORE_NUM = 1;
public static final int MAP_INITIAL_CAPACITY = 16;
+ public static final int HEALTH_CHECK_INTERVAL = 5;
+
+ public static final int AVAILABLE_PROCESSORS = Runtime.getRuntime().availableProcessors();
+
+ public static final String DEFAULT_GROUP = "default group";
+
+ public static final String UNKNOWN = "unknown";
+
+ public static final String EXECUTE_TIMEOUT_TRACE = "executeTimeoutTrace";
+
+ public static final int HTTP_EXECUTE_TIMEOUT = 5000;
+
}
diff --git a/dynamic-threadpool-spring-boot-starter/src/main/java/com/github/dynamic/threadpool/starter/toolkit/thread/Builder.java b/hippo4j-common/src/main/java/cn/hippo4j/common/design/builder/Builder.java
similarity index 80%
rename from dynamic-threadpool-spring-boot-starter/src/main/java/com/github/dynamic/threadpool/starter/toolkit/thread/Builder.java
rename to hippo4j-common/src/main/java/cn/hippo4j/common/design/builder/Builder.java
index 6f78b19e..d787ef53 100644
--- a/dynamic-threadpool-spring-boot-starter/src/main/java/com/github/dynamic/threadpool/starter/toolkit/thread/Builder.java
+++ b/hippo4j-common/src/main/java/cn/hippo4j/common/design/builder/Builder.java
@@ -1,4 +1,4 @@
-package com.github.dynamic.threadpool.starter.toolkit.thread;
+package cn.hippo4j.common.design.builder;
import java.io.Serializable;
diff --git a/hippo4j-common/src/main/java/cn/hippo4j/common/design/observer/AbstractSubjectCenter.java b/hippo4j-common/src/main/java/cn/hippo4j/common/design/observer/AbstractSubjectCenter.java
new file mode 100644
index 00000000..7c176edb
--- /dev/null
+++ b/hippo4j-common/src/main/java/cn/hippo4j/common/design/observer/AbstractSubjectCenter.java
@@ -0,0 +1,134 @@
+package cn.hippo4j.common.design.observer;
+
+import cn.hippo4j.common.toolkit.CollectionUtil;
+import cn.hippo4j.common.toolkit.StringUtil;
+import lombok.extern.slf4j.Slf4j;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+/**
+ * Send observer notification.
+ *
+ * @author chen.ma
+ * @date 2021/12/25 19:47
+ */
+@Slf4j
+public class AbstractSubjectCenter {
+
+ private static final Map> OBSERVERS_MAP = new ConcurrentHashMap();
+
+ /**
+ * Register observer.
+ *
+ * @param observer
+ */
+ public static void register(Observer observer) {
+ register(SubjectType.SPRING_CONTENT_REFRESHED.name(), observer);
+ }
+
+ /**
+ * Register observer.
+ *
+ * @param subjectType
+ * @param observer
+ */
+ public static void register(SubjectType subjectType, Observer observer) {
+ register(subjectType.name(), observer);
+ }
+
+ /**
+ * Register observer.
+ *
+ * @param subject
+ * @param observer
+ */
+ public static void register(String subject, Observer observer) {
+ if (StringUtil.isBlank(subject) || observer == null) {
+ log.warn("Register observer. A string whose subject or observer is empty or empty.");
+ return;
+ }
+
+ List observers = OBSERVERS_MAP.get(subject);
+ if (CollectionUtil.isEmpty(observers)) {
+ observers = new ArrayList();
+ }
+
+ observers.add(observer);
+ OBSERVERS_MAP.put(subject, observers);
+ }
+
+ /**
+ * Remove observer.
+ *
+ * @param observer
+ */
+ public static void remove(Observer observer) {
+ remove(SubjectType.SPRING_CONTENT_REFRESHED.name(), observer);
+ }
+
+ /**
+ * Remove observer.
+ *
+ * @param subject
+ * @param observer
+ */
+ public static void remove(String subject, Observer observer) {
+ List observers;
+ if (StringUtil.isBlank(subject) || CollectionUtil.isEmpty((observers = OBSERVERS_MAP.get(subject))) || observer == null) {
+ log.warn("Remove observer. A string whose subject or observer is empty or empty.");
+ return;
+ }
+
+ observers.remove(observer);
+ }
+
+ /**
+ * Notify.
+ *
+ * @param subjectType
+ * @param observerMessage
+ */
+ public static void notify(SubjectType subjectType, ObserverMessage observerMessage) {
+ notify(subjectType.name(), observerMessage);
+ }
+
+ /**
+ * Notify.
+ *
+ * @param subject
+ * @param observerMessage
+ */
+ public static void notify(String subject, ObserverMessage observerMessage) {
+ List observers = OBSERVERS_MAP.get(subject);
+ if (CollectionUtil.isEmpty(observers)) {
+ log.warn("Under the subject, there is no observer group.");
+ return;
+ }
+
+ observers.parallelStream().forEach(each -> {
+ try {
+ each.accept(observerMessage);
+ } catch (Exception ex) {
+ log.error("Notification subject :: {} observer exception", subject);
+ }
+ });
+ }
+
+ public enum SubjectType {
+
+ /**
+ * Spring content refreshed.
+ */
+ SPRING_CONTENT_REFRESHED,
+
+ /**
+ * Clear config cache.
+ */
+ CLEAR_CONFIG_CACHE
+
+ }
+
+}
diff --git a/hippo4j-common/src/main/java/cn/hippo4j/common/design/observer/Observer.java b/hippo4j-common/src/main/java/cn/hippo4j/common/design/observer/Observer.java
new file mode 100644
index 00000000..a8dbc17f
--- /dev/null
+++ b/hippo4j-common/src/main/java/cn/hippo4j/common/design/observer/Observer.java
@@ -0,0 +1,18 @@
+package cn.hippo4j.common.design.observer;
+
+/**
+ * Observer.
+ *
+ * @author chen.ma
+ * @date 2021/12/25 19:46
+ */
+public interface Observer {
+
+ /**
+ * Receive notification.
+ *
+ * @param observerMessage
+ */
+ void accept(ObserverMessage observerMessage);
+
+}
diff --git a/hippo4j-common/src/main/java/cn/hippo4j/common/design/observer/ObserverMessage.java b/hippo4j-common/src/main/java/cn/hippo4j/common/design/observer/ObserverMessage.java
new file mode 100644
index 00000000..9e9895b5
--- /dev/null
+++ b/hippo4j-common/src/main/java/cn/hippo4j/common/design/observer/ObserverMessage.java
@@ -0,0 +1,18 @@
+package cn.hippo4j.common.design.observer;
+
+/**
+ * Message notifying observer.
+ *
+ * @author chen.ma
+ * @date 2021/12/25 19:54
+ */
+public interface ObserverMessage {
+
+ /**
+ * Message.
+ *
+ * @return
+ */
+ T message();
+
+}
diff --git a/config/src/main/java/com/github/dynamic/threadpool/config/enums/DelEnum.java b/hippo4j-common/src/main/java/cn/hippo4j/common/enums/DelEnum.java
similarity index 91%
rename from config/src/main/java/com/github/dynamic/threadpool/config/enums/DelEnum.java
rename to hippo4j-common/src/main/java/cn/hippo4j/common/enums/DelEnum.java
index b6250841..7e6848c7 100644
--- a/config/src/main/java/com/github/dynamic/threadpool/config/enums/DelEnum.java
+++ b/hippo4j-common/src/main/java/cn/hippo4j/common/enums/DelEnum.java
@@ -1,4 +1,4 @@
-package com.github.dynamic.threadpool.config.enums;
+package cn.hippo4j.common.enums;
/**
* Del enum.
diff --git a/hippo4j-common/src/main/java/cn/hippo4j/common/enums/EnableEnum.java b/hippo4j-common/src/main/java/cn/hippo4j/common/enums/EnableEnum.java
new file mode 100644
index 00000000..81c1b1c4
--- /dev/null
+++ b/hippo4j-common/src/main/java/cn/hippo4j/common/enums/EnableEnum.java
@@ -0,0 +1,46 @@
+package cn.hippo4j.common.enums;
+
+import java.util.Objects;
+
+/**
+ * Enable enum.
+ *
+ * @author chen.ma
+ * @date 2021/12/21 20:34
+ */
+public enum EnableEnum {
+
+ /**
+ * True.
+ */
+ YES("1"),
+
+ /**
+ * False.
+ */
+ NO("0");
+
+ private final String statusCode;
+
+ EnableEnum(String statusCode) {
+ this.statusCode = statusCode;
+ }
+
+ public String getCode() {
+ return this.statusCode;
+ }
+
+ public Integer getIntCode() {
+ return Integer.parseInt(this.statusCode);
+ }
+
+ @Override
+ public String toString() {
+ return statusCode;
+ }
+
+ public static boolean getBool(Integer intStatusCode) {
+ return Objects.equals(intStatusCode, EnableEnum.YES.getIntCode()) ? true : false;
+ }
+
+}
diff --git a/common/src/main/java/com/github/dynamic/threadpool/common/executor/ExecutorFactory.java b/hippo4j-common/src/main/java/cn/hippo4j/common/executor/ExecutorFactory.java
similarity index 93%
rename from common/src/main/java/com/github/dynamic/threadpool/common/executor/ExecutorFactory.java
rename to hippo4j-common/src/main/java/cn/hippo4j/common/executor/ExecutorFactory.java
index 7f5ef744..cebe8a40 100644
--- a/common/src/main/java/com/github/dynamic/threadpool/common/executor/ExecutorFactory.java
+++ b/hippo4j-common/src/main/java/cn/hippo4j/common/executor/ExecutorFactory.java
@@ -1,4 +1,4 @@
-package com.github.dynamic.threadpool.common.executor;
+package cn.hippo4j.common.executor;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
diff --git a/common/src/main/java/com/github/dynamic/threadpool/common/executor/ThreadPoolManager.java b/hippo4j-common/src/main/java/cn/hippo4j/common/executor/ThreadPoolManager.java
similarity index 96%
rename from common/src/main/java/com/github/dynamic/threadpool/common/executor/ThreadPoolManager.java
rename to hippo4j-common/src/main/java/cn/hippo4j/common/executor/ThreadPoolManager.java
index d2262a39..0670aa95 100644
--- a/common/src/main/java/com/github/dynamic/threadpool/common/executor/ThreadPoolManager.java
+++ b/hippo4j-common/src/main/java/cn/hippo4j/common/executor/ThreadPoolManager.java
@@ -1,4 +1,4 @@
-package com.github.dynamic.threadpool.common.executor;
+package cn.hippo4j.common.executor;
import java.util.HashMap;
import java.util.HashSet;
diff --git a/hippo4j-common/src/main/java/cn/hippo4j/common/function/Matcher.java b/hippo4j-common/src/main/java/cn/hippo4j/common/function/Matcher.java
new file mode 100644
index 00000000..92810bfa
--- /dev/null
+++ b/hippo4j-common/src/main/java/cn/hippo4j/common/function/Matcher.java
@@ -0,0 +1,20 @@
+package cn.hippo4j.common.function;
+
+/**
+ * Matcher.
+ *
+ * @author chen.ma
+ * @date 2022/1/9 13:29
+ */
+@FunctionalInterface
+public interface Matcher {
+
+ /**
+ * Match.
+ *
+ * @param t
+ * @return
+ */
+ boolean match(T t);
+
+}
diff --git a/hippo4j-common/src/main/java/cn/hippo4j/common/function/NoArgsConsumer.java b/hippo4j-common/src/main/java/cn/hippo4j/common/function/NoArgsConsumer.java
new file mode 100644
index 00000000..c8fe64ae
--- /dev/null
+++ b/hippo4j-common/src/main/java/cn/hippo4j/common/function/NoArgsConsumer.java
@@ -0,0 +1,17 @@
+package cn.hippo4j.common.function;
+
+/**
+ * 无参消费者.
+ *
+ * @author chen.ma
+ * @date 2021/11/9 00:06
+ */
+@FunctionalInterface
+public interface NoArgsConsumer {
+
+ /**
+ * 方法执行
+ */
+ void accept();
+
+}
diff --git a/common/src/main/java/com/github/dynamic/threadpool/common/model/GlobalRemotePoolInfo.java b/hippo4j-common/src/main/java/cn/hippo4j/common/model/GlobalRemotePoolInfo.java
similarity index 95%
rename from common/src/main/java/com/github/dynamic/threadpool/common/model/GlobalRemotePoolInfo.java
rename to hippo4j-common/src/main/java/cn/hippo4j/common/model/GlobalRemotePoolInfo.java
index ef20d99a..a9f64620 100644
--- a/common/src/main/java/com/github/dynamic/threadpool/common/model/GlobalRemotePoolInfo.java
+++ b/hippo4j-common/src/main/java/cn/hippo4j/common/model/GlobalRemotePoolInfo.java
@@ -1,4 +1,4 @@
-package com.github.dynamic.threadpool.common.model;
+package cn.hippo4j.common.model;
import lombok.Getter;
import lombok.Setter;
diff --git a/common/src/main/java/com/github/dynamic/threadpool/common/model/InstanceInfo.java b/hippo4j-common/src/main/java/cn/hippo4j/common/model/InstanceInfo.java
similarity index 86%
rename from common/src/main/java/com/github/dynamic/threadpool/common/model/InstanceInfo.java
rename to hippo4j-common/src/main/java/cn/hippo4j/common/model/InstanceInfo.java
index 88cb054d..d5d7e526 100644
--- a/common/src/main/java/com/github/dynamic/threadpool/common/model/InstanceInfo.java
+++ b/hippo4j-common/src/main/java/cn/hippo4j/common/model/InstanceInfo.java
@@ -1,4 +1,4 @@
-package com.github.dynamic.threadpool.common.model;
+package cn.hippo4j.common.model;
import lombok.Data;
import lombok.Getter;
@@ -24,6 +24,8 @@ public class InstanceInfo {
private String hostName;
+ private String groupKey;
+
private String port;
private String instanceId;
@@ -34,6 +36,10 @@ public class InstanceInfo {
private String callBackUrl;
+ private String identify;
+
+ private String active;
+
private volatile String vipAddress;
private volatile String secureVipAddress;
@@ -95,14 +101,29 @@ public class InstanceInfo {
public enum InstanceStatus {
+ /**
+ * UP
+ */
UP,
+ /**
+ * DOWN
+ */
DOWN,
+ /**
+ * STARTING
+ */
STARTING,
+ /**
+ * OUT_OF_SERVICE
+ */
OUT_OF_SERVICE,
+ /**
+ * UNKNOWN
+ */
UNKNOWN;
public static InstanceStatus toEnum(String s) {
@@ -119,10 +140,19 @@ public class InstanceInfo {
}
public enum ActionType {
+ /**
+ * ADDED
+ */
ADDED,
+ /**
+ * MODIFIED
+ */
MODIFIED,
+ /**
+ * DELETED
+ */
DELETED
}
diff --git a/hippo4j-common/src/main/java/cn/hippo4j/common/model/ManyPoolRunStateInfo.java b/hippo4j-common/src/main/java/cn/hippo4j/common/model/ManyPoolRunStateInfo.java
new file mode 100644
index 00000000..76f205ed
--- /dev/null
+++ b/hippo4j-common/src/main/java/cn/hippo4j/common/model/ManyPoolRunStateInfo.java
@@ -0,0 +1,29 @@
+package cn.hippo4j.common.model;
+
+import lombok.Data;
+
+/**
+ * Many pool run state info.
+ *
+ * @author chen.ma
+ * @date 2022/1/8 12:54
+ */
+@Data
+public class ManyPoolRunStateInfo extends PoolRunStateInfo {
+
+ /**
+ * identify
+ */
+ private String identify;
+
+ /**
+ * active
+ */
+ private String active;
+
+ /**
+ * state
+ */
+ private String state;
+
+}
diff --git a/hippo4j-common/src/main/java/cn/hippo4j/common/model/PoolBaseInfo.java b/hippo4j-common/src/main/java/cn/hippo4j/common/model/PoolBaseInfo.java
new file mode 100644
index 00000000..9217821a
--- /dev/null
+++ b/hippo4j-common/src/main/java/cn/hippo4j/common/model/PoolBaseInfo.java
@@ -0,0 +1,46 @@
+package cn.hippo4j.common.model;
+
+import lombok.Data;
+import lombok.experimental.Accessors;
+
+/**
+ * Pool base info.
+ *
+ * @author chen.ma
+ * @date 2022/1/22 12:10
+ */
+@Data
+@Accessors(chain = true)
+public class PoolBaseInfo {
+
+ /**
+ * coreSize
+ */
+ private Integer coreSize;
+
+ /**
+ * maximumSize
+ */
+ private Integer maximumSize;
+
+ /**
+ * queueType
+ */
+ private String queueType;
+
+ /**
+ * queueCapacity
+ */
+ private Integer queueCapacity;
+
+ /**
+ * rejectedName
+ */
+ private String rejectedName;
+
+ /**
+ * keepAliveTime
+ */
+ private Long keepAliveTime;
+
+}
diff --git a/common/src/main/java/com/github/dynamic/threadpool/common/model/PoolParameter.java b/hippo4j-common/src/main/java/cn/hippo4j/common/model/PoolParameter.java
similarity index 88%
rename from common/src/main/java/com/github/dynamic/threadpool/common/model/PoolParameter.java
rename to hippo4j-common/src/main/java/cn/hippo4j/common/model/PoolParameter.java
index e46e4504..c21e380d 100644
--- a/common/src/main/java/com/github/dynamic/threadpool/common/model/PoolParameter.java
+++ b/hippo4j-common/src/main/java/cn/hippo4j/common/model/PoolParameter.java
@@ -1,4 +1,4 @@
-package com.github.dynamic.threadpool.common.model;
+package cn.hippo4j.common.model;
/**
* Pool parameter.
@@ -92,4 +92,11 @@ public interface PoolParameter {
*/
Integer getLivenessAlarm();
+ /**
+ * allowCoreThreadTimeOut
+ *
+ * @return
+ */
+ Integer getAllowCoreThreadTimeOut();
+
}
diff --git a/common/src/main/java/com/github/dynamic/threadpool/common/model/PoolParameterInfo.java b/hippo4j-common/src/main/java/cn/hippo4j/common/model/PoolParameterInfo.java
similarity index 90%
rename from common/src/main/java/com/github/dynamic/threadpool/common/model/PoolParameterInfo.java
rename to hippo4j-common/src/main/java/cn/hippo4j/common/model/PoolParameterInfo.java
index 18e5a354..5eaf0020 100644
--- a/common/src/main/java/com/github/dynamic/threadpool/common/model/PoolParameterInfo.java
+++ b/hippo4j-common/src/main/java/cn/hippo4j/common/model/PoolParameterInfo.java
@@ -1,4 +1,4 @@
-package com.github.dynamic.threadpool.common.model;
+package cn.hippo4j.common.model;
import lombok.Data;
import lombok.experimental.Accessors;
@@ -82,4 +82,9 @@ public class PoolParameterInfo implements PoolParameter, Serializable {
*/
private Integer livenessAlarm;
+ /**
+ * allowCoreThreadTimeOut
+ */
+ private Integer allowCoreThreadTimeOut;
+
}
diff --git a/common/src/main/java/com/github/dynamic/threadpool/common/model/PoolRunStateInfo.java b/hippo4j-common/src/main/java/cn/hippo4j/common/model/PoolRunStateInfo.java
similarity index 60%
rename from common/src/main/java/com/github/dynamic/threadpool/common/model/PoolRunStateInfo.java
rename to hippo4j-common/src/main/java/cn/hippo4j/common/model/PoolRunStateInfo.java
index f2915c93..b29bcb2b 100644
--- a/common/src/main/java/com/github/dynamic/threadpool/common/model/PoolRunStateInfo.java
+++ b/hippo4j-common/src/main/java/cn/hippo4j/common/model/PoolRunStateInfo.java
@@ -1,4 +1,4 @@
-package com.github.dynamic.threadpool.common.model;
+package cn.hippo4j.common.model;
import lombok.Getter;
import lombok.Setter;
@@ -13,7 +13,7 @@ import java.io.Serializable;
*/
@Getter
@Setter
-public class PoolRunStateInfo implements Serializable {
+public class PoolRunStateInfo extends PoolBaseInfo implements Serializable {
/**
* currentLoad
@@ -31,14 +31,9 @@ public class PoolRunStateInfo implements Serializable {
private String tpId;
/**
- * coreSize
+ * activeCount
*/
- private Integer coreSize;
-
- /**
- * maximumSize
- */
- private Integer maximumSize;
+ private Integer activeCount;
/**
* poolSize
@@ -55,16 +50,6 @@ public class PoolRunStateInfo implements Serializable {
*/
private Integer largestPoolSize;
- /**
- * queueType
- */
- private String queueType;
-
- /**
- * queueCapacity
- */
- private Integer queueCapacity;
-
/**
* queueSize
*/
@@ -83,11 +68,39 @@ public class PoolRunStateInfo implements Serializable {
/**
* rejectCount
*/
- private Integer rejectCount;
+ private Long rejectCount;
/**
* host
*/
private String host;
+ /**
+ * memoryProportion
+ */
+ private String memoryProportion;
+
+ /**
+ * freeMemory
+ */
+ private String freeMemory;
+
+ /**
+ * clientLastRefreshTime
+ */
+ private String clientLastRefreshTime;
+
+ /**
+ * timestamp
+ */
+ private Long timestamp;
+
+ public Integer getSimpleCurrentLoad() {
+ return Integer.parseInt(getCurrentLoad().replace("%", ""));
+ }
+
+ public Integer getSimplePeakLoad() {
+ return Integer.parseInt(getPeakLoad().replace("%", ""));
+ }
+
}
diff --git a/hippo4j-common/src/main/java/cn/hippo4j/common/model/ThreadDetailStateInfo.java b/hippo4j-common/src/main/java/cn/hippo4j/common/model/ThreadDetailStateInfo.java
new file mode 100644
index 00000000..72663bd9
--- /dev/null
+++ b/hippo4j-common/src/main/java/cn/hippo4j/common/model/ThreadDetailStateInfo.java
@@ -0,0 +1,38 @@
+package cn.hippo4j.common.model;
+
+import lombok.Data;
+import lombok.experimental.Accessors;
+
+import java.util.List;
+
+/**
+ * Thread detail state info.
+ *
+ * @author chen.ma
+ * @date 2022/1/9 12:36
+ */
+@Data
+@Accessors(chain = true)
+public class ThreadDetailStateInfo {
+
+ /**
+ * threadId
+ */
+ private Long threadId;
+
+ /**
+ * threadName
+ */
+ private String threadName;
+
+ /**
+ * threadStatus
+ */
+ private String threadStatus;
+
+ /**
+ * threadStack
+ */
+ private List threadStack;
+
+}
diff --git a/hippo4j-common/src/main/java/cn/hippo4j/common/model/TokenInfo.java b/hippo4j-common/src/main/java/cn/hippo4j/common/model/TokenInfo.java
new file mode 100644
index 00000000..81a2a2eb
--- /dev/null
+++ b/hippo4j-common/src/main/java/cn/hippo4j/common/model/TokenInfo.java
@@ -0,0 +1,28 @@
+package cn.hippo4j.common.model;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * Token info.
+ *
+ * @author chen.ma
+ * @date 2021/12/20 20:02
+ */
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+public class TokenInfo {
+
+ /**
+ * accessToken
+ */
+ private String accessToken;
+
+ /**
+ * tokenTtl
+ */
+ private Long tokenTtl;
+
+}
diff --git a/hippo4j-common/src/main/java/cn/hippo4j/common/monitor/AbstractMessage.java b/hippo4j-common/src/main/java/cn/hippo4j/common/monitor/AbstractMessage.java
new file mode 100644
index 00000000..201c48da
--- /dev/null
+++ b/hippo4j-common/src/main/java/cn/hippo4j/common/monitor/AbstractMessage.java
@@ -0,0 +1,33 @@
+package cn.hippo4j.common.monitor;
+
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.util.List;
+
+/**
+ * Base message.
+ *
+ * @author chen.ma
+ * @date 2021/12/7 20:31
+ */
+@Data
+@NoArgsConstructor
+public abstract class AbstractMessage implements Message {
+
+ /**
+ * groupKey: tenant + item + tpId + identify
+ */
+ private String groupKey;
+
+ /**
+ * messageTypeEnum
+ */
+ private MessageTypeEnum messageType;
+
+ /**
+ * message
+ */
+ private List messages;
+
+}
diff --git a/hippo4j-common/src/main/java/cn/hippo4j/common/monitor/Message.java b/hippo4j-common/src/main/java/cn/hippo4j/common/monitor/Message.java
new file mode 100644
index 00000000..70de9bdd
--- /dev/null
+++ b/hippo4j-common/src/main/java/cn/hippo4j/common/monitor/Message.java
@@ -0,0 +1,35 @@
+package cn.hippo4j.common.monitor;
+
+import java.io.Serializable;
+import java.util.List;
+
+/**
+ * Abstract message monitoring interface.
+ *
+ * @author chen.ma
+ * @date 2021/12/6 20:16
+ */
+public interface Message extends Serializable {
+
+ /**
+ * Get groupKey.
+ *
+ * @return
+ */
+ String getGroupKey();
+
+ /**
+ * Get message type.
+ *
+ * @return
+ */
+ MessageTypeEnum getMessageType();
+
+ /**
+ * Get messages.
+ *
+ * @return
+ */
+ List getMessages();
+
+}
diff --git a/hippo4j-common/src/main/java/cn/hippo4j/common/monitor/MessageRequest.java b/hippo4j-common/src/main/java/cn/hippo4j/common/monitor/MessageRequest.java
new file mode 100644
index 00000000..8ca09d64
--- /dev/null
+++ b/hippo4j-common/src/main/java/cn/hippo4j/common/monitor/MessageRequest.java
@@ -0,0 +1,35 @@
+package cn.hippo4j.common.monitor;
+
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Message request.
+ *
+ * @author chen.ma
+ * @date 2021/12/10 21:17
+ */
+public interface MessageRequest {
+
+ /**
+ * Get content params.
+ *
+ * @return
+ */
+ List