Skip to content

Instantly share code, notes, and snippets.

@shilder
Created August 13, 2018 16:53
Show Gist options
  • Save shilder/b619503558d0d01caa1411293751f2b7 to your computer and use it in GitHub Desktop.
Save shilder/b619503558d0d01caa1411293751f2b7 to your computer and use it in GitHub Desktop.
clojure-soap-simple
# generate java sources for WSDL
# http://fias.nalog.ru/WebServices/Public/DownloadService.asmx?WSDL
wsimport -B-npa -Xnocompile -s src/java -encoding utf-8 -p ru.nalog.fias resources/DownloadService.xml
(ns mill.jaxws
(:require [clojure.java.io :as io])
(:import (ru.nalog.fias DownloadService DownloadServiceSoap DownloadFileInfo)
(com.sun.xml.internal.ws.client BindingProviderProperties)
(javax.xml.ws BindingProvider)
(javax.xml.namespace QName)))
; Create JAX-WS endpoint with custom parameters
(defn- ^DownloadServiceSoap get-service-port
[]
(let [ws (DownloadService.
; Get WSDL from resource (it should be on classpath)
(io/resource "DownloadService.xml")
; service specific (copy from DownloadService constructor)
(QName. "http://fias.nalog.ru/WebServices/Public/DownloadService.asmx", "DownloadService"))
port (.getDownloadServiceSoap ws)
rcx (.getRequestContext ^BindingProvider port)]
; set url to https
(.put rcx BindingProvider/ENDPOINT_ADDRESS_PROPERTY "https://fias.nalog.ru/WebServices/Public/DownloadService.asmx")
; default timeouts are not specified, so set them here
(.put rcx BindingProviderProperties/CONNECT_TIMEOUT (int 10000))
(.put rcx BindingProviderProperties/REQUEST_TIMEOUT (int 10000))
port))
(defn- convert-download-info [^DownloadFileInfo info]
; can use bean function to achieve approximately this
{:FiasCompleteDbfUrl (.getFiasCompleteDbfUrl info)
:FiasCompleteXmlUrl (.getFiasCompleteXmlUrl info)
:FiasDeltaDbfUrl (.getFiasDeltaDbfUrl info)
:FiasDeltaXmlUrl (.getFiasDeltaXmlUrl info)
:TextVersion (.getTextVersion info)
:VersionId (.getVersionId info)})
(defn get-last-download-info []
(let [info (.getLastDownloadFileInfo (get-service-port))]
(convert-download-info info)))
(defn get-all-download-info []
(let [data (.getAllDownloadFileInfo (get-service-port))]
(map convert-download-info (.getDownloadFileInfo data))))
(ns mill.plain
(:require [clojure.data.xml :as xml]
[clojure.data.zip.xml :refer [xml-> xml1-> text]]
[aleph.http :as http]
[manifold.deferred :as d]
[byte-streams :as bs]
[clojure.zip :as zip]))
; pure XML emitter
(defn- soap-xml [method]
(xml/emit-str
(xml/sexp-as-element
[:soap:Envelope
{:xmlns/soap "http://www.w3.org/2003/05/soap-envelope"
:xmlns/m "http://fias.nalog.ru/WebServices/Public/DownloadService.asmx"}
[:soap:Header]
[:soap:Body
[(str "m:" method)]]])))
(defn soap-call [url method]
(-> (http/request {:request-method :post
:url url
:body (soap-xml method)
:request-timeout 10000
:connection-timeout 10000
:headers {"Content-Type" "application/soap+xml; charset=utf-8"
"SOAPAction" "http://www.w3.org/2003/05/soap-envelope"}})
(d/chain
(fn [r]
(bs/to-string (:body r))))))
(defn stupid-xml-parse [m node tag]
(assoc m tag (xml1-> node tag text)))
; can be generalized for simple XML
(defn parse-file-info [node]
(-> {}
(stupid-xml-parse node :VersionId)
(stupid-xml-parse node :TextVersion)
(stupid-xml-parse node :FiasCompleteDbfUrl)
(stupid-xml-parse node :FiasCompleteXmlUrl)
(stupid-xml-parse node :FiasDeltaDbfUrl)
(stupid-xml-parse node :FiasDeltaXmlUrl)
(stupid-xml-parse node :Kladr4ArjUrl)
(stupid-xml-parse node :Kladr47ZUrl)))
(def fias-url "https://fias.nalog.ru/WebServices/Public/DownloadService.asmx")
(defn last-download-info []
(-> (soap-call fias-url "GetLastDownloadFileInfo")
(d/chain
(fn [xml]
(let [z (zip/xml-zip (xml/parse-str xml))]
(parse-file-info (xml1-> z
:Body
:GetLastDownloadFileInfoResponse
:GetLastDownloadFileInfoResult)))))))
(defn all-download-info []
(-> (soap-call fias-url "GetAllDownloadFileInfo")
(d/chain
(fn [xml]
(let [z (zip/xml-zip (xml/parse-str xml))]
(mapv parse-file-info (xml-> z
:Body
:GetAllDownloadFileInfoResponse
:GetAllDownloadFileInfoResult
:DownloadFileInfo)))))))
;; usage: @(last-download-info)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment