diff --git a/pigx-visual/pigx-seata-server/pom.xml b/pigx-visual/pigx-seata-server/pom.xml
index 26d7f66dc..9ca5fbb5d 100644
--- a/pigx-visual/pigx-seata-server/pom.xml
+++ b/pigx-visual/pigx-seata-server/pom.xml
@@ -28,111 +28,171 @@
pigx-seata-server
- 1.4.2
+ 1.6.1
6.5
0.2.0-RC2
1.72
27.0.1-jre
+
+
+
+
+ io.seata
+ seata-dependencies
+ ${seata.version}
+ pom
+ import
+
+
+
+
+
-
- io.seata
- seata-core
- ${seata.version}
-
-
- io.seata
- seata-config-all
- ${seata.version}
-
-
- io.seata
- seata-discovery-all
- ${seata.version}
-
-
- io.seata
- seata-serializer-all
- ${seata.version}
-
-
- io.seata
- seata-compressor-all
- ${seata.version}
-
+
+ io.seata
+ seata-spring-autoconfigure-server
+ ${seata.version}
+
-
- io.seata
- seata-metrics-all
- ${seata.version}
-
+
+ io.seata
+ seata-core
+ ${seata.version}
+
+
+ io.seata
+ seata-config-all
+ ${seata.version}
+
+
+ log4j
+ log4j
+
+
+
+
+ io.seata
+ seata-discovery-all
+ ${seata.version}
+
+
+ io.seata
+ seata-serializer-all
+ ${seata.version}
+
+
+ io.seata
+ seata-compressor-all
+ ${seata.version}
+
-
-
- com.alibaba
- druid
-
-
- org.apache.commons
- commons-dbcp2
-
-
- com.zaxxer
- HikariCP
-
-
- com.h2database
- h2
-
-
- mysql
- mysql-connector-java
-
-
- org.postgresql
- postgresql
-
-
- com.beust
- jcommander
- ${jcommander.version}
-
+
+ io.seata
+ seata-metrics-all
+ ${seata.version}
+
-
-
- com.google.guava
- guava
- ${guava.version}
-
+
+ io.seata
+ seata-console
+ ${seata.version}
+
-
-
- ch.qos.logback
- logback-classic
-
+
+
+ com.alibaba
+ druid
+
+
+ org.apache.commons
+ commons-dbcp2
+
+
+ com.zaxxer
+ HikariCP
+
+
+ com.h2database
+ h2
+
+
+
+ mysql
+ mysql-connector-java
+
+
+ org.postgresql
+ postgresql
+
+
-
-
- redis.clients
- jedis
-
+
+ com.beust
+ jcommander
+
+
+
+
+ com.google.guava
+ guava
+
+
+
+
+ redis.clients
+ jedis
+
+
+
+ com.github.microwww
+ redis-server
+ test
+
+
+
+ com.alibaba
+ fastjson
+
+
+
+
+ ch.qos.logback
+ logback-classic
+
+
+ ch.qos.logback
+ logback-core
+
+
+
+ net.logstash.logback
+ logstash-logback-encoder
+
+
+ com.github.danielwegener
+ logback-kafka-appender
+
+
+
+
+ org.springframework.boot
+ spring-boot-starter-web
+
+
+
+ org.springframework.boot
+ spring-boot-starter-undertow
+
-
- com.alibaba
- fastjson
-
-
- net.logstash.logback
- logstash-logback-encoder
- ${logstash-logback-encoder.version}
-
-
- com.github.danielwegener
- logback-kafka-appender
- ${kafka-appender.version}
-
diff --git a/pigx-visual/pigx-seata-server/src/main/java/io/seata/server/AbstractTCInboundHandler.java b/pigx-visual/pigx-seata-server/src/main/java/io/seata/server/AbstractTCInboundHandler.java
index 4ba44b6af..c824abf66 100644
--- a/pigx-visual/pigx-seata-server/src/main/java/io/seata/server/AbstractTCInboundHandler.java
+++ b/pigx-visual/pigx-seata-server/src/main/java/io/seata/server/AbstractTCInboundHandler.java
@@ -20,25 +20,7 @@ import io.seata.core.exception.AbstractExceptionHandler;
import io.seata.core.exception.TransactionException;
import io.seata.core.exception.TransactionExceptionCode;
import io.seata.core.model.GlobalStatus;
-import io.seata.core.protocol.transaction.AbstractGlobalEndRequest;
-import io.seata.core.protocol.transaction.AbstractGlobalEndResponse;
-import io.seata.core.protocol.transaction.BranchRegisterRequest;
-import io.seata.core.protocol.transaction.BranchRegisterResponse;
-import io.seata.core.protocol.transaction.BranchReportRequest;
-import io.seata.core.protocol.transaction.BranchReportResponse;
-import io.seata.core.protocol.transaction.GlobalBeginRequest;
-import io.seata.core.protocol.transaction.GlobalBeginResponse;
-import io.seata.core.protocol.transaction.GlobalCommitRequest;
-import io.seata.core.protocol.transaction.GlobalCommitResponse;
-import io.seata.core.protocol.transaction.GlobalLockQueryRequest;
-import io.seata.core.protocol.transaction.GlobalLockQueryResponse;
-import io.seata.core.protocol.transaction.GlobalReportRequest;
-import io.seata.core.protocol.transaction.GlobalReportResponse;
-import io.seata.core.protocol.transaction.GlobalRollbackRequest;
-import io.seata.core.protocol.transaction.GlobalRollbackResponse;
-import io.seata.core.protocol.transaction.GlobalStatusRequest;
-import io.seata.core.protocol.transaction.GlobalStatusResponse;
-import io.seata.core.protocol.transaction.TCInboundHandler;
+import io.seata.core.protocol.transaction.*;
import io.seata.core.rpc.RpcContext;
import io.seata.server.session.GlobalSession;
import io.seata.server.session.SessionHolder;
diff --git a/pigx-visual/pigx-seata-server/src/main/java/io/seata/server/ParameterParser.java b/pigx-visual/pigx-seata-server/src/main/java/io/seata/server/ParameterParser.java
index e3a533e70..4c9d21f22 100644
--- a/pigx-visual/pigx-seata-server/src/main/java/io/seata/server/ParameterParser.java
+++ b/pigx-visual/pigx-seata-server/src/main/java/io/seata/server/ParameterParser.java
@@ -19,12 +19,11 @@ import com.beust.jcommander.JCommander;
import com.beust.jcommander.Parameter;
import com.beust.jcommander.ParameterException;
import io.seata.common.util.StringUtils;
+import io.seata.config.Configuration;
import io.seata.config.ConfigurationFactory;
-import io.seata.core.constants.ConfigurationKeys;
import io.seata.server.env.ContainerHelper;
+import io.seata.server.store.StoreConfig;
-import static io.seata.common.DefaultValues.SERVER_DEFAULT_PORT;
-import static io.seata.common.DefaultValues.SERVER_DEFAULT_STORE_MODE;
import static io.seata.config.ConfigurationFactory.ENV_PROPERTY_KEY;
/**
@@ -36,6 +35,8 @@ public class ParameterParser {
private static final String PROGRAM_NAME = "sh seata-server.sh(for linux and mac) or cmd seata-server.bat(for windows)";
+ private static final Configuration CONFIG = ConfigurationFactory.getInstance();
+
@Parameter(names = "--help", help = true)
private boolean help;
@@ -43,9 +44,9 @@ public class ParameterParser {
private String host;
@Parameter(names = { "--port", "-p" }, description = "The port to listen.", order = 2)
- private int port = SERVER_DEFAULT_PORT;
+ private int port;
- @Parameter(names = { "--storeMode", "-m" }, description = "log store mode : file, db", order = 3)
+ @Parameter(names = { "--storeMode", "-m" }, description = "log store mode : file, db, redis", order = 3)
private String storeMode;
@Parameter(names = { "--serverNode", "-n" },
@@ -57,39 +58,33 @@ public class ParameterParser {
order = 5)
private String seataEnv;
+ @Parameter(names = { "--sessionStoreMode", "-ssm" }, description = "session log store mode : file, db, redis",
+ order = 6)
+ private String sessionStoreMode;
+
+ @Parameter(names = { "--lockStoreMode", "-lsm" }, description = "lock log store mode : file, db, redis", order = 7)
+ private String lockStoreMode;
+
/**
* Instantiates a new Parameter parser.
* @param args the args
*/
- public ParameterParser(String[] args) {
+ public ParameterParser(String... args) {
this.init(args);
}
+ /**
+ * startup args > docker env
+ * @param args
+ */
private void init(String[] args) {
try {
- if (ContainerHelper.isRunningInContainer()) {
- this.seataEnv = ContainerHelper.getEnv();
- this.host = ContainerHelper.getHost();
- this.port = ContainerHelper.getPort();
- this.serverNode = ContainerHelper.getServerNode();
- this.storeMode = ContainerHelper.getStoreMode();
- }
- else {
- JCommander jCommander = JCommander.newBuilder().addObject(this).build();
- jCommander.parse(args);
- if (help) {
- jCommander.setProgramName(PROGRAM_NAME);
- jCommander.usage();
- System.exit(0);
- }
- }
+ getCommandParameters(args);
+ getEnvParameters();
if (StringUtils.isNotBlank(seataEnv)) {
System.setProperty(ENV_PROPERTY_KEY, seataEnv);
}
- if (StringUtils.isBlank(storeMode)) {
- storeMode = ConfigurationFactory.getInstance().getConfig(ConfigurationKeys.STORE_MODE,
- SERVER_DEFAULT_STORE_MODE);
- }
+ StoreConfig.setStartupParameter(storeMode, sessionStoreMode, lockStoreMode);
}
catch (ParameterException e) {
printError(e);
@@ -97,6 +92,31 @@ public class ParameterParser {
}
+ private void getCommandParameters(String[] args) {
+ JCommander jCommander = JCommander.newBuilder().addObject(this).build();
+ jCommander.parse(args);
+ if (help) {
+ jCommander.setProgramName(PROGRAM_NAME);
+ jCommander.usage();
+ System.exit(0);
+ }
+ }
+
+ private void getEnvParameters() {
+ if (StringUtils.isBlank(seataEnv)) {
+ seataEnv = ContainerHelper.getEnv();
+ }
+ if (StringUtils.isBlank(host)) {
+ host = ContainerHelper.getHost();
+ }
+ if (port == 0) {
+ port = ContainerHelper.getPort();
+ }
+ if (serverNode == null) {
+ serverNode = ContainerHelper.getServerNode();
+ }
+ }
+
private void printError(ParameterException e) {
System.err.println("Option error " + e.getMessage());
e.getJCommander().setProgramName(PROGRAM_NAME);
@@ -128,6 +148,22 @@ public class ParameterParser {
return storeMode;
}
+ /**
+ * Gets lock store mode.
+ * @return the store mode
+ */
+ public String getLockStoreMode() {
+ return lockStoreMode;
+ }
+
+ /**
+ * Gets session store mode.
+ * @return the store mode
+ */
+ public String getSessionStoreMode() {
+ return sessionStoreMode;
+ }
+
/**
* Is help boolean.
* @return the boolean
diff --git a/pigx-visual/pigx-seata-server/src/main/java/io/seata/server/PigxSeataServer.java b/pigx-visual/pigx-seata-server/src/main/java/io/seata/server/Server.java
similarity index 63%
rename from pigx-visual/pigx-seata-server/src/main/java/io/seata/server/PigxSeataServer.java
rename to pigx-visual/pigx-seata-server/src/main/java/io/seata/server/Server.java
index 665175b6f..e366d5fda 100644
--- a/pigx-visual/pigx-seata-server/src/main/java/io/seata/server/PigxSeataServer.java
+++ b/pigx-visual/pigx-seata-server/src/main/java/io/seata/server/Server.java
@@ -18,46 +18,34 @@ package io.seata.server;
import io.seata.common.XID;
import io.seata.common.thread.NamedThreadFactory;
import io.seata.common.util.NetUtil;
-import io.seata.core.constants.ConfigurationKeys;
-import io.seata.core.rpc.ShutdownHook;
+import io.seata.common.util.StringUtils;
+import io.seata.config.ConfigurationFactory;
import io.seata.core.rpc.netty.NettyRemotingServer;
import io.seata.core.rpc.netty.NettyServerConfig;
import io.seata.server.coordinator.DefaultCoordinator;
-import io.seata.server.env.ContainerHelper;
-import io.seata.server.env.PortHelper;
+import io.seata.server.lock.LockerManagerFactory;
import io.seata.server.metrics.MetricsManager;
import io.seata.server.session.SessionHolder;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import java.io.IOException;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
+import static io.seata.spring.boot.autoconfigure.StarterConstants.REGEX_SPLIT_CHAR;
+import static io.seata.spring.boot.autoconfigure.StarterConstants.REGISTRY_PREFERED_NETWORKS;
+
/**
* The type Server.
*
* @author slievrly
*/
-public class PigxSeataServer {
+public class Server {
/**
* The entry point of application.
* @param args the input arguments
- * @throws IOException the io exception
*/
- public static void main(String[] args) throws IOException {
- // get port first, use to logback.xml
- int port = PortHelper.getPort(args);
- System.setProperty(ConfigurationKeys.SERVER_PORT, Integer.toString(port));
-
- // create logger
- final Logger logger = LoggerFactory.getLogger(PigxSeataServer.class);
- if (ContainerHelper.isRunningInContainer()) {
- logger.info("The server is running in container.");
- }
-
+ public static void start(String[] args) {
// initialize the parameter parser
// Note that the parameter parser should always be the first line to execute.
// Because, here we need to parse the parameters needed for startup.
@@ -66,46 +54,41 @@ public class PigxSeataServer {
// initialize the metrics
MetricsManager.get().init();
- System.setProperty(ConfigurationKeys.STORE_MODE, parameterParser.getStoreMode());
-
ThreadPoolExecutor workingThreads = new ThreadPoolExecutor(NettyServerConfig.getMinServerPoolSize(),
NettyServerConfig.getMaxServerPoolSize(), NettyServerConfig.getKeepAliveTime(), TimeUnit.SECONDS,
new LinkedBlockingQueue<>(NettyServerConfig.getMaxTaskQueueSize()),
new NamedThreadFactory("ServerHandlerThread", NettyServerConfig.getMaxServerPoolSize()),
new ThreadPoolExecutor.CallerRunsPolicy());
- NettyRemotingServer nettyRemotingServer = new NettyRemotingServer(workingThreads);
- // server port
- nettyRemotingServer.setListenPort(parameterParser.getPort());
- UUIDGenerator.init(parameterParser.getServerNode());
- // log store mode : file, db, redis
- SessionHolder.init(parameterParser.getStoreMode());
-
- DefaultCoordinator coordinator = new DefaultCoordinator(nettyRemotingServer);
- coordinator.init();
- nettyRemotingServer.setHandler(coordinator);
- // register ShutdownHook
- ShutdownHook.getInstance().addDisposable(coordinator);
- ShutdownHook.getInstance().addDisposable(nettyRemotingServer);
-
// 127.0.0.1 and 0.0.0.0 are not valid here.
if (NetUtil.isValidIp(parameterParser.getHost(), false)) {
XID.setIpAddress(parameterParser.getHost());
}
else {
- XID.setIpAddress(NetUtil.getLocalIp());
+ String preferredNetworks = ConfigurationFactory.getInstance().getConfig(REGISTRY_PREFERED_NETWORKS);
+ if (StringUtils.isNotBlank(preferredNetworks)) {
+ XID.setIpAddress(NetUtil.getLocalIp(preferredNetworks.split(REGEX_SPLIT_CHAR)));
+ }
+ else {
+ XID.setIpAddress(NetUtil.getLocalIp());
+ }
}
+
+ NettyRemotingServer nettyRemotingServer = new NettyRemotingServer(workingThreads);
XID.setPort(nettyRemotingServer.getListenPort());
+ UUIDGenerator.init(parameterParser.getServerNode());
+ // log store mode : file, db, redis
+ SessionHolder.init();
+ LockerManagerFactory.init();
+ DefaultCoordinator coordinator = DefaultCoordinator.getInstance(nettyRemotingServer);
+ coordinator.init();
+ nettyRemotingServer.setHandler(coordinator);
- try {
- nettyRemotingServer.init();
- }
- catch (Throwable e) {
- logger.error("nettyServer init error:{}", e.getMessage(), e);
- System.exit(-1);
- }
+ // let ServerRunner do destroy instead ShutdownHook, see
+ // https://github.com/seata/seata/issues/4028
+ ServerRunner.addDisposable(coordinator);
- System.exit(0);
+ nettyRemotingServer.init();
}
}
diff --git a/pigx-visual/pigx-seata-server/src/main/java/io/seata/server/ServerApplication.java b/pigx-visual/pigx-seata-server/src/main/java/io/seata/server/ServerApplication.java
new file mode 100644
index 000000000..536bc3407
--- /dev/null
+++ b/pigx-visual/pigx-seata-server/src/main/java/io/seata/server/ServerApplication.java
@@ -0,0 +1,34 @@
+/*
+ * Copyright 1999-2019 Seata.io Group.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package io.seata.server;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+
+import java.io.IOException;
+
+/**
+ * @author spilledyear@outlook.com
+ */
+@SpringBootApplication(scanBasePackages = { "io.seata" })
+public class ServerApplication {
+
+ public static void main(String[] args) throws IOException {
+ // run the spring-boot application
+ SpringApplication.run(ServerApplication.class, args);
+ }
+
+}
diff --git a/pigx-visual/pigx-seata-server/src/main/java/io/seata/server/ServerApplicationListener.java b/pigx-visual/pigx-seata-server/src/main/java/io/seata/server/ServerApplicationListener.java
new file mode 100644
index 000000000..3c3ddb817
--- /dev/null
+++ b/pigx-visual/pigx-seata-server/src/main/java/io/seata/server/ServerApplicationListener.java
@@ -0,0 +1,129 @@
+/*
+ * Copyright 1999-2019 Seata.io Group.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package io.seata.server;
+
+import io.seata.common.holder.ObjectHolder;
+import io.seata.common.util.StringUtils;
+import io.seata.server.store.StoreConfig;
+import io.seata.spring.boot.autoconfigure.SeataCoreEnvironmentPostProcessor;
+import io.seata.spring.boot.autoconfigure.SeataServerEnvironmentPostProcessor;
+import org.springframework.boot.context.event.ApplicationEnvironmentPreparedEvent;
+import org.springframework.boot.context.logging.LoggingApplicationListener;
+import org.springframework.context.ApplicationEvent;
+import org.springframework.context.event.GenericApplicationListener;
+import org.springframework.core.ResolvableType;
+import org.springframework.core.env.ConfigurableEnvironment;
+import org.springframework.core.env.PropertiesPropertySource;
+
+import java.util.Properties;
+
+import static io.seata.common.Constants.OBJECT_KEY_SPRING_CONFIGURABLE_ENVIRONMENT;
+import static io.seata.common.DefaultValues.SERVICE_OFFSET_SPRING_BOOT;
+import static io.seata.core.constants.ConfigurationKeys.*;
+
+/**
+ * @author slievrly
+ * @author funkye
+ */
+public class ServerApplicationListener implements GenericApplicationListener {
+
+ @Override
+ public boolean supportsEventType(ResolvableType eventType) {
+ return eventType.getRawClass() != null
+ && ApplicationEnvironmentPreparedEvent.class.isAssignableFrom(eventType.getRawClass());
+ }
+
+ @Override
+ public void onApplicationEvent(ApplicationEvent event) {
+ if (!(event instanceof ApplicationEnvironmentPreparedEvent)) {
+ return;
+ }
+ ApplicationEnvironmentPreparedEvent environmentPreparedEvent = (ApplicationEnvironmentPreparedEvent) event;
+ ConfigurableEnvironment environment = environmentPreparedEvent.getEnvironment();
+ ObjectHolder.INSTANCE.setObject(OBJECT_KEY_SPRING_CONFIGURABLE_ENVIRONMENT, environment);
+ SeataCoreEnvironmentPostProcessor.init();
+ SeataServerEnvironmentPostProcessor.init();
+ // Load by priority
+ System.setProperty("sessionMode", StoreConfig.getSessionMode().getName());
+ System.setProperty("lockMode", StoreConfig.getLockMode().getName());
+
+ String[] args = environmentPreparedEvent.getArgs();
+
+ // port: -p > -D > env > yml > default
+
+ // -p 8091
+ if (args != null && args.length >= 2) {
+ for (int i = 0; i < args.length; ++i) {
+ if ("-p".equalsIgnoreCase(args[i]) && i < args.length - 1) {
+ setTargetPort(environment, args[i + 1], true);
+ return;
+ }
+ }
+ }
+
+ // -Dserver.servicePort=8091
+ String dPort = environment.getProperty(SERVER_SERVICE_PORT_CAMEL, String.class);
+ if (StringUtils.isNotBlank(dPort)) {
+ setTargetPort(environment, dPort, true);
+ return;
+ }
+
+ // docker -e SEATA_PORT=8091
+ String envPort = environment.getProperty(ENV_SEATA_PORT_KEY, String.class);
+ if (StringUtils.isNotBlank(envPort)) {
+ setTargetPort(environment, envPort, true);
+ return;
+ }
+
+ // yml properties server.service-port=8091
+ String configPort = environment.getProperty(SERVER_SERVICE_PORT_CONFIG, String.class);
+ if (StringUtils.isNotBlank(configPort)) {
+ setTargetPort(environment, configPort, false);
+ return;
+ }
+
+ // server.port=7091
+ String serverPort = environment.getProperty("server.port", String.class);
+ if (StringUtils.isBlank(serverPort)) {
+ serverPort = "8080";
+ }
+ String servicePort = String.valueOf(Integer.parseInt(serverPort) + SERVICE_OFFSET_SPRING_BOOT);
+ setTargetPort(environment, servicePort, true);
+ }
+
+ private void setTargetPort(ConfigurableEnvironment environment, String port, boolean needAddPropertySource) {
+ // get rpc port first, use to logback-spring.xml, @see the class named
+ // `SystemPropertyLoggerContextListener`
+ System.setProperty(SERVER_SERVICE_PORT_CAMEL, port);
+
+ if (needAddPropertySource) {
+ // add property source to the first position
+ Properties pro = new Properties();
+ pro.setProperty(SERVER_SERVICE_PORT_CONFIG, port);
+ environment.getPropertySources().addFirst(new PropertiesPropertySource("serverProperties", pro));
+ }
+ }
+
+ /**
+ * higher than LoggingApplicationListener
+ * @return the order
+ */
+ @Override
+ public int getOrder() {
+ return LoggingApplicationListener.DEFAULT_ORDER - 1;
+ }
+
+}
diff --git a/pigx-visual/pigx-seata-server/src/main/java/io/seata/server/ServerRunner.java b/pigx-visual/pigx-seata-server/src/main/java/io/seata/server/ServerRunner.java
new file mode 100644
index 000000000..4129b307a
--- /dev/null
+++ b/pigx-visual/pigx-seata-server/src/main/java/io/seata/server/ServerRunner.java
@@ -0,0 +1,81 @@
+/*
+ * Copyright 1999-2019 Seata.io Group.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package io.seata.server;
+
+import io.seata.core.rpc.Disposable;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.DisposableBean;
+import org.springframework.boot.CommandLineRunner;
+import org.springframework.stereotype.Component;
+
+import java.util.List;
+import java.util.concurrent.CopyOnWriteArrayList;
+
+/**
+ * @author spilledyear@outlook.com
+ */
+@Component
+public class ServerRunner implements CommandLineRunner, DisposableBean {
+
+ private static final Logger LOGGER = LoggerFactory.getLogger(ServerRunner.class);
+
+ private boolean started = Boolean.FALSE;
+
+ private static final List DISPOSABLE_LIST = new CopyOnWriteArrayList<>();
+
+ public static void addDisposable(Disposable disposable) {
+ DISPOSABLE_LIST.add(disposable);
+ }
+
+ @Override
+ public void run(String... args) {
+ try {
+ long start = System.currentTimeMillis();
+ Server.start(args);
+ started = true;
+
+ long cost = System.currentTimeMillis() - start;
+ LOGGER.info("seata server started in {} millSeconds", cost);
+ }
+ catch (Throwable e) {
+ started = Boolean.FALSE;
+ LOGGER.error("seata server start error: {} ", e.getMessage(), e);
+ System.exit(-1);
+ }
+ }
+
+ public boolean started() {
+ return started;
+ }
+
+ @Override
+ public void destroy() throws Exception {
+
+ if (LOGGER.isDebugEnabled()) {
+ LOGGER.debug("destoryAll starting");
+ }
+
+ for (Disposable disposable : DISPOSABLE_LIST) {
+ disposable.destroy();
+ }
+
+ if (LOGGER.isDebugEnabled()) {
+ LOGGER.debug("destoryAll finish");
+ }
+ }
+
+}
diff --git a/pigx-visual/pigx-seata-server/src/main/java/io/seata/server/auth/AbstractCheckAuthHandler.java b/pigx-visual/pigx-seata-server/src/main/java/io/seata/server/auth/AbstractCheckAuthHandler.java
index bf0d531b3..ca297602f 100644
--- a/pigx-visual/pigx-seata-server/src/main/java/io/seata/server/auth/AbstractCheckAuthHandler.java
+++ b/pigx-visual/pigx-seata-server/src/main/java/io/seata/server/auth/AbstractCheckAuthHandler.java
@@ -13,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package io.seata.server.auth;
import io.seata.config.ConfigurationFactory;
diff --git a/pigx-visual/pigx-seata-server/src/main/java/io/seata/server/auth/DefaultCheckAuthHandler.java b/pigx-visual/pigx-seata-server/src/main/java/io/seata/server/auth/DefaultCheckAuthHandler.java
index e98da6338..8fe75e898 100644
--- a/pigx-visual/pigx-seata-server/src/main/java/io/seata/server/auth/DefaultCheckAuthHandler.java
+++ b/pigx-visual/pigx-seata-server/src/main/java/io/seata/server/auth/DefaultCheckAuthHandler.java
@@ -13,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package io.seata.server.auth;
import io.seata.common.loader.LoadLevel;
diff --git a/pigx-visual/pigx-seata-server/src/main/java/io/seata/server/console/controller/BranchSessionController.java b/pigx-visual/pigx-seata-server/src/main/java/io/seata/server/console/controller/BranchSessionController.java
new file mode 100644
index 000000000..849343131
--- /dev/null
+++ b/pigx-visual/pigx-seata-server/src/main/java/io/seata/server/console/controller/BranchSessionController.java
@@ -0,0 +1,36 @@
+/*
+ * Copyright 1999-2019 Seata.io Group.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package io.seata.server.console.controller;
+
+import io.seata.server.console.service.BranchSessionService;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import javax.annotation.Resource;
+
+/**
+ * Branch Session Controller
+ *
+ * @author zhongxiang.wang
+ */
+@RestController
+@RequestMapping("console/branchSession")
+public class BranchSessionController {
+
+ @Resource(type = BranchSessionService.class)
+ private BranchSessionService branchSessionService;
+
+}
diff --git a/pigx-visual/pigx-seata-server/src/main/java/io/seata/server/console/controller/GlobalLockController.java b/pigx-visual/pigx-seata-server/src/main/java/io/seata/server/console/controller/GlobalLockController.java
new file mode 100644
index 000000000..1c5034eb7
--- /dev/null
+++ b/pigx-visual/pigx-seata-server/src/main/java/io/seata/server/console/controller/GlobalLockController.java
@@ -0,0 +1,51 @@
+/*
+ * Copyright 1999-2019 Seata.io Group.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package io.seata.server.console.controller;
+
+import io.seata.console.result.PageResult;
+import io.seata.server.console.param.GlobalLockParam;
+import io.seata.server.console.service.GlobalLockService;
+import io.seata.server.console.vo.GlobalLockVO;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.ModelAttribute;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import javax.annotation.Resource;
+
+/**
+ * Global Lock Controller
+ *
+ * @author zhongxiang.wang
+ */
+@RestController
+@RequestMapping("/api/v1/console/globalLock")
+public class GlobalLockController {
+
+ @Resource(type = GlobalLockService.class)
+ private GlobalLockService globalLockService;
+
+ /**
+ * Query locks by param
+ * @param param the param
+ * @return the list of GlobalLockVO
+ */
+ @GetMapping("query")
+ public PageResult query(@ModelAttribute GlobalLockParam param) {
+ return globalLockService.query(param);
+ }
+
+}
diff --git a/pigx-visual/pigx-seata-server/src/main/java/io/seata/server/console/controller/GlobalSessionController.java b/pigx-visual/pigx-seata-server/src/main/java/io/seata/server/console/controller/GlobalSessionController.java
new file mode 100644
index 000000000..0d1bdc95f
--- /dev/null
+++ b/pigx-visual/pigx-seata-server/src/main/java/io/seata/server/console/controller/GlobalSessionController.java
@@ -0,0 +1,51 @@
+/*
+ * Copyright 1999-2019 Seata.io Group.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package io.seata.server.console.controller;
+
+import io.seata.console.result.PageResult;
+import io.seata.server.console.param.GlobalSessionParam;
+import io.seata.server.console.service.GlobalSessionService;
+import io.seata.server.console.vo.GlobalSessionVO;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.ModelAttribute;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import javax.annotation.Resource;
+
+/**
+ * Global Session Controller
+ *
+ * @author zhongxiang.wang
+ */
+@RestController
+@RequestMapping("/api/v1/console/globalSession")
+public class GlobalSessionController {
+
+ @Resource(type = GlobalSessionService.class)
+ private GlobalSessionService globalSessionService;
+
+ /**
+ * Query all globalSession
+ * @param param param for query globalSession
+ * @return the list of GlobalSessionVO
+ */
+ @GetMapping("query")
+ public PageResult query(@ModelAttribute GlobalSessionParam param) {
+ return globalSessionService.query(param);
+ }
+
+}
diff --git a/pigx-visual/pigx-seata-server/src/main/java/io/seata/server/console/impl/db/BranchSessionDBServiceImpl.java b/pigx-visual/pigx-seata-server/src/main/java/io/seata/server/console/impl/db/BranchSessionDBServiceImpl.java
new file mode 100644
index 000000000..a92864bfb
--- /dev/null
+++ b/pigx-visual/pigx-seata-server/src/main/java/io/seata/server/console/impl/db/BranchSessionDBServiceImpl.java
@@ -0,0 +1,104 @@
+/*
+ * Copyright 1999-2019 Seata.io Group.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package io.seata.server.console.impl.db;
+
+import io.seata.common.ConfigurationKeys;
+import io.seata.common.exception.StoreException;
+import io.seata.common.loader.EnhancedServiceLoader;
+import io.seata.common.util.IOUtil;
+import io.seata.common.util.StringUtils;
+import io.seata.config.Configuration;
+import io.seata.config.ConfigurationFactory;
+import io.seata.console.result.PageResult;
+import io.seata.core.store.db.DataSourceProvider;
+import io.seata.core.store.db.sql.log.LogStoreSqlsFactory;
+import io.seata.server.console.service.BranchSessionService;
+import io.seata.server.console.vo.BranchSessionVO;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression;
+import org.springframework.stereotype.Component;
+
+import javax.sql.DataSource;
+import java.sql.Connection;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.util.ArrayList;
+import java.util.List;
+
+import static io.seata.common.DefaultValues.DEFAULT_STORE_DB_BRANCH_TABLE;
+
+/**
+ * Branch Session DataBase ServiceImpl
+ *
+ * @author zhongxiang.wang
+ * @author lvekee 734843455@qq.com
+ */
+@Component
+@org.springframework.context.annotation.Configuration
+@ConditionalOnExpression("#{'db'.equals('${sessionMode}')}")
+public class BranchSessionDBServiceImpl implements BranchSessionService {
+
+ private String branchTable;
+
+ private String dbType;
+
+ private DataSource dataSource;
+
+ public BranchSessionDBServiceImpl() {
+ Configuration configuration = ConfigurationFactory.getInstance();
+ branchTable = configuration.getConfig(ConfigurationKeys.STORE_DB_BRANCH_TABLE, DEFAULT_STORE_DB_BRANCH_TABLE);
+ dbType = configuration.getConfig(ConfigurationKeys.STORE_DB_TYPE);
+ if (StringUtils.isBlank(dbType)) {
+ throw new IllegalArgumentException(ConfigurationKeys.STORE_DB_TYPE + " should not be blank");
+ }
+ String dbDataSource = configuration.getConfig(ConfigurationKeys.STORE_DB_DATASOURCE_TYPE);
+ if (StringUtils.isBlank(dbDataSource)) {
+ throw new IllegalArgumentException(ConfigurationKeys.STORE_DB_DATASOURCE_TYPE + " should not be blank");
+ }
+ dataSource = EnhancedServiceLoader.load(DataSourceProvider.class, dbDataSource).provide();
+ }
+
+ @Override
+ public PageResult queryByXid(String xid) {
+ if (StringUtils.isBlank(xid)) {
+ throw new IllegalArgumentException("xid should not be blank");
+ }
+
+ String whereCondition = " where xid = ? ";
+ String branchSessionSQL = LogStoreSqlsFactory.getLogStoreSqls(dbType).getAllBranchSessionSQL(branchTable,
+ whereCondition);
+
+ List list = new ArrayList<>();
+ ResultSet rs = null;
+
+ try (Connection conn = dataSource.getConnection();
+ PreparedStatement ps = conn.prepareStatement(branchSessionSQL)) {
+ ps.setObject(1, xid);
+ rs = ps.executeQuery();
+ while (rs.next()) {
+ list.add(BranchSessionVO.convert(rs));
+ }
+ }
+ catch (SQLException e) {
+ throw new StoreException(e);
+ }
+ finally {
+ IOUtil.close(rs);
+ }
+ return PageResult.success(list, list.size(), 0, 0, 0);
+ }
+
+}
diff --git a/pigx-visual/pigx-seata-server/src/main/java/io/seata/server/console/impl/db/GlobalLockDBServiceImpl.java b/pigx-visual/pigx-seata-server/src/main/java/io/seata/server/console/impl/db/GlobalLockDBServiceImpl.java
new file mode 100644
index 000000000..fdba6ef35
--- /dev/null
+++ b/pigx-visual/pigx-seata-server/src/main/java/io/seata/server/console/impl/db/GlobalLockDBServiceImpl.java
@@ -0,0 +1,146 @@
+/*
+ * Copyright 1999-2019 Seata.io Group.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package io.seata.server.console.impl.db;
+
+import io.seata.common.ConfigurationKeys;
+import io.seata.common.exception.StoreException;
+import io.seata.common.loader.EnhancedServiceLoader;
+import io.seata.common.util.IOUtil;
+import io.seata.common.util.PageUtil;
+import io.seata.common.util.StringUtils;
+import io.seata.config.Configuration;
+import io.seata.config.ConfigurationFactory;
+import io.seata.console.result.PageResult;
+import io.seata.core.store.db.DataSourceProvider;
+import io.seata.core.store.db.sql.lock.LockStoreSqlFactory;
+import io.seata.server.console.param.GlobalLockParam;
+import io.seata.server.console.service.GlobalLockService;
+import io.seata.server.console.vo.GlobalLockVO;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression;
+import org.springframework.stereotype.Component;
+
+import javax.sql.DataSource;
+import java.sql.Connection;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.util.ArrayList;
+import java.util.List;
+
+import static io.seata.common.DefaultValues.DEFAULT_LOCK_DB_TABLE;
+
+/**
+ * Global Lock DB ServiceImpl
+ *
+ * @author zhongxiang.wang
+ * @author lvekee 734843455@qq.com
+ */
+@Component
+@org.springframework.context.annotation.Configuration
+@ConditionalOnExpression("#{'db'.equals('${lockMode}')}")
+public class GlobalLockDBServiceImpl implements GlobalLockService {
+
+ private String lockTable;
+
+ private String dbType;
+
+ private DataSource dataSource;
+
+ public GlobalLockDBServiceImpl() {
+ Configuration configuration = ConfigurationFactory.getInstance();
+ lockTable = configuration.getConfig(ConfigurationKeys.LOCK_DB_TABLE, DEFAULT_LOCK_DB_TABLE);
+ dbType = configuration.getConfig(ConfigurationKeys.STORE_DB_TYPE);
+ if (StringUtils.isBlank(dbType)) {
+ throw new IllegalArgumentException(ConfigurationKeys.STORE_DB_TYPE + " should not be blank");
+ }
+ String dbDataSource = configuration.getConfig(ConfigurationKeys.STORE_DB_DATASOURCE_TYPE);
+ if (StringUtils.isBlank(dbDataSource)) {
+ throw new IllegalArgumentException(ConfigurationKeys.STORE_DB_DATASOURCE_TYPE + " should not be blank");
+ }
+ dataSource = EnhancedServiceLoader.load(DataSourceProvider.class, dbDataSource).provide();
+ }
+
+ @Override
+ public PageResult query(GlobalLockParam param) {
+ PageUtil.checkParam(param.getPageNum(), param.getPageSize());
+
+ List