You are viewing an old version of this page. View the current version.

Compare with Current View Page History

« Previous Version 30 Next »

Indledning

Nedenstående er en kortfattet oversigt over teknisk og forretningsmæssig funktionalitet på NSP platformen.

Formålet er at skabe en oversigt, som kan danne udgangspunkt for hvilke målepunkter der er relevante i forbindelse med etablering af SLA målinger og kaldstatistik.

Dokumentet bliver løbende opdateret.

 

Flows gennem NSP-platformens proxyservices.

De enkelte services kan tilgåes på en eller flere af nedenstående måder.

Direkte adgang (cNSP/dNSP)

Komponenten tilgås direkte udefra uden at passere proxy-service (DCC eller gateway) på vej ind. Dette er muligt for alle komponenter både centralt og decentralt. Det anbefales dog så vidt muligt at tilgå funktionalitet gennem en proxy.

Adgang via gateway på dNSP

Komponenten tilgås her på en dNSP via en gateway. Kalder vedhæfter et vilkårligt id-kort, som af SOSI-GW erstattes med et signeret user id-kort fra cachen (hvis dette findes) - uanset om vedlagte id-kort allerede er signeret eller ej.

Dette kræver ikke konfiguration for den enkelte komponent, men er muligt for alle (interne og eksterne) komponenter der kræver et user id-kort. Kalder medsender information om hvilken bagvedliggende service der skal videresendes til. 

Adgang via DCC (cNSP/dNSP) og evt. gateway

Komponenten tilgås gennem DCC uden at passere en gateway før eller efter. Dette er muligt både på cNSP og dNSP. Dette kræver dog at miljøets DCC er konfigureret med adgang til denne komponent.

På cNSP tilgås alle komponenter direkte fra DCC.

På dNSP afhænger adgangsvejen af DCC'ens konfiguration:

  • Flertallet af komponenterne er konfigureret til direkte adgang fra DCC til komponent.
  • Enkelte komponenter (en delmængde af de der kræver et user id-kort) er konfigureret til at gå gennem en mellemliggende gateway.

Adgangsvejen afhænger således af NSP-miljøets DCC-konfiguration. Kalder har ingen indflydelse på denne.

Adgang via central gateway (cNSP) - evt med mellemliggende DCC

Her tilgås komponenten på en cNSP gennem en central gateway. Den centrale gateway sørger (om nødvendigt og om muligt) for udskiftning af et usigneret id-kort med et signeret fra cachen. Den bagvedliggende service bestemmes af kalder ved hjælp af WS-adressing.

Dette er muligt for alle services der kræver et user id-kort. Såfremt den bagvedliggende service er konfigureret i DCC, kan adgangen endvidere ske gennem denne.

NSP services

Basisservices

 

Service/funktionalitetServiceadresse/endpointBeskrivelse/actionsKomponenterProxyadgangeForretningsproduktDefinition af målepunktUdstilling
STS 

Overordnet STS produkt som samler SecurityTokenService, IdentityTokenService og omveksling

STSDCCSTS

Samlet antal kald til endpoints SecurityTokenService, NewSecurityTokenService, IdentityTokenService, Sosi2OIOSaml og OIOSaml2Sosi


signIdCard

RequestSecurityToken

Kald for cvr udstilles på stamkort for aftale

 

Samlede antal kald er udstillet på Overblik over servicekald

STS signering

SecurityTokenService

(STS udstedelse og signering af idkort)

 

/sts/services/SecurityTokenService 

(/sts/services/NewSecurityTokenService)

Signering af ikke-signeret id-kort

operation: signIdCard

STSDCCSecurityTokenServiceAntal kald på endpoint 

STS signering

IdentityTokenService

(STS ITS)

 

/sts/services/IdentityTokenServiceUdstedelse af identitytoken på bagrund af user id-kortSTS

DCC

DCC+Gateway

Gateway

Gateway+DCC

IdentityTokenService  

STS billetomveksling

Sosi2OIOSaml

(STS IBO)

 

/sts/services/Sosi2OIOSamlOmveksling af signeret user id-kort til OIOSaml tokenSTS

DCC

DCC+Gateway

Gateway

Gateway+DCC

Sosi2OIOSaml  

STS billetomveksling

OIOSaml2Sosi

(STS NBO)

/sts/services/OIOSaml2SosiOmveksling af Nem-login token til signeret user id-kortSTS OIOSaml2Sosi  
Gateway Cache til idkortGW GWSamlede antal kald på endpoint sosigwSamlede antal kald er udstillet på Overblik over servicekald

NGW

/sosigw/service/sosigw

Central gateway til login/idkort signering

Ligger på cnsp

Bruges af kommunerne

https://wsdl.nspop.dk/sosigw/service/sosigw?wsdl (:getValidIdCard, :requestIdCardDigestForSigning, :signIdCard, :logout)

NGW

STS

DCC

 

Central gateway (ngw)

Samlede antal kald på endpoint med actions getValidIdCard, requestIdCardDigestForSigning, signIdCard, logout

(endpoint på cnsp)

Kald for cvr udstilles på stamkort for aftale

SOSI-GW

/sosigw/service/sosigw

login/logout/id kort signering

https://wsdl.nspop.dk/sosigw/service/sosigw?wsdl (:getValidIdCard, :requestIdCardDigestForSigning, :signIdCard, :logout)

Sosi-GW

STS

DCC

Decentral gateway (sosi-gw)

Samlede antal kald på endpoint med actions getValidIdCard, requestIdCardDigestForSigning, signIdCard, logoutKald for cvr udstilles på stamkort for aftale
Viderestillingskomponent (DCC) Viderestilling af servicekaldDCCGWDCCAntal kald på DCCSamlede antal kald er udstillet på Overblik over servicekald

Støtteservices

Service/funktionalitetServiceadresseBeskrivelseKomponenterProxyadgangeForretningsproduktDefinition af målepunktUdstilling
NTS (NSP Test Service)/nts/service

NSP test service der giver mulighed for at verificere korrekthed af DGWS request med forskellige typer id-kort

https://wsdl.nspop.dk/nts/service?wsdl (:invoke)

NTS

DCC

Gateway

Gateway+DCC

TestserviceAlle kald på endpointSamlede antal kald er udstillet på Overblik over servicekald

 

Forretningsservices

Service/funktionalitet

Serviceadresse / endpoint

Beskrivelse/actions

Komponent

Proxy adgange

Forretningsprodukt

Definition af målepunkt

Udstilling
Advisering 

National adviseringsservice, NAS

Giv og hent adviseringer om nyt inden for specifikt emneområde

NAS    

Advisering - aftager

(NAS PullPoint Service, hent notifikationer)

/pullpoint/service

Hent notifikationer fra et pullpoint på baggrund af allerede opsat abonnement

https://wsdl.nspop.dk/pullpoint/service?wsdl (:getMessages)

NASDCC

Advisering - aftager, hent notifikationer

 

kald på endpoint med action GetMessages

Kald for cvr udstilles på stamkort for aftale pr 1/3-15
NAS PullPointFactory Service/pullpointfactory/service

Opret pullpoint / Nedlæg pullpoint når der ingen abonnenter er

https://wsdl.nspop.dk/pullpointfactory/service?wsdl (:CreatePullPoint, :DestroyPullPoint)

NASDCCNAS aftager, opret/nedlæg pullpoint n/a
NAS IDList Service/idlist/service

Opret/nedlæg id-liste

https://wsdl.nspop.dk/idlist/service?wsdl (:CreateIDList, :DestroyIDList)

NASDCCNAS aftager, opret/nedlæg id-liste n/a
NAS Subscription Manager Service/subscriptionmanager/servicehttps://wsdl.nspop.dk/subscriptionmanager/service?wsdl (:Subscribe, :Unsubscribe)NASDCCNAS aftager, opret/nedlæg abonnementSamlede antal kald på endpoint med actions Subscribe, Unsubscriben/a
 /notificationbroker/service

Adviser abonnenter om notifikationer

https://wsdl.nspop.dk/notificationbroker/service?wsdl (:Notify)

NASDCCAdvisering - udbyder, notify

Kald på endpoint med action Notify

Kald for cvr udstilles på stamkort for aftale pr 1/3-15
NAS Notificationbroker Service/notificationbroker/service

Opret/nedlæg abonnent

https://wsdl.nspop.dk/notificationbroker/service?wsdl (:Subscribe, :Unsubscribe)

NASDCCNAS udbyder, opret/nedlæg abonnentSamlede antal kald på endpoint med actions Subscribe, Unsubscriben/a

Behandlingsrelation med GOS


 

Behandlingsrelationservice, BRS, giver adgang til at verificere og følge op på eksistensen og kvaliteten af en behandlingsrelation. BRS kommer altid med CPR abbonement og GOS

Kræver STS signeret system id-kort

     
BRS/brs-nsp/service/brs

Hent behandlingsrelation

https://wsdl.nspop.dk/brs-nsp/service/brs?wsdl (:treatmentRelation)

BRSDCCBehandlingsrelation, hent behandlingsrelation

Kald på endpoint med action treatmentRelation

Kald for cvr udstilles på stamkort for aftalen pr 1/3-15
CPR abbonement CPR abbonement kommer altid med GOS     
CPR abonnementsservice /cprabbs/service/cprabbs

https://wsdl.nspop.dk/cprabbs/service/cprabbs?wsdl (:getChangedCprs)

Benytter stamdatamodulet

CPRABBSDCCCPR abbonementKald på endpoint med action getChangedCprs Kald for cvr udstilles på stamkort for aftalen pr 1/3-15
Generisk opsamlingsservice (GOS)

/gos/service/gos

Til bestilling af en opfølgning på graden af evidens for en aktuel behandlingsrelation, abonnementer på CPR-numre, samt registrering af forespørgsler på ændrede CPR-numre

https://wsdl.nspop.dk/gos/service/gos?wsdl (:create)

GOS

DCCGenerisk opsamlingsservice (GOS)Kald på endpoint med action create 
Notificationsservice/gos/service/notification

Hent notifikation om udfaldet af den bestilte opfølgning

https://wsdl.nspop.dk/gos/service/notification?wsdl (:notificationQuery)

 

DCC   
MinLog 

Tilbyder registrering og opslag af borgers Min-log-servicedata

Kræver STS signeret user id-kort. DCC konfigureret uden gateway bagved.

     

MinLog udtræk

 

 

 

/minlog

MinLog udtræksservice, opslag i opsamlede logs baseret på cpr

En borger kan udtrække log-registreringer, der indeholder detaljer omhandlende sundhedspersoners indhentning af data om borgeren

https://wsdl.nspop.dk/minlog.wsdl (:ListLogStatements) 

Minlog

DCC

Gateway

Gateway+DCC

Min logAlle kald på endpoint med action ListLogStatements 
MinLog udtræk/minlog

En sundhedsperson kan udtrække log-registreringer, hvor andre sundhedspersoner har anført at arbejde på vegne af sundhedspersonen

https://wsdl.nspop.dk/minlog.wsdl (:ListLogStatementsOnBehalfOf

Minlog 

DCC

Gateway

Gateway+DCC

 Alle kald på endpoint med action ListLogStatementsOnBehalfOf 

MinLog registrering

 

/minlog-registration/service

MinLog registreringsservice opretter logs i MinLog systemet

https://wsdl.nspop.dk/minlog-registration/service?wsdl (:LogDataAdd)

Minlog

DCC

Gateway

Gateway+DCC

Min log registrering Udstilles ikke

MinLog export

(DoDi)

 

Komponenten importerer log opsamlet af Minlog Registration og indeholder også "oprydningsjobbet" der sletter log der har nået en vis alder

    Udstilles ikke
Samtykke 

Tilbyder vedligehold og verificering af samtykkeregistreringer

Kræver STS signeret system id-kort

     
Samtykkeverifikation/consent-verification/service

Kan kun kaldes hvis samytykke er givet

https://wsdl.nspop.dk/consent-verification/service?wsdl (:ConsentForUserCheck, :ConsentForDataCheck, :ConsentForForeignersCheck)

SamtykkeDCCSamtykkeverifikation

Samlede antal kald på endpoint med actions ConsentForUserCheck, ConsentForForeignersCheck og ConsentForDataCheck

Kald for cvr udstilles på stamkort for aftalen pr 1/3-15
Samtykkeadministration/consent-administration/service

En borger (eller sundhedsfaglig person på vegne af) kan hente, registrere og vedligeholde samtykkeregistreringer

https://wsdl.nspop.dk/consent-administration/service?wsdl (flere operationer)

Samtykke

DCC

SamtykkeadministrationSamlede antal kald på endpointUdstilles ikke
Dokumentdelingservice (DDS) Dokumentdelingsservice, NPI/DDS     
Dokumentdeling/npiservice

https://wsdl.nspop.dk/npiservice?wsdl

 

DokumentdelingDCCDokumentdelingAntal kald på endpointn/a
eCPR Tilbyder rekvirerering og håndtering af CPR erstatningsnumre     
eCPR/ecpr-ws/servicehttps://wsdl.nspop.dk/ecpr-ws/service?wsdl (:GenerateReplacementCPROperation, :GenerateReplacementCPRWithCheckOperation, :BulkGenerateReplacementCPROperation, :GetReplacementCPRDataOnReplacementCPROperation, :GetReplacementCPRDataOnEPIDOperation, :LinkValidEPIDWithReplacementCPROperation, :UnlinkReplacementCPROperation)eCPRDCCeCPR

Samlede antal kald på endpoint med actions GenerateReplacementCPROperation, GenerateReplacementCPRWithCheckOperation, BulkGenerateReplacementCPROperation, GetReplacementCPRDataOnReplacementCPROperation, GetReplacementCPRDataOnEPIDOperation, LinkValidEPIDWithReplacementCPROperation, UnlinkReplacementCPROperation

Kald for cvr udstilles på stamkort for aftale pr 1/3-15

Datasamlinger (SDM)

Stamdata registerudtræk (SKRS)

Service/funktionalitetServiceadresseBeskrivelseKomponentForretningsproduktDefinition af målepunktUdstilling
Kopiregisterservice/stamdata-batch-copy-ws/service/StamdataReplication

Kopiregisterservicen, SKRS, tilbyder komplette registerudtræk

https://wsdl.nspop.dk/stamdata-batch-copy-ws/service/StamdataReplication?wsdl (:replicate)

SKRS Via DCC: entries i log på action "http://nsi.dk/2011/10/21/StamdataKrs/replicate" 
CPR registeropslag v1

 

Pre 2013 CPR registerudtræk

 

SKRSCPR v1 registerudtræk

Udtræk fra sla log på GenericCallParms(x):

register=cpr,

datatype=person, version=1

...

kald for cvr udstilles på stamkort for aftalen pr 1/3-15
CPR registeropslag v2, reduceret udtræk CPR registerudtræk reduceret. Til privateSKRSCPR v2 registerudtræk

Udtræk fra sla log på GenericCallParms(x):

register=cpr,

datatype=person, version=2

...

kald for cvr udstilles på stamkort for aftalen pr 1/3-15
CPR registeropslag v2, fuldt udtræk CPR registerudtræk med alle dataSKRSCPR v2 registerudtræk

Udtræk fra sla log på GenericCallParms(x):

register=cpr,

datatype=person, version=2

...

kald for cvr udstilles på stamkort for aftalen pr 1/3-15
Autorisation  SKRS 

Udtræk fra sla log på GenericCallParms(x):

register=autorisationsregisteret,

datatype=autorisation

Hvis adgangen er bestilt er antal kald på registeret pr. cvr udstillet på stamkort for aftaler fra den 1/3-15
Bemyndigelse  SKRS 

Udtræk fra sla log på GenericCallParms(x):

register=bemyndigelsesservice

datatype=bemyndigelse

Hvis adgangen er bestilt er antal kald på registeret pr. cvr udstillet på stamkort for aftaler fra den 1/3-15
Dosering  SKRS 

Udtræk fra sla log på GenericCallParms(x):

register=doseringsforslag,

datatype=dosagestructure

datatype=dosageunit

datatype=drug

datatype=drugdosagestructurerelation

datatype=version

Hvis adgangen er bestilt er det samlede antal kald på samtlige datatyper for registeret pr. cvr udstillet på stamkort for aftaler fra den 1/3-15
Medicinpriser (taksten)  SKRS 

Udtræk fra sla log på GenericCallParms(x):

register=dkma,

datatype=administrationsvej

datatype=atc

datatype=beregningsregler

datatype=dosering

...

Hvis adgangen er bestilt er det samlede antal kald på samtlige datatyper for registeret pr. cvr udstillet på stamkort for aftaler fra den 1/3-15
Sikrede  SKRS 

Udtræk fra sla log på GenericCallParms(x):

register=sikrede,

datatype=sikrede

Hvis adgangen er bestilt, er antal kald på registeret pr. cvr udstillet på stamkort for aftaler fra den 1/3-15
SKS  SKRS 

Udtræk fra sla log på GenericCallParms(x):

register=sks

datatype=institution

Hvis adgangen er bestilt er antal kald på registeret pr. cvr udstillet på stamkort for aftaler fra den 1/3-15
SOR  SKRS 

Udtræk fra sla log på GenericCallParms(x):

register=sor,

datatype=apotek

datatype=paksis

...

Hvis adgangen er bestilt er det samlede antal kald på samtlige datatyper for registeret pr. cvr udstillet på stamkort for aftaler fra den 1/3-15
Tilknyttede behandlinger  SKRS 

