refactor: bug fix and refactor init logic
This commit is contained in:
parent
57caa53015
commit
7586354476
@ -129,8 +129,8 @@
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<configuration>
|
||||
<source>6</source>
|
||||
<target>6</target>
|
||||
<source>7</source>
|
||||
<target>7</target>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
|
@ -54,7 +54,7 @@ public class NacosConfigService implements ConfigService {
|
||||
|
||||
private static final Logger LOGGER = LogUtils.logger(NacosConfigService.class);
|
||||
|
||||
private static final long POST_TIMEOUT = 3000L;
|
||||
private static final long POST_TIMEOUT = 10000L;
|
||||
|
||||
private static final String EMPTY = "";
|
||||
|
||||
|
@ -16,7 +16,7 @@
|
||||
package com.alibaba.nacos.client.config.impl;
|
||||
|
||||
import com.alibaba.nacos.api.config.ConfigChangeItem;
|
||||
import com.alibaba.nacos.client.utils.StringUtils;
|
||||
import com.alibaba.nacos.common.utils.StringUtils;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.StringReader;
|
||||
|
@ -22,6 +22,7 @@ import com.alibaba.nacos.client.config.impl.EventDispatcher.ServerlistChangeEven
|
||||
import com.alibaba.nacos.client.config.impl.HttpSimpleClient.HttpResult;
|
||||
import com.alibaba.nacos.client.utils.*;
|
||||
import com.alibaba.nacos.common.utils.IoUtils;
|
||||
import com.alibaba.nacos.common.utils.StringUtils;
|
||||
import org.slf4j.Logger;
|
||||
|
||||
import java.io.IOException;
|
||||
|
@ -16,7 +16,7 @@
|
||||
package com.alibaba.nacos.client.config.impl;
|
||||
|
||||
import com.alibaba.nacos.api.config.ConfigChangeItem;
|
||||
import com.alibaba.nacos.client.utils.StringUtils;
|
||||
import com.alibaba.nacos.common.utils.StringUtils;
|
||||
import org.yaml.snakeyaml.Yaml;
|
||||
import java.util.*;
|
||||
|
||||
|
@ -16,7 +16,7 @@
|
||||
package com.alibaba.nacos.client.naming.core;
|
||||
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import com.alibaba.nacos.client.utils.StringUtils;
|
||||
import com.alibaba.nacos.common.utils.StringUtils;
|
||||
import com.alibaba.nacos.common.utils.IoUtils;
|
||||
|
||||
import java.net.DatagramPacket;
|
||||
|
@ -20,6 +20,7 @@ import com.alibaba.nacos.api.PropertyKeyConst;
|
||||
import com.alibaba.nacos.api.SystemPropertyKeyConst;
|
||||
import com.alibaba.nacos.api.common.Constants;
|
||||
import com.alibaba.nacos.client.utils.*;
|
||||
import com.alibaba.nacos.common.utils.StringUtils;
|
||||
|
||||
import java.util.Properties;
|
||||
import java.util.concurrent.Callable;
|
||||
|
@ -15,6 +15,8 @@
|
||||
*/
|
||||
package com.alibaba.nacos.client.utils;
|
||||
|
||||
import com.alibaba.nacos.common.utils.StringUtils;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
/**
|
||||
|
@ -15,6 +15,8 @@
|
||||
*/
|
||||
package com.alibaba.nacos.client.utils;
|
||||
|
||||
import com.alibaba.nacos.common.utils.StringUtils;
|
||||
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
|
@ -15,6 +15,8 @@
|
||||
*/
|
||||
package com.alibaba.nacos.client.utils;
|
||||
|
||||
import com.alibaba.nacos.common.utils.StringUtils;
|
||||
|
||||
import java.util.concurrent.Callable;
|
||||
|
||||
/**
|
||||
|
@ -15,6 +15,8 @@
|
||||
*/
|
||||
package com.alibaba.nacos.client.utils;
|
||||
|
||||
import com.alibaba.nacos.common.utils.StringUtils;
|
||||
|
||||
/**
|
||||
* Tenant Util
|
||||
*
|
||||
|
@ -17,6 +17,7 @@
|
||||
package com.alibaba.nacos.client.utils;
|
||||
|
||||
import com.alibaba.nacos.api.PropertyKeyConst;
|
||||
import com.alibaba.nacos.common.utils.StringUtils;
|
||||
|
||||
import java.util.Properties;
|
||||
import java.util.regex.Matcher;
|
||||
|
@ -1,9 +1,6 @@
|
||||
package com.alibaba.nacos.client;
|
||||
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import com.alibaba.nacos.api.common.ResponseCode;
|
||||
import com.alibaba.nacos.api.exception.NacosException;
|
||||
import com.alibaba.nacos.api.naming.CommonParams;
|
||||
import com.alibaba.nacos.client.naming.beat.BeatInfo;
|
||||
import com.alibaba.nacos.client.naming.beat.BeatReactor;
|
||||
import com.alibaba.nacos.client.naming.net.NamingProxy;
|
||||
|
@ -16,12 +16,13 @@
|
||||
|
||||
package com.alibaba.nacos.client.utils;
|
||||
|
||||
import com.alibaba.nacos.common.utils.StringUtils;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
|
||||
import static com.alibaba.nacos.client.utils.StringUtils.*;
|
||||
import static com.alibaba.nacos.common.utils.StringUtils.*;
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
/**
|
||||
|
@ -73,8 +73,8 @@
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<configuration>
|
||||
<source>6</source>
|
||||
<target>6</target>
|
||||
<source>7</source>
|
||||
<target>7</target>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
|
@ -14,10 +14,8 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.alibaba.nacos.core.executor;
|
||||
package com.alibaba.nacos.common.executor;
|
||||
|
||||
import com.alibaba.nacos.common.ThreadPoolManager;
|
||||
import com.alibaba.nacos.common.utils.ShutdownUtils;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.ForkJoinPool;
|
@ -14,7 +14,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.alibaba.nacos.core.executor;
|
||||
package com.alibaba.nacos.common.executor;
|
||||
|
||||
import java.util.concurrent.ThreadFactory;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
@ -13,7 +13,7 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.alibaba.nacos.common;
|
||||
package com.alibaba.nacos.common.executor;
|
||||
|
||||
|
||||
import com.alibaba.nacos.common.utils.ShutdownUtils;
|
||||
@ -69,38 +69,38 @@ public final class ThreadPoolManager {
|
||||
/**
|
||||
* Register the thread pool resources with the resource manager
|
||||
*
|
||||
* @param biz business name
|
||||
* @param resourceName resource name
|
||||
* @param namespace namespace name
|
||||
* @param group group name
|
||||
* @param executor {@link ExecutorService}
|
||||
*/
|
||||
public void register(String biz, String resourceName, ExecutorService executor) {
|
||||
public void register(String namespace, String group, ExecutorService executor) {
|
||||
synchronized(this) {
|
||||
if (!resourcesManager.containsKey(biz)) {
|
||||
resourcesManager.put(biz, new HashMap<String, Set<ExecutorService>>(8));
|
||||
lockers.put(biz, new Object());
|
||||
if (!resourcesManager.containsKey(namespace)) {
|
||||
resourcesManager.put(namespace, new HashMap<String, Set<ExecutorService>>(8));
|
||||
lockers.put(namespace, new Object());
|
||||
}
|
||||
}
|
||||
final Object monitor = lockers.get(biz);
|
||||
final Object monitor = lockers.get(namespace);
|
||||
synchronized (monitor) {
|
||||
Map<String, Set<ExecutorService>> map = resourcesManager.get(biz);
|
||||
if (!map.containsKey(resourceName)) {
|
||||
map.put(resourceName, new HashSet<ExecutorService>());
|
||||
Map<String, Set<ExecutorService>> map = resourcesManager.get(namespace);
|
||||
if (!map.containsKey(group)) {
|
||||
map.put(group, new HashSet<ExecutorService>());
|
||||
}
|
||||
map.get(resourceName).add(executor);
|
||||
map.get(group).add(executor);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Cancel the uniform lifecycle management for all threads under this resource
|
||||
*
|
||||
* @param biz business name
|
||||
* @param resourceName resource name
|
||||
* @param namespace namespace name
|
||||
* @param group group name
|
||||
*/
|
||||
public void deregister(String biz, String resourceName) {
|
||||
if (resourcesManager.containsKey(biz)) {
|
||||
final Object monitor = lockers.get(biz);
|
||||
public void deregister(String namespace, String group) {
|
||||
if (resourcesManager.containsKey(namespace)) {
|
||||
final Object monitor = lockers.get(namespace);
|
||||
synchronized (monitor) {
|
||||
resourcesManager.get(biz).remove(resourceName);
|
||||
resourcesManager.get(namespace).remove(group);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -108,26 +108,26 @@ public final class ThreadPoolManager {
|
||||
/**
|
||||
* Undoing the uniform lifecycle management of {@link ExecutorService} under this resource
|
||||
*
|
||||
* @param biz business name
|
||||
* @param resourceName resource name
|
||||
* @param namespace namespace name
|
||||
* @param group group name
|
||||
* @param executor {@link ExecutorService}
|
||||
*/
|
||||
public synchronized void deregister(String biz, String resourceName, ExecutorService executor) {
|
||||
if (resourcesManager.containsKey(biz)) {
|
||||
final Map<String, Set<ExecutorService>> subResourceMap = resourcesManager.get(biz);
|
||||
if (subResourceMap.containsKey(resourceName)) {
|
||||
subResourceMap.get(resourceName).remove(executor);
|
||||
public synchronized void deregister(String namespace, String group, ExecutorService executor) {
|
||||
if (resourcesManager.containsKey(namespace)) {
|
||||
final Map<String, Set<ExecutorService>> subResourceMap = resourcesManager.get(namespace);
|
||||
if (subResourceMap.containsKey(group)) {
|
||||
subResourceMap.get(group).remove(executor);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public synchronized void destroy(String biz) {
|
||||
final Object monitor = lockers.get(biz);
|
||||
public synchronized void destroy(String namespace) {
|
||||
final Object monitor = lockers.get(namespace);
|
||||
if (monitor == null) {
|
||||
throw new NoSuchElementException("This module does not have any thread pool resources : " + biz);
|
||||
throw new NoSuchElementException("This module does not have any thread pool resources : " + namespace);
|
||||
}
|
||||
synchronized (monitor) {
|
||||
Map<String, Set<ExecutorService>> subResource = resourcesManager.get(biz);
|
||||
Map<String, Set<ExecutorService>> subResource = resourcesManager.get(namespace);
|
||||
if (subResource == null) {
|
||||
return;
|
||||
}
|
||||
@ -137,8 +137,8 @@ public final class ThreadPoolManager {
|
||||
}
|
||||
}
|
||||
|
||||
resourcesManager.get(biz).clear();
|
||||
resourcesManager.remove(biz);
|
||||
resourcesManager.get(namespace).clear();
|
||||
resourcesManager.remove(namespace);
|
||||
|
||||
}
|
||||
}
|
||||
@ -162,8 +162,8 @@ public final class ThreadPoolManager {
|
||||
|
||||
private void destroyAll() {
|
||||
Set<String> bizs = resourcesManager.keySet();
|
||||
for (String biz : bizs) {
|
||||
destroy(biz);
|
||||
for (String namespace : bizs) {
|
||||
destroy(namespace);
|
||||
}
|
||||
}
|
||||
}
|
@ -16,14 +16,11 @@
|
||||
|
||||
package com.alibaba.nacos.common.http;
|
||||
|
||||
import com.alibaba.fastjson.TypeReference;
|
||||
import com.alibaba.nacos.common.http.handler.ResponseHandler;
|
||||
import com.alibaba.nacos.common.http.param.Header;
|
||||
import com.alibaba.nacos.common.http.param.Query;
|
||||
import com.alibaba.nacos.common.model.HttpRestResult;
|
||||
import com.alibaba.nacos.common.model.RestResult;
|
||||
import org.apache.http.HttpResponse;
|
||||
import org.apache.http.HttpStatus;
|
||||
import org.apache.http.client.methods.CloseableHttpResponse;
|
||||
import org.apache.http.client.methods.HttpEntityEnclosingRequestBase;
|
||||
import org.apache.http.client.methods.HttpRequestBase;
|
||||
@ -35,6 +32,7 @@ import org.apache.http.impl.nio.client.CloseableHttpAsyncClient;
|
||||
import org.apache.http.util.EntityUtils;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.Type;
|
||||
import java.net.URI;
|
||||
|
||||
/**
|
||||
@ -42,120 +40,89 @@ import java.net.URI;
|
||||
*/
|
||||
public abstract class BaseHttpClient {
|
||||
|
||||
protected <T> HttpRestResult<T> execute(CloseableHttpClient httpClient,
|
||||
final TypeReference<RestResult<T>> reference,
|
||||
HttpUriRequest request)
|
||||
throws Exception {
|
||||
CloseableHttpResponse response = httpClient.execute(request);
|
||||
try {
|
||||
final String body = EntityUtils.toString(response.getEntity());
|
||||
HttpRestResult<T> resResult = new HttpRestResult<T>();
|
||||
resResult.setCode(response.getStatusLine().getStatusCode());
|
||||
resResult.setHttpCode(response.getStatusLine().getStatusCode());
|
||||
if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
|
||||
RestResult<T> data = ResponseHandler.convert(body, reference);
|
||||
if (data != null && data.getCode() == HttpStatus.SC_OK) {
|
||||
resResult.setCode(data.getCode());
|
||||
resResult.setData(data.getData());
|
||||
return resResult;
|
||||
} else {
|
||||
resResult.setCode(response.getStatusLine().getStatusCode());
|
||||
resResult.setMessage(data != null ? data.getMessage() : "");
|
||||
}
|
||||
} else {
|
||||
resResult.setMessage(body);
|
||||
}
|
||||
resResult.setHeader(convertHeader(response.getAllHeaders()));
|
||||
return resResult;
|
||||
} finally {
|
||||
HttpClientUtils.closeQuietly(response);
|
||||
}
|
||||
}
|
||||
protected <T> RestResult<T> execute(CloseableHttpClient httpClient,
|
||||
final Type type, HttpUriRequest request) throws Exception {
|
||||
CloseableHttpResponse response = httpClient.execute(request);
|
||||
try {
|
||||
final String body = EntityUtils.toString(response.getEntity());
|
||||
RestResult<T> data = ResponseHandler.convert(body, type);
|
||||
return data;
|
||||
}
|
||||
finally {
|
||||
HttpClientUtils.closeQuietly(response);
|
||||
}
|
||||
}
|
||||
|
||||
protected <T> void execute(CloseableHttpAsyncClient httpAsyncClient,
|
||||
final TypeReference<RestResult<T>> reference,
|
||||
final Callback<T> callback,
|
||||
final HttpUriRequest request) {
|
||||
httpAsyncClient.execute(request, new FutureCallback<HttpResponse>() {
|
||||
protected <T> void execute(CloseableHttpAsyncClient httpAsyncClient, final Type type,
|
||||
final Callback<T> callback, final HttpUriRequest request) {
|
||||
httpAsyncClient.execute(request, new FutureCallback<HttpResponse>() {
|
||||
|
||||
@Override
|
||||
public void completed(HttpResponse response) {
|
||||
try {
|
||||
final String body = EntityUtils.toString(response.getEntity());
|
||||
HttpRestResult<T> resResult = new HttpRestResult<T>();
|
||||
resResult.setCode(response.getStatusLine().getStatusCode());
|
||||
resResult.setHttpCode(response.getStatusLine().getStatusCode());
|
||||
if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
|
||||
RestResult<T> data = ResponseHandler.convert(body, reference);
|
||||
if (data != null && data.getCode() == HttpStatus.SC_OK) {
|
||||
resResult.setCode(200);
|
||||
resResult.setData(data.getData());
|
||||
} else {
|
||||
resResult.setCode(response.getStatusLine().getStatusCode());
|
||||
resResult.setMessage(data != null ? data.getMessage() : "");
|
||||
}
|
||||
} else {
|
||||
resResult.setMessage(body);
|
||||
}
|
||||
resResult.setHeader(convertHeader(response.getAllHeaders()));
|
||||
callback.onReceive(resResult);
|
||||
} catch (IOException e) {
|
||||
callback.onError(e);
|
||||
}
|
||||
}
|
||||
@Override
|
||||
public void completed(HttpResponse response) {
|
||||
try {
|
||||
final String body = EntityUtils.toString(response.getEntity());
|
||||
RestResult<T> data = ResponseHandler.convert(body, type);
|
||||
callback.onReceive(data);
|
||||
}
|
||||
catch (IOException e) {
|
||||
callback.onError(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void failed(Exception ex) {
|
||||
callback.onError(ex);
|
||||
}
|
||||
@Override
|
||||
public void failed(Exception ex) {
|
||||
callback.onError(ex);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void cancelled() {
|
||||
@Override
|
||||
public void cancelled() {
|
||||
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
protected String buildUrl(String baseUrl, Query query) {
|
||||
String url = baseUrl + "?" + query.toQueryUrl();
|
||||
return url;
|
||||
}
|
||||
protected String buildUrl(String baseUrl, Query query) {
|
||||
if (query.isEmpty()) {
|
||||
return baseUrl;
|
||||
}
|
||||
return baseUrl + "?" + query.toQueryUrl();
|
||||
}
|
||||
|
||||
protected HttpRequestBase build(String url, Header header, String method) {
|
||||
return build(url, header, null, method);
|
||||
}
|
||||
protected HttpRequestBase build(String url, Header header, String method) {
|
||||
return build(url, header, null, method);
|
||||
}
|
||||
|
||||
protected HttpRequestBase build(String url, Header header, Object body,
|
||||
String method) {
|
||||
protected HttpRequestBase build(String url, Header header, Object body,
|
||||
String method) {
|
||||
|
||||
BaseHttpMethod httpMethod = BaseHttpMethod.sourceOf(method);
|
||||
httpMethod.init(url);
|
||||
httpMethod.initHeader(header);
|
||||
httpMethod.initEntity(body, header.getValue("Content-Type"));
|
||||
return httpMethod.getRequestBase();
|
||||
}
|
||||
BaseHttpMethod httpMethod = BaseHttpMethod.sourceOf(method);
|
||||
httpMethod.init(url);
|
||||
httpMethod.initHeader(header);
|
||||
httpMethod.initEntity(body, header.getValue("Content-Type"));
|
||||
return httpMethod.getRequestBase();
|
||||
}
|
||||
|
||||
private Header convertHeader(org.apache.http.Header[] headers) {
|
||||
final Header nHeader = Header.newInstance();
|
||||
for (org.apache.http.Header header : headers) {
|
||||
nHeader.addParam(header.getName(), header.getValue());
|
||||
}
|
||||
return nHeader;
|
||||
}
|
||||
private Header convertHeader(org.apache.http.Header[] headers) {
|
||||
final Header nHeader = Header.newInstance();
|
||||
for (org.apache.http.Header header : headers) {
|
||||
nHeader.addParam(header.getName(), header.getValue());
|
||||
}
|
||||
return nHeader;
|
||||
}
|
||||
|
||||
public static class HttpGetWithEntity extends HttpEntityEnclosingRequestBase {
|
||||
public static class HttpGetWithEntity extends HttpEntityEnclosingRequestBase {
|
||||
|
||||
public final static String METHOD_NAME = "GET";
|
||||
public final static String METHOD_NAME = "GET";
|
||||
|
||||
public HttpGetWithEntity(String url) {
|
||||
super();
|
||||
setURI(URI.create(url));
|
||||
}
|
||||
public HttpGetWithEntity(String url) {
|
||||
super();
|
||||
setURI(URI.create(url));
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getMethod() {
|
||||
return METHOD_NAME;
|
||||
}
|
||||
}
|
||||
@Override
|
||||
public String getMethod() {
|
||||
return METHOD_NAME;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -176,7 +176,7 @@ public enum BaseHttpMethod {
|
||||
return method;
|
||||
}
|
||||
}
|
||||
throw new IllegalArgumentException("Unsupported http method");
|
||||
throw new IllegalArgumentException("Unsupported http method : " + name);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -16,7 +16,7 @@
|
||||
|
||||
package com.alibaba.nacos.common.http;
|
||||
|
||||
import com.alibaba.nacos.common.model.HttpRestResult;
|
||||
import com.alibaba.nacos.common.model.RestResult;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:liaochuntao@live.com">liaochuntao</a>
|
||||
@ -26,9 +26,9 @@ public interface Callback<T> {
|
||||
/**
|
||||
* Callback after the request is responded
|
||||
*
|
||||
* @param result {@link HttpRestResult}
|
||||
* @param result {@link RestResult}
|
||||
*/
|
||||
void onReceive(HttpRestResult<T> result);
|
||||
void onReceive(RestResult<T> result);
|
||||
|
||||
/**
|
||||
* An error occurred during the request
|
||||
|
@ -25,6 +25,8 @@ import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Use the same HttpClient object in the same space
|
||||
*
|
||||
* @author <a href="mailto:liaochuntao@live.com">liaochuntao</a>
|
||||
*/
|
||||
@SuppressWarnings("all")
|
||||
@ -36,7 +38,7 @@ public class HttpClientManager {
|
||||
|
||||
private static final int TIMEOUT = 5000;
|
||||
|
||||
private static final Map<String, NSyncHttpClient> HTTP_CLIENT_MAP = new HashMap<String, NSyncHttpClient>(
|
||||
private static final Map<String, NSyncHttpClient> HTTP_SYNC_CLIENT_MAP = new HashMap<String, NSyncHttpClient>(
|
||||
8);
|
||||
|
||||
private static final Map<String, NAsyncHttpClient> HTTP_ASYNC_CLIENT_MAP = new HashMap<String, NAsyncHttpClient>(
|
||||
@ -48,7 +50,7 @@ public class HttpClientManager {
|
||||
|
||||
System.out.println("[NSyncHttpClient] Start destroying HttpClient");
|
||||
|
||||
for (Map.Entry<String, NSyncHttpClient> entry : HTTP_CLIENT_MAP
|
||||
for (Map.Entry<String, NSyncHttpClient> entry : HTTP_SYNC_CLIENT_MAP
|
||||
.entrySet()) {
|
||||
try {
|
||||
entry.getValue().close();
|
||||
@ -85,10 +87,10 @@ public class HttpClientManager {
|
||||
private static final RequestConfig DEFAULT_CONFIG = RequestConfig.custom()
|
||||
.setConnectTimeout(TIMEOUT).setSocketTimeout(TIMEOUT << 1).build();
|
||||
|
||||
public static NSyncHttpClient newHttpClient(String owner) {
|
||||
public static NSyncHttpClient newHttpClient(String namespace) {
|
||||
synchronized (SYNC_MONITOR) {
|
||||
|
||||
NSyncHttpClient nSyncHttpClient = HTTP_CLIENT_MAP.get(owner);
|
||||
NSyncHttpClient nSyncHttpClient = HTTP_SYNC_CLIENT_MAP.get(namespace);
|
||||
|
||||
if (nSyncHttpClient != null) {
|
||||
return nSyncHttpClient;
|
||||
@ -96,15 +98,15 @@ public class HttpClientManager {
|
||||
|
||||
nSyncHttpClient = new NacosSyncHttpClient(
|
||||
HttpClients.custom().setDefaultRequestConfig(DEFAULT_CONFIG).build());
|
||||
HTTP_CLIENT_MAP.put(owner, nSyncHttpClient);
|
||||
HTTP_SYNC_CLIENT_MAP.put(namespace, nSyncHttpClient);
|
||||
return nSyncHttpClient;
|
||||
}
|
||||
}
|
||||
|
||||
public static NAsyncHttpClient newAsyncHttpClient(String owner) {
|
||||
public static NAsyncHttpClient newAsyncHttpClient(String namespace) {
|
||||
synchronized (ASYNC_MONITOR) {
|
||||
|
||||
NAsyncHttpClient nAsyncHttpClient = HTTP_ASYNC_CLIENT_MAP.get(owner);
|
||||
NAsyncHttpClient nAsyncHttpClient = HTTP_ASYNC_CLIENT_MAP.get(namespace);
|
||||
|
||||
if (nAsyncHttpClient != null) {
|
||||
return nAsyncHttpClient;
|
||||
@ -113,16 +115,16 @@ public class HttpClientManager {
|
||||
nAsyncHttpClient = new NacosAsyncHttpClient(
|
||||
HttpAsyncClients.custom().setDefaultRequestConfig(DEFAULT_CONFIG)
|
||||
.build());
|
||||
HTTP_ASYNC_CLIENT_MAP.put(owner, nAsyncHttpClient);
|
||||
HTTP_ASYNC_CLIENT_MAP.put(namespace, nAsyncHttpClient);
|
||||
return nAsyncHttpClient;
|
||||
}
|
||||
}
|
||||
|
||||
public static NSyncHttpClient newHttpClient(String owner,
|
||||
public static NSyncHttpClient newHttpClient(String namespace,
|
||||
RequestConfig requestConfig) {
|
||||
synchronized (SYNC_MONITOR) {
|
||||
|
||||
NSyncHttpClient nSyncHttpClient = HTTP_CLIENT_MAP.get(owner);
|
||||
NSyncHttpClient nSyncHttpClient = HTTP_SYNC_CLIENT_MAP.get(namespace);
|
||||
|
||||
if (nSyncHttpClient != null) {
|
||||
return nSyncHttpClient;
|
||||
@ -130,15 +132,15 @@ public class HttpClientManager {
|
||||
|
||||
nSyncHttpClient = new NacosSyncHttpClient(
|
||||
HttpClients.custom().setDefaultRequestConfig(requestConfig).build());
|
||||
HTTP_CLIENT_MAP.put(owner, nSyncHttpClient);
|
||||
HTTP_SYNC_CLIENT_MAP.put(namespace, nSyncHttpClient);
|
||||
return nSyncHttpClient;
|
||||
}
|
||||
}
|
||||
|
||||
public static NAsyncHttpClient newAsyncHttpClient(String owner,
|
||||
public static NAsyncHttpClient newAsyncHttpClient(String namespace,
|
||||
RequestConfig requestConfig) {
|
||||
synchronized (ASYNC_MONITOR) {
|
||||
NAsyncHttpClient nAsyncHttpClient = HTTP_ASYNC_CLIENT_MAP.get(owner);
|
||||
NAsyncHttpClient nAsyncHttpClient = HTTP_ASYNC_CLIENT_MAP.get(namespace);
|
||||
|
||||
if (nAsyncHttpClient != null) {
|
||||
return nAsyncHttpClient;
|
||||
@ -147,8 +149,9 @@ public class HttpClientManager {
|
||||
nAsyncHttpClient = new NacosAsyncHttpClient(
|
||||
HttpAsyncClients.custom().setDefaultRequestConfig(requestConfig)
|
||||
.build());
|
||||
HTTP_ASYNC_CLIENT_MAP.put(owner, nAsyncHttpClient);
|
||||
HTTP_ASYNC_CLIENT_MAP.put(namespace, nAsyncHttpClient);
|
||||
return nAsyncHttpClient;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -16,7 +16,7 @@
|
||||
|
||||
package com.alibaba.nacos.common.http;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import com.alibaba.nacos.common.utils.StringUtils;
|
||||
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.net.URLEncoder;
|
||||
@ -24,12 +24,16 @@ import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:liaochuntao@live.com">liaochuntao</a>
|
||||
*/
|
||||
public final class HttpUtils {
|
||||
|
||||
private static final Pattern CONTEXT_PATH_MATCH = Pattern.compile("(\\/)\\1+");
|
||||
|
||||
public static String buildUrl(boolean isHttps, String serverAddr, String... subPaths) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
if (isHttps) {
|
||||
@ -38,12 +42,31 @@ public final class HttpUtils {
|
||||
sb.append("http://");
|
||||
}
|
||||
sb.append(serverAddr);
|
||||
String pre = null;
|
||||
for (String subPath : subPaths) {
|
||||
if (subPath.startsWith("/")) {
|
||||
sb.append(subPath);
|
||||
} else {
|
||||
sb.append("/").append(subPath);
|
||||
if (StringUtils.isBlank(subPath)) {
|
||||
continue;
|
||||
}
|
||||
Matcher matcher = CONTEXT_PATH_MATCH.matcher(subPath);
|
||||
if (matcher.find()) {
|
||||
throw new IllegalArgumentException("Illegal url path expression : " + subPath);
|
||||
}
|
||||
if (pre == null || !pre.endsWith("/")) {
|
||||
if (subPath.startsWith("/")) {
|
||||
sb.append(subPath);
|
||||
}
|
||||
else {
|
||||
sb.append("/").append(subPath);
|
||||
}
|
||||
} else {
|
||||
if (subPath.startsWith("/")) {
|
||||
sb.append(subPath.replaceFirst("\\/", ""));
|
||||
}
|
||||
else {
|
||||
sb.append(subPath);
|
||||
}
|
||||
}
|
||||
pre = subPath;
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
@ -16,11 +16,10 @@
|
||||
|
||||
package com.alibaba.nacos.common.http;
|
||||
|
||||
import com.alibaba.fastjson.TypeReference;
|
||||
import com.alibaba.nacos.common.http.param.Header;
|
||||
import com.alibaba.nacos.common.http.param.Query;
|
||||
import com.alibaba.nacos.common.model.HttpRestResult;
|
||||
import com.alibaba.nacos.common.model.RestResult;
|
||||
|
||||
import java.lang.reflect.Type;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:liaochuntao@live.com">liaochuntao</a>
|
||||
@ -35,10 +34,10 @@ public interface NAsyncHttpClient extends NHttpClient {
|
||||
* @param header http header param
|
||||
* @param query http query param
|
||||
* @param token return type
|
||||
* @param callback {@link Callback#onReceive(HttpRestResult)}
|
||||
* @param callback {@link Callback#onReceive(com.alibaba.nacos.common.model.RestResult)}
|
||||
*/
|
||||
<T> void get(String url, Header header, Query query,
|
||||
TypeReference<RestResult<T>> token, Callback<T> callback);
|
||||
Type token, Callback<T> callback);
|
||||
|
||||
/**
|
||||
* get request, may be pulling a lot of data
|
||||
@ -48,10 +47,10 @@ public interface NAsyncHttpClient extends NHttpClient {
|
||||
* @param query http query param
|
||||
* @param body get with body
|
||||
* @param token return type
|
||||
* @param callback {@link Callback#onReceive(HttpRestResult)}
|
||||
* @param callback {@link Callback#onReceive(com.alibaba.nacos.common.model.RestResult)}
|
||||
*/
|
||||
<T> void getLarge(String url, Header header, Query query, Object body,
|
||||
TypeReference<RestResult<T>> token,
|
||||
Type token,
|
||||
Callback<T> callback);
|
||||
|
||||
/**
|
||||
@ -61,10 +60,10 @@ public interface NAsyncHttpClient extends NHttpClient {
|
||||
* @param header http header param
|
||||
* @param query http query param
|
||||
* @param token return type
|
||||
* @param callback {@link Callback#onReceive(HttpRestResult)}
|
||||
* @param callback {@link Callback#onReceive(com.alibaba.nacos.common.model.RestResult)}
|
||||
*/
|
||||
<T> void delete(String url, Header header, Query query,
|
||||
TypeReference<RestResult<T>> token, Callback<T> callback);
|
||||
Type token, Callback<T> callback);
|
||||
|
||||
/**
|
||||
* http put
|
||||
@ -74,10 +73,10 @@ public interface NAsyncHttpClient extends NHttpClient {
|
||||
* @param query http query param
|
||||
* @param body http body param
|
||||
* @param token return type
|
||||
* @param callback {@link Callback#onReceive(HttpRestResult)}
|
||||
* @param callback {@link Callback#onReceive(com.alibaba.nacos.common.model.RestResult)}
|
||||
*/
|
||||
<T> void put(String url, Header header, Query query, Object body,
|
||||
TypeReference<RestResult<T>> token, Callback<T> callback);
|
||||
Type token, Callback<T> callback);
|
||||
|
||||
/**
|
||||
* http post
|
||||
@ -87,9 +86,9 @@ public interface NAsyncHttpClient extends NHttpClient {
|
||||
* @param query http query param
|
||||
* @param body http body param
|
||||
* @param token return type
|
||||
* @param callback {@link Callback#onReceive(HttpRestResult)}
|
||||
* @param callback {@link Callback#onReceive(com.alibaba.nacos.common.model.RestResult)}
|
||||
*/
|
||||
<T> void post(String url, Header header, Query query, Object body,
|
||||
TypeReference<RestResult<T>> token, Callback<T> callback);
|
||||
Type token, Callback<T> callback);
|
||||
|
||||
}
|
||||
|
@ -16,11 +16,12 @@
|
||||
|
||||
package com.alibaba.nacos.common.http;
|
||||
|
||||
import com.alibaba.fastjson.TypeReference;
|
||||
import com.alibaba.nacos.common.http.param.Header;
|
||||
import com.alibaba.nacos.common.http.param.Query;
|
||||
import com.alibaba.nacos.common.model.RestResult;
|
||||
|
||||
import java.lang.reflect.Type;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:liaochuntao@live.com">liaochuntao</a>
|
||||
*/
|
||||
@ -38,7 +39,7 @@ public interface NSyncHttpClient extends NHttpClient {
|
||||
* @throws Exception
|
||||
*/
|
||||
<T> RestResult<T> get(String url, Header header, Query query,
|
||||
TypeReference<RestResult<T>> token) throws Exception;
|
||||
Type token) throws Exception;
|
||||
|
||||
/**
|
||||
* get request, may be pulling a lot of data
|
||||
@ -52,7 +53,7 @@ public interface NSyncHttpClient extends NHttpClient {
|
||||
* @throws Exception
|
||||
*/
|
||||
<T> RestResult<T> getLarge(String url, Header header, Query query, Object body,
|
||||
TypeReference<RestResult<T>> token) throws Exception;
|
||||
Type token) throws Exception;
|
||||
|
||||
/**
|
||||
* http delete
|
||||
@ -65,7 +66,7 @@ public interface NSyncHttpClient extends NHttpClient {
|
||||
* @throws Exception
|
||||
*/
|
||||
<T> RestResult<T> delete(String url, Header header, Query query,
|
||||
TypeReference<RestResult<T>> token) throws Exception;
|
||||
Type token) throws Exception;
|
||||
|
||||
/**
|
||||
* http put
|
||||
@ -79,7 +80,7 @@ public interface NSyncHttpClient extends NHttpClient {
|
||||
* @throws Exception
|
||||
*/
|
||||
<T> RestResult<T> put(String url, Header header, Query query, Object body,
|
||||
TypeReference<RestResult<T>> token) throws Exception;
|
||||
Type token) throws Exception;
|
||||
|
||||
/**
|
||||
* http post
|
||||
@ -93,6 +94,6 @@ public interface NSyncHttpClient extends NHttpClient {
|
||||
* @throws Exception
|
||||
*/
|
||||
<T> RestResult<T> post(String url, Header header, Query query, Object body,
|
||||
TypeReference<RestResult<T>> token) throws Exception;
|
||||
Type token) throws Exception;
|
||||
|
||||
}
|
||||
|
@ -16,24 +16,23 @@
|
||||
|
||||
package com.alibaba.nacos.common.http;
|
||||
|
||||
import com.alibaba.fastjson.TypeReference;
|
||||
import com.alibaba.nacos.common.http.param.Header;
|
||||
import com.alibaba.nacos.common.http.param.Query;
|
||||
import com.alibaba.nacos.common.model.RestResult;
|
||||
import com.alibaba.nacos.common.utils.HttpMethod;
|
||||
import org.apache.http.client.methods.HttpRequestBase;
|
||||
import org.apache.http.impl.nio.client.CloseableHttpAsyncClient;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.Type;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:liaochuntao@live.com">liaochuntao</a>
|
||||
*/
|
||||
public class NacosAsyncHttpClient extends BaseHttpClient implements NAsyncHttpClient {
|
||||
class NacosAsyncHttpClient extends BaseHttpClient implements NAsyncHttpClient {
|
||||
|
||||
private CloseableHttpAsyncClient asyncClient;
|
||||
|
||||
public NacosAsyncHttpClient(CloseableHttpAsyncClient asyncClient) {
|
||||
NacosAsyncHttpClient(CloseableHttpAsyncClient asyncClient) {
|
||||
this.asyncClient = asyncClient;
|
||||
this.asyncClient.start();
|
||||
}
|
||||
@ -42,7 +41,7 @@ public class NacosAsyncHttpClient extends BaseHttpClient implements NAsyncHttpCl
|
||||
public <T> void get(final String url,
|
||||
final Header header,
|
||||
final Query query,
|
||||
final TypeReference<RestResult<T>> token,
|
||||
final Type token,
|
||||
final Callback<T> callback) {
|
||||
HttpRequestBase requestBase = build(buildUrl(url, query), header, HttpMethod.GET);
|
||||
execute(asyncClient, token, callback, requestBase);
|
||||
@ -53,7 +52,7 @@ public class NacosAsyncHttpClient extends BaseHttpClient implements NAsyncHttpCl
|
||||
final Header header,
|
||||
final Query query,
|
||||
final Object body,
|
||||
final TypeReference<RestResult<T>> token,
|
||||
final Type token,
|
||||
final Callback<T> callback) {
|
||||
HttpRequestBase requestBase = build(buildUrl(url, query), header, body, HttpMethod.GET_LARGE);
|
||||
execute(asyncClient, token, callback, requestBase);
|
||||
@ -63,7 +62,7 @@ public class NacosAsyncHttpClient extends BaseHttpClient implements NAsyncHttpCl
|
||||
public <T> void delete(final String url,
|
||||
final Header header,
|
||||
final Query query,
|
||||
final TypeReference<RestResult<T>> token,
|
||||
final Type token,
|
||||
final Callback<T> callback) {
|
||||
HttpRequestBase requestBase = build(buildUrl(url, query), header, HttpMethod.DELETE);
|
||||
execute(asyncClient, token, callback, requestBase);
|
||||
@ -74,7 +73,7 @@ public class NacosAsyncHttpClient extends BaseHttpClient implements NAsyncHttpCl
|
||||
final Header header,
|
||||
final Query query,
|
||||
final Object body,
|
||||
final TypeReference<RestResult<T>> token,
|
||||
final Type token,
|
||||
final Callback<T> callback) {
|
||||
HttpRequestBase requestBase = build(buildUrl(url, query), header, body, HttpMethod.PUT);
|
||||
execute(asyncClient, token, callback, requestBase);
|
||||
@ -85,7 +84,7 @@ public class NacosAsyncHttpClient extends BaseHttpClient implements NAsyncHttpCl
|
||||
final Header header,
|
||||
final Query query,
|
||||
final Object body,
|
||||
final TypeReference<RestResult<T>> token,
|
||||
final Type token,
|
||||
final Callback<T> callback) {
|
||||
HttpRequestBase requestBase = build(buildUrl(url, query), header, body, HttpMethod.POST);
|
||||
execute(asyncClient, token, callback, requestBase);
|
||||
|
@ -16,7 +16,6 @@
|
||||
|
||||
package com.alibaba.nacos.common.http;
|
||||
|
||||
import com.alibaba.fastjson.TypeReference;
|
||||
import com.alibaba.nacos.common.http.param.Header;
|
||||
import com.alibaba.nacos.common.http.param.Query;
|
||||
import com.alibaba.nacos.common.model.RestResult;
|
||||
@ -25,15 +24,16 @@ import org.apache.http.client.methods.HttpRequestBase;
|
||||
import org.apache.http.impl.client.CloseableHttpClient;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.Type;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:liaochuntao@live.com">liaochuntao</a>
|
||||
*/
|
||||
public class NacosSyncHttpClient extends BaseHttpClient implements NSyncHttpClient {
|
||||
class NacosSyncHttpClient extends BaseHttpClient implements NSyncHttpClient {
|
||||
|
||||
private CloseableHttpClient client;
|
||||
|
||||
public NacosSyncHttpClient(CloseableHttpClient client) {
|
||||
NacosSyncHttpClient(CloseableHttpClient client) {
|
||||
this.client = client;
|
||||
}
|
||||
|
||||
@ -41,13 +41,13 @@ public class NacosSyncHttpClient extends BaseHttpClient implements NSyncHttpClie
|
||||
public <T> RestResult<T> get(final String url,
|
||||
final Header header,
|
||||
final Query query,
|
||||
final TypeReference<RestResult<T>> token) throws Exception {
|
||||
final Type token) throws Exception {
|
||||
HttpRequestBase requestBase = build(buildUrl(url, query), header, HttpMethod.GET);
|
||||
return execute(client, token, requestBase);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> RestResult<T> getLarge(String url, Header header, Query query, Object body, TypeReference<RestResult<T>> token) throws Exception {
|
||||
public <T> RestResult<T> getLarge(String url, Header header, Query query, Object body, Type token) throws Exception {
|
||||
HttpRequestBase requestBase = build(buildUrl(url, query), header, body, HttpMethod.GET_LARGE);
|
||||
return execute(client, token, requestBase);
|
||||
}
|
||||
@ -56,7 +56,7 @@ public class NacosSyncHttpClient extends BaseHttpClient implements NSyncHttpClie
|
||||
public <T> RestResult<T> delete(final String url,
|
||||
final Header header,
|
||||
final Query query,
|
||||
final TypeReference<RestResult<T>> token) throws Exception {
|
||||
final Type token) throws Exception {
|
||||
HttpRequestBase requestBase = build(buildUrl(url, query), header, HttpMethod.DELETE);
|
||||
return execute(client, token, requestBase);
|
||||
}
|
||||
@ -66,7 +66,7 @@ public class NacosSyncHttpClient extends BaseHttpClient implements NSyncHttpClie
|
||||
final Header header,
|
||||
final Query query,
|
||||
final Object body,
|
||||
final TypeReference<RestResult<T>> token) throws Exception {
|
||||
final Type token) throws Exception {
|
||||
HttpRequestBase requestBase = build(buildUrl(url, query), header, body, HttpMethod.PUT);
|
||||
return execute(client, token, requestBase);
|
||||
}
|
||||
@ -76,7 +76,7 @@ public class NacosSyncHttpClient extends BaseHttpClient implements NSyncHttpClie
|
||||
final Header header,
|
||||
final Query query,
|
||||
final Object body,
|
||||
final TypeReference<RestResult<T>> token) throws Exception {
|
||||
final Type token) throws Exception {
|
||||
HttpRequestBase requestBase = build(buildUrl(url, query), header, body, HttpMethod.POST);
|
||||
return execute(client, token, requestBase);
|
||||
}
|
||||
|
@ -17,7 +17,8 @@
|
||||
package com.alibaba.nacos.common.http.handler;
|
||||
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import com.alibaba.fastjson.TypeReference;
|
||||
|
||||
import java.lang.reflect.Type;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:liaochuntao@live.com">liaochuntao</a>
|
||||
@ -28,13 +29,8 @@ public final class ResponseHandler {
|
||||
return JSON.parseObject(s, cls);
|
||||
}
|
||||
|
||||
public static <T> T convert(String s, TypeReference<T> typeReference) {
|
||||
try {
|
||||
return JSON.parseObject(s, typeReference);
|
||||
}
|
||||
catch (Exception e) {
|
||||
return null;
|
||||
}
|
||||
public static <T> T convert(String s, Type type) {
|
||||
return JSON.parseObject(s, type);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -19,7 +19,9 @@ package com.alibaba.nacos.common.http.param;
|
||||
/**
|
||||
* @author <a href="mailto:liaochuntao@live.com">liaochuntao</a>
|
||||
*/
|
||||
public class MediaType {
|
||||
public final class MediaType {
|
||||
|
||||
private MediaType() {}
|
||||
|
||||
public static final String APPLICATION_ATOM_XML = "application/atom+xml";
|
||||
|
||||
|
@ -23,9 +23,6 @@ import java.io.Serializable;
|
||||
*/
|
||||
public class RestResult<T> implements Serializable {
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private static final long serialVersionUID = 6095433538316185017L;
|
||||
|
||||
private int code;
|
||||
|
@ -14,11 +14,10 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.alibaba.nacos.core.utils;
|
||||
package com.alibaba.nacos.common.utils;
|
||||
|
||||
import java.nio.charset.Charset;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.Objects;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
/**
|
||||
@ -26,24 +25,24 @@ import org.apache.commons.lang3.StringUtils;
|
||||
*/
|
||||
public final class ByteUtils {
|
||||
|
||||
private static final byte[] EMPTY = new byte[0];
|
||||
public static final byte[] EMPTY = new byte[0];
|
||||
|
||||
public static byte[] toBytes(String s) {
|
||||
if (Objects.isNull(s)) {
|
||||
if (s == null) {
|
||||
return EMPTY;
|
||||
}
|
||||
return s.getBytes(Charset.forName(StandardCharsets.UTF_8.name()));
|
||||
}
|
||||
|
||||
public static byte[] toBytes(Object s) {
|
||||
if (Objects.isNull(s)) {
|
||||
if (s == null) {
|
||||
return EMPTY;
|
||||
}
|
||||
return toBytes(String.valueOf(s));
|
||||
}
|
||||
|
||||
public static String toString(byte[] bytes) {
|
||||
if (Objects.isNull(bytes)) {
|
||||
if (bytes == null) {
|
||||
return StringUtils.EMPTY;
|
||||
}
|
||||
return new String(bytes, Charset.forName(StandardCharsets.UTF_8.name()));
|
@ -14,7 +14,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.alibaba.nacos.core.utils;
|
||||
package com.alibaba.nacos.common.utils;
|
||||
|
||||
import java.util.AbstractSet;
|
||||
import java.util.Iterator;
|
@ -14,7 +14,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.alibaba.nacos.core.utils;
|
||||
package com.alibaba.nacos.common.utils;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
@ -14,7 +14,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.alibaba.nacos.core.utils;
|
||||
package com.alibaba.nacos.common.utils;
|
||||
|
||||
import java.io.BufferedInputStream;
|
||||
import java.io.BufferedOutputStream;
|
||||
@ -39,6 +39,7 @@ import java.util.zip.Checksum;
|
||||
import java.util.zip.ZipEntry;
|
||||
import java.util.zip.ZipInputStream;
|
||||
import java.util.zip.ZipOutputStream;
|
||||
|
||||
import org.apache.commons.io.FileUtils;
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.apache.commons.io.output.NullOutputStream;
|
@ -13,7 +13,7 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.alibaba.nacos.core.utils;
|
||||
package com.alibaba.nacos.common.utils;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
@ -15,37 +15,27 @@
|
||||
*/
|
||||
package com.alibaba.nacos.common.utils;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
/**
|
||||
* @author nacos
|
||||
*/
|
||||
public class Pair {
|
||||
private String key;
|
||||
private String value;
|
||||
public class Pair<A, B> {
|
||||
private final A first;
|
||||
private final B second;
|
||||
|
||||
public Pair(String key, String value) {
|
||||
this.key = key;
|
||||
this.value = value;
|
||||
Pair(A first, B second) {
|
||||
this.first = first;
|
||||
this.second = second;
|
||||
}
|
||||
|
||||
public Pair() {
|
||||
this(StringUtils.EMPTY, StringUtils.EMPTY);
|
||||
public static <A, B> Pair<A, B> with(A first, B second) {
|
||||
return new Pair<>(first, second);
|
||||
}
|
||||
|
||||
public String getKey() {
|
||||
return key;
|
||||
public A getFirst() {
|
||||
return first;
|
||||
}
|
||||
|
||||
public void setKey(String key) {
|
||||
this.key = key;
|
||||
}
|
||||
|
||||
public String getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
public void setValue(String value) {
|
||||
this.value = value;
|
||||
public B getSecond() {
|
||||
return second;
|
||||
}
|
||||
}
|
||||
|
@ -13,7 +13,7 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.alibaba.nacos.client.utils;
|
||||
package com.alibaba.nacos.common.utils;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.StringWriter;
|
@ -14,7 +14,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.alibaba.nacos.core.utils;
|
||||
package com.alibaba.nacos.common.utils;
|
||||
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
|
@ -14,9 +14,8 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.alibaba.nacos.core.utils;
|
||||
package com.alibaba.nacos.common.utils;
|
||||
|
||||
import org.javatuples.Pair;
|
||||
import org.slf4j.Logger;
|
||||
|
||||
/**
|
||||
@ -34,7 +33,7 @@ public class TimerContext {
|
||||
public static void end(Logger logger) {
|
||||
long endTime = System.currentTimeMillis();
|
||||
Pair<String, Long> record = TIME_RECORD.get();
|
||||
logger.debug("{} cost time : {} ms", record.getValue0(), (endTime - record.getValue1()));
|
||||
logger.debug("{} cost time : {} ms", record.getFirst(), (endTime - record.getSecond()));
|
||||
TIME_RECORD.remove();
|
||||
}
|
||||
|
@ -19,7 +19,7 @@ import com.alibaba.nacos.config.server.constant.Constants;
|
||||
import com.alibaba.nacos.config.server.constant.CounterMode;
|
||||
import com.alibaba.nacos.config.server.model.ConfigInfo;
|
||||
import com.alibaba.nacos.config.server.model.capacity.Capacity;
|
||||
import com.alibaba.nacos.config.server.service.PersistService;
|
||||
import com.alibaba.nacos.config.server.service.repository.PersistService;
|
||||
import com.alibaba.nacos.config.server.service.capacity.CapacityService;
|
||||
import com.alibaba.nacos.config.server.utils.PropertyUtil;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
@ -0,0 +1,86 @@
|
||||
/*
|
||||
* Copyright 1999-2018 Alibaba Group Holding Ltd.
|
||||
*
|
||||
* 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 com.alibaba.nacos.config.server.auth;
|
||||
|
||||
import com.alibaba.nacos.config.server.configuration.ConditionOnEmbeddedStorage;
|
||||
import com.alibaba.nacos.config.server.model.Page;
|
||||
import com.alibaba.nacos.config.server.service.repository.EmbeddedStoragePersistServiceImpl;
|
||||
import com.alibaba.nacos.config.server.service.repository.PaginationHelper;
|
||||
import com.alibaba.nacos.config.server.service.repository.DatabaseOperate;
|
||||
import com.alibaba.nacos.config.server.service.sql.SqlContextUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.annotation.Conditional;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
import static com.alibaba.nacos.config.server.service.RowMapperManager.PERMISSION_ROW_MAPPER;
|
||||
|
||||
/**
|
||||
* There is no self-augmented primary key
|
||||
*
|
||||
* @author <a href="mailto:liaochuntao@live.com">liaochuntao</a>
|
||||
*/
|
||||
@Conditional(value = ConditionOnEmbeddedStorage.class)
|
||||
@Component
|
||||
public class EmbeddedPermissionPersistServiceImpl implements PermissionPersistService {
|
||||
|
||||
@Autowired
|
||||
private DatabaseOperate databaseOperate;
|
||||
|
||||
@Autowired
|
||||
private EmbeddedStoragePersistServiceImpl persistService;
|
||||
|
||||
public Page<PermissionInfo> getPermissions(String role, int pageNo, int pageSize) {
|
||||
PaginationHelper<PermissionInfo> helper = persistService.createPaginationHelper();
|
||||
|
||||
String sqlCountRows = "select count(*) from permissions where ";
|
||||
String sqlFetchRows
|
||||
= "select role,resource,action from permissions where ";
|
||||
|
||||
String where = " role='" + role + "' ";
|
||||
|
||||
if (StringUtils.isBlank(role)) {
|
||||
where = " 1=1 ";
|
||||
}
|
||||
|
||||
Page<PermissionInfo> pageInfo = helper.fetchPage(sqlCountRows
|
||||
+ where, sqlFetchRows + where, new ArrayList<String>().toArray(), pageNo,
|
||||
pageSize, PERMISSION_ROW_MAPPER);
|
||||
|
||||
if (pageInfo == null) {
|
||||
pageInfo = new Page<>();
|
||||
pageInfo.setTotalCount(0);
|
||||
pageInfo.setPageItems(new ArrayList<>());
|
||||
}
|
||||
return pageInfo;
|
||||
}
|
||||
|
||||
public void addPermission(String role, String resource, String action) {
|
||||
String sql = "INSERT into permissions (role, resource, action) VALUES (?, ?, ?)";
|
||||
SqlContextUtils.addSqlContext(sql, role, resource, action);
|
||||
databaseOperate.smartUpdate();
|
||||
}
|
||||
|
||||
public void deletePermission(String role, String resource, String action) {
|
||||
String sql = "DELETE from permissions WHERE role=? and resource=? and action=?";
|
||||
SqlContextUtils.addSqlContext(sql, role, resource, action);
|
||||
databaseOperate.smartUpdate();
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,123 @@
|
||||
/*
|
||||
* Copyright 1999-2018 Alibaba Group Holding Ltd.
|
||||
*
|
||||
* 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 com.alibaba.nacos.config.server.auth;
|
||||
|
||||
import com.alibaba.nacos.config.server.configuration.ConditionOnEmbeddedStorage;
|
||||
import com.alibaba.nacos.config.server.model.Page;
|
||||
import com.alibaba.nacos.config.server.service.repository.EmbeddedStoragePersistServiceImpl;
|
||||
import com.alibaba.nacos.config.server.service.repository.PaginationHelper;
|
||||
import com.alibaba.nacos.config.server.service.repository.DatabaseOperate;
|
||||
import com.alibaba.nacos.config.server.service.sql.SqlContextUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.annotation.Conditional;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
import static com.alibaba.nacos.config.server.service.RowMapperManager.ROLE_INFO_ROW_MAPPER;
|
||||
|
||||
/**
|
||||
* There is no self-augmented primary key
|
||||
*
|
||||
* @author <a href="mailto:liaochuntao@live.com">liaochuntao</a>
|
||||
*/
|
||||
@Conditional(value = ConditionOnEmbeddedStorage.class)
|
||||
@Component
|
||||
public class EmbeddedRolePersistServiceImpl implements RolePersistService {
|
||||
|
||||
@Autowired
|
||||
private DatabaseOperate databaseOperate;
|
||||
|
||||
@Autowired
|
||||
private EmbeddedStoragePersistServiceImpl persistService;
|
||||
|
||||
public Page<RoleInfo> getRoles(int pageNo, int pageSize) {
|
||||
|
||||
PaginationHelper<RoleInfo> helper = persistService.createPaginationHelper();
|
||||
|
||||
String sqlCountRows = "select count(*) from (select distinct role from roles) roles where ";
|
||||
String sqlFetchRows
|
||||
= "select role,username from roles where ";
|
||||
|
||||
String where = " 1=1 ";
|
||||
|
||||
Page<RoleInfo> pageInfo = helper.fetchPage(sqlCountRows
|
||||
+ where, sqlFetchRows + where, new ArrayList<String>().toArray(), pageNo,
|
||||
pageSize, ROLE_INFO_ROW_MAPPER);
|
||||
if (pageInfo == null) {
|
||||
pageInfo = new Page<>();
|
||||
pageInfo.setTotalCount(0);
|
||||
pageInfo.setPageItems(new ArrayList<>());
|
||||
}
|
||||
return pageInfo;
|
||||
|
||||
}
|
||||
|
||||
public Page<RoleInfo> getRolesByUserName(String username, int pageNo, int pageSize) {
|
||||
|
||||
PaginationHelper<RoleInfo> helper = persistService.createPaginationHelper();
|
||||
|
||||
String sqlCountRows = "select count(*) from roles where ";
|
||||
String sqlFetchRows
|
||||
= "select role,username from roles where ";
|
||||
|
||||
String where = " username='" + username + "' ";
|
||||
|
||||
if (StringUtils.isBlank(username)) {
|
||||
where = " 1=1 ";
|
||||
}
|
||||
|
||||
return helper.fetchPage(sqlCountRows
|
||||
+ where, sqlFetchRows + where, new ArrayList<String>().toArray(), pageNo,
|
||||
pageSize, ROLE_INFO_ROW_MAPPER);
|
||||
|
||||
}
|
||||
|
||||
public void addRole(String role, String userName) {
|
||||
|
||||
String sql = "INSERT into roles (role, username) VALUES (?, ?)";
|
||||
|
||||
try {
|
||||
SqlContextUtils.addSqlContext(sql, role, userName);
|
||||
databaseOperate.update(SqlContextUtils.getCurrentSqlContext());
|
||||
} finally {
|
||||
SqlContextUtils.cleanCurrentSqlContext();
|
||||
}
|
||||
}
|
||||
|
||||
public void deleteRole(String role) {
|
||||
String sql = "DELETE from roles WHERE role=?";
|
||||
try {
|
||||
SqlContextUtils.addSqlContext(sql, role);
|
||||
databaseOperate.update(SqlContextUtils.getCurrentSqlContext());
|
||||
} finally {
|
||||
SqlContextUtils.cleanCurrentSqlContext();
|
||||
}
|
||||
}
|
||||
|
||||
public void deleteRole(String role, String username) {
|
||||
String sql = "DELETE from roles WHERE role=? and username=?";
|
||||
try {
|
||||
SqlContextUtils.addSqlContext(sql, role, username);
|
||||
databaseOperate.update(SqlContextUtils.getCurrentSqlContext());
|
||||
} finally {
|
||||
SqlContextUtils.cleanCurrentSqlContext();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,107 @@
|
||||
/*
|
||||
* Copyright 1999-2018 Alibaba Group Holding Ltd.
|
||||
*
|
||||
* 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 com.alibaba.nacos.config.server.auth;
|
||||
|
||||
import com.alibaba.nacos.config.server.configuration.ConditionOnEmbeddedStorage;
|
||||
import com.alibaba.nacos.config.server.model.Page;
|
||||
import com.alibaba.nacos.config.server.model.User;
|
||||
import com.alibaba.nacos.config.server.service.repository.EmbeddedStoragePersistServiceImpl;
|
||||
import com.alibaba.nacos.config.server.service.repository.PaginationHelper;
|
||||
import com.alibaba.nacos.config.server.service.repository.DatabaseOperate;
|
||||
import com.alibaba.nacos.config.server.service.sql.SqlContextUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.annotation.Conditional;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
import static com.alibaba.nacos.config.server.service.RowMapperManager.USER_ROW_MAPPER;
|
||||
|
||||
/**
|
||||
* There is no self-augmented primary key
|
||||
*
|
||||
* @author <a href="mailto:liaochuntao@live.com">liaochuntao</a>
|
||||
*/
|
||||
@Conditional(value = ConditionOnEmbeddedStorage.class)
|
||||
@Component
|
||||
public class EmbeddedUserPersistServiceImpl implements UserPersistService {
|
||||
|
||||
@Autowired
|
||||
private DatabaseOperate databaseOperate;
|
||||
|
||||
@Autowired
|
||||
private EmbeddedStoragePersistServiceImpl persistService;
|
||||
|
||||
public void createUser(String username, String password) {
|
||||
String sql = "INSERT into users (username, password, enabled) VALUES (?, ?, ?)";
|
||||
|
||||
try {
|
||||
SqlContextUtils.addSqlContext(sql, username, password, true);
|
||||
databaseOperate.smartUpdate();
|
||||
} finally {
|
||||
SqlContextUtils.cleanCurrentSqlContext();
|
||||
}
|
||||
}
|
||||
|
||||
public void deleteUser(String username) {
|
||||
String sql = "DELETE from users WHERE username=?";
|
||||
try {
|
||||
SqlContextUtils.addSqlContext(sql, username);
|
||||
databaseOperate.smartUpdate();
|
||||
} finally {
|
||||
SqlContextUtils.cleanCurrentSqlContext();
|
||||
}
|
||||
}
|
||||
|
||||
public void updateUserPassword(String username, String password) {
|
||||
try {
|
||||
SqlContextUtils.addSqlContext(
|
||||
"UPDATE users SET password = ? WHERE username=?",
|
||||
password, username);
|
||||
databaseOperate.smartUpdate();
|
||||
} finally {
|
||||
SqlContextUtils.cleanCurrentSqlContext();
|
||||
}
|
||||
}
|
||||
|
||||
public User findUserByUsername(String username) {
|
||||
String sql = "SELECT username,password FROM users WHERE username=? ";
|
||||
return databaseOperate.queryOne(sql, new Object[]{username}, USER_ROW_MAPPER);
|
||||
}
|
||||
|
||||
public Page<User> getUsers(int pageNo, int pageSize) {
|
||||
|
||||
PaginationHelper<User> helper = persistService.createPaginationHelper();
|
||||
|
||||
String sqlCountRows = "select count(*) from users where ";
|
||||
String sqlFetchRows
|
||||
= "select username,password from users where ";
|
||||
|
||||
String where = " 1=1 ";
|
||||
Page<User> pageInfo = helper.fetchPage(sqlCountRows
|
||||
+ where, sqlFetchRows + where, new ArrayList<String>().toArray(), pageNo,
|
||||
pageSize, USER_ROW_MAPPER);
|
||||
if (pageInfo == null) {
|
||||
pageInfo = new Page<>();
|
||||
pageInfo.setTotalCount(0);
|
||||
pageInfo.setPageItems(new ArrayList<>());
|
||||
}
|
||||
return pageInfo;
|
||||
}
|
||||
|
||||
|
||||
}
|
@ -0,0 +1,110 @@
|
||||
/*
|
||||
* Copyright 1999-2018 Alibaba Group Holding Ltd.
|
||||
*
|
||||
* 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 com.alibaba.nacos.config.server.auth;
|
||||
|
||||
import com.alibaba.nacos.config.server.configuration.ConditionOnEmbeddedStorage;
|
||||
import com.alibaba.nacos.config.server.configuration.ConditionOnExternalStorage;
|
||||
import com.alibaba.nacos.config.server.model.Page;
|
||||
import com.alibaba.nacos.config.server.service.repository.ExternalStoragePersistServiceImpl;
|
||||
import com.alibaba.nacos.config.server.service.repository.PaginationHelper;
|
||||
import com.alibaba.nacos.config.server.utils.LogUtil;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||
import org.springframework.context.annotation.Conditional;
|
||||
import org.springframework.jdbc.CannotGetJdbcConnectionException;
|
||||
import org.springframework.jdbc.core.JdbcTemplate;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import javax.annotation.PostConstruct;
|
||||
import java.util.ArrayList;
|
||||
|
||||
import static com.alibaba.nacos.config.server.service.RowMapperManager.PERMISSION_ROW_MAPPER;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:liaochuntao@live.com">liaochuntao</a>
|
||||
*/
|
||||
@Conditional(value = ConditionOnExternalStorage.class)
|
||||
@Component
|
||||
public class ExternalPermissionPersistServiceImpl implements PermissionPersistService {
|
||||
|
||||
@Autowired
|
||||
private ExternalStoragePersistServiceImpl persistService;
|
||||
|
||||
private JdbcTemplate jt;
|
||||
|
||||
@PostConstruct
|
||||
protected void init() {
|
||||
jt = persistService.getJdbcTemplate();
|
||||
}
|
||||
|
||||
public Page<PermissionInfo> getPermissions(String role, int pageNo, int pageSize) {
|
||||
PaginationHelper<PermissionInfo> helper = persistService.createPaginationHelper();
|
||||
|
||||
String sqlCountRows = "select count(*) from permissions where ";
|
||||
String sqlFetchRows
|
||||
= "select role,resource,action from permissions where ";
|
||||
|
||||
String where = " role='" + role + "' ";
|
||||
|
||||
if (StringUtils.isBlank(role)) {
|
||||
where = " 1=1 ";
|
||||
}
|
||||
|
||||
try {
|
||||
Page<PermissionInfo> pageInfo = helper.fetchPage(sqlCountRows
|
||||
+ where, sqlFetchRows + where, new ArrayList<String>().toArray(), pageNo,
|
||||
pageSize, PERMISSION_ROW_MAPPER);
|
||||
|
||||
if (pageInfo==null) {
|
||||
pageInfo = new Page<>();
|
||||
pageInfo.setTotalCount(0);
|
||||
pageInfo.setPageItems(new ArrayList<>());
|
||||
}
|
||||
|
||||
return pageInfo;
|
||||
|
||||
} catch (CannotGetJdbcConnectionException e) {
|
||||
LogUtil.fatalLog.error("[db-error] " + e.toString(), e);
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
public void addPermission(String role, String resource, String action) {
|
||||
|
||||
String sql = "INSERT into permissions (role, resource, action) VALUES (?, ?, ?)";
|
||||
|
||||
try {
|
||||
jt.update(sql, role, resource, action);
|
||||
} catch (CannotGetJdbcConnectionException e) {
|
||||
LogUtil.fatalLog.error("[db-error] " + e.toString(), e);
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
public void deletePermission(String role, String resource, String action) {
|
||||
|
||||
String sql = "DELETE from permissions WHERE role=? and resource=? and action=?";
|
||||
try {
|
||||
jt.update(sql, role, resource, action);
|
||||
} catch (CannotGetJdbcConnectionException e) {
|
||||
LogUtil.fatalLog.error("[db-error] " + e.toString(), e);
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,151 @@
|
||||
/*
|
||||
* Copyright 1999-2018 Alibaba Group Holding Ltd.
|
||||
*
|
||||
* 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 com.alibaba.nacos.config.server.auth;
|
||||
|
||||
import com.alibaba.nacos.config.server.configuration.ConditionOnExternalStorage;
|
||||
import com.alibaba.nacos.config.server.model.Page;
|
||||
import com.alibaba.nacos.config.server.service.repository.ExternalStoragePersistServiceImpl;
|
||||
import com.alibaba.nacos.config.server.service.repository.PaginationHelper;
|
||||
import com.alibaba.nacos.config.server.utils.LogUtil;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||
import org.springframework.context.annotation.Conditional;
|
||||
import org.springframework.jdbc.CannotGetJdbcConnectionException;
|
||||
import org.springframework.jdbc.core.JdbcTemplate;
|
||||
import org.springframework.jdbc.core.RowMapper;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import javax.annotation.PostConstruct;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.util.ArrayList;
|
||||
|
||||
import static com.alibaba.nacos.config.server.service.RowMapperManager.ROLE_INFO_ROW_MAPPER;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:liaochuntao@live.com">liaochuntao</a>
|
||||
*/
|
||||
@Conditional(value = ConditionOnExternalStorage.class)
|
||||
@Component
|
||||
public class ExternalRolePersistServiceImpl implements RolePersistService {
|
||||
|
||||
@Autowired
|
||||
private ExternalStoragePersistServiceImpl persistService;
|
||||
|
||||
private JdbcTemplate jt;
|
||||
|
||||
@PostConstruct
|
||||
protected void init() {
|
||||
jt = persistService.getJdbcTemplate();
|
||||
}
|
||||
|
||||
public Page<RoleInfo> getRoles(int pageNo, int pageSize) {
|
||||
|
||||
PaginationHelper<RoleInfo> helper = persistService.createPaginationHelper();
|
||||
|
||||
String sqlCountRows = "select count(*) from (select distinct role from roles) roles where ";
|
||||
String sqlFetchRows
|
||||
= "select role,username from roles where ";
|
||||
|
||||
String where = " 1=1 ";
|
||||
|
||||
try {
|
||||
Page<RoleInfo> pageInfo = helper.fetchPage(sqlCountRows
|
||||
+ where, sqlFetchRows + where, new ArrayList<String>().toArray(), pageNo,
|
||||
pageSize, ROLE_INFO_ROW_MAPPER);
|
||||
if (pageInfo == null) {
|
||||
pageInfo = new Page<>();
|
||||
pageInfo.setTotalCount(0);
|
||||
pageInfo.setPageItems(new ArrayList<>());
|
||||
}
|
||||
return pageInfo;
|
||||
} catch (CannotGetJdbcConnectionException e) {
|
||||
LogUtil.fatalLog.error("[db-error] " + e.toString(), e);
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
public Page<RoleInfo> getRolesByUserName(String username, int pageNo, int pageSize) {
|
||||
|
||||
PaginationHelper<RoleInfo> helper = persistService.createPaginationHelper();
|
||||
|
||||
String sqlCountRows = "select count(*) from roles where ";
|
||||
String sqlFetchRows
|
||||
= "select role,username from roles where ";
|
||||
|
||||
String where = " username='" + username + "' ";
|
||||
|
||||
if (StringUtils.isBlank(username)) {
|
||||
where = " 1=1 ";
|
||||
}
|
||||
|
||||
try {
|
||||
return helper.fetchPage(sqlCountRows
|
||||
+ where, sqlFetchRows + where, new ArrayList<String>().toArray(), pageNo,
|
||||
pageSize, ROLE_INFO_ROW_MAPPER);
|
||||
} catch (CannotGetJdbcConnectionException e) {
|
||||
LogUtil.fatalLog.error("[db-error] " + e.toString(), e);
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
public void addRole(String role, String userName) {
|
||||
|
||||
String sql = "INSERT into roles (role, username) VALUES (?, ?)";
|
||||
|
||||
try {
|
||||
jt.update(sql, role, userName);
|
||||
} catch (CannotGetJdbcConnectionException e) {
|
||||
LogUtil.fatalLog.error("[db-error] " + e.toString(), e);
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
public void deleteRole(String role) {
|
||||
String sql = "DELETE from roles WHERE role=?";
|
||||
try {
|
||||
jt.update(sql, role);
|
||||
} catch (CannotGetJdbcConnectionException e) {
|
||||
LogUtil.fatalLog.error("[db-error] " + e.toString(), e);
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
public void deleteRole(String role, String username) {
|
||||
String sql = "DELETE from roles WHERE role=? and username=?";
|
||||
try {
|
||||
jt.update(sql, role, username);
|
||||
} catch (CannotGetJdbcConnectionException e) {
|
||||
LogUtil.fatalLog.error("[db-error] " + e.toString(), e);
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
private static final class RoleInfoRowMapper implements RowMapper<RoleInfo> {
|
||||
@Override
|
||||
public RoleInfo mapRow(ResultSet rs, int rowNum)
|
||||
throws SQLException {
|
||||
RoleInfo roleInfo = new RoleInfo();
|
||||
roleInfo.setRole(rs.getString("role"));
|
||||
roleInfo.setUsername(rs.getString("username"));
|
||||
return roleInfo;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
@ -0,0 +1,129 @@
|
||||
/*
|
||||
* Copyright 1999-2018 Alibaba Group Holding Ltd.
|
||||
*
|
||||
* 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 com.alibaba.nacos.config.server.auth;
|
||||
|
||||
import com.alibaba.nacos.config.server.configuration.ConditionOnExternalStorage;
|
||||
import com.alibaba.nacos.config.server.model.Page;
|
||||
import com.alibaba.nacos.config.server.model.User;
|
||||
import com.alibaba.nacos.config.server.service.repository.ExternalStoragePersistServiceImpl;
|
||||
import com.alibaba.nacos.config.server.service.repository.PaginationHelper;
|
||||
import com.alibaba.nacos.config.server.utils.LogUtil;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||
import org.springframework.context.annotation.Conditional;
|
||||
import org.springframework.dao.EmptyResultDataAccessException;
|
||||
import org.springframework.jdbc.CannotGetJdbcConnectionException;
|
||||
import org.springframework.jdbc.core.JdbcTemplate;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import javax.annotation.PostConstruct;
|
||||
import java.util.ArrayList;
|
||||
|
||||
import static com.alibaba.nacos.config.server.service.RowMapperManager.USER_ROW_MAPPER;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:liaochuntao@live.com">liaochuntao</a>
|
||||
*/
|
||||
@Conditional(value = ConditionOnExternalStorage.class)
|
||||
@Component
|
||||
public class ExternalUserPersistServiceImpl implements UserPersistService {
|
||||
|
||||
@Autowired
|
||||
private ExternalStoragePersistServiceImpl persistService;
|
||||
|
||||
private JdbcTemplate jt;
|
||||
|
||||
@PostConstruct
|
||||
protected void init() {
|
||||
jt = persistService.getJdbcTemplate();
|
||||
}
|
||||
|
||||
public void createUser(String username, String password) {
|
||||
String sql = "INSERT into users (username, password, enabled) VALUES (?, ?, ?)";
|
||||
|
||||
try {
|
||||
jt.update(sql, username, password, true);
|
||||
} catch (CannotGetJdbcConnectionException e) {
|
||||
LogUtil.fatalLog.error("[db-error] " + e.toString(), e);
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
public void deleteUser(String username) {
|
||||
String sql = "DELETE from users WHERE username=?";
|
||||
try {
|
||||
jt.update(sql, username);
|
||||
} catch (CannotGetJdbcConnectionException e) {
|
||||
LogUtil.fatalLog.error("[db-error] " + e.toString(), e);
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
public void updateUserPassword(String username, String password) {
|
||||
try {
|
||||
jt.update(
|
||||
"UPDATE users SET password = ? WHERE username=?",
|
||||
password, username);
|
||||
} catch (CannotGetJdbcConnectionException e) {
|
||||
LogUtil.fatalLog.error("[db-error] " + e.toString(), e);
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
public User findUserByUsername(String username) {
|
||||
String sql = "SELECT username,password FROM users WHERE username=? ";
|
||||
try {
|
||||
return this.jt.queryForObject(sql, new Object[]{username}, USER_ROW_MAPPER);
|
||||
} catch (CannotGetJdbcConnectionException e) {
|
||||
LogUtil.fatalLog.error("[db-error] " + e.toString(), e);
|
||||
throw e;
|
||||
} catch (EmptyResultDataAccessException e) {
|
||||
return null;
|
||||
} catch (Exception e) {
|
||||
LogUtil.fatalLog.error("[db-other-error]" + e.getMessage(), e);
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
public Page<User> getUsers(int pageNo, int pageSize) {
|
||||
|
||||
PaginationHelper<User> helper = persistService.createPaginationHelper();
|
||||
|
||||
String sqlCountRows = "select count(*) from users where ";
|
||||
String sqlFetchRows
|
||||
= "select username,password from users where ";
|
||||
|
||||
String where = " 1=1 ";
|
||||
|
||||
try {
|
||||
Page<User> pageInfo = helper.fetchPage(sqlCountRows
|
||||
+ where, sqlFetchRows + where, new ArrayList<String>().toArray(), pageNo,
|
||||
pageSize, USER_ROW_MAPPER);
|
||||
if (pageInfo == null) {
|
||||
pageInfo = new Page<>();
|
||||
pageInfo.setTotalCount(0);
|
||||
pageInfo.setPageItems(new ArrayList<>());
|
||||
}
|
||||
return pageInfo;
|
||||
} catch (CannotGetJdbcConnectionException e) {
|
||||
LogUtil.fatalLog.error("[db-error] " + e.toString(), e);
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
@ -15,12 +15,15 @@
|
||||
*/
|
||||
package com.alibaba.nacos.config.server.auth;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* @author nkorange
|
||||
* @since 1.2.0
|
||||
*/
|
||||
public class PermissionInfo {
|
||||
public class PermissionInfo implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = 388813573388837395L;
|
||||
/**
|
||||
* Role name
|
||||
*/
|
||||
|
@ -15,18 +15,7 @@
|
||||
*/
|
||||
package com.alibaba.nacos.config.server.auth;
|
||||
|
||||
|
||||
import com.alibaba.nacos.config.server.model.Page;
|
||||
import com.alibaba.nacos.config.server.service.PersistService;
|
||||
import com.alibaba.nacos.config.server.service.transaction.DatabaseOperate;
|
||||
import com.alibaba.nacos.config.server.service.transaction.SqlContextUtils;
|
||||
import com.alibaba.nacos.config.server.utils.PaginationHelper;
|
||||
import java.util.ArrayList;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import static com.alibaba.nacos.config.server.service.RowMapperManager.PERMISSION_ROW_MAPPER;
|
||||
|
||||
/**
|
||||
* Permission CRUD service
|
||||
@ -34,52 +23,13 @@ import static com.alibaba.nacos.config.server.service.RowMapperManager.PERMISSIO
|
||||
* @author nkorange
|
||||
* @since 1.2.0
|
||||
*/
|
||||
@Service
|
||||
public class PermissionPersistService extends PersistService {
|
||||
@SuppressWarnings("PMD.AbstractMethodOrInterfaceMethodMustUseJavadocRule")
|
||||
public interface PermissionPersistService {
|
||||
|
||||
@Autowired
|
||||
private DatabaseOperate databaseOperate;
|
||||
Page<PermissionInfo> getPermissions(String role, int pageNo, int pageSize);
|
||||
|
||||
public Page<PermissionInfo> getPermissions(String role, int pageNo, int pageSize) {
|
||||
PaginationHelper<PermissionInfo> helper = new PaginationHelper<>();
|
||||
void addPermission(String role, String resource, String action);
|
||||
|
||||
String sqlCountRows = "select count(*) from permissions where ";
|
||||
String sqlFetchRows
|
||||
= "select role,resource,action from permissions where ";
|
||||
|
||||
String where = " role='" + role + "' ";
|
||||
|
||||
if (StringUtils.isBlank(role)) {
|
||||
where = " 1=1 ";
|
||||
}
|
||||
|
||||
Page<PermissionInfo> pageInfo = helper.fetchPage(databaseOperate, sqlCountRows
|
||||
+ where, sqlFetchRows + where, new ArrayList<String>().toArray(), pageNo,
|
||||
pageSize, PERMISSION_ROW_MAPPER);
|
||||
|
||||
if (pageInfo == null) {
|
||||
pageInfo = new Page<>();
|
||||
pageInfo.setTotalCount(0);
|
||||
pageInfo.setPageItems(new ArrayList<>());
|
||||
}
|
||||
|
||||
return pageInfo;
|
||||
|
||||
}
|
||||
|
||||
public void addPermission(String role, String resource, String action) {
|
||||
|
||||
String sql = "INSERT into permissions (role, resource, action) VALUES (?, ?, ?)";
|
||||
SqlContextUtils.addSqlContext(sql, role, resource, action);
|
||||
databaseOperate.updateAuto();
|
||||
}
|
||||
|
||||
public void deletePermission(String role, String resource, String action) {
|
||||
|
||||
String sql = "DELETE from permissions WHERE role=? and resource=? and action=?";
|
||||
SqlContextUtils.addSqlContext(sql, role, resource, action);
|
||||
databaseOperate.updateAuto();
|
||||
|
||||
}
|
||||
void deletePermission(String role, String resource, String action);
|
||||
|
||||
}
|
||||
|
@ -16,19 +16,6 @@
|
||||
package com.alibaba.nacos.config.server.auth;
|
||||
|
||||
import com.alibaba.nacos.config.server.model.Page;
|
||||
import com.alibaba.nacos.config.server.service.PersistService;
|
||||
import com.alibaba.nacos.config.server.service.transaction.DatabaseOperate;
|
||||
import com.alibaba.nacos.config.server.service.transaction.SqlContextUtils;
|
||||
import com.alibaba.nacos.config.server.utils.PaginationHelper;
|
||||
import com.alibaba.nacos.core.notify.NotifyCenter;
|
||||
import java.util.ArrayList;
|
||||
import javax.annotation.PostConstruct;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import static com.alibaba.nacos.config.server.service.RowMapperManager.ROLE_INFO_ROW_MAPPER;
|
||||
|
||||
|
||||
/**
|
||||
* Role CRUD service
|
||||
@ -36,92 +23,17 @@ import static com.alibaba.nacos.config.server.service.RowMapperManager.ROLE_INFO
|
||||
* @author nkorange
|
||||
* @since 1.2.0
|
||||
*/
|
||||
@Service
|
||||
public class RolePersistService extends PersistService {
|
||||
@SuppressWarnings("PMD.AbstractMethodOrInterfaceMethodMustUseJavadocRule")
|
||||
public interface RolePersistService {
|
||||
|
||||
@Autowired
|
||||
private DatabaseOperate databaseOperate;
|
||||
Page<RoleInfo> getRoles(int pageNo, int pageSize);
|
||||
|
||||
@PostConstruct
|
||||
protected void postConstruct() {
|
||||
NotifyCenter.registerPublisher(RoleChangeEvent::new, RoleChangeEvent.class);
|
||||
}
|
||||
Page<RoleInfo> getRolesByUserName(String username, int pageNo, int pageSize);
|
||||
|
||||
public Page<RoleInfo> getRoles(int pageNo, int pageSize) {
|
||||
void addRole(String role, String userName);
|
||||
|
||||
PaginationHelper<RoleInfo> helper = new PaginationHelper<>();
|
||||
void deleteRole(String role);
|
||||
|
||||
String sqlCountRows = "select count(*) from (select distinct role from roles) roles where ";
|
||||
String sqlFetchRows
|
||||
= "select role,username from roles where ";
|
||||
|
||||
String where = " 1=1 ";
|
||||
|
||||
Page<RoleInfo> pageInfo = helper.fetchPage(databaseOperate, sqlCountRows
|
||||
+ where, sqlFetchRows + where, new ArrayList<String>().toArray(), pageNo,
|
||||
pageSize, ROLE_INFO_ROW_MAPPER);
|
||||
if (pageInfo == null) {
|
||||
pageInfo = new Page<>();
|
||||
pageInfo.setTotalCount(0);
|
||||
pageInfo.setPageItems(new ArrayList<>());
|
||||
}
|
||||
return pageInfo;
|
||||
|
||||
}
|
||||
|
||||
public Page<RoleInfo> getRolesByUserName(String username, int pageNo, int pageSize) {
|
||||
|
||||
PaginationHelper<RoleInfo> helper = new PaginationHelper<>();
|
||||
|
||||
String sqlCountRows = "select count(*) from roles where ";
|
||||
String sqlFetchRows
|
||||
= "select role,username from roles where ";
|
||||
|
||||
String where = " username='" + username + "' ";
|
||||
|
||||
if (StringUtils.isBlank(username)) {
|
||||
where = " 1=1 ";
|
||||
}
|
||||
|
||||
return helper.fetchPage(databaseOperate, sqlCountRows
|
||||
+ where, sqlFetchRows + where, new ArrayList<String>().toArray(), pageNo,
|
||||
pageSize, ROLE_INFO_ROW_MAPPER);
|
||||
|
||||
}
|
||||
|
||||
public void addRole(String role, String userName) {
|
||||
|
||||
String sql = "INSERT into roles (role, username) VALUES (?, ?)";
|
||||
|
||||
try {
|
||||
SqlContextUtils.addSqlContext(sql, role, userName);
|
||||
databaseOperate.update(SqlContextUtils.getCurrentSqlContext());
|
||||
NotifyCenter.publishEvent(RoleChangeEvent.class, new RoleChangeEvent());
|
||||
} finally {
|
||||
SqlContextUtils.cleanCurrentSqlContext();
|
||||
}
|
||||
}
|
||||
|
||||
public void deleteRole(String role) {
|
||||
String sql = "DELETE from roles WHERE role=?";
|
||||
try {
|
||||
SqlContextUtils.addSqlContext(sql, role);
|
||||
databaseOperate.update(SqlContextUtils.getCurrentSqlContext());
|
||||
NotifyCenter.publishEvent(RoleChangeEvent.class, new RoleChangeEvent());
|
||||
} finally {
|
||||
SqlContextUtils.cleanCurrentSqlContext();
|
||||
}
|
||||
}
|
||||
|
||||
public void deleteRole(String role, String username) {
|
||||
String sql = "DELETE from roles WHERE role=? and username=?";
|
||||
try {
|
||||
SqlContextUtils.addSqlContext(sql, role, username);
|
||||
databaseOperate.update(SqlContextUtils.getCurrentSqlContext());
|
||||
NotifyCenter.publishEvent(RoleChangeEvent.class, new RoleChangeEvent());
|
||||
} finally {
|
||||
SqlContextUtils.cleanCurrentSqlContext();
|
||||
}
|
||||
}
|
||||
void deleteRole(String role, String username);
|
||||
|
||||
}
|
||||
|
@ -17,15 +17,6 @@ package com.alibaba.nacos.config.server.auth;
|
||||
|
||||
import com.alibaba.nacos.config.server.model.Page;
|
||||
import com.alibaba.nacos.config.server.model.User;
|
||||
import com.alibaba.nacos.config.server.service.PersistService;
|
||||
import com.alibaba.nacos.config.server.service.transaction.DatabaseOperate;
|
||||
import com.alibaba.nacos.config.server.service.transaction.SqlContextUtils;
|
||||
import com.alibaba.nacos.config.server.utils.PaginationHelper;
|
||||
import java.util.ArrayList;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import static com.alibaba.nacos.config.server.service.RowMapperManager.USER_ROW_MAPPER;
|
||||
|
||||
/**
|
||||
* User CRUD service
|
||||
@ -33,67 +24,17 @@ import static com.alibaba.nacos.config.server.service.RowMapperManager.USER_ROW_
|
||||
* @author nkorange
|
||||
* @since 1.2.0
|
||||
*/
|
||||
@Service
|
||||
public class UserPersistService extends PersistService {
|
||||
@SuppressWarnings("PMD.AbstractMethodOrInterfaceMethodMustUseJavadocRule")
|
||||
public interface UserPersistService {
|
||||
|
||||
@Autowired
|
||||
private DatabaseOperate databaseOperate;
|
||||
void createUser(String username, String password);
|
||||
|
||||
public void createUser(String username, String password) {
|
||||
String sql = "INSERT into users (username, password, enabled) VALUES (?, ?, ?)";
|
||||
void deleteUser(String username);
|
||||
|
||||
try {
|
||||
SqlContextUtils.addSqlContext(sql, username, password, true);
|
||||
databaseOperate.updateAuto();
|
||||
} finally {
|
||||
SqlContextUtils.cleanCurrentSqlContext();
|
||||
}
|
||||
}
|
||||
void updateUserPassword(String username, String password);
|
||||
|
||||
public void deleteUser(String username) {
|
||||
String sql = "DELETE from users WHERE username=?";
|
||||
try {
|
||||
SqlContextUtils.addSqlContext(sql, username);
|
||||
databaseOperate.updateAuto();
|
||||
} finally {
|
||||
SqlContextUtils.cleanCurrentSqlContext();
|
||||
}
|
||||
}
|
||||
User findUserByUsername(String username);
|
||||
|
||||
public void updateUserPassword(String username, String password) {
|
||||
try {
|
||||
SqlContextUtils.addSqlContext(
|
||||
"UPDATE users SET password = ? WHERE username=?",
|
||||
password, username);
|
||||
databaseOperate.updateAuto();
|
||||
} finally {
|
||||
SqlContextUtils.cleanCurrentSqlContext();
|
||||
}
|
||||
}
|
||||
|
||||
public User findUserByUsername(String username) {
|
||||
String sql = "SELECT username,password FROM users WHERE username=? ";
|
||||
return databaseOperate.queryOne(sql, new Object[]{username}, USER_ROW_MAPPER);
|
||||
}
|
||||
|
||||
public Page<User> getUsers(int pageNo, int pageSize) {
|
||||
|
||||
PaginationHelper<User> helper = new PaginationHelper<>();
|
||||
|
||||
String sqlCountRows = "select count(*) from users where ";
|
||||
String sqlFetchRows
|
||||
= "select username,password from users where ";
|
||||
|
||||
String where = " 1=1 ";
|
||||
Page<User> pageInfo = helper.fetchPage(databaseOperate, sqlCountRows
|
||||
+ where, sqlFetchRows + where, new ArrayList<String>().toArray(), pageNo,
|
||||
pageSize, USER_ROW_MAPPER);
|
||||
if (pageInfo == null) {
|
||||
pageInfo = new Page<>();
|
||||
pageInfo.setTotalCount(0);
|
||||
pageInfo.setPageItems(new ArrayList<>());
|
||||
}
|
||||
return pageInfo;
|
||||
}
|
||||
Page<User> getUsers(int pageNo, int pageSize);
|
||||
|
||||
}
|
||||
|
@ -14,7 +14,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.alibaba.nacos.config.server.service.transaction;
|
||||
package com.alibaba.nacos.config.server.configuration;
|
||||
|
||||
import com.alibaba.nacos.config.server.utils.PropertyUtil;
|
||||
import com.alibaba.nacos.core.utils.ApplicationUtils;
|
||||
@ -27,7 +27,7 @@ import org.springframework.core.type.AnnotatedTypeMetadata;
|
||||
*
|
||||
* @author <a href="mailto:liaochuntao@live.com">liaochuntao</a>
|
||||
*/
|
||||
public class ConditionOnDistributedStore implements Condition {
|
||||
public class ConditionDistributedEmbedStorage implements Condition {
|
||||
|
||||
@Override
|
||||
public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
|
@ -0,0 +1,33 @@
|
||||
/*
|
||||
* Copyright 1999-2018 Alibaba Group Holding Ltd.
|
||||
*
|
||||
* 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 com.alibaba.nacos.config.server.configuration;
|
||||
|
||||
import com.alibaba.nacos.config.server.utils.PropertyUtil;
|
||||
import org.springframework.context.annotation.Condition;
|
||||
import org.springframework.context.annotation.ConditionContext;
|
||||
import org.springframework.core.type.AnnotatedTypeMetadata;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:liaochuntao@live.com">liaochuntao</a>
|
||||
*/
|
||||
public class ConditionOnEmbeddedStorage implements Condition {
|
||||
|
||||
@Override
|
||||
public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
|
||||
return PropertyUtil.isEmbeddedStorage();
|
||||
}
|
||||
}
|
@ -0,0 +1,34 @@
|
||||
/*
|
||||
* Copyright 1999-2018 Alibaba Group Holding Ltd.
|
||||
*
|
||||
* 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 com.alibaba.nacos.config.server.configuration;
|
||||
|
||||
import com.alibaba.nacos.config.server.utils.PropertyUtil;
|
||||
import org.springframework.context.annotation.Condition;
|
||||
import org.springframework.context.annotation.ConditionContext;
|
||||
import org.springframework.core.type.AnnotatedTypeMetadata;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:liaochuntao@live.com">liaochuntao</a>
|
||||
*/
|
||||
public class ConditionOnExternalStorage implements Condition {
|
||||
|
||||
@Override
|
||||
public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
|
||||
return !PropertyUtil.isEmbeddedStorage();
|
||||
}
|
||||
|
||||
}
|
@ -14,7 +14,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.alibaba.nacos.config.server.service.transaction;
|
||||
package com.alibaba.nacos.config.server.configuration;
|
||||
|
||||
import com.alibaba.nacos.config.server.utils.PropertyUtil;
|
||||
import com.alibaba.nacos.core.utils.ApplicationUtils;
|
||||
@ -27,10 +27,10 @@ import org.springframework.core.type.AnnotatedTypeMetadata;
|
||||
*
|
||||
* @author <a href="mailto:liaochuntao@live.com">liaochuntao</a>
|
||||
*/
|
||||
public class ConditionOnDefaultStore implements Condition {
|
||||
public class ConditionStandaloneEmbedStorage implements Condition {
|
||||
|
||||
@Override
|
||||
public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
|
||||
return !(PropertyUtil.isEmbeddedStorage() && !ApplicationUtils.getStandaloneMode());
|
||||
return PropertyUtil.isEmbeddedStorage() && ApplicationUtils.getStandaloneMode();
|
||||
}
|
||||
}
|
@ -17,7 +17,6 @@ package com.alibaba.nacos.config.server.configuration;
|
||||
|
||||
import com.alibaba.nacos.config.server.filter.NacosWebFilter;
|
||||
import com.alibaba.nacos.config.server.filter.TransferToLeaderFilter;
|
||||
import com.alibaba.nacos.config.server.service.transaction.ConditionOnDistributedStore;
|
||||
import org.springframework.boot.web.servlet.FilterRegistrationBean;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Conditional;
|
||||
@ -42,7 +41,7 @@ public class NacosConfigConfiguration {
|
||||
return registration;
|
||||
}
|
||||
|
||||
@Conditional(ConditionOnDistributedStore.class)
|
||||
@Conditional(ConditionDistributedEmbedStorage.class)
|
||||
@Bean
|
||||
public FilterRegistrationBean transferToLeaderRegistration() {
|
||||
FilterRegistrationBean<TransferToLeaderFilter> registration = new FilterRegistrationBean<>();
|
||||
@ -58,7 +57,7 @@ public class NacosConfigConfiguration {
|
||||
return new NacosWebFilter();
|
||||
}
|
||||
|
||||
@Conditional(ConditionOnDistributedStore.class)
|
||||
@Conditional(ConditionDistributedEmbedStorage.class)
|
||||
@Bean
|
||||
public TransferToLeaderFilter transferToLeader() {
|
||||
return new TransferToLeaderFilter();
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -20,7 +20,7 @@ import com.alibaba.nacos.common.model.RestResultUtils;
|
||||
import com.alibaba.nacos.config.server.constant.Constants;
|
||||
import com.alibaba.nacos.config.server.service.DynamicDataSource;
|
||||
import com.alibaba.nacos.config.server.service.LocalDataSourceServiceImpl;
|
||||
import com.alibaba.nacos.config.server.service.PersistService;
|
||||
import com.alibaba.nacos.config.server.service.repository.PersistService;
|
||||
import com.alibaba.nacos.config.server.service.dump.DumpService;
|
||||
import com.alibaba.nacos.config.server.utils.LogUtil;
|
||||
import com.alibaba.nacos.config.server.utils.PropertyUtil;
|
||||
@ -81,17 +81,21 @@ public class ConfigOpsController {
|
||||
@GetMapping(value = "/derby")
|
||||
public RestResult<Object> derbyOps(@RequestParam(value = "sql") String sql) {
|
||||
String selectSign = "select";
|
||||
if (!PropertyUtil.isUseExternalDB()) {
|
||||
LocalDataSourceServiceImpl dataSourceService = (LocalDataSourceServiceImpl) DynamicDataSource
|
||||
.getInstance().getDataSource();
|
||||
if (StringUtils.startsWithIgnoreCase(sql, selectSign)) {
|
||||
JdbcTemplate template = dataSourceService.getJdbcTemplate();
|
||||
List<Map<String, Object>> result = template.queryForList(sql);
|
||||
return RestResultUtils.success(result);
|
||||
try {
|
||||
if (PropertyUtil.isEmbeddedStorage()) {
|
||||
LocalDataSourceServiceImpl dataSourceService = (LocalDataSourceServiceImpl) DynamicDataSource
|
||||
.getInstance().getDataSource();
|
||||
if (StringUtils.startsWithIgnoreCase(sql, selectSign)) {
|
||||
JdbcTemplate template = dataSourceService.getJdbcTemplate();
|
||||
List<Map<String, Object>> result = template.queryForList(sql);
|
||||
return RestResultUtils.success(result);
|
||||
}
|
||||
return RestResultUtils.failed("Only query statements are allowed to be executed");
|
||||
}
|
||||
return RestResultUtils.failedWithData("Only query statements are allowed to be executed");
|
||||
return RestResultUtils.failed("The current storage mode is not Derby");
|
||||
} catch (Exception e) {
|
||||
return RestResultUtils.failed(e.getMessage());
|
||||
}
|
||||
return RestResultUtils.failedWithData("The current storage mode is not Derby");
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -21,7 +21,7 @@ import com.alibaba.nacos.config.server.model.ConfigInfoBase;
|
||||
import com.alibaba.nacos.config.server.service.ConfigService;
|
||||
import com.alibaba.nacos.config.server.service.DiskUtil;
|
||||
import com.alibaba.nacos.config.server.service.LongPollingService;
|
||||
import com.alibaba.nacos.config.server.service.PersistService;
|
||||
import com.alibaba.nacos.config.server.service.repository.PersistService;
|
||||
import com.alibaba.nacos.config.server.service.trace.ConfigTraceService;
|
||||
import com.alibaba.nacos.config.server.utils.*;
|
||||
import com.alibaba.nacos.core.utils.Loggers;
|
||||
@ -141,7 +141,7 @@ public class ConfigServletInner {
|
||||
if (isBeta) {
|
||||
md5 = cacheItem.getMd54Beta();
|
||||
lastModified = cacheItem.getLastModifiedTs4Beta();
|
||||
if (PropertyUtil.isEmbeddedStorage()) {
|
||||
if (PropertyUtil.isDirectRead()) {
|
||||
configInfoBase = persistService.findConfigInfo4Beta(dataId, group, tenant);
|
||||
} else {
|
||||
file = DiskUtil.targetBetaFile(dataId, group, tenant);
|
||||
@ -158,7 +158,7 @@ public class ConfigServletInner {
|
||||
lastModified = cacheItem.tagLastModifiedTs.get(autoTag);
|
||||
}
|
||||
}
|
||||
if (PropertyUtil.isEmbeddedStorage()) {
|
||||
if (PropertyUtil.isDirectRead()) {
|
||||
configInfoBase = persistService.findConfigInfo4Tag(dataId, group, tenant, autoTag);
|
||||
} else {
|
||||
file = DiskUtil.targetTagFile(dataId, group, tenant, autoTag);
|
||||
@ -169,7 +169,7 @@ public class ConfigServletInner {
|
||||
} else {
|
||||
md5 = cacheItem.getMd5();
|
||||
lastModified = cacheItem.getLastModifiedTs();
|
||||
if (PropertyUtil.isEmbeddedStorage()) {
|
||||
if (PropertyUtil.isDirectRead()) {
|
||||
configInfoBase = persistService.findConfigInfo(dataId, group, tenant);
|
||||
} else {
|
||||
file = DiskUtil.targetFile(dataId, group, tenant);
|
||||
@ -201,7 +201,7 @@ public class ConfigServletInner {
|
||||
}
|
||||
}
|
||||
}
|
||||
if (PropertyUtil.isEmbeddedStorage()) {
|
||||
if (PropertyUtil.isDirectRead()) {
|
||||
configInfoBase = persistService.findConfigInfo4Tag(dataId, group, tenant, tag);
|
||||
} else {
|
||||
file = DiskUtil.targetTagFile(dataId, group, tenant, tag);
|
||||
@ -231,14 +231,14 @@ public class ConfigServletInner {
|
||||
response.setHeader("Pragma", "no-cache");
|
||||
response.setDateHeader("Expires", 0);
|
||||
response.setHeader("Cache-Control", "no-cache,no-store");
|
||||
if (PropertyUtil.isEmbeddedStorage()) {
|
||||
if (PropertyUtil.isDirectRead()) {
|
||||
response.setDateHeader("Last-Modified", lastModified);
|
||||
} else {
|
||||
fis = new FileInputStream(file);
|
||||
response.setDateHeader("Last-Modified", file.lastModified());
|
||||
}
|
||||
|
||||
if (PropertyUtil.isEmbeddedStorage()) {
|
||||
if (PropertyUtil.isDirectRead()) {
|
||||
out = response.getWriter();
|
||||
out.print(configInfoBase.getContent());
|
||||
out.flush();
|
||||
|
@ -18,7 +18,7 @@ package com.alibaba.nacos.config.server.controller;
|
||||
import com.alibaba.nacos.config.server.constant.Constants;
|
||||
import com.alibaba.nacos.config.server.model.ConfigHistoryInfo;
|
||||
import com.alibaba.nacos.config.server.model.Page;
|
||||
import com.alibaba.nacos.config.server.service.PersistService;
|
||||
import com.alibaba.nacos.config.server.service.repository.PersistService;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.ui.ModelMap;
|
||||
|
@ -1,44 +0,0 @@
|
||||
/*
|
||||
* Copyright 1999-2018 Alibaba Group Holding Ltd.
|
||||
*
|
||||
* 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 com.alibaba.nacos.config.server.exception;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:liaochuntao@live.com">liaochuntao</a>
|
||||
*/
|
||||
public class CircuitException extends RuntimeException {
|
||||
private static final long serialVersionUID = 8469672506678120188L;
|
||||
|
||||
public CircuitException() {
|
||||
super();
|
||||
}
|
||||
|
||||
public CircuitException(String message) {
|
||||
super(message);
|
||||
}
|
||||
|
||||
public CircuitException(String message, Throwable cause) {
|
||||
super(message, cause);
|
||||
}
|
||||
|
||||
public CircuitException(Throwable cause) {
|
||||
super(cause);
|
||||
}
|
||||
|
||||
protected CircuitException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
|
||||
super(message, cause, enableSuppression, writableStackTrace);
|
||||
}
|
||||
}
|
@ -60,12 +60,9 @@ public class NacosWebFilter implements Filter {
|
||||
|
||||
try {
|
||||
chain.doFilter(request, response);
|
||||
} catch (IOException ioe) {
|
||||
} catch (IOException | ServletException ioe) {
|
||||
defaultLog.debug("Filter catch exception, " + ioe.toString(), ioe);
|
||||
throw ioe;
|
||||
} catch (ServletException se) {
|
||||
defaultLog.debug("Filter catch exception, " + se.toString(), se);
|
||||
throw se;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -16,8 +16,10 @@
|
||||
|
||||
package com.alibaba.nacos.config.server.filter;
|
||||
|
||||
import com.alibaba.nacos.common.http.param.MediaType;
|
||||
import com.alibaba.nacos.config.server.constant.Constants;
|
||||
import com.alibaba.nacos.config.server.model.event.RaftDBErrorEvent;
|
||||
import com.alibaba.nacos.config.server.model.event.RaftDBErrorRecoverEvent;
|
||||
import com.alibaba.nacos.config.server.utils.LogUtil;
|
||||
import com.alibaba.nacos.consistency.cp.CPProtocol;
|
||||
import com.alibaba.nacos.core.cluster.Member;
|
||||
@ -26,8 +28,8 @@ import com.alibaba.nacos.core.cluster.ServerMemberManager;
|
||||
import com.alibaba.nacos.core.code.ControllerMethodsCache;
|
||||
import com.alibaba.nacos.core.notify.Event;
|
||||
import com.alibaba.nacos.core.notify.NotifyCenter;
|
||||
import com.alibaba.nacos.core.notify.listener.Subscribe;
|
||||
import com.alibaba.nacos.core.utils.ExceptionUtil;
|
||||
import com.alibaba.nacos.core.notify.listener.SmartSubscribe;
|
||||
import com.alibaba.nacos.common.utils.ExceptionUtil;
|
||||
import com.alibaba.nacos.core.utils.ReuseHttpRequest;
|
||||
import com.alibaba.nacos.core.utils.ReuseHttpServletRequest;
|
||||
import com.alibaba.nacos.core.utils.ReuseUploadFileHttpServletRequest;
|
||||
@ -36,10 +38,9 @@ import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.http.HttpEntity;
|
||||
import org.springframework.http.HttpHeaders;
|
||||
import org.springframework.http.HttpMethod;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.web.client.RestTemplate;
|
||||
import org.springframework.web.multipart.MultipartHttpServletRequest;
|
||||
import org.springframework.web.multipart.support.StandardMultipartHttpServletRequest;
|
||||
|
||||
import javax.annotation.PostConstruct;
|
||||
import javax.servlet.Filter;
|
||||
@ -78,7 +79,7 @@ public class TransferToLeaderFilter implements Filter {
|
||||
private ControllerMethodsCache controllerMethodsCache;
|
||||
|
||||
private volatile String leaderServer = "";
|
||||
private static final int MAX_TRANSFER_CNT = 3;
|
||||
private static final int MAX_TRANSFER_CNT = 1;
|
||||
|
||||
private final RestTemplate restTemplate = new RestTemplate();
|
||||
|
||||
@ -87,49 +88,15 @@ public class TransferToLeaderFilter implements Filter {
|
||||
@PostConstruct
|
||||
protected void init() {
|
||||
LogUtil.defaultLog.info("Open the request and forward it to the leader");
|
||||
protocol.protocolMetaData()
|
||||
.subscribe(Constants.CONFIG_MODEL_RAFT_GROUP,
|
||||
com.alibaba.nacos.consistency.cp.Constants.LEADER_META_DATA, new Observer() {
|
||||
@Override
|
||||
public void update(Observable o, Object arg) {
|
||||
final String raftLeader = String.valueOf(arg);
|
||||
boolean found = false;
|
||||
for (Map.Entry<String, Member> entry : memberManager.getServerList().entrySet()) {
|
||||
final Member member = entry.getValue();
|
||||
final String raftAddress = member.getIp() + ":" + member.getExtendVal(
|
||||
MemberMetaDataConstants.RAFT_PORT);
|
||||
if (StringUtils.equals(raftLeader, raftAddress)) {
|
||||
leaderServer = entry.getKey();
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!found) {
|
||||
leaderServer = "";
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
NotifyCenter.registerSubscribe(new Subscribe<RaftDBErrorEvent>() {
|
||||
|
||||
@Override
|
||||
public void onEvent(RaftDBErrorEvent event) {
|
||||
downgrading = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<? extends Event> subscribeType() {
|
||||
return RaftDBErrorEvent.class;
|
||||
}
|
||||
});
|
||||
|
||||
listenerLeaderStatus();
|
||||
registerSubscribe();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void doFilter(ServletRequest request, ServletResponse response,
|
||||
FilterChain chain) throws IOException, ServletException {
|
||||
ReuseHttpRequest req;
|
||||
if (StringUtils.containsIgnoreCase(request.getContentType(), "multipart/form-data")) {
|
||||
if (StringUtils.containsIgnoreCase(request.getContentType(), MediaType.MULTIPART_FORM_DATA)) {
|
||||
req = new ReuseUploadFileHttpServletRequest((HttpServletRequest) request);
|
||||
} else {
|
||||
req = new ReuseHttpServletRequest((HttpServletRequest) request);
|
||||
@ -153,9 +120,16 @@ public class TransferToLeaderFilter implements Filter {
|
||||
// Determine if the system degradation was triggered
|
||||
// System demotion is enabled and all requests are forwarded to the leader node
|
||||
|
||||
if (downgrading || method.isAnnotationPresent(ToLeader.class) && !protocol.isLeader(Constants.CONFIG_MODEL_RAFT_GROUP)) {
|
||||
boolean isLeader = protocol.isLeader(Constants.CONFIG_MODEL_RAFT_GROUP);
|
||||
|
||||
if (downgrading && isLeader) {
|
||||
resp.sendError(HttpStatus.LOCKED.value(), "Unable to process the request at this time: System triggered degradation");
|
||||
return;
|
||||
}
|
||||
|
||||
if (downgrading || (method.isAnnotationPresent(ToLeader.class) && !isLeader)) {
|
||||
if (StringUtils.isBlank(leaderServer)) {
|
||||
resp.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "Unable to process the request at this time: no Leader");
|
||||
resp.sendError(HttpStatus.LOCKED.value(), "Unable to process the request at this time: no Leader");
|
||||
return;
|
||||
}
|
||||
|
||||
@ -195,6 +169,7 @@ public class TransferToLeaderFilter implements Filter {
|
||||
"no such api:" + req.getMethod() + ":" + req.getRequestURI());
|
||||
return;
|
||||
} catch (Exception e) {
|
||||
LogUtil.defaultLog.error("An exception occurred when the request was forwarded to the Leader node, {}", e);
|
||||
resp.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR,
|
||||
"Server failed," + ExceptionUtil.getAllExceptionMsg(e));
|
||||
return;
|
||||
@ -206,4 +181,51 @@ public class TransferToLeaderFilter implements Filter {
|
||||
public void destroy() {
|
||||
|
||||
}
|
||||
|
||||
private void listenerLeaderStatus() {
|
||||
protocol.protocolMetaData()
|
||||
.subscribe(Constants.CONFIG_MODEL_RAFT_GROUP,
|
||||
com.alibaba.nacos.consistency.cp.Constants.LEADER_META_DATA,
|
||||
new Observer() {
|
||||
@Override
|
||||
public void update(Observable o, Object arg) {
|
||||
final String raftLeader = String.valueOf(arg);
|
||||
boolean found = false;
|
||||
for (Map.Entry<String, Member> entry : memberManager.getServerList().entrySet()) {
|
||||
final Member member = entry.getValue();
|
||||
final String raftAddress = member.getIp() + ":" + member.getExtendVal(
|
||||
MemberMetaDataConstants.RAFT_PORT);
|
||||
if (StringUtils.equals(raftLeader, raftAddress)) {
|
||||
leaderServer = entry.getKey();
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!found) {
|
||||
leaderServer = "";
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void registerSubscribe() {
|
||||
NotifyCenter.registerSubscribe(new SmartSubscribe() {
|
||||
|
||||
@Override
|
||||
public void onEvent(Event event) {
|
||||
if (event instanceof RaftDBErrorRecoverEvent) {
|
||||
downgrading = false;
|
||||
return;
|
||||
}
|
||||
if (event instanceof RaftDBErrorEvent) {
|
||||
downgrading = true;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canNotify(Event event) {
|
||||
return (event instanceof RaftDBErrorEvent) || (event instanceof RaftDBErrorRecoverEvent);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -15,6 +15,7 @@
|
||||
*/
|
||||
package com.alibaba.nacos.config.server.model;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
@ -23,8 +24,9 @@ import java.util.List;
|
||||
* @author Nacos
|
||||
*/
|
||||
@SuppressWarnings("PMD.ClassNamingShouldBeCamelRule")
|
||||
public class ACLInfo {
|
||||
public class ACLInfo implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = 1383026926036269457L;
|
||||
private Boolean isOpen;
|
||||
private List<String> ips;
|
||||
|
||||
|
@ -15,6 +15,7 @@
|
||||
*/
|
||||
package com.alibaba.nacos.config.server.model;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.sql.Timestamp;
|
||||
|
||||
/**
|
||||
@ -22,8 +23,9 @@ import java.sql.Timestamp;
|
||||
*
|
||||
* @author Nacos
|
||||
*/
|
||||
public class ConfigHistoryInfo {
|
||||
public class ConfigHistoryInfo implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = -7827521105376245603L;
|
||||
/**
|
||||
* id, nid, data_id, group_id, content, md5, gmt_create, gmt_modified, (配置创建时间,配置变更时间) src_user, src_ip, (变更操作者)
|
||||
* op_type(变更操作类型)
|
||||
|
@ -15,13 +15,16 @@
|
||||
*/
|
||||
package com.alibaba.nacos.config.server.model;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* 变化的配置信息, 聚合时使用
|
||||
*
|
||||
* @author leiwen.zh
|
||||
*/
|
||||
public class ConfigInfoChanged {
|
||||
public class ConfigInfoChanged implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = -1819539062100125171L;
|
||||
private String dataId;
|
||||
private String group;
|
||||
private String tenant;
|
||||
|
@ -15,12 +15,16 @@
|
||||
*/
|
||||
package com.alibaba.nacos.config.server.model;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* history context
|
||||
*
|
||||
* @author Nacos
|
||||
*/
|
||||
public class HistoryContext {
|
||||
public class HistoryContext implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = -8400843549603420766L;
|
||||
public String serverId;
|
||||
public String dataId;
|
||||
public String group;
|
||||
|
@ -15,6 +15,7 @@
|
||||
*/
|
||||
package com.alibaba.nacos.config.server.model;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.sql.Timestamp;
|
||||
|
||||
/**
|
||||
@ -22,8 +23,9 @@ import java.sql.Timestamp;
|
||||
*
|
||||
* @author Nacos
|
||||
*/
|
||||
public class SubInfo {
|
||||
public class SubInfo implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = -3900485932969066685L;
|
||||
private String appName;
|
||||
private String dataId;
|
||||
private String group;
|
||||
|
@ -15,12 +15,16 @@
|
||||
*/
|
||||
package com.alibaba.nacos.config.server.model;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* subcriber status
|
||||
*
|
||||
* @author Nacos
|
||||
*/
|
||||
public class SubscriberStatus {
|
||||
public class SubscriberStatus implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = 1065466896062351086L;
|
||||
String groupKey;
|
||||
String md5;
|
||||
Long lastTime;
|
||||
|
@ -15,13 +15,16 @@
|
||||
*/
|
||||
package com.alibaba.nacos.config.server.model;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* tenant info
|
||||
*
|
||||
* @author Nacos
|
||||
*/
|
||||
public class TenantInfo {
|
||||
public class TenantInfo implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = -1498218072016383809L;
|
||||
private String tenantId;
|
||||
private String tenantName;
|
||||
private String tenantDesc;
|
||||
|
@ -15,12 +15,16 @@
|
||||
*/
|
||||
package com.alibaba.nacos.config.server.model;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* user info
|
||||
*
|
||||
* @author wfnuser
|
||||
*/
|
||||
public class User {
|
||||
public class User implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = 3371769277802700069L;
|
||||
private String username;
|
||||
private String password;
|
||||
|
||||
|
@ -15,6 +15,7 @@
|
||||
*/
|
||||
package com.alibaba.nacos.config.server.model.capacity;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.sql.Timestamp;
|
||||
|
||||
/**
|
||||
@ -23,7 +24,9 @@ import java.sql.Timestamp;
|
||||
* @author hexu.hxy
|
||||
* @date 2018/3/13
|
||||
*/
|
||||
public class Capacity {
|
||||
public class Capacity implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = 77343194329627468L;
|
||||
private Long id;
|
||||
private Integer quota;
|
||||
private Integer usage;
|
||||
|
@ -22,6 +22,8 @@ package com.alibaba.nacos.config.server.model.capacity;
|
||||
* @date 2018/3/13
|
||||
*/
|
||||
public class GroupCapacity extends Capacity {
|
||||
|
||||
private static final long serialVersionUID = 5888791286289014878L;
|
||||
private String group;
|
||||
|
||||
public String getGroup() {
|
||||
|
@ -22,6 +22,8 @@ package com.alibaba.nacos.config.server.model.capacity;
|
||||
* @date 2018/3/13
|
||||
*/
|
||||
public class TenantCapacity extends Capacity {
|
||||
|
||||
private static final long serialVersionUID = -1238179608935781384L;
|
||||
private String tenant;
|
||||
|
||||
public String getTenant() {
|
||||
|
@ -15,11 +15,18 @@
|
||||
*/
|
||||
package com.alibaba.nacos.config.server.model.event;
|
||||
|
||||
import com.alibaba.nacos.core.distributed.raft.RaftErrorEvent;
|
||||
import com.alibaba.nacos.core.notify.Event;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:liaochunyhm@live.com">liaochuntao</a>
|
||||
*/
|
||||
@SuppressWarnings("PMD.ClassNamingShouldBeCamelRule")
|
||||
public class RaftDBErrorEvent extends RaftErrorEvent {
|
||||
public class RaftDBErrorEvent implements Event {
|
||||
|
||||
private static final long serialVersionUID = 101591819161802336L;
|
||||
|
||||
@Override
|
||||
public Class<? extends Event> eventType() {
|
||||
return RaftDBErrorEvent.class;
|
||||
}
|
||||
}
|
||||
|
@ -14,35 +14,21 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.alibaba.nacos.common.model;
|
||||
package com.alibaba.nacos.config.server.model.event;
|
||||
|
||||
import com.alibaba.nacos.common.http.param.Header;
|
||||
import com.alibaba.nacos.core.notify.Event;
|
||||
import com.google.common.annotations.VisibleForTesting;
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @author <a href="mailto:liaochuntao@live.com">liaochuntao</a>
|
||||
*/
|
||||
public class HttpRestResult<T> extends RestResult<T> {
|
||||
|
||||
private static final long serialVersionUID = 143520334044543925L;
|
||||
|
||||
private Header header;
|
||||
|
||||
private int httpCode;
|
||||
|
||||
public int getHttpCode() {
|
||||
return httpCode;
|
||||
}
|
||||
|
||||
public void setHttpCode(int httpCode) {
|
||||
this.httpCode = httpCode;
|
||||
}
|
||||
|
||||
public Header getHeader() {
|
||||
return header;
|
||||
}
|
||||
|
||||
public void setHeader(Header header) {
|
||||
this.header = header;
|
||||
}
|
||||
|
||||
@SuppressWarnings("PMD.ClassNamingShouldBeCamelRule")
|
||||
@VisibleForTesting
|
||||
public class RaftDBErrorRecoverEvent implements Event {
|
||||
@Override
|
||||
public Class<? extends Event> eventType() {
|
||||
return RaftDBErrorRecoverEvent.class;
|
||||
}
|
||||
}
|
@ -17,13 +17,12 @@ package com.alibaba.nacos.config.server.service;
|
||||
|
||||
import com.alibaba.nacos.config.server.monitor.MetricsMonitor;
|
||||
import com.alibaba.nacos.config.server.utils.PropertyUtil;
|
||||
import com.alibaba.nacos.core.utils.ApplicationUtils;
|
||||
import org.apache.commons.dbcp.BasicDataSource;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.commons.lang3.math.NumberUtils;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.core.env.Environment;
|
||||
import org.springframework.dao.DataAccessException;
|
||||
import org.springframework.jdbc.CannotGetJdbcConnectionException;
|
||||
import org.springframework.jdbc.core.JdbcTemplate;
|
||||
@ -77,11 +76,6 @@ public class BasicDataSourceServiceImpl implements DataSourceService {
|
||||
private volatile int masterIndex;
|
||||
private static Pattern ipPattern = Pattern.compile("\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}");
|
||||
|
||||
|
||||
@Autowired
|
||||
private Environment env;
|
||||
|
||||
|
||||
static {
|
||||
try {
|
||||
Class.forName(MYSQL_HIGH_LEVEL_DRIVER);
|
||||
@ -143,7 +137,7 @@ public class BasicDataSourceServiceImpl implements DataSourceService {
|
||||
List<BasicDataSource> dblist = new ArrayList<BasicDataSource>();
|
||||
try {
|
||||
String val = null;
|
||||
val = env.getProperty("db.num");
|
||||
val = ApplicationUtils.getProperty("db.num");
|
||||
if (null == val) {
|
||||
throw new IllegalArgumentException("db.num is null");
|
||||
}
|
||||
@ -153,34 +147,34 @@ public class BasicDataSourceServiceImpl implements DataSourceService {
|
||||
BasicDataSource ds = new BasicDataSource();
|
||||
ds.setDriverClassName(JDBC_DRIVER_NAME);
|
||||
|
||||
val = env.getProperty("db.url." + i);
|
||||
val = ApplicationUtils.getProperty("db.url." + i);
|
||||
if (null == val) {
|
||||
fatalLog.error("db.url." + i + " is null");
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
ds.setUrl(val.trim());
|
||||
|
||||
val = env.getProperty("db.user." + i, env.getProperty("db.user"));
|
||||
val = ApplicationUtils.getProperty("db.user." + i, ApplicationUtils.getProperty("db.user"));
|
||||
if (null == val) {
|
||||
fatalLog.error("db.user." + i + " is null");
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
ds.setUsername(val.trim());
|
||||
|
||||
val = env.getProperty("db.password." + i, env.getProperty("db.password"));
|
||||
val = ApplicationUtils.getProperty("db.password." + i, ApplicationUtils.getProperty("db.password"));
|
||||
if (null == val) {
|
||||
fatalLog.error("db.password." + i + " is null");
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
ds.setPassword(val.trim());
|
||||
|
||||
val = env.getProperty("db.initialSize." + i, env.getProperty("db.initialSize"));
|
||||
val = ApplicationUtils.getProperty("db.initialSize." + i, ApplicationUtils.getProperty("db.initialSize"));
|
||||
ds.setInitialSize(Integer.parseInt(defaultIfNull(val, "10")));
|
||||
|
||||
val = env.getProperty("db.maxActive." + i, env.getProperty("db.maxActive"));
|
||||
val = ApplicationUtils.getProperty("db.maxActive." + i, ApplicationUtils.getProperty("db.maxActive"));
|
||||
ds.setMaxActive(Integer.parseInt(defaultIfNull(val, "20")));
|
||||
|
||||
val = env.getProperty("db.maxIdle." + i, env.getProperty("db.maxIdle"));
|
||||
val = ApplicationUtils.getProperty("db.maxIdle." + i, ApplicationUtils.getProperty("db.maxIdle"));
|
||||
ds.setMaxIdle(Integer.parseInt(defaultIfNull(val, "50")));
|
||||
|
||||
ds.setMaxWait(3000L);
|
||||
|
@ -19,6 +19,7 @@ import com.alibaba.nacos.common.utils.Md5Utils;
|
||||
import com.alibaba.nacos.config.server.constant.Constants;
|
||||
import com.alibaba.nacos.config.server.model.CacheItem;
|
||||
import com.alibaba.nacos.config.server.model.ConfigInfoBase;
|
||||
import com.alibaba.nacos.config.server.service.repository.PersistService;
|
||||
import com.alibaba.nacos.config.server.utils.GroupKey;
|
||||
import com.alibaba.nacos.config.server.utils.GroupKey2;
|
||||
import com.alibaba.nacos.config.server.utils.PropertyUtil;
|
||||
@ -76,7 +77,7 @@ public class ConfigService {
|
||||
"[dump-ignore] ignore to save cache file. groupKey={}, md5={}, lastModifiedOld={}, "
|
||||
+ "lastModifiedNew={}",
|
||||
groupKey, md5, ConfigService.getLastModifiedTs(groupKey), lastModifiedTs);
|
||||
} else if (PropertyUtil.isUseExternalDB()) {
|
||||
} else if (!PropertyUtil.isDirectRead()) {
|
||||
DiskUtil.saveToDisk(dataId, group, tenant, content);
|
||||
}
|
||||
updateMd5(groupKey, md5, lastModifiedTs);
|
||||
@ -121,7 +122,7 @@ public class ConfigService {
|
||||
"[dump-beta-ignore] ignore to save cache file. groupKey={}, md5={}, lastModifiedOld={}, "
|
||||
+ "lastModifiedNew={}",
|
||||
groupKey, md5, ConfigService.getLastModifiedTs(groupKey), lastModifiedTs);
|
||||
} else if (PropertyUtil.isUseExternalDB()) {
|
||||
} else if (!PropertyUtil.isDirectRead()) {
|
||||
DiskUtil.saveBetaToDisk(dataId, group, tenant, content);
|
||||
}
|
||||
String[] betaIpsArr = betaIps.split(",");
|
||||
@ -160,7 +161,7 @@ public class ConfigService {
|
||||
"[dump-tag-ignore] ignore to save cache file. groupKey={}, md5={}, lastModifiedOld={}, "
|
||||
+ "lastModifiedNew={}",
|
||||
groupKey, md5, ConfigService.getLastModifiedTs(groupKey), lastModifiedTs);
|
||||
} else if (PropertyUtil.isUseExternalDB()) {
|
||||
} else if (!PropertyUtil.isDirectRead()) {
|
||||
DiskUtil.saveTagToDisk(dataId, group, tenant, tag, content);
|
||||
}
|
||||
|
||||
@ -192,7 +193,7 @@ public class ConfigService {
|
||||
|
||||
try {
|
||||
final String md5 = Md5Utils.getMD5(content, Constants.ENCODE);
|
||||
if (PropertyUtil.isUseExternalDB()) {
|
||||
if (!PropertyUtil.isDirectRead()) {
|
||||
String loacalMd5 = DiskUtil.getLocalConfigMd5(dataId, group, tenant);
|
||||
if (md5.equals(loacalMd5)) {
|
||||
dumpLog.warn(
|
||||
@ -324,7 +325,7 @@ public class ConfigService {
|
||||
}
|
||||
|
||||
try {
|
||||
if (PropertyUtil.isUseExternalDB()) {
|
||||
if (!PropertyUtil.isDirectRead()) {
|
||||
DiskUtil.removeConfigInfo(dataId, group, tenant);
|
||||
}
|
||||
CACHE.remove(groupKey);
|
||||
@ -358,7 +359,7 @@ public class ConfigService {
|
||||
}
|
||||
|
||||
try {
|
||||
if (PropertyUtil.isUseExternalDB()) {
|
||||
if (!PropertyUtil.isDirectRead()) {
|
||||
DiskUtil.removeConfigInfo4Beta(dataId, group, tenant);
|
||||
}
|
||||
EventDispatcher.fireEvent(new LocalDataChangeEvent(groupKey, true, CACHE.get(groupKey).getIps4Beta()));
|
||||
@ -393,7 +394,7 @@ public class ConfigService {
|
||||
}
|
||||
|
||||
try {
|
||||
if (PropertyUtil.isUseExternalDB()) {
|
||||
if (!PropertyUtil.isDirectRead()) {
|
||||
DiskUtil.removeConfigInfo4Tag(dataId, group, tenant, tag);
|
||||
}
|
||||
|
||||
|
@ -18,7 +18,7 @@ package com.alibaba.nacos.config.server.service;
|
||||
import com.alibaba.nacos.config.server.constant.Constants;
|
||||
import com.alibaba.nacos.config.server.utils.LogUtil;
|
||||
import com.alibaba.nacos.config.server.utils.PropertyUtil;
|
||||
import com.alibaba.nacos.core.utils.DiskUtils;
|
||||
import com.alibaba.nacos.common.utils.DiskUtils;
|
||||
import com.alibaba.nacos.core.utils.ApplicationUtils;
|
||||
import com.zaxxer.hikari.HikariDataSource;
|
||||
import java.io.File;
|
||||
@ -59,6 +59,8 @@ public class LocalDataSourceServiceImpl implements DataSourceService {
|
||||
private boolean initialize = false;
|
||||
private boolean jdbcTemplateInit = false;
|
||||
|
||||
private String healthStatus = "UP";
|
||||
|
||||
@PostConstruct
|
||||
@Override
|
||||
public synchronized void init() throws Exception {
|
||||
@ -165,7 +167,11 @@ public class LocalDataSourceServiceImpl implements DataSourceService {
|
||||
|
||||
@Override
|
||||
public String getHealth() {
|
||||
return "UP";
|
||||
return healthStatus;
|
||||
}
|
||||
|
||||
public void setHealthStatus(String healthStatus) {
|
||||
this.healthStatus = healthStatus;
|
||||
}
|
||||
|
||||
/**
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -19,7 +19,7 @@ import com.alibaba.nacos.config.server.constant.CounterMode;
|
||||
import com.alibaba.nacos.config.server.model.capacity.Capacity;
|
||||
import com.alibaba.nacos.config.server.model.capacity.GroupCapacity;
|
||||
import com.alibaba.nacos.config.server.model.capacity.TenantCapacity;
|
||||
import com.alibaba.nacos.config.server.service.PersistService;
|
||||
import com.alibaba.nacos.config.server.service.repository.PersistService;
|
||||
import com.alibaba.nacos.config.server.utils.LogUtil;
|
||||
import com.alibaba.nacos.config.server.utils.PropertyUtil;
|
||||
import com.alibaba.nacos.config.server.utils.TimeUtils;
|
||||
|
@ -26,6 +26,7 @@ import com.alibaba.nacos.config.server.model.ConfigInfoWrapper;
|
||||
import com.alibaba.nacos.config.server.model.Page;
|
||||
import com.alibaba.nacos.config.server.service.*;
|
||||
import com.alibaba.nacos.config.server.service.merge.MergeTaskProcessor;
|
||||
import com.alibaba.nacos.config.server.service.repository.PersistService;
|
||||
import com.alibaba.nacos.config.server.utils.*;
|
||||
|
||||
import com.alibaba.nacos.consistency.cp.CPProtocol;
|
||||
@ -67,7 +68,7 @@ import static com.alibaba.nacos.config.server.utils.LogUtil.fatalLog;
|
||||
public class DumpService {
|
||||
|
||||
@Autowired
|
||||
PersistService persistService;
|
||||
PersistService persistService;
|
||||
|
||||
@Autowired
|
||||
private ServerMemberManager memberManager;
|
||||
@ -416,11 +417,12 @@ public class DumpService {
|
||||
}
|
||||
|
||||
private boolean canExecute() {
|
||||
if (!PropertyUtil.isEmbeddedStorage()) {
|
||||
return true;
|
||||
}
|
||||
try {
|
||||
return protocol.isLeader(Constants.CONFIG_MODEL_RAFT_GROUP);
|
||||
// if is derby + raft mode, only leader can execute
|
||||
if (PropertyUtil.isEmbeddedStorage() && !ApplicationUtils.getStandaloneMode()) {
|
||||
return protocol.isLeader(Constants.CONFIG_MODEL_RAFT_GROUP);
|
||||
}
|
||||
return true;
|
||||
} catch (NoSuchRaftGroupException e) {
|
||||
return true;
|
||||
} catch (Exception e) {
|
||||
|
@ -27,6 +27,7 @@ import com.alibaba.nacos.config.server.model.ConfigInfoTagWrapper;
|
||||
import com.alibaba.nacos.config.server.model.ConfigInfoWrapper;
|
||||
import com.alibaba.nacos.config.server.model.Page;
|
||||
import com.alibaba.nacos.config.server.service.*;
|
||||
import com.alibaba.nacos.config.server.service.repository.PersistService;
|
||||
import com.alibaba.nacos.config.server.service.trace.ConfigTraceService;
|
||||
import com.alibaba.nacos.config.server.utils.GroupKey2;
|
||||
import com.alibaba.nacos.config.server.utils.LogUtil;
|
||||
|
@ -21,7 +21,7 @@ import com.alibaba.nacos.config.server.model.ConfigInfo;
|
||||
import com.alibaba.nacos.config.server.model.ConfigInfoAggr;
|
||||
import com.alibaba.nacos.config.server.model.ConfigInfoChanged;
|
||||
import com.alibaba.nacos.config.server.model.Page;
|
||||
import com.alibaba.nacos.config.server.service.PersistService;
|
||||
import com.alibaba.nacos.config.server.service.repository.PersistService;
|
||||
import com.alibaba.nacos.config.server.utils.ContentUtils;
|
||||
import com.alibaba.nacos.config.server.utils.PropertyUtil;
|
||||
import com.alibaba.nacos.config.server.utils.TimeUtils;
|
||||
|
@ -22,7 +22,7 @@ import com.alibaba.nacos.config.server.model.ConfigInfo;
|
||||
import com.alibaba.nacos.config.server.model.ConfigInfoAggr;
|
||||
import com.alibaba.nacos.config.server.model.Page;
|
||||
import com.alibaba.nacos.config.server.service.ConfigDataChangeEvent;
|
||||
import com.alibaba.nacos.config.server.service.PersistService;
|
||||
import com.alibaba.nacos.config.server.service.repository.PersistService;
|
||||
import com.alibaba.nacos.config.server.service.trace.ConfigTraceService;
|
||||
import com.alibaba.nacos.config.server.utils.ContentUtils;
|
||||
import com.alibaba.nacos.config.server.utils.TimeUtils;
|
||||
|
@ -133,8 +133,9 @@ public class AsyncNotifyService extends AbstractEventListener {
|
||||
if (memberManager.hasMember(
|
||||
targetIp)) {
|
||||
// 启动健康检查且有不监控的ip则直接把放到通知队列,否则通知
|
||||
if (memberManager.isHealthCheck()
|
||||
&& memberManager.isUnHealth(targetIp)) {
|
||||
boolean unHealthNeedDelay = memberManager.isHealthCheck()
|
||||
&& memberManager.isUnHealth(targetIp);
|
||||
if (unHealthNeedDelay) {
|
||||
// target ip 不健康,则放入通知列表中
|
||||
ConfigTraceService.logNotifyEvent(task.getDataId(), task.getGroup(), task.getTenant(), null,
|
||||
task.getLastModified(),
|
||||
|
@ -14,18 +14,20 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.alibaba.nacos.config.server.service.transaction;
|
||||
package com.alibaba.nacos.config.server.service.repository;
|
||||
|
||||
import com.alibaba.nacos.config.server.service.sql.ModifyRequest;
|
||||
import com.alibaba.nacos.config.server.utils.LogUtil;
|
||||
import com.alibaba.nacos.core.utils.ExceptionUtil;
|
||||
import com.alibaba.nacos.common.utils.ExceptionUtil;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import org.springframework.dao.DataAccessException;
|
||||
import org.springframework.dao.DataIntegrityViolationException;
|
||||
import org.springframework.dao.IncorrectResultSizeDataAccessException;
|
||||
import org.springframework.jdbc.BadSqlGrammarException;
|
||||
import org.springframework.jdbc.CannotGetJdbcConnectionException;
|
||||
import org.springframework.jdbc.core.JdbcTemplate;
|
||||
import org.springframework.jdbc.core.RowMapper;
|
||||
import org.springframework.transaction.TransactionException;
|
||||
import org.springframework.transaction.support.TransactionTemplate;
|
||||
|
||||
import static com.alibaba.nacos.config.server.utils.LogUtil.fatalLog;
|
||||
@ -105,7 +107,11 @@ public interface BaseDatabaseOperate {
|
||||
default <R> List<R> queryMany(JdbcTemplate jdbcTemplate, String sql, Object[] args, Class<R> rClass) {
|
||||
try {
|
||||
return jdbcTemplate.queryForList(sql, args, rClass);
|
||||
} catch (CannotGetJdbcConnectionException e) {
|
||||
}
|
||||
catch (IncorrectResultSizeDataAccessException e) {
|
||||
return null;
|
||||
}
|
||||
catch (CannotGetJdbcConnectionException e) {
|
||||
fatalLog.error("[db-error] " + e.toString(), e);
|
||||
throw e;
|
||||
} catch (DataAccessException e) {
|
||||
@ -146,10 +152,12 @@ public interface BaseDatabaseOperate {
|
||||
jdbcTemplate.update(pair.getSql(), pair.getArgs());
|
||||
});
|
||||
return Boolean.TRUE;
|
||||
} catch (TransactionException e) {
|
||||
}
|
||||
catch (BadSqlGrammarException | DataIntegrityViolationException e) {
|
||||
fatalLog.error("[db-error] " + e.toString(), e);
|
||||
return false;
|
||||
} catch (CannotGetJdbcConnectionException e) {
|
||||
}
|
||||
catch (CannotGetJdbcConnectionException e) {
|
||||
fatalLog.error("[db-error] " + e.toString(), e);
|
||||
throw e;
|
||||
} catch (DataAccessException e) {
|
@ -14,10 +14,13 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.alibaba.nacos.config.server.service.transaction;
|
||||
package com.alibaba.nacos.config.server.service.repository;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import com.alibaba.nacos.config.server.service.sql.ModifyRequest;
|
||||
import com.alibaba.nacos.config.server.service.sql.SqlContextUtils;
|
||||
import org.springframework.jdbc.core.RowMapper;
|
||||
|
||||
/**
|
||||
@ -91,7 +94,7 @@ public interface DatabaseOperate {
|
||||
/**
|
||||
* data modify transaction
|
||||
*
|
||||
* @param modifyRequests {@link List< ModifyRequest >}
|
||||
* @param modifyRequests {@link List< ModifyRequest >}
|
||||
* @return is success
|
||||
*/
|
||||
Boolean update(List<ModifyRequest> modifyRequests);
|
||||
@ -102,7 +105,7 @@ public interface DatabaseOperate {
|
||||
*
|
||||
* @return is success
|
||||
*/
|
||||
default Boolean updateAuto() {
|
||||
default Boolean smartUpdate() {
|
||||
try {
|
||||
return update(SqlContextUtils.getCurrentSqlContext());
|
||||
} finally {
|
@ -14,7 +14,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.alibaba.nacos.config.server.service.transaction;
|
||||
package com.alibaba.nacos.config.server.service.repository;
|
||||
|
||||
import com.alibaba.nacos.config.server.service.DataSourceService;
|
||||
import com.alibaba.nacos.config.server.service.DynamicDataSource;
|
||||
@ -26,7 +26,7 @@ import com.alibaba.nacos.consistency.snapshot.Reader;
|
||||
import com.alibaba.nacos.consistency.snapshot.SnapshotOperation;
|
||||
import com.alibaba.nacos.consistency.snapshot.Writer;
|
||||
import com.alibaba.nacos.core.distributed.raft.utils.RaftExecutor;
|
||||
import com.alibaba.nacos.core.utils.DiskUtils;
|
||||
import com.alibaba.nacos.common.utils.DiskUtils;
|
||||
import com.alibaba.nacos.core.utils.ApplicationUtils;
|
||||
import com.alipay.sofa.jraft.util.CRC64;
|
||||
|
@ -0,0 +1,538 @@
|
||||
/*
|
||||
* Copyright 1999-2018 Alibaba Group Holding Ltd.
|
||||
*
|
||||
* 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 com.alibaba.nacos.config.server.service.repository;
|
||||
|
||||
import com.alibaba.nacos.common.utils.Md5Utils;
|
||||
import com.alibaba.nacos.config.server.configuration.ConditionDistributedEmbedStorage;
|
||||
import com.alibaba.nacos.config.server.constant.Constants;
|
||||
import com.alibaba.nacos.config.server.exception.NJdbcException;
|
||||
import com.alibaba.nacos.config.server.model.event.RaftDBErrorEvent;
|
||||
import com.alibaba.nacos.config.server.service.DynamicDataSource;
|
||||
import com.alibaba.nacos.config.server.service.LocalDataSourceServiceImpl;
|
||||
import com.alibaba.nacos.config.server.service.RowMapperManager;
|
||||
import com.alibaba.nacos.config.server.service.sql.ModifyRequest;
|
||||
import com.alibaba.nacos.config.server.service.sql.QueryType;
|
||||
import com.alibaba.nacos.config.server.service.sql.SelectRequest;
|
||||
import com.alibaba.nacos.config.server.utils.LogUtil;
|
||||
import com.alibaba.nacos.consistency.Config;
|
||||
import com.alibaba.nacos.consistency.ConsistencyProtocol;
|
||||
import com.alibaba.nacos.consistency.LogFuture;
|
||||
import com.alibaba.nacos.consistency.SerializeFactory;
|
||||
import com.alibaba.nacos.consistency.Serializer;
|
||||
import com.alibaba.nacos.consistency.cp.LogProcessor4CP;
|
||||
import com.alibaba.nacos.consistency.entity.GetRequest;
|
||||
import com.alibaba.nacos.consistency.entity.GetResponse;
|
||||
import com.alibaba.nacos.consistency.entity.Log;
|
||||
import com.alibaba.nacos.consistency.exception.ConsistencyException;
|
||||
import com.alibaba.nacos.consistency.snapshot.SnapshotOperation;
|
||||
import com.alibaba.nacos.core.cluster.ServerMemberManager;
|
||||
import com.alibaba.nacos.core.distributed.id.SnakeFlowerIdGenerator;
|
||||
import com.alibaba.nacos.core.notify.Event;
|
||||
import com.alibaba.nacos.core.notify.NotifyCenter;
|
||||
import com.alibaba.nacos.core.notify.listener.Subscribe;
|
||||
import com.alibaba.nacos.core.utils.ClassUtils;
|
||||
import com.google.common.annotations.VisibleForTesting;
|
||||
import com.google.common.base.Preconditions;
|
||||
import com.google.protobuf.ByteString;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.annotation.Conditional;
|
||||
import org.springframework.dao.DataAccessException;
|
||||
import org.springframework.dao.DataIntegrityViolationException;
|
||||
import org.springframework.dao.DuplicateKeyException;
|
||||
import org.springframework.jdbc.BadSqlGrammarException;
|
||||
import org.springframework.jdbc.core.JdbcTemplate;
|
||||
import org.springframework.jdbc.core.RowMapper;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.transaction.support.TransactionTemplate;
|
||||
|
||||
import javax.annotation.PostConstruct;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Observable;
|
||||
import java.util.Observer;
|
||||
import java.util.concurrent.locks.ReentrantReadWriteLock;
|
||||
|
||||
/**
|
||||
* <pre>
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
* ┌────────────────────┐
|
||||
* ┌──▶│ PersistService │
|
||||
* │ └────────────────────┘ ┌─────────────────┐
|
||||
* │ │ │ │
|
||||
* │ │ │ ▼
|
||||
* │ │ │ ┌────────────────────────┐
|
||||
* │ │ │ │ acquireSnakeflowerId │
|
||||
* │ │ │ └────────────────────────┘
|
||||
* │ │ │ │
|
||||
* │ │ │ │
|
||||
* │ │ │ ▼
|
||||
* │ │ │ ┌────────────────────┐ save sql
|
||||
* │ ▼ │ │ saveConfig │──────────context─────────────┐
|
||||
* │ ┌────────────────┐ │ └────────────────────┘ │
|
||||
* │ │ publishConfig │───┘ │ │
|
||||
* │ └────────────────┘ │ │
|
||||
* │ ▼ ▼
|
||||
* │ ┌─────────────────────────┐ save sql ┌────────────────────┐
|
||||
* │ │ saveConfigTagRelations │────context────▶│ SqlContextUtils │◀─┐
|
||||
* publish config └─────────────────────────┘ └────────────────────┘ │
|
||||
* │ │ ▲ │
|
||||
* │ │ │ │
|
||||
* │ ▼ │ │
|
||||
* │ ┌───────────────────────┐ save sql │ │
|
||||
* ┌────┐ │ saveConfigHistory │─────────context────────────┘ │
|
||||
* │user│ └───────────────────────┘ │
|
||||
* └────┘ │
|
||||
* ▲ │
|
||||
* │ ┌1:getCurrentSqlContexts───────────────────────────────┘
|
||||
* │ │
|
||||
* │ │
|
||||
* │ │
|
||||
* │ │
|
||||
* │ │
|
||||
* │ │
|
||||
* │ │
|
||||
* │ ┌───────────────┐ ┌─────────────────────┐
|
||||
* │ │ JdbcTemplate │◀───│ DatabaseOperate │───┐
|
||||
* 4:execute result └───────────────┘ └─────────────────────┘ │
|
||||
* │ │ ▲ │
|
||||
* │ │ │ │
|
||||
* │ │ 3:onApply 2:submit(List<ModifyRequest>)
|
||||
* │ │ │ │
|
||||
* │ ▼ │ │
|
||||
* │ ┌──────────────┐ │ │
|
||||
* │ │ Apache Derby │ ┌───────────────────────┐ │
|
||||
* │ └──────────────┘ │ JRaftProtocol │◀─┘
|
||||
* │ └───────────────────────┘
|
||||
* │ │
|
||||
* │ │
|
||||
* └───────────────────────────────────────────┘
|
||||
* </pre>
|
||||
*
|
||||
* @author <a href="mailto:liaochuntao@live.com">liaochuntao</a>
|
||||
*/
|
||||
@SuppressWarnings("all")
|
||||
@Conditional(ConditionDistributedEmbedStorage.class)
|
||||
@Component
|
||||
public class DistributedDatabaseOperateImpl extends LogProcessor4CP
|
||||
implements BaseDatabaseOperate, DatabaseOperate {
|
||||
|
||||
@Autowired
|
||||
private ServerMemberManager memberManager;
|
||||
|
||||
private LocalDataSourceServiceImpl dataSourceService;
|
||||
private JdbcTemplate jdbcTemplate;
|
||||
private TransactionTemplate transactionTemplate;
|
||||
private Serializer serializer = SerializeFactory.getDefault();
|
||||
private ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
|
||||
private ReentrantReadWriteLock.ReadLock readLock = lock.readLock();
|
||||
private ReentrantReadWriteLock.WriteLock writeLock = lock.writeLock();
|
||||
|
||||
@PostConstruct
|
||||
protected void init() throws Exception {
|
||||
dataSourceService = (LocalDataSourceServiceImpl) DynamicDataSource.getInstance()
|
||||
.getDataSource();
|
||||
|
||||
// Because in Raft + Derby mode, ensuring data consistency depends on the Raft's
|
||||
// log playback and snapshot recovery capabilities, and the last data must be cleared
|
||||
dataSourceService.cleanAndReopenDerby();
|
||||
|
||||
jdbcTemplate = dataSourceService.getJdbcTemplate();
|
||||
transactionTemplate = dataSourceService.getTransactionTemplate();
|
||||
|
||||
// Registers a Derby Raft state machine failure event for node degradation processing
|
||||
NotifyCenter.registerPublisher(RaftDBErrorEvent::new, RaftDBErrorEvent.class);
|
||||
|
||||
NotifyCenter.registerSubscribe(new Subscribe<RaftDBErrorEvent>() {
|
||||
@Override
|
||||
public void onEvent(RaftDBErrorEvent event) {
|
||||
dataSourceService.setHealthStatus("DOWN");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<? extends Event> subscribeType() {
|
||||
return RaftDBErrorEvent.class;
|
||||
}
|
||||
});
|
||||
|
||||
LogUtil.defaultLog.info("use DistributedTransactionServicesImpl");
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
public void moickConsistencyProtocol(ConsistencyProtocol protocol) {
|
||||
this.protocol = protocol;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void afterInject(ConsistencyProtocol<? extends Config> protocol) {
|
||||
protocol.protocolMetaData().subscribe(group(),
|
||||
com.alibaba.nacos.consistency.cp.Constants.TERM_META_DATA,
|
||||
new Observer() {
|
||||
@Override
|
||||
public void update(Observable o, Object arg) {
|
||||
long term;
|
||||
if (arg == null) {
|
||||
term = 0L;
|
||||
}
|
||||
else {
|
||||
term = Long.parseLong(String.valueOf(arg));
|
||||
}
|
||||
long dataCenterId =
|
||||
term % SnakeFlowerIdGenerator.MAX_DATA_CENTER_ID;
|
||||
SnakeFlowerIdGenerator.setDataCenterId(dataCenterId);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public <R> R queryOne(String sql, Class<R> cls) {
|
||||
try {
|
||||
LogUtil.defaultLog.debug("queryOne info : sql : {}", sql);
|
||||
|
||||
byte[] data = serializer.serialize(SelectRequest.builder()
|
||||
.queryType(QueryType.QUERY_ONE_NO_MAPPER_NO_ARGS).sql(sql)
|
||||
.className(cls.getCanonicalName()).build());
|
||||
|
||||
GetResponse response = protocol.getData(
|
||||
GetRequest.newBuilder().setGroup(group())
|
||||
.setData(ByteString.copyFrom(data)).build());
|
||||
if (StringUtils.isEmpty(response.getErrMsg())) {
|
||||
return serializer.deserialize(response.getData().toByteArray(), cls);
|
||||
}
|
||||
throw new NJdbcException(response.getErrMsg(), response.getErrMsg());
|
||||
}
|
||||
catch (Exception e) {
|
||||
LogUtil.fatalLog
|
||||
.error("An exception occurred during the query operation : {}", e);
|
||||
throw new NJdbcException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public <R> R queryOne(String sql, Object[] args, Class<R> cls) {
|
||||
try {
|
||||
LogUtil.defaultLog.debug("queryOne info : sql : {}, args : {}", sql, args);
|
||||
|
||||
byte[] data = serializer.serialize(SelectRequest.builder()
|
||||
.queryType(QueryType.QUERY_ONE_NO_MAPPER_WITH_ARGS).sql(sql)
|
||||
.args(args).className(cls.getCanonicalName()).build());
|
||||
|
||||
GetResponse response = protocol.getData(
|
||||
GetRequest.newBuilder().setGroup(group())
|
||||
.setData(ByteString.copyFrom(data)).build());
|
||||
if (StringUtils.isEmpty(response.getErrMsg())) {
|
||||
return serializer.deserialize(response.getData().toByteArray(), cls);
|
||||
}
|
||||
throw new NJdbcException(response.getErrMsg(), response.getErrMsg());
|
||||
}
|
||||
catch (Exception e) {
|
||||
LogUtil.fatalLog
|
||||
.error("An exception occurred during the query operation : {}", e);
|
||||
throw new NJdbcException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public <R> R queryOne(String sql, Object[] args, RowMapper<R> mapper) {
|
||||
try {
|
||||
|
||||
LogUtil.defaultLog.debug("queryOne info : sql : {}, args : {}", sql, args);
|
||||
|
||||
byte[] data = serializer.serialize(SelectRequest.builder()
|
||||
.queryType(QueryType.QUERY_ONE_WITH_MAPPER_WITH_ARGS).sql(sql)
|
||||
.args(args).className(mapper.getClass().getCanonicalName()).build());
|
||||
|
||||
GetResponse response = protocol.getData(
|
||||
GetRequest.newBuilder().setGroup(group())
|
||||
.setData(ByteString.copyFrom(data)).build());
|
||||
if (StringUtils.isEmpty(response.getErrMsg())) {
|
||||
return serializer.deserialize(response.getData().toByteArray(),
|
||||
ClassUtils.resolveGenericTypeByInterface(mapper.getClass()));
|
||||
}
|
||||
throw new NJdbcException(response.getErrMsg(), response.getErrMsg());
|
||||
}
|
||||
catch (Exception e) {
|
||||
LogUtil.fatalLog
|
||||
.error("An exception occurred during the query operation : {}", e);
|
||||
throw new NJdbcException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public <R> List<R> queryMany(String sql, Object[] args, RowMapper<R> mapper) {
|
||||
try {
|
||||
LogUtil.defaultLog.debug("queryMany info : sql : {}, args : {}", sql, args);
|
||||
|
||||
byte[] data = serializer.serialize(SelectRequest.builder()
|
||||
.queryType(QueryType.QUERY_MANY_WITH_MAPPER_WITH_ARGS).sql(sql)
|
||||
.args(args).className(mapper.getClass().getCanonicalName()).build());
|
||||
|
||||
GetResponse response = protocol.getData(
|
||||
GetRequest.newBuilder().setGroup(group())
|
||||
.setData(ByteString.copyFrom(data)).build());
|
||||
if (StringUtils.isEmpty(response.getErrMsg())) {
|
||||
return serializer
|
||||
.deserialize(response.getData().toByteArray(), List.class);
|
||||
}
|
||||
throw new NJdbcException(response.getErrMsg());
|
||||
}
|
||||
catch (Exception e) {
|
||||
LogUtil.fatalLog
|
||||
.error("An exception occurred during the query operation : {}", e);
|
||||
throw new NJdbcException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public <R> List<R> queryMany(String sql, Object[] args, Class<R> rClass) {
|
||||
try {
|
||||
LogUtil.defaultLog.debug("queryMany info : sql : {}, args : {}", sql, args);
|
||||
|
||||
byte[] data = serializer.serialize(SelectRequest.builder()
|
||||
.queryType(QueryType.QUERY_MANY_NO_MAPPER_WITH_ARGS).sql(sql)
|
||||
.args(args).className(rClass.getCanonicalName()).build());
|
||||
GetResponse response = protocol.getData(
|
||||
GetRequest.newBuilder().setGroup(group())
|
||||
.setData(ByteString.copyFrom(data)).build());
|
||||
if (StringUtils.isEmpty(response.getErrMsg())) {
|
||||
return serializer
|
||||
.deserialize(response.getData().toByteArray(), List.class);
|
||||
}
|
||||
throw new NJdbcException(response.getErrMsg());
|
||||
}
|
||||
catch (Exception e) {
|
||||
LogUtil.fatalLog
|
||||
.error("An exception occurred during the query operation : {}", e);
|
||||
throw new NJdbcException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Map<String, Object>> queryMany(String sql, Object[] args) {
|
||||
try {
|
||||
|
||||
LogUtil.defaultLog.debug("queryMany info : sql : {}, args : {}", sql, args);
|
||||
|
||||
byte[] data = serializer.serialize(SelectRequest.builder()
|
||||
.queryType(QueryType.QUERY_MANY_WITH_LIST_WITH_ARGS).sql(sql)
|
||||
.args(args).build());
|
||||
|
||||
GetResponse response = protocol.getData(
|
||||
GetRequest.newBuilder().setGroup(group())
|
||||
.setData(ByteString.copyFrom(data)).build());
|
||||
if (StringUtils.isEmpty(response.getErrMsg())) {
|
||||
return serializer
|
||||
.deserialize(response.getData().toByteArray(), List.class);
|
||||
}
|
||||
throw new NJdbcException(response.getErrMsg());
|
||||
}
|
||||
catch (Exception e) {
|
||||
LogUtil.fatalLog
|
||||
.error("An exception occurred during the query operation : {}", e);
|
||||
throw new NJdbcException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Boolean update(List<ModifyRequest> sqlContext) {
|
||||
try {
|
||||
|
||||
// Since the SQL parameter is Object[], in order to ensure that the types of
|
||||
// array elements are not lost, the serialization here is done using the java-specific
|
||||
// serialization framework, rather than continuing with the protobuff
|
||||
|
||||
LogUtil.defaultLog.debug("modifyRequests info : {}", sqlContext);
|
||||
|
||||
// {timestamp}-{group}-{ip:port}-{signature}
|
||||
|
||||
final String key =
|
||||
System.currentTimeMillis() + "-" + group() + "-" + memberManager.getSelf().getAddress() + "-"
|
||||
+ Md5Utils.getMD5(sqlContext.toString(), Constants.ENCODE);
|
||||
Log log = Log.newBuilder().setGroup(group()).setKey(key)
|
||||
.setData(ByteString.copyFrom(serializer.serialize(sqlContext)))
|
||||
.setType(sqlContext.getClass().getCanonicalName()).build();
|
||||
LogFuture future = this.protocol.submit(log);
|
||||
if (future.isOk()) {
|
||||
return true;
|
||||
}
|
||||
throw future.getError();
|
||||
}
|
||||
catch (Throwable e) {
|
||||
if (e instanceof ConsistencyException) {
|
||||
throw (ConsistencyException) e;
|
||||
}
|
||||
LogUtil.fatalLog
|
||||
.error("An exception occurred during the update operation : {}", e);
|
||||
throw new NJdbcException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<SnapshotOperation> loadSnapshotOperate() {
|
||||
return Collections.singletonList(new DerbySnapshotOperation(writeLock));
|
||||
}
|
||||
|
||||
@SuppressWarnings("all")
|
||||
@Override
|
||||
public GetResponse getData(final GetRequest request) {
|
||||
final SelectRequest selectRequest = serializer
|
||||
.deserialize(request.getData().toByteArray(), SelectRequest.class);
|
||||
|
||||
LogUtil.defaultLog.debug("getData info : selectRequest : {}", selectRequest);
|
||||
|
||||
final RowMapper<Object> mapper = RowMapperManager
|
||||
.getRowMapper(selectRequest.getClassName());
|
||||
final byte type = selectRequest.getQueryType();
|
||||
readLock.lock();
|
||||
Object data;
|
||||
try {
|
||||
switch (type) {
|
||||
case QueryType.QUERY_ONE_WITH_MAPPER_WITH_ARGS:
|
||||
data = onQueryOne(selectRequest.getSql(), selectRequest.getArgs(),
|
||||
mapper);
|
||||
break;
|
||||
case QueryType.QUERY_ONE_NO_MAPPER_NO_ARGS:
|
||||
data = onQueryOne(selectRequest.getSql(),
|
||||
ClassUtils.findClassByName(selectRequest.getClassName()));
|
||||
break;
|
||||
case QueryType.QUERY_ONE_NO_MAPPER_WITH_ARGS:
|
||||
data = onQueryOne(selectRequest.getSql(), selectRequest.getArgs(),
|
||||
ClassUtils.findClassByName(selectRequest.getClassName()));
|
||||
break;
|
||||
case QueryType.QUERY_MANY_WITH_MAPPER_WITH_ARGS:
|
||||
data = onQueryMany(selectRequest.getSql(), selectRequest.getArgs(),
|
||||
mapper);
|
||||
break;
|
||||
case QueryType.QUERY_MANY_WITH_LIST_WITH_ARGS:
|
||||
data = onQueryMany(selectRequest.getSql(), selectRequest.getArgs());
|
||||
break;
|
||||
case QueryType.QUERY_MANY_NO_MAPPER_WITH_ARGS:
|
||||
data = onQueryMany(selectRequest.getSql(), selectRequest.getArgs(),
|
||||
ClassUtils.findClassByName(selectRequest.getClassName()));
|
||||
break;
|
||||
default:
|
||||
throw new IllegalArgumentException("Unsupported data query categories");
|
||||
}
|
||||
ByteString bytes = data == null ?
|
||||
ByteString.EMPTY :
|
||||
ByteString.copyFrom(serializer.serialize(data));
|
||||
return GetResponse.newBuilder().setData(bytes).build();
|
||||
}
|
||||
catch (Exception e) {
|
||||
LogUtil.fatalLog
|
||||
.error("There was an error querying the data, request : {}, error : {}",
|
||||
selectRequest, e);
|
||||
return GetResponse.newBuilder()
|
||||
.setErrMsg(e.getClass().getSimpleName() + ":" + e.getMessage())
|
||||
.build();
|
||||
}
|
||||
finally {
|
||||
readLock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public LogFuture onApply(Log log) {
|
||||
|
||||
LogUtil.defaultLog.debug("onApply info : log : {}", log);
|
||||
|
||||
final ByteString byteString = log.getData();
|
||||
Preconditions.checkArgument(byteString != null, "Log.getData() must not null");
|
||||
List<ModifyRequest> sqlContext = serializer
|
||||
.deserialize(byteString.toByteArray(), List.class);
|
||||
readLock.lock();
|
||||
try {
|
||||
Collections.sort(sqlContext, new Comparator<ModifyRequest>() {
|
||||
@Override
|
||||
public int compare(ModifyRequest pre, ModifyRequest next) {
|
||||
return pre.getExecuteNo() - next.getExecuteNo();
|
||||
}
|
||||
});
|
||||
boolean isOk = onUpdate(sqlContext);
|
||||
return LogFuture.success(isOk);
|
||||
|
||||
// We do not believe that an error caused by a problem with an SQL error
|
||||
// should trigger the stop operation of the raft state machine
|
||||
}
|
||||
catch (DuplicateKeyException e) {
|
||||
return LogFuture.fail(e);
|
||||
}
|
||||
catch (DataIntegrityViolationException e) {
|
||||
return LogFuture.fail(e);
|
||||
}
|
||||
catch (BadSqlGrammarException e) {
|
||||
return LogFuture.fail(e);
|
||||
}
|
||||
catch (DataAccessException e) {
|
||||
throw new ConsistencyException(e);
|
||||
}
|
||||
catch (Throwable t) {
|
||||
throw t;
|
||||
}
|
||||
finally {
|
||||
readLock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onError(Throwable throwable) {
|
||||
// Trigger reversion strategy
|
||||
NotifyCenter.publishEvent(new RaftDBErrorEvent());
|
||||
}
|
||||
|
||||
@Override
|
||||
public String group() {
|
||||
return Constants.CONFIG_MODEL_RAFT_GROUP;
|
||||
}
|
||||
|
||||
public Boolean onUpdate(List<ModifyRequest> sqlContext) {
|
||||
return update(transactionTemplate, jdbcTemplate, sqlContext);
|
||||
}
|
||||
|
||||
public <R> R onQueryOne(String sql, Class<R> rClass) {
|
||||
return queryOne(jdbcTemplate, sql, rClass);
|
||||
}
|
||||
|
||||
public <R> R onQueryOne(String sql, Object[] args, Class<R> rClass) {
|
||||
return queryOne(jdbcTemplate, sql, args, rClass);
|
||||
}
|
||||
|
||||
public <R> R onQueryOne(String sql, Object[] args, RowMapper<R> mapper) {
|
||||
return queryOne(jdbcTemplate, sql, args, mapper);
|
||||
}
|
||||
|
||||
public <R> List<R> onQueryMany(String sql, Object[] args, RowMapper<R> mapper) {
|
||||
return queryMany(jdbcTemplate, sql, args, mapper);
|
||||
}
|
||||
|
||||
public <R> List<R> onQueryMany(String sql, Object[] args, Class<R> rClass) {
|
||||
return queryMany(jdbcTemplate, sql, args, rClass);
|
||||
}
|
||||
|
||||
public List<Map<String, Object>> onQueryMany(String sql, Object[] args) {
|
||||
return queryMany(jdbcTemplate, sql, args);
|
||||
}
|
||||
}
|
@ -13,31 +13,34 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.alibaba.nacos.config.server.utils;
|
||||
package com.alibaba.nacos.config.server.service.repository;
|
||||
|
||||
import com.alibaba.nacos.config.server.model.Page;
|
||||
import com.alibaba.nacos.config.server.service.transaction.DatabaseOperate;
|
||||
import com.alibaba.nacos.config.server.service.transaction.SqlContextUtils;
|
||||
import com.alibaba.nacos.config.server.service.sql.SqlContextUtils;
|
||||
import java.util.List;
|
||||
|
||||
import com.alibaba.nacos.core.utils.ApplicationUtils;
|
||||
import org.springframework.jdbc.core.RowMapper;
|
||||
|
||||
|
||||
/**
|
||||
* 分页辅助类
|
||||
* For Apache Derby
|
||||
*
|
||||
* @param <E>
|
||||
* @author boyan
|
||||
* @date 2010-5-6
|
||||
*/
|
||||
class EmbeddedPaginationHelperImpl<E> implements PaginationHelper {
|
||||
|
||||
public class PaginationHelper<E> {
|
||||
private final DatabaseOperate databaseOperate;
|
||||
|
||||
public EmbeddedPaginationHelperImpl(DatabaseOperate databaseOperate) {
|
||||
this.databaseOperate = databaseOperate;
|
||||
}
|
||||
|
||||
/**
|
||||
* 取分页
|
||||
*
|
||||
* @param services jdbcTemplate
|
||||
* @param sqlCountRows 查询总数的SQL
|
||||
* @param sqlFetchRows 查询数据的sql
|
||||
* @param args 查询参数
|
||||
@ -46,20 +49,20 @@ public class PaginationHelper<E> {
|
||||
* @param rowMapper
|
||||
* @return
|
||||
*/
|
||||
public Page<E> fetchPage(final DatabaseOperate services, final String sqlCountRows, final String sqlFetchRows,
|
||||
final Object[] args, final int pageNo, final int pageSize, final RowMapper<E> rowMapper) {
|
||||
return fetchPage(services, sqlCountRows, sqlFetchRows, args, pageNo, pageSize, null, rowMapper);
|
||||
public Page<E> fetchPage(final String sqlCountRows, final String sqlFetchRows,
|
||||
final Object[] args, final int pageNo, final int pageSize, final RowMapper rowMapper) {
|
||||
return fetchPage(sqlCountRows, sqlFetchRows, args, pageNo, pageSize, null, rowMapper);
|
||||
}
|
||||
|
||||
public Page<E> fetchPage(final DatabaseOperate services, final String sqlCountRows, final String sqlFetchRows,
|
||||
public Page<E> fetchPage(final String sqlCountRows, final String sqlFetchRows,
|
||||
final Object[] args, final int pageNo, final int pageSize, final Long lastMaxId,
|
||||
final RowMapper<E> rowMapper) {
|
||||
final RowMapper rowMapper) {
|
||||
if (pageNo <= 0 || pageSize <= 0) {
|
||||
throw new IllegalArgumentException("pageNo and pageSize must be greater than zero");
|
||||
}
|
||||
|
||||
// 查询当前记录总数
|
||||
Integer rowCountInt = services.queryOne(sqlCountRows, args, Integer.class);
|
||||
Integer rowCountInt = databaseOperate.queryOne(sqlCountRows, args, Integer.class);
|
||||
if (rowCountInt == null) {
|
||||
throw new IllegalArgumentException("fetchPageLimit error");
|
||||
}
|
||||
@ -81,30 +84,23 @@ public class PaginationHelper<E> {
|
||||
}
|
||||
|
||||
final int startRow = (pageNo - 1) * pageSize;
|
||||
String selectSQL = "";
|
||||
if (isDerby()) {
|
||||
selectSQL = sqlFetchRows + " OFFSET " + startRow + " ROWS FETCH NEXT " + pageSize + " ROWS ONLY";
|
||||
} else if (lastMaxId != null) {
|
||||
selectSQL = sqlFetchRows + " and id > " + lastMaxId + " order by id asc" + " limit " + 0 + "," + pageSize;
|
||||
} else {
|
||||
selectSQL = sqlFetchRows + " limit " + startRow + "," + pageSize;
|
||||
}
|
||||
String selectSQL = sqlFetchRows + " OFFSET " + startRow + " ROWS FETCH NEXT " + pageSize + " ROWS ONLY";
|
||||
|
||||
List<E> result = services.queryMany(selectSQL, args, rowMapper);
|
||||
List<E> result = databaseOperate.queryMany(selectSQL, args, rowMapper);
|
||||
for (E item : result) {
|
||||
page.getPageItems().add(item);
|
||||
}
|
||||
return page;
|
||||
}
|
||||
|
||||
public Page<E> fetchPageLimit(final DatabaseOperate services, final String sqlCountRows, final String sqlFetchRows,
|
||||
public Page<E> fetchPageLimit(final String sqlCountRows, final String sqlFetchRows,
|
||||
final Object[] args, final int pageNo, final int pageSize,
|
||||
final RowMapper<E> rowMapper) {
|
||||
final RowMapper rowMapper) {
|
||||
if (pageNo <= 0 || pageSize <= 0) {
|
||||
throw new IllegalArgumentException("pageNo and pageSize must be greater than zero");
|
||||
}
|
||||
// 查询当前记录总数
|
||||
Integer rowCountInt = services.queryOne(sqlCountRows, Integer.class);
|
||||
Integer rowCountInt = databaseOperate.queryOne(sqlCountRows, Integer.class);
|
||||
if (rowCountInt == null) {
|
||||
throw new IllegalArgumentException("fetchPageLimit error");
|
||||
}
|
||||
@ -125,27 +121,23 @@ public class PaginationHelper<E> {
|
||||
return page;
|
||||
}
|
||||
|
||||
String selectSQL = sqlFetchRows;
|
||||
if (isDerby()) {
|
||||
selectSQL = selectSQL.replaceAll("(?i)LIMIT \\?,\\?", "OFFSET ? ROWS FETCH NEXT ? ROWS ONLY");
|
||||
}
|
||||
|
||||
List<E> result = services.queryMany(selectSQL, args, rowMapper);
|
||||
String selectSQL = sqlFetchRows.replaceAll("(?i)LIMIT \\?,\\?", "OFFSET ? ROWS FETCH NEXT ? ROWS ONLY");
|
||||
List<E> result = databaseOperate.queryMany(selectSQL, args, rowMapper);
|
||||
for (E item : result) {
|
||||
page.getPageItems().add(item);
|
||||
}
|
||||
return page;
|
||||
}
|
||||
|
||||
public Page<E> fetchPageLimit(final DatabaseOperate services, final String sqlCountRows, final Object[] args1,
|
||||
public Page<E> fetchPageLimit(final String sqlCountRows, final Object[] args1,
|
||||
final String sqlFetchRows,
|
||||
final Object[] args2, final int pageNo, final int pageSize,
|
||||
final RowMapper<E> rowMapper) {
|
||||
final RowMapper rowMapper) {
|
||||
if (pageNo <= 0 || pageSize <= 0) {
|
||||
throw new IllegalArgumentException("pageNo and pageSize must be greater than zero");
|
||||
}
|
||||
// 查询当前记录总数
|
||||
Integer rowCountInt = services.queryOne(sqlCountRows, args1, Integer.class);
|
||||
Integer rowCountInt = databaseOperate.queryOne(sqlCountRows, args1, Integer.class);
|
||||
if (rowCountInt == null) {
|
||||
throw new IllegalArgumentException("fetchPageLimit error");
|
||||
}
|
||||
@ -166,56 +158,42 @@ public class PaginationHelper<E> {
|
||||
return page;
|
||||
}
|
||||
|
||||
String selectSQL = sqlFetchRows;
|
||||
if (isDerby()) {
|
||||
selectSQL = selectSQL.replaceAll("(?i)LIMIT \\?,\\?", "OFFSET ? ROWS FETCH NEXT ? ROWS ONLY");
|
||||
}
|
||||
String selectSQL = sqlFetchRows.replaceAll("(?i)LIMIT \\?,\\?", "OFFSET ? ROWS FETCH NEXT ? ROWS ONLY");
|
||||
|
||||
List<E> result = services.queryMany(selectSQL, args2, rowMapper);
|
||||
List<E> result = databaseOperate.queryMany(selectSQL, args2, rowMapper);
|
||||
for (E item : result) {
|
||||
page.getPageItems().add(item);
|
||||
}
|
||||
return page;
|
||||
}
|
||||
|
||||
public Page<E> fetchPageLimit(final DatabaseOperate services, final String sqlFetchRows,
|
||||
public Page<E> fetchPageLimit(final String sqlFetchRows,
|
||||
final Object[] args, final int pageNo, final int pageSize,
|
||||
final RowMapper<E> rowMapper) {
|
||||
final RowMapper rowMapper) {
|
||||
if (pageNo <= 0 || pageSize <= 0) {
|
||||
throw new IllegalArgumentException("pageNo and pageSize must be greater than zero");
|
||||
}
|
||||
// 创建Page对象
|
||||
final Page<E> page = new Page<E>();
|
||||
|
||||
String selectSQL = sqlFetchRows;
|
||||
if (isDerby()) {
|
||||
selectSQL = selectSQL.replaceAll("(?i)LIMIT \\?,\\?", "OFFSET ? ROWS FETCH NEXT ? ROWS ONLY");
|
||||
}
|
||||
String selectSQL = sqlFetchRows.replaceAll("(?i)LIMIT \\?,\\?", "OFFSET ? ROWS FETCH NEXT ? ROWS ONLY");
|
||||
|
||||
List<E> result = services.queryMany(selectSQL, args, rowMapper);
|
||||
List<E> result = databaseOperate.queryMany(selectSQL, args, rowMapper);
|
||||
for (E item : result) {
|
||||
page.getPageItems().add(item);
|
||||
}
|
||||
return page;
|
||||
}
|
||||
|
||||
public void updateLimit(final DatabaseOperate services, final String sql, final Object[] args) {
|
||||
String sqlUpdate = sql;
|
||||
|
||||
if (isDerby()) {
|
||||
sqlUpdate = sqlUpdate.replaceAll("limit \\?", "OFFSET 0 ROWS FETCH NEXT ? ROWS ONLY");
|
||||
}
|
||||
public void updateLimit(final String sql, final Object[] args) {
|
||||
String sqlUpdate = sql.replaceAll("limit \\?", "OFFSET 0 ROWS FETCH NEXT ? ROWS ONLY");
|
||||
|
||||
SqlContextUtils.addSqlContext(sqlUpdate, args);
|
||||
try {
|
||||
services.update(SqlContextUtils.getCurrentSqlContext());
|
||||
databaseOperate.update(SqlContextUtils.getCurrentSqlContext());
|
||||
} finally {
|
||||
SqlContextUtils.cleanCurrentSqlContext();
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isDerby() {
|
||||
return (ApplicationUtils.getStandaloneMode() && !PropertyUtil.isUseExternalDB()) ||
|
||||
PropertyUtil.isEmbeddedStorage();
|
||||
}
|
||||
}
|
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,222 @@
|
||||
/*
|
||||
* Copyright 1999-2018 Alibaba Group Holding Ltd.
|
||||
*
|
||||
* 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 com.alibaba.nacos.config.server.service.repository;
|
||||
|
||||
import com.alibaba.nacos.config.server.model.Page;
|
||||
import com.alibaba.nacos.config.server.service.sql.SqlContextUtils;
|
||||
import com.alibaba.nacos.config.server.utils.PropertyUtil;
|
||||
import com.alibaba.nacos.core.utils.ApplicationUtils;
|
||||
import org.springframework.jdbc.core.JdbcTemplate;
|
||||
import org.springframework.jdbc.core.RowMapper;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:liaochuntao@live.com">liaochuntao</a>
|
||||
*/
|
||||
class ExternalStoragePaginationHelperImpl<E> implements PaginationHelper {
|
||||
|
||||
private final JdbcTemplate jdbcTemplate;
|
||||
|
||||
public ExternalStoragePaginationHelperImpl(JdbcTemplate jdbcTemplate) {
|
||||
this.jdbcTemplate = jdbcTemplate;
|
||||
}
|
||||
|
||||
/**
|
||||
* 取分页
|
||||
*
|
||||
* @param sqlCountRows 查询总数的SQL
|
||||
* @param sqlFetchRows 查询数据的sql
|
||||
* @param args 查询参数
|
||||
* @param pageNo 页数
|
||||
* @param pageSize 每页大小
|
||||
* @param rowMapper
|
||||
* @return
|
||||
*/
|
||||
public Page<E> fetchPage(final String sqlCountRows, final String sqlFetchRows,
|
||||
final Object[] args, final int pageNo, final int pageSize, final RowMapper rowMapper) {
|
||||
return fetchPage(sqlCountRows, sqlFetchRows, args, pageNo, pageSize, null, rowMapper);
|
||||
}
|
||||
|
||||
public Page<E> fetchPage(final String sqlCountRows, final String sqlFetchRows,
|
||||
final Object[] args, final int pageNo, final int pageSize, final Long lastMaxId,
|
||||
final RowMapper rowMapper) {
|
||||
if (pageNo <= 0 || pageSize <= 0) {
|
||||
throw new IllegalArgumentException("pageNo and pageSize must be greater than zero");
|
||||
}
|
||||
|
||||
// 查询当前记录总数
|
||||
Integer rowCountInt = jdbcTemplate.queryForObject(sqlCountRows, args, Integer.class);
|
||||
if (rowCountInt == null) {
|
||||
throw new IllegalArgumentException("fetchPageLimit error");
|
||||
}
|
||||
|
||||
// 计算页数
|
||||
int pageCount = rowCountInt / pageSize;
|
||||
if (rowCountInt > pageSize * pageCount) {
|
||||
pageCount++;
|
||||
}
|
||||
|
||||
// 创建Page对象
|
||||
final Page<E> page = new Page<E>();
|
||||
page.setPageNumber(pageNo);
|
||||
page.setPagesAvailable(pageCount);
|
||||
page.setTotalCount(rowCountInt);
|
||||
|
||||
if (pageNo > pageCount) {
|
||||
return page;
|
||||
}
|
||||
|
||||
final int startRow = (pageNo - 1) * pageSize;
|
||||
String selectSQL = "";
|
||||
if (isDerby()) {
|
||||
selectSQL = sqlFetchRows + " OFFSET " + startRow + " ROWS FETCH NEXT " + pageSize + " ROWS ONLY";
|
||||
} else if (lastMaxId != null) {
|
||||
selectSQL = sqlFetchRows + " and id > " + lastMaxId + " order by id asc" + " limit " + 0 + "," + pageSize;
|
||||
} else {
|
||||
selectSQL = sqlFetchRows + " limit " + startRow + "," + pageSize;
|
||||
}
|
||||
|
||||
List<E> result = jdbcTemplate.query(selectSQL, args, rowMapper);
|
||||
for (E item : result) {
|
||||
page.getPageItems().add(item);
|
||||
}
|
||||
return page;
|
||||
}
|
||||
|
||||
public Page<E> fetchPageLimit(final String sqlCountRows, final String sqlFetchRows,
|
||||
final Object[] args, final int pageNo, final int pageSize,
|
||||
final RowMapper rowMapper) {
|
||||
if (pageNo <= 0 || pageSize <= 0) {
|
||||
throw new IllegalArgumentException("pageNo and pageSize must be greater than zero");
|
||||
}
|
||||
// 查询当前记录总数
|
||||
Integer rowCountInt = jdbcTemplate.queryForObject(sqlCountRows, Integer.class);
|
||||
if (rowCountInt == null) {
|
||||
throw new IllegalArgumentException("fetchPageLimit error");
|
||||
}
|
||||
|
||||
// 计算页数
|
||||
int pageCount = rowCountInt / pageSize;
|
||||
if (rowCountInt > pageSize * pageCount) {
|
||||
pageCount++;
|
||||
}
|
||||
|
||||
// 创建Page对象
|
||||
final Page<E> page = new Page<E>();
|
||||
page.setPageNumber(pageNo);
|
||||
page.setPagesAvailable(pageCount);
|
||||
page.setTotalCount(rowCountInt);
|
||||
|
||||
if (pageNo > pageCount) {
|
||||
return page;
|
||||
}
|
||||
|
||||
String selectSQL = sqlFetchRows;
|
||||
if (isDerby()) {
|
||||
selectSQL = selectSQL.replaceAll("(?i)LIMIT \\?,\\?", "OFFSET ? ROWS FETCH NEXT ? ROWS ONLY");
|
||||
}
|
||||
|
||||
List<E> result = jdbcTemplate.query(selectSQL, args, rowMapper);
|
||||
for (E item : result) {
|
||||
page.getPageItems().add(item);
|
||||
}
|
||||
return page;
|
||||
}
|
||||
|
||||
public Page<E> fetchPageLimit(final String sqlCountRows, final Object[] args1,
|
||||
final String sqlFetchRows,
|
||||
final Object[] args2, final int pageNo, final int pageSize,
|
||||
final RowMapper rowMapper) {
|
||||
if (pageNo <= 0 || pageSize <= 0) {
|
||||
throw new IllegalArgumentException("pageNo and pageSize must be greater than zero");
|
||||
}
|
||||
// 查询当前记录总数
|
||||
Integer rowCountInt = jdbcTemplate.queryForObject(sqlCountRows, args1, Integer.class);
|
||||
if (rowCountInt == null) {
|
||||
throw new IllegalArgumentException("fetchPageLimit error");
|
||||
}
|
||||
|
||||
// 计算页数
|
||||
int pageCount = rowCountInt / pageSize;
|
||||
if (rowCountInt > pageSize * pageCount) {
|
||||
pageCount++;
|
||||
}
|
||||
|
||||
// 创建Page对象
|
||||
final Page<E> page = new Page<E>();
|
||||
page.setPageNumber(pageNo);
|
||||
page.setPagesAvailable(pageCount);
|
||||
page.setTotalCount(rowCountInt);
|
||||
|
||||
if (pageNo > pageCount) {
|
||||
return page;
|
||||
}
|
||||
|
||||
String selectSQL = sqlFetchRows;
|
||||
if (isDerby()) {
|
||||
selectSQL = selectSQL.replaceAll("(?i)LIMIT \\?,\\?", "OFFSET ? ROWS FETCH NEXT ? ROWS ONLY");
|
||||
}
|
||||
|
||||
List<E> result = jdbcTemplate.query(selectSQL, args2, rowMapper);
|
||||
for (E item : result) {
|
||||
page.getPageItems().add(item);
|
||||
}
|
||||
return page;
|
||||
}
|
||||
|
||||
public Page<E> fetchPageLimit(final String sqlFetchRows,
|
||||
final Object[] args, final int pageNo, final int pageSize,
|
||||
final RowMapper rowMapper) {
|
||||
if (pageNo <= 0 || pageSize <= 0) {
|
||||
throw new IllegalArgumentException("pageNo and pageSize must be greater than zero");
|
||||
}
|
||||
// 创建Page对象
|
||||
final Page<E> page = new Page<E>();
|
||||
|
||||
String selectSQL = sqlFetchRows;
|
||||
if (isDerby()) {
|
||||
selectSQL = selectSQL.replaceAll("(?i)LIMIT \\?,\\?", "OFFSET ? ROWS FETCH NEXT ? ROWS ONLY");
|
||||
}
|
||||
|
||||
List<E> result = jdbcTemplate.query(selectSQL, args, rowMapper);
|
||||
for (E item : result) {
|
||||
page.getPageItems().add(item);
|
||||
}
|
||||
return page;
|
||||
}
|
||||
|
||||
public void updateLimit(final String sql, final Object[] args) {
|
||||
String sqlUpdate = sql;
|
||||
|
||||
if (isDerby()) {
|
||||
sqlUpdate = sqlUpdate.replaceAll("limit \\?", "OFFSET 0 ROWS FETCH NEXT ? ROWS ONLY");
|
||||
}
|
||||
|
||||
try {
|
||||
jdbcTemplate.update(sqlUpdate, args);
|
||||
} finally {
|
||||
SqlContextUtils.cleanCurrentSqlContext();
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isDerby() {
|
||||
return (ApplicationUtils.getStandaloneMode() && !PropertyUtil.isUseExternalDB()) ||
|
||||
PropertyUtil.isEmbeddedStorage();
|
||||
}
|
||||
|
||||
}
|
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,49 @@
|
||||
/*
|
||||
* Copyright 1999-2018 Alibaba Group Holding Ltd.
|
||||
*
|
||||
* 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 com.alibaba.nacos.config.server.service.repository;
|
||||
|
||||
import com.alibaba.nacos.config.server.model.Page;
|
||||
import org.springframework.jdbc.core.RowMapper;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:liaochuntao@live.com">liaochuntao</a>
|
||||
*/
|
||||
@SuppressWarnings("PMD.AbstractMethodOrInterfaceMethodMustUseJavadocRule")
|
||||
public interface PaginationHelper<E> {
|
||||
|
||||
Page<E> fetchPage(final String sqlCountRows, final String sqlFetchRows,
|
||||
final Object[] args, final int pageNo, final int pageSize, final RowMapper<E> rowMapper);
|
||||
|
||||
Page<E> fetchPage(final String sqlCountRows, final String sqlFetchRows,
|
||||
final Object[] args, final int pageNo, final int pageSize, final Long lastMaxId,
|
||||
final RowMapper<E> rowMapper);
|
||||
|
||||
Page<E> fetchPageLimit(final String sqlCountRows, final String sqlFetchRows,
|
||||
final Object[] args, final int pageNo, final int pageSize,
|
||||
final RowMapper<E> rowMapper);
|
||||
|
||||
Page<E> fetchPageLimit(final String sqlCountRows, final Object[] args1,
|
||||
final String sqlFetchRows,
|
||||
final Object[] args2, final int pageNo, final int pageSize,
|
||||
final RowMapper<E> rowMapper);
|
||||
|
||||
Page<E> fetchPageLimit(final String sqlFetchRows,
|
||||
final Object[] args, final int pageNo, final int pageSize,
|
||||
final RowMapper<E> rowMapper);
|
||||
|
||||
void updateLimit(final String sql, final Object[] args);
|
||||
}
|
@ -0,0 +1,801 @@
|
||||
/*
|
||||
* Copyright 1999-2018 Alibaba Group Holding Ltd.
|
||||
*
|
||||
* 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 com.alibaba.nacos.config.server.service.repository;
|
||||
|
||||
import com.alibaba.nacos.api.exception.NacosException;
|
||||
import com.alibaba.nacos.config.server.model.ConfigAdvanceInfo;
|
||||
import com.alibaba.nacos.config.server.model.ConfigAllInfo;
|
||||
import com.alibaba.nacos.config.server.model.ConfigHistoryInfo;
|
||||
import com.alibaba.nacos.config.server.model.ConfigInfo;
|
||||
import com.alibaba.nacos.config.server.model.ConfigInfo4Beta;
|
||||
import com.alibaba.nacos.config.server.model.ConfigInfo4Tag;
|
||||
import com.alibaba.nacos.config.server.model.ConfigInfoAggr;
|
||||
import com.alibaba.nacos.config.server.model.ConfigInfoBase;
|
||||
import com.alibaba.nacos.config.server.model.ConfigInfoBetaWrapper;
|
||||
import com.alibaba.nacos.config.server.model.ConfigInfoChanged;
|
||||
import com.alibaba.nacos.config.server.model.ConfigInfoTagWrapper;
|
||||
import com.alibaba.nacos.config.server.model.ConfigInfoWrapper;
|
||||
import com.alibaba.nacos.config.server.model.ConfigKey;
|
||||
import com.alibaba.nacos.config.server.model.Page;
|
||||
import com.alibaba.nacos.config.server.model.SameConfigPolicy;
|
||||
import com.alibaba.nacos.config.server.model.SubInfo;
|
||||
import com.alibaba.nacos.config.server.model.TenantInfo;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.sql.Timestamp;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 数据库服务,提供ConfigInfo在数据库的存取<br> 3.0开始增加数据版本号, 并将物理删除改为逻辑删除<br> 3.0增加数据库切换功能
|
||||
*
|
||||
* @author boyan
|
||||
* @author leiwen.zh
|
||||
* @since 1.0
|
||||
*/
|
||||
@SuppressWarnings("all")
|
||||
public interface PersistService {
|
||||
|
||||
/**
|
||||
* @author klw
|
||||
* @Description: constant variables
|
||||
*/
|
||||
String SPOT = ".";
|
||||
Object[] EMPTY_ARRAY = new Object[]{};
|
||||
String SQL_FIND_ALL_CONFIG_INFO = "select id,data_id,group_id,tenant_id,app_name,content,type,md5,gmt_create,gmt_modified,src_user,src_ip,c_desc,c_use,effect,c_schema from config_info";
|
||||
String SQL_TENANT_INFO_COUNT_BY_TENANT_ID = "select count(1) from tenant_info where tenant_id = ?";
|
||||
String SQL_FIND_CONFIG_INFO_BY_IDS = "SELECT ID,data_id,group_id,tenant_id,app_name,content,md5 FROM config_info WHERE ";
|
||||
String SQL_DELETE_CONFIG_INFO_BY_IDS = "DELETE FROM config_info WHERE ";
|
||||
int QUERY_LIMIT_SIZE = 50;
|
||||
String PATTERN_STR = "*";
|
||||
|
||||
<E> PaginationHelper<E> createPaginationHelper();
|
||||
|
||||
/**
|
||||
* 添加普通配置信息,发布数据变更事件
|
||||
*/
|
||||
void addConfigInfo(final String srcIp, final String srcUser, final ConfigInfo configInfo,
|
||||
final Timestamp time, final Map<String, Object> configAdvanceInfo, final boolean notify);
|
||||
|
||||
/**
|
||||
* 添加普通配置信息,发布数据变更事件
|
||||
*/
|
||||
void addConfigInfo4Beta(ConfigInfo configInfo, String betaIps,
|
||||
String srcIp, String srcUser, Timestamp time, boolean notify);
|
||||
|
||||
/**
|
||||
* 添加普通配置信息,发布数据变更事件
|
||||
*/
|
||||
void addConfigInfo4Tag(ConfigInfo configInfo, String tag, String srcIp, String srcUser, Timestamp time,
|
||||
boolean notify);
|
||||
|
||||
/**
|
||||
* 更新配置信息
|
||||
*/
|
||||
void updateConfigInfo(final ConfigInfo configInfo, final String srcIp, final String srcUser,
|
||||
final Timestamp time, final Map<String, Object> configAdvanceInfo,
|
||||
final boolean notify);
|
||||
|
||||
/**
|
||||
* 更新配置信息
|
||||
*/
|
||||
void updateConfigInfo4Beta(ConfigInfo configInfo, String srcIp, String srcUser, Timestamp time,
|
||||
boolean notify);
|
||||
|
||||
/**
|
||||
* 更新配置信息
|
||||
*/
|
||||
void updateConfigInfo4Tag(ConfigInfo configInfo, String tag, String srcIp, String srcUser, Timestamp time,
|
||||
boolean notify);
|
||||
|
||||
void insertOrUpdateBeta(final ConfigInfo configInfo, final String betaIps, final String srcIp,
|
||||
final String srcUser, final Timestamp time, final boolean notify);
|
||||
|
||||
void insertOrUpdateTag(final ConfigInfo configInfo, final String tag, final String srcIp,
|
||||
final String srcUser, final Timestamp time, final boolean notify);
|
||||
|
||||
/**
|
||||
* 更新md5
|
||||
*/
|
||||
void updateMd5(String dataId, String group, String tenant, String md5, Timestamp lastTime);
|
||||
|
||||
void insertOrUpdate(String srcIp, String srcUser, ConfigInfo configInfo, Timestamp time,
|
||||
Map<String, Object> configAdvanceInfo);
|
||||
|
||||
/**
|
||||
* 写入主表,插入或更新
|
||||
*/
|
||||
void insertOrUpdate(String srcIp, String srcUser, ConfigInfo configInfo, Timestamp time,
|
||||
Map<String, Object> configAdvanceInfo, boolean notify);
|
||||
|
||||
// ----------------------- config_aggr_info 表 insert update delete
|
||||
|
||||
/**
|
||||
* 写入主表,插入或更新
|
||||
*/
|
||||
void insertOrUpdateSub(SubInfo subInfo);
|
||||
|
||||
/**
|
||||
* 删除配置信息, 物理删除
|
||||
*/
|
||||
void removeConfigInfo(final String dataId, final String group, final String tenant, final String srcIp,
|
||||
final String srcUser);
|
||||
|
||||
/**
|
||||
* @return List<ConfigInfo> deleted configInfos
|
||||
* @author klw
|
||||
* @Description: delete config info by ids
|
||||
* @Date 2019/7/5 16:45
|
||||
* @Param [ids, srcIp, srcUser]
|
||||
*/
|
||||
List<ConfigInfo> removeConfigInfoByIds(final List<Long> ids, final String srcIp, final String srcUser);
|
||||
|
||||
/**
|
||||
* 删除beta配置信息, 物理删除
|
||||
*/
|
||||
void removeConfigInfo4Beta(final String dataId, final String group, final String tenant);
|
||||
|
||||
/**
|
||||
* 增加聚合前数据到数据库, select -> update or insert
|
||||
*/
|
||||
boolean addAggrConfigInfo(final String dataId, final String group, String tenant, final String datumId,
|
||||
String appName, final String content);
|
||||
|
||||
/**
|
||||
* 删除单条聚合前数据
|
||||
*/
|
||||
void removeSingleAggrConfigInfo(final String dataId,
|
||||
final String group, final String tenant, final String datumId);
|
||||
|
||||
/**
|
||||
* 删除一个dataId下面所有的聚合前数据
|
||||
*/
|
||||
void removeAggrConfigInfo(final String dataId, final String group, final String tenant);
|
||||
|
||||
/**
|
||||
* 批量删除聚合数据,需要指定datum的列表
|
||||
*
|
||||
* @param dataId dataId
|
||||
* @param group group
|
||||
* @param datumList datumList
|
||||
*/
|
||||
boolean batchRemoveAggr(final String dataId, final String group, final String tenant,
|
||||
final List<String> datumList);
|
||||
|
||||
/**
|
||||
* 删除startTime前的数据
|
||||
*/
|
||||
void removeConfigHistory(final Timestamp startTime, final int limitSize);
|
||||
|
||||
/**
|
||||
* 获取指定时间前配置条数
|
||||
*/
|
||||
int findConfigHistoryCountByTime(final Timestamp startTime);
|
||||
|
||||
/**
|
||||
* 获取最大maxId
|
||||
*/
|
||||
long findConfigMaxId();
|
||||
|
||||
/**
|
||||
* 批量添加或者更新数据.事务过程中出现任何异常都会强制抛出TransactionSystemException
|
||||
*
|
||||
* @param dataId dataId
|
||||
* @param group group
|
||||
* @param datumMap datumMap
|
||||
* @return
|
||||
*/
|
||||
boolean batchPublishAggr(final String dataId, final String group, final String tenant,
|
||||
final Map<String, String> datumMap, final String appName);
|
||||
|
||||
/**
|
||||
* 批量替换,先全部删除聚合表中指定DataID+Group的数据,再插入数据. 事务过程中出现任何异常都会强制抛出TransactionSystemException
|
||||
*
|
||||
* @param dataId dataId
|
||||
* @param group group
|
||||
* @param datumMap datumMap
|
||||
* @return
|
||||
*/
|
||||
boolean replaceAggr(final String dataId, final String group, final String tenant,
|
||||
final Map<String, String> datumMap, final String appName);
|
||||
|
||||
/**
|
||||
* 查找所有的dataId和group。保证不返回NULL。
|
||||
*/
|
||||
@Deprecated
|
||||
List<ConfigInfo> findAllDataIdAndGroup();
|
||||
|
||||
/**
|
||||
* 根据dataId和group查询配置信息
|
||||
*/
|
||||
ConfigInfo4Beta findConfigInfo4Beta(final String dataId, final String group, final String tenant);
|
||||
|
||||
/**
|
||||
* 根据dataId和group查询配置信息
|
||||
*/
|
||||
ConfigInfo4Tag findConfigInfo4Tag(final String dataId, final String group, final String tenant,
|
||||
final String tag);
|
||||
|
||||
/**
|
||||
* 根据dataId和group查询配置信息
|
||||
*/
|
||||
ConfigInfo findConfigInfoApp(final String dataId, final String group, final String tenant,
|
||||
final String appName);
|
||||
|
||||
/**
|
||||
* 根据dataId和group查询配置信息
|
||||
*/
|
||||
ConfigInfo findConfigInfoAdvanceInfo(final String dataId, final String group, final String tenant,
|
||||
final Map<String, Object> configAdvanceInfo);
|
||||
|
||||
/**
|
||||
* 根据dataId和group查询配置信息
|
||||
*/
|
||||
ConfigInfoBase findConfigInfoBase(final String dataId, final String group);
|
||||
|
||||
/**
|
||||
* 根据数据库主键ID查询配置信息
|
||||
*
|
||||
* @param id id
|
||||
* @return {@link ConfigInfo}
|
||||
*/
|
||||
ConfigInfo findConfigInfo(long id);
|
||||
|
||||
/**
|
||||
* 根据dataId查询配置信息
|
||||
*
|
||||
* @param pageNo 页码(必须大于0)
|
||||
* @param pageSize 每页大小(必须大于0)
|
||||
* @param dataId
|
||||
* @return ConfigInfo对象的集合
|
||||
*/
|
||||
Page<ConfigInfo> findConfigInfoByDataId(final int pageNo, final int pageSize, final String dataId,
|
||||
final String tenant);
|
||||
|
||||
/**
|
||||
* 根据dataId查询配置信息
|
||||
*
|
||||
* @param pageNo 页码(必须大于0)
|
||||
* @param pageSize 每页大小(必须大于0)
|
||||
* @param dataId
|
||||
* @return ConfigInfo对象的集合
|
||||
*/
|
||||
Page<ConfigInfo> findConfigInfoByDataIdAndApp(final int pageNo, final int pageSize, final String dataId,
|
||||
final String tenant, final String appName);
|
||||
|
||||
Page<ConfigInfo> findConfigInfoByDataIdAndAdvance(final int pageNo, final int pageSize, final String dataId,
|
||||
final String tenant,
|
||||
final Map<String, Object> configAdvanceInfo);
|
||||
|
||||
Page<ConfigInfo> findConfigInfo4Page(final int pageNo, final int pageSize, final String dataId,
|
||||
final String group,
|
||||
final String tenant, final Map<String, Object> configAdvanceInfo);
|
||||
|
||||
/**
|
||||
* 根据dataId查询配置信息
|
||||
*
|
||||
* @param pageNo 页码(必须大于0)
|
||||
* @param pageSize 每页大小(必须大于0)
|
||||
* @param dataId
|
||||
* @return ConfigInfo对象的集合
|
||||
*/
|
||||
Page<ConfigInfoBase> findConfigInfoBaseByDataId(final int pageNo,
|
||||
final int pageSize, final String dataId);
|
||||
|
||||
/**
|
||||
* 根据group查询配置信息
|
||||
*
|
||||
* @param pageNo 页码(必须大于0)
|
||||
* @param pageSize 每页大小(必须大于0)
|
||||
* @param group
|
||||
* @return ConfigInfo对象的集合
|
||||
*/
|
||||
Page<ConfigInfo> findConfigInfoByGroup(final int pageNo, final int pageSize, final String group,
|
||||
final String tenant);
|
||||
|
||||
/**
|
||||
* 根据group查询配置信息
|
||||
*
|
||||
* @param pageNo 页码(必须大于0)
|
||||
* @param pageSize 每页大小(必须大于0)
|
||||
* @param group
|
||||
* @return ConfigInfo对象的集合
|
||||
*/
|
||||
Page<ConfigInfo> findConfigInfoByGroupAndApp(final int pageNo,
|
||||
final int pageSize, final String group, final String tenant,
|
||||
final String appName);
|
||||
|
||||
Page<ConfigInfo> findConfigInfoByGroupAndAdvance(final int pageNo,
|
||||
final int pageSize, final String group, final String tenant,
|
||||
final Map<String, Object> configAdvanceInfo);
|
||||
|
||||
/**
|
||||
* 根据group查询配置信息
|
||||
*
|
||||
* @param pageNo 页码(必须大于0)
|
||||
* @param pageSize 每页大小(必须大于0)
|
||||
* @return ConfigInfo对象的集合
|
||||
*/
|
||||
Page<ConfigInfo> findConfigInfoByApp(final int pageNo,
|
||||
final int pageSize, final String tenant, final String appName);
|
||||
|
||||
Page<ConfigInfo> findConfigInfoByAdvance(final int pageNo,
|
||||
final int pageSize, final String tenant,
|
||||
final Map<String, Object> configAdvanceInfo);
|
||||
|
||||
/**
|
||||
* 根据group查询配置信息
|
||||
*
|
||||
* @param pageNo 页码(必须大于0)
|
||||
* @param pageSize 每页大小(必须大于0)
|
||||
* @param group
|
||||
* @return ConfigInfo对象的集合
|
||||
*/
|
||||
Page<ConfigInfoBase> findConfigInfoBaseByGroup(final int pageNo,
|
||||
final int pageSize, final String group);
|
||||
|
||||
/**
|
||||
* 返回配置项个数
|
||||
*/
|
||||
int configInfoCount();
|
||||
|
||||
/**
|
||||
* 返回配置项个数
|
||||
*/
|
||||
int configInfoCount(String tenant);
|
||||
|
||||
/**
|
||||
* 返回beta配置项个数
|
||||
*/
|
||||
int configInfoBetaCount();
|
||||
|
||||
/**
|
||||
* 返回beta配置项个数
|
||||
*/
|
||||
int configInfoTagCount();
|
||||
|
||||
List<String> getTenantIdList(int page, int pageSize);
|
||||
|
||||
List<String> getGroupIdList(int page, int pageSize);
|
||||
|
||||
int aggrConfigInfoCount(String dataId, String group, String tenant);
|
||||
|
||||
int aggrConfigInfoCountIn(String dataId, String group, String tenant, List<String> datumIds);
|
||||
|
||||
int aggrConfigInfoCountNotIn(String dataId, String group, String tenant, List<String> datumIds);
|
||||
|
||||
int aggrConfigInfoCount(String dataId, String group, String tenant, List<String> datumIds,
|
||||
boolean isIn);
|
||||
|
||||
/**
|
||||
* 分页查询所有的配置信息
|
||||
*
|
||||
* @param pageNo 页码(从1开始)
|
||||
* @param pageSize 每页大小(必须大于0)
|
||||
* @return ConfigInfo对象的集合
|
||||
*/
|
||||
Page<ConfigInfo> findAllConfigInfo(final int pageNo, final int pageSize, final String tenant);
|
||||
|
||||
/**
|
||||
* 分页查询所有的配置信息
|
||||
*
|
||||
* @param pageNo 页码(从1开始)
|
||||
* @param pageSize 每页大小(必须大于0)
|
||||
* @return ConfigInfo对象的集合
|
||||
*/
|
||||
Page<ConfigKey> findAllConfigKey(final int pageNo, final int pageSize, final String tenant);
|
||||
|
||||
/**
|
||||
* 分页查询所有的配置信息
|
||||
*
|
||||
* @param pageNo 页码(从1开始)
|
||||
* @param pageSize 每页大小(必须大于0)
|
||||
* @return ConfigInfo对象的集合
|
||||
*/
|
||||
@Deprecated
|
||||
Page<ConfigInfoBase> findAllConfigInfoBase(final int pageNo,
|
||||
final int pageSize);
|
||||
|
||||
Page<ConfigInfoWrapper> findAllConfigInfoForDumpAll(
|
||||
final int pageNo, final int pageSize);
|
||||
|
||||
Page<ConfigInfoWrapper> findAllConfigInfoFragment(final long lastMaxId, final int pageSize);
|
||||
|
||||
Page<ConfigInfoBetaWrapper> findAllConfigInfoBetaForDumpAll(
|
||||
final int pageNo, final int pageSize);
|
||||
|
||||
Page<ConfigInfoTagWrapper> findAllConfigInfoTagForDumpAll(
|
||||
final int pageNo, final int pageSize);
|
||||
|
||||
/**
|
||||
* 通过select in方式实现db记录的批量查询; subQueryLimit指定in中条件的个数,上限20
|
||||
*/
|
||||
List<ConfigInfo> findConfigInfoByBatch(final List<String> dataIds,
|
||||
final String group, final String tenant, int subQueryLimit);
|
||||
|
||||
/**
|
||||
* 根据dataId和group模糊查询配置信息
|
||||
*
|
||||
* @param pageNo 页码(必须大于0)
|
||||
* @param pageSize 每页大小(必须大于0)
|
||||
* @param dataId 支持模糊查询
|
||||
* @param group 支持模糊查询
|
||||
* @param tenant 支持模糊查询
|
||||
* @return ConfigInfo对象的集合
|
||||
*/
|
||||
Page<ConfigInfo> findConfigInfoLike(final int pageNo, final int pageSize, final String dataId,
|
||||
final String group, final String tenant, final String appName,
|
||||
final String content);
|
||||
|
||||
Page<ConfigInfo> findConfigInfoLike4Page(final int pageNo, final int pageSize, final String dataId,
|
||||
final String group, final String tenant,
|
||||
final Map<String, Object> configAdvanceInfo);
|
||||
|
||||
/**
|
||||
* 根据dataId和group模糊查询配置信息
|
||||
*
|
||||
* @param pageNo 页码(必须大于0)
|
||||
* @param pageSize 每页大小(必须大于0)
|
||||
* @param configKeys 查询配置列表
|
||||
* @param blacklist 是否黑名单
|
||||
* @return ConfigInfo对象的集合
|
||||
*/
|
||||
Page<ConfigInfo> findConfigInfoLike(final int pageNo,
|
||||
final int pageSize, final ConfigKey[] configKeys,
|
||||
final boolean blacklist);
|
||||
|
||||
/**
|
||||
* 根据dataId和group模糊查询配置信息
|
||||
*
|
||||
* @param pageNo 页码(必须大于0)
|
||||
* @param pageSize 每页大小(必须大于0)
|
||||
* @param dataId
|
||||
* @param group
|
||||
* @return ConfigInfo对象的集合
|
||||
* @throws IOException
|
||||
*/
|
||||
Page<ConfigInfoBase> findConfigInfoBaseLike(final int pageNo,
|
||||
final int pageSize, final String dataId, final String group,
|
||||
final String content) throws IOException;
|
||||
|
||||
/**
|
||||
* 查找聚合前的单条数据
|
||||
*
|
||||
* @param dataId
|
||||
* @param group
|
||||
* @param datumId
|
||||
* @return {@link ConfigInfoAggr}
|
||||
*/
|
||||
ConfigInfoAggr findSingleConfigInfoAggr(String dataId, String group, String tenant, String datumId);
|
||||
|
||||
/**
|
||||
* 查找一个dataId下面的所有聚合前的数据. 保证不返回NULL.
|
||||
*/
|
||||
List<ConfigInfoAggr> findConfigInfoAggr(String dataId, String group, String tenant);
|
||||
|
||||
Page<ConfigInfoAggr> findConfigInfoAggrByPage(String dataId, String group, String tenant, final int pageNo,
|
||||
final int pageSize);
|
||||
|
||||
/**
|
||||
* 查询符合条件的聚合数据
|
||||
*
|
||||
* @param pageNo pageNo
|
||||
* @param pageSize pageSize
|
||||
* @param configKeys 聚合数据条件
|
||||
* @param blacklist 黑名单
|
||||
* @return {@link Page<ConfigInfoAggr>}
|
||||
*/
|
||||
Page<ConfigInfoAggr> findConfigInfoAggrLike(final int pageNo, final int pageSize, ConfigKey[] configKeys,
|
||||
boolean blacklist);
|
||||
|
||||
/**
|
||||
* 找到所有聚合数据组。
|
||||
*/
|
||||
List<ConfigInfoChanged> findAllAggrGroup();
|
||||
|
||||
/**
|
||||
* 由datum内容查找datumId
|
||||
*
|
||||
* @param dataId data id
|
||||
* @param groupId group
|
||||
* @param content content
|
||||
* @return datum keys
|
||||
*/
|
||||
List<String> findDatumIdByContent(String dataId, String groupId,
|
||||
String content);
|
||||
|
||||
List<ConfigInfoWrapper> findChangeConfig(final Timestamp startTime,
|
||||
final Timestamp endTime);
|
||||
|
||||
/**
|
||||
* 根据时间段和配置条件查询符合条件的配置
|
||||
*
|
||||
* @param dataId dataId 支持模糊
|
||||
* @param group dataId 支持模糊
|
||||
* @param appName 产品名
|
||||
* @param startTime 起始时间
|
||||
* @param endTime 截止时间
|
||||
* @param pageNo pageNo
|
||||
* @param pageSize pageSize
|
||||
* @return {@link Page<ConfigInfoWrapper>}
|
||||
*/
|
||||
Page<ConfigInfoWrapper> findChangeConfig(final String dataId, final String group, final String tenant,
|
||||
final String appName, final Timestamp startTime,
|
||||
final Timestamp endTime, final int pageNo,
|
||||
final int pageSize, final long lastMaxId);
|
||||
|
||||
List<ConfigInfo> findDeletedConfig(final Timestamp startTime,
|
||||
final Timestamp endTime);
|
||||
|
||||
/**
|
||||
* 增加配置;数据库原子操作,最小sql动作,无业务封装
|
||||
*
|
||||
* @param srcIp ip
|
||||
* @param srcUser user
|
||||
* @param configInfo info
|
||||
* @param time time
|
||||
* @param configAdvanceInfo advance info
|
||||
* @return excute sql result
|
||||
*/
|
||||
long addConfigInfoAtomic(final long id, final String srcIp, final String srcUser, final ConfigInfo configInfo,
|
||||
final Timestamp time,
|
||||
Map<String, Object> configAdvanceInfo);
|
||||
|
||||
/**
|
||||
* 增加配置;数据库原子操作,最小sql动作,无业务封装
|
||||
*
|
||||
* @param configId id
|
||||
* @param tagName tag
|
||||
* @param dataId data id
|
||||
* @param group group
|
||||
* @param tenant tenant
|
||||
*/
|
||||
void addConfigTagRelationAtomic(long configId, String tagName, String dataId, String group, String tenant);
|
||||
|
||||
/**
|
||||
* 增加配置;数据库原子操作
|
||||
*
|
||||
* @param configId config id
|
||||
* @param configTags tags
|
||||
* @param dataId dataId
|
||||
* @param group group
|
||||
* @param tenant tenant
|
||||
*/
|
||||
void addConfigTagsRelation(long configId, String configTags, String dataId, String group,
|
||||
String tenant);
|
||||
|
||||
void removeTagByIdAtomic(long id);
|
||||
|
||||
List<String> getConfigTagsByTenant(String tenant);
|
||||
|
||||
List<String> selectTagByConfig(String dataId, String group, String tenant);
|
||||
|
||||
/**
|
||||
* 删除配置;数据库原子操作,最小sql动作,无业务封装
|
||||
*
|
||||
* @param dataId dataId
|
||||
* @param group group
|
||||
* @param tenant tenant
|
||||
* @param srcIp ip
|
||||
* @param srcUser user
|
||||
*/
|
||||
void removeConfigInfoAtomic(final String dataId, final String group, final String tenant,
|
||||
final String srcIp,
|
||||
final String srcUser);
|
||||
|
||||
/**
|
||||
* @return void
|
||||
* @author klw
|
||||
* @Description: Delete configuration; database atomic operation, minimum SQL action, no business encapsulation
|
||||
* @Date 2019/7/5 16:39
|
||||
* @Param [id]
|
||||
*/
|
||||
void removeConfigInfoByIdsAtomic(final String ids);
|
||||
|
||||
/**
|
||||
* 删除配置;数据库原子操作,最小sql动作,无业务封装
|
||||
*
|
||||
* @param dataId dataId
|
||||
* @param group group
|
||||
* @param tenant tenant
|
||||
* @param tag tag
|
||||
* @param srcIp ip
|
||||
* @param srcUser user
|
||||
*/
|
||||
void removeConfigInfoTag(final String dataId, final String group, final String tenant, final String tag,
|
||||
final String srcIp,
|
||||
final String srcUser);
|
||||
|
||||
/**
|
||||
* 更新配置;数据库原子操作,最小sql动作,无业务封装
|
||||
*
|
||||
* @param configInfo config info
|
||||
* @param srcIp ip
|
||||
* @param srcUser user
|
||||
* @param time time
|
||||
* @param configAdvanceInfo advance info
|
||||
*/
|
||||
void updateConfigInfoAtomic(final ConfigInfo configInfo, final String srcIp, final String srcUser,
|
||||
final Timestamp time, Map<String, Object> configAdvanceInfo);
|
||||
|
||||
/**
|
||||
* 查询配置信息;数据库原子操作,最小sql动作,无业务封装
|
||||
*
|
||||
* @param dataId dataId
|
||||
* @param group group
|
||||
* @param tenant tenant
|
||||
* @return config info
|
||||
*/
|
||||
ConfigInfo findConfigInfo(final String dataId, final String group, final String tenant);
|
||||
|
||||
/**
|
||||
* @return {@link java.util.List<com.alibaba.nacos.config.server.model.ConfigInfo>}
|
||||
* @author klw
|
||||
* @Description: find ConfigInfo by ids
|
||||
* @Date 2019/7/5 16:37
|
||||
* @Param [ids]
|
||||
*/
|
||||
List<ConfigInfo> findConfigInfosByIds(final String ids);
|
||||
|
||||
/**
|
||||
* 查询配置信息;数据库原子操作,最小sql动作,无业务封装
|
||||
*
|
||||
* @param dataId dataId
|
||||
* @param group group
|
||||
* @param tenant tenant
|
||||
* @return advance info
|
||||
*/
|
||||
ConfigAdvanceInfo findConfigAdvanceInfo(final String dataId, final String group, final String tenant);
|
||||
|
||||
/**
|
||||
* 查询配置信息;数据库原子操作,最小sql动作,无业务封装
|
||||
*
|
||||
* @param dataId dataId
|
||||
* @param group group
|
||||
* @param tenant tenant
|
||||
* @return advance info
|
||||
*/
|
||||
ConfigAllInfo findConfigAllInfo(final String dataId, final String group, final String tenant);
|
||||
|
||||
/**
|
||||
* 更新变更记录;数据库原子操作,最小sql动作,无业务封装
|
||||
*
|
||||
* @param configHistoryId id
|
||||
* @param configInfo config info
|
||||
* @param srcIp ip
|
||||
* @param srcUser user
|
||||
* @param time time
|
||||
* @param ops ops type
|
||||
*/
|
||||
void insertConfigHistoryAtomic(long id, ConfigInfo configInfo, String srcIp, String srcUser,
|
||||
final Timestamp time, String ops);
|
||||
|
||||
/**
|
||||
* list配置的历史变更记录
|
||||
*
|
||||
* @param dataId data Id
|
||||
* @param group group
|
||||
* @param tenant tenant
|
||||
* @param pageNo no
|
||||
* @param pageSize size
|
||||
* @return history info
|
||||
*/
|
||||
Page<ConfigHistoryInfo> findConfigHistory(String dataId, String group, String tenant, int pageNo,
|
||||
int pageSize);
|
||||
|
||||
/**
|
||||
* 增加配置;数据库原子操作,最小sql动作,无业务封装
|
||||
*
|
||||
* @param dataId dataId
|
||||
* @param group group
|
||||
* @param appName appName
|
||||
* @param date date
|
||||
*/
|
||||
void addConfigSubAtomic(final String dataId, final String group, final String appName,
|
||||
final Timestamp date);
|
||||
|
||||
/**
|
||||
* 更新配置;数据库原子操作,最小sql动作,无业务封装
|
||||
*
|
||||
* @param dataId data Id
|
||||
* @param group group
|
||||
* @param appName app name
|
||||
* @param time time
|
||||
*/
|
||||
void updateConfigSubAtomic(final String dataId, final String group, final String appName,
|
||||
final Timestamp time);
|
||||
|
||||
ConfigHistoryInfo detailConfigHistory(Long nid);
|
||||
|
||||
/**
|
||||
* insert tenant info
|
||||
*
|
||||
* @param kp kp
|
||||
* @param tenantId tenant Id
|
||||
* @param tenantName tenant name
|
||||
* @param tenantDesc tenant description
|
||||
* @param time time
|
||||
*/
|
||||
void insertTenantInfoAtomic(String kp, String tenantId, String tenantName, String tenantDesc,
|
||||
String createResoure, final long time);
|
||||
|
||||
/**
|
||||
* Update tenantInfo showname
|
||||
*
|
||||
* @param kp kp
|
||||
* @param tenantId tenant Id
|
||||
* @param tenantName tenant name
|
||||
* @param tenantDesc tenant description
|
||||
*/
|
||||
void updateTenantNameAtomic(String kp, String tenantId, String tenantName, String tenantDesc);
|
||||
|
||||
List<TenantInfo> findTenantByKp(String kp);
|
||||
|
||||
TenantInfo findTenantByKp(String kp, String tenantId);
|
||||
|
||||
void removeTenantInfoAtomic(final String kp, final String tenantId);
|
||||
|
||||
List<ConfigInfo> convertDeletedConfig(List<Map<String, Object>> list);
|
||||
|
||||
List<ConfigInfoWrapper> convertChangeConfig(List<Map<String, Object>> list);
|
||||
|
||||
/**
|
||||
* 获取所有的配置的Md5值,通过分页方式获取。
|
||||
*
|
||||
* @return {@link List<ConfigInfoWrapper>}
|
||||
*/
|
||||
List<ConfigInfoWrapper> listAllGroupKeyMd5();
|
||||
|
||||
List<ConfigInfoWrapper> listGroupKeyMd5ByPage(int pageNo, int pageSize);
|
||||
|
||||
String generateLikeArgument(String s);
|
||||
|
||||
ConfigInfoWrapper queryConfigInfo(final String dataId, final String group, final String tenant);
|
||||
|
||||
boolean isExistTable(String tableName);
|
||||
|
||||
Boolean completeMd5();
|
||||
|
||||
/**
|
||||
* query all configuration information according to group, appName, tenant (for export)
|
||||
*
|
||||
* @param group
|
||||
* @return Collection of ConfigInfo objects
|
||||
*/
|
||||
List<ConfigAllInfo> findAllConfigInfo4Export(final String dataId, final String group, final String tenant,
|
||||
final String appName, final List<Long> ids);
|
||||
|
||||
/**
|
||||
* batch operation,insert or update
|
||||
* the format of the returned:
|
||||
* succCount: number of successful imports
|
||||
* skipCount: number of import skips (only with skip for the same configs)
|
||||
* failData: import failed data (only with abort for the same configs)
|
||||
* skipData: data skipped at import (only with skip for the same configs)
|
||||
*/
|
||||
Map<String, Object> batchInsertOrUpdate(List<ConfigAllInfo> configInfoList, String srcUser, String srcIp,
|
||||
Map<String, Object> configAdvanceInfo, Timestamp time, boolean notify, SameConfigPolicy policy) throws
|
||||
NacosException;
|
||||
|
||||
/**
|
||||
* query tenantInfo (namespace) existence based by tenantId
|
||||
*
|
||||
* @param tenantId
|
||||
* @return count by tenantId
|
||||
*/
|
||||
int tenantInfoCountByTenantId(String tenantId);
|
||||
}
|
@ -0,0 +1,88 @@
|
||||
/*
|
||||
* Copyright 1999-2018 Alibaba Group Holding Ltd.
|
||||
*
|
||||
* 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 com.alibaba.nacos.config.server.service.repository;
|
||||
|
||||
import com.alibaba.nacos.config.server.configuration.ConditionStandaloneEmbedStorage;
|
||||
import com.alibaba.nacos.config.server.service.DataSourceService;
|
||||
import com.alibaba.nacos.config.server.service.DynamicDataSource;
|
||||
import com.alibaba.nacos.config.server.service.sql.ModifyRequest;
|
||||
import com.alibaba.nacos.config.server.utils.LogUtil;
|
||||
import org.springframework.context.annotation.Conditional;
|
||||
import org.springframework.jdbc.core.JdbcTemplate;
|
||||
import org.springframework.jdbc.core.RowMapper;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.transaction.support.TransactionTemplate;
|
||||
|
||||
import javax.annotation.PostConstruct;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:liaochuntao@live.com">liaochuntao</a>
|
||||
*/
|
||||
@Conditional(ConditionStandaloneEmbedStorage.class)
|
||||
@Component
|
||||
public class StandaloneDatabaseOperateImpl implements BaseDatabaseOperate, DatabaseOperate {
|
||||
|
||||
private DataSourceService dataSourceService;
|
||||
|
||||
private JdbcTemplate jdbcTemplate;
|
||||
private TransactionTemplate transactionTemplate;
|
||||
|
||||
@PostConstruct
|
||||
protected void init() {
|
||||
dataSourceService = DynamicDataSource.getInstance().getDataSource();
|
||||
jdbcTemplate = dataSourceService.getJdbcTemplate();
|
||||
transactionTemplate = dataSourceService.getTransactionTemplate();
|
||||
LogUtil.defaultLog.info("use StandaloneDatabaseOperateImpl");
|
||||
}
|
||||
|
||||
@Override
|
||||
public <R> R queryOne(String sql, Class<R> cls) {
|
||||
return queryOne(jdbcTemplate, sql, cls);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <R> R queryOne(String sql, Object[] args, Class<R> cls) {
|
||||
return queryOne(jdbcTemplate, sql, args, cls);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <R> R queryOne(String sql, Object[] args, RowMapper<R> mapper) {
|
||||
return queryOne(jdbcTemplate, sql, args, mapper);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <R> List<R> queryMany(String sql, Object[] args, RowMapper<R> mapper) {
|
||||
return queryMany(jdbcTemplate, sql, args, mapper);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <R> List<R> queryMany(String sql, Object[] args, Class<R> rClass) {
|
||||
return queryMany(jdbcTemplate, sql, args, rClass);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Map<String, Object>> queryMany(String sql, Object[] args) {
|
||||
return queryMany(jdbcTemplate, sql, args);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Boolean update(List<ModifyRequest> requestList) {
|
||||
return update(transactionTemplate, jdbcTemplate, requestList);
|
||||
}
|
||||
}
|
@ -14,12 +14,14 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.alibaba.nacos.config.server.service.transaction;
|
||||
package com.alibaba.nacos.config.server.service.sql;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
* Represents a database UPDATE or INSERT or DELETE statement
|
||||
*
|
||||
* @author <a href="mailto:liaochuntao@live.com">liaochuntao</a>
|
||||
*/
|
||||
@SuppressWarnings("PMD.ClassNamingShouldBeCamelRule")
|
@ -0,0 +1,58 @@
|
||||
/*
|
||||
* Copyright 1999-2018 Alibaba Group Holding Ltd.
|
||||
*
|
||||
* 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 com.alibaba.nacos.config.server.service.sql;
|
||||
|
||||
import org.springframework.jdbc.core.RowMapper;
|
||||
|
||||
/**
|
||||
* Associated with the method correspondence of the {@link org.springframework.jdbc.core.JdbcTemplate}
|
||||
*
|
||||
* @author <a href="mailto:liaochuntao@live.com">liaochuntao</a>
|
||||
*/
|
||||
public class QueryType {
|
||||
|
||||
/**
|
||||
* {@link org.springframework.jdbc.core.JdbcTemplate#queryForObject(String, RowMapper)}
|
||||
*/
|
||||
public static final byte QUERY_ONE_WITH_MAPPER_WITH_ARGS = 0;
|
||||
|
||||
/**
|
||||
* {@link org.springframework.jdbc.core.JdbcTemplate#queryForObject(String, Class)}
|
||||
*/
|
||||
public static final byte QUERY_ONE_NO_MAPPER_NO_ARGS = 1;
|
||||
|
||||
/**
|
||||
* {@link org.springframework.jdbc.core.JdbcTemplate#queryForObject(String, Object[], Class)}
|
||||
*/
|
||||
public static final byte QUERY_ONE_NO_MAPPER_WITH_ARGS = 2;
|
||||
|
||||
/**
|
||||
* {@link org.springframework.jdbc.core.JdbcTemplate#query(String, Object[], RowMapper)}
|
||||
*/
|
||||
public static final byte QUERY_MANY_WITH_MAPPER_WITH_ARGS = 3;
|
||||
|
||||
/**
|
||||
* {@link org.springframework.jdbc.core.JdbcTemplate#queryForList(String, Object...)}
|
||||
*/
|
||||
public static final byte QUERY_MANY_WITH_LIST_WITH_ARGS = 4;
|
||||
|
||||
/**
|
||||
* {@link org.springframework.jdbc.core.JdbcTemplate#queryForList(String, Object[], Class)}
|
||||
*/
|
||||
public static final byte QUERY_MANY_NO_MAPPER_WITH_ARGS = 5;
|
||||
|
||||
}
|
@ -14,12 +14,14 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.alibaba.nacos.config.server.service.transaction;
|
||||
package com.alibaba.nacos.config.server.service.sql;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
* Represents a database SELECT statement
|
||||
*
|
||||
* @author <a href="mailto:liaochuntao@live.com">liaochuntao</a>
|
||||
*/
|
||||
public class SelectRequest implements Serializable {
|
@ -14,12 +14,15 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.alibaba.nacos.config.server.service.transaction;
|
||||
package com.alibaba.nacos.config.server.service.sql;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Temporarily saves all insert, update, and delete statements under
|
||||
* a transaction in the order in which they occur
|
||||
*
|
||||
* @author <a href="mailto:liaochuntao@live.com">liaochuntao</a>
|
||||
*/
|
||||
public class SqlContextUtils {
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user