Skip to content

Commit 3fd0862

Browse files
Scripts: Adds Stream APIs for CRUD Operations (#4978)
# Pull Request Template ## Description Adds new Stream APIs for CRUD operations on stored procedures, triggers, and user defined functions in the `Scripts` namespace. ## Type of change Please delete options that are not relevant. - [] New feature (non-breaking change which adds functionality) ## Closing issues To automatically close an issue: closes #4951
1 parent 5e1dd0c commit 3fd0862

File tree

8 files changed

+1140
-110
lines changed

8 files changed

+1140
-110
lines changed

Microsoft.Azure.Cosmos/src/Resource/Scripts/Scripts.cs

Lines changed: 434 additions & 1 deletion
Large diffs are not rendered by default.

Microsoft.Azure.Cosmos/src/Resource/Scripts/ScriptsCore.cs

Lines changed: 276 additions & 107 deletions
Large diffs are not rendered by default.

Microsoft.Azure.Cosmos/src/Resource/Scripts/ScriptsInlineCore.cs

Lines changed: 228 additions & 1 deletion
Large diffs are not rendered by default.

Microsoft.Azure.Cosmos/src/Serializer/CosmosSerializerCore.cs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -156,7 +156,11 @@ private CosmosSerializer GetSerializer<T>(
156156
string directAssemblyName = typeof(Documents.PartitionKeyRange).Assembly.GetName().Name;
157157
string inputAssemblyName = inputType.Assembly.GetName().Name;
158158
bool inputIsClientOrDirect = string.Equals(inputAssemblyName, clientAssemblyName) || string.Equals(inputAssemblyName, directAssemblyName);
159-
bool typeIsWhiteListed = inputType == typeof(Document) || (inputType.IsGenericType && inputType.GetGenericTypeDefinition() == typeof(ChangeFeedItem<>));
159+
bool typeIsWhiteListed = inputType == typeof(Document)
160+
|| (inputType.IsGenericType && inputType.GetGenericTypeDefinition() == typeof(ChangeFeedItem<>))
161+
|| inputType == typeof(StoredProcedureResponse)
162+
|| inputType == typeof(TriggerResponse)
163+
|| inputType == typeof(UserDefinedFunctionResponse);
160164

161165
if (!typeIsWhiteListed && inputIsClientOrDirect)
162166
{

Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/StoredProcedureTests.cs

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,52 @@ public async Task CRUDTest()
123123
Assert.IsTrue(diagnostics.Contains("StatusCode"));
124124
}
125125

126+
[TestMethod]
127+
public async Task CRUDStreamTest()
128+
{
129+
string sprocId = Guid.NewGuid().ToString();
130+
string sprocBody = "function() { { var x = 42; } }";
131+
132+
StoredProcedureProperties storedProcedureProperties = new StoredProcedureProperties(sprocId, sprocBody);
133+
ResponseMessage responseMessage = await this.scripts.CreateStoredProcedureStreamAsync(
134+
storedProcedureProperties);
135+
Assert.AreEqual(HttpStatusCode.Created, responseMessage.StatusCode);
136+
Assert.IsNotNull(responseMessage.Diagnostics);
137+
string diagnostics = responseMessage.Diagnostics.ToString();
138+
Assert.IsFalse(string.IsNullOrEmpty(diagnostics));
139+
Assert.IsTrue(diagnostics.Contains("StatusCode"));
140+
141+
responseMessage = await this.scripts.ReadStoredProcedureStreamAsync(sprocId);
142+
Assert.AreEqual(HttpStatusCode.OK, responseMessage.StatusCode);
143+
Assert.IsNotNull(responseMessage.Diagnostics);
144+
diagnostics = responseMessage.Diagnostics.ToString();
145+
Assert.IsFalse(string.IsNullOrEmpty(diagnostics));
146+
Assert.IsTrue(diagnostics.Contains("StatusCode"));
147+
148+
string updatedBody = @"function(name) { var context = getContext();
149+
var response = context.getResponse();
150+
response.setBody(""hello there "" + name);
151+
}";
152+
153+
storedProcedureProperties = new StoredProcedureProperties(sprocId, updatedBody);
154+
ResponseMessage replaceResponseMessage = await this.scripts.ReplaceStoredProcedureStreamAsync(
155+
storedProcedureProperties);
156+
157+
Assert.AreEqual(HttpStatusCode.OK, replaceResponseMessage.StatusCode);
158+
Assert.IsNotNull(replaceResponseMessage.Diagnostics);
159+
diagnostics = replaceResponseMessage.Diagnostics.ToString();
160+
Assert.IsFalse(string.IsNullOrEmpty(diagnostics));
161+
Assert.IsTrue(diagnostics.Contains("StatusCode"));
162+
163+
164+
ResponseMessage deleteResponseMessage = await this.scripts.DeleteStoredProcedureStreamAsync(sprocId);
165+
Assert.AreEqual(HttpStatusCode.NoContent, deleteResponseMessage.StatusCode);
166+
Assert.IsNotNull(deleteResponseMessage.Diagnostics);
167+
diagnostics = deleteResponseMessage.Diagnostics.ToString();
168+
Assert.IsFalse(string.IsNullOrEmpty(diagnostics));
169+
Assert.IsTrue(diagnostics.Contains("StatusCode"));
170+
}
171+
126172
[TestMethod]
127173
public async Task ExecutionLogsTests()
128174
{

Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/TriggersTests.cs

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,53 @@ public async Task CRUDTest()
106106
}
107107

108108
[TestMethod]
109+
public async Task CRUDStreamTest()
110+
{
111+
TriggerProperties settings = new TriggerProperties
112+
{
113+
Id = Guid.NewGuid().ToString(),
114+
Body = TriggersTests.GetTriggerFunction(".05"),
115+
TriggerOperation = Cosmos.Scripts.TriggerOperation.Create,
116+
TriggerType = Cosmos.Scripts.TriggerType.Pre
117+
};
118+
119+
120+
ResponseMessage triggerResponseMessage =
121+
await this.scripts.CreateTriggerStreamAsync(
122+
settings);
123+
Assert.AreEqual(HttpStatusCode.Created, triggerResponseMessage.StatusCode);
124+
Assert.IsNotNull(triggerResponseMessage.Diagnostics);
125+
string diagnostics = triggerResponseMessage.Diagnostics.ToString();
126+
Assert.IsFalse(string.IsNullOrEmpty(diagnostics));
127+
Assert.IsTrue(diagnostics.Contains("StatusCode"));
128+
129+
triggerResponseMessage = await this.scripts.ReadTriggerStreamAsync(settings.Id);
130+
Assert.AreEqual(HttpStatusCode.OK, triggerResponseMessage.StatusCode);
131+
Assert.IsNotNull(triggerResponseMessage.Diagnostics);
132+
diagnostics = triggerResponseMessage.Diagnostics.ToString();
133+
Assert.IsFalse(string.IsNullOrEmpty(diagnostics));
134+
Assert.IsTrue(diagnostics.Contains("StatusCode"));
135+
136+
TriggerProperties updatedSettings = settings;
137+
updatedSettings.Body = TriggersTests.GetTriggerFunction(".42");
138+
139+
ResponseMessage replaceResponseMessage = await this.scripts.ReplaceTriggerStreamAsync(
140+
updatedSettings);
141+
Assert.AreEqual(HttpStatusCode.OK, replaceResponseMessage.StatusCode);
142+
Assert.IsNotNull(replaceResponseMessage.Diagnostics);
143+
diagnostics = replaceResponseMessage.Diagnostics.ToString();
144+
Assert.IsFalse(string.IsNullOrEmpty(diagnostics));
145+
Assert.IsTrue(diagnostics.Contains("StatusCode"));
146+
147+
replaceResponseMessage = await this.scripts.DeleteTriggerStreamAsync(updatedSettings.Id);
148+
Assert.AreEqual(HttpStatusCode.NoContent, replaceResponseMessage.StatusCode);
149+
Assert.IsNotNull(replaceResponseMessage.Diagnostics);
150+
diagnostics = replaceResponseMessage.Diagnostics.ToString();
151+
Assert.IsFalse(string.IsNullOrEmpty(diagnostics));
152+
Assert.IsTrue(diagnostics.Contains("StatusCode"));
153+
}
154+
155+
109156
[DataRow(TriggerOperation.Create, false, DisplayName = "TriggerOperation - Create with Binary encoding disabled.")]
110157
[DataRow(TriggerOperation.Create, true, DisplayName = "TriggerOperation - Create with Binary encoding enabled.")]
111158
[DataRow(TriggerOperation.Upsert, false, DisplayName = "TriggerOperation - Upsert with Binary encoding disabled.")]

Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/UserDefinedFunctionsTests.cs

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,50 @@ public async Task CRUDTest()
101101
Assert.AreEqual(HttpStatusCode.NoContent, replaceResponse.StatusCode);
102102
}
103103