Udtræk fra sla log på GenericCallParms(x):

register=tilknyttedebehandlinger,

datatype=additionalname

datatype=supplementtreatment

Hvis adgangen er bestilt er det samlede antal kald på samtlige datatyper for registeret pr. cvr udstillet på stamkort for aftaler fra den 1/3-15
Tilskudsblanket  SKRS 

Udtræk fra sla log på GenericCallParms(x):

register=tilskudsblanket,

datatype=blanket

datatype=blanketenkelt

datatype=blanketforhoejet

datatype=blanketkroniker

datatype=blanketterminal

datatype=forhoejettakst

Hvis adgangen er bestilt er det samlede antal kald på samtlige datatyper for registeret pr. cvr udstillet på stamkort for aftaler fra den 1/3-15
Vaccination (DDV)  SKRS 

Udtræk fra sla log på GenericCallParms(x):

register=ddv,

datatype=diseases

datatype=diseases_vaccines

datatype=dosageoptions

datatype=ssidrugs

datatype=vaccinationplan

datatype=vaccinationplanitems

datatype=vaccines

datatype=vaccines_drugs

Hvis adgangen er bestilt er det samlede antal kald på samtlige datatyper for registeret pr. cvr udstillet på stamkort for aftaler fra den 1/3-15
Vitaminer  SKRS 

Udtræk fra sla log på GenericCallParms(x):

register=vitamin,

datatype=firmadata

datatype=grunddata

datatype=indholdsstoffer

datatype=udgaaedenavne

Hvis adgangen er bestilt er det samlede antal kald på samtlige datatyper for registeret pr. cvr udstillet på stamkort for aftaler fra den 1/3-15
Yder  SKRS 

Udtræk fra sla log på GenericCallParms(x):

register=yder,

datatype=person

datatype=yder

Hvis adgangen er bestilt er det samlede antal kald på begge datatyper for registeret pr. cvr udstillet på stamkort for aftaler fra den 1/3-15

Stamdata enkeltopslag (SCES, SAES)

Service/funktionalitetServiceadresse / endpointBeskrivelseKomponentProxy adgangeForretningsproduktDefinition af målepunktUdstilling
Enkeltopslagsservices 

Tilbyder enkeltopslag i autorisationsregisteret og cpr-registeret

Autorisation enkeltopslag (SAES)

CPR enkeltopslag (SCES)

Adgang kræver STS signeret system id-kort

     
CPR enkeltopslag (uden læge)

https://[host]:[port]/stamdata-cpr-ws/service/StamdataPersonLookup

 

SCES uden lægeoplysninger

https://wsdl.nspop.dk/stamdata-cpr-ws/service/StamdataPersonLookup?wsdl (:getPersonDetails)

SCESDCCcpr enkeltopslag

kald på endpoint med action getPersonDetails

Kald for cvr udstilles på stamkort for aftalen pr 1/3-15
Det gode CPR opslag (med læge) (v.1.0.0)https://[host:[port]]/stamdata-cpr-ws/service/DetGodeCPROpslag

SCES med lægeoplysninger

https://wsdl.nspop.dk/stamdata-cpr-ws/service/DetGodeCPROpslag?wsdl (:getPersonInformation, :getPersonWithHealthCareInformation)

SCESDCCDet gode cpr opslag v1

Samlede antal kald på endpoint med actions getPersonInformation og getPersonWithHealthCareInformation 

Kald udstilles ikke, da kald går videre til v2

Det gode CPR opslag (med læge) (v.1.0.2)

  • anbefalet

 

https://[host]:[port]/stamdata-cpr-ws/service/DetGodeCPROpslag-1.0.2

SCES med lægeoplysninger

https://wsdl.nspop.dk/stamdata-cpr-ws/service/DetGodeCPROpslag-1.0.2?wsdl (:getPersonInformation, :getPersonWithHealthCareInformation)

SCESDCCDet gode cpr opslag v2Samlede antal kald på endpoint med actions getPersonInformation og getPersonWithHealthCareInformation Kald for cvr udstilles på stamkort for aftalen pr 1/3-15
Autorisation enkeltopslag

https://[host]:[port]/stamdata-authorization-lookup-ws/service/AuthorizationService

 

SAES

https://wsdl.nspop.dk/stamdata-authorization-lookup-ws/service/AuthorizationService?wsdl (:Authorization)

SAESDCCAutorisation enkeltopslag

Kald på endpoint

Kald for cvr udstilles på stamkort for aftalen pr 1/3-15

 

Adgang til ekstern service gennem delegerende NSP service

Service/funktionalitetServicenavnBeskrivelseKomponenterProxyadgangeForretningsproduktDefinition af målepunktUdstilling

Indberetning af fødselsanmeldelser

(Adgang til fødselsindberetningsservice)

/fibs

Adgang til FIBS - sker gennem NSP service som kalder videre

https://wsdl.nspop.dk/fibs/?wsdl (:Input)

FIBS

 

DCC

FødselsindberetningKald på endpoint med action InputKald for cvr udstilles på stamkort for aftalen pr 1/3-15

Indberetning af bivirkninger

(Adgang til bivirkningsservice)

/bivwsp/submissionservice

Adgang til Bivirkningswebservice - sker gennem NSP service som kalder videre

https://wsdl.nspop.dk/bivwsp/submissionservice?wsdl (:UploadE2B, :ValidateE2B, :UploadE2BXml, :ValidateE2BXml)

BIVWSP

 

DCC

 

BivirkningsindberetningSamlede antal kald på endpoint med actions UploadE2B og ValidateE2BKald for cvr udstilles på stamkort for aftalen pr 1/3-15

Direkte adgang til eksterne services

Service/funktionalitetBeskrivelseKomponenterProxyadgangeForretningsproduktDefinition af målepunktUdstilling
Adgang til FMKAdgang til FMK - direkte fra proxy-komponent til ekstern komponent.Ekstern service

DCC

DCC+Gateway

Gateway

Gateway+DCC

  kald for cvr udstilles på stamkort for aftalen pr 1/3-15
 Adgang til DDVAdgang til vaccinationsregister - direkte fra proxy-komponent til ekstern komponentEkstern service

DCC

DCC+Gateway

Gateway

Gateway+DCC

 
  kald for cvr udstilles på stamkort for aftalen pr 1/3-15

 

Opsummering af mulige adgangsveje.

Sammenfattende kan adgangen således passere først 0-2 proxy komponenter, herefter 0-2 NSP komponenter og til sidst 0-1 ekstern komponent.

Bemærk at SOSI-GW afhængig af anvendelsen kan spille rollen som enten proxy-servies eller NSP komponent.

Etablering af SLA målinger kræver mulighed for at korellere samme kald på tværs af komponenter for at undgå dobbelt-målinger. Endvidere er det ønskeligt at sammenholde dette med eksterne kald - idet tid anvendt i en ekstern komponent (f.eks. FMK) ikke bør medregnes i SLA for NSP-platformen.

 

 

 

kald for cvr udstilles på stamkort for aftalen pr 1/3-15

/*
 * The contents of this file is the CONFIDENTAL and PROPRIETARY
 * property of Arosii Information Systems A/S. Any unauthorized use,
 * reproduction or transfer of this file is strictly prohibited.
 *
 * Copyright (C) 2012 Arosii Information Systems A/S.  All rights reserved.
 * This is an unpublished work, and is subject to limited
 * distribution and restricted disclosure only.
 */
package dk.nsi.nsp.guides.nas;

import dk.medcom.dgws._2006._04.dgws_1_0.Header;
import dk.nsi._2012._12.nas.idlist.CreateIDListRequest;
import dk.nsi._2012._12.nas.idlist.CreateIDListResponse;
import dk.nsi._2012._12.nas.idlist.DestroyIDListRequest;
import dk.nsi._2012._12.nas.idlist.DestroyIDListResponse;
import dk.nsi._2012._12.nas.idlist.IDList;
import dk.nsi._2012._12.nas.idlist.IDListService;
import dk.nsi.advis.v10.IDFilter;
import dk.nsi.advis.v10.NotifyContent;
import dk.nsi.nsp.guides.common.http.JAXBHelper;
import dk.nsi.nsp.guides.common.http.RequestHelper;
import dk.nsi.nsp.guides.common.http.StsHelper;
import dk.sosi.seal.SOSIFactory;
import dk.sosi.seal.model.AuthenticationLevel;
import dk.sosi.seal.model.CareProvider;
import dk.sosi.seal.model.Request;
import dk.sosi.seal.model.SignatureUtil;
import dk.sosi.seal.model.SystemIDCard;
import dk.sosi.seal.model.constants.SubjectIdentifierTypeValues;
import dk.sosi.seal.pki.SOSITestFederation;
import dk.sosi.seal.vault.ClasspathCredentialVault;
import dk.sosi.seal.vault.CredentialVault;
import org.junit.Before;
import org.junit.Test;
import org.oasis_open.docs.wsn.b_2.CreatePullPoint;
import org.oasis_open.docs.wsn.b_2.CreatePullPointResponse;
import org.oasis_open.docs.wsn.b_2.DestroyPullPoint;
import org.oasis_open.docs.wsn.b_2.DestroyPullPointResponse;
import org.oasis_open.docs.wsn.b_2.FilterType;
import org.oasis_open.docs.wsn.b_2.GetMessages;
import org.oasis_open.docs.wsn.b_2.GetMessagesResponse;
import org.oasis_open.docs.wsn.b_2.NotificationMessageHolderType;
import org.oasis_open.docs.wsn.b_2.NotificationMessageHolderType.Message;
import org.oasis_open.docs.wsn.b_2.Notify;
import org.oasis_open.docs.wsn.b_2.NotifyResponse;
import org.oasis_open.docs.wsn.b_2.ObjectFactory;
import org.oasis_open.docs.wsn.b_2.QueryExpressionType;
import org.oasis_open.docs.wsn.b_2.Subscribe;
import org.oasis_open.docs.wsn.b_2.SubscribeResponse;
import org.oasis_open.docs.wsn.b_2.TopicExpressionType;
import org.oasis_open.docs.wsn.b_2.Unsubscribe;
import org.oasis_open.docs.wsn.b_2.UnsubscribeResponse;
import org.oasis_open.docs.wsn.bw_2.NotificationConsumer;
import org.oasis_open.docs.wsn.bw_2.NotificationConsumerService;
import org.oasis_open.docs.wsn.bw_2.NotificationProducer;
import org.oasis_open.docs.wsn.bw_2.NotificationProducerService;
import org.oasis_open.docs.wsn.bw_2.PullPoint;
import org.oasis_open.docs.wsn.bw_2.PullPointFactoryService;
import org.oasis_open.docs.wsn.bw_2.PullPointService;
import org.oasis_open.docs.wss._2004._01.oasis_200401_wss_wssecurity_secext_1_0.Security;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xmlsoap.schemas.soap.envelope.Body;
import org.xmlsoap.schemas.soap.envelope.Envelope;

import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBElement;
import javax.xml.namespace.NamespaceContext;
import javax.xml.namespace.QName;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.soap.SOAPMessage;
import javax.xml.transform.dom.DOMResult;
import javax.xml.ws.BindingProvider;
import javax.xml.ws.Holder;
import javax.xml.ws.handler.Handler;
import javax.xml.ws.handler.MessageContext;
import javax.xml.ws.handler.soap.SOAPHandler;
import javax.xml.ws.handler.soap.SOAPMessageContext;
import javax.xml.ws.wsaddressing.W3CEndpointReference;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathFactory;
import java.math.BigInteger;
import java.security.cert.X509Certificate;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
import java.util.UUID;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;

/**
 * 
 * @author Jacob Qvortrup
 */
public class SubscriptionExample {

	private static final String TOPIC_EXPRESSION_TYPE_SIMPLE = "http://docs.oasis-open.org/wsn/t-1/TopicExpression/Simple";

	private static final String ADVIS_NAMESPACE = "http://nsi.dk/nsp/guides/nas";

	private static final String ADVIS_LOCAL_NAME = "SubscriptionExample";

	private static final String ADVIS_TEXT_CONTENT = "This could be any xml structure";

	private static final String ID_LIST_DESCRIPTION = "NSP K3G NAS Example";

	private static final String ID_TYPE_UUID = "http://nsi.dk/advis/v10/UUID";

	/** The type of identification used for the organization */
	private String org_type = SubjectIdentifierTypeValues.CVR_NUMBER;

	/** The identification of the organization (Here a CVR number), must match the one in the certificate */
	private String org_id = "46837428";

	/** The name of the organization */
	private String org_name = "Statens Serum Institut";

	/** This Java keystore file is located inside the classpath */
	private String keystore_path = "Statens_Serum_Institut_FOCES.jks";

	/** The password for the Seal Testtools keystore file */
	private String keystore_password = "!234Qwer";

	/** The name of the IT system calling NAS */
	private String it_system_name = "Kom Godt i Gang Guider";

	/** The topic used for the notifications */
	private String topic = "nsi201410:GuidesTopic";

	/** The identification of the notification */
	private String notification_identification;

	/** The name of the identification list used */
	private String identification_list_name;

	/** The Id List Service endpoint that will be used */
	private String idlist_endpoint = "http://test2.ekstern-test.nspop.dk:8080/idlist/service";

	/** The Pullpoint Factory Service endpoint that will be used */
	private String pullpointfactory_endpoint = "http://test2.ekstern-test.nspop.dk:8080/pullpointfactory/service";

	/** The Subscription Manager Service endpoint that will be used */
	private String subscriptionmanager_endpoint = "http://test2.ekstern-test.nspop.dk:8080/subscriptionmanager/service";

	/** The Notofication Broker Service endpoint that will be used */
	private String notificationbroker_endpoint = "http://test2.ekstern-test.nspop.dk:8080/notificationbroker/service";

	/** The Pullpoint Service endpoint that will be used */
	private String pullpoint_endpoint = "http://test2.ekstern-test.nspop.dk:8080/pullpoint/service";

	@Before
	public void generateUUIDs() {
		/*
		 * Create random identifications for the id lists and notifications
		 */
		notification_identification = UUID.randomUUID().toString();
		identification_list_name = "dk:nsi:nsp:guides:nas:" + UUID.randomUUID().toString();
		topic = "nsi201410:Guides:" + UUID.randomUUID().toString();
	}

	private static class SosiHeader {
		public final Security securityHeader;
		public final Holder<Header> medcomHeader;

		private SosiHeader(Security securityHeader, Holder<Header> medcomHeader) {
			this.securityHeader = securityHeader;
			this.medcomHeader = medcomHeader;
		}
	}

	private SosiHeader createHeader(SOSIFactory sosiFactory, SystemIDCard stsSignedIdCard) throws Exception {
		JAXBContext jaxbContext = JAXBContext.newInstance(Security.class, Header.class);
		XPath xpath = XPathFactory.newInstance().newXPath();
		xpath.setNamespaceContext(new DGWSNSContext());
		Request sosiRequest = sosiFactory.createNewRequest(false, UUID.randomUUID().toString()); // Flow id provided and Message ID generated
		sosiRequest.setIDCard(stsSignedIdCard);
		sosiRequest.setDGWSVersion("1.0.1");
		Document sosiRequestDocument = sosiRequest.serialize2DOMDocument();
		Node securityNode = (Node) xpath.compile("//soap:Header/wssec:Security").evaluate(sosiRequestDocument, XPathConstants.NODE);
		Security securityHeader = jaxbContext.createUnmarshaller().unmarshal(securityNode, Security.class).getValue();
		Node medcomHeaderNode = (Node) xpath.compile("//soap:Header/medcom:Header").evaluate(sosiRequestDocument, XPathConstants.NODE);
		Holder<Header> medcomHeader = new Holder<Header>(jaxbContext.createUnmarshaller().unmarshal(medcomHeaderNode, Header.class).getValue());

		return new SosiHeader(securityHeader, medcomHeader);
	}

