add hmily load config module

This commit is contained in:
yu199195 2020-08-18 18:50:23 +08:00
parent 9118991b9d
commit a703d8cacb
24 changed files with 1473 additions and 38 deletions

View File

@ -43,5 +43,4 @@
</dependency>
</dependencies>
</project>

View File

@ -56,37 +56,15 @@ public final class ConfigEnv {
return INST;
}
/**
* Add a class Path that needs to be processed.
*
* @param classPath class path.
*/
public void addConfigClassPath(String classPath) {
if (classPath.startsWith("java.")) {
logger.warn("config class path Ignore {}", classPath);
return;
}
try {
Class<?> clazz = Class.forName(classPath);
addConfigClass(clazz);
} catch (ClassNotFoundException e) {
throw new ConfigException(e);
}
}
/**
* Add config class.
* Register config.
*
* @param clazz the clazz
* @param config the config
*/
public void addConfigClass(Class<?> clazz) {
if (clazz.getSuperclass().isAssignableFrom(AbstractConfig.class)) {
try {
AbstractConfig configParent = (AbstractConfig) clazz.newInstance();
putBean(configParent);
} catch (IllegalAccessException | InstantiationException e) {
throw new ConfigException(e);
}
public void registerConfig(final Config config) {
if (config.getClass().getSuperclass().isAssignableFrom(AbstractConfig.class)) {
putBean(config);
}
}
@ -98,7 +76,7 @@ public final class ConfigEnv {
* @return the config
*/
@SuppressWarnings("unchecked")
public <T extends Config> T getConfig(Class<T> clazz) {
public <T extends Config> T getConfig(final Class<T> clazz) {
return (T) configBeans.get(clazz);
}
@ -107,7 +85,7 @@ public final class ConfigEnv {
*
* @param parent parent.
*/
public void putBean(Config parent) {
public void putBean(final Config parent) {
if (parent != null && StringUtils.isNotBlank(parent.prefix())) {
if (configBeans.containsKey(parent.getClass())) {
return;

View File

@ -0,0 +1,37 @@
/*
* 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.dromara.hmily.config.api;
import java.util.List;
import org.dromara.hmily.spi.ExtensionLoaderFactory;
/**
* ConfigScan
* Scan config information to add.
*
* @author xiaoyu
*/
public final class ConfigScan {
public static void scan() {
List<Config> configs = ExtensionLoaderFactory.loadAll(Config.class);
for (Config conf : configs) {
ConfigEnv.getInstance().registerConfig(conf);
}
}
}

View File

@ -0,0 +1,49 @@
/*
*
* 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
* he 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.dromara.hmily.config.api.constant;
/**
* The interface Config constants.
*
* @author xiaoyu
*/
public interface PrefixConstants {
/**
* The constant SERVER_PREFIX.
*/
String SERVER_PREFIX = "hmily.server";
/**
* The constant CONFIG_PREFIX.
*/
String CONFIG_PREFIX = "hmily.config";
/**
* The constant APOLLO_PREFIX.
*/
String APOLLO_PREFIX = "hmily.apollo";
/**
* The constant NACOS_PREFIX.
*/
String NACOS_PREFIX = "hmily.nacos";
}

View File

@ -0,0 +1,137 @@
/*
* 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.dromara.hmily.config.api.entity;
import lombok.Data;
import org.dromara.hmily.config.api.AbstractConfig;
import org.dromara.hmily.config.api.constant.PrefixConstants;
import org.dromara.hmily.spi.HmilySPI;
/**
* hmily config.
*
* @author xiaoyu
*/
@Data
@HmilySPI("hmilyConfig")
public class HmilyConfig extends AbstractConfig {
/**
* Resource suffix this parameter please fill in about is the transaction store path.
* If it's a table store this is a table suffix, it's stored the same way.
* If this parameter is not filled in, the applicationName of the application is retrieved by default
*/
private String appName;
/**
* log serializer.
*/
private String serializer = "kryo";
/**
* contextTransmittalMode.
*/
private String contextTransmittalMode = "threadLocal";
/**
* scheduledPool Thread size.
*/
private int scheduledThreadMax = Runtime.getRuntime().availableProcessors() << 1;
/**
* scheduledPool scheduledDelay unit SECONDS.
*/
private int scheduledRecoveryDelay = 60;
/**
* scheduled clean delay.
*/
private int scheduledCleanDelay = 60;
/**
* scheduledPhyDeletedDelay.
*/
private int scheduledPhyDeletedDelay = 600;
/**
* scheduledPool scheduledInitDelay unit SECONDS.
*/
private int scheduledInitDelay = 30;
/**
* recoverDelayTime Unit seconds
* (note that this time represents how many seconds after the local transaction was created before execution).
*/
private int recoverDelayTime = 60;
/**
* cleanDelayTime Unit seconds
* (note that this time represents how many seconds after the local transaction was created before execution).
*/
private int cleanDelayTime = 180;
/**
* query by limit.
*/
private int limit = 100;
/**
* retry max.
*/
private int retryMax = 10;
/**
* disruptor bufferSize.
*/
private int bufferSize = 4096 * 2 * 2;
/**
* this is disruptor consumerThreads.
*/
private int consumerThreads = Runtime.getRuntime().availableProcessors() << 1;
/**
* asyncRepository.
*/
private boolean asyncRepository = true;
/**
* autoSql.
*/
private boolean autoSql = true;
/**
* phyDeleted is true means physically deleted is false means update status to death.
*/
private boolean phyDeleted = true;
/**
* when phyDeleted is false , store days.
*/
private int storeDays = 3;
/**
* repository.
*/
private String repository = "mysql";
@Override
public String prefix() {
return PrefixConstants.CONFIG_PREFIX;
}
}

View File

@ -0,0 +1,42 @@
/*
* 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.dromara.hmily.config.api.entity;
import lombok.Data;
import org.dromara.hmily.config.api.AbstractConfig;
import org.dromara.hmily.config.api.constant.PrefixConstants;
import org.dromara.hmily.spi.HmilySPI;
/**
* The type Hmily server.
*
* @author xiaoyu
*/
@Data
@HmilySPI("hmilyServer")
public class HmilyServer extends AbstractConfig {
private String appName;
private String configMode;
@Override
public String prefix() {
return PrefixConstants.SERVER_PREFIX;
}
}

View File

@ -0,0 +1,2 @@
org.dromara.hmily.config.api.entity.HmilyConfig
org.dromara.hmily.config.api.entity.HmilyServer

View File

@ -20,8 +20,8 @@
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>hmily-config</artifactId>
<groupId>org.dromara</groupId>
<artifactId>hmily-config</artifactId>
<version>2.1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
@ -34,15 +34,15 @@
<artifactId>hmily-config-api</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>commons-beanutils</groupId>
<artifactId>commons-beanutils</artifactId>
<version>1.9.3</version>
</dependency>
<dependency>
<groupId>org.yaml</groupId>
<artifactId>snakeyaml</artifactId>
<version>1.23</version>
</dependency>
<dependency>
<groupId>commons-beanutils</groupId>
<artifactId>commons-beanutils</artifactId>
<version>1.9.3</version>
</dependency>
</dependencies>
</project>

View File

@ -0,0 +1,51 @@
/*
* 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.dromara.hmily.config.loader;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.dromara.hmily.config.api.ConfigScan;
import org.dromara.hmily.spi.ExtensionLoaderFactory;
/**
* The type Hmily config server.
*/
@Slf4j
public class ConfigLoaderServer {
/**
* Load config.
*/
public static void load() {
// Start processing the associated parameters.
ConfigScan.scan();
ServerConfigLoader loader = new ServerConfigLoader();
loader.load(ConfigLoader.Context::new, (context, config) -> {
if (config != null) {
if (StringUtils.isNotBlank(config.getConfigMode())) {
String configMode = config.getConfigMode();
ConfigLoader<?> configLoader = ExtensionLoaderFactory.load(ConfigLoader.class, configMode);
log.info("Load the configuration【{}】information...", configMode);
configLoader.load(context, (contextAfter, configAfter) -> {
log.info("Configuration information: {}", configAfter);
});
}
}
});
}
}

View File

@ -0,0 +1,51 @@
/*
*
* 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.dromara.hmily.config.loader;
import java.util.Objects;
import java.util.function.Supplier;
import org.dromara.hmily.config.api.Config;
import org.dromara.hmily.config.api.ConfigEnv;
import org.dromara.hmily.config.loader.bind.BindData;
import org.dromara.hmily.config.loader.bind.Binder;
import org.dromara.hmily.config.loader.bind.DataType;
import org.dromara.hmily.config.loader.property.ConfigPropertySource;
import org.dromara.hmily.config.loader.property.DefaultConfigPropertySource;
import org.dromara.hmily.config.loader.property.PropertyKeyParse;
import org.dromara.hmily.config.loader.property.PropertyKeySource;
/**
* The type Original config loader.
*
* @author xiaoyu
*/
public class OriginalConfigLoader implements ConfigLoader<Config> {
@Override
public void load(Supplier<Context> context, LoaderHandler<Config> handler) {
for (PropertyKeySource<?> propertyKeySource : context.get().getSource()) {
ConfigPropertySource configPropertySource = new DefaultConfigPropertySource<>(propertyKeySource, PropertyKeyParse.INSTANCE);
ConfigEnv.getInstance().stream().map(e -> {
Binder binder = Binder.of(configPropertySource);
return binder.bind(e.prefix(), BindData.of(DataType.of(e.getClass()), () -> e));
}).filter(Objects::nonNull).peek(Config::flagLoad).forEach(e -> handler.finish(context, e));
}
}
}

View File

@ -0,0 +1,90 @@
/*
*
* 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.dromara.hmily.config.loader;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.net.URL;
import java.util.List;
import java.util.function.Supplier;
import org.dromara.hmily.common.utils.StringUtils;
import org.dromara.hmily.config.api.entity.HmilyServer;
import org.dromara.hmily.config.api.exception.ConfigException;
import org.dromara.hmily.config.loader.property.PropertyKeySource;
import org.dromara.hmily.config.loader.yaml.YamlPropertyLoader;
/**
* ParentConfigLoader .
* Read basic BaseConfig information processing.
*
* @author xiaoyu
*/
public class ServerConfigLoader implements ConfigLoader<HmilyServer> {
private final YamlPropertyLoader propertyLoader = new YamlPropertyLoader();
@Override
public void load(final Supplier<Context> context, final LoaderHandler<HmilyServer> handler) {
String filePath = System.getProperty("hmily.conf");
File configFile;
if (StringUtils.isBlank(filePath)) {
String dirPath = getDirGlobal();
configFile = new File(dirPath);
if (configFile.exists()) {
filePath = dirPath;
throw new ConfigException("ConfigLoader:loader config error,error file path:" + filePath);
} else {
//Mainly used for development environment
ClassLoader loader = ConfigLoader.class.getClassLoader();
URL url = loader.getResource("hmily.yml");
if (url != null) {
filePath = url.getFile();
configFile = new File(filePath);
} else {
throw new ConfigException("ConfigLoader:loader config error,error file path:" + filePath);
}
}
} else {
configFile = new File(filePath);
if (!configFile.exists()) {
throw new ConfigException("ConfigLoader:loader config error,error file path:" + filePath);
}
}
try (FileInputStream inputStream = new FileInputStream(configFile)) {
List<PropertyKeySource<?>> propertyKeySources = propertyLoader.load(filePath, inputStream);
OriginalConfigLoader original = new OriginalConfigLoader();
againLoad(() -> context.get().with(propertyKeySources, original), handler, HmilyServer.class);
} catch (IOException e) {
throw new ConfigException("ConfigLoader:loader config error,file path:" + filePath);
}
}
/**
* Get the current project path.
*
* @return Current project path
*/
private String getDirGlobal() {
String userDir = System.getProperty("user.dir");
String fileName = "hmily.yml";
return String.join(String.valueOf(File.separatorChar), userDir, fileName);
}
}

View File

@ -0,0 +1,139 @@
/*
*
* 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.dromara.hmily.config.loader.yaml;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
import org.yaml.snakeyaml.DumperOptions;
import org.yaml.snakeyaml.LoaderOptions;
import org.yaml.snakeyaml.Yaml;
import org.yaml.snakeyaml.constructor.BaseConstructor;
import org.yaml.snakeyaml.constructor.Constructor;
import org.yaml.snakeyaml.nodes.MappingNode;
import org.yaml.snakeyaml.nodes.Node;
import org.yaml.snakeyaml.nodes.NodeTuple;
import org.yaml.snakeyaml.nodes.ScalarNode;
import org.yaml.snakeyaml.nodes.Tag;
import org.yaml.snakeyaml.representer.Representer;
import org.yaml.snakeyaml.resolver.Resolver;
/**
* Class to load {@code .yml} files into a map of {@code String} to
*
* @author xiaoyu
*/
public class OriginTrackedYamlLoader extends YamlProcessor {
private final InputStream resource;
public OriginTrackedYamlLoader(final InputStream resource) {
this.resource = resource;
setResources(resource);
}
@Override
protected Yaml createYaml() {
BaseConstructor constructor = new OriginTrackingConstructor();
Representer representer = new Representer();
DumperOptions dumperOptions = new DumperOptions();
LimitedResolver resolver = new LimitedResolver();
LoaderOptions loaderOptions = new LoaderOptions();
loaderOptions.setAllowDuplicateKeys(false);
return new Yaml(constructor, representer, dumperOptions, loaderOptions, resolver);
}
public List<Map<String, Object>> load() {
final List<Map<String, Object>> result = new ArrayList<>();
process((properties, map) -> result.add(getFlattenedMap(map)));
return result;
}
/**
* {@link Constructor} that tracks property origins.
*/
private static class OriginTrackingConstructor extends Constructor {
@Override
protected Object constructObject(final Node node) {
if (node instanceof ScalarNode) {
if (!(node instanceof KeyScalarNode)) {
return constructTrackedObject(node, super.constructObject(node));
}
} else if (node instanceof MappingNode) {
replaceMappingNodeKeys((MappingNode) node);
}
return super.constructObject(node);
}
private void replaceMappingNodeKeys(final MappingNode node) {
node.setValue(node.getValue().stream().map(KeyScalarNode::get).collect(Collectors.toList()));
}
private Object constructTrackedObject(final Node node, Object value) {
return value;
}
private Object getValue(final Object value) {
return (value != null ? value : "");
}
}
/**
* {@link ScalarNode} that replaces the key node in a {@link NodeTuple}.
*/
private static class KeyScalarNode extends ScalarNode {
public KeyScalarNode(final ScalarNode node) {
super(node.getTag(), true, node.getValue(), node.getStartMark(), node.getEndMark(), node.getStyle());
}
public static NodeTuple get(final NodeTuple nodeTuple) {
Node keyNode = nodeTuple.getKeyNode();
Node valueNode = nodeTuple.getValueNode();
return new NodeTuple(KeyScalarNode.get(keyNode), valueNode);
}
private static Node get(final Node node) {
if (node instanceof ScalarNode) {
return new KeyScalarNode((ScalarNode) node);
}
return node;
}
}
/**
* {@link Resolver} that limits {@link Tag#TIMESTAMP} tags.
*/
private static class LimitedResolver extends Resolver {
@Override
public void addImplicitResolver(final Tag tag, final Pattern regexp, final String first) {
if (tag == Tag.TIMESTAMP) {
return;
}
super.addImplicitResolver(tag, regexp, first);
}
}
}

View File

@ -0,0 +1,380 @@
/*
*
* 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.dromara.hmily.config.loader.yaml;
import java.io.IOException;
import java.io.InputStream;
import java.io.Reader;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.yaml.snakeyaml.LoaderOptions;
import org.yaml.snakeyaml.Yaml;
import org.yaml.snakeyaml.reader.UnicodeReader;
/**
* Base class for YAML factories.
* <p>
* Requires SnakeYAML 1.18 or higher, as of Spring Framework 5.0.6.
* ref: org.springframework.beans.factory.config.YamlProcessor
*
* @author Dave Syer
* @author Juergen Hoeller
* @author xiaoyu
* @since 4.1
*/
public abstract class YamlProcessor {
private ResolutionMethod resolutionMethod = ResolutionMethod.OVERRIDE;
private Logger logger = LoggerFactory.getLogger(YamlProcessor.class);
private List<DocumentMatcher> documentMatchers = Collections.emptyList();
private boolean matchDefault = true;
private InputStream[] resources = new InputStream[0];
/**
* A map of document matchers allowing callers to selectively use only
* some of the documents in a YAML resource. In YAML documents are
* separated by <code>---<code> lines, and each document is converted
* to properties before the match is made. E.g.
* <pre class="code">
* environment: dev
* url: http://dev.bar.com
* name: Developer Setup
* ---
* environment: prod
* url:http://foo.bar.com
* name: My Cool App
* </pre>
* when mapped with
* <pre class="code">
* setDocumentMatchers(properties ->
* ("prod".equals(properties.getProperty("environment")) ? MatchStatus.FOUND : MatchStatus.NOT_FOUND));
* </pre>
* would end up as
* <pre class="code">
* environment=prod
* url=http://foo.bar.com
* name=My Cool App
* </pre>
*/
public void setDocumentMatchers(final DocumentMatcher... matchers) {
this.documentMatchers = Arrays.asList(matchers);
}
/**
* Flag indicating that a document for which all the
* {@link #setDocumentMatchers(DocumentMatcher...) document matchers} abstain will
* nevertheless match. Default is {@code true}.
*/
public void setMatchDefault(final boolean matchDefault) {
this.matchDefault = matchDefault;
}
/**
* Method to use for resolving resources. Each resource will be converted to a Map,
* so this property is used to decide which map entries to keep in the final output
* from this factory. Default is {@link ResolutionMethod#OVERRIDE}.
*/
public void setResolutionMethod(final ResolutionMethod resolutionMethod) {
this.resolutionMethod = resolutionMethod;
}
/**
* Set locations of YAML {@link InputStream resources} to be loaded.
*
* @see ResolutionMethod
*/
public void setResources(final InputStream... resources) {
this.resources = resources;
}
/**
* Provide an opportunity for subclasses to process the Yaml parsed from the supplied
* resources. Each resource is parsed in turn and the documents inside checked against
* the {@link #setDocumentMatchers(DocumentMatcher...) matchers}. If a document
* matches it is passed into the callback, along with its representation as Properties.
* Depending on the {@link #setResolutionMethod(ResolutionMethod)} not all of the
* documents will be parsed.
*
* @param callback a callback to delegate to once matching documents are found
* @see #createYaml()
*/
protected void process(final MatchCallback callback) {
Yaml yaml = createYaml();
for (InputStream resource : this.resources) {
boolean found = process(callback, yaml, resource);
if (this.resolutionMethod == ResolutionMethod.FIRST_FOUND && found) {
return;
}
}
}
/**
* Create the {@link Yaml} instance to use.
* <p>The default implementation sets the "allowDuplicateKeys" flag to {@code false},
* enabling built-in duplicate key handling in SnakeYAML 1.18+.
*
* @see LoaderOptions#setAllowDuplicateKeys(boolean)
*/
protected Yaml createYaml() {
LoaderOptions options = new LoaderOptions();
options.setAllowDuplicateKeys(false);
return new Yaml(options);
}
private boolean process(final MatchCallback callback, final Yaml yaml, final InputStream resource) {
int count = 0;
try {
if (logger.isDebugEnabled()) {
logger.debug("Loading from YAML: " + resource);
}
try (Reader reader = new UnicodeReader(resource)) {
for (Object object : yaml.loadAll(reader)) {
if (object != null && process(asMap(object), callback)) {
count++;
if (this.resolutionMethod == ResolutionMethod.FIRST_FOUND) {
break;
}
}
}
if (logger.isDebugEnabled()) {
logger.debug("Loaded " + count + " document" + (count > 1 ? "s" : "") +
" from YAML resource: " + resource);
}
}
} catch (IOException ex) {
handleProcessError(resource, ex);
}
return (count > 0);
}
private void handleProcessError(final InputStream resource, final IOException ex) {
if (this.resolutionMethod != ResolutionMethod.FIRST_FOUND &&
this.resolutionMethod != ResolutionMethod.OVERRIDE_AND_IGNORE) {
throw new IllegalStateException(ex);
}
if (logger.isWarnEnabled()) {
logger.warn("Could not load map from " + resource + ": " + ex.getMessage());
}
}
@SuppressWarnings("unchecked")
private Map<String, Object> asMap(final Object object) {
// YAML can have numbers as keys
Map<String, Object> result = new LinkedHashMap<>();
if (!(object instanceof Map)) {
// A document can be a text literal
result.put("document", object);
return result;
}
Map<Object, Object> map = (Map<Object, Object>) object;
map.forEach((key, value) -> {
if (value instanceof Map) {
value = asMap(value);
}
if (key instanceof CharSequence) {
result.put(key.toString(), value);
} else {
// It has to be a map key in this case
result.put("[" + key.toString() + "]", value);
}
});
return result;
}
private boolean process(final Map<String, Object> map, final MatchCallback callback) {
Properties properties = new Properties();
properties.putAll(getFlattenedMap(map));
if (this.documentMatchers.isEmpty()) {
if (logger.isDebugEnabled()) {
logger.debug("Merging document (no matchers set): " + map);
}
callback.process(properties, map);
return true;
}
MatchStatus result = MatchStatus.ABSTAIN;
for (DocumentMatcher matcher : this.documentMatchers) {
MatchStatus match = matcher.matches(properties);
result = MatchStatus.getMostSpecific(match, result);
if (match == MatchStatus.FOUND) {
if (logger.isDebugEnabled()) {
logger.debug("Matched document with document matcher: " + properties);
}
callback.process(properties, map);
return true;
}
}
if (result == MatchStatus.ABSTAIN && this.matchDefault) {
if (logger.isDebugEnabled()) {
logger.debug("Matched document with default matcher: " + map);
}
callback.process(properties, map);
return true;
}
if (logger.isDebugEnabled()) {
logger.debug("Unmatched document: " + map);
}
return false;
}
/**
* Return a flattened version of the given map, recursively following any nested Map
* or Collection values. Entries from the resulting map retain the same order as the
* source. When called with the Map from a {@link MatchCallback} the result will
* contain the same values as the {@link MatchCallback} Properties.
*
* @param source the source map
* @return a flattened map
* @since 4.1.3
*/
protected final Map<String, Object> getFlattenedMap(final Map<String, Object> source) {
Map<String, Object> result = new LinkedHashMap<>();
buildFlattenedMap(result, source, null);
return result;
}
private void buildFlattenedMap(final Map<String, Object> result, final Map<String, Object> source, final String path) {
source.forEach((key, value) -> {
if (StringUtils.isNotBlank(path)) {
if (key.startsWith("[")) {
key = path + key;
} else {
key = path + '.' + key;
}
}
if (value instanceof String) {
result.put(key, value);
} else if (value instanceof Map) {
// Need a compound key
@SuppressWarnings("unchecked")
Map<String, Object> map = (Map<String, Object>) value;
buildFlattenedMap(result, map, key);
} else if (value instanceof Collection) {
// Need a compound key
@SuppressWarnings("unchecked")
Collection<Object> collection = (Collection<Object>) value;
if (collection.isEmpty()) {
result.put(key, "");
} else {
int count = 0;
for (Object object : collection) {
buildFlattenedMap(result, Collections.singletonMap(
"[" + (count++) + "]", object), key);
}
}
} else {
result.put(key, (value != null ? value : ""));
}
});
}
/**
* Callback interface used to process the YAML parsing results.
*/
public interface MatchCallback {
/**
* Process the given representation of the parsing results.
*
* @param properties the properties to process (as a flattened
* representation with indexed keys in case of a collection or map)
* @param map the result map (preserving the original value structure
* in the YAML document)
*/
void process(Properties properties, Map<String, Object> map);
}
/**
* Strategy interface used to test if properties match.
*/
public interface DocumentMatcher {
/**
* Test if the given properties match.
*
* @param properties the properties to test
* @return the status of the match
*/
MatchStatus matches(Properties properties);
}
/**
* Status returned from {@link DocumentMatcher#matches(Properties)}
*/
public enum MatchStatus {
/**
* A match was found.
*/
FOUND,
/**
* The matcher should not be considered.
*/
ABSTAIN;
/**
* Compare two {@link MatchStatus} items, returning the most specific status.
*/
public static MatchStatus getMostSpecific(MatchStatus a, MatchStatus b) {
return (a.ordinal() < b.ordinal() ? a : b);
}
}
/**
* Method to use for resolving resources.
*/
public enum ResolutionMethod {
/**
* Replace values from earlier in the list.
*/
OVERRIDE,
/**
* Replace values from earlier in the list, ignoring any failures.
*/
OVERRIDE_AND_IGNORE,
/**
* Take the first resource in the list that exists and use just that.
*/
FIRST_FOUND
}
}

View File

@ -0,0 +1,60 @@
/*
*
* 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.dromara.hmily.config.loader.yaml;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import org.dromara.hmily.config.loader.PropertyLoader;
import org.dromara.hmily.config.loader.property.MapPropertyKeySource;
import org.dromara.hmily.config.loader.property.PropertyKeySource;
/**
* The type Yaml property loader.
*
* @author xiaoyu
*/
public class YamlPropertyLoader implements PropertyLoader {
@Override
public boolean checkFile(final String fileName) {
String fileExtName = fileName.substring(fileName.lastIndexOf("."));
String extName = ".yml";
return extName.equals(fileExtName);
}
@Override
public List<PropertyKeySource<?>> load(final String name, final InputStream resource) {
if (!checkFile(name)) {
return Collections.emptyList();
}
List<Map<String, Object>> loaded = new OriginTrackedYamlLoader(resource).load();
if (loaded.isEmpty()) {
return Collections.emptyList();
}
List<PropertyKeySource<?>> propertySources = new ArrayList<>(loaded.size());
for (int i = 0; i < loaded.size(); i++) {
propertySources.add(new MapPropertyKeySource(name + (loaded.size() != 1 ? " (document #" + i + ")" : ""), loaded.get(i)));
}
return propertySources;
}
}

View File

@ -0,0 +1,111 @@
/*
*
* 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.dromara.hmily.config.loader.bind;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import lombok.Data;
import org.dromara.hmily.config.loader.property.ConfigPropertySource;
import org.dromara.hmily.config.loader.property.DefaultConfigPropertySource;
import org.dromara.hmily.config.loader.property.MapPropertyKeySource;
import org.dromara.hmily.config.loader.property.PropertyKeyParse;
import org.dromara.hmily.config.loader.property.PropertyKeySource;
import org.junit.Assert;
import org.junit.Test;
public final class CollectionBinderTest {
@Test
public void testArrayList() {
String name = "hmily.yml";
Map<String, Object> map = new HashMap<>();
map.put("hmily.list[0]", 123);
map.put("hmily.list[1]", 234);
PropertyKeySource<?> propertySource = new MapPropertyKeySource(name, map);
ConfigPropertySource configPropertySource = new DefaultConfigPropertySource<>(propertySource, PropertyKeyParse.INSTANCE);
Binder binder = Binder.of(configPropertySource);
BindData<CollectionPojo> data = BindData.of(DataType.of(CollectionPojo.class), CollectionPojo::new);
CollectionPojo bind = binder.bind("hmily", data);
Assert.assertEquals(bind.getList().get(0), 123);
Assert.assertEquals(bind.getList().get(1), 234);
}
@Test
public void testNotSetArrayList() {
String name = "hmily.yml";
Map<String, Object> map = new HashMap<>();
map.put("hmily.list[0]", 123);
map.put("hmily.list[1]", 234);
PropertyKeySource<?> propertySource = new MapPropertyKeySource(name, map);
ConfigPropertySource configPropertySource = new DefaultConfigPropertySource<>(propertySource, PropertyKeyParse.INSTANCE);
Binder binder = Binder.of(configPropertySource);
BindData<CollectionPojo2> data = BindData.of(DataType.of(CollectionPojo2.class), CollectionPojo2::new);
CollectionPojo2 bind = binder.bind("hmily", data);
Assert.assertNull(bind);
}
@Test
public void testListGeneric() {
String name = "hmily.yml";
Map<String, Object> map = new HashMap<>();
map.put("hmily.list2[0]", "123");
map.put("hmily.list2[1]", 234);
PropertyKeySource<?> propertySource = new MapPropertyKeySource(name, map);
ConfigPropertySource configPropertySource = new DefaultConfigPropertySource<>(propertySource, PropertyKeyParse.INSTANCE);
Binder binder = Binder.of(configPropertySource);
BindData<CollectionPojo> data = BindData.of(DataType.of(CollectionPojo.class), CollectionPojo::new);
CollectionPojo bind = binder.bind("hmily", data);
Assert.assertEquals(bind.getList2().get(0), Integer.valueOf(123));
Assert.assertEquals(bind.getList2().get(1), Integer.valueOf(234));
}
@Test
public void testArray() {
String name = "hmily.yml";
Map<String, Object> map = new HashMap<>();
map.put("hmily.intArray[0]", 123);
map.put("hmily.intArray[1]", 234);
PropertyKeySource<?> propertySource = new MapPropertyKeySource(name, map);
ConfigPropertySource configPropertySource = new DefaultConfigPropertySource<>(propertySource, PropertyKeyParse.INSTANCE);
Binder binder = Binder.of(configPropertySource);
BindData<CollectionPojo> data = BindData.of(DataType.of(CollectionPojo.class), CollectionPojo::new);
CollectionPojo bind = binder.bind("hmily", data);
Assert.assertEquals(bind.getIntArray()[0], Integer.valueOf(123));
Assert.assertEquals(bind.getIntArray()[1], Integer.valueOf(234));
}
@Data
public static class CollectionPojo {
private List list;
private List<Integer> list2;
private Integer[] intArray;
}
@Data
public static class CollectionPojo2 {
private List list;
}
}

View File

@ -0,0 +1,100 @@
/*
*
* 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.dromara.hmily.config.loader.bind;
import java.util.HashMap;
import java.util.Map;
import lombok.Data;
import org.dromara.hmily.config.loader.property.ConfigPropertySource;
import org.dromara.hmily.config.loader.property.DefaultConfigPropertySource;
import org.dromara.hmily.config.loader.property.MapPropertyKeySource;
import org.dromara.hmily.config.loader.property.PropertyKeyParse;
import org.dromara.hmily.config.loader.property.PropertyKeySource;
import org.junit.Assert;
import org.junit.Test;
@Data
public class JavaBeanBinderTest {
private String stringTest;
private Integer integerTest;
private Double doubleTest;
private Long longTest;
private Character chartTest;
private Float floatTest;
private Boolean boolTest;
@Test
public void testJavaBeanBind() {
String name = "hmily.yml";
Map<String, Object> map = new HashMap<>();
map.put("hmily.stringTest", "123");
map.put("hmily.integerTest", 456);
map.put("hmily.doubleTest", 42.12);
map.put("hmily.longTest", 100L);
map.put("hmily.chartTest", 'a');
map.put("hmily.floatTest", 12.1F);
map.put("hmily.boolTest", true);
PropertyKeySource<?> propertySource = new MapPropertyKeySource(name, map);
ConfigPropertySource configPropertySource = new DefaultConfigPropertySource<>(propertySource, PropertyKeyParse.INSTANCE);
Binder binder = Binder.of(configPropertySource);
BindData<JavaBeanBinderTest> data = BindData.of(DataType.of(JavaBeanBinderTest.class), JavaBeanBinderTest::new);
JavaBeanBinderTest bind = binder.bind("hmily", data);
Assert.assertEquals(map.get("hmily.stringTest"), bind.getStringTest());
Assert.assertEquals(map.get("hmily.integerTest"), bind.getIntegerTest());
Assert.assertEquals(map.get("hmily.doubleTest"), bind.getDoubleTest());
Assert.assertEquals(map.get("hmily.chartTest"), bind.getChartTest());
Assert.assertEquals(map.get("hmily.longTest"), bind.getLongTest());
Assert.assertEquals(map.get("hmily.floatTest"), bind.getFloatTest());
Assert.assertEquals(map.get("hmily.boolTest"), bind.getBoolTest());
}
@Test
public void testJavaBeanBindParse() {
String name = "hmily.yml";
Map<String, Object> map = new HashMap<>();
map.put("hmily.stringTest", 123);
map.put("hmily.integerTest", "123");
map.put("hmily.doubleTest", "123");
map.put("hmily.longTest", "123");
map.put("hmily.chartTest", "A");
map.put("hmily.floatTest", "123");
map.put("hmily.boolTest", "true");
PropertyKeySource<?> propertySource = new MapPropertyKeySource(name, map);
ConfigPropertySource configPropertySource = new DefaultConfigPropertySource<>(propertySource, PropertyKeyParse.INSTANCE);
Binder binder = Binder.of(configPropertySource);
BindData<JavaBeanBinderTest> data = BindData.of(DataType.of(JavaBeanBinderTest.class), JavaBeanBinderTest::new);
JavaBeanBinderTest bind = binder.bind("hmily", data);
Assert.assertEquals("123", bind.getStringTest());
Assert.assertEquals(Integer.valueOf(123), bind.getIntegerTest());
Assert.assertEquals(Double.valueOf(123), bind.getDoubleTest());
Assert.assertEquals(Character.valueOf('A'), bind.getChartTest());
Assert.assertEquals(Long.valueOf(123), bind.getLongTest());
Assert.assertEquals(Float.valueOf(123), bind.getFloatTest());
Assert.assertEquals(Boolean.TRUE, bind.getBoolTest());
}
}

View File

@ -0,0 +1,74 @@
/*
*
* 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.dromara.hmily.config.loader.bind;
import java.util.HashMap;
import java.util.Map;
import lombok.Data;
import org.dromara.hmily.config.loader.property.ConfigPropertySource;
import org.dromara.hmily.config.loader.property.DefaultConfigPropertySource;
import org.dromara.hmily.config.loader.property.MapPropertyKeySource;
import org.dromara.hmily.config.loader.property.PropertyKeyParse;
import org.dromara.hmily.config.loader.property.PropertyKeySource;
import org.junit.Assert;
import org.junit.Test;
public class MapBinderTest {
@Test
public void testMap() {
String name = "hmily.yml";
Map<String, Object> map = new HashMap<>();
map.put("hmily.map.userName", "sixh");
map.put("hmily.map.passWord", 123456);
PropertyKeySource<?> propertySource = new MapPropertyKeySource(name, map);
ConfigPropertySource configPropertySource = new DefaultConfigPropertySource<>(propertySource, PropertyKeyParse.INSTANCE);
Binder binder = Binder.of(configPropertySource);
BindData<MapPojo> data = BindData.of(DataType.of(MapPojo.class), MapPojo::new);
MapPojo bind = binder.bind("hmily", data);
Assert.assertEquals(bind.getMap().get("userName"), map.get("hmily.map.userName"));
Assert.assertEquals(bind.getMap().get("passWord"), map.get("hmily.map.passWord"));
System.out.println(bind);
}
@Test
public void testMapGeneric() {
String name = "hmily.yml";
Map<String, Object> map = new HashMap<>();
map.put("hmily.map2.userName", "456");
map.put("hmily.map2.passWord", 123456);
PropertyKeySource<?> propertySource = new MapPropertyKeySource(name, map);
ConfigPropertySource configPropertySource = new DefaultConfigPropertySource<>(propertySource, PropertyKeyParse.INSTANCE);
Binder binder = Binder.of(configPropertySource);
BindData<MapPojo> data = BindData.of(DataType.of(MapPojo.class), MapPojo::new);
MapPojo bind = binder.bind("hmily", data);
Assert.assertEquals(bind.getMap2().get("userName"), Integer.valueOf(456));
Assert.assertEquals(bind.getMap2().get("passWord"), map.get("hmily.map2.passWord"));
System.out.println(bind);
}
@Data
public static class MapPojo {
private Map map;
private Map<String,Integer> map2;
}
}

View File

@ -20,13 +20,20 @@
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>hmily-config</artifactId>
<groupId>org.dromara</groupId>
<artifactId>hmily-config</artifactId>
<version>2.1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>hmily-config-local</artifactId>
<dependencies>
<dependency>
<groupId>org.dromara</groupId>
<artifactId>hmily-config-loader</artifactId>
<version>${project.version}</version>
</dependency>
</dependencies>
</project>

View File

@ -0,0 +1,42 @@
/*
*
* 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.dromara.hmily.config.local;
import java.util.function.Supplier;
import org.dromara.hmily.config.api.Config;
import org.dromara.hmily.config.loader.ConfigLoader;
import org.dromara.hmily.spi.HmilySPI;
/**
* LocalConfigLoader .
* Loading local yml file processing.
*
* @author xiaoyu
*/
@HmilySPI("local")
public class LocalConfigLoader implements ConfigLoader<Config> {
@Override
public void load(final Supplier<Context> context, final LoaderHandler<Config> handler) {
ConfigLoader<Config> original = context.get().getOriginal();
original.load(context, handler);
}
}

View File

@ -0,0 +1 @@
org.dromara.hmily.config.local.LocalConfigLoader

View File

@ -0,0 +1,56 @@
/*
*
* 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.dromara.hmily.config.local;
import org.apache.commons.lang3.StringUtils;
import org.dromara.hmily.config.api.ConfigEnv;
import org.dromara.hmily.config.api.ConfigScan;
import org.dromara.hmily.config.api.entity.HmilyConfig;
import org.dromara.hmily.config.api.entity.HmilyServer;
import org.dromara.hmily.config.loader.ConfigLoader;
import org.dromara.hmily.config.loader.ServerConfigLoader;
import org.junit.Test;
/**
* Created by apa7 on 2019/10/10.
*/
public final class LocalConfigLoaderTest {
@Test
public void load() {
ConfigScan.scan();
ServerConfigLoader loader = new ServerConfigLoader();
loader.load(ConfigLoader.Context::new, (context, config) -> {
System.out.println("config:---->" + config);
if (config != null) {
if (StringUtils.isNotBlank(config.getConfigMode())) {
String configMode = config.getConfigMode();
if (configMode.equals("local")) {
new LocalConfigLoader().load(context, (context1, config1) -> System.out.println("config1:-->" + config1));
}
}
}
});
HmilyServer server = ConfigEnv.getInstance().getConfig(HmilyServer.class);
HmilyConfig config = ConfigEnv.getInstance().getConfig(HmilyConfig.class);
System.out.println(server);
System.out.println(config);
}
}

View File

@ -0,0 +1,11 @@
hmily:
server:
configMode: local
appName: xiaoyu
# 如果server.mode eq local 的时候才会读取到这里的配置信息.
config:
serializer: kryo
contextTransmittalMode: threadLocal
scheduledRecoveryDelay: 120
limit : 200

View File

@ -29,7 +29,7 @@ public final class TransactionTotalCounterMetricsTracker implements CounterMetri
private static final Counter TRANSACTION_TOTAL = Counter.build()
.name("transaction_total")
.labelNames("type")
.help("soul request total count")
.help("hmily request total count")
.register();
@Override

18
pom.xml
View File

@ -622,6 +622,24 @@
</instrumentation>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-enforcer-plugin</artifactId>
<version>1.3.1</version>
<executions>
<execution>
<id>enforce</id>
<configuration>
<rules>
<DependencyConvergence />
</rules>
</configuration>
<goals>
<goal>enforce</goal>
</goals>
</execution>
</executions>
</plugin>
<!-- <plugin>-->
<!-- <groupId>org.apache.maven.plugins</groupId>-->
<!-- <artifactId>maven-checkstyle-plugin</artifactId>-->