CSLA.NET 5.4.2
CSLA .NET is a software development framework that helps you build a reusable, maintainable object-oriented business layer for your app.
GrpcPortal.cs
Go to the documentation of this file.
1//-----------------------------------------------------------------------
2// <copyright file="GrpcPortal.cs" company="Marimer LLC">
3// Copyright (c) Marimer LLC. All rights reserved.
4// Website: https://cslanet.com
5// </copyright>
6// <summary>Exposes server-side DataPortal functionality</summary>
7//-----------------------------------------------------------------------
8using System;
9using System.Collections.Generic;
10using System.IO;
11using System.Security.Principal;
12using System.Text;
13using System.Threading.Tasks;
14using Csla.Core;
17using Csla.Server;
19using Google.Protobuf;
20using Grpc.Core;
21
23{
28 public class GrpcPortal : Csla.Channels.Grpc.GrpcService.GrpcServiceBase
29 {
36 public override async Task<ResponseMessage> Invoke(RequestMessage request, ServerCallContext context)
37 {
38 var operation = request.Operation;
39 if (operation.Contains("/"))
40 {
41 var temp = operation.Split('/');
42 return await RouteMessage(temp[0], temp[1], request);
43 }
44 else
45 {
46 return await InvokePortal(operation, request.Body).ConfigureAwait(false);
47 }
48 }
49
55 protected static Dictionary<string, string> RoutingTagUrls = new Dictionary<string, string>();
56
63 protected virtual async Task<ResponseMessage> RouteMessage(string operation, string routingTag, RequestMessage request)
64 {
65 if (RoutingTagUrls.TryGetValue(routingTag, out string route) && route != "localhost")
66 {
67 var url = $"{route}?operation={operation}";
68 var proxy = new GrpcProxy(url);
69 var clientRequest = new RequestMessage
70 {
71 Body = request.Body,
72 Operation = operation
73 };
74 var clientResponse = await proxy.RouteMessage(clientRequest);
75 return new ResponseMessage { Body = clientResponse.Body };
76 }
77 else
78 {
79 return await InvokePortal(operation, request.Body).ConfigureAwait(false);
80 }
81 }
82
83 private async Task<ResponseMessage> InvokePortal(string operation, ByteString requestData)
84 {
85 var result = new DataPortalResponse();
86 DataPortalErrorInfo errorData = null;
87 try
88 {
89 var request = SerializationFormatterFactory.GetFormatter().Deserialize(requestData.ToByteArray());
90 result = await CallPortal(operation, request);
91 }
92 catch (Exception ex)
93 {
94 errorData = new DataPortalErrorInfo(ex);
95 }
96 var portalResult = new DataPortalResponse { ErrorData = errorData, GlobalContext = result.GlobalContext, ObjectData = result.ObjectData };
97 var buffer = SerializationFormatterFactory.GetFormatter().Serialize(portalResult);
98 return new ResponseMessage { Body = ByteString.CopyFrom(buffer) };
99 }
100
101 private async Task<DataPortalResponse> CallPortal(string operation, object request)
102 {
103 DataPortalResponse result;
104 switch (operation)
105 {
106 case "create":
107 result = await Create((CriteriaRequest)request).ConfigureAwait(false);
108 break;
109
110 case "fetch":
111 result = await Fetch((CriteriaRequest)request).ConfigureAwait(false);
112 break;
113
114 case "update":
115 result = await Update((UpdateRequest)request).ConfigureAwait(false);
116 break;
117
118 case "delete":
119 result = await Delete((CriteriaRequest)request).ConfigureAwait(false);
120 break;
121
122 default:
123 throw new InvalidOperationException(operation);
124 }
125 return result;
126 }
127
132 public async Task<DataPortalResponse> Create(CriteriaRequest request)
133 {
134 var result = new DataPortalResponse();
135 try
136 {
137 request = ConvertRequest(request);
138
139 // unpack criteria data into object
140 object criteria = GetCriteria(request.CriteriaData);
142 {
143 criteria = ((Csla.DataPortalClient.PrimitiveCriteria)criteria).Value;
144 }
145
146 var objectType = Csla.Reflection.MethodCaller.GetType(AssemblyNameTranslator.GetAssemblyQualifiedName(request.TypeName), true);
147 var context = new DataPortalContext(
148 (IPrincipal)SerializationFormatterFactory.GetFormatter().Deserialize(request.Principal),
149 true,
150 request.ClientCulture,
151 request.ClientUICulture,
152 (ContextDictionary)SerializationFormatterFactory.GetFormatter().Deserialize(request.ClientContext),
153 (ContextDictionary)SerializationFormatterFactory.GetFormatter().Deserialize(request.GlobalContext));
154
155 var prtl = new Csla.Server.DataPortal();
156 var dpr = await prtl.Create(objectType, criteria, context, true);
157
158 if (dpr.Error != null)
159 result.ErrorData = new DataPortalErrorInfo(dpr.Error);
160 result.GlobalContext = SerializationFormatterFactory.GetFormatter().Serialize(dpr.GlobalContext);
161 result.ObjectData = SerializationFormatterFactory.GetFormatter().Serialize(dpr.ReturnObject);
162 }
163 catch (Exception ex)
164 {
165 result.ErrorData = new DataPortalErrorInfo(ex);
166 throw;
167 }
168 finally
169 {
170 result = ConvertResponse(result);
171 }
172 return result;
173 }
174
179 public async Task<DataPortalResponse> Fetch(CriteriaRequest request)
180 {
181 var result = new DataPortalResponse();
182 try
183 {
184 request = ConvertRequest(request);
185
186 // unpack criteria data into object
187 object criteria = GetCriteria(request.CriteriaData);
189 {
190 criteria = ((Csla.DataPortalClient.PrimitiveCriteria)criteria).Value;
191 }
192
193 var objectType = Csla.Reflection.MethodCaller.GetType(AssemblyNameTranslator.GetAssemblyQualifiedName(request.TypeName), true);
194 var context = new DataPortalContext(
195 (IPrincipal)SerializationFormatterFactory.GetFormatter().Deserialize(request.Principal),
196 true,
197 request.ClientCulture,
198 request.ClientUICulture,
199 (ContextDictionary)SerializationFormatterFactory.GetFormatter().Deserialize(request.ClientContext),
200 (ContextDictionary)SerializationFormatterFactory.GetFormatter().Deserialize(request.GlobalContext));
201
202 var prtl = new Csla.Server.DataPortal();
203 var dpr = await prtl.Fetch(objectType, criteria, context, true);
204
205 if (dpr.Error != null)
206 result.ErrorData = new DataPortalErrorInfo(dpr.Error);
207 result.GlobalContext = SerializationFormatterFactory.GetFormatter().Serialize(dpr.GlobalContext);
208 result.ObjectData = SerializationFormatterFactory.GetFormatter().Serialize(dpr.ReturnObject);
209 }
210 catch (Exception ex)
211 {
212 result.ErrorData = new DataPortalErrorInfo(ex);
213 throw;
214 }
215 finally
216 {
217 result = ConvertResponse(result);
218 }
219 return result;
220 }
221
226 public async Task<DataPortalResponse> Update(UpdateRequest request)
227 {
228 var result = new DataPortalResponse();
229 try
230 {
231 request = ConvertRequest(request);
232 // unpack object
233 object obj = GetCriteria(request.ObjectData);
234
235 var context = new DataPortalContext(
236 (IPrincipal)SerializationFormatterFactory.GetFormatter().Deserialize(request.Principal),
237 true,
238 request.ClientCulture,
239 request.ClientUICulture,
240 (ContextDictionary)SerializationFormatterFactory.GetFormatter().Deserialize(request.ClientContext),
241 (ContextDictionary)SerializationFormatterFactory.GetFormatter().Deserialize(request.GlobalContext));
242
243 var prtl = new Csla.Server.DataPortal();
244 var dpr = await prtl.Update(obj, context, true);
245
246 if (dpr.Error != null)
247 result.ErrorData = new DataPortalErrorInfo(dpr.Error);
248
249 result.GlobalContext = SerializationFormatterFactory.GetFormatter().Serialize(dpr.GlobalContext);
250 result.ObjectData = SerializationFormatterFactory.GetFormatter().Serialize(dpr.ReturnObject);
251 }
252 catch (Exception ex)
253 {
254 result.ErrorData = new DataPortalErrorInfo(ex);
255 throw;
256 }
257 finally
258 {
259 result = ConvertResponse(result);
260 }
261 return result;
262 }
263
268 public async Task<DataPortalResponse> Delete(CriteriaRequest request)
269 {
270 var result = new DataPortalResponse();
271 try
272 {
273 request = ConvertRequest(request);
274
275 // unpack criteria data into object
276 object criteria = GetCriteria(request.CriteriaData);
278 {
279 criteria = ((Csla.DataPortalClient.PrimitiveCriteria)criteria).Value;
280 }
281
282 var objectType = Csla.Reflection.MethodCaller.GetType(AssemblyNameTranslator.GetAssemblyQualifiedName(request.TypeName), true);
283 var context = new DataPortalContext(
284 (IPrincipal)SerializationFormatterFactory.GetFormatter().Deserialize(request.Principal),
285 true,
286 request.ClientCulture,
287 request.ClientUICulture,
288 (ContextDictionary)SerializationFormatterFactory.GetFormatter().Deserialize(request.ClientContext),
289 (ContextDictionary)SerializationFormatterFactory.GetFormatter().Deserialize(request.GlobalContext));
290
291 var prtl = new Csla.Server.DataPortal();
292 var dpr = await prtl.Delete(objectType, criteria, context, true);
293
294 if (dpr.Error != null)
295 result.ErrorData = new DataPortalErrorInfo(dpr.Error);
296 result.GlobalContext = SerializationFormatterFactory.GetFormatter().Serialize(dpr.GlobalContext);
297 result.ObjectData = SerializationFormatterFactory.GetFormatter().Serialize(dpr.ReturnObject);
298 }
299 catch (Exception ex)
300 {
301 result.ErrorData = new DataPortalErrorInfo(ex);
302 throw;
303 }
304 finally
305 {
306 result = ConvertResponse(result);
307 }
308 return result;
309 }
310
311 #region Criteria
312
313 private static object GetCriteria(byte[] criteriaData)
314 {
315 object criteria = null;
316 if (criteriaData != null)
317 criteria = SerializationFormatterFactory.GetFormatter().Deserialize(criteriaData);
318 return criteria;
319 }
320
321 #endregion Criteria
322
323 #region Extention Method for Requests
324
330 protected virtual UpdateRequest ConvertRequest(UpdateRequest request)
331 {
332 return request;
333 }
334
341 {
342 return request;
343 }
344
351 {
352 return response;
353 }
354
355 #endregion Extention Method for Requests
356 }
357}
Exposes server-side DataPortal functionality through gRPC.
Definition: GrpcPortal.cs:29
async Task< DataPortalResponse > Delete(CriteriaRequest request)
Delete a business object.
Definition: GrpcPortal.cs:268
static Dictionary< string, string > RoutingTagUrls
Gets a dictionary containing the URLs for each data portal route, where each key is the routing tag i...
Definition: GrpcPortal.cs:55
async Task< DataPortalResponse > Create(CriteriaRequest request)
Create and initialize an existing business object.
Definition: GrpcPortal.cs:132
async Task< DataPortalResponse > Fetch(CriteriaRequest request)
Get an existing business object.
Definition: GrpcPortal.cs:179
virtual DataPortalResponse ConvertResponse(DataPortalResponse response)
Override to convert the response data after it comes back from the network.
Definition: GrpcPortal.cs:350
virtual CriteriaRequest ConvertRequest(CriteriaRequest request)
Override to convert the request data before it is transferred over the network.
Definition: GrpcPortal.cs:340
async Task< DataPortalResponse > Update(UpdateRequest request)
Update a business object.
Definition: GrpcPortal.cs:226
override async Task< ResponseMessage > Invoke(RequestMessage request, ServerCallContext context)
Handle inbound message.
Definition: GrpcPortal.cs:36
virtual UpdateRequest ConvertRequest(UpdateRequest request)
Override to convert the request data before it is transferred over the network.
Definition: GrpcPortal.cs:330
virtual async Task< ResponseMessage > RouteMessage(string operation, string routingTag, RequestMessage request)
Entry point for routing tag based data portal operations.
Definition: GrpcPortal.cs:63
Implements a data portal proxy to relay data portal calls to a remote application server by using gRP...
Definition: GrpcProxy.cs:28
Dictionary type that is serializable with the SerializationFormatterFactory.GetFormatter().
Class used as a wrapper for criteria based requests that use primitives
Provides consistent context information between the client and server DataPortal objects.
Implements the server-side DataPortal message router as discussed in Chapter 4.
async Task< DataPortalResult > Fetch(Type objectType, object criteria, DataPortalContext context, bool isSync)
Get an existing business object.
async Task< DataPortalResult > Update(object obj, DataPortalContext context, bool isSync)
Update a business object.
async Task< DataPortalResult > Create(Type objectType, object criteria, DataPortalContext context, bool isSync)
Create a new business object.
async Task< DataPortalResult > Delete(Type objectType, object criteria, DataPortalContext context, bool isSync)
Delete a business object.
byte[] CriteriaData
Serialized data for the criteria object.
string TypeName
Assembly qualified name of the business object type to create.
byte[] GlobalContext
Serialized data for the global context object.
byte[] ClientContext
Serialized data for the client context object.
byte[] Principal
Serialized data for the principal object.
Message containing details about any server-side exception.
Response message for returning the results of a data portal call.
Request message for updating a business object.
byte[] GlobalContext
Serialized data for the global context object.
byte[] ClientContext
Serialized data for the client context object.
byte[] Principal
Serialized data for the principal object.