SipOHttp(s) -rajapinta

Lisää sipmessages-endpointin Kohan REST APIin,jonka kautta voi keskustella SIP-serverin kanssa XML-viestein (/api/v1/sipmessages). Viestiin tulee SIP-käyttäjätunnus ja salasana mukaan, joten käyttö vain HTTPS:n kanssa.

KD-4439: https://tiketti.koha-suomi.fi/issues/4439

Viestintä

REST-rajapinnan kutsuma SipOHttp.pm -moduuli keskustelee sip-palvelimen kanssa socketeilla, joiden välinen yhteys luodaan SipOHttp.pm-moduulissa aina uuden viestin saapuessa endpointiin (käynnistää SipOHttp.pm-modulin process-metodin). Kun XML-viestin sisältö on purettu ja käsitelty ja SIP2-palvelin palauttanut vastauksen, socket-yhteys katkeaa.

Jokainen rajapintaan tuleva viesti autentikoidaan sen mukana tulevalla tunnus/salasanayhdistelmällä sip2-palvelinta hyödyntäen. Jos autentikointi ei onnistu, XML-viestin sisältämää varsinaista sip2-viestiä ei välitetä edelleen sip2-palvelimelle.

Laitteet, jotka käyttävät sipohttp:tä tarvitsevat sip2-palvelimen konfiguraatiotiedostoon (esim. SIPConfig.xml) tunnuksensa yhteyteen (<accounts></accounts>) määrityksen sipohttp="XXXXXXX".
Tämän lisäksi konfiguraatiotiedostoon on lisättävä nimi, ip- ja porttimääritys sipohttp-parametrin määrittämiseksi (<sipohttp></sipohttp>). Näillä määrityksillä SIP2-viestiliikenne ohjataan haluttuun sip2-palvelinosoitteeseen. SIP2-palvelimen konfiguraatiotiedoston transport-tyypiksi on asetettava "RAW". Timeout- eli aikakatkaisuarvon oletus on 5 sekuntia, jonka jälkeen mahdollinen edelleen avoin yhteys rajapinnan ja SIP2-palvelimen välillä katkaistaan. Jos aikakatkaisu tapahtuu, lähettää rajapinta paluuviestinä XML-viestin, jossa on tyhjä SIP2-viesti response-osassa.

Esimerkki määritystiedostosta SIPconfig.xml, jossa sipohttp-liikenne ohjataan konfiguraatiotiedoston tiedoilla käynnistettyyn samaiseen sip2-palvelimeen (127.0.0.1:6009):

<acsconfig xmlns="http://openncip.org/acs-config/1.0/">
  <server-params
    min_servers='1'
    min_spare_servers='1'
  />

  <listeners>
    <service
      port="127.0.0.1:6009/tcp" 
      transport="RAW" 
      protocol="SIP/2.10" 
      timeout="600" />
  </listeners>

  <sipohttp>
    <service 
      name="lappisipohttp" 
      host="127.0.0.1" 
      port="6009" />
  </sipohttp>

  <accounts>
    <login id="siptesti"  password="automaatti123" institution="ROOU" delimiter="|" error-detect="enabled" terminator="CR" encoding="utf8" checked_in_ok="1" 
    no_alert="1" sipohttp="lappisipohttp" />
  </accounts>

<institutions>
   <institution id="ROOU" implementation="ILS" parms="">
     <policy checkin="true" renewal="true" checkout="true" 
       status_update="false" offline="false" 
       timeout="25" 
       retries="5" />
   </institution>
</institutions>
</acsconfig>

SipOHttp.pm

Kun rajapinnan sipmessages-polku vastaanottaa POST-viestin, SIPoHTTP.pm tarkistaa, että pyynnön bodyssa kulkee XML-muotoinen viesti sisältäen SIP-viestin.
XML-muotoisen viestin on noudatettava seuraavaa xml-skeemaa: /koha/Koha/koha-tmpl/sipschema.xsd (tällä hetkellä skeematarkistusta ei suoriteta laitevalmistajan tuen puuttuessa).