	@Test
	public void subscribeExampleWithJAXWS() throws Exception {
		/*
		 * Create the SOSI factory containing a credential vault and get a signed id card from STS
		 */
		SOSIFactory sosiFactory = createSOSIFactory();
		SystemIDCard stsSignedIdCard = getStsSignedIdCard(sosiFactory);
		assertNotNull("No IdCard was received", stsSignedIdCard);

		/*
		 * Build Security and Medcom header from a Seal Request as JAXB objects
		 */
		SosiHeader sosiHeader = createHeader(sosiFactory, stsSignedIdCard);

		/*
		 * Create an id list containing the single UUID in the notification_identification variable.
		 */
		System.out.println("Creating an identification list named '" + identification_list_name + "' containing the identification '" + notification_identification + "'");
		IDListService createIdListService = new IDListService(getClass().getResource("wsdl/idlist.wsdl"), new QName("http://www.nsi.dk/2012/12/nas/idlist", "IDListService"));
		IDList createIdListPort = createIdListService.getSoap();
		setEndpoint(createIdListPort, idlist_endpoint);
		CreateIDListRequest createIDListRequest = createIdListRequest(identification_list_name, notification_identification);
		CreateIDListResponse createIDListResponse = createIdListPort.createIDList(createIDListRequest, sosiHeader.securityHeader, sosiHeader.medcomHeader);
		assertFalse(createIDListResponse.isExistingListUpdated());
		System.out.println();

		/*
		 * Rebuild Security and MedCom header for a new Seal Request with new flow ID and message ID
		 */
		sosiHeader = createHeader(sosiFactory, stsSignedIdCard);

		/*
		 * Create a pull point and save the endpoint reference for later use.
		 */
		System.out.println("Creating a pull point");
		PullPointFactoryService createPullPointService = new PullPointFactoryService(getClass().getResource("wsdl/pullpointfactory.wsdl"), new QName("http://docs.oasis-open.org/wsn/bw-2", "PullPointFactoryService"));
		org.oasis_open.docs.wsn.bw_2.CreatePullPoint createPullPointPort = createPullPointService.getSoap();
		setEndpoint(createPullPointPort, pullpointfactory_endpoint);
		CreatePullPoint createPullPointRequest = createPullPointRequest();
		CreatePullPointResponse createPullPointResponse = createPullPointPort.createPullPoint(createPullPointRequest, sosiHeader.securityHeader, sosiHeader.medcomHeader);
		W3CEndpointReference pullPointReference = createPullPointResponse.getPullPoint();
		assertNotNull(pullPointReference);
		System.out.println();

		/*
		 * Rebuild Security and MedCom header for a new Seal Request with new flow ID and message ID
		 */
		sosiHeader = createHeader(sosiFactory, stsSignedIdCard);

		/*
		 * Create a subscription that binds the idlist and pull point together, saving the endpoint reference for later
		 * use.
		 */
		System.out.println("Creating a subscription using the identificationn list '" + identification_list_name + "' and the pull point '" + getAddress(pullPointReference) + "'");
		NotificationProducerService subscribeService = new NotificationProducerService(getClass().getResource("wsdl/broker.wsdl"), new QName("http://docs.oasis-open.org/wsn/bw-2", "NotificationProducerService"));
		NotificationProducer subscribePort = subscribeService.getSoap();
		setEndpoint(subscribePort, subscriptionmanager_endpoint);
		Subscribe subscribeRequest = createSubscribeRequest(topic, identification_list_name, pullPointReference);
		SubscribeResponse subscribeResponse = subscribePort.subscribe(subscribeRequest, sosiHeader.securityHeader, sosiHeader.medcomHeader);
		W3CEndpointReference subscriptionReference = subscribeResponse.getSubscriptionReference();
		assertNotNull(subscriptionReference);
		System.out.println();

		/*
		 * Ensure that the subscription have been created and synchronized on all nodes.
		 */
		Thread.sleep(1000);

		/*
		 * Create a single notification on the UUID in the notification_identification variable.
		 */
		System.out.println("Sending a single notification on the identification '" + notification_identification + "'");
		NotificationConsumerService createNotificationService = new NotificationConsumerService(getClass().getResource("wsdl/broker.wsdl"), new QName("http://docs.oasis-open.org/wsn/bw-2", "NotificationConsumerService"));
		NotificationConsumer createNotificationPort = createNotificationService.getSoap();
		setEndpoint(createNotificationPort, notificationbroker_endpoint);
		Notify createNotificationRequest = createNotificationRequest(topic, notification_identification);
		createNotificationPort.notify(createNotificationRequest);
		System.out.println();

		/*
		 * Ensure that the notification have been synchronized on all nodes.
		 */
		Thread.sleep(1000);

		/*
		 * Rebuild Security and MedCom header for a new Seal Request with new flow ID and message ID
		 */
		sosiHeader = createHeader(sosiFactory, stsSignedIdCard);

		/*
		 * Pull all notifications from the pull point (There should be only the one we just created.)
		 */
		System.out.println("Getting all messages on the pullpoint '" + getAddress(pullPointReference) + "'");
		PullPointService getMessagesService = new PullPointService(getClass().getResource("wsdl/pullpoint.wsdl"), new QName("http://docs.oasis-open.org/wsn/bw-2", "PullPointService"));
		PullPoint getMessagesPort = getMessagesService.getSoap();
		setEndpoint(getMessagesPort, pullpoint_endpoint + "/" + getEndpointReferenceId(pullPointReference));
		GetMessages getMessagesRequest = createGetMessagesRequest();
		GetMessagesResponse getMessagesResponse = getMessagesPort.getMessages(getMessagesRequest, sosiHeader.securityHeader, sosiHeader.medcomHeader);
		List<NotificationMessageHolderType> notifications = getMessagesResponse.getNotificationMessage();
		assertNotNull(notifications);
		assertEquals(1, notifications.size());
		for (NotificationMessageHolderType notificationMessageHolder : notifications) {
			Object notification = notificationMessageHolder.getMessage().getAny();
			assertTrue(notification instanceof NotifyContent);
			NotifyContent content = (NotifyContent) notification;
			assertEquals(notification_identification, content.getId());
			assertEquals(ID_TYPE_UUID, content.getIdType());
			assertTrue(content.getAny() instanceof Element);
			Element element = (Element) content.getAny();
			assertEquals(ADVIS_NAMESPACE, element.getNamespaceURI());
			assertEquals(ADVIS_LOCAL_NAME, element.getLocalName());
			assertEquals(ADVIS_TEXT_CONTENT, element.getTextContent());
		}
		System.out.println();

		/*
		 * Rebuild Security and MedCom header for a new Seal Request with new flow ID and message ID
		 */
		sosiHeader = createHeader(sosiFactory, stsSignedIdCard);

		/*
		 * Destroy the subscription since we no longer need to use it.
		 */
		System.out.println("Destroying the subscription at '" + getAddress(subscriptionReference) + "'");
		NotificationProducerService unsubscribeService = new NotificationProducerService(getClass().getResource("wsdl/broker.wsdl"), new QName("http://docs.oasis-open.org/wsn/bw-2", "NotificationProducerService"));
		NotificationProducer unsubscribePort = unsubscribeService.getSoap();
		setEndpoint(unsubscribePort, subscriptionmanager_endpoint + "/" + getEndpointReferenceId(subscriptionReference));
		Unsubscribe unsubscribeRequest = createUnsubscribeRequest();
		unsubscribePort.unsubscribe(unsubscribeRequest, sosiHeader.securityHeader, sosiHeader.medcomHeader);
		System.out.println();

		/*
		 * Rebuild Security and MedCom header for a new Seal Request with new flow ID and message ID
		 */
		sosiHeader = createHeader(sosiFactory, stsSignedIdCard);

		/*
		 * Destroy the pull point since we no longer need to use it.
		 */
		System.out.println("Destroying the pull point at '" + getAddress(pullPointReference) + "'");
		PullPointService destroyPullPointService = new PullPointService(getClass().getResource("wsdl/pullpoint.wsdl"), new QName("http://docs.oasis-open.org/wsn/bw-2", "PullPointService"));
		PullPoint destroyPullPointPort = destroyPullPointService.getSoap();
		setEndpoint(destroyPullPointPort, pullpoint_endpoint + "/" + getEndpointReferenceId(pullPointReference));
		DestroyPullPoint destroyPullPointRequest = createDestroyPullPointRequest();
		destroyPullPointPort.destroyPullPoint(destroyPullPointRequest, sosiHeader.securityHeader, sosiHeader.medcomHeader);
		System.out.println();

		/*
		 * Rebuild Security and MedCom header for a new Seal Request with new flow ID and message ID
		 */
		sosiHeader = createHeader(sosiFactory, stsSignedIdCard);

		/*
		 * Destroy the id list since we no longer need to use it.
		 */
		System.out.println("Destroying the identification list '" + identification_list_name + "'");
		IDListService destroyIdListService = new IDListService(getClass().getResource("wsdl/idlist.wsdl"), new QName("http://www.nsi.dk/2012/12/nas/idlist", "IDListService"));
		IDList destroyIdListPort = destroyIdListService.getSoap();
		setEndpoint(destroyIdListPort, idlist_endpoint);
		DestroyIDListRequest destroyIDListRequest = createDestroyIdListRequest(identification_list_name);
		DestroyIDListResponse destroyIDListResponse = destroyIdListPort.destroyIDList(destroyIDListRequest, sosiHeader.securityHeader, sosiHeader.medcomHeader);
		assertFalse(destroyIDListResponse.isNoSuchList());
		System.out.println();

		System.out.println("Done");
		System.out.println();
	}

	@Test
	public void subscribeExampleWithJAXBAndDOM() throws Exception {
		/*
		 * Create the SOSI factory containing a credential vault and get a signed id card from STS
		 */
		SOSIFactory sosiFactory = createSOSIFactory();
		SystemIDCard stsSignedIdCard = getStsSignedIdCard(sosiFactory);
		assertNotNull("No IdCard was received", stsSignedIdCard);

		/*
		 * Create Security and Medcom header from a Seal Request as JAXB objects
		 */
		SosiHeader sosiHeader = createHeader(sosiFactory, stsSignedIdCard);

		JAXBHelper jaxbHelper = new JAXBHelper(Envelope.class, Security.class, Header.class, CreateIDListRequest.class, CreateIDListResponse.class, DestroyIDListRequest.class, DestroyIDListResponse.class, CreatePullPoint.class, CreatePullPointResponse.class, DestroyPullPoint.class, DestroyPullPointResponse.class, Subscribe.class, SubscribeResponse.class, IDFilter.class, Unsubscribe.class, UnsubscribeResponse.class);

		/*
		 * Create an id list containing the single UUID in the notification_identification variable.
		 */
		System.out.println("Creating an identification list named '" + identification_list_name + "' containing the identification '" + notification_identification + "'");
		CreateIDListRequest createIDListRequest = createIdListRequest(identification_list_name, notification_identification);
		Envelope createIDListRequestEnvelope = createEnvelope(sosiHeader.securityHeader, sosiHeader.medcomHeader.value, createIDListRequest);
		String createIDListRequestXml = jaxbHelper.toString(createIDListRequestEnvelope);

		System.out.println("This is the reqeust we are sending to NAS (" + idlist_endpoint + "):");
		System.out.println(createIDListRequestXml);
		String createIDListResponseXml = RequestHelper.sendRequest(idlist_endpoint, "http://www.nsi.dk/nas/idlist#CreateIDList", createIDListRequestXml);
		System.out.println("This is the response we got from NAS (" + idlist_endpoint + "):");
		System.out.println(createIDListResponseXml);
		System.out.println();

		Envelope createIDListResponseEnvelope = jaxbHelper.fromString(createIDListResponseXml);
		CreateIDListResponse createIDListResponse = (CreateIDListResponse) createIDListResponseEnvelope.getBody().getAny().get(0);
		assertFalse(createIDListResponse.isExistingListUpdated());

		/*
		 * Rebuild Security and MedCom header for a new Seal Request with new flow ID and message ID
		 */
		sosiHeader = createHeader(sosiFactory, stsSignedIdCard);

		/*
		 * Create a pull point and save the endpoint reference for later use.
		 */
		System.out.println("Creating a pull point");
		CreatePullPoint createPullPointRequest = createPullPointRequest();
		Envelope createPullPointRequestEnvelope = createEnvelope(sosiHeader.securityHeader, sosiHeader.medcomHeader.value, createPullPointRequest);
		String createPullPointRequestXml = jaxbHelper.toString(createPullPointRequestEnvelope);

		System.out.println("This is the reqeust we are sending to NAS (" + pullpointfactory_endpoint + "):");
		System.out.println(createPullPointRequestXml);
		String createPullPointResponseXml = RequestHelper.sendRequest(pullpointfactory_endpoint, "http://docs.oasis-open.org/wsn/bw-2/CreatePullPoint/CreatePullPointRequest", createPullPointRequestXml);
		System.out.println("This is the response we got from NAS (" + pullpointfactory_endpoint + "):");
		System.out.println(createPullPointResponseXml);
		System.out.println();

		Envelope createPullPointResponseEnvelope = jaxbHelper.fromString(createPullPointResponseXml);
		CreatePullPointResponse createPullPointResponse = (CreatePullPointResponse) createPullPointResponseEnvelope.getBody().getAny().get(0);
		W3CEndpointReference pullPointReference = createPullPointResponse.getPullPoint();
		assertNotNull(pullPointReference);

		/*
		 * Rebuild Security and MedCom header for a new Seal Request with new flow ID and message ID
		 */
		sosiHeader = createHeader(sosiFactory, stsSignedIdCard);

		/*
		 * Create a subscription that binds the idlist and pull point together, saving the endpoint reference for later
		 * use.
		 */
		System.out.println("Creating a subscription using the identificationn list '" + identification_list_name + "' and the pull point '" + getAddress(pullPointReference) + "'");
		Subscribe subscribeRequest = createSubscribeRequest(topic, identification_list_name, pullPointReference);
		Envelope subscribeRequestEnvelope = createEnvelope(sosiHeader.securityHeader, sosiHeader.medcomHeader.value, subscribeRequest);
		String subscribeRequestXml = jaxbHelper.toString(subscribeRequestEnvelope);

		System.out.println("This is the reqeust we are sending to NAS (" + subscriptionmanager_endpoint + "):");
		System.out.println(subscribeRequestXml);
		String subscribeResponseXml = RequestHelper.sendRequest(subscriptionmanager_endpoint, "http://docs.oasis-open.org/wsn/bw-2/NotificationProducer/SubscribeRequest", subscribeRequestXml);
		System.out.println("This is the response we got from NAS (" + subscriptionmanager_endpoint + "):");
		System.out.println(subscribeResponseXml);
		System.out.println();

		Envelope subscribeResponseEnvelope = jaxbHelper.fromString(subscribeResponseXml);
		SubscribeResponse subscribeResponse = (SubscribeResponse) subscribeResponseEnvelope.getBody().getAny().get(0);
		W3CEndpointReference subscriptionReference = subscribeResponse.getSubscriptionReference();
		assertNotNull(subscriptionReference);

		/*
		 * Ensure that the subscription have been created and synchronized on all nodes.
		 */
		Thread.sleep(1000);

		/*
		 * Rebuild Security and MedCom header for a new Seal Request with new flow ID and message ID
		 */
		sosiHeader = createHeader(sosiFactory, stsSignedIdCard);

		/*
		 * Create a single notification on the UUID in the notification_identification variable.
		 */
		System.out.println("Sending a single notification on the identification '" + notification_identification + "'");
		Notify createNotificationRequest = createNotificationRequest(topic, notification_identification);
		Envelope createNotificationRequestEnvelope = createEnvelope(sosiHeader.securityHeader, sosiHeader.medcomHeader.value, createNotificationRequest);
		String createNotificationRequestXml = jaxbHelper.toString(createNotificationRequestEnvelope);

		System.out.println("This is the reqeust we are sending to NAS (" + notificationbroker_endpoint + "):");
		System.out.println(createNotificationRequestXml);
		String createNotificationResponseXml = RequestHelper.sendRequest(notificationbroker_endpoint, "http://docs.oasis-open.org/wsn/bw-2/NotificationConsumer/Notify", createNotificationRequestXml);
		System.out.println("This is the response we got from NAS (" + notificationbroker_endpoint + "):");
		System.out.println(createNotificationResponseXml);
		System.out.println();

		Envelope createNotificationResponseEnvelope = jaxbHelper.fromString(createNotificationResponseXml);
		NotifyResponse createNotificationResponse = (NotifyResponse) createNotificationResponseEnvelope.getBody().getAny().get(0);
		assertNotNull(createNotificationResponse);

		/*
		 * Ensure that the notification have been synchronized on all nodes.
		 */
		Thread.sleep(1000);

		/*
		 * Rebuild Security and MedCom header for a new Seal Request with new flow ID and message ID
		 */
		sosiHeader = createHeader(sosiFactory, stsSignedIdCard);

		/*
		 * Pull all notifications from the pull point (There should be only the one we just created.)
		 */
		System.out.println("Getting all messages on the pullpoint '" + getAddress(pullPointReference) + "'");
		GetMessages getMessagesRequest = createGetMessagesRequest();
		Envelope getMessagesRequestEnvelope = createEnvelope(sosiHeader.securityHeader, sosiHeader.medcomHeader.value, getMessagesRequest);
		String getMessagesRequestXml = jaxbHelper.toString(getMessagesRequestEnvelope);

		System.out.println("This is the reqeust we are sending to NAS (" + pullpoint_endpoint + "/" + getEndpointReferenceId(pullPointReference) + "):");
		System.out.println(getMessagesRequestXml);
		String getMessagesResponseXml = RequestHelper.sendRequest(pullpoint_endpoint + "/" + getEndpointReferenceId(pullPointReference), "http://docs.oasis-open.org/wsn/bw-2/PullPoint/GetMessagesRequest", getMessagesRequestXml);
		System.out.println("This is the response we got from NAS (" + pullpoint_endpoint + "/" + getEndpointReferenceId(pullPointReference) + "):");
		System.out.println(getMessagesResponseXml);
		System.out.println();

		Envelope getMessagesResponseEnvelope = jaxbHelper.fromString(getMessagesResponseXml);
		GetMessagesResponse getMessagesResponse = (GetMessagesResponse) getMessagesResponseEnvelope.getBody().getAny().get(0);
		List<NotificationMessageHolderType> notifications = getMessagesResponse.getNotificationMessage();
		assertNotNull(notifications);
		assertEquals(1, notifications.size());
		for (NotificationMessageHolderType notificationMessageHolder : notifications) {
			Object notification = notificationMessageHolder.getMessage().getAny();
			assertTrue(notification instanceof NotifyContent);
			NotifyContent content = (NotifyContent) notification;
			assertEquals(notification_identification, content.getId());
			assertEquals(ID_TYPE_UUID, content.getIdType());
			assertTrue(content.getAny() instanceof Element);
			Element element = (Element) content.getAny();
			assertEquals(ADVIS_NAMESPACE, element.getNamespaceURI());
			assertEquals(ADVIS_LOCAL_NAME, element.getLocalName());
			assertEquals(ADVIS_TEXT_CONTENT, element.getTextContent());
		}

		/*
		 * Rebuild Security and MedCom header for a new Seal Request with new flow ID and message ID
		 */
		sosiHeader = createHeader(sosiFactory, stsSignedIdCard);

		/*
		 * Destroy the subscription since we no longer need to use it.
		 */
		System.out.println("Destroying the subscription at '" + getAddress(subscriptionReference) + "'");
		Unsubscribe unsubscribeRequest = createUnsubscribeRequest();
		Envelope unsubscribeRequestEnvelope = createEnvelope(sosiHeader.securityHeader, sosiHeader.medcomHeader.value, unsubscribeRequest);
		String unsubscribeRequestXml = jaxbHelper.toString(unsubscribeRequestEnvelope);

		System.out.println("This is the reqeust we are sending to NAS (" + subscriptionmanager_endpoint + "/" + getEndpointReferenceId(subscriptionReference) + "):");
		System.out.println(unsubscribeRequestXml);
		String unsubscribeResponseXml = RequestHelper.sendRequest(subscriptionmanager_endpoint + "/" + getEndpointReferenceId(subscriptionReference), "http://docs.oasis-open.org/wsn/bw-2/SubscriptionManager/UnsubscribeRequest", unsubscribeRequestXml);
		System.out.println("This is the response we got from NAS (" + subscriptionmanager_endpoint + "/" + getEndpointReferenceId(subscriptionReference) + "):");
		System.out.println(unsubscribeResponseXml);
		System.out.println();

		Envelope unsubscribeResponseEnvelope = jaxbHelper.fromString(unsubscribeResponseXml);
		UnsubscribeResponse unsubscribeResponse = (UnsubscribeResponse) unsubscribeResponseEnvelope.getBody().getAny().get(0);
		assertNotNull(unsubscribeResponse);

		/*
		 * Rebuild Security and MedCom header for a new Seal Request with new flow ID and message ID
		 */
		sosiHeader = createHeader(sosiFactory, stsSignedIdCard);

		/*
		 * Destroy the pull point since we no longer need to use it.
		 */
		System.out.println("Destroying the pull point at '" + getAddress(pullPointReference) + "'");
		DestroyPullPoint destroyPullPointRequest = createDestroyPullPointRequest();
		Envelope destroyPullPointRequestEnvelope = createEnvelope(sosiHeader.securityHeader, sosiHeader.medcomHeader.value, destroyPullPointRequest);
		String destroyPullPointRequestXml = jaxbHelper.toString(destroyPullPointRequestEnvelope);

		System.out.println("This is the reqeust we are sending to NAS (" + pullpoint_endpoint + "/" + getEndpointReferenceId(pullPointReference) + "):");
		System.out.println(destroyPullPointRequestXml);
		String destroyPullPointResponseXml = RequestHelper.sendRequest(pullpoint_endpoint + "/" + getEndpointReferenceId(pullPointReference), "http://docs.oasis-open.org/wsn/bw-2/PullPoint/DestroyPullPointRequest", destroyPullPointRequestXml);
		System.out.println("This is the response we got from NAS (" + pullpoint_endpoint + "/" + getEndpointReferenceId(pullPointReference) + "):");
		System.out.println(destroyPullPointResponseXml);
		System.out.println();

		Envelope destroyPullPointResponseEnvelope = jaxbHelper.fromString(destroyPullPointResponseXml);
		DestroyPullPointResponse destroyPullPointResponse = (DestroyPullPointResponse) destroyPullPointResponseEnvelope.getBody().getAny().get(0);
		assertNotNull(destroyPullPointResponse);

		/*
		 * Rebuild Security and MedCom header for a new Seal Request with new flow ID and message ID
		 */
		sosiHeader = createHeader(sosiFactory, stsSignedIdCard);

		/*
		 * Destroy the id list since we no longer need to use it.
		 */
		System.out.println("Destroying the identification list '" + identification_list_name + "'");
		DestroyIDListRequest destroyIDListRequest = createDestroyIdListRequest(identification_list_name);
		Envelope destroyIDListRequestEnvelope = createEnvelope(sosiHeader.securityHeader, sosiHeader.medcomHeader.value, destroyIDListRequest);
		String destroyIDListRequestXml = jaxbHelper.toString(destroyIDListRequestEnvelope);

		System.out.println("This is the reqeust we are sending to NAS (" + idlist_endpoint + "):");
		System.out.println(destroyIDListRequestXml);
		String destroyIDListResponseXml = RequestHelper.sendRequest(idlist_endpoint, "http://www.nsi.dk/nas/idlist#destroyIDList", destroyIDListRequestXml);
		System.out.println("This is the response we got from NAS (" + idlist_endpoint + "):");
		System.out.println(destroyIDListResponseXml);
		System.out.println();

		Envelope destroyIDListResponseEnvelope = jaxbHelper.fromString(destroyIDListResponseXml);
		DestroyIDListResponse destroyIDListResponse = (DestroyIDListResponse) destroyIDListResponseEnvelope.getBody().getAny().get(0);
		assertFalse(destroyIDListResponse.isNoSuchList());
		
		System.out.println("Done");
		System.out.println();
	}

