Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

Code Block
languagejs
export interface NAP {
	fromHost$: Observable<NAPMessage>;
	toHost$: Subject<NAPMessage>;
	errors$: Observable<NAPError>;
	subscribe: (subscriber: NAPHostSubscriber) => void; 
	unsubscribe: (subscriber: NAPHostSubscriber) => void; 
	send: (message: NAPMessage) => void;
}
NavnForklaring
fromHost$

...

Beskeder af NAPMessages fra værtssystemet. Udstillet som en Observable.
toHost$

...

Send en NAPMessage til hosten. Denne er udstillet som et subject, som man kan skubbe beskeder til med next().
errors$

...

SDK fejl, udstillet som en Observable.
subscribe

...

Subscriber til NAPMessages fra værtsystemet. Det fungere på samme måde som med `fromHost$`, bare uden brug af observables.
unsubscribe

...

Unsubscribe af NAPMessages fra værtssystemet.
send

...

()Send en NAPMessage - Det fungerer på samme måde som to `toHost$`, bare uden brug af observables.


Denne wrapping foregår i createNAP() funktion, som SDKet eksporterer. En NAP bro kan således fanges gennem sdket ved et simpel kald:

...

Den grundlæggende model for nap beskeder, der kører over (fromHost$, toHost$, subscrbe subscribe og send).

Består af følgende felter, hvor context propertien, er meget inspireret af FHIR / FHIRcast (https://fhircast.org/specification/Feb2020Ballot/),.

Code Block
languagejs
export interface NAPMessage {
  date: string;
  id: string;
  event: NAPEvent;
}
export interface NAPEvent {
  type: NAPEventType;
  context?: FHIR.Context[];
}

Eventkataloget definerer de eventtyper, der kan sendes over NAP i en given version.

...

Dette eventkatalog lægger sig op af FHIR / FHIRcast.

...

Eventkatalog version 1

...


export interface Context {
    resource?: {
        resourceType: string;
        meta?: Meta;
        code?: {
            coding: Coding[];
        };
        name?: Name[];
        identifier?: Identifier[];
        extension?: Extension[];
    };
}
export interface Name {
    family: string;
    given: string[];
}
export interface Extension {
    url: string;
    value: string;
}
export interface Identifier {
    system: string;
    value: string;
}
export interface Coding {
    system: string;
    code: string;
}
export interface Meta {
    profile: string[];
}

Eventkataloget definerer de eventtyper, der kan sendes over NAP i en given version.

Der er fortaget en minimal implementation af FHIR for at kunne opfylde nedenstående eventkatalog.


Eventkatalog

Dette eventkatalog lægger sig op af FHIR / FHIRcast.

Eventkatalog version 1

NAPEventTypeFunktionelle beskrivelse
SessionOpenStart en trusted session hvor brugerens SAMLassertion overføres
SessionCloseHvis en bruger ønskes lukkes ud. Alt state skal slettes på web-applikationen
PatientOpenDen brugervalgte patient journal.
PatientCloseDen brugervalgte patient journal lukkes.
SessionErrorHvis der sker en uventet fejl i gæstesystemet skal dette sendes til værtssystemet og vice versa.


Eksempel på at anvendelse af eventkatalog version 1: 

Code Block
languagejs
import { NAPEventCatalogue } from 'nap-typescript-sdk';
const sessionCloseEvent = NAPEventCatalogue.v1.SessionClose;

NAPError

Model for de SDK fejl. Disse beskeder sendes, hvis sker der fejl i createNAP() kaldet -  når NAP bridge skal wrappes.

Code Block
languagejs
export interface NAPError {
  id: number;
  message: string;
  isFatal: boolean;
}

Eksempel på brug af errors$

Fejl bliver således skrevet i web konsollen.

Code Block
languagejs
this.napAngular.errors$.subscribe(res => {
     console.error(res);
    });

Eksemplet er taget fra NapRefWeb Referenceimplementering (NAP) - Leverancebeskrivelse.

Hjælpefunktioner

Nap-typescript-sdk indeholder derudover en række hjælpefunktioner, som kan være brugbare til at hente værdier eller undgå stavefejl, når der skal laves NAPMessages.

Komplet liste over hjælpefunktioner:

Funktion

getSessionValue(napMessage: NAPMessage): string | undefined

Henter samlAssertion. Returnere undefined, hvis ikke data kan formateres.

getPatientInfo(napMessage: NAPMessage): NAPPatientInfo | undefinedHenter patientinfo. Returnere undefined, hvis ikke data kan formateres.
filterEvents(type: string): Observable<NAPMessage>Filtrer på et array eventtypes. Returnerer en observable, der førte emitter, hvis et event med en af de angevne typer emittes fra source.

filterEvent(type: string): Observable<NAPMessage>

Filtrer på en event. Returnerer en observable, der førte emitter, hvis et event med en den angevne type emittes fra source.


Fhir-Value-getter

Funktioner, som gør det lettere at hente FHIR specifikke værdier ud af en NAPMessage. Disse kan bruges ved at importere namespacet FHIRValueGetter.

Eksempel på anvendelse Fhir-value-getter

Følgende eksempel mapper en NAPMessage til en SAMLassertion og PatientInfo.

Code Block
languagejs
import { FHIRValueGetter, NAPMessage, NAPPatientInfo } from 'nap-typescript-sdk';
const sessionToken = FHIRValueGetter.getSessionValue(napMessage);
const patientData: NAPPatientInfo = FHIRValueGetter.getSessionValue(napMessage);

Eksempel på anvendelse af filterEvents

Code Block
languagejs
import {filterEvents, NAPEventCatalogue} from 'nap-typescript-sdk';

nap.incomming$.pipe(

Eksempel på at anvendelse af eventkatalog version 1: 

Code Block
languagejs
import { NAPEventCatalogue } from 'nap-typescript-sdk';
const sessionCloseEvent = NAPEventCatalogue.v1.SessionClose;

NAPError

Model for de SDK fejl. Disse beskeder sendes, hvis sker der fejl i createNAP() kaldet -  når NAP bridge skal wrappes.

Code Block
languagejs
export interface NAPError {
  id: number;
  message: string;
  isFatal: boolean;
}

Eksempel på brug af errors$

Fejl bliver således skrevet i web konsollen.

Code Block
languagejs
this.napAngular.errors$.subscribe(res => {
     console.error(res);
    });

Eksemplet er taget fra NapRefWeb Referenceimplementering (NAP) - Leverancebeskrivelse.

Hjælpefunktioner

Nap-typescript-sdk indeholder derudover en række hjælpefunktioner, som kan være brugbare til at hente værdier eller undgå stavefejl, når der skal laves NAPMessages.

Fhir-Value-getter

Funktioner, som gør det lettere at hente FHIR specifikke værdier ud af en NAPMessage. Disse kan bruges ved at importere namespacet FHIRValueGetter.

Eksempel på anvendelse Fhir-value-getter

Følgende eksempel mapper en NAPMessage til en SAMLassertion og PatientInfo.

Code Block
languagejs
import { FHIRValueGetter, NAPMessage, NAPPatientInfo } from 'nap-typescript-sdk';
const sessionToken = FHIRValueGetter.getSessionValue(napMessage);
const patientData: NAPPatientInfo = FHIRValueGetter.getSessionValue(napMessage);

Fhir-Value-Setter

Enums som gør det nemmere at lave NAPMessages indholdende data.

Eksempel på anvendelse Fhir-Value-Setter

Følgende er et eksempel hvordan der sendes en fejlbesked.

Code Block
languagejs
import {NAPMessage, NAPEventCatalogue, FHIRValueSetter} from 'nap-typescript-sdk';
import { v4 as UUID } from 'uuid';

const napMessageSessionError: NAPMessage = {
  date: new Date().toISOString(),
  id: UUID(),
  event: {
    type: NAPEventCatalogue.v1.SessionError,
    context: [
      {
        resource: {
          resourceType: FHIRValueSetter.FHIRResourceType.Basic,
          code: {
            coding: [
              {
                code: NAPEventCatalogue.v1.SessionError,
                system: FHIRValueSetter.FHIRSystem.NAP,
              },
            ],
          },
          identifier: [
            {
              system: FHIRValueSetter.FHIRIdentifierSystem.NAPErrorMessage,
        filterEvents([
      value: 'This is my error message' NAPEventCatalogue.v1.SessionOpen,
            }NAPEventCatalogue.v1.SessionClose,
            {])
      )

Fhir-Value-Setter

Enums som gør det nemmere at lave NAPMessages indholdende de værdier, som overholder FHIR standarden.

Komplet liste over hjælpeværdier.

Enum

FHIRResourceType.Patient

FHIRResourceType.Basic

FHIRSystem.NAP

FHIRIdentifierSystem.CPR

FHIRIdentifierSystem.NAPErrorMessage
FHIRIdentifierSystem.NapErrorDescription
Eksempel på anvendelse Fhir-Value-Setter

Følgende er et eksempel hvordan der sendes en fejlbesked.

Code Block
languagejs
import {NAPMessage, NAPEventCatalogue, FHIRValueSetter} from 'nap-typescript-sdk';
import { v4 as UUID } from 'uuid';

const napMessageSessionError: NAPMessage = {
  date: new Date().toISOString(),
  id: UUID(),
  event: {
    type: NAPEventCatalogue.v1.SessionError,
    context: [
        system: FHIRValueSetter.FHIRIdentifierSystem.NAPErrorDescription,
              value: 'This is a longere description of the error message',
            },
          ],{
        },
 resource: {
           }resourceType: FHIRValueSetter.FHIRResourceType.Basic,
    ],      code: {
  },
};

NapTypescriptSdk.send(napMessageSessionError)

Nap-angular-sdk

Hvis du ønsker at bruge Angular som udviklingsværktøj.

Da nap-angular-sdk er en angular specifik wrapper af nap-typescript-sdk, har den en "peer dependency" hertil. 

Funktionalitet

SDK'et udstiller en service, som sørger for at kalde createNAP() fra nap-typescript-sdket og dermed initialisere kontekstbroen.

Efterfølgende subscribes der på de forskellige messagestreams, og deres emits bliver håndteret i forhold til Angulars change detection zone.

Udfra dette generer den nye observables som er tilgængelig som public felter.

Code Block
languagejs
NapAngularService {
	// attributter
	incomming$: Observable<NAPmessage>
	errors$: Observable<NAPError>
	outgoing$: Subject<NapMessage>
	sendMessage(message: NAPMessage):void
 	subscribeToMessages(callback: (message: NAPMessage) => void): void
}

Effekten for anvenderen bliver, at broen initialiseres som en singleton og at Angular opfanger beskeder sendt over broen og opdaterer UI på baggrund af disse værdier.

Eksempel på implementing af nap-angular-sdk

Følgende eksempel sender en Session-Open besked og får en SAMLassertion tilbage:

          coding: [
              {
                code: NAPEventCatalogue.v1.SessionError,
                system: FHIRValueSetter.FHIRSystem.NAP,
              },
            ],
          },
          identifier: [
            {
              system: FHIRValueSetter.FHIRIdentifierSystem.NAPErrorMessage,
              value: 'This is my error message',
            },
            {
              system: FHIRValueSetter.FHIRIdentifierSystem.NAPErrorDescription,
              value: 'This is a longere description of the error message',
            },
          ],
        },
      },
    ],
  },
};

NapTypescriptSdk.send(napMessageSessionError)

Nap-angular-sdk

Hvis du ønsker at bruge Angular som udviklingsværktøj.

Da nap-angular-sdk er en angular specifik wrapper af nap-typescript-sdk, har den en "peer dependency" hertil. 

Funktionalitet

SDK'et udstiller en service, som sørger for at kalde createNAP() fra nap-typescript-sdket og dermed initialisere kontekstbroen.

Efterfølgende subscribes der på de forskellige messagestreams, og deres emits bliver håndteret i forhold til Angulars change detection zone.

Udfra dette generer den nye observables som er tilgængelig som public felter.


Code Block
languagejs
NapAngularService {
	// attributter
	incomming$: Observable<NAPmessage>
	errors$: Observable<NAPError>
	outgoing$: Subject<NapMessage>
	sendMessage(message: NAPMessage):void
 	subscribeToMessages(callback: (message: NAPMessage) => void): void
}

Effekten for anvenderen bliver, at broen initialiseres som en singleton og at Angular opfanger beskeder sendt over broen og opdaterer UI på baggrund af disse værdier.

Eksempel på implementing af nap-angular-sdk

Generel kodedokumentation findes i biblioteket. Fuld implementation af eventkataloget ses i nap-reference-web her https://svn.nspop.dk/svn/components/nap/nap-reference-web/trunk/.

Session-open

Følgende eksempel sender en Session-Open besked og får en SAMLassertion tilbage:

Code Block
languagejs
import { NapAngularService } from 'nap-angular-sdk';
import { filterEvents, NAPEventCatalogue, NAPMessage } from 'nap-typescript-sdk';
import { v4 as UUID } from 'uuid';

export class MyComponent {
	
	// proxy for SAMLAssertion
	public session$: Observable<NAPMessage | undefined> = 
		this.napSDK.incomming$.pipe(
		filterEvents([NAPEventCatalogue.v1.SessionOpen, NAPEventCatalogue.v1.SessionClose])
	);
		//inject the nap-angular-sdk service
	constructor(private napSK: NapAngularService) {
		// Construct an SessionOpen NAPMessage
		const napMsg: NAPMessage = {
		date: new Date().toISOString(),
		id: UUID(),
		event: { type: NAPEventCatalogue.v1.SessionOpen },
	};

		// Ask for the SAMLassertion in host
		this.napSDK.sendMessage(napMsg);
	}
}

Patient-Open og Patient-close

Følgende eksempel sender en patient-Open besked og får en patient tilbage.

Code Block
languagejs
import { NapAngularService } from 'nap-angular-sdk';
import { filterEvents, NAPEventCatalogue, NAPMessage, FHIRValueSetter, FHIRValueGetter } from 'nap-typescript-sdk';
import { v4 as UUID } from 'uuid';

export class MyComponent {
	
	// proxy for currentPatient
	public currentPatient$: Observable<NAPPatientInfo | undefined> = this.napSDK.incomming$.pipe(
    	filterEvent(NAPEventCatalogue.v1.PatientOpen),
	    map((message) => FHIRValueGetter.getPatientInfo(message))
    );
	
	//inject the nap-angular-sdk service
	constructor(private napSK: NapAngularService) {
	  	
		// Construct an patient NAPMessage
	 	const napMsg: NAPMessage = {
			date: new Date().toISOString(),
      		id: UUID(),
      		event: { type: NAPEventCatalogue.v1.PatientOpen}
     	 };
      	
		this.napSDK.sendMessage(napMsg);

	  	// Ask for the patient context in host
	  	this.napSDK.sendMessage(napMsg);
	}

	// Something triggerede a patientClose on the client site 
	public patientClose(patient: NAPPatientInfo) {
		const napMsg: NAPMessage = {
  			date: new Date().toISOstring(),
			id: UUID(),
		  	event: {
    			type: NAPEventType.PatientClose,
		    	context: [{
        			resource: {
		          	resourceType: FHIRValueSetter.FHIRResourceType.Patient,
          		  	code: { 
						coding: [{ code: NAPEventCatalogue.v1.Close, system: FHIRSystem.NAP}] 
						},
	          		identifier: [{
		        	      system: FHIRSystem.CPR,
        		    	  value: patient.ssNo,
			           	 }],
          			name: [{ family: patient.familyName, given: [patient.familyName] }],
		          	meta: {profile: ['http://hl7.dk/fhir/core/StructureDefinition/dk-core-patient']},
      			}],
  			}
		};
		
		// Send the message
Code Block
languagejs
import { NapAngularService } from 'nap-angular-sdk';
import { filterEvents, NAPEventCatalogue, NAPMessage } from 'nap-typescript-sdk';
import { v4 as UUID } from 'uuid';
import { NapAngularService } from 'nap-angular-sdk';
import { filterEvents, NAPEventCatalogue, NAPMessage } from 'nap-typescript-sdk';
import { shareReplay } from 'rxjs/operators';
import { v4 as UUID } from 'uuid';

export class MyComponent {
	
	// proxy for SAMLAssertion
	public session$: Observable<NAPMessage | undefined> = 
		this.napSDK.incomming$.pipe(
		filterEvents([NAPEventCatalogue.v1.SessionOpen, NAPEventCatalogue.v1.SessionClose])
	);

	constructor(private napSK: NapAngularService) {

		//Construct an SessionOpen NAPMessage
		const napMsg: NAPMessage = {
		date: new Date().toISOString(),
		id: UUID(),
		event: { type: NAPEventCatalogue.v1.SessionOpen },
	};

		// Ask for the SAMLassertion in host
		this.napSDK.sendMessage(napMsg);
	}
}

Generel kodedokumentation findes i biblioteket.

...


	
}

Nap-react-sdk

Hvis du ønsker at bruge React som udviklingsværktøj.

...