Example #1
0
        /// <summary>
        /// Create a new SMSAPI HTTP client.
        /// </summary>
        /// <param name="RemoteURL">The remote URL of the OICP HTTP endpoint to connect to.</param>
        /// <param name="VirtualHostname">An optional HTTP virtual hostname.</param>
        /// <param name="Description">An optional description of this CPO client.</param>
        /// <param name="RemoteCertificateValidator">The remote SSL/TLS certificate validator.</param>
        /// <param name="HTTPUserAgent">The HTTP user agent identification.</param>
        /// <param name="BasicAuthentication">An optional HTTP basic authentication.</param>
        /// <param name="Credentials">The default API authentication.</param>
        /// <param name="RequestTimeout">An optional request timeout.</param>
        /// <param name="TransmissionRetryDelay">The delay between transmission retries.</param>
        /// <param name="MaxNumberOfRetries">The maximum number of transmission retries for HTTP request.</param>
        /// <param name="DNSClient">The DNS client to use.</param>
        public SMSAPI(URL?RemoteURL = null,
                      HTTPHostname?VirtualHostname = null,
                      String Description           = null,
                      RemoteCertificateValidationCallback RemoteCertificateValidator = null,
                      String HTTPUserAgent            = DefaultHTTPUserAgent,
                      Credentials BasicAuthentication = null,
                      Credentials Credentials         = null,
                      TimeSpan?RequestTimeout         = null,
                      TransmissionRetryDelayDelegate TransmissionRetryDelay = null,
                      UInt16?MaxNumberOfRetries = DefaultMaxNumberOfRetries,
                      DNSClient DNSClient       = null)

            : base(RemoteURL,
                   VirtualHostname,
                   Description,
                   RemoteCertificateValidator,
                   HTTPUserAgent,
                   BasicAuthentication,
                   Credentials,
                   RequestTimeout,
                   TransmissionRetryDelay,
                   MaxNumberOfRetries,
                   DNSClient)

        {
        }
Example #2
0
        /// <summary>
        /// Create a new SMSAPI HTTP client.
        /// </summary>
        /// <param name="RemoteURL">The remote URL of the OICP HTTP endpoint to connect to.</param>
        /// <param name="VirtualHostname">An optional HTTP virtual hostname.</param>
        /// <param name="Description">An optional description of this CPO client.</param>
        /// <param name="RemoteCertificateValidator">The remote SSL/TLS certificate validator.</param>
        /// <param name="HTTPUserAgent">The HTTP user agent identification.</param>
        /// <param name="BasicAuthentication">An optional HTTP basic authentication.</param>
        /// <param name="Credentials">The default API authentication.</param>
        /// <param name="RequestTimeout">An optional request timeout.</param>
        /// <param name="TransmissionRetryDelay">The delay between transmission retries.</param>
        /// <param name="MaxNumberOfRetries">The maximum number of transmission retries for HTTP request.</param>
        /// <param name="DNSClient">The DNS client to use.</param>
        public SMSAPIClient(URL?RemoteURL = null,
                            HTTPHostname?VirtualHostname = null,
                            String Description           = null,
                            RemoteCertificateValidationCallback RemoteCertificateValidator = null,
                            String HTTPUserAgent            = DefaultHTTPUserAgent,
                            Credentials BasicAuthentication = null,
                            Credentials Credentials         = null,
                            TimeSpan?RequestTimeout         = null,
                            TransmissionRetryDelayDelegate TransmissionRetryDelay = null,
                            UInt16?MaxNumberOfRetries = DefaultMaxNumberOfRetries,
                            DNSClient DNSClient       = null)

            : base(RemoteURL ?? URL.Parse("https://api.smsapi.com/api/"),
                   VirtualHostname,
                   Description,
                   RemoteCertificateValidator,
                   null,
                   null,
                   HTTPUserAgent ?? DefaultHTTPUserAgent,
                   RequestTimeout,
                   TransmissionRetryDelay,
                   MaxNumberOfRetries ?? DefaultMaxNumberOfRetries,
                   false,
                   null,
                   DNSClient)

        {
            this.BasicAuthentication = BasicAuthentication;
            this.Credentials         = Credentials;
        }
