# HG changeset patch # User Sascha L. Teichmann # Date 1536074005 -7200 # Node ID 5e45f441aed67e3b0461c5c979afa8f1aa8c614a # Parent 4bc27eea4f090f539962907623c1fc681f52c8cd Added SOAP client for the IFBN bottleneck service. Generated by github.com/hooklift/gowsdl from official WSDL (2018-09-03) and edit by hand to resolve some problems. diff -r 4bc27eea4f09 -r 5e45f441aed6 cmd/bottlenecks/main.go --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/cmd/bottlenecks/main.go Tue Sep 04 17:13:25 2018 +0200 @@ -0,0 +1,40 @@ +package main + +import ( + "flag" + "fmt" + "log" + + "gemma.intevation.de/gemma/pkg/soap/ifbn" +) + +func main() { + + url := flag.String("url", "", "the IFBN service") + insecure := flag.Bool("insecure", false, "skip SSL verification") + + flag.Parse() + + client := ifbn.NewIBottleneckService(*url, *insecure, nil) + + req := &ifbn.Export_bn_by_isrs{} + + resp, err := client.Export_bn_by_isrs(req) + if err != nil { + log.Fatalf("error: %v\n", err) + } + + fmt.Printf("%v\n", resp) + + if resp.Export_bn_by_isrsResult == nil { + return + } + bns := resp.Export_bn_by_isrsResult.BottleNeckType + + log.Printf("bottle necks: %d\n", len(bns)) + + for i := range bns { + bn := bns[i] + log.Printf("%s: %s %v\n", bn.Fk_g_fid, bn.OBJNAM, bn.Date_Info) + } +} diff -r 4bc27eea4f09 -r 5e45f441aed6 pkg/soap/ifbn/service.go --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pkg/soap/ifbn/service.go Tue Sep 04 17:13:25 2018 +0200 @@ -0,0 +1,898 @@ +package ifbn + +import ( + "crypto/tls" + "encoding/xml" + "time" + + "gemma.intevation.de/gemma/pkg/soap" +) + +type Export_bn_by_id struct { + XMLName xml.Name `xml:"http://www.ris.eu/bottleneck/3.0 export_bn_by_id"` + + Bottleneck_id *ArrayOfString `xml:"bottleneck_id,omitempty"` + + Period *RequestedPeriod `xml:"period,omitempty"` +} + +type Export_bn_by_idResponse struct { + XMLName xml.Name `xml:"http://www.ris.eu/bottleneck/3.0 export_bn_by_idResponse"` + + Export_bn_by_idResult *ArrayOfBottleNeckType `xml:"export_bn_by_idResult,omitempty"` +} + +type Export_bn_by_isrs struct { + //XMLName xml.Name `xml:"http://www.ris.eu/bottleneck/3.0 export_bn_by_isrs"` + XMLName xml.Name `xml:"http://www.ris.eu/bottleneck/3.0 export_bn_by_isrs"` + + ISRS *ArrayOfISRSPair `xml:"ISRS,omitempty"` + + Period *RequestedPeriod `xml:"period,omitempty"` +} + +type Export_bn_by_isrsResponse struct { + XMLName xml.Name `xml:"http://www.ris.eu/bottleneck/3.0 export_bn_by_isrsResponse"` + + Export_bn_by_isrsResult *ArrayOfBottleNeckType `xml:"export_bn_by_isrsResult,omitempty"` +} + +type ArrayOfBottleNeckType struct { + //XMLName xml.Name `xml:"http://www.ris.eu/bottleneck/3.0 ArrayOfBottleNeckType"` + + BottleNeckType []*BottleNeckType `xml:"BottleNeckType,omitempty"` +} + +type BottleNeckType struct { + //XMLName xml.Name `xml:"http://www.ris.eu/bottleneck/3.0 BottleNeckType"` + + Bottleneck_id string `xml:"bottleneck_id,omitempty"` + + Fk_g_fid string `xml:"fk_g_fid,omitempty"` + + OBJNAM string `xml:"OBJNAM,omitempty"` + + NOBJNM string `xml:"NOBJNM,omitempty"` + + From_ISRS string `xml:"from_ISRS,omitempty"` + + To_ISRS string `xml:"to_ISRS,omitempty"` + + Rb_lb string `xml:"rb_lb,omitempty"` + + Riverbed *ArrayOfMaterial `xml:"riverbed,omitempty"` + + Responsible_country *CountryCode `xml:"responsible_country,omitempty"` + + Revisiting_time string `xml:"revisiting_time,omitempty"` + + SURTYP *SurtypEnum `xml:"SURTYP,omitempty"` + + Coverage *CoverageEnum `xml:"Coverage,omitempty"` + + Limiting_factor *LimitingFactorEnum `xml:"Limiting_factor,omitempty"` + + Depth_reference *DepthReferenceEnum `xml:"Depth_reference,omitempty"` + + Date_Info time.Time `xml:"Date_Info,omitempty"` + + Source string `xml:"Source,omitempty"` + + AdditionalData *ArrayOfKeyValuePair `xml:"AdditionalData,omitempty"` +} + +type ErrorCode string + +const ( + + // Description: message type not supported, Explanation: + // web service does not support the requested message type + // + ErrorCodeE010 ErrorCode = "e010" + + // Description: syntax error in request, Explanation: + // request violates the schema for requests + ErrorCodeE100 ErrorCode = "e100" + + // Description: incorrect message type, Explanation: given + // message type is not known + ErrorCodeE110 ErrorCode = "e110" + + // Description: incorrect type-specific parameters, + // Explanation: type-specific parameters are erroneous + ErrorCodeE120 ErrorCode = "e120" + + // Description: operation not known, Explanation: the + // requested operation is unknown + ErrorCodeE200 ErrorCode = "e200" + + // Description: requested method or operation is not + // implemented + ErrorCodeE210 ErrorCode = "e210" + + // Description: data source unavailable, Explanation: data + // source of the web service for is temporarily unavailable + // + ErrorCodeE300 ErrorCode = "e300" + + // Description: too many results for request, Explanation: + // server is unable to handle number of results + ErrorCodeE310 ErrorCode = "e310" + + // Description: unexpected or other error + // + ErrorCodeE999 ErrorCode = "e999" +) + +type CountryCode string + +const ( + CountryCodeAF CountryCode = "AF" + + CountryCodeAX CountryCode = "AX" + + CountryCodeAL CountryCode = "AL" + + CountryCodeDZ CountryCode = "DZ" + + CountryCodeAS CountryCode = "AS" + + CountryCodeAD CountryCode = "AD" + + CountryCodeAO CountryCode = "AO" + + CountryCodeAI CountryCode = "AI" + + CountryCodeAQ CountryCode = "AQ" + + CountryCodeAG CountryCode = "AG" + + CountryCodeAR CountryCode = "AR" + + CountryCodeAM CountryCode = "AM" + + CountryCodeAW CountryCode = "AW" + + CountryCodeAU CountryCode = "AU" + + CountryCodeAT CountryCode = "AT" + + CountryCodeAZ CountryCode = "AZ" + + CountryCodeBS CountryCode = "BS" + + CountryCodeBH CountryCode = "BH" + + CountryCodeBD CountryCode = "BD" + + CountryCodeBB CountryCode = "BB" + + CountryCodeBY CountryCode = "BY" + + CountryCodeBE CountryCode = "BE" + + CountryCodeBZ CountryCode = "BZ" + + CountryCodeBJ CountryCode = "BJ" + + CountryCodeBM CountryCode = "BM" + + CountryCodeBT CountryCode = "BT" + + CountryCodeBO CountryCode = "BO" + + CountryCodeBQ CountryCode = "BQ" + + CountryCodeBA CountryCode = "BA" + + CountryCodeBW CountryCode = "BW" + + CountryCodeBV CountryCode = "BV" + + CountryCodeBR CountryCode = "BR" + + CountryCodeIO CountryCode = "IO" + + CountryCodeBN CountryCode = "BN" + + CountryCodeBG CountryCode = "BG" + + CountryCodeBF CountryCode = "BF" + + CountryCodeBI CountryCode = "BI" + + CountryCodeCV CountryCode = "CV" + + CountryCodeKH CountryCode = "KH" + + CountryCodeCM CountryCode = "CM" + + CountryCodeCA CountryCode = "CA" + + CountryCodeKY CountryCode = "KY" + + CountryCodeCF CountryCode = "CF" + + CountryCodeTD CountryCode = "TD" + + CountryCodeCL CountryCode = "CL" + + CountryCodeCN CountryCode = "CN" + + CountryCodeCX CountryCode = "CX" + + CountryCodeCC CountryCode = "CC" + + CountryCodeCO CountryCode = "CO" + + CountryCodeKM CountryCode = "KM" + + CountryCodeCG CountryCode = "CG" + + CountryCodeCD CountryCode = "CD" + + CountryCodeCK CountryCode = "CK" + + CountryCodeCR CountryCode = "CR" + + CountryCodeCI CountryCode = "CI" + + CountryCodeHR CountryCode = "HR" + + CountryCodeCU CountryCode = "CU" + + CountryCodeCW CountryCode = "CW" + + CountryCodeCY CountryCode = "CY" + + CountryCodeCZ CountryCode = "CZ" + + CountryCodeDK CountryCode = "DK" + + CountryCodeDJ CountryCode = "DJ" + + CountryCodeDM CountryCode = "DM" + + CountryCodeDO CountryCode = "DO" + + CountryCodeEC CountryCode = "EC" + + CountryCodeEG CountryCode = "EG" + + CountryCodeSV CountryCode = "SV" + + CountryCodeGQ CountryCode = "GQ" + + CountryCodeER CountryCode = "ER" + + CountryCodeEE CountryCode = "EE" + + CountryCodeET CountryCode = "ET" + + CountryCodeFK CountryCode = "FK" + + CountryCodeFO CountryCode = "FO" + + CountryCodeFJ CountryCode = "FJ" + + CountryCodeFI CountryCode = "FI" + + CountryCodeFR CountryCode = "FR" + + CountryCodeGF CountryCode = "GF" + + CountryCodePF CountryCode = "PF" + + CountryCodeTF CountryCode = "TF" + + CountryCodeGA CountryCode = "GA" + + CountryCodeGM CountryCode = "GM" + + CountryCodeGE CountryCode = "GE" + + CountryCodeDE CountryCode = "DE" + + CountryCodeGH CountryCode = "GH" + + CountryCodeGI CountryCode = "GI" + + CountryCodeGR CountryCode = "GR" + + CountryCodeGL CountryCode = "GL" + + CountryCodeGD CountryCode = "GD" + + CountryCodeGP CountryCode = "GP" + + CountryCodeGU CountryCode = "GU" + + CountryCodeGT CountryCode = "GT" + + CountryCodeGG CountryCode = "GG" + + CountryCodeGN CountryCode = "GN" + + CountryCodeGW CountryCode = "GW" + + CountryCodeGY CountryCode = "GY" + + CountryCodeHT CountryCode = "HT" + + CountryCodeHM CountryCode = "HM" + + CountryCodeVA CountryCode = "VA" + + CountryCodeHN CountryCode = "HN" + + CountryCodeHK CountryCode = "HK" + + CountryCodeHU CountryCode = "HU" + + CountryCodeIS CountryCode = "IS" + + CountryCodeIN CountryCode = "IN" + + CountryCodeID CountryCode = "ID" + + CountryCodeIR CountryCode = "IR" + + CountryCodeIQ CountryCode = "IQ" + + CountryCodeIE CountryCode = "IE" + + CountryCodeIM CountryCode = "IM" + + CountryCodeIL CountryCode = "IL" + + CountryCodeIT CountryCode = "IT" + + CountryCodeJM CountryCode = "JM" + + CountryCodeJP CountryCode = "JP" + + CountryCodeJE CountryCode = "JE" + + CountryCodeJO CountryCode = "JO" + + CountryCodeKZ CountryCode = "KZ" + + CountryCodeKE CountryCode = "KE" + + CountryCodeKI CountryCode = "KI" + + CountryCodeKP CountryCode = "KP" + + CountryCodeKR CountryCode = "KR" + + CountryCodeKW CountryCode = "KW" + + CountryCodeKG CountryCode = "KG" + + CountryCodeLA CountryCode = "LA" + + CountryCodeLV CountryCode = "LV" + + CountryCodeLB CountryCode = "LB" + + CountryCodeLS CountryCode = "LS" + + CountryCodeLR CountryCode = "LR" + + CountryCodeLY CountryCode = "LY" + + CountryCodeLI CountryCode = "LI" + + CountryCodeLT CountryCode = "LT" + + CountryCodeLU CountryCode = "LU" + + CountryCodeMO CountryCode = "MO" + + CountryCodeMK CountryCode = "MK" + + CountryCodeMG CountryCode = "MG" + + CountryCodeMW CountryCode = "MW" + + CountryCodeMY CountryCode = "MY" + + CountryCodeMV CountryCode = "MV" + + CountryCodeML CountryCode = "ML" + + CountryCodeMT CountryCode = "MT" + + CountryCodeMH CountryCode = "MH" + + CountryCodeMQ CountryCode = "MQ" + + CountryCodeMR CountryCode = "MR" + + CountryCodeMU CountryCode = "MU" + + CountryCodeYT CountryCode = "YT" + + CountryCodeMX CountryCode = "MX" + + CountryCodeFM CountryCode = "FM" + + CountryCodeMD CountryCode = "MD" + + CountryCodeMC CountryCode = "MC" + + CountryCodeMN CountryCode = "MN" + + CountryCodeME CountryCode = "ME" + + CountryCodeMS CountryCode = "MS" + + CountryCodeMA CountryCode = "MA" + + CountryCodeMZ CountryCode = "MZ" + + CountryCodeMM CountryCode = "MM" + + CountryCodeNA CountryCode = "NA" + + CountryCodeNR CountryCode = "NR" + + CountryCodeNP CountryCode = "NP" + + CountryCodeNL CountryCode = "NL" + + CountryCodeNC CountryCode = "NC" + + CountryCodeNZ CountryCode = "NZ" + + CountryCodeNI CountryCode = "NI" + + CountryCodeNE CountryCode = "NE" + + CountryCodeNG CountryCode = "NG" + + CountryCodeNU CountryCode = "NU" + + CountryCodeNF CountryCode = "NF" + + CountryCodeMP CountryCode = "MP" + + CountryCodeNO CountryCode = "NO" + + CountryCodeOM CountryCode = "OM" + + CountryCodePK CountryCode = "PK" + + CountryCodePW CountryCode = "PW" + + CountryCodePS CountryCode = "PS" + + CountryCodePA CountryCode = "PA" + + CountryCodePG CountryCode = "PG" + + CountryCodePY CountryCode = "PY" + + CountryCodePE CountryCode = "PE" + + CountryCodePH CountryCode = "PH" + + CountryCodePN CountryCode = "PN" + + CountryCodePL CountryCode = "PL" + + CountryCodePT CountryCode = "PT" + + CountryCodePR CountryCode = "PR" + + CountryCodeQA CountryCode = "QA" + + CountryCodeRE CountryCode = "RE" + + CountryCodeRO CountryCode = "RO" + + CountryCodeRU CountryCode = "RU" + + CountryCodeRW CountryCode = "RW" + + CountryCodeBL CountryCode = "BL" + + CountryCodeSH CountryCode = "SH" + + CountryCodeKN CountryCode = "KN" + + CountryCodeLC CountryCode = "LC" + + CountryCodeMF CountryCode = "MF" + + CountryCodePM CountryCode = "PM" + + CountryCodeVC CountryCode = "VC" + + CountryCodeWS CountryCode = "WS" + + CountryCodeSM CountryCode = "SM" + + CountryCodeST CountryCode = "ST" + + CountryCodeSA CountryCode = "SA" + + CountryCodeSN CountryCode = "SN" + + CountryCodeRS CountryCode = "RS" + + CountryCodeSC CountryCode = "SC" + + CountryCodeSL CountryCode = "SL" + + CountryCodeSG CountryCode = "SG" + + CountryCodeSX CountryCode = "SX" + + CountryCodeSK CountryCode = "SK" + + CountryCodeSI CountryCode = "SI" + + CountryCodeSB CountryCode = "SB" + + CountryCodeSO CountryCode = "SO" + + CountryCodeZA CountryCode = "ZA" + + CountryCodeGS CountryCode = "GS" + + CountryCodeSS CountryCode = "SS" + + CountryCodeES CountryCode = "ES" + + CountryCodeLK CountryCode = "LK" + + CountryCodeSD CountryCode = "SD" + + CountryCodeSR CountryCode = "SR" + + CountryCodeSJ CountryCode = "SJ" + + CountryCodeSZ CountryCode = "SZ" + + CountryCodeSE CountryCode = "SE" + + CountryCodeCH CountryCode = "CH" + + CountryCodeSY CountryCode = "SY" + + CountryCodeTW CountryCode = "TW" + + CountryCodeTJ CountryCode = "TJ" + + CountryCodeTZ CountryCode = "TZ" + + CountryCodeTH CountryCode = "TH" + + CountryCodeTL CountryCode = "TL" + + CountryCodeTG CountryCode = "TG" + + CountryCodeTK CountryCode = "TK" + + CountryCodeTO CountryCode = "TO" + + CountryCodeTT CountryCode = "TT" + + CountryCodeTN CountryCode = "TN" + + CountryCodeTR CountryCode = "TR" + + CountryCodeTM CountryCode = "TM" + + CountryCodeTC CountryCode = "TC" + + CountryCodeTV CountryCode = "TV" + + CountryCodeUG CountryCode = "UG" + + CountryCodeUA CountryCode = "UA" + + CountryCodeAE CountryCode = "AE" + + CountryCodeGB CountryCode = "GB" + + CountryCodeUS CountryCode = "US" + + CountryCodeUM CountryCode = "UM" + + CountryCodeUY CountryCode = "UY" + + CountryCodeUZ CountryCode = "UZ" + + CountryCodeVU CountryCode = "VU" + + CountryCodeVE CountryCode = "VE" + + CountryCodeVN CountryCode = "VN" + + CountryCodeVG CountryCode = "VG" + + CountryCodeVI CountryCode = "VI" + + CountryCodeWF CountryCode = "WF" + + CountryCodeEH CountryCode = "EH" + + CountryCodeYE CountryCode = "YE" + + CountryCodeZM CountryCode = "ZM" + + CountryCodeZW CountryCode = "ZW" +) + +type CoverageEnum string + +const ( + CoverageEnumCrossProfiles CoverageEnum = "CrossProfiles" + + CoverageEnumLongitudinalProfiles CoverageEnum = "LongitudinalProfiles" + + CoverageEnumFairway CoverageEnum = "Fairway" + + CoverageEnumRiver CoverageEnum = "River" + + CoverageEnumRiverBanks CoverageEnum = "RiverBanks" +) + +type DepthReferenceEnum string + +const ( + DepthReferenceEnumNAP DepthReferenceEnum = "NAP" + + DepthReferenceEnumKP DepthReferenceEnum = "KP" + + DepthReferenceEnumFZP DepthReferenceEnum = "FZP" + + DepthReferenceEnumADR DepthReferenceEnum = "ADR" + + DepthReferenceEnumTAW DepthReferenceEnum = "TAW" + + DepthReferenceEnumPUL DepthReferenceEnum = "PUL" + + DepthReferenceEnumNGM DepthReferenceEnum = "NGM" + + DepthReferenceEnumETRS DepthReferenceEnum = "ETRS" + + DepthReferenceEnumPOT DepthReferenceEnum = "POT" + + DepthReferenceEnumLDC DepthReferenceEnum = "LDC" + + DepthReferenceEnumHDC DepthReferenceEnum = "HDC" + + DepthReferenceEnumZPG DepthReferenceEnum = "ZPG" + + DepthReferenceEnumGLW DepthReferenceEnum = "GLW" + + DepthReferenceEnumHSW DepthReferenceEnum = "HSW" + + DepthReferenceEnumLNW DepthReferenceEnum = "LNW" + + DepthReferenceEnumHNW DepthReferenceEnum = "HNW" + + DepthReferenceEnumIGN DepthReferenceEnum = "IGN" + + DepthReferenceEnumWGS DepthReferenceEnum = "WGS" + + DepthReferenceEnumRN DepthReferenceEnum = "RN" + + DepthReferenceEnumHBO DepthReferenceEnum = "HBO" +) + +type LimitingFactorEnum string + +const ( + LimitingFactorEnumDepth LimitingFactorEnum = "depth" + + LimitingFactorEnumWidth LimitingFactorEnum = "width" + + LimitingFactorEnumCurveRadius LimitingFactorEnum = "curveRadius" +) + +type LosEnum string + +const ( + LosEnumNotAvailable LosEnum = "NotAvailable" + + LosEnumLOS1 LosEnum = "LOS1" + + LosEnumLOS2 LosEnum = "LOS2" + + LosEnumLOS3 LosEnum = "LOS3" +) + +type MaterialEnum string + +const ( + MaterialEnumGravel MaterialEnum = "Gravel" + + MaterialEnumRocky MaterialEnum = "Rocky" + + MaterialEnumStone MaterialEnum = "Stone" + + MaterialEnumAndesite MaterialEnum = "Andesite" + + MaterialEnumSleazyAndesite MaterialEnum = "SleazyAndesite" + + MaterialEnumSandyGravel MaterialEnum = "SandyGravel" + + MaterialEnumMarl MaterialEnum = "Marl" + + MaterialEnumSand MaterialEnum = "Sand" + + MaterialEnumSarmatianLimestone MaterialEnum = "SarmatianLimestone" + + MaterialEnumSandstonePeaks MaterialEnum = "SandstonePeaks" + + MaterialEnumRoughSandyGravel MaterialEnum = "RoughSandyGravel" +) + +type MeasureType string + +const ( + MeasureTypeMeasured MeasureType = "Measured" + + MeasureTypeForecasted MeasureType = "Forecasted" + + MeasureTypeMinimumGuaranteed MeasureType = "MinimumGuaranteed" +) + +type PositionEnum string + +const ( + PositionEnumRedBuoy PositionEnum = "RedBuoy" + + PositionEnumGreenBuoy PositionEnum = "GreenBuoy" + + PositionEnumRightBank PositionEnum = "RightBank" + + PositionEnumLeftBank PositionEnum = "LeftBank" + + PositionEnumMiddle PositionEnum = "Middle" + + PositionEnumAll PositionEnum = "All" +) + +type SurtypEnum string + +const ( + SurtypEnumMultibeam SurtypEnum = "Multibeam" + + SurtypEnumSinglebeam SurtypEnum = "Singlebeam" + + SurtypEnumADCP SurtypEnum = "ADCP" + + SurtypEnumInspectionTour SurtypEnum = "InspectionTour" +) + +type Error struct { + XMLName xml.Name `xml:"http://www.ris.eu/wamos/common/3.0 Error"` + + Detail string `xml:"detail,omitempty"` + + Error_code *ErrorCode `xml:"error_code,omitempty"` +} + +type ArrayOfMaterial struct { + //XMLName xml.Name `xml:"http://www.ris.eu/wamos/common/3.0 ArrayOfMaterial"` + + Material []*MaterialEnum `xml:"Material,omitempty"` +} + +type ArrayOfKeyValuePair struct { + //XMLName xml.Name `xml:"http://www.ris.eu/wamos/common/3.0 ArrayOfKeyValuePair"` + + KeyValuePair []*KeyValuePair `xml:"KeyValuePair,omitempty"` +} + +type KeyValuePair struct { + XMLName xml.Name `xml:"http://www.ris.eu/wamos/common/3.0 KeyValuePair"` + + Key string `xml:"Key,omitempty"` + + Value string `xml:"Value,omitempty"` +} + +type ArrayOfISRSPair struct { + //XMLName xml.Name `xml:"http://www.ris.eu/wamos/common/3.0 ArrayOfISRSPair"` + + ISRSPair []*ISRSPair `xml:"ISRSPair,omitempty"` +} + +type ISRSPair struct { + //XMLName xml.Name `xml:"http://www.ris.eu/wamos/common/3.0 ISRSPair"` + + FromISRS string `xml:"fromISRS,omitempty"` + + ToISRS string `xml:"toISRS,omitempty"` +} + +type RequestedPeriod struct { + //XMLName xml.Name `xml:"http://www.ris.eu/wamos/common/3.0 RequestedPeriod"` + + Date_start time.Time `xml:"Date_start,omitempty"` + + Date_end time.Time `xml:"Date_end,omitempty"` + + Value_interval int32 `xml:"Value_interval,omitempty"` +} + +type ArrayOfString struct { + XMLName xml.Name `xml:"http://www.ris.eu/wamos/common/3.0 ArrayOfString"` + + String []string `xml:"string,omitempty"` +} + +//type Char int32 + +//type Duration *Duration + +//type Guid string + +type IBottleneckService struct { + client *soap.SOAPClient +} + +func NewIBottleneckService(url string, tls bool, auth *soap.BasicAuth) *IBottleneckService { + if url == "" { + url = "" + } + client := soap.NewSOAPClient(url, tls, auth) + + return &IBottleneckService{ + client: client, + } +} + +func NewIBottleneckServiceWithTLSConfig(url string, tlsCfg *tls.Config, auth *soap.BasicAuth) *IBottleneckService { + if url == "" { + url = "" + } + client := soap.NewSOAPClientWithTLSConfig(url, tlsCfg, auth) + + return &IBottleneckService{ + client: client, + } +} + +func (service *IBottleneckService) AddHeader(header interface{}) { + service.client.AddHeader(header) +} + +// Backwards-compatible function: use AddHeader instead +func (service *IBottleneckService) SetHeader(header interface{}) { + service.client.AddHeader(header) +} + +// Error can be either of the following types: +// +// - ErrorFault + +func (service *IBottleneckService) Export_bn_by_id(request *Export_bn_by_id) (*Export_bn_by_idResponse, error) { + response := new(Export_bn_by_idResponse) + err := service.client.Call("http://www.ris.eu/bottleneck/3.0/IBottleneckService/export_bn_by_id", request, response) + if err != nil { + return nil, err + } + + return response, nil +} + +// Error can be either of the following types: +// +// - ErrorFault + +func (service *IBottleneckService) Export_bn_by_isrs(request *Export_bn_by_isrs) (*Export_bn_by_isrsResponse, error) { + response := new(Export_bn_by_isrsResponse) + err := service.client.Call("http://www.ris.eu/bottleneck/3.0/IBottleneckService/export_bn_by_isrs", request, response) + if err != nil { + return nil, err + } + + return response, nil +} diff -r 4bc27eea4f09 -r 5e45f441aed6 pkg/soap/soap.go --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pkg/soap/soap.go Tue Sep 04 17:13:25 2018 +0200 @@ -0,0 +1,289 @@ +package soap + +import ( + "bytes" + "crypto/tls" + "encoding/xml" + "io/ioutil" + "log" + "math/rand" + "net" + "net/http" + "time" +) + +const timeout = time.Duration(30 * time.Second) + +func dialTimeout(network, addr string) (net.Conn, error) { + return net.DialTimeout(network, addr, timeout) +} + +type SOAPEnvelope struct { + XMLName xml.Name `xml:"http://schemas.xmlsoap.org/soap/envelope/ Envelope"` + Header *SOAPHeader + Body SOAPBody +} + +type SOAPHeader struct { + XMLName xml.Name `xml:"http://schemas.xmlsoap.org/soap/envelope/ Header"` + + Items []interface{} `xml:",omitempty"` +} + +type SOAPBody struct { + XMLName xml.Name `xml:"http://schemas.xmlsoap.org/soap/envelope/ Body"` + + Fault *SOAPFault `xml:",omitempty"` + Content interface{} `xml:",omitempty"` +} + +type SOAPFault struct { + XMLName xml.Name `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault"` + + Code string `xml:"faultcode,omitempty"` + String string `xml:"faultstring,omitempty"` + Actor string `xml:"faultactor,omitempty"` + Detail string `xml:"detail,omitempty"` +} + +const ( + // Predefined WSS namespaces to be used in + WssNsWSSE string = "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" + WssNsWSU string = "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" + WssNsType string = "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText" +) + +type WSSSecurityHeader struct { + XMLName xml.Name `xml:"http://schemas.xmlsoap.org/soap/envelope/ wsse:Security"` + XmlNSWsse string `xml:"xmlns:wsse,attr"` + + MustUnderstand string `xml:"mustUnderstand,attr,omitempty"` + + Token *WSSUsernameToken `xml:",omitempty"` +} + +type WSSUsernameToken struct { + XMLName xml.Name `xml:"wsse:UsernameToken"` + XmlNSWsu string `xml:"xmlns:wsu,attr"` + XmlNSWsse string `xml:"xmlns:wsse,attr"` + + Id string `xml:"wsu:Id,attr,omitempty"` + + Username *WSSUsername `xml:",omitempty"` + Password *WSSPassword `xml:",omitempty"` +} + +type WSSUsername struct { + XMLName xml.Name `xml:"wsse:Username"` + XmlNSWsse string `xml:"xmlns:wsse,attr"` + + Data string `xml:",chardata"` +} + +type WSSPassword struct { + XMLName xml.Name `xml:"wsse:Password"` + XmlNSWsse string `xml:"xmlns:wsse,attr"` + XmlNSType string `xml:"Type,attr"` + + Data string `xml:",chardata"` +} + +type BasicAuth struct { + Login string + Password string +} + +type SOAPClient struct { + url string + tlsCfg *tls.Config + auth *BasicAuth + headers []interface{} +} + +// ********** +// Accepted solution from http://stackoverflow.com/questions/22892120/how-to-generate-a-random-string-of-a-fixed-length-in-golang +// Author: Icza - http://stackoverflow.com/users/1705598/icza + +const ( + letterBytes = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789" + letterIdxBits = 6 // 6 bits to represent a letter index + letterIdxMask = 1<= 0; { + if remain == 0 { + cache, remain = src.Int63(), letterIdxMax + } + if idx := int(cache & letterIdxMask); idx < len(letterBytes) { + b[i] = letterBytes[idx] + i-- + } + cache >>= letterIdxBits + remain-- + } + return string(b) +} + +// ********** + +func NewWSSSecurityHeader(user, pass, mustUnderstand string) *WSSSecurityHeader { + hdr := &WSSSecurityHeader{XmlNSWsse: WssNsWSSE, MustUnderstand: mustUnderstand} + hdr.Token = &WSSUsernameToken{XmlNSWsu: WssNsWSU, XmlNSWsse: WssNsWSSE, Id: "UsernameToken-" + randStringBytesMaskImprSrc(9)} + hdr.Token.Username = &WSSUsername{XmlNSWsse: WssNsWSSE, Data: user} + hdr.Token.Password = &WSSPassword{XmlNSWsse: WssNsWSSE, XmlNSType: WssNsType, Data: pass} + return hdr +} + +func (b *SOAPBody) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error { + if b.Content == nil { + return xml.UnmarshalError("Content must be a pointer to a struct") + } + + var ( + token xml.Token + err error + consumed bool + ) + +Loop: + for { + if token, err = d.Token(); err != nil { + return err + } + + if token == nil { + break + } + + switch se := token.(type) { + case xml.StartElement: + if consumed { + return xml.UnmarshalError("Found multiple elements inside SOAP body; not wrapped-document/literal WS-I compliant") + } else if se.Name.Space == "http://schemas.xmlsoap.org/soap/envelope/" && se.Name.Local == "Fault" { + b.Fault = &SOAPFault{} + b.Content = nil + + err = d.DecodeElement(b.Fault, &se) + if err != nil { + return err + } + + consumed = true + } else { + if err = d.DecodeElement(b.Content, &se); err != nil { + return err + } + + consumed = true + } + case xml.EndElement: + break Loop + } + } + + return nil +} + +func (f *SOAPFault) Error() string { + return f.String +} + +func NewSOAPClient(url string, insecureSkipVerify bool, auth *BasicAuth) *SOAPClient { + tlsCfg := &tls.Config{ + InsecureSkipVerify: insecureSkipVerify, + } + return NewSOAPClientWithTLSConfig(url, tlsCfg, auth) +} + +func NewSOAPClientWithTLSConfig(url string, tlsCfg *tls.Config, auth *BasicAuth) *SOAPClient { + return &SOAPClient{ + url: url, + tlsCfg: tlsCfg, + auth: auth, + } +} + +func (s *SOAPClient) AddHeader(header interface{}) { + s.headers = append(s.headers, header) +} + +func (s *SOAPClient) Call(soapAction string, request, response interface{}) error { + envelope := SOAPEnvelope{} + + if s.headers != nil && len(s.headers) > 0 { + soapHeader := &SOAPHeader{Items: make([]interface{}, len(s.headers))} + copy(soapHeader.Items, s.headers) + envelope.Header = soapHeader + } + + envelope.Body.Content = request + buffer := new(bytes.Buffer) + + encoder := xml.NewEncoder(buffer) + //encoder.Indent("", " ") + + if err := encoder.Encode(envelope); err != nil { + return err + } + + if err := encoder.Flush(); err != nil { + return err + } + + //log.Println(buffer.String()) + + req, err := http.NewRequest("POST", s.url, buffer) + if err != nil { + return err + } + if s.auth != nil { + req.SetBasicAuth(s.auth.Login, s.auth.Password) + } + + req.Header.Add("Content-Type", "text/xml; charset=\"utf-8\"") + req.Header.Add("SOAPAction", soapAction) + + req.Header.Set("User-Agent", "gowsdl/0.1") + req.Close = true + + tr := &http.Transport{ + TLSClientConfig: s.tlsCfg, + Dial: dialTimeout, + } + + client := &http.Client{Transport: tr} + res, err := client.Do(req) + if err != nil { + return err + } + defer res.Body.Close() + + rawbody, err := ioutil.ReadAll(res.Body) + if err != nil { + return err + } + if len(rawbody) == 0 { + log.Println("empty response") + return nil + } + + //log.Println(string(rawbody)) + respEnvelope := new(SOAPEnvelope) + respEnvelope.Body = SOAPBody{Content: response} + err = xml.Unmarshal(rawbody, respEnvelope) + if err != nil { + return err + } + + fault := respEnvelope.Body.Fault + if fault != nil { + return fault + } + + return nil +}