예제 #1
0
        /// <summary>
        /// Call all subscribers in parallel and wait for all to complete.
        /// </summary>
        /// <typeparam name="T">The type of the results.</typeparam>
        /// <param name="ServerTimestamp">The timestamp of the event.</param>
        /// <param name="OCPIAPI">The sending OCPI/HTTP API.</param>
        /// <param name="Request">The incoming request.</param>
        /// <param name="Response">The outgoing response.</param>
        /// <param name="VerifyResult">A delegate to verify and filter results.</param>
        /// <param name="Timeout">A timeout for this operation.</param>
        /// <param name="DefaultResult">A default result in case of errors or a timeout.</param>
        public Task <T> WhenFirst <T>(DateTime ServerTimestamp,
                                      HTTPAPI OCPIAPI,
                                      OCPIRequest Request,
                                      OCPIResponse Response,
                                      Func <T, Boolean> VerifyResult,
                                      TimeSpan?Timeout = null,
                                      Func <TimeSpan, T> DefaultResult = null)
        {
            #region Data

            List <Task> _invocationList;
            Task        WorkDone;
            Task <T>    Result;
            DateTime    StartTime   = DateTime.UtcNow;
            Task        TimeoutTask = null;

            #endregion

            lock (subscribers)
            {
                _invocationList = subscribers.
                                  Select(callback => callback(ServerTimestamp, OCPIAPI, Request, Response)).
                                  ToList();

                if (Timeout.HasValue)
                {
                    _invocationList.Add(TimeoutTask = Task.Run(() => System.Threading.Thread.Sleep(Timeout.Value)));
                }
            }

            do
            {
                try
                {
                    WorkDone = Task.WhenAny(_invocationList);

                    _invocationList.Remove(WorkDone);

                    if (WorkDone != TimeoutTask)
                    {
                        Result = WorkDone as Task <T>;

                        if (Result != null &&
                            !EqualityComparer <T> .Default.Equals(Result.Result, default(T)) &&
                            VerifyResult(Result.Result))
                        {
                            return(Result);
                        }
                    }
                }
                catch (Exception e)
                {
                    DebugX.LogT(e.Message);
                    WorkDone = null;
                }
            }while (!(WorkDone == TimeoutTask || _invocationList.Count == 0));

            return(Task.FromResult(DefaultResult(DateTime.UtcNow - StartTime)));
        }
예제 #2
0
        /// <summary>
        /// Call all subscribers in parallel and wait for all to complete.
        /// </summary>
        /// <param name="ServerTimestamp">The timestamp of the event.</param>
        /// <param name="OCPIAPI">The sending OCPI/HTTP API.</param>
        /// <param name="Request">The incoming request.</param>
        public Task WhenAll(DateTime ServerTimestamp,
                            HTTPAPI OCPIAPI,
                            OCPIRequest Request)
        {
            Task[] _invocationList;

            lock (subscribers)
            {
                _invocationList = subscribers.
                                  Select(callback => callback(ServerTimestamp, OCPIAPI, Request)).
                                  ToArray();
            }

            return(Task.WhenAll(_invocationList));
        }
예제 #3
0
        /// <summary>
        /// Call all subscribers sequentially.
        /// </summary>
        /// <param name="ServerTimestamp">The timestamp of the event.</param>
        /// <param name="OCPIAPI">The sending OCPI/HTTP API.</param>
        /// <param name="Request">The incoming request.</param>
        public async Task InvokeAsync(DateTime ServerTimestamp,
                                      HTTPAPI OCPIAPI,
                                      OCPIRequest Request)
        {
            OCPIRequestLogHandler[] _invocationList;

            lock (subscribers)
            {
                _invocationList = subscribers.ToArray();
            }

            foreach (var callback in _invocationList)
            {
                await callback(ServerTimestamp, OCPIAPI, Request).ConfigureAwait(false);
            }
        }
예제 #4
0
        /// <summary>
        /// Call all subscribers in parallel and wait for any to complete.
        /// </summary>
        /// <param name="ServerTimestamp">The timestamp of the event.</param>
        /// <param name="OCPIAPI">The sending OCPI/HTTP API.</param>
        /// <param name="Request">The incoming request.</param>
        /// <param name="Timeout">A timeout for this operation.</param>
        public Task WhenAny(DateTime ServerTimestamp,
                            HTTPAPI OCPIAPI,
                            OCPIRequest Request,
                            TimeSpan?Timeout = null)
        {
            List <Task> _invocationList;

            lock (subscribers)
            {
                _invocationList = subscribers.
                                  Select(callback => callback(ServerTimestamp, OCPIAPI, Request)).
                                  ToList();

                if (Timeout.HasValue)
                {
                    _invocationList.Add(Task.Delay(Timeout.Value));
                }
            }

            return(Task.WhenAny(_invocationList));
        }
예제 #5
0
        /// <summary>
        /// Add a method callback for the given URL template.
        /// </summary>
        /// <param name="CommonAPI">The OCPI Common API.</param>
        /// <param name="Hostname">The HTTP hostname.</param>
        /// <param name="HTTPMethod">The HTTP method.</param>
        /// <param name="URLTemplate">The URL template.</param>
        /// <param name="HTTPContentType">The HTTP content type.</param>
        /// <param name="URLAuthentication">Whether this method needs explicit uri authentication or not.</param>
        /// <param name="HTTPMethodAuthentication">Whether this method needs explicit HTTP method authentication or not.</param>
        /// <param name="ContentTypeAuthentication">Whether this method needs explicit HTTP content type authentication or not.</param>
        /// <param name="OCPIRequestLogger">A OCPI request logger.</param>
        /// <param name="OCPIResponseLogger">A OCPI response logger.</param>
        /// <param name="DefaultErrorHandler">The default error handler.</param>
        /// <param name="OCPIRequestHandler">The method to call.</param>
        public static void AddOCPIMethod(this CommonAPI CommonAPI,
                                         HTTPHostname Hostname,
                                         HTTPMethod HTTPMethod,
                                         HTTPPath URLTemplate,
                                         HTTPContentType HTTPContentType              = null,
                                         HTTPAuthentication URLAuthentication         = null,
                                         HTTPAuthentication HTTPMethodAuthentication  = null,
                                         HTTPAuthentication ContentTypeAuthentication = null,
                                         OCPIRequestLogHandler OCPIRequestLogger      = null,
                                         OCPIResponseLogHandler OCPIResponseLogger    = null,
                                         HTTPDelegate DefaultErrorHandler             = null,
                                         OCPIRequestDelegate OCPIRequestHandler       = null,
                                         URLReplacement AllowReplacement              = URLReplacement.Fail)

        {
            CommonAPI.HTTPServer.
            AddMethodCallback(Hostname,
                              HTTPMethod,
                              URLTemplate,
                              HTTPContentType,
                              URLAuthentication,
                              HTTPMethodAuthentication,
                              ContentTypeAuthentication,
                              (timestamp, httpAPI, httpRequest) => OCPIRequestLogger?.Invoke(timestamp, null, HTTP.OCPIRequest.Parse(httpRequest, CommonAPI)),
                              (timestamp, httpAPI, httpRequest, httpResponse) => OCPIResponseLogger?.Invoke(timestamp, null, httpRequest.SubprotocolRequest  as OCPIRequest,
                                                                                                            (httpResponse.SubprotocolResponse as OCPIResponse)
                                                                                                            ?? new OCPIResponse(httpRequest.SubprotocolRequest as OCPIRequest,
                                                                                                                                2000,
                                                                                                                                "OCPIResponse is null!",
                                                                                                                                httpResponse.HTTPBodyAsUTF8String,
                                                                                                                                httpResponse.Timestamp,
                                                                                                                                httpResponse)),
                              DefaultErrorHandler,
                              async httpRequest => {
                try
                {
                    // When no OCPIRequestLogger was used!
                    if (httpRequest.SubprotocolRequest is null)
                    {
                        httpRequest.SubprotocolRequest = OCPIRequest.Parse(httpRequest, CommonAPI);
                    }

                    var OCPIResponseBuilder = await OCPIRequestHandler(httpRequest.SubprotocolRequest as OCPIRequest);
                    var httpResponseBuilder = OCPIResponseBuilder.ToHTTPResponseBuilder();

                    httpResponseBuilder.SubprotocolResponse = new OCPIResponse(OCPIResponseBuilder.Request,
                                                                               OCPIResponseBuilder.StatusCode ?? 3000,
                                                                               OCPIResponseBuilder.StatusMessage,
                                                                               OCPIResponseBuilder.AdditionalInformation,
                                                                               OCPIResponseBuilder.Timestamp ?? DateTime.UtcNow,
                                                                               httpResponseBuilder.AsImmutable);

                    return(httpResponseBuilder);
                }
                catch (Exception e)
                {
                    return(new HTTPResponse.Builder(HTTPStatusCode.InternalServerError)
                    {
                        ContentType = HTTPContentType.JSON_UTF8,
                        Content = new OCPIResponse <JObject>(
                            JSONObject.Create(
                                new JProperty("description", e.Message),
                                new JProperty("stacktrace", e.StackTrace.Split(new String[] { Environment.NewLine }, StringSplitOptions.None).ToArray()),
                                new JProperty("source", e.TargetSite.Module.Name),
                                new JProperty("type", e.TargetSite.ReflectedType.Name)
                                ),
                            2000,
                            e.Message,
                            null,
                            DateTime.UtcNow,
                            null,
                            (httpRequest.SubprotocolRequest as OCPIRequest)?.RequestId,
                            (httpRequest.SubprotocolRequest as OCPIRequest)?.CorrelationId
                            ).ToJSON(json => json).ToUTF8Bytes(),
                        Connection = "close"
                    });
                }
            },
                              AllowReplacement);
        }