Example #3
0
        /// <summary>
        /// Attach JSON I/O to the given WWCP HTTP API.
        /// </summary>
        /// <param name="WWCPAPI">A WWCP HTTP API.</param>
        /// <param name="Hostname">Limit this JSON I/O handling to the given HTTP hostname.</param>
        /// <param name="URIPrefix">A common URI prefix for all URIs within this API.</param>
        public static void Attach_JSON_IO(this WWCP_HTTPAPI WWCPAPI,
                                          HTTPHostname?Hostname = null,
                                          HTTPPath?URIPrefix    = null)
        {
            // /AdminStatus
            // /Status

            WWCPAPI.Attach_JSON_IO_RoamingNetworks(Hostname, URIPrefix);
            WWCPAPI.Attach_JSON_IO_ChargingOperators(Hostname, URIPrefix);
            WWCPAPI.Attach_JSON_IO_ParkingOperators(Hostname, URIPrefix);
            WWCPAPI.Attach_JSON_IO_eMobilityProviders(Hostname, URIPrefix);
            WWCPAPI.Attach_JSON_IO_SmartCities(Hostname, URIPrefix);
            WWCPAPI.Attach_JSON_IO_Reservations(Hostname, URIPrefix);
            WWCPAPI.Attach_JSON_IO_ChargingSessions(Hostname, URIPrefix);
        }
 /// <summary>
 /// Create a new abstract remote charging station operator attached via a computer network (HTTPS/TCP/IP).
 /// </summary>
 /// <param name="Hostname">The remote hostname.</param>
 /// <param name="VirtualHostname">An optional remote virtual hostname.</param>
 /// <param name="RemotePort">An optional remote HTTPS port.</param>
 /// <param name="RemoteCertificateValidator">An optional remote SSL/TLS certificate validator.</param>
 /// <param name="RoamingNetworkId">An optional roaming network identification.</param>
 /// <param name="RequestTimeout">An optional request timeout.</param>
 /// <param name="DNSClient">An optional DNS client to use.</param>
 public ANetworkChargingStationOperator(HTTPHostname Hostname,
                                        HTTPHostname?VirtualHostname = null,
                                        IPPort?RemotePort            = null,
                                        RemoteCertificateValidationCallback RemoteCertificateValidator = null,
                                        RoamingNetwork_Id?RoamingNetworkId = null,
                                        TimeSpan?RequestTimeout            = null,
                                        DNSClient DNSClient = null)
 {
     this.Hostname                   = Hostname;
     this.VirtualHostname            = VirtualHostname ?? this.Hostname;
     this.RemotePort                 = RemotePort ?? DefaultRemotePort;
     this.RemoteCertificateValidator = RemoteCertificateValidator ?? ((sender, certificate, chain, policyErrors) => true);
     this.RoamingNetworkId           = RoamingNetworkId ?? DefaultRoamingNetworkId;
     this.RequestTimeout             = RequestTimeout ?? DefaultRequestTimeout;
     this.DNSClient                  = DNSClient;
 }
        /// <summary>
        /// Attach CSV I/O to the given WWCP HTTP API.
        /// </summary>
        /// <param name="OpenChargingCloudAPI">A WWCP HTTP API.</param>
        /// <param name="Hostname">Limit this CSV I/O handling to the given HTTP hostname.</param>
        /// <param name="URIPrefix">A common URI prefix for all URIs within this API.</param>
        public static void Attach_CSV_IO(this OpenChargingCloudAPI OpenChargingCloudAPI,
                                         HTTPHostname?Hostname = null,
                                         HTTPPath?URIPrefix    = null)
        {
            var _Hostname = Hostname ?? HTTPHostname.Any;

            // /AdminStatus
            // /Status

            //WWCPAPI.Attach_CSV_IO_RoamingNetworks   (Hostname, URIPrefix);
            //WWCPAPI.Attach_CSV_IO_ChargingOperators (Hostname, URIPrefix);
            //WWCPAPI.Attach_CSV_IO_ParkingOperators  (Hostname, URIPrefix);
            //WWCPAPI.Attach_CSV_IO_EMobilityProviders(Hostname, URIPrefix);
            //WWCPAPI.Attach_CSV_IO_SmartCities       (Hostname, URIPrefix);
            //WWCPAPI.Attach_CSV_IO_Reservations      (Hostname, URIPrefix);
            //WWCPAPI.Attach_CSV_IO_ChargingSessions  (Hostname, URIPrefix);
        }
        /// <summary>
        /// Create a new OICP Mobile client.
        /// </summary>
        /// <param name="ClientId">A unqiue identification of this client.</param>
        /// <param name="Hostname">The OICP hostname to connect to.</param>
        /// <param name="RemotePort">An optional OICP TCP port to connect to.</param>
        /// <param name="RemoteCertificateValidator">A delegate to verify the remote TLS certificate.</param>
        /// <param name="ClientCertificateSelector">A delegate to select a TLS client certificate.</param>
        /// <param name="HTTPVirtualHost">An optional HTTP virtual host name to use.</param>
        /// <param name="HTTPUserAgent">An optional HTTP user agent to use.</param>
        /// <param name="RequestTimeout">An optional timeout for upstream queries.</param>
        /// <param name="MaxNumberOfRetries">The default number of maximum transmission retries.</param>
        /// <param name="DNSClient">An optional DNS client.</param>
        /// <param name="LoggingContext">An optional context for logging client methods.</param>
        /// <param name="LogfileCreator">A delegate to create a log file from the given context and log file name.</param>
        public MobileClient(String ClientId,
                            HTTPHostname Hostname,
                            IPPort?RemotePort = null,
                            RemoteCertificateValidationCallback RemoteCertificateValidator = null,
                            LocalCertificateSelectionCallback ClientCertificateSelector    = null,
                            HTTPHostname?HTTPVirtualHost          = null,
                            HTTPPath?URLPrefix                    = null,
                            String MobileAuthorizationURL         = DefaultMobileAuthorizationURL,
                            String HTTPUserAgent                  = DefaultHTTPUserAgent,
                            TimeSpan?RequestTimeout               = null,
                            Byte?MaxNumberOfRetries               = DefaultMaxNumberOfRetries,
                            DNSClient DNSClient                   = null,
                            String LoggingContext                 = MobileClientLogger.DefaultContext,
                            LogfileCreatorDelegate LogfileCreator = null)

            : base(ClientId,
                   Hostname,
                   RemotePort ?? DefaultRemotePort,
                   RemoteCertificateValidator,
                   ClientCertificateSelector,
                   HTTPVirtualHost,
                   URLPrefix ?? DefaultURLPrefix,
                   null,
                   HTTPUserAgent,
                   RequestTimeout,
                   null,
                   MaxNumberOfRetries,
                   DNSClient)

        {
            #region Initial checks

            if (ClientId.IsNullOrEmpty())
            {
                throw new ArgumentNullException(nameof(ClientId), "The given client identification must not be null or empty!");
            }

            #endregion

            this.MobileAuthorizationURL = MobileAuthorizationURL ?? DefaultMobileAuthorizationURL;

            this.Logger = new MobileClientLogger(this,
                                                 LoggingContext,
                                                 LogfileCreator);
        }
