Skip to content

Commit cf5db91

Browse files
billwertsrnagar
andauthored
Eg sync stack testproxy (#36656)
* Add missing sync test cases * Enable sync-stack * Remove extra set of aeg-channel-name. * enable AssertingHttpClient * add back missing Context arguments * Don't stop trying dev credentials on failures Fixes #34733 For our dev time credentials we want to always keep going. This change wraps any failure from the credentials in a `CredentialUnavailableException` so `ChainedTokenCredential` will continue them properly. It only does so in the context of a `ChainedTokenCredential`. Regular uses of these credentials is unaffected. * Tests now use test proxy and recordings are pushed to assets repo * address pr comments * fix merge conflicts * add exports * fix version * remove unused imports * use unreleased test version * fix tag * fix tag * refactor * fix spring test after sync stack migration * log the test proxy response on error * fix header sanitizer in Service Bus * fix regex for quantum job tests * Add missing sync test cases * Enable sync-stack * Remove extra set of aeg-channel-name. * enable AssertingHttpClient * add back missing Context arguments * Tests now use test proxy and recordings are pushed to assets repo * address pr comments * add exports * fix version * use unreleased test version * fix tag * fix tag * refactor * fix spring test after sync stack migration * log the test proxy response on error * fix header sanitizer in Service Bus * fix regex for quantum job tests * Put a semaphore around starting the proxy. * make the methods of `TestProxyManager` static and synchronized. * Use the working directory to search for the root of the repo from. * add missing sanitizer setup * base class has this so it's not needed here * removed this in merge accidentally * pin azure-core version --------- Co-authored-by: Srikanta Nagaraja <srnagar@microsoft.com> Co-authored-by: Srikanta <51379715+srnagar@users.noreply.github.com>
1 parent d8fee5f commit cf5db91

File tree

43 files changed

+659
-920
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

43 files changed

+659
-920
lines changed

eng/versioning/version_client.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -441,6 +441,7 @@ com.azure.tools:azure-sdk-build-tool;1.0.0;1.1.0-beta.1
441441
# note: The unreleased dependencies will not be manipulated with the automatic PR creation code.
442442
# In the pom, the version update tag after the version should name the unreleased package and the dependency version:
443443
# <!-- {x-version-update;unreleased_com.azure:azure-core;dependency} -->
444+
unreleased_com.azure:azure-messaging-eventgrid;4.19.0-beta.1
444445

445446
# Released Beta dependencies: Copy the entry from above, prepend "beta_", remove the current
446447
# version and set the version to the released beta. Released beta dependencies are only valid

sdk/core/azure-core-test/src/main/java/com/azure/core/test/TestProxyTestBase.java

Lines changed: 1 addition & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -5,15 +5,9 @@
55

66
import com.azure.core.test.utils.TestProxyManager;
77
import com.azure.core.util.logging.ClientLogger;
8-
import org.junit.jupiter.api.AfterAll;
98
import org.junit.jupiter.api.BeforeAll;
109
import org.junit.jupiter.api.TestInfo;
1110

12-
import java.nio.file.Path;
13-
import java.nio.file.Paths;
14-
15-
import static com.azure.core.test.utils.TestUtils.toURI;
16-
1711
/**
1812
* Base class for running live and playback tests using test-proxy
1913
*/
@@ -30,8 +24,6 @@ public TestProxyTestBase() {
3024
super();
3125
}
3226

33-
private static TestProxyManager testProxyManager;
34-
3527
/**
3628
* Before tests are executed, determines the test mode by reading the {@code AZURE_TEST_MODE} environment variable.
3729
* If it is not set, {@link TestMode#PLAYBACK}
@@ -40,20 +32,8 @@ public TestProxyTestBase() {
4032
@BeforeAll
4133
public static void setupTestProxy(TestInfo testInfo) {
4234
testMode = initializeTestMode();
43-
Path testClassPath = Paths.get(toURI(testInfo.getTestClass().get().getResource(testInfo.getTestClass().get().getSimpleName() + ".class")));
4435
if (isTestProxyEnabled() && (testMode == TestMode.PLAYBACK || testMode == TestMode.RECORD)) {
45-
testProxyManager = new TestProxyManager(testClassPath);
46-
testProxyManager.startProxy();
47-
}
48-
}
49-
50-
/**
51-
* Performs cleanup actions after all tests are executed.
52-
*/
53-
@AfterAll
54-
public static void teardownTestProxy() {
55-
if (testProxyManager != null) {
56-
testProxyManager.stopProxy();
36+
TestProxyManager.startProxy();
5737
}
5838
}
5939
}

