diff --git a/sdk/core/azure-core/CHANGELOG.md b/sdk/core/azure-core/CHANGELOG.md
index 24b6579649129..3861d123bfdf7 100644
--- a/sdk/core/azure-core/CHANGELOG.md
+++ b/sdk/core/azure-core/CHANGELOG.md
@@ -1,16 +1,20 @@
# Release History
-## 1.32.0-beta.1 (Unreleased)
+## 1.32.0 (2022-09-01)
+### Features Added
+
+- Added new constructor overloads to `PagedIterable` and introduced `PageRetrieverSync`.
- Added `com.azure.core.util.metrics.LongGauge` instrument support to metrics.
+- Added `CoreUtils.stringJoin` which optimizes `String.join` for small `List`s.
-### Features Added
+### Other Changes
-### Breaking Changes
+- Miscellaneous performance improvements.
-### Bugs Fixed
+#### Dependency Updates
-### Other Changes
+- Upgraded Reactor from `3.4.2` to `3.4.22`.
## 1.31.0 (2022-08-05)
diff --git a/sdk/core/azure-core/README.md b/sdk/core/azure-core/README.md
index e051caf8b628e..7aa94df9a6249 100644
--- a/sdk/core/azure-core/README.md
+++ b/sdk/core/azure-core/README.md
@@ -58,7 +58,7 @@ add the direct dependency to your project as follows.
com.azure
azure-core
- 1.31.0
+ 1.32.0
```
[//]: # ({x-version-update-end})
diff --git a/sdk/core/azure-core/pom.xml b/sdk/core/azure-core/pom.xml
index 1029a9a43094f..82c3700cea0e5 100644
--- a/sdk/core/azure-core/pom.xml
+++ b/sdk/core/azure-core/pom.xml
@@ -15,7 +15,7 @@
com.azure
azure-core
jar
- 1.32.0-beta.1
+ 1.32.0
Microsoft Azure Java Core Library
This package contains core types for Azure Java clients.
diff --git a/sdk/core/azure-json-gson/src/main/java/com/azure/json/gson/GsonJsonProvider.java b/sdk/core/azure-json-gson/src/main/java/com/azure/json/gson/GsonJsonProvider.java
new file mode 100644
index 0000000000000..6ae9888c87969
--- /dev/null
+++ b/sdk/core/azure-json-gson/src/main/java/com/azure/json/gson/GsonJsonProvider.java
@@ -0,0 +1,49 @@
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT License.
+
+package com.azure.json.gson;
+
+import com.azure.json.JsonOptions;
+import com.azure.json.JsonProvider;
+import com.azure.json.JsonReader;
+import com.azure.json.JsonWriter;
+
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.Reader;
+import java.io.Writer;
+
+/**
+ * Implementation of {@link JsonProvider} that creates instances using GSON.
+ */
+public class GsonJsonProvider implements JsonProvider {
+ @Override
+ public JsonReader createReader(byte[] json, JsonOptions options) {
+ return GsonJsonReader.fromBytes(json, options);
+ }
+
+ @Override
+ public JsonReader createReader(String json, JsonOptions options) {
+ return GsonJsonReader.fromString(json, options);
+ }
+
+ @Override
+ public JsonReader createReader(InputStream json, JsonOptions options) {
+ return GsonJsonReader.fromStream(json, options);
+ }
+
+ @Override
+ public JsonReader createReader(Reader json, JsonOptions options) {
+ return GsonJsonReader.fromReader(json, options);
+ }
+
+ @Override
+ public JsonWriter createWriter(OutputStream json, JsonOptions options) {
+ return GsonJsonWriter.toStream(json, options);
+ }
+
+ @Override
+ public JsonWriter createWriter(Writer json, JsonOptions options) {
+ return GsonJsonWriter.toWriter(json, options);
+ }
+}
diff --git a/sdk/core/azure-json-gson/src/main/java/com/azure/json/gson/GsonJsonReader.java b/sdk/core/azure-json-gson/src/main/java/com/azure/json/gson/GsonJsonReader.java
index 4087f6b15454a..7a9f8260c4014 100644
--- a/sdk/core/azure-json-gson/src/main/java/com/azure/json/gson/GsonJsonReader.java
+++ b/sdk/core/azure-json-gson/src/main/java/com/azure/json/gson/GsonJsonReader.java
@@ -3,6 +3,7 @@
package com.azure.json.gson;
+import com.azure.json.JsonOptions;
import com.azure.json.JsonReader;
import com.azure.json.JsonToken;
@@ -25,46 +26,71 @@ public final class GsonJsonReader extends JsonReader {
private final byte[] jsonBytes;
private final String jsonString;
private final boolean resetSupported;
+ private final boolean nonNumericNumbersSupported;
private JsonToken currentToken;
private boolean consumed = false;
+ private boolean complete = false;
/**
* Constructs an instance of {@link GsonJsonReader} from a {@code byte[]}.
*
* @param json JSON {@code byte[]}.
+ * @param options {@link JsonOptions} to configure the creation of the {@link JsonReader}.
* @return An instance of {@link GsonJsonReader}.
*/
- public static JsonReader fromBytes(byte[] json) {
+ static JsonReader fromBytes(byte[] json, JsonOptions options) {
return new GsonJsonReader(new InputStreamReader(new ByteArrayInputStream(json), StandardCharsets.UTF_8),
- true, json, null);
+ true, json, null, options);
}
/**
* Constructs an instance of {@link GsonJsonReader} from a String.
*
* @param json JSON String.
+ * @param options {@link JsonOptions} to configure the creation of the {@link JsonReader}.
* @return An instance of {@link GsonJsonReader}.
*/
- public static JsonReader fromString(String json) {
- return new GsonJsonReader(new StringReader(json), true, null, json);
+ static JsonReader fromString(String json, JsonOptions options) {
+ return new GsonJsonReader(new StringReader(json), true, null, json, options);
}
/**
* Constructs an instance of {@link GsonJsonReader} from an {@link InputStream}.
*
* @param json JSON {@link InputStream}.
+ * @param options {@link JsonOptions} to configure the creation of the {@link JsonReader}.
* @return An instance of {@link GsonJsonReader}.
*/
- public static JsonReader fromStream(InputStream json) {
- return new GsonJsonReader(new InputStreamReader(json, StandardCharsets.UTF_8), false, null, null);
+ static JsonReader fromStream(InputStream json, JsonOptions options) {
+ return new GsonJsonReader(new InputStreamReader(json, StandardCharsets.UTF_8), json.markSupported(), null, null,
+ options);
}
- private GsonJsonReader(Reader reader, boolean resetSupported, byte[] jsonBytes, String jsonString) {
+ /**
+ * Constructs an instance of {@link GsonJsonReader} from a {@link Reader}.
+ *
+ * @param json JSON {@link Reader}.
+ * @param options {@link JsonOptions} to configure the creation of the {@link JsonReader}.
+ * @return An instance of {@link GsonJsonReader}.
+ */
+ static JsonReader fromReader(Reader json, JsonOptions options) {
+ return new GsonJsonReader(json, json.markSupported(), null, null, options);
+ }
+
+ private GsonJsonReader(Reader reader, boolean resetSupported, byte[] jsonBytes, String jsonString,
+ JsonOptions options) {
+ this(reader, resetSupported, jsonBytes, jsonString, options.isNonNumericNumbersSupported());
+ }
+
+ private GsonJsonReader(Reader reader, boolean resetSupported, byte[] jsonBytes, String jsonString,
+ boolean nonNumericNumbersSupported) {
this.reader = new com.google.gson.stream.JsonReader(reader);
+ this.reader.setLenient(nonNumericNumbersSupported);
this.resetSupported = resetSupported;
this.jsonBytes = jsonBytes;
this.jsonString = jsonString;
+ this.nonNumericNumbersSupported = nonNumericNumbersSupported;
}
@Override
@@ -74,6 +100,10 @@ public JsonToken currentToken() {
@Override
public JsonToken nextToken() {
+ if (complete) {
+ return currentToken;
+ }
+
// GSON requires explicitly beginning and ending arrays and objects and consuming null values.
// The contract of JsonReader implicitly overlooks these properties.
try {
@@ -112,7 +142,12 @@ public JsonToken nextToken() {
}
}
- currentToken = mapToken(reader.peek());
+ com.google.gson.stream.JsonToken gsonToken = reader.peek();
+ if (gsonToken == com.google.gson.stream.JsonToken.END_DOCUMENT) {
+ complete = true;
+ }
+
+ currentToken = mapToken(gsonToken);
consumed = false;
return currentToken;
} catch (IOException e) {
@@ -235,7 +270,8 @@ public JsonReader bufferObject() {
consumed = true;
StringBuilder bufferedObject = new StringBuilder();
readChildren(bufferedObject);
- return GsonJsonReader.fromString(bufferedObject.toString());
+ String json = bufferedObject.toString();
+ return new GsonJsonReader(new StringReader(json), true, null, json, nonNumericNumbersSupported);
} else {
throw new IllegalStateException("Cannot buffer a JSON object from a non-object, non-field name "
+ "starting location. Starting location: " + currentToken());
@@ -254,9 +290,11 @@ public JsonReader reset() {
}
if (jsonBytes != null) {
- return GsonJsonReader.fromBytes(jsonBytes);
+ return new GsonJsonReader(
+ new InputStreamReader(new ByteArrayInputStream(jsonBytes), StandardCharsets.UTF_8), true, jsonBytes,
+ null, nonNumericNumbersSupported);
} else {
- return GsonJsonReader.fromString(jsonString);
+ return new GsonJsonReader(new StringReader(jsonString), true, null, jsonString, nonNumericNumbersSupported);
}
}
@@ -275,33 +313,19 @@ private static JsonToken mapToken(com.google.gson.stream.JsonToken token) {
}
switch (token) {
- case BEGIN_OBJECT:
- return JsonToken.START_OBJECT;
-
- case END_OBJECT:
- case END_DOCUMENT:
- return JsonToken.END_OBJECT;
-
- case BEGIN_ARRAY:
- return JsonToken.START_ARRAY;
-
- case END_ARRAY:
- return JsonToken.END_ARRAY;
-
- case NAME:
- return JsonToken.FIELD_NAME;
-
- case STRING:
- return JsonToken.STRING;
+ case BEGIN_OBJECT: return JsonToken.START_OBJECT;
+ case END_OBJECT: return JsonToken.END_OBJECT;
- case NUMBER:
- return JsonToken.NUMBER;
+ case BEGIN_ARRAY: return JsonToken.START_ARRAY;
+ case END_ARRAY: return JsonToken.END_ARRAY;
- case BOOLEAN:
- return JsonToken.BOOLEAN;
+ case NAME: return JsonToken.FIELD_NAME;
+ case STRING: return JsonToken.STRING;
+ case NUMBER: return JsonToken.NUMBER;
+ case BOOLEAN: return JsonToken.BOOLEAN;
+ case NULL: return JsonToken.NULL;
- case NULL:
- return JsonToken.NULL;
+ case END_DOCUMENT: return JsonToken.END_DOCUMENT;
default:
throw new IllegalStateException("Unsupported token type: '" + token + "'.");
diff --git a/sdk/core/azure-json-gson/src/main/java/com/azure/json/gson/GsonJsonWriter.java b/sdk/core/azure-json-gson/src/main/java/com/azure/json/gson/GsonJsonWriter.java
index 2818bb42cb905..0e5b382d935d1 100644
--- a/sdk/core/azure-json-gson/src/main/java/com/azure/json/gson/GsonJsonWriter.java
+++ b/sdk/core/azure-json-gson/src/main/java/com/azure/json/gson/GsonJsonWriter.java
@@ -3,6 +3,7 @@
package com.azure.json.gson;
+import com.azure.json.JsonOptions;
import com.azure.json.JsonToken;
import com.azure.json.JsonWriteContext;
import com.azure.json.JsonWriter;
@@ -11,6 +12,7 @@
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.UncheckedIOException;
+import java.io.Writer;
import java.nio.charset.StandardCharsets;
import java.util.Base64;
import java.util.Objects;
@@ -31,15 +33,30 @@ public final class GsonJsonWriter extends JsonWriter {
* isn't the owner of the stream.
*
* @param stream The {@link OutputStream} that will be written.
+ * @param options {@link JsonOptions} to configure the creation of the {@link JsonWriter}.
* @return An instance of {@link GsonJsonWriter}.
*/
- public static JsonWriter toStream(OutputStream stream) {
- return new GsonJsonWriter(new com.google.gson.stream.JsonWriter(
- new OutputStreamWriter(stream, StandardCharsets.UTF_8)));
+ static JsonWriter toStream(OutputStream stream, JsonOptions options) {
+ return new GsonJsonWriter(new OutputStreamWriter(stream, StandardCharsets.UTF_8), options);
}
- private GsonJsonWriter(com.google.gson.stream.JsonWriter writer) {
- this.writer = writer;
+ /**
+ * Creates a {@link GsonJsonWriter} that writes the given {@link Writer}.
+ *
+ * The passed {@link Writer} won't be closed when {@link #close()} is called as the {@link GsonJsonWriter}
+ * isn't the owner of the stream.
+ *
+ * @param writer The {@link Writer} that will be written.
+ * @param options {@link JsonOptions} to configure the creation of the {@link JsonWriter}.
+ * @return An instance of {@link GsonJsonWriter}.
+ */
+ static JsonWriter toWriter(Writer writer, JsonOptions options) {
+ return new GsonJsonWriter(writer, options);
+ }
+
+ private GsonJsonWriter(Writer writer, JsonOptions options) {
+ this.writer = new com.google.gson.stream.JsonWriter(writer);
+ this.writer.setLenient(options.isNonNumericNumbersSupported());
}
@Override
diff --git a/sdk/core/azure-json-gson/src/main/java/module-info.java b/sdk/core/azure-json-gson/src/main/java/module-info.java
index eaa4376caf735..9ef2e6e8dc8d1 100644
--- a/sdk/core/azure-json-gson/src/main/java/module-info.java
+++ b/sdk/core/azure-json-gson/src/main/java/module-info.java
@@ -7,4 +7,6 @@
requires com.google.gson;
exports com.azure.json.gson;
+
+ provides com.azure.json.JsonProvider with com.azure.json.gson.GsonJsonProvider;
}
diff --git a/sdk/core/azure-json-gson/src/main/resources/META-INF/services/com.azure.json.JsonProvider b/sdk/core/azure-json-gson/src/main/resources/META-INF/services/com.azure.json.JsonProvider
new file mode 100644
index 0000000000000..2c52ef3599b3f
--- /dev/null
+++ b/sdk/core/azure-json-gson/src/main/resources/META-INF/services/com.azure.json.JsonProvider
@@ -0,0 +1 @@
+com.azure.json.gson.GsonJsonProvider
diff --git a/sdk/core/azure-json-gson/src/test/java/com/azure/json/gson/GsonJsonInstantiationTests.java b/sdk/core/azure-json-gson/src/test/java/com/azure/json/gson/GsonJsonInstantiationTests.java
index 236a88e99f243..03b96f5f6e07a 100644
--- a/sdk/core/azure-json-gson/src/test/java/com/azure/json/gson/GsonJsonInstantiationTests.java
+++ b/sdk/core/azure-json-gson/src/test/java/com/azure/json/gson/GsonJsonInstantiationTests.java
@@ -24,11 +24,13 @@ public void throwsNullPointerException(Executable executable) {
@SuppressWarnings("resource")
private static Stream throwsNullPointerExceptionSupplier() {
return Stream.of(
- () -> GsonJsonReader.fromBytes(null),
- () -> GsonJsonReader.fromString(null),
- () -> GsonJsonReader.fromStream(null),
+ () -> GsonJsonReader.fromBytes(null, null),
+ () -> GsonJsonReader.fromReader(null, null),
+ () -> GsonJsonReader.fromString(null, null),
+ () -> GsonJsonReader.fromStream(null, null),
- () -> GsonJsonWriter.toStream(null)
+ () -> GsonJsonWriter.toStream(null, null),
+ () -> GsonJsonWriter.toWriter(null, null)
);
}
}
diff --git a/sdk/core/azure-json-gson/src/test/java/com/azure/json/gson/GsonJsonReaderContractTests.java b/sdk/core/azure-json-gson/src/test/java/com/azure/json/gson/GsonJsonReaderContractTests.java
index e03a1d1280329..71abd8e5bdf78 100644
--- a/sdk/core/azure-json-gson/src/test/java/com/azure/json/gson/GsonJsonReaderContractTests.java
+++ b/sdk/core/azure-json-gson/src/test/java/com/azure/json/gson/GsonJsonReaderContractTests.java
@@ -3,6 +3,7 @@
package com.azure.json.gson;
+import com.azure.json.JsonOptions;
import com.azure.json.JsonReader;
import com.azure.json.contract.JsonReaderContractTests;
@@ -12,6 +13,6 @@
public class GsonJsonReaderContractTests extends JsonReaderContractTests {
@Override
public JsonReader getJsonReader(String json) {
- return GsonJsonReader.fromString(json);
+ return GsonJsonReader.fromString(json, new JsonOptions());
}
}
diff --git a/sdk/core/azure-json-gson/src/test/java/com/azure/json/gson/GsonJsonWriterContractTests.java b/sdk/core/azure-json-gson/src/test/java/com/azure/json/gson/GsonJsonWriterContractTests.java
index 88b2a0828fcd8..34d0aeaf18c99 100644
--- a/sdk/core/azure-json-gson/src/test/java/com/azure/json/gson/GsonJsonWriterContractTests.java
+++ b/sdk/core/azure-json-gson/src/test/java/com/azure/json/gson/GsonJsonWriterContractTests.java
@@ -3,6 +3,7 @@
package com.azure.json.gson;
+import com.azure.json.JsonOptions;
import com.azure.json.JsonWriter;
import com.azure.json.contract.JsonWriterContractTests;
import org.junit.jupiter.api.BeforeEach;
@@ -21,7 +22,7 @@ public class GsonJsonWriterContractTests extends JsonWriterContractTests {
@BeforeEach
public void beforeEach() {
this.outputStream = new ByteArrayOutputStream();
- this.writer = GsonJsonWriter.toStream(outputStream);
+ this.writer = GsonJsonWriter.toStream(outputStream, new JsonOptions());
}
@Override
diff --git a/sdk/core/azure-json/src/main/java/com/azure/json/JsonOptions.java b/sdk/core/azure-json/src/main/java/com/azure/json/JsonOptions.java
new file mode 100644
index 0000000000000..deb7c0f21f403
--- /dev/null
+++ b/sdk/core/azure-json/src/main/java/com/azure/json/JsonOptions.java
@@ -0,0 +1,37 @@
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT License.
+
+package com.azure.json;
+
+/**
+ * Contains configuration options for creating a {@link JsonReader} or {@link JsonWriter}.
+ */
+public final class JsonOptions {
+ static final JsonOptions DEFAULT_OPTIONS = new JsonOptions();
+
+ private boolean nonNumericNumbersSupported = true;
+
+ /**
+ * Whether non-numeric numbers such as {@code NaN} and {@code INF} and {@code -INF} are supported.
+ *
+ * By default, this is configured to true.
+ *
+ * @return Whether non-numeric numbers are supported.
+ */
+ public boolean isNonNumericNumbersSupported() {
+ return nonNumericNumbersSupported;
+ }
+
+ /**
+ * Sets whether non-numeric numbers such as {@code NaN} and {@code INF} and {@code -INF} are supported.
+ *
+ * By default, this is configured to true.
+ *
+ * @param nonNumericNumbersSupported Whether non-numeric numbers are supported.
+ * @return The updated JsonOptions object.
+ */
+ public JsonOptions setNonNumericNumbersSupported(boolean nonNumericNumbersSupported) {
+ this.nonNumericNumbersSupported = nonNumericNumbersSupported;
+ return this;
+ }
+}
diff --git a/sdk/core/azure-json/src/main/java/com/azure/json/JsonProvider.java b/sdk/core/azure-json/src/main/java/com/azure/json/JsonProvider.java
new file mode 100644
index 0000000000000..699bf67dafc18
--- /dev/null
+++ b/sdk/core/azure-json/src/main/java/com/azure/json/JsonProvider.java
@@ -0,0 +1,141 @@
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT License.
+
+package com.azure.json;
+
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.Reader;
+import java.io.Writer;
+
+/**
+ * An interface to be implemented by any azure-json plugin that wishes to provide an alternate {@link JsonReader} or
+ * {@link JsonWriter} implementation.
+ */
+public interface JsonProvider {
+ /**
+ * Creates an instance of {@link JsonReader} that reads a {@code byte[]}.
+ *
+ * @param json The JSON represented as a {@code byte[]}.
+ * @return A new instance of {@link JsonReader}.
+ * @throws NullPointerException If {@code json} is null.
+ */
+ default JsonReader createReader(byte[] json) {
+ return createReader(json, JsonOptions.DEFAULT_OPTIONS);
+ }
+
+ /**
+ * Creates an instance of {@link JsonReader} that reads a {@code byte[]}.
+ *
+ * @param json The JSON represented as a {@code byte[]}.
+ * @param options {@link JsonOptions} to configure the creation of the {@link JsonReader}.
+ * @return A new instance of {@link JsonReader}.
+ * @throws NullPointerException If {@code json} is null.
+ */
+ JsonReader createReader(byte[] json, JsonOptions options);
+
+ /**
+ * Creates an instance of {@link JsonReader} that reads a {@link String}.
+ *
+ * @param json The JSON represented as a {@link String}.
+ * @return A new instance of {@link JsonReader}.
+ * @throws NullPointerException If {@code json} is null.
+ */
+ default JsonReader createReader(String json) {
+ return createReader(json, JsonOptions.DEFAULT_OPTIONS);
+ }
+
+ /**
+ * Creates an instance of {@link JsonReader} that reads a {@link String}.
+ *
+ * @param json The JSON represented as a {@link String}.
+ * @param options {@link JsonOptions} to configure the creation of the {@link JsonReader}.
+ * @return A new instance of {@link JsonReader}.
+ * @throws NullPointerException If {@code json} is null.
+ */
+ JsonReader createReader(String json, JsonOptions options);
+
+ /**
+ * Creates an instance of {@link JsonReader} that reads a {@link InputStream}.
+ *
+ * @param json The JSON represented as a {@link InputStream}.
+ * @return A new instance of {@link JsonReader}.
+ * @throws NullPointerException If {@code json} is null.
+ */
+ default JsonReader createReader(InputStream json) {
+ return createReader(json, JsonOptions.DEFAULT_OPTIONS);
+ }
+
+ /**
+ * Creates an instance of {@link JsonReader} that reads a {@link InputStream}.
+ *
+ * @param json The JSON represented as a {@link InputStream}.
+ * @param options {@link JsonOptions} to configure the creation of the {@link JsonReader}.
+ * @return A new instance of {@link JsonReader}.
+ * @throws NullPointerException If {@code json} is null.
+ */
+ JsonReader createReader(InputStream json, JsonOptions options);
+
+ /**
+ * Creates an instance of {@link JsonReader} that reads a {@link Reader}.
+ *
+ * @param json The JSON represented as a {@link Reader}.
+ * @return A new instance of {@link JsonReader}.
+ * @throws NullPointerException If {@code json} is null.
+ */
+ default JsonReader createReader(Reader json) {
+ return createReader(json, JsonOptions.DEFAULT_OPTIONS);
+ }
+
+ /**
+ * Creates an instance of {@link JsonReader} that reads a {@link Reader}.
+ *
+ * @param json The JSON represented as a {@link Reader}.
+ * @param options {@link JsonOptions} to configure the creation of the {@link JsonReader}.
+ * @return A new instance of {@link JsonReader}.
+ * @throws NullPointerException If {@code json} is null.
+ */
+ JsonReader createReader(Reader json, JsonOptions options);
+
+ /**
+ * Creates an instance of {@link JsonWriter} that writes to an {@link OutputStream}.
+ *
+ * @param json The JSON represented as an {@link OutputStream}.
+ * @return A new instance of {@link JsonWriter}.
+ * @throws NullPointerException If {@code json} is null.
+ */
+ default JsonWriter createWriter(OutputStream json) {
+ return createWriter(json, JsonOptions.DEFAULT_OPTIONS);
+ }
+
+ /**
+ * Creates an instance of {@link JsonWriter} that writes to an {@link OutputStream}.
+ *
+ * @param json The JSON represented as an {@link OutputStream}.
+ * @param options {@link JsonOptions} to configure the creation of the {@link JsonWriter}.
+ * @return A new instance of {@link JsonWriter}.
+ * @throws NullPointerException If {@code json} is null.
+ */
+ JsonWriter createWriter(OutputStream json, JsonOptions options);
+
+ /**
+ * Creates an instance of {@link JsonWriter} that writes to an {@link Writer}.
+ *
+ * @param json The JSON represented as an {@link Writer}.
+ * @return A new instance of {@link JsonWriter}.
+ * @throws NullPointerException If {@code json} is null.
+ */
+ default JsonWriter createWriter(Writer json) {
+ return createWriter(json, JsonOptions.DEFAULT_OPTIONS);
+ }
+
+ /**
+ * Creates an instance of {@link JsonWriter} that writes to an {@link Writer}.
+ *
+ * @param json The JSON represented as an {@link Writer}.
+ * @param options {@link JsonOptions} to configure the creation of the {@link JsonWriter}.
+ * @return A new instance of {@link JsonWriter}.
+ * @throws NullPointerException If {@code json} is null.
+ */
+ JsonWriter createWriter(Writer json, JsonOptions options);
+}
diff --git a/sdk/core/azure-json/src/main/java/com/azure/json/JsonProviders.java b/sdk/core/azure-json/src/main/java/com/azure/json/JsonProviders.java
new file mode 100644
index 0000000000000..e995663167f3a
--- /dev/null
+++ b/sdk/core/azure-json/src/main/java/com/azure/json/JsonProviders.java
@@ -0,0 +1,269 @@
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT License.
+
+package com.azure.json;
+
+import com.azure.json.implementation.DefaultJsonReader;
+import com.azure.json.implementation.DefaultJsonWriter;
+
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.Reader;
+import java.io.Writer;
+import java.util.Iterator;
+import java.util.ServiceLoader;
+
+/**
+ * Handles loading an instance of {@link JsonProvider} found on the classpath.
+ */
+public final class JsonProviders {
+ private static final String CANNOT_FIND_JSON = "A request was made to load a JsonReader and JsonWriter provider "
+ + "but one could not be found on the classpath. If you are using a dependency manager, consider including a "
+ + "dependency on azure-json-gson or azure-json-reflect or indicate to the loader to fallback to the default "
+ + "implementation. Depending on your existing dependencies, you have the choice of Jackson or JSON "
+ + "implementations. Additionally, refer to https://aka.ms/azsdk/java/docs/custom-json to learn about writing "
+ + "your own implementation.";
+
+ private static JsonProvider defaultProvider;
+
+ static {
+ // Use as classloader to load provider-configuration files and provider classes the classloader
+ // that loaded this class. In most cases this will be the System classloader.
+ // But this choice here provides additional flexibility in managed environments that control
+ // classloading differently (OSGi, Spring and others) and don't/ depend on the
+ // System classloader to load HttpClientProvider classes.
+ ServiceLoader serviceLoader = ServiceLoader.load(JsonProvider.class,
+ JsonProvider.class.getClassLoader());
+ // Use the first provider found in the service loader iterator.
+ Iterator it = serviceLoader.iterator();
+ if (it.hasNext()) {
+ defaultProvider = it.next();
+ }
+
+ while (it.hasNext()) {
+ it.next();
+ }
+ }
+
+ private JsonProviders() {
+ // no-op
+ }
+
+ /**
+ * Creates an instance of {@link JsonReader} that reads a {@code byte[]}.
+ *
+ * If a provider could not be found on the classpath this will use the default implementation, effectively the
+ * equivalent to {@link #createReader(byte[], JsonOptions, boolean) createReader(json, new JsonOptions(), true)}.
+ *
+ * @param json The JSON represented as a {@code byte[]}.
+ * @return A new instance of {@link JsonReader}.
+ * @throws NullPointerException If {@code json} is null.
+ */
+ public static JsonReader createReader(byte[] json) {
+ return createReader(json, JsonOptions.DEFAULT_OPTIONS, true);
+ }
+
+ /**
+ * Creates an instance of {@link JsonReader} that reads a {@code byte[]}.
+ *
+ * @param json The JSON represented as a {@code byte[]}.
+ * @param options {@link JsonOptions} to configure the creation of the {@link JsonReader}.
+ * @param useDefault Whether the default implementation should be used if one could not be found on the classpath.
+ * @return A new instance of {@link JsonReader}.
+ * @throws NullPointerException If {@code json} is null.
+ * @throws IllegalStateException If a provider could not be found on the classpath and {@code useDefault} is false.
+ */
+ public static JsonReader createReader(byte[] json, JsonOptions options, boolean useDefault) {
+ if (defaultProvider == null) {
+ if (useDefault) {
+ return DefaultJsonReader.fromBytes(json, options);
+ } else {
+ throw new IllegalStateException(CANNOT_FIND_JSON);
+ }
+ } else {
+ return defaultProvider.createReader(json, options);
+ }
+ }
+
+ /**
+ * Creates an instance of {@link JsonReader} that reads a {@link String}.
+ *
+ * If a provider could not be found on the classpath this will use the default implementation, effectively the
+ * equivalent to {@link #createReader(String, JsonOptions, boolean) createReader(json, new JsonOptions(), true)}.
+ *
+ * @param json The JSON represented as a {@link String}.
+ * @return A new instance of {@link JsonReader}.
+ * @throws NullPointerException If {@code json} is null.
+ */
+ public static JsonReader createReader(String json) {
+ return createReader(json, JsonOptions.DEFAULT_OPTIONS, true);
+ }
+
+ /**
+ * Creates an instance of {@link JsonReader} that reads a {@link String}.
+ *
+ * @param json The JSON represented as a {@link String}.
+ * @param options {@link JsonOptions} to configure the creation of the {@link JsonReader}.
+ * @param useDefault Whether the default implementation should be used if one could not be found on the classpath.
+ * @return A new instance of {@link JsonReader}.
+ * @throws NullPointerException If {@code json} is null.
+ * @throws IllegalStateException If a provider could not be found on the classpath and {@code useDefault} is false.
+ */
+ public static JsonReader createReader(String json, JsonOptions options, boolean useDefault) {
+ if (defaultProvider == null) {
+ if (useDefault) {
+ return DefaultJsonReader.fromString(json, options);
+ } else {
+ throw new IllegalStateException(CANNOT_FIND_JSON);
+ }
+ } else {
+ return defaultProvider.createReader(json, options);
+ }
+ }
+
+ /**
+ * Creates an instance of {@link JsonReader} that reads a {@link InputStream}.
+ *
+ * If a provider could not be found on the classpath this will use the default implementation, effectively the
+ * equivalent to
+ * {@link #createReader(InputStream, JsonOptions, boolean) createReader(json, new JsonOptions(), true)}.
+ *
+ * @param json The JSON represented as a {@link InputStream}.
+ * @return A new instance of {@link JsonReader}.
+ * @throws NullPointerException If {@code json} is null.
+ */
+ public static JsonReader createReader(InputStream json) {
+ return createReader(json, JsonOptions.DEFAULT_OPTIONS, true);
+ }
+
+ /**
+ * Creates an instance of {@link JsonReader} that reads a {@link InputStream}.
+ *
+ * @param json The JSON represented as a {@link InputStream}.
+ * @param options {@link JsonOptions} to configure the creation of the {@link JsonReader}.
+ * @param useDefault Whether the default implementation should be used if one could not be found on the classpath.
+ * @return A new instance of {@link JsonReader}.
+ * @throws NullPointerException If {@code json} is null.
+ * @throws IllegalStateException If a provider could not be found on the classpath and {@code useDefault} is false.
+ */
+ public static JsonReader createReader(InputStream json, JsonOptions options, boolean useDefault) {
+ if (defaultProvider == null) {
+ if (useDefault) {
+ return DefaultJsonReader.fromStream(json, options);
+ } else {
+ throw new IllegalStateException(CANNOT_FIND_JSON);
+ }
+ } else {
+ return defaultProvider.createReader(json, options);
+ }
+ }
+
+ /**
+ * Creates an instance of {@link JsonReader} that reads a {@link Reader}.
+ *
+ * If a provider could not be found on the classpath this will use the default implementation, effectively the
+ * equivalent to {@link #createReader(Reader, JsonOptions, boolean) createReader(json, new JsonOptions(), true)}.
+ *
+ * @param json The JSON represented as a {@link Reader}.
+ * @return A new instance of {@link JsonReader}.
+ * @throws NullPointerException If {@code json} is null.
+ */
+ public static JsonReader createReader(Reader json) {
+ return createReader(json, JsonOptions.DEFAULT_OPTIONS, true);
+ }
+
+ /**
+ * Creates an instance of {@link JsonReader} that reads a {@link Reader}.
+ *
+ * @param json The JSON represented as a {@link Reader}.
+ * @param options {@link JsonOptions} to configure the creation of the {@link JsonReader}.
+ * @param useDefault Whether the default implementation should be used if one could not be found on the classpath.
+ * @return A new instance of {@link JsonReader}.
+ * @throws NullPointerException If {@code json} is null.
+ * @throws IllegalStateException If a provider could not be found on the classpath and {@code useDefault} is false.
+ */
+ public static JsonReader createReader(Reader json, JsonOptions options, boolean useDefault) {
+ if (defaultProvider == null) {
+ if (useDefault) {
+ return DefaultJsonReader.fromReader(json, options);
+ } else {
+ throw new IllegalStateException(CANNOT_FIND_JSON);
+ }
+ } else {
+ return defaultProvider.createReader(json, options);
+ }
+ }
+
+ /**
+ * Creates an instance of {@link JsonWriter} that writes to an {@link OutputStream}.
+ *
+ * If a provider could not be found on the classpath this will use the default implementation, effectively the
+ * equivalent to
+ * {@link #createWriter(OutputStream, JsonOptions, boolean) createWriter(json, new JsonOptions(), true)}.
+ *
+ * @param json The JSON represented as an {@link OutputStream}.
+ * @return A new instance of {@link JsonWriter}.
+ * @throws NullPointerException If {@code json} is null.
+ */
+ public static JsonWriter createWriter(OutputStream json) {
+ return createWriter(json, JsonOptions.DEFAULT_OPTIONS, true);
+ }
+
+ /**
+ * Creates an instance of {@link JsonWriter} that writes to an {@link OutputStream}.
+ *
+ * @param json The JSON represented as an {@link OutputStream}.
+ * @param options {@link JsonOptions} to configure the creation of the {@link JsonWriter}.
+ * @param useDefault Whether the default implementation should be used if one could not be found on the classpath.
+ * @return A new instance of {@link JsonWriter}.
+ * @throws NullPointerException If {@code json} is null.
+ * @throws IllegalStateException If a provider could not be found on the classpath and {@code useDefault} is false.
+ */
+ public static JsonWriter createWriter(OutputStream json, JsonOptions options, boolean useDefault) {
+ if (defaultProvider == null) {
+ if (useDefault) {
+ return DefaultJsonWriter.toStream(json, options);
+ } else {
+ throw new IllegalStateException(CANNOT_FIND_JSON);
+ }
+ } else {
+ return defaultProvider.createWriter(json, options);
+ }
+ }
+
+ /**
+ * Creates an instance of {@link JsonWriter} that writes to an {@link Writer}.
+ *
+ * If a provider could not be found on the classpath this will use the default implementation, effectively the
+ * equivalent to {@link #createWriter(Writer, JsonOptions, boolean) createWriter(json, new JsonOptions(), true)}.
+ *
+ * @param json The JSON represented as an {@link Writer}.
+ * @return A new instance of {@link JsonWriter}.
+ * @throws NullPointerException If {@code json} is null.
+ */
+ public static JsonWriter createWriter(Writer json) {
+ return createWriter(json, JsonOptions.DEFAULT_OPTIONS, true);
+ }
+
+ /**
+ * Creates an instance of {@link JsonWriter} that writes to an {@link Writer}.
+ *
+ * @param json The JSON represented as an {@link Writer}.
+ * @param options {@link JsonOptions} to configure the creation of the {@link JsonWriter}.
+ * @param useDefault Whether the default implementation should be used if one could not be found on the classpath.
+ * @return A new instance of {@link JsonWriter}.
+ * @throws NullPointerException If {@code json} is null.
+ * @throws IllegalStateException If a provider could not be found on the classpath and {@code useDefault} is false.
+ */
+ public static JsonWriter createWriter(Writer json, JsonOptions options, boolean useDefault) {
+ if (defaultProvider == null) {
+ if (useDefault) {
+ return DefaultJsonWriter.toWriter(json, options);
+ } else {
+ throw new IllegalStateException(CANNOT_FIND_JSON);
+ }
+ } else {
+ return defaultProvider.createWriter(json, options);
+ }
+ }
+}
diff --git a/sdk/core/azure-json/src/main/java/com/azure/json/JsonReader.java b/sdk/core/azure-json/src/main/java/com/azure/json/JsonReader.java
index 04b6c0adcb9c8..7edf214626f0e 100644
--- a/sdk/core/azure-json/src/main/java/com/azure/json/JsonReader.java
+++ b/sdk/core/azure-json/src/main/java/com/azure/json/JsonReader.java
@@ -491,7 +491,14 @@ private Object readUntypedHelper(int depth) {
return getBoolean();
} else if (token == JsonToken.NUMBER) {
String numberText = getText();
- if (numberText.contains(".")) {
+
+ if ("INF".equals(numberText) || "Infinity".equals(numberText)
+ || "-INF".equals(numberText) || "-Infinity".equals(numberText)
+ || "NaN".equals(numberText)) {
+ // Return special Double values as text as not all implementations of JsonReader may be able to handle
+ // them as Doubles when parsing generically.
+ return numberText;
+ } else if (numberText.contains(".")) {
// Unlike integers always use Double to prevent floating point rounding issues.
return Double.parseDouble(numberText);
} else {
diff --git a/sdk/core/azure-json/src/main/java/com/azure/json/JsonToken.java b/sdk/core/azure-json/src/main/java/com/azure/json/JsonToken.java
index f87889278f47e..f33f3594647f0 100644
--- a/sdk/core/azure-json/src/main/java/com/azure/json/JsonToken.java
+++ b/sdk/core/azure-json/src/main/java/com/azure/json/JsonToken.java
@@ -50,5 +50,10 @@ public enum JsonToken {
/**
* String, in value context.
*/
- STRING
+ STRING,
+
+ /**
+ * JSON document has completed.
+ */
+ END_DOCUMENT
}
diff --git a/sdk/core/azure-json/src/main/java/com/azure/json/DefaultJsonReader.java b/sdk/core/azure-json/src/main/java/com/azure/json/implementation/DefaultJsonReader.java
similarity index 62%
rename from sdk/core/azure-json/src/main/java/com/azure/json/DefaultJsonReader.java
rename to sdk/core/azure-json/src/main/java/com/azure/json/implementation/DefaultJsonReader.java
index f62e87e4aec36..dcc197af19dbc 100644
--- a/sdk/core/azure-json/src/main/java/com/azure/json/DefaultJsonReader.java
+++ b/sdk/core/azure-json/src/main/java/com/azure/json/implementation/DefaultJsonReader.java
@@ -1,13 +1,19 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
-package com.azure.json;
+package com.azure.json.implementation;
+import com.azure.json.JsonOptions;
+import com.azure.json.JsonReader;
+import com.azure.json.JsonToken;
+import com.azure.json.JsonWriter;
import com.azure.json.implementation.jackson.core.JsonFactory;
import com.azure.json.implementation.jackson.core.JsonParser;
+import com.azure.json.implementation.jackson.core.json.JsonReadFeature;
import java.io.IOException;
import java.io.InputStream;
+import java.io.Reader;
import java.io.UncheckedIOException;
/**
@@ -20,18 +26,22 @@ public final class DefaultJsonReader extends JsonReader {
private final byte[] jsonBytes;
private final String jsonString;
private final boolean resetSupported;
+ private final boolean nonNumericNumbersSupported;
+
+ private JsonToken currentToken;
/**
* Constructs an instance of {@link DefaultJsonReader} from a {@code byte[]}.
*
* @param json JSON {@code byte[]}.
+ * @param options {@link JsonOptions} to configure the creation of the {@link JsonReader}.
* @return An instance of {@link DefaultJsonReader}.
* @throws UncheckedIOException If a {@link DefaultJsonReader} wasn't able to be constructed from the JSON
* {@code byte[]}.
*/
- public static JsonReader fromBytes(byte[] json) {
+ public static JsonReader fromBytes(byte[] json, JsonOptions options) {
try {
- return new DefaultJsonReader(FACTORY.createParser(json), true, json, null);
+ return new DefaultJsonReader(FACTORY.createParser(json), true, json, null, options);
} catch (IOException e) {
throw new UncheckedIOException(e);
}
@@ -41,12 +51,13 @@ public static JsonReader fromBytes(byte[] json) {
* Constructs an instance of {@link DefaultJsonReader} from a String.
*
* @param json JSON String.
+ * @param options {@link JsonOptions} to configure the creation of the {@link JsonWriter}.
* @return An instance of {@link DefaultJsonReader}.
* @throws UncheckedIOException If a {@link DefaultJsonReader} wasn't able to be constructed from the JSON String.
*/
- public static JsonReader fromString(String json) {
+ public static JsonReader fromString(String json, JsonOptions options) {
try {
- return new DefaultJsonReader(FACTORY.createParser(json), true, null, json);
+ return new DefaultJsonReader(FACTORY.createParser(json), true, null, json, options);
} catch (IOException e) {
throw new UncheckedIOException(e);
}
@@ -56,34 +67,61 @@ public static JsonReader fromString(String json) {
* Constructs an instance of {@link DefaultJsonReader} from an {@link InputStream}.
*
* @param json JSON {@link InputStream}.
+ * @param options {@link JsonOptions} to configure the creation of the {@link JsonWriter}.
* @return An instance of {@link DefaultJsonReader}.
* @throws UncheckedIOException If a {@link DefaultJsonReader} wasn't able to be constructed from the JSON
* {@link InputStream}.
*/
- public static JsonReader fromStream(InputStream json) {
+ public static JsonReader fromStream(InputStream json, JsonOptions options) {
+ try {
+ return new DefaultJsonReader(FACTORY.createParser(json), json.markSupported(), null, null, options);
+ } catch (IOException e) {
+ throw new UncheckedIOException(e);
+ }
+ }
+
+ /**
+ * Constructs an instance of {@link DefaultJsonReader} from a {@link Reader}.
+ *
+ * @param reader JSON {@link Reader}.
+ * @param options {@link JsonOptions} to configure the creation of the {@link JsonWriter}.
+ * @return An instance of {@link DefaultJsonReader}.
+ * @throws UncheckedIOException If a {@link DefaultJsonReader} wasn't able to be constructed from the JSON
+ * {@link Reader}.
+ */
+ public static JsonReader fromReader(Reader reader, JsonOptions options) {
try {
- return new DefaultJsonReader(FACTORY.createParser(json), true, null, null);
+ return new DefaultJsonReader(FACTORY.createParser(reader), reader.markSupported(), null, null, options);
} catch (IOException e) {
throw new UncheckedIOException(e);
}
}
- private DefaultJsonReader(JsonParser parser, boolean resetSupported, byte[] jsonBytes, String jsonString) {
+ private DefaultJsonReader(JsonParser parser, boolean resetSupported, byte[] jsonBytes, String jsonString,
+ JsonOptions options) {
+ this(parser, resetSupported, jsonBytes, jsonString, options.isNonNumericNumbersSupported());
+ }
+
+ private DefaultJsonReader(JsonParser parser, boolean resetSupported, byte[] jsonBytes, String jsonString,
+ boolean nonNumericNumbersSupported) {
this.parser = parser;
+ this.parser.configure(JsonReadFeature.ALLOW_NON_NUMERIC_NUMBERS.mappedFeature(), nonNumericNumbersSupported);
this.resetSupported = resetSupported;
this.jsonBytes = jsonBytes;
this.jsonString = jsonString;
+ this.nonNumericNumbersSupported = nonNumericNumbersSupported;
}
@Override
public JsonToken currentToken() {
- return mapToken(parser.currentToken());
+ return currentToken;
}
@Override
public JsonToken nextToken() {
try {
- return mapToken(parser.nextToken());
+ currentToken = mapToken(parser.nextToken(), currentToken);
+ return currentToken;
} catch (IOException e) {
throw new UncheckedIOException(e);
}
@@ -181,7 +219,12 @@ public JsonReader bufferObject() {
|| (currentToken == JsonToken.FIELD_NAME && nextToken() == JsonToken.START_OBJECT)) {
StringBuilder bufferedObject = new StringBuilder();
readChildren(bufferedObject);
- return DefaultJsonReader.fromString(bufferedObject.toString());
+ String json = bufferedObject.toString();
+ try {
+ return new DefaultJsonReader(FACTORY.createParser(json), true, null, json, nonNumericNumbersSupported);
+ } catch (IOException ex) {
+ throw new UncheckedIOException(ex);
+ }
} else {
throw new IllegalStateException("Cannot buffer a JSON object from a non-object, non-field name "
+ "starting location. Starting location: " + currentToken());
@@ -199,10 +242,16 @@ public JsonReader reset() {
throw new IllegalStateException("'reset' isn't supported by this JsonReader.");
}
- if (jsonBytes != null) {
- return DefaultJsonReader.fromBytes(jsonBytes);
- } else {
- return DefaultJsonReader.fromString(jsonString);
+ try {
+ if (jsonBytes != null) {
+ return new DefaultJsonReader(FACTORY.createParser(jsonBytes), true, jsonBytes, null,
+ nonNumericNumbersSupported);
+ } else {
+ return new DefaultJsonReader(FACTORY.createParser(jsonString), true, null, jsonString,
+ nonNumericNumbersSupported);
+ }
+ } catch (IOException ex) {
+ throw new UncheckedIOException(ex);
}
}
@@ -217,30 +266,24 @@ public void close() throws IOException {
* azure-json doesn't support the EMBEDDED_OBJECT or NOT_AVAILABLE Jackson Core JsonTokens, but those should only
* be returned by specialty implementations that aren't used.
*/
- private static JsonToken mapToken(com.azure.json.implementation.jackson.core.JsonToken token) {
+ private static JsonToken mapToken(com.azure.json.implementation.jackson.core.JsonToken nextToken,
+ JsonToken currentToken) {
// Special case for when currentToken is called after instantiating the JsonReader.
- if (token == null) {
+ if (nextToken == null && currentToken == null) {
return null;
+ } else if (nextToken == null) {
+ return JsonToken.END_DOCUMENT;
}
- switch (token) {
- case START_OBJECT:
- return JsonToken.START_OBJECT;
-
- case END_OBJECT:
- return JsonToken.END_OBJECT;
-
- case START_ARRAY:
- return JsonToken.START_ARRAY;
-
- case END_ARRAY:
- return JsonToken.END_ARRAY;
+ switch (nextToken) {
+ case START_OBJECT: return JsonToken.START_OBJECT;
+ case END_OBJECT: return JsonToken.END_OBJECT;
- case FIELD_NAME:
- return JsonToken.FIELD_NAME;
+ case START_ARRAY: return JsonToken.START_ARRAY;
+ case END_ARRAY: return JsonToken.END_ARRAY;
- case VALUE_STRING:
- return JsonToken.STRING;
+ case FIELD_NAME: return JsonToken.FIELD_NAME;
+ case VALUE_STRING: return JsonToken.STRING;
case VALUE_NUMBER_INT:
case VALUE_NUMBER_FLOAT:
@@ -250,11 +293,10 @@ private static JsonToken mapToken(com.azure.json.implementation.jackson.core.Jso
case VALUE_FALSE:
return JsonToken.BOOLEAN;
- case VALUE_NULL:
- return JsonToken.NULL;
+ case VALUE_NULL: return JsonToken.NULL;
default:
- throw new IllegalStateException("Unsupported token type: '" + token + "'.");
+ throw new IllegalStateException("Unsupported token type: '" + nextToken + "'.");
}
}
}
diff --git a/sdk/core/azure-json/src/main/java/com/azure/json/DefaultJsonWriter.java b/sdk/core/azure-json/src/main/java/com/azure/json/implementation/DefaultJsonWriter.java
similarity index 82%
rename from sdk/core/azure-json/src/main/java/com/azure/json/DefaultJsonWriter.java
rename to sdk/core/azure-json/src/main/java/com/azure/json/implementation/DefaultJsonWriter.java
index e45830914ae2a..5ce38df8786a0 100644
--- a/sdk/core/azure-json/src/main/java/com/azure/json/DefaultJsonWriter.java
+++ b/sdk/core/azure-json/src/main/java/com/azure/json/implementation/DefaultJsonWriter.java
@@ -1,14 +1,20 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
-package com.azure.json;
+package com.azure.json.implementation;
+import com.azure.json.JsonOptions;
+import com.azure.json.JsonToken;
+import com.azure.json.JsonWriteContext;
+import com.azure.json.JsonWriter;
import com.azure.json.implementation.jackson.core.JsonFactory;
import com.azure.json.implementation.jackson.core.JsonGenerator;
+import com.azure.json.implementation.jackson.core.json.JsonWriteFeature;
import java.io.IOException;
import java.io.OutputStream;
import java.io.UncheckedIOException;
+import java.io.Writer;
import java.util.Objects;
/**
@@ -29,20 +35,43 @@ public final class DefaultJsonWriter extends JsonWriter {
* isn't the owner of the stream.
*
* @param stream The {@link OutputStream} that will be written.
+ * @param options {@link JsonOptions} to configure the creation of the {@link JsonWriter}.
* @return An instance of {@link DefaultJsonWriter}.
* @throws UncheckedIOException If a {@link DefaultJsonWriter} wasn't able to be constructed from the
* {@link OutputStream}.
*/
- public static JsonWriter toStream(OutputStream stream) {
+ public static JsonWriter toStream(OutputStream stream, JsonOptions options) {
try {
- return new DefaultJsonWriter(FACTORY.createGenerator(stream));
+ return new DefaultJsonWriter(FACTORY.createGenerator(stream), options);
} catch (IOException e) {
throw new UncheckedIOException(e);
}
}
- private DefaultJsonWriter(JsonGenerator generator) {
+ /**
+ * Creates a {@link DefaultJsonWriter} that writes the given {@link Writer}.
+ *
+ * The passed {@link Writer} won't be closed when {@link #close()} is called as the {@link DefaultJsonWriter}
+ * isn't the owner of the stream.
+ *
+ * @param writer The {@link Writer} that will be written.
+ * @param options {@link JsonOptions} to configure the creation of the {@link JsonWriter}.
+ * @return An instance of {@link DefaultJsonWriter}.
+ * @throws UncheckedIOException If a {@link DefaultJsonWriter} wasn't able to be constructed from the
+ * {@link Writer}.
+ */
+ public static JsonWriter toWriter(Writer writer, JsonOptions options) {
+ try {
+ return new DefaultJsonWriter(FACTORY.createGenerator(writer), options);
+ } catch (IOException e) {
+ throw new UncheckedIOException(e);
+ }
+ }
+
+ private DefaultJsonWriter(JsonGenerator generator, JsonOptions options) {
this.generator = generator;
+ this.generator.configure(JsonWriteFeature.WRITE_NAN_AS_STRINGS.mappedFeature(),
+ options.isNonNumericNumbersSupported());
}
@Override
diff --git a/sdk/core/azure-json/src/main/java/com/azure/json/implementation/package-info.java b/sdk/core/azure-json/src/main/java/com/azure/json/implementation/package-info.java
new file mode 100644
index 0000000000000..46016bb266715
--- /dev/null
+++ b/sdk/core/azure-json/src/main/java/com/azure/json/implementation/package-info.java
@@ -0,0 +1,7 @@
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT License.
+
+/**
+ * Contains general implementation classes for handling JSON.
+ */
+package com.azure.json.implementation;
diff --git a/sdk/core/azure-json/src/main/java/module-info.java b/sdk/core/azure-json/src/main/java/module-info.java
index 614f137bfebec..2ee0b1b8bac4e 100644
--- a/sdk/core/azure-json/src/main/java/module-info.java
+++ b/sdk/core/azure-json/src/main/java/module-info.java
@@ -3,4 +3,7 @@
module com.azure.json {
exports com.azure.json;
+ exports com.azure.json.implementation;
+
+ uses com.azure.json.JsonProvider;
}
diff --git a/sdk/core/azure-json/src/test/java/com/azure/json/contract/JsonReaderContractTests.java b/sdk/core/azure-json/src/test/java/com/azure/json/contract/JsonReaderContractTests.java
index 035a05cbf315d..61b968d59e6d3 100644
--- a/sdk/core/azure-json/src/test/java/com/azure/json/contract/JsonReaderContractTests.java
+++ b/sdk/core/azure-json/src/test/java/com/azure/json/contract/JsonReaderContractTests.java
@@ -13,14 +13,21 @@
import org.junit.jupiter.params.provider.Arguments;
import org.junit.jupiter.params.provider.MethodSource;
+import java.io.IOException;
import java.nio.charset.StandardCharsets;
+import java.util.ArrayList;
+import java.util.Arrays;
import java.util.Base64;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
import java.util.function.Function;
import java.util.stream.Stream;
import static org.junit.jupiter.api.Assertions.assertArrayEquals;
import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertIterableEquals;
import static org.junit.jupiter.api.Assertions.assertNull;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.jupiter.api.Assertions.assertTrue;
@@ -46,13 +53,14 @@ public abstract class JsonReaderContractTests {
@ParameterizedTest
@MethodSource("basicOperationsSupplier")
- public void basicOperations(String json, T expectedValue, Function function) {
- JsonReader reader = getJsonReader(json);
- reader.nextToken(); // Initialize the JsonReader for reading.
+ public void basicOperations(String json, T expectedValue, Function function) throws IOException {
+ try (JsonReader reader = getJsonReader(json)) {
+ reader.nextToken(); // Initialize the JsonReader for reading.
- T actualValue = assertDoesNotThrow(() -> function.apply(reader));
+ T actualValue = assertDoesNotThrow(() -> function.apply(reader));
- assertEquals(expectedValue, actualValue);
+ assertEquals(expectedValue, actualValue);
+ }
}
private static Stream basicOperationsSupplier() {
@@ -98,13 +106,14 @@ private static Stream basicOperationsSupplier() {
// Byte arrays can't use Object.equals as they'll be compared by memory location instead of value equality.
@ParameterizedTest
@MethodSource("binaryOperationsSupplier")
- public void binaryOperations(String json, byte[] expectedValue, Function function) {
- JsonReader reader = getJsonReader(json);
- reader.nextToken(); // Initialize the JsonReader for reading.
+ public void binaryOperations(String json, byte[] expectedValue, Function function) throws IOException {
+ try (JsonReader reader = getJsonReader(json)) {
+ reader.nextToken(); // Initialize the JsonReader for reading.
- byte[] actualValue = assertDoesNotThrow(() -> function.apply(reader));
+ byte[] actualValue = assertDoesNotThrow(() -> function.apply(reader));
- assertArrayEquals(expectedValue, actualValue);
+ assertArrayEquals(expectedValue, actualValue);
+ }
}
private static Stream binaryOperationsSupplier() {
@@ -118,137 +127,142 @@ private static Stream binaryOperationsSupplier() {
}
@Test
- public void emptyObject() {
+ public void emptyObject() throws IOException {
String json = "{}";
- JsonReader reader = getJsonReader(json);
+ try (JsonReader reader = getJsonReader(json)) {
- assertJsonReaderStructInitialization(reader, JsonToken.START_OBJECT);
+ assertJsonReaderStructInitialization(reader, JsonToken.START_OBJECT);
- while (reader.nextToken() != JsonToken.END_OBJECT) {
- fail("Empty object shouldn't have any non-END_OBJECT JsonTokens but found: " + reader.currentToken());
+ while (reader.nextToken() != JsonToken.END_OBJECT) {
+ fail("Empty object shouldn't have any non-END_OBJECT JsonTokens but found: " + reader.currentToken());
+ }
}
}
@Test
- public void emptyArray() {
+ public void emptyArray() throws IOException {
String json = "[]";
- JsonReader reader = getJsonReader(json);
+ try (JsonReader reader = getJsonReader(json)) {
- assertJsonReaderStructInitialization(reader, JsonToken.START_ARRAY);
+ assertJsonReaderStructInitialization(reader, JsonToken.START_ARRAY);
- while (reader.nextToken() != JsonToken.END_ARRAY) {
- fail("Empty array shouldn't have any non-END_ARRAY JsonTokens but found: " + reader.currentToken());
+ while (reader.nextToken() != JsonToken.END_ARRAY) {
+ fail("Empty array shouldn't have any non-END_ARRAY JsonTokens but found: " + reader.currentToken());
+ }
}
}
@Test
- public void simpleObject() {
+ public void simpleObject() throws IOException {
String json = "{\"stringProperty\":\"string\",\"nullProperty\":null,\"integerProperty\":10,\"floatProperty\":10.0,\"booleanProperty\":true}";
- JsonReader reader = getJsonReader(json);
-
- assertJsonReaderStructInitialization(reader, JsonToken.START_OBJECT);
-
- String stringProperty = null;
- boolean hasNullProperty = false;
- int integerProperty = 0;
- float floatProperty = 0.0F;
- boolean booleanProperty = false;
- while (reader.nextToken() != JsonToken.END_OBJECT) {
- String fieldName = reader.getFieldName();
- reader.nextToken();
-
- if ("stringProperty".equals(fieldName)) {
- stringProperty = reader.getString();
- } else if ("nullProperty".equals(fieldName)) {
- hasNullProperty = true;
- } else if ("integerProperty".equals(fieldName)) {
- integerProperty = reader.getInt();
- } else if ("floatProperty".equals(fieldName)) {
- floatProperty = reader.getFloat();
- } else if ("booleanProperty".equals(fieldName)) {
- booleanProperty = reader.getBoolean();
- } else {
- fail("Unknown property name: '" + fieldName + "'");
+ try (JsonReader reader = getJsonReader(json)) {
+
+ assertJsonReaderStructInitialization(reader, JsonToken.START_OBJECT);
+
+ String stringProperty = null;
+ boolean hasNullProperty = false;
+ int integerProperty = 0;
+ float floatProperty = 0.0F;
+ boolean booleanProperty = false;
+ while (reader.nextToken() != JsonToken.END_OBJECT) {
+ String fieldName = reader.getFieldName();
+ reader.nextToken();
+
+ if ("stringProperty".equals(fieldName)) {
+ stringProperty = reader.getString();
+ } else if ("nullProperty".equals(fieldName)) {
+ hasNullProperty = true;
+ } else if ("integerProperty".equals(fieldName)) {
+ integerProperty = reader.getInt();
+ } else if ("floatProperty".equals(fieldName)) {
+ floatProperty = reader.getFloat();
+ } else if ("booleanProperty".equals(fieldName)) {
+ booleanProperty = reader.getBoolean();
+ } else {
+ fail("Unknown property name: '" + fieldName + "'");
+ }
}
- }
- assertEquals("string", stringProperty);
- assertTrue(hasNullProperty, "Didn't find the expected 'nullProperty'.");
- assertEquals(10, integerProperty);
- assertEquals(10.0F, floatProperty);
- assertEquals(true, booleanProperty);
+ assertEquals("string", stringProperty);
+ assertTrue(hasNullProperty, "Didn't find the expected 'nullProperty'.");
+ assertEquals(10, integerProperty);
+ assertEquals(10.0F, floatProperty);
+ assertEquals(true, booleanProperty);
+ }
}
@Test
- public void arrayOfBasicTypesInJsonRoot() {
+ public void arrayOfBasicTypesInJsonRoot() throws IOException {
String json = "[\"string\",null,10,10.0,true]";
- JsonReader reader = getJsonReader(json);
+ try (JsonReader reader = getJsonReader(json)) {
- assertJsonReaderStructInitialization(reader, JsonToken.START_ARRAY);
+ assertJsonReaderStructInitialization(reader, JsonToken.START_ARRAY);
- Object[] jsonArray = new Object[5];
- int jsonArrayIndex = 0;
- while (reader.nextToken() != JsonToken.END_ARRAY) {
- jsonArray[jsonArrayIndex++] = ContractUtils.readUntypedField(reader);
- }
+ Object[] jsonArray = new Object[5];
+ int jsonArrayIndex = 0;
+ while (reader.nextToken() != JsonToken.END_ARRAY) {
+ jsonArray[jsonArrayIndex++] = ContractUtils.readUntypedField(reader);
+ }
- assertEquals("string", jsonArray[0]);
- assertNull(jsonArray[1]);
- assertEquals(10, jsonArray[2]);
- assertEquals(10.0F, jsonArray[3]);
- assertEquals(true, jsonArray[4]);
+ assertEquals("string", jsonArray[0]);
+ assertNull(jsonArray[1]);
+ assertEquals(10, jsonArray[2]);
+ assertEquals(10.0F, jsonArray[3]);
+ assertEquals(true, jsonArray[4]);
+ }
}
@ParameterizedTest
@MethodSource("objectWithInnerObjectSupplier")
- public void objectWithInnerObject(String json) {
- JsonReader reader = getJsonReader(json);
-
- assertJsonReaderStructInitialization(reader, JsonToken.START_OBJECT);
-
- String stringProperty = null;
- boolean hasNullProperty = false;
- int integerProperty = 0;
- float floatProperty = 0.0F;
- boolean booleanProperty = false;
- String innerStringProperty = null;
- while (reader.nextToken() != JsonToken.END_OBJECT) {
- String fieldName = reader.getFieldName();
- reader.nextToken();
-
- if ("stringProperty".equals(fieldName)) {
- stringProperty = reader.getString();
- } else if ("nullProperty".equals(fieldName)) {
- hasNullProperty = true;
- } else if ("integerProperty".equals(fieldName)) {
- integerProperty = reader.getInt();
- } else if ("floatProperty".equals(fieldName)) {
- floatProperty = reader.getFloat();
- } else if ("booleanProperty".equals(fieldName)) {
- booleanProperty = reader.getBoolean();
- } else if ("innerObject".equals(fieldName)) {
- assertEquals(JsonToken.START_OBJECT, reader.currentToken());
- while (reader.nextToken() != JsonToken.END_OBJECT) {
- fieldName = reader.getFieldName();
- reader.nextToken();
-
- if ("innerStringProperty".equals(fieldName)) {
- innerStringProperty = reader.getString();
- } else {
- fail("Unknown property name: '" + fieldName + "'");
+ public void objectWithInnerObject(String json) throws IOException {
+ try (JsonReader reader = getJsonReader(json)) {
+
+ assertJsonReaderStructInitialization(reader, JsonToken.START_OBJECT);
+
+ String stringProperty = null;
+ boolean hasNullProperty = false;
+ int integerProperty = 0;
+ float floatProperty = 0.0F;
+ boolean booleanProperty = false;
+ String innerStringProperty = null;
+ while (reader.nextToken() != JsonToken.END_OBJECT) {
+ String fieldName = reader.getFieldName();
+ reader.nextToken();
+
+ if ("stringProperty".equals(fieldName)) {
+ stringProperty = reader.getString();
+ } else if ("nullProperty".equals(fieldName)) {
+ hasNullProperty = true;
+ } else if ("integerProperty".equals(fieldName)) {
+ integerProperty = reader.getInt();
+ } else if ("floatProperty".equals(fieldName)) {
+ floatProperty = reader.getFloat();
+ } else if ("booleanProperty".equals(fieldName)) {
+ booleanProperty = reader.getBoolean();
+ } else if ("innerObject".equals(fieldName)) {
+ assertEquals(JsonToken.START_OBJECT, reader.currentToken());
+ while (reader.nextToken() != JsonToken.END_OBJECT) {
+ fieldName = reader.getFieldName();
+ reader.nextToken();
+
+ if ("innerStringProperty".equals(fieldName)) {
+ innerStringProperty = reader.getString();
+ } else {
+ fail("Unknown property name: '" + fieldName + "'");
+ }
}
+ } else {
+ fail("Unknown property name: '" + fieldName + "'");
}
- } else {
- fail("Unknown property name: '" + fieldName + "'");
}
- }
- assertEquals("string", stringProperty);
- assertTrue(hasNullProperty, "Didn't find the expected 'nullProperty'.");
- assertEquals(10, integerProperty);
- assertEquals(10.0F, floatProperty);
- assertEquals(true, booleanProperty);
- assertEquals("innerString", innerStringProperty);
+ assertEquals("string", stringProperty);
+ assertTrue(hasNullProperty, "Didn't find the expected 'nullProperty'.");
+ assertEquals(10, integerProperty);
+ assertEquals(10.0F, floatProperty);
+ assertEquals(true, booleanProperty);
+ assertEquals("innerString", innerStringProperty);
+ }
}
private static Stream objectWithInnerObjectSupplier() {
@@ -270,50 +284,51 @@ private static Stream objectWithInnerObjectSupplier() {
@ParameterizedTest
@MethodSource("objectWithInnerArraySupplier")
- public void objectWithInnerArray(String json) {
- JsonReader reader = getJsonReader(json);
-
- assertJsonReaderStructInitialization(reader, JsonToken.START_OBJECT);
-
- String stringProperty = null;
- boolean hasNullProperty = false;
- int integerProperty = 0;
- float floatProperty = 0.0F;
- boolean booleanProperty = false;
- String innerStringProperty = null;
- while (reader.nextToken() != JsonToken.END_OBJECT) {
- String fieldName = reader.getFieldName();
- reader.nextToken();
-
- if ("stringProperty".equals(fieldName)) {
- stringProperty = reader.getString();
- } else if ("nullProperty".equals(fieldName)) {
- hasNullProperty = true;
- } else if ("integerProperty".equals(fieldName)) {
- integerProperty = reader.getInt();
- } else if ("floatProperty".equals(fieldName)) {
- floatProperty = reader.getFloat();
- } else if ("booleanProperty".equals(fieldName)) {
- booleanProperty = reader.getBoolean();
- } else if ("innerArray".equals(fieldName)) {
- assertEquals(JsonToken.START_ARRAY, reader.currentToken());
- while (reader.nextToken() != JsonToken.END_ARRAY) {
- if (innerStringProperty != null) {
- fail("Only expected one value in the inner array but found more.");
+ public void objectWithInnerArray(String json) throws IOException {
+ try (JsonReader reader = getJsonReader(json)) {
+
+ assertJsonReaderStructInitialization(reader, JsonToken.START_OBJECT);
+
+ String stringProperty = null;
+ boolean hasNullProperty = false;
+ int integerProperty = 0;
+ float floatProperty = 0.0F;
+ boolean booleanProperty = false;
+ String innerStringProperty = null;
+ while (reader.nextToken() != JsonToken.END_OBJECT) {
+ String fieldName = reader.getFieldName();
+ reader.nextToken();
+
+ if ("stringProperty".equals(fieldName)) {
+ stringProperty = reader.getString();
+ } else if ("nullProperty".equals(fieldName)) {
+ hasNullProperty = true;
+ } else if ("integerProperty".equals(fieldName)) {
+ integerProperty = reader.getInt();
+ } else if ("floatProperty".equals(fieldName)) {
+ floatProperty = reader.getFloat();
+ } else if ("booleanProperty".equals(fieldName)) {
+ booleanProperty = reader.getBoolean();
+ } else if ("innerArray".equals(fieldName)) {
+ assertEquals(JsonToken.START_ARRAY, reader.currentToken());
+ while (reader.nextToken() != JsonToken.END_ARRAY) {
+ if (innerStringProperty != null) {
+ fail("Only expected one value in the inner array but found more.");
+ }
+ innerStringProperty = reader.getString();
}
- innerStringProperty = reader.getString();
+ } else {
+ fail("Unknown property name: '" + fieldName + "'");
}
- } else {
- fail("Unknown property name: '" + fieldName + "'");
}
- }
- assertEquals("string", stringProperty);
- assertTrue(hasNullProperty, "Didn't find the expected 'nullProperty'.");
- assertEquals(10, integerProperty);
- assertEquals(10.0F, floatProperty);
- assertEquals(true, booleanProperty);
- assertEquals("innerString", innerStringProperty);
+ assertEquals("string", stringProperty);
+ assertTrue(hasNullProperty, "Didn't find the expected 'nullProperty'.");
+ assertEquals(10, integerProperty);
+ assertEquals(10.0F, floatProperty);
+ assertEquals(true, booleanProperty);
+ assertEquals("innerString", innerStringProperty);
+ }
}
private static Stream objectWithInnerArraySupplier() {
@@ -334,33 +349,34 @@ private static Stream objectWithInnerArraySupplier() {
@ParameterizedTest
@MethodSource("arrayWithInnerArraySupplier")
- public void arrayWithInnerArray(String json) {
- JsonReader reader = getJsonReader(json);
+ public void arrayWithInnerArray(String json) throws IOException {
+ try (JsonReader reader = getJsonReader(json)) {
- assertJsonReaderStructInitialization(reader, JsonToken.START_ARRAY);
+ assertJsonReaderStructInitialization(reader, JsonToken.START_ARRAY);
- Object[] jsonArray = new Object[6];
- int jsonArrayIndex = 0;
- while (reader.nextToken() != JsonToken.END_ARRAY) {
- if (reader.currentToken() == JsonToken.START_ARRAY) {
- while (reader.nextToken() != JsonToken.END_ARRAY) {
- if (jsonArray[5] != null) {
- fail("Only expected one value in the inner array but found more.");
- }
+ Object[] jsonArray = new Object[6];
+ int jsonArrayIndex = 0;
+ while (reader.nextToken() != JsonToken.END_ARRAY) {
+ if (reader.currentToken() == JsonToken.START_ARRAY) {
+ while (reader.nextToken() != JsonToken.END_ARRAY) {
+ if (jsonArray[5] != null) {
+ fail("Only expected one value in the inner array but found more.");
+ }
- jsonArray[5] = reader.getString();
+ jsonArray[5] = reader.getString();
+ }
+ } else {
+ jsonArray[jsonArrayIndex++] = ContractUtils.readUntypedField(reader);
}
- } else {
- jsonArray[jsonArrayIndex++] = ContractUtils.readUntypedField(reader);
}
- }
- assertEquals("string", jsonArray[0]);
- assertNull(jsonArray[1]);
- assertEquals(10, jsonArray[2]);
- assertEquals(10.0F, jsonArray[3]);
- assertEquals(true, jsonArray[4]);
- assertEquals("innerString", jsonArray[5]);
+ assertEquals("string", jsonArray[0]);
+ assertNull(jsonArray[1]);
+ assertEquals(10, jsonArray[2]);
+ assertEquals(10.0F, jsonArray[3]);
+ assertEquals(true, jsonArray[4]);
+ assertEquals("innerString", jsonArray[5]);
+ }
}
private static Stream arrayWithInnerArraySupplier() {
@@ -378,36 +394,37 @@ private static Stream arrayWithInnerArraySupplier() {
@ParameterizedTest
@MethodSource("arrayWithInnerObjectSupplier")
- public void arrayWithInnerObject(String json) {
- JsonReader reader = getJsonReader(json);
-
- assertJsonReaderStructInitialization(reader, JsonToken.START_ARRAY);
-
- Object[] jsonArray = new Object[6];
- int jsonArrayIndex = 0;
- while (reader.nextToken() != JsonToken.END_ARRAY) {
- if (reader.currentToken() == JsonToken.START_OBJECT) {
- while (reader.nextToken() != JsonToken.END_OBJECT) {
- String fieldName = reader.getFieldName();
- reader.nextToken();
-
- if ("innerStringProperty".equals(fieldName)) {
- jsonArray[5] = reader.getString();
- } else {
- fail("Unknown property name: '" + fieldName + "'");
+ public void arrayWithInnerObject(String json) throws IOException {
+ try (JsonReader reader = getJsonReader(json)) {
+
+ assertJsonReaderStructInitialization(reader, JsonToken.START_ARRAY);
+
+ Object[] jsonArray = new Object[6];
+ int jsonArrayIndex = 0;
+ while (reader.nextToken() != JsonToken.END_ARRAY) {
+ if (reader.currentToken() == JsonToken.START_OBJECT) {
+ while (reader.nextToken() != JsonToken.END_OBJECT) {
+ String fieldName = reader.getFieldName();
+ reader.nextToken();
+
+ if ("innerStringProperty".equals(fieldName)) {
+ jsonArray[5] = reader.getString();
+ } else {
+ fail("Unknown property name: '" + fieldName + "'");
+ }
}
+ } else {
+ jsonArray[jsonArrayIndex++] = ContractUtils.readUntypedField(reader);
}
- } else {
- jsonArray[jsonArrayIndex++] = ContractUtils.readUntypedField(reader);
}
- }
- assertEquals("string", jsonArray[0]);
- assertNull(jsonArray[1]);
- assertEquals(10, jsonArray[2]);
- assertEquals(10.0F, jsonArray[3]);
- assertEquals(true, jsonArray[4]);
- assertEquals("innerString", jsonArray[5]);
+ assertEquals("string", jsonArray[0]);
+ assertNull(jsonArray[1]);
+ assertEquals(10, jsonArray[2]);
+ assertEquals(10.0F, jsonArray[3]);
+ assertEquals(true, jsonArray[4]);
+ assertEquals("innerString", jsonArray[5]);
+ }
}
private static Stream arrayWithInnerObjectSupplier() {
@@ -423,6 +440,129 @@ private static Stream arrayWithInnerObjectSupplier() {
);
}
+ @ParameterizedTest
+ @MethodSource("readUntypedSimpleSupplier")
+ public void readUntypedSimple(String json, int nextCount, Object expected) throws IOException {
+ try (JsonReader reader = getJsonReader(json)) {
+ for (int i = 0; i < nextCount; i++) {
+ reader.nextToken();
+ }
+
+ Object actual = reader.readUntyped();
+ assertEquals(expected, actual);
+ }
+
+ }
+
+ private static Stream readUntypedSimpleSupplier() {
+ return Stream.of(
+ Arguments.of("null", 1, null),
+ Arguments.of("true", 1, true),
+ Arguments.of("false", 1, false),
+ Arguments.of("3.14", 1, 3.14),
+ Arguments.of("NaN", 1, String.valueOf(Double.NaN)),
+ Arguments.of("-Infinity", 1, String.valueOf(Double.NEGATIVE_INFINITY)),
+ Arguments.of("Infinity", 1, String.valueOf(Double.POSITIVE_INFINITY)),
+ Arguments.of("42", 1, 42),
+ Arguments.of("420000000000", 1, 420000000000L),
+ Arguments.of("\"hello\"", 1, "hello")
+ );
+ }
+
+ @SuppressWarnings("unchecked")
+ @ParameterizedTest
+ @MethodSource("readUntypedArraySupplier")
+ public void readUntypedArray(String json, int nextCount, List expected) throws IOException {
+ try (JsonReader reader = getJsonReader(json)) {
+ for (int i = 0; i < nextCount; i++) {
+ reader.nextToken();
+ }
+
+ List actual = (List) reader.readUntyped();
+ assertIterableEquals(expected, actual);
+ }
+
+ }
+
+ private static Stream readUntypedArraySupplier() {
+ return Stream.of(
+ Arguments.of("[]", 1, new ArrayList<>()),
+ Arguments.of("[42,true,\"hello\"]", 1, Arrays.asList(42, true, "hello"))
+ );
+ }
+
+ @SuppressWarnings("unchecked")
+ @ParameterizedTest
+ @MethodSource("readUntypedObjectSupplier")
+ public void readUntypedObject(String json, int nextCount, Map expected) throws IOException {
+ try (JsonReader reader = getJsonReader(json)) {
+ for (int i = 0; i < nextCount; i++) {
+ reader.nextToken();
+ }
+
+ Map actual = (Map) reader.readUntyped();
+ assertEquals(expected.size(), actual.size());
+ for (Map.Entry expectedKvp : expected.entrySet()) {
+ assertTrue(actual.containsKey(expectedKvp.getKey()));
+ assertEquals(expectedKvp.getValue(), actual.get(expectedKvp.getKey()));
+ }
+ }
+ }
+
+ private static Stream readUntypedObjectSupplier() {
+ Map complexExpected = new LinkedHashMap<>();
+ complexExpected.put("field1", 42);
+ complexExpected.put("field2", true);
+ complexExpected.put("field3", "hello");
+
+ return Stream.of(
+ Arguments.of("{}", 1, new LinkedHashMap<>()),
+ Arguments.of("{\"field1\":42,\"field2\":true,\"field3\":\"hello\"}", 1, complexExpected)
+ );
+ }
+
+ @ParameterizedTest
+ @MethodSource("readUntypedIllegalStartSupplier")
+ public void readUntypedIllegalStart(String json, int nextCount) throws IOException {
+ try (JsonReader reader = getJsonReader(json)) {
+ for (int i = 0; i < nextCount; i++) {
+ reader.nextToken();
+ }
+
+ assertThrows(IllegalStateException.class, reader::readUntyped);
+ }
+ }
+
+ private static Stream readUntypedIllegalStartSupplier() {
+ return Stream.of(
+ Arguments.of("{}", 2),
+ Arguments.of("[]", 2),
+ Arguments.of("{\"field\":\"value\"}", 2)
+ );
+ }
+
+ @Test
+ public void readUntypedPreventsStackOverflow() throws IOException {
+ // At 1000 levels of nesting readUntyped will throw an exception.
+ StringBuilder builder = new StringBuilder();
+ for (int i = 0; i < 1001; i++) {
+ builder.append("{\"field\":");
+ }
+
+ builder.append("null");
+
+ for (int i = 0; i < 1001; i++) {
+ builder.append('}');
+ }
+
+ String deeplyNestJson = builder.toString();
+
+ try (JsonReader reader = getJsonReader(deeplyNestJson)) {
+ reader.nextToken();
+ assertThrows(IllegalStateException.class, reader::readUntyped);
+ }
+ }
+
@ParameterizedTest
@MethodSource("bufferObjectSupplier")
public void bufferObject(String json, int nextCount) {
diff --git a/sdk/core/azure-json/src/test/java/com/azure/json/DefaultJsonReaderContractTests.java b/sdk/core/azure-json/src/test/java/com/azure/json/implementation/DefaultJsonReaderContractTests.java
similarity index 69%
rename from sdk/core/azure-json/src/test/java/com/azure/json/DefaultJsonReaderContractTests.java
rename to sdk/core/azure-json/src/test/java/com/azure/json/implementation/DefaultJsonReaderContractTests.java
index 7a957a2cc1301..171ac70a956a2 100644
--- a/sdk/core/azure-json/src/test/java/com/azure/json/DefaultJsonReaderContractTests.java
+++ b/sdk/core/azure-json/src/test/java/com/azure/json/implementation/DefaultJsonReaderContractTests.java
@@ -1,8 +1,10 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
-package com.azure.json;
+package com.azure.json.implementation;
+import com.azure.json.JsonOptions;
+import com.azure.json.JsonReader;
import com.azure.json.contract.JsonReaderContractTests;
/**
@@ -11,6 +13,6 @@
public class DefaultJsonReaderContractTests extends JsonReaderContractTests {
@Override
public JsonReader getJsonReader(String json) {
- return DefaultJsonReader.fromString(json);
+ return DefaultJsonReader.fromString(json, new JsonOptions());
}
}
diff --git a/sdk/core/azure-json/src/test/java/com/azure/json/DefaultJsonWriterContractTests.java b/sdk/core/azure-json/src/test/java/com/azure/json/implementation/DefaultJsonWriterContractTests.java
similarity index 84%
rename from sdk/core/azure-json/src/test/java/com/azure/json/DefaultJsonWriterContractTests.java
rename to sdk/core/azure-json/src/test/java/com/azure/json/implementation/DefaultJsonWriterContractTests.java
index 1c69d7f352a63..c1117545c5f69 100644
--- a/sdk/core/azure-json/src/test/java/com/azure/json/DefaultJsonWriterContractTests.java
+++ b/sdk/core/azure-json/src/test/java/com/azure/json/implementation/DefaultJsonWriterContractTests.java
@@ -1,8 +1,10 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
-package com.azure.json;
+package com.azure.json.implementation;
+import com.azure.json.JsonOptions;
+import com.azure.json.JsonWriter;
import com.azure.json.contract.JsonWriterContractTests;
import org.junit.jupiter.api.BeforeEach;
@@ -20,7 +22,7 @@ public class DefaultJsonWriterContractTests extends JsonWriterContractTests {
@BeforeEach
public void beforeEach() {
this.outputStream = new ByteArrayOutputStream();
- this.writer = DefaultJsonWriter.toStream(outputStream);
+ this.writer = DefaultJsonWriter.toStream(outputStream, new JsonOptions());
}
@Override
diff --git a/sdk/core/azure-xml/src/main/java/com/azure/xml/XmlProvider.java b/sdk/core/azure-xml/src/main/java/com/azure/xml/XmlProvider.java
new file mode 100644
index 0000000000000..79c40e12b6f61
--- /dev/null
+++ b/sdk/core/azure-xml/src/main/java/com/azure/xml/XmlProvider.java
@@ -0,0 +1,69 @@
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT License.
+
+package com.azure.xml;
+
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.Reader;
+import java.io.Writer;
+
+/**
+ * An interface to be implemented by any azure-xml plugin that wishes to provide an alternate {@link XmlReader} or
+ * {@link XmlWriter} implementation.
+ */
+public interface XmlProvider {
+ /**
+ * Creates an instance of {@link XmlReader} that reads a {@code byte[]}.
+ *
+ * @param json The JSON represented as a {@code byte[]}.
+ * @return A new instance of {@link XmlReader}.
+ * @throws NullPointerException If {@code json} is null.
+ */
+ XmlReader createReader(byte[] json);
+
+ /**
+ * Creates an instance of {@link XmlReader} that reads a {@link String}.
+ *
+ * @param json The JSON represented as a {@link String}.
+ * @return A new instance of {@link XmlReader}.
+ * @throws NullPointerException If {@code json} is null.
+ */
+ XmlReader createReader(String json);
+
+ /**
+ * Creates an instance of {@link XmlReader} that reads a {@link InputStream}.
+ *
+ * @param json The JSON represented as a {@link InputStream}.
+ * @return A new instance of {@link XmlReader}.
+ * @throws NullPointerException If {@code json} is null.
+ */
+ XmlReader createReader(InputStream json);
+
+ /**
+ * Creates an instance of {@link XmlReader} that reads a {@link Reader}.
+ *
+ * @param json The JSON represented as a {@link Reader}.
+ * @return A new instance of {@link XmlReader}.
+ * @throws NullPointerException If {@code json} is null.
+ */
+ XmlReader createReader(Reader json);
+
+ /**
+ * Creates an instance of {@link XmlWriter} that writes to an {@link OutputStream}.
+ *
+ * @param json The JSON represented as an {@link OutputStream}.
+ * @return A new instance of {@link XmlWriter}.
+ * @throws NullPointerException If {@code json} is null.
+ */
+ XmlWriter createWriter(OutputStream json);
+
+ /**
+ * Creates an instance of {@link XmlWriter} that writes to an {@link Writer}.
+ *
+ * @param json The JSON represented as an {@link Writer}.
+ * @return A new instance of {@link XmlWriter}.
+ * @throws NullPointerException If {@code json} is null.
+ */
+ XmlWriter createWriter(Writer json);
+}
diff --git a/sdk/core/azure-xml/src/main/java/com/azure/xml/XmlProviders.java b/sdk/core/azure-xml/src/main/java/com/azure/xml/XmlProviders.java
new file mode 100644
index 0000000000000..243be901851f0
--- /dev/null
+++ b/sdk/core/azure-xml/src/main/java/com/azure/xml/XmlProviders.java
@@ -0,0 +1,260 @@
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT License.
+
+package com.azure.xml;
+
+import com.azure.xml.implementation.DefaultXmlReader;
+import com.azure.xml.implementation.DefaultXmlWriter;
+
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.Reader;
+import java.io.Writer;
+import java.util.Iterator;
+import java.util.ServiceLoader;
+
+/**
+ * Handles loading an instance of {@link XmlProvider} found on the classpath.
+ */
+public final class XmlProviders {
+ private static final String CANNOT_FIND_XML = "A request was made to load an XmlReader and XmlWriter provider "
+ + "but one could not be found on the classpath. If you are using a dependency manager, consider including a "
+ + "dependency that supplies a provider for XmlProvider or indicate to the loader to fallback to the default "
+ + "implementation. Additionally, refer to https://aka.ms/azsdk/java/docs/custom-xml to learn about writing "
+ + "your own implementation.";
+
+ private static XmlProvider defaultProvider;
+
+ static {
+ // Use as classloader to load provider-configuration files and provider classes the classloader
+ // that loaded this class. In most cases this will be the System classloader.
+ // But this choice here provides additional flexibility in managed environments that control
+ // classloading differently (OSGi, Spring and others) and don't/ depend on the
+ // System classloader to load HttpClientProvider classes.
+ ServiceLoader serviceLoader = ServiceLoader.load(XmlProvider.class,
+ XmlProvider.class.getClassLoader());
+ // Use the first provider found in the service loader iterator.
+ Iterator it = serviceLoader.iterator();
+ if (it.hasNext()) {
+ defaultProvider = it.next();
+ }
+
+ while (it.hasNext()) {
+ it.next();
+ }
+ }
+
+ private XmlProviders() {
+ // no-op
+ }
+
+ /**
+ * Creates an instance of {@link XmlReader} that reads a {@code byte[]}.
+ *
+ * If a provider could not be found on the classpath this will use the default implementation, effectively the
+ * equivalent to {@link #createReader(byte[], boolean) createReader(xml, true)}.
+ *
+ * @param xml The XML represented as a {@code byte[]}.
+ * @return A new instance of {@link XmlReader}.
+ * @throws NullPointerException If {@code xml} is null.
+ */
+ public static XmlReader createReader(byte[] xml) {
+ return createReader(xml, true);
+ }
+
+ /**
+ * Creates an instance of {@link XmlReader} that reads a {@code byte[]}.
+ *
+ * @param xml The XML represented as a {@code byte[]}.
+ * @param useDefault Whether the default implementation should be used if one could not be found on the classpath.
+ * @return A new instance of {@link XmlReader}.
+ * @throws NullPointerException If {@code xml} is null.
+ * @throws IllegalStateException If a provider could not be found on the classpath and {@code useDefault} is false.
+ */
+ public static XmlReader createReader(byte[] xml, boolean useDefault) {
+ if (defaultProvider == null) {
+ if (useDefault) {
+ return DefaultXmlReader.fromBytes(xml);
+ } else {
+ throw new IllegalStateException(CANNOT_FIND_XML);
+ }
+ } else {
+ return defaultProvider.createReader(xml);
+ }
+ }
+
+ /**
+ * Creates an instance of {@link XmlReader} that reads a {@link String}.
+ *
+ * If a provider could not be found on the classpath this will use the default implementation, effectively the
+ * equivalent to {@link #createReader(String, boolean) createReader(xml, true)}.
+ *
+ * @param xml The XML represented as a {@link String}.
+ * @return A new instance of {@link XmlReader}.
+ * @throws NullPointerException If {@code xml} is null.
+ */
+ public static XmlReader createReader(String xml) {
+ return createReader(xml, true);
+ }
+
+ /**
+ * Creates an instance of {@link XmlReader} that reads a {@link String}.
+ *
+ * @param xml The XML represented as a {@link String}.
+ * @param useDefault Whether the default implementation should be used if one could not be found on the classpath.
+ * @return A new instance of {@link XmlReader}.
+ * @throws NullPointerException If {@code xml} is null.
+ * @throws IllegalStateException If a provider could not be found on the classpath and {@code useDefault} is false.
+ */
+ public static XmlReader createReader(String xml, boolean useDefault) {
+ if (defaultProvider == null) {
+ if (useDefault) {
+ return DefaultXmlReader.fromString(xml);
+ } else {
+ throw new IllegalStateException(CANNOT_FIND_XML);
+ }
+ } else {
+ return defaultProvider.createReader(xml);
+ }
+ }
+
+ /**
+ * Creates an instance of {@link XmlReader} that reads a {@link InputStream}.
+ *
+ * If a provider could not be found on the classpath this will use the default implementation, effectively the
+ * equivalent to {@link #createReader(InputStream, boolean) createReader(xml, true)}.
+ *
+ * @param xml The XML represented as a {@link InputStream}.
+ * @return A new instance of {@link XmlReader}.
+ * @throws NullPointerException If {@code xml} is null.
+ */
+ public static XmlReader createReader(InputStream xml) {
+ return createReader(xml, true);
+ }
+
+ /**
+ * Creates an instance of {@link XmlReader} that reads a {@link InputStream}.
+ *
+ * @param xml The XML represented as a {@link InputStream}.
+ * @param useDefault Whether the default implementation should be used if one could not be found on the classpath.
+ * @return A new instance of {@link XmlReader}.
+ * @throws NullPointerException If {@code xml} is null.
+ * @throws IllegalStateException If a provider could not be found on the classpath and {@code useDefault} is false.
+ */
+ public static XmlReader createReader(InputStream xml, boolean useDefault) {
+ if (defaultProvider == null) {
+ if (useDefault) {
+ return DefaultXmlReader.fromStream(xml);
+ } else {
+ throw new IllegalStateException(CANNOT_FIND_XML);
+ }
+ } else {
+ return defaultProvider.createReader(xml);
+ }
+ }
+
+ /**
+ * Creates an instance of {@link XmlReader} that reads a {@link Reader}.
+ *
+ * If a provider could not be found on the classpath this will use the default implementation, effectively the
+ * equivalent to {@link #createReader(Reader, boolean) createReader(xml, true)}.
+ *
+ * @param xml The XML represented as a {@link Reader}.
+ * @return A new instance of {@link XmlReader}.
+ * @throws NullPointerException If {@code xml} is null.
+ */
+ public static XmlReader createReader(Reader xml) {
+ return createReader(xml, true);
+ }
+
+ /**
+ * Creates an instance of {@link XmlReader} that reads a {@link Reader}.
+ *
+ * @param xml The XML represented as a {@link Reader}.
+ * @param useDefault Whether the default implementation should be used if one could not be found on the classpath.
+ * @return A new instance of {@link XmlReader}.
+ * @throws NullPointerException If {@code xml} is null.
+ * @throws IllegalStateException If a provider could not be found on the classpath and {@code useDefault} is false.
+ */
+ public static XmlReader createReader(Reader xml, boolean useDefault) {
+ if (defaultProvider == null) {
+ if (useDefault) {
+ return DefaultXmlReader.fromReader(xml);
+ } else {
+ throw new IllegalStateException(CANNOT_FIND_XML);
+ }
+ } else {
+ return defaultProvider.createReader(xml);
+ }
+ }
+
+ /**
+ * Creates an instance of {@link XmlWriter} that writes to an {@link OutputStream}.
+ *
+ * If a provider could not be found on the classpath this will use the default implementation, effectively the
+ * equivalent to {@link #createWriter(OutputStream, boolean) createWriter(xml, true)}.
+ *
+ * @param xml The XML represented as an {@link OutputStream}.
+ * @return A new instance of {@link XmlWriter}.
+ * @throws NullPointerException If {@code xml} is null.
+ */
+ public static XmlWriter createWriter(OutputStream xml) {
+ return createWriter(xml, true);
+ }
+
+ /**
+ * Creates an instance of {@link XmlWriter} that writes to an {@link OutputStream}.
+ *
+ * @param xml The XML represented as an {@link OutputStream}.
+ * @param useDefault Whether the default implementation should be used if one could not be found on the classpath.
+ * @return A new instance of {@link XmlWriter}.
+ * @throws NullPointerException If {@code xml} is null.
+ * @throws IllegalStateException If a provider could not be found on the classpath and {@code useDefault} is false.
+ */
+ public static XmlWriter createWriter(OutputStream xml, boolean useDefault) {
+ if (defaultProvider == null) {
+ if (useDefault) {
+ return DefaultXmlWriter.toStream(xml);
+ } else {
+ throw new IllegalStateException(CANNOT_FIND_XML);
+ }
+ } else {
+ return defaultProvider.createWriter(xml);
+ }
+ }
+
+ /**
+ * Creates an instance of {@link XmlWriter} that writes to an {@link Writer}.
+ *
+ * If a provider could not be found on the classpath this will use the default implementation, effectively the
+ * equivalent to {@link #createWriter(Writer, boolean) createWriter(xml, true)}.
+ *
+ * @param xml The XML represented as an {@link Writer}.
+ * @return A new instance of {@link XmlWriter}.
+ * @throws NullPointerException If {@code xml} is null.
+ */
+ public static XmlWriter createWriter(Writer xml) {
+ return createWriter(xml, true);
+ }
+
+ /**
+ * Creates an instance of {@link XmlWriter} that writes to an {@link Writer}.
+ *
+ * @param xml The XML represented as an {@link Writer}.
+ * @param useDefault Whether the default implementation should be used if one could not be found on the classpath.
+ * @return A new instance of {@link XmlWriter}.
+ * @throws NullPointerException If {@code xml} is null.
+ * @throws IllegalStateException If a provider could not be found on the classpath and {@code useDefault} is false.
+ */
+ public static XmlWriter createWriter(Writer xml, boolean useDefault) {
+ if (defaultProvider == null) {
+ if (useDefault) {
+ return DefaultXmlWriter.toWriter(xml);
+ } else {
+ throw new IllegalStateException(CANNOT_FIND_XML);
+ }
+ } else {
+ return defaultProvider.createWriter(xml);
+ }
+ }
+}
diff --git a/sdk/core/azure-xml/src/main/java/com/azure/xml/DefaultXmlReader.java b/sdk/core/azure-xml/src/main/java/com/azure/xml/implementation/DefaultXmlReader.java
similarity index 96%
rename from sdk/core/azure-xml/src/main/java/com/azure/xml/DefaultXmlReader.java
rename to sdk/core/azure-xml/src/main/java/com/azure/xml/implementation/DefaultXmlReader.java
index d6d136b0f9cf6..8109472ef22ec 100644
--- a/sdk/core/azure-xml/src/main/java/com/azure/xml/DefaultXmlReader.java
+++ b/sdk/core/azure-xml/src/main/java/com/azure/xml/implementation/DefaultXmlReader.java
@@ -1,7 +1,11 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
-package com.azure.xml;
+package com.azure.xml.implementation;
+
+import com.azure.xml.XmlReader;
+import com.azure.xml.XmlToken;
+import com.azure.xml.XmlWriter;
import javax.xml.namespace.QName;
import javax.xml.stream.XMLInputFactory;
@@ -37,7 +41,7 @@ public final class DefaultXmlReader extends XmlReader {
* @return A new {@link XmlReader} instance.
*/
public static XmlReader fromBytes(byte[] xml) {
- return fromInputStream(new ByteArrayInputStream(xml));
+ return fromStream(new ByteArrayInputStream(xml));
}
/**
@@ -57,7 +61,7 @@ public static XmlReader fromString(String xml) {
* @return A new {@link XmlReader} instance.
* @throws RuntimeException If an {@link XmlReader} cannot be instantiated.
*/
- public static XmlReader fromInputStream(InputStream xml) {
+ public static XmlReader fromStream(InputStream xml) {
try {
return new DefaultXmlReader(XML_INPUT_FACTORY.createXMLStreamReader(xml));
} catch (XMLStreamException e) {
diff --git a/sdk/core/azure-xml/src/main/java/com/azure/xml/DefaultXmlWriter.java b/sdk/core/azure-xml/src/main/java/com/azure/xml/implementation/DefaultXmlWriter.java
similarity index 86%
rename from sdk/core/azure-xml/src/main/java/com/azure/xml/DefaultXmlWriter.java
rename to sdk/core/azure-xml/src/main/java/com/azure/xml/implementation/DefaultXmlWriter.java
index 019eaef65f670..662bd523d5fd4 100644
--- a/sdk/core/azure-xml/src/main/java/com/azure/xml/DefaultXmlWriter.java
+++ b/sdk/core/azure-xml/src/main/java/com/azure/xml/implementation/DefaultXmlWriter.java
@@ -1,7 +1,9 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
-package com.azure.xml;
+package com.azure.xml.implementation;
+
+import com.azure.xml.XmlWriter;
import javax.xml.stream.XMLOutputFactory;
import javax.xml.stream.XMLStreamException;
@@ -9,6 +11,7 @@
import java.io.IOException;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
+import java.io.Writer;
import java.nio.charset.StandardCharsets;
import java.util.Objects;
@@ -29,7 +32,7 @@ public final class DefaultXmlWriter extends XmlWriter {
* @return A new instance of {@link XmlWriter}.
* @throws RuntimeException If an {@link XmlWriter} cannot be instantiated.
*/
- public static XmlWriter toOutputStream(OutputStream outputStream) {
+ public static XmlWriter toStream(OutputStream outputStream) {
try {
return new DefaultXmlWriter(XML_OUTPUT_FACTORY.createXMLStreamWriter(
new OutputStreamWriter(outputStream, StandardCharsets.UTF_8)));
@@ -38,6 +41,21 @@ public static XmlWriter toOutputStream(OutputStream outputStream) {
}
}
+ /**
+ * Creates an instance of {@link XmlWriter} that writes to the provided {@link Writer}.
+ *
+ * @param writer The {@link Writer} where content will be written.
+ * @return A new instance of {@link XmlWriter}.
+ * @throws RuntimeException If an {@link XmlWriter} cannot be instantiated.
+ */
+ public static XmlWriter toWriter(Writer writer) {
+ try {
+ return new DefaultXmlWriter(XML_OUTPUT_FACTORY.createXMLStreamWriter(writer));
+ } catch (XMLStreamException ex) {
+ throw new RuntimeException(ex);
+ }
+ }
+
private DefaultXmlWriter(XMLStreamWriter writer) {
this.writer = writer;
}
diff --git a/sdk/core/azure-xml/src/main/java/module-info.java b/sdk/core/azure-xml/src/main/java/module-info.java
index 9336476b78c5f..1a38d62f075d5 100644
--- a/sdk/core/azure-xml/src/main/java/module-info.java
+++ b/sdk/core/azure-xml/src/main/java/module-info.java
@@ -5,4 +5,7 @@
requires java.xml;
exports com.azure.xml;
+ exports com.azure.xml.implementation;
+
+ uses com.azure.xml.XmlProvider;
}
diff --git a/sdk/core/azure-xml/src/test/java/com/azure/xml/DefaultXmlReaderContractTests.java b/sdk/core/azure-xml/src/test/java/com/azure/xml/DefaultXmlReaderContractTests.java
index 1525610f9ef0a..0fe58723e5a22 100644
--- a/sdk/core/azure-xml/src/test/java/com/azure/xml/DefaultXmlReaderContractTests.java
+++ b/sdk/core/azure-xml/src/test/java/com/azure/xml/DefaultXmlReaderContractTests.java
@@ -4,6 +4,7 @@
package com.azure.xml;
import com.azure.xml.contract.XmlReaderContractTests;
+import com.azure.xml.implementation.DefaultXmlReader;
/**
* Tests {@link DefaultXmlReader} against the contract required by {@link XmlReader}.
diff --git a/sdk/core/azure-xml/src/test/java/com/azure/xml/DefaultXmlWriterContractTests.java b/sdk/core/azure-xml/src/test/java/com/azure/xml/DefaultXmlWriterContractTests.java
index 1ce7ca0098715..1090b77641ff2 100644
--- a/sdk/core/azure-xml/src/test/java/com/azure/xml/DefaultXmlWriterContractTests.java
+++ b/sdk/core/azure-xml/src/test/java/com/azure/xml/DefaultXmlWriterContractTests.java
@@ -4,6 +4,7 @@
package com.azure.xml;
import com.azure.xml.contract.XmlWriterContractTests;
+import com.azure.xml.implementation.DefaultXmlWriter;
import org.junit.jupiter.api.BeforeEach;
import java.io.ByteArrayOutputStream;
@@ -20,7 +21,7 @@ public final class DefaultXmlWriterContractTests extends XmlWriterContractTests
@BeforeEach
public void beforeEach() {
this.outputStream = new ByteArrayOutputStream();
- this.writer = DefaultXmlWriter.toOutputStream(outputStream);
+ this.writer = DefaultXmlWriter.toStream(outputStream);
}
@Override
diff --git a/sdk/core/azure-xml/src/test/java/com/azure/xml/PlaygroundTests.java b/sdk/core/azure-xml/src/test/java/com/azure/xml/PlaygroundTests.java
index 3ed25abc3ff09..d4afc07f0ce38 100644
--- a/sdk/core/azure-xml/src/test/java/com/azure/xml/PlaygroundTests.java
+++ b/sdk/core/azure-xml/src/test/java/com/azure/xml/PlaygroundTests.java
@@ -3,6 +3,8 @@
package com.azure.xml;
+import com.azure.xml.implementation.DefaultXmlReader;
+import com.azure.xml.implementation.DefaultXmlWriter;
import org.junit.jupiter.api.Test;
import java.io.ByteArrayOutputStream;
@@ -63,7 +65,7 @@ public void toXmlSimple() throws IOException {
SignedIdentifiersWrapper wrapper = new SignedIdentifiersWrapper(Collections.singletonList(signedIdentifier));
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
- try (XmlWriter xmlWriter = DefaultXmlWriter.toOutputStream(byteArrayOutputStream)) {
+ try (XmlWriter xmlWriter = DefaultXmlWriter.toStream(byteArrayOutputStream)) {
xmlWriter.writeStartDocument();
wrapper.toXml(xmlWriter);
}
@@ -137,7 +139,7 @@ public void toXmlComplex() throws IOException {
.setContent(namespacePropertiesEntryContent);
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
- try (XmlWriter xmlWriter = DefaultXmlWriter.toOutputStream(byteArrayOutputStream)) {
+ try (XmlWriter xmlWriter = DefaultXmlWriter.toStream(byteArrayOutputStream)) {
xmlWriter.writeStartDocument();
namespacePropertiesEntry.toXml(xmlWriter);
}
diff --git a/sdk/core/azure-xml/src/test/java/com/azure/xml/storage/DeserializeListBlobsTests.java b/sdk/core/azure-xml/src/test/java/com/azure/xml/storage/DeserializeListBlobsTests.java
index 5307ad073c3bf..ce07e4356be3b 100644
--- a/sdk/core/azure-xml/src/test/java/com/azure/xml/storage/DeserializeListBlobsTests.java
+++ b/sdk/core/azure-xml/src/test/java/com/azure/xml/storage/DeserializeListBlobsTests.java
@@ -3,7 +3,7 @@
package com.azure.xml.storage;
-import com.azure.xml.DefaultXmlReader;
+import com.azure.xml.implementation.DefaultXmlReader;
import org.junit.jupiter.api.Test;
import java.util.ArrayList;
diff --git a/sdk/cosmos/azure-cosmos/CHANGELOG.md b/sdk/cosmos/azure-cosmos/CHANGELOG.md
index 3030781b3dbbc..fbc3f8933cde4 100644
--- a/sdk/cosmos/azure-cosmos/CHANGELOG.md
+++ b/sdk/cosmos/azure-cosmos/CHANGELOG.md
@@ -11,6 +11,8 @@
#### Other Changes
* Added system property to turn on replica validation - See [PR 29767](https://github.com/Azure/azure-sdk-for-java/pull/29767)
* Added improvement to avoid retry on same replica that previously failed with 410, 408 and >= 500 status codes - See [PR 29767](https://github.com/Azure/azure-sdk-for-java/pull/29767)
+* Improvement when `connectionEndpointRediscoveryEnabled` is enabled - See [PR 30281](https://github.com/Azure/azure-sdk-for-java/pull/30281)
+* Added replica validation for Unknown status if `openConnectionsAndInitCaches` is used and replica validation is enabled - See [PR 30277](https://github.com/Azure/azure-sdk-for-java/pull/30277)
### 4.35.1 (2022-08-29)
#### Other Changes
diff --git a/sdk/cosmos/azure-cosmos/src/main/java/com/azure/cosmos/implementation/CosmosSchedulers.java b/sdk/cosmos/azure-cosmos/src/main/java/com/azure/cosmos/implementation/CosmosSchedulers.java
index aa79b180ef0d0..e8016e1da4421 100644
--- a/sdk/cosmos/azure-cosmos/src/main/java/com/azure/cosmos/implementation/CosmosSchedulers.java
+++ b/sdk/cosmos/azure-cosmos/src/main/java/com/azure/cosmos/implementation/CosmosSchedulers.java
@@ -11,6 +11,7 @@ public class CosmosSchedulers {
private final static String TRANSPORT_RESPONSE_BOUNDED_ELASTIC_THREAD_NAME = "transport-response-bounded-elastic";
private final static String BULK_EXECUTOR_BOUNDED_ELASTIC_THREAD_NAME = "bulk-executor-bounded-elastic";
private final static String OPEN_CONNECTIONS_BOUNDED_ELASTIC_THREAD_NAME = "open-connections-bounded-elastic";
+ private final static String ASYNC_CACHE_BACKGROUND_REFRESH_THREAD_NAME = "async-cache-background-refresh-bounded-elastic";
private final static int TTL_FOR_SCHEDULER_WORKER_IN_SECONDS = 60; // same as BoundedElasticScheduler.DEFAULT_TTL_SECONDS
// Using a custom parallel scheduler to be able to schedule retries etc.
@@ -47,4 +48,13 @@ public class CosmosSchedulers {
TTL_FOR_SCHEDULER_WORKER_IN_SECONDS,
true
);
+
+ // Custom bounded elastic scheduler for async cache background refresh task
+ public final static Scheduler ASYNC_CACHE_BACKGROUND_REFRESH_BOUNDED_ELASTIC = Schedulers.newBoundedElastic(
+ Schedulers.DEFAULT_BOUNDED_ELASTIC_SIZE,
+ Schedulers.DEFAULT_BOUNDED_ELASTIC_QUEUESIZE,
+ ASYNC_CACHE_BACKGROUND_REFRESH_THREAD_NAME,
+ TTL_FOR_SCHEDULER_WORKER_IN_SECONDS,
+ true
+ );
}
diff --git a/sdk/cosmos/azure-cosmos/src/main/java/com/azure/cosmos/implementation/DiagnosticsClientContext.java b/sdk/cosmos/azure-cosmos/src/main/java/com/azure/cosmos/implementation/DiagnosticsClientContext.java
index ec6cb9f419c6c..485795c9fb6ac 100644
--- a/sdk/cosmos/azure-cosmos/src/main/java/com/azure/cosmos/implementation/DiagnosticsClientContext.java
+++ b/sdk/cosmos/azure-cosmos/src/main/java/com/azure/cosmos/implementation/DiagnosticsClientContext.java
@@ -18,6 +18,7 @@
import java.io.IOException;
import java.util.List;
import java.util.Locale;
+import java.util.Map;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
@@ -53,6 +54,15 @@ public void serialize(DiagnosticsClientConfig clientConfig, JsonGenerator genera
generator.writeStringField("machineId", ClientTelemetry.getMachineId(clientConfig));
generator.writeStringField("connectionMode", clientConfig.getConnectionMode().toString());
generator.writeNumberField("numberOfClients", clientConfig.getActiveClientsCount());
+ generator.writeObjectFieldStart("clientEndpoints");
+ for (Map.Entry entry: clientConfig.clientMap.entrySet()) {
+ try {
+ generator.writeNumberField(entry.getKey(), entry.getValue());
+ } catch (Exception e) {
+ logger.debug("unexpected failure", e);
+ }
+ }
+ generator.writeEndObject();
generator.writeObjectFieldStart("connCfg");
try {
generator.writeStringField("rntbd", clientConfig.rntbdConfig());
@@ -75,6 +85,7 @@ class DiagnosticsClientConfig {
private AtomicInteger activeClientsCnt;
private int clientId;
+ private Map clientMap;
private ConsistencyLevel consistencyLevel;
private boolean connectionSharingAcrossClientsEnabled;
@@ -90,16 +101,24 @@ class DiagnosticsClientConfig {
private String machineId;
private boolean replicaValidationEnabled = Configs.isReplicaAddressValidationEnabled();
- public void withMachineId(String machineId) {
+ public DiagnosticsClientConfig withMachineId(String machineId) {
this.machineId = machineId;
+ return this;
}
- public void withActiveClientCounter(AtomicInteger activeClientsCnt) {
+ public DiagnosticsClientConfig withActiveClientCounter(AtomicInteger activeClientsCnt) {
this.activeClientsCnt = activeClientsCnt;
+ return this;
}
- public void withClientId(int clientId) {
+ public DiagnosticsClientConfig withClientId(int clientId) {
this.clientId = clientId;
+ return this;
+ }
+
+ public DiagnosticsClientConfig withClientMap(Map clientMap) {
+ this.clientMap = clientMap;
+ return this;
}
public DiagnosticsClientConfig withEndpointDiscoveryEnabled(boolean endpointDiscoveryEnabled) {
diff --git a/sdk/cosmos/azure-cosmos/src/main/java/com/azure/cosmos/implementation/RxDocumentClientImpl.java b/sdk/cosmos/azure-cosmos/src/main/java/com/azure/cosmos/implementation/RxDocumentClientImpl.java
index c38a9a6e2ec43..a1eb9f38447ac 100644
--- a/sdk/cosmos/azure-cosmos/src/main/java/com/azure/cosmos/implementation/RxDocumentClientImpl.java
+++ b/sdk/cosmos/azure-cosmos/src/main/java/com/azure/cosmos/implementation/RxDocumentClientImpl.java
@@ -110,6 +110,7 @@ public class RxDocumentClientImpl implements AsyncDocumentClient, IAuthorization
DiagnosticsClientContext {
private static final String tempMachineId = "uuid:" + UUID.randomUUID();
private static final AtomicInteger activeClientsCnt = new AtomicInteger(0);
+ private static final Map clientMap = new ConcurrentHashMap<>();
private static final AtomicInteger clientIdGenerator = new AtomicInteger(0);
private static final Range RANGE_INCLUDING_ALL_PARTITION_KEY_RANGES = new Range<>(
PartitionKeyInternalHelper.MinimumInclusiveEffectivePartitionKey,
@@ -332,9 +333,11 @@ private RxDocumentClientImpl(URI serviceEndpoint,
activeClientsCnt.incrementAndGet();
this.clientId = clientIdGenerator.incrementAndGet();
+ clientMap.put(serviceEndpoint.toString(), clientMap.getOrDefault(serviceEndpoint.toString(), 0) + 1);
this.diagnosticsClientConfig = new DiagnosticsClientConfig();
this.diagnosticsClientConfig.withClientId(this.clientId);
this.diagnosticsClientConfig.withActiveClientCounter(activeClientsCnt);
+ this.diagnosticsClientConfig.withClientMap(clientMap);
this.diagnosticsClientConfig.withConnectionSharingAcrossClientsEnabled(connectionSharingAcrossClientsEnabled);
this.diagnosticsClientConfig.withConsistency(consistencyLevel);
diff --git a/sdk/cosmos/azure-cosmos/src/main/java/com/azure/cosmos/implementation/caches/AsyncCacheNonBlocking.java b/sdk/cosmos/azure-cosmos/src/main/java/com/azure/cosmos/implementation/caches/AsyncCacheNonBlocking.java
index 18304146a9302..5b86a8194fb5f 100644
--- a/sdk/cosmos/azure-cosmos/src/main/java/com/azure/cosmos/implementation/caches/AsyncCacheNonBlocking.java
+++ b/sdk/cosmos/azure-cosmos/src/main/java/com/azure/cosmos/implementation/caches/AsyncCacheNonBlocking.java
@@ -3,6 +3,7 @@
package com.azure.cosmos.implementation.caches;
import com.azure.cosmos.CosmosException;
+import com.azure.cosmos.implementation.CosmosSchedulers;
import com.azure.cosmos.implementation.Exceptions;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -81,26 +82,26 @@ public Mono getAsync(
return Mono.just(value);
}
- Mono refreshMono = initialLazyValue.createAndWaitForBackgroundRefreshTaskAsync(key, singleValueInitFunc);
+ Mono refreshMono = initialLazyValue.getOrCreateBackgroundRefreshTaskAsync(singleValueInitFunc);
return refreshMono.onErrorResume(
(exception) -> {
- logger.debug("refresh cache [{}] resulted in error", key, exception);
-
// In some scenarios when a background failure occurs like a 404 the initial cache value should be removed.
if (exception instanceof CosmosException && removeNotFoundFromCacheException((CosmosException) exception)) {
if (initialLazyValue.shouldRemoveFromCache()) {
this.remove(key);
}
}
+
+ logger.debug("refresh cache [{}] resulted in error", key, exception);
return Mono.error(exception);
}
);
}).onErrorResume((exception) -> {
- logger.debug("cache[{}] resulted in error", key, exception);
if (initialLazyValue.shouldRemoveFromCache()) {
this.remove(key);
}
+ logger.debug("cache[{}] resulted in error", key, exception);
return Mono.error(exception);
});
}
@@ -115,16 +116,32 @@ public Mono getAsync(
return result.getValueAsync().onErrorResume(
(exception) -> {
- logger.debug("cache[{}] resulted in error", key, exception);
// Remove the failed task from the dictionary so future requests can send other calls.
if (result.shouldRemoveFromCache()) {
this.remove(key);
}
+ logger.debug("cache[{}] resulted in error", key, exception);
return Mono.error(exception);
}
);
}
+ public void refresh(
+ TKey key,
+ Function> singleValueInitFunc) {
+
+ logger.debug("refreshing cache[{}]", key);
+ AsyncLazyWithRefresh initialLazyValue = values.get(key);
+ if (initialLazyValue != null) {
+ Mono backgroundRefreshTask = initialLazyValue.refresh(singleValueInitFunc);
+ if (backgroundRefreshTask != null) {
+ backgroundRefreshTask
+ .subscribeOn(CosmosSchedulers.ASYNC_CACHE_BACKGROUND_REFRESH_BOUNDED_ELASTIC)
+ .subscribe();
+ }
+ }
+ }
+
public void set(TKey key, TValue value) {
logger.debug("set cache[{}]={}", key, value);
AsyncLazyWithRefresh updatedValue = new AsyncLazyWithRefresh(value);
@@ -140,23 +157,21 @@ public void remove(TKey key) {
* be used to update the value. This allows concurrent requests
* to use the stale value while the refresh is occurring.
*/
- private class AsyncLazyWithRefresh {
-// private final Function> createValueFunc;
+ private static class AsyncLazyWithRefresh {
private final AtomicBoolean removeFromCache = new AtomicBoolean(false);
private final AtomicReference> value;
- private Mono refreshInProgress;
- private final AtomicBoolean refreshInProgressCompleted = new AtomicBoolean(false);
+ private final AtomicReference> refreshInProgress;
public AsyncLazyWithRefresh(TValue value) {
this.value = new AtomicReference<>();
this.value.set(Mono.just(value));
- this.refreshInProgress = null;
+ this.refreshInProgress = new AtomicReference<>(null);
}
public AsyncLazyWithRefresh(Function> taskFactory) {
this.value = new AtomicReference<>();
this.value.set(taskFactory.apply(null).cache());
- this.refreshInProgress = null;
+ this.refreshInProgress = new AtomicReference<>(null);
}
public Mono getValueAsync() {
@@ -168,26 +183,59 @@ public Mono value() {
return value.get();
}
- @SuppressWarnings("unchecked")
- public Mono createAndWaitForBackgroundRefreshTaskAsync(TKey key, Function> createRefreshFunction) {
- Mono valueMono = this.value.get();
+ public Mono getOrCreateBackgroundRefreshTaskAsync(Function> createRefreshFunction) {
+ Mono refreshInProgressSnapshot = this.refreshInProgress.updateAndGet(existingMono -> {
+ if (existingMono == null) {
+ logger.debug("Started a new background task");
+ return this.createBackgroundRefreshTask(createRefreshFunction);
+ } else {
+ logger.debug("Background refresh task is already in progress");
+ }
+
+ return existingMono;
+ });
+ return refreshInProgressSnapshot == null ? this.value.get() : refreshInProgressSnapshot;
+ }
- return valueMono.flatMap(value -> {
- if(this.refreshInProgressCompleted.compareAndSet(false, true)) {
- this.refreshInProgress = createRefreshFunction.apply(value).cache();
- return this.refreshInProgress
+ private Mono createBackgroundRefreshTask(Function> createRefreshFunction) {
+ return this.value
+ .get()
+ .flatMap(createRefreshFunction)
.flatMap(response -> {
- this.value.set(Mono.just(response));
- this.refreshInProgressCompleted.set(false);
- return this.value.get();
- }).doOnError(e -> this.refreshInProgressCompleted.set(false));
+ this.refreshInProgress.set(null);
+ return this.value.updateAndGet(existingValue -> Mono.just(response));
+ })
+ .doOnError(throwable -> {
+ this.refreshInProgress.set(null);
+ logger.warn("Background refresh task failed", throwable);
+ })
+ .cache();
+ }
- }
- return this.refreshInProgress == null ? valueMono : refreshInProgress;
- });
+ /***
+ * If there is no refresh in progress background task, then create a new one, else skip
+ *
+ * @param createRefreshFunction the createRefreshFunction
+ * @return if there is already a refreshInProgress task ongoing, then return Mono.empty, else return the newly created background refresh task
+ */
+ public Mono refresh(Function> createRefreshFunction) {
+ if (this.refreshInProgress.compareAndSet(null, this.createBackgroundRefreshTask(createRefreshFunction))) {
+ logger.debug("Started a new background task");
+ return this.refreshInProgress.get();
+ }
+
+ logger.debug("Background refresh task is already in progress, skip creating a new one");
+ return null;
}
public boolean shouldRemoveFromCache() {
+ // Multiple threads could subscribe to the Mono, only one of them will be allowed to remove the Mono from the cache
+ // For example for the following scenario:
+ // Request1 -> getAsync -> Mono1
+ // Request2 -> getAsync -> Mono1
+ // Mono1 failed, and we decided to remove this entry from the cache. Request1 has removed the entry from the cache
+ // Request3 -> getAsync -> Mono2
+ // without this check, request2 will end up removing the cache entry created by request3
return this.removeFromCache.compareAndSet(false, true);
}
}
diff --git a/sdk/cosmos/azure-cosmos/src/main/java/com/azure/cosmos/implementation/directconnectivity/AddressResolver.java b/sdk/cosmos/azure-cosmos/src/main/java/com/azure/cosmos/implementation/directconnectivity/AddressResolver.java
index b7fd625564f7d..69ed8ba22337c 100644
--- a/sdk/cosmos/azure-cosmos/src/main/java/com/azure/cosmos/implementation/directconnectivity/AddressResolver.java
+++ b/sdk/cosmos/azure-cosmos/src/main/java/com/azure/cosmos/implementation/directconnectivity/AddressResolver.java
@@ -9,9 +9,11 @@
import com.azure.cosmos.implementation.DocumentCollection;
import com.azure.cosmos.implementation.HttpConstants;
import com.azure.cosmos.implementation.ICollectionRoutingMapCache;
+import com.azure.cosmos.implementation.IOpenConnectionsHandler;
import com.azure.cosmos.implementation.InternalServerErrorException;
import com.azure.cosmos.implementation.InvalidPartitionException;
import com.azure.cosmos.implementation.NotFoundException;
+import com.azure.cosmos.implementation.OpenConnectionResponse;
import com.azure.cosmos.implementation.OperationType;
import com.azure.cosmos.implementation.PartitionKeyRange;
import com.azure.cosmos.implementation.PartitionKeyRangeGoneException;
@@ -24,8 +26,6 @@
import com.azure.cosmos.implementation.apachecommons.lang.NotImplementedException;
import com.azure.cosmos.implementation.apachecommons.lang.StringUtils;
import com.azure.cosmos.implementation.caches.RxCollectionCache;
-import com.azure.cosmos.implementation.IOpenConnectionsHandler;
-import com.azure.cosmos.implementation.OpenConnectionResponse;
import com.azure.cosmos.implementation.routing.CollectionRoutingMap;
import com.azure.cosmos.implementation.routing.PartitionKeyInternal;
import com.azure.cosmos.implementation.routing.PartitionKeyInternalHelper;
@@ -35,7 +35,6 @@
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
-import java.net.URI;
import java.util.concurrent.Callable;
import java.util.function.Function;
@@ -87,11 +86,6 @@ public Mono resolveAsync(
});
}
- @Override
- public int updateAddresses(URI serverKey) {
- throw new NotImplementedException("updateAddresses() is not supported in AddressResolver");
- }
-
@Override
public Flux openConnectionsAndInitCaches(String containerLink) {
return Flux.empty();
diff --git a/sdk/cosmos/azure-cosmos/src/main/java/com/azure/cosmos/implementation/directconnectivity/GatewayAddressCache.java b/sdk/cosmos/azure-cosmos/src/main/java/com/azure/cosmos/implementation/directconnectivity/GatewayAddressCache.java
index 53d599b3d3a2e..0f0d24d6a9ee3 100644
--- a/sdk/cosmos/azure-cosmos/src/main/java/com/azure/cosmos/implementation/directconnectivity/GatewayAddressCache.java
+++ b/sdk/cosmos/azure-cosmos/src/main/java/com/azure/cosmos/implementation/directconnectivity/GatewayAddressCache.java
@@ -63,10 +63,8 @@
import java.util.HashMap;
import java.util.List;
import java.util.Map;
-import java.util.Objects;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors;
import static com.azure.cosmos.implementation.guava25.base.Preconditions.checkNotNull;
@@ -97,14 +95,12 @@ public class GatewayAddressCache implements IAddressCache {
private volatile Pair masterPartitionAddressCache;
private volatile Instant suboptimalMasterPartitionTimestamp;
- private final ConcurrentHashMap> serverPartitionAddressToPkRangeIdMap;
- private final boolean tcpConnectionEndpointRediscoveryEnabled;
-
private final ConcurrentHashMap lastForcedRefreshMap;
private final GlobalEndpointManager globalEndpointManager;
private IOpenConnectionsHandler openConnectionsHandler;
private final ConnectionPolicy connectionPolicy;
private final boolean replicaAddressValidationEnabled;
+ private final Set replicaValidationScopes;
public GatewayAddressCache(
DiagnosticsClientContext clientContext,
@@ -114,7 +110,6 @@ public GatewayAddressCache(
UserAgentContainer userAgent,
HttpClient httpClient,
long suboptimalPartitionForceRefreshIntervalInSeconds,
- boolean tcpConnectionEndpointRediscoveryEnabled,
ApiType apiType,
GlobalEndpointManager globalEndpointManager,
ConnectionPolicy connectionPolicy,
@@ -156,13 +151,15 @@ public GatewayAddressCache(
// Set requested API version header for version enforcement.
defaultRequestHeaders.put(HttpConstants.HttpHeaders.VERSION, HttpConstants.Versions.CURRENT_VERSION);
- this.serverPartitionAddressToPkRangeIdMap = new ConcurrentHashMap<>();
- this.tcpConnectionEndpointRediscoveryEnabled = tcpConnectionEndpointRediscoveryEnabled;
this.lastForcedRefreshMap = new ConcurrentHashMap<>();
this.globalEndpointManager = globalEndpointManager;
this.openConnectionsHandler = openConnectionsHandler;
this.connectionPolicy = connectionPolicy;
this.replicaAddressValidationEnabled = Configs.isReplicaAddressValidationEnabled();
+ this.replicaValidationScopes = ConcurrentHashMap.newKeySet();
+ if (this.replicaAddressValidationEnabled) {
+ this.replicaValidationScopes.add(Uri.HealthStatus.UnhealthyPending);
+ }
}
public GatewayAddressCache(
@@ -172,7 +169,6 @@ public GatewayAddressCache(
IAuthorizationTokenProvider tokenProvider,
UserAgentContainer userAgent,
HttpClient httpClient,
- boolean tcpConnectionEndpointRediscoveryEnabled,
ApiType apiType,
GlobalEndpointManager globalEndpointManager,
ConnectionPolicy connectionPolicy,
@@ -184,42 +180,12 @@ public GatewayAddressCache(
userAgent,
httpClient,
DefaultSuboptimalPartitionForceRefreshIntervalInSeconds,
- tcpConnectionEndpointRediscoveryEnabled,
apiType,
globalEndpointManager,
connectionPolicy,
openConnectionsHandler);
}
- @Override
- public int updateAddresses(final URI serverKey) {
-
- Objects.requireNonNull(serverKey, "expected non-null serverKey");
-
- AtomicInteger updatedCacheEntryCount = new AtomicInteger(0);
-
- if (this.tcpConnectionEndpointRediscoveryEnabled) {
- this.serverPartitionAddressToPkRangeIdMap.computeIfPresent(serverKey, (uri, partitionKeyRangeIdentitySet) -> {
-
- for (PartitionKeyRangeIdentity partitionKeyRangeIdentity : partitionKeyRangeIdentitySet) {
- if (partitionKeyRangeIdentity.getPartitionKeyRangeId().equals(PartitionKeyRange.MASTER_PARTITION_KEY_RANGE_ID)) {
- this.masterPartitionAddressCache = null;
- } else {
- this.serverPartitionAddressCache.remove(partitionKeyRangeIdentity);
- }
-
- updatedCacheEntryCount.incrementAndGet();
- }
-
- return null;
- });
- } else {
- logger.warn("tcpConnectionEndpointRediscovery is not enabled, should not reach here.");
- }
-
- return updatedCacheEntryCount.get();
- }
-
@Override
public Mono> tryGetAddresses(RxDocumentServiceRequest request,
PartitionKeyRangeIdentity partitionKeyRangeIdentity,
@@ -289,8 +255,7 @@ public Mono> tryGetAddresses(RxDocumentS
for (Uri failedEndpoints : request.requestContext.getFailedEndpoints()) {
failedEndpoints.setUnhealthy();
}
- return forceRefreshPartitionAddressesModified
- || Arrays.stream(cachedAddresses).anyMatch(addressInformation -> addressInformation.getPhysicalUri().shouldRefreshHealthStatus());
+ return forceRefreshPartitionAddressesModified;
})
.map(Utils.ValueHolder::new);
@@ -303,6 +268,20 @@ public Mono> tryGetAddresses(RxDocumentS
this.suboptimalServerPartitionTimestamps.putIfAbsent(partitionKeyRangeIdentity, Instant.now());
}
+ // Refresh the cache if there was an address has been marked as unhealthy long enough and need to revalidate its status
+ // If you are curious about why we do not depend on 410 to force refresh the addresses, the reason being:
+ // When an address is marked as unhealthy, then the address enumerator will move it to the end of the list
+ // So it could happen that no request will use the unhealthy address for an extended period of time
+ // So the 410 -> forceRefresh workflow may not happen
+ if (Arrays
+ .stream(addressesValueHolder.v)
+ .anyMatch(addressInformation -> addressInformation.getPhysicalUri().shouldRefreshHealthStatus())) {
+ logger.info("refresh cache due to address uri in unhealthy status");
+ this.serverPartitionAddressCache.refresh(
+ partitionKeyRangeIdentity,
+ cachedAddresses -> this.getAddressesForRangeId(request, partitionKeyRangeIdentity, true, cachedAddresses));
+ }
+
return addressesValueHolder;
})
.onErrorResume(ex -> {
@@ -875,12 +854,24 @@ private void validateReplicaAddresses(AddressInformation[] addresses) {
// By theory, when we reach here, the status of the address should be in one of the three status: Unknown, Connected, UnhealthyPending
// using open connection to validate addresses in UnhealthyPending status
// Could extend to also open connection for unknown in the future
- List addressesNeedToValidation =
- Arrays
- .stream(addresses)
- .map(address -> address.getPhysicalUri())
- .filter(addressUri -> addressUri.getHealthStatus() == Uri.HealthStatus.UnhealthyPending)
- .collect(Collectors.toList());
+
+ List addressesNeedToValidation = new ArrayList<>();
+ for (AddressInformation address : addresses) {
+ if (this.replicaValidationScopes.contains(address.getPhysicalUri().getHealthStatus())) {
+ switch (address.getPhysicalUri().getHealthStatus()) {
+ case UnhealthyPending:
+ // Generally, an unhealthyPending replica has more chances to fail the request compared to unknown replica
+ // so we want to put it at the head of the validation list
+ addressesNeedToValidation.add(0, address.getPhysicalUri());
+ break;
+ case Unknown:
+ addressesNeedToValidation.add(address.getPhysicalUri());
+ break;
+ default:
+ throw new IllegalStateException("Validate replica status is not support for status " + address.getPhysicalUri().getHealthStatus());
+ }
+ }
+ }
if (addressesNeedToValidation.size() > 0) {
this.openConnectionsHandler
@@ -905,26 +896,6 @@ private Pair toPartitionAddress
.collect(Collectors.toList())
.toArray(new AddressInformation[addresses.size()]);
- if (this.tcpConnectionEndpointRediscoveryEnabled) {
- for (AddressInformation addressInfo : addressInfos) {
- if (logger.isDebugEnabled()) {
- logger.debug(
- "Added address to serverPartitionAddressToPkRangeIdMap: ({\"partitionKeyRangeIdentity\":{},\"address\":{}})",
- partitionKeyRangeIdentity,
- addressInfo);
- }
-
- this.serverPartitionAddressToPkRangeIdMap.compute(addressInfo.getServerKey(), (serverKey, partitionKeyRangeIdentitySet) -> {
- if (partitionKeyRangeIdentitySet == null) {
- partitionKeyRangeIdentitySet = ConcurrentHashMap.newKeySet();
- }
-
- partitionKeyRangeIdentitySet.add(partitionKeyRangeIdentity);
- return partitionKeyRangeIdentitySet;
- });
- }
- }
-
return Pair.of(partitionKeyRangeIdentity, addressInfos);
}
@@ -946,6 +917,10 @@ public Flux openConnectionsAndInitCaches(
JavaStreamUtils.toString(partitionKeyRangeIdentities, ","));
}
+ if (this.replicaAddressValidationEnabled) {
+ this.replicaValidationScopes.add(Uri.HealthStatus.Unknown);
+ }
+
List>> tasks = new ArrayList<>();
int batchSize = GatewayAddressCache.DefaultBatchSize;
diff --git a/sdk/cosmos/azure-cosmos/src/main/java/com/azure/cosmos/implementation/directconnectivity/GlobalAddressResolver.java b/sdk/cosmos/azure-cosmos/src/main/java/com/azure/cosmos/implementation/directconnectivity/GlobalAddressResolver.java
index 77eaf6c48188e..fd7302073f230 100644
--- a/sdk/cosmos/azure-cosmos/src/main/java/com/azure/cosmos/implementation/directconnectivity/GlobalAddressResolver.java
+++ b/sdk/cosmos/azure-cosmos/src/main/java/com/azure/cosmos/implementation/directconnectivity/GlobalAddressResolver.java
@@ -31,9 +31,7 @@
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
-import java.util.Objects;
import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors;
import static com.azure.cosmos.implementation.guava25.base.Preconditions.checkArgument;
@@ -96,26 +94,6 @@ public GlobalAddressResolver(
}
}
- @Override
- public int updateAddresses(final URI serverKey) {
-
- Objects.requireNonNull(serverKey, "expected non-null serverKey");
-
- AtomicInteger updatedCount = new AtomicInteger(0);
-
- if (this.tcpConnectionEndpointRediscoveryEnabled) {
- for (EndpointCache endpointCache : this.addressCacheByEndpoint.values()) {
- final GatewayAddressCache addressCache = endpointCache.addressCache;
-
- updatedCount.accumulateAndGet(addressCache.updateAddresses(serverKey), (oldValue, newValue) -> oldValue + newValue);
- }
- } else {
- logger.warn("tcpConnectionEndpointRediscovery is not enabled, should not reach here.");
- }
-
- return updatedCount.get();
- }
-
@Override
public Flux openConnectionsAndInitCaches(String containerLink) {
checkArgument(StringUtils.isNotEmpty(containerLink), "Argument 'containerLink' should not be null nor empty");
@@ -211,7 +189,6 @@ private EndpointCache getOrAddEndpoint(URI endpoint) {
this.tokenProvider,
this.userAgentContainer,
this.httpClient,
- this.tcpConnectionEndpointRediscoveryEnabled,
this.apiType,
this.endpointManager,
this.connectionPolicy,
diff --git a/sdk/cosmos/azure-cosmos/src/main/java/com/azure/cosmos/implementation/directconnectivity/GoneAndRetryWithRetryPolicy.java b/sdk/cosmos/azure-cosmos/src/main/java/com/azure/cosmos/implementation/directconnectivity/GoneAndRetryWithRetryPolicy.java
index 1aae68b46dc43..c743ef28b0307 100644
--- a/sdk/cosmos/azure-cosmos/src/main/java/com/azure/cosmos/implementation/directconnectivity/GoneAndRetryWithRetryPolicy.java
+++ b/sdk/cosmos/azure-cosmos/src/main/java/com/azure/cosmos/implementation/directconnectivity/GoneAndRetryWithRetryPolicy.java
@@ -46,8 +46,7 @@ public GoneAndRetryWithRetryPolicy(RxDocumentServiceRequest request, Integer wai
waitTimeInSeconds,
this.retryContext
);
- this.retryWithRetryPolicy = new RetryWithRetryPolicy(
- waitTimeInSeconds, this.retryContext);
+ this.retryWithRetryPolicy = new RetryWithRetryPolicy(waitTimeInSeconds, this.retryContext);
this.start = Instant.now();
}
diff --git a/sdk/cosmos/azure-cosmos/src/main/java/com/azure/cosmos/implementation/directconnectivity/IAddressCache.java b/sdk/cosmos/azure-cosmos/src/main/java/com/azure/cosmos/implementation/directconnectivity/IAddressCache.java
index 8123db36fe31d..4a67cd86f4adf 100644
--- a/sdk/cosmos/azure-cosmos/src/main/java/com/azure/cosmos/implementation/directconnectivity/IAddressCache.java
+++ b/sdk/cosmos/azure-cosmos/src/main/java/com/azure/cosmos/implementation/directconnectivity/IAddressCache.java
@@ -3,23 +3,14 @@
package com.azure.cosmos.implementation.directconnectivity;
+import com.azure.cosmos.implementation.IOpenConnectionsHandler;
import com.azure.cosmos.implementation.RxDocumentServiceRequest;
import com.azure.cosmos.implementation.Utils;
-import com.azure.cosmos.implementation.IOpenConnectionsHandler;
import com.azure.cosmos.implementation.routing.PartitionKeyRangeIdentity;
import reactor.core.publisher.Mono;
-import java.net.URI;
-
public interface IAddressCache {
- /**
- * Update the physical address of the {@link PartitionKeyRangeIdentity partition key range identity} associated to the serverKey.
- *
- *
- */
- int updateAddresses(URI serverKey);
-
/**
* Resolves physical addresses by either PartitionKeyRangeIdentity.
*
diff --git a/sdk/cosmos/azure-cosmos/src/main/java/com/azure/cosmos/implementation/directconnectivity/IAddressResolver.java b/sdk/cosmos/azure-cosmos/src/main/java/com/azure/cosmos/implementation/directconnectivity/IAddressResolver.java
index 0d70c26b60b3c..5fbcd28a139fe 100644
--- a/sdk/cosmos/azure-cosmos/src/main/java/com/azure/cosmos/implementation/directconnectivity/IAddressResolver.java
+++ b/sdk/cosmos/azure-cosmos/src/main/java/com/azure/cosmos/implementation/directconnectivity/IAddressResolver.java
@@ -3,22 +3,18 @@
package com.azure.cosmos.implementation.directconnectivity;
-import com.azure.cosmos.implementation.RxDocumentServiceRequest;
import com.azure.cosmos.implementation.IOpenConnectionsHandler;
import com.azure.cosmos.implementation.OpenConnectionResponse;
+import com.azure.cosmos.implementation.RxDocumentServiceRequest;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
-import java.net.URI;
-
public interface IAddressResolver {
Mono resolveAsync(
RxDocumentServiceRequest request,
boolean forceRefreshPartitionAddresses);
- int updateAddresses(URI serverKey);
-
/***
* Warm up caches and open connections to all replicas of the container for the current read region.
*
diff --git a/sdk/cosmos/azure-cosmos/src/main/java/com/azure/cosmos/implementation/directconnectivity/Uri.java b/sdk/cosmos/azure-cosmos/src/main/java/com/azure/cosmos/implementation/directconnectivity/Uri.java
index 86813b94abc75..02179a15454a6 100644
--- a/sdk/cosmos/azure-cosmos/src/main/java/com/azure/cosmos/implementation/directconnectivity/Uri.java
+++ b/sdk/cosmos/azure-cosmos/src/main/java/com/azure/cosmos/implementation/directconnectivity/Uri.java
@@ -160,7 +160,7 @@ public HealthStatus getEffectiveHealthStatus() {
public boolean shouldRefreshHealthStatus() {
return this.healthStatus.get() == HealthStatus.Unhealthy
- && Instant.now().compareTo(this.lastUnhealthyTimestamp.plusMillis(DEFAULT_NON_HEALTHY_RESET_TIME_IN_MILLISECONDS)) > 0;
+ && Instant.now().compareTo(this.lastUnhealthyTimestamp.plusMillis(DEFAULT_NON_HEALTHY_RESET_TIME_IN_MILLISECONDS)) >= 0;
}
public String getHealthStatusDiagnosticString() {
@@ -195,10 +195,10 @@ public String toString() {
*
*/
public enum HealthStatus {
- Connected(0),
- Unknown(1),
- UnhealthyPending(2),
- Unhealthy(3);
+ Connected(100),
+ Unknown(200),
+ UnhealthyPending(300),
+ Unhealthy(400);
private int priority;
HealthStatus(int priority) {
diff --git a/sdk/cosmos/azure-cosmos/src/main/java/com/azure/cosmos/implementation/directconnectivity/rntbd/RntbdConnectionStateListener.java b/sdk/cosmos/azure-cosmos/src/main/java/com/azure/cosmos/implementation/directconnectivity/rntbd/RntbdConnectionStateListener.java
index 105040b0d286a..448471667b46a 100644
--- a/sdk/cosmos/azure-cosmos/src/main/java/com/azure/cosmos/implementation/directconnectivity/rntbd/RntbdConnectionStateListener.java
+++ b/sdk/cosmos/azure-cosmos/src/main/java/com/azure/cosmos/implementation/directconnectivity/rntbd/RntbdConnectionStateListener.java
@@ -3,13 +3,15 @@
package com.azure.cosmos.implementation.directconnectivity.rntbd;
-import com.azure.cosmos.implementation.directconnectivity.IAddressResolver;
+import com.azure.cosmos.implementation.directconnectivity.Uri;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.IOException;
import java.nio.channels.ClosedChannelException;
import java.time.Instant;
+import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
import static com.azure.cosmos.implementation.guava25.base.Preconditions.checkNotNull;
@@ -18,24 +20,29 @@ public class RntbdConnectionStateListener {
private static final Logger logger = LoggerFactory.getLogger(RntbdConnectionStateListener.class);
- private final IAddressResolver addressResolver;
private final RntbdEndpoint endpoint;
private final RntbdConnectionStateListenerMetrics metrics;
+ private final Set addressUris;
// endregion
// region Constructors
- public RntbdConnectionStateListener(final IAddressResolver addressResolver, final RntbdEndpoint endpoint) {
- this.addressResolver = checkNotNull(addressResolver, "expected non-null addressResolver");
+ public RntbdConnectionStateListener(final RntbdEndpoint endpoint) {
this.endpoint = checkNotNull(endpoint, "expected non-null endpoint");
this.metrics = new RntbdConnectionStateListenerMetrics();
+ this.addressUris = ConcurrentHashMap.newKeySet();
}
// endregion
// region Methods
+ public void onBeforeSendRequest(Uri addressUri) {
+ checkNotNull(addressUri, "Argument 'addressUri' should not be null");
+ this.addressUris.add(addressUri);
+ }
+
public void onException(Throwable exception) {
checkNotNull(exception, "expect non-null exception");
@@ -81,7 +88,12 @@ private int onConnectionEvent(final RntbdConnectionEvent event, final Throwable
RntbdObjectMapper.toJson(exception));
}
- return this.addressResolver.updateAddresses(this.endpoint.serverKey());
+ for (Uri addressUri : this.addressUris) {
+ addressUri.setUnhealthy();
+ }
+
+ return addressUris.size();
+
} else {
if (logger.isDebugEnabled()) {
logger.debug("Endpoint closed while onConnectionEvent: {}", this.endpoint);
diff --git a/sdk/cosmos/azure-cosmos/src/main/java/com/azure/cosmos/implementation/directconnectivity/rntbd/RntbdServiceEndpoint.java b/sdk/cosmos/azure-cosmos/src/main/java/com/azure/cosmos/implementation/directconnectivity/rntbd/RntbdServiceEndpoint.java
index 432dcfb7e531c..9b5def28f2e25 100644
--- a/sdk/cosmos/azure-cosmos/src/main/java/com/azure/cosmos/implementation/directconnectivity/rntbd/RntbdServiceEndpoint.java
+++ b/sdk/cosmos/azure-cosmos/src/main/java/com/azure/cosmos/implementation/directconnectivity/rntbd/RntbdServiceEndpoint.java
@@ -123,8 +123,7 @@ private RntbdServiceEndpoint(
this.maxConcurrentRequests = config.maxConcurrentRequestsPerEndpoint();
this.connectionStateListener = this.provider.addressResolver != null && config.isConnectionEndpointRediscoveryEnabled()
- ? new RntbdConnectionStateListener(this.provider.addressResolver, this)
- : null;
+ ? new RntbdConnectionStateListener(this) : null;
this.channelPool = new RntbdClientChannelPool(this, bootstrap, config, clientTelemetry, this.connectionStateListener);
this.clientTelemetry = clientTelemetry;
@@ -270,6 +269,10 @@ public RntbdRequestRecord request(final RntbdRequestArgs args) {
int concurrentRequestSnapshot = this.concurrentRequests.incrementAndGet();
+ if (this.connectionStateListener != null) {
+ this.connectionStateListener.onBeforeSendRequest(args.physicalAddressUri());
+ }
+
RntbdEndpointStatistics stat = endpointMetricsSnapshot(concurrentRequestSnapshot);
if (concurrentRequestSnapshot > this.maxConcurrentRequests) {
@@ -307,6 +310,10 @@ public OpenConnectionRntbdRequestRecord openConnection(Uri addressUri) {
this.throwIfClosed();
+ if (this.connectionStateListener != null) {
+ this.connectionStateListener.onBeforeSendRequest(addressUri);
+ }
+
OpenConnectionRntbdRequestRecord requestRecord = new OpenConnectionRntbdRequestRecord(addressUri);
final Future openChannelFuture = this.channelPool.acquire(requestRecord);
diff --git a/sdk/cosmos/azure-cosmos/src/test/java/com/azure/cosmos/CosmosDiagnosticsTest.java b/sdk/cosmos/azure-cosmos/src/test/java/com/azure/cosmos/CosmosDiagnosticsTest.java
index 2753528f5eede..221d3e7c2e5e5 100644
--- a/sdk/cosmos/azure-cosmos/src/test/java/com/azure/cosmos/CosmosDiagnosticsTest.java
+++ b/sdk/cosmos/azure-cosmos/src/test/java/com/azure/cosmos/CosmosDiagnosticsTest.java
@@ -383,6 +383,65 @@ public void requestSessionTokenDiagnostics() {
}
}
+ @Test(groups = {"simple"})
+ public void databaseAccountToClients() {
+ CosmosClient testClient = null;
+ try {
+ testClient = new CosmosClientBuilder()
+ .endpoint(TestConfigurations.HOST)
+ .key(TestConfigurations.MASTER_KEY)
+ .contentResponseOnWriteEnabled(true)
+ .directMode()
+ .buildClient();
+ CosmosContainer cosmosContainer =
+ testClient.getDatabase(cosmosAsyncContainer.getDatabase().getId()).getContainer(cosmosAsyncContainer.getId());
+ InternalObjectNode internalObjectNode = getInternalObjectNode();
+ CosmosItemResponse createResponse = cosmosContainer.createItem(internalObjectNode);
+ String diagnostics = createResponse.getDiagnostics().toString();
+
+ // assert diagnostics shows the correct format for tracking client instances
+ assertThat(diagnostics).contains(String.format("\"clientEndpoints\"" +
+ ":{\"%s\"", TestConfigurations.HOST));
+ // track number of clients currently mapped to account
+ int clientsIndex = diagnostics.indexOf("\"clientEndpoints\":");
+ // we do end at +120 to ensure we grab the bracket even if the account is very long or if
+ // we have hundreds of clients (triple digit ints) running at once in the pipelines
+ String[] substrings = diagnostics.substring(clientsIndex, clientsIndex + 120)
+ .split("}")[0].split(":");
+ String intString = substrings[substrings.length-1];
+ int intValue = Integer.parseInt(intString);
+
+
+ CosmosClient testClient2 = new CosmosClientBuilder()
+ .endpoint(TestConfigurations.HOST)
+ .key(TestConfigurations.MASTER_KEY)
+ .contentResponseOnWriteEnabled(true)
+ .directMode()
+ .buildClient();
+
+ internalObjectNode = getInternalObjectNode();
+ createResponse = cosmosContainer.createItem(internalObjectNode);
+ diagnostics = createResponse.getDiagnostics().toString();
+ // assert diagnostics shows the correct format for tracking client instances
+ assertThat(diagnostics).contains(String.format("\"clientEndpoints\"" +
+ ":{\"%s\"", TestConfigurations.HOST));
+ // grab new value and assert one additional client is mapped to the same account used previously
+ clientsIndex = diagnostics.indexOf("\"clientEndpoints\":");
+ substrings = diagnostics.substring(clientsIndex, clientsIndex + 120)
+ .split("}")[0].split(":");
+ intString = substrings[substrings.length-1];
+ assertThat(Integer.parseInt(intString)).isEqualTo(intValue+1);
+
+ //close second client
+ testClient2.close();
+
+ } finally {
+ if (testClient != null) {
+ testClient.close();
+ }
+ }
+ }
+
@Test(groups = {"simple"}, timeOut = TIMEOUT)
public void queryPlanDiagnostics() throws JsonProcessingException {
CosmosContainer cosmosContainer = directClient.getDatabase(cosmosAsyncContainer.getDatabase().getId()).getContainer(cosmosAsyncContainer.getId());
diff --git a/sdk/cosmos/azure-cosmos/src/test/java/com/azure/cosmos/implementation/ClientConfigDiagnosticsTest.java b/sdk/cosmos/azure-cosmos/src/test/java/com/azure/cosmos/implementation/ClientConfigDiagnosticsTest.java
index 50f639b5973ec..65148bafcb8c9 100644
--- a/sdk/cosmos/azure-cosmos/src/test/java/com/azure/cosmos/implementation/ClientConfigDiagnosticsTest.java
+++ b/sdk/cosmos/azure-cosmos/src/test/java/com/azure/cosmos/implementation/ClientConfigDiagnosticsTest.java
@@ -17,6 +17,7 @@
import java.io.StringWriter;
import java.time.Duration;
+import java.util.HashMap;
import java.util.UUID;
import java.util.concurrent.atomic.AtomicInteger;
@@ -35,6 +36,7 @@ public void bareMinimum() throws Exception {
diagnosticsClientConfig.withClientId(1);
diagnosticsClientConfig.withConnectionMode(ConnectionMode.DIRECT);
diagnosticsClientConfig.withActiveClientCounter(new AtomicInteger(2));
+ diagnosticsClientConfig.withClientMap(new HashMap<>());
Mockito.doReturn(diagnosticsClientConfig).when(clientContext).getConfig();
@@ -67,6 +69,7 @@ public void rntbd() throws Exception {
diagnosticsClientConfig.withActiveClientCounter(new AtomicInteger(2));
diagnosticsClientConfig.withRntbdOptions( new RntbdTransportClient.Options.Builder(ConnectionPolicy.getDefaultPolicy()).build().toDiagnosticsString());
diagnosticsClientConfig.withGatewayHttpClientConfig(new HttpClientConfig(new Configs()).toDiagnosticsString());
+ diagnosticsClientConfig.withClientMap(new HashMap<>());
Mockito.doReturn(diagnosticsClientConfig).when(clientContext).getConfig();
@@ -101,6 +104,7 @@ public void gw() throws Exception {
httpConfig.withMaxIdleConnectionTimeout(Duration.ofSeconds(17));
httpConfig.withNetworkRequestTimeout(Duration.ofSeconds(18));
diagnosticsClientConfig.withGatewayHttpClientConfig(httpConfig.toDiagnosticsString());
+ diagnosticsClientConfig.withClientMap(new HashMap<>());
Mockito.doReturn(diagnosticsClientConfig).when(clientContext).getConfig();
@@ -139,6 +143,7 @@ public void full() throws Exception {
diagnosticsClientConfig.withPreferredRegions(ImmutableList.of("west us 1", "west us 2"));
diagnosticsClientConfig.withConnectionSharingAcrossClientsEnabled(true);
diagnosticsClientConfig.withEndpointDiscoveryEnabled(true);
+ diagnosticsClientConfig.withClientMap(new HashMap<>());
Mockito.doReturn(diagnosticsClientConfig).when(clientContext).getConfig();
diff --git a/sdk/cosmos/azure-cosmos/src/test/java/com/azure/cosmos/implementation/caches/AsyncCacheNonBlockingTest.java b/sdk/cosmos/azure-cosmos/src/test/java/com/azure/cosmos/implementation/caches/AsyncCacheNonBlockingTest.java
index c905b63dd3f51..ef246c9cd7b7a 100644
--- a/sdk/cosmos/azure-cosmos/src/test/java/com/azure/cosmos/implementation/caches/AsyncCacheNonBlockingTest.java
+++ b/sdk/cosmos/azure-cosmos/src/test/java/com/azure/cosmos/implementation/caches/AsyncCacheNonBlockingTest.java
@@ -7,6 +7,7 @@
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
+import java.time.Duration;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;
@@ -15,7 +16,7 @@
import static org.assertj.core.api.Assertions.assertThat;
public class AsyncCacheNonBlockingTest {
- private static final int TIMEOUT = 2000;
+ private static final int TIMEOUT = 20000;
@Test(groups = {"unit"}, timeOut = TIMEOUT)
public void getAsync() {
@@ -80,6 +81,40 @@ public void getAsync() {
assertThat(numberOfCacheRefreshes.get()).isEqualTo(20);
// verify that we still have the old value in the cache
assertThat(cache.getAsync(2, value -> refreshFunc2.apply(2), forceRefresh -> false).block()).isEqualTo(5);
+ }
+
+ @Test(groups = {"unit"}, timeOut = TIMEOUT)
+ public void refreshAsync() throws InterruptedException {
+ AtomicInteger numberOfCacheRefreshes = new AtomicInteger(0);
+ final Function> refreshFunc = key -> {
+ return Mono.just(key * 2)
+ .doOnNext(t -> {
+ numberOfCacheRefreshes.incrementAndGet();
+ });
+ };
+
+ AsyncCacheNonBlocking cache = new AsyncCacheNonBlocking<>();
+ // populate the cache
+ int cacheKey = 1;
+ cache.getAsync(cacheKey, value -> refreshFunc.apply(cacheKey), forceRefresh -> false).block();
+ assertThat(numberOfCacheRefreshes.get()).isEqualTo(1);
+
+ // refresh the cache, since there is no refresh in progress, it will start a new one
+ Function> refreshFuncWithDelay = key -> {
+ return Mono.just(key * 2)
+ .doOnNext(t -> numberOfCacheRefreshes.incrementAndGet())
+ .delayElement(Duration.ofMinutes(5));
+ };
+
+ cache.refresh(cacheKey, refreshFuncWithDelay);
+ //since the refresh happens asynchronously, so wait for sometime
+ Thread.sleep(100);
+ assertThat(numberOfCacheRefreshes.get()).isEqualTo(2);
+ // start another refresh, since there is a refresh in progress, so it will not start a new one
+ cache.refresh(cacheKey, refreshFunc);
+ //since the refresh happens asynchronously, so wait for sometime
+ Thread.sleep(100);
+ assertThat(numberOfCacheRefreshes.get()).isEqualTo(2);
}
}
diff --git a/sdk/cosmos/azure-cosmos/src/test/java/com/azure/cosmos/implementation/directconnectivity/ConnectionStateListenerTest.java b/sdk/cosmos/azure-cosmos/src/test/java/com/azure/cosmos/implementation/directconnectivity/ConnectionStateListenerTest.java
index b9bddc9e8b819..b8ee6a722b4cb 100644
--- a/sdk/cosmos/azure-cosmos/src/test/java/com/azure/cosmos/implementation/directconnectivity/ConnectionStateListenerTest.java
+++ b/sdk/cosmos/azure-cosmos/src/test/java/com/azure/cosmos/implementation/directconnectivity/ConnectionStateListenerTest.java
@@ -11,10 +11,10 @@
import com.azure.cosmos.implementation.ResourceType;
import com.azure.cosmos.implementation.RxDocumentServiceRequest;
import com.azure.cosmos.implementation.UserAgentContainer;
-import com.azure.cosmos.implementation.directconnectivity.TcpServerMock.TcpServerFactory;
-import com.azure.cosmos.implementation.directconnectivity.TcpServerMock.TcpServer;
import com.azure.cosmos.implementation.directconnectivity.TcpServerMock.RequestResponseType;
import com.azure.cosmos.implementation.directconnectivity.TcpServerMock.SslContextUtils;
+import com.azure.cosmos.implementation.directconnectivity.TcpServerMock.TcpServer;
+import com.azure.cosmos.implementation.directconnectivity.TcpServerMock.TcpServerFactory;
import com.azure.cosmos.implementation.routing.PartitionKeyRangeIdentity;
import io.netty.handler.ssl.SslContext;
import org.mockito.Mockito;
@@ -30,6 +30,7 @@
import java.util.concurrent.atomic.AtomicInteger;
import static com.azure.cosmos.implementation.TestUtils.mockDiagnosticsClientContext;
+import static org.assertj.core.api.Assertions.assertThat;
public class ConnectionStateListenerTest {
private static final Logger logger = LoggerFactory.getLogger(ConnectionStateListenerTest.class);
@@ -42,13 +43,13 @@ public class ConnectionStateListenerTest {
@DataProvider(name = "connectionStateListenerConfigProvider")
public Object[][] connectionStateListenerConfigProvider() {
return new Object[][]{
- // isTcpConnectionEndpointRediscoveryEnabled, serverResponseType, updateAddresses() called times on request, updateAddresses() called times when server shutdown
- {true, RequestResponseType.CHANNEL_FIN, 1, 0},
- {false, RequestResponseType.CHANNEL_FIN, 0, 0},
- {true, RequestResponseType.CHANNEL_RST, 0, 0},
- {false, RequestResponseType.CHANNEL_RST, 0, 0},
- {true, RequestResponseType.NONE, 0, 1}, // the request will be timed out, but the connection will be active. When tcp server shutdown, the connection will be closed gracefully
- {false, RequestResponseType.NONE, 0, 0},
+ // isTcpConnectionEndpointRediscoveryEnabled, serverResponseType, replicaStatusUpdated, replicaStatusUpdated when server shutdown
+ {true, RequestResponseType.CHANNEL_FIN, true, false},
+ {false, RequestResponseType.CHANNEL_FIN, false, false},
+ {true, RequestResponseType.CHANNEL_RST, false, false},
+ {false, RequestResponseType.CHANNEL_RST, false, false},
+ {true, RequestResponseType.NONE, false, true}, // the request will be timed out, but the connection will be active. When tcp server shutdown, the connection will be closed gracefully
+ {false, RequestResponseType.NONE, false, false},
};
}
@@ -56,8 +57,8 @@ public Object[][] connectionStateListenerConfigProvider() {
public void connectionStateListener_OnConnectionEvent(
boolean isTcpConnectionEndpointRediscoveryEnabled,
RequestResponseType responseType,
- int timesOnRequest,
- int timesOnServerShutdown) throws ExecutionException, InterruptedException {
+ boolean markUnhealthy,
+ boolean markUnhealthyWhenServerShutdown) throws ExecutionException, InterruptedException {
// using a random generated server port
int serverPort = port + randomPort.getAndIncrement();
@@ -96,12 +97,21 @@ public void connectionStateListener_OnConnectionEvent(
logger.info("expected failed request with reason {}", e);
}
- Mockito.verify(addressResolver, Mockito.times(timesOnRequest)).updateAddresses(Mockito.any());
+ if (markUnhealthy) {
+ assertThat(targetUri.getHealthStatus()).isEqualTo(Uri.HealthStatus.Unhealthy);
+ TcpServerFactory.shutdownRntbdServer(server);
+ assertThat(targetUri.getHealthStatus()).isEqualTo(Uri.HealthStatus.Unhealthy);
- Mockito.clearInvocations(addressResolver);
+ } else {
+ assertThat(targetUri.getHealthStatus()).isEqualTo(Uri.HealthStatus.Connected);
- TcpServerFactory.shutdownRntbdServer(server);
- Mockito.verify(addressResolver, Mockito.times(timesOnServerShutdown)).updateAddresses(Mockito.any());
+ TcpServerFactory.shutdownRntbdServer(server);
+ if (markUnhealthyWhenServerShutdown) {
+ assertThat(targetUri.getHealthStatus()).isEqualTo(Uri.HealthStatus.Unhealthy);
+ } else {
+ assertThat(targetUri.getHealthStatus()).isEqualTo(Uri.HealthStatus.Connected);
+ }
+ }
}
private Document getDocumentDefinition() {
diff --git a/sdk/cosmos/azure-cosmos/src/test/java/com/azure/cosmos/implementation/directconnectivity/GatewayAddressCacheTest.java b/sdk/cosmos/azure-cosmos/src/test/java/com/azure/cosmos/implementation/directconnectivity/GatewayAddressCacheTest.java
index 1bab56dc0df5d..a6f6f6ddae92a 100644
--- a/sdk/cosmos/azure-cosmos/src/test/java/com/azure/cosmos/implementation/directconnectivity/GatewayAddressCacheTest.java
+++ b/sdk/cosmos/azure-cosmos/src/test/java/com/azure/cosmos/implementation/directconnectivity/GatewayAddressCacheTest.java
@@ -55,6 +55,7 @@
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
+import java.util.Set;
import java.util.UUID;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
@@ -64,6 +65,7 @@
import static com.azure.cosmos.implementation.TestUtils.mockDiagnosticsClientContext;
import static com.azure.cosmos.implementation.directconnectivity.Uri.HealthStatus.Connected;
import static com.azure.cosmos.implementation.directconnectivity.Uri.HealthStatus.UnhealthyPending;
+import static com.azure.cosmos.implementation.directconnectivity.Uri.HealthStatus.Unknown;
import static org.assertj.core.api.Assertions.assertThat;
public class GatewayAddressCacheTest extends TestSuiteBase {
@@ -105,9 +107,11 @@ public Object[][] protocolProvider() {
@DataProvider(name = "replicaValidationArgsProvider")
public Object[][] replicaValidationArgsProvider() {
return new Object[][]{
- // replica validation is enabled
- { false },
- { true },
+ // replicaValidationIsEnabled, openConnectionsAndInitCaches
+ { false, false },
+ { false, true },
+ { true, false },
+ { true, true },
};
}
@@ -126,7 +130,6 @@ public void getServerAddressesViaGateway(List partitionKeyRangeIds,
authorizationTokenProvider,
null,
getHttpClient(configs),
- false,
null,
null,
ConnectionPolicy.getDefaultPolicy(),
@@ -164,7 +167,6 @@ public void getMasterAddressesViaGatewayAsync(Protocol protocol) throws Exceptio
authorizationTokenProvider,
null,
getHttpClient(configs),
- false,
null,
null,
ConnectionPolicy.getDefaultPolicy(),
@@ -213,7 +215,6 @@ public void tryGetAddresses_ForDataPartitions(String partitionKeyRangeId, String
authorizationTokenProvider,
null,
getHttpClient(configs),
- false,
null,
null,
ConnectionPolicy.getDefaultPolicy(),
@@ -240,63 +241,6 @@ public void tryGetAddresses_ForDataPartitions(String partitionKeyRangeId, String
assertSameAs(addressInfosFromCache, expectedAddresses);
}
- @Test(groups = { "direct" }, dataProvider = "targetPartitionsKeyRangeAndCollectionLinkParams", timeOut = TIMEOUT)
- public void tryGetAddress_OnConnectionEvent_Refresh(String partitionKeyRangeId, String collectionLink, Protocol protocol) throws Exception {
-
- Configs configs = ConfigsBuilder.instance().withProtocol(protocol).build();
- URI serviceEndpoint = new URI(TestConfigurations.HOST);
- IAuthorizationTokenProvider authorizationTokenProvider = (RxDocumentClientImpl) client;
- HttpClientUnderTestWrapper httpClientWrapper = getHttpClientUnderTestWrapper(configs);
-
- GatewayAddressCache cache = new GatewayAddressCache(
- mockDiagnosticsClientContext(),
- serviceEndpoint,
- protocol,
- authorizationTokenProvider,
- null,
- httpClientWrapper.getSpyHttpClient(),
- true,
- null,
- null,
- ConnectionPolicy.getDefaultPolicy(),
- null);
-
- RxDocumentServiceRequest req =
- RxDocumentServiceRequest.create(mockDiagnosticsClientContext(), OperationType.Create, ResourceType.Document,
- collectionLink,
- new Database(), new HashMap<>());
-
- PartitionKeyRangeIdentity partitionKeyRangeIdentity = new PartitionKeyRangeIdentity(createdCollection.getResourceId(), partitionKeyRangeId);
- boolean forceRefreshPartitionAddresses = false;
-
- Mono> addressesInfosFromCacheObs =
- cache.tryGetAddresses(req, partitionKeyRangeIdentity, forceRefreshPartitionAddresses);
-
- ArrayList addressInfosFromCache =
- Lists.newArrayList(getSuccessResult(addressesInfosFromCacheObs, TIMEOUT).v);
-
- assertThat(httpClientWrapper.capturedRequests)
- .describedAs("getAddress will read addresses from gateway")
- .asList().hasSize(1);
-
- httpClientWrapper.capturedRequests.clear();
-
- // for the second request with the same partitionkeyRangeIdentity, the address result should be fetched from the cache
- getSuccessResult(cache.tryGetAddresses(req, partitionKeyRangeIdentity, forceRefreshPartitionAddresses), TIMEOUT);
- assertThat(httpClientWrapper.capturedRequests)
- .describedAs("getAddress should read from cache")
- .asList().hasSize(0);
-
- httpClientWrapper.capturedRequests.clear();
-
- // Now emulate onConnectionEvent happened, and the address should be removed from the cache
- cache.updateAddresses(addressInfosFromCache.get(0).getServerKey());
- getSuccessResult(cache.tryGetAddresses(req, partitionKeyRangeIdentity, forceRefreshPartitionAddresses), TIMEOUT);
- assertThat(httpClientWrapper.capturedRequests)
- .describedAs("getAddress will read addresses from gateway after onConnectionEvent")
- .asList().hasSize(1);
- }
-
@DataProvider(name = "openAsyncTargetAndTargetPartitionsKeyRangeAndCollectionLinkParams")
public Object[][] openAsyncTargetAndPartitionsKeyRangeTargetAndCollectionLinkParams() {
return new Object[][] {
@@ -329,7 +273,6 @@ public void tryGetAddresses_ForDataPartitions_AddressCachedByOpenAsync_NoHttpReq
authorizationTokenProvider,
null,
httpClientWrapper.getSpyHttpClient(),
- false,
null,
null,
ConnectionPolicy.getDefaultPolicy(),
@@ -394,7 +337,6 @@ public void tryGetAddresses_ForDataPartitions_ForceRefresh(
authorizationTokenProvider,
null,
httpClientWrapper.getSpyHttpClient(),
- false,
null,
null,
ConnectionPolicy.getDefaultPolicy(),
@@ -462,7 +404,6 @@ public void tryGetAddresses_ForDataPartitions_Suboptimal_Refresh(
null,
httpClientWrapper.getSpyHttpClient(),
suboptimalRefreshTime,
- false,
null,
null,
ConnectionPolicy.getDefaultPolicy(),
@@ -576,7 +517,6 @@ public void tryGetAddresses_ForMasterPartition(Protocol protocol) throws Excepti
authorizationTokenProvider,
null,
getHttpClient(configs),
- false,
null,
null,
ConnectionPolicy.getDefaultPolicy(),
@@ -628,7 +568,6 @@ public void tryGetAddresses_ForMasterPartition_MasterPartitionAddressAlreadyCach
null,
clientWrapper.getSpyHttpClient(),
suboptimalPartitionForceRefreshIntervalInSeconds,
- false,
null,
null,
ConnectionPolicy.getDefaultPolicy(),
@@ -679,7 +618,6 @@ public void tryGetAddresses_ForMasterPartition_ForceRefresh() throws Exception {
authorizationTokenProvider,
null,
clientWrapper.getSpyHttpClient(),
- false,
null,
null,
ConnectionPolicy.getDefaultPolicy(),
@@ -737,7 +675,6 @@ public void tryGetAddresses_SuboptimalMasterPartition_NotStaleEnough_NoRefresh()
null,
clientWrapper.getSpyHttpClient(),
refreshPeriodInSeconds,
- false,
ApiType.SQL,
null,
ConnectionPolicy.getDefaultPolicy(),
@@ -835,7 +772,6 @@ public void tryGetAddresses_SuboptimalMasterPartition_Stale_DoRefresh() throws E
null,
clientWrapper.getSpyHttpClient(),
refreshPeriodInSeconds,
- false,
null,
null,
ConnectionPolicy.getDefaultPolicy(),
@@ -928,7 +864,7 @@ public Mono> answer(InvocationOnMock invocationOnMock) throws Thro
@SuppressWarnings("unchecked")
@Test(groups = { "direct" }, dataProvider = "replicaValidationArgsProvider", timeOut = TIMEOUT)
- public void tryGetAddress_replicaValidationTests(boolean replicaValidationEnabled) throws Exception {
+ public void tryGetAddress_replicaValidationTests(boolean replicaValidationEnabled, boolean openConnectionAndInitCaches) throws Exception {
Configs configs = ConfigsBuilder.instance().withProtocol(Protocol.TCP).build();
URI serviceEndpoint = new URI(TestConfigurations.HOST);
IAuthorizationTokenProvider authorizationTokenProvider = (RxDocumentClientImpl) client;
@@ -951,7 +887,6 @@ public void tryGetAddress_replicaValidationTests(boolean replicaValidationEnable
authorizationTokenProvider,
null,
httpClientWrapper.getSpyHttpClient(),
- true,
null,
null,
ConnectionPolicy.getDefaultPolicy(),
@@ -966,8 +901,15 @@ public void tryGetAddress_replicaValidationTests(boolean replicaValidationEnable
new Database(),
new HashMap<>());
+ if (openConnectionAndInitCaches) {
+ List pkriList = Arrays.asList(new PartitionKeyRangeIdentity("0"));
+ cache.openConnectionsAndInitCaches(createdCollection, pkriList).blockLast();
+ Mockito.clearInvocations(openConnectionsHandlerMock);
+ httpClientWrapper.capturedRequests.clear();
+ }
+
PartitionKeyRangeIdentity partitionKeyRangeIdentity = new PartitionKeyRangeIdentity(createdCollection.getResourceId(), "0");
- boolean forceRefreshPartitionAddresses = false;
+ boolean forceRefreshPartitionAddresses = true;
Mono> addressesInfosFromCacheObs =
cache.tryGetAddresses(req, partitionKeyRangeIdentity, forceRefreshPartitionAddresses);
@@ -982,21 +924,38 @@ public void tryGetAddress_replicaValidationTests(boolean replicaValidationEnable
if (replicaValidationEnabled) {
ArgumentCaptor> openConnectionArguments = ArgumentCaptor.forClass(List.class);
- // Open connection will only be called for unhealthyPending status address
- Mockito.verify(openConnectionsHandlerMock, Mockito.times(0)).openConnections(openConnectionArguments.capture());
+ if (openConnectionAndInitCaches) {
+ // If openConnectionAndInitCaches is called, then replica validation will also include for unknown status
+ Mockito.verify(openConnectionsHandlerMock, Mockito.times(1)).openConnections(openConnectionArguments.capture());
+ assertThat(openConnectionArguments.getValue()).hasSize(addressInfosFromCache.size());
+ } else {
+ // Open connection will only be called for unhealthyPending status address
+ Mockito.verify(openConnectionsHandlerMock, Mockito.times(0)).openConnections(openConnectionArguments.capture());
+ }
} else {
Mockito.verify(openConnectionsHandlerMock, Mockito.never()).openConnections(Mockito.any());
}
- // Mark one of the uri as unhealthy, others as connected
- // and then force refresh the addresses again, make sure the health status of the uri is reserved
httpClientWrapper.capturedRequests.clear();
Mockito.clearInvocations(openConnectionsHandlerMock);
- for (AddressInformation address : addressInfosFromCache) {
- address.getPhysicalUri().setConnected();
+
+ // Mark one of the uri as unhealthy, one as unknown, others as connected
+ // and then force refresh the addresses again, make sure the health status of the uri is reserved
+ assertThat(addressInfosFromCache.size()).isGreaterThan(2);
+ Uri unknownAddressUri = null;
+ Uri unhealthyAddressUri = null;
+ for (int i = 0; i < addressInfosFromCache.size(); i++) {
+ if (i == 0) {
+ unknownAddressUri = addressInfosFromCache.get(0).getPhysicalUri();
+ continue;
+ }
+ if (i == 1) {
+ unhealthyAddressUri = addressInfosFromCache.get(1).getPhysicalUri();
+ unhealthyAddressUri.setUnhealthy();
+ } else {
+ addressInfosFromCache.get(i).getPhysicalUri().setConnected();
+ }
}
- Uri unhealthyAddressUri = addressInfosFromCache.get(0).getPhysicalUri();
- unhealthyAddressUri.setUnhealthy();
ArrayList refreshedAddresses =
Lists.newArrayList(getSuccessResult(cache.tryGetAddresses(req, partitionKeyRangeIdentity, true), TIMEOUT).v);
@@ -1007,9 +966,12 @@ public void tryGetAddress_replicaValidationTests(boolean replicaValidationEnable
// validate connected status will be reserved
// validate unhealthy status will change into unhealthyPending status
- // validate openConnection will only be called for addresses not in connected status
+ // Validate openConnection will be called for addresses in unhealthyPending status
+ // Validate openConnection will be called for addresses in unknown status if openConnectionAndInitCaches is called
for (AddressInformation addressInformation : refreshedAddresses) {
- if (addressInformation.getPhysicalUri().equals(unhealthyAddressUri)) {
+ if (addressInformation.getPhysicalUri().equals(unknownAddressUri)) {
+ assertThat(addressInformation.getPhysicalUri().getHealthStatus()).isEqualTo(Unknown);
+ } else if (addressInformation.getPhysicalUri().equals(unhealthyAddressUri)) {
assertThat(addressInformation.getPhysicalUri().getHealthStatus()).isEqualTo(UnhealthyPending);
} else {
assertThat(addressInformation.getPhysicalUri().getHealthStatus()).isEqualTo(Connected);
@@ -1019,8 +981,12 @@ public void tryGetAddress_replicaValidationTests(boolean replicaValidationEnable
if (replicaValidationEnabled) {
ArgumentCaptor> openConnectionArguments = ArgumentCaptor.forClass(List.class);
Mockito.verify(openConnectionsHandlerMock, Mockito.times(1)).openConnections(openConnectionArguments.capture());
+ if (openConnectionAndInitCaches) {
+ assertThat(openConnectionArguments.getValue()).containsExactlyElementsOf(Arrays.asList(unhealthyAddressUri, unknownAddressUri));
+ } else {
+ assertThat(openConnectionArguments.getValue()).containsExactly(unhealthyAddressUri);
+ }
- assertThat(openConnectionArguments.getValue()).hasSize(1).containsExactly(unhealthyAddressUri);
} else {
Mockito.verify(openConnectionsHandlerMock, Mockito.never()).openConnections(Mockito.any());
}
@@ -1044,7 +1010,6 @@ public void tryGetAddress_failedEndpointTests() throws Exception {
authorizationTokenProvider,
null,
httpClientWrapper.getSpyHttpClient(),
- true,
null,
null,
ConnectionPolicy.getDefaultPolicy(),
@@ -1107,7 +1072,6 @@ public void tryGetAddress_unhealthyStatus_forceRefresh() throws Exception {
authorizationTokenProvider,
null,
httpClientWrapper.getSpyHttpClient(),
- true,
null,
null,
ConnectionPolicy.getDefaultPolicy(),
@@ -1151,6 +1115,9 @@ public void tryGetAddress_unhealthyStatus_forceRefresh() throws Exception {
ArrayList cachedAddresses =
Lists.newArrayList(getSuccessResult(cache.tryGetAddresses(req, partitionKeyRangeIdentity, false), TIMEOUT).v);
+ // since the refresh will happen asynchronously in the background, wait here some time for it to happen
+ Thread.sleep(500);
+
// validate the cache will be refreshed
assertThat(httpClientWrapper.capturedRequests)
.describedAs("getAddress will read addresses from gateway")
@@ -1175,7 +1142,6 @@ public void validateReplicaAddressesTests() throws URISyntaxException, NoSuchMet
authorizationTokenProvider,
null,
httpClientWrapper.getSpyHttpClient(),
- true,
null,
null,
ConnectionPolicy.getDefaultPolicy(),
@@ -1188,7 +1154,7 @@ public void validateReplicaAddressesTests() throws URISyntaxException, NoSuchMet
AddressInformation address1 = new AddressInformation(true, true, "rntbd://127.0.0.1:1", Protocol.TCP);
address1.getPhysicalUri().setConnected();
- // remain in unknwon status
+ // remain in unknown status
AddressInformation address2 = new AddressInformation(true, false, "rntbd://127.0.0.1:2", Protocol.TCP);
// unhealthy status
@@ -1200,14 +1166,19 @@ public void validateReplicaAddressesTests() throws URISyntaxException, NoSuchMet
AtomicReference healthStatus = ReflectionUtils.getHealthStatus(address4.getPhysicalUri());
healthStatus.set(UnhealthyPending);
+ // Set the replica validation scope
+ Set replicaValidationScopes = ReflectionUtils.getReplicaValidationScopes(cache);
+ replicaValidationScopes.add(Unknown);
+ replicaValidationScopes.add(UnhealthyPending);
+
validateReplicaAddressesMethod.invoke(cache, new Object[]{ new AddressInformation[]{ address1, address2, address3, address4 }}) ;
// Validate openConnection will only be called for address in unhealthyPending status
ArgumentCaptor> openConnectionArguments = ArgumentCaptor.forClass(List.class);
Mockito.verify(openConnectionsHandlerMock, Mockito.times(1)).openConnections(openConnectionArguments.capture());
- assertThat(openConnectionArguments.getValue()).hasSize(1).containsExactlyElementsOf(
- Arrays.asList(address4)
+ assertThat(openConnectionArguments.getValue()).containsExactlyElementsOf(
+ Arrays.asList(address4, address2)
.stream()
.map(addressInformation -> addressInformation.getPhysicalUri())
.collect(Collectors.toList()));
@@ -1230,7 +1201,6 @@ public void mergeAddressesTests() throws URISyntaxException, NoSuchMethodExcepti
authorizationTokenProvider,
null,
httpClientWrapper.getSpyHttpClient(),
- true,
null,
null,
ConnectionPolicy.getDefaultPolicy(),
diff --git a/sdk/cosmos/azure-cosmos/src/test/java/com/azure/cosmos/implementation/directconnectivity/ReflectionUtils.java b/sdk/cosmos/azure-cosmos/src/test/java/com/azure/cosmos/implementation/directconnectivity/ReflectionUtils.java
index 0c66981c0e618..56dcd9b11160a 100644
--- a/sdk/cosmos/azure-cosmos/src/test/java/com/azure/cosmos/implementation/directconnectivity/ReflectionUtils.java
+++ b/sdk/cosmos/azure-cosmos/src/test/java/com/azure/cosmos/implementation/directconnectivity/ReflectionUtils.java
@@ -49,6 +49,7 @@
import java.lang.reflect.Method;
import java.time.Duration;
import java.util.List;
+import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.Future;
import java.util.concurrent.atomic.AtomicBoolean;
@@ -396,4 +397,9 @@ public static void setClientTelemetryMetadataHttpClient(ClientTelemetry clientTe
public static AtomicReference getHealthStatus(Uri uri) {
return get(AtomicReference.class, uri, "healthStatus");
}
+
+ @SuppressWarnings("unchecked")
+ public static Set getReplicaValidationScopes(GatewayAddressCache gatewayAddressCache) {
+ return get(Set.class, gatewayAddressCache, "replicaValidationScopes");
+ }
}
diff --git a/sdk/e2e/pom.xml b/sdk/e2e/pom.xml
index b530f81560a3d..8c8104cf6ed2e 100644
--- a/sdk/e2e/pom.xml
+++ b/sdk/e2e/pom.xml
@@ -29,12 +29,12 @@
com.azure
azure-core
- 1.32.0-beta.1
+ 1.32.0
com.azure
azure-core-http-netty
- 1.13.0-beta.1
+ 1.12.5
com.azure
@@ -70,7 +70,7 @@
com.azure
azure-core-test
- 1.12.0-beta.1
+ 1.12.0
test
diff --git a/sdk/storage/azure-storage-blob/src/main/java/com/azure/storage/blob/BlobContainerAsyncClient.java b/sdk/storage/azure-storage-blob/src/main/java/com/azure/storage/blob/BlobContainerAsyncClient.java
index 0f3b5221ae664..a87c44140b1d1 100644
--- a/sdk/storage/azure-storage-blob/src/main/java/com/azure/storage/blob/BlobContainerAsyncClient.java
+++ b/sdk/storage/azure-storage-blob/src/main/java/com/azure/storage/blob/BlobContainerAsyncClient.java
@@ -44,7 +44,6 @@
import com.azure.storage.blob.models.TaggedBlobItem;
import com.azure.storage.blob.models.UserDelegationKey;
import com.azure.storage.blob.options.BlobContainerCreateOptions;
-import com.azure.storage.blob.options.BlobContainerRenameOptions;
import com.azure.storage.blob.options.FindBlobsOptions;
import com.azure.storage.blob.sas.BlobServiceSasSignatureValues;
import com.azure.storage.common.StorageSharedKeyCredential;
@@ -1538,80 +1537,44 @@ Mono> getAccountInfoWithResponse(Context context) {
});
}
- /**
- * Renames an existing blob container.
- *
- * Code Samples
- *
- *
- *
- * BlobContainerAsyncClient blobContainerAsyncClient =
- * client.rename("newContainerName")
- * .block();
- *
- *
- *
- * @param destinationContainerName The new name of the container.
- * @return A {@link Mono} containing a {@link BlobContainerAsyncClient} used to interact with the renamed container.
- */
- @ServiceMethod(returns = ReturnType.SINGLE)
- public Mono rename(String destinationContainerName) {
- return renameWithResponse(new BlobContainerRenameOptions(destinationContainerName)).flatMap(FluxUtil::toMono);
- }
-
- /**
- * Renames an existing blob container.
- *
- * Code Samples
- *
- *
- *
- * BlobRequestConditions requestConditions = new BlobRequestConditions().setLeaseId("lease-id");
- * BlobContainerAsyncClient containerClient =
- * client.renameWithResponse(new BlobContainerRenameOptions("newContainerName")
- * .setRequestConditions(requestConditions)).block().getValue();
- *
- *
- *
- * @param options {@link BlobContainerRenameOptions}
- * @return A {@link Mono} containing a {@link Response} whose {@link Response#getValue() value} contains a
- * {@link BlobContainerAsyncClient} used to interact with the renamed container.
- */
- @ServiceMethod(returns = ReturnType.SINGLE)
- public Mono> renameWithResponse(BlobContainerRenameOptions options) {
- try {
- return withContext(context -> this.renameWithResponse(options, context));
- } catch (RuntimeException ex) {
- return monoError(LOGGER, ex);
- }
- }
-
- Mono> renameWithResponse(BlobContainerRenameOptions options, Context context) {
- // TODO (gapra) : Change this when we have migrated to new generator. There will be a cleaner way to do this by
- // calling the container constructor directly instead of needing to do URI surgery
- BlobContainerAsyncClient destinationContainerClient = getServiceAsyncClient()
- .getBlobContainerAsyncClient(options.getDestinationContainerName());
- return destinationContainerClient.renameWithResponseHelper(this.getBlobContainerName(), options, context);
- }
-
- Mono> renameWithResponseHelper(String sourceContainerName,
- BlobContainerRenameOptions options, Context context) {
- StorageImplUtils.assertNotNull("options", options);
- BlobRequestConditions requestConditions = options.getRequestConditions() == null ? new BlobRequestConditions()
- : options.getRequestConditions();
- context = context == null ? Context.NONE : context;
-
- if (!validateNoETag(requestConditions) || !validateNoTime(requestConditions)
- || requestConditions.getTagsConditions() != null) {
- throw LOGGER.logExceptionAsError(new UnsupportedOperationException(
- "Lease-Id is the only HTTP access condition supported for this API"));
- }
-
- return this.azureBlobStorage.getContainers().renameWithResponseAsync(containerName,
- sourceContainerName, null, null, requestConditions.getLeaseId(),
- context.addData(AZ_TRACING_NAMESPACE_KEY, STORAGE_TRACING_NAMESPACE_VALUE))
- .map(response -> new SimpleResponse<>(response, this));
- }
+ // TODO: Reintroduce this API once service starts supporting it.
+// Mono rename(String destinationContainerName) {
+// return renameWithResponse(new BlobContainerRenameOptions(destinationContainerName)).flatMap(FluxUtil::toMono);
+// }
+
+ // TODO: Reintroduce this API once service starts supporting it.
+// Mono> renameWithResponse(BlobContainerRenameOptions options) {
+// try {
+// return withContext(context -> this.renameWithResponse(options, context));
+// } catch (RuntimeException ex) {
+// return monoError(LOGGER, ex);
+// }
+// }
+
+// Mono> renameWithResponse(BlobContainerRenameOptions options, Context context) {
+// BlobContainerAsyncClient destinationContainerClient = getServiceAsyncClient()
+// .getBlobContainerAsyncClient(options.getDestinationContainerName());
+// return destinationContainerClient.renameWithResponseHelper(this.getBlobContainerName(), options, context);
+// }
+
+// Mono> renameWithResponseHelper(String sourceContainerName,
+// BlobContainerRenameOptions options, Context context) {
+// StorageImplUtils.assertNotNull("options", options);
+// BlobRequestConditions requestConditions = options.getRequestConditions() == null ? new BlobRequestConditions()
+// : options.getRequestConditions();
+// context = context == null ? Context.NONE : context;
+//
+// if (!validateNoETag(requestConditions) || !validateNoTime(requestConditions)
+// || requestConditions.getTagsConditions() != null) {
+// throw LOGGER.logExceptionAsError(new UnsupportedOperationException(
+// "Lease-Id is the only HTTP access condition supported for this API"));
+// }
+//
+// return this.azureBlobStorage.getContainers().renameWithResponseAsync(containerName,
+// sourceContainerName, null, null, requestConditions.getLeaseId(),
+// context.addData(AZ_TRACING_NAMESPACE_KEY, STORAGE_TRACING_NAMESPACE_VALUE))
+// .map(response -> new SimpleResponse<>(response, this));
+// }
/**
* Generates a user delegation SAS for the container using the specified {@link BlobServiceSasSignatureValues}.
@@ -1741,11 +1704,11 @@ private static boolean validateNoETag(BlobRequestConditions modifiedRequestCondi
return modifiedRequestConditions.getIfMatch() == null && modifiedRequestConditions.getIfNoneMatch() == null;
}
- private boolean validateNoTime(BlobRequestConditions modifiedRequestConditions) {
- if (modifiedRequestConditions == null) {
- return true;
- }
- return modifiedRequestConditions.getIfModifiedSince() == null
- && modifiedRequestConditions.getIfUnmodifiedSince() == null;
- }
+// private boolean validateNoTime(BlobRequestConditions modifiedRequestConditions) {
+// if (modifiedRequestConditions == null) {
+// return true;
+// }
+// return modifiedRequestConditions.getIfModifiedSince() == null
+// && modifiedRequestConditions.getIfUnmodifiedSince() == null;
+// }
}
diff --git a/sdk/storage/azure-storage-blob/src/main/java/com/azure/storage/blob/BlobContainerClient.java b/sdk/storage/azure-storage-blob/src/main/java/com/azure/storage/blob/BlobContainerClient.java
index 1e602eb290fcf..711ccdd6f7cb9 100644
--- a/sdk/storage/azure-storage-blob/src/main/java/com/azure/storage/blob/BlobContainerClient.java
+++ b/sdk/storage/azure-storage-blob/src/main/java/com/azure/storage/blob/BlobContainerClient.java
@@ -9,7 +9,6 @@
import com.azure.core.http.HttpPipeline;
import com.azure.core.http.rest.PagedIterable;
import com.azure.core.http.rest.Response;
-import com.azure.core.http.rest.SimpleResponse;
import com.azure.core.util.Context;
import com.azure.storage.blob.models.BlobContainerAccessPolicies;
import com.azure.storage.blob.models.BlobContainerProperties;
@@ -23,7 +22,6 @@
import com.azure.storage.blob.models.TaggedBlobItem;
import com.azure.storage.blob.models.UserDelegationKey;
import com.azure.storage.blob.options.BlobContainerCreateOptions;
-import com.azure.storage.blob.options.BlobContainerRenameOptions;
import com.azure.storage.blob.options.FindBlobsOptions;
import com.azure.storage.blob.sas.BlobServiceSasSignatureValues;
import com.azure.storage.common.StorageSharedKeyCredential;
@@ -1053,58 +1051,20 @@ public Response getAccountInfoWithResponse(Duration timeout,
return blockWithOptionalTimeout(response, timeout);
}
- /**
- * Renames an existing blob container.
- *
- * Code Samples
- *
- *
- *
- * BlobContainerClient blobContainerClient = client.rename("newContainerName");
- *
- *
- *
- * @param destinationContainerName The new name of the container.
- * @return A {@link BlobContainerClient} used to interact with the renamed container.
- */
- @ServiceMethod(returns = ReturnType.SINGLE)
- public BlobContainerClient rename(String destinationContainerName) {
- return renameWithResponse(new BlobContainerRenameOptions(destinationContainerName
- ), null, Context.NONE).getValue();
- }
-
- /**
- * Renames an existing blob container.
- *
- * Code Samples
- *
- *
- *
- * BlobRequestConditions requestConditions = new BlobRequestConditions().setLeaseId("lease-id");
- * Context context = new Context("Key", "Value");
- *
- * BlobContainerClient blobContainerClient = client.renameWithResponse(
- * new BlobContainerRenameOptions("newContainerName")
- * .setRequestConditions(requestConditions),
- * Duration.ofSeconds(1),
- * context).getValue();
- *
- *
- *
- * @param options {@link BlobContainerRenameOptions}
- * @param timeout An optional timeout value beyond which a {@link RuntimeException} will be raised.
- * @param context Additional context that is passed through the Http pipeline during the service call.
- * @return A {@link Response} whose {@link Response#getValue() value} contains a
- * {@link BlobContainerClient} used to interact with the renamed container.
- */
- @ServiceMethod(returns = ReturnType.SINGLE)
- public Response renameWithResponse(BlobContainerRenameOptions options, Duration timeout,
- Context context) {
- Mono> response = this.client.renameWithResponse(options, context)
- .map(r -> new SimpleResponse<>(r, new BlobContainerClient(r.getValue())));
+ // TODO: Reintroduce this API once service starts supporting it.
+// BlobContainerClient rename(String destinationContainerName) {
+// return renameWithResponse(new BlobContainerRenameOptions(destinationContainerName
+// ), null, Context.NONE).getValue();
+// }
- return StorageImplUtils.blockWithOptionalTimeout(response, timeout);
- }
+ // TODO: Reintroduce this API once service starts supporting it.
+// Response renameWithResponse(BlobContainerRenameOptions options, Duration timeout,
+// Context context) {
+// Mono> response = this.client.renameWithResponse(options, context)
+// .map(r -> new SimpleResponse<>(r, new BlobContainerClient(r.getValue())));
+//
+// return StorageImplUtils.blockWithOptionalTimeout(response, timeout);
+// }
/**
* Generates a user delegation SAS for the container using the specified {@link BlobServiceSasSignatureValues}.
diff --git a/sdk/storage/azure-storage-blob/src/samples/java/com/azure/storage/blob/BlobContainerAsyncClientJavaDocCodeSnippets.java b/sdk/storage/azure-storage-blob/src/samples/java/com/azure/storage/blob/BlobContainerAsyncClientJavaDocCodeSnippets.java
index c6f2644a4ab96..07fab9945be48 100644
--- a/sdk/storage/azure-storage-blob/src/samples/java/com/azure/storage/blob/BlobContainerAsyncClientJavaDocCodeSnippets.java
+++ b/sdk/storage/azure-storage-blob/src/samples/java/com/azure/storage/blob/BlobContainerAsyncClientJavaDocCodeSnippets.java
@@ -12,7 +12,6 @@
import com.azure.storage.blob.models.PublicAccessType;
import com.azure.storage.blob.models.UserDelegationKey;
import com.azure.storage.blob.options.BlobContainerCreateOptions;
-import com.azure.storage.blob.options.BlobContainerRenameOptions;
import com.azure.storage.blob.options.FindBlobsOptions;
import com.azure.storage.blob.sas.BlobContainerSasPermission;
import com.azure.storage.blob.sas.BlobServiceSasSignatureValues;
@@ -492,26 +491,26 @@ public void deleteIfExistsCodeSnippets() {
// END: com.azure.storage.blob.BlobContainerAsyncClient.deleteIfExistsWithResponse#BlobRequestConditions
}
- /**
- * Code snippet for {@link BlobContainerAsyncClient#rename(String)}
- */
- public void renameContainer() {
- // BEGIN: com.azure.storage.blob.BlobContainerAsyncClient.rename#String
- BlobContainerAsyncClient blobContainerAsyncClient =
- client.rename("newContainerName")
- .block();
- // END: com.azure.storage.blob.BlobContainerAsyncClient.rename#String
- }
-
- /**
- * Code snippet for {@link BlobContainerAsyncClient#renameWithResponse(BlobContainerRenameOptions)}
- */
- public void renameContainerWithResponse() {
- // BEGIN: com.azure.storage.blob.BlobContainerAsyncClient.renameWithResponse#BlobContainerRenameOptions
- BlobRequestConditions requestConditions = new BlobRequestConditions().setLeaseId("lease-id");
- BlobContainerAsyncClient containerClient =
- client.renameWithResponse(new BlobContainerRenameOptions("newContainerName")
- .setRequestConditions(requestConditions)).block().getValue();
- // END: com.azure.storage.blob.BlobContainerAsyncClient.renameWithResponse#BlobContainerRenameOptions
- }
+// /**
+// * Code snippet for {@link BlobContainerAsyncClient#rename(String)}
+// */
+// public void renameContainer() {
+// // BEGIN: com.azure.storage.blob.BlobContainerAsyncClient.rename#String
+// BlobContainerAsyncClient blobContainerAsyncClient =
+// client.rename("newContainerName")
+// .block();
+// // END: com.azure.storage.blob.BlobContainerAsyncClient.rename#String
+// }
+//
+// /**
+// * Code snippet for {@link BlobContainerAsyncClient#renameWithResponse(BlobContainerRenameOptions)}
+// */
+// public void renameContainerWithResponse() {
+// // BEGIN: com.azure.storage.blob.BlobContainerAsyncClient.renameWithResponse#BlobContainerRenameOptions
+// BlobRequestConditions requestConditions = new BlobRequestConditions().setLeaseId("lease-id");
+// BlobContainerAsyncClient containerClient =
+// client.renameWithResponse(new BlobContainerRenameOptions("newContainerName")
+// .setRequestConditions(requestConditions)).block().getValue();
+// // END: com.azure.storage.blob.BlobContainerAsyncClient.renameWithResponse#BlobContainerRenameOptions
+// }
}
diff --git a/sdk/storage/azure-storage-blob/src/samples/java/com/azure/storage/blob/BlobContainerClientJavaDocCodeSnippets.java b/sdk/storage/azure-storage-blob/src/samples/java/com/azure/storage/blob/BlobContainerClientJavaDocCodeSnippets.java
index 5974a696d31c3..874bb9b6d688d 100644
--- a/sdk/storage/azure-storage-blob/src/samples/java/com/azure/storage/blob/BlobContainerClientJavaDocCodeSnippets.java
+++ b/sdk/storage/azure-storage-blob/src/samples/java/com/azure/storage/blob/BlobContainerClientJavaDocCodeSnippets.java
@@ -18,7 +18,6 @@
import com.azure.storage.blob.models.StorageAccountInfo;
import com.azure.storage.blob.models.UserDelegationKey;
import com.azure.storage.blob.options.BlobContainerCreateOptions;
-import com.azure.storage.blob.options.BlobContainerRenameOptions;
import com.azure.storage.blob.options.FindBlobsOptions;
import com.azure.storage.blob.sas.BlobContainerSasPermission;
import com.azure.storage.blob.sas.BlobServiceSasSignatureValues;
@@ -511,28 +510,28 @@ public void deleteIfExistsCodeSnippets() {
// END: com.azure.storage.blob.BlobContainerClient.deleteIfExistsWithResponse#BlobRequestConditions-Duration-Context
}
- /**
- * Code snippet for {@link BlobContainerClient#rename(String)}
- */
- public void renameContainer() {
- // BEGIN: com.azure.storage.blob.BlobContainerClient.rename#String
- BlobContainerClient blobContainerClient = client.rename("newContainerName");
- // END: com.azure.storage.blob.BlobContainerClient.rename#String
- }
-
- /**
- * Code snippet for {@link BlobContainerClient#renameWithResponse(BlobContainerRenameOptions, Duration, Context)}
- */
- public void renameContainerWithResponse() {
- // BEGIN: com.azure.storage.blob.BlobContainerClient.renameWithResponse#BlobContainerRenameOptions-Duration-Context
- BlobRequestConditions requestConditions = new BlobRequestConditions().setLeaseId("lease-id");
- Context context = new Context("Key", "Value");
-
- BlobContainerClient blobContainerClient = client.renameWithResponse(
- new BlobContainerRenameOptions("newContainerName")
- .setRequestConditions(requestConditions),
- Duration.ofSeconds(1),
- context).getValue();
- // END: com.azure.storage.blob.BlobContainerClient.renameWithResponse#BlobContainerRenameOptions-Duration-Context
- }
+// /**
+// * Code snippet for {@link BlobContainerClient#rename(String)}
+// */
+// public void renameContainer() {
+// // BEGIN: com.azure.storage.blob.BlobContainerClient.rename#String
+// BlobContainerClient blobContainerClient = client.rename("newContainerName");
+// // END: com.azure.storage.blob.BlobContainerClient.rename#String
+// }
+//
+// /**
+// * Code snippet for {@link BlobContainerClient#renameWithResponse(BlobContainerRenameOptions, Duration, Context)}
+// */
+// public void renameContainerWithResponse() {
+// // BEGIN: com.azure.storage.blob.BlobContainerClient.renameWithResponse#BlobContainerRenameOptions-Duration-Context
+// BlobRequestConditions requestConditions = new BlobRequestConditions().setLeaseId("lease-id");
+// Context context = new Context("Key", "Value");
+//
+// BlobContainerClient blobContainerClient = client.renameWithResponse(
+// new BlobContainerRenameOptions("newContainerName")
+// .setRequestConditions(requestConditions),
+// Duration.ofSeconds(1),
+// context).getValue();
+// // END: com.azure.storage.blob.BlobContainerClient.renameWithResponse#BlobContainerRenameOptions-Duration-Context
+// }
}
diff --git a/sdk/storage/azure-storage-blob/src/test/java/com/azure/storage/blob/ContainerAPITest.groovy b/sdk/storage/azure-storage-blob/src/test/java/com/azure/storage/blob/ContainerAPITest.groovy
index 1e9822fbe83fd..e47710166b7b5 100644
--- a/sdk/storage/azure-storage-blob/src/test/java/com/azure/storage/blob/ContainerAPITest.groovy
+++ b/sdk/storage/azure-storage-blob/src/test/java/com/azure/storage/blob/ContainerAPITest.groovy
@@ -28,7 +28,6 @@ import com.azure.storage.blob.models.ObjectReplicationStatus
import com.azure.storage.blob.models.PublicAccessType
import com.azure.storage.blob.models.RehydratePriority
import com.azure.storage.blob.options.BlobContainerCreateOptions
-import com.azure.storage.blob.options.BlobContainerRenameOptions
import com.azure.storage.blob.options.BlobParallelUploadOptions
import com.azure.storage.blob.options.BlobSetAccessTierOptions
import com.azure.storage.blob.options.FindBlobsOptions
@@ -36,10 +35,6 @@ import com.azure.storage.blob.options.PageBlobCreateOptions
import com.azure.storage.blob.specialized.AppendBlobClient
import com.azure.storage.blob.specialized.BlobClientBase
import com.azure.storage.common.Utility
-import com.azure.storage.common.sas.AccountSasPermission
-import com.azure.storage.common.sas.AccountSasResourceType
-import com.azure.storage.common.sas.AccountSasService
-import com.azure.storage.common.sas.AccountSasSignatureValues
import com.azure.storage.common.test.shared.extensions.PlaybackOnly
import com.azure.storage.common.test.shared.extensions.RequiredServiceVersion
import reactor.test.StepVerifier
@@ -2213,115 +2208,117 @@ class ContainerAPITest extends APISpec {
response.getHeaders().getValue("x-ms-version") == "2017-11-09"
}
- def "Rename"() {
- setup:
- def newName = generateContainerName()
-
- when:
- def renamedContainer = cc.rename(newName)
-
- then:
- renamedContainer.getPropertiesWithResponse(null, null, null).getStatusCode() == 200
-
- cleanup:
- renamedContainer.delete()
- }
-
- def "Rename sas"() {
- setup:
- def newName = generateContainerName()
- def service = new AccountSasService()
- .setBlobAccess(true)
- def resourceType = new AccountSasResourceType()
- .setContainer(true)
- .setService(true)
- .setObject(true)
- def expiryTime = namer.getUtcNow().plusDays(1)
- def permissions = new AccountSasPermission()
- .setReadPermission(true)
- .setWritePermission(true)
- .setCreatePermission(true)
- .setDeletePermission(true)
-
- def sasValues = new AccountSasSignatureValues(expiryTime, permissions, service, resourceType)
- def sas = primaryBlobServiceClient.generateAccountSas(sasValues)
- def sasClient = getContainerClient(sas, cc.getBlobContainerUrl())
-
- when:
- def renamedContainer = sasClient.rename(newName)
-
- then:
- renamedContainer.getPropertiesWithResponse(null, null, null).getStatusCode() == 200
-
- cleanup:
- renamedContainer.delete()
- }
-
- @Unroll
- def "Rename AC"() {
- setup:
- leaseID = setupContainerLeaseCondition(cc, leaseID)
- def cac = new BlobRequestConditions()
- .setLeaseId(leaseID)
-
- expect:
- cc.renameWithResponse(new BlobContainerRenameOptions(generateContainerName()).setRequestConditions(cac),
- null, null).getStatusCode() == 200
-
- where:
- leaseID || _
- null || _
- receivedLeaseID || _
- }
-
- @Unroll
- def "Rename AC fail"() {
- setup:
- def cac = new BlobRequestConditions()
- .setLeaseId(leaseID)
-
- when:
- cc.renameWithResponse(new BlobContainerRenameOptions(generateContainerName()).setRequestConditions(cac),
- null, null)
-
- then:
- thrown(BlobStorageException)
-
- where:
- leaseID || _
- garbageLeaseID || _
- }
-
- @Unroll
- def "Rename AC illegal"() {
- setup:
- def ac = new BlobRequestConditions().setIfMatch(match).setIfNoneMatch(noneMatch).setIfModifiedSince(modified).setIfUnmodifiedSince(unmodified).setTagsConditions(tags)
-
- when:
- cc.renameWithResponse(new BlobContainerRenameOptions(generateContainerName()).setRequestConditions(ac),
- null, null)
-
- then:
- thrown(UnsupportedOperationException)
-
- where:
- modified | unmodified | match | noneMatch | tags
- oldDate | null | null | null | null
- null | newDate | null | null | null
- null | null | receivedEtag | null | null
- null | null | null | garbageEtag | null
- null | null | null | null | "tags"
- }
-
- def "Rename error"() {
- setup:
- cc = primaryBlobServiceClient.getBlobContainerClient(generateContainerName())
- def newName = generateContainerName()
-
- when:
- cc.rename(newName)
-
- then:
- thrown(BlobStorageException)
- }
+// TODO: Reintroduce these tests once service starts supporting it.
+
+// def "Rename"() {
+// setup:
+// def newName = generateContainerName()
+//
+// when:
+// def renamedContainer = cc.rename(newName)
+//
+// then:
+// renamedContainer.getPropertiesWithResponse(null, null, null).getStatusCode() == 200
+//
+// cleanup:
+// renamedContainer.delete()
+// }
+
+// def "Rename sas"() {
+// setup:
+// def newName = generateContainerName()
+// def service = new AccountSasService()
+// .setBlobAccess(true)
+// def resourceType = new AccountSasResourceType()
+// .setContainer(true)
+// .setService(true)
+// .setObject(true)
+// def expiryTime = namer.getUtcNow().plusDays(1)
+// def permissions = new AccountSasPermission()
+// .setReadPermission(true)
+// .setWritePermission(true)
+// .setCreatePermission(true)
+// .setDeletePermission(true)
+//
+// def sasValues = new AccountSasSignatureValues(expiryTime, permissions, service, resourceType)
+// def sas = primaryBlobServiceClient.generateAccountSas(sasValues)
+// def sasClient = getContainerClient(sas, cc.getBlobContainerUrl())
+//
+// when:
+// def renamedContainer = sasClient.rename(newName)
+//
+// then:
+// renamedContainer.getPropertiesWithResponse(null, null, null).getStatusCode() == 200
+//
+// cleanup:
+// renamedContainer.delete()
+// }
+
+// @Unroll
+// def "Rename AC"() {
+// setup:
+// leaseID = setupContainerLeaseCondition(cc, leaseID)
+// def cac = new BlobRequestConditions()
+// .setLeaseId(leaseID)
+//
+// expect:
+// cc.renameWithResponse(new BlobContainerRenameOptions(generateContainerName()).setRequestConditions(cac),
+// null, null).getStatusCode() == 200
+//
+// where:
+// leaseID || _
+// null || _
+// receivedLeaseID || _
+// }
+
+// @Unroll
+// def "Rename AC fail"() {
+// setup:
+// def cac = new BlobRequestConditions()
+// .setLeaseId(leaseID)
+//
+// when:
+// cc.renameWithResponse(new BlobContainerRenameOptions(generateContainerName()).setRequestConditions(cac),
+// null, null)
+//
+// then:
+// thrown(BlobStorageException)
+//
+// where:
+// leaseID || _
+// garbageLeaseID || _
+// }
+
+// @Unroll
+// def "Rename AC illegal"() {
+// setup:
+// def ac = new BlobRequestConditions().setIfMatch(match).setIfNoneMatch(noneMatch).setIfModifiedSince(modified).setIfUnmodifiedSince(unmodified).setTagsConditions(tags)
+//
+// when:
+// cc.renameWithResponse(new BlobContainerRenameOptions(generateContainerName()).setRequestConditions(ac),
+// null, null)
+//
+// then:
+// thrown(UnsupportedOperationException)
+//
+// where:
+// modified | unmodified | match | noneMatch | tags
+// oldDate | null | null | null | null
+// null | newDate | null | null | null
+// null | null | receivedEtag | null | null
+// null | null | null | garbageEtag | null
+// null | null | null | null | "tags"
+// }
+
+// def "Rename error"() {
+// setup:
+// cc = primaryBlobServiceClient.getBlobContainerClient(generateContainerName())
+// def newName = generateContainerName()
+//
+// when:
+// cc.rename(newName)
+//
+// then:
+// thrown(BlobStorageException)
+// }
}
diff --git a/sdk/storage/azure-storage-blob/src/test/resources/session-records/ContainerAPITestRename.json b/sdk/storage/azure-storage-blob/src/test/resources/session-records/ContainerAPITestRename.json
deleted file mode 100644
index 8c5bf40ace576..0000000000000
--- a/sdk/storage/azure-storage-blob/src/test/resources/session-records/ContainerAPITestRename.json
+++ /dev/null
@@ -1,91 +0,0 @@
-{
- "networkCallRecords" : [ {
- "Method" : "PUT",
- "Uri" : "https://REDACTED.blob.core.windows.net/a8add0010a8add001465681847902c7aef6aa4e9485f?restype=container",
- "Headers" : {
- "x-ms-version" : "2021-10-04",
- "User-Agent" : "azsdk-java-azure-storage-blob/12.20.0-beta.2 (11.0.14; Windows 10; 10.0)",
- "x-ms-client-request-id" : "da39f7eb-1379-43cc-92f4-6ea363fd9817"
- },
- "Response" : {
- "content-length" : "0",
- "x-ms-version" : "2021-10-04",
- "Server" : "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0",
- "eTag" : "0x8DA89F78B793EFC",
- "Last-Modified" : "Mon, 29 Aug 2022 19:49:11 GMT",
- "retry-after" : "0",
- "StatusCode" : "201",
- "x-ms-request-id" : "40eba2c6-901e-0054-39e0-bb9595000000",
- "x-ms-client-request-id" : "da39f7eb-1379-43cc-92f4-6ea363fd9817",
- "Date" : "Mon, 29 Aug 2022 19:49:11 GMT"
- },
- "Exception" : null
- }, {
- "Method" : "PUT",
- "Uri" : "https://REDACTED.blob.core.windows.net/a8add0011a8add00146583374b15a2496fafa4095ac0?restype=container&comp=rename",
- "Headers" : {
- "x-ms-version" : "2021-10-04",
- "User-Agent" : "azsdk-java-azure-storage-blob/12.20.0-beta.2 (11.0.14; Windows 10; 10.0)",
- "x-ms-client-request-id" : "d07b77cb-a0d4-4b40-850c-ac3e7848c68c"
- },
- "Response" : {
- "content-length" : "0",
- "x-ms-version" : "2021-10-04",
- "Server" : "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0",
- "retry-after" : "0",
- "StatusCode" : "200",
- "x-ms-request-id" : "40eba385-901e-0054-69e0-bb9595000000",
- "x-ms-client-request-id" : "d07b77cb-a0d4-4b40-850c-ac3e7848c68c",
- "Date" : "Mon, 29 Aug 2022 19:49:12 GMT"
- },
- "Exception" : null
- }, {
- "Method" : "GET",
- "Uri" : "https://REDACTED.blob.core.windows.net/a8add0011a8add00146583374b15a2496fafa4095ac0?restype=container",
- "Headers" : {
- "x-ms-version" : "2021-10-04",
- "User-Agent" : "azsdk-java-azure-storage-blob/12.20.0-beta.2 (11.0.14; Windows 10; 10.0)",
- "x-ms-client-request-id" : "84775690-4b2a-4f5e-8d78-fa1d3ccde52a"
- },
- "Response" : {
- "content-length" : "0",
- "x-ms-version" : "2021-10-04",
- "x-ms-lease-status" : "unlocked",
- "x-ms-immutable-storage-with-versioning-enabled" : "false",
- "Server" : "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0",
- "x-ms-lease-state" : "available",
- "x-ms-deny-encryption-scope-override" : "false",
- "Last-Modified" : "Mon, 29 Aug 2022 19:49:12 GMT",
- "retry-after" : "0",
- "StatusCode" : "200",
- "x-ms-has-legal-hold" : "false",
- "Date" : "Mon, 29 Aug 2022 19:49:13 GMT",
- "x-ms-default-encryption-scope" : "$account-encryption-key",
- "x-ms-has-immutability-policy" : "false",
- "eTag" : "0x8DA89F78C30FDBF",
- "x-ms-request-id" : "40eba74f-901e-0054-50e0-bb9595000000",
- "x-ms-client-request-id" : "84775690-4b2a-4f5e-8d78-fa1d3ccde52a"
- },
- "Exception" : null
- }, {
- "Method" : "DELETE",
- "Uri" : "https://REDACTED.blob.core.windows.net/a8add0011a8add00146583374b15a2496fafa4095ac0?restype=container",
- "Headers" : {
- "x-ms-version" : "2021-10-04",
- "User-Agent" : "azsdk-java-azure-storage-blob/12.20.0-beta.2 (11.0.14; Windows 10; 10.0)",
- "x-ms-client-request-id" : "4a14c824-34f2-4dde-bd11-3321667ef171"
- },
- "Response" : {
- "content-length" : "0",
- "x-ms-version" : "2021-10-04",
- "Server" : "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0",
- "retry-after" : "0",
- "StatusCode" : "202",
- "x-ms-request-id" : "40eba781-901e-0054-7fe0-bb9595000000",
- "x-ms-client-request-id" : "4a14c824-34f2-4dde-bd11-3321667ef171",
- "Date" : "Mon, 29 Aug 2022 19:49:13 GMT"
- },
- "Exception" : null
- } ],
- "variables" : [ "a8add0010a8add001465681847902c7aef6aa4e9485f", "a8add00196773d1a", "a8add0018736921c", "a8add0011a8add00146583374b15a2496fafa4095ac0" ]
-}
\ No newline at end of file
diff --git a/sdk/storage/azure-storage-blob/src/test/resources/session-records/ContainerAPITestRenameACFail[0].json b/sdk/storage/azure-storage-blob/src/test/resources/session-records/ContainerAPITestRenameACFail[0].json
deleted file mode 100644
index 1b20c271967cd..0000000000000
--- a/sdk/storage/azure-storage-blob/src/test/resources/session-records/ContainerAPITestRenameACFail[0].json
+++ /dev/null
@@ -1,47 +0,0 @@
-{
- "networkCallRecords" : [ {
- "Method" : "PUT",
- "Uri" : "https://REDACTED.blob.core.windows.net/e1739e460e1739e46f6a20124f2a009559ba24c118e3?restype=container",
- "Headers" : {
- "x-ms-version" : "2021-10-04",
- "User-Agent" : "azsdk-java-azure-storage-blob/12.20.0-beta.2 (11.0.14; Windows 10; 10.0)",
- "x-ms-client-request-id" : "f1afb546-0129-4556-aede-65e8542c9427"
- },
- "Response" : {
- "content-length" : "0",
- "x-ms-version" : "2021-10-04",
- "Server" : "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0",
- "eTag" : "0x8DA89F7D4C4F21C",
- "Last-Modified" : "Mon, 29 Aug 2022 19:51:14 GMT",
- "retry-after" : "0",
- "StatusCode" : "201",
- "x-ms-request-id" : "49584001-301e-003f-16e0-bb1261000000",
- "x-ms-client-request-id" : "f1afb546-0129-4556-aede-65e8542c9427",
- "Date" : "Mon, 29 Aug 2022 19:51:15 GMT"
- },
- "Exception" : null
- }, {
- "Method" : "PUT",
- "Uri" : "https://REDACTED.blob.core.windows.net/e1739e461e1739e46f6a68928b9f5802ee2a94ef3884?restype=container&comp=rename",
- "Headers" : {
- "x-ms-version" : "2021-10-04",
- "User-Agent" : "azsdk-java-azure-storage-blob/12.20.0-beta.2 (11.0.14; Windows 10; 10.0)",
- "x-ms-client-request-id" : "47f3b163-0709-4b5e-91fd-dde35c31ef65"
- },
- "Response" : {
- "content-length" : "252",
- "x-ms-version" : "2021-10-04",
- "Server" : "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0",
- "x-ms-error-code" : "LeaseNotPresentWithContainerOperation",
- "retry-after" : "0",
- "StatusCode" : "412",
- "x-ms-request-id" : "495840cb-301e-003f-36e0-bb1261000000",
- "Body" : "\nLeaseNotPresentWithContainerOperation
There is currently no lease on the container.\nRequestId:495840cb-301e-003f-36e0-bb1261000000\nTime:2022-08-29T19:51:17.4254504Z ",
- "x-ms-client-request-id" : "47f3b163-0709-4b5e-91fd-dde35c31ef65",
- "Date" : "Mon, 29 Aug 2022 19:51:17 GMT",
- "Content-Type" : "application/xml"
- },
- "Exception" : null
- } ],
- "variables" : [ "e1739e460e1739e46f6a20124f2a009559ba24c118e3", "e1739e46687434be", "e1739e46019199c3", "e1739e461e1739e46f6a68928b9f5802ee2a94ef3884" ]
-}
\ No newline at end of file
diff --git a/sdk/storage/azure-storage-blob/src/test/resources/session-records/ContainerAPITestRenameACIllegal[0].json b/sdk/storage/azure-storage-blob/src/test/resources/session-records/ContainerAPITestRenameACIllegal[0].json
deleted file mode 100644
index f446d35fb924e..0000000000000
--- a/sdk/storage/azure-storage-blob/src/test/resources/session-records/ContainerAPITestRenameACIllegal[0].json
+++ /dev/null
@@ -1,25 +0,0 @@
-{
- "networkCallRecords" : [ {
- "Method" : "PUT",
- "Uri" : "https://REDACTED.blob.core.windows.net/e48d3c7c0e48d3c7c54034732b9742ec71b5b446dad3?restype=container",
- "Headers" : {
- "x-ms-version" : "2021-10-04",
- "User-Agent" : "azsdk-java-azure-storage-blob/12.20.0-beta.2 (11.0.14; Windows 10; 10.0)",
- "x-ms-client-request-id" : "5f92eb6c-227a-456d-9531-1dd3d2fda3e6"
- },
- "Response" : {
- "content-length" : "0",
- "x-ms-version" : "2021-10-04",
- "Server" : "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0",
- "eTag" : "0x8DA89F7D4C3C64F",
- "Last-Modified" : "Mon, 29 Aug 2022 19:51:14 GMT",
- "retry-after" : "0",
- "StatusCode" : "201",
- "x-ms-request-id" : "c77786da-a01e-0002-07e0-bb647a000000",
- "x-ms-client-request-id" : "5f92eb6c-227a-456d-9531-1dd3d2fda3e6",
- "Date" : "Mon, 29 Aug 2022 19:51:14 GMT"
- },
- "Exception" : null
- } ],
- "variables" : [ "e48d3c7c0e48d3c7c54034732b9742ec71b5b446dad3", "e48d3c7c29513451", "e48d3c7c12559103", "e48d3c7c1e48d3c7c54021240e228b8d81f16446eaf7" ]
-}
\ No newline at end of file
diff --git a/sdk/storage/azure-storage-blob/src/test/resources/session-records/ContainerAPITestRenameACIllegal[1].json b/sdk/storage/azure-storage-blob/src/test/resources/session-records/ContainerAPITestRenameACIllegal[1].json
deleted file mode 100644
index e3b2ace2dc900..0000000000000
--- a/sdk/storage/azure-storage-blob/src/test/resources/session-records/ContainerAPITestRenameACIllegal[1].json
+++ /dev/null
@@ -1,25 +0,0 @@
-{
- "networkCallRecords" : [ {
- "Method" : "PUT",
- "Uri" : "https://REDACTED.blob.core.windows.net/fd960d3d0fd960d3dab945527178fc6c447424ecabe9?restype=container",
- "Headers" : {
- "x-ms-version" : "2021-10-04",
- "User-Agent" : "azsdk-java-azure-storage-blob/12.20.0-beta.2 (11.0.14; Windows 10; 10.0)",
- "x-ms-client-request-id" : "74f7f5b7-6a1e-4ca5-bc4e-ebc56c9006bd"
- },
- "Response" : {
- "content-length" : "0",
- "x-ms-version" : "2021-10-04",
- "Server" : "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0",
- "eTag" : "0x8DA89F7D4C3ED62",
- "Last-Modified" : "Mon, 29 Aug 2022 19:51:14 GMT",
- "retry-after" : "0",
- "StatusCode" : "201",
- "x-ms-request-id" : "eccdd303-801e-0067-80e0-bbca3e000000",
- "x-ms-client-request-id" : "74f7f5b7-6a1e-4ca5-bc4e-ebc56c9006bd",
- "Date" : "Mon, 29 Aug 2022 19:51:14 GMT"
- },
- "Exception" : null
- } ],
- "variables" : [ "fd960d3d0fd960d3dab945527178fc6c447424ecabe9", "fd960d3d308567c6", "fd960d3d44482204", "fd960d3d1fd960d3dab98453818432faf67164e3f80e" ]
-}
\ No newline at end of file
diff --git a/sdk/storage/azure-storage-blob/src/test/resources/session-records/ContainerAPITestRenameACIllegal[2].json b/sdk/storage/azure-storage-blob/src/test/resources/session-records/ContainerAPITestRenameACIllegal[2].json
deleted file mode 100644
index dcc4ce1980d9e..0000000000000
--- a/sdk/storage/azure-storage-blob/src/test/resources/session-records/ContainerAPITestRenameACIllegal[2].json
+++ /dev/null
@@ -1,25 +0,0 @@
-{
- "networkCallRecords" : [ {
- "Method" : "PUT",
- "Uri" : "https://REDACTED.blob.core.windows.net/d6bb5efe0d6bb5efe94992631adbb430a9d2c4683a55?restype=container",
- "Headers" : {
- "x-ms-version" : "2021-10-04",
- "User-Agent" : "azsdk-java-azure-storage-blob/12.20.0-beta.2 (11.0.14; Windows 10; 10.0)",
- "x-ms-client-request-id" : "f6d97dcb-c0bb-40b5-80d1-65faa0f85cd0"
- },
- "Response" : {
- "content-length" : "0",
- "x-ms-version" : "2021-10-04",
- "Server" : "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0",
- "eTag" : "0x8DA89F7D4C2F424",
- "Last-Modified" : "Mon, 29 Aug 2022 19:51:14 GMT",
- "retry-after" : "0",
- "StatusCode" : "201",
- "x-ms-request-id" : "1a3b0a3f-f01e-000f-08e0-bbacae000000",
- "x-ms-client-request-id" : "f6d97dcb-c0bb-40b5-80d1-65faa0f85cd0",
- "Date" : "Mon, 29 Aug 2022 19:51:13 GMT"
- },
- "Exception" : null
- } ],
- "variables" : [ "d6bb5efe0d6bb5efe94992631adbb430a9d2c4683a55", "d6bb5efe14150977", "d6bb5efe35806eb5", "d6bb5efe1d6bb5efe949391467cc9c61778064d3cb3a" ]
-}
\ No newline at end of file
diff --git a/sdk/storage/azure-storage-blob/src/test/resources/session-records/ContainerAPITestRenameACIllegal[3].json b/sdk/storage/azure-storage-blob/src/test/resources/session-records/ContainerAPITestRenameACIllegal[3].json
deleted file mode 100644
index 62d672a0cce0e..0000000000000
--- a/sdk/storage/azure-storage-blob/src/test/resources/session-records/ContainerAPITestRenameACIllegal[3].json
+++ /dev/null
@@ -1,25 +0,0 @@
-{
- "networkCallRecords" : [ {
- "Method" : "PUT",
- "Uri" : "https://REDACTED.blob.core.windows.net/cfa06fbf0cfa06fbfd8277294c66bf650caef46918d7?restype=container",
- "Headers" : {
- "x-ms-version" : "2021-10-04",
- "User-Agent" : "azsdk-java-azure-storage-blob/12.20.0-beta.2 (11.0.14; Windows 10; 10.0)",
- "x-ms-client-request-id" : "545215e2-1b5f-4e82-aa30-51c218392d26"
- },
- "Response" : {
- "content-length" : "0",
- "x-ms-version" : "2021-10-04",
- "Server" : "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0",
- "eTag" : "0x8DA89F7D4C4102E",
- "Last-Modified" : "Mon, 29 Aug 2022 19:51:14 GMT",
- "retry-after" : "0",
- "StatusCode" : "201",
- "x-ms-request-id" : "4579b2c7-601e-008b-62e0-bbdeaf000000",
- "x-ms-client-request-id" : "545215e2-1b5f-4e82-aa30-51c218392d26",
- "Date" : "Mon, 29 Aug 2022 19:51:14 GMT"
- },
- "Exception" : null
- } ],
- "variables" : [ "cfa06fbf0cfa06fbfd8277294c66bf650caef46918d7", "cfa06fbf691968c8", "cfa06fbf04998792", "cfa06fbf1cfa06fbfd8258540e2de39e7674042b9826" ]
-}
\ No newline at end of file
diff --git a/sdk/storage/azure-storage-blob/src/test/resources/session-records/ContainerAPITestRenameACIllegal[4].json b/sdk/storage/azure-storage-blob/src/test/resources/session-records/ContainerAPITestRenameACIllegal[4].json
deleted file mode 100644
index df6a7598b76a9..0000000000000
--- a/sdk/storage/azure-storage-blob/src/test/resources/session-records/ContainerAPITestRenameACIllegal[4].json
+++ /dev/null
@@ -1,25 +0,0 @@
-{
- "networkCallRecords" : [ {
- "Method" : "PUT",
- "Uri" : "https://REDACTED.blob.core.windows.net/80e1f978080e1f97806056264cad307a9de8d4f0e99a?restype=container",
- "Headers" : {
- "x-ms-version" : "2021-10-04",
- "User-Agent" : "azsdk-java-azure-storage-blob/12.20.0-beta.2 (11.0.14; Windows 10; 10.0)",
- "x-ms-client-request-id" : "bbd62cbe-6055-4b6a-987a-91091676999b"
- },
- "Response" : {
- "content-length" : "0",
- "x-ms-version" : "2021-10-04",
- "Server" : "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0",
- "eTag" : "0x8DA89F7D4C413FD",
- "Last-Modified" : "Mon, 29 Aug 2022 19:51:14 GMT",
- "retry-after" : "0",
- "StatusCode" : "201",
- "x-ms-request-id" : "c54c4322-a01e-003d-2de0-bbacd9000000",
- "x-ms-client-request-id" : "bbd62cbe-6055-4b6a-987a-91091676999b",
- "Date" : "Mon, 29 Aug 2022 19:51:14 GMT"
- },
- "Exception" : null
- } ],
- "variables" : [ "80e1f978080e1f97806056264cad307a9de8d4f0e99a", "80e1f978099053bf", "80e1f978722964a2", "80e1f978180e1f97806096226deecfc84ca99461d915" ]
-}
\ No newline at end of file
diff --git a/sdk/storage/azure-storage-blob/src/test/resources/session-records/ContainerAPITestRenameAC[0].json b/sdk/storage/azure-storage-blob/src/test/resources/session-records/ContainerAPITestRenameAC[0].json
deleted file mode 100644
index 01b00d6bb7998..0000000000000
--- a/sdk/storage/azure-storage-blob/src/test/resources/session-records/ContainerAPITestRenameAC[0].json
+++ /dev/null
@@ -1,44 +0,0 @@
-{
- "networkCallRecords" : [ {
- "Method" : "PUT",
- "Uri" : "https://REDACTED.blob.core.windows.net/2c2fc32702c2fc327dc736183d62b4440e1c54b439de?restype=container",
- "Headers" : {
- "x-ms-version" : "2021-10-04",
- "User-Agent" : "azsdk-java-azure-storage-blob/12.20.0-beta.2 (11.0.14; Windows 10; 10.0)",
- "x-ms-client-request-id" : "8bb42b43-cc26-4f42-a53e-de0a0f8ba584"
- },
- "Response" : {
- "content-length" : "0",
- "x-ms-version" : "2021-10-04",
- "Server" : "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0",
- "eTag" : "0x8DA89F7D4C3A47F",
- "Last-Modified" : "Mon, 29 Aug 2022 19:51:14 GMT",
- "retry-after" : "0",
- "StatusCode" : "201",
- "x-ms-request-id" : "58f34824-301e-0000-1fe0-bbdac2000000",
- "x-ms-client-request-id" : "8bb42b43-cc26-4f42-a53e-de0a0f8ba584",
- "Date" : "Mon, 29 Aug 2022 19:51:14 GMT"
- },
- "Exception" : null
- }, {
- "Method" : "PUT",
- "Uri" : "https://REDACTED.blob.core.windows.net/2c2fc32712c2fc327dc784778337cb2624df2465c8f5?restype=container&comp=rename",
- "Headers" : {
- "x-ms-version" : "2021-10-04",
- "User-Agent" : "azsdk-java-azure-storage-blob/12.20.0-beta.2 (11.0.14; Windows 10; 10.0)",
- "x-ms-client-request-id" : "610228cd-6a3a-44f0-b710-3cb4dce63439"
- },
- "Response" : {
- "content-length" : "0",
- "x-ms-version" : "2021-10-04",
- "Server" : "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0",
- "retry-after" : "0",
- "StatusCode" : "200",
- "x-ms-request-id" : "c7778896-a01e-0002-0ee0-bb647a000000",
- "x-ms-client-request-id" : "610228cd-6a3a-44f0-b710-3cb4dce63439",
- "Date" : "Mon, 29 Aug 2022 19:51:15 GMT"
- },
- "Exception" : null
- } ],
- "variables" : [ "2c2fc32702c2fc327dc736183d62b4440e1c54b439de", "2c2fc32772671c9f", "2c2fc327877896e6", "2c2fc32712c2fc327dc784778337cb2624df2465c8f5" ]
-}
\ No newline at end of file
diff --git a/sdk/storage/azure-storage-blob/src/test/resources/session-records/ContainerAPITestRenameAC[1].json b/sdk/storage/azure-storage-blob/src/test/resources/session-records/ContainerAPITestRenameAC[1].json
deleted file mode 100644
index 40fb43af719fd..0000000000000
--- a/sdk/storage/azure-storage-blob/src/test/resources/session-records/ContainerAPITestRenameAC[1].json
+++ /dev/null
@@ -1,66 +0,0 @@
-{
- "networkCallRecords" : [ {
- "Method" : "PUT",
- "Uri" : "https://REDACTED.blob.core.windows.net/3534f26603534f266c6435788e51b653de38046a3afa?restype=container",
- "Headers" : {
- "x-ms-version" : "2021-10-04",
- "User-Agent" : "azsdk-java-azure-storage-blob/12.20.0-beta.2 (11.0.14; Windows 10; 10.0)",
- "x-ms-client-request-id" : "d6ef9566-f2df-449b-bde7-51f097b7eba7"
- },
- "Response" : {
- "content-length" : "0",
- "x-ms-version" : "2021-10-04",
- "Server" : "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0",
- "eTag" : "0x8DA89F7D4C3A118",
- "Last-Modified" : "Mon, 29 Aug 2022 19:51:14 GMT",
- "retry-after" : "0",
- "StatusCode" : "201",
- "x-ms-request-id" : "ce33008c-f01e-0042-13e0-bb6342000000",
- "x-ms-client-request-id" : "d6ef9566-f2df-449b-bde7-51f097b7eba7",
- "Date" : "Mon, 29 Aug 2022 19:51:14 GMT"
- },
- "Exception" : null
- }, {
- "Method" : "PUT",
- "Uri" : "https://REDACTED.blob.core.windows.net/3534f26603534f266c6435788e51b653de38046a3afa?comp=lease&restype=container",
- "Headers" : {
- "x-ms-version" : "2021-10-04",
- "User-Agent" : "azsdk-java-azure-storage-blob/12.20.0-beta.2 (11.0.14; Windows 10; 10.0)",
- "x-ms-client-request-id" : "d787e447-7b49-4958-acd0-d94c2cefc9be"
- },
- "Response" : {
- "content-length" : "0",
- "x-ms-version" : "2021-10-04",
- "Server" : "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0",
- "x-ms-lease-id" : "908812c1-aaea-4748-9833-27de801c96e7",
- "eTag" : "0x8DA89F7D4C3A118",
- "Last-Modified" : "Mon, 29 Aug 2022 19:51:14 GMT",
- "retry-after" : "0",
- "StatusCode" : "201",
- "x-ms-request-id" : "eccdd3ef-801e-0067-4ce0-bbca3e000000",
- "x-ms-client-request-id" : "d787e447-7b49-4958-acd0-d94c2cefc9be",
- "Date" : "Mon, 29 Aug 2022 19:51:15 GMT"
- },
- "Exception" : null
- }, {
- "Method" : "PUT",
- "Uri" : "https://REDACTED.blob.core.windows.net/3534f26613534f266c64412191a2c6f3a22714879a01?restype=container&comp=rename",
- "Headers" : {
- "x-ms-version" : "2021-10-04",
- "User-Agent" : "azsdk-java-azure-storage-blob/12.20.0-beta.2 (11.0.14; Windows 10; 10.0)",
- "x-ms-client-request-id" : "84da3438-db6c-4bcc-9bd3-ecfb07a012fe"
- },
- "Response" : {
- "content-length" : "0",
- "x-ms-version" : "2021-10-04",
- "Server" : "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0",
- "retry-after" : "0",
- "StatusCode" : "200",
- "x-ms-request-id" : "eccdd44d-801e-0067-1ee0-bbca3e000000",
- "x-ms-client-request-id" : "84da3438-db6c-4bcc-9bd3-ecfb07a012fe",
- "Date" : "Mon, 29 Aug 2022 19:51:16 GMT"
- },
- "Exception" : null
- } ],
- "variables" : [ "3534f26603534f266c6435788e51b653de38046a3afa", "3534f26699302dfd", "3534f2660645320f", "3534f26613534f266c64412191a2c6f3a22714879a01" ]
-}
\ No newline at end of file
diff --git a/sdk/storage/azure-storage-blob/src/test/resources/session-records/ContainerAPITestRenameError.json b/sdk/storage/azure-storage-blob/src/test/resources/session-records/ContainerAPITestRenameError.json
deleted file mode 100644
index f0fc5cfff2f29..0000000000000
--- a/sdk/storage/azure-storage-blob/src/test/resources/session-records/ContainerAPITestRenameError.json
+++ /dev/null
@@ -1,47 +0,0 @@
-{
- "networkCallRecords" : [ {
- "Method" : "PUT",
- "Uri" : "https://REDACTED.blob.core.windows.net/3056fb8e03056fb8e56136005aff852f09ea14c0fa29?restype=container",
- "Headers" : {
- "x-ms-version" : "2021-10-04",
- "User-Agent" : "azsdk-java-azure-storage-blob/12.20.0-beta.2 (11.0.14; Windows 10; 10.0)",
- "x-ms-client-request-id" : "fe124576-4647-4e5c-b363-a4bb3773d8bd"
- },
- "Response" : {
- "content-length" : "0",
- "x-ms-version" : "2021-10-04",
- "Server" : "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0",
- "eTag" : "0x8DA89F7D4C39C7F",
- "Last-Modified" : "Mon, 29 Aug 2022 19:51:14 GMT",
- "retry-after" : "0",
- "StatusCode" : "201",
- "x-ms-request-id" : "620b392b-201e-0023-45e0-bb4001000000",
- "x-ms-client-request-id" : "fe124576-4647-4e5c-b363-a4bb3773d8bd",
- "Date" : "Mon, 29 Aug 2022 19:51:14 GMT"
- },
- "Exception" : null
- }, {
- "Method" : "PUT",
- "Uri" : "https://REDACTED.blob.core.windows.net/3056fb8e23056fb8e5618743307b87fa6e18540c7982?restype=container&comp=rename",
- "Headers" : {
- "x-ms-version" : "2021-10-04",
- "User-Agent" : "azsdk-java-azure-storage-blob/12.20.0-beta.2 (11.0.14; Windows 10; 10.0)",
- "x-ms-client-request-id" : "55a2d59c-1a5f-4247-83ab-d9fcadd0aa60"
- },
- "Response" : {
- "content-length" : "226",
- "x-ms-version" : "2021-10-04",
- "Server" : "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0",
- "x-ms-error-code" : "ContainerNotFound",
- "retry-after" : "0",
- "StatusCode" : "404",
- "x-ms-request-id" : "844526a0-501e-0074-5de0-bbee32000000",
- "Body" : "\nContainerNotFound
The specified container does not exist.\nRequestId:844526a0-501e-0074-5de0-bbee32000000\nTime:2022-08-29T19:51:18.7662387Z ",
- "x-ms-client-request-id" : "55a2d59c-1a5f-4247-83ab-d9fcadd0aa60",
- "Date" : "Mon, 29 Aug 2022 19:51:18 GMT",
- "Content-Type" : "application/xml"
- },
- "Exception" : null
- } ],
- "variables" : [ "3056fb8e03056fb8e56136005aff852f09ea14c0fa29", "3056fb8e075034fd", "3056fb8e3479411b", "3056fb8e13056fb8e5617510951a330f78dec4a569da", "3056fb8e23056fb8e5618743307b87fa6e18540c7982" ]
-}
\ No newline at end of file
diff --git a/sdk/storage/azure-storage-blob/src/test/resources/session-records/ContainerAPITestRenameSas.json b/sdk/storage/azure-storage-blob/src/test/resources/session-records/ContainerAPITestRenameSas.json
deleted file mode 100644
index 6f0644478d3ef..0000000000000
--- a/sdk/storage/azure-storage-blob/src/test/resources/session-records/ContainerAPITestRenameSas.json
+++ /dev/null
@@ -1,91 +0,0 @@
-{
- "networkCallRecords" : [ {
- "Method" : "PUT",
- "Uri" : "https://REDACTED.blob.core.windows.net/0ccc434e00ccc434ea0d50026d7c4613270524eb49ea?restype=container",
- "Headers" : {
- "x-ms-version" : "2021-10-04",
- "User-Agent" : "azsdk-java-azure-storage-blob/12.20.0-beta.2 (11.0.14; Windows 10; 10.0)",
- "x-ms-client-request-id" : "35d978a5-4fb9-4603-8098-866ded17cc5c"
- },
- "Response" : {
- "content-length" : "0",
- "x-ms-version" : "2021-10-04",
- "Server" : "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0",
- "eTag" : "0x8DA8A18272D604A",
- "Last-Modified" : "Mon, 29 Aug 2022 23:42:36 GMT",
- "retry-after" : "0",
- "StatusCode" : "201",
- "x-ms-request-id" : "dd0da0d3-401e-0035-0201-bcb6d6000000",
- "x-ms-client-request-id" : "35d978a5-4fb9-4603-8098-866ded17cc5c",
- "Date" : "Mon, 29 Aug 2022 23:42:35 GMT"
- },
- "Exception" : null
- }, {
- "Method" : "PUT",
- "Uri" : "https://REDACTED.blob.core.windows.net/0ccc434e10ccc434ea0d78544028d98c6ad5e489ba9a?restype=container&comp=rename&sv=2021-10-04&ss=b&srt=sco&se=2022-08-30T23%3A42%3A36Z&sp=rwdc&sig=REDACTED",
- "Headers" : {
- "x-ms-version" : "2021-10-04",
- "User-Agent" : "azsdk-java-azure-storage-blob/12.20.0-beta.2 (11.0.14; Windows 10; 10.0)",
- "x-ms-client-request-id" : "04c30745-a7c3-49ab-82ac-d8cf7c3a2749"
- },
- "Response" : {
- "content-length" : "0",
- "x-ms-version" : "2021-10-04",
- "Server" : "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0",
- "retry-after" : "0",
- "StatusCode" : "200",
- "x-ms-request-id" : "dd0da10c-401e-0035-3001-bcb6d6000000",
- "x-ms-client-request-id" : "04c30745-a7c3-49ab-82ac-d8cf7c3a2749",
- "Date" : "Mon, 29 Aug 2022 23:42:37 GMT"
- },
- "Exception" : null
- }, {
- "Method" : "GET",
- "Uri" : "https://REDACTED.blob.core.windows.net/0ccc434e10ccc434ea0d78544028d98c6ad5e489ba9a?restype=container&sv=2021-10-04&ss=b&srt=sco&se=2022-08-30T23%3A42%3A36Z&sp=rwdc&sig=REDACTED",
- "Headers" : {
- "x-ms-version" : "2021-10-04",
- "User-Agent" : "azsdk-java-azure-storage-blob/12.20.0-beta.2 (11.0.14; Windows 10; 10.0)",
- "x-ms-client-request-id" : "d83058c5-c2dd-4b0c-be49-d6bdf3b979b3"
- },
- "Response" : {
- "content-length" : "0",
- "x-ms-version" : "2021-10-04",
- "x-ms-lease-status" : "unlocked",
- "x-ms-immutable-storage-with-versioning-enabled" : "false",
- "Server" : "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0",
- "x-ms-lease-state" : "available",
- "x-ms-deny-encryption-scope-override" : "false",
- "Last-Modified" : "Mon, 29 Aug 2022 23:42:38 GMT",
- "retry-after" : "0",
- "StatusCode" : "200",
- "x-ms-has-legal-hold" : "false",
- "Date" : "Mon, 29 Aug 2022 23:42:37 GMT",
- "x-ms-default-encryption-scope" : "$account-encryption-key",
- "x-ms-has-immutability-policy" : "false",
- "eTag" : "0x8DA8A1827F7DED2",
- "x-ms-request-id" : "dd0da303-401e-0035-6d01-bcb6d6000000",
- "x-ms-client-request-id" : "d83058c5-c2dd-4b0c-be49-d6bdf3b979b3"
- },
- "Exception" : null
- }, {
- "Method" : "DELETE",
- "Uri" : "https://REDACTED.blob.core.windows.net/0ccc434e10ccc434ea0d78544028d98c6ad5e489ba9a?restype=container&sv=2021-10-04&ss=b&srt=sco&se=2022-08-30T23%3A42%3A36Z&sp=rwdc&sig=REDACTED",
- "Headers" : {
- "x-ms-version" : "2021-10-04",
- "User-Agent" : "azsdk-java-azure-storage-blob/12.20.0-beta.2 (11.0.14; Windows 10; 10.0)",
- "x-ms-client-request-id" : "82d23a08-26cc-479a-8601-cbc24c81ecbb"
- },
- "Response" : {
- "content-length" : "0",
- "x-ms-version" : "2021-10-04",
- "Server" : "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0",
- "retry-after" : "0",
- "StatusCode" : "202",
- "x-ms-request-id" : "dd0da32c-401e-0035-1401-bcb6d6000000",
- "x-ms-client-request-id" : "82d23a08-26cc-479a-8601-cbc24c81ecbb",
- "Date" : "Mon, 29 Aug 2022 23:42:37 GMT"
- },
- "Exception" : null
- } ],
- "variables" : [ "0ccc434e00ccc434ea0d50026d7c4613270524eb49ea", "0ccc434e9681811d", "0ccc434e24942fc5", "0ccc434e10ccc434ea0d78544028d98c6ad5e489ba9a", "2022-08-29T23:42:36.790068500Z" ]
-}
\ No newline at end of file
diff --git a/sdk/storage/azure-storage-file-datalake/src/main/java/com/azure/storage/file/datalake/DataLakeFileSystemAsyncClient.java b/sdk/storage/azure-storage-file-datalake/src/main/java/com/azure/storage/file/datalake/DataLakeFileSystemAsyncClient.java
index 9bb6799af106d..7362a727c98c8 100644
--- a/sdk/storage/azure-storage-file-datalake/src/main/java/com/azure/storage/file/datalake/DataLakeFileSystemAsyncClient.java
+++ b/sdk/storage/azure-storage-file-datalake/src/main/java/com/azure/storage/file/datalake/DataLakeFileSystemAsyncClient.java
@@ -53,7 +53,6 @@
import com.azure.storage.file.datalake.models.UserDelegationKey;
import com.azure.storage.file.datalake.options.DataLakePathCreateOptions;
import com.azure.storage.file.datalake.options.DataLakePathDeleteOptions;
-import com.azure.storage.file.datalake.options.FileSystemRenameOptions;
import com.azure.storage.file.datalake.sas.DataLakeServiceSasSignatureValues;
import reactor.core.publisher.Mono;
@@ -1825,73 +1824,39 @@ public Mono> getAccessPolicyWithResponse(Stri
Transforms.toFileSystemAccessPolicies(response.getValue())));
}
- /**
- * Renames an existing file system.
- *
- * Code Samples
- *
- *
- *
- * DataLakeFileSystemAsyncClient fileSystemAsyncClient =
- * client.rename("newFileSystemName")
- * .block();
- *
- *
- *
- * @param destinationContainerName The new name of the file system.
- * @return A {@link Mono} containing a {@link DataLakeFileSystemAsyncClient} used to interact with the renamed file system.
- */
- @ServiceMethod(returns = ReturnType.SINGLE)
- public Mono rename(String destinationContainerName) {
- return renameWithResponse(new FileSystemRenameOptions(destinationContainerName)).flatMap(FluxUtil::toMono);
- }
-
- /**
- * Renames an existing file system.
- *
- * Code Samples
- *
- *
- *
- * DataLakeRequestConditions requestConditions = new DataLakeRequestConditions().setLeaseId("lease-id");
- * DataLakeFileSystemAsyncClient fileSystemAsyncClient = client
- * .renameWithResponse(new FileSystemRenameOptions( "newFileSystemName")
- * .setRequestConditions(requestConditions)).block().getValue();
- *
- *
- *
- * @param options {@link FileSystemRenameOptions}
- * @return A {@link Mono} containing a {@link Response} whose {@link Response#getValue() value} contains a
- * {@link DataLakeFileSystemAsyncClient} used to interact with the renamed file system.
- */
- @ServiceMethod(returns = ReturnType.SINGLE)
- public Mono> renameWithResponse(FileSystemRenameOptions options) {
- try {
- return blobContainerAsyncClient.renameWithResponse(Transforms.toBlobContainerRenameOptions(options))
- .onErrorMap(DataLakeImplUtils::transformBlobStorageException)
- .map(response -> new SimpleResponse<>(response,
- this.getFileSystemAsyncClient(options.getDestinationFileSystemName())));
- } catch (RuntimeException ex) {
- return monoError(LOGGER, ex);
- }
- }
-
- /**
- * Takes in a destination and creates a DataLakeFileSystemAsyncClient with a new path
- * @param destinationFileSystem The destination file system
- * @return A DataLakeFileSystemAsyncClient
- */
- DataLakeFileSystemAsyncClient getFileSystemAsyncClient(String destinationFileSystem) {
- if (CoreUtils.isNullOrEmpty(destinationFileSystem)) {
- throw LOGGER.logExceptionAsError(new IllegalArgumentException("'destinationFileSystem' can not be set to null"));
- }
- // Get current Datalake URL and replace current filesystem with user provided filesystem
- String newDfsEndpoint = BlobUrlParts.parse(getFileSystemUrl())
- .setContainerName(destinationFileSystem).toUrl().toString();
-
- return new DataLakeFileSystemAsyncClient(getHttpPipeline(), newDfsEndpoint, serviceVersion, accountName,
- destinationFileSystem, prepareBuilderReplacePath(destinationFileSystem).buildAsyncClient(), sasToken);
- }
+ // TODO: Reintroduce this API once service starts supporting it.
+// Mono rename(String destinationContainerName) {
+// return renameWithResponse(new FileSystemRenameOptions(destinationContainerName)).flatMap(FluxUtil::toMono);
+// }
+
+ // TODO: Reintroduce this API once service starts supporting it.
+// Mono> renameWithResponse(FileSystemRenameOptions options) {
+// try {
+// return blobContainerAsyncClient.renameWithResponse(Transforms.toBlobContainerRenameOptions(options))
+// .onErrorMap(DataLakeImplUtils::transformBlobStorageException)
+// .map(response -> new SimpleResponse<>(response,
+// this.getFileSystemAsyncClient(options.getDestinationFileSystemName())));
+// } catch (RuntimeException ex) {
+// return monoError(LOGGER, ex);
+// }
+// }
+
+// /**
+// * Takes in a destination and creates a DataLakeFileSystemAsyncClient with a new path
+// * @param destinationFileSystem The destination file system
+// * @return A DataLakeFileSystemAsyncClient
+// */
+// DataLakeFileSystemAsyncClient getFileSystemAsyncClient(String destinationFileSystem) {
+// if (CoreUtils.isNullOrEmpty(destinationFileSystem)) {
+// throw LOGGER.logExceptionAsError(new IllegalArgumentException("'destinationFileSystem' can not be set to null"));
+// }
+// // Get current Datalake URL and replace current filesystem with user provided filesystem
+// String newDfsEndpoint = BlobUrlParts.parse(getFileSystemUrl())
+// .setContainerName(destinationFileSystem).toUrl().toString();
+//
+// return new DataLakeFileSystemAsyncClient(getHttpPipeline(), newDfsEndpoint, serviceVersion, accountName,
+// destinationFileSystem, prepareBuilderReplacePath(destinationFileSystem).buildAsyncClient(), sasToken);
+// }
/**
* Takes in a destination path and creates a ContainerClientBuilder with a new path name
@@ -1912,9 +1877,9 @@ BlobContainerClientBuilder prepareBuilderReplacePath(String destinationFileSyste
.serviceVersion(TransformUtils.toBlobServiceVersion(getServiceVersion()));
}
- BlobContainerAsyncClient getBlobContainerAsyncClient() {
- return blobContainerAsyncClient;
- }
+// BlobContainerAsyncClient getBlobContainerAsyncClient() {
+// return blobContainerAsyncClient;
+// }
/**
* Generates a user delegation SAS for the file system using the specified
diff --git a/sdk/storage/azure-storage-file-datalake/src/main/java/com/azure/storage/file/datalake/DataLakeFileSystemClient.java b/sdk/storage/azure-storage-file-datalake/src/main/java/com/azure/storage/file/datalake/DataLakeFileSystemClient.java
index 8e7931b44b5db..a854c28ed4ad5 100644
--- a/sdk/storage/azure-storage-file-datalake/src/main/java/com/azure/storage/file/datalake/DataLakeFileSystemClient.java
+++ b/sdk/storage/azure-storage-file-datalake/src/main/java/com/azure/storage/file/datalake/DataLakeFileSystemClient.java
@@ -34,7 +34,6 @@
import com.azure.storage.file.datalake.models.UserDelegationKey;
import com.azure.storage.file.datalake.options.DataLakePathCreateOptions;
import com.azure.storage.file.datalake.options.DataLakePathDeleteOptions;
-import com.azure.storage.file.datalake.options.FileSystemRenameOptions;
import com.azure.storage.file.datalake.sas.DataLakeServiceSasSignatureValues;
import reactor.core.publisher.Mono;
@@ -1617,64 +1616,24 @@ public Response setAccessPolicyWithResponse(PublicAccessType accessType,
timeout, context), LOGGER);
}
- /**
- * Renames an existing file system.
- *
- * Code Samples
- *
- *
- *
- * DataLakeFileSystemClient fileSystemClient = client.rename("newFileSystemName");
- *
- *
- *
- * @param destinationFileSystemName The new name of the file system.
- * @return A {@link DataLakeFileSystemClient} used to interact with the renamed file system.
- */
- @ServiceMethod(returns = ReturnType.SINGLE)
- public DataLakeFileSystemClient rename(String destinationFileSystemName) {
- return this.renameWithResponse(new FileSystemRenameOptions(destinationFileSystemName), null, Context.NONE).getValue();
- }
-
- /**
- * Renames an existing file system.
- *
- * Code Samples
- *
- *
- *
- * DataLakeRequestConditions requestConditions = new DataLakeRequestConditions().setLeaseId("lease-id");
- * Context context = new Context("Key", "Value");
- *
- * DataLakeFileSystemClient fileSystemClient = client.renameWithResponse(
- * new FileSystemRenameOptions("newFileSystemName")
- * .setRequestConditions(requestConditions),
- * Duration.ofSeconds(1),
- * context).getValue();
- *
- *
- *
- * @param options {@link FileSystemRenameOptions}
- * @param timeout An optional timeout value beyond which a {@link RuntimeException} will be raised.
- * @param context Additional context that is passed through the Http pipeline during the service call.
- * @return A {@link Response} whose {@link Response#getValue() value} contains a
- * {@link DataLakeFileSystemClient} used to interact with the renamed file system.
- */
- @ServiceMethod(returns = ReturnType.SINGLE)
- public Response renameWithResponse(FileSystemRenameOptions options,
- Duration timeout, Context context) {
- return DataLakeImplUtils.returnOrConvertException(() -> {
- Response response = blobContainerClient
- .renameWithResponse(Transforms.toBlobContainerRenameOptions(options), timeout, context);
- return new SimpleResponse<>(response, getFileSystemClient(options.getDestinationFileSystemName()));
- }, LOGGER);
- }
-
- private DataLakeFileSystemClient getFileSystemClient(String destinationFileSystem) {
- return new DataLakeFileSystemClient(
- dataLakeFileSystemAsyncClient.getFileSystemAsyncClient(destinationFileSystem),
- dataLakeFileSystemAsyncClient.prepareBuilderReplacePath(destinationFileSystem).buildClient());
- }
+// DataLakeFileSystemClient rename(String destinationFileSystemName) {
+// return this.renameWithResponse(new FileSystemRenameOptions(destinationFileSystemName), null, Context.NONE).getValue();
+// }
+
+// Response renameWithResponse(FileSystemRenameOptions options,
+// Duration timeout, Context context) {
+// return DataLakeImplUtils.returnOrConvertException(() -> {
+// Response response = blobContainerClient
+// .renameWithResponse(Transforms.toBlobContainerRenameOptions(options), timeout, context);
+// return new SimpleResponse<>(response, getFileSystemClient(options.getDestinationFileSystemName()));
+// }, LOGGER);
+// }
+
+// private DataLakeFileSystemClient getFileSystemClient(String destinationFileSystem) {
+// return new DataLakeFileSystemClient(
+// dataLakeFileSystemAsyncClient.getFileSystemAsyncClient(destinationFileSystem),
+// dataLakeFileSystemAsyncClient.prepareBuilderReplacePath(destinationFileSystem).buildClient());
+// }
BlobContainerClient getBlobContainerClient() {
return blobContainerClient;
diff --git a/sdk/storage/azure-storage-file-datalake/src/samples/java/com/azure/storage/file/datalake/FileSystemAsyncClientJavaDocCodeSamples.java b/sdk/storage/azure-storage-file-datalake/src/samples/java/com/azure/storage/file/datalake/FileSystemAsyncClientJavaDocCodeSamples.java
index 21bd00816a1a7..ae8d456ee7772 100644
--- a/sdk/storage/azure-storage-file-datalake/src/samples/java/com/azure/storage/file/datalake/FileSystemAsyncClientJavaDocCodeSamples.java
+++ b/sdk/storage/azure-storage-file-datalake/src/samples/java/com/azure/storage/file/datalake/FileSystemAsyncClientJavaDocCodeSamples.java
@@ -14,7 +14,6 @@
import com.azure.storage.file.datalake.models.UserDelegationKey;
import com.azure.storage.file.datalake.options.DataLakePathCreateOptions;
import com.azure.storage.file.datalake.options.DataLakePathDeleteOptions;
-import com.azure.storage.file.datalake.options.FileSystemRenameOptions;
import com.azure.storage.file.datalake.sas.DataLakeServiceSasSignatureValues;
import com.azure.storage.file.datalake.sas.FileSystemSasPermission;
import reactor.core.publisher.Mono;
@@ -724,27 +723,27 @@ public void deleteDirectoryIfExistsCodeSnippets() {
// END: com.azure.storage.file.datalake.DataLakeFileSystemAsyncClient.deleteDirectoryIfExistsWithResponse#String-DataLakePathDeleteOptions
}
- /**
- * Code snippet for {@link DataLakeFileSystemAsyncClient#rename(String)}
- */
- public void renameFileSystem() {
- // BEGIN: com.azure.storage.file.datalake.DataLakeFileSystemAsyncClient.rename#String
- DataLakeFileSystemAsyncClient fileSystemAsyncClient =
- client.rename("newFileSystemName")
- .block();
- // END: com.azure.storage.file.datalake.DataLakeFileSystemAsyncClient.rename#String
- }
-
- /**
- * Code snippet for {@link DataLakeFileSystemAsyncClient#renameWithResponse(FileSystemRenameOptions)}
- */
- public void renameFileSystemWithResponse() {
- // BEGIN: com.azure.storage.file.datalake.DataLakeFileSystemAsyncClient.renameWithResponse#FileSystemRenameOptions
- DataLakeRequestConditions requestConditions = new DataLakeRequestConditions().setLeaseId("lease-id");
- DataLakeFileSystemAsyncClient fileSystemAsyncClient = client
- .renameWithResponse(new FileSystemRenameOptions("newFileSystemName")
- .setRequestConditions(requestConditions)).block().getValue();
- // END: com.azure.storage.file.datalake.DataLakeFileSystemAsyncClient.renameWithResponse#FileSystemRenameOptions
- }
+// /**
+// * Code snippet for {@link DataLakeFileSystemAsyncClient#rename(String)}
+// */
+// public void renameFileSystem() {
+// // BEGIN: com.azure.storage.file.datalake.DataLakeFileSystemAsyncClient.rename#String
+// DataLakeFileSystemAsyncClient fileSystemAsyncClient =
+// client.rename("newFileSystemName")
+// .block();
+// // END: com.azure.storage.file.datalake.DataLakeFileSystemAsyncClient.rename#String
+// }
+
+// /**
+// * Code snippet for {@link DataLakeFileSystemAsyncClient#renameWithResponse(FileSystemRenameOptions)}
+// */
+// public void renameFileSystemWithResponse() {
+// // BEGIN: com.azure.storage.file.datalake.DataLakeFileSystemAsyncClient.renameWithResponse#FileSystemRenameOptions
+// DataLakeRequestConditions requestConditions = new DataLakeRequestConditions().setLeaseId("lease-id");
+// DataLakeFileSystemAsyncClient fileSystemAsyncClient = client
+// .renameWithResponse(new FileSystemRenameOptions("newFileSystemName")
+// .setRequestConditions(requestConditions)).block().getValue();
+// // END: com.azure.storage.file.datalake.DataLakeFileSystemAsyncClient.renameWithResponse#FileSystemRenameOptions
+// }
}
diff --git a/sdk/storage/azure-storage-file-datalake/src/samples/java/com/azure/storage/file/datalake/FileSystemClientJavaDocCodeSamples.java b/sdk/storage/azure-storage-file-datalake/src/samples/java/com/azure/storage/file/datalake/FileSystemClientJavaDocCodeSamples.java
index e02dfdc9a270e..508cf5d2ebb2b 100644
--- a/sdk/storage/azure-storage-file-datalake/src/samples/java/com/azure/storage/file/datalake/FileSystemClientJavaDocCodeSamples.java
+++ b/sdk/storage/azure-storage-file-datalake/src/samples/java/com/azure/storage/file/datalake/FileSystemClientJavaDocCodeSamples.java
@@ -18,7 +18,6 @@
import com.azure.storage.file.datalake.models.UserDelegationKey;
import com.azure.storage.file.datalake.options.DataLakePathCreateOptions;
import com.azure.storage.file.datalake.options.DataLakePathDeleteOptions;
-import com.azure.storage.file.datalake.options.FileSystemRenameOptions;
import com.azure.storage.file.datalake.sas.DataLakeServiceSasSignatureValues;
import com.azure.storage.file.datalake.sas.FileSystemSasPermission;
@@ -742,29 +741,29 @@ public void deleteDirectoryIfExistsCodeSnippets() {
// END: com.azure.storage.file.datalake.DataLakeFileSystemClient.deleteDirectoryIfExistsWithResponse#String-DataLakePathDeleteOptions-Duration-Context
}
- /**
- * Code snippet for {@link DataLakeFileSystemClient#rename(String)}
- */
- public void renameContainer() {
- // BEGIN: com.azure.storage.file.datalake.DataLakeFileSystemClient.rename#String
- DataLakeFileSystemClient fileSystemClient = client.rename("newFileSystemName");
- // END: com.azure.storage.file.datalake.DataLakeFileSystemClient.rename#String
- }
-
- /**
- * Code snippet for {@link DataLakeFileSystemClient#renameWithResponse(FileSystemRenameOptions, Duration, Context)}
- */
- public void renameContainerWithResponse() {
- // BEGIN: com.azure.storage.file.datalake.DataLakeFileSystemClient.renameWithResponse#FileSystemRenameOptions-Duration-Context
- DataLakeRequestConditions requestConditions = new DataLakeRequestConditions().setLeaseId("lease-id");
- Context context = new Context("Key", "Value");
-
- DataLakeFileSystemClient fileSystemClient = client.renameWithResponse(
- new FileSystemRenameOptions("newFileSystemName")
- .setRequestConditions(requestConditions),
- Duration.ofSeconds(1),
- context).getValue();
- // END: com.azure.storage.file.datalake.DataLakeFileSystemClient.renameWithResponse#FileSystemRenameOptions-Duration-Context
- }
+// /**
+// * Code snippet for {@link DataLakeFileSystemClient#rename(String)}
+// */
+// public void renameContainer() {
+// // BEGIN: com.azure.storage.file.datalake.DataLakeFileSystemClient.rename#String
+// DataLakeFileSystemClient fileSystemClient = client.rename("newFileSystemName");
+// // END: com.azure.storage.file.datalake.DataLakeFileSystemClient.rename#String
+// }
+
+// /**
+// * Code snippet for {@link DataLakeFileSystemClient#renameWithResponse(FileSystemRenameOptions, Duration, Context)}
+// */
+// public void renameContainerWithResponse() {
+// // BEGIN: com.azure.storage.file.datalake.DataLakeFileSystemClient.renameWithResponse#FileSystemRenameOptions-Duration-Context
+// DataLakeRequestConditions requestConditions = new DataLakeRequestConditions().setLeaseId("lease-id");
+// Context context = new Context("Key", "Value");
+//
+// DataLakeFileSystemClient fileSystemClient = client.renameWithResponse(
+// new FileSystemRenameOptions("newFileSystemName")
+// .setRequestConditions(requestConditions),
+// Duration.ofSeconds(1),
+// context).getValue();
+// // END: com.azure.storage.file.datalake.DataLakeFileSystemClient.renameWithResponse#FileSystemRenameOptions-Duration-Context
+// }
}
diff --git a/sdk/storage/azure-storage-file-datalake/src/test/java/com/azure/storage/file/datalake/FileSystemAPITest.groovy b/sdk/storage/azure-storage-file-datalake/src/test/java/com/azure/storage/file/datalake/FileSystemAPITest.groovy
index 186c9eefbd832..534751906fa25 100644
--- a/sdk/storage/azure-storage-file-datalake/src/test/java/com/azure/storage/file/datalake/FileSystemAPITest.groovy
+++ b/sdk/storage/azure-storage-file-datalake/src/test/java/com/azure/storage/file/datalake/FileSystemAPITest.groovy
@@ -5,10 +5,6 @@ import com.azure.identity.DefaultAzureCredentialBuilder
import com.azure.storage.blob.BlobUrlParts
import com.azure.storage.blob.models.BlobErrorCode
import com.azure.storage.common.Utility
-import com.azure.storage.common.sas.AccountSasPermission
-import com.azure.storage.common.sas.AccountSasResourceType
-import com.azure.storage.common.sas.AccountSasService
-import com.azure.storage.common.sas.AccountSasSignatureValues
import com.azure.storage.common.test.shared.extensions.RequiredServiceVersion
import com.azure.storage.common.test.shared.extensions.PlaybackOnly
import com.azure.storage.file.datalake.models.DataLakeAccessPolicy
@@ -2759,115 +2755,115 @@ class FileSystemAPITest extends APISpec {
response.getHeaders().getValue("x-ms-version") == "2019-02-02"
}
- def "Rename"() {
- setup:
- def newName = generateFileSystemName()
-
- when:
- def renamedContainer = fsc.rename(newName)
-
- then:
- renamedContainer.getPropertiesWithResponse(null, null, null).getStatusCode() == 200
-
- cleanup:
- renamedContainer.delete()
- }
-
- def "Rename sas"() {
- setup:
- def service = new AccountSasService()
- .setBlobAccess(true)
- def resourceType = new AccountSasResourceType()
- .setContainer(true)
- .setService(true)
- .setObject(true)
- def permissions = new AccountSasPermission()
- .setReadPermission(true)
- .setCreatePermission(true)
- .setWritePermission(true)
- .setDeletePermission(true)
- def expiryTime = namer.getUtcNow().plusDays(1)
-
- def newName = generateFileSystemName()
- def sasValues = new AccountSasSignatureValues(expiryTime, permissions, service, resourceType)
- def sas = primaryDataLakeServiceClient.generateAccountSas(sasValues)
- def sasClient = getFileSystemClient(sas, fsc.getFileSystemUrl())
-
- when:
- def renamedContainer = sasClient.rename(newName)
-
- then:
- renamedContainer.getPropertiesWithResponse(null, null, null).getStatusCode() == 200
-
- cleanup:
- renamedContainer.delete()
- }
-
- @Unroll
- def "Rename AC"() {
- setup:
- leaseID = setupFileSystemLeaseCondition(fsc, leaseID)
- def cac = new DataLakeRequestConditions()
- .setLeaseId(leaseID)
-
- expect:
- fsc.renameWithResponse(new FileSystemRenameOptions(generateFileSystemName()).setRequestConditions(cac),
- null, null).getStatusCode() == 200
-
- where:
- leaseID || _
- null || _
- receivedLeaseID || _
- }
-
- @Unroll
- def "Rename AC fail"() {
- setup:
- def cac = new DataLakeRequestConditions()
- .setLeaseId(leaseID)
-
- when:
- fsc.renameWithResponse(new FileSystemRenameOptions(generateFileSystemName()).setRequestConditions(cac),
- null, null)
-
- then:
- thrown(DataLakeStorageException)
-
- where:
- leaseID || _
- garbageLeaseID || _
- }
-
- @Unroll
- def "Rename AC illegal"() {
- setup:
- def ac = new DataLakeRequestConditions().setIfMatch(match).setIfNoneMatch(noneMatch).setIfModifiedSince(modified).setIfUnmodifiedSince(unmodified)
-
- when:
- fsc.renameWithResponse(new FileSystemRenameOptions(generateFileSystemName()).setRequestConditions(ac),
- null, null)
-
- then:
- thrown(UnsupportedOperationException)
-
- where:
- modified | unmodified | match | noneMatch
- oldDate | null | null | null
- null | newDate | null | null
- null | null | receivedEtag | null
- null | null | null | garbageEtag
- }
-
- def "Rename error"() {
- setup:
- fsc = primaryDataLakeServiceClient.getFileSystemClient(generateFileSystemName())
- def newName = generateFileSystemName()
-
- when:
- fsc.rename(newName)
-
- then:
- thrown(DataLakeStorageException)
- }
+// def "Rename"() {
+// setup:
+// def newName = generateFileSystemName()
+//
+// when:
+// def renamedContainer = fsc.rename(newName)
+//
+// then:
+// renamedContainer.getPropertiesWithResponse(null, null, null).getStatusCode() == 200
+//
+// cleanup:
+// renamedContainer.delete()
+// }
+
+// def "Rename sas"() {
+// setup:
+// def service = new AccountSasService()
+// .setBlobAccess(true)
+// def resourceType = new AccountSasResourceType()
+// .setContainer(true)
+// .setService(true)
+// .setObject(true)
+// def permissions = new AccountSasPermission()
+// .setReadPermission(true)
+// .setCreatePermission(true)
+// .setWritePermission(true)
+// .setDeletePermission(true)
+// def expiryTime = namer.getUtcNow().plusDays(1)
+//
+// def newName = generateFileSystemName()
+// def sasValues = new AccountSasSignatureValues(expiryTime, permissions, service, resourceType)
+// def sas = primaryDataLakeServiceClient.generateAccountSas(sasValues)
+// def sasClient = getFileSystemClient(sas, fsc.getFileSystemUrl())
+//
+// when:
+// def renamedContainer = sasClient.rename(newName)
+//
+// then:
+// renamedContainer.getPropertiesWithResponse(null, null, null).getStatusCode() == 200
+//
+// cleanup:
+// renamedContainer.delete()
+// }
+
+// @Unroll
+// def "Rename AC"() {
+// setup:
+// leaseID = setupFileSystemLeaseCondition(fsc, leaseID)
+// def cac = new DataLakeRequestConditions()
+// .setLeaseId(leaseID)
+//
+// expect:
+// fsc.renameWithResponse(new FileSystemRenameOptions(generateFileSystemName()).setRequestConditions(cac),
+// null, null).getStatusCode() == 200
+//
+// where:
+// leaseID || _
+// null || _
+// receivedLeaseID || _
+// }
+
+// @Unroll
+// def "Rename AC fail"() {
+// setup:
+// def cac = new DataLakeRequestConditions()
+// .setLeaseId(leaseID)
+//
+// when:
+// fsc.renameWithResponse(new FileSystemRenameOptions(generateFileSystemName()).setRequestConditions(cac),
+// null, null)
+//
+// then:
+// thrown(DataLakeStorageException)
+//
+// where:
+// leaseID || _
+// garbageLeaseID || _
+// }
+
+// @Unroll
+// def "Rename AC illegal"() {
+// setup:
+// def ac = new DataLakeRequestConditions().setIfMatch(match).setIfNoneMatch(noneMatch).setIfModifiedSince(modified).setIfUnmodifiedSince(unmodified)
+//
+// when:
+// fsc.renameWithResponse(new FileSystemRenameOptions(generateFileSystemName()).setRequestConditions(ac),
+// null, null)
+//
+// then:
+// thrown(UnsupportedOperationException)
+//
+// where:
+// modified | unmodified | match | noneMatch
+// oldDate | null | null | null
+// null | newDate | null | null
+// null | null | receivedEtag | null
+// null | null | null | garbageEtag
+// }
+
+// def "Rename error"() {
+// setup:
+// fsc = primaryDataLakeServiceClient.getFileSystemClient(generateFileSystemName())
+// def newName = generateFileSystemName()
+//
+// when:
+// fsc.rename(newName)
+//
+// then:
+// thrown(DataLakeStorageException)
+// }
}
diff --git a/sdk/storage/azure-storage-file-datalake/src/test/resources/session-records/FileSystemAPITestRename.json b/sdk/storage/azure-storage-file-datalake/src/test/resources/session-records/FileSystemAPITestRename.json
deleted file mode 100644
index 52608581eab0c..0000000000000
--- a/sdk/storage/azure-storage-file-datalake/src/test/resources/session-records/FileSystemAPITestRename.json
+++ /dev/null
@@ -1,91 +0,0 @@
-{
- "networkCallRecords" : [ {
- "Method" : "PUT",
- "Uri" : "https://REDACTED.blob.core.windows.net/9e430f7009e430f7062c13438e2b13aaba587429a97a?restype=container",
- "Headers" : {
- "x-ms-version" : "2021-10-04",
- "User-Agent" : "azsdk-java-azure-storage-blob/12.20.0-beta.2 azsdk-java-azure-storage-file-datalake/12.13.0-beta.1 (11.0.14; Windows 10; 10.0)",
- "x-ms-client-request-id" : "d7e6dddb-b64a-4336-9b3c-31e9c304eac2"
- },
- "Response" : {
- "content-length" : "0",
- "x-ms-version" : "2021-10-04",
- "Server" : "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0",
- "eTag" : "0x8DA89F8AE8027B5",
- "Last-Modified" : "Mon, 29 Aug 2022 19:57:19 GMT",
- "retry-after" : "0",
- "StatusCode" : "201",
- "x-ms-request-id" : "8ae425fc-701e-0011-4be1-bb4076000000",
- "x-ms-client-request-id" : "d7e6dddb-b64a-4336-9b3c-31e9c304eac2",
- "Date" : "Mon, 29 Aug 2022 19:57:19 GMT"
- },
- "Exception" : null
- }, {
- "Method" : "PUT",
- "Uri" : "https://REDACTED.blob.core.windows.net/9e430f7019e430f7062c05162298f0d55004b47fdba3?restype=container&comp=rename",
- "Headers" : {
- "x-ms-version" : "2021-10-04",
- "User-Agent" : "azsdk-java-azure-storage-blob/12.20.0-beta.2 azsdk-java-azure-storage-file-datalake/12.13.0-beta.1 (11.0.14; Windows 10; 10.0)",
- "x-ms-client-request-id" : "bb07a887-9bb8-4984-a12f-ab46c757d68c"
- },
- "Response" : {
- "content-length" : "0",
- "x-ms-version" : "2021-10-04",
- "Server" : "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0",
- "retry-after" : "0",
- "StatusCode" : "200",
- "x-ms-request-id" : "6a71dfd4-001e-0079-49e1-bb26e6000000",
- "x-ms-client-request-id" : "bb07a887-9bb8-4984-a12f-ab46c757d68c",
- "Date" : "Mon, 29 Aug 2022 19:57:21 GMT"
- },
- "Exception" : null
- }, {
- "Method" : "GET",
- "Uri" : "https://REDACTED.blob.core.windows.net/9e430f7019e430f7062c05162298f0d55004b47fdba3?restype=container",
- "Headers" : {
- "x-ms-version" : "2021-10-04",
- "User-Agent" : "azsdk-java-azure-storage-file-datalake/12.13.0-beta.1 (11.0.14; Windows 10; 10.0)",
- "x-ms-client-request-id" : "88b42515-ce1b-4c48-9e9d-9d08d5c05a13"
- },
- "Response" : {
- "content-length" : "0",
- "x-ms-version" : "2021-10-04",
- "x-ms-lease-status" : "unlocked",
- "x-ms-immutable-storage-with-versioning-enabled" : "false",
- "Server" : "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0",
- "x-ms-lease-state" : "available",
- "x-ms-deny-encryption-scope-override" : "false",
- "Last-Modified" : "Mon, 29 Aug 2022 19:57:21 GMT",
- "retry-after" : "0",
- "StatusCode" : "200",
- "x-ms-has-legal-hold" : "false",
- "Date" : "Mon, 29 Aug 2022 19:57:21 GMT",
- "x-ms-default-encryption-scope" : "$account-encryption-key",
- "x-ms-has-immutability-policy" : "false",
- "eTag" : "0x8DA89F8AF358579",
- "x-ms-request-id" : "6a71e309-001e-0079-79e1-bb26e6000000",
- "x-ms-client-request-id" : "88b42515-ce1b-4c48-9e9d-9d08d5c05a13"
- },
- "Exception" : null
- }, {
- "Method" : "DELETE",
- "Uri" : "https://REDACTED.blob.core.windows.net/9e430f7019e430f7062c05162298f0d55004b47fdba3?restype=container",
- "Headers" : {
- "x-ms-version" : "2021-10-04",
- "User-Agent" : "azsdk-java-azure-storage-file-datalake/12.13.0-beta.1 (11.0.14; Windows 10; 10.0)",
- "x-ms-client-request-id" : "e2c8a93a-b503-478a-bab8-2a4c491acad0"
- },
- "Response" : {
- "content-length" : "0",
- "x-ms-version" : "2021-10-04",
- "Server" : "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0",
- "retry-after" : "0",
- "StatusCode" : "202",
- "x-ms-request-id" : "6a71e337-001e-0079-1be1-bb26e6000000",
- "x-ms-client-request-id" : "e2c8a93a-b503-478a-bab8-2a4c491acad0",
- "Date" : "Mon, 29 Aug 2022 19:57:21 GMT"
- },
- "Exception" : null
- } ],
- "variables" : [ "9e430f7009e430f7062c13438e2b13aaba587429a97a", "9e430f7019e430f7062c05162298f0d55004b47fdba3" ]
-}
\ No newline at end of file
diff --git a/sdk/storage/azure-storage-file-datalake/src/test/resources/session-records/FileSystemAPITestRenameACFail[0].json b/sdk/storage/azure-storage-file-datalake/src/test/resources/session-records/FileSystemAPITestRenameACFail[0].json
deleted file mode 100644
index 3203dc7d6d1c6..0000000000000
--- a/sdk/storage/azure-storage-file-datalake/src/test/resources/session-records/FileSystemAPITestRenameACFail[0].json
+++ /dev/null
@@ -1,47 +0,0 @@
-{
- "networkCallRecords" : [ {
- "Method" : "PUT",
- "Uri" : "https://REDACTED.blob.core.windows.net/582a149a0582a149ae9a09141ec1291250ed549048ed?restype=container",
- "Headers" : {
- "x-ms-version" : "2021-10-04",
- "User-Agent" : "azsdk-java-azure-storage-blob/12.20.0-beta.2 azsdk-java-azure-storage-file-datalake/12.13.0-beta.2 (11.0.14; Windows 10; 10.0)",
- "x-ms-client-request-id" : "064aec13-cd7f-4430-8968-4ea551494c29"
- },
- "Response" : {
- "content-length" : "0",
- "x-ms-version" : "2021-10-04",
- "Server" : "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0",
- "eTag" : "0x8DA8A1C4D90F554",
- "Last-Modified" : "Tue, 30 Aug 2022 00:12:19 GMT",
- "retry-after" : "0",
- "StatusCode" : "201",
- "x-ms-request-id" : "33a2b645-301e-0096-7105-bcd313000000",
- "x-ms-client-request-id" : "064aec13-cd7f-4430-8968-4ea551494c29",
- "Date" : "Tue, 30 Aug 2022 00:12:18 GMT"
- },
- "Exception" : null
- }, {
- "Method" : "PUT",
- "Uri" : "https://REDACTED.blob.core.windows.net/582a149a1582a149ae9a9787432ca1a15b6eb44348bb?restype=container&comp=rename",
- "Headers" : {
- "x-ms-version" : "2021-10-04",
- "User-Agent" : "azsdk-java-azure-storage-blob/12.20.0-beta.2 azsdk-java-azure-storage-file-datalake/12.13.0-beta.2 (11.0.14; Windows 10; 10.0)",
- "x-ms-client-request-id" : "878a8ef4-2add-4e7b-bcef-625d7b2d480e"
- },
- "Response" : {
- "content-length" : "252",
- "x-ms-version" : "2021-10-04",
- "Server" : "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0",
- "x-ms-error-code" : "LeaseNotPresentWithContainerOperation",
- "retry-after" : "0",
- "StatusCode" : "412",
- "x-ms-request-id" : "33a2b6b1-301e-0096-4905-bcd313000000",
- "Body" : "\nLeaseNotPresentWithContainerOperation
There is currently no lease on the container.\nRequestId:33a2b6b1-301e-0096-4905-bcd313000000\nTime:2022-08-30T00:12:20.6460978Z ",
- "x-ms-client-request-id" : "878a8ef4-2add-4e7b-bcef-625d7b2d480e",
- "Date" : "Tue, 30 Aug 2022 00:12:19 GMT",
- "Content-Type" : "application/xml"
- },
- "Exception" : null
- } ],
- "variables" : [ "582a149a0582a149ae9a09141ec1291250ed549048ed", "582a149a1582a149ae9a9787432ca1a15b6eb44348bb" ]
-}
\ No newline at end of file
diff --git a/sdk/storage/azure-storage-file-datalake/src/test/resources/session-records/FileSystemAPITestRenameACIllegal[0].json b/sdk/storage/azure-storage-file-datalake/src/test/resources/session-records/FileSystemAPITestRenameACIllegal[0].json
deleted file mode 100644
index 49b483c3b266f..0000000000000
--- a/sdk/storage/azure-storage-file-datalake/src/test/resources/session-records/FileSystemAPITestRenameACIllegal[0].json
+++ /dev/null
@@ -1,25 +0,0 @@
-{
- "networkCallRecords" : [ {
- "Method" : "PUT",
- "Uri" : "https://REDACTED.blob.core.windows.net/b3c569000b3c569009b71630094cc6c53ccfd4b2a887?restype=container",
- "Headers" : {
- "x-ms-version" : "2021-10-04",
- "User-Agent" : "azsdk-java-azure-storage-blob/12.20.0-beta.2 azsdk-java-azure-storage-file-datalake/12.13.0-beta.1 (11.0.14; Windows 10; 10.0)",
- "x-ms-client-request-id" : "b6cdb4d7-8aac-407c-8e0c-f62e61798eb8"
- },
- "Response" : {
- "content-length" : "0",
- "x-ms-version" : "2021-10-04",
- "Server" : "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0",
- "eTag" : "0x8DA8A04E18C3184",
- "Last-Modified" : "Mon, 29 Aug 2022 21:24:39 GMT",
- "retry-after" : "0",
- "StatusCode" : "201",
- "x-ms-request-id" : "80c97e31-101e-0091-06ed-bbbf70000000",
- "x-ms-client-request-id" : "b6cdb4d7-8aac-407c-8e0c-f62e61798eb8",
- "Date" : "Mon, 29 Aug 2022 21:24:39 GMT"
- },
- "Exception" : null
- } ],
- "variables" : [ "b3c569000b3c569009b71630094cc6c53ccfd4b2a887", "b3c569001b3c569009b766375bc10d7920b9f4c4daff" ]
-}
\ No newline at end of file
diff --git a/sdk/storage/azure-storage-file-datalake/src/test/resources/session-records/FileSystemAPITestRenameACIllegal[1].json b/sdk/storage/azure-storage-file-datalake/src/test/resources/session-records/FileSystemAPITestRenameACIllegal[1].json
deleted file mode 100644
index a62a5a0f4b831..0000000000000
--- a/sdk/storage/azure-storage-file-datalake/src/test/resources/session-records/FileSystemAPITestRenameACIllegal[1].json
+++ /dev/null
@@ -1,25 +0,0 @@
-{
- "networkCallRecords" : [ {
- "Method" : "PUT",
- "Uri" : "https://REDACTED.blob.core.windows.net/aade58410aade5841bad13201c3238934911f4b43a64?restype=container",
- "Headers" : {
- "x-ms-version" : "2021-10-04",
- "User-Agent" : "azsdk-java-azure-storage-blob/12.20.0-beta.2 azsdk-java-azure-storage-file-datalake/12.13.0-beta.1 (11.0.14; Windows 10; 10.0)",
- "x-ms-client-request-id" : "ebd06352-6172-4afa-ba40-944bc54cd8ee"
- },
- "Response" : {
- "content-length" : "0",
- "x-ms-version" : "2021-10-04",
- "Server" : "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0",
- "eTag" : "0x8DA8A04E18CB241",
- "Last-Modified" : "Mon, 29 Aug 2022 21:24:39 GMT",
- "retry-after" : "0",
- "StatusCode" : "201",
- "x-ms-request-id" : "4edfc84e-801e-0048-32ed-bbc7f5000000",
- "x-ms-client-request-id" : "ebd06352-6172-4afa-ba40-944bc54cd8ee",
- "Date" : "Mon, 29 Aug 2022 21:24:39 GMT"
- },
- "Exception" : null
- } ],
- "variables" : [ "aade58410aade5841bad13201c3238934911f4b43a64", "aade58411aade5841bad822999176775eb90446079ff" ]
-}
\ No newline at end of file
diff --git a/sdk/storage/azure-storage-file-datalake/src/test/resources/session-records/FileSystemAPITestRenameACIllegal[2].json b/sdk/storage/azure-storage-file-datalake/src/test/resources/session-records/FileSystemAPITestRenameACIllegal[2].json
deleted file mode 100644
index 97edd1ed4e827..0000000000000
--- a/sdk/storage/azure-storage-file-datalake/src/test/resources/session-records/FileSystemAPITestRenameACIllegal[2].json
+++ /dev/null
@@ -1,25 +0,0 @@
-{
- "networkCallRecords" : [ {
- "Method" : "PUT",
- "Uri" : "https://REDACTED.blob.core.windows.net/81f30b82081f30b82e0853448a1e20400c02c403585d?restype=container",
- "Headers" : {
- "x-ms-version" : "2021-10-04",
- "User-Agent" : "azsdk-java-azure-storage-blob/12.20.0-beta.2 azsdk-java-azure-storage-file-datalake/12.13.0-beta.1 (11.0.14; Windows 10; 10.0)",
- "x-ms-client-request-id" : "a76d8114-dc79-41e5-a08c-bc1c18620e69"
- },
- "Response" : {
- "content-length" : "0",
- "x-ms-version" : "2021-10-04",
- "Server" : "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0",
- "eTag" : "0x8DA8A04E18C8B09",
- "Last-Modified" : "Mon, 29 Aug 2022 21:24:39 GMT",
- "retry-after" : "0",
- "StatusCode" : "201",
- "x-ms-request-id" : "01ba6878-b01e-007c-63ed-bbf43d000000",
- "x-ms-client-request-id" : "a76d8114-dc79-41e5-a08c-bc1c18620e69",
- "Date" : "Mon, 29 Aug 2022 21:24:39 GMT"
- },
- "Exception" : null
- } ],
- "variables" : [ "81f30b82081f30b82e0853448a1e20400c02c403585d", "81f30b82181f30b82e08106528c67c05289b747dd8b6" ]
-}
\ No newline at end of file
diff --git a/sdk/storage/azure-storage-file-datalake/src/test/resources/session-records/FileSystemAPITestRenameACIllegal[3].json b/sdk/storage/azure-storage-file-datalake/src/test/resources/session-records/FileSystemAPITestRenameACIllegal[3].json
deleted file mode 100644
index 4810fae19a298..0000000000000
--- a/sdk/storage/azure-storage-file-datalake/src/test/resources/session-records/FileSystemAPITestRenameACIllegal[3].json
+++ /dev/null
@@ -1,25 +0,0 @@
-{
- "networkCallRecords" : [ {
- "Method" : "PUT",
- "Uri" : "https://REDACTED.blob.core.windows.net/98e83ac3098e83ac311134268f5d73c90094b45d7ad8?restype=container",
- "Headers" : {
- "x-ms-version" : "2021-10-04",
- "User-Agent" : "azsdk-java-azure-storage-blob/12.20.0-beta.2 azsdk-java-azure-storage-file-datalake/12.13.0-beta.1 (11.0.14; Windows 10; 10.0)",
- "x-ms-client-request-id" : "5d4bbcce-fc3d-4d9b-bf23-7534b3a21a19"
- },
- "Response" : {
- "content-length" : "0",
- "x-ms-version" : "2021-10-04",
- "Server" : "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0",
- "eTag" : "0x8DA8A04E18C9FD2",
- "Last-Modified" : "Mon, 29 Aug 2022 21:24:39 GMT",
- "retry-after" : "0",
- "StatusCode" : "201",
- "x-ms-request-id" : "c7a6e2c4-a01e-0002-50ed-bb647a000000",
- "x-ms-client-request-id" : "5d4bbcce-fc3d-4d9b-bf23-7534b3a21a19",
- "Date" : "Mon, 29 Aug 2022 21:24:38 GMT"
- },
- "Exception" : null
- } ],
- "variables" : [ "98e83ac3098e83ac311134268f5d73c90094b45d7ad8", "98e83ac3198e83ac3111104925f2c3c4c4a9d403aaa7" ]
-}
\ No newline at end of file
diff --git a/sdk/storage/azure-storage-file-datalake/src/test/resources/session-records/FileSystemAPITestRenameAC[0].json b/sdk/storage/azure-storage-file-datalake/src/test/resources/session-records/FileSystemAPITestRenameAC[0].json
deleted file mode 100644
index 24d6099f34ed8..0000000000000
--- a/sdk/storage/azure-storage-file-datalake/src/test/resources/session-records/FileSystemAPITestRenameAC[0].json
+++ /dev/null
@@ -1,44 +0,0 @@
-{
- "networkCallRecords" : [ {
- "Method" : "PUT",
- "Uri" : "https://REDACTED.blob.core.windows.net/bccacf480bccacf48c0e7029900d3ce1aea314eccb54?restype=container",
- "Headers" : {
- "x-ms-version" : "2021-10-04",
- "User-Agent" : "azsdk-java-azure-storage-blob/12.20.0-beta.2 azsdk-java-azure-storage-file-datalake/12.13.0-beta.1 (11.0.14; Windows 10; 10.0)",
- "x-ms-client-request-id" : "b5536b22-7ffc-4903-9d15-19239202371b"
- },
- "Response" : {
- "content-length" : "0",
- "x-ms-version" : "2021-10-04",
- "Server" : "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0",
- "eTag" : "0x8DA89F8AE8019A5",
- "Last-Modified" : "Mon, 29 Aug 2022 19:57:19 GMT",
- "retry-after" : "0",
- "StatusCode" : "201",
- "x-ms-request-id" : "25c29c90-401e-0078-1ce1-bb793a000000",
- "x-ms-client-request-id" : "b5536b22-7ffc-4903-9d15-19239202371b",
- "Date" : "Mon, 29 Aug 2022 19:57:19 GMT"
- },
- "Exception" : null
- }, {
- "Method" : "PUT",
- "Uri" : "https://REDACTED.blob.core.windows.net/bccacf481bccacf48c0e66951a2e9942b11af46909bf?restype=container&comp=rename",
- "Headers" : {
- "x-ms-version" : "2021-10-04",
- "User-Agent" : "azsdk-java-azure-storage-blob/12.20.0-beta.2 azsdk-java-azure-storage-file-datalake/12.13.0-beta.1 (11.0.14; Windows 10; 10.0)",
- "x-ms-client-request-id" : "9e0ff522-7300-45bb-afe0-4c2531affd9b"
- },
- "Response" : {
- "content-length" : "0",
- "x-ms-version" : "2021-10-04",
- "Server" : "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0",
- "retry-after" : "0",
- "StatusCode" : "200",
- "x-ms-request-id" : "8ae42624-701e-0011-6de1-bb4076000000",
- "x-ms-client-request-id" : "9e0ff522-7300-45bb-afe0-4c2531affd9b",
- "Date" : "Mon, 29 Aug 2022 19:57:22 GMT"
- },
- "Exception" : null
- } ],
- "variables" : [ "bccacf480bccacf48c0e7029900d3ce1aea314eccb54", "bccacf481bccacf48c0e66951a2e9942b11af46909bf" ]
-}
\ No newline at end of file
diff --git a/sdk/storage/azure-storage-file-datalake/src/test/resources/session-records/FileSystemAPITestRenameAC[1].json b/sdk/storage/azure-storage-file-datalake/src/test/resources/session-records/FileSystemAPITestRenameAC[1].json
deleted file mode 100644
index 34710ac1eb0be..0000000000000
--- a/sdk/storage/azure-storage-file-datalake/src/test/resources/session-records/FileSystemAPITestRenameAC[1].json
+++ /dev/null
@@ -1,66 +0,0 @@
-{
- "networkCallRecords" : [ {
- "Method" : "PUT",
- "Uri" : "https://REDACTED.blob.core.windows.net/a5d1fe090a5d1fe092eb94985f0f908a9a3e341dab89?restype=container",
- "Headers" : {
- "x-ms-version" : "2021-10-04",
- "User-Agent" : "azsdk-java-azure-storage-blob/12.20.0-beta.2 azsdk-java-azure-storage-file-datalake/12.13.0-beta.1 (11.0.14; Windows 10; 10.0)",
- "x-ms-client-request-id" : "4904ca6b-88e7-4786-bf29-71ad24f68c07"
- },
- "Response" : {
- "content-length" : "0",
- "x-ms-version" : "2021-10-04",
- "Server" : "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0",
- "eTag" : "0x8DA89F8AE801998",
- "Last-Modified" : "Mon, 29 Aug 2022 19:57:19 GMT",
- "retry-after" : "0",
- "StatusCode" : "201",
- "x-ms-request-id" : "e7c5ceb7-001e-0024-17e1-bb2c62000000",
- "x-ms-client-request-id" : "4904ca6b-88e7-4786-bf29-71ad24f68c07",
- "Date" : "Mon, 29 Aug 2022 19:57:19 GMT"
- },
- "Exception" : null
- }, {
- "Method" : "PUT",
- "Uri" : "https://REDACTED.blob.core.windows.net/a5d1fe090a5d1fe092eb94985f0f908a9a3e341dab89?comp=lease&restype=container",
- "Headers" : {
- "x-ms-version" : "2021-10-04",
- "User-Agent" : "azsdk-java-azure-storage-file-datalake/12.13.0-beta.1 (11.0.14; Windows 10; 10.0)",
- "x-ms-client-request-id" : "7f245f37-4ee1-48ed-bc12-428b0e8584a1"
- },
- "Response" : {
- "content-length" : "0",
- "x-ms-version" : "2021-10-04",
- "Server" : "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0",
- "x-ms-lease-id" : "30d82a3e-9c3e-450a-80b0-de27fa647c9e",
- "eTag" : "0x8DA89F8AE801998",
- "Last-Modified" : "Mon, 29 Aug 2022 19:57:19 GMT",
- "retry-after" : "0",
- "StatusCode" : "201",
- "x-ms-request-id" : "25c29d47-401e-0078-43e1-bb793a000000",
- "x-ms-client-request-id" : "7f245f37-4ee1-48ed-bc12-428b0e8584a1",
- "Date" : "Mon, 29 Aug 2022 19:57:19 GMT"
- },
- "Exception" : null
- }, {
- "Method" : "PUT",
- "Uri" : "https://REDACTED.blob.core.windows.net/a5d1fe091a5d1fe092eb62165abedde9166b0495793f?restype=container&comp=rename",
- "Headers" : {
- "x-ms-version" : "2021-10-04",
- "User-Agent" : "azsdk-java-azure-storage-blob/12.20.0-beta.2 azsdk-java-azure-storage-file-datalake/12.13.0-beta.1 (11.0.14; Windows 10; 10.0)",
- "x-ms-client-request-id" : "76838022-df18-4ecc-85a1-dc9ac8014645"
- },
- "Response" : {
- "content-length" : "0",
- "x-ms-version" : "2021-10-04",
- "Server" : "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0",
- "retry-after" : "0",
- "StatusCode" : "200",
- "x-ms-request-id" : "25c29d84-401e-0078-7ee1-bb793a000000",
- "x-ms-client-request-id" : "76838022-df18-4ecc-85a1-dc9ac8014645",
- "Date" : "Mon, 29 Aug 2022 19:57:21 GMT"
- },
- "Exception" : null
- } ],
- "variables" : [ "a5d1fe090a5d1fe092eb94985f0f908a9a3e341dab89", "a5d1fe091a5d1fe092eb62165abedde9166b0495793f" ]
-}
\ No newline at end of file
diff --git a/sdk/storage/azure-storage-file-datalake/src/test/resources/session-records/FileSystemAPITestRenameError.json b/sdk/storage/azure-storage-file-datalake/src/test/resources/session-records/FileSystemAPITestRenameError.json
deleted file mode 100644
index c829cc5621499..0000000000000
--- a/sdk/storage/azure-storage-file-datalake/src/test/resources/session-records/FileSystemAPITestRenameError.json
+++ /dev/null
@@ -1,47 +0,0 @@
-{
- "networkCallRecords" : [ {
- "Method" : "PUT",
- "Uri" : "https://REDACTED.blob.core.windows.net/a0b3f7e10a0b3f7e16fc3973528e758338af7497abe3?restype=container",
- "Headers" : {
- "x-ms-version" : "2021-10-04",
- "User-Agent" : "azsdk-java-azure-storage-blob/12.20.0-beta.2 azsdk-java-azure-storage-file-datalake/12.13.0-beta.1 (11.0.14; Windows 10; 10.0)",
- "x-ms-client-request-id" : "1727a741-3f26-4daa-8c71-eacc4c2c1280"
- },
- "Response" : {
- "content-length" : "0",
- "x-ms-version" : "2021-10-04",
- "Server" : "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0",
- "eTag" : "0x8DA8A00390B9876",
- "Last-Modified" : "Mon, 29 Aug 2022 20:51:18 GMT",
- "retry-after" : "0",
- "StatusCode" : "201",
- "x-ms-request-id" : "77b6774d-901e-006b-24e9-bb5d36000000",
- "x-ms-client-request-id" : "1727a741-3f26-4daa-8c71-eacc4c2c1280",
- "Date" : "Mon, 29 Aug 2022 20:51:18 GMT"
- },
- "Exception" : null
- }, {
- "Method" : "PUT",
- "Uri" : "https://REDACTED.blob.core.windows.net/a0b3f7e12a0b3f7e16fc3454491209e95887d4124829?restype=container&comp=rename",
- "Headers" : {
- "x-ms-version" : "2021-10-04",
- "User-Agent" : "azsdk-java-azure-storage-blob/12.20.0-beta.2 azsdk-java-azure-storage-file-datalake/12.13.0-beta.1 (11.0.14; Windows 10; 10.0)",
- "x-ms-client-request-id" : "ecb76597-553c-4b06-a32d-1c1cbecaf40a"
- },
- "Response" : {
- "content-length" : "226",
- "x-ms-version" : "2021-10-04",
- "Server" : "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0",
- "x-ms-error-code" : "ContainerNotFound",
- "retry-after" : "0",
- "StatusCode" : "404",
- "x-ms-request-id" : "77b677b7-901e-006b-01e9-bb5d36000000",
- "Body" : "\nContainerNotFound
The specified container does not exist.\nRequestId:77b677b7-901e-006b-01e9-bb5d36000000\nTime:2022-08-29T20:51:21.5794976Z ",
- "x-ms-client-request-id" : "ecb76597-553c-4b06-a32d-1c1cbecaf40a",
- "Date" : "Mon, 29 Aug 2022 20:51:20 GMT",
- "Content-Type" : "application/xml"
- },
- "Exception" : null
- } ],
- "variables" : [ "a0b3f7e10a0b3f7e16fc3973528e758338af7497abe3", "a0b3f7e11a0b3f7e16fc78352d6b2504480e14e35b4c", "a0b3f7e12a0b3f7e16fc3454491209e95887d4124829" ]
-}
\ No newline at end of file
diff --git a/sdk/storage/azure-storage-file-datalake/src/test/resources/session-records/FileSystemAPITestRenameSas.json b/sdk/storage/azure-storage-file-datalake/src/test/resources/session-records/FileSystemAPITestRenameSas.json
deleted file mode 100644
index 2fd92f0082cf3..0000000000000
--- a/sdk/storage/azure-storage-file-datalake/src/test/resources/session-records/FileSystemAPITestRenameSas.json
+++ /dev/null
@@ -1,91 +0,0 @@
-{
- "networkCallRecords" : [ {
- "Method" : "PUT",
- "Uri" : "https://REDACTED.blob.core.windows.net/18ed57b0018ed57b0ae592810fa6a3ff132ea4d68a50?restype=container",
- "Headers" : {
- "x-ms-version" : "2021-10-04",
- "User-Agent" : "azsdk-java-azure-storage-blob/12.20.0-beta.2 azsdk-java-azure-storage-file-datalake/12.13.0-beta.1 (11.0.14; Windows 10; 10.0)",
- "x-ms-client-request-id" : "1f494353-a756-4a73-a78f-17104a9e5c5e"
- },
- "Response" : {
- "content-length" : "0",
- "x-ms-version" : "2021-10-04",
- "Server" : "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0",
- "eTag" : "0x8DA89F8AE82713C",
- "Last-Modified" : "Mon, 29 Aug 2022 19:57:19 GMT",
- "retry-after" : "0",
- "StatusCode" : "201",
- "x-ms-request-id" : "6a71df75-001e-0079-7ee1-bb26e6000000",
- "x-ms-client-request-id" : "1f494353-a756-4a73-a78f-17104a9e5c5e",
- "Date" : "Mon, 29 Aug 2022 19:57:19 GMT"
- },
- "Exception" : null
- }, {
- "Method" : "PUT",
- "Uri" : "https://REDACTED.blob.core.windows.net/18ed57b0118ed57b0ae595216958861d123b24f579cb?restype=container&comp=rename&sv=2021-10-04&ss=b&srt=sco&se=2022-08-30T19%3A57%3A19Z&sp=rwdc&sig=REDACTED",
- "Headers" : {
- "x-ms-version" : "2021-10-04",
- "User-Agent" : "azsdk-java-azure-storage-blob/12.20.0-beta.2 azsdk-java-azure-storage-file-datalake/12.13.0-beta.1 (11.0.14; Windows 10; 10.0)",
- "x-ms-client-request-id" : "0f1780e2-ff86-4006-8e74-fa0b20feba2d"
- },
- "Response" : {
- "content-length" : "0",
- "x-ms-version" : "2021-10-04",
- "Server" : "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0",
- "retry-after" : "0",
- "StatusCode" : "200",
- "x-ms-request-id" : "e7c5cf02-001e-0024-55e1-bb2c62000000",
- "x-ms-client-request-id" : "0f1780e2-ff86-4006-8e74-fa0b20feba2d",
- "Date" : "Mon, 29 Aug 2022 19:57:20 GMT"
- },
- "Exception" : null
- }, {
- "Method" : "GET",
- "Uri" : "https://REDACTED.blob.core.windows.net/18ed57b0118ed57b0ae595216958861d123b24f579cb?restype=container&sv=2021-10-04&ss=b&srt=sco&se=2022-08-30T19%3A57%3A19Z&sp=rwdc&sig=REDACTED",
- "Headers" : {
- "x-ms-version" : "2021-10-04",
- "User-Agent" : "azsdk-java-azure-storage-file-datalake/12.13.0-beta.1 (11.0.14; Windows 10; 10.0)",
- "x-ms-client-request-id" : "46ca0b66-7c1d-4bc8-88e8-7f8e0e252c40"
- },
- "Response" : {
- "content-length" : "0",
- "x-ms-version" : "2021-10-04",
- "x-ms-lease-status" : "unlocked",
- "x-ms-immutable-storage-with-versioning-enabled" : "false",
- "Server" : "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0",
- "x-ms-lease-state" : "available",
- "x-ms-deny-encryption-scope-override" : "false",
- "Last-Modified" : "Mon, 29 Aug 2022 19:57:20 GMT",
- "retry-after" : "0",
- "StatusCode" : "200",
- "x-ms-has-legal-hold" : "false",
- "Date" : "Mon, 29 Aug 2022 19:57:20 GMT",
- "x-ms-default-encryption-scope" : "$account-encryption-key",
- "x-ms-has-immutability-policy" : "false",
- "eTag" : "0x8DA89F8AEB89E96",
- "x-ms-request-id" : "e7c5cfa2-001e-0024-63e1-bb2c62000000",
- "x-ms-client-request-id" : "46ca0b66-7c1d-4bc8-88e8-7f8e0e252c40"
- },
- "Exception" : null
- }, {
- "Method" : "DELETE",
- "Uri" : "https://REDACTED.blob.core.windows.net/18ed57b0118ed57b0ae595216958861d123b24f579cb?restype=container&sv=2021-10-04&ss=b&srt=sco&se=2022-08-30T19%3A57%3A19Z&sp=rwdc&sig=REDACTED",
- "Headers" : {
- "x-ms-version" : "2021-10-04",
- "User-Agent" : "azsdk-java-azure-storage-file-datalake/12.13.0-beta.1 (11.0.14; Windows 10; 10.0)",
- "x-ms-client-request-id" : "34939e24-622d-4c61-91e7-bacb34f20cf5"
- },
- "Response" : {
- "content-length" : "0",
- "x-ms-version" : "2021-10-04",
- "Server" : "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0",
- "retry-after" : "0",
- "StatusCode" : "202",
- "x-ms-request-id" : "e7c5cfc2-001e-0024-7ee1-bb2c62000000",
- "x-ms-client-request-id" : "34939e24-622d-4c61-91e7-bacb34f20cf5",
- "Date" : "Mon, 29 Aug 2022 19:57:20 GMT"
- },
- "Exception" : null
- } ],
- "variables" : [ "18ed57b0018ed57b0ae592810fa6a3ff132ea4d68a50", "2022-08-29T19:57:19.965086800Z", "18ed57b0118ed57b0ae595216958861d123b24f579cb" ]
-}
\ No newline at end of file
diff --git a/sdk/textanalytics/azure-ai-textanalytics/CHANGELOG.md b/sdk/textanalytics/azure-ai-textanalytics/CHANGELOG.md
index 5ddeb0ec44496..d6e511c23e679 100644
--- a/sdk/textanalytics/azure-ai-textanalytics/CHANGELOG.md
+++ b/sdk/textanalytics/azure-ai-textanalytics/CHANGELOG.md
@@ -3,6 +3,16 @@
## 5.2.0-beta.5 (Unreleased)
### Features Added
+- Added `displayName` property which is the name of long-running operation, to the following classes to
+ set the optional display name:
+ - `AnalyzeHealthcareEntitiesOptions`
+ - `MultiLabelClassifyOptions`
+ - `RecognizeCustomEntitiesOptions`
+ - `SingleLabelClassifyOptions`
+- Added `displayName` property to the following operations to read the optional display name set on options classes above:
+ - `AnalyzeHealthcareEntitiesOperationDetail` from `AnalyzeHealthcareEntitiesOptions`
+ - `ClassifyDocumentOperationDetail` from `MultiLabelClassifyOptions` and `SingleLabelClassifyOptions`
+ - `RecognizeCustomEntitiesOperationDetail` from `RecognizeCustomEntitiesOptions`
### Breaking Changes
diff --git a/sdk/textanalytics/azure-ai-textanalytics/src/main/java/com/azure/ai/textanalytics/AnalyzeActionsAsyncClient.java b/sdk/textanalytics/azure-ai-textanalytics/src/main/java/com/azure/ai/textanalytics/AnalyzeActionsAsyncClient.java
index 3717d10565caa..ec8089916f2db 100644
--- a/sdk/textanalytics/azure-ai-textanalytics/src/main/java/com/azure/ai/textanalytics/AnalyzeActionsAsyncClient.java
+++ b/sdk/textanalytics/azure-ai-textanalytics/src/main/java/com/azure/ai/textanalytics/AnalyzeActionsAsyncClient.java
@@ -134,9 +134,11 @@
import static com.azure.ai.textanalytics.TextAnalyticsAsyncClient.COGNITIVE_TRACING_NAMESPACE_VALUE;
import static com.azure.ai.textanalytics.implementation.Utility.DEFAULT_POLL_INTERVAL;
+import static com.azure.ai.textanalytics.implementation.Utility.getUnsupportedServiceApiVersionMessage;
import static com.azure.ai.textanalytics.implementation.Utility.inputDocumentsValidation;
import static com.azure.ai.textanalytics.implementation.Utility.parseNextLink;
import static com.azure.ai.textanalytics.implementation.Utility.parseOperationId;
+import static com.azure.ai.textanalytics.implementation.Utility.throwIfTargetServiceVersionFound;
import static com.azure.ai.textanalytics.implementation.Utility.toAnalyzeHealthcareEntitiesResultCollection;
import static com.azure.ai.textanalytics.implementation.Utility.toAnalyzeSentimentResultCollection;
import static com.azure.ai.textanalytics.implementation.Utility.toCategoriesFilter;
@@ -174,19 +176,24 @@ class AnalyzeActionsAsyncClient {
private final ClientLogger logger = new ClientLogger(AnalyzeActionsAsyncClient.class);
private final TextAnalyticsClientImpl legacyService;
private final AnalyzeTextsImpl service;
+
+ private final TextAnalyticsServiceVersion serviceVersion;
+
private static final Pattern PATTERN;
static {
PATTERN = Pattern.compile(REGEX_ACTION_ERROR_TARGET, Pattern.MULTILINE);
}
- AnalyzeActionsAsyncClient(TextAnalyticsClientImpl legacyService) {
+ AnalyzeActionsAsyncClient(TextAnalyticsClientImpl legacyService, TextAnalyticsServiceVersion serviceVersion) {
this.legacyService = legacyService;
this.service = null;
+ this.serviceVersion = serviceVersion;
}
- AnalyzeActionsAsyncClient(AnalyzeTextsImpl service) {
+ AnalyzeActionsAsyncClient(AnalyzeTextsImpl service, TextAnalyticsServiceVersion serviceVersion) {
this.legacyService = null;
this.service = service;
+ this.serviceVersion = serviceVersion;
}
PollerFlux beginAnalyzeActions(
@@ -194,6 +201,9 @@ PollerFlux beginAn
Context context) {
try {
Objects.requireNonNull(actions, "'actions' cannot be null.");
+ throwIfTargetServiceVersionFound(this.serviceVersion, Arrays.asList(TextAnalyticsServiceVersion.V3_0),
+ getUnsupportedServiceApiVersionMessage("beginAnalyzeActions", serviceVersion,
+ TextAnalyticsServiceVersion.V3_1));
inputDocumentsValidation(documents);
options = getNotNullAnalyzeActionsOptions(options);
final Context finalContext = getNotNullContext(context)
@@ -229,6 +239,8 @@ PollerFlux beginAn
);
}
+ throwIfTargetServiceVersionFoundForActions(this.serviceVersion,
+ Arrays.asList(TextAnalyticsServiceVersion.V3_0, TextAnalyticsServiceVersion.V3_1), actions);
final AnalyzeBatchInput analyzeBatchInput =
new AnalyzeBatchInput()
.setAnalysisInput(new MultiLanguageBatchInput().setDocuments(toMultiLanguageInput(documents)))
@@ -263,6 +275,9 @@ PollerFlux beg
Context context) {
try {
Objects.requireNonNull(actions, "'actions' cannot be null.");
+ throwIfTargetServiceVersionFound(this.serviceVersion, Arrays.asList(TextAnalyticsServiceVersion.V3_0),
+ getUnsupportedServiceApiVersionMessage("beginAnalyzeActions", serviceVersion,
+ TextAnalyticsServiceVersion.V3_1));
inputDocumentsValidation(documents);
options = getNotNullAnalyzeActionsOptions(options);
final Context finalContext = getNotNullContext(context)
@@ -301,6 +316,8 @@ PollerFlux beg
);
}
+ throwIfTargetServiceVersionFoundForActions(this.serviceVersion,
+ Arrays.asList(TextAnalyticsServiceVersion.V3_0, TextAnalyticsServiceVersion.V3_1), actions);
return new PollerFlux<>(
DEFAULT_POLL_INTERVAL,
activationOperation(
@@ -1284,4 +1301,31 @@ private String[] parseActionErrorTarget(String targetReference, String errorMess
}
return taskNameIdPair;
}
+
+ private void throwIfTargetServiceVersionFoundForActions(TextAnalyticsServiceVersion sourceVersion,
+ List targetVersions, TextAnalyticsActions actions) {
+ if (actions.getMultiLabelClassifyActions() != null) {
+ throwIfTargetServiceVersionFound(sourceVersion, targetVersions,
+ getUnsupportedServiceApiVersionMessage("MultiLabelClassifyAction", serviceVersion,
+ TextAnalyticsServiceVersion.V2022_05_01));
+ }
+
+ if (actions.getSingleLabelClassifyActions() != null) {
+ throwIfTargetServiceVersionFound(sourceVersion, targetVersions,
+ getUnsupportedServiceApiVersionMessage("SingleLabelClassifyAction", serviceVersion,
+ TextAnalyticsServiceVersion.V2022_05_01));
+ }
+
+ if (actions.getRecognizeCustomEntitiesActions() != null) {
+ throwIfTargetServiceVersionFound(sourceVersion, targetVersions,
+ getUnsupportedServiceApiVersionMessage("RecognizeCustomEntitiesAction", serviceVersion,
+ TextAnalyticsServiceVersion.V2022_05_01));
+ }
+
+ if (actions.getAnalyzeHealthcareEntitiesActions() != null) {
+ throwIfTargetServiceVersionFound(sourceVersion, targetVersions,
+ getUnsupportedServiceApiVersionMessage("AnalyzeHealthcareEntitiesAction", serviceVersion,
+ TextAnalyticsServiceVersion.V2022_05_01));
+ }
+ }
}
diff --git a/sdk/textanalytics/azure-ai-textanalytics/src/main/java/com/azure/ai/textanalytics/AnalyzeHealthcareEntityAsyncClient.java b/sdk/textanalytics/azure-ai-textanalytics/src/main/java/com/azure/ai/textanalytics/AnalyzeHealthcareEntityAsyncClient.java
index 3e216d0172a8a..9183799bae480 100644
--- a/sdk/textanalytics/azure-ai-textanalytics/src/main/java/com/azure/ai/textanalytics/AnalyzeHealthcareEntityAsyncClient.java
+++ b/sdk/textanalytics/azure-ai-textanalytics/src/main/java/com/azure/ai/textanalytics/AnalyzeHealthcareEntityAsyncClient.java
@@ -58,9 +58,11 @@
import static com.azure.ai.textanalytics.TextAnalyticsAsyncClient.COGNITIVE_TRACING_NAMESPACE_VALUE;
import static com.azure.ai.textanalytics.implementation.Utility.DEFAULT_POLL_INTERVAL;
import static com.azure.ai.textanalytics.implementation.Utility.getNotNullContext;
+import static com.azure.ai.textanalytics.implementation.Utility.getUnsupportedServiceApiVersionMessage;
import static com.azure.ai.textanalytics.implementation.Utility.inputDocumentsValidation;
import static com.azure.ai.textanalytics.implementation.Utility.parseNextLink;
import static com.azure.ai.textanalytics.implementation.Utility.parseOperationId;
+import static com.azure.ai.textanalytics.implementation.Utility.throwIfTargetServiceVersionFound;
import static com.azure.ai.textanalytics.implementation.Utility.toAnalyzeHealthcareEntitiesResultCollection;
import static com.azure.ai.textanalytics.implementation.Utility.toMultiLanguageInput;
import static com.azure.ai.textanalytics.implementation.models.State.CANCELLED;
@@ -75,20 +77,30 @@ class AnalyzeHealthcareEntityAsyncClient {
private final TextAnalyticsClientImpl legacyService;
private final AnalyzeTextsImpl service;
- AnalyzeHealthcareEntityAsyncClient(TextAnalyticsClientImpl legacyService) {
+ private final TextAnalyticsServiceVersion serviceVersion;
+
+ AnalyzeHealthcareEntityAsyncClient(TextAnalyticsClientImpl legacyService,
+ TextAnalyticsServiceVersion serviceVersion) {
this.legacyService = legacyService;
this.service = null;
+ this.serviceVersion = serviceVersion;
}
- AnalyzeHealthcareEntityAsyncClient(AnalyzeTextsImpl service) {
+ AnalyzeHealthcareEntityAsyncClient(AnalyzeTextsImpl service, TextAnalyticsServiceVersion serviceVersion) {
this.legacyService = null;
this.service = service;
+ this.serviceVersion = serviceVersion;
}
PollerFlux
beginAnalyzeHealthcareEntities(Iterable documents, AnalyzeHealthcareEntitiesOptions options,
Context context) {
try {
+ throwIfTargetServiceVersionFound(this.serviceVersion,
+ Arrays.asList(TextAnalyticsServiceVersion.V3_0),
+ getUnsupportedServiceApiVersionMessage("beginAnalyzeHealthcareEntities", serviceVersion,
+ TextAnalyticsServiceVersion.V3_1));
+ throwIfCallingNotAvailableFeatureInOptions(options);
inputDocumentsValidation(documents);
options = getNotNullAnalyzeHealthcareEntitiesOptions(options);
final Context finalContext = getNotNullContext(context)
@@ -99,11 +111,13 @@ class AnalyzeHealthcareEntityAsyncClient {
final boolean finalLoggingOptOut = options.isServiceLogsDisabled();
if (service != null) {
+ final String displayName = options.getDisplayName();
return new PollerFlux<>(
DEFAULT_POLL_INTERVAL,
activationOperation(
service.submitJobWithResponseAsync(
new AnalyzeTextJobsInput()
+ .setDisplayName(displayName)
.setAnalysisInput(
new MultiLanguageAnalysisInput().setDocuments(toMultiLanguageInput(documents)))
.setTasks(Arrays.asList(
@@ -162,6 +176,11 @@ class AnalyzeHealthcareEntityAsyncClient {
beginAnalyzeHealthcarePagedIterable(Iterable documents,
AnalyzeHealthcareEntitiesOptions options, Context context) {
try {
+ throwIfTargetServiceVersionFound(this.serviceVersion,
+ Arrays.asList(TextAnalyticsServiceVersion.V3_0),
+ getUnsupportedServiceApiVersionMessage("beginAnalyzeHealthcareEntities", serviceVersion,
+ TextAnalyticsServiceVersion.V3_1));
+ throwIfCallingNotAvailableFeatureInOptions(options);
inputDocumentsValidation(documents);
options = getNotNullAnalyzeHealthcareEntitiesOptions(options);
final Context finalContext = getNotNullContext(context)
@@ -172,11 +191,13 @@ class AnalyzeHealthcareEntityAsyncClient {
final boolean finalLoggingOptOut = options.isServiceLogsDisabled();
if (service != null) {
+ final String displayName = options.getDisplayName();
return new PollerFlux<>(
DEFAULT_POLL_INTERVAL,
activationOperation(
service.submitJobWithResponseAsync(
new AnalyzeTextJobsInput()
+ .setDisplayName(displayName)
.setAnalysisInput(
new MultiLanguageAnalysisInput().setDocuments(toMultiLanguageInput(documents)))
.setTasks(Arrays.asList(
@@ -526,7 +547,8 @@ private Mono> processAnal
status = LongRunningOperationStatus.fromString(
analyzeOperationResultResponse.getValue().getStatus().toString(), true);
}
-
+ AnalyzeHealthcareEntitiesOperationDetailPropertiesHelper.setDisplayName(operationResultPollResponse.getValue(),
+ analyzeOperationResultResponse.getValue().getDisplayName());
AnalyzeHealthcareEntitiesOperationDetailPropertiesHelper.setCreatedAt(operationResultPollResponse.getValue(),
analyzeOperationResultResponse.getValue().getCreatedDateTime());
AnalyzeHealthcareEntitiesOperationDetailPropertiesHelper.setLastModifiedAt(
@@ -540,4 +562,13 @@ private AnalyzeHealthcareEntitiesOptions getNotNullAnalyzeHealthcareEntitiesOpti
AnalyzeHealthcareEntitiesOptions options) {
return options == null ? new AnalyzeHealthcareEntitiesOptions() : options;
}
+
+ private void throwIfCallingNotAvailableFeatureInOptions(AnalyzeHealthcareEntitiesOptions options) {
+ if (options != null && options.getDisplayName() != null) {
+ throwIfTargetServiceVersionFound(serviceVersion,
+ Arrays.asList(TextAnalyticsServiceVersion.V3_1),
+ getUnsupportedServiceApiVersionMessage("AnalyzeHealthcareEntitiesOptions.displayName",
+ serviceVersion, TextAnalyticsServiceVersion.V2022_05_01));
+ }
+ }
}
diff --git a/sdk/textanalytics/azure-ai-textanalytics/src/main/java/com/azure/ai/textanalytics/AnalyzeSentimentAsyncClient.java b/sdk/textanalytics/azure-ai-textanalytics/src/main/java/com/azure/ai/textanalytics/AnalyzeSentimentAsyncClient.java
index 9268917eb0a84..499ac274ad4ab 100644
--- a/sdk/textanalytics/azure-ai-textanalytics/src/main/java/com/azure/ai/textanalytics/AnalyzeSentimentAsyncClient.java
+++ b/sdk/textanalytics/azure-ai-textanalytics/src/main/java/com/azure/ai/textanalytics/AnalyzeSentimentAsyncClient.java
@@ -21,10 +21,14 @@
import com.azure.core.util.logging.ClientLogger;
import reactor.core.publisher.Mono;
+import java.util.Arrays;
+
import static com.azure.ai.textanalytics.TextAnalyticsAsyncClient.COGNITIVE_TRACING_NAMESPACE_VALUE;
import static com.azure.ai.textanalytics.implementation.Utility.getDocumentCount;
import static com.azure.ai.textanalytics.implementation.Utility.getNotNullContext;
+import static com.azure.ai.textanalytics.implementation.Utility.getUnsupportedServiceApiVersionMessage;
import static com.azure.ai.textanalytics.implementation.Utility.inputDocumentsValidation;
+import static com.azure.ai.textanalytics.implementation.Utility.throwIfTargetServiceVersionFound;
import static com.azure.ai.textanalytics.implementation.Utility.toMultiLanguageInput;
import static com.azure.core.util.FluxUtil.monoError;
import static com.azure.core.util.FluxUtil.withContext;
@@ -38,14 +42,19 @@ class AnalyzeSentimentAsyncClient {
private final TextAnalyticsClientImpl legacyService;
private final MicrosoftCognitiveLanguageServiceTextAnalysisImpl service;
- AnalyzeSentimentAsyncClient(TextAnalyticsClientImpl legacyService) {
+ private final TextAnalyticsServiceVersion serviceVersion;
+
+ AnalyzeSentimentAsyncClient(TextAnalyticsClientImpl legacyService, TextAnalyticsServiceVersion serviceVersion) {
this.legacyService = legacyService;
this.service = null;
+ this.serviceVersion = serviceVersion;
}
- AnalyzeSentimentAsyncClient(MicrosoftCognitiveLanguageServiceTextAnalysisImpl service) {
+ AnalyzeSentimentAsyncClient(MicrosoftCognitiveLanguageServiceTextAnalysisImpl service,
+ TextAnalyticsServiceVersion serviceVersion) {
this.legacyService = null;
this.service = service;
+ this.serviceVersion = serviceVersion;
}
/**
@@ -64,7 +73,6 @@ class AnalyzeSentimentAsyncClient {
public Mono> analyzeSentimentBatch(
Iterable documents, AnalyzeSentimentOptions options) {
try {
- inputDocumentsValidation(documents);
return withContext(context -> getAnalyzedSentimentResponse(documents, options, context));
} catch (RuntimeException ex) {
return monoError(logger, ex);
@@ -85,7 +93,6 @@ public Mono> analyzeSentimentBatch(
Mono> analyzeSentimentBatchWithContext(
Iterable documents, AnalyzeSentimentOptions options, Context context) {
try {
- inputDocumentsValidation(documents);
return getAnalyzedSentimentResponse(documents, options, context);
} catch (RuntimeException ex) {
return monoError(logger, ex);
@@ -105,6 +112,8 @@ Mono> analyzeSentimentBatchWithContex
*/
private Mono> getAnalyzedSentimentResponse(
Iterable documents, AnalyzeSentimentOptions options, Context context) {
+ throwIfCallingNotAvailableFeatureInOptions(options);
+ inputDocumentsValidation(documents);
options = options == null ? new AnalyzeSentimentOptions() : options;
if (service != null) {
@@ -146,4 +155,20 @@ private Mono> getAnalyzedSentimentRes
.map(Utility::toAnalyzeSentimentResultCollectionResponse)
.onErrorMap(Utility::mapToHttpResponseExceptionIfExists);
}
+
+ private void throwIfCallingNotAvailableFeatureInOptions(AnalyzeSentimentOptions options) {
+ if (options == null) {
+ return;
+ }
+ if (options.isIncludeOpinionMining()) {
+ throwIfTargetServiceVersionFound(this.serviceVersion, Arrays.asList(TextAnalyticsServiceVersion.V3_0),
+ getUnsupportedServiceApiVersionMessage("AnalyzeSentimentOptions.includeOpinionMining",
+ serviceVersion, TextAnalyticsServiceVersion.V3_1));
+ }
+ if (options.isServiceLogsDisabled()) {
+ throwIfTargetServiceVersionFound(this.serviceVersion, Arrays.asList(TextAnalyticsServiceVersion.V3_0),
+ getUnsupportedServiceApiVersionMessage("TextAnalyticsRequestOptions.disableServiceLogs",
+ serviceVersion, TextAnalyticsServiceVersion.V3_1));
+ }
+ }
}
diff --git a/sdk/textanalytics/azure-ai-textanalytics/src/main/java/com/azure/ai/textanalytics/DetectLanguageAsyncClient.java b/sdk/textanalytics/azure-ai-textanalytics/src/main/java/com/azure/ai/textanalytics/DetectLanguageAsyncClient.java
index fc4fb4342cb1b..7bd95f8dd4316 100644
--- a/sdk/textanalytics/azure-ai-textanalytics/src/main/java/com/azure/ai/textanalytics/DetectLanguageAsyncClient.java
+++ b/sdk/textanalytics/azure-ai-textanalytics/src/main/java/com/azure/ai/textanalytics/DetectLanguageAsyncClient.java
@@ -21,10 +21,14 @@
import com.azure.core.util.logging.ClientLogger;
import reactor.core.publisher.Mono;
+import java.util.Arrays;
+
import static com.azure.ai.textanalytics.TextAnalyticsAsyncClient.COGNITIVE_TRACING_NAMESPACE_VALUE;
import static com.azure.ai.textanalytics.implementation.Utility.getDocumentCount;
import static com.azure.ai.textanalytics.implementation.Utility.getNotNullContext;
+import static com.azure.ai.textanalytics.implementation.Utility.getUnsupportedServiceApiVersionMessage;
import static com.azure.ai.textanalytics.implementation.Utility.inputDocumentsValidation;
+import static com.azure.ai.textanalytics.implementation.Utility.throwIfTargetServiceVersionFound;
import static com.azure.ai.textanalytics.implementation.Utility.toLanguageInput;
import static com.azure.core.util.FluxUtil.monoError;
import static com.azure.core.util.FluxUtil.withContext;
@@ -38,14 +42,19 @@ class DetectLanguageAsyncClient {
private final TextAnalyticsClientImpl legacyService;
private final MicrosoftCognitiveLanguageServiceTextAnalysisImpl service;
- DetectLanguageAsyncClient(TextAnalyticsClientImpl legacyService) {
+ private final TextAnalyticsServiceVersion serviceVersion;
+
+ DetectLanguageAsyncClient(TextAnalyticsClientImpl legacyService, TextAnalyticsServiceVersion serviceVersion) {
this.legacyService = legacyService;
this.service = null;
+ this.serviceVersion = serviceVersion;
}
- DetectLanguageAsyncClient(MicrosoftCognitiveLanguageServiceTextAnalysisImpl service) {
+ DetectLanguageAsyncClient(MicrosoftCognitiveLanguageServiceTextAnalysisImpl service,
+ TextAnalyticsServiceVersion serviceVersion) {
this.legacyService = null;
this.service = service;
+ this.serviceVersion = serviceVersion;
}
/**
@@ -59,7 +68,6 @@ class DetectLanguageAsyncClient {
Mono> detectLanguageBatch(
Iterable documents, TextAnalyticsRequestOptions options) {
try {
- inputDocumentsValidation(documents);
return withContext(context -> getDetectedLanguageResponse(documents, options, context));
} catch (RuntimeException ex) {
return monoError(logger, ex);
@@ -78,7 +86,6 @@ Mono> detectLanguageBatch(
Mono> detectLanguageBatchWithContext(
Iterable documents, TextAnalyticsRequestOptions options, Context context) {
try {
- inputDocumentsValidation(documents);
return getDetectedLanguageResponse(documents, options, context);
} catch (RuntimeException ex) {
return monoError(logger, ex);
@@ -97,6 +104,8 @@ Mono> detectLanguageBatchWithContext(
*/
private Mono> getDetectedLanguageResponse(
Iterable documents, TextAnalyticsRequestOptions options, Context context) {
+ throwIfCallingNotAvailableFeatureInOptions(options);
+ inputDocumentsValidation(documents);
options = options == null ? new TextAnalyticsRequestOptions() : options;
if (service != null) {
return service
@@ -135,4 +144,12 @@ private Mono> getDetectedLanguageRespon
.map(Utility::toDetectLanguageResultCollectionResponse)
.onErrorMap(Utility::mapToHttpResponseExceptionIfExists);
}
+
+ private void throwIfCallingNotAvailableFeatureInOptions(TextAnalyticsRequestOptions options) {
+ if (options != null && options.isServiceLogsDisabled()) {
+ throwIfTargetServiceVersionFound(this.serviceVersion, Arrays.asList(TextAnalyticsServiceVersion.V3_0),
+ getUnsupportedServiceApiVersionMessage("TextAnalyticsRequestOptions.disableServiceLogs",
+ serviceVersion, TextAnalyticsServiceVersion.V3_1));
+ }
+ }
}
diff --git a/sdk/textanalytics/azure-ai-textanalytics/src/main/java/com/azure/ai/textanalytics/ExtractKeyPhraseAsyncClient.java b/sdk/textanalytics/azure-ai-textanalytics/src/main/java/com/azure/ai/textanalytics/ExtractKeyPhraseAsyncClient.java
index 8a90137b95fcd..a84eaf7215c7d 100644
--- a/sdk/textanalytics/azure-ai-textanalytics/src/main/java/com/azure/ai/textanalytics/ExtractKeyPhraseAsyncClient.java
+++ b/sdk/textanalytics/azure-ai-textanalytics/src/main/java/com/azure/ai/textanalytics/ExtractKeyPhraseAsyncClient.java
@@ -22,13 +22,16 @@
import com.azure.core.util.logging.ClientLogger;
import reactor.core.publisher.Mono;
+import java.util.Arrays;
import java.util.Collections;
import java.util.Objects;
import static com.azure.ai.textanalytics.TextAnalyticsAsyncClient.COGNITIVE_TRACING_NAMESPACE_VALUE;
import static com.azure.ai.textanalytics.implementation.Utility.getDocumentCount;
import static com.azure.ai.textanalytics.implementation.Utility.getNotNullContext;
+import static com.azure.ai.textanalytics.implementation.Utility.getUnsupportedServiceApiVersionMessage;
import static com.azure.ai.textanalytics.implementation.Utility.inputDocumentsValidation;
+import static com.azure.ai.textanalytics.implementation.Utility.throwIfTargetServiceVersionFound;
import static com.azure.ai.textanalytics.implementation.Utility.toMultiLanguageInput;
import static com.azure.ai.textanalytics.implementation.Utility.toTextAnalyticsException;
import static com.azure.core.util.FluxUtil.monoError;
@@ -43,14 +46,19 @@ class ExtractKeyPhraseAsyncClient {
private final TextAnalyticsClientImpl legacyService;
private final MicrosoftCognitiveLanguageServiceTextAnalysisImpl service;
- ExtractKeyPhraseAsyncClient(TextAnalyticsClientImpl legacyService) {
+ private final TextAnalyticsServiceVersion serviceVersion;
+
+ ExtractKeyPhraseAsyncClient(TextAnalyticsClientImpl legacyService, TextAnalyticsServiceVersion serviceVersion) {
this.legacyService = legacyService;
this.service = null;
+ this.serviceVersion = serviceVersion;
}
- ExtractKeyPhraseAsyncClient(MicrosoftCognitiveLanguageServiceTextAnalysisImpl service) {
+ ExtractKeyPhraseAsyncClient(MicrosoftCognitiveLanguageServiceTextAnalysisImpl service,
+ TextAnalyticsServiceVersion serviceVersion) {
this.legacyService = null;
this.service = service;
+ this.serviceVersion = serviceVersion;
}
/**
@@ -96,7 +104,6 @@ Mono extractKeyPhrasesSingleText(String document, String l
Mono> extractKeyPhrasesWithResponse(
Iterable documents, TextAnalyticsRequestOptions options) {
try {
- inputDocumentsValidation(documents);
return withContext(context -> getExtractedKeyPhrasesResponse(documents, options, context));
} catch (RuntimeException ex) {
return monoError(logger, ex);
@@ -116,7 +123,6 @@ Mono> extractKeyPhrasesWithResponse(
Mono> extractKeyPhrasesBatchWithContext(
Iterable documents, TextAnalyticsRequestOptions options, Context context) {
try {
- inputDocumentsValidation(documents);
return getExtractedKeyPhrasesResponse(documents, options, context);
} catch (RuntimeException ex) {
return monoError(logger, ex);
@@ -135,6 +141,8 @@ Mono> extractKeyPhrasesBatchWithCont
*/
private Mono> getExtractedKeyPhrasesResponse(
Iterable documents, TextAnalyticsRequestOptions options, Context context) {
+ throwIfCallingNotAvailableFeatureInOptions(options);
+ inputDocumentsValidation(documents);
options = options == null ? new TextAnalyticsRequestOptions() : options;
if (service != null) {
@@ -171,4 +179,12 @@ private Mono> getExtractedKeyPhrases
.map(Utility::toExtractKeyPhrasesResultCollectionResponse)
.onErrorMap(Utility::mapToHttpResponseExceptionIfExists);
}
+
+ private void throwIfCallingNotAvailableFeatureInOptions(TextAnalyticsRequestOptions options) {
+ if (options != null && options.isServiceLogsDisabled()) {
+ throwIfTargetServiceVersionFound(this.serviceVersion, Arrays.asList(TextAnalyticsServiceVersion.V3_0),
+ getUnsupportedServiceApiVersionMessage("TextAnalyticsRequestOptions.disableServiceLogs",
+ serviceVersion, TextAnalyticsServiceVersion.V3_1));
+ }
+ }
}
diff --git a/sdk/textanalytics/azure-ai-textanalytics/src/main/java/com/azure/ai/textanalytics/LabelClassifyAsyncClient.java b/sdk/textanalytics/azure-ai-textanalytics/src/main/java/com/azure/ai/textanalytics/LabelClassifyAsyncClient.java
index f7802827091a2..79e91024900ad 100644
--- a/sdk/textanalytics/azure-ai-textanalytics/src/main/java/com/azure/ai/textanalytics/LabelClassifyAsyncClient.java
+++ b/sdk/textanalytics/azure-ai-textanalytics/src/main/java/com/azure/ai/textanalytics/LabelClassifyAsyncClient.java
@@ -58,9 +58,11 @@
import static com.azure.ai.textanalytics.TextAnalyticsAsyncClient.COGNITIVE_TRACING_NAMESPACE_VALUE;
import static com.azure.ai.textanalytics.implementation.Utility.DEFAULT_POLL_INTERVAL;
import static com.azure.ai.textanalytics.implementation.Utility.getNotNullContext;
+import static com.azure.ai.textanalytics.implementation.Utility.getUnsupportedServiceApiVersionMessage;
import static com.azure.ai.textanalytics.implementation.Utility.inputDocumentsValidation;
import static com.azure.ai.textanalytics.implementation.Utility.parseNextLink;
import static com.azure.ai.textanalytics.implementation.Utility.parseOperationId;
+import static com.azure.ai.textanalytics.implementation.Utility.throwIfTargetServiceVersionFound;
import static com.azure.ai.textanalytics.implementation.Utility.toLabelClassificationResultCollection;
import static com.azure.ai.textanalytics.implementation.Utility.toMultiLanguageInput;
import static com.azure.ai.textanalytics.implementation.models.State.CANCELLED;
@@ -74,26 +76,35 @@ class LabelClassifyAsyncClient {
private static final ClientLogger LOGGER = new ClientLogger(LabelClassifyAsyncClient.class);
private final AnalyzeTextsImpl service;
- LabelClassifyAsyncClient(AnalyzeTextsImpl service) {
+ private final TextAnalyticsServiceVersion serviceVersion;
+
+ LabelClassifyAsyncClient(AnalyzeTextsImpl service, TextAnalyticsServiceVersion serviceVersion) {
this.service = service;
+ this.serviceVersion = serviceVersion;
}
PollerFlux singleLabelClassify(
Iterable documents, String projectName, String deploymentName,
SingleLabelClassifyOptions options, Context context) {
try {
+ throwIfTargetServiceVersionFound(this.serviceVersion,
+ Arrays.asList(TextAnalyticsServiceVersion.V3_0, TextAnalyticsServiceVersion.V3_1),
+ getUnsupportedServiceApiVersionMessage("beginSingleLabelClassify", serviceVersion,
+ TextAnalyticsServiceVersion.V2022_05_01));
inputDocumentsValidation(documents);
options = getNotNullSingleLabelClassifyOptions(options);
final Context finalContext = getNotNullContext(context)
.addData(AZ_TRACING_NAMESPACE_KEY, COGNITIVE_TRACING_NAMESPACE_VALUE);
final boolean finalLoggingOptOut = options.isServiceLogsDisabled();
final boolean finalIncludeStatistics = options.isIncludeStatistics();
+ final String displayName = options.getDisplayName();
return new PollerFlux<>(
DEFAULT_POLL_INTERVAL,
activationOperation(
service.submitJobWithResponseAsync(
new AnalyzeTextJobsInput()
+ .setDisplayName(displayName)
.setAnalysisInput(
new MultiLanguageAnalysisInput().setDocuments(toMultiLanguageInput(documents)))
.setTasks(Arrays.asList(
@@ -129,18 +140,24 @@ PollerFlux singl
Iterable documents, String projectName, String deploymentName,
SingleLabelClassifyOptions options, Context context) {
try {
+ throwIfTargetServiceVersionFound(this.serviceVersion,
+ Arrays.asList(TextAnalyticsServiceVersion.V3_0, TextAnalyticsServiceVersion.V3_1),
+ getUnsupportedServiceApiVersionMessage("beginSingleLabelClassify", serviceVersion,
+ TextAnalyticsServiceVersion.V2022_05_01));
inputDocumentsValidation(documents);
options = getNotNullSingleLabelClassifyOptions(options);
final Context finalContext = getNotNullContext(context)
.addData(AZ_TRACING_NAMESPACE_KEY, COGNITIVE_TRACING_NAMESPACE_VALUE);
final boolean finalIncludeStatistics = options.isIncludeStatistics();
final boolean finalLoggingOptOut = options.isServiceLogsDisabled();
+ final String displayName = options.getDisplayName();
return new PollerFlux<>(
DEFAULT_POLL_INTERVAL,
activationOperation(
service.submitJobWithResponseAsync(
new AnalyzeTextJobsInput()
+ .setDisplayName(displayName)
.setAnalysisInput(
new MultiLanguageAnalysisInput().setDocuments(toMultiLanguageInput(documents)))
.setTasks(Arrays.asList(
@@ -176,18 +193,24 @@ PollerFlux multiLabe
Iterable documents, String projectName, String deploymentName,
MultiLabelClassifyOptions options, Context context) {
try {
+ throwIfTargetServiceVersionFound(this.serviceVersion,
+ Arrays.asList(TextAnalyticsServiceVersion.V3_0, TextAnalyticsServiceVersion.V3_1),
+ getUnsupportedServiceApiVersionMessage("beginMultiLabelClassify", serviceVersion,
+ TextAnalyticsServiceVersion.V2022_05_01));
inputDocumentsValidation(documents);
options = getNotNullMultiLabelClassifyOptions(options);
final Context finalContext = getNotNullContext(context)
.addData(AZ_TRACING_NAMESPACE_KEY, COGNITIVE_TRACING_NAMESPACE_VALUE);
final boolean finalLoggingOptOut = options.isServiceLogsDisabled();
final boolean finalIncludeStatistics = options.isIncludeStatistics();
+ final String displayName = options.getDisplayName();
return new PollerFlux<>(
DEFAULT_POLL_INTERVAL,
activationOperation(
service.submitJobWithResponseAsync(
new AnalyzeTextJobsInput()
+ .setDisplayName(displayName)
.setAnalysisInput(
new MultiLanguageAnalysisInput().setDocuments(toMultiLanguageInput(documents)))
.setTasks(Arrays.asList(
@@ -223,18 +246,24 @@ PollerFlux multi
Iterable documents, String projectName, String deploymentName,
MultiLabelClassifyOptions options, Context context) {
try {
+ throwIfTargetServiceVersionFound(this.serviceVersion,
+ Arrays.asList(TextAnalyticsServiceVersion.V3_0, TextAnalyticsServiceVersion.V3_1),
+ getUnsupportedServiceApiVersionMessage("beginMultiLabelClassify", serviceVersion,
+ TextAnalyticsServiceVersion.V2022_05_01));
inputDocumentsValidation(documents);
options = getNotNullMultiLabelClassifyOptions(options);
final Context finalContext = getNotNullContext(context)
.addData(AZ_TRACING_NAMESPACE_KEY, COGNITIVE_TRACING_NAMESPACE_VALUE);
final boolean finalIncludeStatistics = options.isIncludeStatistics();
final boolean finalLoggingOptOut = options.isServiceLogsDisabled();
+ final String displayName = options.getDisplayName();
return new PollerFlux<>(
DEFAULT_POLL_INTERVAL,
activationOperation(
service.submitJobWithResponseAsync(
new AnalyzeTextJobsInput()
+ .setDisplayName(displayName)
.setAnalysisInput(
new MultiLanguageAnalysisInput().setDocuments(toMultiLanguageInput(documents)))
.setTasks(Arrays.asList(
@@ -443,7 +472,8 @@ private Mono> processAnalyzeTextMo
status = LongRunningOperationStatus.fromString(
analyzeOperationResultResponse.getValue().getStatus().toString(), true);
}
-
+ ClassifyDocumentOperationDetailPropertiesHelper.setDisplayName(operationResultPollResponse.getValue(),
+ analyzeOperationResultResponse.getValue().getDisplayName());
ClassifyDocumentOperationDetailPropertiesHelper.setCreatedAt(operationResultPollResponse.getValue(),
analyzeOperationResultResponse.getValue().getCreatedDateTime());
ClassifyDocumentOperationDetailPropertiesHelper.setLastModifiedAt(
diff --git a/sdk/textanalytics/azure-ai-textanalytics/src/main/java/com/azure/ai/textanalytics/RecognizeCustomEntitiesAsyncClient.java b/sdk/textanalytics/azure-ai-textanalytics/src/main/java/com/azure/ai/textanalytics/RecognizeCustomEntitiesAsyncClient.java
index 6bff6a5ff68fd..b1c398db5e4ac 100644
--- a/sdk/textanalytics/azure-ai-textanalytics/src/main/java/com/azure/ai/textanalytics/RecognizeCustomEntitiesAsyncClient.java
+++ b/sdk/textanalytics/azure-ai-textanalytics/src/main/java/com/azure/ai/textanalytics/RecognizeCustomEntitiesAsyncClient.java
@@ -55,9 +55,11 @@
import static com.azure.ai.textanalytics.TextAnalyticsAsyncClient.COGNITIVE_TRACING_NAMESPACE_VALUE;
import static com.azure.ai.textanalytics.implementation.Utility.DEFAULT_POLL_INTERVAL;
import static com.azure.ai.textanalytics.implementation.Utility.getNotNullContext;
+import static com.azure.ai.textanalytics.implementation.Utility.getUnsupportedServiceApiVersionMessage;
import static com.azure.ai.textanalytics.implementation.Utility.inputDocumentsValidation;
import static com.azure.ai.textanalytics.implementation.Utility.parseNextLink;
import static com.azure.ai.textanalytics.implementation.Utility.parseOperationId;
+import static com.azure.ai.textanalytics.implementation.Utility.throwIfTargetServiceVersionFound;
import static com.azure.ai.textanalytics.implementation.Utility.toMultiLanguageInput;
import static com.azure.ai.textanalytics.implementation.Utility.toRecognizeCustomEntitiesResultCollection;
import static com.azure.ai.textanalytics.implementation.models.State.CANCELLED;
@@ -71,14 +73,22 @@ class RecognizeCustomEntitiesAsyncClient {
private final ClientLogger logger = new ClientLogger(RecognizeCustomEntitiesAsyncClient.class);
private final AnalyzeTextsImpl service;
- RecognizeCustomEntitiesAsyncClient(AnalyzeTextsImpl service) {
+ private final TextAnalyticsServiceVersion serviceVersion;
+
+ RecognizeCustomEntitiesAsyncClient(AnalyzeTextsImpl service,
+ TextAnalyticsServiceVersion serviceVersion) {
this.service = service;
+ this.serviceVersion = serviceVersion;
}
PollerFlux recognizeCustomEntities(
Iterable documents, String projectName, String deploymentName,
RecognizeCustomEntitiesOptions options, Context context) {
try {
+ throwIfTargetServiceVersionFound(this.serviceVersion,
+ Arrays.asList(TextAnalyticsServiceVersion.V3_0, TextAnalyticsServiceVersion.V3_1),
+ getUnsupportedServiceApiVersionMessage("beginRecognizeCustomEntities", serviceVersion,
+ TextAnalyticsServiceVersion.V2022_05_01));
inputDocumentsValidation(documents);
options = getNotNullRecognizeCustomEntitiesOptions(options);
final Context finalContext = getNotNullContext(context)
@@ -86,12 +96,14 @@ PollerFlux(
DEFAULT_POLL_INTERVAL,
activationOperation(
service.submitJobWithResponseAsync(
new AnalyzeTextJobsInput()
+ .setDisplayName(displayName)
.setAnalysisInput(
new MultiLanguageAnalysisInput().setDocuments(toMultiLanguageInput(documents)))
.setTasks(Arrays.asList(
@@ -127,6 +139,10 @@ PollerFlux documents,
String projectName, String deploymentName, RecognizeCustomEntitiesOptions options, Context context) {
try {
+ throwIfTargetServiceVersionFound(this.serviceVersion,
+ Arrays.asList(TextAnalyticsServiceVersion.V3_0, TextAnalyticsServiceVersion.V3_1),
+ getUnsupportedServiceApiVersionMessage("beginRecognizeCustomEntities", serviceVersion,
+ TextAnalyticsServiceVersion.V2022_05_01));
inputDocumentsValidation(documents);
options = getNotNullRecognizeCustomEntitiesOptions(options);
final Context finalContext = getNotNullContext(context)
@@ -134,12 +150,14 @@ PollerFlux(
DEFAULT_POLL_INTERVAL,
activationOperation(
service.submitJobWithResponseAsync(
new AnalyzeTextJobsInput()
+ .setDisplayName(displayName)
.setAnalysisInput(
new MultiLanguageAnalysisInput().setDocuments(toMultiLanguageInput(documents)))
.setTasks(Arrays.asList(
@@ -338,7 +356,8 @@ private Mono> processAnalyz
status = LongRunningOperationStatus.fromString(
analyzeOperationResultResponse.getValue().getStatus().toString(), true);
}
-
+ RecognizeCustomEntitiesOperationDetailPropertiesHelper.setDisplayName(operationResultPollResponse.getValue(),
+ analyzeOperationResultResponse.getValue().getDisplayName());
RecognizeCustomEntitiesOperationDetailPropertiesHelper.setCreatedAt(operationResultPollResponse.getValue(),
analyzeOperationResultResponse.getValue().getCreatedDateTime());
RecognizeCustomEntitiesOperationDetailPropertiesHelper.setLastModifiedAt(
diff --git a/sdk/textanalytics/azure-ai-textanalytics/src/main/java/com/azure/ai/textanalytics/RecognizeEntityAsyncClient.java b/sdk/textanalytics/azure-ai-textanalytics/src/main/java/com/azure/ai/textanalytics/RecognizeEntityAsyncClient.java
index d79e88fab8154..11a9010f464af 100644
--- a/sdk/textanalytics/azure-ai-textanalytics/src/main/java/com/azure/ai/textanalytics/RecognizeEntityAsyncClient.java
+++ b/sdk/textanalytics/azure-ai-textanalytics/src/main/java/com/azure/ai/textanalytics/RecognizeEntityAsyncClient.java
@@ -23,13 +23,16 @@
import com.azure.core.util.logging.ClientLogger;
import reactor.core.publisher.Mono;
+import java.util.Arrays;
import java.util.Collections;
import java.util.Objects;
import static com.azure.ai.textanalytics.TextAnalyticsAsyncClient.COGNITIVE_TRACING_NAMESPACE_VALUE;
import static com.azure.ai.textanalytics.implementation.Utility.getDocumentCount;
import static com.azure.ai.textanalytics.implementation.Utility.getNotNullContext;
+import static com.azure.ai.textanalytics.implementation.Utility.getUnsupportedServiceApiVersionMessage;
import static com.azure.ai.textanalytics.implementation.Utility.inputDocumentsValidation;
+import static com.azure.ai.textanalytics.implementation.Utility.throwIfTargetServiceVersionFound;
import static com.azure.ai.textanalytics.implementation.Utility.toMultiLanguageInput;
import static com.azure.ai.textanalytics.implementation.Utility.toTextAnalyticsException;
import static com.azure.core.util.FluxUtil.monoError;
@@ -44,14 +47,19 @@ class RecognizeEntityAsyncClient {
private final TextAnalyticsClientImpl legacyService;
private final MicrosoftCognitiveLanguageServiceTextAnalysisImpl service;
- RecognizeEntityAsyncClient(TextAnalyticsClientImpl legacyService) {
+ private final TextAnalyticsServiceVersion serviceVersion;
+
+ RecognizeEntityAsyncClient(TextAnalyticsClientImpl legacyService, TextAnalyticsServiceVersion serviceVersion) {
this.legacyService = legacyService;
this.service = null;
+ this.serviceVersion = serviceVersion;
}
- RecognizeEntityAsyncClient(MicrosoftCognitiveLanguageServiceTextAnalysisImpl service) {
+ RecognizeEntityAsyncClient(MicrosoftCognitiveLanguageServiceTextAnalysisImpl service,
+ TextAnalyticsServiceVersion serviceVersion) {
this.legacyService = null;
this.service = service;
+ this.serviceVersion = serviceVersion;
}
/**
@@ -97,7 +105,6 @@ Mono recognizeEntities(String document, String lang
Mono> recognizeEntitiesBatch(
Iterable documents, TextAnalyticsRequestOptions options) {
try {
- inputDocumentsValidation(documents);
return withContext(context -> getRecognizedEntitiesResponse(documents, options, context));
} catch (RuntimeException ex) {
return monoError(logger, ex);
@@ -116,7 +123,6 @@ Mono> recognizeEntitiesBatch(
Mono> recognizeEntitiesBatchWithContext(
Iterable documents, TextAnalyticsRequestOptions options, Context context) {
try {
- inputDocumentsValidation(documents);
return getRecognizedEntitiesResponse(documents, options, context);
} catch (RuntimeException ex) {
return monoError(logger, ex);
@@ -135,6 +141,8 @@ Mono> recognizeEntitiesBatchWithCont
*/
private Mono> getRecognizedEntitiesResponse(
Iterable documents, TextAnalyticsRequestOptions options, Context context) {
+ throwIfCallingNotAvailableFeatureInOptions(options);
+ inputDocumentsValidation(documents);
options = options == null ? new TextAnalyticsRequestOptions() : options;
final Context finalContext = getNotNullContext(context)
.addData(AZ_TRACING_NAMESPACE_KEY, COGNITIVE_TRACING_NAMESPACE_VALUE);
@@ -180,4 +188,12 @@ private Mono> getRecognizedEntitiesR
.map(Utility::toRecognizeEntitiesResultCollection)
.onErrorMap(Utility::mapToHttpResponseExceptionIfExists);
}
+
+ private void throwIfCallingNotAvailableFeatureInOptions(TextAnalyticsRequestOptions options) {
+ if (options != null && options.isServiceLogsDisabled()) {
+ throwIfTargetServiceVersionFound(this.serviceVersion, Arrays.asList(TextAnalyticsServiceVersion.V3_0),
+ getUnsupportedServiceApiVersionMessage("TextAnalyticsRequestOptions.disableServiceLogs",
+ serviceVersion, TextAnalyticsServiceVersion.V3_1));
+ }
+ }
}
diff --git a/sdk/textanalytics/azure-ai-textanalytics/src/main/java/com/azure/ai/textanalytics/RecognizeLinkedEntityAsyncClient.java b/sdk/textanalytics/azure-ai-textanalytics/src/main/java/com/azure/ai/textanalytics/RecognizeLinkedEntityAsyncClient.java
index 3c3d86bb95b46..e0c826c2ebc37 100644
--- a/sdk/textanalytics/azure-ai-textanalytics/src/main/java/com/azure/ai/textanalytics/RecognizeLinkedEntityAsyncClient.java
+++ b/sdk/textanalytics/azure-ai-textanalytics/src/main/java/com/azure/ai/textanalytics/RecognizeLinkedEntityAsyncClient.java
@@ -23,13 +23,16 @@
import com.azure.core.util.logging.ClientLogger;
import reactor.core.publisher.Mono;
+import java.util.Arrays;
import java.util.Collections;
import java.util.Objects;
import static com.azure.ai.textanalytics.TextAnalyticsAsyncClient.COGNITIVE_TRACING_NAMESPACE_VALUE;
import static com.azure.ai.textanalytics.implementation.Utility.getDocumentCount;
import static com.azure.ai.textanalytics.implementation.Utility.getNotNullContext;
+import static com.azure.ai.textanalytics.implementation.Utility.getUnsupportedServiceApiVersionMessage;
import static com.azure.ai.textanalytics.implementation.Utility.inputDocumentsValidation;
+import static com.azure.ai.textanalytics.implementation.Utility.throwIfTargetServiceVersionFound;
import static com.azure.ai.textanalytics.implementation.Utility.toMultiLanguageInput;
import static com.azure.ai.textanalytics.implementation.Utility.toTextAnalyticsException;
import static com.azure.core.util.FluxUtil.monoError;
@@ -44,14 +47,20 @@ class RecognizeLinkedEntityAsyncClient {
private final TextAnalyticsClientImpl legacyService;
private final MicrosoftCognitiveLanguageServiceTextAnalysisImpl service;
- RecognizeLinkedEntityAsyncClient(TextAnalyticsClientImpl legacyService) {
+ private final TextAnalyticsServiceVersion serviceVersion;
+
+ RecognizeLinkedEntityAsyncClient(TextAnalyticsClientImpl legacyService,
+ TextAnalyticsServiceVersion serviceVersion) {
this.legacyService = legacyService;
this.service = null;
+ this.serviceVersion = serviceVersion;
}
- RecognizeLinkedEntityAsyncClient(MicrosoftCognitiveLanguageServiceTextAnalysisImpl service) {
+ RecognizeLinkedEntityAsyncClient(MicrosoftCognitiveLanguageServiceTextAnalysisImpl service,
+ TextAnalyticsServiceVersion serviceVersion) {
this.legacyService = null;
this.service = service;
+ this.serviceVersion = serviceVersion;
}
/**
@@ -97,7 +106,6 @@ Mono recognizeLinkedEntities(String document, String lan
Mono> recognizeLinkedEntitiesBatch(
Iterable documents, TextAnalyticsRequestOptions options) {
try {
- inputDocumentsValidation(documents);
return withContext(context -> getRecognizedLinkedEntitiesResponse(documents, options, context));
} catch (RuntimeException ex) {
return monoError(logger, ex);
@@ -118,7 +126,6 @@ Mono> recognizeLinkedEntitiesB
recognizeLinkedEntitiesBatchWithContext(Iterable documents,
TextAnalyticsRequestOptions options, Context context) {
try {
- inputDocumentsValidation(documents);
return getRecognizedLinkedEntitiesResponse(documents, options, context);
} catch (RuntimeException ex) {
return monoError(logger, ex);
@@ -136,6 +143,8 @@ Mono> recognizeLinkedEntitiesB
*/
private Mono> getRecognizedLinkedEntitiesResponse(
Iterable documents, TextAnalyticsRequestOptions options, Context context) {
+ throwIfCallingNotAvailableFeatureInOptions(options);
+ inputDocumentsValidation(documents);
options = options == null ? new TextAnalyticsRequestOptions() : options;
final Context finalContext = getNotNullContext(context)
.addData(AZ_TRACING_NAMESPACE_KEY, COGNITIVE_TRACING_NAMESPACE_VALUE);
@@ -180,4 +189,12 @@ private Mono> getRecognizedLin
.map(Utility::toRecognizeLinkedEntitiesResultCollectionResponse)
.onErrorMap(Utility::mapToHttpResponseExceptionIfExists);
}
+
+ private void throwIfCallingNotAvailableFeatureInOptions(TextAnalyticsRequestOptions options) {
+ if (options != null && options.isServiceLogsDisabled()) {
+ throwIfTargetServiceVersionFound(this.serviceVersion, Arrays.asList(TextAnalyticsServiceVersion.V3_0),
+ getUnsupportedServiceApiVersionMessage("TextAnalyticsRequestOptions.disableServiceLogs",
+ serviceVersion, TextAnalyticsServiceVersion.V3_1));
+ }
+ }
}
diff --git a/sdk/textanalytics/azure-ai-textanalytics/src/main/java/com/azure/ai/textanalytics/RecognizePiiEntityAsyncClient.java b/sdk/textanalytics/azure-ai-textanalytics/src/main/java/com/azure/ai/textanalytics/RecognizePiiEntityAsyncClient.java
index 1d0038585f610..e690c8439239d 100644
--- a/sdk/textanalytics/azure-ai-textanalytics/src/main/java/com/azure/ai/textanalytics/RecognizePiiEntityAsyncClient.java
+++ b/sdk/textanalytics/azure-ai-textanalytics/src/main/java/com/azure/ai/textanalytics/RecognizePiiEntityAsyncClient.java
@@ -24,12 +24,15 @@
import com.azure.core.util.logging.ClientLogger;
import reactor.core.publisher.Mono;
+import java.util.Arrays;
import java.util.Collections;
import java.util.Objects;
import static com.azure.ai.textanalytics.TextAnalyticsAsyncClient.COGNITIVE_TRACING_NAMESPACE_VALUE;
import static com.azure.ai.textanalytics.implementation.Utility.getNotNullContext;
+import static com.azure.ai.textanalytics.implementation.Utility.getUnsupportedServiceApiVersionMessage;
import static com.azure.ai.textanalytics.implementation.Utility.inputDocumentsValidation;
+import static com.azure.ai.textanalytics.implementation.Utility.throwIfTargetServiceVersionFound;
import static com.azure.ai.textanalytics.implementation.Utility.toCategoriesFilter;
import static com.azure.ai.textanalytics.implementation.Utility.toMultiLanguageInput;
import static com.azure.ai.textanalytics.implementation.Utility.toTextAnalyticsException;
@@ -45,14 +48,19 @@ class RecognizePiiEntityAsyncClient {
private final TextAnalyticsClientImpl legacyService;
private final MicrosoftCognitiveLanguageServiceTextAnalysisImpl service;
- RecognizePiiEntityAsyncClient(TextAnalyticsClientImpl legacyService) {
+ private final TextAnalyticsServiceVersion serviceVersion;
+
+ RecognizePiiEntityAsyncClient(TextAnalyticsClientImpl legacyService, TextAnalyticsServiceVersion serviceVersion) {
this.legacyService = legacyService;
this.service = null;
+ this.serviceVersion = serviceVersion;
}
- RecognizePiiEntityAsyncClient(MicrosoftCognitiveLanguageServiceTextAnalysisImpl service) {
+ RecognizePiiEntityAsyncClient(MicrosoftCognitiveLanguageServiceTextAnalysisImpl service,
+ TextAnalyticsServiceVersion serviceVersion) {
this.legacyService = null;
this.service = service;
+ this.serviceVersion = serviceVersion;
}
/**
@@ -69,6 +77,10 @@ class RecognizePiiEntityAsyncClient {
Mono recognizePiiEntities(String document, String language,
RecognizePiiEntitiesOptions options) {
try {
+ throwIfTargetServiceVersionFound(this.serviceVersion,
+ Arrays.asList(TextAnalyticsServiceVersion.V3_0),
+ getUnsupportedServiceApiVersionMessage("recognizePiiEntitiesBatch", serviceVersion,
+ TextAnalyticsServiceVersion.V3_1));
Objects.requireNonNull(document, "'document' cannot be null.");
return recognizePiiEntitiesBatch(
Collections.singletonList(new TextDocumentInput("0", document).setLanguage(language)), options)
@@ -102,7 +114,6 @@ Mono recognizePiiEntities(String document, String language,
Mono> recognizePiiEntitiesBatch(
Iterable documents, RecognizePiiEntitiesOptions options) {
try {
- inputDocumentsValidation(documents);
return withContext(context -> getRecognizePiiEntitiesResponse(documents, options, context));
} catch (RuntimeException ex) {
return monoError(logger, ex);
@@ -122,7 +133,6 @@ Mono> recognizePiiEntitiesBatch(
Mono> recognizePiiEntitiesBatchWithContext(
Iterable documents, RecognizePiiEntitiesOptions options, Context context) {
try {
- inputDocumentsValidation(documents);
return getRecognizePiiEntitiesResponse(documents, options, context);
} catch (RuntimeException ex) {
return monoError(logger, ex);
@@ -139,9 +149,15 @@ Mono> recognizePiiEntitiesBatchWi
* @param context Additional context that is passed through the Http pipeline during the service call.
*
* @return A mono {@link Response} that contains {@link RecognizePiiEntitiesResultCollection}.
+ *
*/
private Mono> getRecognizePiiEntitiesResponse(
Iterable documents, RecognizePiiEntitiesOptions options, Context context) {
+ throwIfTargetServiceVersionFound(this.serviceVersion,
+ Arrays.asList(TextAnalyticsServiceVersion.V3_0),
+ getUnsupportedServiceApiVersionMessage("recognizePiiEntitiesBatch", serviceVersion,
+ TextAnalyticsServiceVersion.V3_1));
+ inputDocumentsValidation(documents);
options = options == null ? new RecognizePiiEntitiesOptions() : options;
final Context finalContext = getNotNullContext(context)
.addData(AZ_TRACING_NAMESPACE_KEY, COGNITIVE_TRACING_NAMESPACE_VALUE);
diff --git a/sdk/textanalytics/azure-ai-textanalytics/src/main/java/com/azure/ai/textanalytics/TextAnalyticsAsyncClient.java b/sdk/textanalytics/azure-ai-textanalytics/src/main/java/com/azure/ai/textanalytics/TextAnalyticsAsyncClient.java
index 07a4ba089f2a6..993bb174860ef 100644
--- a/sdk/textanalytics/azure-ai-textanalytics/src/main/java/com/azure/ai/textanalytics/TextAnalyticsAsyncClient.java
+++ b/sdk/textanalytics/azure-ai-textanalytics/src/main/java/com/azure/ai/textanalytics/TextAnalyticsAsyncClient.java
@@ -8,6 +8,7 @@
import com.azure.ai.textanalytics.implementation.TextAnalyticsClientImpl;
import com.azure.ai.textanalytics.models.AnalyzeActionsOperationDetail;
import com.azure.ai.textanalytics.models.AnalyzeActionsOptions;
+import com.azure.ai.textanalytics.models.AnalyzeHealthcareEntitiesAction;
import com.azure.ai.textanalytics.models.AnalyzeHealthcareEntitiesOperationDetail;
import com.azure.ai.textanalytics.models.AnalyzeHealthcareEntitiesOptions;
import com.azure.ai.textanalytics.models.AnalyzeSentimentOptions;
@@ -20,11 +21,14 @@
import com.azure.ai.textanalytics.models.DocumentSentiment;
import com.azure.ai.textanalytics.models.KeyPhrasesCollection;
import com.azure.ai.textanalytics.models.LinkedEntityCollection;
+import com.azure.ai.textanalytics.models.MultiLabelClassifyAction;
import com.azure.ai.textanalytics.models.MultiLabelClassifyOptions;
import com.azure.ai.textanalytics.models.PiiEntityCollection;
+import com.azure.ai.textanalytics.models.RecognizeCustomEntitiesAction;
import com.azure.ai.textanalytics.models.RecognizeCustomEntitiesOperationDetail;
import com.azure.ai.textanalytics.models.RecognizeCustomEntitiesOptions;
import com.azure.ai.textanalytics.models.RecognizePiiEntitiesOptions;
+import com.azure.ai.textanalytics.models.SingleLabelClassifyAction;
import com.azure.ai.textanalytics.models.SingleLabelClassifyOptions;
import com.azure.ai.textanalytics.models.TextAnalyticsActions;
import com.azure.ai.textanalytics.models.TextAnalyticsError;
@@ -121,16 +125,16 @@ public final class TextAnalyticsAsyncClient {
this.serviceVersion = serviceVersion;
this.defaultCountryHint = defaultCountryHint;
this.defaultLanguage = defaultLanguage;
- this.detectLanguageAsyncClient = new DetectLanguageAsyncClient(legacyService);
- this.analyzeSentimentAsyncClient = new AnalyzeSentimentAsyncClient(legacyService);
- this.extractKeyPhraseAsyncClient = new ExtractKeyPhraseAsyncClient(legacyService);
- this.recognizeEntityAsyncClient = new RecognizeEntityAsyncClient(legacyService);
- this.recognizePiiEntityAsyncClient = new RecognizePiiEntityAsyncClient(legacyService);
- this.recognizeLinkedEntityAsyncClient = new RecognizeLinkedEntityAsyncClient(legacyService);
- this.recognizeCustomEntitiesAsyncClient = new RecognizeCustomEntitiesAsyncClient(null);
- this.analyzeHealthcareEntityAsyncClient = new AnalyzeHealthcareEntityAsyncClient(legacyService);
- this.analyzeActionsAsyncClient = new AnalyzeActionsAsyncClient(legacyService);
- this.labelClassifyAsyncClient = new LabelClassifyAsyncClient(null);
+ this.detectLanguageAsyncClient = new DetectLanguageAsyncClient(legacyService, serviceVersion);
+ this.analyzeSentimentAsyncClient = new AnalyzeSentimentAsyncClient(legacyService, serviceVersion);
+ this.extractKeyPhraseAsyncClient = new ExtractKeyPhraseAsyncClient(legacyService, serviceVersion);
+ this.recognizeEntityAsyncClient = new RecognizeEntityAsyncClient(legacyService, serviceVersion);
+ this.recognizePiiEntityAsyncClient = new RecognizePiiEntityAsyncClient(legacyService, serviceVersion);
+ this.recognizeLinkedEntityAsyncClient = new RecognizeLinkedEntityAsyncClient(legacyService, serviceVersion);
+ this.recognizeCustomEntitiesAsyncClient = new RecognizeCustomEntitiesAsyncClient(null, serviceVersion);
+ this.analyzeHealthcareEntityAsyncClient = new AnalyzeHealthcareEntityAsyncClient(legacyService, serviceVersion);
+ this.analyzeActionsAsyncClient = new AnalyzeActionsAsyncClient(legacyService, serviceVersion);
+ this.labelClassifyAsyncClient = new LabelClassifyAsyncClient(null, serviceVersion);
}
TextAnalyticsAsyncClient(MicrosoftCognitiveLanguageServiceTextAnalysisImpl service,
@@ -140,16 +144,18 @@ public final class TextAnalyticsAsyncClient {
this.serviceVersion = serviceVersion;
this.defaultCountryHint = defaultCountryHint;
this.defaultLanguage = defaultLanguage;
- this.detectLanguageAsyncClient = new DetectLanguageAsyncClient(service);
- this.analyzeSentimentAsyncClient = new AnalyzeSentimentAsyncClient(service);
- this.extractKeyPhraseAsyncClient = new ExtractKeyPhraseAsyncClient(service);
- this.recognizeEntityAsyncClient = new RecognizeEntityAsyncClient(service);
- this.recognizePiiEntityAsyncClient = new RecognizePiiEntityAsyncClient(service);
- this.recognizeLinkedEntityAsyncClient = new RecognizeLinkedEntityAsyncClient(service);
- this.recognizeCustomEntitiesAsyncClient = new RecognizeCustomEntitiesAsyncClient(new AnalyzeTextsImpl(service));
- this.analyzeHealthcareEntityAsyncClient = new AnalyzeHealthcareEntityAsyncClient(new AnalyzeTextsImpl(service));
- this.analyzeActionsAsyncClient = new AnalyzeActionsAsyncClient(new AnalyzeTextsImpl(service));
- this.labelClassifyAsyncClient = new LabelClassifyAsyncClient(new AnalyzeTextsImpl(service));
+ this.detectLanguageAsyncClient = new DetectLanguageAsyncClient(service, serviceVersion);
+ this.analyzeSentimentAsyncClient = new AnalyzeSentimentAsyncClient(service, serviceVersion);
+ this.extractKeyPhraseAsyncClient = new ExtractKeyPhraseAsyncClient(service, serviceVersion);
+ this.recognizeEntityAsyncClient = new RecognizeEntityAsyncClient(service, serviceVersion);
+ this.recognizePiiEntityAsyncClient = new RecognizePiiEntityAsyncClient(service, serviceVersion);
+ this.recognizeLinkedEntityAsyncClient = new RecognizeLinkedEntityAsyncClient(service, serviceVersion);
+ this.recognizeCustomEntitiesAsyncClient = new RecognizeCustomEntitiesAsyncClient(
+ new AnalyzeTextsImpl(service), serviceVersion);
+ this.analyzeHealthcareEntityAsyncClient = new AnalyzeHealthcareEntityAsyncClient(new AnalyzeTextsImpl(service),
+ serviceVersion);
+ this.analyzeActionsAsyncClient = new AnalyzeActionsAsyncClient(new AnalyzeTextsImpl(service), serviceVersion);
+ this.labelClassifyAsyncClient = new LabelClassifyAsyncClient(new AnalyzeTextsImpl(service), serviceVersion);
}
/**
@@ -300,6 +306,9 @@ public Mono detectLanguage(String document, String countryHint
* @return A {@link Mono} contains a {@link DetectLanguageResultCollection}.
*
* @throws NullPointerException if {@code documents} is null.
+ * @throws IllegalStateException if {@link TextAnalyticsRequestOptions#isServiceLogsDisabled()} is true in service
+ * API version {@link TextAnalyticsServiceVersion#V3_0}. {@code disableServiceLogs} is only available for API
+ * version v3.1 and newer.
*/
@ServiceMethod(returns = ReturnType.SINGLE)
public Mono detectLanguageBatch(
@@ -364,6 +373,9 @@ public Mono detectLanguageBatch(
* @return A {@link Mono} contains a {@link Response} which contains a {@link DetectLanguageResultCollection}.
*
* @throws NullPointerException if {@code documents} is null.
+ * @throws IllegalStateException if {@link TextAnalyticsRequestOptions#isServiceLogsDisabled()} is true in service
+ * API version {@link TextAnalyticsServiceVersion#V3_0}. {@code disableServiceLogs} is only available for API
+ * version v3.1 and newer.
*/
@ServiceMethod(returns = ReturnType.SINGLE)
public Mono> detectLanguageBatchWithResponse(
@@ -490,6 +502,9 @@ public Mono recognizeEntities(String document, Stri
* @return A {@link Mono} contains a {@link RecognizeEntitiesResultCollection}.
*
* @throws NullPointerException if {@code documents} is null.
+ * @throws IllegalStateException if {@link TextAnalyticsRequestOptions#isServiceLogsDisabled()} is true in service
+ * API version {@link TextAnalyticsServiceVersion#V3_0}. {@code disableServiceLogs} is only available for API
+ * version v3.1 and newer.
*/
@ServiceMethod(returns = ReturnType.SINGLE)
public Mono recognizeEntitiesBatch(
@@ -552,6 +567,9 @@ public Mono recognizeEntitiesBatch(
* @return A {@link Mono} contains a {@link Response} which contains a {@link RecognizeEntitiesResultCollection}.
*
* @throws NullPointerException if {@code documents} is null.
+ * @throws IllegalStateException if {@link TextAnalyticsRequestOptions#isServiceLogsDisabled()} is true in service
+ * API version {@link TextAnalyticsServiceVersion#V3_0}. {@code disableServiceLogs} is only available for API
+ * version v3.1 and newer.
*/
@ServiceMethod(returns = ReturnType.SINGLE)
public Mono> recognizeEntitiesBatchWithResponse(
@@ -595,6 +613,9 @@ public Mono> recognizeEntitiesBatchW
*
* @throws NullPointerException if {@code document} is null.
* @throws TextAnalyticsException if the response returned with an {@link TextAnalyticsError error}.
+ * @throws IllegalStateException if {@code recognizePiiEntities} is called with service API version
+ * {@link TextAnalyticsServiceVersion#V3_0}. {@code recognizePiiEntities} is only available for
+ * API version v3.1 and newer.
*/
@ServiceMethod(returns = ReturnType.SINGLE)
public Mono recognizePiiEntities(String document) {
@@ -635,6 +656,9 @@ public Mono recognizePiiEntities(String document) {
*
* @throws NullPointerException if {@code document} is null.
* @throws TextAnalyticsException if the response returned with an {@link TextAnalyticsError error}.
+ * @throws IllegalStateException if {@code recognizePiiEntities} is called with service API version
+ * {@link TextAnalyticsServiceVersion#V3_0}. {@code recognizePiiEntities} is only available for
+ * API version v3.1 and newer.
*/
@ServiceMethod(returns = ReturnType.SINGLE)
public Mono recognizePiiEntities(String document, String language) {
@@ -679,6 +703,9 @@ public Mono recognizePiiEntities(String document, String la
*
* @throws NullPointerException if {@code document} is null.
* @throws TextAnalyticsException if the response returned with an {@link TextAnalyticsError error}.
+ * @throws IllegalStateException if {@code recognizePiiEntities} is called with service API version
+ * {@link TextAnalyticsServiceVersion#V3_0}. {@code recognizePiiEntities} is only available for
+ * API version v3.1 and newer.
*/
@ServiceMethod(returns = ReturnType.SINGLE)
public Mono recognizePiiEntities(String document, String language,
@@ -735,6 +762,9 @@ public Mono recognizePiiEntities(String document, String la
*
* @throws NullPointerException if {@code documents} is null.
* @throws IllegalArgumentException if {@code documents} is empty.
+ * @throws IllegalStateException if {@code recognizePiiEntitiesBatch} is called with service API version
+ * {@link TextAnalyticsServiceVersion#V3_0}. {@code recognizePiiEntitiesBatch} is only available for
+ * API version v3.1 and newer.
*/
@ServiceMethod(returns = ReturnType.SINGLE)
public Mono recognizePiiEntitiesBatch(
@@ -801,6 +831,9 @@ public Mono recognizePiiEntitiesBatch(
*
* @throws NullPointerException if {@code documents} is null.
* @throws IllegalArgumentException if {@code documents} is empty.
+ * @throws IllegalStateException if {@code recognizePiiEntitiesBatchWithResponse} is called with service API version
+ * {@link TextAnalyticsServiceVersion#V3_0}. {@code recognizePiiEntitiesBatchWithResponse} is only available for
+ * API version v3.1 and newer.
*/
@ServiceMethod(returns = ReturnType.SINGLE)
public Mono> recognizePiiEntitiesBatchWithResponse(
@@ -938,6 +971,9 @@ public Mono recognizeLinkedEntities(String document, Str
* @return A {@link Mono} contains a {@link RecognizeLinkedEntitiesResultCollection}.
*
* @throws NullPointerException if {@code documents} is null.
+ * @throws IllegalStateException if {@link TextAnalyticsRequestOptions#isServiceLogsDisabled()} is true in service
+ * API version {@link TextAnalyticsServiceVersion#V3_0}. {@code disableServiceLogs} is only available for API
+ * version v3.1 and newer.
*/
@ServiceMethod(returns = ReturnType.SINGLE)
public Mono recognizeLinkedEntitiesBatch(
@@ -1006,6 +1042,9 @@ public Mono recognizeLinkedEntitiesBatc
* {@link RecognizeLinkedEntitiesResultCollection}.
*
* @throws NullPointerException if {@code documents} is null.
+ * @throws IllegalStateException if {@link TextAnalyticsRequestOptions#isServiceLogsDisabled()} is true in service
+ * API version {@link TextAnalyticsServiceVersion#V3_0}. {@code disableServiceLogs} is only available for API
+ * version v3.1 and newer.
*/
@ServiceMethod(returns = ReturnType.SINGLE)
public Mono> recognizeLinkedEntitiesBatchWithResponse(
@@ -1120,6 +1159,9 @@ public Mono extractKeyPhrases(String document, String lang
* @return A {@link Mono} contains a {@link ExtractKeyPhrasesResultCollection}.
*
* @throws NullPointerException if {@code documents} is null.
+ * @throws IllegalStateException if {@link TextAnalyticsRequestOptions#isServiceLogsDisabled()} is true in service
+ * API version {@link TextAnalyticsServiceVersion#V3_0}. {@code disableServiceLogs} is only available for API
+ * version v3.1 and newer.
*/
@ServiceMethod(returns = ReturnType.SINGLE)
public Mono extractKeyPhrasesBatch(
@@ -1182,6 +1224,9 @@ public Mono extractKeyPhrasesBatch(
* @return A {@link Mono} contains a {@link Response} that contains a {@link ExtractKeyPhrasesResultCollection}.
*
* @throws NullPointerException if {@code documents} is null.
+ * @throws IllegalStateException if {@link TextAnalyticsRequestOptions#isServiceLogsDisabled()} is true in service
+ * API version {@link TextAnalyticsServiceVersion#V3_0}. {@code disableServiceLogs} is only available for API
+ * version v3.1 and newer.
*/
@ServiceMethod(returns = ReturnType.SINGLE)
public Mono> extractKeyPhrasesBatchWithResponse(
@@ -1324,6 +1369,10 @@ public Mono analyzeSentiment(String document, String language
*
* @throws NullPointerException if {@code document} is null.
* @throws TextAnalyticsException if the response returned with an {@link TextAnalyticsError error}.
+ * @throws IllegalStateException if {@link AnalyzeSentimentOptions#isServiceLogsDisabled()} or
+ * {@link AnalyzeSentimentOptions#isIncludeOpinionMining()} is true in service API version
+ * {@link TextAnalyticsServiceVersion#V3_0}. {@code disableServiceLogs} and {@code includeOpinionMining} are only
+ * available for API version v3.1 and newer.
*/
@ServiceMethod(returns = ReturnType.SINGLE)
public Mono analyzeSentiment(String document, String language, AnalyzeSentimentOptions options) {
@@ -1479,6 +1528,10 @@ public Mono analyzeSentimentBatch(
*
* @throws NullPointerException if {@code documents} is null.
* @throws IllegalArgumentException if {@code documents} is empty.
+ * @throws IllegalStateException if {@link AnalyzeSentimentOptions#isServiceLogsDisabled()} or
+ * {@link AnalyzeSentimentOptions#isIncludeOpinionMining()} is true in service API version
+ * {@link TextAnalyticsServiceVersion#V3_0}. {@code disableServiceLogs} and {@code includeOpinionMining} are only
+ * available for API version v3.1 and newer.
*/
@ServiceMethod(returns = ReturnType.SINGLE)
public Mono analyzeSentimentBatch(Iterable documents,
@@ -1624,6 +1677,10 @@ public Mono> analyzeSentimentBatchWit
*
* @throws NullPointerException if {@code documents} is null.
* @throws IllegalArgumentException if {@code documents} is empty.
+ * @throws IllegalStateException if {@link AnalyzeSentimentOptions#isServiceLogsDisabled()} or
+ * {@link AnalyzeSentimentOptions#isIncludeOpinionMining()} is true in service API version
+ * {@link TextAnalyticsServiceVersion#V3_0}. {@code disableServiceLogs} and {@code includeOpinionMining} are only
+ * available for API version v3.1 and newer.
*/
@ServiceMethod(returns = ReturnType.SINGLE)
public Mono> analyzeSentimentBatchWithResponse(
@@ -1651,6 +1708,9 @@ public Mono> analyzeSentimentBatchWit
*
* @throws NullPointerException if {@code documents} is null.
* @throws IllegalArgumentException if {@code documents} is empty.
+ * @throws IllegalStateException if {@code beginAnalyzeHealthcareEntities} is called with service API version
+ * {@link TextAnalyticsServiceVersion#V3_0}. {@code beginAnalyzeHealthcareEntities} is only available for API
+ * version v3.1 and newer.
* @throws TextAnalyticsException If analyze operation fails.
*/
@ServiceMethod(returns = ReturnType.COLLECTION)
@@ -1752,6 +1812,9 @@ public Mono> analyzeSentimentBatchWit
*
* @throws NullPointerException if {@code documents} is null.
* @throws IllegalArgumentException if {@code documents} is empty.
+ * @throws IllegalStateException if {@code beginAnalyzeHealthcareEntities} is called with service API version
+ * {@link TextAnalyticsServiceVersion#V3_0}. {@code beginAnalyzeHealthcareEntities} is only available for API
+ * version v3.1 and newer.
* @throws TextAnalyticsException If analyze operation fails.
*/
@ServiceMethod(returns = ReturnType.COLLECTION)
@@ -1829,6 +1892,9 @@ public Mono> analyzeSentimentBatchWit
*
* @throws NullPointerException if {@code documents} is null.
* @throws IllegalArgumentException if {@code documents} is empty.
+ * @throws IllegalStateException if {@code beginRecognizeCustomEntities} is called with service API version
+ * {@link TextAnalyticsServiceVersion#V3_0} or {@link TextAnalyticsServiceVersion#V3_1}.
+ * {@code beginRecognizeCustomEntities} is only available for API version 2022-05-01 and newer.
* @throws TextAnalyticsException If analyze operation fails.
*/
@ServiceMethod(returns = ReturnType.COLLECTION)
@@ -1906,6 +1972,9 @@ public Mono> analyzeSentimentBatchWit
*
* @throws NullPointerException if {@code documents} is null.
* @throws IllegalArgumentException if {@code documents} is empty.
+ * @throws IllegalStateException if {@code beginRecognizeCustomEntities} is called with service API version
+ * {@link TextAnalyticsServiceVersion#V3_0} or {@link TextAnalyticsServiceVersion#V3_1}.
+ * {@code beginRecognizeCustomEntities} is only available for API version 2022-05-01 and newer.
* @throws TextAnalyticsException If analyze operation fails.
*/
@ServiceMethod(returns = ReturnType.COLLECTION)
@@ -1987,6 +2056,9 @@ public Mono> analyzeSentimentBatchWit
*
* @throws NullPointerException if {@code documents} is null.
* @throws IllegalArgumentException if {@code documents} is empty.
+ * @throws IllegalStateException if {@code beginSingleLabelClassify} is called with service API version
+ * {@link TextAnalyticsServiceVersion#V3_0} or {@link TextAnalyticsServiceVersion#V3_1}.
+ * {@code beginSingleLabelClassify} is only available for API version 2022-05-01 and newer.
* @throws TextAnalyticsException If analyze operation fails.
*/
@ServiceMethod(returns = ReturnType.COLLECTION)
@@ -2065,6 +2137,9 @@ public PollerFlux be
*
* @throws NullPointerException if {@code documents} is null.
* @throws IllegalArgumentException if {@code documents} is empty.
+ * @throws IllegalStateException if {@code beginSingleLabelClassify} is called with service API version
+ * {@link TextAnalyticsServiceVersion#V3_0} or {@link TextAnalyticsServiceVersion#V3_1}.
+ * {@code beginSingleLabelClassify} is only available for API version 2022-05-01 and newer.
* @throws TextAnalyticsException If analyze operation fails.
*/
@ServiceMethod(returns = ReturnType.COLLECTION)
@@ -2141,6 +2216,9 @@ public PollerFlux be
*
* @throws NullPointerException if {@code documents} is null.
* @throws IllegalArgumentException if {@code documents} is empty.
+ * @throws IllegalStateException if {@code beginMultiLabelClassify} is called with service API version
+ * {@link TextAnalyticsServiceVersion#V3_0} or {@link TextAnalyticsServiceVersion#V3_1}.
+ * {@code beginMultiLabelClassify} is only available for API version 2022-05-01 and newer.
* @throws TextAnalyticsException If analyze operation fails.
*/
@ServiceMethod(returns = ReturnType.COLLECTION)
@@ -2215,6 +2293,9 @@ public PollerFlux be
*
* @throws NullPointerException if {@code documents} is null.
* @throws IllegalArgumentException if {@code documents} is empty.
+ * @throws IllegalStateException if {@code beginMultiLabelClassify} is called with service API version
+ * {@link TextAnalyticsServiceVersion#V3_0} or {@link TextAnalyticsServiceVersion#V3_1}.
+ * {@code beginMultiLabelClassify} is only available for API version 2022-05-01 and newer.
* @throws TextAnalyticsException If analyze operation fails.
*/
@ServiceMethod(returns = ReturnType.COLLECTION)
@@ -2291,6 +2372,13 @@ public PollerFlux be
*
* @throws NullPointerException if {@code documents} is null.
* @throws IllegalArgumentException if {@code documents} is empty.
+ * @throws IllegalStateException if {@code beginAnalyzeActions} is called with service API version
+ * {@link TextAnalyticsServiceVersion#V3_0}. {@code beginAnalyzeActions} is only available for API version
+ * v3.1 and newer.
+ * @throws IllegalStateException if request {@link AnalyzeHealthcareEntitiesAction},
+ * {@link RecognizeCustomEntitiesAction}, {@link SingleLabelClassifyAction}, or {@link MultiLabelClassifyAction}
+ * in service API version {@link TextAnalyticsServiceVersion#V3_0} or {@link TextAnalyticsServiceVersion#V3_1}.
+ * Those actions are only available for API version 2022-05-01 and newer.
* @throws TextAnalyticsException If analyze operation fails.
*/
@ServiceMethod(returns = ReturnType.COLLECTION)
@@ -2367,6 +2455,13 @@ public PollerFlux
*
* @throws NullPointerException if {@code documents} or {@code actions} is null.
* @throws IllegalArgumentException if {@code documents} is empty.
+ * @throws IllegalStateException if {@code beginAnalyzeActions} is called with service API version
+ * {@link TextAnalyticsServiceVersion#V3_0}. {@code beginAnalyzeActions} is only available for API version
+ * v3.1 and newer.
+ * @throws IllegalStateException if request {@link AnalyzeHealthcareEntitiesAction},
+ * {@link RecognizeCustomEntitiesAction}, {@link SingleLabelClassifyAction}, or {@link MultiLabelClassifyAction}
+ * in service API version {@link TextAnalyticsServiceVersion#V3_0} or {@link TextAnalyticsServiceVersion#V3_1}.
+ * Those actions are only available for API version 2022-05-01 and newer.
* @throws TextAnalyticsException If analyze operation fails.
*/
@ServiceMethod(returns = ReturnType.COLLECTION)
diff --git a/sdk/textanalytics/azure-ai-textanalytics/src/main/java/com/azure/ai/textanalytics/TextAnalyticsClient.java b/sdk/textanalytics/azure-ai-textanalytics/src/main/java/com/azure/ai/textanalytics/TextAnalyticsClient.java
index 1fbd69dc6935e..d41e1600ca031 100644
--- a/sdk/textanalytics/azure-ai-textanalytics/src/main/java/com/azure/ai/textanalytics/TextAnalyticsClient.java
+++ b/sdk/textanalytics/azure-ai-textanalytics/src/main/java/com/azure/ai/textanalytics/TextAnalyticsClient.java
@@ -5,6 +5,7 @@
import com.azure.ai.textanalytics.models.AnalyzeActionsOperationDetail;
import com.azure.ai.textanalytics.models.AnalyzeActionsOptions;
+import com.azure.ai.textanalytics.models.AnalyzeHealthcareEntitiesAction;
import com.azure.ai.textanalytics.models.AnalyzeHealthcareEntitiesOperationDetail;
import com.azure.ai.textanalytics.models.AnalyzeHealthcareEntitiesOptions;
import com.azure.ai.textanalytics.models.AnalyzeSentimentOptions;
@@ -17,11 +18,14 @@
import com.azure.ai.textanalytics.models.KeyPhrasesCollection;
import com.azure.ai.textanalytics.models.LinkedEntity;
import com.azure.ai.textanalytics.models.LinkedEntityCollection;
+import com.azure.ai.textanalytics.models.MultiLabelClassifyAction;
import com.azure.ai.textanalytics.models.MultiLabelClassifyOptions;
import com.azure.ai.textanalytics.models.PiiEntityCollection;
+import com.azure.ai.textanalytics.models.RecognizeCustomEntitiesAction;
import com.azure.ai.textanalytics.models.RecognizeCustomEntitiesOperationDetail;
import com.azure.ai.textanalytics.models.RecognizeCustomEntitiesOptions;
import com.azure.ai.textanalytics.models.RecognizePiiEntitiesOptions;
+import com.azure.ai.textanalytics.models.SingleLabelClassifyAction;
import com.azure.ai.textanalytics.models.SingleLabelClassifyOptions;
import com.azure.ai.textanalytics.models.TextAnalyticsActions;
import com.azure.ai.textanalytics.models.TextAnalyticsError;
@@ -247,6 +251,9 @@ public DetectedLanguage detectLanguage(String document, String countryHint) {
*
* @throws NullPointerException if {@code documents} is null.
* @throws IllegalArgumentException if {@code documents} is empty.
+ * @throws IllegalStateException if {@link TextAnalyticsRequestOptions#isServiceLogsDisabled()} is true in service
+ * API version {@link TextAnalyticsServiceVersion#V3_0}. {@code disableServiceLogs} is only available for API
+ * version v3.1 and newer.
*/
@ServiceMethod(returns = ReturnType.SINGLE)
public DetectLanguageResultCollection detectLanguageBatch(
@@ -306,6 +313,9 @@ public DetectLanguageResultCollection detectLanguageBatch(
*
* @throws NullPointerException if {@code documents} is null.
* @throws IllegalArgumentException if {@code documents} is empty.
+ * @throws IllegalStateException if {@link TextAnalyticsRequestOptions#isServiceLogsDisabled()} is true in service
+ * API version {@link TextAnalyticsServiceVersion#V3_0}. {@code disableServiceLogs} is only available for API
+ * version v3.1 and newer.
*/
@ServiceMethod(returns = ReturnType.SINGLE)
public Response detectLanguageBatchWithResponse(
@@ -427,6 +437,9 @@ public CategorizedEntityCollection recognizeEntities(String document, String lan
*
* @throws NullPointerException if {@code documents} is null.
* @throws IllegalArgumentException if {@code documents} is empty.
+ * @throws IllegalStateException if {@link TextAnalyticsRequestOptions#isServiceLogsDisabled()} is true in service
+ * API version {@link TextAnalyticsServiceVersion#V3_0}. {@code disableServiceLogs} is only available for API
+ * version v3.1 and newer.
*/
@ServiceMethod(returns = ReturnType.SINGLE)
public RecognizeEntitiesResultCollection recognizeEntitiesBatch(
@@ -481,6 +494,9 @@ public RecognizeEntitiesResultCollection recognizeEntitiesBatch(
*
* @throws NullPointerException if {@code documents} is null.
* @throws IllegalArgumentException if {@code documents} is empty.
+ * @throws IllegalStateException if {@link TextAnalyticsRequestOptions#isServiceLogsDisabled()} is true in service
+ * API version {@link TextAnalyticsServiceVersion#V3_0}. {@code disableServiceLogs} is only available for API
+ * version v3.1 and newer.
*/
@ServiceMethod(returns = ReturnType.SINGLE)
public Response recognizeEntitiesBatchWithResponse(
@@ -522,6 +538,9 @@ public Response recognizeEntitiesBatchWithRes
*
* @throws NullPointerException if {@code document} is null.
* @throws TextAnalyticsException if the response returned with an {@link TextAnalyticsError error}.
+ * @throws IllegalStateException if {@code recognizePiiEntities} is called with service API version
+ * {@link TextAnalyticsServiceVersion#V3_0}. {@code recognizePiiEntities} is only available for
+ * API version v3.1 and newer.
*/
@ServiceMethod(returns = ReturnType.SINGLE)
public PiiEntityCollection recognizePiiEntities(String document) {
@@ -559,6 +578,9 @@ public PiiEntityCollection recognizePiiEntities(String document) {
*
* @throws NullPointerException if {@code document} is null.
* @throws TextAnalyticsException if the response returned with an {@link TextAnalyticsError error}.
+ * @throws IllegalStateException if {@code recognizePiiEntities} is called with service API version
+ * {@link TextAnalyticsServiceVersion#V3_0}. {@code recognizePiiEntities} is only available for
+ * API version v3.1 and newer.
*/
@ServiceMethod(returns = ReturnType.SINGLE)
public PiiEntityCollection recognizePiiEntities(String document, String language) {
@@ -600,6 +622,9 @@ public PiiEntityCollection recognizePiiEntities(String document, String language
*
* @throws NullPointerException if {@code document} is null.
* @throws TextAnalyticsException if the response returned with an {@link TextAnalyticsError error}.
+ * @throws IllegalStateException if {@code recognizePiiEntities} is called with service API version
+ * {@link TextAnalyticsServiceVersion#V3_0}. {@code recognizePiiEntities} is only available for
+ * API version v3.1 and newer.
*/
@ServiceMethod(returns = ReturnType.SINGLE)
public PiiEntityCollection recognizePiiEntities(String document, String language,
@@ -652,6 +677,9 @@ public PiiEntityCollection recognizePiiEntities(String document, String language
*
* @throws NullPointerException if {@code documents} is null.
* @throws IllegalArgumentException if {@code documents} is empty.
+ * @throws IllegalStateException if {@code recognizePiiEntitiesBatch} is called with service API version
+ * {@link TextAnalyticsServiceVersion#V3_0}. {@code recognizePiiEntitiesBatch} is only available for
+ * API version v3.1 and newer.
*/
@ServiceMethod(returns = ReturnType.SINGLE)
public RecognizePiiEntitiesResultCollection recognizePiiEntitiesBatch(
@@ -707,6 +735,9 @@ public RecognizePiiEntitiesResultCollection recognizePiiEntitiesBatch(
*
* @throws NullPointerException if {@code documents} is null.
* @throws IllegalArgumentException if {@code documents} is empty.
+ * @throws IllegalStateException if {@code recognizePiiEntitiesBatchWithResponse} is called with service API version
+ * {@link TextAnalyticsServiceVersion#V3_0}. {@code recognizePiiEntitiesBatchWithResponse} is only available for
+ * API version v3.1 and newer.
*/
@ServiceMethod(returns = ReturnType.SINGLE)
public Response recognizePiiEntitiesBatchWithResponse(
@@ -843,6 +874,9 @@ public LinkedEntityCollection recognizeLinkedEntities(String document, String la
*
* @throws NullPointerException if {@code documents} is null.
* @throws IllegalArgumentException if {@code documents} is empty.
+ * @throws IllegalStateException if {@link TextAnalyticsRequestOptions#isServiceLogsDisabled()} is true in service
+ * API version {@link TextAnalyticsServiceVersion#V3_0}. {@code disableServiceLogs} is only available for API
+ * version v3.1 and newer.
*/
@ServiceMethod(returns = ReturnType.SINGLE)
public RecognizeLinkedEntitiesResultCollection recognizeLinkedEntitiesBatch(
@@ -905,6 +939,9 @@ public RecognizeLinkedEntitiesResultCollection recognizeLinkedEntitiesBatch(
*
* @throws NullPointerException if {@code documents} is null.
* @throws IllegalArgumentException if {@code documents} is empty.
+ * @throws IllegalStateException if {@link TextAnalyticsRequestOptions#isServiceLogsDisabled()} is true in service
+ * API version {@link TextAnalyticsServiceVersion#V3_0}. {@code disableServiceLogs} is only available for API
+ * version v3.1 and newer.
*/
@ServiceMethod(returns = ReturnType.SINGLE)
public Response recognizeLinkedEntitiesBatchWithResponse(
@@ -1025,6 +1062,9 @@ public KeyPhrasesCollection extractKeyPhrases(String document, String language)
*
* @throws NullPointerException if {@code documents} is null.
* @throws IllegalArgumentException if {@code documents} is empty.
+ * @throws IllegalStateException if {@link TextAnalyticsRequestOptions#isServiceLogsDisabled()} is true in service
+ * API version {@link TextAnalyticsServiceVersion#V3_0}. {@code disableServiceLogs} is only available for API
+ * version v3.1 and newer.
*/
@ServiceMethod(returns = ReturnType.SINGLE)
public ExtractKeyPhrasesResultCollection extractKeyPhrasesBatch(
@@ -1086,6 +1126,9 @@ public ExtractKeyPhrasesResultCollection extractKeyPhrasesBatch(
*
* @throws NullPointerException if {@code documents} is null.
* @throws IllegalArgumentException if {@code documents} is empty.
+ * @throws IllegalStateException if {@link TextAnalyticsRequestOptions#isServiceLogsDisabled()} is true in service
+ * API version {@link TextAnalyticsServiceVersion#V3_0}. {@code disableServiceLogs} is only available for API
+ * version v3.1 and newer.
*/
@ServiceMethod(returns = ReturnType.SINGLE)
public Response extractKeyPhrasesBatchWithResponse(
@@ -1233,6 +1276,10 @@ public DocumentSentiment analyzeSentiment(String document, String language) {
*
* @throws NullPointerException if {@code document} is null.
* @throws TextAnalyticsException if the response returned with an {@link TextAnalyticsError error}.
+ * @throws IllegalStateException if {@link AnalyzeSentimentOptions#isServiceLogsDisabled()} or
+ * {@link AnalyzeSentimentOptions#isIncludeOpinionMining()} is true in service API version
+ * {@link TextAnalyticsServiceVersion#V3_0}. {@code disableServiceLogs} and {@code includeOpinionMining} are only
+ * available for API version v3.1 and newer.
*/
@ServiceMethod(returns = ReturnType.SINGLE)
public DocumentSentiment analyzeSentiment(String document, String language, AnalyzeSentimentOptions options) {
@@ -1360,6 +1407,10 @@ public AnalyzeSentimentResultCollection analyzeSentimentBatch(
*
* @throws NullPointerException if {@code documents} is null.
* @throws IllegalArgumentException if {@code documents} is empty.
+ * @throws IllegalStateException if {@link AnalyzeSentimentOptions#isServiceLogsDisabled()} or
+ * {@link AnalyzeSentimentOptions#isIncludeOpinionMining()} is true in service API version
+ * {@link TextAnalyticsServiceVersion#V3_0}. {@code disableServiceLogs} and {@code includeOpinionMining} are only
+ * available for API version v3.1 and newer.
*/
@ServiceMethod(returns = ReturnType.SINGLE)
public AnalyzeSentimentResultCollection analyzeSentimentBatch(Iterable documents,
@@ -1515,6 +1566,10 @@ public Response analyzeSentimentBatchWithRespo
*
* @throws NullPointerException if {@code documents} is null.
* @throws IllegalArgumentException if {@code documents} is empty.
+ * @throws IllegalStateException if {@link AnalyzeSentimentOptions#isServiceLogsDisabled()} or
+ * {@link AnalyzeSentimentOptions#isIncludeOpinionMining()} is true in service API version
+ * {@link TextAnalyticsServiceVersion#V3_0}. {@code disableServiceLogs} and {@code includeOpinionMining} are only
+ * available for API version v3.1 and newer.
*/
@ServiceMethod(returns = ReturnType.SINGLE)
public Response analyzeSentimentBatchWithResponse(
@@ -1541,6 +1596,9 @@ public Response analyzeSentimentBatchWithRespo
*
* @throws NullPointerException if {@code documents} is null.
* @throws IllegalArgumentException if {@code documents} is empty.
+ * @throws IllegalStateException if {@code beginAnalyzeHealthcareEntities} is called with service API version
+ * {@link TextAnalyticsServiceVersion#V3_0}. {@code beginAnalyzeHealthcareEntities} is only available for API
+ * version v3.1 and newer.
* @throws TextAnalyticsException If analyze operation fails.
*/
@ServiceMethod(returns = ReturnType.COLLECTION)
@@ -1642,6 +1700,9 @@ public Response analyzeSentimentBatchWithRespo
*
* @throws NullPointerException if {@code documents} is null.
* @throws IllegalArgumentException if {@code documents} is empty.
+ * @throws IllegalStateException if {@code beginAnalyzeHealthcareEntities} is called with service API version
+ * {@link TextAnalyticsServiceVersion#V3_0}. {@code beginAnalyzeHealthcareEntities} is only available for API
+ * version v3.1 and newer.
* @throws TextAnalyticsException If analyze operation fails.
*/
@ServiceMethod(returns = ReturnType.COLLECTION)
@@ -1706,6 +1767,9 @@ public Response analyzeSentimentBatchWithRespo
*
* @throws NullPointerException if {@code documents} is null.
* @throws IllegalArgumentException if {@code documents} is empty.
+ * @throws IllegalStateException if {@code beginRecognizeCustomEntities} is called with service API version
+ * {@link TextAnalyticsServiceVersion#V3_0} or {@link TextAnalyticsServiceVersion#V3_1}.
+ * {@code beginRecognizeCustomEntities} is only available for API version 2022-05-01 and newer.
* @throws TextAnalyticsException If analyze operation fails.
*/
@ServiceMethod(returns = ReturnType.COLLECTION)
@@ -1774,6 +1838,9 @@ public Response analyzeSentimentBatchWithRespo
*
* @throws NullPointerException if {@code documents} is null.
* @throws IllegalArgumentException if {@code documents} is empty.
+ * @throws IllegalStateException if {@code beginRecognizeCustomEntities} is called with service API version
+ * {@link TextAnalyticsServiceVersion#V3_0} or {@link TextAnalyticsServiceVersion#V3_1}.
+ * {@code beginRecognizeCustomEntities} is only available for API version 2022-05-01 and newer.
* @throws TextAnalyticsException If analyze operation fails.
*/
@ServiceMethod(returns = ReturnType.COLLECTION)
@@ -1841,6 +1908,9 @@ public Response analyzeSentimentBatchWithRespo
*
* @throws NullPointerException if {@code documents} is null.
* @throws IllegalArgumentException if {@code documents} is empty.
+ * @throws IllegalStateException if {@code beginSingleLabelClassify} is called with service API version
+ * {@link TextAnalyticsServiceVersion#V3_0} or {@link TextAnalyticsServiceVersion#V3_1}.
+ * {@code beginSingleLabelClassify} is only available for API version 2022-05-01 and newer.
* @throws TextAnalyticsException If analyze operation fails.
*/
@ServiceMethod(returns = ReturnType.COLLECTION)
@@ -1907,6 +1977,9 @@ public Response analyzeSentimentBatchWithRespo
*
* @throws NullPointerException if {@code documents} is null.
* @throws IllegalArgumentException if {@code documents} is empty.
+ * @throws IllegalStateException if {@code beginSingleLabelClassify} is called with service API version
+ * {@link TextAnalyticsServiceVersion#V3_0} or {@link TextAnalyticsServiceVersion#V3_1}.
+ * {@code beginSingleLabelClassify} is only available for API version 2022-05-01 and newer.
* @throws TextAnalyticsException If analyze operation fails.
*/
@ServiceMethod(returns = ReturnType.COLLECTION)
@@ -1968,6 +2041,9 @@ public Response analyzeSentimentBatchWithRespo
*
* @throws NullPointerException if {@code documents} is null.
* @throws IllegalArgumentException if {@code documents} is empty.
+ * @throws IllegalStateException if {@code beginMultiLabelClassify} is called with service API version
+ * {@link TextAnalyticsServiceVersion#V3_0} or {@link TextAnalyticsServiceVersion#V3_1}.
+ * {@code beginMultiLabelClassify} is only available for API version 2022-05-01 and newer.
* @throws TextAnalyticsException If analyze operation fails.
*/
@ServiceMethod(returns = ReturnType.COLLECTION)
@@ -2030,6 +2106,9 @@ public Response analyzeSentimentBatchWithRespo
*
* @throws NullPointerException if {@code documents} is null.
* @throws IllegalArgumentException if {@code documents} is empty.
+ * @throws IllegalStateException if {@code beginMultiLabelClassify} is called with service API version
+ * {@link TextAnalyticsServiceVersion#V3_0} or {@link TextAnalyticsServiceVersion#V3_1}.
+ * {@code beginMultiLabelClassify} is only available for API version 2022-05-01 and newer.
* @throws TextAnalyticsException If analyze operation fails.
*/
@ServiceMethod(returns = ReturnType.COLLECTION)
@@ -2109,6 +2188,13 @@ public Response analyzeSentimentBatchWithRespo
*
* @throws NullPointerException if {@code documents} is null.
* @throws IllegalArgumentException if {@code documents} is empty.
+ * @throws IllegalStateException if {@code beginAnalyzeActions} is called with service API version
+ * {@link TextAnalyticsServiceVersion#V3_0}. {@code beginAnalyzeActions} is only available for API version
+ * v3.1 and newer.
+ * @throws IllegalStateException if request {@link AnalyzeHealthcareEntitiesAction},
+ * {@link RecognizeCustomEntitiesAction}, {@link SingleLabelClassifyAction}, or {@link MultiLabelClassifyAction}
+ * in service API version {@link TextAnalyticsServiceVersion#V3_0} or {@link TextAnalyticsServiceVersion#V3_1}.
+ * Those actions are only available for API version 2022-05-01 and newer.
* @throws TextAnalyticsException If analyze operation fails.
*/
@ServiceMethod(returns = ReturnType.COLLECTION)
@@ -2188,6 +2274,13 @@ public SyncPoller