	/**
	 * Creates a request used tto create an id list with the provided name and identifications.
	 */
	private static CreateIDListRequest createIdListRequest(String name, String... ids) {
		CreateIDListRequest createIDListRequest = new dk.nsi._2012._12.nas.idlist.ObjectFactory().createCreateIDListRequest();
		createIDListRequest.setName(name);
		createIDListRequest.setDescription(ID_LIST_DESCRIPTION);
		createIDListRequest.setIDType(ID_TYPE_UUID);
		createIDListRequest.getId().addAll(Arrays.asList(ids));
		return createIDListRequest;
	}

	/**
	 * Creates a request used to create a pullpoint
	 */
	private static CreatePullPoint createPullPointRequest() {
		org.oasis_open.docs.wsn.b_2.ObjectFactory objectFactory = new org.oasis_open.docs.wsn.b_2.ObjectFactory();
		CreatePullPoint createPullPointRequest = objectFactory.createCreatePullPoint();
		return createPullPointRequest;
	}

	/**
	 * Creates a request for a subscription to be created with the provided id list and pull point.
	 */
	private static Subscribe createSubscribeRequest(String topic, String idListName, W3CEndpointReference pullPointReference) {
		org.oasis_open.docs.wsn.b_2.ObjectFactory objectFactory = new org.oasis_open.docs.wsn.b_2.ObjectFactory();
		Subscribe subscribeRequest = objectFactory.createSubscribe();
		subscribeRequest.setConsumerReference(pullPointReference);
		FilterType filterType = objectFactory.createFilterType();
		subscribeRequest.setFilter(filterType);
		TopicExpressionType topicExpressionType = objectFactory.createTopicExpressionType();
		topicExpressionType.setDialect(TOPIC_EXPRESSION_TYPE_SIMPLE);
		topicExpressionType.getContent().add(topic);
		filterType.getAny().add(objectFactory.createTopicExpression(topicExpressionType));
		QueryExpressionType queryExprType = objectFactory.createQueryExpressionType();
		queryExprType.setDialect("http://nsi.dk/advis/v10/IDMCP_Dialect");
		JAXBElement<QueryExpressionType> messageContent = objectFactory.createMessageContent(queryExprType);
		filterType.getAny().add(messageContent);
		dk.nsi.advis.v10.ObjectFactory filterObjectFactory = new dk.nsi.advis.v10.ObjectFactory();
		IDFilter idFilter = filterObjectFactory.createIDFilter();
		dk.nsi.advis.v10.IDList idList = filterObjectFactory.createIDList();
		idList.setName(idListName);
		idFilter.setIDList(idList);
		messageContent.getValue().getContent().add(idFilter);
		return subscribeRequest;
	}

	/**
	 * Creates a request used to send a single notification on the provided identification
	 */
	private static Notify createNotificationRequest(String topic, String id) {
		org.oasis_open.docs.wsn.b_2.ObjectFactory objectFactory = new org.oasis_open.docs.wsn.b_2.ObjectFactory();
		Notify request = objectFactory.createNotify();
		NotificationMessageHolderType notificationMessageHolderType = objectFactory.createNotificationMessageHolderType();
		TopicExpressionType topicExpressionType = objectFactory.createTopicExpressionType();
		topicExpressionType.setDialect(TOPIC_EXPRESSION_TYPE_SIMPLE);
		topicExpressionType.getContent().add(topic);
		notificationMessageHolderType.setTopic(topicExpressionType);
		dk.nsi.advis.v10.ObjectFactory filterObjFactory = new dk.nsi.advis.v10.ObjectFactory();
		NotifyContent notifyContent = filterObjFactory.createNotifyContent();
		notifyContent.setId(id);
		notifyContent.setIdType(ID_TYPE_UUID);
		notifyContent.setIsSystemNotification(false);
		notifyContent.setAny(new JAXBElement<String>(new QName(ADVIS_NAMESPACE, ADVIS_LOCAL_NAME), String.class, ADVIS_TEXT_CONTENT));
		Message message = objectFactory.createNotificationMessageHolderTypeMessage();
		message.setAny(notifyContent);
		notificationMessageHolderType.setMessage(message);
		request.getNotificationMessage().add(notificationMessageHolderType);
		return request;
	}

