Commit 745a83e3 by 房斌

增加 monitor监控组件

parent b04cca81
......@@ -5,7 +5,7 @@
<parent>
<artifactId>matrix</artifactId>
<groupId>com.secoo.mall</groupId>
<version>2.0.8.RELEASE</version>
<version>2.0.9-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
......
......@@ -5,7 +5,7 @@
<parent>
<artifactId>matrix</artifactId>
<groupId>com.secoo.mall</groupId>
<version>2.0.8.RELEASE</version>
<version>2.0.9-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
......
......@@ -5,7 +5,7 @@
<parent>
<artifactId>matrix</artifactId>
<groupId>com.secoo.mall</groupId>
<version>2.0.8.RELEASE</version>
<version>2.0.9-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
......
......@@ -5,7 +5,7 @@
<parent>
<artifactId>matrix</artifactId>
<groupId>com.secoo.mall</groupId>
<version>2.0.8.RELEASE</version>
<version>2.0.9-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
......
......@@ -5,7 +5,7 @@
<parent>
<artifactId>matrix-bigdata</artifactId>
<groupId>com.secoo.mall</groupId>
<version>2.0.8.RELEASE</version>
<version>2.0.9-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
......
......@@ -5,7 +5,7 @@
<parent>
<artifactId>matrix-bigdata</artifactId>
<groupId>com.secoo.mall</groupId>
<version>2.0.8.RELEASE</version>
<version>2.0.9-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
......
......@@ -5,7 +5,7 @@
<parent>
<artifactId>matrix</artifactId>
<groupId>com.secoo.mall</groupId>
<version>2.0.8.RELEASE</version>
<version>2.0.9-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
......
......@@ -5,7 +5,7 @@
<parent>
<artifactId>matrix-bus</artifactId>
<groupId>com.secoo.mall</groupId>
<version>2.0.8.RELEASE</version>
<version>2.0.9-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
......
......@@ -5,7 +5,7 @@
<parent>
<artifactId>matrix</artifactId>
<groupId>com.secoo.mall</groupId>
<version>2.0.8.RELEASE</version>
<version>2.0.9-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
......
......@@ -5,7 +5,7 @@
<parent>
<artifactId>matrix-client</artifactId>
<groupId>com.secoo.mall</groupId>
<version>2.0.8.RELEASE</version>
<version>2.0.9-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
......
......@@ -5,7 +5,7 @@
<parent>
<artifactId>matrix</artifactId>
<groupId>com.secoo.mall</groupId>
<version>2.0.8.RELEASE</version>
<version>2.0.9-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
......
......@@ -5,7 +5,7 @@
<parent>
<artifactId>matrix-datahelper</artifactId>
<groupId>com.secoo.mall</groupId>
<version>2.0.8.RELEASE</version>
<version>2.0.9-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
......
......@@ -5,7 +5,7 @@
<parent>
<artifactId>matrix-datahelper</artifactId>
<groupId>com.secoo.mall</groupId>
<version>2.0.8.RELEASE</version>
<version>2.0.9-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
......
......@@ -5,7 +5,7 @@
<parent>
<artifactId>matrix</artifactId>
<groupId>com.secoo.mall</groupId>
<version>2.0.8.RELEASE</version>
<version>2.0.9-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
......@@ -21,7 +21,7 @@
<dependency>
<groupId>com.secoo.mall</groupId>
<artifactId>matrix-datahelper-redis-core</artifactId>
<version>2.0.8.RELEASE</version>
<version>2.0.9-SNAPSHOT</version>
</dependency>
</dependencies>
</dependencyManagement>
......
......@@ -5,7 +5,7 @@
<parent>
<artifactId>matrix-datasource</artifactId>
<groupId>com.secoo.mall</groupId>
<version>2.0.8.RELEASE</version>
<version>2.0.9-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
......
......@@ -5,7 +5,7 @@
<parent>
<artifactId>matrix-datasource</artifactId>
<groupId>com.secoo.mall</groupId>
<version>2.0.8.RELEASE</version>
<version>2.0.9-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
......
......@@ -5,7 +5,7 @@
<parent>
<artifactId>matrix</artifactId>
<groupId>com.secoo.mall</groupId>
<version>2.0.8.RELEASE</version>
<version>2.0.9-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
......@@ -21,7 +21,7 @@
<dependency>
<groupId>com.secoo.mall</groupId>
<artifactId>matrix-datasource-core</artifactId>
<version>2.0.8.RELEASE</version>
<version>2.0.9-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
......
......@@ -5,7 +5,7 @@
<parent>
<artifactId>matrix-job</artifactId>
<groupId>com.secoo.mall</groupId>
<version>2.0.8.RELEASE</version>
<version>2.0.9-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
......
......@@ -5,7 +5,7 @@
<parent>
<artifactId>matrix-job</artifactId>
<groupId>com.secoo.mall</groupId>
<version>2.0.8.RELEASE</version>
<version>2.0.9-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
......
......@@ -5,7 +5,7 @@
<parent>
<artifactId>matrix-job</artifactId>
<groupId>com.secoo.mall</groupId>
<version>2.0.8.RELEASE</version>
<version>2.0.9-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
......
......@@ -5,7 +5,7 @@
<parent>
<artifactId>matrix</artifactId>
<groupId>com.secoo.mall</groupId>
<version>2.0.8.RELEASE</version>
<version>2.0.9-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
......@@ -21,12 +21,12 @@
<dependency>
<groupId>com.secoo.mall</groupId>
<artifactId>matrix-job-core</artifactId>
<version>2.0.8.RELEASE</version>
<version>2.0.9-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>com.secoo.mall</groupId>
<artifactId>matrix-job-xxl-core</artifactId>
<version>2.0.8.RELEASE</version>
<version>2.0.9-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>com.secoo</groupId>
......
......@@ -5,7 +5,7 @@
<parent>
<artifactId>matrix-mq</artifactId>
<groupId>com.secoo.mall</groupId>
<version>2.0.8.RELEASE</version>
<version>2.0.9-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
......
......@@ -5,7 +5,7 @@
<parent>
<artifactId>matrix-mq</artifactId>
<groupId>com.secoo.mall</groupId>
<version>2.0.8.RELEASE</version>
<version>2.0.9-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
......
......@@ -5,7 +5,7 @@
<parent>
<artifactId>matrix-mq</artifactId>
<groupId>com.secoo.mall</groupId>
<version>2.0.8.RELEASE</version>
<version>2.0.9-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
......
......@@ -5,7 +5,7 @@
<parent>
<artifactId>matrix</artifactId>
<groupId>com.secoo.mall</groupId>
<version>2.0.8.RELEASE</version>
<version>2.0.9-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
......@@ -27,7 +27,7 @@
<dependency>
<groupId>com.secoo.mall</groupId>
<artifactId>matrix-mq-rocketmq-core</artifactId>
<version>2.0.8.RELEASE</version>
<version>2.0.9-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.apache.rocketmq</groupId>
......
......@@ -5,7 +5,7 @@
<parent>
<artifactId>matrix-mybatis</artifactId>
<groupId>com.secoo.mall</groupId>
<version>2.0.8.RELEASE</version>
<version>2.0.9-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
......
......@@ -5,7 +5,7 @@
<parent>
<artifactId>matrix-mybatis</artifactId>
<groupId>com.secoo.mall</groupId>
<version>2.0.8.RELEASE</version>
<version>2.0.9-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
......
......@@ -5,7 +5,7 @@
<parent>
<artifactId>matrix</artifactId>
<groupId>com.secoo.mall</groupId>
<version>2.0.8.RELEASE</version>
<version>2.0.9-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
......@@ -25,17 +25,17 @@
<dependency>
<groupId>com.secoo.mall</groupId>
<artifactId>matrix-mybatis-core</artifactId>
<version>2.0.8.RELEASE</version>
<version>2.0.9-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>com.secoo.mall</groupId>
<artifactId>matrix-datasource-druid</artifactId>
<version>2.0.8.RELEASE</version>
<version>2.0.9-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>com.secoo.mall</groupId>
<artifactId>matrix-mybatis-starter</artifactId>
<version>2.0.8.RELEASE</version>
<version>2.0.9-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
......
......@@ -5,7 +5,7 @@
<parent>
<artifactId>matrix-protocol</artifactId>
<groupId>com.secoo.mall</groupId>
<version>2.0.8.RELEASE</version>
<version>2.0.9-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
......
......@@ -5,7 +5,7 @@
<parent>
<artifactId>matrix-protocol</artifactId>
<groupId>com.secoo.mall</groupId>
<version>2.0.8.RELEASE</version>
<version>2.0.9-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
......@@ -35,6 +35,21 @@
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-commons</artifactId>
<version>2.1.6.RELEASE</version>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpmime</artifactId>
</dependency>
</dependencies>
</project>
\ No newline at end of file
/*
* 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 com.secoo.mall.dubbo.monitor.config;
import com.secoo.mall.dubbo.monitor.dubbo.Constants.Constants;
import com.secoo.mall.dubbo.monitor.dubbo.exception.ConfigurationException;
import com.secoo.mall.dubbo.monitor.dubbo.metadata.MetaDataCollector;
import com.secoo.mall.dubbo.monitor.dubbo.metadata.impl.NoOpMetadataCollector;
import com.secoo.mall.dubbo.monitor.dubbo.register.GovernanceConfiguration;
import org.apache.commons.lang3.StringUtils;
import org.apache.dubbo.common.URL;
import org.apache.dubbo.common.extension.ExtensionLoader;
import org.apache.dubbo.common.logger.Logger;
import org.apache.dubbo.common.logger.LoggerFactory;
import org.apache.dubbo.registry.Registry;
import org.apache.dubbo.registry.RegistryFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.DependsOn;
import java.util.Arrays;
import static org.apache.dubbo.common.constants.CommonConstants.CLUSTER_KEY;
@Configuration
public class ConfigCenter {
//centers in dubbo 2.7
@Value("${admin.config-center:}")
private String configCenter;
@Value("${admin.registry.address:}")
private String registryAddress;
@Value("${admin.metadata-report.address:}")
private String metadataAddress;
@Value("${admin.metadata-report.cluster:false}")
private boolean cluster;
@Value("${admin.registry.group:dubbo}")
private String registryGroup;
@Value("${admin.config-center.group:dubbo}")
private String configCenterGroup;
@Value("${admin.metadata-report.group:dubbo}")
private String metadataGroup;
@Value("${admin.config-center.username:}")
private String username;
@Value("${admin.config-center.password:}")
private String password;
private static final Logger logger = LoggerFactory.getLogger(ConfigCenter.class);
private URL configCenterUrl;
private URL registryUrl;
private URL metadataUrl;
/*
* generate dynamic configuration client
*/
@Bean("governanceConfiguration")
GovernanceConfiguration getDynamicConfiguration() {
GovernanceConfiguration dynamicConfiguration = null;
if (StringUtils.isNotEmpty(configCenter)) {
configCenterUrl = formUrl(configCenter, configCenterGroup, username, password);
dynamicConfiguration = ExtensionLoader.getExtensionLoader(GovernanceConfiguration.class).getExtension(configCenterUrl.getProtocol());
dynamicConfiguration.setUrl(configCenterUrl);
dynamicConfiguration.init();
String config = dynamicConfiguration.getConfig(Constants.GLOBAL_CONFIG_PATH);
if (StringUtils.isNotEmpty(config)) {
Arrays.stream(config.split("\n")).forEach( s -> {
if(s.startsWith(Constants.REGISTRY_ADDRESS)) {
String registryAddress = s.split("=")[1].trim();
registryUrl = formUrl(registryAddress, configCenterGroup, username, password);
} else if (s.startsWith(Constants.METADATA_ADDRESS)) {
metadataUrl = formUrl(s.split("=")[1].trim(), configCenterGroup, username, password);
}
});
}
}
if (dynamicConfiguration == null) {
if (StringUtils.isNotEmpty(registryAddress)) {
registryUrl = formUrl(registryAddress, registryGroup, username, password);
dynamicConfiguration = ExtensionLoader.getExtensionLoader(GovernanceConfiguration.class).getExtension(registryUrl.getProtocol());
dynamicConfiguration.setUrl(registryUrl);
dynamicConfiguration.init();
logger.warn("you are using dubbo.registry.address, which is not recommend, please refer to: https://github.com/apache/incubator-dubbo-admin/wiki/Dubbo-Admin-configuration");
} else {
throw new ConfigurationException("Either config center or registry address is needed, please refer to https://github.com/apache/incubator-dubbo-admin/wiki/Dubbo-Admin-configuration");
//throw exception
}
}
return dynamicConfiguration;
}
/*
* generate registry client
*/
@Bean
@DependsOn("governanceConfiguration")
Registry getRegistry() {
Registry registry = null;
if (registryUrl == null) {
if (StringUtils.isBlank(registryAddress)) {
throw new ConfigurationException("Either config center or registry address is needed, please refer to https://github.com/apache/incubator-dubbo-admin/wiki/Dubbo-Admin-configuration");
}
registryUrl = formUrl(registryAddress, registryGroup, username, password);
}
RegistryFactory registryFactory = ExtensionLoader.getExtensionLoader(RegistryFactory.class).getAdaptiveExtension();
registry = registryFactory.getRegistry(registryUrl);
return registry;
}
/*
* generate metadata client
*/
@Bean
@DependsOn("governanceConfiguration")
MetaDataCollector getMetadataCollector() {
MetaDataCollector metaDataCollector = new NoOpMetadataCollector();
if (metadataUrl == null) {
if (StringUtils.isNotEmpty(metadataAddress)) {
metadataUrl = formUrl(metadataAddress, metadataGroup, username, password);
metadataUrl = metadataUrl.addParameter(CLUSTER_KEY, cluster);
}
}
if (metadataUrl != null) {
metaDataCollector = ExtensionLoader.getExtensionLoader(MetaDataCollector.class).getExtension(metadataUrl.getProtocol());
metaDataCollector.setUrl(metadataUrl);
metaDataCollector.init();
} else {
logger.warn("you are using dubbo.registry.address, which is not recommend, please refer to: https://github.com/apache/incubator-dubbo-admin/wiki/Dubbo-Admin-configuration");
}
return metaDataCollector;
}
private URL formUrl(String config, String group, String username, String password) {
URL url = URL.valueOf(config);
if (StringUtils.isNotEmpty(group)) {
url = url.addParameter(Constants.GROUP_KEY, group);
}
if (StringUtils.isNotEmpty(username)) {
url = url.setUsername(username);
}
if (StringUtils.isNotEmpty(password)) {
url = url.setPassword(password);
}
return url;
}
}
/*
* 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 com.secoo.mall.dubbo.monitor.dubbo.Constants;
import java.util.HashSet;
import java.util.Set;
public class Constants {
public static final String REGISTRY_ADDRESS = "dubbo.registry.address";
public static final String METADATA_ADDRESS = "dubbo.metadata-report.address";
public static final String DEFAULT_ROOT = "dubbo";
public static final String PATH_SEPARATOR = "/";
public static final String GROUP_KEY = "group";
public static final String CONFIG_KEY = "config" + PATH_SEPARATOR + "dubbo";
public static final String DUBBO_PROPERTY = "dubbo.properties";
public static final String PROVIDER_SIDE = "provider";
public static final String CONSUMER_SIDE = "consumer";
public static final String CATEGORY_KEY = "category";
public static final String ROUTERS_CATEGORY = "routers";
public static final String CONDITION_ROUTE = "condition_route";
public static final String CONDITION_RULE_SUFFIX = ".condition-router";
public static final String CONFIGURATOR = "configurators";
public static final String CONFIGURATOR_RULE_SUFFIX = ".configurators";
public static final String TAG_ROUTE = "tag_route";
public static final String TAG_RULE_SUFFIX = ".tag-router";
public static final String COMPATIBLE_CONFIG = "compatible_config";
public static final String WEIGHT = "weight";
public static final String BALANCING = "balancing";
public static final String SERVICE = "service";
public static final String APPLICATION = "application";
public static final String PUNCTUATION_POINT = ".";
public static final String PUNCTUATION_SEPARATOR_POINT = "\\.";
public static final String INTERROGATION_POINT = "?";
public static final String ANY_VALUE = "*";
public static final String PLUS_SIGNS = "+";
public static final String IP = "ip";
public static final String INTERFACE_KEY = "interface";
public static final String DYNAMIC_KEY = "dynamic";
public static final String CONSUMER_PROTOCOL = "consumer";
public static final String PROVIDER_PROTOCOL = "provider";
public static final String ROUTE_PROTOCOL = "route";
public static final String APPLICATION_KEY = "application";
public static final String ENABLED_KEY = "enabled";
public static final String RULE_KEY = "rule";
public static final String ANYHOST_VALUE = "0.0.0.0";
public static final String OVERRIDE_PROTOCOL = "override";
public static final String CONFIGURATORS_CATEGORY = "configurators";
public static final String EMPTY_PROTOCOL = "empty";
public static final String WEIGHT_KEY = "weight";
public static final int DEFAULT_WEIGHT = 100;
public static final String ADMIN_PROTOCOL = "admin";
public static final String CLASSIFIER_KEY = "classifier";
public static final String CHECK_KEY = "check";
public static final String VERSION_KEY = "version";
public static final String PROVIDERS_CATEGORY = "providers";
public static final String CONSUMERS_CATEGORY = "consumers";
public static final String SPECIFICATION_VERSION_KEY = "release";
public static final String GLOBAL_CONFIG = "global";
public static final String GLOBAL_CONFIG_PATH = "config/dubbo/dubbo.properties";
public static final String METRICS_PORT = "metrics.port";
public static final String METRICS_PROTOCOL = "metrics.protocol";
public static final Set<String> CONFIGS = new HashSet<>();
static {
CONFIGS.add(WEIGHT);
CONFIGS.add(BALANCING);
}
}
/*
* 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 com.secoo.mall.dubbo.monitor.dubbo.domain;
import java.io.Serializable;
import java.util.Date;
import java.util.List;
/**
* Entity
*
*/
public abstract class Entity implements Serializable {
private static final long serialVersionUID = -3031128781434583143L;
private List<Long> ids;
private Long id;
private String hash;
private Date created;
private Date modified;
private Date now;
private String operator;
private String operatorAddress;
private boolean miss;
public Entity() {
}
public Entity(Long id) {
this.id = id;
}
public List<Long> getIds() {
return ids;
}
public void setIds(List<Long> ids) {
this.ids = ids;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getHash() {
return hash;
}
public void setHash(String hash) {
this.hash = hash;
}
public Date getCreated() {
return created;
}
public void setCreated(Date created) {
this.created = created;
}
public Date getModified() {
return modified;
}
public void setModified(Date modified) {
this.modified = modified;
}
public Date getNow() {
return now;
}
public void setNow(Date now) {
this.now = now;
}
public String getOperator() {
return operator;
}
public void setOperator(String operator) {
if (operator != null && operator.length() > 200) {
operator = operator.substring(0, 200);
}
this.operator = operator;
}
public String getOperatorAddress() {
return operatorAddress;
}
public void setOperatorAddress(String operatorAddress) {
this.operatorAddress = operatorAddress;
}
public boolean isMiss() {
return miss;
}
public void setMiss(boolean miss) {
this.miss = miss;
}
}
/*
* 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 com.secoo.mall.dubbo.monitor.dubbo.domain;
import com.secoo.mall.dubbo.monitor.dubbo.Constants.Constants;
import com.secoo.mall.dubbo.monitor.utils.ConvertUtil;
import org.apache.dubbo.common.URL;
import java.util.Date;
import java.util.List;
import java.util.Map;
/**
* Provider
*
*/
public class Provider extends Entity {
private static final long serialVersionUID = 5981342400350878171L;
private String service;/* The name of the service provided by the provider */
private String url; /* Provider's address for service */
private String parameters; /* Provider provides service parameters */
private String address; /* Provider address */
private String registry;/* The provider's registry address */
private boolean dynamic; /* provider was registered dynamically */
private boolean enabled; /* provider enabled or not */
private int weight; /* provider weight */
private String application; /* application name */
private String username; /* operator */
private Date expired; /* time to expire */
private long alived; /* time to live in milliseconds */
private Override override;
private List<Override> overrides;
public Provider() {
}
public Provider(Long id) {
super(id);
}
public String getService() {
return service;
}
public void setService(String service) {
this.service = service;
}
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
public String getParameters() {
return parameters;
}
public void setParameters(String parameters) {
this.parameters = parameters;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public String getRegistry() {
return registry;
}
public void setRegistry(String registry) {
this.registry = registry;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getApplication() {
return application;
}
public void setApplication(String application) {
this.application = application;
}
public boolean isDynamic() {
return dynamic;
}
public void setDynamic(boolean dynamic) {
this.dynamic = dynamic;
}
public boolean isEnabled() {
return enabled;
}
public void setEnabled(boolean enabled) {
this.enabled = enabled;
}
public Date getExpired() {
return expired;
}
public void setExpired(Date expired) {
this.expired = expired;
}
public long getAlived() {
return alived;
}
public void setAlived(long aliveSeconds) {
this.alived = aliveSeconds;
}
public int getWeight() {
return weight;
}
public void setWeight(int weight) {
this.weight = weight;
}
public Override getOverride() {
return override;
}
public void setOverride(Override override) {
this.override = override;
}
public List<Override> getOverrides() {
return overrides;
}
public void setOverrides(List<Override> overrides) {
this.overrides = overrides;
}
public URL toUrl() {
Map<String, String> serviceName2Map = ConvertUtil.serviceName2Map(getService());
/*if(!serviceName2Map.containsKey(Constants.INTERFACE_KEY)) {
throw new IllegalArgumentException("No interface info");
}
if(!serviceName2Map.containsKey(Constants.VERSION_KEY)) {
throw new IllegalArgumentException("No version info");
}*/
String u = getUrl();
URL url = URL.valueOf(u + "?" + getParameters());
url = url.addParameters(serviceName2Map);
boolean dynamic = isDynamic();
if (!dynamic) {
url = url.addParameter(Constants.DYNAMIC_KEY, false);
}
boolean enabled = isEnabled();
if (enabled != url.getParameter("enabled", true)) {
if (enabled) {
url = url.removeParameter("enabled");
} else {
url = url.addParameter("enabled", false);
}
}
return url;
}
}
/*
* 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 com.secoo.mall.dubbo.monitor.dubbo.exception;
public class ConfigurationException extends RuntimeException{
public ConfigurationException(String message) {
super(message);
}
}
/*
* 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 com.secoo.mall.dubbo.monitor.dubbo.exception;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.ResponseStatus;
/**
* Parameter validation failure exception
*/
@ResponseStatus(value = HttpStatus.BAD_REQUEST)
public class ParamValidationException extends SystemException {
public ParamValidationException(String message) {
super(message);
}
}
/*
* 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 com.secoo.mall.dubbo.monitor.dubbo.exception;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.ResponseStatus;
/**
* System Exception
*/
@ResponseStatus(value = HttpStatus.INTERNAL_SERVER_ERROR)
public class SystemException extends RuntimeException {
public SystemException() {
super();
}
public SystemException(String message) {
super(message);
}
public SystemException(String message, Throwable cause) {
super(message, cause);
}
public SystemException(Throwable cause) {
super(cause);
}
}
/*
* 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 com.secoo.mall.dubbo.monitor.dubbo.metadata;
import org.apache.dubbo.common.URL;
import org.apache.dubbo.common.extension.SPI;
import org.apache.dubbo.metadata.identifier.MetadataIdentifier;
@SPI("zookeeper")
public interface MetaDataCollector {
void setUrl(URL url);
URL getUrl();
void init();
String getProviderMetaData(MetadataIdentifier key);
String getConsumerMetaData(MetadataIdentifier key);
}
/*
* 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 com.secoo.mall.dubbo.monitor.dubbo.metadata.impl;
import com.secoo.mall.dubbo.monitor.dubbo.metadata.MetaDataCollector;
import org.apache.dubbo.common.URL;
import org.apache.dubbo.metadata.identifier.MetadataIdentifier;
public class NoOpMetadataCollector implements MetaDataCollector {
@Override
public void setUrl(URL url) {
}
@Override
public URL getUrl() {
return null;
}
@Override
public void init() {
}
@Override
public String getProviderMetaData(MetadataIdentifier key) {
return null;
}
@Override
public String getConsumerMetaData(MetadataIdentifier key) {
return null;
}
}
/*
* 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 com.secoo.mall.dubbo.monitor.dubbo.metadata.impl;
import com.secoo.mall.dubbo.monitor.dubbo.Constants.Constants;
import com.secoo.mall.dubbo.monitor.dubbo.metadata.MetaDataCollector;
import org.apache.curator.framework.CuratorFramework;
import org.apache.curator.framework.CuratorFrameworkFactory;
import org.apache.curator.retry.ExponentialBackoffRetry;
import org.apache.dubbo.common.URL;
import org.apache.dubbo.common.logger.Logger;
import org.apache.dubbo.common.logger.LoggerFactory;
import org.apache.dubbo.metadata.identifier.MetadataIdentifier;
public class ZookeeperMetaDataCollector implements MetaDataCollector {
private static final Logger logger = LoggerFactory.getLogger(ZookeeperMetaDataCollector.class);
private CuratorFramework client;
private URL url;
private String root;
private final static String DEFAULT_ROOT = "dubbo";
@Override
public void setUrl(URL url) {
this.url = url;
}
@Override
public URL getUrl() {
return url;
}
@Override
public void init() {
String group = url.getParameter(Constants.GROUP_KEY, DEFAULT_ROOT);
if (!group.startsWith(Constants.PATH_SEPARATOR)) {
group = Constants.PATH_SEPARATOR + group;
}
root = group;
client = CuratorFrameworkFactory.newClient(url.getAddress(), new ExponentialBackoffRetry(1000, 3));
client.start();
}
@Override
public String getProviderMetaData(MetadataIdentifier key) {
return doGetMetadata(key);
}
@Override
public String getConsumerMetaData(MetadataIdentifier key) {
return doGetMetadata(key);
}
private String getNodePath(MetadataIdentifier metadataIdentifier) {
return toRootDir() + metadataIdentifier.getUniqueKey(MetadataIdentifier.KeyTypeEnum.PATH);
}
private String toRootDir() {
if (root.equals(Constants.PATH_SEPARATOR)) {
return root;
}
return root + Constants.PATH_SEPARATOR;
}
private String doGetMetadata(MetadataIdentifier identifier) {
//TODO error handing
try {
String path = getNodePath(identifier);
if (client.checkExists().forPath(path) == null) {
return null;
}
return new String(client.getData().forPath(path));
} catch (Exception e) {
logger.error(e.getMessage(), e);
}
return null;
}
}
/*
* 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 com.secoo.mall.dubbo.monitor.dubbo.model.domain;
import com.secoo.mall.dubbo.monitor.dubbo.Constants.Constants;
import com.secoo.mall.dubbo.monitor.utils.Tool;
import org.apache.dubbo.common.URL;
import org.apache.dubbo.common.utils.StringUtils;
import java.util.Date;
import java.util.List;
import java.util.Map;
/**
* Consumer
*
*/
public class Consumer extends Entity {
private static final long serialVersionUID = -1140894843784583237L;
private String service; /* The name of the service referenced by the consumer */
private String parameters;
private String result; /*route result*/
private String address; /* address of consumer */
private String registry; /* Consumer connected registry address */
private String application; /* application name */
private String username; /* user name of consumer */
private String statistics; /* Service call statistics */
private Date collected; /* Date statistics was recorded */
private Override override;
private List<Override> overrides;
private List<Route> conditionRoutes;
private List<Provider> providers;
private Date expired;
private long alived; /*Time to live in milliseconds*/
public Consumer() {
}
public Consumer(Long id) {
super(id);
}
public String getService() {
return service;
}
public void setService(String service) {
this.service = service;
}
public String getParameters() {
return parameters;
}
public void setParameters(String parameters) {
this.parameters = parameters;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public String getRegistry() {
return registry;
}
public void setRegistry(String registry) {
this.registry = registry;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getStatistics() {
return statistics;
}
public void setStatistics(String statistics) {
this.statistics = statistics;
}
public Date getCollected() {
return collected;
}
public void setCollected(Date collected) {
this.collected = collected;
}
public String getResult() {
return result;
}
public void setResult(String result) {
this.result = result;
}
public String getApplication() {
return application;
}
public void setApplication(String application) {
this.application = application;
}
public Date getExpired() {
return expired;
}
public void setExpired(Date expired) {
this.expired = expired;
}
public long getAlived() {
return alived;
}
public void setAlived(long alived) {
this.alived = alived;
}
public Override getOverride() {
return override;
}
public void setOverride(Override override) {
this.override = override;
}
public List<Override> getOverrides() {
return overrides;
}
public void setOverrides(List<Override> overrides) {
this.overrides = overrides;
}
public List<Route> getConditionRoutes() {
return conditionRoutes;
}
public void setConditionRoutes(List<Route> conditionRoutes) {
this.conditionRoutes = conditionRoutes;
}
public List<Provider> getProviders() {
return providers;
}
public void setProviders(List<Provider> providers) {
this.providers = providers;
}
@Override
public String toString() {
return "Consumer [service=" + service + ", parameters=" + parameters + ", result=" + result
+ ", address=" + address + ", registry=" + registry + ", application="
+ application + ", username=" + username + ", statistics=" + statistics
+ ", collected=" + collected + ", conditionRoutes=" + conditionRoutes + ", overrides=" + overrides
+ ", expired=" + expired + ", alived=" + alived + "]";
}
public URL toUrl() {
String group = Tool.getGroup(service);
String version = Tool.getVersion(service);
String interfaze = Tool.getInterface(service);
Map<String, String> param = StringUtils.parseQueryString(parameters);
param.put(Constants.CATEGORY_KEY, Constants.CONSUMERS_CATEGORY);
if (group != null) {
param.put(Constants.GROUP_KEY, group);
}
if (version != null) {
param.put(Constants.VERSION_KEY, version);
}
return URL.valueOf(Constants.CONSUMER_PROTOCOL + "://" + address + "/" + interfaze
+ "?" + StringUtils.toQueryString(param));
}
}
/*
* 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 com.secoo.mall.dubbo.monitor.dubbo.model.domain;
import java.io.Serializable;
import java.util.Date;
import java.util.List;
/**
* Entity
*
*/
public abstract class Entity implements Serializable {
private static final long serialVersionUID = -3031128781434583143L;
private List<Long> ids;
private Long id;
private String hash;
private Date created;
private Date modified;
private Date now;
private String operator;
private String operatorAddress;
private boolean miss;
public Entity() {
}
public Entity(Long id) {
this.id = id;
}
public List<Long> getIds() {
return ids;
}
public void setIds(List<Long> ids) {
this.ids = ids;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getHash() {
return hash;
}
public void setHash(String hash) {
this.hash = hash;
}
public Date getCreated() {
return created;
}
public void setCreated(Date created) {
this.created = created;
}
public Date getModified() {
return modified;
}
public void setModified(Date modified) {
this.modified = modified;
}
public Date getNow() {
return now;
}
public void setNow(Date now) {
this.now = now;
}
public String getOperator() {
return operator;
}
public void setOperator(String operator) {
if (operator != null && operator.length() > 200) {
operator = operator.substring(0, 200);
}
this.operator = operator;
}
public String getOperatorAddress() {
return operatorAddress;
}
public void setOperatorAddress(String operatorAddress) {
this.operatorAddress = operatorAddress;
}
public boolean isMiss() {
return miss;
}
public void setMiss(boolean miss) {
this.miss = miss;
}
}
/*
* 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 com.secoo.mall.dubbo.monitor.dubbo.model.domain;
import com.secoo.mall.dubbo.monitor.dubbo.Constants.Constants;
import com.secoo.mall.dubbo.monitor.utils.ConvertUtil;
import org.apache.dubbo.common.URL;
import java.util.Date;
import java.util.List;
import java.util.Map;
/**
* Provider
*
*/
public class Provider extends Entity {
private static final long serialVersionUID = 5981342400350878171L;
private String service;/* The name of the service provided by the provider */
private String url; /* Provider's address for service */
private String parameters; /* Provider provides service parameters */
private String address; /* Provider address */
private String registry;/* The provider's registry address */
private boolean dynamic; /* provider was registered dynamically */
private boolean enabled; /* provider enabled or not */
private int weight; /* provider weight */
private String application; /* application name */
private String username; /* operator */
private Date expired; /* time to expire */
private long alived; /* time to live in milliseconds */
private Override override;
private List<Override> overrides;
public Provider() {
}
public Provider(Long id) {
super(id);
}
public String getService() {
return service;
}
public void setService(String service) {
this.service = service;
}
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
public String getParameters() {
return parameters;
}
public void setParameters(String parameters) {
this.parameters = parameters;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public String getRegistry() {
return registry;
}
public void setRegistry(String registry) {
this.registry = registry;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getApplication() {
return application;
}
public void setApplication(String application) {
this.application = application;
}
public boolean isDynamic() {
return dynamic;
}
public void setDynamic(boolean dynamic) {
this.dynamic = dynamic;
}
public boolean isEnabled() {
return enabled;
}
public void setEnabled(boolean enabled) {
this.enabled = enabled;
}
public Date getExpired() {
return expired;
}
public void setExpired(Date expired) {
this.expired = expired;
}
public long getAlived() {
return alived;
}
public void setAlived(long aliveSeconds) {
this.alived = aliveSeconds;
}
public int getWeight() {
return weight;
}
public void setWeight(int weight) {
this.weight = weight;
}
public Override getOverride() {
return override;
}
public void setOverride(Override override) {
this.override = override;
}
public List<Override> getOverrides() {
return overrides;
}
public void setOverrides(List<Override> overrides) {
this.overrides = overrides;
}
public URL toUrl() {
Map<String, String> serviceName2Map = ConvertUtil.serviceName2Map(getService());
/*if(!serviceName2Map.containsKey(Constants.INTERFACE_KEY)) {
throw new IllegalArgumentException("No interface info");
}
if(!serviceName2Map.containsKey(Constants.VERSION_KEY)) {
throw new IllegalArgumentException("No version info");
}*/
String u = getUrl();
URL url = URL.valueOf(u + "?" + getParameters());
url = url.addParameters(serviceName2Map);
boolean dynamic = isDynamic();
if (!dynamic) {
url = url.addParameter(Constants.DYNAMIC_KEY, false);
}
boolean enabled = isEnabled();
if (enabled != url.getParameter("enabled", true)) {
if (enabled) {
url = url.removeParameter("enabled");
} else {
url = url.addParameter("enabled", false);
}
}
return url;
}
}
/*
* 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 com.secoo.mall.dubbo.monitor.dubbo.model.domain;
import com.secoo.mall.dubbo.monitor.dubbo.Constants.Constants;
import com.secoo.mall.dubbo.monitor.utils.Tool;
import org.apache.dubbo.common.URL;
import java.util.List;
public class Route extends Entity {
public static final String ALL_METHOD = "*";
public static final String KEY_METHOD = "method";
// WHEN KEY
public static final String KEY_CONSUMER_APPLICATION = "consumer.application";
public static final String KEY_CONSUMER_GROUP = "consumer.cluster";
public static final String KEY_CONSUMER_VERSION = "consumer.version";
public static final String KEY_CONSUMER_HOST = "host";
public static final String KEY_CONSUMER_METHODS = "consumer.methods";
public static final String KEY_PROVIDER_APPLICATION = "provider.application";
// THEN KEY
public static final String KEY_PROVIDER_GROUP = "provider.cluster";
public static final String KEY_PROVIDER_PROTOCOL = "provider.protocol";
public static final String KEY_PROVIDER_VERSION = "provider.version";
public static final String KEY_PROVIDER_HOST = "provider.host";
public static final String KEY_PROVIDER_PORT = "provider.port";
private static final long serialVersionUID = -7630589008164140656L;
private long parentId; //default 0
private String name;
private String service;
private String rule;
private String matchRule;
private String filterRule;
private int priority;
private String username;
private boolean enabled;
private boolean force;
private boolean dynamic;
private boolean runtime;
private List<Route> children;
public Route() {
}
public Route(Long id) {
super(id);
}
public int getPriority() {
return priority;
}
public void setPriority(int priority) {
this.priority = priority;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public long getParentId() {
return parentId;
}
public void setParentId(long parentId) {
this.parentId = parentId;
}
public List<Route> getChildren() {
return children;
}
public void setChildren(List<Route> subRules) {
this.children = subRules;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public boolean isEnabled() {
return enabled;
}
public void setEnabled(boolean enabled) {
this.enabled = enabled;
}
public boolean isDynamic() {
return dynamic;
}
public void setDynamic(boolean dynamic) {
this.dynamic = dynamic;
}
public boolean isRuntime() {
return runtime;
}
public void setRuntime(boolean runtime) {
this.runtime = runtime;
}
public boolean isForce() {
return force;
}
public void setForce(boolean force) {
this.force = force;
}
public String getService() {
return service;
}
public void setService(String service) {
this.service = service;
}
public String getRule() {
return rule;
}
public void setRule(String rule) {
this.rule = rule.trim();
String[] rules = rule.split("=>");
if (rules.length != 2) {
if (rule.endsWith("=>")) {
this.matchRule = rules[0].trim();
this.filterRule = "";
} else {
throw new IllegalArgumentException("Illegal Route Condition Rule");
}
} else {
this.matchRule = rules[0].trim();
this.filterRule = rules[1].trim();
}
}
public String getMatchRule() {
return matchRule;
}
public void setMatchRule(String matchRule) {
if (matchRule != null) {
this.matchRule = matchRule.trim();
} else {
this.matchRule = matchRule;
}
}
public String getFilterRule() {
return filterRule;
}
public void setFilterRule(String filterRule) {
if (filterRule != null) {
this.filterRule = filterRule.trim();
} else {
this.filterRule = filterRule;
}
}
@Override
public String toString() {
return "Route [parentId=" + parentId + ", name=" + name
+ ", serviceName=" + service + ", matchRule=" + matchRule
+ ", filterRule=" + filterRule + ", priority=" + priority
+ ", username=" + username + ", enabled=" + enabled + "]";
}
public URL toUrl() {
String group = Tool.getGroup(service);
String version = Tool.getVersion(service);
String interfaze = Tool.getInterface(service);
return URL.valueOf(Constants.ROUTE_PROTOCOL + "://" + Constants.ANYHOST_VALUE + "/" + interfaze
+ "?" + Constants.CATEGORY_KEY + "=" + Constants.ROUTERS_CATEGORY
+ "&router=condition&runtime=" + isRuntime() + "&enabled=" + isEnabled() + "&priority=" + getPriority() + "&force=" + isForce() + "&dynamic=" + isDynamic()
+ "&name=" + getName() + "&" + Constants.RULE_KEY + "=" + URL.encode(getMatchRule() + " => " + getFilterRule())
+ (group == null ? "" : "&" + Constants.GROUP_KEY + "=" + group)
+ (version == null ? "" : "&" + Constants.VERSION_KEY + "=" + version));
}
}
/*
* 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 com.secoo.mall.dubbo.monitor.dubbo.model.dto;
import org.apache.commons.lang3.StringUtils;
import java.util.Objects;
public class ServiceDTO implements Comparable<ServiceDTO>{
private String service;
private String appName;
private String group;
private String version;
private Long id;
private String address;
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getService() {
return service;
}
public void setService(String service) {
this.service = service;
}
public String getAppName() {
return appName;
}
public void setAppName(String appName) {
this.appName = appName;
}
public String getGroup() {
return group;
}
public void setGroup(String group) {
this.group = group;
}
public String getVersion() {
return version;
}
public void setVersion(String version) {
this.version = version;
}
@Override
public int compareTo(ServiceDTO o) {
int result = StringUtils.trimToEmpty(appName).compareTo(StringUtils.trimToEmpty(o.getAppName()));
if (result == 0) {
result = StringUtils.trimToEmpty(service).compareTo(StringUtils.trimToEmpty(o.getService()));
if (result == 0) {
result = StringUtils.trimToEmpty(group).compareTo(StringUtils.trimToEmpty(o.getGroup()));
}
if (result == 0) {
result = StringUtils.trimToEmpty(version).compareTo(StringUtils.trimToEmpty(o.getVersion()));
}
}
return result;
}
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
ServiceDTO that = (ServiceDTO) o;
return Objects.equals(service, that.service) && Objects.equals(appName, that.appName) && Objects
.equals(group, that.group) && Objects.equals(version, that.version);
}
@Override
public int hashCode() {
return Objects.hash(service, appName, group, version);
}
}
/*
* 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 com.secoo.mall.dubbo.monitor.dubbo.register;
import org.apache.dubbo.common.URL;
import org.apache.dubbo.common.extension.SPI;
@SPI("zookeeper")
public interface GovernanceConfiguration {
void init();
void setUrl(URL url);
URL getUrl();
String setConfig(String key, String value);
String getConfig(String key);
boolean deleteConfig(String key);
String setConfig(String group, String key, String value);
String getConfig(String group, String key);
boolean deleteConfig(String group, String key);
String getPath(String key);
String getPath(String group, String key);
}
/*
* 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 com.secoo.mall.dubbo.monitor.dubbo.register.impl;
import com.secoo.mall.dubbo.monitor.dubbo.Constants.Constants;
import com.secoo.mall.dubbo.monitor.dubbo.register.GovernanceConfiguration;
import org.apache.commons.lang3.StringUtils;
import org.apache.curator.framework.CuratorFramework;
import org.apache.curator.framework.CuratorFrameworkFactory;
import org.apache.curator.retry.ExponentialBackoffRetry;
import org.apache.dubbo.common.URL;
import org.apache.dubbo.common.logger.Logger;
import org.apache.dubbo.common.logger.LoggerFactory;
public class ZookeeperConfiguration implements GovernanceConfiguration {
private static final Logger logger = LoggerFactory.getLogger(ZookeeperConfiguration.class);
private CuratorFramework zkClient;
private URL url;
private String root;
@Override
public void setUrl(URL url) {
this.url = url;
}
@Override
public URL getUrl() {
return url;
}
@Override
public void init() {
if (url == null) {
throw new IllegalStateException("server url is null, cannot init");
}
CuratorFrameworkFactory.Builder zkClientBuilder = CuratorFrameworkFactory.builder().
connectString(url.getAddress()).
retryPolicy(new ExponentialBackoffRetry(1000, 3));
if (StringUtils.isNotEmpty(url.getUsername()) && StringUtils.isNotEmpty(url.getPassword())) {
// add authorization
String auth = url.getUsername() + ":" + url.getPassword();
zkClientBuilder.authorization("digest", auth.getBytes());
}
zkClient = zkClientBuilder.build();
String group = url.getParameter(Constants.GROUP_KEY, Constants.DEFAULT_ROOT);
if (!group.startsWith(Constants.PATH_SEPARATOR)) {
group = Constants.PATH_SEPARATOR + group;
}
root = group;
zkClient.start();
}
@Override
public String setConfig(String key, String value) {
return setConfig(null, key, value);
}
@Override
public String getConfig(String key) {
return getConfig(null, key);
}
@Override
public boolean deleteConfig(String key) {
return deleteConfig(null, key);
}
@Override
public String setConfig(String group, String key, String value) {
if (key == null || value == null) {
throw new IllegalArgumentException("key or value cannot be null");
}
String path = getNodePath(key, group);
try {
if (zkClient.checkExists().forPath(path) == null) {
zkClient.create().creatingParentsIfNeeded().forPath(path);
}
zkClient.setData().forPath(path, value.getBytes());
return value;
} catch (Exception e) {
logger.error(e.getMessage(), e);
}
return null;
}
@Override
public String getConfig(String group, String key) {
if (key == null) {
throw new IllegalArgumentException("key cannot be null");
}
String path = getNodePath(key, group);
try {
if (zkClient.checkExists().forPath(path) == null) {
return null;
}
return new String(zkClient.getData().forPath(path));
} catch (Exception e) {
logger.error(e.getMessage(), e);
}
return null;
}
@Override
public boolean deleteConfig(String group, String key) {
if (key == null) {
throw new IllegalArgumentException("key cannot be null");
}
String path = getNodePath(key, group);
try {
zkClient.delete().forPath(path);
} catch (Exception e) {
logger.error(e.getMessage(), e);
return false;
}
return true;
}
@Override
public String getPath(String key) {
return getNodePath(key, null);
}
@Override
public String getPath(String group, String key) {
return getNodePath(key, group);
}
private String getNodePath(String path, String group) {
if (path == null) {
throw new IllegalArgumentException("path cannot be null");
}
return toRootDir(group) + path;
}
private String toRootDir(String group) {
if (group != null) {
if (!group.startsWith(Constants.PATH_SEPARATOR)) {
root = Constants.PATH_SEPARATOR + group;
} else {
root = group;
}
}
if (root.equals(Constants.PATH_SEPARATOR)) {
return root;
}
return root + Constants.PATH_SEPARATOR;
}
}
/*
* 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 com.secoo.mall.dubbo.monitor.dubbo.service;
import com.secoo.mall.dubbo.monitor.dubbo.model.domain.Consumer;
import org.apache.dubbo.metadata.identifier.MetadataIdentifier;
import java.util.List;
/**
* Query service for consumer info
*
*/
public interface ConsumerService {
List<Consumer> findByService(String serviceName);
String getConsumerMetadata(MetadataIdentifier consumerIdentifier);
List<Consumer> findAll();
/**
* query for all consumer addresses
*/
List<Consumer> findByAddress(String consumerAddress);
}
/*
* 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 com.secoo.mall.dubbo.monitor.dubbo.service;
import com.secoo.mall.dubbo.monitor.dubbo.model.domain.Provider;
import com.secoo.mall.dubbo.monitor.dubbo.model.dto.ServiceDTO;
import org.apache.dubbo.metadata.identifier.MetadataIdentifier;
import java.util.List;
import java.util.Set;
/**
* ProviderService
*
*/
public interface ProviderService {
void create(Provider provider);
// void enableProvider(String id);
// void disableProvider(String id);
// void doublingProvider(String id);
// void halvingProvider(String id);
void deleteStaticProvider(String id);
void updateProvider(Provider provider);
Provider findProvider(String id);
String getProviderMetaData(MetadataIdentifier providerIdentifier);
/**
* Get all provider's service name
*
* @return list of all provider's service name
*/
Set<String> findServices();
String findServiceVersion(String serviceName, String application);
String findVersionInApplication(String application);
List<String> findAddresses();
List<String> findAddressesByApplication(String application);
List<String> findAddressesByService(String serviceName);
List<String> findApplicationsByServiceName(String serviceName);
/**
* Get provider list with specific service name.
*
* @param serviceName specific service name, cannot be fuzzy string
* @return list of provider object
*/
List<Provider> findByService(String serviceName);
List<Provider> findByAppandService(String app, String serviceName);
List<Provider> findAll();
/**
* Get provider list with specific ip address.
*
* @param providerAddress provider's ip address
* @return list of provider object
*/
List<Provider> findByAddress(String providerAddress);
List<String> findServicesByAddress(String providerAddress);
Set<String> findApplications();
/**
* Get provider list with specific application name.
*
* @param application specific application name
* @return list of provider object
*/
List<Provider> findByApplication(String application);
List<String> findServicesByApplication(String application);
List<String> findMethodsByService(String serviceName);
Provider findByServiceAndAddress(String service, String address);
/**
* Get a set of service data object.
*
* ServiceDTO object contains base information include
* service name , application, group and version.
*
* @param pattern {@code String} type of search
* @param filter {@code String} input filter string
* @param env {@code String}the environment of front end
* @return a set of services for fore-end page
*/
Set<ServiceDTO> getServiceDTOS(String pattern, String filter, String env);
List<Provider> getServiceDTOSByQuery(String pattern, String filter, String env);
}
/*
* 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 com.secoo.mall.dubbo.monitor.dubbo.service;
import com.secoo.mall.dubbo.monitor.dubbo.Constants.Constants;
import com.secoo.mall.dubbo.monitor.utils.CoderUtil;
import com.secoo.mall.dubbo.monitor.utils.Tool;
import org.apache.dubbo.common.URL;
import org.apache.dubbo.common.logger.Logger;
import org.apache.dubbo.common.logger.LoggerFactory;
import org.apache.dubbo.common.utils.NetUtils;
import org.apache.dubbo.common.utils.StringUtils;
import org.apache.dubbo.registry.NotifyListener;
import org.apache.dubbo.registry.Registry;
import org.apache.dubbo.registry.support.FailbackRegistry;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.stereotype.Component;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.atomic.AtomicLong;
@Component
public class RegistryServerSync implements InitializingBean, DisposableBean, NotifyListener , CommandLineRunner {
private static final Logger logger = LoggerFactory.getLogger(RegistryServerSync.class);
private static final URL SUBSCRIBE = new URL(Constants.ADMIN_PROTOCOL, NetUtils.getLocalHost(), 0, "",
Constants.INTERFACE_KEY, Constants.ANY_VALUE,
Constants.GROUP_KEY, Constants.ANY_VALUE,
Constants.VERSION_KEY, Constants.ANY_VALUE,
Constants.CLASSIFIER_KEY, Constants.ANY_VALUE,
Constants.CATEGORY_KEY, Constants.PROVIDERS_CATEGORY + ","
+ Constants.CONSUMERS_CATEGORY + ","
+ Constants.ROUTERS_CATEGORY + ","
+ Constants.CONFIGURATORS_CATEGORY,
Constants.ENABLED_KEY, Constants.ANY_VALUE,
Constants.CHECK_KEY, String.valueOf(false));
private static final AtomicLong ID = new AtomicLong();
/**
* Make sure ID never changed when the same url notified many times
*/
private final ConcurrentHashMap<String, String> URL_IDS_MAPPER = new ConcurrentHashMap<>();
/**
* ConcurrentMap<category, ConcurrentMap<servicename, Map<MD5, URL>>>
* registryCache
*/
private final ConcurrentMap<String, ConcurrentMap<String, Map<String, URL>>> registryCache = new ConcurrentHashMap<>();
@Autowired
private Registry registry;
public ConcurrentMap<String, ConcurrentMap<String, Map<String, URL>>> getRegistryCache() {
return registryCache;
}
@Override
public void afterPropertiesSet() throws Exception {
logger.info("Init Dubbo Admin Sync Cache...");
// FailbackRegistry parentRegister= (FailbackRegistry)registry;
// Set<URL> urls= parentRegister.getRegistered();
// for(URL u: urls){
// if(u.getParameter(Constants.CATEGORY_KEY).endsWith(Constants.PROVIDER_PROTOCOL)) {
// registry.subscribe(u, this);
// }
// }
registry.subscribe(SUBSCRIBE, this);
}
@Override
public void destroy() throws Exception {
registry.unsubscribe(SUBSCRIBE, this);
}
// Notification of of any service with any type (override、subcribe、route、provider) is full.
@Override
public void notify(List<URL> urls) {
if (urls == null || urls.isEmpty()) {
return;
}
// Map<category, Map<servicename, Map<Long, URL>>>
final Map<String, Map<String, Map<String, URL>>> categories = new HashMap<>();
String interfaceName = null;
for (URL url : urls) {
String category = url.getParameter(Constants.CATEGORY_KEY, Constants.PROVIDERS_CATEGORY);
// NOTE: group and version in empty protocol is *
if (Constants.EMPTY_PROTOCOL.equalsIgnoreCase(url.getProtocol())) {
ConcurrentMap<String, Map<String, URL>> services = registryCache.get(category);
if (services != null) {
String group = url.getParameter(Constants.GROUP_KEY);
String version = url.getParameter(Constants.VERSION_KEY);
// NOTE: group and version in empty protocol is *
if (!Constants.ANY_VALUE.equals(group) && !Constants.ANY_VALUE.equals(version)) {
services.remove(url.getServiceKey());
} else {
for (Map.Entry<String, Map<String, URL>> serviceEntry : services.entrySet()) {
String service = serviceEntry.getKey();
if (Tool.getInterface(service).equals(url.getServiceInterface())
&& (Constants.ANY_VALUE.equals(group) || StringUtils.isEquals(group, Tool.getGroup(service)))
&& (Constants.ANY_VALUE.equals(version) || StringUtils.isEquals(version, Tool.getVersion(service)))) {
services.remove(service);//版本 和分组匹配就干掉?
}
}
}
}
} else {
if (StringUtils.isEmpty(interfaceName)) {
interfaceName = url.getServiceInterface();
}
Map<String, Map<String, URL>> services = categories.get(category);
if (services == null) {
services = new HashMap<>();
categories.put(category, services);
}
String service = url.getServiceKey();
Map<String, URL> ids = services.get(service);
if (ids == null) {
ids = new HashMap<>();
services.put(service, ids);
}
// Make sure we use the same ID for the same URL
if (URL_IDS_MAPPER.containsKey(url.toFullString())) {
ids.put(URL_IDS_MAPPER.get(url.toFullString()), url);
} else {
String md5 = CoderUtil.MD5_16bit(url.toFullString());
ids.put(md5, url);
URL_IDS_MAPPER.putIfAbsent(url.toFullString(), md5);
}
}
}
if (categories.size() == 0) {
return;
}
for (Map.Entry<String, Map<String, Map<String, URL>>> categoryEntry : categories.entrySet()) {
String category = categoryEntry.getKey();
ConcurrentMap<String, Map<String, URL>> services = registryCache.get(category);
if (services == null) {
services = new ConcurrentHashMap<String, Map<String, URL>>();
registryCache.put(category, services);
} else {// Fix map can not be cleared when service is unregistered: when a unique “group/service:version” service is unregistered, but we still have the same services with different version or group, so empty protocols can not be invoked.
Set<String> keys = new HashSet<String>(services.keySet());
for (String key : keys) { //接口
if (Tool.getInterface(key).equals(interfaceName) && !categoryEntry.getValue().entrySet().contains(key)) {
services.remove(key);
}
}
}
services.putAll(categoryEntry.getValue());
}
}
/**
* Callback used to run the bean.
*
* @param args incoming main method arguments
* @throws Exception on error
*/
@Override
public void run(String... args) throws Exception {
logger.info("Init Dubbo Admin Sync Cache...");
// FailbackRegistry parentRegister= (FailbackRegistry)registry;
// Set<URL> urls= parentRegister.getRegistered();
// for(URL u: urls){
// if(u.getParameter(Constants.CATEGORY_KEY).endsWith(Constants.PROVIDER_PROTOCOL)) {
// registry.subscribe(u, this);
// }
// }
}
}
/*
* 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 com.secoo.mall.dubbo.monitor.dubbo.service.impl;
import com.secoo.mall.dubbo.monitor.dubbo.metadata.MetaDataCollector;
import com.secoo.mall.dubbo.monitor.dubbo.register.GovernanceConfiguration;
import com.secoo.mall.dubbo.monitor.dubbo.service.RegistryServerSync;
import org.apache.dubbo.common.URL;
import org.apache.dubbo.common.logger.Logger;
import org.apache.dubbo.common.logger.LoggerFactory;
import org.apache.dubbo.registry.Registry;
import org.springframework.beans.factory.annotation.Autowired;
import java.util.Map;
import java.util.concurrent.ConcurrentMap;
public class AbstractService {
protected static final Logger logger = LoggerFactory.getLogger(AbstractService.class);
@Autowired
protected Registry registry;
@Autowired
protected GovernanceConfiguration dynamicConfiguration;
@Autowired
protected MetaDataCollector metaDataCollector;
@Autowired
private RegistryServerSync sync;
public ConcurrentMap<String, ConcurrentMap<String, Map<String, URL>>> getRegistryCache() {
return sync.getRegistryCache();
}
}
/*
* 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 com.secoo.mall.dubbo.monitor.dubbo.service.impl;
import com.secoo.mall.dubbo.monitor.dubbo.Constants.Constants;
import com.secoo.mall.dubbo.monitor.dubbo.model.domain.Consumer;
import com.secoo.mall.dubbo.monitor.dubbo.service.ConsumerService;
import com.secoo.mall.dubbo.monitor.utils.SyncUtils;
import org.apache.dubbo.common.URL;
import org.apache.dubbo.metadata.identifier.MetadataIdentifier;
import org.springframework.stereotype.Component;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@Component
public class ConsumerServiceImpl extends AbstractService implements ConsumerService {
@Override
public List<Consumer> findByService(String service) {
return SyncUtils.url2ConsumerList(findConsumerUrlByService(service));
}
@Override
public List<Consumer> findAll() {
return SyncUtils.url2ConsumerList(findAllConsumerUrl());
}
@Override
public String getConsumerMetadata(MetadataIdentifier consumerIdentifier) {
return metaDataCollector.getConsumerMetaData(consumerIdentifier);
}
private Map<String, URL> findAllConsumerUrl() {
Map<String, String> filter = new HashMap<String, String>();
filter.put(Constants.CATEGORY_KEY, Constants.CONSUMERS_CATEGORY);
return SyncUtils.filterFromCategory(getRegistryCache(), filter);
}
@Override
public List<Consumer> findByAddress(String consumerAddress) {
return SyncUtils.url2ConsumerList(findConsumerUrlByAddress(consumerAddress));
}
private Map<String, URL> findConsumerUrlByAddress(String address) {
Map<String, String> filter = new HashMap<String, String>();
filter.put(Constants.CATEGORY_KEY, Constants.CONSUMERS_CATEGORY);
filter.put(SyncUtils.ADDRESS_FILTER_KEY, address);
return SyncUtils.filterFromCategory(getRegistryCache(), filter);
}
public Map<String, URL> findConsumerUrlByService(String service) {
Map<String, String> filter = new HashMap<String, String>();
filter.put(Constants.CATEGORY_KEY, Constants.CONSUMERS_CATEGORY);
filter.put(SyncUtils.SERVICE_FILTER_KEY, service);
return SyncUtils.filterFromCategory(getRegistryCache(), filter);
}
}
/*
* 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 com.secoo.mall.dubbo.monitor.dubbo.service.impl;
import com.secoo.mall.dubbo.monitor.dubbo.Constants.Constants;
import com.secoo.mall.dubbo.monitor.dubbo.exception.ParamValidationException;
import com.secoo.mall.dubbo.monitor.dubbo.model.domain.Provider;
import com.secoo.mall.dubbo.monitor.dubbo.model.dto.ServiceDTO;
import com.secoo.mall.dubbo.monitor.dubbo.service.ProviderService;
import com.secoo.mall.dubbo.monitor.utils.Pair;
import com.secoo.mall.dubbo.monitor.utils.ParseUtils;
import com.secoo.mall.dubbo.monitor.utils.SyncUtils;
import com.secoo.mall.dubbo.monitor.utils.Tool;
import org.apache.dubbo.common.URL;
import org.apache.dubbo.metadata.identifier.MetadataIdentifier;
import org.springframework.stereotype.Component;
import java.util.*;
import java.util.Map.Entry;
import java.util.concurrent.ConcurrentMap;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
@Component
public class ProviderServiceImpl extends AbstractService implements ProviderService {
//注册 服务
@Override
public void create(Provider provider) {
URL url = provider.toUrl();
registry.register(url);
}
//todo 看不懂
@Override
public String getProviderMetaData(MetadataIdentifier providerIdentifier) {
return metaDataCollector.getProviderMetaData(providerIdentifier);
}
//删除服务
@Override
public void deleteStaticProvider(String id) {
URL oldProvider = findProviderUrl(id);
if (oldProvider == null) {
throw new IllegalStateException("Provider was changed!");
}
registry.unregister(oldProvider);
}
//更新服务
@Override
public void updateProvider(Provider provider) {
String hash = provider.getHash();
if (hash == null) {
throw new IllegalStateException("no provider id");
}
URL oldProvider = findProviderUrl(hash);
if (oldProvider == null) {
throw new IllegalStateException("Provider was changed!");
}
URL newProvider = provider.toUrl();
registry.unregister(oldProvider);
registry.register(newProvider);
}
//根据id查找服务
@Override
public Provider findProvider(String id) {
return SyncUtils.url2Provider(findProviderUrlPair(id));
}
public Pair<String, URL> findProviderUrlPair(String id) {
return SyncUtils.filterFromCategory(getRegistryCache(), Constants.PROVIDERS_CATEGORY, id);
}
//查找所有已经注册的服务
@Override
public Set<String> findServices() {
Set<String> ret = new HashSet<>();
ConcurrentMap<String, Map<String, URL>> providerUrls = getRegistryCache().get(Constants.PROVIDERS_CATEGORY);
if (providerUrls != null){
ret.addAll(providerUrls.keySet());
}
return ret;
}
//根据地址查找服务
@Override
public List<String> findAddresses() {
List<String> ret = new ArrayList<String>();
ConcurrentMap<String, Map<String, URL>> providerUrls = getRegistryCache().get(Constants.PROVIDERS_CATEGORY);
if (null == providerUrls) {
return ret;
}
for (Entry<String, Map<String, URL>> e1 : providerUrls.entrySet()) {
Map<String, URL> value = e1.getValue();
for (Entry<String, URL> e2 : value.entrySet()) {
URL u = e2.getValue();
String app = u.getAddress();
if (app != null) {
ret.add(app);
}
}
}
return ret;
}
//根据应用名 查找服务 所在的ip
@Override
public List<String> findAddressesByApplication(String application) {
List<String> ret = new ArrayList<String>();
ConcurrentMap<String, Map<String, URL>> providerUrls = getRegistryCache().get(Constants.PROVIDERS_CATEGORY);
for (Entry<String, Map<String, URL>> e1 : providerUrls.entrySet()) {
Map<String, URL> value = e1.getValue();
for (Entry<String, URL> e2 : value.entrySet()) {
URL u = e2.getValue();
if (application.equals(u.getParameter(Constants.APPLICATION))) {
String addr = u.getAddress();
if (addr != null) {
ret.add(addr);
}
}
}
}
return ret;
}
//根据服务查找 目前所在的机器ip
@Override
public List<String> findAddressesByService(String service) {
List<String> ret = new ArrayList<String>();
ConcurrentMap<String, Map<String, URL>> providerUrls = getRegistryCache().get(Constants.PROVIDERS_CATEGORY);
if (null == providerUrls) {
return ret;
}
for (Entry<String, URL> e2 : providerUrls.get(service).entrySet()) {
URL u = e2.getValue();
String app = u.getAddress();
if (app != null) {
ret.add(app);
}
}
return ret;
}
//根据服务查找 所在的应用关系
@Override
public List<String> findApplicationsByServiceName(String service) {
List<String> ret = new ArrayList<String>();
ConcurrentMap<String, Map<String, URL>> providerUrls = getRegistryCache().get(Constants.PROVIDERS_CATEGORY);
if (null == providerUrls) {
return ret;
}
Map<String, URL> value = providerUrls.get(service);
if (value == null) {
return ret;
}
for (Entry<String, URL> e2 : value.entrySet()) {
URL u = e2.getValue();
String app = u.getParameter(Constants.APPLICATION);
if (app != null){
ret.add(app);
}
}
return ret;
}
//根据服务名查找所有的提供者
@Override
public List<Provider> findByService(String serviceName) {
return SyncUtils.url2ProviderList(findProviderUrlByService(serviceName));
}
//根据应用和服务名,查找提供者
@Override
public List<Provider> findByAppandService(String app, String serviceName) {
return SyncUtils.url2ProviderList(findProviderUrlByAppandService(app, serviceName));
}
//根据服务名,查询目前所有的服务url
private Map<String, URL> findProviderUrlByService(String service) {
Map<String, String> filter = new HashMap<String, String>();
filter.put(Constants.CATEGORY_KEY, Constants.PROVIDERS_CATEGORY);
filter.put(SyncUtils.SERVICE_FILTER_KEY, service);
return SyncUtils.filterFromCategory(getRegistryCache(), filter);
}
@Override
//查询所有的url
public List<Provider> findAll() {
return SyncUtils.url2ProviderList(findAllProviderUrl());
}
private Map<String, URL> findAllProviderUrl() {
Map<String, String> filter = new HashMap<String, String>();
filter.put(Constants.CATEGORY_KEY, Constants.PROVIDERS_CATEGORY);
return SyncUtils.filterFromCategory(getRegistryCache(), filter);
}
@Override
//根据 ip查询
public List<Provider> findByAddress(String providerAddress) {
return SyncUtils.url2ProviderList(findProviderUrlByAddress(providerAddress));
}
//根据地质查询所有的服务url
public Map<String, URL> findProviderUrlByAddress(String address) {
Map<String, String> filter = new HashMap<String, String>();
filter.put(Constants.CATEGORY_KEY, Constants.PROVIDERS_CATEGORY);
filter.put(SyncUtils.ADDRESS_FILTER_KEY, address);
return SyncUtils.filterFromCategory(getRegistryCache(), filter);
}
@Override
//根据ip 查询 所有的服务
public List<String> findServicesByAddress(String address) {
List<String> ret = new ArrayList<String>();
ConcurrentMap<String, Map<String, URL>> providerUrls = getRegistryCache().get(Constants.PROVIDERS_CATEGORY);
if (providerUrls == null || address == null || address.length() == 0) {
return ret;
}
for (Entry<String, Map<String, URL>> e1 : providerUrls.entrySet()) {
Map<String, URL> value = e1.getValue();
for (Entry<String, URL> e2 : value.entrySet()) {
URL u = e2.getValue();
if (address.equals(u.getAddress())) {
ret.add(e1.getKey());
break;
}
}
}
return ret;
}
//查询所有的应用
@Override
public Set<String> findApplications() {
Set<String> ret = new HashSet<>();
ConcurrentMap<String, Map<String, URL>> providerUrls = getRegistryCache().get(Constants.PROVIDERS_CATEGORY);
if (providerUrls == null){
return ret;
}
for (Entry<String, Map<String, URL>> e1 : providerUrls.entrySet()) {
Map<String, URL> value = e1.getValue();
for (Entry<String, URL> e2 : value.entrySet()) {
URL u = e2.getValue();
String app = u.getParameter(Constants.APPLICATION);
if (app != null) {
ret.add(app);
}
}
}
return ret;
}
@Override
//根据应用名 查询目前所有的服务提供者
public List<Provider> findByApplication(String application) {
return SyncUtils.url2ProviderList(findProviderUrlByApplication(application));
}
//根据应用名 查询目前所有的服务提供者 版本
@Override
public String findVersionInApplication(String application) {
List<String> services = findServicesByApplication(application);
if (services == null || services.size() == 0) {
throw new ParamValidationException("there is no service for application: " + application);
}
return findServiceVersion(services.get(0), application);
}
@Override
//根据服务名和应用,查询服务
public String findServiceVersion(String serviceName, String application) {
String version = "2.6";
Map<String, URL> result = findProviderUrlByAppandService(application, serviceName);
if (result != null && result.size() > 0) {
URL url = result.values().stream().findFirst().get();
if (url.getParameter(Constants.SPECIFICATION_VERSION_KEY) != null) {
version = url.getParameter(Constants.SPECIFICATION_VERSION_KEY);
}
}
return version;
}
//根据应用和服务 查询url
private Map<String, URL> findProviderUrlByAppandService(String app, String service) {
Map<String, String> filter = new HashMap<>();
filter.put(Constants.CATEGORY_KEY, Constants.PROVIDERS_CATEGORY);
filter.put(Constants.APPLICATION, app);
filter.put(SyncUtils.SERVICE_FILTER_KEY, service);
return SyncUtils.filterFromCategory(getRegistryCache(), filter);
}
private Map<String, URL> findProviderUrlByApplication(String application) {
Map<String, String> filter = new HashMap<>();
filter.put(Constants.CATEGORY_KEY, Constants.PROVIDERS_CATEGORY);
filter.put(Constants.APPLICATION, application);
return SyncUtils.filterFromCategory(getRegistryCache(), filter);
}
@Override
public List<String> findServicesByApplication(String application) {
List<String> ret = new ArrayList<String>();
ConcurrentMap<String, Map<String, URL>> providerUrls = getRegistryCache().get(Constants.PROVIDERS_CATEGORY);
if (providerUrls == null || application == null || application.length() == 0) {
return ret;
}
for (Entry<String, Map<String, URL>> e1 : providerUrls.entrySet()) {
Map<String, URL> value = e1.getValue();
for (Entry<String, URL> e2 : value.entrySet()) {
URL u = e2.getValue();
if (application.equals(u.getParameter(Constants.APPLICATION))) {
ret.add(e1.getKey());
break;
}
}
}
return ret;
}
@Override
//查询服务下面的所有提供的方法
public List<String> findMethodsByService(String service) {
List<String> ret = new ArrayList<String>();
ConcurrentMap<String, Map<String, URL>> providerUrls = getRegistryCache().get(Constants.PROVIDERS_CATEGORY);
if (providerUrls == null || service == null || service.length() == 0){
return ret;
}
Map<String, URL> providers = providerUrls.get(service);
if (null == providers || providers.isEmpty()) {
return ret;
}
Entry<String, URL> p = providers.entrySet().iterator().next();
String value = p.getValue().getParameter("methods");
if (value == null || value.length() == 0) {
return ret;
}
String[] methods = value.split(ParseUtils.METHOD_SPLIT);
if (methods == null || methods.length == 0) {
return ret;
}
for (String m : methods) {
ret.add(m);
}
return ret;
}
private URL findProviderUrl(String id) {
return findProvider(id).toUrl();
}
//根据服务名和地址查询提供者
@Override
public Provider findByServiceAndAddress(String service, String address) {
return SyncUtils.url2Provider(findProviderUrl(service, address));
}
//根据服务名和地址,查询提供的者
private Pair<String, URL> findProviderUrl(String service, String address) {
Map<String, String> filter = new HashMap<String, String>();
filter.put(Constants.CATEGORY_KEY, Constants.PROVIDERS_CATEGORY);
filter.put(SyncUtils.ADDRESS_FILTER_KEY, address);
Map<String, URL> ret = SyncUtils.filterFromCategory(getRegistryCache(), filter);
if (ret.isEmpty()) {
return null;
} else {
String key = ret.entrySet().iterator().next().getKey();
return new Pair<String, URL>(key, ret.get(key));
}
}
//查询服务,可以根据ip查询,根据服务名查询,也可以根据应用名查询
@Override
public Set<ServiceDTO> getServiceDTOS(String pattern, String filter, String env) {
List<Provider> providers = new ArrayList<>();
if (!filter.contains(Constants.ANY_VALUE) && !filter.contains(Constants.INTERROGATION_POINT)) {
// filter with specific string
if (Constants.IP.equals(pattern)) { //根据ip查询
providers = findByAddress(filter);
} else if (Constants.SERVICE.equals(pattern)) { //根据服务名查询
providers = findByService(filter);
} else if (Constants.APPLICATION.equals(pattern)) {//根据应用查询
providers = findByApplication(filter);
}
} else { //正则匹配
// filter with fuzzy search
Set<String> candidates = Collections.emptySet();
if (Constants.SERVICE.equals(pattern)) {
candidates = findServices();
} else if (Constants.APPLICATION.equals(pattern)) {
candidates = findApplications();
}
else if (Constants.IP.equals(pattern)) {
candidates = findAddresses().stream().collect(Collectors.toSet());
}
// replace dot symbol and asterisk symbol to java-based regex pattern
filter = filter.toLowerCase().replace(Constants.PUNCTUATION_POINT, Constants.PUNCTUATION_SEPARATOR_POINT);
// filter start with [* 、? 、+] will triggering PatternSyntaxException
if (filter.startsWith(Constants.ANY_VALUE)
|| filter.startsWith(Constants.INTERROGATION_POINT) || filter.startsWith(Constants.PLUS_SIGNS)) {
filter = Constants.PUNCTUATION_POINT + filter;
}
// search with no case insensitive
Pattern regex = Pattern.compile(filter, Pattern.CASE_INSENSITIVE);
for (String candidate : candidates) {
Matcher matcher = regex.matcher(candidate);
if (matcher.matches() || matcher.lookingAt()) {
if (Constants.SERVICE.equals(pattern)) {
providers.addAll(findByService(candidate));
}
else if (Constants.IP.equals(pattern)) {
providers.addAll(findByAddress(candidate));
}
else {
providers.addAll(findByApplication(candidate));
}
}
}
}
Set<ServiceDTO> result = convertProviders2DTO(providers);
return result;
}
@Override
public List<Provider> getServiceDTOSByQuery(String pattern, String filter, String env) {
List<Provider> providers = new ArrayList<>();
if (!filter.contains(Constants.ANY_VALUE) && !filter.contains(Constants.INTERROGATION_POINT)) {
// filter with specific string
if (Constants.IP.equals(pattern)) { //根据ip查询
providers = findByAddress(filter);
} else if (Constants.SERVICE.equals(pattern)) { //根据服务名查询
providers = findByService(filter);
} else if (Constants.APPLICATION.equals(pattern)) {//根据应用查询
providers = findByApplication(filter);
}
} else { //正则匹配
// filter with fuzzy search
Set<String> candidates = Collections.emptySet();
if (Constants.SERVICE.equals(pattern)) {
candidates = findServices();
} else if (Constants.APPLICATION.equals(pattern)) {
candidates = findApplications();
}
else if (Constants.IP.equals(pattern)) {
candidates = findAddresses().stream().collect(Collectors.toSet());
}
// replace dot symbol and asterisk symbol to java-based regex pattern
filter = filter.toLowerCase().replace(Constants.PUNCTUATION_POINT, Constants.PUNCTUATION_SEPARATOR_POINT);
// filter start with [* 、? 、+] will triggering PatternSyntaxException
if (filter.startsWith(Constants.ANY_VALUE)
|| filter.startsWith(Constants.INTERROGATION_POINT) || filter.startsWith(Constants.PLUS_SIGNS)) {
filter = Constants.PUNCTUATION_POINT + filter;
}
// search with no case insensitive
Pattern regex = Pattern.compile(filter, Pattern.CASE_INSENSITIVE);
for (String candidate : candidates) {
Matcher matcher = regex.matcher(candidate);
if (matcher.matches() || matcher.lookingAt()) {
if (Constants.SERVICE.equals(pattern)) {
providers.addAll(findByService(candidate));
}
else if (Constants.IP.equals(pattern)) {
providers.addAll(findByAddress(candidate));
}
else {
providers.addAll(findByApplication(candidate));
}
}
}
}
return providers;
}
/**
* Convert provider list to ServiceDTO list
*
* @param providers list of providers
* @return ServiceDTO list of front page
*/
public Set<ServiceDTO> convertProviders2DTO(List<Provider> providers) {
Set<ServiceDTO> result = new TreeSet<>();
for (Provider provider : providers) {
String app = provider.getApplication();
String service = provider.getService();
String group = Tool.getGroup(service);
String version = Tool.getVersion(service);
String interfaze = Tool.getInterface(service);
String address=provider.getAddress();
ServiceDTO s = new ServiceDTO();
s.setAppName(app);
s.setService(interfaze);
s.setGroup(group);
s.setVersion(version);
// s.setId(provider.getId());
// s.setAddress(address);
result.add(s);
}
return result;
}
}
/*
* 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 com.secoo.mall.dubbo.monitor.utils;
import org.apache.dubbo.common.io.Bytes;
import org.apache.dubbo.common.logger.Logger;
import org.apache.dubbo.common.logger.LoggerFactory;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
public class CoderUtil {
private static final Logger logger = LoggerFactory.getLogger(CoderUtil.class);
private static MessageDigest md;
private static final char[] hexCode = "0123456789ABCDEF".toCharArray();
static {
try {
md = MessageDigest.getInstance("MD5");
} catch (NoSuchAlgorithmException e) {
logger.error(e.getMessage(), e);
}
}
public static String MD5_16bit(String input) {
String hash = MD5_32bit(input);
if (hash == null) {
return null;
}
return hash.substring(8, 24);
}
public static String MD5_32bit(String input) {
if (input == null || input.length() == 0) {
return null;
}
md.update(input.getBytes());
byte[] digest = md.digest();
String hash = convertToString(digest);
return hash;
}
public static String MD5_32bit(byte[] input) {
if (input == null || input.length == 0) {
return null;
}
md.update(input);
byte[] digest = md.digest();
String hash = convertToString(digest);
return hash;
}
private static String convertToString(byte[] data) {
StringBuilder r = new StringBuilder(data.length * 2);
for (byte b : data) {
r.append(hexCode[(b >> 4) & 0xF]);
r.append(hexCode[(b & 0xF)]);
}
return r.toString();
}
public static String decodeBase64(String source) {
return new String(Bytes.base642bytes(source));
}
}
/*
* 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 com.secoo.mall.dubbo.monitor.utils;
import com.secoo.mall.dubbo.monitor.dubbo.Constants.Constants;
import org.apache.dubbo.common.utils.StringUtils;
import org.apache.dubbo.metadata.definition.model.MethodDefinition;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class ConvertUtil {
private ConvertUtil() {
}
public static Map<String, String> serviceName2Map(String serviceName) {
String group = Tool.getGroup(serviceName);
String version = Tool.getVersion(serviceName);
String interfaze = Tool.getInterface(serviceName);
Map<String, String> ret = new HashMap<String, String>();
if (!StringUtils.isEmpty(serviceName)) {
ret.put(Constants.INTERFACE_KEY, interfaze);
}
if (!StringUtils.isEmpty(version)) {
ret.put(Constants.VERSION_KEY, version);
}
if (!StringUtils.isEmpty(group)) {
ret.put(Constants.GROUP_KEY, group);
}
return ret;
}
public static Map methodList2Map(List<MethodDefinition> methods) {
Map<String, MethodDefinition> res = new HashMap<>();
for (int i = 0; i < methods.size(); i++) {
res.put(methods.get(i).getName(), methods.get(i));
}
return res;
}
}
package com.secoo.mall.dubbo.monitor.utils;
import org.apache.commons.lang3.StringUtils;
import java.time.*;
import java.time.format.DateTimeFormatter;
import java.time.temporal.ChronoUnit;
import java.time.temporal.TemporalAdjusters;
import java.time.temporal.TemporalUnit;
import java.util.Date;
/**
* 日期计算模式
*
* @author QIANGLU on 2019/9/11
*/
public class DateUtils {
public static final ZoneId ASIA_SHANGHAI = ZoneId.of("Asia/Shanghai");
/**
* 计算心跳
*/
public static long heartTime(long heart) {
Date heartTime = new Date(heart);
LocalDateTime.ofInstant(heartTime.toInstant(), ASIA_SHANGHAI);
long seconds = ChronoUnit.SECONDS.between(LocalDateTime.ofInstant(heartTime.toInstant(), ASIA_SHANGHAI), LocalDateTime.now(ASIA_SHANGHAI));
return seconds;
}
/**
* 计算时间差
*/
public static String calculateTimeDifference(LocalDateTime source) {
long seconds = ChronoUnit.SECONDS.between(source, LocalDateTime.now(ASIA_SHANGHAI));
StringBuilder builder = new StringBuilder();
long day = seconds / (60 * 60 * 24);
if (day != 0) {
builder.append(day).append(" 天").append(" ");
}
long hour = (seconds / (60 * 60)) - (day * 24);
if (hour != 0) {
builder.append(hour).append(" 小时").append(" ");
}
long min = (seconds / 60) - (hour * 60) - (day * 24 * 60);
if (min != 0) {
builder.append(min).append(" 分").append(" ");
}
long sec = seconds - (hour * 60 * 60) - (min * 60) - (day * 24 * 60 * 60);
if (sec != 0) {
builder.append(sec).append(" 秒");
}
return builder.toString();
}
public static String calculateTime(LocalDateTime source) {
long seconds = ChronoUnit.SECONDS.between(source, LocalDateTime.now(ASIA_SHANGHAI));
if (seconds > 300) {
return "offline";
}
return calculateTimeDifference(source) + "前";
}
public static LocalDate dateTime2Date(LocalDateTime localDateTime) {
return localDateTime.toLocalDate();
}
public static LocalDateTime getTime(String endTime) {
return getTimeByPattern(endTime,"yyyy-MM-dd HH:mm:ss");
}
public static LocalDateTime getTimeByPattern(String endTime,String pattern) {
LocalDateTime localDate = LocalDateTime.now();
if (StringUtils.isNotEmpty(endTime)) {
DateTimeFormatter formatter = DateTimeFormatter.ofPattern(pattern);
localDate = DateUtils.str2Date(endTime, formatter);
}
return localDate;
}
public static Date localDateToDate(LocalDate localDate) {
ZonedDateTime zdt = localDate.atStartOfDay(ZoneId.systemDefault());
return Date.from(zdt.toInstant());
}
public static Date stringToDate(String strDate) {
return stringToDate(strDate,"yyyy-MM-dd HH:mm:ss");
}
public static Date stringToDate(String strDate,String pattern) {
DateTimeFormatter formatter = DateTimeFormatter.ofPattern(pattern);
LocalDateTime localDateTime = LocalDateTime.parse(strDate, formatter);
ZonedDateTime zdt = localDateTime.atZone(ASIA_SHANGHAI);
return Date.from(zdt.toInstant());
}
/**
* 计算minutes分钟前的时间
*
* @param strDate
* @param minutes
* @return
*/
public static Date stringToDate(String strDate, long minutes) {
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
LocalDateTime localDateTime = LocalDateTime.parse(strDate, formatter);
localDateTime.minusMinutes(minutes);
ZonedDateTime zdt = localDateTime.atZone(ASIA_SHANGHAI);
return Date.from(zdt.toInstant());
}
/**
* 日期对象转换为日期对象
*
* @param localDate 日期对象
* @return 日期时间对象
*/
public static LocalDateTime dateToDateTime(LocalDate localDate) {
return LocalDateTime.of(localDate, LocalTime.NOON);
}
/**
* 字符串转换为日期
*
* @param strDate 字符串日期
* @return 日期对象 yyyy-mm-dd
*/
public static LocalDate str2Date(String strDate) {
return LocalDate.parse(strDate, DateTimeFormatter.ISO_DATE);
}
public static LocalDateTime str2Date(String strDate, DateTimeFormatter formatter) {
return LocalDateTime.parse(strDate, formatter);
}
/**
* 日期对象转换为字符串
*
* @param localDate 日期对象
* @return 日期字符串 yyyy-mm-dd
*/
public static String date2Str(LocalDate localDate) {
return localDate.format(DateTimeFormatter.ISO_DATE);
}
/**
* 日期时间对象转换为字符串
*
* @param localDateTime 日期时间对象
* @param dateTimeFormatter 格式化字符串
* @return 日期字符串
*/
public static String dateTime2Str(LocalDateTime localDateTime, String dateTimeFormatter) {
return localDateTime.format(DateTimeFormatter.ofPattern(dateTimeFormatter));
}
/**
* 日期时间转字符串函数
* 返回ISO标准的日期字符串
*
* @param localDateTime 日期时间对象
* @return 日期字符串
*/
public static String dateTime2Str(LocalDateTime localDateTime) {
return localDateTime.format(DateTimeFormatter.ISO_DATE_TIME);
}
/**
* 计算两个日期之间相差的天数
*
* @param date1 起始日期
* @param date2 结束日期
* @return
*/
public static int daysBetween(LocalDate date1, LocalDate date2) {
Period period = Period.between(date1, date2);
return period.getDays();
}
/**
* 计算两个日期之间相差的月数
*
* @param date1 起始日期
* @param date2 结束日期
* @return
*/
public static int monthsBetween(LocalDate date1, LocalDate date2) {
Period period = Period.between(date1, date2);
return period.getMonths();
}
/**
* 计算两个日期之间相差的年数
*
* @param date1 起始日期
* @param date2 结束日期
* @return
*/
public static int yearsBetween(LocalDate date1, LocalDate date2) {
Period period = Period.between(date1, date2);
return period.getYears();
}
/**
* 计算两个日期之间相差的天数
*
* @param date1 起始日期
* @param date2 结束日期
* @return
*/
public static int daysBetween(Date date1, Date date2) {
Instant instantDate1 = date1.toInstant();
Instant instantDate2 = date2.toInstant();
LocalDate localDate1 = instantDate1.atZone(ASIA_SHANGHAI).toLocalDate();
LocalDate localDate2 = instantDate2.atZone(ASIA_SHANGHAI).toLocalDate();
instantDate1.atZone(ASIA_SHANGHAI);
Period period = Period.between(localDate1, localDate2);
return period.getDays();
}
/**
* 计算两个日期之间相差的月数
*
* @param date1 起始日期
* @param date2 结束日期
* @return
*/
public static int monthsBetween(Date date1, Date date2) {
Instant instantDate1 = date1.toInstant();
Instant instantDate2 = date2.toInstant();
LocalDate localDate1 = instantDate1.atZone(ASIA_SHANGHAI).toLocalDate();
LocalDate localDate2 = instantDate2.atZone(ASIA_SHANGHAI).toLocalDate();
instantDate1.atZone(ASIA_SHANGHAI);
Period period = Period.between(localDate1, localDate2);
return period.getMonths();
}
/**
* 计算两个日期之间相差的年数
*
* @param date1 起始日期
* @param date2 结束日期
* @return
*/
public static int yearsBetween(Date date1, Date date2) {
Instant instantDate1 = date1.toInstant();
Instant instantDate2 = date2.toInstant();
LocalDate localDate1 = instantDate1.atZone(ASIA_SHANGHAI).toLocalDate();
LocalDate localDate2 = instantDate2.atZone(ASIA_SHANGHAI).toLocalDate();
instantDate1.atZone(ASIA_SHANGHAI);
Period period = Period.between(localDate1, localDate2);
return period.getYears();
}
/**
* 获取指定日期对象当前月的起始日
*
* @param localDate 指定日期
* @return
*/
public static int getFirstDayInMonth(LocalDate localDate) {
LocalDate result = localDate.with(TemporalAdjusters.firstDayOfMonth());
return result.getDayOfMonth();
}
/**
* 获取指定日期对象的当前月的结束日
*
* @param localDate 指定日期
* @return
*/
public static int getLastDayInMonth(LocalDate localDate) {
LocalDate result = localDate.with(TemporalAdjusters.lastDayOfMonth());
return result.getDayOfMonth();
}
/**
* 获取指定日期对象本月的某周某天的日期
*
* @param localDate 日期对象
* @param weekNumber 周
* @param dayNumber 日
* @return
*/
public static LocalDate getLocalDateBydayAndWeek(LocalDate localDate, int weekNumber, int dayNumber) {
return localDate.with(TemporalAdjusters.dayOfWeekInMonth(weekNumber, DayOfWeek.of(dayNumber)));
}
public static String getDateFormat(long timestamp) {
LocalDateTime heartTime = LocalDateTime.ofInstant(new Date(timestamp).toInstant(), DateUtils.ASIA_SHANGHAI);
return heartTime.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
}
public static String getDateFormat(Date date) {
return getDateFormat(date,"yyyy-MM-dd HH:mm:ss");
}
public static String getDateFormat(Date date,String format) {
LocalDateTime time = LocalDateTime.ofInstant(date.toInstant(), DateUtils.ASIA_SHANGHAI);
return time.format(DateTimeFormatter.ofPattern(format));
}
public static LocalDateTime minu(LocalDateTime time, long number, TemporalUnit field) {
return time.minus(number, field);
}
}
package com.secoo.mall.dubbo.monitor.utils;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.HttpEntity;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.mime.MultipartEntityBuilder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.FileInputStream;
import java.util.HashMap;
/**
* @ClassName FileSystemUtils
* @Author QIANGLU
* @Date 2019/12/4 2:08 下午
* @Version 1.0
*/
public class FileUploadUtils {
private static String DEV_PATH = "http://172.17.105.26:6080/file-server/api/v1/upload/single";
private static Logger logger = LoggerFactory.getLogger(FileUploadUtils.class);
private static String APP_SECRET = "exwarn_secoo";
/**
* 上传文件
*
* @param fileName 文件名称
* @param path 内容
* @param appid 应用唯一标识
* @param uri 发送地址
*/
public static String uploadFile(String fileName, String path, String appid, String uri, String appSecret) {
try {
if (StringUtils.isEmpty(uri)) {
logger.warn("uploadFile uri can not null");
return "";
}
logger.info("开始进行文件上传,fileName:{} , path: {} ,appid:{} ",fileName,path,appid);
MultipartEntityBuilder builder = MultipartEntityBuilder.create();
builder.addTextBody("fileName", fileName);
builder.addTextBody("appId", appid);
builder.addTextBody("appSecret", appSecret);
builder.addTextBody("storageClass", "2");
builder.addTextBody("isDownloadLink", "1");
builder.addBinaryBody("file", new FileInputStream(path), ContentType.MULTIPART_FORM_DATA, fileName);
HttpEntity entity = builder.build();
String result = HttpClientUtils.doPost(uri, entity, new HashMap<>());
JSONObject obj = JSON.parseObject(result);
Integer code = obj.getInteger("code");
if (code == null && code.intValue() != 0) {
logger.error("upload fail :{}", result);
return "";
}
logger.info("upload succ -> filename:{},result:{}", fileName, result);
JSONObject data = obj.getJSONObject("data");
return data.getString("filePath");
} catch (Exception e) {
logger.warn("upload file fial,fileName:{},appid:{}.,error:{}", fileName, appid, e);
}
return "";
}
public static String downloadFile(String fileName, String appid, String uri) {
if (StringUtils.isEmpty(uri)) {
logger.warn("uploadFile uri can not null");
return null;
}
try {
MultipartEntityBuilder builder = MultipartEntityBuilder.create();
builder.addTextBody("appId", appid);
builder.addTextBody("fileName", fileName);
builder.addTextBody("policy", "1");
builder.addTextBody("appSecret", APP_SECRET);
HttpEntity entity = builder.build();
String result = HttpClientUtils.doPost(uri, entity, new HashMap<>());
JSONObject datas = JSON.parseObject(result);
JSONObject data = datas.getJSONObject("data");
return data != null ? data.getString("filePath") : null;
} catch (Exception e) {
logger.error("下载文件出错,fileName:{},appid:{},error:{}", fileName, appid, e);
}
return null;
}
}
package com.secoo.mall.dubbo.monitor.utils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.zip.GZIPInputStream;
import java.util.zip.GZIPOutputStream;
/**
* @author luqiang
*/
public class GzipUtils {
private static Logger logger = LoggerFactory.getLogger(GzipUtils.class);
/**
* 压缩字符串
*
* @param body 压缩的字符串
* @return 压缩后的字符串
*/
public static String compress(String body) {
if (StringUtils.isEmpty(body)) {
return body;
}
try {
ByteArrayOutputStream outputStream = compressToStream(body);
if (outputStream != null) {
// 通过解码字节将缓冲区内容转换为字符串
return new String(outputStream.toByteArray(), "ISO-8859-1");
}
} catch (Exception e) {
logger.warn("GZIP compress 压缩失败,使用源文件", e);
}
return body;
}
/**
* 压缩字符串
*
* @param body 压缩的字符串
* @return 压缩后的字符串
*/
public static ByteArrayOutputStream compressToStream(String body) {
try (
ByteArrayOutputStream bos = new ByteArrayOutputStream();
GZIPOutputStream os = new GZIPOutputStream(bos);
) {
// 写入输出流
os.write(body.getBytes());
return bos;
} catch (IOException e) {
logger.warn("GZIP compressToStream 压缩失败,使用源文件", e);
}
return null;
}
/**
* 解压缩字符串
*
* @param body 解压缩的字符串
* @return 解压后的字符串
*/
public static String decompress(String body) {
if (StringUtils.isEmpty(body)) {
return body;
}
byte[] buf = new byte[1024];
int len = 0;
try (
ByteArrayInputStream bis = new ByteArrayInputStream(body.getBytes("ISO-8859-1"));
ByteArrayOutputStream bos = new ByteArrayOutputStream();
GZIPInputStream is = new GZIPInputStream(bis);
) {
// 将未压缩数据读入字节数组
while ((len = is.read(buf)) != -1) {
// 将指定 byte 数组中从偏移量 off 开始的 len 个字节写入此byte数组输出流
bos.write(buf, 0, len);
}
// 通过解码字节将缓冲区内容转换为字符串
return new String(bos.toByteArray());
} catch (Exception e) {
logger.warn("GZIP 解压失败,使用源文件", e);
return body;
}
}
}
package com.secoo.mall.dubbo.monitor.utils;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import org.apache.commons.io.IOUtils;
import org.apache.http.HttpEntity;
import org.apache.http.NameValuePair;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.*;
import org.apache.http.client.utils.URIBuilder;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.conn.ssl.TrustSelfSignedStrategy;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.ssl.SSLContexts;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.StringUtils;
import javax.net.ssl.SSLContext;
import java.io.IOException;
import java.io.InputStream;
import java.net.URI;
import java.nio.charset.Charset;
import java.security.KeyManagementException;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* httpClient封装
*
* @author QIANG
*/
public class HttpClientUtils {
private static Logger LOG = LoggerFactory.getLogger(HttpClientUtils.class);
private static PoolingHttpClientConnectionManager connMgr;
private static RequestConfig requestConfig;
private static final int CONNECT_TIMEOUT = 100000;
private static final int SOCKET_TIMEOUT = 100000;
private static final int REQUEST_TIMEOUT = 2000;
private static final String CHARSET = "UTF-8";
static {
// 设置连接池
connMgr = new PoolingHttpClientConnectionManager();
// 设置连接池大小
connMgr.setMaxTotal(300);
connMgr.setDefaultMaxPerRoute(300);
RequestConfig.Builder configBuilder = RequestConfig.custom();
// 请求超时时间
configBuilder.setConnectTimeout(CONNECT_TIMEOUT);
// 连接不够时等待超时时间,不设置将阻塞线程
configBuilder.setConnectionRequestTimeout(REQUEST_TIMEOUT);
// 等待数据超时时间
configBuilder.setSocketTimeout(SOCKET_TIMEOUT);
LOG.debug("Http参数设置,连接超时时间[{}],Socket超时时间[{}],请求超时时间[{}]", CONNECT_TIMEOUT, SOCKET_TIMEOUT);
requestConfig = configBuilder.build();
}
/**
* 设置连接超时和请求超时
*
* @param connectTimeout
* @param socketTimeout
* @param connectionRequestTimeout
*/
public static void setHttpParam(int connectTimeout, int socketTimeout, int connectionRequestTimeout) {
RequestConfig.Builder configBuilder = RequestConfig.custom();
configBuilder.setConnectTimeout(connectTimeout);
configBuilder.setSocketTimeout(socketTimeout);
configBuilder.setConnectionRequestTimeout(connectionRequestTimeout);
LOG.debug("Http参数自定义设置,请求超时时间[{}],等待数据超时时间[{}],连接不够时等待超时时间[{}]", connectTimeout, socketTimeout,
connectionRequestTimeout);
requestConfig = configBuilder.build();
}
/**
* 发送 GET 请求(HTTP),不带输入数据
*
* @param url
* @return
* @throws Exception
*/
public static String doGet(String url) {
try {
String result = doGet(url, new HashMap<>(10));
return result;
} catch (Exception e) {
LOG.error("发送 GET 请求ERROR :{}", e);
}
return "";
}
/**
* 发送 GET 请求(HTTP),K-V形式
*
* @param url
* @param params
* @return
* @throws Exception
*/
public static String doGet(String url, Map<String, Object> params) throws Exception {
return doGet(url, params, CHARSET, new HashMap<>(16));
}
public static String doGet(String url, Map<String, Object> params, String charset, Map<String, String> headers) throws Exception {
String result = null;
if (StringUtils.isEmpty(url)) {
LOG.debug("warn:doGet url is null or '' ");
return result;
}
List<NameValuePair> pairList = new ArrayList<>(params.size());
for (Map.Entry<String, Object> entry : params.entrySet()) {
pairList.add(new BasicNameValuePair(entry.getKey(), entry.getValue().toString()));
}
CloseableHttpClient httpclient = HttpClients.custom().setDefaultRequestConfig(requestConfig)
.setConnectionManager(connMgr).build();
CloseableHttpResponse response = null;
InputStream instream = null;
try {
URIBuilder uriBuilder = new URIBuilder(url);
uriBuilder.setCharset(Charset.forName(StringUtils.isEmpty(charset) ? CHARSET : charset));
uriBuilder.addParameters(pairList);
URI uri = uriBuilder.build();
HttpGet httpGet = new HttpGet(uri);
headers.entrySet().forEach(entry -> {
httpGet.setHeader(entry.getKey(), entry.getValue());
});
response = httpclient.execute(httpGet);
HttpEntity entity = response.getEntity();
if (entity != null) {
instream = entity.getContent();
result = IOUtils.toString(instream, charset);
}
} finally {
if (null != instream) {
instream.close();
}
if (null != response) {
response.close();
}
LOG.debug("close instream response httpClient connection succ");
}
return result;
}
public static HttpEntity doGetByDefault(String url) throws Exception {
CloseableHttpClient httpclient = HttpClients.custom().setDefaultRequestConfig(requestConfig)
.setConnectionManager(connMgr).build();
HttpGet httpGet = new HttpGet(url);
CloseableHttpResponse response = httpclient.execute(httpGet);
LOG.info("doGet statusCode:{}", response.getStatusLine().getStatusCode());
return response.getEntity();
}
public static String doDelete(String url, Map<String, String> headers, Map<String, String> params) throws Exception {
CloseableHttpClient httpclient = HttpClients.custom().setDefaultRequestConfig(requestConfig)
.setConnectionManager(connMgr).build();
CloseableHttpResponse response = null;
InputStream instream = null;
List<NameValuePair> pairList = new ArrayList<>(params.size());
params.entrySet().forEach(entry -> {
pairList.add(new BasicNameValuePair(entry.getKey(), entry.getValue()));
});
try {
URIBuilder uriBuilder = new URIBuilder(url);
uriBuilder.setCharset(Charset.forName(CHARSET));
uriBuilder.addParameters(pairList);
URI uri = uriBuilder.build();
HttpDelete httpDelete = new HttpDelete(uri);
headers.entrySet().forEach(entry -> {
httpDelete.setHeader(entry.getKey(), entry.getValue());
});
response = httpclient.execute(httpDelete);
LOG.info("httpDelete statusCode:{}", response.getStatusLine().getStatusCode());
HttpEntity entity = response.getEntity();
if (entity != null) {
instream = entity.getContent();
return IOUtils.toString(instream, CHARSET);
}
} finally {
if (null != instream) {
instream.close();
}
if (null != response) {
response.close();
}
LOG.debug("close instream response httpClient connection succ");
}
return "";
}
/**
* 发送 PUT 请求(HTTP),K-V形式
*
* @param url
* @param params
* @return
* @throws Exception
*/
public static String doPut(String url, Map<String, Object> params, String charset, Map<String, String> headers, String body) throws Exception {
String result = null;
if (StringUtils.isEmpty(url)) {
return result;
}
List<NameValuePair> pairList = new ArrayList<>(params.size());
params.entrySet().forEach(entry -> {
pairList.add(new BasicNameValuePair(entry.getKey(), entry.getValue().toString()));
});
CloseableHttpClient httpclient = HttpClients.custom().setDefaultRequestConfig(requestConfig)
.setConnectionManager(connMgr).build();
CloseableHttpResponse response = null;
InputStream instream = null;
try {
URIBuilder uriBuilder = new URIBuilder(url);
uriBuilder.setCharset(Charset.forName(StringUtils.isEmpty(charset) ? CHARSET : charset));
uriBuilder.addParameters(pairList);
URI uri = uriBuilder.build();
HttpPut httpPut = new HttpPut(uri);
if (!StringUtils.isEmpty(body)) {
httpPut.setEntity(new StringEntity(body, "UTF-8"));
}
if (headers != null && headers.size() > 0) {
for (Map.Entry<String, String> entry : headers.entrySet()) {
httpPut.setHeader(entry.getKey(), entry.getValue());
}
}
response = httpclient.execute(httpPut);
LOG.info("doGet statusCode:{}", response.getStatusLine().getStatusCode());
HttpEntity entity = response.getEntity();
if (entity != null) {
instream = entity.getContent();
result = IOUtils.toString(instream, charset);
}
} finally {
if (null != instream) {
instream.close();
}
if (null != response) {
response.close();
}
LOG.debug("close instream response httpClient connection succ");
}
return result;
}
/**
* 发送 POST 请求(HTTP),不带输入数据
*
* @param url
* @return
* @throws Exception
*/
public static String doPost(String url) throws Exception {
return doPost(url, new HashMap<>(16));
}
/**
* 发送 POST 请求(HTTP),K-V形式
*
* @param url API接口URL
* @param params 参数map
* @return
* @throws Exception
*/
public static String doPost(String url, Map<String, Object> params) throws Exception {
if (StringUtils.isEmpty(url)) {
LOG.info("warn:doPost url is null or '' ");
return null;
}
List<NameValuePair> pairList = new ArrayList<>(params.size());
for (Map.Entry<String, Object> entry : params.entrySet()) {
pairList.add(new BasicNameValuePair(entry.getKey(), entry.getValue().toString()));
}
HttpPost httpPost = new HttpPost(url);
httpPost.setEntity(new UrlEncodedFormEntity(pairList, Charset.forName(CHARSET)));
return send(httpPost, false);
}
/**
* 发送 POST 请求(HTTP),xml
*
* @param url API接口URL
* @param xml xml 参数
* @return
* @throws Exception
*/
public static String doPost(String url, String xml) throws Exception {
if (StringUtils.isEmpty(url)) {
LOG.info("warn:doPost url is null or '' ");
return null;
}
HttpPost httpPost = new HttpPost(url);
httpPost.setEntity(new StringEntity(xml, "GBK"));
return send(httpPost, false);
}
/**
* 发送 POST 请求(HTTP),JSON形式
*
* @param url
* @param json json对象
* @return
* @throws Exception
*/
public static String doPost(String url, Object json) throws Exception {
if (StringUtils.isEmpty(url)) {
LOG.error("warn:doPostByJson url is null or '' ");
return null;
}
HttpPost httpPost = new HttpPost(url);
StringEntity stringEntity = new StringEntity(json.toString(), CHARSET);
stringEntity.setContentType("application/json");
httpPost.setEntity(stringEntity);
return send(httpPost, false);
}
public static String doPost(String url, HttpEntity entity, Map<String, String> headers) throws Exception {
if (StringUtils.isEmpty(url)) {
LOG.error("warn:doPostByJson url is null or '' ");
return null;
}
HttpPost httpPost = new HttpPost(url);
httpPost.setEntity(entity);
headers.forEach((k, v) -> {
httpPost.setHeader(k, v);
});
return send(httpPost, false);
}
/**
* 发送 SSL POST 请求(HTTPS),K-V形式
*
* @param apiUrl API接口URL
* @param params 参数map
* @return
* @throws Exception
*/
public static String doPostSsl(String apiUrl, Map<String, Object> params) throws Exception {
if (StringUtils.isEmpty(apiUrl)) {
LOG.info("warn:doPostSSL url is null or '' ");
return null;
}
List<NameValuePair> pairList = new ArrayList<>(params.size());
for (Map.Entry<String, Object> entry : params.entrySet()) {
NameValuePair pair = new BasicNameValuePair(entry.getKey(), entry.getValue().toString());
pairList.add(pair);
}
HttpPost httpPost = new HttpPost(apiUrl);
httpPost.setEntity(new UrlEncodedFormEntity(pairList, Charset.forName("utf-8")));
return send(httpPost, true);
}
/**
* 发送 SSL POST 请求(HTTPS),JSON形式
*
* @param apiUrl API接口URL
* @param json JSON对象
* @return
* @throws Exception
*/
public static String doPostSsl(String apiUrl, Object json) throws Exception {
if (StringUtils.isEmpty(apiUrl)) {
LOG.info("warn:doPostSSL By Json url is null or '' ");
return null;
}
StringEntity stringEntity = new StringEntity(json.toString(), CHARSET);
HttpPost httpPost = new HttpPost(apiUrl);
httpPost.setEntity(stringEntity);
stringEntity.setContentEncoding(CHARSET);
stringEntity.setContentType("application/json");
return send(httpPost, true);
}
/**
* 发送Post请求
*
* @param httpPost
* @return
* @throws IOException
* @throws ClientProtocolException
* @throws KeyStoreException
* @throws NoSuchAlgorithmException
* @throws KeyManagementException
*/
private static String send(HttpPost httpPost, boolean isSsl) throws ClientProtocolException, IOException,
KeyManagementException, NoSuchAlgorithmException, KeyStoreException {
CloseableHttpClient httpClient = null;
InputStream instream = null;
String result = null;
CloseableHttpResponse response = null;
try {
if (isSsl) {
SSLContext sslcontext = SSLContexts.custom().loadTrustMaterial(null, new TrustSelfSignedStrategy())
.build();
SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(sslcontext);
httpClient = HttpClients.custom().setConnectionManager(connMgr).setSSLSocketFactory(sslsf)
.setDefaultRequestConfig(requestConfig).build();
} else {
httpClient = HttpClients.custom().setDefaultRequestConfig(requestConfig).setConnectionManager(connMgr)
.build();
}
response = httpClient.execute(httpPost);
HttpEntity entity = response.getEntity();
if (entity != null) {
instream = entity.getContent();
result = IOUtils.toString(instream, CHARSET);
}
} finally {
if (null != instream) {
instream.close();
}
if (null != response) {
response.close();
}
LOG.debug("close instream response httpClient connection succ");
}
return result;
}
public static void checkResult(String result,String codeMsg){
JSONObject data = JSON.parseObject(result);
int resultCode = data.getInteger(StringUtils.isEmpty(codeMsg)?"errcode":codeMsg);
if (resultCode != 0) {
LOG.error("send http resultCode not 0,result:{}", result);
}
}
}
package com.secoo.mall.dubbo.monitor.utils;
import java.io.UnsupportedEncodingException;
import java.security.MessageDigest;
/**
* @ClassName Md5Utils
* @Author QIANGLU
* @Date 2019/12/30 9:05 上午
* @Version 1.0
*/
public class Md5Utils {
private static final int HEX_VALUE_COUNT = 16;
public Md5Utils() {
}
public static String getMD5(byte[] bytes) {
char[] hexDigits = new char[]{'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};
char[] str = new char[32];
try {
MessageDigest md = MessageDigest.getInstance("MD5");
md.update(bytes);
byte[] tmp = md.digest();
int k = 0;
for(int i = 0; i < HEX_VALUE_COUNT; ++i) {
byte byte0 = tmp[i];
str[k++] = hexDigits[byte0 >>> 4 & 15];
str[k++] = hexDigits[byte0 & 15];
}
} catch (Exception var8) {
var8.printStackTrace();
}
return new String(str);
}
public static String getMD5(String value, String encode) {
String result = "";
try {
result = getMD5(value.getBytes(encode));
} catch (UnsupportedEncodingException var4) {
var4.printStackTrace();
}
return result;
}
}
package com.secoo.mall.dubbo.monitor.utils;
import java.lang.management.ManagementFactory;
import java.net.*;
import java.util.*;
/**
* @author luqiang
*/
public class OSUtil {
private static volatile String OS_NAME;
private static volatile String HOST_NAME;
private static volatile List<String> IPV4_LIST;
private static volatile int PROCESS_NO = 0;
public static int getAvailableProcessors() {
return Runtime.getRuntime().availableProcessors() - 1;
}
public static String getOsName() {
if (OS_NAME == null) {
OS_NAME = System.getProperty("os.name");
}
return OS_NAME;
}
public static String getHostName() {
if (HOST_NAME == null) {
try {
InetAddress host = InetAddress.getLocalHost();
HOST_NAME = host.getHostName();
} catch (UnknownHostException e) {
HOST_NAME = "unknown";
}
}
return HOST_NAME;
}
/**
* 获取系统环境变量分隔符
*
* @return
*/
public static String getPathSeparator() {
return System.getProperty("path.separator");
}
public static List<String> getAllIPV4() {
if (IPV4_LIST == null) {
IPV4_LIST = new LinkedList<String>();
try {
Enumeration<NetworkInterface> interfs = NetworkInterface.getNetworkInterfaces();
while (interfs.hasMoreElements()) {
NetworkInterface networkInterface = interfs.nextElement();
Enumeration<InetAddress> inetAddresses = networkInterface.getInetAddresses();
while (inetAddresses.hasMoreElements()) {
InetAddress address = inetAddresses.nextElement();
if (address instanceof Inet4Address) {
String addressStr = address.getHostAddress();
if ("127.0.0.1".equals(addressStr)) {
continue;
}
IPV4_LIST.add(addressStr);
}
}
}
} catch (SocketException e) {
}
}
return IPV4_LIST;
}
public static int getProcessNo() {
if (PROCESS_NO == 0) {
try {
PROCESS_NO = Integer.parseInt(ManagementFactory.getRuntimeMXBean().getName().split("@")[0]);
} catch (Exception e) {
PROCESS_NO = -1;
}
}
return PROCESS_NO;
}
public static Map<String, String> buildOSInfo() {
Map<String, String> osInfo = new HashMap<>();
String osName = getOsName();
if (osName != null) {
osInfo.put("os_name", osName);
}
String hostName = getHostName();
if (hostName != null) {
osInfo.put("host_name", hostName);
}
List<String> allIPV4 = getAllIPV4();
if (allIPV4.size() > 0) {
osInfo.put("ipv4", Arrays.toString(allIPV4.toArray()));
}
osInfo.put("process_no", getProcessNo() + "");
osInfo.put("language", "java");
return osInfo;
}
}
/*
* 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 com.secoo.mall.dubbo.monitor.utils;
import java.util.Map;
public class Pair<K, V> implements Map.Entry<K, V> {
private K key;
private V value;
public Pair() {
}
public Pair(K key, V value) {
this.key = key;
this.value = value;
}
public K getKey() {
return key;
}
public void setKey(K key) {
this.key = key;
}
public V getValue() {
return value;
}
public V setValue(V value) {
V old = this.value;
this.value = value;
return old;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((key == null) ? 0 : key.hashCode());
result = prime * result + ((value == null) ? 0 : value.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Pair<?, ?> other = (Pair<?, ?>) obj;
if (key == null) {
if (other.key != null)
return false;
} else if (!key.equals(other.key))
return false;
if (value == null) {
if (other.value != null)
return false;
} else if (!value.equals(other.value))
return false;
return true;
}
}
\ No newline at end of file
/*
* 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 com.secoo.mall.dubbo.monitor.utils;
import org.apache.dubbo.common.utils.StringUtils;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* String parsing tools related to interpolation, including Glob mode, Query string, Service URL processing.
*
*/
public class ParseUtils {
private static final ConcurrentMap<String, Pattern>
REPLACE_PARAMETER_PATTERNS = new ConcurrentHashMap<String, Pattern>();
public static String METHOD_SPLIT = ",";
private static Pattern VARIABLE_PATTERN = Pattern.compile(
"\\$\\s*\\{?\\s*([\\._0-9a-zA-Z]+)\\s*\\}?");
private static Pattern QUERY_PATTERN = Pattern
.compile("([&=]?)\\s*([^&=\\s]+)");
private ParseUtils() {
}
/**
* Execute interpolation (variable insertion).
*
* @param expression Expression string containing variables. Variable names in expressions can also be enclosed in <code> {} </ code>。
* @param params Variable set. Variable names can include <code>. </ Code>, <code> _ </ code> characters.
* @return After the completion of the interpolation string. Such as: <code> <pre> xxx $ {name} zzz -> xxxjerryzzz </ pre> </ code> (where the variable name = "jerry")
* @throws IllegalStateException The variables used in the expression string are not in the variable set
*/
// FIXME Is it reasonable to throw an IllegalStateException??
public static String interpolate(String expression, Map<String, String> params) {
if (expression == null || expression.length() == 0) {
throw new IllegalArgumentException("glob pattern is empty!");
}
if (expression.indexOf('$') < 0) {
return expression;
}
Matcher matcher = VARIABLE_PATTERN.matcher(expression);
StringBuffer sb = new StringBuffer();
while (matcher.find()) { // match one by one
String key = matcher.group(1);
String value = params == null ? null : params.get(key);
if (value == null) {
value = "";
}
matcher.appendReplacement(sb, value);
}
matcher.appendTail(sb);
return sb.toString();
}
public static List<String> interpolate(List<String> expressions, Map<String, String> params) {
List<String> ret = new ArrayList<String>();
if (null == expressions || expressions.isEmpty()) {
return ret;
}
for (String expr : expressions) {
ret.add(interpolate(expr, params));
}
return ret;
}
/**
* Match Glob mode. The current implementation only supports <code>*</ code> and supports only one. Does not support <code>?</ Code>.
* @return For code or value of <code> null </ code>, return <code> false </ code> directly.
*/
public static boolean isMatchGlobPattern(String pattern, String value) {
if ("*".equals(pattern))
return true;
if ((pattern == null || pattern.length() == 0)
&& (value == null || value.length() == 0))
return true;
if ((pattern == null || pattern.length() == 0)
|| (value == null || value.length() == 0))
return false;
int i = pattern.lastIndexOf('*');
// No asterisk found
if (i == -1) {
return value.equals(pattern);
}
// Asterisk at the end
else if (i == pattern.length() - 1) {
return value.startsWith(pattern.substring(0, i));
}
// Asterisk at the beginning
else if (i == 0) {
return value.endsWith(pattern.substring(i + 1));
}
// Asterisk in the middle of the string
else {
String prefix = pattern.substring(0, i);
String suffix = pattern.substring(i + 1);
return value.startsWith(prefix) && value.endsWith(suffix);
}
}
/**
* Whether to match Glob mode. Glob mode is the expression to be interpolated. Glob pattern has more than one, as long as matching a pattern, that match is successful.
*
* @param patternsNeedInterpolate Multiple Glob patterns to interpolate
     * @param interpolateParams Set of variables used for interpolation
     * @param value Glob mode value
*/
public static boolean isMatchGlobPatternsNeedInterpolate(
Collection<String> patternsNeedInterpolate,
Map<String, String> interpolateParams, String value) {
if (patternsNeedInterpolate != null && !patternsNeedInterpolate.isEmpty()) {
for (String patternNeedItp : patternsNeedInterpolate) {
if (StringUtils.isEmpty(patternNeedItp)) {
continue;
}
// FIXME ERROR!! The original implementation, here and only the first non-blank pattern comparison, return the corresponding result!
// FIXME ERROR!! Should be confirmed with Liang Fei!!
String pattern = interpolate(patternNeedItp, interpolateParams);
if (isMatchGlobPattern(pattern, value)) {
return true;
}
}
}
return false;
}
/**
* Returns the entries in the collection that match the Glob pattern.
*/
public static Set<String> filterByGlobPattern(String pattern, Collection<String> values) {
Set<String> ret = new HashSet<String>();
if (pattern == null || values == null) {
return ret;
}
for (String v : values) {
if (isMatchGlobPattern(pattern, v)) {
ret.add(v);
}
}
return ret;
}
/**
* Find the string that matches the Glob pattern. Multiple patterns, as long as a match pattern, it returns this string.
*/
public static Set<String> filterByGlobPattern(Collection<String> patterns, Collection<String> values) {
Set<String> ret = new HashSet<String>();
if (null == patterns || values == null || patterns.isEmpty() || values.isEmpty()) {
return ret;
}
for (String p : patterns) {
for (String v : values) {
if (isMatchGlobPattern(p, v)) {
ret.add(v);
}
}
}
return ret;
}
/**
* Whether two Glob patterns have intersection.
*/
public static boolean hasIntersection(String glob1, String glob2) {
if (null == glob1 || null == glob2) {
return false;
}
if (glob1.contains("*") && glob2.contains("*")) {
int index1 = glob1.indexOf("*");
int index2 = glob2.indexOf("*");
String s11 = glob1.substring(0, index1);
String s12 = glob1.substring(index1 + 1, glob1.length());
String s21 = glob2.substring(0, index2);
String s22 = glob2.substring(index2 + 1, glob2.length());
if (!s11.startsWith(s21) && !s21.startsWith(s11)) return false;
if (!s12.endsWith(s22) && !s22.endsWith(s12)) return false;
return true;
} else if (glob1.contains("*")) {
return isMatchGlobPattern(glob1, glob2);
} else if (glob2.contains("*")) {
return isMatchGlobPattern(glob2, glob1);
} else {
return glob1.equals(glob2);
}
}
/**
* Parse Query String into Map. For strings that have only Key, key3 = </ code> is ignored.
*
* @param keyPrefix In the output of the Map Key plus a unified prefix.
* @param query Query String,For example: <code>key1=value1&key2=value2</code>
* @return When Query String is <code>key1=value1&key2=value2</code>, and prefix is <code>pre.</code>,
* then <code>Map{pre.key1=value1, pre.key=value2}</code> will be returned.
*/
// FIXME Is it reasonable to throw an IllegalStateException??
public static Map<String, String> parseQuery(String keyPrefix, String query) {
if (query == null)
return new HashMap<String, String>();
if (keyPrefix == null)
keyPrefix = "";
Matcher matcher = QUERY_PATTERN.matcher(query);
Map<String, String> routeQuery = new HashMap<String, String>();
String key = null;
while (matcher.find()) { // Match one by one
String separator = matcher.group(1);
String content = matcher.group(2);
if (separator == null || separator.length() == 0
|| "&".equals(separator)) {
if (key != null)
throw new IllegalStateException("Illegal query string \""
+ query + "\", The error char '" + separator
+ "' at index " + matcher.start() + " before \""
+ content + "\".");
key = content;
} else if ("=".equals(separator)) {
if (key == null)
throw new IllegalStateException("Illegal query string \""
+ query + "\", The error char '" + separator
+ "' at index " + matcher.start() + " before \""
+ content + "\".");
routeQuery.put(keyPrefix + key, content);
key = null;
} else {
if (key == null)
throw new IllegalStateException("Illegal query string \""
+ query + "\", The error char '" + separator
+ "' at index " + matcher.start() + " before \""
+ content + "\".");
}
}
/*if (key != null)
throw new IllegalStateException("Illegal route rule \"" + query
+ "\", The error in the end char: " + key);*/
return routeQuery;
}
public static Map<String, String> parseQuery(String query) {
return parseQuery("", query);
}
/**
* Replace the value of the url parameter.
*/
public static String replaceParameter(String query, String key, String value) {
if (query == null || query.length() == 0) {
return key + "=" + value;
}
if (query.indexOf(key + "=") == -1) {
return query + "&" + key + "=" + value;
}
Pattern pattern = REPLACE_PARAMETER_PATTERNS.get(key);
if (pattern == null) {
pattern = Pattern.compile(key.replaceAll("([^(_0-9A-Za-z)])", "\\\\$0") + "=[^&]+");
}
Matcher matcher = pattern.matcher(query);
StringBuffer sb = new StringBuffer();
while (matcher.find()) {
matcher.appendReplacement(sb, (key + "=" + value).replace("$", "\\$"));
}
matcher.appendTail(sb);
return sb.toString();
}
public static String appendParamToUri(String uri, String name, String value) {
if (StringUtils.isEmpty(name) || StringUtils.isEmpty(value)) return uri;
if (uri.indexOf('?') != -1) {
uri += "&" + name + "=" + value;
} else {
uri += "?" + name + "=" + value;
}
return uri;
}
public static String appendParamsToUri(String uri, Map<String, String> params) {
StringBuilder buf = new StringBuilder(uri);
boolean first = (uri.indexOf('?') < 0);
for (Map.Entry<String, String> entry : params.entrySet()) {
String key = entry.getKey();
String value = entry.getValue();
if (StringUtils.isEmpty(key) || StringUtils.isEmpty(value))
continue;
if (first) {
buf.append("?");
first = false;
} else {
buf.append("&");
}
buf.append(key);
buf.append("=");
buf.append(value);
}
return buf.toString();
}
public static boolean matchEndStarPattern(String value, String pattern) {
if (!pattern.endsWith("*")) throw new IllegalArgumentException("not end star pattern!");
String perfix = pattern.substring(0, pattern.length() - 1);
return value.startsWith(perfix);
}
}
package com.secoo.mall.dubbo.monitor.utils;
import lombok.extern.slf4j.Slf4j;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicInteger;
@Slf4j
public class ProcessUtil {
/**
* Buffer size of process input-stream (used for reading the
* output (sic!) of the process). Currently 64KB.
*/
public static final int BUFFER_SIZE = 65536;
public static final int EXEC_TIME_OUT = 2;
public static final String CMD_PRX = "ffmpeg -i ";
private ExecutorService exec;
private ProcessUtil() {
exec = new ThreadPoolExecutor(6,
12,
1,
TimeUnit.MINUTES,
new LinkedBlockingQueue<>(10),
new CustomThreadFactory("cmd-process"),
new ThreadPoolExecutor.CallerRunsPolicy());
}
public static ProcessUtil instance() {
return InputStreamConsumer.instance;
}
/**
* 处理基础命令
*
* @return
*/
public String cmdStr(String org, String def) {
StringBuffer buffer = new StringBuffer();
buffer.append(CMD_PRX).append(org).append(" ").append(def);
return buffer.toString();
}
/**
* 简单的封装, 执行cmd命令
*
* @param cmd 待执行的操作命令
* @return
* @throws IOException
* @throws InterruptedException
*/
public boolean process(String cmd) {
try {
log.info("开始进行文件webm -> mp4转换,cmd:{}", cmd);
Process process = Runtime.getRuntime().exec(cmd);
waitForProcess(process);
} catch (Exception e) {
log.error("process video cmd:{}", cmd, e);
return false;
}
return true;
}
/**
* Perform process input/output and wait for process to terminate.
* <p>
* 源码参考 im4java 的实现修改而来
*/
private int waitForProcess(final Process pProcess)
throws IOException, InterruptedException, TimeoutException, ExecutionException {
// Process stdout and stderr of subprocess in parallel.
// This prevents deadlock under Windows, if there is a lot of
// stderr-output (e.g. from ghostscript called by convert)
FutureTask<Object> outTask = new FutureTask<Object>(() -> {
processOutput(pProcess.getInputStream(), InputStreamConsumer.DEFAULT_CONSUMER);
return null;
});
exec.submit(outTask);
FutureTask<Object> errTask = new FutureTask<Object>(() -> {
processError(pProcess.getErrorStream(), InputStreamConsumer.DEFAULT_CONSUMER);
return null;
});
exec.submit(errTask);
// Wait and check IO exceptions (FutureTask.get() blocks).
try {
outTask.get();
errTask.get();
} catch (ExecutionException e) {
Throwable t = e.getCause();
if (t instanceof IOException) {
throw (IOException) t;
} else if (t instanceof RuntimeException) {
throw (RuntimeException) t;
} else {
throw new IllegalStateException(e);
}
}
FutureTask<Integer> processTask = new FutureTask<Integer>(() -> {
pProcess.waitFor();
return pProcess.exitValue();
});
exec.submit(processTask);
// 设置超时时间,防止死等
int rc = processTask.get(EXEC_TIME_OUT, TimeUnit.SECONDS);
// just to be on the safe side
try {
pProcess.getInputStream().close();
pProcess.getOutputStream().close();
pProcess.getErrorStream().close();
} catch (Exception e) {
log.error("close stream error! e: {}", e);
}
return rc;
}
//////////////////////////////////////////////////////////////////////////////
/**
* Let the OutputConsumer process the output of the command.
* <p>
* 方便后续对输出流的扩展
*/
private void processOutput(InputStream pInputStream,
InputStreamConsumer pConsumer) throws IOException {
pConsumer.consume(pInputStream);
}
/**
* Let the ErrorConsumer process the stderr-stream.
* <p>
* 方便对后续异常流的处理
*/
private void processError(InputStream pInputStream,
InputStreamConsumer pConsumer) throws IOException {
pConsumer.consume(pInputStream);
}
private static class InputStreamConsumer {
static ProcessUtil instance = new ProcessUtil();
static InputStreamConsumer DEFAULT_CONSUMER = new InputStreamConsumer();
void consume(InputStream stream) throws IOException {
StringBuilder builder = new StringBuilder();
BufferedReader reader = new BufferedReader(new InputStreamReader(stream), BUFFER_SIZE);
String temp;
while ((temp = reader.readLine()) != null) {
builder.append(temp);
}
if (log.isDebugEnabled()) {
log.info("cmd process input stream: {}", builder.toString());
}
reader.close();
}
}
private static class CustomThreadFactory implements ThreadFactory {
private String name;
private AtomicInteger count = new AtomicInteger(0);
public CustomThreadFactory(String name) {
this.name = name;
}
@Override
public Thread newThread(Runnable r) {
return new Thread(r, name + "-" + count.addAndGet(1));
}
}
}
/*
* 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 com.secoo.mall.dubbo.monitor.utils;
import com.secoo.mall.dubbo.monitor.dubbo.Constants.Constants;
import com.secoo.mall.dubbo.monitor.dubbo.model.domain.Consumer;
import com.secoo.mall.dubbo.monitor.dubbo.model.domain.Provider;
import org.apache.dubbo.common.URL;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class SyncUtils {
public static final String SERVICE_FILTER_KEY = ".service";
public static final String ADDRESS_FILTER_KEY = ".address";
public static final String ID_FILTER_KEY = ".id";
public static final String COLON = ":";
public static Provider url2Provider(Pair<String, URL> pair) {
if (pair == null) {
return null;
}
String id = pair.getKey();
URL url = pair.getValue();
if (url == null)
return null;
Provider p = new Provider();
p.setHash(id);
p.setService(url.getServiceKey());
p.setAddress(url.getAddress());
p.setApplication(url.getParameter(Constants.APPLICATION_KEY));
p.setUrl(url.toIdentityString());
p.setParameters(url.toParameterString());
p.setDynamic(url.getParameter("dynamic", true));
p.setEnabled(url.getParameter(Constants.ENABLED_KEY, true));
p.setWeight(url.getParameter(Constants.WEIGHT_KEY, Constants.DEFAULT_WEIGHT));
p.setUsername(url.getParameter("owner"));
return p;
}
public static List<Provider> url2ProviderList(Map<String, URL> ps) {
List<Provider> ret = new ArrayList<>();
for (Map.Entry<String, URL> entry : ps.entrySet()) {
ret.add(url2Provider(new Pair<>(entry.getKey(), entry.getValue())));
}
return ret;
}
public static Consumer url2Consumer(Pair<String, URL> pair) {
if (pair == null) {
return null;
}
String id = pair.getKey();
URL url = pair.getValue();
if (null == url)
return null;
Consumer c = new Consumer();
c.setHash(id);
c.setService(url.getServiceKey());
c.setAddress(url.getHost());
c.setApplication(url.getParameter(Constants.APPLICATION_KEY));
c.setParameters(url.toParameterString());
return c;
}
public static List<Consumer> url2ConsumerList(Map<String, URL> cs) {
List<Consumer> list = new ArrayList<Consumer>();
if (cs == null) return list;
for (Map.Entry<String, URL> entry : cs.entrySet()) {
list.add(url2Consumer(new Pair<>(entry.getKey(), entry.getValue())));
}
return list;
}
// Map<category, Map<servicename, Map<Long, URL>>>0 = {ConcurrentHashMap$MapEntry@8908} "com.imooc.springboot.dubbo.demo.DemoService" -> " size = 2"
public static <SM extends Map<String, Map<String, URL>>> Map<String, URL> filterFromCategory(Map<String, SM> urls, Map<String, String> filter) {
String c = (String) filter.get(Constants.CATEGORY_KEY);
if (c == null) throw new IllegalArgumentException("no category");
filter.remove(Constants.CATEGORY_KEY);
return filterFromService(urls.get(c), filter);
}
// Map<servicename, Map<Long, URL>>
public static Map<String, URL> filterFromService(Map<String, Map<String, URL>> urls, Map<String, String> filter) {
Map<String, URL> ret = new HashMap<>();
if (urls == null) return ret;
String s = (String) filter.remove(SERVICE_FILTER_KEY);
if (s == null) {
for (Map.Entry<String, Map<String, URL>> entry : urls.entrySet()) {
filterFromUrls(entry.getValue(), ret, filter); //根据ip 或application 查询
}
} else {
Map<String, URL> map = urls.get(s);
filterFromUrls(map, ret, filter);
}
return ret;
}
// Map<Long, URL>
static void filterFromUrls(Map<String, URL> from, Map<String, URL> to, Map<String, String> filter) {
if (from == null || from.isEmpty()) return;
for (Map.Entry<String, URL> entry : from.entrySet()) {
URL url = entry.getValue();
boolean match = true;
for (Map.Entry<String, String> e : filter.entrySet()) {
String key = e.getKey();
String value = e.getValue();
if (ADDRESS_FILTER_KEY.equals(key)) {
// value is address:port
if (value.contains(COLON)) {
if (!value.equals(url.getIp() + COLON + url.getPort())) {
match = false;
break;
}
}
else { // value is just address
if (!value.equals(url.getIp())) {
match = false;
break;
}
}
} else {
if (!value.equals(url.getParameter(key))) {
match = false;
break;
}
}
}
if (match) {
to.put(entry.getKey(), url);
}
}
}
public static <SM extends Map<String, Map<String, URL>>> Pair<String, URL> filterFromCategory(Map<String, SM> urls, String category, String id) {
SM services = urls.get(category);
if (services == null) return null;
for (Map.Entry<String, Map<String, URL>> e1 : services.entrySet()) {
Map<String, URL> u = e1.getValue();
if (u.containsKey(id)) return new Pair<>(id, u.get(id));
}
return null;
}
}
/*
* 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 com.secoo.mall.dubbo.monitor.utils;
/**
* Tool
*
*/
public class Tool {
public static String getInterface(String service) {
if (service != null && service.length() > 0) {
int i = service.indexOf('/');
if (i >= 0) {
service = service.substring(i + 1);
}
i = service.lastIndexOf(':');
if (i >= 0) {
service = service.substring(0, i);
}
}
return service;
}
public static String getGroup(String service) {
if (service != null && service.length() > 0) {
int i = service.indexOf('/');
if (i >= 0) {
return service.substring(0, i);
}
}
return null;
}
public static String getVersion(String service) {
if (service != null && service.length() > 0) {
int i = service.lastIndexOf(':');
if (i >= 0) {
return service.substring(i + 1);
}
}
return null;
}
}
zookeeper=com.secoo.monitor.dubbo.register.impl.ZookeeperConfiguration
\ No newline at end of file
......@@ -5,11 +5,12 @@
<parent>
<artifactId>matrix-protocol</artifactId>
<groupId>com.secoo.mall</groupId>
<version>2.0.8.RELEASE</version>
<version>2.0.9-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>matrix-protocol-dubbo-starter</artifactId>
<artifactId>matrix-pro2.7.4.1tocol-dubbo-starter</artifactId>
<dependencies>
<dependency>
......
package com.secoo.mall.dubbo.spring.boot.autoconfigure;
import com.secoo.mall.common.util.date.DateUtil;
import org.apache.catalina.connector.Connector;
import org.apache.dubbo.config.DubboShutdownHook;
import org.apache.tomcat.util.threads.ThreadPoolExecutor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.web.embedded.tomcat.TomcatConnectorCustomizer;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationListener;
import org.springframework.context.event.ContextClosedEvent;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.concurrent.Executor;
import java.util.concurrent.TimeUnit;
public class GracefullyShoutDown implements CommandLineRunner, ApplicationListener<ContextClosedEvent>, TomcatConnectorCustomizer {
private final Logger logger = LoggerFactory.getLogger(this.getClass());
private ApplicationContext context;
private static final int TIMEOUT = 10;
private volatile Connector connector;
//容器初始化后执行
@Override
public void run(String... args) throws Exception {
logger.info("nimam2-------------->");
if(DubboShutdownHook.getDubboShutdownHook()!=null) {
DubboShutdownHook.getDubboShutdownHook().unregister();
//TODO 遍历listern 然后移除,一种方法更改dubbo源码,第二种方法,反射搞定。
// ApplicationEventMulticaster multicaster= context.getBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, ApplicationEventMulticaster.class);
// multicaster.removeApplicationListener(SpringExtensionFactory.SHUTDOWN_HOOK_LISTENER);
logger.info("dubbo unreister success");
}else{
logger.info("dubbo unreister obj is null");
}
}
//容器关闭后执行
@Override
public void onApplicationEvent(ContextClosedEvent contextClosedEvent) {
logger.info("zidingyi zhixing application close version2=============time:" + new SimpleDateFormat("yyyy-MM-dd HH:mm:ss:SSS").format(new Date() ));
try {
this.connector.pause();
Executor executor = this.connector.getProtocolHandler().getExecutor();
if (executor instanceof ThreadPoolExecutor) {
try {
ThreadPoolExecutor threadPoolExecutor = (ThreadPoolExecutor) executor;
threadPoolExecutor.shutdown();
logger.info("apache connector executor shutdown=============time:" + DateUtil.getDateTime());
if (!threadPoolExecutor.awaitTermination(TIMEOUT, TimeUnit.SECONDS)) {
logger.info("Tomcat thread pool did not shut down gracefully within "
+ TIMEOUT + " seconds. Proceeding with forceful shutdown");
threadPoolExecutor.shutdownNow();
if (!threadPoolExecutor.awaitTermination(TIMEOUT, TimeUnit.SECONDS)) {
logger.info("Tomcat thread pool did not terminate");
}
}
} catch (InterruptedException ex) {
Thread.currentThread().interrupt();
}
}
logger.info("DubboShutdownHook begin time------------>" + new SimpleDateFormat("yyyy-MM-dd HH:mm:ss:SSS").format(new Date() ));
DubboShutdownHook.getDubboShutdownHook().doDestroy();
logger.info("DubboShutdownHook begin end------------>" +new SimpleDateFormat("yyyy-MM-dd HH:mm:ss:SSS").format(new Date() ));
} catch (Exception e) {
logger.error("matrix.GracefullyShoutDown.error", e);
}
}
@Override
public void customize(Connector connector) {
this.connector = connector;
}
}
......@@ -3,10 +3,15 @@ package com.secoo.mall.dubbo.spring.boot.autoconfigure;
import com.github.xiaoymin.swaggerbootstrapui.annotations.EnableSwaggerBootstrapUI;
import com.secoo.mall.common.condition.BateEnvCondition;
import com.secoo.mall.common.util.sys.SystemUtil;
import com.secoo.mall.dubbo.monitor.config.ConfigCenter;
import com.secoo.mall.dubbo.monitor.dubbo.service.RegistryServerSync;
import com.secoo.mall.dubbo.swagger.annotations.EnableDubboSwagger;
import org.apache.dubbo.config.spring.context.annotation.EnableDubbo;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory;
import org.springframework.boot.web.servlet.server.ConfigurableServletWebServerFactory;
import org.springframework.boot.web.servlet.server.ServletWebServerFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import springfox.documentation.builders.ApiInfoBuilder;
......@@ -42,5 +47,24 @@ public class MatrixDubboAutoConfiguration {
.description("更多内容请关注:http://apims.siku.cn")
.build();
}
@Bean
public GracefullyShoutDown createGraceObject(){
return new GracefullyShoutDown();
}
// @Bean
// public RegistryServerSync createSynObject(){
// return new RegistryServerSync();
// }
// @Bean
// public ConfigCenter createSynConfig(){
// return new ConfigCenter();
// }
//
}
\ No newline at end of file
# Auto Configure
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.secoo.mall.dubbo.spring.boot.autoconfigure.MatrixDubboAutoConfiguration
\ No newline at end of file
com.secoo.mall.dubbo.spring.boot.autoconfigure.MatrixDubboAutoConfiguration,\
com.secoo.mall.dubbo.monitor.config.ConfigCenter
\ No newline at end of file
......@@ -5,7 +5,7 @@
<parent>
<artifactId>matrix-protocol</artifactId>
<groupId>com.secoo.mall</groupId>
<version>2.0.8.RELEASE</version>
<version>2.0.9-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
......
......@@ -5,7 +5,7 @@
<parent>
<artifactId>matrix-protocol</artifactId>
<groupId>com.secoo.mall</groupId>
<version>2.0.8.RELEASE</version>
<version>2.0.9-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
......
......@@ -5,7 +5,7 @@
<parent>
<artifactId>matrix</artifactId>
<groupId>com.secoo.mall</groupId>
<version>2.0.8.RELEASE</version>
<version>2.0.9-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
......@@ -29,27 +29,27 @@
<dependency>
<groupId>com.secoo.mall</groupId>
<artifactId>matrix-protocol-core</artifactId>
<version>2.0.8.RELEASE</version>
<version>2.0.9-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>com.secoo.mall</groupId>
<artifactId>matrix-protocol-web-core</artifactId>
<version>2.0.8.RELEASE</version>
<version>2.0.9-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>com.secoo.mall</groupId>
<artifactId>matrix-protocol-dubbo-core</artifactId>
<version>2.0.8.RELEASE</version>
<version>2.0.9-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>com.secoo.mall</groupId>
<artifactId>matrix-protocol-web-starter</artifactId>
<version>2.0.8.RELEASE</version>
<version>2.0.9-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>com.secoo.mall</groupId>
<artifactId>matrix-protocol-dubbo-starter</artifactId>
<version>2.0.8.RELEASE</version>
<version>2.0.9.RELEASE</version>
</dependency>
<!-- Aapche Dubbo -->
......
......@@ -6,7 +6,7 @@
<groupId>com.secoo.mall</groupId>
<artifactId>matrix</artifactId>
<version>2.0.8.RELEASE</version>
<version>2.0.9-SNAPSHOT</version>
<packaging>pom</packaging>
......@@ -53,119 +53,119 @@
<dependency>
<groupId>com.secoo.mall</groupId>
<artifactId>logger-starter</artifactId>
<version>2.0.8.RELEASE</version>
<version>2.0.9-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>com.secoo.mall</groupId>
<artifactId>common-core</artifactId>
<version>2.0.8.RELEASE</version>
<version>2.0.9-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>com.secoo.mall</groupId>
<artifactId>config-starter</artifactId>
<version>2.0.8.RELEASE</version>
<version>2.0.9-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>com.secoo.mall</groupId>
<artifactId>common-util</artifactId>
<version>2.0.8.RELEASE</version>
<version>2.0.9-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>com.secoo.mall</groupId>
<artifactId>matrix-datasource-druid</artifactId>
<version>2.0.8.RELEASE</version>
<version>2.0.9-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>com.secoo.mall</groupId>
<artifactId>matrix-mybatis-core</artifactId>
<version>2.0.8.RELEASE</version>
<version>2.0.9-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>com.secoo.mall</groupId>
<artifactId>matrix-mybatis-starter</artifactId>
<version>2.0.8.RELEASE</version>
<version>2.0.9-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>com.secoo.mall</groupId>
<artifactId>matrix-mq-rocketmq-core</artifactId>
<version>2.0.8.RELEASE</version>
<version>2.0.9-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>com.secoo.mall</groupId>
<artifactId>matrix-mq-rocketmq-client</artifactId>
<version>2.0.8.RELEASE</version>
<version>2.0.9-SNAPSHOT</version>
</dependency>
<!--rocketmq-starter废弃,启用matrix-mq-rocketmq-starter-->
<dependency>
<groupId>com.secoo.mall</groupId>
<artifactId>matrix-mq-rocketmq-starter</artifactId>
<version>2.0.8.RELEASE</version>
<version>2.0.9-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>com.secoo.mall</groupId>
<artifactId>matrix-protocol-core</artifactId>
<version>2.0.8.RELEASE</version>
<version>2.0.9-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>com.secoo.mall</groupId>
<artifactId>matrix-protocol-dubbo-core</artifactId>
<version>2.0.8.RELEASE</version>
<version>2.0.9-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>com.secoo.mall</groupId>
<artifactId>matrix-protocol-dubbo-starter</artifactId>
<version>2.0.8.RELEASE</version>
<version>2.0.9.RELEASE</version>
</dependency>
<dependency>
<groupId>com.secoo.mall</groupId>
<artifactId>matrix-protocol-web-core</artifactId>
<version>2.0.8.RELEASE</version>
<version>2.0.9-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>com.secoo.mall</groupId>
<artifactId>matrix-protocol-web-starter</artifactId>
<version>2.0.8.RELEASE</version>
<version>2.0.9-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>com.secoo.mall</groupId>
<artifactId>matrix-job-xxl-core</artifactId>
<version>2.0.8.RELEASE</version>
<version>2.0.9-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>com.secoo.mall</groupId>
<artifactId>matrix-job-xxl-starter</artifactId>
<version>2.0.8.RELEASE</version>
<version>2.0.9-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>com.secoo.mall</groupId>
<artifactId>matrix-bigdata-hbase-starter</artifactId>
<version>2.0.8.RELEASE</version>
<version>2.0.9-SNAPSHOT</version>
</dependency>
<!--redis-->
<dependency>
<groupId>com.secoo.mall</groupId>
<artifactId>matrix-datahelper-redis-core</artifactId>
<version>2.0.8.RELEASE</version>
<version>2.0.9-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>com.secoo.mall</groupId>
<artifactId>matrix-datahelper-redis-starter</artifactId>
<version>2.0.8.RELEASE</version>
<version>2.0.9-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>com.secoo.mall</groupId>
<artifactId>matrix-client-openfeign-starter</artifactId>
<version>2.0.8.RELEASE</version>
<version>2.0.9-SNAPSHOT</version>
</dependency>
<!-- bus -->
<dependency>
<groupId>com.secoo.mall</groupId>
<artifactId>matrix-bus-canal-starter</artifactId>
<version>2.0.8.RELEASE</version>
<version>2.0.9-SNAPSHOT</version>
</dependency>
<!--普通jar-->
......@@ -306,18 +306,54 @@
</plugins>
</pluginManagement>
</build>
<profiles>
<profile>
<id>dev</id>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
<properties>
<ver_type>-DEV-SNAPSHOT</ver_type>
</properties>
<distributionManagement>
<snapshotRepository>
<repository>
<id>secoo-dev</id>
<name>secoo-dev-repository</name>
<url>http://nexus.secoo.com:8081/nexus/content/repositories/secoo-hosted-dev/</url>
</snapshotRepository>
</repository>
</distributionManagement>
</profile>
<profile>
<id>test</id>
<properties>
<ver_type>-SNAPSHOT</ver_type>
</properties>
<distributionManagement>
<repository>
<id>secoo-test</id>
<name>secoo-test-repository</name>
<url>http://nexus.secoo.com:8081/nexus/content/repositories/secoo-hosted-test/</url>
</repository>
</distributionManagement>
</profile>
<profile>
<id>pro</id>
<properties>
<ver_type>.RELEASE</ver_type>
</properties>
<distributionManagement>
<repository>
<id>secoo-pro</id>
<name>secoo-pro-repository</name>
<url>http://nexus.secoo.com:8081/nexus/content/repositories/secoo-hosted-pro/</url>
</repository>
</distributionManagement>
</profile>
</profiles>
</project>
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment