[3.0]Cleanup EventDispatcher mechanism (#7677)
This commit is contained in:
parent
87bc352bc3
commit
db41d2a5f4
|
|
@ -142,7 +142,7 @@ public interface Logger {
|
|||
|
||||
/**
|
||||
* Is debug logging currently enabled?
|
||||
*
|
||||
*
|
||||
* @return true if debug is enabled
|
||||
*/
|
||||
boolean isDebugEnabled();
|
||||
|
|
|
|||
|
|
@ -16,19 +16,14 @@
|
|||
*/
|
||||
package org.apache.dubbo.common.threadpool.event;
|
||||
|
||||
import org.apache.dubbo.event.Event;
|
||||
|
||||
/**
|
||||
* An {@link Event Dubbo event} when the Dubbo thread pool is exhausted.
|
||||
*
|
||||
* @see Event
|
||||
* An Event when the Dubbo thread pool is exhausted.
|
||||
*/
|
||||
public class ThreadPoolExhaustedEvent extends Event {
|
||||
public class ThreadPoolExhaustedEvent {
|
||||
|
||||
final String msg;
|
||||
|
||||
public ThreadPoolExhaustedEvent(Object source, String msg) {
|
||||
super(source);
|
||||
public ThreadPoolExhaustedEvent(String msg) {
|
||||
this.msg = msg;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -14,16 +14,13 @@
|
|||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.dubbo.event;
|
||||
package org.apache.dubbo.common.threadpool.event;
|
||||
|
||||
/**
|
||||
* Echo {@link Event}
|
||||
*
|
||||
* @since 2.7.5
|
||||
*/
|
||||
class EchoEvent extends Event {
|
||||
public interface ThreadPoolExhaustedListener {
|
||||
|
||||
public EchoEvent(Object source) {
|
||||
super(source);
|
||||
}
|
||||
/**
|
||||
* Notify when the thread pool is exhausted.
|
||||
* {@link org.apache.dubbo.common.threadpool.support.AbortPolicyWithReport}
|
||||
*/
|
||||
void onEvent(ThreadPoolExhaustedEvent event);
|
||||
}
|
||||
|
|
@ -20,14 +20,16 @@ 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.threadpool.event.ThreadPoolExhaustedEvent;
|
||||
import org.apache.dubbo.common.threadpool.event.ThreadPoolExhaustedListener;
|
||||
import org.apache.dubbo.common.utils.ConcurrentHashSet;
|
||||
import org.apache.dubbo.common.utils.JVMUtil;
|
||||
import org.apache.dubbo.common.utils.StringUtils;
|
||||
import org.apache.dubbo.event.EventDispatcher;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Date;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.RejectedExecutionException;
|
||||
|
|
@ -65,6 +67,8 @@ public class AbortPolicyWithReport extends ThreadPoolExecutor.AbortPolicy {
|
|||
|
||||
private static final String USER_HOME = System.getProperty("user.home");
|
||||
|
||||
private final Set<ThreadPoolExhaustedListener> listeners = new ConcurrentHashSet<>();
|
||||
|
||||
public AbortPolicyWithReport(String threadName, URL url) {
|
||||
this.threadName = threadName;
|
||||
this.url = url;
|
||||
|
|
@ -73,25 +77,33 @@ public class AbortPolicyWithReport extends ThreadPoolExecutor.AbortPolicy {
|
|||
@Override
|
||||
public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {
|
||||
String msg = String.format("Thread pool is EXHAUSTED!" +
|
||||
" Thread Name: %s, Pool Size: %d (active: %d, core: %d, max: %d, largest: %d), Task: %d (completed: "
|
||||
+ "%d)," +
|
||||
" Executor status:(isShutdown:%s, isTerminated:%s, isTerminating:%s), in %s://%s:%d!",
|
||||
threadName, e.getPoolSize(), e.getActiveCount(), e.getCorePoolSize(), e.getMaximumPoolSize(),
|
||||
e.getLargestPoolSize(),
|
||||
e.getTaskCount(), e.getCompletedTaskCount(), e.isShutdown(), e.isTerminated(), e.isTerminating(),
|
||||
url.getProtocol(), url.getIp(), url.getPort());
|
||||
" Thread Name: %s, Pool Size: %d (active: %d, core: %d, max: %d, largest: %d)," +
|
||||
" Task: %d (completed: %d)," +
|
||||
" Executor status:(isShutdown:%s, isTerminated:%s, isTerminating:%s), in %s://%s:%d!",
|
||||
threadName, e.getPoolSize(), e.getActiveCount(), e.getCorePoolSize(), e.getMaximumPoolSize(),
|
||||
e.getLargestPoolSize(),
|
||||
e.getTaskCount(), e.getCompletedTaskCount(), e.isShutdown(), e.isTerminated(), e.isTerminating(),
|
||||
url.getProtocol(), url.getIp(), url.getPort());
|
||||
logger.warn(msg);
|
||||
dumpJStack();
|
||||
dispatchThreadPoolExhaustedEvent(msg);
|
||||
throw new RejectedExecutionException(msg);
|
||||
}
|
||||
|
||||
public void addThreadPoolExhaustedEventListener(ThreadPoolExhaustedListener listener) {
|
||||
listeners.add(listener);
|
||||
}
|
||||
|
||||
public void removeThreadPoolExhaustedEventListener(ThreadPoolExhaustedListener listener) {
|
||||
listeners.remove(listener);
|
||||
}
|
||||
|
||||
/**
|
||||
* dispatch ThreadPoolExhaustedEvent
|
||||
* @param msg
|
||||
*/
|
||||
public void dispatchThreadPoolExhaustedEvent(String msg) {
|
||||
EventDispatcher.getDefaultExtension().dispatch(new ThreadPoolExhaustedEvent(this, msg));
|
||||
listeners.forEach(listener -> listener.onEvent(new ThreadPoolExhaustedEvent(msg)));
|
||||
}
|
||||
|
||||
private void dumpJStack() {
|
||||
|
|
@ -124,7 +136,7 @@ public class AbortPolicyWithReport extends ThreadPoolExecutor.AbortPolicy {
|
|||
String dateStr = sdf.format(new Date());
|
||||
//try-with-resources
|
||||
try (FileOutputStream jStackStream = new FileOutputStream(
|
||||
new File(dumpPath, "Dubbo_JStack.log" + "." + dateStr))) {
|
||||
new File(dumpPath, "Dubbo_JStack.log" + "." + dateStr))) {
|
||||
JVMUtil.jstack(jStackStream);
|
||||
} catch (Throwable t) {
|
||||
logger.error("dump jStack error", t);
|
||||
|
|
|
|||
|
|
@ -1,168 +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.apache.dubbo.event;
|
||||
|
||||
import org.apache.dubbo.common.extension.ExtensionLoader;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.ServiceLoader;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.ConcurrentMap;
|
||||
import java.util.concurrent.Executor;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.Predicate;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import static java.util.Collections.sort;
|
||||
import static java.util.Collections.unmodifiableList;
|
||||
import static org.apache.dubbo.event.EventListener.findEventType;
|
||||
|
||||
/**
|
||||
* The abstract {@link EventDispatcher} providers the common implementation.
|
||||
*
|
||||
* @see EventDispatcher
|
||||
* @see Listenable
|
||||
* @see ServiceLoader
|
||||
* @see EventListener
|
||||
* @see Event
|
||||
* @since 2.7.5
|
||||
*/
|
||||
public abstract class AbstractEventDispatcher implements EventDispatcher {
|
||||
|
||||
private final Object mutex = new Object();
|
||||
|
||||
private final ConcurrentMap<Class<? extends Event>, List<EventListener>> listenersCache = new ConcurrentHashMap<>();
|
||||
|
||||
private final Executor executor;
|
||||
|
||||
/**
|
||||
* Constructor with an instance of {@link Executor}
|
||||
*
|
||||
* @param executor {@link Executor}
|
||||
* @throws NullPointerException <code>executor</code> is <code>null</code>
|
||||
*/
|
||||
protected AbstractEventDispatcher(Executor executor) {
|
||||
if (executor == null) {
|
||||
throw new NullPointerException("executor must not be null");
|
||||
}
|
||||
this.executor = executor;
|
||||
this.loadEventListenerInstances();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addEventListener(EventListener<?> listener) throws NullPointerException, IllegalArgumentException {
|
||||
Listenable.assertListener(listener);
|
||||
doInListener(listener, listeners -> {
|
||||
addIfAbsent(listeners, listener);
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeEventListener(EventListener<?> listener) throws NullPointerException, IllegalArgumentException {
|
||||
Listenable.assertListener(listener);
|
||||
doInListener(listener, listeners -> listeners.remove(listener));
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<EventListener<?>> getAllEventListeners() {
|
||||
List<EventListener<?>> listeners = new LinkedList<>();
|
||||
|
||||
sortedListeners().forEach(listener -> {
|
||||
addIfAbsent(listeners, listener);
|
||||
});
|
||||
|
||||
return unmodifiableList(listeners);
|
||||
}
|
||||
|
||||
protected Stream<EventListener> sortedListeners() {
|
||||
return sortedListeners(e -> true);
|
||||
}
|
||||
|
||||
protected Stream<EventListener> sortedListeners(Predicate<Map.Entry<Class<? extends Event>, List<EventListener>>> predicate) {
|
||||
return listenersCache
|
||||
.entrySet()
|
||||
.stream()
|
||||
.filter(predicate)
|
||||
.map(Map.Entry::getValue)
|
||||
.flatMap(Collection::stream)
|
||||
.sorted();
|
||||
}
|
||||
|
||||
private <E> void addIfAbsent(Collection<E> collection, E element) {
|
||||
if (!collection.contains(element)) {
|
||||
collection.add(element);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dispatch(Event event) {
|
||||
|
||||
Executor executor = getExecutor();
|
||||
|
||||
// execute in sequential or parallel execution model
|
||||
executor.execute(() -> {
|
||||
sortedListeners(entry -> entry.getKey().isAssignableFrom(event.getClass()))
|
||||
.forEach(listener -> {
|
||||
if (listener instanceof ConditionalEventListener) {
|
||||
ConditionalEventListener predicateEventListener = (ConditionalEventListener) listener;
|
||||
if (!predicateEventListener.accept(event)) { // No accept
|
||||
return;
|
||||
}
|
||||
}
|
||||
// Handle the event
|
||||
listener.onEvent(event);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the non-null {@link Executor}
|
||||
*/
|
||||
@Override
|
||||
public final Executor getExecutor() {
|
||||
return executor;
|
||||
}
|
||||
|
||||
protected void doInListener(EventListener<?> listener, Consumer<Collection<EventListener>> consumer) {
|
||||
Class<? extends Event> eventType = findEventType(listener);
|
||||
if (eventType != null) {
|
||||
synchronized (mutex) {
|
||||
List<EventListener> listeners = listenersCache.computeIfAbsent(eventType, e -> new LinkedList<>());
|
||||
// consume
|
||||
consumer.accept(listeners);
|
||||
// sort
|
||||
sort(listeners);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Default, load the instances of {@link EventListener event listeners} by {@link ServiceLoader}
|
||||
* <p>
|
||||
* It could be override by the sub-class
|
||||
*
|
||||
* @see EventListener
|
||||
* @see ServiceLoader#load(Class)
|
||||
*/
|
||||
protected void loadEventListenerInstances() {
|
||||
ExtensionLoader<EventListener> loader = ExtensionLoader.getExtensionLoader(EventListener.class);
|
||||
loader.getSupportedExtensionInstances().forEach(this::addEventListener);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,35 +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.apache.dubbo.event;
|
||||
|
||||
/**
|
||||
* An {@link EventListener} extending the the conditional feature that {@link #accept(Event) decides} some
|
||||
* {@link Event event} is handled or not by current listener.
|
||||
*
|
||||
* @see EventListener
|
||||
* @since 2.7.5
|
||||
*/
|
||||
public interface ConditionalEventListener<E extends Event> extends EventListener<E> {
|
||||
|
||||
/**
|
||||
* Accept the event is handled or not by current listener
|
||||
*
|
||||
* @param event {@link Event event}
|
||||
* @return if handled, return <code>true</code>, or <code>false</code>
|
||||
*/
|
||||
boolean accept(E event);
|
||||
}
|
||||
|
|
@ -1,31 +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.apache.dubbo.event;
|
||||
|
||||
/**
|
||||
* Direct {@link EventDispatcher} implementation uses current thread execution model
|
||||
*
|
||||
* @see EventDispatcher
|
||||
* @since 2.7.5
|
||||
*/
|
||||
public final class DirectEventDispatcher extends AbstractEventDispatcher {
|
||||
public static final String NAME = "direct";
|
||||
|
||||
public DirectEventDispatcher() {
|
||||
super(DIRECT_EXECUTOR);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,49 +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.apache.dubbo.event;
|
||||
|
||||
import java.util.EventObject;
|
||||
|
||||
/**
|
||||
* An event object of Dubbo is based on the Java standard {@link EventObject event}
|
||||
*
|
||||
* @since 2.7.5
|
||||
*/
|
||||
public abstract class Event extends EventObject {
|
||||
|
||||
private static final long serialVersionUID = -1704315605423947137L;
|
||||
|
||||
/**
|
||||
* The timestamp of event occurs
|
||||
*/
|
||||
private final long timestamp;
|
||||
|
||||
/**
|
||||
* Constructs a prototypical Event.
|
||||
*
|
||||
* @param source The object on which the Event initially occurred.
|
||||
* @throws IllegalArgumentException if source is null.
|
||||
*/
|
||||
public Event(Object source) {
|
||||
super(source);
|
||||
this.timestamp = System.currentTimeMillis();
|
||||
}
|
||||
|
||||
public long getTimestamp() {
|
||||
return timestamp;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,66 +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.apache.dubbo.event;
|
||||
|
||||
import org.apache.dubbo.common.extension.ExtensionLoader;
|
||||
import org.apache.dubbo.common.extension.SPI;
|
||||
|
||||
import java.util.concurrent.Executor;
|
||||
|
||||
/**
|
||||
* {@link Event Dubbo Event} Dispatcher
|
||||
*
|
||||
* @see Event
|
||||
* @see EventListener
|
||||
* @see DirectEventDispatcher
|
||||
* @since 2.7.5
|
||||
*/
|
||||
@SPI(DirectEventDispatcher.NAME)
|
||||
public interface EventDispatcher extends Listenable<EventListener<?>> {
|
||||
|
||||
/**
|
||||
* Direct {@link Executor} uses sequential execution model
|
||||
*/
|
||||
Executor DIRECT_EXECUTOR = Runnable::run;
|
||||
|
||||
/**
|
||||
* Dispatch a Dubbo event to the registered {@link EventListener Dubbo event listeners}
|
||||
*
|
||||
* @param event a {@link Event Dubbo event}
|
||||
*/
|
||||
void dispatch(Event event);
|
||||
|
||||
/**
|
||||
* The {@link Executor} to dispatch a {@link Event Dubbo event}
|
||||
*
|
||||
* @return default implementation directly invoke {@link Runnable#run()} method, rather than multiple-threaded
|
||||
* {@link Executor}. If the return value is <code>null</code>, the behavior is same as default.
|
||||
* @see #DIRECT_EXECUTOR
|
||||
*/
|
||||
default Executor getExecutor() {
|
||||
return DIRECT_EXECUTOR;
|
||||
}
|
||||
|
||||
/**
|
||||
* The default extension of {@link EventDispatcher} is loaded by {@link ExtensionLoader}
|
||||
*
|
||||
* @return the default extension of {@link EventDispatcher}
|
||||
*/
|
||||
static EventDispatcher getDefaultExtension() {
|
||||
return ExtensionLoader.getExtensionLoader(EventDispatcher.class).getDefaultExtension();
|
||||
}
|
||||
}
|
||||
|
|
@ -1,120 +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.apache.dubbo.event;
|
||||
|
||||
import org.apache.dubbo.common.extension.SPI;
|
||||
import org.apache.dubbo.common.lang.Prioritized;
|
||||
|
||||
import java.lang.reflect.ParameterizedType;
|
||||
import java.lang.reflect.Type;
|
||||
import java.util.Objects;
|
||||
|
||||
import static org.apache.dubbo.common.utils.ReflectUtils.findParameterizedTypes;
|
||||
|
||||
/**
|
||||
* The {@link Event Dubbo Event} Listener that is based on Java standard {@link java.util.EventListener} interface supports
|
||||
* the generic {@link Event}.
|
||||
* <p>
|
||||
* The {@link #onEvent(Event) handle method} will be notified when the matched-type {@link Event Dubbo Event} is
|
||||
* published, whose priority could be changed by {@link #getPriority()} method.
|
||||
*
|
||||
* @param <E> the concrete class of {@link Event Dubbo Event}
|
||||
* @see Event
|
||||
* @see java.util.EventListener
|
||||
* @since 2.7.5
|
||||
*/
|
||||
@SPI
|
||||
@FunctionalInterface
|
||||
public interface EventListener<E extends Event> extends java.util.EventListener, Prioritized {
|
||||
|
||||
/**
|
||||
* Handle a {@link Event Dubbo Event} when it's be published
|
||||
*
|
||||
* @param event a {@link Event Dubbo Event}
|
||||
*/
|
||||
void onEvent(E event);
|
||||
|
||||
/**
|
||||
* The priority of {@link EventListener current listener}.
|
||||
*
|
||||
* @return the value is more greater, the priority is more lower.
|
||||
* {@link Integer#MIN_VALUE} indicates the highest priority. The default value is {@link Integer#MAX_VALUE}.
|
||||
* The comparison rule , refer to {@link #compareTo}.
|
||||
*/
|
||||
@Override
|
||||
default int getPriority() {
|
||||
return NORMAL_PRIORITY;
|
||||
}
|
||||
|
||||
/**
|
||||
* Find the {@link Class type} {@link Event Dubbo event} from the specified {@link EventListener Dubbo event listener}
|
||||
*
|
||||
* @param listener the {@link Class class} of {@link EventListener Dubbo event listener}
|
||||
* @return <code>null</code> if not found
|
||||
*/
|
||||
static Class<? extends Event> findEventType(EventListener<?> listener) {
|
||||
return findEventType(listener.getClass());
|
||||
}
|
||||
|
||||
/**
|
||||
* Find the {@link Class type} {@link Event Dubbo event} from the specified {@link EventListener Dubbo event listener}
|
||||
*
|
||||
* @param listenerClass the {@link Class class} of {@link EventListener Dubbo event listener}
|
||||
* @return <code>null</code> if not found
|
||||
*/
|
||||
static Class<? extends Event> findEventType(Class<?> listenerClass) {
|
||||
Class<? extends Event> eventType = null;
|
||||
|
||||
if (listenerClass != null && EventListener.class.isAssignableFrom(listenerClass)) {
|
||||
eventType = findParameterizedTypes(listenerClass)
|
||||
.stream()
|
||||
.map(EventListener::findEventType)
|
||||
.filter(Objects::nonNull)
|
||||
.findAny()
|
||||
.orElse((Class) findEventType(listenerClass.getSuperclass()));
|
||||
}
|
||||
|
||||
return eventType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Find the type {@link Event Dubbo event} from the specified {@link ParameterizedType} presents
|
||||
* a class of {@link EventListener Dubbo event listener}
|
||||
*
|
||||
* @param parameterizedType the {@link ParameterizedType} presents a class of {@link EventListener Dubbo event listener}
|
||||
* @return <code>null</code> if not found
|
||||
*/
|
||||
static Class<? extends Event> findEventType(ParameterizedType parameterizedType) {
|
||||
Class<? extends Event> eventType = null;
|
||||
|
||||
Type rawType = parameterizedType.getRawType();
|
||||
if ((rawType instanceof Class) && EventListener.class.isAssignableFrom((Class) rawType)) {
|
||||
Type[] typeArguments = parameterizedType.getActualTypeArguments();
|
||||
for (Type typeArgument : typeArguments) {
|
||||
if (typeArgument instanceof Class) {
|
||||
Class argumentClass = (Class) typeArgument;
|
||||
if (Event.class.isAssignableFrom(argumentClass)) {
|
||||
eventType = argumentClass;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return eventType;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,34 +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.apache.dubbo.event;
|
||||
|
||||
/**
|
||||
* Generic {@link Event Dubbo event}
|
||||
*
|
||||
* @param <S> the type of event source
|
||||
* @since 2.7.5
|
||||
*/
|
||||
public class GenericEvent<S> extends Event {
|
||||
|
||||
public GenericEvent(S source) {
|
||||
super(source);
|
||||
}
|
||||
|
||||
public S getSource() {
|
||||
return (S) super.getSource();
|
||||
}
|
||||
}
|
||||
|
|
@ -1,130 +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.apache.dubbo.event;
|
||||
|
||||
import org.apache.dubbo.common.function.ThrowableConsumer;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import static java.util.Collections.emptySet;
|
||||
import static java.util.stream.Stream.of;
|
||||
import static org.apache.dubbo.common.function.ThrowableFunction.execute;
|
||||
|
||||
/**
|
||||
* An abstract class of {@link EventListener} for Generic events, the sub class could add more {@link Event event}
|
||||
* handle methods, rather than only binds the {@link EventListener#onEvent(Event)} method that is declared to be
|
||||
* <code>final</code> the implementation can't override. It's notable that all {@link Event event} handle methods must
|
||||
* meet following conditions:
|
||||
* <ul>
|
||||
* <li>not {@link #onEvent(Event)} method</li>
|
||||
* <li><code>public</code> accessibility</li>
|
||||
* <li><code>void</code> return type</li>
|
||||
* <li>no {@link Exception exception} declaration</li>
|
||||
* <li>only one {@link Event} type argument</li>
|
||||
* </ul>
|
||||
*
|
||||
* @see Event
|
||||
* @see EventListener
|
||||
* @since 2.7.5
|
||||
*/
|
||||
public abstract class GenericEventListener implements EventListener<Event> {
|
||||
|
||||
private final Method onEventMethod;
|
||||
|
||||
private final Map<Class<?>, Set<Method>> handleEventMethods;
|
||||
|
||||
protected GenericEventListener() {
|
||||
this.onEventMethod = findOnEventMethod();
|
||||
this.handleEventMethods = findHandleEventMethods();
|
||||
}
|
||||
|
||||
private Method findOnEventMethod() {
|
||||
return execute(getClass(), listenerClass -> listenerClass.getMethod("onEvent", Event.class));
|
||||
}
|
||||
|
||||
private Map<Class<?>, Set<Method>> findHandleEventMethods() {
|
||||
// Event class for key, the eventMethods' Set as value
|
||||
Map<Class<?>, Set<Method>> eventMethods = new HashMap<>();
|
||||
of(getClass().getMethods())
|
||||
.filter(this::isHandleEventMethod)
|
||||
.forEach(method -> {
|
||||
Class<?> paramType = method.getParameterTypes()[0];
|
||||
Set<Method> methods = eventMethods.computeIfAbsent(paramType, key -> new LinkedHashSet<>());
|
||||
methods.add(method);
|
||||
});
|
||||
return eventMethods;
|
||||
}
|
||||
|
||||
public final void onEvent(Event event) {
|
||||
Class<?> eventClass = event.getClass();
|
||||
handleEventMethods.getOrDefault(eventClass, emptySet()).forEach(method -> {
|
||||
ThrowableConsumer.execute(method, m -> {
|
||||
m.invoke(this, event);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* The {@link Event event} handle methods must meet following conditions:
|
||||
* <ul>
|
||||
* <li>not {@link #onEvent(Event)} method</li>
|
||||
* <li><code>public</code> accessibility</li>
|
||||
* <li><code>void</code> return type</li>
|
||||
* <li>no {@link Exception exception} declaration</li>
|
||||
* <li>only one {@link Event} type argument</li>
|
||||
* </ul>
|
||||
*
|
||||
* @param method
|
||||
* @return
|
||||
*/
|
||||
private boolean isHandleEventMethod(Method method) {
|
||||
|
||||
if (onEventMethod.equals(method)) { // not {@link #onEvent(Event)} method
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!Modifier.isPublic(method.getModifiers())) { // not public
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!void.class.equals(method.getReturnType())) { // void return type
|
||||
return false;
|
||||
}
|
||||
|
||||
Class[] exceptionTypes = method.getExceptionTypes();
|
||||
|
||||
if (exceptionTypes.length > 0) { // no exception declaration
|
||||
return false;
|
||||
}
|
||||
|
||||
Class[] paramTypes = method.getParameterTypes();
|
||||
if (paramTypes.length != 1) { // not only one argument
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!Event.class.isAssignableFrom(paramTypes[0])) { // not Event type argument
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,131 +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.apache.dubbo.event;
|
||||
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import static java.util.stream.StreamSupport.stream;
|
||||
|
||||
/**
|
||||
* Dubbo Event Listenable
|
||||
*
|
||||
* @see EventDispatcher
|
||||
* @since 2.7.5
|
||||
*/
|
||||
public interface Listenable<E extends EventListener<?>> {
|
||||
|
||||
/**
|
||||
* Add a {@link EventListener Dubbo event listener}
|
||||
*
|
||||
* @param listener a {@link EventListener Dubbo event listener}
|
||||
* If current {@link EventListener} is existed, return <code>false</code>
|
||||
* @throws NullPointerException if <code>listener</code> argument is <code>null</code>
|
||||
* @throws IllegalArgumentException if <code>listener</code> argument is not concrete instance
|
||||
*/
|
||||
void addEventListener(E listener) throws NullPointerException, IllegalArgumentException;
|
||||
|
||||
/**
|
||||
* Add one or more {@link EventListener Dubbo event listeners}
|
||||
*
|
||||
* @param listener a {@link EventListener Dubbo event listener}
|
||||
* @param others an optional {@link EventListener Dubbo event listeners}
|
||||
* @throws NullPointerException if one of arguments is <code>null</code>
|
||||
* @throws IllegalArgumentException if one of arguments argument is not concrete instance
|
||||
*/
|
||||
default void addEventListeners(E listener, E... others) throws NullPointerException,
|
||||
IllegalArgumentException {
|
||||
List<E> listeners = new ArrayList<>(1 + others.length);
|
||||
listeners.add(listener);
|
||||
listeners.addAll(Arrays.asList(others));
|
||||
addEventListeners(listeners);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add multiple {@link EventListener Dubbo event listeners}
|
||||
*
|
||||
* @param listeners the {@link EventListener Dubbo event listeners}
|
||||
* @throws NullPointerException if <code>listeners</code> argument is <code>null</code>
|
||||
* @throws IllegalArgumentException if any element of <code>listeners</code> is not concrete instance
|
||||
*/
|
||||
default void addEventListeners(Iterable<E> listeners) throws NullPointerException, IllegalArgumentException {
|
||||
stream(listeners.spliterator(), false).forEach(this::addEventListener);
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove a {@link EventListener Dubbo event listener}
|
||||
*
|
||||
* @param listener a {@link EventListener Dubbo event listener}
|
||||
* @return If remove successfully, return <code>true</code>.
|
||||
* If current {@link EventListener} is existed, return <code>false</code>
|
||||
* @throws NullPointerException if <code>listener</code> argument is <code>null</code>
|
||||
*/
|
||||
void removeEventListener(E listener) throws NullPointerException, IllegalArgumentException;
|
||||
|
||||
/**
|
||||
* Remove a {@link EventListener Dubbo event listener}
|
||||
*
|
||||
* @param listeners the {@link EventListener Dubbo event listeners}
|
||||
* @return If remove successfully, return <code>true</code>.
|
||||
* If current {@link EventListener} is existed, return <code>false</code>
|
||||
* @throws NullPointerException if <code>listener</code> argument is <code>null</code>
|
||||
* @throws IllegalArgumentException if any element of <code>listeners</code> is not concrete instance
|
||||
*/
|
||||
default void removeEventListeners(Iterable<E> listeners) throws NullPointerException, IllegalArgumentException {
|
||||
stream(listeners.spliterator(), false).forEach(this::removeEventListener);
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove all {@link EventListener Dubbo event listeners}
|
||||
*
|
||||
* @return a amount of removed listeners
|
||||
*/
|
||||
default void removeAllEventListeners() {
|
||||
removeEventListeners(getAllEventListeners());
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all registered {@link EventListener Dubbo event listeners}
|
||||
*
|
||||
* @return non-null read-only ordered {@link EventListener Dubbo event listeners}
|
||||
* @see EventListener#getPriority()
|
||||
*/
|
||||
List<E> getAllEventListeners();
|
||||
|
||||
|
||||
/**
|
||||
* Assets the listener is valid or not
|
||||
*
|
||||
* @param listener the instance of {@link EventListener}
|
||||
* @throws NullPointerException
|
||||
*/
|
||||
static void assertListener(EventListener<?> listener) throws NullPointerException {
|
||||
if (listener == null) {
|
||||
throw new NullPointerException("The listener must not be null.");
|
||||
}
|
||||
|
||||
Class<?> listenerClass = listener.getClass();
|
||||
|
||||
int modifiers = listenerClass.getModifiers();
|
||||
|
||||
if (Modifier.isAbstract(modifiers) || Modifier.isInterface(modifiers)) {
|
||||
throw new IllegalArgumentException("The listener must be concrete class");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,33 +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.apache.dubbo.event;
|
||||
|
||||
import java.util.concurrent.ForkJoinPool;
|
||||
|
||||
/**
|
||||
* Parallel {@link EventDispatcher} implementation uses {@link ForkJoinPool#commonPool() JDK common thread pool}
|
||||
*
|
||||
* @see ForkJoinPool#commonPool()
|
||||
* @since 2.7.5
|
||||
*/
|
||||
public class ParallelEventDispatcher extends AbstractEventDispatcher {
|
||||
public static final String NAME = "parallel";
|
||||
|
||||
public ParallelEventDispatcher() {
|
||||
super(ForkJoinPool.commonPool());
|
||||
}
|
||||
}
|
||||
|
|
@ -1,2 +0,0 @@
|
|||
direct=org.apache.dubbo.event.DirectEventDispatcher
|
||||
parallel=org.apache.dubbo.event.ParallelEventDispatcher
|
||||
|
|
@ -16,8 +16,6 @@
|
|||
*/
|
||||
package org.apache.dubbo.common.threadpool.event;
|
||||
|
||||
import org.apache.dubbo.event.*;
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
|
|
@ -28,32 +26,23 @@ import static org.junit.jupiter.api.Assertions.assertEquals;
|
|||
*/
|
||||
public class ThreadPoolExhaustedEventListenerTest {
|
||||
|
||||
private EventDispatcher eventDispatcher;
|
||||
|
||||
private ThreadPoolExhaustedEventListenerTest.MyGenericEventListener listener;
|
||||
private MyListener listener;
|
||||
|
||||
@BeforeEach
|
||||
public void init() {
|
||||
this.listener = new ThreadPoolExhaustedEventListenerTest.MyGenericEventListener();
|
||||
this.eventDispatcher = EventDispatcher.getDefaultExtension();
|
||||
this.eventDispatcher.addEventListener(listener);
|
||||
}
|
||||
|
||||
@AfterEach
|
||||
public void destroy() {
|
||||
this.eventDispatcher.removeAllEventListeners();
|
||||
this.listener = new MyListener();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testOnEvent() {
|
||||
String msg = "Thread pool is EXHAUSTED! Thread Name: DubboServerHandler-127.0.0.1:12345, Pool Size: 1 (active: 0, core: 1, max: 1, largest: 1), Task: 6 (completed: 6), Executor status:(isShutdown:false, isTerminated:false, isTerminating:false), in dubbo://127.0.0.1:12345!, dubbo version: 2.7.3, current host: 127.0.0.1";
|
||||
ThreadPoolExhaustedEvent exhaustedEvent = new ThreadPoolExhaustedEvent(this, msg);
|
||||
eventDispatcher.dispatch(exhaustedEvent);
|
||||
ThreadPoolExhaustedEvent exhaustedEvent = new ThreadPoolExhaustedEvent(msg);
|
||||
listener.onEvent(exhaustedEvent);
|
||||
assertEquals(exhaustedEvent, listener.getThreadPoolExhaustedEvent());
|
||||
assertEquals(this, listener.getThreadPoolExhaustedEvent().getSource());
|
||||
}
|
||||
|
||||
class MyGenericEventListener implements EventListener<ThreadPoolExhaustedEvent> {
|
||||
static class MyListener implements ThreadPoolExhaustedListener {
|
||||
|
||||
private ThreadPoolExhaustedEvent threadPoolExhaustedEvent;
|
||||
|
||||
|
|
|
|||
|
|
@ -19,7 +19,6 @@ package org.apache.dubbo.common.threadpool.event;
|
|||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
|
||||
/**
|
||||
* {@link ThreadPoolExhaustedEvent} Test
|
||||
|
|
@ -28,12 +27,9 @@ public class ThreadPoolExhaustedEventTest {
|
|||
|
||||
@Test
|
||||
public void test() {
|
||||
long timestamp = System.currentTimeMillis();
|
||||
String msg = "Thread pool is EXHAUSTED! Thread Name: DubboServerHandler-127.0.0.1:12345, Pool Size: 1 (active: 0, core: 1, max: 1, largest: 1), Task: 6 (completed: 6), Executor status:(isShutdown:false, isTerminated:false, isTerminating:false), in dubbo://127.0.0.1:12345!, dubbo version: 2.7.3, current host: 127.0.0.1";
|
||||
ThreadPoolExhaustedEvent event = new ThreadPoolExhaustedEvent(this, msg);
|
||||
ThreadPoolExhaustedEvent event = new ThreadPoolExhaustedEvent(msg);
|
||||
|
||||
assertEquals(this, event.getSource());
|
||||
assertEquals(msg, event.getMsg());
|
||||
assertTrue(event.getTimestamp() >= timestamp);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,6 +17,8 @@
|
|||
package org.apache.dubbo.common.threadpool.support;
|
||||
|
||||
import org.apache.dubbo.common.URL;
|
||||
import org.apache.dubbo.common.threadpool.event.ThreadPoolExhaustedEvent;
|
||||
import org.apache.dubbo.common.threadpool.event.ThreadPoolExhaustedListener;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
|
|
@ -25,6 +27,8 @@ import java.util.concurrent.Executors;
|
|||
import java.util.concurrent.RejectedExecutionException;
|
||||
import java.util.concurrent.ThreadPoolExecutor;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
|
||||
public class AbortPolicyWithReportTest {
|
||||
@Test
|
||||
public void jStackDumpTest() throws InterruptedException {
|
||||
|
|
@ -96,4 +100,30 @@ public class AbortPolicyWithReportTest {
|
|||
|
||||
Thread.sleep(1000);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test_dispatchThreadPoolExhaustedEvent() {
|
||||
URL url = URL.valueOf("dubbo://admin:hello1234@10.20.130.230:20880/context/path?dump.directory=/tmp&version=1.0.0&application=morgan&noValue=");
|
||||
AbortPolicyWithReport abortPolicyWithReport = new AbortPolicyWithReport("Test", url);
|
||||
String msg = "Thread pool is EXHAUSTED! Thread Name: DubboServerHandler-127.0.0.1:12345, Pool Size: 1 (active: 0, core: 1, max: 1, largest: 1), Task: 6 (completed: 6), Executor status:(isShutdown:false, isTerminated:false, isTerminating:false), in dubbo://127.0.0.1:12345!, dubbo version: 2.7.3, current host: 127.0.0.1";
|
||||
MyListener listener = new MyListener();
|
||||
abortPolicyWithReport.addThreadPoolExhaustedEventListener(listener);
|
||||
abortPolicyWithReport.dispatchThreadPoolExhaustedEvent(msg);
|
||||
|
||||
assertEquals(listener.getThreadPoolExhaustedEvent().getMsg(), msg);
|
||||
}
|
||||
|
||||
static class MyListener implements ThreadPoolExhaustedListener {
|
||||
|
||||
private ThreadPoolExhaustedEvent threadPoolExhaustedEvent;
|
||||
|
||||
@Override
|
||||
public void onEvent(ThreadPoolExhaustedEvent event) {
|
||||
this.threadPoolExhaustedEvent = event;
|
||||
}
|
||||
|
||||
public ThreadPoolExhaustedEvent getThreadPoolExhaustedEvent() {
|
||||
return threadPoolExhaustedEvent;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,40 +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.apache.dubbo.event;
|
||||
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
public abstract class AbstractEventListener<E extends Event> implements EventListener<E> {
|
||||
|
||||
private final AtomicInteger eventOccurs = new AtomicInteger(0);
|
||||
|
||||
@Override
|
||||
public final void onEvent(E event) {
|
||||
eventOccurs.getAndIncrement();
|
||||
handleEvent(event);
|
||||
}
|
||||
|
||||
protected abstract void handleEvent(E event);
|
||||
|
||||
public int getEventOccurs() {
|
||||
return eventOccurs.get();
|
||||
}
|
||||
|
||||
protected void println(String message) {
|
||||
System.out.printf("[%s] %s\n", Thread.currentThread().getName(), message);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,77 +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.apache.dubbo.event;
|
||||
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertNull;
|
||||
|
||||
/**
|
||||
* {@link ConditionalEventListener} test
|
||||
*
|
||||
* @since 2.7.5
|
||||
*/
|
||||
public class ConditionalEventListenerTest {
|
||||
|
||||
private final EventDispatcher eventDispatcher = EventDispatcher.getDefaultExtension();
|
||||
|
||||
@BeforeEach
|
||||
public void init() {
|
||||
eventDispatcher.removeAllEventListeners();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testOnEvent() {
|
||||
|
||||
OnlyHelloWorldEventListener listener = new OnlyHelloWorldEventListener();
|
||||
|
||||
eventDispatcher.addEventListener(listener);
|
||||
|
||||
eventDispatcher.dispatch(new EchoEvent("1"));
|
||||
|
||||
assertNull(listener.getSource());
|
||||
|
||||
eventDispatcher.dispatch(new EchoEvent("Hello,World"));
|
||||
|
||||
assertEquals("Hello,World", listener.getSource());
|
||||
|
||||
// fix EventDispatcherTest.testDefaultMethods may contain OnlyHelloWorldEventListener
|
||||
// ( ConditionalEventListenerTest and EventDispatcherTest are running together in one suite case )
|
||||
eventDispatcher.removeAllEventListeners();
|
||||
}
|
||||
|
||||
static class OnlyHelloWorldEventListener implements ConditionalEventListener<EchoEvent> {
|
||||
|
||||
private String source;
|
||||
|
||||
@Override
|
||||
public boolean accept(EchoEvent event) {
|
||||
return "Hello,World".equals(event.getSource());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onEvent(EchoEvent event) {
|
||||
source = (String) event.getSource();
|
||||
}
|
||||
|
||||
public String getSource() {
|
||||
return source;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,153 +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.apache.dubbo.event;
|
||||
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static java.util.Arrays.asList;
|
||||
import static java.util.Collections.emptyList;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
|
||||
/**
|
||||
* {@link DirectEventDispatcher} Test
|
||||
*
|
||||
* @since 2.7.5
|
||||
*/
|
||||
public class DirectEventDispatcherTest {
|
||||
|
||||
private DirectEventDispatcher dispatcher;
|
||||
|
||||
private EchoEventListener echoEventListener;
|
||||
|
||||
private EchoEventListener2 echoEventListener2;
|
||||
|
||||
@BeforeEach
|
||||
public void init() {
|
||||
dispatcher = new DirectEventDispatcher();
|
||||
echoEventListener = new EchoEventListener();
|
||||
echoEventListener2 = new EchoEventListener2();
|
||||
}
|
||||
|
||||
@AfterEach
|
||||
public void destroy() {
|
||||
dispatcher.removeAllEventListeners();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetExecutor() {
|
||||
assertNotNull(dispatcher.getExecutor());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetAllListeners() {
|
||||
assertTrue(dispatcher.getAllEventListeners().isEmpty());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSingleListener() {
|
||||
// add two listeners
|
||||
dispatcher.addEventListener(echoEventListener);
|
||||
dispatcher.addEventListener(echoEventListener2);
|
||||
assertEquals(asList(echoEventListener2, echoEventListener), dispatcher.getAllEventListeners());
|
||||
|
||||
// add a duplicated listener
|
||||
dispatcher.addEventListener(echoEventListener);
|
||||
assertEquals(asList(echoEventListener2, echoEventListener), dispatcher.getAllEventListeners());
|
||||
|
||||
// remove
|
||||
dispatcher.removeEventListener(echoEventListener);
|
||||
assertEquals(asList(echoEventListener2), dispatcher.getAllEventListeners());
|
||||
|
||||
dispatcher.removeEventListener(echoEventListener2);
|
||||
assertEquals(emptyList(), dispatcher.getAllEventListeners());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMultipleListeners() {
|
||||
|
||||
// add two listeners
|
||||
dispatcher.addEventListeners(echoEventListener, echoEventListener2);
|
||||
assertEquals(asList(echoEventListener2, echoEventListener), dispatcher.getAllEventListeners());
|
||||
|
||||
// remove all listeners
|
||||
dispatcher.removeAllEventListeners();
|
||||
assertEquals(emptyList(), dispatcher.getAllEventListeners());
|
||||
|
||||
// add the duplicated listeners
|
||||
dispatcher.addEventListeners(echoEventListener, echoEventListener, echoEventListener2);
|
||||
assertEquals(asList(echoEventListener2, echoEventListener), dispatcher.getAllEventListeners());
|
||||
|
||||
// remove all listeners
|
||||
dispatcher.removeAllEventListeners();
|
||||
assertEquals(emptyList(), dispatcher.getAllEventListeners());
|
||||
|
||||
dispatcher.addEventListeners(asList(echoEventListener, echoEventListener, echoEventListener2));
|
||||
assertEquals(asList(echoEventListener2, echoEventListener), dispatcher.getAllEventListeners());
|
||||
|
||||
dispatcher.removeEventListeners(asList(echoEventListener, echoEventListener, echoEventListener2));
|
||||
assertEquals(emptyList(), dispatcher.getAllEventListeners());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDispatchEvent() {
|
||||
|
||||
dispatcher.addEventListener(echoEventListener);
|
||||
|
||||
// dispatch a Event
|
||||
dispatcher.dispatch(new Event("Test") {
|
||||
});
|
||||
|
||||
// no-op occurs
|
||||
assertEquals(0, echoEventListener.getEventOccurs());
|
||||
|
||||
// dispatch a EchoEvent
|
||||
dispatcher.dispatch(new EchoEvent("Hello,World"));
|
||||
|
||||
// event has been handled
|
||||
assertEquals(1, echoEventListener.getEventOccurs());
|
||||
|
||||
dispatcher.addEventListener(echoEventListener2);
|
||||
|
||||
// reset the listeners
|
||||
init();
|
||||
dispatcher.addEventListeners(echoEventListener, echoEventListener2);
|
||||
|
||||
// dispatch a Event
|
||||
dispatcher.dispatch(new Event("Test") {
|
||||
});
|
||||
|
||||
// echoEventListener will be not triggered + 0
|
||||
// echoEventListener2 will be triggered + 1
|
||||
assertEquals(0, echoEventListener.getEventOccurs());
|
||||
assertEquals(1, echoEventListener2.getEventOccurs());
|
||||
|
||||
// dispatch a EchoEvent
|
||||
// echoEventListener and echoEventListener2 are triggered both (+1)
|
||||
dispatcher.dispatch(new EchoEvent("Hello,World"));
|
||||
assertEquals(1, echoEventListener.getEventOccurs());
|
||||
assertEquals(2, echoEventListener2.getEventOccurs());
|
||||
|
||||
// both +1
|
||||
dispatcher.dispatch(new EchoEvent("2019"));
|
||||
assertEquals(2, echoEventListener.getEventOccurs());
|
||||
assertEquals(3, echoEventListener2.getEventOccurs());
|
||||
}
|
||||
}
|
||||
|
|
@ -1,32 +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.apache.dubbo.event;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* {@link EchoEvent} {@link EventListener}
|
||||
*
|
||||
* @since 2.7.5
|
||||
*/
|
||||
public class EchoEventListener extends AbstractEventListener<EchoEvent> implements Serializable {
|
||||
|
||||
@Override
|
||||
public void handleEvent(EchoEvent event) {
|
||||
println("EchoEventListener : " + event);
|
||||
}
|
||||
}
|
||||
|
|
@ -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.apache.dubbo.event;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Objects;
|
||||
import java.util.Vector;
|
||||
|
||||
/**
|
||||
* {@link EchoEvent} {@link EventListener} 2
|
||||
*
|
||||
* @since 2.7.5
|
||||
*/
|
||||
public class EchoEventListener2 extends Vector<EventListener<Event>> implements Serializable, EventListener<Event> {
|
||||
|
||||
private AbstractEventListener<Event> delegate = new AbstractEventListener<Event>() {
|
||||
@Override
|
||||
protected void handleEvent(Event event) {
|
||||
println("EchoEventListener2 : " + event);
|
||||
}
|
||||
};
|
||||
|
||||
@Override
|
||||
public void onEvent(Event event) {
|
||||
delegate.onEvent(event);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getPriority() {
|
||||
return -1;
|
||||
}
|
||||
|
||||
public int getEventOccurs() {
|
||||
return delegate.getEventOccurs();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
return this.getClass().equals(o.getClass());
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(this.getClass());
|
||||
}
|
||||
}
|
||||
|
|
@ -1,45 +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.apache.dubbo.event;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.apache.dubbo.event.EventDispatcher.DIRECT_EXECUTOR;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
|
||||
/**
|
||||
* {@link EventDispatcher} Test
|
||||
*
|
||||
* @see DirectEventDispatcher
|
||||
* @since 2.7.5
|
||||
*/
|
||||
public class EventDispatcherTest {
|
||||
|
||||
private EventDispatcher defaultInstance = EventDispatcher.getDefaultExtension();
|
||||
|
||||
@Test
|
||||
public void testDefaultInstance() {
|
||||
assertEquals(DirectEventDispatcher.class, defaultInstance.getClass());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDefaultMethods() {
|
||||
assertEquals(DIRECT_EXECUTOR, defaultInstance.getExecutor());
|
||||
assertTrue(defaultInstance.getAllEventListeners().isEmpty());
|
||||
}
|
||||
}
|
||||
|
|
@ -1,44 +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.apache.dubbo.event;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.apache.dubbo.event.EventListener.findEventType;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
|
||||
/**
|
||||
* {@link EventListener} Test
|
||||
*
|
||||
* @since 2.7.5
|
||||
*/
|
||||
public class EventListenerTest {
|
||||
|
||||
@Test
|
||||
public void testFindEventHierarchicalTypes() {
|
||||
assertEquals(EchoEvent.class, findEventType(new EchoEventListener()));
|
||||
assertEquals(Event.class, findEventType(new EchoEventListener2()));
|
||||
|
||||
assertEquals(EchoEvent.class, findEventType(EchoEventListener.class));
|
||||
assertEquals(Event.class, findEventType(EchoEventListener2.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testOnEvent() {
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,77 +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.apache.dubbo.event;
|
||||
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
|
||||
/**
|
||||
* {@link GenericEventListener} Test
|
||||
*
|
||||
* @since 2.7.5
|
||||
*/
|
||||
public class GenericEventListenerTest {
|
||||
|
||||
private EventDispatcher eventDispatcher;
|
||||
|
||||
private MyGenericEventListener listener;
|
||||
|
||||
@BeforeEach
|
||||
public void init() {
|
||||
this.listener = new MyGenericEventListener();
|
||||
this.eventDispatcher = EventDispatcher.getDefaultExtension();
|
||||
this.eventDispatcher.addEventListener(listener);
|
||||
}
|
||||
|
||||
@AfterEach
|
||||
public void destroy() {
|
||||
this.eventDispatcher.removeAllEventListeners();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testOnEvent() {
|
||||
String value = "Hello,World";
|
||||
EchoEvent echoEvent = new EchoEvent(value);
|
||||
eventDispatcher.dispatch(echoEvent);
|
||||
assertEquals(echoEvent, listener.getEchoEvent());
|
||||
assertEquals(value, listener.getEchoEvent().getSource());
|
||||
}
|
||||
|
||||
class MyGenericEventListener extends GenericEventListener {
|
||||
|
||||
private EchoEvent echoEvent;
|
||||
|
||||
public void onEvent(EchoEvent echoEvent) {
|
||||
this.echoEvent = echoEvent;
|
||||
}
|
||||
|
||||
public void event(EchoEvent echoEvent) {
|
||||
assertEquals("Hello,World", echoEvent.getSource());
|
||||
}
|
||||
|
||||
public void event(EchoEvent echoEvent, Object arg) {
|
||||
this.echoEvent = echoEvent;
|
||||
}
|
||||
|
||||
public EchoEvent getEchoEvent() {
|
||||
return echoEvent;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,41 +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.apache.dubbo.event;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
|
||||
/**
|
||||
* {@link GenericEvent} Test
|
||||
*
|
||||
* @since 2.7.5
|
||||
*/
|
||||
public class GenericEventTest {
|
||||
|
||||
@Test
|
||||
public void test() {
|
||||
|
||||
long timestamp = System.currentTimeMillis();
|
||||
GenericEvent<String> event = new GenericEvent("Hello,World");
|
||||
|
||||
assertEquals("Hello,World", event.getSource());
|
||||
assertTrue(event.getTimestamp() >= timestamp);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,59 +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.apache.dubbo.event;
|
||||
|
||||
import org.junit.jupiter.api.AfterAll;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.util.concurrent.ForkJoinPool;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
|
||||
/**
|
||||
* {@link ParallelEventDispatcher} Test
|
||||
*
|
||||
* @since 2.7.5
|
||||
*/
|
||||
public class ParallelEventDispatcherTest {
|
||||
|
||||
private EventDispatcher eventDispatcher;
|
||||
|
||||
private AbstractEventListener listener;
|
||||
|
||||
@BeforeEach
|
||||
public void init() {
|
||||
eventDispatcher = new ParallelEventDispatcher();
|
||||
listener = new EchoEventListener();
|
||||
eventDispatcher.addEventListener(listener);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDispatchEvent() throws InterruptedException {
|
||||
eventDispatcher.dispatch(new EchoEvent("Hello,World"));
|
||||
ForkJoinPool.commonPool().awaitTermination(1, TimeUnit.SECONDS);
|
||||
// event has been handled
|
||||
assertEquals(1, listener.getEventOccurs());
|
||||
}
|
||||
|
||||
@AfterAll
|
||||
public static void destroy() {
|
||||
ForkJoinPool.commonPool().shutdown();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -19,11 +19,6 @@ package org.apache.dubbo.config;
|
|||
import org.apache.dubbo.common.lang.ShutdownHookCallbacks;
|
||||
import org.apache.dubbo.common.logger.Logger;
|
||||
import org.apache.dubbo.common.logger.LoggerFactory;
|
||||
import org.apache.dubbo.config.event.DubboServiceDestroyedEvent;
|
||||
import org.apache.dubbo.config.event.DubboShutdownHookRegisteredEvent;
|
||||
import org.apache.dubbo.config.event.DubboShutdownHookUnregisteredEvent;
|
||||
import org.apache.dubbo.event.Event;
|
||||
import org.apache.dubbo.event.EventDispatcher;
|
||||
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
|
||||
|
|
@ -51,8 +46,6 @@ public class DubboShutdownHook extends Thread {
|
|||
*/
|
||||
private static final AtomicBoolean destroyed = new AtomicBoolean(false);
|
||||
|
||||
private final EventDispatcher eventDispatcher = EventDispatcher.getDefaultExtension();
|
||||
|
||||
private DubboShutdownHook(String name) {
|
||||
super(name);
|
||||
}
|
||||
|
|
@ -91,7 +84,6 @@ public class DubboShutdownHook extends Thread {
|
|||
if (registered.compareAndSet(false, true)) {
|
||||
DubboShutdownHook dubboShutdownHook = getDubboShutdownHook();
|
||||
Runtime.getRuntime().addShutdownHook(dubboShutdownHook);
|
||||
dispatch(new DubboShutdownHookRegisteredEvent(dubboShutdownHook));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -102,7 +94,6 @@ public class DubboShutdownHook extends Thread {
|
|||
if (registered.compareAndSet(true, false)) {
|
||||
DubboShutdownHook dubboShutdownHook = getDubboShutdownHook();
|
||||
Runtime.getRuntime().removeShutdownHook(dubboShutdownHook);
|
||||
dispatch(new DubboShutdownHookUnregisteredEvent(dubboShutdownHook));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -110,12 +101,9 @@ public class DubboShutdownHook extends Thread {
|
|||
* Destroy all the resources, including registries and protocols.
|
||||
*/
|
||||
public void doDestroy() {
|
||||
// dispatch the DubboDestroyedEvent @since 2.7.5
|
||||
dispatch(new DubboServiceDestroyedEvent(this));
|
||||
}
|
||||
|
||||
private void dispatch(Event event) {
|
||||
eventDispatcher.dispatch(event);
|
||||
if (logger.isInfoEnabled()) {
|
||||
logger.info("Dubbo Service has been destroyed.");
|
||||
}
|
||||
}
|
||||
|
||||
public boolean getRegistered() {
|
||||
|
|
|
|||
|
|
@ -31,12 +31,8 @@ import org.apache.dubbo.common.utils.StringUtils;
|
|||
import org.apache.dubbo.common.utils.UrlUtils;
|
||||
import org.apache.dubbo.config.annotation.Reference;
|
||||
import org.apache.dubbo.config.bootstrap.DubboBootstrap;
|
||||
import org.apache.dubbo.config.event.ReferenceConfigDestroyedEvent;
|
||||
import org.apache.dubbo.config.event.ReferenceConfigInitializedEvent;
|
||||
import org.apache.dubbo.config.support.Parameter;
|
||||
import org.apache.dubbo.config.utils.ConfigValidationUtils;
|
||||
import org.apache.dubbo.event.Event;
|
||||
import org.apache.dubbo.event.EventDispatcher;
|
||||
import org.apache.dubbo.registry.client.metadata.MetadataUtils;
|
||||
import org.apache.dubbo.rpc.Invoker;
|
||||
import org.apache.dubbo.rpc.Protocol;
|
||||
|
|
@ -225,9 +221,6 @@ public class ReferenceConfig<T> extends ReferenceConfigBase<T> {
|
|||
}
|
||||
invoker = null;
|
||||
ref = null;
|
||||
|
||||
// dispatch a ReferenceConfigDestroyedEvent since 2.7.4
|
||||
dispatch(new ReferenceConfigDestroyedEvent(this));
|
||||
}
|
||||
|
||||
protected synchronized void init() {
|
||||
|
|
@ -341,9 +334,6 @@ public class ReferenceConfig<T> extends ReferenceConfigBase<T> {
|
|||
initialized = true;
|
||||
|
||||
checkInvokerAvailable();
|
||||
|
||||
// dispatch a ReferenceConfigInitializedEvent since 2.7.4
|
||||
dispatch(new ReferenceConfigInitializedEvent(this, invoker));
|
||||
}
|
||||
|
||||
@SuppressWarnings({"unchecked", "rawtypes", "deprecation"})
|
||||
|
|
@ -552,16 +542,6 @@ public class ReferenceConfig<T> extends ReferenceConfigBase<T> {
|
|||
return isJvmRefer;
|
||||
}
|
||||
|
||||
/**
|
||||
* Dispatch an {@link Event event}
|
||||
*
|
||||
* @param event an {@link Event event}
|
||||
* @since 2.7.5
|
||||
*/
|
||||
protected void dispatch(Event event) {
|
||||
EventDispatcher.getDefaultExtension().dispatch(event);
|
||||
}
|
||||
|
||||
public DubboBootstrap getBootstrap() {
|
||||
return bootstrap;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -31,13 +31,9 @@ import org.apache.dubbo.common.utils.NamedThreadFactory;
|
|||
import org.apache.dubbo.common.utils.StringUtils;
|
||||
import org.apache.dubbo.config.annotation.Service;
|
||||
import org.apache.dubbo.config.bootstrap.DubboBootstrap;
|
||||
import org.apache.dubbo.config.event.ServiceConfigExportedEvent;
|
||||
import org.apache.dubbo.config.event.ServiceConfigUnexportedEvent;
|
||||
import org.apache.dubbo.config.invoker.DelegateProviderMetaDataInvoker;
|
||||
import org.apache.dubbo.config.support.Parameter;
|
||||
import org.apache.dubbo.config.utils.ConfigValidationUtils;
|
||||
import org.apache.dubbo.event.Event;
|
||||
import org.apache.dubbo.event.EventDispatcher;
|
||||
import org.apache.dubbo.metadata.MetadataService;
|
||||
import org.apache.dubbo.metadata.ServiceNameMapping;
|
||||
import org.apache.dubbo.metadata.ServiceNameMappingHandler;
|
||||
|
|
@ -179,9 +175,6 @@ public class ServiceConfig<T> extends ServiceConfigBase<T> {
|
|||
exporters.clear();
|
||||
}
|
||||
unexported = true;
|
||||
|
||||
// dispatch a ServiceConfigUnExportedEvent since 2.7.4
|
||||
dispatch(new ServiceConfigUnexportedEvent(this));
|
||||
}
|
||||
|
||||
public synchronized void export() {
|
||||
|
|
@ -230,8 +223,6 @@ public class ServiceConfig<T> extends ServiceConfigBase<T> {
|
|||
ServiceNameMapping serviceNameMapping = ServiceNameMapping.getExtension(parameters != null ? parameters.get(MAPPING_KEY) : null);
|
||||
ServiceNameMappingHandler.map(serviceNameMapping, url);
|
||||
});
|
||||
// dispatch a ServiceConfigExportedEvent since 2.7.4
|
||||
dispatch(new ServiceConfigExportedEvent(this));
|
||||
}
|
||||
|
||||
private void checkAndUpdateSubConfigs() {
|
||||
|
|
@ -735,16 +726,6 @@ public class ServiceConfig<T> extends ServiceConfigBase<T> {
|
|||
configPostProcessors.forEach(component -> component.postProcessServiceConfig(this));
|
||||
}
|
||||
|
||||
/**
|
||||
* Dispatch an {@link Event event}
|
||||
*
|
||||
* @param event an {@link Event event}
|
||||
* @since 2.7.5
|
||||
*/
|
||||
private void dispatch(Event event) {
|
||||
EventDispatcher.getDefaultExtension().dispatch(event);
|
||||
}
|
||||
|
||||
public DubboBootstrap getBootstrap() {
|
||||
return bootstrap;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,32 +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.apache.dubbo.config.event;
|
||||
|
||||
import org.apache.dubbo.event.Event;
|
||||
|
||||
/**
|
||||
* An {@link Event Dubbo event} when the Dubbo service is about to be destroyed.
|
||||
*
|
||||
* @see Event
|
||||
* @since 2.7.5
|
||||
*/
|
||||
public class DubboServiceDestroyedEvent extends Event {
|
||||
|
||||
public DubboServiceDestroyedEvent(Object source) {
|
||||
super(source);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,46 +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.apache.dubbo.config.event;
|
||||
|
||||
import org.apache.dubbo.config.DubboShutdownHook;
|
||||
import org.apache.dubbo.event.Event;
|
||||
|
||||
/**
|
||||
* An event raised when the {@link DubboShutdownHook} {@link Runtime#addShutdownHook(Thread) registered} on
|
||||
* {@link ApplicationShutdownHooks JVM ShutdownHooks}
|
||||
*
|
||||
* @see DubboShutdownHook
|
||||
* @see ApplicationShutdownHooks
|
||||
* @since 2.7.5
|
||||
*/
|
||||
public class DubboShutdownHookRegisteredEvent extends Event {
|
||||
|
||||
/**
|
||||
* Constructs a prototypical Event.
|
||||
*
|
||||
* @param dubboShutdownHook The object on which the Event initially occurred.
|
||||
* @throws IllegalArgumentException if source is null.
|
||||
*/
|
||||
public DubboShutdownHookRegisteredEvent(DubboShutdownHook dubboShutdownHook) {
|
||||
super(dubboShutdownHook);
|
||||
}
|
||||
|
||||
public DubboShutdownHook getDubboShutdownHook() {
|
||||
return (DubboShutdownHook) getSource();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,45 +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.apache.dubbo.config.event;
|
||||
|
||||
import org.apache.dubbo.config.DubboShutdownHook;
|
||||
import org.apache.dubbo.event.Event;
|
||||
|
||||
/**
|
||||
* An event raised when the {@link DubboShutdownHook} {@link Runtime#removeShutdownHook(Thread) unregistered} on
|
||||
* {@link ApplicationShutdownHooks JVM ShutdownHooks}
|
||||
*
|
||||
* @see DubboShutdownHook
|
||||
* @see ApplicationShutdownHooks
|
||||
* @since 2.7.5
|
||||
*/
|
||||
public class DubboShutdownHookUnregisteredEvent extends Event {
|
||||
|
||||
/**
|
||||
* Constructs a prototypical Event.
|
||||
*
|
||||
* @param dubboShutdownHook The object on which the Event initially occurred.
|
||||
* @throws IllegalArgumentException if source is null.
|
||||
*/
|
||||
public DubboShutdownHookUnregisteredEvent(DubboShutdownHook dubboShutdownHook) {
|
||||
super(dubboShutdownHook);
|
||||
}
|
||||
|
||||
public DubboShutdownHook getDubboShutdownHook() {
|
||||
return (DubboShutdownHook) getSource();
|
||||
}
|
||||
}
|
||||
|
|
@ -1,41 +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.apache.dubbo.config.event;
|
||||
|
||||
import org.apache.dubbo.config.ReferenceConfig;
|
||||
import org.apache.dubbo.config.annotation.Reference;
|
||||
import org.apache.dubbo.event.Event;
|
||||
|
||||
/**
|
||||
* The {@link ReferenceConfig Dubbo service ReferenceConfig} destroyed {@link Event event}
|
||||
*
|
||||
* @see Reference
|
||||
* @see ReferenceConfig#destroy()
|
||||
* @see Event
|
||||
* @since 2.7.5
|
||||
*/
|
||||
public class ReferenceConfigDestroyedEvent extends Event {
|
||||
|
||||
public ReferenceConfigDestroyedEvent(ReferenceConfig referenceConfig) {
|
||||
super(referenceConfig);
|
||||
}
|
||||
|
||||
public ReferenceConfig getReferenceConfig() {
|
||||
return (ReferenceConfig) getSource();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,48 +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.apache.dubbo.config.event;
|
||||
|
||||
import org.apache.dubbo.config.ReferenceConfig;
|
||||
import org.apache.dubbo.config.annotation.Reference;
|
||||
import org.apache.dubbo.event.Event;
|
||||
import org.apache.dubbo.rpc.Invoker;
|
||||
|
||||
/**
|
||||
* The {@link ReferenceConfig Dubbo service ReferenceConfig} initialized {@link Event event}
|
||||
*
|
||||
* @see Reference
|
||||
* @see ReferenceConfig#get()
|
||||
* @see Event
|
||||
* @since 2.7.5
|
||||
*/
|
||||
public class ReferenceConfigInitializedEvent extends Event {
|
||||
|
||||
private final Invoker<?> invoker;
|
||||
|
||||
public ReferenceConfigInitializedEvent(ReferenceConfig referenceConfig, Invoker<?> invoker) {
|
||||
super(referenceConfig);
|
||||
this.invoker = invoker;
|
||||
}
|
||||
|
||||
public ReferenceConfig getReferenceConfig() {
|
||||
return (ReferenceConfig) getSource();
|
||||
}
|
||||
|
||||
public Invoker<?> getInvoker() {
|
||||
return invoker;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,36 +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.apache.dubbo.config.event;
|
||||
|
||||
import org.apache.dubbo.config.ServiceConfig;
|
||||
import org.apache.dubbo.event.Event;
|
||||
|
||||
/**
|
||||
* {@link ServiceConfig} event post-{@link ServiceConfig#export() export}
|
||||
*
|
||||
* @since 2.7.5
|
||||
*/
|
||||
public class ServiceConfigExportedEvent extends Event {
|
||||
|
||||
public ServiceConfigExportedEvent(ServiceConfig source) {
|
||||
super(source);
|
||||
}
|
||||
|
||||
public ServiceConfig getServiceConfig() {
|
||||
return (ServiceConfig) getSource();
|
||||
}
|
||||
}
|
||||
|
|
@ -1,36 +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.apache.dubbo.config.event;
|
||||
|
||||
import org.apache.dubbo.config.ServiceConfig;
|
||||
import org.apache.dubbo.event.Event;
|
||||
|
||||
/**
|
||||
* {@link ServiceConfig} event post-{@link ServiceConfig#unexport() unexport}
|
||||
*
|
||||
* @since 2.7.5
|
||||
*/
|
||||
public class ServiceConfigUnexportedEvent extends Event {
|
||||
|
||||
public ServiceConfigUnexportedEvent(ServiceConfig source) {
|
||||
super(source);
|
||||
}
|
||||
|
||||
public ServiceConfig getServiceConfig() {
|
||||
return (ServiceConfig) getSource();
|
||||
}
|
||||
}
|
||||
|
|
@ -1,51 +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.apache.dubbo.config.event.listener;
|
||||
|
||||
import org.apache.dubbo.common.logger.Logger;
|
||||
import org.apache.dubbo.common.logger.LoggerFactory;
|
||||
import org.apache.dubbo.config.event.DubboServiceDestroyedEvent;
|
||||
import org.apache.dubbo.config.event.ServiceConfigExportedEvent;
|
||||
import org.apache.dubbo.event.Event;
|
||||
import org.apache.dubbo.event.GenericEventListener;
|
||||
|
||||
import static java.lang.String.format;
|
||||
|
||||
/**
|
||||
* A listener for logging the {@link Event Dubbo event}
|
||||
*
|
||||
* @see ServiceConfigExportedEvent
|
||||
* @since 2.7.5
|
||||
*/
|
||||
public class LoggingEventListener extends GenericEventListener {
|
||||
|
||||
private static final String NAME = "Dubbo Service";
|
||||
|
||||
private final Logger logger = LoggerFactory.getLogger(getClass());
|
||||
|
||||
public void onEvent(DubboServiceDestroyedEvent event) {
|
||||
if (logger.isInfoEnabled()) {
|
||||
logger.info(NAME + " has been destroyed.");
|
||||
}
|
||||
}
|
||||
|
||||
private void debug(String pattern, Object... args) {
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug(format(pattern, args));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1 +0,0 @@
|
|||
config-logging=org.apache.dubbo.config.event.listener.LoggingEventListener
|
||||
|
|
@ -1,90 +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.apache.dubbo.config.event.listener;
|
||||
|
||||
import org.apache.dubbo.common.utils.NetUtils;
|
||||
import org.apache.dubbo.config.ApplicationConfig;
|
||||
import org.apache.dubbo.config.ProtocolConfig;
|
||||
import org.apache.dubbo.config.RegistryConfig;
|
||||
import org.apache.dubbo.config.ServiceConfig;
|
||||
import org.apache.dubbo.config.bootstrap.DubboBootstrap;
|
||||
import org.apache.dubbo.config.bootstrap.EchoService;
|
||||
import org.apache.dubbo.config.bootstrap.EchoServiceImpl;
|
||||
import org.apache.dubbo.config.context.ConfigManager;
|
||||
import org.apache.dubbo.config.event.ServiceConfigExportedEvent;
|
||||
import org.apache.dubbo.metadata.WritableMetadataService;
|
||||
import org.apache.dubbo.metadata.definition.ServiceDefinitionBuilder;
|
||||
import org.apache.dubbo.metadata.definition.model.ServiceDefinition;
|
||||
import org.apache.dubbo.rpc.model.ApplicationModel;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.util.Random;
|
||||
|
||||
import static org.apache.dubbo.common.constants.CommonConstants.DEFAULT_METADATA_STORAGE_TYPE;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
|
||||
/**
|
||||
* {@link PublishingServiceDefinitionListener} Test-Cases
|
||||
*
|
||||
* @since 2.7.8
|
||||
*/
|
||||
public class PublishingServiceDefinitionListenerTest {
|
||||
|
||||
private WritableMetadataService writableMetadataService;
|
||||
|
||||
@BeforeEach
|
||||
public void init() {
|
||||
DubboBootstrap.reset();
|
||||
String metadataType = DEFAULT_METADATA_STORAGE_TYPE;
|
||||
ConfigManager configManager = ApplicationModel.getConfigManager();
|
||||
ApplicationConfig applicationConfig = new ApplicationConfig("dubbo-demo-provider");
|
||||
applicationConfig.setMetadataType(metadataType);
|
||||
configManager.setApplication(applicationConfig);
|
||||
this.writableMetadataService = WritableMetadataService.getDefaultExtension();
|
||||
}
|
||||
|
||||
@AfterEach
|
||||
public void reset() {
|
||||
DubboBootstrap.reset();
|
||||
}
|
||||
|
||||
/**
|
||||
* Test {@link ServiceConfigExportedEvent} arising
|
||||
*/
|
||||
@Test
|
||||
public void testOnServiceConfigExportedEvent() {
|
||||
ProtocolConfig protocolConfig = new ProtocolConfig("dubbo");
|
||||
protocolConfig.setPort(NetUtils.getAvailablePort(20880 + new Random().nextInt(10000)));
|
||||
|
||||
ServiceConfig<EchoService> serviceConfig = new ServiceConfig<>();
|
||||
serviceConfig.setInterface(EchoService.class);
|
||||
serviceConfig.setProtocol(protocolConfig);
|
||||
serviceConfig.setRef(new EchoServiceImpl());
|
||||
serviceConfig.setRegistry(new RegistryConfig("N/A"));
|
||||
serviceConfig.export();
|
||||
|
||||
String serviceDefinition = writableMetadataService.getServiceDefinition(EchoService.class.getName());
|
||||
|
||||
ServiceDefinition serviceDefinitionBuild = ServiceDefinitionBuilder.build(serviceConfig.getInterfaceClass());
|
||||
|
||||
assertEquals(serviceDefinition, new Gson().toJson(serviceDefinitionBuild));
|
||||
}
|
||||
}
|
||||
|
|
@ -609,12 +609,6 @@
|
|||
META-INF/dubbo/internal/org.apache.dubbo.metadata.report.MetadataReportFactory
|
||||
</resource>
|
||||
</transformer>
|
||||
<!-- @since 2.7.5 -->
|
||||
<transformer
|
||||
implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
|
||||
<resource>META-INF/dubbo/internal/org.apache.dubbo.event.EventDispatcher
|
||||
</resource>
|
||||
</transformer>
|
||||
<transformer
|
||||
implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
|
||||
<resource>META-INF/dubbo/internal/org.apache.dubbo.metadata.MetadataServiceExporter
|
||||
|
|
@ -653,11 +647,6 @@
|
|||
META-INF/dubbo/internal/org.apache.dubbo.metadata.definition.builder.TypeBuilder
|
||||
</resource>
|
||||
</transformer>
|
||||
<transformer
|
||||
implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
|
||||
<resource>META-INF/dubbo/internal/org.apache.dubbo.event.EventListener
|
||||
</resource>
|
||||
</transformer>
|
||||
<transformer
|
||||
implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
|
||||
<resource>
|
||||
|
|
|
|||
|
|
@ -299,12 +299,6 @@
|
|||
META-INF/dubbo/internal/org.apache.dubbo.metadata.report.MetadataReportFactory
|
||||
</resource>
|
||||
</transformer>
|
||||
<!-- @since 2.7.5 -->
|
||||
<transformer
|
||||
implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
|
||||
<resource>META-INF/dubbo/internal/org.apache.dubbo.event.EventDispatcher
|
||||
</resource>
|
||||
</transformer>
|
||||
<transformer
|
||||
implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
|
||||
<resource>META-INF/dubbo/internal/org.apache.dubbo.metadata.MetadataServiceExporter
|
||||
|
|
@ -343,11 +337,6 @@
|
|||
META-INF/dubbo/internal/org.apache.dubbo.metadata.definition.builder.TypeBuilder
|
||||
</resource>
|
||||
</transformer>
|
||||
<transformer
|
||||
implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
|
||||
<resource>META-INF/dubbo/internal/org.apache.dubbo.event.EventListener
|
||||
</resource>
|
||||
</transformer>
|
||||
<transformer
|
||||
implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
|
||||
<resource>
|
||||
|
|
|
|||
|
|
@ -23,8 +23,6 @@ import org.apache.dubbo.common.lang.ShutdownHookCallbacks;
|
|||
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.event.EventListener;
|
||||
import org.apache.dubbo.registry.client.event.ServiceInstancesChangedEvent;
|
||||
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import org.apache.commons.io.FileUtils;
|
||||
|
|
@ -54,7 +52,7 @@ import static org.apache.dubbo.common.config.configcenter.file.FileSystemDynamic
|
|||
* @see FileSystemDynamicConfiguration
|
||||
* @since 2.7.5
|
||||
*/
|
||||
public class FileSystemServiceDiscovery implements ServiceDiscovery, EventListener<ServiceInstancesChangedEvent> {
|
||||
public class FileSystemServiceDiscovery implements ServiceDiscovery {
|
||||
|
||||
private final Logger logger = LoggerFactory.getLogger(getClass());
|
||||
|
||||
|
|
@ -64,11 +62,6 @@ public class FileSystemServiceDiscovery implements ServiceDiscovery, EventListen
|
|||
|
||||
private ServiceInstance serviceInstance;
|
||||
|
||||
@Override
|
||||
public void onEvent(ServiceInstancesChangedEvent event) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initialize(URL registryURL) throws Exception {
|
||||
dynamicConfiguration = createDynamicConfiguration(registryURL);
|
||||
|
|
|
|||
|
|
@ -21,8 +21,6 @@ import org.apache.dubbo.common.extension.SPI;
|
|||
import org.apache.dubbo.common.lang.Prioritized;
|
||||
import org.apache.dubbo.common.utils.Page;
|
||||
import org.apache.dubbo.common.utils.StringUtils;
|
||||
import org.apache.dubbo.event.EventDispatcher;
|
||||
import org.apache.dubbo.event.EventListener;
|
||||
import org.apache.dubbo.registry.NotifyListener;
|
||||
import org.apache.dubbo.registry.client.event.ServiceInstancesChangedEvent;
|
||||
import org.apache.dubbo.registry.client.event.listener.ServiceInstancesChangedListener;
|
||||
|
|
@ -37,7 +35,6 @@ import java.util.stream.Stream;
|
|||
import static java.util.Collections.unmodifiableList;
|
||||
import static java.util.Collections.unmodifiableMap;
|
||||
import static org.apache.dubbo.common.constants.CommonConstants.REGISTRY_DELAY_NOTIFICATION_KEY;
|
||||
import static org.apache.dubbo.event.EventDispatcher.getDefaultExtension;
|
||||
|
||||
/**
|
||||
* The common operations of Service Discovery
|
||||
|
|
@ -196,13 +193,30 @@ public interface ServiceDiscovery extends Prioritized {
|
|||
return unmodifiableMap(instances);
|
||||
}
|
||||
|
||||
default void dispatchServiceInstancesChangedEvent(String serviceName) {
|
||||
dispatchServiceInstancesChangedEvent(serviceName, getInstances(serviceName));
|
||||
}
|
||||
|
||||
default void dispatchServiceInstancesChangedEvent(String serviceName, String... otherServiceNames) {
|
||||
dispatchServiceInstancesChangedEvent(serviceName, getInstances(serviceName));
|
||||
if (otherServiceNames != null) {
|
||||
Stream.of(otherServiceNames)
|
||||
.filter(StringUtils::isNotEmpty)
|
||||
.forEach(this::dispatchServiceInstancesChangedEvent);
|
||||
}
|
||||
}
|
||||
|
||||
default void dispatchServiceInstancesChangedEvent(String serviceName, List<ServiceInstance> serviceInstances) {
|
||||
dispatchServiceInstancesChangedEvent(new ServiceInstancesChangedEvent(serviceName, serviceInstances));
|
||||
}
|
||||
|
||||
default void dispatchServiceInstancesChangedEvent(ServiceInstancesChangedEvent event) {}
|
||||
|
||||
/**
|
||||
* Add an instance of {@link ServiceInstancesChangedListener} for specified service
|
||||
* <p>
|
||||
* Default, current method will be invoked by {@link ServiceDiscoveryRegistry#subscribe(URL, NotifyListener)
|
||||
* the ServiceDiscoveryRegistry on the subscription}, and it's mandatory to
|
||||
* {@link EventDispatcher#addEventListener(EventListener) add} the {@link ServiceInstancesChangedListener} argument
|
||||
* into {@link EventDispatcher} whether the subclass implements same approach or not, thus this method is used to
|
||||
* Default, Current method will be invoked by {@link ServiceDiscoveryRegistry#subscribe(URL, NotifyListener)
|
||||
* the ServiceDiscoveryRegistry on the subscription}, this method is used to
|
||||
* trigger or adapt the vendor's change notification mechanism typically, like Zookeeper Watcher,
|
||||
* Nacos EventListener. If the registry observes the change, It's suggested that the implementation could invoke
|
||||
* {@link #dispatchServiceInstancesChangedEvent(String)} method or variants
|
||||
|
|
@ -210,7 +224,6 @@ public interface ServiceDiscovery extends Prioritized {
|
|||
* @param listener an instance of {@link ServiceInstancesChangedListener}
|
||||
* @throws NullPointerException
|
||||
* @throws IllegalArgumentException
|
||||
* @see EventDispatcher
|
||||
*/
|
||||
default void addServiceInstancesChangedListener(ServiceInstancesChangedListener listener)
|
||||
throws NullPointerException, IllegalArgumentException {
|
||||
|
|
@ -230,49 +243,6 @@ public interface ServiceDiscovery extends Prioritized {
|
|||
return new ServiceInstancesChangedListener(serviceNames, this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Dispatch the {@link ServiceInstancesChangedEvent}
|
||||
*
|
||||
* @param serviceName the name of service whose service instances have been changed
|
||||
*/
|
||||
default void dispatchServiceInstancesChangedEvent(String serviceName) {
|
||||
dispatchServiceInstancesChangedEvent(serviceName, getInstances(serviceName));
|
||||
}
|
||||
|
||||
/**
|
||||
* Dispatch the {@link ServiceInstancesChangedEvent}
|
||||
*
|
||||
* @param serviceName the name of service whose service instances have been changed
|
||||
* @param otherServiceNames the names of other services
|
||||
*/
|
||||
default void dispatchServiceInstancesChangedEvent(String serviceName, String... otherServiceNames) {
|
||||
dispatchServiceInstancesChangedEvent(serviceName, getInstances(serviceName));
|
||||
if (otherServiceNames != null) {
|
||||
Stream.of(otherServiceNames)
|
||||
.filter(StringUtils::isNotEmpty)
|
||||
.forEach(this::dispatchServiceInstancesChangedEvent);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Dispatch the {@link ServiceInstancesChangedEvent}
|
||||
*
|
||||
* @param serviceName the name of service whose service instances have been changed
|
||||
* @param serviceInstances the service instances have been changed
|
||||
*/
|
||||
default void dispatchServiceInstancesChangedEvent(String serviceName, List<ServiceInstance> serviceInstances) {
|
||||
dispatchServiceInstancesChangedEvent(new ServiceInstancesChangedEvent(serviceName, serviceInstances));
|
||||
}
|
||||
|
||||
/**
|
||||
* Dispatch the {@link ServiceInstancesChangedEvent}
|
||||
*
|
||||
* @param event the {@link ServiceInstancesChangedEvent}
|
||||
*/
|
||||
default void dispatchServiceInstancesChangedEvent(ServiceInstancesChangedEvent event) {
|
||||
getDefaultExtension().dispatch(event);
|
||||
}
|
||||
|
||||
// ==================================================================================== //
|
||||
|
||||
// String getKey(URL exportedURL);
|
||||
|
|
|
|||
|
|
@ -1,33 +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.apache.dubbo.registry.client.event;
|
||||
|
||||
import org.apache.dubbo.registry.client.ServiceDiscovery;
|
||||
|
||||
/**
|
||||
* An event raised after the {@link ServiceDiscovery Service Discovery} destroyed.
|
||||
*
|
||||
* @see ServiceDiscovery#destroy()
|
||||
* @since 2.7.5
|
||||
*/
|
||||
public class ServiceDiscoveryDestroyedEvent extends ServiceDiscoveryEvent {
|
||||
|
||||
public ServiceDiscoveryDestroyedEvent(ServiceDiscovery source, ServiceDiscovery original) {
|
||||
super(source, original);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,33 +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.apache.dubbo.registry.client.event;
|
||||
|
||||
import org.apache.dubbo.registry.client.ServiceDiscovery;
|
||||
|
||||
/**
|
||||
* An event raised when the {@link ServiceDiscovery Service Discovery} is destroying.
|
||||
*
|
||||
* @see ServiceDiscovery#destroy()
|
||||
* @since 2.7.5
|
||||
*/
|
||||
public class ServiceDiscoveryDestroyingEvent extends ServiceDiscoveryEvent {
|
||||
|
||||
public ServiceDiscoveryDestroyingEvent(ServiceDiscovery source, ServiceDiscovery original) {
|
||||
super(source, original);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,67 +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.apache.dubbo.registry.client.event;
|
||||
|
||||
import org.apache.dubbo.event.Event;
|
||||
import org.apache.dubbo.registry.client.ServiceDiscovery;
|
||||
|
||||
/**
|
||||
* An abstract {@link Event} class for {@link ServiceDiscovery}
|
||||
*
|
||||
* @see Event
|
||||
* @see ServiceDiscovery
|
||||
* @since 2.7.5
|
||||
*/
|
||||
public abstract class ServiceDiscoveryEvent extends Event {
|
||||
|
||||
private final ServiceDiscovery original;
|
||||
|
||||
/**
|
||||
* Constructs a prototypical Event.
|
||||
*
|
||||
* @param source The object on which the Event initially occurred.
|
||||
* @param original The original {@link ServiceDiscovery}
|
||||
* @throws IllegalArgumentException if source is null.
|
||||
*/
|
||||
public ServiceDiscoveryEvent(ServiceDiscovery source, ServiceDiscovery original) {
|
||||
super(source);
|
||||
this.original = original;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ServiceDiscovery getSource() {
|
||||
return (ServiceDiscovery) super.getSource();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the {@link ServiceDiscovery} on which the Event initially occurred.
|
||||
*
|
||||
* @return {@link ServiceDiscovery} instance
|
||||
*/
|
||||
public final ServiceDiscovery getServiceDiscovery() {
|
||||
return getSource();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the original {@link ServiceDiscovery}
|
||||
*
|
||||
* @return the original {@link ServiceDiscovery}
|
||||
*/
|
||||
public final ServiceDiscovery getOriginal() {
|
||||
return original;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,48 +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.apache.dubbo.registry.client.event;
|
||||
|
||||
import org.apache.dubbo.registry.client.ServiceDiscovery;
|
||||
|
||||
/**
|
||||
* An event raised when the {@link ServiceDiscovery Service Discovery} met with some exception
|
||||
*
|
||||
* @see ServiceDiscovery
|
||||
* @see org.apache.dubbo.event.Event
|
||||
* @since 2.7.5
|
||||
*/
|
||||
public class ServiceDiscoveryExceptionEvent extends ServiceDiscoveryEvent {
|
||||
|
||||
private final Throwable cause;
|
||||
|
||||
public ServiceDiscoveryExceptionEvent(ServiceDiscovery source, ServiceDiscovery original, Throwable cause) {
|
||||
super(source, original);
|
||||
if (cause == null) {
|
||||
throw new NullPointerException("The cause of Exception must not null");
|
||||
}
|
||||
this.cause = cause;
|
||||
}
|
||||
|
||||
/**
|
||||
* The cause of {@link Throwable}
|
||||
*
|
||||
* @return non-nul
|
||||
*/
|
||||
public Throwable getCause() {
|
||||
return cause;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,33 +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.apache.dubbo.registry.client.event;
|
||||
|
||||
import org.apache.dubbo.common.URL;
|
||||
import org.apache.dubbo.registry.client.ServiceDiscovery;
|
||||
|
||||
/**
|
||||
* An event raised after the {@link ServiceDiscovery Service Discovery} initialized
|
||||
*
|
||||
* @see ServiceDiscovery#initialize(URL)
|
||||
* @since 2.7.5
|
||||
*/
|
||||
public class ServiceDiscoveryInitializedEvent extends ServiceDiscoveryEvent {
|
||||
|
||||
public ServiceDiscoveryInitializedEvent(ServiceDiscovery source, ServiceDiscovery original) {
|
||||
super(source, original);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,33 +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.apache.dubbo.registry.client.event;
|
||||
|
||||
import org.apache.dubbo.common.URL;
|
||||
import org.apache.dubbo.registry.client.ServiceDiscovery;
|
||||
|
||||
/**
|
||||
* An event raised when the {@link ServiceDiscovery Service Discovery} is initializing.
|
||||
*
|
||||
* @see ServiceDiscovery#initialize(URL)
|
||||
* @since 2.7.5
|
||||
*/
|
||||
public class ServiceDiscoveryInitializingEvent extends ServiceDiscoveryEvent {
|
||||
|
||||
public ServiceDiscoveryInitializingEvent(ServiceDiscovery source, ServiceDiscovery original) {
|
||||
super(source, original);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,47 +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.apache.dubbo.registry.client.event;
|
||||
|
||||
import org.apache.dubbo.event.Event;
|
||||
import org.apache.dubbo.registry.client.ServiceInstance;
|
||||
|
||||
/**
|
||||
* The {@link Event Dubbo event} for {@link ServiceInstance an service instance}
|
||||
*
|
||||
* @since 2.7.5
|
||||
*/
|
||||
public abstract class ServiceInstanceEvent extends Event {
|
||||
|
||||
private final ServiceInstance serviceInstance;
|
||||
|
||||
/**
|
||||
* @param serviceInstance {@link ServiceInstance an service instance}
|
||||
*/
|
||||
public ServiceInstanceEvent(Object source, ServiceInstance serviceInstance) {
|
||||
super(source);
|
||||
this.serviceInstance = serviceInstance;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get current {@link ServiceInstance service instance}
|
||||
*
|
||||
* @return current {@link ServiceInstance service instance}
|
||||
*/
|
||||
public ServiceInstance getServiceInstance() {
|
||||
return serviceInstance;
|
||||
}
|
||||
}
|
||||
|
|
@ -16,7 +16,6 @@
|
|||
*/
|
||||
package org.apache.dubbo.registry.client.event;
|
||||
|
||||
import org.apache.dubbo.event.Event;
|
||||
import org.apache.dubbo.registry.client.ServiceInstance;
|
||||
import org.apache.dubbo.registry.client.event.listener.ServiceInstancesChangedListener;
|
||||
|
||||
|
|
@ -31,7 +30,7 @@ import static java.util.Collections.unmodifiableList;
|
|||
* @see ServiceInstancesChangedListener
|
||||
* @since 2.7.5
|
||||
*/
|
||||
public class ServiceInstancesChangedEvent extends Event {
|
||||
public class ServiceInstancesChangedEvent {
|
||||
|
||||
private final String serviceName;
|
||||
|
||||
|
|
@ -43,13 +42,11 @@ public class ServiceInstancesChangedEvent extends Event {
|
|||
* @throws IllegalArgumentException if source is null.
|
||||
*/
|
||||
public ServiceInstancesChangedEvent(String serviceName, List<ServiceInstance> serviceInstances) {
|
||||
super(serviceName);
|
||||
this.serviceName = serviceName;
|
||||
this.serviceInstances = unmodifiableList(serviceInstances);
|
||||
}
|
||||
|
||||
protected ServiceInstancesChangedEvent() {
|
||||
super("");
|
||||
this.serviceInstances = Collections.emptyList();
|
||||
this.serviceName = "";
|
||||
}
|
||||
|
|
|
|||
|
|
@ -22,8 +22,6 @@ import org.apache.dubbo.common.logger.Logger;
|
|||
import org.apache.dubbo.common.logger.LoggerFactory;
|
||||
import org.apache.dubbo.common.threadpool.manager.ExecutorRepository;
|
||||
import org.apache.dubbo.common.utils.CollectionUtils;
|
||||
import org.apache.dubbo.event.ConditionalEventListener;
|
||||
import org.apache.dubbo.event.EventListener;
|
||||
import org.apache.dubbo.metadata.MetadataInfo;
|
||||
import org.apache.dubbo.metadata.MetadataInfo.ServiceInfo;
|
||||
import org.apache.dubbo.metadata.MetadataService;
|
||||
|
|
@ -60,12 +58,12 @@ import static org.apache.dubbo.metadata.RevisionResolver.EMPTY_REVISION;
|
|||
import static org.apache.dubbo.registry.client.metadata.ServiceInstanceMetadataUtils.getExportedServicesRevision;
|
||||
|
||||
/**
|
||||
* The Service Discovery Changed {@link EventListener Event Listener}
|
||||
* The Service Discovery Changed Listener
|
||||
*
|
||||
* @see ServiceInstancesChangedEvent
|
||||
* @since 2.7.5
|
||||
*/
|
||||
public class ServiceInstancesChangedListener implements ConditionalEventListener<ServiceInstancesChangedEvent> {
|
||||
public class ServiceInstancesChangedListener {
|
||||
|
||||
private static final Logger logger = LoggerFactory.getLogger(ServiceInstancesChangedListener.class);
|
||||
|
||||
|
|
@ -102,10 +100,7 @@ public class ServiceInstancesChangedListener implements ConditionalEventListener
|
|||
* @param event {@link ServiceInstancesChangedEvent}
|
||||
*/
|
||||
public synchronized void onEvent(ServiceInstancesChangedEvent event) {
|
||||
if (destroyed.get()) {
|
||||
return;
|
||||
}
|
||||
if (this.isRetryAndExpired(event)) {
|
||||
if (destroyed.get() || this.isRetryAndExpired(event) || !accept(event)) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -158,20 +153,17 @@ public class ServiceInstancesChangedListener implements ConditionalEventListener
|
|||
|
||||
localServiceToRevisions.forEach((serviceInfo, revisions) -> {
|
||||
String protocol = serviceInfo.getProtocol();
|
||||
Map<Set<String>, Object> revisionsToUrls = protocolRevisionsToUrls.computeIfAbsent(protocol, k -> {
|
||||
return new HashMap<>();
|
||||
});
|
||||
Map<Set<String>, Object> revisionsToUrls = protocolRevisionsToUrls.computeIfAbsent(protocol, k -> new HashMap<>());
|
||||
Object urls = revisionsToUrls.get(revisions);
|
||||
if (urls != null) {
|
||||
newServiceUrls.put(serviceInfo.getMatchKey(), urls);
|
||||
} else {
|
||||
if (urls == null) {
|
||||
urls = getServiceUrlsCache(revisionToInstances, revisions, protocol);
|
||||
revisionsToUrls.put(revisions, urls);
|
||||
newServiceUrls.put(serviceInfo.getMatchKey(), urls);
|
||||
}
|
||||
});
|
||||
this.serviceUrls = newServiceUrls;
|
||||
|
||||
newServiceUrls.put(serviceInfo.getMatchKey(), urls);
|
||||
});
|
||||
|
||||
this.serviceUrls = newServiceUrls;
|
||||
this.notifyAddressChanged();
|
||||
}
|
||||
|
||||
|
|
@ -233,7 +225,7 @@ public class ServiceInstancesChangedListener implements ConditionalEventListener
|
|||
* @param event {@link ServiceInstancesChangedEvent event}
|
||||
* @return If service name matches, return <code>true</code>, or <code>false</code>
|
||||
*/
|
||||
public final boolean accept(ServiceInstancesChangedEvent event) {
|
||||
private boolean accept(ServiceInstancesChangedEvent event) {
|
||||
return serviceNames.contains(event.getServiceName());
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1 +0,0 @@
|
|||
registry-logging=org.apache.dubbo.registry.client.event.listener.LoggingEventListener
|
||||
|
|
@ -19,7 +19,7 @@ package org.apache.dubbo.registry.client;
|
|||
import org.apache.dubbo.common.URL;
|
||||
import org.apache.dubbo.common.utils.DefaultPage;
|
||||
import org.apache.dubbo.common.utils.Page;
|
||||
import org.apache.dubbo.event.EventDispatcher;
|
||||
import org.apache.dubbo.registry.client.event.ServiceInstancesChangedEvent;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
|
|
@ -38,8 +38,6 @@ import static java.util.Collections.emptyList;
|
|||
*/
|
||||
public class InMemoryServiceDiscovery implements ServiceDiscovery {
|
||||
|
||||
private final EventDispatcher dispatcher = EventDispatcher.getDefaultExtension();
|
||||
|
||||
private Map<String, List<ServiceInstance>> repository = new HashMap<>();
|
||||
|
||||
private ServiceInstance serviceInstance;
|
||||
|
|
|
|||
|
|
@ -110,9 +110,7 @@ public class ZookeeperServiceDiscovery extends AbstractServiceDiscovery {
|
|||
}
|
||||
|
||||
public void unregister(ServiceInstance serviceInstance) throws RuntimeException {
|
||||
doInServiceRegistry(serviceDiscovery -> {
|
||||
serviceDiscovery.unregisterService(build(serviceInstance));
|
||||
});
|
||||
doInServiceRegistry(serviceDiscovery -> serviceDiscovery.unregisterService(build(serviceInstance)));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -188,9 +186,7 @@ public class ZookeeperServiceDiscovery extends AbstractServiceDiscovery {
|
|||
}
|
||||
|
||||
private void doInServiceRegistry(ThrowableConsumer<org.apache.curator.x.discovery.ServiceDiscovery> consumer) {
|
||||
ThrowableConsumer.execute(serviceDiscovery, s -> {
|
||||
consumer.accept(s);
|
||||
});
|
||||
ThrowableConsumer.execute(serviceDiscovery, s -> consumer.accept(s));
|
||||
}
|
||||
|
||||
private <R> R doInServiceDiscovery(ThrowableFunction<org.apache.curator.x.discovery.ServiceDiscovery, R> function) {
|
||||
|
|
|
|||
|
|
@ -19,7 +19,6 @@ package org.apache.dubbo.registry.zookeeper;
|
|||
import org.apache.dubbo.common.URL;
|
||||
import org.apache.dubbo.common.utils.NetUtils;
|
||||
import org.apache.dubbo.common.utils.Page;
|
||||
import org.apache.dubbo.event.EventDispatcher;
|
||||
import org.apache.dubbo.registry.client.DefaultServiceInstance;
|
||||
import org.apache.dubbo.registry.client.ServiceInstance;
|
||||
|
||||
|
|
@ -63,7 +62,6 @@ public class ZookeeperServiceDiscoveryTest {
|
|||
|
||||
@BeforeEach
|
||||
public void init() throws Exception {
|
||||
EventDispatcher.getDefaultExtension().removeAllEventListeners();
|
||||
zkServerPort = getAvailablePort();
|
||||
zkServer = new TestingServer(zkServerPort, true);
|
||||
zkServer.start();
|
||||
|
|
|
|||
Loading…
Reference in New Issue