All Downloads are FREE. Search and download functionalities are using the official Maven repository.

io.github.icodegarden.nursery.springboot.web.reactive.util.ReactiveWebUtils Maven / Gradle / Ivy

The newest version!
package io.github.icodegarden.nursery.springboot.web.reactive.util;

import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import org.springframework.core.io.buffer.DefaultDataBuffer;
import org.springframework.core.io.buffer.DefaultDataBufferFactory;
import org.springframework.http.HttpHeaders;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;
import org.springframework.web.server.ServerWebExchange;

import io.github.icodegarden.nursery.springboot.web.reactive.factory.ServerInitiatedImmediateSchedulersFactory;
import io.github.icodegarden.nursery.springboot.web.util.BaseWebUtils;
import io.github.icodegarden.nutrient.lang.annotation.Nullable;
import io.github.icodegarden.nutrient.lang.tuple.Tuple2;
import lombok.Getter;
import lombok.extern.slf4j.Slf4j;
import reactor.core.publisher.Mono;
import reactor.core.scheduler.Schedulers;
import reactor.netty.ReactorNetty;

/**
 * 
 * @author Fangfang.Xu
 *
 */
@Slf4j
public class ReactiveWebUtils extends BaseWebUtils {
	private ReactiveWebUtils() {
	}

	private static final ThreadLocal SERVERWEBEXCHANGE_HOLDER = new ThreadLocal<>();

	@Getter
	private static enum ServerType {
		Gateway("500"/* 网关不是计算密集型,数量大比较好,配置成等于xxx.httpclient.pool.max-connections */, "2000"), //
		General("200", "800"), //
		Compute("50", "200"), //
		IO("400", "1600");

		private final String ioSelectCount = Runtime.getRuntime().availableProcessors() == 1 ? "1" : "2";
		private final String ioWorkerCount;
		private final String poolMaxConnections;

		private ServerType(String ioWorkerCount, String poolMaxConnections) {
			this.ioWorkerCount = ioWorkerCount;
			this.poolMaxConnections = poolMaxConnections;
		}
	}

	public static void initGatewayServerConfig() {
		initServerConfig(ServerType.Gateway);
	}

	public static void initGeneralServerConfig() {
		initServerConfig(ServerType.General);
	}

	public static void initComputeServerConfig() {
		initServerConfig(ServerType.Compute);
	}

	public static void initIoServerConfig() {
		initServerConfig(ServerType.IO);
	}

	private static void initServerConfig(ServerType type) {
		// --------------------------------------------------------------------
		String ioSelectCount = System.getProperty(ReactorNetty.IO_SELECT_COUNT);// 默认无
		log.info("found config IO_SELECT_COUNT is {}", ioSelectCount);
		if (!StringUtils.hasText(ioSelectCount)) {
			ioSelectCount = type.getIoSelectCount();
		}
		log.info("use IO_SELECT_COUNT:{}", ioSelectCount);
		System.setProperty(ReactorNetty.IO_SELECT_COUNT, ioSelectCount);

		// --------------------------------------------------------------------
		String ioWorkerCount = System.getProperty(ReactorNetty.IO_WORKER_COUNT);// 默认等于cpu线程数,但最少4
		log.info("found config IO_WORKER_COUNT is {}", ioWorkerCount);
		if (!StringUtils.hasText(ioWorkerCount)) {
			ioWorkerCount = type.getIoWorkerCount();
		}
		log.info("use IO_WORKER_COUNT:{}", ioWorkerCount);
		System.setProperty(ReactorNetty.IO_WORKER_COUNT, ioWorkerCount);

		// --------------------------------------------------------------------
		String poolMaxConnections = System.getProperty(ReactorNetty.POOL_MAX_CONNECTIONS);// 默认等于2*cpu线程数,但最少16
		log.info("found config POOL_MAX_CONNECTIONS is {}", poolMaxConnections);
		if (!StringUtils.hasText(poolMaxConnections)) {
			poolMaxConnections = type.getPoolMaxConnections();
		}
		log.info("use POOL_MAX_CONNECTIONS:{}", poolMaxConnections);
		System.setProperty(ReactorNetty.POOL_MAX_CONNECTIONS, poolMaxConnections);

		// --------------------------------------------------------------------
		/**
		 * 由server.netty.xxx配置
		 */
//		String poolMaxIdleTime = System.getProperty(ReactorNetty.POOL_MAX_IDLE_TIME);// 默认无配置
//		log.info("found config POOL_MAX_IDLE_TIME is {}", poolMaxIdleTime);
//		if (!StringUtils.hasText(poolMaxIdleTime)) {
//			poolMaxIdleTime = "";
//		}
//		log.info("use POOL_MAX_IDLE_TIME:{}", poolMaxIdleTime);
//		System.setProperty(ReactorNetty.POOL_MAX_IDLE_TIME, poolMaxIdleTime);

		// --------------------------------------------------------------------
		/**
		 * 由server.netty.xxx配置
		 */
//		String poolMaxLifeTime = System.getProperty(ReactorNetty.POOL_MAX_LIFE_TIME);// 默认无配置
//		log.info("found config POOL_MAX_LIFE_TIME is {}", poolMaxLifeTime);
//		if (!StringUtils.hasText(poolMaxLifeTime)) {
//			poolMaxLifeTime = "";
//		}
//		log.info("use POOL_MAX_LIFE_TIME:{}", poolMaxLifeTime);
//		System.setProperty(ReactorNetty.POOL_MAX_LIFE_TIME, poolMaxLifeTime);

//        String poolLeasingStrategy = System.getProperty(ReactorNetty.POOL_LEASING_STRATEGY);

		/**
		 * global
		 */
		Schedulers.setFactory(new ServerInitiatedImmediateSchedulersFactory());
	}

	public static ServerWebExchange getExchange() {
		return SERVERWEBEXCHANGE_HOLDER.get();
	}

	public static void setExchange(ServerWebExchange exchange) {
		SERVERWEBEXCHANGE_HOLDER.set(exchange);
	}

	public static List getHeaderNames() {
		ServerWebExchange request = getExchange();
		if (request == null) {
			return Collections.emptyList();
		}

		HttpHeaders headers = request.getRequest().getHeaders();
		return new ArrayList(headers.keySet());
	}

	public static String getHeader(String name) {
		ServerWebExchange request = getExchange();
		if (request == null) {
			return null;
		}

		return request.getRequest().getHeaders().getFirst(name);
	}

	public static String getJWT() {
		String bearerToken = getAuthorizationToken();
		if (bearerToken != null) {
			return resolveBearerToken(bearerToken, " ");
		}
		return null;
	}

	public static void setJWT(String jwt) {
		ServerWebExchange request = getExchange();
		if (request != null) {
			String bearerToken = createBearerToken(jwt, " ");
			request.getAttributes().put(HEADER_AUTHORIZATION, bearerToken);// use for rpc;
		}
	}

	public static String getBasicAuthorizationToken() {
		String basicToken = getAuthorizationToken();
		if (basicToken != null) {
			return resolveBasicToken(basicToken, " ");
		}
		return null;
	}

	public static String getAuthorizationToken() {
		ServerWebExchange request = getExchange();
		if (request == null) {
			return null;
		}
		String authorizationToken = (String) request.getAttribute(HEADER_AUTHORIZATION);
		return authorizationToken != null ? authorizationToken
				: request.getRequest().getHeaders().getFirst(HEADER_AUTHORIZATION);
	}

	public static boolean isApiRpc() {
		ServerWebExchange request = getExchange();
		if (request == null) {
			return false;
		}

		String header = request.getRequest().getHeaders().getFirst(HEADER_API_REQUEST);
		return header != null && Boolean.valueOf(header);
	}

	public static boolean isOpenapiRpc() {
		ServerWebExchange request = getExchange();
		if (request == null) {
			return false;
		}

		String header = request.getRequest().getHeaders().getFirst(HEADER_OPENAPI_REQUEST);
		return header != null && Boolean.valueOf(header);
	}

	public static boolean isInternalRpc() {
		ServerWebExchange request = getExchange();
		if (request == null) {
			return false;
		}

		String header = request.getRequest().getHeaders().getFirst(HEADER_INTERNAL_RPC);
		return header != null && Boolean.valueOf(header);
	}

	public static String getRequestId() {
		ServerWebExchange request = getExchange();
		if (request == null) {
			return null;
		}

		return request.getRequest().getHeaders().getFirst(HEADER_REQUEST_ID);
	}

	public static void responseJWT(String jwt, ServerWebExchange exchange) {
		String bearerToken = createBearerToken(jwt, " ");
		exchange.getResponse().getHeaders().set(HEADER_AUTHORIZATION, bearerToken);
	}

	public static  Mono responseWrite(int status, String body, ServerWebExchange exchange) {
		Assert.hasText(body, "body must not empty");
		return responseWrite(status, null, body, exchange);
	}

	public static  Mono responseWrite(int status, List>> headers,
			ServerWebExchange exchange) {
		Assert.notEmpty(headers, "headers must not empty");
		return responseWrite(status, headers, null, exchange);
	}

	public static  Mono responseWrite(int status, @Nullable List>> headers,
			@Nullable String body, ServerWebExchange exchange) {
		exchange.getResponse().setRawStatusCode(status);
		if (headers != null && !headers.isEmpty()) {
			for (Tuple2> header : headers) {
				for (String value : header.getT2()) {
					exchange.getResponse().getHeaders().add(header.getT1(), value);
				}
			}
		}

		if (body == null) {
			body = "";
		}

		exchange.getResponse().getHeaders().set("Content-Type", "application/json;charset=utf-8");
		DefaultDataBuffer dataBuffer = DefaultDataBufferFactory.sharedInstance
				.wrap(body.getBytes(StandardCharsets.UTF_8));
		return (Mono) exchange.getResponse().writeWith(Mono.just(dataBuffer));
	}
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy