Remove StateMachineInterceptor deprecations
- Forward port #905 - Fixes #906
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2015-2019 the original author or authors.
|
||||
* Copyright 2015-2020 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -417,24 +417,12 @@ public abstract class AbstractStateMachineFactory<S, E> extends LifecycleObjectS
|
||||
return interceptor.stateMachineError(stateMachine, exception);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void preStateChange(State<S, E> state, Message<E> message, Transition<S, E> transition,
|
||||
StateMachine<S, E> stateMachine) {
|
||||
interceptor.preStateChange(state, message, transition, stateMachine, rootStateMachine);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void preStateChange(State<S, E> state, Message<E> message, Transition<S, E> transition,
|
||||
StateMachine<S, E> stateMachine, StateMachine<S, E> rootStateMachine) {
|
||||
interceptor.preStateChange(state, message, transition, stateMachine, rootStateMachine);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void postStateChange(State<S, E> state, Message<E> message, Transition<S, E> transition,
|
||||
StateMachine<S, E> stateMachine) {
|
||||
interceptor.postStateChange(state, message, transition, stateMachine, rootStateMachine);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void postStateChange(State<S, E> state, Message<E> message, Transition<S, E> transition,
|
||||
StateMachine<S, E> stateMachine, StateMachine<S, E> rootStateMachine) {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2015-2019 the original author or authors.
|
||||
* Copyright 2015-2020 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -196,11 +196,6 @@ public class DistributedStateMachine<S, E> extends LifecycleObjectSupport implem
|
||||
return message;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void preStateChange(State<S, E> state, Message<E> message, Transition<S, E> transition,
|
||||
StateMachine<S, E> stateMachine) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void preStateChange(State<S, E> state, Message<E> message, Transition<S, E> transition,
|
||||
StateMachine<S, E> stateMachine, StateMachine<S, E> rootStateMachine) {
|
||||
@@ -216,11 +211,6 @@ public class DistributedStateMachine<S, E> extends LifecycleObjectSupport implem
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void postStateChange(State<S, E> state, Message<E> message, Transition<S, E> transition,
|
||||
StateMachine<S, E> stateMachine) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void postStateChange(State<S, E> state, Message<E> message, Transition<S, E> transition,
|
||||
StateMachine<S, E> stateMachine, StateMachine<S, E> rootStateMachine) {
|
||||
|
||||
@@ -42,19 +42,6 @@ public interface StateMachineInterceptor<S, E> {
|
||||
*/
|
||||
Message<E> preEvent(Message<E> message, StateMachine<S, E> stateMachine);
|
||||
|
||||
/**
|
||||
* Called prior of a state change. Throwing an exception
|
||||
* from this method will stop a state change logic.
|
||||
*
|
||||
* @param state the state
|
||||
* @param message the message
|
||||
* @param transition the transition
|
||||
* @param stateMachine the state machine
|
||||
* @deprecated in favour of {@link #preStateChange(State, Message, Transition, StateMachine, StateMachine)}
|
||||
*/
|
||||
void preStateChange(State<S, E> state, Message<E> message, Transition<S, E> transition,
|
||||
StateMachine<S, E> stateMachine);
|
||||
|
||||
/**
|
||||
* Called prior of a state change. Throwing an exception
|
||||
* from this method will stop a state change logic.
|
||||
@@ -68,18 +55,6 @@ public interface StateMachineInterceptor<S, E> {
|
||||
void preStateChange(State<S, E> state, Message<E> message, Transition<S, E> transition,
|
||||
StateMachine<S, E> stateMachine, StateMachine<S, E> rootStateMachine);
|
||||
|
||||
/**
|
||||
* Called after a state change.
|
||||
*
|
||||
* @param state the state
|
||||
* @param message the message
|
||||
* @param transition the transition
|
||||
* @param stateMachine the state machine
|
||||
* @deprecated in favour of {@link #postStateChange(State, Message, Transition, StateMachine, StateMachine)}
|
||||
*/
|
||||
void postStateChange(State<S, E> state, Message<E> message, Transition<S, E> transition,
|
||||
StateMachine<S, E> stateMachine);
|
||||
|
||||
/**
|
||||
* Called after a state change.
|
||||
*
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2015-2019 the original author or authors.
|
||||
* Copyright 2015-2020 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -36,21 +36,11 @@ public class StateMachineInterceptorAdapter<S, E> implements StateMachineInterce
|
||||
return message;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void preStateChange(State<S, E> state, Message<E> message, Transition<S, E> transition,
|
||||
StateMachine<S, E> stateMachine) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void preStateChange(State<S, E> state, Message<E> message, Transition<S, E> transition,
|
||||
StateMachine<S, E> stateMachine, StateMachine<S, E> rootStateMachine) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void postStateChange(State<S, E> state, Message<E> message, Transition<S, E> transition,
|
||||
StateMachine<S, E> stateMachine) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void postStateChange(State<S, E> state, Message<E> message, Transition<S, E> transition,
|
||||
StateMachine<S, E> stateMachine, StateMachine<S, E> rootStateMachine) {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2015-2019 the original author or authors.
|
||||
* Copyright 2015-2020 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -99,7 +99,6 @@ public class StateMachineInterceptorList<S, E> {
|
||||
public void preStateChange(State<S, E> state, Message<E> message, Transition<S, E> transition,
|
||||
StateMachine<S, E> stateMachine, StateMachine<S, E> rootStateMachine) {
|
||||
for (StateMachineInterceptor<S, E> interceptor : interceptors) {
|
||||
interceptor.preStateChange(state, message, transition, stateMachine);
|
||||
interceptor.preStateChange(state, message, transition, stateMachine, rootStateMachine);
|
||||
}
|
||||
}
|
||||
@@ -117,7 +116,6 @@ public class StateMachineInterceptorList<S, E> {
|
||||
public void postStateChange(State<S, E> state, Message<E> message, Transition<S, E> transition,
|
||||
StateMachine<S, E> stateMachine, StateMachine<S, E> rootStateMachine) {
|
||||
for (StateMachineInterceptor<S, E> interceptor : interceptors) {
|
||||
interceptor.postStateChange(state, message, transition, stateMachine);
|
||||
interceptor.postStateChange(state, message, transition, stateMachine, rootStateMachine);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2015-2019 the original author or authors.
|
||||
* Copyright 2015-2020 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -1321,11 +1321,6 @@ public class DocsConfigurationSampleTests extends AbstractStateMachineTests {
|
||||
return stateContext;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void preStateChange(State<String, String> state, Message<String> message,
|
||||
Transition<String, String> transition, StateMachine<String, String> stateMachine) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void preStateChange(State<String, String> state, Message<String> message,
|
||||
Transition<String, String> transition, StateMachine<String, String> stateMachine,
|
||||
@@ -1337,11 +1332,6 @@ public class DocsConfigurationSampleTests extends AbstractStateMachineTests {
|
||||
return stateContext;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void postStateChange(State<String, String> state, Message<String> message,
|
||||
Transition<String, String> transition, StateMachine<String, String> stateMachine) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void postStateChange(State<String, String> state, Message<String> message,
|
||||
Transition<String, String> transition, StateMachine<String, String> stateMachine,
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2015-2019 the original author or authors.
|
||||
* Copyright 2015-2020 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -280,11 +280,12 @@ public class JoinStateTests extends AbstractStateMachineTests {
|
||||
machine.addStateMachineInterceptor(new StateMachineInterceptorAdapter<TestStates,TestEvents>() {
|
||||
@Override
|
||||
public void postStateChange(State<TestStates, TestEvents> state, Message<TestEvents> message,
|
||||
Transition<TestStates, TestEvents> transition, StateMachine<TestStates, TestEvents> stateMachine) {
|
||||
Transition<TestStates, TestEvents> transition, StateMachine<TestStates, TestEvents> stateMachine,
|
||||
StateMachine<TestStates, TestEvents> rootStateMachine) {
|
||||
if (state.getId() == TestStates.S4) {
|
||||
nullCheck.set(transition == null);
|
||||
}
|
||||
super.postStateChange(state, message, transition, stateMachine);
|
||||
super.postStateChange(state, message, transition, stateMachine, rootStateMachine);
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2015-2019 the original author or authors.
|
||||
* Copyright 2015-2020 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -83,8 +83,6 @@ public class StateChangeInterceptorTests extends AbstractStateMachineTests {
|
||||
machine.sendEvent(Events.C);
|
||||
assertThat(listener.stateChangedLatch.await(2, TimeUnit.SECONDS), is(true));
|
||||
assertThat(listener.stateChangedCount, is(3));
|
||||
assertThat(interceptor.preStateChangeLatch1.await(2, TimeUnit.SECONDS), is(true));
|
||||
assertThat(interceptor.preStateChangeCount1, is(1));
|
||||
assertThat(interceptor.preStateChangeLatch2.await(2, TimeUnit.SECONDS), is(true));
|
||||
assertThat(interceptor.preStateChangeCount2, is(1));
|
||||
assertThat(machine.getState().getIds(), containsInAnyOrder(States.S0, States.S2, States.S21, States.S211));
|
||||
@@ -122,8 +120,6 @@ public class StateChangeInterceptorTests extends AbstractStateMachineTests {
|
||||
assertThat(listener.stateChangedLatch.await(2, TimeUnit.SECONDS), is(true));
|
||||
assertThat(listener.stateChangedCount, is(1));
|
||||
assertThat(machine.getState().getIds(), containsInAnyOrder(States.S1));
|
||||
assertThat(interceptor.preStateChangeLatch1.await(2, TimeUnit.SECONDS), is(true));
|
||||
assertThat(interceptor.preStateChangeCount1, is(1));
|
||||
assertThat(interceptor.preStateChangeLatch2.await(2, TimeUnit.SECONDS), is(true));
|
||||
assertThat(interceptor.preStateChangeCount2, is(1));
|
||||
|
||||
@@ -133,8 +129,6 @@ public class StateChangeInterceptorTests extends AbstractStateMachineTests {
|
||||
assertThat(listener.stateChangedLatch.await(2, TimeUnit.SECONDS), is(true));
|
||||
assertThat(listener.stateChangedCount, is(1));
|
||||
assertThat(machine.getState().getIds(), containsInAnyOrder(States.S2));
|
||||
assertThat(interceptor.preStateChangeLatch1.await(2, TimeUnit.SECONDS), is(true));
|
||||
assertThat(interceptor.preStateChangeCount1, is(1));
|
||||
assertThat(interceptor.preStateChangeLatch2.await(2, TimeUnit.SECONDS), is(true));
|
||||
assertThat(interceptor.preStateChangeCount2, is(1));
|
||||
|
||||
@@ -144,8 +138,6 @@ public class StateChangeInterceptorTests extends AbstractStateMachineTests {
|
||||
assertThat(listener.stateChangedLatch.await(2, TimeUnit.SECONDS), is(true));
|
||||
assertThat(listener.stateChangedCount, is(1));
|
||||
assertThat(machine.getState().getIds(), containsInAnyOrder(States.S0));
|
||||
assertThat(interceptor.preStateChangeLatch1.await(2, TimeUnit.SECONDS), is(true));
|
||||
assertThat(interceptor.preStateChangeCount1, is(1));
|
||||
assertThat(interceptor.preStateChangeLatch2.await(2, TimeUnit.SECONDS), is(true));
|
||||
assertThat(interceptor.preStateChangeCount2, is(1));
|
||||
}
|
||||
@@ -179,8 +171,6 @@ public class StateChangeInterceptorTests extends AbstractStateMachineTests {
|
||||
assertThat(listener.stateChangedLatch.await(2, TimeUnit.SECONDS), is(true));
|
||||
assertThat(listener.stateChangedCount, is(1));
|
||||
assertThat(machine.getState().getIds(), containsInAnyOrder(States.S2));
|
||||
assertThat(interceptor.preStateChangeLatch1.await(2, TimeUnit.SECONDS), is(true));
|
||||
assertThat(interceptor.preStateChangeCount1, is(1));
|
||||
assertThat(interceptor.preStateChangeLatch2.await(2, TimeUnit.SECONDS), is(true));
|
||||
assertThat(interceptor.preStateChangeCount2, is(1));
|
||||
}
|
||||
@@ -214,13 +204,6 @@ public class StateChangeInterceptorTests extends AbstractStateMachineTests {
|
||||
assertThat(listener.stateChangedLatch.await(2, TimeUnit.SECONDS), is(true));
|
||||
assertThat(listener.stateChangedCount, is(1));
|
||||
assertThat(machine.getState().getIds(), containsInAnyOrder(States.S2));
|
||||
assertThat(interceptor.preStateChangeLatch1.await(2, TimeUnit.SECONDS), is(true));
|
||||
assertThat(interceptor.preStateChangeCount1, is(1));
|
||||
assertThat(interceptor.postStateChangeLatch1.await(2, TimeUnit.SECONDS), is(true));
|
||||
assertThat(interceptor.postStateChangeCount1, is(1));
|
||||
assertThat(interceptor.preStateChangeStates1.size(), is(1));
|
||||
assertThat(interceptor.postStateChangeStates1.size(), is(1));
|
||||
assertThat(interceptor.preStateChangeStates1.get(0).getId(), is(interceptor.postStateChangeStates1.get(0).getId()));
|
||||
assertThat(interceptor.preStateChangeLatch2.await(2, TimeUnit.SECONDS), is(true));
|
||||
assertThat(interceptor.preStateChangeCount2, is(1));
|
||||
assertThat(interceptor.postStateChangeLatch2.await(2, TimeUnit.SECONDS), is(true));
|
||||
@@ -259,13 +242,6 @@ public class StateChangeInterceptorTests extends AbstractStateMachineTests {
|
||||
assertThat(listener.stateChangedLatch.await(2, TimeUnit.SECONDS), is(true));
|
||||
assertThat(listener.stateChangedCount, is(1));
|
||||
assertThat(machine.getState().getIds(), containsInAnyOrder(States.S3));
|
||||
assertThat(interceptor.preStateChangeLatch1.await(2, TimeUnit.SECONDS), is(true));
|
||||
assertThat(interceptor.preStateChangeCount1, is(1));
|
||||
assertThat(interceptor.postStateChangeLatch1.await(2, TimeUnit.SECONDS), is(true));
|
||||
assertThat(interceptor.postStateChangeCount1, is(1));
|
||||
assertThat(interceptor.preStateChangeStates1.size(), is(1));
|
||||
assertThat(interceptor.postStateChangeStates1.size(), is(1));
|
||||
assertThat(interceptor.preStateChangeStates1.get(0).getId(), is(interceptor.postStateChangeStates1.get(0).getId()));
|
||||
assertThat(interceptor.preStateChangeLatch2.await(2, TimeUnit.SECONDS), is(true));
|
||||
assertThat(interceptor.preStateChangeCount2, is(1));
|
||||
assertThat(interceptor.postStateChangeLatch2.await(2, TimeUnit.SECONDS), is(true));
|
||||
@@ -304,8 +280,6 @@ public class StateChangeInterceptorTests extends AbstractStateMachineTests {
|
||||
assertThat(listener.stateChangedLatch.await(2, TimeUnit.SECONDS), is(true));
|
||||
assertThat(listener.stateChangedCount, is(1));
|
||||
assertThat(machine.getState().getIds(), containsInAnyOrder(States.S1));
|
||||
assertThat(interceptor.preStateChangeLatch1.await(2, TimeUnit.SECONDS), is(true));
|
||||
assertThat(interceptor.preStateChangeCount1, is(1));
|
||||
assertThat(interceptor.preStateChangeLatch2.await(2, TimeUnit.SECONDS), is(true));
|
||||
assertThat(interceptor.preStateChangeCount2, is(1));
|
||||
|
||||
@@ -315,8 +289,6 @@ public class StateChangeInterceptorTests extends AbstractStateMachineTests {
|
||||
assertThat(listener.stateChangedLatch.await(2, TimeUnit.SECONDS), is(true));
|
||||
assertThat(listener.stateChangedCount, is(1));
|
||||
assertThat(machine.getState().getIds(), containsInAnyOrder(States.S2));
|
||||
assertThat(interceptor.preStateChangeLatch1.await(2, TimeUnit.SECONDS), is(true));
|
||||
assertThat(interceptor.preStateChangeCount1, is(1));
|
||||
assertThat(interceptor.preStateChangeLatch2.await(2, TimeUnit.SECONDS), is(true));
|
||||
assertThat(interceptor.preStateChangeCount2, is(1));
|
||||
}
|
||||
@@ -350,23 +322,10 @@ public class StateChangeInterceptorTests extends AbstractStateMachineTests {
|
||||
assertThat(listener.stateChangedLatch.await(2, TimeUnit.SECONDS), is(true));
|
||||
assertThat(listener.stateChangedCount, is(2));
|
||||
assertThat(machine.getState().getIds(), containsInAnyOrder(States.S2));
|
||||
assertThat(interceptor.preStateChangeLatch1.await(2, TimeUnit.SECONDS), is(true));
|
||||
assertThat(interceptor.preStateChangeCount1, is(2));
|
||||
assertThat(interceptor.preStateChangeLatch2.await(2, TimeUnit.SECONDS), is(true));
|
||||
assertThat(interceptor.preStateChangeCount2, is(2));
|
||||
assertThat(interceptor.postStateChangeLatch1.await(2, TimeUnit.SECONDS), is(true));
|
||||
assertThat(interceptor.postStateChangeCount1, is(2));
|
||||
assertThat(interceptor.postStateChangeLatch2.await(2, TimeUnit.SECONDS), is(true));
|
||||
assertThat(interceptor.postStateChangeCount2, is(2));
|
||||
|
||||
assertThat(interceptor.preStateChangeStates1.size(), is(2));
|
||||
assertThat(interceptor.postStateChangeStates1.size(), is(2));
|
||||
|
||||
assertThat(interceptor.preStateChangeStates1.get(0).getId(), is(States.S1));
|
||||
assertThat(interceptor.preStateChangeStates1.get(1).getId(), is(States.S2));
|
||||
|
||||
assertThat(interceptor.postStateChangeStates1.get(0).getId(), is(States.S1));
|
||||
assertThat(interceptor.postStateChangeStates1.get(1).getId(), is(States.S2));
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@@ -718,17 +677,11 @@ public class StateChangeInterceptorTests extends AbstractStateMachineTests {
|
||||
|
||||
private static class TestStateChangeInterceptor implements StateMachineInterceptor<States, Events> {
|
||||
|
||||
volatile CountDownLatch preStateChangeLatch1 = new CountDownLatch(1);
|
||||
volatile CountDownLatch preStateChangeLatch2 = new CountDownLatch(1);
|
||||
volatile CountDownLatch postStateChangeLatch1 = new CountDownLatch(1);
|
||||
volatile CountDownLatch postStateChangeLatch2 = new CountDownLatch(1);
|
||||
volatile int preStateChangeCount1 = 0;
|
||||
volatile int preStateChangeCount2 = 0;
|
||||
volatile int postStateChangeCount1 = 0;
|
||||
volatile int postStateChangeCount2 = 0;
|
||||
ArrayList<State<States, Events>> preStateChangeStates1 = new ArrayList<>();
|
||||
ArrayList<State<States, Events>> preStateChangeStates2 = new ArrayList<>();
|
||||
ArrayList<State<States, Events>> postStateChangeStates1 = new ArrayList<>();
|
||||
ArrayList<State<States, Events>> postStateChangeStates2 = new ArrayList<>();
|
||||
|
||||
@Override
|
||||
@@ -736,14 +689,6 @@ public class StateChangeInterceptorTests extends AbstractStateMachineTests {
|
||||
return message;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void preStateChange(State<States, Events> state, Message<Events> message,
|
||||
Transition<States, Events> transition, StateMachine<States, Events> stateMachine) {
|
||||
preStateChangeStates1.add(state);
|
||||
preStateChangeCount1++;
|
||||
preStateChangeLatch1.countDown();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void preStateChange(State<States, Events> state, Message<Events> message,
|
||||
Transition<States, Events> transition, StateMachine<States, Events> stateMachine,
|
||||
@@ -753,14 +698,6 @@ public class StateChangeInterceptorTests extends AbstractStateMachineTests {
|
||||
preStateChangeLatch2.countDown();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void postStateChange(State<States, Events> state, Message<Events> message,
|
||||
Transition<States, Events> transition, StateMachine<States, Events> stateMachine) {
|
||||
postStateChangeStates1.add(state);
|
||||
postStateChangeCount1++;
|
||||
postStateChangeLatch1.countDown();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void postStateChange(State<States, Events> state, Message<Events> message,
|
||||
Transition<States, Events> transition, StateMachine<States, Events> stateMachine,
|
||||
@@ -781,17 +718,11 @@ public class StateChangeInterceptorTests extends AbstractStateMachineTests {
|
||||
}
|
||||
|
||||
public void reset(int c1) {
|
||||
preStateChangeLatch1 = new CountDownLatch(c1);
|
||||
preStateChangeLatch2 = new CountDownLatch(c1);
|
||||
preStateChangeCount1 = 0;
|
||||
preStateChangeCount2 = 0;
|
||||
postStateChangeLatch1 = new CountDownLatch(c1);
|
||||
postStateChangeLatch2 = new CountDownLatch(c1);
|
||||
postStateChangeCount1 = 0;
|
||||
postStateChangeCount2 = 0;
|
||||
preStateChangeStates1.clear();
|
||||
preStateChangeStates2.clear();
|
||||
postStateChangeStates1.clear();
|
||||
postStateChangeStates2.clear();
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user