Skip to content

Commit 3813ee7

Browse files
committed
Addition of DeltaFunctionsSample
1 parent 9a0c7db commit 3813ee7

10 files changed

+329
-0
lines changed

AspNetCoreOData.sln

+7
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ODataAlternateKeySample", "
2929
EndProject
3030
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BenchmarkServer", "sample\BenchmarkServer\BenchmarkServer.csproj", "{8346AD1B-00E3-462D-B6B1-9AA3C2FB2850}"
3131
EndProject
32+
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DeltaFunctionsSample", "sample\DeltaFunctions\DeltaFunctionsSample.csproj", "{B4D2B1EE-14DA-47E2-AFAD-11087C8508D2}"
33+
EndProject
3234
Global
3335
GlobalSection(SolutionConfigurationPlatforms) = preSolution
3436
Debug|Any CPU = Debug|Any CPU
@@ -75,6 +77,10 @@ Global
7577
{8346AD1B-00E3-462D-B6B1-9AA3C2FB2850}.Debug|Any CPU.Build.0 = Debug|Any CPU
7678
{8346AD1B-00E3-462D-B6B1-9AA3C2FB2850}.Release|Any CPU.ActiveCfg = Release|Any CPU
7779
{8346AD1B-00E3-462D-B6B1-9AA3C2FB2850}.Release|Any CPU.Build.0 = Release|Any CPU
80+
{B4D2B1EE-14DA-47E2-AFAD-11087C8508D2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
81+
{B4D2B1EE-14DA-47E2-AFAD-11087C8508D2}.Debug|Any CPU.Build.0 = Debug|Any CPU
82+
{B4D2B1EE-14DA-47E2-AFAD-11087C8508D2}.Release|Any CPU.ActiveCfg = Release|Any CPU
83+
{B4D2B1EE-14DA-47E2-AFAD-11087C8508D2}.Release|Any CPU.Build.0 = Release|Any CPU
7884
EndGlobalSection
7985
GlobalSection(SolutionProperties) = preSolution
8086
HideSolutionNode = FALSE
@@ -90,6 +96,7 @@ Global
9096
{647EFCFA-55A7-4F0A-AD40-4B6EB1BFCFFA} = {B1F86961-6958-4617-ACA4-C231F95AE099}
9197
{7B153669-A42F-4511-8BDB-587B3B27B2F3} = {B1F86961-6958-4617-ACA4-C231F95AE099}
9298
{8346AD1B-00E3-462D-B6B1-9AA3C2FB2850} = {B1F86961-6958-4617-ACA4-C231F95AE099}
99+
{B4D2B1EE-14DA-47E2-AFAD-11087C8508D2} = {B1F86961-6958-4617-ACA4-C231F95AE099}
93100
EndGlobalSection
94101
GlobalSection(ExtensibilityGlobals) = postSolution
95102
SolutionGuid = {540C9752-AAC0-49EA-BA60-78490C90FF86}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,131 @@
1+
//-----------------------------------------------------------------------------
2+
// <copyright file="PeopleController.cs" company=".NET Foundation">
3+
// Copyright (c) .NET Foundation and Contributors. All rights reserved.
4+
// See License.txt in the project root for license information.
5+
// </copyright>
6+
//------------------------------------------------------------------------------
7+
8+
using Microsoft.AspNetCore.Mvc;
9+
using Microsoft.AspNetCore.OData.Formatter.Value;
10+
using Microsoft.AspNetCore.OData.Query;
11+
using Microsoft.AspNetCore.OData.Routing.Controllers;
12+
using Microsoft.OData.Edm;
13+
14+
namespace microsoft.graph;
15+
16+
public class recoveryPreviewJobsController : ODataController
17+
{
18+
private recoveryPreviewJob[] recoveryPreviewJobs =
19+
{
20+
new recoveryPreviewJob()
21+
};
22+
23+
[HttpGet]
24+
public recoveryPreviewJob Get(string id)
25+
{
26+
return recoveryPreviewJobs[0];
27+
}
28+
29+
[HttpGet]
30+
public IActionResult Get()
31+
{
32+
return Ok(recoveryPreviewJobs);
33+
}
34+
35+
[HttpGet]
36+
public IActionResult getChanges([FromRoute] string key, ODataQueryOptions<recoveryChangeObject> queryOptions)
37+
{
38+
var result = new EdmChangedObjectCollection(GraphModel.recoveryChangeObjectType);
39+
//could alternatively use DeltaSet<T>
40+
//var result = new DeltaSet<recoveryChangeObject>();
41+
42+
// Get IQueryable<recoveryChangeObject> of the changes and apply filter, orderby, etc. to that queryable
43+
// IQueryable<recoveryChangeObject> changeObjects = getChangeObjects();
44+
// var filteredChanges = queryOptions.ApplyTo(changeObjects);
45+
// Loop through the recoveryChangeObject instances and generate the delta payload
46+
// foreach(recoveryChangeObject changeObject in filteredChanges)...
47+
48+
// example: create recoveryChangeObject for changed user
49+
var recoveryChangeObject = new EdmEntityObject(GraphModel.recoveryChangeObjectType);
50+
// could alternatively do Delta<recoveryChangeObject>
51+
// var recoveryChangeObject = new Delta<recoveryChangeObject>();
52+
// Set properties
53+
// recoveryChangeObject.TrySetPropertyValue("id", "1");
54+
recoveryChangeObject.TrySetPropertyValue("currentState", getUser());
55+
recoveryChangeObject.TrySetPropertyValue("deltaFromCurrent", getChangedUser());
56+
// Add to result
57+
result.Add(recoveryChangeObject);
58+
59+
// Create recoveryChangeObject for group w/members
60+
recoveryChangeObject = new EdmEntityObject(GraphModel.recoveryChangeObjectType);
61+
// alternatively:
62+
// recoveryChangeObject = new Delta<recoveryChangeObject>();
63+
// Set Properties
64+
recoveryChangeObject.TrySetPropertyValue("id", "2");
65+
recoveryChangeObject.TrySetPropertyValue("currentState", getGroup());
66+
recoveryChangeObject.TrySetPropertyValue("deltaFromCurrent", getChangedGroup());
67+
// Add to result
68+
result.Add(recoveryChangeObject);
69+
70+
return Ok(result);
71+
}
72+
73+
//TODO: getChanges isn't found as a valid segment
74+
//[HttpGet("recoveryChangeObjects/{id}/microsoft.graph.getChanges()/{key}/deltaFromCurrent")]
75+
[EnableQuery]
76+
public IActionResult getChangesFromRecoveryChangeObject([FromRoute] string id, [FromRoute] string key)
77+
{
78+
return Ok(getChangedUser());
79+
}
80+
81+
// Example function to get a user
82+
private EdmEntityObject getUser()
83+
{
84+
EdmEntityObject user = new EdmEntityObject(GraphModel.userType);
85+
user.TrySetPropertyValue("id", "user1");
86+
user.TrySetPropertyValue("displayName", "William");
87+
return user;
88+
}
89+
90+
// Example function to get a group
91+
private EdmEntityObject getGroup()
92+
{
93+
EdmEntityObject user = new EdmEntityObject(GraphModel.groupType);
94+
user.TrySetPropertyValue("id", "group1");
95+
var members = new EdmEntityObjectCollection(new EdmCollectionTypeReference(new EdmCollectionType(new EdmEntityTypeReference(EdmCoreModel.Instance.GetEntityType(),false))));
96+
var member1 = new EdmEntityObject(GraphModel.userType);
97+
member1.TrySetPropertyValue("id", "user7");
98+
member1.TrySetPropertyValue("email", "[email protected]");
99+
members.Add(member1);
100+
user.TrySetPropertyValue("members",members);
101+
return user;
102+
}
103+
104+
// Example function showing creating a changed user
105+
private EdmDeltaResourceObject getChangedUser()
106+
{
107+
var changedUser = new EdmDeltaResourceObject(GraphModel.userType);
108+
changedUser.TrySetPropertyValue("id", "user1");
109+
changedUser.TrySetPropertyValue("displayName", "Bill");
110+
return changedUser;
111+
}
112+
113+
// Example function showing creating a changed group
114+
private EdmDeltaResourceObject getChangedGroup() {
115+
var members = new EdmChangedObjectCollection(EdmCoreModel.Instance.GetEntityType());
116+
117+
var addedMember = new EdmDeltaResourceObject(GraphModel.userType);
118+
addedMember.TrySetPropertyValue("id", "user3");
119+
members.Add(addedMember);
120+
121+
var deletedMember = new EdmDeltaDeletedResourceObject(GraphModel.userType);
122+
deletedMember.Id = new Uri("https://graph.microsoft.com/v1.0/users/4");
123+
deletedMember.TrySetPropertyValue("id", "user4");
124+
members.Add(deletedMember);
125+
126+
var group = new EdmDeltaResourceObject(GraphModel.groupType);
127+
group.TrySetPropertyValue("id", "group1");
128+
group.TrySetPropertyValue("members", members);
129+
return group;
130+
}
131+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
<Project Sdk="Microsoft.NET.Sdk.Web">
2+
3+
<PropertyGroup>
4+
<TargetFramework>net8.0</TargetFramework>
5+
<ImplicitUsings>enable</ImplicitUsings>
6+
</PropertyGroup>
7+
8+
<ItemGroup>
9+
<ProjectReference Include="..\..\src\Microsoft.AspNetCore.OData\Microsoft.AspNetCore.OData.csproj" />
10+
</ItemGroup>
11+
12+
</Project>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
//-----------------------------------------------------------------------------
2+
// <copyright file="EdmModelBuilder.cs" company=".NET Foundation">
3+
// Copyright (c) .NET Foundation and Contributors. All rights reserved.
4+
// See License.txt in the project root for license information.
5+
// </copyright>
6+
//------------------------------------------------------------------------------
7+
8+
using Microsoft.AspNetCore.OData.Formatter.Value;
9+
using Microsoft.OData.Edm;
10+
using Microsoft.OData.ModelBuilder;
11+
using System.ComponentModel;
12+
13+
namespace microsoft.graph;
14+
15+
public class GraphModel
16+
{
17+
public static EdmModel Model = GetEdmModel();
18+
public static EdmEntityType userType;
19+
public static EdmEntityType groupType;
20+
public static EdmEntityType recoveryChangeObjectType;
21+
public static EdmModel GetEdmModel()
22+
{
23+
var model = new EdmModel();
24+
string graphNamespace = "microsoft.graph";
25+
var entityContainer = model.AddEntityContainer(graphNamespace, "graphService");
26+
27+
// define recovery preview job
28+
var recoveryPreviewJobType = model.AddEntityType(graphNamespace,"recoveryPreviewJob");
29+
recoveryPreviewJobType.AddKeys(
30+
recoveryPreviewJobType.AddStructuralProperty("id", EdmPrimitiveTypeKind.String)
31+
);
32+
entityContainer.AddEntitySet("recoveryPreviewJobs", recoveryPreviewJobType);
33+
34+
// define recovery change object
35+
recoveryChangeObjectType = model.AddEntityType(graphNamespace, "recoveryChangeObject");
36+
recoveryChangeObjectType.AddKeys(
37+
recoveryChangeObjectType.AddStructuralProperty("id", EdmPrimitiveTypeKind.String)
38+
);
39+
recoveryChangeObjectType.AddUnidirectionalNavigation(new EdmNavigationPropertyInfo
40+
{
41+
Name = "currentState",
42+
Target = EdmCoreModel.Instance.GetEntityType(),
43+
TargetMultiplicity = EdmMultiplicity.One
44+
});
45+
recoveryChangeObjectType.AddUnidirectionalNavigation(new EdmNavigationPropertyInfo
46+
{
47+
Name = "deltaFromCurrent",
48+
Target = EdmCoreModel.Instance.GetEntityType(),
49+
TargetMultiplicity = EdmMultiplicity.One
50+
});
51+
52+
// schema for graph types (loaded from graph csdl)
53+
var directoryObjectType = model.AddEntityType(graphNamespace, "directoryObject");
54+
directoryObjectType.AddKeys(
55+
directoryObjectType.AddStructuralProperty("id", EdmPrimitiveTypeKind.String)
56+
);
57+
directoryObjectType.AddStructuralProperty("displayName",EdmPrimitiveTypeKind.String);
58+
userType = model.AddEntityType(graphNamespace, "user", directoryObjectType);
59+
userType.AddStructuralProperty("emailName", EdmPrimitiveTypeKind.String);
60+
groupType = model.AddEntityType(graphNamespace, "group", directoryObjectType);
61+
groupType.AddUnidirectionalNavigation(new EdmNavigationPropertyInfo
62+
{
63+
Name = "members",
64+
Target = directoryObjectType,
65+
TargetMultiplicity= EdmMultiplicity.Many
66+
});
67+
68+
// add getChanges function
69+
var recoveryChangeObjectCollectionType = new EdmCollectionTypeReference(new EdmCollectionType(new EdmEntityTypeReference(recoveryChangeObjectType,false)));
70+
var getChangesFunction = new EdmFunction(graphNamespace, "getChanges", recoveryChangeObjectCollectionType, true, null, true);
71+
getChangesFunction.AddParameter("recoveryPreviewJob", new EdmEntityTypeReference(recoveryPreviewJobType, false));
72+
73+
model.AddElement(getChangesFunction);
74+
75+
// TODO: Temportary hack to provide navigation source when writing; get rid of this
76+
entityContainer.AddEntitySet("recoveryChangeObjects", recoveryChangeObjectType);
77+
model.SetAnnotationValue<ReturnedEntitySetAnnotation>(getChangesFunction, new ReturnedEntitySetAnnotation("recoveryChangeObjects"));
78+
79+
//jobs.EntityType.Function("getChanges").ReturnsCollectionFromEntitySet<recoveryChangeObject>("recoveryChangeObjects");
80+
//jobs.EntityType.Function("getChanges").ReturnsCollectionViaEntitySetPath<recoveryChangeObject>("getChanges");
81+
//jobs.EntityType.Function("getChanges").ReturnsCollection<recoveryChangeObject>();
82+
83+
return model;
84+
}
85+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
using Microsoft.OData.ModelBuilder;
2+
3+
namespace microsoft.graph;
4+
5+
/// <summary>
6+
/// RecoveryChangeObject as entity
7+
/// </summary>
8+
public class recoveryChangeObject
9+
{
10+
public string id { get; set; }
11+
[AutoExpand]
12+
public object currentState { get; set; }
13+
[AutoExpand]
14+
public object deltaFromCurrent { get; set; }
15+
}
16+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
namespace microsoft.graph;
2+
3+
/// <summary>
4+
/// RecoveryPreviewJob
5+
/// </summary>
6+
public class recoveryPreviewJob
7+
{
8+
public string id { get; set; }
9+
}

sample/DeltaFunctions/Program.cs

+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
using Microsoft.AspNetCore.OData;
2+
using microsoft.graph;
3+
4+
5+
var builder = WebApplication.CreateBuilder(args);
6+
7+
builder.Services.AddControllers().
8+
AddOData(opt => opt.EnableQueryFeatures()
9+
.AddRouteComponents("", GraphModel.Model));
10+
11+
var app = builder.Build();
12+
13+
// Configure the HTTP request pipeline.
14+
15+
app.UseODataRouteDebug();
16+
17+
app.UseAuthorization();
18+
19+
app.MapControllers();
20+
21+
app.Run();
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
{
2+
"$schema": "https://json.schemastore.org/launchsettings.json",
3+
"iisSettings": {
4+
"windowsAuthentication": false,
5+
"anonymousAuthentication": true,
6+
"iisExpress": {
7+
"applicationUrl": "http://localhost:48226",
8+
"sslPort": 0
9+
}
10+
},
11+
"profiles": {
12+
"ODataAlternateKeySample": {
13+
"commandName": "Project",
14+
"dotnetRunMessages": true,
15+
"launchBrowser": true,
16+
"launchUrl": "$odata",
17+
"applicationUrl": "http://localhost:5219",
18+
"environmentVariables": {
19+
"ASPNETCORE_ENVIRONMENT": "Development"
20+
}
21+
},
22+
"IIS Express": {
23+
"commandName": "IISExpress",
24+
"launchBrowser": true,
25+
"launchUrl": "weatherforecast",
26+
"environmentVariables": {
27+
"ASPNETCORE_ENVIRONMENT": "Development"
28+
}
29+
}
30+
}
31+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
{
2+
"Logging": {
3+
"LogLevel": {
4+
"Default": "Information",
5+
"Microsoft.AspNetCore": "Warning"
6+
}
7+
}
8+
}
+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
{
2+
"Logging": {
3+
"LogLevel": {
4+
"Default": "Information",
5+
"Microsoft.AspNetCore": "Warning"
6+
}
7+
},
8+
"AllowedHosts": "*"
9+
}

0 commit comments

Comments
 (0)