<?xml version="1.0" encoding="UTF-8"?>

<!-- sipschema.xsd  $Revision: 1.0 $ [email protected] -->

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:ns1="https://koha-suomi.fi/sipschema.xsd" targetNamespace="https://koha-suomi.fi/sipschema.xsd" elementFormDefault="unqualified" attributeFormDefault="unqualified">

  <xs:element name="sip">

    <xs:complexType>

      <xs:choice>

        <xs:element name="request" type="xs:string"/>

        <xs:element name="response" type="xs:string"/>

        <xs:element name="error" type="xs:string"/>

      </xs:choice>

      <xs:attribute name="login" type="xs:string"/>

      <xs:attribute name="password" type="xs:string"/>

    </xs:complexType>

  </xs:element>

</xs:schema>

XML-viestiä verrataan tähän skeematiedostoon ja jos xml-rakenteessa on virheitä, skripti palauttaa rajapintaan virhekoodin.

Laite, minkä tunnistautuminen vaaditaan puretaan "login:" ja "password" -tiedoista rajapintaan saapuneesta XML:stä. Näillä tiedoilla rakennetaan sip-palvelimelle viesti autentikointia varten.
Sip2-palvelin johon viestit lähetetään, luetaan palvelinymäristössä sijaitsevan SIPconfig-hakemiston sisältämistä konfiguraatiotiedostoista (esim. sipconfig.xml) ja jos tunnus löytyy, autentikointiviesti lähetetään tunnukselle määritettyyn sip2-palvelinosoitteeseen.

Jos autentikointi onnistuu ja sip2-palvelin vastaa "941", lähetetään itse xml:n <request></request> sisällä oleva sip-viesti sip2-palvelimelle. Palautuneesta SIP-viestistä muodostetaan xml-muotoinen paluuviesti.
Paluuviesti välitetään rajapinnan vastaukseksi POST-pyyntöön response bodyssa.

Mikäli sip2-laitteen tunnistautuminen ei onnistu, palautetaan rajapintaan sip-palvelimen palauttama "940"-viesti ja prosessi keskeytyy.

Virhetilanteet ja loki

SipOHttp-skripti palauttaa rajapinnan kautta seuraavat virheilmoitukset response bodyssa POST-kyselyihin:

-XML validointi epäonnistui skeematiedostoa vastaan: HTTP-virhe 400 viestillä "Invalid Request. Validation failed."
-Jos XML-viestin "login:" tai "password:" parametria vastaavia asetuksia ei löydy XML-konfiguraatiotiedostoista: HTTP 400 "Invalid request. No config found for login device."
-Jos XML-viestin "login:" tai "password:" parametrit ovat puutteelliset: HTTP 400 "Invalid request. Missing login/pw in XML."
-Jos XML-viestin "request" eli SIP2-viesti puuttuu: HTTP 400 "Invalid request. Missing SIP Request in XML."
-Jos sip2-palvelimeen ei saa muodostettua yhteyttä/muu virhe: HTTP 500 "Something went wrong, check the logs."
-Jos SIP2-palvelin aikakatkaisee yhteyden: Paluu-XML, jossa response-osa tyhjä.

Lokit: Sipohttp:n määritykset lokitasosta ja lokin sijainnista määritetään log4perl.conf -tiedostoon.

DEBUG-tasolla sipohttp lokittaa jokaisen rajapintaan saapuvan XML-viestin sisällön ja SIP2-viestiliikenteen SIP2-palvelimen kanssa + virhetilanteet.
ERROR-taso lokittaa vain virheet ja kriittiset virheet (jos SIP2-palvelimeen ei saa luotua socket-yhteyttä).
Lokikonfiguraation/lokituksen puuttuminen ei estä sipohttp:n toimintaa.

Esimerkki log4perl-configuraatiosta:

log4perl.logger.sipohttp = DEBUG, SIPoHTTP
log4perl.appender.SIPoHTTP=Log::Log4perl::Appender::File
log4perl.appender.SIPoHTTP.filename=/var/log/koha/sipohttp.log
log4perl.appender.SIPoHTTP.mode=append
log4perl.appender.SIPoHTTP.create_at_logtime=true
log4perl.appender.SIPoHTTP.syswrite=true
log4perl.appender.SIPoHTTP.recreate=true
log4perl.appender.SIPoHTTP.layout=PatternLayout
log4perl.appender.SIPoHTTP.layout.ConversionPattern=[%d{yyyy-MM-dd HH:mm:ss,SSS}] %p %m%n
log4perl.appender.SIPoHTTP.utf8=1

Käyttöönotto

- kopioi Koha/koha-tmpl/sipschema.xsd koha-dev/koha-tmpl/ - vaatii myös että tämä tiedosto on saatavilla osoitteesta https://koha-suomi.fi/sipschema.xsd (skeematarkistus ei tällä hetkellä käytössä)
- tee vaadittavat muutokset sip2-palvelimen konfiguraatiotietostoon/tiedostoihin (ks. yllä)

Testaus

Endpointtia voi testata komentoriviltä esim. curlilla:

curl -X POST -H 'Content-Type: application/xml' -H 'Accept: text/html' 'https://127.0.0.1:8086/api/v1/sipmessages?query=XXX'

Korvaa IP ja portti tarvittaviksi. XXX korvataan seuraavanlaisella XML:llä:

 <?xml version="1.0" encoding="UTF-8"?>
 <ns1:sip login="LOGINNIMI" password="SALASANA" xsi:schemaLocation="https://koha-suomi.fi/sipschema.xsd"  xmlns:ns1="https://koha-suomi.fi/sipschema.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
   <request>9900302.00</request>
 </ns1:sip>


Vaihda LOGINNIMI ja SALASANA siihen SIP-käyttäjätunnukseen ja sen salasanaan. query-parametri sisältää halutun SIP-komennon.

curl -X POST \
     --insecure \
     --header 'Content-Type: application/xml' \
     --header 'Accept: text/html' \
     'https://127.0.0.1:8086/api/v1/sipmessages?query=%3C%3Fxml+version%3D%221.0%22+encoding%3D%22UTF-8%22%3F%3E%3Cns1%3Asip+login%3D%22LOGINNIMI%22+password%3D%22SALASANA%22+xsi%3AschemaLocation%3D%22https%3A%2F%2Fkoha-suomi.fi%2Fsipschema.xsd%22+xmlns%3Ans1%3D%22https%3A%2F%2Fkoha-suomi.fi%2Fsipschema.xsd%22+xmlns%3Axsi%3D%22http%3A%2F%2Fwww.w3.org%2F2001%2FXMLSchema-instance%22%3E%3Crequest%3E9900302.00%3C%2Frequest%3E%3C%2Fns1%3Asip%3E'

tai, parempi tapa on lähettää XML-data bodyssä, jolloin salasana ja käyttäjätunnus eivät jää http-serverin logiin:

curl -X POST \
     --header 'Content-Type: application/xml' \
     --header 'Accept: text/html' \
     -d '<?xml version="1.0" encoding="UTF-8"?><ns1:sip login="LOGINNIMI" password="SALASANA" xsi:schemaLocation="https://koha-suomi.fi/sipschema.xsd"  xmlns:ns1="https://koha-suomi.fi/sipschema.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"><request>9900302.00</request></ns1:sip>' \
     'https://127.0.0.1/api/v1/sipmessages'

Koodin parannusta (TODO)

- Tällä hetkellä vastaus-XML rakennetaan "kovakoodatusti" LibXML:llä, tämän voisi parametroida joko template-tiedostoksi, tai esim. Kohan systempreferenceksi.
- Automaattien tunnukset/salasanat eivät saa sisältää ei-escapetettuja merkkejä (epävalidia XML:ää), aiheuttaa parsimisvirheen konfiguraatiotiedostoja luettaessa.
- Autentikaation voisi tehdä koha-olioilla.

  • No labels