/// <summary>Validates the input parameters in the session context and applies the implicit parameter values.</summary> /// <remarks>The input parameters object is modified in-place.</remarks> public bool ValidateParameters(BplOperation operation, BplContextNode input) { if (operation == null || input == null || input.Class != operation.Input) return false; if (operation.ImplicitParameters != null) { foreach (var parameter in operation.ImplicitParameters.Where(p => p.ClientRole.Match(ClientRole))) { var property = parameter.Property; var sessionVariable = parameter.SessionVariable; if (sessionVariable == "DriverId" || sessionVariable == "UserId") { if (!_applyImplicitValue(input, property, UserId)) return false; } else if (sessionVariable == "VehicleId") { if (!_applyImplicitValue(input, property, VehicleId)) return false; } else if (sessionVariable == "DeviceId") { if (!_applyImplicitValue(input, property, DeviceId)) return false; } else if (sessionVariable == "BatteryId") { if (!_applyImplicitValue(input, property, BatteryId)) return false; } else if (sessionVariable == "VehicleSN") { if (!_applyImplicitValue(input, property, VehicleSN)) return false; } else if (sessionVariable == "BatterySN") { if (!_applyImplicitValue(input, property, BatterySN)) return false; } else if (sessionVariable == "Operator") { if (!_applyImplicitValue(input, property, Operator)) return false; } else { // unsupported implicit parameter return false; } } } return true; }
public AsyncNodeResult(BplContextNode node, NodeResultFormat format, AsyncCallback callback, object state) { AsyncWaitHandle = new ManualResetEvent(false); AsyncState = state; Request = node; ResultFormat = format; if (node is GeneralFailure) { Log.Warn("Expected general failure {0}", ((GeneralFailure)node).Error); ResponseCode = HttpStatusCode.BadRequest; ResponseResult = node; ((ManualResetEvent)AsyncWaitHandle).Set(); if (callback != null) { callback(this); } IsCompleted = true; } OnResponse = o => { ResponseCode = HttpStatusCode.OK; Log.Info("Operation {0}->{1} completed successfully.", Request, o); if (o != null) { ResponseResult = o; } else { ResponseCode = HttpStatusCode.NoContent; ResponseResult = null; } IsCompleted = true; ((ManualResetEvent)AsyncWaitHandle).Set(); if (callback != null) { callback(this); } }; OnFailure = e => { // TODO: [BK] check and decide on what is HTTP response for timeout // - GeneralFailure.Timeout is translated to GatewayTimeout // - old-style "t" timeout bool was translated to RequestTimeout ResponseCode = (e as GeneralFailure).ToHttpCode(); Log.Warn("Operation {0}->{1} completed with error code: {2}.", Request, e, ResponseCode); // TODO: [BK] it's probably very bad (security) that error content is returned entirely to the client if (e != null) { ResponseResult = e; } else { ResponseCode = HttpStatusCode.NoContent; ResponseResult = null; } IsCompleted = true; ((ManualResetEvent)AsyncWaitHandle).Set(); if (callback != null) { callback(this); } }; //invoke CompletedSynchronously = IsCompleted; }
/// <summary>Determines whether the Id of this entity is equal to the Id of the other entity.</summary> /// <returns>True if the two entities have the same Id.</returns> /// <remarks>See <see cref="M:IdentityEquals(BplEntity,object"/> for an explanation of the Id comparison rules.</remarks> public static bool IdentityEquals(this BplContextNode entity, BplContextNode otherEntity) { if (otherEntity == null) return entity == null; if (otherEntity.IsA<BplEntity>()) { return entity.IdentityEquals(((BplEntity)otherEntity).Id); } else { var idProperty = entity.Class.IdentityProperty; if (idProperty != null) { return IdentityEquals(entity, (BplIdentity)idProperty.GetValue(entity)); } } return IdentityEquals(entity, BplIdentity.Empty); }
private void _handleRegistrationOperation(BplContextNode request, Action<BplContextNode> onSuccess, Action<GeneralFailure> onFailure) { Log.Info("Driver registration: Start"); // 1: check validity of the request if (request is RegisterDriver) { _checkNewDriver((RegisterDriver)request, r => onSuccess(new Value<DriverAuthorizationResult> { result = r }), onFailure); } else if (request is StampRegistrationToken) { _stampToken((StampRegistrationToken)request, r => onSuccess(new Value<string> { result = r }), e => onFailure(new GeneralFailure(e))); } else if (request is ExtractContact) { _extractContactInfo((ExtractContact)request, r => onSuccess(new Value<LoginContact> { result = r }), e => onFailure(new GeneralFailure(e))); } else if (request is ActivateDriver) { var req = (ActivateDriver)request; _resetDriver(req.Token, req.Password, r => onSuccess(new Value<LoginResult> { result = r }), e => onFailure(new GeneralFailure(e))); } else if (request is ResetPassword) { _resetPassword((ResetPassword)request, r => onSuccess(new Value<DriverAuthorizationResult> { result = r }), e => onFailure(new GeneralFailure(e))); } }
// get the orphan tree that contains the given node, if there is such private HashSet<BplContextNode> _getDisconnectedClosure(BplContextNode node) { var root = node; while (root.Parent.IsA<BplContextNode>()) { root = (BplContextNode)root.Parent; } if (root.Parent.IsA<BplContext>()) return null; return root.Select<BplContextNode>(BplRelation.Self | BplRelation.Contained).ToHashSet(); }
// detach all the nodes that may have become unreachable due to the recent changes to the specified node private void _detachFromContext(BplContextNode node) { // taxonomies are never detached from global context if (node is BplTaxonomy) return; // get the disconnected closure of the given node, if there is such var closure = _getDisconnectedClosure(node); // if no disconnected closure exists, then there is nothing to do if (closure == null) { return; } // if the closure is self contained, detach it and return if (Context.IsSelfContained(closure)) { Context.DetachNodes(closure); return; } // if the closure is not self contained, it can still be unreachable - so we must do a full garbage collection. // this is the worst case scenario that can happen when there are inter-associations between multiple orphan closures. Context.GarbageCollect(); }
// attaches a node to the given context private void _attachToContext(BplContextNode node, BplContext context) { // check that the node can and needs to be attached to the context // assumptions: node and context are not null and node.Context != context if (node.Context != null) { _verifyContextCompatibility(node.Context, context); return; } if (context.IsA<BplGlobalContext>() && !node.IsA<BplTaxonomy>()) { return; } // attach node to context, and index/seal it as needed context.AttachNode(node); // recursively attach the node's children foreach (var child in node.Children.Where(child => child.Context != context)) { _attachToContext(child, context); } // recursively attach the node's target associations if (node.HasTargets) { foreach (var target in node.Targets.Where(target => target.Context != context)) { _attachToContext(target, context); } } // recursively attach the node's source associations if (node.HasSources) { foreach (var source in node.Sources.Where(source => BplContext.GetOwner(source) != context)) { if (source.IsA<BplContext>()) { _verifyContextCompatibility((BplContext)source, context); } else { _attachToContext((BplContextNode)source, context); } } } }
/// <summary>OBSOLETE. Invokes BPL service, providing optional callback which is called when response arrives, and an optional failure/timeout handler.</summary> protected void Invoke_OLD(BplContextNode input, Action<BplContextNode> onSuccess, Action<GeneralFailure> onFailure) { ServiceManager.SendServiceRequest(null, input, onSuccess, onFailure); }
/// <summary>Creates a new <see cref="BplItemRemoved"/> instance.</summary> internal BplItemRemoved(BplObject source, BplProperty property, int oldIndex, BplContextNode oldItem) : base(source, property) { OldIndex = oldIndex; OldItem = oldItem; }
/// <summary>Creates a new <see cref="BplItemReplaced"/> instance.</summary> internal BplItemReplaced(BplObject source, BplProperty property, int index, BplContextNode oldItem, BplContextNode newItem) : base(source, property) { Index = index; OldItem = oldItem; NewItem = newItem; }
private static BplContextNode _unwrapMessage(BplContextNode node) { if (node.IsA<OscarRequestWrapper>()) { return ((OscarRequestWrapper)node).Input; } else if (node.IsA<OscarResponseWrapper>()) { return ((OscarResponseWrapper)node).Output; } else if (node.IsA<OscarFailureWrapper>()) { return ((OscarFailureWrapper)node).Error; } return node; }
private static bool _applyImplicitValue(BplContextNode input, BplProperty property, string implicitValue) { var inputValue = property.GetValue(input) as string; if (inputValue == null) { property.SetValue(input, implicitValue); return true; } else { return inputValue == implicitValue; } }
private static bool _applyImplicitValue(BplContextNode input, BplProperty property, Operator implicitValue) { if (property.UnderlyingType.IsA<BplIdentity>()) { return _applyImplicitValue(input, property, implicitValue != null ? implicitValue.Id : BplIdentity.Empty); } var inputValue = property.GetValue(input) as Operator; if (inputValue == null) { property.SetValue(input, implicitValue); return true; } else { return inputValue == implicitValue; } }
private static bool _applyImplicitValue(BplContextNode input, BplProperty property, BplIdentity implicitValue) { var inputValue = (BplIdentity)property.GetValue(input); if (inputValue.IsEmpty) { property.SetValue(input, implicitValue); return true; } else { return inputValue == implicitValue; } }
/// <summary>Creates a new <see cref="BplItemInserted"/> instance.</summary> internal BplItemInserted(BplObject source, BplProperty property, int newIndex, BplContextNode newItem) : base(source, property) { NewIndex = newIndex; NewItem = newItem; }
private bool _isRegistrationOperation(BplContextNode request) { return request is RegisterDriver || request is ResetPassword || request is StampRegistrationToken || request is ExtractContact || request is ActivateDriver; }