Example #7
0
        /// <summary>
        /// Create an instance of the Open Charging Cloud API.
        /// </summary>
        /// <param name="ServiceName">The name of the service.</param>
        /// <param name="HTTPServerName">The default HTTP servername, used whenever no HTTP Host-header had been given.</param>
        /// <param name="LocalHostname">The HTTP hostname for all URIs within this API.</param>
        /// <param name="LocalPort">A TCP port to listen on.</param>
        /// <param name="ExternalDNSName">The offical URL/DNS name of this service, e.g. for sending e-mails.</param>
        /// <param name="URLPathPrefix">A common prefix for all URLs.</param>
        ///
        /// <param name="ServerCertificateSelector">An optional delegate to select a SSL/TLS server certificate.</param>
        /// <param name="ClientCertificateValidator">An optional delegate to verify the SSL/TLS client certificate used for authentication.</param>
        /// <param name="ClientCertificateSelector">An optional delegate to select the SSL/TLS client certificate used for authentication.</param>
        /// <param name="AllowedTLSProtocols">The SSL/TLS protocol(s) allowed for this connection.</param>
        ///
        /// <param name="APIEMailAddress">An e-mail address for this API.</param>
        /// <param name="APIPassphrase">A GPG passphrase for this API.</param>
        /// <param name="APIAdminEMails">A list of admin e-mail addresses.</param>
        /// <param name="APISMTPClient">A SMTP client for sending e-mails.</param>
        ///
        /// <param name="SMSAPICredentials">The credentials for the SMS API.</param>
        /// <param name="SMSSenderName">The (default) SMS sender name.</param>
        /// <param name="APIAdminSMS">A list of admin SMS phonenumbers.</param>
        ///
        /// <param name="TelegramBotToken">The Telegram API access token of the bot.</param>
        ///
        /// <param name="CookieName">The name of the HTTP Cookie for authentication.</param>
        /// <param name="UseSecureCookies">Force the web browser to send cookies only via HTTPS.</param>
        /// <param name="Language">The main language of the API.</param>
        /// <param name="NewUserSignUpEMailCreator">A delegate for sending a sign-up e-mail to a new user.</param>
        /// <param name="NewUserWelcomeEMailCreator">A delegate for sending a welcome e-mail to a new user.</param>
        /// <param name="ResetPasswordEMailCreator">A delegate for sending a reset password e-mail to a user.</param>
        /// <param name="PasswordChangedEMailCreator">A delegate for sending a password changed e-mail to a user.</param>
        /// <param name="MinUserNameLength">The minimal user name length.</param>
        /// <param name="MinRealmLength">The minimal realm length.</param>
        /// <param name="PasswordQualityCheck">A delegate to ensure a minimal password quality.</param>
        /// <param name="SignInSessionLifetime">The sign-in session lifetime.</param>
        ///
        /// <param name="ServerThreadName">The optional name of the TCP server thread.</param>
        /// <param name="ServerThreadPriority">The optional priority of the TCP server thread.</param>
        /// <param name="ServerThreadIsBackground">Whether the TCP server thread is a background thread or not.</param>
        /// <param name="ConnectionIdBuilder">An optional delegate to build a connection identification based on IP socket information.</param>
        /// <param name="ConnectionThreadsNameBuilder">An optional delegate to set the name of the TCP connection threads.</param>
        /// <param name="ConnectionThreadsPriorityBuilder">An optional delegate to set the priority of the TCP connection threads.</param>
        /// <param name="ConnectionThreadsAreBackground">Whether the TCP connection threads are background threads or not (default: yes).</param>
        /// <param name="ConnectionTimeout">The TCP client timeout for all incoming client connections in seconds (default: 30 sec).</param>
        /// <param name="MaxClientConnections">The maximum number of concurrent TCP client connections (default: 4096).</param>
        ///
        /// <param name="SkipURLTemplates">Skip URI templates.</param>
        /// <param name="DisableNotifications">Disable external notifications.</param>
        /// <param name="DisableLogfile">Disable the log file.</param>
        /// <param name="LoggingPath">The path for all logfiles.</param>
        /// <param name="LogfileName">The name of the logfile for this API.</param>
        /// <param name="DNSClient">The DNS client of the API.</param>
        /// <param name="Autostart">Whether to start the API automatically.</param>
        public OpenChargingCloudCSOAPI(String ServiceName         = "GraphDefined Open Charging Cloud CSO API",
                                       String HTTPServerName      = "GraphDefined Open Charging Cloud CSO API",
                                       HTTPHostname?LocalHostname = null,
                                       IPPort?LocalPort           = null,
                                       String ExternalDNSName     = null,
                                       HTTPPath?URLPathPrefix     = null,
                                       String HTMLTemplate        = null,
                                       JObject APIVersionHashes   = null,

                                       ServerCertificateSelectorDelegate ServerCertificateSelector    = null,
                                       RemoteCertificateValidationCallback ClientCertificateValidator = null,
                                       LocalCertificateSelectionCallback ClientCertificateSelector    = null,
                                       SslProtocols AllowedTLSProtocols = SslProtocols.Tls12,

                                       EMailAddress APIEMailAddress    = null,
                                       String APIPassphrase            = null,
                                       EMailAddressList APIAdminEMails = null,
                                       SMTPClient APISMTPClient        = null,

                                       Credentials SMSAPICredentials         = null,
                                       String SMSSenderName                  = null,
                                       IEnumerable <PhoneNumber> APIAdminSMS = null,

                                       String TelegramBotToken = null,

                                       HTTPCookieName?CookieName = null,
                                       Boolean UseSecureCookies  = true,
                                       Languages?Language        = null,
                                       NewUserSignUpEMailCreatorDelegate NewUserSignUpEMailCreator     = null,
                                       NewUserWelcomeEMailCreatorDelegate NewUserWelcomeEMailCreator   = null,
                                       ResetPasswordEMailCreatorDelegate ResetPasswordEMailCreator     = null,
                                       PasswordChangedEMailCreatorDelegate PasswordChangedEMailCreator = null,
                                       Byte?MinLoginLength    = null,
                                       Byte?MinRealmLength    = null,
                                       Byte?MinUserNameLength = null,
                                       PasswordQualityCheckDelegate PasswordQualityCheck = null,
                                       TimeSpan?SignInSessionLifetime = null,

                                       String ServerThreadName                 = null,
                                       ThreadPriority ServerThreadPriority     = ThreadPriority.AboveNormal,
                                       Boolean ServerThreadIsBackground        = true,
                                       ConnectionIdBuilder ConnectionIdBuilder = null,
                                       ConnectionThreadsNameBuilder ConnectionThreadsNameBuilder         = null,
                                       ConnectionThreadsPriorityBuilder ConnectionThreadsPriorityBuilder = null,
                                       Boolean ConnectionThreadsAreBackground = true,
                                       TimeSpan?ConnectionTimeout             = null,
                                       UInt32 MaxClientConnections            = TCPServer.__DefaultMaxClientConnections,

                                       TimeSpan?MaintenanceEvery       = null,
                                       Boolean DisableMaintenanceTasks = false,

                                       Boolean SkipURLTemplates     = false,
                                       Boolean DisableNotifications = false,
                                       Boolean DisableLogfile       = false,
                                       String DatabaseFile          = DefaultOpenChargingCloudAPIDatabaseFile,
                                       String LoggingPath           = null,
                                       String LogfileName           = DefaultOpenChargingCloudAPILogFile,
                                       DNSClient DNSClient          = null,
                                       Boolean Autostart            = false)

            : base(ServiceName ?? "GraphDefined Open Charging Cloud CSO API",
                   HTTPServerName ?? "GraphDefined Open Charging Cloud CSO API",
                   LocalHostname,
                   LocalPort,
                   ExternalDNSName,
                   URLPathPrefix,
                   HTMLTemplate,
                   APIVersionHashes,

                   ServerCertificateSelector,
                   ClientCertificateValidator,
                   ClientCertificateSelector,
                   AllowedTLSProtocols,

                   APIEMailAddress,
                   APIPassphrase,
                   APIAdminEMails,
                   APISMTPClient,

                   SMSAPICredentials,
                   SMSSenderName ?? "Open Charging Cloud",
                   APIAdminSMS,

                   TelegramBotToken,

                   CookieName ?? HTTPCookieName.Parse("OpenChargingCloudCSOAPI"),
                   UseSecureCookies,
                   Language,
                   NewUserSignUpEMailCreator,
                   NewUserWelcomeEMailCreator,
                   ResetPasswordEMailCreator,
                   PasswordChangedEMailCreator,
                   MinLoginLength,
                   MinRealmLength,
                   MinUserNameLength,
                   PasswordQualityCheck,
                   SignInSessionLifetime,

                   ServerThreadName,
                   ServerThreadPriority,
                   ServerThreadIsBackground,
                   ConnectionIdBuilder,
                   ConnectionThreadsNameBuilder,
                   ConnectionThreadsPriorityBuilder,
                   ConnectionThreadsAreBackground,
                   ConnectionTimeout,
                   MaxClientConnections,

                   MaintenanceEvery,
                   DisableMaintenanceTasks,

                   SkipURLTemplates,
                   DisableNotifications,
                   DisableLogfile,
                   DatabaseFile ?? DefaultOpenChargingCloudCSOAPIDatabaseFile,
                   LoggingPath ?? "default",
                   LogfileName ?? DefaultOpenChargingCloudCSOAPILogFile,
                   DNSClient,
                   false)

        {
            //RegisterURLTemplates();

            if (Autostart)
            {
                Start();
            }
        }
Example #8
0
        /// <summary>
        /// Attach JSON I/O to the given WWCP HTTP API.
        /// </summary>
        /// <param name="WWCPAPI">A WWCP HTTP API.</param>
        /// <param name="Hostname">Limit this JSON I/O handling to the given HTTP hostname.</param>
        /// <param name="URIPrefix">A common URI prefix for all URIs within this API.</param>
        public static void Attach_JSON_IO_eMobilityProviders(this WWCP_HTTPAPI WWCPAPI,
                                                             HTTPHostname?Hostname = null,
                                                             HTTPPath?URIPrefix    = null)
        {
            var _Hostname  = Hostname ?? HTTPHostname.Any;
            var _URIPrefix = URIPrefix ?? HTTPPath.Parse("/");

            #region ~/RNs/{RoamingNetworkId}/eMobilityProviders

            #region GET         ~/RNs/{RoamingNetworkId}/eMobilityProviders

            // -----------------------------------------------------------------------------------------
            // curl -v -H "Accept: application/json" http://127.0.0.1:3004/RNs/Test/eMobilityProviders
            // -----------------------------------------------------------------------------------------
            WWCPAPI.HTTPServer.AddMethodCallback(_Hostname,
                                                 HTTPMethod.GET,
                                                 _URIPrefix + "RNs/{RoamingNetworkId}/eMobilityProviders",
                                                 HTTPContentType.JSON_UTF8,
                                                 HTTPDelegate: Request => {
                #region Check parameters

                HTTPResponse _HTTPResponse;
                RoamingNetwork _RoamingNetwork;

                if (!Request.ParseRoamingNetwork(WWCPAPI, out _RoamingNetwork, out _HTTPResponse))
                {
                    return(Task.FromResult(_HTTPResponse));
                }

                #endregion

                var skip   = Request.QueryString.GetUInt64("skip");
                var take   = Request.QueryString.GetUInt64("take");
                var expand = Request.QueryString.GetStrings("expand", true);
                //var expandChargingPools     = !expand.Contains("-chargingpools");
                //var expandChargingStations  = !expand.Contains("-chargingstations");
                //var expandBrands            = expand.Contains("brands");

                //ToDo: Getting the expected total count might be very expensive!
                var _ExpectedCount = _RoamingNetwork.eMobilityProviders.ULongCount();

                return(Task.FromResult(
                           new HTTPResponse.Builder(Request)
                {
                    HTTPStatusCode = HTTPStatusCode.OK,
                    Server = WWCPAPI.HTTPServer.DefaultServerName,
                    Date = DateTime.UtcNow,
                    AccessControlAllowOrigin = "*",
                    AccessControlAllowMethods = "GET, COUNT, STATUS",
                    AccessControlAllowHeaders = "Content-Type, Accept, Authorization",
                    ETag = "1",
                    ContentType = HTTPContentType.JSON_UTF8,
                    Content = _RoamingNetwork.eMobilityProviders.
                              ToJSON(skip,
                                     take,
                                     false).
                              //expandChargingPools,
                              //expandChargingStations,
                              //expandBrands).
                              ToUTF8Bytes(),
                    X_ExpectedTotalNumberOfItems = _ExpectedCount
                }.AsImmutable));
            });

            #endregion

            #region COUNT       ~/RNs/{RoamingNetworkId}/eMobilityProviders

            // ----------------------------------------------------------------------------------------------------------------
            // curl -v -X COUNT -H "Accept: application/json" http://127.0.0.1:3004/RNs/{RoamingNetworkId}/eMobilityProviders
            // ----------------------------------------------------------------------------------------------------------------
            WWCPAPI.HTTPServer.AddMethodCallback(_Hostname,
                                                 HTTPMethod.COUNT,
                                                 _URIPrefix + "RNs/{RoamingNetworkId}/eMobilityProviders",
                                                 HTTPContentType.JSON_UTF8,
                                                 HTTPDelegate: Request => {
                #region Check parameters

                HTTPResponse _HTTPResponse;
                RoamingNetwork _RoamingNetwork;

                if (!Request.ParseRoamingNetwork(WWCPAPI, out _RoamingNetwork, out _HTTPResponse))
                {
                    return(Task.FromResult(_HTTPResponse));
                }

                #endregion

                return(Task.FromResult(
                           new HTTPResponse.Builder(Request)
                {
                    HTTPStatusCode = HTTPStatusCode.OK,
                    Server = WWCPAPI.HTTPServer.DefaultServerName,
                    Date = DateTime.UtcNow,
                    AccessControlAllowOrigin = "*",
                    AccessControlAllowMethods = "GET, COUNT, STATUS",
                    AccessControlAllowHeaders = "Content-Type, Accept, Authorization",
                    ETag = "1",
                    ContentType = HTTPContentType.JSON_UTF8,
                    Content = JSONObject.Create(
                        new JProperty("count", _RoamingNetwork.ChargingStationOperators.ULongCount())
                        ).ToUTF8Bytes()
                }.AsImmutable));
            });

            #endregion

            #region GET         ~/RNs/{RoamingNetworkId}/eMobilityProviders->AdminStatus

            // ------------------------------------------------------------------------------------------------------
            // curl -v -H "Accept: application/json" http://127.0.0.1:3004/RNs/Test/eMobilityProviders->AdminStatus
            // ------------------------------------------------------------------------------------------------------
            WWCPAPI.HTTPServer.AddMethodCallback(_Hostname,
                                                 HTTPMethod.GET,
                                                 _URIPrefix + "RNs/{RoamingNetworkId}/eMobilityProviders->AdminStatus",
                                                 HTTPContentType.JSON_UTF8,
                                                 HTTPDelegate: Request => {
                #region Check parameters

                HTTPResponse _HTTPResponse;
                RoamingNetwork _RoamingNetwork;

                if (!Request.ParseRoamingNetwork(WWCPAPI, out _RoamingNetwork, out _HTTPResponse))
                {
                    return(Task.FromResult(_HTTPResponse));
                }

                #endregion

                var skip        = Request.QueryString.GetUInt64("skip");
                var take        = Request.QueryString.GetUInt64("take");
                var historysize = Request.QueryString.GetUInt64("historysize", 1);

                //ToDo: Getting the expected total count might be very expensive!
                var _ExpectedCount = _RoamingNetwork.ChargingStationOperatorAdminStatus.ULongCount();

                return(Task.FromResult(
                           new HTTPResponse.Builder(Request)
                {
                    HTTPStatusCode = HTTPStatusCode.OK,
                    Server = WWCPAPI.HTTPServer.DefaultServerName,
                    Date = DateTime.UtcNow,
                    AccessControlAllowOrigin = "*",
                    AccessControlAllowMethods = "GET",
                    AccessControlAllowHeaders = "Content-Type, Accept, Authorization",
                    ETag = "1",
                    ContentType = HTTPContentType.JSON_UTF8,
                    Content = _RoamingNetwork.ChargingStationOperatorAdminStatus.
                              OrderBy(kvp => kvp.Key).
                              ToJSON(skip,
                                     take,
                                     historysize).
                              ToUTF8Bytes(),
                    X_ExpectedTotalNumberOfItems = _ExpectedCount
                }.AsImmutable));
            });

            #endregion

            #region GET         ~/RNs/{RoamingNetworkId}/eMobilityProviders->Status

            // -------------------------------------------------------------------------------------------------
            // curl -v -H "Accept: application/json" http://127.0.0.1:3004/RNs/Test/eMobilityProviders->Status
            // -------------------------------------------------------------------------------------------------
            WWCPAPI.HTTPServer.AddMethodCallback(_Hostname,
                                                 HTTPMethod.GET,
                                                 _URIPrefix + "RNs/{RoamingNetworkId}/eMobilityProviders->Status",
                                                 HTTPContentType.JSON_UTF8,
                                                 HTTPDelegate: Request => {
                #region Check parameters

                HTTPResponse _HTTPResponse;
                RoamingNetwork _RoamingNetwork;

                if (!Request.ParseRoamingNetwork(WWCPAPI, out _RoamingNetwork, out _HTTPResponse))
                {
                    return(Task.FromResult(_HTTPResponse));
                }

                #endregion

                var skip        = Request.QueryString.GetUInt64("skip");
                var take        = Request.QueryString.GetUInt64("take");
                var historysize = Request.QueryString.GetUInt64("historysize", 1);

                //ToDo: Getting the expected total count might be very expensive!
                var _ExpectedCount = _RoamingNetwork.ChargingStationOperatorStatus.ULongCount();

                return(Task.FromResult(
                           new HTTPResponse.Builder(Request)
                {
                    HTTPStatusCode = HTTPStatusCode.OK,
                    Server = WWCPAPI.HTTPServer.DefaultServerName,
                    Date = DateTime.UtcNow,
                    AccessControlAllowOrigin = "*",
                    AccessControlAllowMethods = "GET",
                    AccessControlAllowHeaders = "Content-Type, Accept, Authorization",
                    ETag = "1",
                    ContentType = HTTPContentType.JSON_UTF8,
                    Content = _RoamingNetwork.ChargingStationOperatorStatus.
                              OrderBy(kvp => kvp.Key).
                              ToJSON(skip,
                                     take,
                                     historysize).
                              ToUTF8Bytes(),
                    X_ExpectedTotalNumberOfItems = _ExpectedCount
                }.AsImmutable));
            });

            #endregion

            #endregion

            #region ~/RNs/{RoamingNetworkId}/eMobilityProviders/{eMobilityProviderId}

            #region GET         ~/RNs/{RoamingNetworkId}/eMobilityProviders/{eMobilityProviderId}

            WWCPAPI.HTTPServer.AddMethodCallback(_Hostname,
                                                 HTTPMethod.GET,
                                                 _URIPrefix + "RNs/{RoamingNetworkId}/eMobilityProviders/{eMobilityProviderId}",
                                                 HTTPContentType.JSON_UTF8,
                                                 HTTPDelegate: Request => {
                #region Check HTTP parameters

                if (!Request.ParseRoamingNetworkAndEMobilityProvider(WWCPAPI,
                                                                     out RoamingNetwork _RoamingNetwork,
                                                                     out eMobilityProvider _eMobilityProvider,
                                                                     out HTTPResponse _HTTPResponse))
                {
                    return(Task.FromResult(_HTTPResponse));
                }

                #endregion

                return(Task.FromResult(
                           new HTTPResponse.Builder(Request)
                {
                    HTTPStatusCode = HTTPStatusCode.OK,
                    Server = WWCPAPI.HTTPServer.DefaultServerName,
                    Date = DateTime.UtcNow,
                    AccessControlAllowOrigin = "*",
                    AccessControlAllowMethods = "GET, CREATE, DELETE",
                    AccessControlAllowHeaders = "Content-Type, Accept, Authorization",
                    ETag = "1",
                    ContentType = HTTPContentType.JSON_UTF8,
                    Content = _eMobilityProvider.ToJSON().ToUTF8Bytes()
                }.AsImmutable));
            });
        /// <summary>
        /// Create a new OICP roaming client for CPOs.
        /// </summary>
        /// <param name="ClientId">A unqiue identification of this client.</param>
        /// <param name="RemoteHostname">The hostname of the remote OICP service.</param>
        /// <param name="RemoteTCPPort">An optional TCP port of the remote OICP service.</param>
        /// <param name="RemoteCertificateValidator">A delegate to verify the remote TLS certificate.</param>
        /// <param name="ClientCertificateSelector">A delegate to select a TLS client certificate.</param>
        /// <param name="RemoteHTTPVirtualHost">An optional HTTP virtual hostname of the remote OICP service.</param>
        /// <param name="HTTPUserAgent">An optional HTTP user agent identification string for this HTTP client.</param>
        /// <param name="RequestTimeout">An optional timeout for upstream queries.</param>
        /// <param name="MaxNumberOfRetries">The default number of maximum transmission retries.</param>
        ///
        /// <param name="ServerName">An optional identification string for the HTTP server.</param>
        /// <param name="ServiceName">An optional identification for this SOAP service.</param>
        /// <param name="ServerTCPPort">An optional TCP port for the HTTP server.</param>
        /// <param name="ServerURLPrefix">An optional prefix for the HTTP URLs.</param>
        /// <param name="ServerContentType">An optional HTTP content type to use.</param>
        /// <param name="ServerRegisterHTTPRootService">Register HTTP root services for sending a notice to clients connecting via HTML or plain text.</param>
        /// <param name="ServerAutoStart">Whether to start the server immediately or not.</param>
        ///
        /// <param name="ClientLoggingContext">An optional context for logging client methods.</param>
        /// <param name="ServerLoggingContext">An optional context for logging server methods.</param>
        /// <param name="LogfileCreator">A delegate to create a log file from the given context and log file name.</param>
        ///
        /// <param name="DNSClient">An optional DNS client to use.</param>
        public CPORoaming(String ClientId,
                          HTTPHostname RemoteHostname,
                          IPPort?RemoteTCPPort = null,
                          RemoteCertificateValidationCallback RemoteCertificateValidator = null,
                          LocalCertificateSelectionCallback ClientCertificateSelector    = null,
                          HTTPHostname?RemoteHTTPVirtualHost = null,
                          HTTPPath?URLPrefix           = null,
                          String EVSEDataURL           = CPOClient.DefaultEVSEDataURL,
                          String EVSEStatusURL         = CPOClient.DefaultEVSEStatusURL,
                          String AuthorizationURL      = CPOClient.DefaultAuthorizationURL,
                          String AuthenticationDataURL = CPOClient.DefaultAuthenticationDataURL,
                          String HTTPUserAgent         = CPOClient.DefaultHTTPUserAgent,
                          TimeSpan?RequestTimeout      = null,
                          Byte?MaxNumberOfRetries      = CPOClient.DefaultMaxNumberOfRetries,

                          String ServerName                     = CPOSOAPServer.DefaultHTTPServerName,
                          IPPort?ServerTCPPort                  = null,
                          String ServiceName                    = null,
                          HTTPPath?ServerURLPrefix              = null,
                          String ServerAuthorizationURL         = CPOSOAPServer.DefaultAuthorizationURL,
                          String ServerReservationURL           = CPOSOAPServer.DefaultReservationURL,
                          HTTPContentType ServerContentType     = null,
                          Boolean ServerRegisterHTTPRootService = true,
                          Boolean ServerAutoStart               = false,

                          String ClientLoggingContext           = CPOClient.CPOClientLogger.DefaultContext,
                          String ServerLoggingContext           = CPOServerLogger.DefaultContext,
                          LogfileCreatorDelegate LogfileCreator = null,

                          DNSClient DNSClient = null)

            : this(new CPOClient(ClientId,
                                 RemoteHostname,
                                 RemoteTCPPort,
                                 RemoteCertificateValidator,
                                 ClientCertificateSelector,
                                 RemoteHTTPVirtualHost,
                                 URLPrefix ?? CPOClient.DefaultURLPrefix,
                                 EVSEDataURL,
                                 EVSEStatusURL,
                                 AuthorizationURL,
                                 AuthenticationDataURL,
                                 HTTPUserAgent,
                                 RequestTimeout,
                                 MaxNumberOfRetries,
                                 DNSClient,
                                 ClientLoggingContext,
                                 LogfileCreator),

                   new CPOSOAPServer(ServerName,
                                     ServerTCPPort,
                                     ServiceName,
                                     ServerURLPrefix ?? CPOSOAPServer.DefaultURLPathPrefix,
                                     ServerAuthorizationURL,
                                     ServerReservationURL,
                                     ServerContentType,
                                     ServerRegisterHTTPRootService,
                                     DNSClient,
                                     false),

                   ServerLoggingContext,
                   LogfileCreator)

        {
            if (ServerAutoStart)
            {
                Start();
            }
        }
Example #10
0
        /// <summary>
        /// Attach JSON I/O to the given WWCP HTTP API.
        /// </summary>
        /// <param name="WWCPAPI">A WWCP HTTP API.</param>
        /// <param name="Hostname">Limit this JSON I/O handling to the given HTTP hostname.</param>
        /// <param name="URIPrefix">A common URI prefix for all URIs within this API.</param>
        public static void Attach_JSON_IO_Reservations(this WWCP_HTTPAPI WWCPAPI,
                                                       HTTPHostname?Hostname = null,
                                                       HTTPPath?URIPrefix    = null)
        {
            var _Hostname  = Hostname ?? HTTPHostname.Any;
            var _URIPrefix = URIPrefix ?? HTTPPath.Parse("/");

            #region ~/RNs/{RoamingNetworkId}/Reservations

            #region GET         ~/RNs/{RoamingNetworkId}/Reservations

            // ----------------------------------------------------------------------------------
            // curl -v -H "Accept: application/json" http://127.0.0.1:3004/RNs/Test/Reservations
            // ----------------------------------------------------------------------------------
            WWCPAPI.HTTPServer.AddMethodCallback(_Hostname,
                                                 HTTPMethod.GET,
                                                 _URIPrefix + "/RNs/{RoamingNetworkId}/Reservations",
                                                 HTTPContentType.JSON_UTF8,
                                                 HTTPDelegate: async HTTPRequest => {
                #region Check HTTP Basic Authentication

                //if (HTTPRequest.Authorization          == null        ||
                //    HTTPRequest.Authorization.Username != HTTPLogin   ||
                //    HTTPRequest.Authorization.Password != HTTPPassword)
                //    return new HTTPResponse.Builder(HTTPRequest) {
                //        HTTPStatusCode   = HTTPStatusCode.Unauthorized,
                //        WWWAuthenticate  = @"Basic realm=""WWCP EV Charging""",
                //        Server           = _API.HTTPServer.DefaultServerName,
                //        Date             = DateTime.UtcNow,
                //        Connection       = "close"
                //    };

                #endregion

                #region Check parameters

                HTTPResponse _HTTPResponse;
                RoamingNetwork RoamingNetwork;

                if (!HTTPRequest.ParseRoamingNetwork(WWCPAPI, out RoamingNetwork, out _HTTPResponse))
                {
                    return(_HTTPResponse);
                }

                #endregion

                var skip = HTTPRequest.QueryString.GetUInt64("skip");
                var take = HTTPRequest.QueryString.GetUInt32("take");

                var _ChargingReservations = RoamingNetwork.
                                            ChargingReservations.
                                            OrderBy(reservation => reservation.Id.ToString()).
                                            Skip(skip).
                                            Take(take).
                                            ToArray();

                //ToDo: Getting the expected total count might be very expensive!
                var _ExpectedCount = RoamingNetwork.ChargingReservations.LongCount();

                return(new HTTPResponse.Builder(HTTPRequest)
                {
                    HTTPStatusCode = _ChargingReservations.Any()
                                                                                          ? HTTPStatusCode.OK
                                                                                          : HTTPStatusCode.NoContent,
                    Server = WWCPAPI.HTTPServer.DefaultServerName,
                    Date = DateTime.UtcNow,
                    AccessControlAllowOrigin = "*",
                    AccessControlAllowMethods = "GET",
                    AccessControlAllowHeaders = "Content-Type, Accept, Authorization",
                    ETag = "1",
                    ContentType = HTTPContentType.JSON_UTF8,
                    Content = (_ChargingReservations.Any()
                                                                                          ? _ChargingReservations.ToJSON()
                                                                                          : new JArray()
                               ).ToUTF8Bytes()
                }.Set(new HTTPHeaderField("X-ExpectedTotalNumberOfItems", typeof(UInt64), HeaderFieldType.Response, RequestPathSemantic.EndToEnd),
                      _ExpectedCount));
            });

            #endregion

            #endregion

            #region ~/RNs/{RoamingNetworkId}/Reservations/{ReservationId}

            #region GET         ~/RNs/{RoamingNetworkId}/Reservations/{ReservationId}

            // -----------------------------------------------------------------------------------
            // curl -v -H "Accept: application/json" http://127.0.0.1:3004/RNs/Test/Reservations
            // -----------------------------------------------------------------------------------
            WWCPAPI.HTTPServer.AddMethodCallback(_Hostname,
                                                 HTTPMethod.GET,
                                                 _URIPrefix + "RNs/{RoamingNetworkId}/Reservations/{ReservationId}",
                                                 HTTPContentType.JSON_UTF8,
                                                 HTTPDelegate: async HTTPRequest => {
                #region Check HTTP Basic Authentication

                //if (HTTPRequest.Authorization          == null        ||
                //    HTTPRequest.Authorization.Username != HTTPLogin   ||
                //    HTTPRequest.Authorization.Password != HTTPPassword)
                //    return new HTTPResponse.Builder(HTTPRequest) {
                //        HTTPStatusCode   = HTTPStatusCode.Unauthorized,
                //        WWWAuthenticate  = @"Basic realm=""WWCP EV Charging""",
                //        Server           = _API.HTTPServer.DefaultServerName,
                //        Date             = DateTime.UtcNow,
                //        Connection       = "close"
                //    };

                #endregion

                #region Check ChargingReservationId parameter

                HTTPResponse _HTTPResponse;
                RoamingNetwork RoamingNetwork;
                ChargingReservation Reservation;

                if (!HTTPRequest.ParseRoamingNetworkAndReservation(WWCPAPI,
                                                                   out RoamingNetwork,
                                                                   out Reservation,
                                                                   out _HTTPResponse))
                {
                    return(_HTTPResponse);
                }

                #endregion

                return(new HTTPResponse.Builder(HTTPRequest)
                {
                    HTTPStatusCode = HTTPStatusCode.OK,
                    Server = WWCPAPI.HTTPServer.DefaultServerName,
                    Date = DateTime.UtcNow,
                    AccessControlAllowOrigin = "*",
                    AccessControlAllowMethods = "GET, SETEXPIRED, DELETE",
                    AccessControlAllowHeaders = "Content-Type, Accept, Authorization",
                    ETag = "1",
                    ContentType = HTTPContentType.JSON_UTF8,
                    Content = Reservation.ToJSON().ToUTF8Bytes()
                });
            });

            #endregion

            #region SETEXPIRED  ~/RNs/{RoamingNetworkId}/Reservations/{ReservationId}

            // -----------------------------------------------------------------------------------
            // curl -v -H "Accept: application/json" http://127.0.0.1:3004/RNs/Test/Reservations
            // -----------------------------------------------------------------------------------
            WWCPAPI.HTTPServer.AddMethodCallback(_Hostname,
                                                 WWCP_HTTPAPI.SETEXPIRED,
                                                 _URIPrefix + "RNs/{RoamingNetworkId}/Reservations/{ReservationId}",
                                                 HTTPContentType.JSON_UTF8,
                                                 HTTPDelegate: async Request => {
                #region Check HTTP Basic Authentication

                //if (HTTPRequest.Authorization          == null        ||
                //    HTTPRequest.Authorization.Username != HTTPLogin   ||
                //    HTTPRequest.Authorization.Password != HTTPPassword)
                //    return new HTTPResponse.Builder(HTTPRequest) {
                //        HTTPStatusCode   = HTTPStatusCode.Unauthorized,
                //        WWWAuthenticate  = @"Basic realm=""WWCP EV Charging""",
                //        Server           = _API.HTTPServer.DefaultServerName,
                //        Date             = DateTime.UtcNow,
                //        Connection       = "close"
                //    };

                #endregion

                #region Check ChargingReservationId parameter

                HTTPResponse _HTTPResponse;
                RoamingNetwork RoamingNetwork;
                ChargingReservation Reservation;

                if (!Request.ParseRoamingNetworkAndReservation(WWCPAPI,
                                                               out RoamingNetwork,
                                                               out Reservation,
                                                               out _HTTPResponse))
                {
                    return(_HTTPResponse);
                }

                #endregion


                var response = RoamingNetwork.CancelReservation(Reservation.Id,
                                                                ChargingReservationCancellationReason.Deleted,
                                                                //   null, //ToDo: Refacor me to make use of the ProviderId!
                                                                //    null,

                                                                Request.Timestamp,
                                                                Request.CancellationToken,
                                                                Request.EventTrackingId,
                                                                TimeSpan.FromSeconds(60)).Result;

                switch (response.Result)
                {
                case CancelReservationResultTypes.Success:
                    return(new HTTPResponse.Builder(Request)
                    {
                        HTTPStatusCode = HTTPStatusCode.OK,
                        Server = WWCPAPI.HTTPServer.DefaultServerName,
                        Date = DateTime.UtcNow,
                        AccessControlAllowOrigin = "*",
                        AccessControlAllowMethods = "GET, SETEXPIRED, DELETE",
                        AccessControlAllowHeaders = "Content-Type, Accept, Authorization",
                        ContentType = HTTPContentType.JSON_UTF8,
                        Content = JSONObject.Create(new JProperty("en", "Reservation removed. Additional costs may be charged!")).ToUTF8Bytes()
                    });

                default:
                    return(new HTTPResponse.Builder(Request)
                    {
                        HTTPStatusCode = HTTPStatusCode.InternalServerError,
                        Server = WWCPAPI.HTTPServer.DefaultServerName,
                        Date = DateTime.UtcNow,
                        AccessControlAllowOrigin = "*",
                        AccessControlAllowMethods = "GET, DELETE",
                        AccessControlAllowHeaders = "Content-Type, Accept, Authorization",
                        ContentType = HTTPContentType.JSON_UTF8,
                        Content = JSONObject.Create(new JProperty("description", "Could not remove reservation!")).ToUTF8Bytes()
                    });
                }
            });

            #endregion

            #region DELETE      ~/RNs/{RoamingNetworkId}/Reservations/{ReservationId}

            // -----------------------------------------------------------------------------------
            // curl -v -H "Accept: application/json" http://127.0.0.1:3004/RNs/Test/Reservations
            // -----------------------------------------------------------------------------------
            WWCPAPI.HTTPServer.AddMethodCallback(_Hostname,
                                                 HTTPMethod.DELETE,
                                                 _URIPrefix + "RNs/{RoamingNetworkId}/Reservations/{ReservationId}",
                                                 HTTPContentType.JSON_UTF8,
                                                 HTTPDelegate: async Request => {
                #region Check HTTP Basic Authentication

                //if (HTTPRequest.Authorization          == null        ||
                //    HTTPRequest.Authorization.Username != HTTPLogin   ||
                //    HTTPRequest.Authorization.Password != HTTPPassword)
                //    return new HTTPResponse.Builder(HTTPRequest) {
                //        HTTPStatusCode   = HTTPStatusCode.Unauthorized,
                //        WWWAuthenticate  = @"Basic realm=""WWCP EV Charging""",
                //        Server           = _API.HTTPServer.DefaultServerName,
                //        Date             = DateTime.UtcNow,
                //        Connection       = "close"
                //    };

                #endregion

                #region Check ChargingReservationId parameter

                HTTPResponse _HTTPResponse;
                RoamingNetwork RoamingNetwork;
                ChargingReservation Reservation;

                if (!Request.ParseRoamingNetworkAndReservation(WWCPAPI,
                                                               out RoamingNetwork,
                                                               out Reservation,
                                                               out _HTTPResponse))
                {
                    return(_HTTPResponse);
                }

                #endregion


                var response = RoamingNetwork.CancelReservation(Reservation.Id,
                                                                ChargingReservationCancellationReason.Deleted,
                                                                //    null, //ToDo: Refacor me to make use of the ProviderId!
                                                                //    null,

                                                                Request.Timestamp,
                                                                Request.CancellationToken,
                                                                Request.EventTrackingId,
                                                                TimeSpan.FromSeconds(60)).Result;

                switch (response.Result)
                {
                case CancelReservationResultTypes.Success:
                    return(new HTTPResponse.Builder(Request)
                    {
                        HTTPStatusCode = HTTPStatusCode.OK,
                        Server = WWCPAPI.HTTPServer.DefaultServerName,
                        Date = DateTime.UtcNow,
                        AccessControlAllowOrigin = "*",
                        AccessControlAllowMethods = "GET, SETEXPIRED, DELETE",
                        AccessControlAllowHeaders = "Content-Type, Accept, Authorization",
                        ContentType = HTTPContentType.JSON_UTF8,
                        Content = JSONObject.Create(new JProperty("en", "Reservation removed. Additional costs may be charged!")).ToUTF8Bytes()
                    });

                default:
                    return(new HTTPResponse.Builder(Request)
                    {
                        HTTPStatusCode = HTTPStatusCode.InternalServerError,
                        Server = WWCPAPI.HTTPServer.DefaultServerName,
                        Date = DateTime.UtcNow,
                        AccessControlAllowOrigin = "*",
                        AccessControlAllowMethods = "GET, DELETE",
                        AccessControlAllowHeaders = "Content-Type, Accept, Authorization",
                        ContentType = HTTPContentType.JSON_UTF8,
                        Content = JSONObject.Create(new JProperty("description", "Could not remove reservation!")).ToUTF8Bytes()
                    });
                }
            });

            #endregion

            #endregion
        }
Example #11
0
        /// <summary>
        /// Attach JSON I/O to the given WWCP HTTP API.
        /// </summary>
        /// <param name="WWCPAPI">A WWCP HTTP API.</param>
        /// <param name="Hostname">Limit this JSON I/O handling to the given HTTP hostname.</param>
        /// <param name="URIPrefix">A common URI prefix for all URIs within this API.</param>
        public static void Attach_JSON_IO_ChargingSessions(this WWCP_HTTPAPI WWCPAPI,
                                                           HTTPHostname?Hostname = null,
                                                           HTTPPath?URIPrefix    = null)
        {
            var _Hostname  = Hostname ?? HTTPHostname.Any;
            var _URIPrefix = URIPrefix ?? HTTPPath.Parse("/");

            #region ~/RNs/{RoamingNetworkId}/ChargingSessions

            WWCPAPI.HTTPServer.AddMethodCallback(_Hostname,
                                                 HTTPMethod.GET,
                                                 _URIPrefix + "ChargingSessions",
                                                 HTTPContentType.JSON_UTF8,
                                                 HTTPDelegate: async HTTPRequest => {
                #region Check HTTP Basic Authentication

                //if (HTTPRequest.Authorization          == null        ||
                //    HTTPRequest.Authorization.Username != HTTPLogin   ||
                //    HTTPRequest.Authorization.Password != HTTPPassword)
                //    return new HTTPResponse.Builder() {
                //        HTTPStatusCode   = HTTPStatusCode.Unauthorized,
                //        WWWAuthenticate  = @"Basic realm=""Bosch E-Bike""",
                //        Server           = _HTTPServer.DefaultServerName,
                //        Date             = DateTime.UtcNow,
                //        Connection       = "close"
                //    };

                #endregion

                #region Check parameters

                HTTPResponse _HTTPResponse;
                RoamingNetwork RoamingNetwork;

                if (!HTTPRequest.ParseRoamingNetwork(WWCPAPI, out RoamingNetwork, out _HTTPResponse))
                {
                    return(_HTTPResponse);
                }

                #endregion

                var skip = HTTPRequest.QueryString.GetUInt32("skip");
                var take = HTTPRequest.QueryString.GetUInt32("take");

                var _ChargingSessions = RoamingNetwork.
                                        ChargingSessions.
                                        OrderBy(session => session.Id.ToString()).
                                        Skip(skip).
                                        Take(take).
                                        ToArray();

                //ToDo: Getting the expected total count might be very expensive!
                var _ExpectedCount = RoamingNetwork.ChargingSessions.LongCount();


                return(new HTTPResponse.Builder(HTTPRequest)
                {
                    HTTPStatusCode = _ChargingSessions.Any()
                                                                                          ? HTTPStatusCode.OK
                                                                                          : HTTPStatusCode.NoContent,
                    Server = WWCPAPI.HTTPServer.DefaultServerName,
                    Date = DateTime.UtcNow,
                    AccessControlAllowOrigin = "*",
                    AccessControlAllowMethods = "GET",
                    AccessControlAllowHeaders = "Content-Type, Accept, Authorization",
                    ETag = "1",
                    ContentType = HTTPContentType.JSON_UTF8,
                    Content = (_ChargingSessions.Any()
                                                                                          ? _ChargingSessions.ToJSON()
                                                                                          : new JArray()
                               ).ToUTF8Bytes()
                }.Set(new HTTPHeaderField("X-ExpectedTotalNumberOfItems", typeof(UInt64), HeaderFieldType.Response, RequestPathSemantic.EndToEnd),
                      _ExpectedCount));
            });

            #endregion

            #region ~/RNs/{RoamingNetworkId}/ChargeDetailRecords

            #endregion

            #region ~/RNs/{RoamingNetworkId}/ChargeDetailRecords/{ChargingSession_Id}

            #endregion
        }