	/**
	 * Creates a request used to get at most 10 new notifications.
	 */
	private static GetMessages createGetMessagesRequest() {
		org.oasis_open.docs.wsn.b_2.ObjectFactory objectFactory = new org.oasis_open.docs.wsn.b_2.ObjectFactory();
		GetMessages getMessagesRequest = objectFactory.createGetMessages();
		getMessagesRequest.setMaximumNumber(BigInteger.valueOf(10));
		return getMessagesRequest;
	}

	/**
	 * Creates a request used to cancel a subscription
	 */
	private static Unsubscribe createUnsubscribeRequest() {
		org.oasis_open.docs.wsn.b_2.ObjectFactory objectFactory = new org.oasis_open.docs.wsn.b_2.ObjectFactory();
		Unsubscribe unsubscribeRequest = objectFactory.createUnsubscribe();
		return unsubscribeRequest;
	}

	/**
	 * Creates a request used to destroy a pull point
	 */
	private static DestroyPullPoint createDestroyPullPointRequest() {
		org.oasis_open.docs.wsn.b_2.ObjectFactory objectFactory = new org.oasis_open.docs.wsn.b_2.ObjectFactory();
		DestroyPullPoint destroyPullPointRequest = objectFactory.createDestroyPullPoint();
		return destroyPullPointRequest;
	}

	/**
	 * Creates a request used to destroy the id list identified by the provided name.
	 */
	private static DestroyIDListRequest createDestroyIdListRequest(String idListName) {
		dk.nsi._2012._12.nas.idlist.ObjectFactory objectFactory = new dk.nsi._2012._12.nas.idlist.ObjectFactory();
		DestroyIDListRequest destroyIDListRequest = objectFactory.createDestroyIDListRequest();
		destroyIDListRequest.setName(idListName);
		return destroyIDListRequest;
	}

	/**
	 * Insert the handler chain to print the content of the messages and overwrite the endpoint address given in the
	 * wsdl file.
	 */
	private static void setEndpoint(Object servicePort, String endpoint) {
		BindingProvider bindingProvider = (BindingProvider) servicePort;
		bindingProvider.getBinding().setHandlerChain(PrintSOAPMessageHandler.HANDLER_CHAIN);
		bindingProvider.getRequestContext().put(BindingProvider.ENDPOINT_ADDRESS_PROPERTY, endpoint);
	}

	/**
	 * Extract the last part of the URL in the provided reference.
	 */
	private static String getEndpointReferenceId(W3CEndpointReference epr) throws ParserConfigurationException {
		String address = getAddress(epr);
		String[] addressArray = address.split("/");
		return addressArray[addressArray.length - 1];
	}

	/**
	 * Extract the address (URL) from the endpoint reference.
	 */
	private static String getAddress(W3CEndpointReference epr) throws ParserConfigurationException {
		Document document = DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument();
		Element element = document.createElement("element");
		epr.writeTo(new DOMResult(element));
		NodeList nl = element.getElementsByTagNameNS("http://www.w3.org/2005/08/addressing", "Address");
		String result = "";
		if (nl != null && nl.getLength() > 0) {
			Element e = (Element) nl.item(0);
			result = e.getTextContent();
		}
		return result;
	}

	/**
	 * Builds a SOSI factory that will validate all documents created. The factory is configured to work in the test
	 * federation.
	 */
	private SOSIFactory createSOSIFactory() {
		Properties props = SignatureUtil.setupCryptoProviderForJVM();
		props.setProperty(SOSIFactory.PROPERTYNAME_SOSI_VALIDATE, Boolean.toString(true));
		CredentialVault vault = new ClasspathCredentialVault(props, keystore_path, keystore_password);
		SOSIFactory sosiFactory = new SOSIFactory(new SOSITestFederation(new Properties()), vault, props);
		return sosiFactory;
	}

	/**
	 * Constructs a FOCES signed ID-card and requests the STS to sign it. For the purpose of calling SAES, one could
	 * have used a VOCES to initially sign.
	 */
	private SystemIDCard getStsSignedIdCard(SOSIFactory sosiFactory) {
		// Null since we do not create level 2 id cards in this example
		String idcard_username = null;
		// Null since we do not create level 2 id cards in this example
		String idcard_password = null;
		// Null since we let Seal deside what our nameid should be
		String idcard_alternative_identifier = null;

		CareProvider careProvider = new CareProvider(org_type, org_id, org_name);
		X509Certificate certificate = sosiFactory.getCredentialVault().getSystemCredentialPair().getCertificate();
		SystemIDCard systemIDCard = sosiFactory.createNewSystemIDCard(it_system_name, careProvider, AuthenticationLevel.VOCES_TRUSTED_SYSTEM, idcard_username, idcard_password, certificate, idcard_alternative_identifier);
		return StsHelper.getSTSSignedIdCard(sosiFactory, systemIDCard, StsHelper.DEFAULT_STS_ENDPOINT);
	}

	/**
	 * Wrap the two DGWS headers and a request body into a JAXB SOAP Envelope instance
	 */
	private Envelope createEnvelope(Security securityHeader, Header medcomHeader, Object requestBody) {
		Body body = new Body();
		body.getAny().add(requestBody);

		org.xmlsoap.schemas.soap.envelope.Header header = new org.xmlsoap.schemas.soap.envelope.Header();
		header.getAny().add(securityHeader);
		header.getAny().add(medcomHeader);

		Envelope envelope = new Envelope();
		envelope.setHeader(header);
		envelope.setBody(body);
		return envelope;
	}

	@SuppressWarnings("rawtypes")
	private static class PrintSOAPMessageHandler implements SOAPHandler<SOAPMessageContext> {

		public static final Handler HANDLER = (Handler) new PrintSOAPMessageHandler();

		public static final List<Handler> HANDLER_CHAIN = Arrays.asList(HANDLER);

		/**
		 * {@inheritDoc}
		 */
		@Override
		public boolean handleMessage(SOAPMessageContext context) {
			printMessage(context);
			return true;
		}

		/**
		 * {@inheritDoc}
		 */
		@Override
		public boolean handleFault(SOAPMessageContext context) {
			printMessage(context);
			return true;
		}

		/**
		 * {@inheritDoc}
		 */
		@Override
		public void close(MessageContext context) {
		}

		/**
		 * {@inheritDoc}
		 */
		@Override
		public Set<QName> getHeaders() {
			return null;
		}

		private void printMessage(SOAPMessageContext context) {
			Boolean outboundProperty = (Boolean) context.get(MessageContext.MESSAGE_OUTBOUND_PROPERTY);
			String endpointAddress = (String) context.get(BindingProvider.ENDPOINT_ADDRESS_PROPERTY);
			if (outboundProperty.booleanValue()) {
				System.out.println("This is the reqeust we are sending to NAS (" + endpointAddress + "):");
			} else {
				System.out.println("This is the response we got from NAS (" + endpointAddress + "):");
			}

			SOAPMessage message = context.getMessage();
			try {
				message.writeTo(System.out);
				System.out.println();
			} catch (Exception e) {
				System.out.println("Exception in handler:");
				e.printStackTrace();
			}
		}
	}

	/**
	 * A simple namespace context that knows the namespaces used in DGWS.
	 */
	private static class DGWSNSContext implements NamespaceContext {

		private final static Map<String, String> nsMap = new HashMap<String, String>();

		static {
			nsMap.put("hsuid", "http://www.nsi.dk/hsuid/2012/03/hsuid-1.0.xsd");
			nsMap.put("wssec", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd");
			nsMap.put("medcom", "http://www.medcom.dk/dgws/2006/04/dgws-1.0.xsd");
			nsMap.put("soap", "http://schemas.xmlsoap.org/soap/envelope/");
			nsMap.put("saml", "urn:oasis:names:tc:SAML:2.0:assertion");
			nsMap.put("ds", "http://www.w3.org/2000/09/xmldsig#");
		}

		@Override
		public String getNamespaceURI(String prefix) {
			return nsMap.get(prefix);
		}

		@Override
		public String getPrefix(String namespaceURI) {
			return null;
		}

		@Override
		public Iterator<?> getPrefixes(String namespaceURI) {
			return null;
		}
	}
}
  • No labels