Skip to content

Commit

Permalink
3.0 service discovery metadata refactor (apache#9506)
Browse files Browse the repository at this point in the history
  • Loading branch information
chickenlj authored Dec 29, 2021
1 parent 32a083c commit b2a4f61
Show file tree
Hide file tree
Showing 603 changed files with 5,477 additions and 10,466 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,9 @@

import org.apache.dubbo.common.extension.Activate;
import org.apache.dubbo.rpc.Filter;
import org.apache.dubbo.rpc.Result;
import org.apache.dubbo.rpc.Invoker;
import org.apache.dubbo.rpc.Invocation;
import org.apache.dubbo.rpc.Invoker;
import org.apache.dubbo.rpc.Result;
import org.apache.dubbo.rpc.RpcException;

import static org.apache.dubbo.common.constants.CommonConstants.CONSUMER;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
package org.apache.dubbo.rpc.cluster.merger;

import org.apache.dubbo.rpc.model.ApplicationModel;

import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,14 +20,15 @@
import org.apache.dubbo.rpc.cluster.router.mesh.rule.virtualservice.DubboRoute;
import org.apache.dubbo.rpc.cluster.router.mesh.rule.virtualservice.DubboRouteDetail;
import org.apache.dubbo.rpc.cluster.router.mesh.rule.virtualservice.VirtualServiceRule;

import org.junit.jupiter.api.Test;
import org.yaml.snakeyaml.Yaml;

import java.util.List;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertNull;
import static org.junit.jupiter.api.Assertions.assertEquals;


public class VirtualServiceRuleTest {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
import org.apache.dubbo.rpc.RpcInvocation;
import org.apache.dubbo.rpc.cluster.Directory;
import org.apache.dubbo.rpc.cluster.filter.DemoService;

import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
import org.apache.dubbo.common.URL;
import org.apache.dubbo.common.URLBuilder;
import org.apache.dubbo.rpc.model.ApplicationModel;

import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,6 @@
import java.util.LinkedList;
import java.util.List;
import java.util.Set;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.ThreadLocalRandom;

import static org.mockito.Mockito.when;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,6 @@
import java.util.Map;

import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.mockito.BDDMockito.given;
import static org.mockito.Mockito.mock;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,31 +20,32 @@
import org.apache.dubbo.common.URL;
import org.apache.dubbo.common.URLBuilder;
import org.apache.dubbo.rpc.cluster.ProviderURLMergeProcessor;

import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;

import static org.apache.dubbo.common.constants.CommonConstants.ALIVE_KEY;
import static org.apache.dubbo.common.constants.CommonConstants.APPLICATION_KEY;
import static org.apache.dubbo.common.constants.CommonConstants.CLUSTER_KEY;
import static org.apache.dubbo.common.constants.CommonConstants.CORE_THREADS_KEY;
import static org.apache.dubbo.common.constants.CommonConstants.DEFAULT_KEY_PREFIX;
import static org.apache.dubbo.common.constants.CommonConstants.DUBBO_PROTOCOL;
import static org.apache.dubbo.common.constants.CommonConstants.DUBBO_VERSION_KEY;
import static org.apache.dubbo.common.constants.CommonConstants.GROUP_KEY;
import static org.apache.dubbo.common.constants.CommonConstants.LOADBALANCE_KEY;
import static org.apache.dubbo.common.constants.CommonConstants.METHODS_KEY;
import static org.apache.dubbo.common.constants.CommonConstants.PID_KEY;
import static org.apache.dubbo.common.constants.CommonConstants.QUEUES_KEY;
import static org.apache.dubbo.common.constants.CommonConstants.REFERENCE_FILTER_KEY;
import static org.apache.dubbo.common.constants.CommonConstants.RELEASE_KEY;
import static org.apache.dubbo.common.constants.CommonConstants.TAG_KEY;
import static org.apache.dubbo.common.constants.CommonConstants.THREADPOOL_KEY;
import static org.apache.dubbo.common.constants.CommonConstants.THREADS_KEY;
import static org.apache.dubbo.common.constants.CommonConstants.THREAD_NAME_KEY;
import static org.apache.dubbo.common.constants.CommonConstants.RELEASE_KEY;
import static org.apache.dubbo.common.constants.CommonConstants.VERSION_KEY;
import static org.apache.dubbo.common.constants.CommonConstants.METHODS_KEY;
import static org.apache.dubbo.common.constants.CommonConstants.TIMESTAMP_KEY;
import static org.apache.dubbo.common.constants.CommonConstants.CLUSTER_KEY;
import static org.apache.dubbo.common.constants.CommonConstants.TIMEOUT_KEY;
import static org.apache.dubbo.common.constants.CommonConstants.LOADBALANCE_KEY;
import static org.apache.dubbo.common.constants.CommonConstants.TIMESTAMP_KEY;
import static org.apache.dubbo.common.constants.CommonConstants.VERSION_KEY;

public class DefaultProviderURLMergeProcessorTest {

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,238 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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 org.apache.dubbo.common.cache;

import org.apache.dubbo.common.logger.Logger;
import org.apache.dubbo.common.logger.LoggerFactory;
import org.apache.dubbo.common.utils.CollectionUtils;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.RandomAccessFile;
import java.nio.channels.FileChannel;
import java.nio.channels.FileLock;
import java.nio.channels.OverlappingFileLockException;
import java.nio.charset.StandardCharsets;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

/**
* Local file interaction class that can back different caches.
*
* All items in local file are of human friendly format.
*/
public class FileCacheStore {
private static final Logger logger = LoggerFactory.getLogger(FileCacheStore.class);

private static final int DEL = 0x7F;
private static final char ESCAPE = '%';
private static final Set<Character> ILLEGALS = new HashSet<Character>();
private static final String SUFFIX = ".dubbo.cache";

private String fileName;
private File basePath;
private File cacheFile;
private FileLock directoryLock;
private File lockFile;

public FileCacheStore(String basePath, String fileName) throws IOException, PathNotExclusiveException {
if (basePath == null) {
basePath = System.getProperty("user.home") + "/.dubbo/";
}
this.basePath = new File(basePath);
this.fileName = fileName;

this.cacheFile = getFile(fileName, SUFFIX);
if (cacheFile != null && !cacheFile.exists()) {
cacheFile.createNewFile();
}
}

public Map<String, String> loadCache(int entrySize) throws IOException {
Map<String, String> properties = new HashMap<>();
try (BufferedReader reader = new BufferedReader(new FileReader(cacheFile))) {
int count = 1;
String line = reader.readLine();
while (line != null && count <= entrySize) {
// content has '=' need to be encoded before write
if (!line.equals("") && !line.startsWith("#") && line.contains("=")) {
String[] pairs = line.split("=");
properties.put(pairs[0], pairs[1]);
count++;
}
line = reader.readLine();
}

if (count > entrySize) {
logger.warn("Cache file was truncated for exceeding the maximum entry size " + entrySize);
}
} catch (IOException e) {
logger.warn("Load cache failed ", e);
throw e;
}
return properties;
}

public File getFile(String cacheName, String suffix) throws PathNotExclusiveException {
cacheName = safeName(cacheName);
if (!cacheName.endsWith(suffix)) {
cacheName = cacheName + suffix;
}
return getFile(cacheName);
}

/**
* Get a file object for the given name
*
* @param name the file name
* @return a file object
*/
public File getFile(String name) throws PathNotExclusiveException {
synchronized (this) {
File candidate = basePath;
// ensure cache store path exists
if (!candidate.isDirectory() && !candidate.mkdirs()) {
throw new RuntimeException("Cache store path can't be created: " + candidate);
}

try {
tryFileLock(name);
} catch (PathNotExclusiveException e) {
logger.warn("Path '" + basePath
+ "' is already used by an existing Dubbo process.\n"
+ "Please specify another one explicitly.");
throw e;
}
}

File file = new File(basePath, name);
for (File parent = file.getParentFile(); parent != null; parent = parent.getParentFile()) {
if (basePath.equals(parent)) {
return file;
}
}

throw new IllegalArgumentException("Attempted to access file outside the dubbo cache path");
}

/**
* sanitize a name for valid file or directory name
*
* @param name
* @return sanitized version of name
*/
private static String safeName(String name) {
int len = name.length();
StringBuilder sb = new StringBuilder(len);
for (int i = 0; i < len; i++) {
char c = name.charAt(i);
if (c <= ' ' || c >= DEL || (c >= 'A' && c <= 'Z') || ILLEGALS.contains(c) || c == ESCAPE) {
sb.append(ESCAPE);
sb.append(String.format("%04x", (int) c));
} else {
sb.append(c);
}
}
return sb.toString();
}

private void tryFileLock(String fileName) throws PathNotExclusiveException {
lockFile = new File(basePath.getAbsoluteFile(), fileName + ".lock");
lockFile.deleteOnExit();

FileLock dirLock;
try {
lockFile.createNewFile();
if (!lockFile.exists()) {
throw new AssertionError("Failed to create lock file " + lockFile);
}
FileChannel lockFileChannel = new RandomAccessFile(lockFile, "rw").getChannel();
dirLock = lockFileChannel.tryLock();
} catch (OverlappingFileLockException ofle) {
dirLock = null;
} catch (IOException ioe) {
throw new RuntimeException(ioe);
}

if (dirLock == null) {
throw new PathNotExclusiveException(basePath.getAbsolutePath() + "/" + fileName + " is not exclusive.");
}

this.directoryLock = dirLock;
}

private void unlock() {
if (directoryLock != null && directoryLock.isValid()) {
try {
directoryLock.release();
directoryLock.channel().close();
deleteFile(lockFile);
} catch (IOException e) {
throw new RuntimeException("Failed to release cache path's lock file:" + lockFile, e);
}
}
}

public void refreshCache(Map<String, String> properties, String comment) {
if (CollectionUtils.isEmptyMap(properties)) {
return;
}

try (BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(cacheFile, false), StandardCharsets.UTF_8))) {
bw.write("#" + comment);
bw.write("#" + new Date().toString());
bw.newLine();
for (Map.Entry<String, String> e : properties.entrySet()) {
String key = e.getKey();
String val = e.getValue();
bw.write(key + "=" + val);
bw.newLine();
}
bw.flush();
} catch (IOException e) {
logger.warn("Update cache error.");
}
}

private static void deleteFile(File f) {
if (!f.delete()) {
logger.debug("Failed to delete file " + f.getAbsolutePath());
}
}

private static class PathNotExclusiveException extends Exception {
public PathNotExclusiveException() {
super();
}

public PathNotExclusiveException(String msg) {
super(msg);
}
}

public void destroy() {
unlock();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ public CompositeConfiguration(Configuration... configurations) {
}
}

//FIXME, consider change configList to SortedMap to replace this boolean status.
//FIXME, consider changing configList to SortedMap to replace this boolean status.
public boolean isDynamicIncluded() {
return dynamicIncluded;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -164,7 +164,7 @@ public static int get(ScopeModel scopeModel, String property, int defaultValue)
public static Map<String, String> parseProperties(String content) throws IOException {
Map<String, String> map = new HashMap<>();
if (StringUtils.isEmpty(content)) {
logger.warn("You specified the config center, but there's not even one single config item in it.");
logger.warn("Config center was specified, but no config item found.");
} else {
Properties properties = new Properties();
properties.load(new StringReader(content));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,6 @@
*/
package org.apache.dubbo.common.config.configcenter.file;

import org.apache.commons.io.FileUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.dubbo.common.URL;
import org.apache.dubbo.common.config.configcenter.ConfigChangeType;
import org.apache.dubbo.common.config.configcenter.ConfigChangedEvent;
Expand All @@ -33,6 +30,10 @@
import org.apache.dubbo.rpc.model.ScopeModel;
import org.apache.dubbo.rpc.model.ScopeModelUtil;

import org.apache.commons.io.FileUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import java.io.File;
import java.io.IOException;
import java.nio.file.FileSystem;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ public void close() throws Exception {
try {
configuration.close();
} catch (Exception e) {
logger.warn("close dynamic configuration failed: " + e.getMessage(), e);
logger.warn("close dynamic configuration " + configuration.getClass().getName() + "failed: " + e.getMessage(), e);
}
}
configurations.clear();
Expand Down
Loading

0 comments on commit b2a4f61

Please sign in to comment.