Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
65 commits
Select commit Hold shift + click to select a range
540a16d
Initial changes
aayush3011 Apr 24, 2024
6f49c75
Initial changes
aayush3011 Apr 25, 2024
97509eb
Merge branch 'main' into users/akataria/nonStreamingOrderBy
aayush3011 Apr 25, 2024
938279a
Increment versions for core releases (#40003)
azure-sdk May 2, 2024
c6c520e
Ensure ServiceBus session idle timeout fall back to retry-options::tr…
anuchandy May 2, 2024
222f2d9
Added Alpha3 Java Media Streaming Events (#40002)
v-durgeshs May 2, 2024
387170a
Update version of github-event-processor to 1.0.0-dev.20240502.2 (#40…
azure-sdk May 2, 2024
b1e8fdc
Prepare May 2024 Identity Release (#40006)
billwert May 2, 2024
c3c4648
Prepare Identity Broker May 2024 Release (#40014)
billwert May 2, 2024
a5127c6
Increment package versions for identity releases (#40015)
azure-sdk May 2, 2024
ba334df
[JobRouter] SDK Review updates (#40011)
williamzhao87 May 2, 2024
5682de3
FixFaultInjectionRuleFailedToApplyPerPartitionInGatewayMode (#40005)
xinlian12 May 3, 2024
39cb79f
azure-cosmos-test_1.0.0.beta.7Release (#40021)
xinlian12 May 3, 2024
86b36d3
Merge branch 'main' into users/akataria/nonStreamingOrderBy
aayush3011 May 3, 2024
9a38357
Fixed existsById API in ReactiveCosmosTemplate (#40022)
kushagraThapar May 3, 2024
a979c11
Initial changes
aayush3011 May 3, 2024
e2756a5
Initial changes
aayush3011 May 3, 2024
d768057
Skip Recorded test and delete Event record until test proxy to work w…
minwoolee-msft May 3, 2024
71b1905
Fix invalid CODEOWNERS (#40032)
alzimmermsft May 3, 2024
8be2277
Initial changes
aayush3011 May 3, 2024
28a2b5a
ServiceBus: fix session tracing (#39962)
May 3, 2024
deff567
[Automation] Generate SDK based on TypeSpec 0.15.15 (#40048)
azure-sdk May 6, 2024
058f8a8
[CODEOWNERS] Updates for org changes (#40049)
jsquire May 6, 2024
9406783
Move from using the docker image to java2docfx for docs validation (#…
JimSuplizio May 6, 2024
6dee85b
owners (#39686)
harsimar May 6, 2024
61b177c
Use ClientLogger in testing output (#40010)
alzimmermsft May 6, 2024
8349880
Fix null pointer exception and context usage (#40053)
alzimmermsft May 6, 2024
c75b369
Rename AML to AzureMachineLearning (#40056)
alzimmermsft May 6, 2024
af7f403
Fixed the Key Vault `test-resources.json` file to properly configure …
vcolin7 May 6, 2024
c9da24c
Close response body in bearer policy (#40052)
May 6, 2024
7055e66
Running Prepare-Release for azure-messaging-servicebus 7.17.0 (#40058)
anuchandy May 7, 2024
4428897
mgmt, TypeSpec code generation pipeline (#39963)
XiaofeiCao May 7, 2024
a755e6a
Add codeowner linter owners (#39997)
weshaggard May 7, 2024
23b7d1e
Update to ESRP task version that supports federated auth (#40059)
hallipr May 7, 2024
94bd0d4
Increment package versions for cosmos releases (#40031)
azure-sdk May 7, 2024
149bd61
Update azure-sdk-build-tools Repository Resource Refs in Yaml files (…
azure-sdk May 7, 2024
847a8ae
Add reduced embeddings sample to azure-search-documents (#40069)
alzimmermsft May 7, 2024
376955f
Search May Preview Regen Updates (#40057)
jairmyree May 7, 2024
f01f7f4
Preparing Search May 2024 Beta Release (#40071)
jairmyree May 7, 2024
e491b9d
Resolving comments
aayush3011 May 7, 2024
151bb50
Fixing build issues
aayush3011 May 7, 2024
c86b87e
eng, update autorest.java, improve error output in sdk automation (#4…
weidongxu-microsoft May 8, 2024
a3d2d26
Merge to main after spring cloud azure 4.18.0 released (#40075)
Netyyyy May 8, 2024
f6909fb
Miscellaneous Core performance improvements (#39552)
alzimmermsft May 8, 2024
73afd5b
Merge branch 'Azure:main' into users/akataria/nonStreamingOrderBy
aayush3011 May 8, 2024
3271984
Increment package versions for search releases (#40072)
azure-sdk May 9, 2024
0e921d2
Update io.fabric8:kubernetes-client (#40086)
jairmyree May 9, 2024
b2a4bef
Increment package versions for servicebus releases (#40094)
azure-sdk May 9, 2024
6884420
Emit stable auto-instrumented otel metrics (#39960)
heyams May 9, 2024
3b0d751
Merge branch 'Azure:main' into users/akataria/nonStreamingOrderBy
aayush3011 May 9, 2024
87572f7
Merge branch 'feature/vector_search' into users/akataria/nonStreaming…
aayush3011 May 9, 2024
92a1a90
[Key Vault] Added support for `/prerestore` and `/prebackup` endpoint…
vcolin7 May 9, 2024
179f904
Initial changes
aayush3011 May 9, 2024
5602e33
Merge branch 'users/akataria/nonStreamingOrderBy' of github.com:aayus…
aayush3011 May 9, 2024
36ab9b7
Merge branch 'feature/vector_search' into users/akataria/nonStreaming…
aayush3011 May 9, 2024
0b29ce1
Prepare to release beta.22 (#40097)
heyams May 9, 2024
28217eb
Fix template name (#40099)
JimSuplizio May 9, 2024
a8fcba9
Update partner release to use WIF (#40101)
weshaggard May 9, 2024
0db1017
core mgmt, `SubResource` implements `JsonSerializable` to support azu…
XiaofeiCao May 10, 2024
2fae403
Update spring-reference and sync changelog (#40105)
Netyyyy May 10, 2024
47b1085
Support per-call response timeout in all HttpClient implementations (…
alzimmermsft May 10, 2024
e7deb7b
Change how JavaType is resolved to support JsonSerializable better (#…
alzimmermsft May 10, 2024
70639b5
Initial changes
aayush3011 May 10, 2024
c45c3a5
Fixes
aayush3011 May 10, 2024
6c255ee
Merge branch 'Azure:main' into users/akataria/nonStreamingOrderBy
aayush3011 May 10, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Miscellaneous Core performance improvements (#39552)
Miscellaneous Core performance improvements
  • Loading branch information
alzimmermsft authored May 8, 2024
commit f6909fbb68fa293ba5702f18346e77ed72c34e21
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
package com.azure.core.http.jdk.httpclient.implementation;

import com.azure.core.http.HttpHeaders;
import com.azure.core.implementation.util.HttpHeadersAccessHelper;
import com.azure.core.util.CoreUtils;

import java.nio.ByteBuffer;
Expand All @@ -25,13 +26,14 @@ public final class JdkHttpUtils {
* @param headers the JDK Http headers
* @return the azure-core Http headers
*/
@SuppressWarnings("deprecation")
public static HttpHeaders fromJdkHttpHeaders(java.net.http.HttpHeaders headers) {
final HttpHeaders httpHeaders = new HttpHeaders((int) (headers.map().size() / 0.75F));

for (Map.Entry<String, List<String>> kvp : headers.map().entrySet()) {
if (!CoreUtils.isNullOrEmpty(kvp.getValue())) {
httpHeaders.set(kvp.getKey(), kvp.getValue());
// JDK HttpClient parses headers to lower case, use the access helper to bypass lowercasing the header
// name (or in this case, just checking that the header name is lowercased).
HttpHeadersAccessHelper.setInternal(httpHeaders, kvp.getKey(), kvp.getKey(), kvp.getValue());
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,13 @@
import com.azure.core.http.HttpHeaders;
import com.azure.core.http.HttpRequest;
import com.azure.core.http.HttpResponse;
import com.azure.core.implementation.util.HttpHeadersAccessHelper;
import io.netty.util.AsciiString;
import reactor.netty.http.client.HttpClientResponse;

import java.util.Iterator;
import java.util.Map;
import java.util.Objects;

/**
* Base response class for Reactor Netty with implementations for response metadata.
Expand Down Expand Up @@ -40,8 +43,19 @@ public abstract class NettyAsyncHttpResponseBase extends HttpResponse {
while (nettyHeadersIterator.hasNext()) {
Map.Entry<CharSequence, CharSequence> next = nettyHeadersIterator.next();
// Value may be null and that needs to be guarded but key should never be null.
CharSequence value = next.getValue();
this.headers.add(next.getKey().toString(), (value == null) ? null : value.toString());
String value = Objects.toString(next.getValue(), null);
CharSequence key = next.getKey();

// Check for the header name being a Netty AsciiString as it has optimizations around lowercasing.
if (key instanceof AsciiString) {
// Hook into optimizations exposed through shared implementation to speed up the conversion.
AsciiString asciiString = (AsciiString) key;
HttpHeadersAccessHelper.addInternal(headers, asciiString.toLowerCase().toString(),
asciiString.toString(), value);
} else {
// If it isn't an AsciiString, then fallback to the shared, albeit, slower path.
this.headers.add(key.toString(), value);
}
}
} else {
this.headers = new NettyToAzureCoreHttpHeadersWrapper(nettyHeaders);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,10 +51,9 @@ public final class Utility {
* @return A newly allocated {@link ByteBuffer} containing the copied bytes.
*/
public static ByteBuffer deepCopyBuffer(ByteBuf byteBuf) {
ByteBuffer buffer = ByteBuffer.allocate(byteBuf.readableBytes());
byteBuf.readBytes(buffer);
buffer.rewind();
return buffer;
byte[] bytes = new byte[byteBuf.readableBytes()];
byteBuf.getBytes(byteBuf.readerIndex(), bytes);
return ByteBuffer.wrap(bytes);
}

/**
Expand Down
6 changes: 6 additions & 0 deletions sdk/core/azure-core/spotbugs-exclude.xml
Original file line number Diff line number Diff line change
Expand Up @@ -449,4 +449,10 @@
<Class name="com.azure.core.implementation.http.rest.SwaggerMethodParser" />
<Method name="serialize" />
</Match>

<Match>
<Bug pattern="EI_EXPOSE_STATIC_REP2" />
<Class name="com.azure.core.implementation.util.HttpHeadersAccessHelper" />
<Method name="setAccessor" />
</Match>
</FindBugsFilter>
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,22 @@ public class HttpHeaders implements Iterable<HttpHeader> {
private final Map<String, HttpHeader> headers;

static {
HttpHeadersAccessHelper.setAccessor(headers -> headers.headers);
HttpHeadersAccessHelper.setAccessor(new HttpHeadersAccessHelper.HttpHeadersAccessor() {
@Override
public Map<String, HttpHeader> getRawHeaderMap(HttpHeaders headers) {
return headers.headers;
}

@Override
public void addInternal(HttpHeaders headers, String formattedName, String name, String value) {
headers.addInternal(formattedName, name, value);
}

@Override
public void setInternal(HttpHeaders headers, String formattedName, String name, List<String> values) {
headers.setInternal(formattedName, name, values);
}
});
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -82,8 +82,6 @@ public Mono<HttpResponse> send(HttpRequest request, Context contextData) {

@Override
public Object invoke(Object proxy, final Method method, Object[] args) {
RestProxyUtils.validateResumeOperationIsNotPresent(method);

// Note: request options need to be evaluated here, as it is a public class with package private methods.
// Evaluating here allows the package private methods to be invoked here for downstream use.
final SwaggerMethodParser methodParser = getMethodParser(method);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -75,8 +75,6 @@ Mono<HttpResponse> send(HttpRequest request, Context contextData) {
@SuppressWarnings({ "try", "unused" })
public Object invoke(Object proxy, Method method, RequestOptions options, EnumSet<ErrorOptions> errorOptions,
Consumer<HttpRequest> requestCallback, SwaggerMethodParser methodParser, HttpRequest request, Context context) {
RestProxyUtils.validateResumeOperationIsNotPresent(method);

context = startTracingSpan(methodParser, context);

// If there is 'RequestOptions' apply its request callback operations before validating the body.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -98,8 +98,6 @@ public RestProxyBase(HttpPipeline httpPipeline, SerializerAdapter serializer,
*/
public final Object invoke(Object proxy, Method method, RequestOptions options, EnumSet<ErrorOptions> errorOptions,
Consumer<HttpRequest> requestCallback, SwaggerMethodParser methodParser, boolean isAsync, Object[] args) {
RestProxyUtils.validateResumeOperationIsNotPresent(method);

try {
HttpRequest request = createHttpRequest(methodParser, serializer, isAsync, args);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -285,6 +285,8 @@ public SwaggerMethodParser(Method swaggerMethod) {
this.responseEagerlyRead = isResponseEagerlyRead(unwrappedReturnType);
this.ignoreResponseBody = isResponseBodyIgnored(unwrappedReturnType);
this.spanName = interfaceParser.getServiceName() + "." + swaggerMethod.getName();

RestProxyUtils.validateResumeOperationIsNotPresent(swaggerMethod);
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
import com.azure.core.http.HttpHeader;
import com.azure.core.http.HttpHeaders;

import java.util.List;
import java.util.Locale;
import java.util.Map;

/**
Expand All @@ -24,6 +26,34 @@ public interface HttpHeadersAccessor {
* @return The raw header map.
*/
Map<String, HttpHeader> getRawHeaderMap(HttpHeaders headers);

/**
* Adds a header value to the backing map in {@link HttpHeaders}.
* <p>
* This bypasses using {@link HttpHeaders#add(String, String)} which uses {@link String#toLowerCase(Locale)},
* which may be slower than options available by implementing HTTP stacks (such as Netty which has an ASCII
* string class which has optimizations around lowercasing due to ASCII constraints).
*
* @param headers The {@link HttpHeaders} to add the header to.
* @param formattedName The lower-cased header name.
* @param name The original header name.
* @param value The header value.
*/
void addInternal(HttpHeaders headers, String formattedName, String name, String value);

/**
* Sets a header value to the backing map in {@link HttpHeaders}.
* <p>
* This bypasses using {@link HttpHeaders#set(String, List)} which uses {@link String#toLowerCase(Locale)},
* which may be slower than options available by implementing HTTP stacks (such as JDK HttpClient where all
* response header names are already lowercased).
*
* @param headers The {@link HttpHeaders} to set the header to.
* @param formattedName The lower-cased header name.
* @param name The original header name.
* @param values The header values.
*/
void setInternal(HttpHeaders headers, String formattedName, String name, List<String> values);
}

/**
Expand All @@ -36,6 +66,38 @@ public static Map<String, HttpHeader> getRawHeaderMap(HttpHeaders headers) {
return accessor.getRawHeaderMap(headers);
}

/**
* Adds a header value to the backing map in {@link HttpHeaders}.
* <p>
* This bypasses using {@link HttpHeaders#add(String, String)} which uses {@link String#toLowerCase(Locale)},
* which may be slower than options available by implementing HTTP stacks (such as Netty which has an ASCII
* string class which has optimizations around lowercasing due to ASCII constraints).
*
* @param headers The {@link HttpHeaders} to add the header to.
* @param formattedName The lower-cased header name.
* @param name The original header name.
* @param value The header value.
*/
public static void addInternal(HttpHeaders headers, String formattedName, String name, String value) {
accessor.addInternal(headers, formattedName, name, value);
}

/**
* Sets a header value to the backing map in {@link HttpHeaders}.
* <p>
* This bypasses using {@link HttpHeaders#set(String, List)} which uses {@link String#toLowerCase(Locale)},
* which may be slower than options available by implementing HTTP stacks (such as JDK HttpClient where all
* response header names are already lowercased).
*
* @param headers The {@link HttpHeaders} to set the header to.
* @param formattedName The lower-cased header name.
* @param name The original header name.
* @param values The header values.
*/
public static void setInternal(HttpHeaders headers, String formattedName, String name, List<String> values) {
accessor.setInternal(headers, formattedName, name, values);
}

/**
* Sets the {@link HttpHeadersAccessor}.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,6 @@
import com.azure.core.util.logging.ClientLogger;
import com.azure.core.util.logging.LogLevel;

import java.util.Map;
import java.util.TreeMap;

/**
* Supported serialization encoding formats.
*/
Expand All @@ -32,20 +29,6 @@ public enum SerializerEncoding {
TEXT;

private static final ClientLogger LOGGER = new ClientLogger(SerializerEncoding.class);
private static final Map<String, SerializerEncoding> SUPPORTED_MIME_TYPES;

static {
// Encodings and suffixes from: https://tools.ietf.org/html/rfc6838
SUPPORTED_MIME_TYPES = new TreeMap<>(String.CASE_INSENSITIVE_ORDER);
SUPPORTED_MIME_TYPES.put("text/xml", XML);
SUPPORTED_MIME_TYPES.put("application/xml", XML);
SUPPORTED_MIME_TYPES.put("application/json", JSON);
SUPPORTED_MIME_TYPES.put("text/css", TEXT);
SUPPORTED_MIME_TYPES.put("text/csv", TEXT);
SUPPORTED_MIME_TYPES.put("text/html", TEXT);
SUPPORTED_MIME_TYPES.put("text/javascript", TEXT);
SUPPORTED_MIME_TYPES.put("text/plain", TEXT);
}

/**
* Determines the serializer encoding to use based on the Content-Type header.
Expand All @@ -63,7 +46,7 @@ public static SerializerEncoding fromHeaders(HttpHeaders headers) {

int contentTypeEnd = mimeContentType.indexOf(';');
String contentType = (contentTypeEnd == -1) ? mimeContentType : mimeContentType.substring(0, contentTypeEnd);
final SerializerEncoding encoding = SUPPORTED_MIME_TYPES.get(contentType);
SerializerEncoding encoding = checkForKnownEncoding(contentType);
if (encoding != null) {
return encoding;
}
Expand Down Expand Up @@ -97,4 +80,43 @@ public static SerializerEncoding fromHeaders(HttpHeaders headers) {

return JSON;
}

/*
* There is a limited set of serialization encodings that are known ahead of time. Instead of using a TreeMap with
* a case-insensitive comparator, use an optimized search specifically for the known encodings.
*/
private static SerializerEncoding checkForKnownEncoding(String contentType) {
int length = contentType.length();

// Check the length of the content type first as it is a quick check.
if (length != 8 && length != 9 && length != 10 && length != 15 && length != 16) {
return null;
}

if ("text/".regionMatches(true, 0, contentType, 0, 5)) {
if (length == 8) {
if ("xml".regionMatches(true, 0, contentType, 5, 3)) {
return XML;
} else if ("csv".regionMatches(true, 0, contentType, 5, 3)) {
return TEXT;
} else if ("css".regionMatches(true, 0, contentType, 5, 3)) {
return TEXT;
}
} else if (length == 9 && "html".regionMatches(true, 0, contentType, 5, 4)) {
return TEXT;
} else if (length == 10 && "plain".regionMatches(true, 0, contentType, 5, 5)) {
return TEXT;
} else if (length == 15 && "javascript".regionMatches(true, 0, contentType, 5, 10)) {
return TEXT;
}
} else if ("application/".regionMatches(true, 0, contentType, 0, 12)) {
if (length == 16 && "json".regionMatches(true, 0, contentType, 12, 4)) {
return JSON;
} else if (length == 15 && "xml".regionMatches(true, 0, contentType, 12, 3)) {
return XML;
}
}

return null;
}
}