blob: 209a9fab9e04c9a27d3fbc612d30479260fdf369 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.dubbo.registry.client.metadata.store;
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.StringUtils;
import org.apache.dubbo.metadata.MetadataInfo;
import org.apache.dubbo.metadata.WritableMetadataService;
import org.apache.dubbo.metadata.definition.ServiceDefinitionBuilder;
import org.apache.dubbo.metadata.definition.model.FullServiceDefinition;
import org.apache.dubbo.metadata.report.MetadataReport;
import org.apache.dubbo.metadata.report.MetadataReportInstance;
import org.apache.dubbo.metadata.report.identifier.MetadataIdentifier;
import org.apache.dubbo.metadata.report.identifier.SubscriberMetadataIdentifier;
import org.apache.dubbo.registry.client.ServiceInstance;
import org.apache.dubbo.registry.client.metadata.ServiceInstanceMetadataUtils;
import org.apache.dubbo.remoting.Constants;
import org.apache.dubbo.rpc.RpcException;
import java.util.Map;
import static org.apache.dubbo.common.constants.CommonConstants.APPLICATION_KEY;
import static org.apache.dubbo.common.constants.CommonConstants.CONSUMER_SIDE;
import static org.apache.dubbo.common.constants.CommonConstants.GROUP_KEY;
import static org.apache.dubbo.common.constants.CommonConstants.INTERFACE_KEY;
import static org.apache.dubbo.common.constants.CommonConstants.PID_KEY;
import static org.apache.dubbo.common.constants.CommonConstants.PROVIDER_SIDE;
import static org.apache.dubbo.common.constants.CommonConstants.SIDE_KEY;
import static org.apache.dubbo.common.constants.CommonConstants.TIMESTAMP_KEY;
import static org.apache.dubbo.common.constants.CommonConstants.VERSION_KEY;
import static org.apache.dubbo.common.constants.RegistryConstants.REGISTRY_CLUSTER_KEY;
public class RemoteMetadataServiceImpl {
protected final Logger logger = LoggerFactory.getLogger(getClass());
private WritableMetadataService localMetadataService;
public RemoteMetadataServiceImpl(WritableMetadataService writableMetadataService) {
this.localMetadataService = writableMetadataService;
}
public Map<String, MetadataReport> getMetadataReports() {
return MetadataReportInstance.getMetadataReports(false);
}
public void publishMetadata(String serviceName) {
Map<String, MetadataInfo> metadataInfos = localMetadataService.getMetadataInfos();
metadataInfos.forEach((registryCluster, metadataInfo) -> {
if (!metadataInfo.hasReported()) {
SubscriberMetadataIdentifier identifier = new SubscriberMetadataIdentifier(serviceName, metadataInfo.calAndGetRevision());
metadataInfo.calAndGetRevision();
metadataInfo.getExtendParams().put(REGISTRY_CLUSTER_KEY, registryCluster);
MetadataReport metadataReport = getMetadataReports().get(registryCluster);
if (metadataReport == null) {
metadataReport = getMetadataReports().entrySet().iterator().next().getValue();
}
logger.info("Publishing metadata to " + metadataReport.getClass().getSimpleName());
if (logger.isDebugEnabled()) {
logger.debug(metadataInfo.toString());
}
metadataReport.publishAppMetadata(identifier, metadataInfo);
metadataInfo.markReported();
}
});
}
public MetadataInfo getMetadata(ServiceInstance instance) {
SubscriberMetadataIdentifier identifier = new SubscriberMetadataIdentifier(instance.getServiceName(),
ServiceInstanceMetadataUtils.getExportedServicesRevision(instance));
String registryCluster = instance.getExtendParams().get(REGISTRY_CLUSTER_KEY);
MetadataReport metadataReport = getMetadataReports().get(registryCluster);
if (metadataReport == null) {
metadataReport = getMetadataReports().entrySet().iterator().next().getValue();
}
return metadataReport.getAppMetadata(identifier, instance.getExtendParams());
}
public void publishServiceDefinition(URL url) {
String side = url.getParameter(SIDE_KEY);
if (PROVIDER_SIDE.equalsIgnoreCase(side)) {
//TODO, the params part is duplicate with that stored by exportURL(url), can be further optimized in the future.
publishProvider(url);
} else {
//TODO, only useful for ops showing the url parameters, this is duplicate with subscribeURL(url), can be removed in the future.
publishConsumer(url);
}
}
private void publishProvider(URL providerUrl) throws RpcException {
//first add into the list
// remove the individual param
providerUrl = providerUrl.removeParameters(PID_KEY, TIMESTAMP_KEY, Constants.BIND_IP_KEY,
Constants.BIND_PORT_KEY, TIMESTAMP_KEY);
try {
String interfaceName = providerUrl.getParameter(INTERFACE_KEY);
if (StringUtils.isNotEmpty(interfaceName)) {
Class interfaceClass = Class.forName(interfaceName);
FullServiceDefinition fullServiceDefinition = ServiceDefinitionBuilder.buildFullDefinition(interfaceClass,
providerUrl.getParameters());
for (Map.Entry<String, MetadataReport> entry : getMetadataReports().entrySet()) {
MetadataReport metadataReport = entry.getValue();
metadataReport.storeProviderMetadata(new MetadataIdentifier(providerUrl.getServiceInterface(),
providerUrl.getParameter(VERSION_KEY), providerUrl.getParameter(GROUP_KEY),
PROVIDER_SIDE, providerUrl.getParameter(APPLICATION_KEY)), fullServiceDefinition);
}
return;
}
logger.error("publishProvider interfaceName is empty . providerUrl: " + providerUrl.toFullString());
} catch (ClassNotFoundException e) {
//ignore error
logger.error("publishProvider getServiceDescriptor error. providerUrl: " + providerUrl.toFullString(), e);
}
}
private void publishConsumer(URL consumerURL) throws RpcException {
final URL url = consumerURL.removeParameters(PID_KEY, TIMESTAMP_KEY, Constants.BIND_IP_KEY,
Constants.BIND_PORT_KEY, TIMESTAMP_KEY);
getMetadataReports().forEach((registryKey, config) -> {
config.storeConsumerMetadata(new MetadataIdentifier(url.getServiceInterface(),
url.getParameter(VERSION_KEY), url.getParameter(GROUP_KEY), CONSUMER_SIDE,
url.getParameter(APPLICATION_KEY)), url.getParameters());
});
}
}