15
15
import org .mockserver .integration .ClientAndServer ;
16
16
import org .mockserver .matchers .TimeToLive ;
17
17
import org .mockserver .matchers .Times ;
18
+ import org .mockserver .mock .Expectation ;
18
19
import org .mockserver .mock .HttpState ;
19
20
import org .mockserver .mock .action .ExpectationResponseCallback ;
21
+ import org .mockserver .mock .listeners .MockServerMatcherNotifier ;
20
22
import org .mockserver .model .*;
21
23
import org .mockserver .netty .MockServerUnificationInitializer ;
22
24
import org .mockserver .verify .VerificationTimes ;
23
25
24
26
import java .util .*;
25
27
import java .util .concurrent .CompletableFuture ;
28
+ import java .util .concurrent .atomic .AtomicBoolean ;
26
29
import java .util .concurrent .atomic .AtomicReference ;
27
30
import java .util .regex .Matcher ;
28
31
import java .util .regex .Pattern ;
@@ -50,7 +53,7 @@ protected Integer initialize() throws ConcurrentException {
50
53
return CLIENT_AND_SERVER .getLocalPort ();
51
54
}
52
55
};
53
- private static final Map <String , UpdatableExpectationResponseCallback > MOCKS = new LinkedHashMap <>();
56
+ private static final Map <String , Pair < Expectation [], UpdatableExpectationResponseCallback > > MOCKS = new LinkedHashMap <>();
54
57
private static final ConcurrentInitializer <HttpState > HTTP_STATE = new LazyInitializer <HttpState >() {
55
58
56
59
@ Override
@@ -62,24 +65,39 @@ protected HttpState initialize() throws ConcurrentException {
62
65
}
63
66
};
64
67
private static final Set <String > MOCKED_PATHS = new LinkedHashSet <>();
68
+ private static int latestPriority = 0 ;
65
69
66
70
public static synchronized void add_mock (HttpRequest httpRequest , ExpectationResponseCallback callback ) {
67
71
HttpState httpState = unchecked (HTTP_STATE ::get );
68
72
httpState .getRequestMatchers ().retrieveActiveExpectations (httpRequest )
69
73
// we are redefining an old mock with a matches, let's see if we have old callbacks still in 404
70
74
.stream ()
71
- .filter (expectation -> MOCKS .get (expectation .getHttpRequest ().toString ()).callback .equals (NOT_FOUND ))
75
+ .filter (expectation -> MOCKS .get (expectation .getHttpRequest ().toString ()).getValue (). callback .equals (NOT_FOUND ))
72
76
.forEach (expectation -> {
73
77
httpState .getRequestMatchers ().clear (expectation .getHttpRequest ());
74
78
MOCKS .remove (expectation .getHttpRequest ().toString ());
75
79
log .debug ("removing expectation {}" , expectation .getHttpRequest ());
76
80
});
77
81
78
- MOCKS .computeIfAbsent (httpRequest .toString (), k -> {
82
+ AtomicBoolean isNew = new AtomicBoolean (false );
83
+ latestPriority ++;
84
+ final Pair <Expectation [], UpdatableExpectationResponseCallback > expectationIdsWithCallback = MOCKS .computeIfAbsent (httpRequest .toString (), k -> {
85
+ isNew .set (true );
79
86
UpdatableExpectationResponseCallback updatableCallback = new UpdatableExpectationResponseCallback ();
80
- CLIENT_AND_SERVER .when (httpRequest , Times .unlimited (), TimeToLive .unlimited (), MOCKS .size ()).respond (updatableCallback );
81
- return updatableCallback ;
82
- }).set (callback );
87
+ final Expectation [] expectations = CLIENT_AND_SERVER .when (httpRequest , Times .unlimited (), TimeToLive .unlimited (), latestPriority ).respond (updatableCallback );
88
+ return Pair .of (expectations , updatableCallback );
89
+ });
90
+ expectationIdsWithCallback .getValue ().set (callback );
91
+
92
+ if (!isNew .get ()) {
93
+
94
+ Arrays .stream (expectationIdsWithCallback .getKey ())
95
+ // update the priority of the expectation
96
+ .map (expectation -> expectation .withPriority (latestPriority ))
97
+ // re-add the expectations, this will resort the CircularPriorityQueue
98
+ .forEach (expectation -> httpState .getRequestMatchers ().add (expectation , MockServerMatcherNotifier .Cause .API ));
99
+ }
100
+
83
101
PATH_PATTERNS .add (Pattern .compile (httpRequest .getPath ().getValue ()));
84
102
}
85
103
@@ -269,7 +287,7 @@ public static ClientAndServer clientAndServer() {
269
287
}
270
288
271
289
public static void reset () {
272
- MOCKS .values ().forEach (callback -> callback .set (NOT_FOUND ));
290
+ MOCKS .values ().forEach (expectationIdsWithUpdatableCallback -> expectationIdsWithUpdatableCallback . getValue () .set (NOT_FOUND ));
273
291
unchecked (HTTP_STATE ::get ).getMockServerLog ().reset ();
274
292
MOCKED_PATHS .clear ();
275
293
PATH_PATTERNS .clear ();
0 commit comments