예제 #1
0
 /// <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;
 }
예제 #2
0
      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;
      }
예제 #3
0
 /// <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);
 }
예제 #4
0
      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)));
         }
      }
예제 #5
0
 // 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();
 }
예제 #6
0
      // 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();
      }
예제 #7
0
      // 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);
               }
            }
         }
      }
예제 #8
0
 /// <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);
 }
예제 #9
0
 /// <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;
 }
예제 #10
0
 /// <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;
 }
예제 #11
0
 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;
 }
예제 #12
0
 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;
    }
 }
예제 #13
0
 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;
    }
 }
예제 #14
0
 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;
    }
 }
예제 #15
0
 /// <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;
 }
예제 #16
0
 private bool _isRegistrationOperation(BplContextNode request) {
    return request is RegisterDriver || request is ResetPassword || request is StampRegistrationToken || request is ExtractContact || request is ActivateDriver;
 }