/// <summary> /// Execute SDMX Query against the NSI WS to retrieve SDMX-ML Data as a Stream /// </summary> /// <param name="query"> /// The SDMX Query to execute /// </param> /// <param name="operationName"> /// The type of operation, GetCompactData or GetCrossSectionalData /// </param> /// <exception cref="NsiClientException">Failute to execute query</exception> /// <returns> /// The SDMX-ML data as a stream. /// </returns> public void ExecuteQuery(IDataQuery query, SDMXWSFunction operationName, string tempFileName) { if (query == null) { throw new ArgumentNullException("query"); } try { this.SendSdmxQuery(query, operationName, tempFileName); } catch (NsiClientException e) { Logger.Error(Resources.ExceptionExecuteQuery); NsiClientHelper.TryToDelete(tempFileName); Logger.Error(e.Message, e); throw; } catch (DataflowException e) { throw; } catch (Exception e) { Logger.Error(Resources.ExceptionExecuteQuery); NsiClientHelper.TryToDelete(tempFileName); throw new NsiClientException(Resources.ExceptionExecuteQuery, e); } }
/// <summary> /// Gets a bean with data about the key family for specified dataflow. /// </summary> /// <param name="dataflow"> /// The dataflow /// </param> /// <param name="dataStructures"> /// The data Structures. /// </param> /// <returns> /// a <c>StructureBean</c> instance with requested data; the result is never <c>null</c> or incomplete, instead an exception is throwed away if something goes wrong and not all required data is successfully retrieved /// </returns> /// <remarks> /// The resulted bean will contain exactly one key family, but also will include any concepts and codelists referenced by the key family. /// </remarks> public ISdmxObjects GetStructure(IDataflowObject dataflow, ISet <IDataStructureObject> dataStructures) { Logger.InfoFormat( CultureInfo.InvariantCulture, Resources.InfoGettingStructureFormat3, dataflow.AgencyId, dataflow.Id, dataflow.Version); ISdmxObjects structure = new SdmxObjectsImpl(); try { ISdmxObjects responseConceptScheme = new SdmxObjectsImpl(); ISdmxObjects response = new SdmxObjectsImpl(); IStructureQueryFormat <string> structureQueryFormat = new RestQueryFormat(); IStructureQueryFactory factory = new RestStructureQueryFactory(); IStructureQueryBuilderManager structureQueryBuilderManager = new StructureQueryBuilderManager(factory); IDataStructureObject dsd = NsiClientHelper.GetDsdFromDataflow(dataflow, dataStructures); structure.AddDataStructure(dsd); NsiClientValidation.CheckifStructureComplete(structure, dataflow); IEnumerable <IStructureReference> conceptRefs = NsiClientHelper.BuildConceptSchemeRequest(structure.DataStructures.First()); foreach (var structureReference in conceptRefs) { IRestStructureQuery structureQuery = new RESTStructureQueryCore(StructureQueryDetail.GetFromEnum(StructureQueryDetailEnumType.Full), StructureReferenceDetail.GetFromEnum(StructureReferenceDetailEnumType.None), null, structureReference, false); string request = structureQueryBuilderManager.BuildStructureQuery(structureQuery, structureQueryFormat); responseConceptScheme = this.SendQueryStructureRequest(request); response.Merge(responseConceptScheme); } structure.Merge(response); NsiClientValidation.CheckConcepts(structure); Logger.Info(Resources.InfoSuccess); } catch (NsiClientException e) { Logger.Error(Resources.ExceptionGettingStructure); Logger.Error(e.Message, e); throw; } catch (Exception e) { Logger.Error(Resources.ExceptionGettingStructure); Logger.Error(e.Message, e); throw new NsiClientException(Resources.ExceptionGettingStructure, e); } return(structure); }
/// <summary> /// Gets a bean with data about the key family for specified dataflow. /// </summary> /// <param name="dataflow"> /// The dataflow /// </param> /// <returns> /// a <c>StructureBean</c> instance with requested data; the result is never <c>null</c> or incomplete, instead an exception is throwed away if something goes wrong and not all required data is successfully retrieved /// </returns> /// <remarks> /// The resulted bean will contain exactly one key family, but also will include any concepts and codelists referenced by the key family. /// </remarks> public ISdmxObjects GetStructure(IDataflowObject dataflow, ISet <IDataStructureObject> dataStructures) { Logger.InfoFormat( CultureInfo.InvariantCulture, Resources.InfoGettingStructureFormat3, dataflow.AgencyId, dataflow.Id, dataflow.Version); ISdmxObjects structure = new SdmxObjectsImpl(); try { ISdmxObjects responseConceptScheme = new SdmxObjectsImpl(); ISdmxObjects response = new SdmxObjectsImpl(); IDataStructureObject dsd = NsiClientHelper.GetDsdFromDataflow(dataflow, dataStructures); structure.AddDataStructure(dsd); NsiClientValidation.CheckifStructureComplete(structure, dataflow); IEnumerable <IStructureReference> conceptRefs = NsiClientHelper.BuildConceptSchemeRequest(structure.DataStructures.First()); foreach (var structureReference in conceptRefs) { IRestStructureQuery structureQueryConceptScheme = new RESTStructureQueryCore(structureReference); IBuilder <IComplexStructureQuery, IRestStructureQuery> transformerCategoryScheme = new StructureQuery2ComplexQueryBuilder(); IComplexStructureQuery complexStructureQueryConceptScheme = transformerCategoryScheme.Build(structureQueryConceptScheme); responseConceptScheme = this.SendQueryStructureRequest(complexStructureQueryConceptScheme, SDMXWSFunctionV21.GetConceptScheme); response.Merge(responseConceptScheme); } structure.Merge(response); NsiClientValidation.CheckConcepts(structure); Logger.Info(Resources.InfoSuccess); } catch (NsiClientException e) { Logger.Error(Resources.ExceptionGettingStructure); Logger.Error(e.Message, e); throw; } catch (Exception e) { Logger.Error(Resources.ExceptionGettingStructure); Logger.Error(e.Message, e); throw new NsiClientException(Resources.ExceptionGettingStructure, e); } return(structure); }
/// <summary> /// Gets a bean with data about the key family for specified dataflow. /// </summary> /// <param name="dataflow"> /// The dataflow /// </param> /// <returns> /// a <c>StructureBean</c> instance with requested data; the result is never <c>null</c> or incomplete, instead an exception is throwed away if something goes wrong and not all required data is successfully retrieved /// </returns> /// <remarks> /// The resulted bean will contain exactly one key family, but also will include any concepts and codelists referenced by the key family. /// </remarks> public ISdmxObjects GetStructure(IDataflowObject dataflow, ISet <IDataStructureObject> dataStructures) { Logger.InfoFormat( CultureInfo.InvariantCulture, Resources.InfoGettingStructureFormat3, dataflow.AgencyId, dataflow.Id, dataflow.Version); ISdmxObjects structure; var keyFamilyRefBean = new StructureReferenceImpl(SdmxStructureType.GetFromEnum(SdmxStructureEnumType.Dsd)) { MaintainableId = dataflow.DataStructureRef.MaintainableReference.MaintainableId, AgencyId = dataflow.DataStructureRef.MaintainableReference.AgencyId, Version = dataflow.DataStructureRef.MaintainableReference.Version }; try { ISdmxObjects response; structure = this.SendQueryStructureRequest(keyFamilyRefBean, false); NsiClientValidation.CheckifStructureComplete(structure, dataflow); IEnumerable <IStructureReference> conceptRefs = NsiClientHelper.BuildConceptSchemeRequest(structure.DataStructures.First()); response = this.SendQueryStructureRequest(conceptRefs, false); structure.Merge(response); NsiClientValidation.CheckConcepts(structure); Logger.Info(Resources.InfoSuccess); } catch (NsiClientException e) { Logger.Error(Resources.ExceptionGettingStructure); Logger.Error(e.Message, e); throw; } catch (Exception e) { Logger.Error(Resources.ExceptionGettingStructure); Logger.Error(e.Message, e); throw new NsiClientException(Resources.ExceptionGettingStructure, e); } return(structure); }
/// <summary> /// Initializes a new instance of the <see cref="NsiClientWS"/> class. /// </summary> /// <param name="config"> /// The config /// </param> public NsiClientWSV21(WsInfo config) { if (config == null) { throw new ArgumentNullException("config"); } if (string.IsNullOrEmpty(config.EndPoint)) { throw new ArgumentException(Resources.ExceptionEndpointNotSet, "config"); } //getting nsiClientWs WsInfo wsInfo = new WsInfo(config.Config, SdmxSchemaEnumType.VersionTwo); _nsiClientWs = new NsiClientWS(wsInfo); Logger.Info(Resources.InfoCreatingNsiClient); _config = config; Logger.Info(Resources.InfoGetWSDL); try { this._wsdlConfig = new WSDLSettings(config); Logger.Info(Resources.InfoWSDLSuccess); } catch (WebException ex) { throw NsiClientHelper.HandleWsdlException(config.EndPoint, ex, config.Wsdl); } catch (InvalidOperationException ex) { throw NsiClientHelper.HandleWsdlException(config.EndPoint, ex, config.Wsdl); } catch (UriFormatException ex) { throw NsiClientHelper.HandleWsdlException(config.EndPoint, ex, config.Wsdl); } this._defaultHeader = new HeaderImpl("NSIClient", "NSIClient"); Utils.PopulateHeaderFromSettings(this._defaultHeader); }
/// <summary> /// Constructs a SOAP envelope request, with a body that includes the operation as element and the W3C Document and saves the SDMX Part of the response to the specified ouput /// The W3C Document contains either a SDMX-ML Query or a SDMX-ML Registry Interface /// </summary> /// <param name="request"> /// The W3C Document representation of a SDMX-ML Query or QueryStructureRequest /// </param> /// <param name="webServiceOperation"> /// The Web Service function /// </param> /// <param name="tempFileName"> /// The temporary file name /// </param> /// <exception cref="ArgumentNullException"> /// request is null /// </exception> /// <exception cref="NsiClientException"> /// Error in server response or communication /// </exception> private void SendRequest(XmlDocument request, SDMXWSFunctionV21 webServiceOperation, string tempFileName) { if (request == null) { throw new ArgumentNullException("request"); } NsiClientHelper.LogSdmx(_config, request); var sb = new StringBuilder(); sb.AppendFormat(SoapConstants.SoapRequest, this._config.Prefix, this._wsdlConfig.GetTargetNamespace()); var doc = new XmlDocument(); doc.LoadXml(sb.ToString()); string operationName = webServiceOperation.ToString(); XmlNodeList nodes = doc.GetElementsByTagName(SoapConstants.Body, SoapConstants.Soap11Ns); XmlElement operation = doc.CreateElement( this._config.Prefix, operationName, this._wsdlConfig.GetTargetNamespace()); XmlElement queryParent = operation; string parameterName = this._wsdlConfig.GetParameterName(operationName); if (!string.IsNullOrEmpty(parameterName)) { queryParent = doc.CreateElement( this._config.Prefix, parameterName, this._wsdlConfig.GetTargetNamespace()); operation.AppendChild(queryParent); } if (request.DocumentElement != null) { XmlNode sdmxQueryNode = doc.ImportNode(request.DocumentElement, true); queryParent.AppendChild(sdmxQueryNode); } nodes[0].AppendChild(operation); var endpointUri = new Uri(this._config.EndPoint); var webRequest = (HttpWebRequest)WebRequest.Create(endpointUri); webRequest.Headers.Add("Accept-Encoding", "gzip, deflate"); webRequest.AutomaticDecompression = DecompressionMethods.Deflate | DecompressionMethods.GZip; string soapAction = this._wsdlConfig.GetSoapAction(operationName); if (soapAction != null) { webRequest.Headers.Add(SoapConstants.SoapAction, soapAction); } webRequest.ContentType = HttpConstants.Content; // webRequest.Accept = "text/xml"; webRequest.Method = HttpConstants.Post; webRequest.Timeout = 1800 * 1000; // webRequest.CookieContainer = new CookieContainer(); this._config.SetupWebRequestAuth(webRequest); using (Stream stream = webRequest.GetRequestStream()) { doc.Save(stream); } try { using (WebResponse response = webRequest.GetResponse()) { using (Stream stream = response.GetResponseStream()) { if (stream != null) { XmlWriterSettings settings = new XmlWriterSettings(); settings.Indent = true; using (XmlWriter writer = XmlWriter.Create(tempFileName, settings)) { SoapUtils.ExtractSdmxMessage(stream, writer); } NsiClientHelper.LogSdmx(_config, tempFileName, Resources.InfoSoapResponse); } } } } catch (WebException ex) { NsiClientHelper.HandleSoapFault(ex); } }
/// <summary> /// Execute SDMX Query against the NSI WS to retrieve SDMX-ML Data as a Stream /// </summary> /// <param name="query"> /// The SDMX Query to execute /// </param> /// <param name="operationName"> /// The type of operation, GetCompactData or GetCrossSectionalData /// </param> /// <param name="tempFileName"> /// The temporary file name /// </param> /// <exception cref="NsiClientException">Failute to execute query</exception> /// <returns> /// The SDMX-ML data as a stream. /// </returns> public void ExecuteQuery(IDataQuery query, SDMXWSFunction operationName, string tempFileName) { if (query == null) { throw new ArgumentNullException("query"); } try { switch (operationName) { case SDMXWSFunction.GetCompactData: { this.SendSdmxQuery(query, SDMXWSFunctionV21.GetStructureSpecificData, tempFileName); using (var dataLocation = new FileReadableDataLocation(tempFileName)) { var sdmxFooterMessage = SdmxMessageUtilExt.ParseSdmxFooterMessage(dataLocation); if (sdmxFooterMessage != null && (sdmxFooterMessage.Code.Equals("510") || sdmxFooterMessage.Code.Equals("130"))) { var sb = new StringBuilder(); foreach (var footerText in sdmxFooterMessage.FooterText) { sb.Append(footerText.Value + " "); } string info = string.Format(CultureInfo.InvariantCulture, Resources.SdmxFooterMessage, sb, sdmxFooterMessage.Code, sdmxFooterMessage.Severity); Logger.ErrorFormat(CultureInfo.InvariantCulture, Resources.MaxObservations, info); throw new FooterMessageException(Resources.EnterMoreCriteria); } } break; } case SDMXWSFunction.GetCrossSectionalData: { _nsiClientWs.ExecuteQuery(query, operationName, tempFileName); break; } default: { Logger.Error(Resources.ExceptionExecuteQuery); throw new NsiClientException(Resources.ExceptionExecuteQuery); } } } catch (NsiClientException e) { Logger.Error(Resources.ExceptionExecuteQuery); NsiClientHelper.TryToDelete(tempFileName); Logger.Error(e.Message, e); throw; } catch (DataflowException e) { throw; } catch (FooterMessageException e) { NsiClientHelper.TryToDelete(tempFileName); throw; } catch (Exception e) { Logger.Error(Resources.ExceptionExecuteQuery); NsiClientHelper.TryToDelete(tempFileName); throw new NsiClientException(Resources.ExceptionExecuteQuery, e); } }
/// <summary> /// Constructs a SOAP envelope request, with a body that includes the operation as element and the W3C Document and saves the SDMX Part of the response to the specified ouput /// The W3C Document contains either a SDMX-ML Query or a SDMX-ML Registry Interface /// </summary> /// <param name="request"> /// The W3C Document representation of a SDMX-ML Query or QueryStructureRequest /// </param> /// <param name="tempFileName"> /// The temporary file name /// </param> /// <param name="requestType"> /// The request type /// </param> /// <exception cref="ArgumentNullException"> /// request is null /// </exception> /// <exception cref="NsiClientException"> /// Error in server response or communication /// </exception> private void SendRequest(string request, string tempFileName, RequestType requestType) { if (request == null) { throw new ArgumentNullException("request"); } NsiClientHelper.LogSdmx(this._config, request); var endpointUri = new Uri(this._config.EndPoint); try { using (var writer = File.OpenWrite(tempFileName)) { var client = new RestClient(endpointUri.ToString()); var restRequest = new RestRequest(request, Method.GET); restRequest.AddHeader("Accept-Encoding", "gzip, deflate"); if (requestType == RequestType.Data) { restRequest.AddHeader("Accept", "application/vnd.sdmx.structurespecificdata+xml;version=2.1"); if (Logger.IsDebugEnabled) { var buildUri = client.BuildUri(restRequest); Logger.DebugFormat("Requesting URI : {0}", buildUri); } } this._config.SetupRestAuth(client, restRequest); restRequest.Timeout = 1800 * 1000; // the lambda is executed inside the using // ReSharper disable AccessToDisposedClosure restRequest.ResponseWriter = (responseStream) => responseStream.CopyTo(writer); // ReSharper restore AccessToDisposedClosure var response = client.Execute(restRequest); var httpStatusCode = response.StatusCode; var responseStatus = response.ResponseStatus; var responseUri = response.ResponseUri; Logger.DebugFormat("HTTP status {0}, Response Status {1}, ResponseUri {2}", httpStatusCode, responseStatus, responseUri); // we need to check the status if it is OK or not. No exceptions are thrown. if (httpStatusCode == HttpStatusCode.NotFound || httpStatusCode == HttpStatusCode.Unauthorized) { throw new DataflowException(Resources.NoResultsFound); } if (httpStatusCode != HttpStatusCode.OK) { Logger.ErrorFormat("HTTP status {0}, Response Status {1}, ResponseUri {2}", httpStatusCode, responseStatus, responseUri); Logger.ErrorFormat("ContentType {0}, Content Length: \n{1}", response.ContentType, response.ContentLength); throw new NsiClientException(response.StatusDescription); } } NsiClientHelper.LogSdmx(this._config, tempFileName, Resources.InfoSoapResponse); } catch (Exception ex) { Logger.Error(ex.Message, ex); throw; } }