104+
[TestMethod]
105+
public async Task CRUDStreamTest()
106+
{
107+
UserDefinedFunctionProperties settings = new UserDefinedFunctionProperties
108+
{
109+
Id = Guid.NewGuid().ToString(),
110+
Body = UserDefinedFunctionsTests.function,
111+
};
112+
113+
ResponseMessage responseMessage =
114+
await this.scripts.CreateUserDefinedFunctionStreamAsync(
115+
settings);
116+
Assert.AreEqual(HttpStatusCode.Created, responseMessage.StatusCode);
117+
Assert.IsNotNull(responseMessage.Diagnostics);
118+
string diagnostics = responseMessage.Diagnostics.ToString();
119+
Assert.IsFalse(string.IsNullOrEmpty(diagnostics));
120+
Assert.IsTrue(diagnostics.Contains("StatusCode"));
121+
122+
responseMessage = await this.scripts.ReadUserDefinedFunctionStreamAsync(settings.Id);
123+
Assert.AreEqual(HttpStatusCode.OK, responseMessage.StatusCode);
124+
Assert.IsNotNull(responseMessage.Diagnostics);
125+
diagnostics = responseMessage.Diagnostics.ToString();
126+
Assert.IsFalse(string.IsNullOrEmpty(diagnostics));
127+
Assert.IsTrue(diagnostics.Contains("StatusCode"));
128+
129+
UserDefinedFunctionProperties updatedSettings = settings;
130+
updatedSettings.Body = @"function(amt) { return amt * 0.42; }";
131+
132+
ResponseMessage replaceResponseMessage = await this.scripts.ReplaceUserDefinedFunctionStreamAsync(
133+
updatedSettings);
134+
Assert.IsNotNull(replaceResponseMessage.Diagnostics);
135+
diagnostics = replaceResponseMessage.Diagnostics.ToString();
136+
Assert.IsFalse(string.IsNullOrEmpty(diagnostics));
137+
Assert.IsTrue(diagnostics.Contains("StatusCode"));
138+
Assert.AreEqual(HttpStatusCode.OK, replaceResponseMessage.StatusCode);
139+
140+
replaceResponseMessage = await this.scripts.DeleteUserDefinedFunctionStreamAsync(settings.Id);
141+
Assert.IsNotNull(replaceResponseMessage.Diagnostics);
142+
diagnostics = replaceResponseMessage.Diagnostics.ToString();
143+
Assert.IsFalse(string.IsNullOrEmpty(diagnostics));
144+
Assert.IsTrue(diagnostics.Contains("StatusCode"));
145+
Assert.AreEqual(HttpStatusCode.NoContent, replaceResponseMessage.StatusCode);
146+
}
147+
104148
[TestMethod]
105149
public async Task ValidateUserDefinedFunctionsTest()
106150
{

Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Contracts/DotNetSDKAPI.json

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9180,6 +9180,36 @@
91809180
"Attributes": [],
91819181
"MethodInfo": "Microsoft.Azure.Cosmos.FeedIterator`1[T] GetUserDefinedFunctionQueryIterator[T](System.String, System.String, Microsoft.Azure.Cosmos.QueryRequestOptions);IsAbstract:True;IsStatic:False;IsVirtual:True;IsGenericMethod:True;IsConstructor:False;IsFinal:False;"
91829182
},
9183+
"System.Threading.Tasks.Task`1[Microsoft.Azure.Cosmos.ResponseMessage] CreateStoredProcedureStreamAsync(Microsoft.Azure.Cosmos.Scripts.StoredProcedureProperties, Microsoft.Azure.Cosmos.RequestOptions, System.Threading.CancellationToken)": {
9184+
"Type": "Method",
9185+
"Attributes": [],
9186+
"MethodInfo": "System.Threading.Tasks.Task`1[Microsoft.Azure.Cosmos.ResponseMessage] CreateStoredProcedureStreamAsync(Microsoft.Azure.Cosmos.Scripts.StoredProcedureProperties, Microsoft.Azure.Cosmos.RequestOptions, System.Threading.CancellationToken);IsAbstract:True;IsStatic:False;IsVirtual:True;IsGenericMethod:False;IsConstructor:False;IsFinal:False;"
9187+
},
9188+
"System.Threading.Tasks.Task`1[Microsoft.Azure.Cosmos.ResponseMessage] CreateTriggerStreamAsync(Microsoft.Azure.Cosmos.Scripts.TriggerProperties, Microsoft.Azure.Cosmos.RequestOptions, System.Threading.CancellationToken)": {
9189+
"Type": "Method",
9190+
"Attributes": [],
9191+
"MethodInfo": "System.Threading.Tasks.Task`1[Microsoft.Azure.Cosmos.ResponseMessage] CreateTriggerStreamAsync(Microsoft.Azure.Cosmos.Scripts.TriggerProperties, Microsoft.Azure.Cosmos.RequestOptions, System.Threading.CancellationToken);IsAbstract:True;IsStatic:False;IsVirtual:True;IsGenericMethod:False;IsConstructor:False;IsFinal:False;"
9192+
},
9193+
"System.Threading.Tasks.Task`1[Microsoft.Azure.Cosmos.ResponseMessage] CreateUserDefinedFunctionStreamAsync(Microsoft.Azure.Cosmos.Scripts.UserDefinedFunctionProperties, Microsoft.Azure.Cosmos.RequestOptions, System.Threading.CancellationToken)": {
9194+
"Type": "Method",
9195+
"Attributes": [],
9196+
"MethodInfo": "System.Threading.Tasks.Task`1[Microsoft.Azure.Cosmos.ResponseMessage] CreateUserDefinedFunctionStreamAsync(Microsoft.Azure.Cosmos.Scripts.UserDefinedFunctionProperties, Microsoft.Azure.Cosmos.RequestOptions, System.Threading.CancellationToken);IsAbstract:True;IsStatic:False;IsVirtual:True;IsGenericMethod:False;IsConstructor:False;IsFinal:False;"
9197+
},
9198+
"System.Threading.Tasks.Task`1[Microsoft.Azure.Cosmos.ResponseMessage] DeleteStoredProcedureStreamAsync(System.String, Microsoft.Azure.Cosmos.RequestOptions, System.Threading.CancellationToken)": {
9199+
"Type": "Method",
9200+
"Attributes": [],
9201+
"MethodInfo": "System.Threading.Tasks.Task`1[Microsoft.Azure.Cosmos.ResponseMessage] DeleteStoredProcedureStreamAsync(System.String, Microsoft.Azure.Cosmos.RequestOptions, System.Threading.CancellationToken);IsAbstract:True;IsStatic:False;IsVirtual:True;IsGenericMethod:False;IsConstructor:False;IsFinal:False;"
9202+
},
9203+
"System.Threading.Tasks.Task`1[Microsoft.Azure.Cosmos.ResponseMessage] DeleteTriggerStreamAsync(System.String, Microsoft.Azure.Cosmos.RequestOptions, System.Threading.CancellationToken)": {
9204+
"Type": "Method",
9205+
"Attributes": [],
9206+
"MethodInfo": "System.Threading.Tasks.Task`1[Microsoft.Azure.Cosmos.ResponseMessage] DeleteTriggerStreamAsync(System.String, Microsoft.Azure.Cosmos.RequestOptions, System.Threading.CancellationToken);IsAbstract:True;IsStatic:False;IsVirtual:True;IsGenericMethod:False;IsConstructor:False;IsFinal:False;"
9207+
},
9208+
"System.Threading.Tasks.Task`1[Microsoft.Azure.Cosmos.ResponseMessage] DeleteUserDefinedFunctionStreamAsync(System.String, Microsoft.Azure.Cosmos.RequestOptions, System.Threading.CancellationToken)": {
9209+
"Type": "Method",
9210+
"Attributes": [],
9211+
"MethodInfo": "System.Threading.Tasks.Task`1[Microsoft.Azure.Cosmos.ResponseMessage] DeleteUserDefinedFunctionStreamAsync(System.String, Microsoft.Azure.Cosmos.RequestOptions, System.Threading.CancellationToken);IsAbstract:True;IsStatic:False;IsVirtual:True;IsGenericMethod:False;IsConstructor:False;IsFinal:False;"
9212+
},
91839213
"System.Threading.Tasks.Task`1[Microsoft.Azure.Cosmos.ResponseMessage] ExecuteStoredProcedureStreamAsync(System.String, Microsoft.Azure.Cosmos.PartitionKey, System.Object[], Microsoft.Azure.Cosmos.Scripts.StoredProcedureRequestOptions, System.Threading.CancellationToken)": {
91849214
"Type": "Method",
91859215
"Attributes": [],
@@ -9190,6 +9220,36 @@
91909220
"Attributes": [],
91919221
"MethodInfo": "System.Threading.Tasks.Task`1[Microsoft.Azure.Cosmos.ResponseMessage] ExecuteStoredProcedureStreamAsync(System.String, System.IO.Stream, Microsoft.Azure.Cosmos.PartitionKey, Microsoft.Azure.Cosmos.Scripts.StoredProcedureRequestOptions, System.Threading.CancellationToken);IsAbstract:True;IsStatic:False;IsVirtual:True;IsGenericMethod:False;IsConstructor:False;IsFinal:False;"
91929222
},
9223+
"System.Threading.Tasks.Task`1[Microsoft.Azure.Cosmos.ResponseMessage] ReadStoredProcedureStreamAsync(System.String, Microsoft.Azure.Cosmos.RequestOptions, System.Threading.CancellationToken)": {
9224+
"Type": "Method",
9225+
"Attributes": [],
9226+
"MethodInfo": "System.Threading.Tasks.Task`1[Microsoft.Azure.Cosmos.ResponseMessage] ReadStoredProcedureStreamAsync(System.String, Microsoft.Azure.Cosmos.RequestOptions, System.Threading.CancellationToken);IsAbstract:True;IsStatic:False;IsVirtual:True;IsGenericMethod:False;IsConstructor:False;IsFinal:False;"
9227+
},
9228+
"System.Threading.Tasks.Task`1[Microsoft.Azure.Cosmos.ResponseMessage] ReadTriggerStreamAsync(System.String, Microsoft.Azure.Cosmos.RequestOptions, System.Threading.CancellationToken)": {
9229+
"Type": "Method",
9230+
"Attributes": [],
9231+
"MethodInfo": "System.Threading.Tasks.Task`1[Microsoft.Azure.Cosmos.ResponseMessage] ReadTriggerStreamAsync(System.String, Microsoft.Azure.Cosmos.RequestOptions, System.Threading.CancellationToken);IsAbstract:True;IsStatic:False;IsVirtual:True;IsGenericMethod:False;IsConstructor:False;IsFinal:False;"
9232+
},
9233+
"System.Threading.Tasks.Task`1[Microsoft.Azure.Cosmos.ResponseMessage] ReadUserDefinedFunctionStreamAsync(System.String, Microsoft.Azure.Cosmos.RequestOptions, System.Threading.CancellationToken)": {
9234+
"Type": "Method",
9235+
"Attributes": [],
9236+
"MethodInfo": "System.Threading.Tasks.Task`1[Microsoft.Azure.Cosmos.ResponseMessage] ReadUserDefinedFunctionStreamAsync(System.String, Microsoft.Azure.Cosmos.RequestOptions, System.Threading.CancellationToken);IsAbstract:True;IsStatic:False;IsVirtual:True;IsGenericMethod:False;IsConstructor:False;IsFinal:False;"
9237+
},
9238+
"System.Threading.Tasks.Task`1[Microsoft.Azure.Cosmos.ResponseMessage] ReplaceStoredProcedureStreamAsync(Microsoft.Azure.Cosmos.Scripts.StoredProcedureProperties, Microsoft.Azure.Cosmos.RequestOptions, System.Threading.CancellationToken)": {
9239+
"Type": "Method",
9240+
"Attributes": [],
9241+
"MethodInfo": "System.Threading.Tasks.Task`1[Microsoft.Azure.Cosmos.ResponseMessage] ReplaceStoredProcedureStreamAsync(Microsoft.Azure.Cosmos.Scripts.StoredProcedureProperties, Microsoft.Azure.Cosmos.RequestOptions, System.Threading.CancellationToken);IsAbstract:True;IsStatic:False;IsVirtual:True;IsGenericMethod:False;IsConstructor:False;IsFinal:False;"
9242+
},
9243+
"System.Threading.Tasks.Task`1[Microsoft.Azure.Cosmos.ResponseMessage] ReplaceTriggerStreamAsync(Microsoft.Azure.Cosmos.Scripts.TriggerProperties, Microsoft.Azure.Cosmos.RequestOptions, System.Threading.CancellationToken)": {
9244+
"Type": "Method",
9245+
"Attributes": [],
9246+
"MethodInfo": "System.Threading.Tasks.Task`1[Microsoft.Azure.Cosmos.ResponseMessage] ReplaceTriggerStreamAsync(Microsoft.Azure.Cosmos.Scripts.TriggerProperties, Microsoft.Azure.Cosmos.RequestOptions, System.Threading.CancellationToken);IsAbstract:True;IsStatic:False;IsVirtual:True;IsGenericMethod:False;IsConstructor:False;IsFinal:False;"
9247+
},
9248+
"System.Threading.Tasks.Task`1[Microsoft.Azure.Cosmos.ResponseMessage] ReplaceUserDefinedFunctionStreamAsync(Microsoft.Azure.Cosmos.Scripts.UserDefinedFunctionProperties, Microsoft.Azure.Cosmos.RequestOptions, System.Threading.CancellationToken)": {
9249+
"Type": "Method",
9250+
"Attributes": [],
9251+
"MethodInfo": "System.Threading.Tasks.Task`1[Microsoft.Azure.Cosmos.ResponseMessage] ReplaceUserDefinedFunctionStreamAsync(Microsoft.Azure.Cosmos.Scripts.UserDefinedFunctionProperties, Microsoft.Azure.Cosmos.RequestOptions, System.Threading.CancellationToken);IsAbstract:True;IsStatic:False;IsVirtual:True;IsGenericMethod:False;IsConstructor:False;IsFinal:False;"
9252+
},
91939253
"System.Threading.Tasks.Task`1[Microsoft.Azure.Cosmos.Scripts.StoredProcedureExecuteResponse`1[TOutput]] ExecuteStoredProcedureAsync[TOutput](System.String, Microsoft.Azure.Cosmos.PartitionKey, System.Object[], Microsoft.Azure.Cosmos.Scripts.StoredProcedureRequestOptions, System.Threading.CancellationToken)": {
91949254
"Type": "Method",
91959255
"Attributes": [],

0 commit comments

Comments
 (0)