sdk/core/azure-core-test/src/main/java/com/azure/core/test/http/TestProxyPlaybackClient.java

Lines changed: 35 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
import com.azure.core.test.utils.HttpURLConnectionHttpClient;
1515
import com.azure.core.test.utils.TestProxyUtils;
1616
import com.azure.core.util.Context;
17+
import com.azure.core.util.logging.ClientLogger;
1718
import com.azure.core.util.serializer.JacksonAdapter;
1819
import com.azure.core.util.serializer.SerializerAdapter;
1920
import com.azure.core.util.serializer.SerializerEncoding;
@@ -32,6 +33,7 @@
3233
import java.util.List;
3334
import java.util.Map;
3435
import java.util.Queue;
36+
import java.util.concurrent.TimeUnit;
3537

3638
import static com.azure.core.test.implementation.TestingHelpers.X_RECORDING_FILE_LOCATION;
3739
import static com.azure.core.test.implementation.TestingHelpers.X_RECORDING_ID;
@@ -46,6 +48,7 @@
4648
*/
4749
public class TestProxyPlaybackClient implements HttpClient {
4850

51+
private static final ClientLogger LOGGER = new ClientLogger(TestProxyPlaybackClient.class);
4952
private final HttpClient client;
5053
private final URL proxyUrl;
5154
private String xRecordingId;
@@ -89,11 +92,7 @@ public Queue<String> startPlayback(File recordFile, Path testClassPath) {
8992
SerializerEncoding.JSON))
9093
.setHeader(HttpHeaderName.ACCEPT, "application/json")
9194
.setHeader(HttpHeaderName.CONTENT_TYPE, "application/json");
92-
} catch (IOException e) {
93-
throw new RuntimeException(e);
94-
}
95-
96-
try (HttpResponse response = client.sendSync(request, Context.NONE)) {
95+
HttpResponse response = sendRequestWithRetries(request);
9796
checkForTestProxyErrors(response);
9897
xRecordingId = response.getHeaderValue(X_RECORDING_ID);
9998
xRecordingFileLocation = new String(Base64.getUrlDecoder().decode(
@@ -127,13 +126,42 @@ public Queue<String> startPlayback(File recordFile, Path testClassPath) {
127126
}
128127
}
129128

129+
private HttpResponse sendRequestWithRetries(HttpRequest request) {
130+
int retries = 0;
131+
while (true) {
132+
try {
133+
HttpResponse response = client.sendSync(request, Context.NONE);
134+
if (response.getStatusCode() / 100 != 2) {
135+
throw new RuntimeException("Test proxy returned a non-successful status code. "
136+
+ response.getStatusCode() + "; response: " + response.getBodyAsString().block());
137+
}
138+
return response;
139+
} catch (Exception e) {
140+
retries++;
141+
if (retries >= 3) {
142+
throw e;
143+
}
144+
sleep(1);
145+
LOGGER.warning("Retrying request to test proxy. Retry attempt: " + retries);
146+
}
147+
}
148+
}
149+
150+
private void sleep(int durationInSeconds) {
151+
try {
152+
TimeUnit.SECONDS.sleep(durationInSeconds);
153+
} catch (InterruptedException e) {
154+
throw new RuntimeException(e);
155+
}
156+
}
157+
130158
/**
131159
* Stops playback of a test recording.
132160
*/
133161
public void stopPlayback() {
134162
HttpRequest request = new HttpRequest(HttpMethod.POST, proxyUrl + "/playback/stop")
135163
.setHeader(X_RECORDING_ID, xRecordingId);
136-
client.sendSync(request, Context.NONE).close();
164+
sendRequestWithRetries(request);
137165
}
138166

139167
/**
@@ -210,7 +238,7 @@ public void addMatcherRequests(List<TestProxyRequestMatcher> matchers) {
210238
}
211239
matcherRequests.forEach(request -> {
212240
request.setHeader(X_RECORDING_ID, xRecordingId);
213-
client.sendSync(request, Context.NONE).close();
241+
sendRequestWithRetries(request);
214242
});
215243
} else {
216244
this.matchers.addAll(matchers);

sdk/core/azure-core-test/src/main/java/com/azure/core/test/utils/TestProxyManager.java

Lines changed: 13 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -24,37 +24,34 @@
2424
/**
2525
* Manages running the test recording proxy server
2626
*/
27-
public class TestProxyManager {
27+
public final class TestProxyManager {
2828
private static final ClientLogger LOGGER = new ClientLogger(TestProxyManager.class);
29-
private Process proxy;
30-
private final Path testClassPath;
29+
private static Process proxy;
30+
private static final Path WORKING_DIRECTORY = Paths.get(System.getProperty("user.dir"));
3131

32-
/**
33-
* Construct a {@link TestProxyManager} for controlling the external test proxy.
34-
* @param testClassPath the test class path
35-
*/
36-
public TestProxyManager(Path testClassPath) {
37-
this.testClassPath = testClassPath;
38-
// This is necessary to stop the proxy when the debugger is stopped.
39-
Runtime.getRuntime().addShutdownHook(new Thread(this::stopProxy));
32+
static {
33+
Runtime.getRuntime().addShutdownHook(new Thread(TestProxyManager::stopProxy));
4034
if (runningLocally()) {
41-
TestProxyDownloader.installTestProxy(testClassPath);
35+
TestProxyDownloader.installTestProxy(WORKING_DIRECTORY);
4236
}
4337
}
4438

39+
@Deprecated
40+
private TestProxyManager() { }
41+
4542
/**
4643
* Start an instance of the test proxy.
4744
* @throws UncheckedIOException There was an issue communicating with the proxy.
4845
* @throws RuntimeException There was an issue starting the proxy process.
4946
*/
50-
public void startProxy() {
47+
public static synchronized void startProxy() {
5148
try {
5249
// if we're not running in CI we will check to see if someone has started the proxy, and start one if not.
5350
if (runningLocally() && !checkAlive(1, Duration.ofSeconds(1), null)) {
5451
String commandLine = Paths.get(TestProxyDownloader.getProxyDirectory().toString(),
5552
TestProxyUtils.getProxyProcessName()).toString();
5653

57-
Path repoRoot = TestUtils.getRepoRootResolveUntil(testClassPath, "eng");
54+
Path repoRoot = TestUtils.getRepoRootResolveUntil(WORKING_DIRECTORY, "eng");
5855

5956
// Resolve the path to the repo root 'target' folder and create the folder if it doesn't exist.
6057
// This folder will be used to store the 'test-proxy.log' file to enable simpler debugging of Test Proxy
@@ -128,7 +125,7 @@ private static boolean checkAlive(int loops, Duration waitTime, Process proxy) t
128125
/**
129126
* Stop the running instance of the test proxy.
130127
*/
131-
public void stopProxy() {
128+
private static void stopProxy() {
132129
if (proxy != null && proxy.isAlive()) {
133130
proxy.destroy();
134131
}
@@ -138,7 +135,7 @@ public void stopProxy() {
138135
* Checks the environment variables commonly set in CI to determine if the run is local.
139136
* @return True if the run is local.
140137
*/
141-
private boolean runningLocally() {
138+
private static boolean runningLocally() {
142139
return Configuration.getGlobalConfiguration().get("TF_BUILD") == null
143140
&& Configuration.getGlobalConfiguration().get("CI") == null;
144141
}

sdk/eventgrid/azure-messaging-eventgrid/CHANGELOG.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
### Other Changes
1919

2020
#### Dependency Updates
21-
-
21+
2222
- Upgraded `azure-core` from `1.42.0` to version `1.43.0`.
2323
- Upgraded `azure-core-http-netty` from `1.13.6` to version `1.13.7`.
2424

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
{
2+
"AssetsRepo": "Azure/azure-sdk-assets",
3+
"AssetsRepoPrefixPath": "java",
4+
"TagPrefix": "java/eventgrid/azure-messaging-eventgrid",
5+
"Tag": "java/eventgrid/azure-messaging-eventgrid_7bb36a1579"
6+
}

sdk/eventgrid/azure-messaging-eventgrid/pom.xml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,8 @@
5656
--add-opens com.azure.messaging.eventgrid/com.azure.messaging.eventgrid.implementation=ALL-UNNAMED
5757

5858
--add-reads com.azure.messaging.eventgrid=com.azure.core.serializer.json.jackson
59+
--add-exports com.azure.core/com.azure.core.implementation.util=ALL-UNNAMED
60+
--add-exports com.azure.core/com.azure.core.implementation=ALL-UNNAMED
5961
</javaModulesSurefireArgLine>
6062
</properties>
6163

sdk/eventgrid/azure-messaging-eventgrid/src/main/java/com/azure/messaging/eventgrid/EventGridPublisherAsyncClient.java

Lines changed: 3 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -8,14 +8,11 @@
88
import com.azure.core.annotation.ServiceMethod;
99
import com.azure.core.credential.AzureKeyCredential;
1010
import com.azure.core.credential.AzureSasCredential;
11-
import com.azure.core.http.HttpHeaders;
1211
import com.azure.core.http.HttpPipeline;
13-
import com.azure.core.http.policy.AddHeadersFromContextPolicy;
1412
import com.azure.core.http.rest.Response;
1513
import com.azure.core.models.CloudEvent;
1614
import com.azure.core.util.BinaryData;
1715
import com.azure.core.util.Context;
18-
import com.azure.core.util.CoreUtils;
1916
import com.azure.core.util.logging.ClientLogger;
2017
import com.azure.core.util.tracing.Tracer;
2118
import com.azure.messaging.eventgrid.implementation.Constants;
@@ -39,7 +36,6 @@
3936
import java.util.Base64;
4037
import java.util.Collections;
4138
import java.util.List;
42-
import java.util.Map;
4339
import java.util.Objects;
4440

4541
import static com.azure.core.util.FluxUtil.monoError;
@@ -155,7 +151,6 @@
155151
@ServiceClient(builder = EventGridPublisherClientBuilder.class, isAsync = true)
156152
public final class EventGridPublisherAsyncClient<T> {
157153

158-
private static final String PARTNER_CHANNEL_HEADER_NAME = "aeg-channel-name";
159154
private final String hostname;
160155

161156
private final EventGridPublisherClientImpl impl;
@@ -312,25 +307,9 @@ Mono<Response<Void>> sendEventsWithResponse(Iterable<T> events, String channelNa
312307
if (context == null) {
313308
context = Context.NONE;
314309
}
315-
if (!CoreUtils.isNullOrEmpty(channelName)) {
316-
String requestHttpHeadersKey = AddHeadersFromContextPolicy.AZURE_REQUEST_HTTP_HEADERS_KEY;
317-
Map<Object, Object> keyValues = context.getValues();
318-
if (keyValues != null && keyValues.containsKey(requestHttpHeadersKey)) {
319-
// if the given Context instance already contains custom headers,
320-
// add partner channel header to HttpHeaders
321-
Object value = keyValues.get(requestHttpHeadersKey);
322-
if (value instanceof HttpHeaders) {
323-
HttpHeaders headers = (HttpHeaders) value;
324-
headers.add(PARTNER_CHANNEL_HEADER_NAME, channelName);
325-
}
326-
} else {
327-
context = context.addData(requestHttpHeadersKey,
328-
new HttpHeaders().add(PARTNER_CHANNEL_HEADER_NAME, channelName));
329-
}
330-
}
331310

332311
if (this.eventClass == CloudEvent.class) {
333-
return this.sendCloudEventsWithResponse((Iterable<CloudEvent>) events, context);
312+
return this.sendCloudEventsWithResponse((Iterable<CloudEvent>) events, channelName, context);
334313
} else if (this.eventClass == EventGridEvent.class) {
335314
return this.sendEventGridEventsWithResponse((Iterable<EventGridEvent>) events, context);
336315
} else {
@@ -395,15 +374,15 @@ Mono<Response<Void>> sendEventGridEventsWithResponse(Iterable<EventGridEvent> ev
395374
.flatMap(list -> this.impl.publishEventGridEventsWithResponseAsync(this.hostname, list, finalContext));
396375
}
397376

398-
Mono<Response<Void>> sendCloudEventsWithResponse(Iterable<CloudEvent> events, Context context) {
377+
Mono<Response<Void>> sendCloudEventsWithResponse(Iterable<CloudEvent> events, String channelName, Context context) {
399378
if (events == null) {
400379
return monoError(logger, new NullPointerException("'events' cannot be null."));
401380
}
402381
final Context finalContext = context != null ? context : Context.NONE;
403382
this.addCloudEventTracePlaceHolder(events);
404383
return Flux.fromIterable(events)
405384
.collectList()
406-
.flatMap(list -> this.impl.publishCloudEventEventsWithResponseAsync(this.hostname, list, null, finalContext));
385+
.flatMap(list -> this.impl.publishCloudEventEventsWithResponseAsync(this.hostname, list, channelName, finalContext));
407386
}
408387

409388
Mono<Response<Void>> sendCustomEventsWithResponse(Iterable<BinaryData> events, Context context) {

0 commit comments

Comments
 (0)