Refactor Dubbo Service registration logic:
1. Simplify registration implementation 2. Add Event-Drivenpull/514/head
parent
36d2b8ba46
commit
3407cd36de
@ -1,68 +0,0 @@
|
|||||||
/*
|
|
||||||
* 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.springframework.cloud.alibaba.dubbo.registry;
|
|
||||||
|
|
||||||
import org.apache.dubbo.common.Constants;
|
|
||||||
import org.apache.dubbo.common.URL;
|
|
||||||
import org.springframework.cloud.alibaba.dubbo.registry.handler.DubboRegistryServiceIdHandler;
|
|
||||||
import org.springframework.cloud.client.DefaultServiceInstance;
|
|
||||||
import org.springframework.cloud.client.ServiceInstance;
|
|
||||||
import org.springframework.cloud.client.serviceregistry.Registration;
|
|
||||||
import org.springframework.context.ConfigurableApplicationContext;
|
|
||||||
|
|
||||||
import java.util.LinkedHashMap;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Abstract {@link RegistrationFactory} implementation
|
|
||||||
* <p>
|
|
||||||
*
|
|
||||||
* @param <R> The subclass of {@link Registration}
|
|
||||||
* @author <a href="mailto:mercyblitz@gmail.com">Mercy</a>
|
|
||||||
*/
|
|
||||||
public abstract class AbstractRegistrationFactory<R extends Registration> implements RegistrationFactory<R> {
|
|
||||||
|
|
||||||
public final R create(URL url, ConfigurableApplicationContext applicationContext) {
|
|
||||||
ServiceInstance serviceInstance = createServiceInstance(url, applicationContext);
|
|
||||||
return create(serviceInstance, applicationContext);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Create an instance {@link ServiceInstance}. This method maybe override by sub-class.
|
|
||||||
*
|
|
||||||
* @param url The Dubbo's {@link URL}
|
|
||||||
* @param applicationContext {@link ConfigurableApplicationContext}
|
|
||||||
* @return an instance {@link ServiceInstance}
|
|
||||||
*/
|
|
||||||
protected ServiceInstance createServiceInstance(URL url, ConfigurableApplicationContext applicationContext) {
|
|
||||||
String serviceId = createServiceId(url, applicationContext);
|
|
||||||
// Append default category if absent
|
|
||||||
String category = url.getParameter(Constants.CATEGORY_KEY, Constants.DEFAULT_CATEGORY);
|
|
||||||
URL newURL = url.addParameter(Constants.CATEGORY_KEY, category);
|
|
||||||
newURL = newURL.addParameter(Constants.PROTOCOL_KEY, url.getProtocol());
|
|
||||||
String ip = url.getIp();
|
|
||||||
int port = newURL.getParameter(Constants.BIND_PORT_KEY, url.getPort());
|
|
||||||
DefaultServiceInstance serviceInstance = new DefaultServiceInstance(url.toIdentityString(), serviceId, ip, port, false);
|
|
||||||
serviceInstance.getMetadata().putAll(new LinkedHashMap<>(newURL.getParameters()));
|
|
||||||
return serviceInstance;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected String createServiceId(URL url, ConfigurableApplicationContext applicationContext) {
|
|
||||||
DubboRegistryServiceIdHandler handler = applicationContext.getBean(DubboRegistryServiceIdHandler.class);
|
|
||||||
return handler.createServiceId(url);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -0,0 +1,293 @@
|
|||||||
|
/*
|
||||||
|
* 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.springframework.cloud.alibaba.dubbo.registry;
|
||||||
|
|
||||||
|
import org.apache.dubbo.common.Constants;
|
||||||
|
import org.apache.dubbo.common.URL;
|
||||||
|
import org.apache.dubbo.common.utils.UrlUtils;
|
||||||
|
import org.apache.dubbo.registry.NotifyListener;
|
||||||
|
import org.apache.dubbo.registry.RegistryFactory;
|
||||||
|
import org.apache.dubbo.registry.support.FailbackRegistry;
|
||||||
|
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
import org.springframework.cloud.client.ServiceInstance;
|
||||||
|
import org.springframework.cloud.client.discovery.DiscoveryClient;
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.LinkedHashSet;
|
||||||
|
import java.util.LinkedList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.concurrent.ScheduledExecutorService;
|
||||||
|
import java.util.concurrent.ScheduledFuture;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
|
import static java.util.Collections.singleton;
|
||||||
|
import static org.apache.dubbo.common.Constants.PROVIDER_SIDE;
|
||||||
|
import static org.apache.dubbo.common.Constants.SIDE_KEY;
|
||||||
|
import static org.springframework.util.ObjectUtils.isEmpty;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Abstract Dubbo {@link RegistryFactory} uses Spring Cloud Service Registration abstraction, whose protocol is "spring-cloud"
|
||||||
|
*
|
||||||
|
* @author <a href="mailto:mercyblitz@gmail.com">Mercy</a>
|
||||||
|
*/
|
||||||
|
public abstract class AbstractSpringCloudRegistry extends FailbackRegistry {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The parameter name of {@link #servicesLookupInterval}
|
||||||
|
*/
|
||||||
|
public static final String SERVICES_LOOKUP_INTERVAL_PARAM_NAME = "dubbo.services.lookup.interval";
|
||||||
|
|
||||||
|
protected final Logger logger = LoggerFactory.getLogger(getClass());
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The interval in second of lookup service names(only for Dubbo-OPS)
|
||||||
|
*/
|
||||||
|
private final long servicesLookupInterval;
|
||||||
|
|
||||||
|
private final DiscoveryClient discoveryClient;
|
||||||
|
|
||||||
|
protected final ScheduledExecutorService servicesLookupScheduler;
|
||||||
|
|
||||||
|
public AbstractSpringCloudRegistry(URL url,
|
||||||
|
DiscoveryClient discoveryClient,
|
||||||
|
ScheduledExecutorService servicesLookupScheduler) {
|
||||||
|
super(url);
|
||||||
|
this.servicesLookupInterval = url.getParameter(SERVICES_LOOKUP_INTERVAL_PARAM_NAME, 60L);
|
||||||
|
this.discoveryClient = discoveryClient;
|
||||||
|
this.servicesLookupScheduler = servicesLookupScheduler;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected boolean shouldRegister(URL url) {
|
||||||
|
String side = url.getParameter(SIDE_KEY);
|
||||||
|
|
||||||
|
boolean should = PROVIDER_SIDE.equals(side); // Only register the Provider.
|
||||||
|
|
||||||
|
if (!should) {
|
||||||
|
if (logger.isDebugEnabled()) {
|
||||||
|
logger.debug("The URL[{}] should not be registered.", url.toString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return should;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public final void doRegister(URL url) {
|
||||||
|
if (!shouldRegister(url)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
doRegister0(url);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The sub-type should implement to register
|
||||||
|
*
|
||||||
|
* @param url {@link URL}
|
||||||
|
*/
|
||||||
|
protected abstract void doRegister0(URL url);
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public final void doUnregister(URL url) {
|
||||||
|
if (!shouldRegister(url)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
doUnregister0(url);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The sub-type should implement to unregister
|
||||||
|
*
|
||||||
|
* @param url {@link URL}
|
||||||
|
*/
|
||||||
|
protected abstract void doUnregister0(URL url);
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public final void doSubscribe(URL url, NotifyListener listener) {
|
||||||
|
Set<String> serviceNames = getServiceNames(url);
|
||||||
|
doSubscribe(url, listener, serviceNames);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public final void doUnsubscribe(URL url, NotifyListener listener) {
|
||||||
|
if (isAdminProtocol(url)) {
|
||||||
|
shutdownServiceNamesLookup();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isAvailable() {
|
||||||
|
return !discoveryClient.getServices().isEmpty();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void shutdownServiceNamesLookup() {
|
||||||
|
if (servicesLookupScheduler != null) {
|
||||||
|
servicesLookupScheduler.shutdown();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void filterServiceNames(Collection<String> serviceNames) {
|
||||||
|
filter(serviceNames, new Filter<String>() {
|
||||||
|
@Override
|
||||||
|
public boolean accept(String serviceName) {
|
||||||
|
return supports(serviceName);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
protected abstract boolean supports(String serviceName);
|
||||||
|
|
||||||
|
protected final Set<String> getAllServiceNames() {
|
||||||
|
return new LinkedHashSet<>(discoveryClient.getServices());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the service names from the specified {@link URL url}
|
||||||
|
*
|
||||||
|
* @param url {@link URL}
|
||||||
|
* @return non-null
|
||||||
|
*/
|
||||||
|
private Set<String> getServiceNames(URL url) {
|
||||||
|
if (isAdminProtocol(url)) {
|
||||||
|
return getServiceNamesForOps(url);
|
||||||
|
} else {
|
||||||
|
return singleton(getServiceName(url));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected boolean isAdminProtocol(URL url) {
|
||||||
|
return Constants.ADMIN_PROTOCOL.equals(url.getProtocol());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the service names for Dubbo OPS
|
||||||
|
*
|
||||||
|
* @param url {@link URL}
|
||||||
|
* @return non-null
|
||||||
|
*/
|
||||||
|
protected Set<String> getServiceNamesForOps(URL url) {
|
||||||
|
Set<String> serviceNames = getAllServiceNames();
|
||||||
|
filterServiceNames(serviceNames);
|
||||||
|
return serviceNames;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected abstract String getServiceName(URL url);
|
||||||
|
|
||||||
|
private void doSubscribe(final URL url, final NotifyListener listener, final Collection<String> serviceNames) {
|
||||||
|
|
||||||
|
subscribe(url, listener, serviceNames);
|
||||||
|
|
||||||
|
schedule(() -> {
|
||||||
|
subscribe(url, listener, serviceNames);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
protected ScheduledFuture<?> schedule(Runnable runnable) {
|
||||||
|
return this.servicesLookupScheduler.scheduleAtFixedRate(runnable, servicesLookupInterval,
|
||||||
|
servicesLookupInterval, TimeUnit.SECONDS);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected List<ServiceInstance> getServiceInstances(String serviceName) {
|
||||||
|
return discoveryClient.getInstances(serviceName);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void subscribe(final URL url, final NotifyListener listener, final Collection<String> serviceNames) {
|
||||||
|
for (String serviceName : serviceNames) {
|
||||||
|
List<ServiceInstance> serviceInstances = getServiceInstances(serviceName);
|
||||||
|
if (!isEmpty(serviceInstances)) {
|
||||||
|
notifySubscriber(url, listener, serviceInstances);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Notify the Healthy {@link ServiceInstance service instance} to subscriber.
|
||||||
|
*
|
||||||
|
* @param url {@link URL}
|
||||||
|
* @param listener {@link NotifyListener}
|
||||||
|
* @param serviceInstances all {@link ServiceInstance instances}
|
||||||
|
*/
|
||||||
|
protected abstract void notifySubscriber(URL url, NotifyListener listener, List<ServiceInstance> serviceInstances);
|
||||||
|
|
||||||
|
protected void filterHealthyInstances(Collection<ServiceInstance> instances) {
|
||||||
|
filter(instances, new Filter<ServiceInstance>() {
|
||||||
|
@Override
|
||||||
|
public boolean accept(ServiceInstance data) {
|
||||||
|
// TODO check the details of status
|
||||||
|
// return serviceRegistry.getStatus(new DubboRegistration(data)) != null;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
protected List<URL> buildURLs(URL consumerURL, Collection<ServiceInstance> serviceInstances) {
|
||||||
|
if (serviceInstances.isEmpty()) {
|
||||||
|
return Collections.emptyList();
|
||||||
|
}
|
||||||
|
List<URL> urls = new LinkedList<URL>();
|
||||||
|
for (ServiceInstance serviceInstance : serviceInstances) {
|
||||||
|
URL url = buildURL(serviceInstance);
|
||||||
|
if (UrlUtils.isMatch(consumerURL, url)) {
|
||||||
|
urls.add(url);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return urls;
|
||||||
|
}
|
||||||
|
|
||||||
|
private URL buildURL(ServiceInstance serviceInstance) {
|
||||||
|
URL url = new URL(serviceInstance.getMetadata().get(Constants.PROTOCOL_KEY),
|
||||||
|
serviceInstance.getHost(),
|
||||||
|
serviceInstance.getPort(),
|
||||||
|
serviceInstance.getMetadata());
|
||||||
|
return url;
|
||||||
|
}
|
||||||
|
|
||||||
|
private <T> void filter(Collection<T> collection, Filter<T> filter) {
|
||||||
|
Iterator<T> iterator = collection.iterator();
|
||||||
|
while (iterator.hasNext()) {
|
||||||
|
T data = iterator.next();
|
||||||
|
if (!filter.accept(data)) { // remove if not accept
|
||||||
|
iterator.remove();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static <T> T[] of(T... values) {
|
||||||
|
return values;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A filter
|
||||||
|
*/
|
||||||
|
public interface Filter<T> {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests whether or not the specified data should be accepted.
|
||||||
|
*
|
||||||
|
* @param data The data to be tested
|
||||||
|
* @return <code>true</code> if and only if <code>data</code>
|
||||||
|
* should be accepted
|
||||||
|
*/
|
||||||
|
boolean accept(T data);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -1,50 +0,0 @@
|
|||||||
/*
|
|
||||||
* 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.springframework.cloud.alibaba.dubbo.registry;
|
|
||||||
|
|
||||||
import org.apache.dubbo.common.URL;
|
|
||||||
import org.springframework.cloud.client.ServiceInstance;
|
|
||||||
import org.springframework.cloud.client.serviceregistry.Registration;
|
|
||||||
import org.springframework.context.ConfigurableApplicationContext;
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* {@link Registration} Factory to createServiceInstance a instance of {@link Registration}
|
|
||||||
*
|
|
||||||
* @param <R> The subclass of {@link Registration}
|
|
||||||
* @author <a href="mailto:mercyblitz@gmail.com">Mercy</a>
|
|
||||||
*/
|
|
||||||
public interface RegistrationFactory<R extends Registration> {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Create a instance of {@link R}
|
|
||||||
*
|
|
||||||
* @param url The Dubbo's {@link URL}
|
|
||||||
* @param applicationContext {@link ConfigurableApplicationContext}
|
|
||||||
* @return a instance of {@link R}, if null, it indicates the registration will not be executed.
|
|
||||||
*/
|
|
||||||
R create(URL url, ConfigurableApplicationContext applicationContext);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Create a instance of {@link R}
|
|
||||||
*
|
|
||||||
* @param serviceInstance {@link ServiceInstance}
|
|
||||||
* @param applicationContext {@link ConfigurableApplicationContext}
|
|
||||||
* @return a instance of {@link R}, if null, it indicates the registration will not be executed.
|
|
||||||
*/
|
|
||||||
R create(ServiceInstance serviceInstance, ConfigurableApplicationContext applicationContext);
|
|
||||||
}
|
|
@ -1,144 +0,0 @@
|
|||||||
/*
|
|
||||||
* 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.springframework.cloud.alibaba.dubbo.registry;
|
|
||||||
|
|
||||||
import org.slf4j.Logger;
|
|
||||||
import org.slf4j.LoggerFactory;
|
|
||||||
import org.springframework.beans.BeansException;
|
|
||||||
import org.springframework.beans.factory.FactoryBean;
|
|
||||||
import org.springframework.cloud.client.serviceregistry.Registration;
|
|
||||||
import org.springframework.cloud.client.serviceregistry.ServiceRegistry;
|
|
||||||
import org.springframework.context.ApplicationContext;
|
|
||||||
import org.springframework.context.ApplicationContextAware;
|
|
||||||
import org.springframework.core.ResolvableType;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import static org.springframework.beans.BeanUtils.instantiateClass;
|
|
||||||
import static org.springframework.core.ResolvableType.forInstance;
|
|
||||||
import static org.springframework.core.ResolvableType.forType;
|
|
||||||
import static org.springframework.core.io.support.SpringFactoriesLoader.loadFactoryNames;
|
|
||||||
import static org.springframework.util.ClassUtils.isPresent;
|
|
||||||
import static org.springframework.util.ClassUtils.resolveClassName;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* {@link RegistrationFactory} Provider
|
|
||||||
*
|
|
||||||
* @author <a href="mailto:mercyblitz@gmail.com">Mercy</a>
|
|
||||||
*/
|
|
||||||
public class RegistrationFactoryProvider implements FactoryBean<RegistrationFactory>, ApplicationContextAware {
|
|
||||||
|
|
||||||
private final Logger logger = LoggerFactory.getLogger(getClass());
|
|
||||||
|
|
||||||
private RegistrationFactory registrationFactory;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public RegistrationFactory getObject() throws BeansException {
|
|
||||||
return registrationFactory;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Class<?> getObjectType() {
|
|
||||||
return RegistrationFactory.class;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isSingleton() {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
|
|
||||||
ServiceRegistry<Registration> serviceRegistry = applicationContext.getBean(ServiceRegistry.class);
|
|
||||||
ClassLoader classLoader = applicationContext.getClassLoader();
|
|
||||||
this.registrationFactory = buildRegistrationFactory(serviceRegistry, classLoader);
|
|
||||||
}
|
|
||||||
|
|
||||||
private RegistrationFactory buildRegistrationFactory(ServiceRegistry<Registration> serviceRegistry,
|
|
||||||
ClassLoader classLoader) {
|
|
||||||
RegistrationFactory registrationFactory = null;
|
|
||||||
List<String> factoryClassNames = loadFactoryNames(RegistrationFactory.class, classLoader);
|
|
||||||
|
|
||||||
ResolvableType serviceRegistryType = forInstance(serviceRegistry);
|
|
||||||
// Get first generic Class
|
|
||||||
Class<?> registrationClass = resolveGenericClass(serviceRegistryType, ServiceRegistry.class, 0);
|
|
||||||
|
|
||||||
for (String factoryClassName : factoryClassNames) {
|
|
||||||
if (isPresent(factoryClassName, classLoader)) { // ignore compilation issue
|
|
||||||
Class<?> factoryClass = resolveClassName(factoryClassName, classLoader);
|
|
||||||
ResolvableType registrationFactoryType = forType(factoryClass);
|
|
||||||
Class<?> actualRegistrationClass = resolveGenericClass(registrationFactoryType, RegistrationFactory.class, 0);
|
|
||||||
if (registrationClass.equals(actualRegistrationClass)) {
|
|
||||||
registrationFactory = (RegistrationFactory) instantiateClass(registrationFactoryType.getRawClass());
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (registrationFactory == null) {
|
|
||||||
|
|
||||||
if (logger.isWarnEnabled()) {
|
|
||||||
logger.warn("{} implementation can't be resolved by ServiceRegistry[{}]",
|
|
||||||
registrationClass.getSimpleName(), serviceRegistry.getClass().getName());
|
|
||||||
}
|
|
||||||
|
|
||||||
registrationFactory = new DefaultRegistrationFactory();
|
|
||||||
} else {
|
|
||||||
if (logger.isInfoEnabled()) {
|
|
||||||
logger.info("{} has been resolved by ServiceRegistry[{}]",
|
|
||||||
registrationFactory.getClass().getName(), serviceRegistry.getClass().getName());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return registrationFactory;
|
|
||||||
}
|
|
||||||
|
|
||||||
private Class<?> resolveGenericClass(ResolvableType implementedType, Class<?> interfaceClass, int index) {
|
|
||||||
|
|
||||||
ResolvableType resolvableType = implementedType;
|
|
||||||
|
|
||||||
try {
|
|
||||||
OUTER:
|
|
||||||
while (true) {
|
|
||||||
|
|
||||||
ResolvableType[] interfaceTypes = resolvableType.getInterfaces();
|
|
||||||
|
|
||||||
for (ResolvableType interfaceType : interfaceTypes) {
|
|
||||||
if (interfaceType.resolve().equals(interfaceClass)) {
|
|
||||||
resolvableType = interfaceType;
|
|
||||||
break OUTER;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ResolvableType superType = resolvableType.getSuperType();
|
|
||||||
|
|
||||||
Class<?> superClass = superType.resolve();
|
|
||||||
|
|
||||||
if (Object.class.equals(superClass)) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
resolvableType = superType;
|
|
||||||
}
|
|
||||||
|
|
||||||
} catch (Throwable e) {
|
|
||||||
resolvableType = ResolvableType.forType(void.class);
|
|
||||||
}
|
|
||||||
|
|
||||||
return resolvableType.resolveGeneric(index);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -0,0 +1,59 @@
|
|||||||
|
/*
|
||||||
|
* 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.springframework.cloud.alibaba.dubbo.registry;
|
||||||
|
|
||||||
|
import org.aspectj.lang.annotation.After;
|
||||||
|
import org.aspectj.lang.annotation.Aspect;
|
||||||
|
import org.aspectj.lang.annotation.Before;
|
||||||
|
import org.springframework.cloud.alibaba.dubbo.registry.event.ServiceInstancePreRegisteredEvent;
|
||||||
|
import org.springframework.cloud.alibaba.dubbo.registry.event.ServiceInstanceRegisteredEvent;
|
||||||
|
import org.springframework.cloud.client.serviceregistry.Registration;
|
||||||
|
import org.springframework.cloud.client.serviceregistry.ServiceRegistry;
|
||||||
|
import org.springframework.context.ApplicationEventPublisher;
|
||||||
|
import org.springframework.context.ApplicationEventPublisherAware;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@link ServiceRegistry} Aspect
|
||||||
|
*
|
||||||
|
* @author <a href="mailto:mercyblitz@gmail.com">Mercy</a>
|
||||||
|
*/
|
||||||
|
@Aspect
|
||||||
|
public class ServiceRegistryAspect implements ApplicationEventPublisherAware {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The pointcut expression for {@link ServiceRegistry#register(Registration)}
|
||||||
|
*/
|
||||||
|
private static final String REGISTER_POINTCUT_EXPRESSION =
|
||||||
|
"execution(* org.springframework.cloud.client.serviceregistry.ServiceRegistry.register(*)) && args(registration)";
|
||||||
|
|
||||||
|
private ApplicationEventPublisher applicationEventPublisher;
|
||||||
|
|
||||||
|
@Before(REGISTER_POINTCUT_EXPRESSION)
|
||||||
|
public void beforeRegister(Registration registration) {
|
||||||
|
applicationEventPublisher.publishEvent(new ServiceInstancePreRegisteredEvent(registration));
|
||||||
|
}
|
||||||
|
|
||||||
|
@After(REGISTER_POINTCUT_EXPRESSION)
|
||||||
|
public void afterRegister(Registration registration) {
|
||||||
|
applicationEventPublisher.publishEvent(new ServiceInstanceRegisteredEvent(registration));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setApplicationEventPublisher(ApplicationEventPublisher applicationEventPublisher) {
|
||||||
|
this.applicationEventPublisher = applicationEventPublisher;
|
||||||
|
}
|
||||||
|
}
|
@ -1,52 +0,0 @@
|
|||||||
/*
|
|
||||||
* 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.springframework.cloud.alibaba.dubbo.registry.apache.zookeeper;
|
|
||||||
|
|
||||||
import org.springframework.cloud.alibaba.dubbo.registry.AbstractRegistrationFactory;
|
|
||||||
import org.springframework.cloud.alibaba.dubbo.registry.RegistrationFactory;
|
|
||||||
import org.springframework.cloud.client.ServiceInstance;
|
|
||||||
import org.springframework.cloud.zookeeper.discovery.ZookeeperInstance;
|
|
||||||
import org.springframework.cloud.zookeeper.serviceregistry.ServiceInstanceRegistration;
|
|
||||||
import org.springframework.cloud.zookeeper.serviceregistry.ZookeeperRegistration;
|
|
||||||
import org.springframework.context.ConfigurableApplicationContext;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Zookeeper {@link RegistrationFactory}
|
|
||||||
*
|
|
||||||
* @author <a href="mailto:mercyblitz@gmail.com">Mercy</a>
|
|
||||||
*/
|
|
||||||
public class ZookeeperRegistrationFactory extends AbstractRegistrationFactory<ZookeeperRegistration> {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public ZookeeperRegistration create(ServiceInstance serviceInstance, ConfigurableApplicationContext applicationContext) {
|
|
||||||
ZookeeperInstance zookeeperInstance = new ZookeeperInstance(serviceInstance.getInstanceId(),
|
|
||||||
serviceInstance.getServiceId(), serviceInstance.getMetadata());
|
|
||||||
|
|
||||||
ZookeeperRegistration registration = ServiceInstanceRegistration
|
|
||||||
.builder()
|
|
||||||
.address(serviceInstance.getHost())
|
|
||||||
.name(serviceInstance.getServiceId())
|
|
||||||
.payload(zookeeperInstance)
|
|
||||||
.port(serviceInstance.getPort())
|
|
||||||
.build();
|
|
||||||
|
|
||||||
// To trigger build() method
|
|
||||||
registration.getServiceInstance();
|
|
||||||
|
|
||||||
return registration;
|
|
||||||
}
|
|
||||||
}
|
|
@ -0,0 +1,39 @@
|
|||||||
|
/*
|
||||||
|
* 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.springframework.cloud.alibaba.dubbo.registry.event;
|
||||||
|
|
||||||
|
import org.springframework.cloud.client.ServiceInstance;
|
||||||
|
import org.springframework.cloud.client.serviceregistry.Registration;
|
||||||
|
import org.springframework.cloud.client.serviceregistry.ServiceRegistry;
|
||||||
|
import org.springframework.context.ApplicationEvent;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The before-{@link ServiceRegistry#register(Registration) register} event for {@link ServiceInstance}
|
||||||
|
*
|
||||||
|
* @author <a href="mailto:mercyblitz@gmail.com">Mercy</a>
|
||||||
|
*/
|
||||||
|
public class ServiceInstancePreRegisteredEvent extends ApplicationEvent {
|
||||||
|
|
||||||
|
public ServiceInstancePreRegisteredEvent(Registration source) {
|
||||||
|
super(source);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Registration getSource() {
|
||||||
|
return (Registration) super.getSource();
|
||||||
|
}
|
||||||
|
}
|
@ -1,88 +0,0 @@
|
|||||||
/*
|
|
||||||
* 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.springframework.cloud.alibaba.dubbo.registry.hashicorp.consul;
|
|
||||||
|
|
||||||
import com.ecwid.consul.v1.agent.model.NewService;
|
|
||||||
import org.springframework.cloud.alibaba.dubbo.registry.AbstractRegistrationFactory;
|
|
||||||
import org.springframework.cloud.alibaba.dubbo.registry.RegistrationFactory;
|
|
||||||
import org.springframework.cloud.client.ServiceInstance;
|
|
||||||
import org.springframework.cloud.consul.discovery.ConsulDiscoveryProperties;
|
|
||||||
import org.springframework.cloud.consul.discovery.ConsulServerUtils;
|
|
||||||
import org.springframework.cloud.consul.serviceregistry.ConsulRegistration;
|
|
||||||
import org.springframework.context.ConfigurableApplicationContext;
|
|
||||||
|
|
||||||
import java.util.LinkedHashSet;
|
|
||||||
import java.util.LinkedList;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* {@link ConsulRegistration} {@link RegistrationFactory} implementation
|
|
||||||
*
|
|
||||||
* @author <a href="mailto:mercyblitz@gmail.com">Mercy</a>
|
|
||||||
*/
|
|
||||||
public class ConsulRegistrationFactory extends AbstractRegistrationFactory<ConsulRegistration> {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public ConsulRegistration create(ServiceInstance serviceInstance, ConfigurableApplicationContext applicationContext) {
|
|
||||||
Map<String, String> metadata = getMetadata(serviceInstance);
|
|
||||||
List<String> tags = createTags(metadata);
|
|
||||||
|
|
||||||
NewService service = new NewService();
|
|
||||||
service.setId(serviceInstance.getInstanceId());
|
|
||||||
service.setName(serviceInstance.getServiceId());
|
|
||||||
service.setAddress(serviceInstance.getHost());
|
|
||||||
service.setPort(serviceInstance.getPort());
|
|
||||||
service.setMeta(metadata);
|
|
||||||
service.setTags(tags);
|
|
||||||
|
|
||||||
ConsulDiscoveryProperties properties = applicationContext.getBean(ConsulDiscoveryProperties.class);
|
|
||||||
|
|
||||||
ConsulRegistration registration = new ConsulRegistration(service, properties);
|
|
||||||
return registration;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param metadata
|
|
||||||
* @return
|
|
||||||
* @see ConsulServerUtils#getMetadata(java.util.List)
|
|
||||||
*/
|
|
||||||
private List<String> createTags(Map<String, String> metadata) {
|
|
||||||
List<String> tags = new LinkedList<>();
|
|
||||||
for (Map.Entry<String, String> entry : metadata.entrySet()) {
|
|
||||||
String tag = entry.getKey() + "=" + entry.getValue();
|
|
||||||
tags.add(tag);
|
|
||||||
|
|
||||||
}
|
|
||||||
return tags;
|
|
||||||
}
|
|
||||||
|
|
||||||
private Map<String, String> getMetadata(ServiceInstance serviceInstance) {
|
|
||||||
Map<String, String> metadata = serviceInstance.getMetadata();
|
|
||||||
Set<String> removedKeys = new LinkedHashSet<>();
|
|
||||||
for (String key : metadata.keySet()) {
|
|
||||||
if (key.contains(".")) {
|
|
||||||
removedKeys.add(key);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for (String removedKey : removedKeys) {
|
|
||||||
metadata.remove(removedKey);
|
|
||||||
}
|
|
||||||
return metadata;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,60 +0,0 @@
|
|||||||
/*
|
|
||||||
* 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.springframework.cloud.alibaba.dubbo.registry.netflix.eureka;
|
|
||||||
|
|
||||||
import com.netflix.appinfo.HealthCheckHandler;
|
|
||||||
import com.netflix.discovery.EurekaClientConfig;
|
|
||||||
import org.springframework.beans.BeanUtils;
|
|
||||||
import org.springframework.beans.factory.ObjectProvider;
|
|
||||||
import org.springframework.cloud.alibaba.dubbo.registry.AbstractRegistrationFactory;
|
|
||||||
import org.springframework.cloud.client.ServiceInstance;
|
|
||||||
import org.springframework.cloud.commons.util.InetUtils;
|
|
||||||
import org.springframework.cloud.netflix.eureka.CloudEurekaInstanceConfig;
|
|
||||||
import org.springframework.cloud.netflix.eureka.EurekaInstanceConfigBean;
|
|
||||||
import org.springframework.cloud.netflix.eureka.serviceregistry.EurekaRegistration;
|
|
||||||
import org.springframework.context.ConfigurableApplicationContext;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* {@link EurekaRegistration} Factory
|
|
||||||
*
|
|
||||||
* @author <a href="mailto:mercyblitz@gmail.com">Mercy</a>
|
|
||||||
*/
|
|
||||||
public class EurekaRegistrationFactory extends AbstractRegistrationFactory<EurekaRegistration> {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public EurekaRegistration create(ServiceInstance serviceInstance, ConfigurableApplicationContext applicationContext) {
|
|
||||||
CloudEurekaInstanceConfig cloudEurekaInstanceConfig = applicationContext.getBean(CloudEurekaInstanceConfig.class);
|
|
||||||
ObjectProvider<HealthCheckHandler> healthCheckHandler = applicationContext.getBeanProvider(HealthCheckHandler.class);
|
|
||||||
EurekaClientConfig eurekaClientConfig = applicationContext.getBean(EurekaClientConfig.class);
|
|
||||||
InetUtils inetUtils = applicationContext.getBean(InetUtils.class);
|
|
||||||
EurekaInstanceConfigBean eurekaInstanceConfigBean = new EurekaInstanceConfigBean(inetUtils);
|
|
||||||
BeanUtils.copyProperties(cloudEurekaInstanceConfig, eurekaInstanceConfigBean);
|
|
||||||
String serviceId = serviceInstance.getServiceId();
|
|
||||||
eurekaInstanceConfigBean.setInstanceId(serviceInstance.getInstanceId());
|
|
||||||
eurekaInstanceConfigBean.setVirtualHostName(serviceId);
|
|
||||||
eurekaInstanceConfigBean.setSecureVirtualHostName(serviceId);
|
|
||||||
eurekaInstanceConfigBean.setAppname(serviceId);
|
|
||||||
eurekaInstanceConfigBean.setHostname(serviceInstance.getHost());
|
|
||||||
eurekaInstanceConfigBean.setNonSecurePort(serviceInstance.getPort());
|
|
||||||
eurekaInstanceConfigBean.setMetadataMap(serviceInstance.getMetadata());
|
|
||||||
|
|
||||||
return EurekaRegistration.builder(eurekaInstanceConfigBean)
|
|
||||||
.with(healthCheckHandler)
|
|
||||||
.with(eurekaClientConfig, applicationContext)
|
|
||||||
.build();
|
|
||||||
}
|
|
||||||
}
|
|
@ -0,0 +1,72 @@
|
|||||||
|
/*
|
||||||
|
* 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.springframework.cloud.alibaba.dubbo.util;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||||
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
|
import com.fasterxml.jackson.databind.SerializationFeature;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
import org.springframework.util.StringUtils;
|
||||||
|
|
||||||
|
import javax.annotation.PostConstruct;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* JSON Utilities class
|
||||||
|
*
|
||||||
|
* @author <a href="mailto:mercyblitz@gmail.com">Mercy</a>
|
||||||
|
*/
|
||||||
|
public class JSONUtils {
|
||||||
|
|
||||||
|
private final Logger logger = LoggerFactory.getLogger(getClass());
|
||||||
|
|
||||||
|
private final ObjectMapper objectMapper = new ObjectMapper();
|
||||||
|
|
||||||
|
@PostConstruct
|
||||||
|
public void init() {
|
||||||
|
this.objectMapper.enable(SerializationFeature.INDENT_OUTPUT);
|
||||||
|
}
|
||||||
|
|
||||||
|
public String toJSON(Object object) {
|
||||||
|
String jsonContent = null;
|
||||||
|
try {
|
||||||
|
jsonContent = objectMapper.writeValueAsString(object);
|
||||||
|
} catch (JsonProcessingException e) {
|
||||||
|
if (logger.isErrorEnabled()) {
|
||||||
|
logger.error(e.getMessage(), e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return jsonContent;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<String> toList(String json) {
|
||||||
|
List<String> list = Collections.emptyList();
|
||||||
|
try {
|
||||||
|
if (StringUtils.hasText(json)) {
|
||||||
|
list = objectMapper.readValue(json, List.class);
|
||||||
|
}
|
||||||
|
} catch (IOException e) {
|
||||||
|
if (logger.isErrorEnabled()) {
|
||||||
|
logger.error(e.getMessage(), e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue