/// <summary> /// Encapsulate the given XML within a XML SOAP frame. /// </summary> /// <param name="SOAPHeader">A SOAP header.</param> /// <param name="SOAPBody">The internal XML for the SOAP body.</param> /// <param name="XMLNamespaces">An optional delegate to process the XML namespaces.</param> public static XElement Encapsulation(SOAPHeader SOAPHeader, XElement SOAPBody, XMLNamespacesDelegate XMLNamespaces = null) => Encapsulation(SOAPHeader.ChargeBoxIdentity, SOAPHeader.Action, SOAPHeader.MessageId, SOAPHeader.RelatesTo, SOAPHeader.From, SOAPHeader.To, SOAPBody, XMLNamespaces);
/// <summary> /// Encapsulate the given XML within a XML SOAP frame. /// </summary> /// <param name="ChargeBoxIdentity">The unique identification of the charge box.</param> /// <param name="Action">The SOAP action.</param> /// <param name="MessageId">An unique message identification.</param> /// <param name="From">The source URI of the SOAP message.</param> /// <param name="To">The destination URI of the SOAP message.</param> /// <param name="SOAPBody">The internal XML for the SOAP body.</param> /// <param name="XMLNamespaces">An optional delegate to process the XML namespaces.</param> public static XElement Encapsulation(ChargeBox_Id ChargeBoxIdentity, String Action, String MessageId, String From, String To, XElement SOAPBody, XMLNamespacesDelegate XMLNamespaces = null) => Encapsulation(ChargeBoxIdentity, Action, MessageId, null, From, To, SOAPBody, XMLNamespaces);
/// <summary> /// Attach the eMIP+ WebAPI to the given HTTP server. /// </summary> /// <param name="HTTPServer">A HTTP server.</param> /// <param name="URLPathPrefix">An optional prefix for the HTTP URIs.</param> /// <param name="HTTPRealm">The HTTP realm, if HTTP Basic Authentication is used.</param> /// <param name="HTTPLogins">An enumeration of logins for an optional HTTP Basic Authentication.</param> /// /// <param name="XMLNamespaces">An optional delegate to process the XML namespaces.</param> /// <param name="XMLPostProcessing">An optional delegate to process the XML after its final creation.</param> public WebAPI(HTTPServer <RoamingNetworks, RoamingNetwork> HTTPServer, HTTPPath?URLPathPrefix = null, String HTTPRealm = DefaultHTTPRealm, IEnumerable <KeyValuePair <String, String> > HTTPLogins = null, XMLNamespacesDelegate XMLNamespaces = null, XMLPostProcessingDelegate XMLPostProcessing = null, CustomOperatorIdMapperDelegate CustomOperatorIdMapper = null, CustomEVSEIdMapperDelegate CustomEVSEIdMapper = null) { this.HTTPServer = HTTPServer ?? throw new ArgumentNullException(nameof(HTTPServer), "The given HTTP server must not be null!"); this.URLPathPrefix = URLPathPrefix ?? DefaultURLPathPrefix; this.HTTPRealm = HTTPRealm.IsNotNullOrEmpty() ? HTTPRealm : DefaultHTTPRealm; this.HTTPLogins = HTTPLogins ?? new KeyValuePair <String, String> [0]; this.DNSClient = HTTPServer.DNSClient; this.XMLNamespaces = XMLNamespaces; this.XMLPostProcessing = XMLPostProcessing; this.CustomOperatorIdMapper = CustomOperatorIdMapper; this.CustomEVSEIdMapper = CustomEVSEIdMapper; this._CPOAdapters = new List <WWCPCPOAdapter>(); // Link HTTP events... HTTPServer.RequestLog += (HTTPProcessor, ServerTimestamp, Request) => RequestLog.WhenAll(HTTPProcessor, ServerTimestamp, Request); HTTPServer.ResponseLog += (HTTPProcessor, ServerTimestamp, Request, Response) => ResponseLog.WhenAll(HTTPProcessor, ServerTimestamp, Request, Response); HTTPServer.ErrorLog += (HTTPProcessor, ServerTimestamp, Request, Response, Error, LastException) => ErrorLog.WhenAll(HTTPProcessor, ServerTimestamp, Request, Response, Error, LastException); var LogfilePrefix = "HTTPSSEs" + Path.DirectorySeparatorChar; this.DebugLog = HTTPServer.AddJSONEventSource(EventIdentification: DebugLogId, URLTemplate: this.URLPathPrefix + "/DebugLog", MaxNumberOfCachedEvents: 10000, RetryIntervall: TimeSpan.FromSeconds(5), EnableLogging: true, LogfilePrefix: LogfilePrefix); RegisterURITemplates(); }
/// <summary> /// Encapsulate the given XML within a XML SOAP frame. /// </summary> /// <param name="ChargeBoxIdentity">The unique identification of the charge box.</param> /// <param name="Action">The SOAP action.</param> /// <param name="MessageId">An unique message identification.</param> /// <param name="RelatesTo">The unique message identification of the related SOAP request.</param> /// <param name="From">The source URI of the SOAP message.</param> /// <param name="To">The destination URI of the SOAP message.</param> /// <param name="SOAPBody">The internal XML for the SOAP body.</param> /// <param name="XMLNamespaces">An optional delegate to process the XML namespaces.</param> public static XElement Encapsulation(ChargeBox_Id ChargeBoxIdentity, String Action, String MessageId, String RelatesTo, String From, String To, XElement SOAPBody, XMLNamespacesDelegate XMLNamespaces = null) { #region Initial checks if (ChargeBoxIdentity == null) { throw new ArgumentNullException(nameof(ChargeBoxIdentity), "The given charge box identity must not be null!"); } if (Action == null) { throw new ArgumentNullException(nameof(Action), "The given SOAP action must not be null!"); } if (MessageId == null) { throw new ArgumentNullException(nameof(MessageId), "The given SOAP message identification must not be null!"); } if (From == null) { throw new ArgumentNullException(nameof(From), "The given SOAP message source must not be null!"); } if (To == null) { throw new ArgumentNullException(nameof(To), "The given SOAP message destination must not be null!"); } if (SOAPBody == null) { throw new ArgumentNullException(nameof(SOAPBody), "The given XML must not be null!"); } if (XMLNamespaces == null) { XMLNamespaces = xml => xml; } #endregion #region Documentation // <soap:Envelope xmlns:soap = "http://www.w3.org/2003/05/soap-envelope" // xmlns:wsa = "http://www.w3.org/2005/08/addressing" // xmlns:ns = "urn://Ocpp/Cs/2015/10/"> // // <soap:Header> // <ns:chargeBoxIdentity>?</ns:chargeBoxIdentity> // <wsa:Action soap:mustUnderstand="1">/Authorize</wsa:Action> // <wsa:ReplyTo soap:mustUnderstand="1"> // <wsa:Address>http://www.w3.org/2005/08/addressing/anonymous</wsa:Address> // </wsa:ReplyTo> // <wsa:MessageID soap:mustUnderstand="1">uuid:516f7065-074c-4f4a-8b6d-fd3603d88e3d</wsa:MessageID> // <wsa:RelatesTo soap:mustUnderstand="1">uuid:35245423-4545-4454-8454-f45243645672</wsa:MessageID> // <wsa:To soap:mustUnderstand="1">http://127.0.0.1:2010/v1.6</wsa:To> // </soap:Header> // // <soap:Body> // ... // </soap:Body> // // </soap:Envelope> #endregion return(XMLNamespaces( new XElement(SOAPNS.v1_2.NS.SOAPEnvelope + "Envelope", new XAttribute(XNamespace.Xmlns + "SOAP", SOAPNS.v1_2.NS.SOAPEnvelope.NamespaceName), new XAttribute(XNamespace.Xmlns + "CS", OCPPNS.OCPPv1_6_CS.NamespaceName), new XAttribute(XNamespace.Xmlns + "CP", OCPPNS.OCPPv1_6_CP.NamespaceName), new SOAPHeader(ChargeBoxIdentity, Action, MessageId.IsNotNullOrEmpty() ? MessageId : "uuid:" + Guid.NewGuid().ToString(), RelatesTo, From, To).ToXML(), new XElement(SOAPNS.v1_2.NS.SOAPEnvelope + "Body", SOAPBody) ) )); }
/// <summary> /// Convert the given enumeration of EVSE data records to XML. /// </summary> /// <param name="EVSEDataRecords">An enumeration of EVSE data records.</param> /// <param name="RoamingNetwork">The WWCP roaming network.</param> /// <param name="XMLNamespaces">An optional delegate to process the XML namespaces.</param> /// <param name="EVSEDataRecord2XML">An optional delegate to process an EVSE data record XML before sending it somewhere.</param> /// <param name="XMLPostProcessing">An optional delegate to process the XML after its final creation.</param> public static XElement ToXML(this IEnumerable <EVSEDataRecord> EVSEDataRecords, RoamingNetwork RoamingNetwork, XMLNamespacesDelegate XMLNamespaces = null, //EVSEDataRecord2XMLDelegate EVSEDataRecord2XML = null, XMLPostProcessingDelegate XMLPostProcessing = null) { #region Initial checks if (EVSEDataRecords == null) { throw new ArgumentNullException(nameof(EVSEDataRecords), "The given enumeration of EVSE data records must not be null!"); } var _EVSEDataRecords = EVSEDataRecords.ToArray(); //if (EVSEDataRecord2XML == null) // EVSEDataRecord2XML = (evsedatarecord, xml) => xml; if (XMLPostProcessing == null) { XMLPostProcessing = xml => xml; } #endregion return(XMLPostProcessing( SOAP.Encapsulation(new XElement(OICPNS.EVSEData + "eRoamingEvseData", new XElement(OICPNS.EVSEData + "EvseData", _EVSEDataRecords.Any() ? _EVSEDataRecords. ToLookup(evsedatarecord => evsedatarecord.Id.OperatorId). Select(group => group.Any(evsedatarecord => evsedatarecord != null) ? new XElement(OICPNS.EVSEData + "OperatorEvseData", new XElement(OICPNS.EVSEData + "OperatorID", group.Key.ToString()), RoamingNetwork.GetChargingStationOperatorById(group.Key.ToWWCP().Value).Name.Any() ? new XElement(OICPNS.EVSEData + "OperatorName", RoamingNetwork.GetChargingStationOperatorById(group.Key.ToWWCP().Value).Name.FirstText()) : null, new XElement(OICPPlusNS.EVSEOperator + "DataLicenses", RoamingNetwork.GetChargingStationOperatorById(group.Key.ToWWCP().Value).DataLicenses. SafeSelect(license => new XElement(OICPPlusNS.EVSEOperator + "DataLicense", new XElement(OICPPlusNS.EVSEOperator + "Id", license.Id), new XElement(OICPPlusNS.EVSEOperator + "Description", license.Description), license.URIs.Any() ? new XElement(OICPPlusNS.EVSEOperator + "DataLicenseURIs", license.URIs.SafeSelect(uri => new XElement(OICPPlusNS.EVSEOperator + "DataLicenseURI", uri))) : null )) ), // <EvseDataRecord> ... </EvseDataRecord> group.Where(evsedatarecord => evsedatarecord != null). //Select(evsedatarecord => EVSEDataRecord2XML(evsedatarecord, evsedatarecord.ToXML())). ToArray() ) : null ).ToArray() : null ) ), XMLNamespaces))); }
/// <summary> /// Convert the given enumeration of EVSEs into an EVSE status records XML. /// </summary> /// <param name="EVSEs">An enumeration of EVSEs.</param> /// <param name="RoamingNetwork">The WWCP roaming network.</param> /// <param name="XMLNamespaces">An optional delegate to process the XML namespaces.</param> /// <param name="EVSEStatusRecord2XML">An optional delegate to process an EVSE status record XML before sending it somewhere.</param> /// <param name="XMLPostProcessing">An optional delegate to process the XML after its final creation.</param> public static XElement ToXML(this IEnumerable <EVSE> EVSEs, RoamingNetwork RoamingNetwork, XMLNamespacesDelegate XMLNamespaces = null, //EVSEStatusRecord2XMLDelegate EVSEStatusRecord2XML = null, XMLPostProcessingDelegate XMLPostProcessing = null) { #region Initial checks if (EVSEs == null) { throw new ArgumentNullException(nameof(EVSEs), "The given enumeration of EVSEs must not be null!"); } //if (EVSEStatusRecord2XML == null) // EVSEStatusRecord2XML = (evsestatusrecord, xml) => xml; if (XMLPostProcessing == null) { XMLPostProcessing = xml => xml; } #endregion return(XMLPostProcessing( SOAP.Encapsulation(new XElement(OICPNS.EVSEStatus + "eRoamingEvseStatus", new XElement(OICPNS.EVSEStatus + "EvseStatuses", EVSEs.ToLookup(evse => evse.Operator, evse => { try { return WWCP.EVSEStatus.Snapshot(evse).AsOICPEVSEStatus(); } #pragma warning disable RCS1075 // Avoid empty catch clause that catches System.Exception. #pragma warning disable RECS0022 // A catch clause that catches System.Exception and has an empty body catch (Exception) #pragma warning restore RECS0022 // A catch clause that catches System.Exception and has an empty body #pragma warning restore RCS1075 // Avoid empty catch clause that catches System.Exception. { } return null; }). Select(group => group.Any(evsestatusrecord => evsestatusrecord != null) ? new XElement(OICPNS.EVSEStatus + "OperatorEvseStatus", new XElement(OICPNS.EVSEStatus + "OperatorID", group.Key.Id.ToString()), group.Key.Name.Any() ? new XElement(OICPNS.EVSEStatus + "OperatorName", group.Key.Name.FirstText()) : null, new XElement(OICPPlusNS.EVSEOperator + "DataLicenses", group.Key.DataLicenses.SafeSelect(license => new XElement(OICPPlusNS.EVSEOperator + "DataLicense", new XElement(OICPPlusNS.EVSEOperator + "Id", license.Id), new XElement(OICPPlusNS.EVSEOperator + "Description", license.Description), license.URIs.Any() ? new XElement(OICPPlusNS.EVSEOperator + "DataLicenseURIs", license.URIs.SafeSelect(uri => new XElement(OICPPlusNS.EVSEOperator + "DataLicenseURI", uri))) : null )) ), // <EvseStatusRecord> ... </EvseStatusRecord> group.Where(evsestatusrecord => evsestatusrecord != null). //Select(evsestatusrecord => EVSEStatusRecord2XML(evsestatusrecord, evsestatusrecord.ToXML())). ToArray() ) : null ).ToArray() ) ), XMLNamespaces))); }