Jämförda versioner

Nyckel

  • Dessa rader lades till.
  • Denna rad togs bort.
  • Formateringen ändrades.
Kommentera: Uppdaterat bildstorlek

Implementations vy

http://code.google.com/p/oppna-program/wiki/Anvisningar_Kallkodstruktur

TODO: Uppdatera map EI

Mule flödena är implementerade mha Mule Studio och återges nedan som skärmdumpar från verktyget.

Image Removed

aggregating-service

aggregating-service är en generisk mönster-implementation av en aggregerande tjänst. Den kan anpassas för specifika aggregerande tjänsters behovs på tre ställen:

...

Image Removed

process-notification-service

Image Removed

Mekanismer

TODO: Beskriv hantering timeouter och cachning samt konfigurerbara parametrer för detta:

Kodblock
# Default timeout for synchronous services
SERVICE_TIMEOUT_MS=4000
AGGREGATE_TIMEOUT_MS=4500
AGGREGATED_SERVICE_TIMEOUT_MS=5000

# Cache properties
CACHE_MAX_ENTRIES=1000
CACHE_TTL_MS=5000
CACHE_EXPIRATION_INTERVAL_MS=1000

 

Tjänstespecifika implementationer anges enligt:

Kodblock
# POJO implementations of the agp-api
QUERY_OBJECT_FACTORY_IMPL=se.skltp.aggregatingservices.riv.crm.requeststatus.getrequestactivities.QueryObjectFactoryImpl
REQUEST_LIST_FACTORY_IMPL=se.skltp.aggregatingservices.riv.crm.requeststatus.getrequestactivities.RequestListFactoryImpl
RESPONSE_LIST_FACTORY_IMPL=se.skltp.aggregatingservices.riv.crm.requeststatus.getrequestactivities.ResponseListFactoryImpl

 

Meddelandemappningar

I detta kapitel beskrivs de mappningar som behöver göras mellan meddelanden i respektive användningsfall.

TODO: Rensa upp och beskriv utgående från aggregeringsplattformen!

Konsument anropar aggregerande tjänst

Tre mappningar behövar göras för detta användningsfall, se tillhörande sekvensdiagram för överblick:

  1. Mappning AggregatedGetSubjectOfCareSchedule-request till FindContent-request
  2. Mappning FindContent-response till GetSubjectOfCareSchedule-request
  3. Mappning GetSubjectOfCareSchedule-response till AggregatedGetSubjectOfCareSchedule-response

...

  1. se.skl.tp.at.tidbokning.engagemangsindex.FindContentRequestTransformer
  2. se.skl.tp.at.tidbokning.tidbokning.TidbokningRequestTransformer
  3. se.skl.tp.at.tidbokning.tidbokning.TidbokningResponseTransformer

...

  • at: Variabel för aggregeringstjänsten GetSubjectOfCareAggregatedSchedule
  • ei: Variebel för engagemangsindex tjänsten FindContent
  • ks: Variable för källsystemens tjänst GetSubjectOfCareSchedule

Mappning AggregatedGetSubjectOfCareSchedule-request till FindContent-request

GetSubjectOfCareAggregatedSchedule in-parametrar:

  • at.in.logicalAdress = hsa-id för aggr tjänst
  • at.in.actor = SUBJECT_OF_CARE eller SUBJECT_OF_CARE_AGENT
  • at.in.subject_of_care = personnummer för patienten i fråga

FindContent in-parametrar mappas enligt: 

  • ei.in.logicalAdress = hsa-id för nationellt EI
  • ei.in.registeredResidentIdentification = at.in.subject_of_care
  • ei.in.serviceDomain = "riv:crm:scheduling"

Not: Övriga element i FindContent requestet utelämnas och antas ge wildcard-funktionelitet, t ex Categorization och MostRecentChange

Kommentar av Johan Eltes:

Vi kanske skulle speca att en aggregerande tjänst kan parameteriseras (konfigureras) med ett datum för MostRecentChange och för antal dagar i cachen. Till exempel kanske tidbokningar i dåtid inte är intressant, mer än någon månad tillbaka...

 

Svar: Magnus Larsson:

Låter rimligt, låter kommentaren stå kvar så får vi se var den kommer in....

Mappning FindContent-response till GetSubjectOfCareSchedule-request

FindContent ut-parametrar:

...

GetSubjectOfCareSchedule in-parametrar mappas enligt:

  • ks.in.logicalAdress = ei.ut.engagement-list.row.logicalAddress
  • ks.in.actor = at.in.actor
  • ks.in.healthcare_facility = ei.ut.engagement-list.row.logicalAddress
  • ks.in.subject_of_care = ei.ut.engagement-list.row.registeredResidentIdentification

 

Mappning GetSubjectOfCareSchedule-response till AggregatedGetSubjectOfCareSchedule-response

...

 

...

GetSubjectOfCareAggregatedSchedule ut-parametrar mappas enligt:

  • ks.ut.timeSlotDetail-list, summan av alla inkomna svar från källsystemen.

 

Engagemangsindex uppdaterar aggregerande tjänst

TBD

Rensning av cache

TBDInnehåll:

Innehållsförteckning

Tillgång till källkoden

Se Instruktioner för utvecklare.

Översikt

Implementationen av engagemangsindex följer en traditionell lagerindelning:

  • Integrationslager
    Hanterar all extern och intern kommunikation inklusive hantering av transaktioner, loggning fel och omsändning.
    Detta lager använder Apache Camel, och ansluter till Apache ActiveMQ som JMS provider.

  • Verksamhetslager
    Innehåller regelverk som följer regler i tjänstekontraktet för engagemangsindex.
    Detta lager är implementerat som rena Java klasser (POJO's) och använder Spring Framework för att hantering av beroenden i runtime (DI).

  • Persistenslager
    Hanterar lagring och sökning av engagemangsindex-information i databasen.
    Detta lager är beroende av JPA 2.0 samt Spring Data. För lokala tester används en HSQL in-memory databas och för externa tester används MySQL.
    Persistenslagret kan konfigureras för att använda andra databaser som MS SQL Server, IBM D2 eller Oracle.

Följande bild återger källkostrukturen ner på Mavenmodulnivå:

Image Added

Foldrarna innehåller följande projekt:

  • skltp-ei-application
    Spring Boot-applikation för att köra front- och backend som en kombinerad tjänst
  • skltp-ei-backend
    Spring Boot-applikation med alla komponenter förutom update-service och notification-service som som ligger i frontend
  • skltp-ei-common
    Innehålller kod som delas mellan frontend och backend
  • skltp-ei-data-model
    Innehåller källkoden för persistenslagret.
  • skltp-ei-frontend
    Spring Boot-applikation med komponenterna update-service och notification-service.
    Not: Så länge frontend är uppe så kan EI ta emot uppdateringar även om backend och dess databas är nere för t ex underhåll.
  • skltp-ei-schemas
    Innehåller de tjänstekontrakt som implementationen exponerar och/eller konsumerar.
  • skltp-ei-teststub
    Stubbar för att underlätta testning

Följande modell beskriver de mest centrala källkodsartefakterna samt var de finns placerade i källkodsträdet:

Image Added

Persistenslager

Detta lager är baserat på JPA 2.0 samt Spring Data och Hibernate. För lokala tester används en HSQL in-memory databas och för externa tester används MySQL.
Persistenslagret kan konfigureras för att använda andra databaser som MS SQL Server, IBM D2 eller Oracle, men har endast verifierats med MySQL.

Mappning till tabell

Databasstrukturen är enkel med en enda huvudtabell där nästan hela posten är en primärnyckel och den information som uppdateras är endast två datumfält.

Tabellen ser ut enligt:

engagement_index_table

KolumnnamnNull

Primär-

nyckel

Del av

logisk-

nyckel

Typ och Längd
idNejX
Varchar(64)

registered_resident_id

Nej
XVarchar(32)

service_domain

Nej
XVarchar(255)

categorization

Nej
XVarchar(255)

logical_address

Nej
XVarchar(64)

business_object_instance_id

Nej
XVarchar(128)

source_system

Nej
XVarchar(64)

data_controller

Nej
XVarchar(64)

owner

Nej
XVarchar(64)

clinical_process_interest_id

Nej
XVarchar(128)

creation_time

Nej

Timestamp

update_time

Ja

Timestamp

most_recent_content

Ja

Timestamp


Förutom primärnyckeln som är id så finns ett sökindex med namnet engagement_search_index.

Primärnyckel

I enlighet med specifikationen är den unika verksamhetsnyckeln ganska komplex och är just nu (RC8) baserad på nio fält, och för att underlätta databashanteringen har en teknisk primärnyckel valts där den denna härleds utifrån verksamhetsnyckeln. Den valda algoritmen för att skapa denna unika nyckel är SHA-2 eller mer exakt SHA-256, och resultatet är en 32 bytes array som sedan konverteras till en 64 teckens sträng på hexadecimalt format. I teorin kan duplikat uppstå, men i praktiken har ingen funnit några duplikat vid användning av denna algoritm, se även http://en.wikipedia.org/wiki/SHA-2.

Observera att användningen av en teknisk primärnyckel inte förändrar det faktum att man inte under några omständigheter kan ändra på någon del av verksamhetsnyckeln, dvs. utifrån detta perspektiv är det exakt samma hantering som om verksamhetsnyckeln hade används som primärnyckel. Därför har varje fält som ingår i verksamhetsnyckeln markerats med en JPA indikator om att fältet ifråga inte ska uppdateras.

Tidstämpel

Det finns 3 fält av typen tidstämpel, och två av dessa creation_time och update_time hanteras till fullo av persistenslagret. För att update_time ska ändras måste posten ändras och detta görs endast när värdet på most_recent_content ändras.

Sökningar

För sökningar används springs JPA repository interface, där sökningar definieras antingen med namnkonvention eller med SQL (JPQL) satser. För närvarande krävs fälten registered_resident_id och service_domain för sökningar i enlighet med findContent meddelandet, och detta skiljer sig från den nuvarande specifikationen (RC10).

Om tidstämpel är angiven (most_recent_content) så returneras alla poster som har ett värde som är större eller lika med detta. För samtliga övriga fält måste värdena vara exakt lika.

Transaktioner

Precis som förespråkas i tjänstekontraktsbeskrivningen så krävs ingen särskild transaktionskonsistens när man läser data, dvs. man tillåter så kallade "dirty reads" om nu den underliggande databasen tillåter detta. Självfallet måste alla skrivningar hanteras på ett atomärt och konsistent sätt, även om man tillåter sk. "dirty reads".

Portering av databas

Nuvarande implementation har endast verifierats med MySQL 5 databas och då med InnoDB som transaktionsmotor (engine). Det finns ett antal punkter som man bör reflektera över när det gäller portering till andra databaser:

  • Vid sökning av flera poster med hjälp av primärnyckeln används en "IN" sats och vissa databaser kan kan ha begränsningar med avseende på batch-storleken för denna typ av anrop
  • Längden på några av kolumnerna kan möjligen överskrida någon begränsning
  • Det kan finnas effektivare sätt att lagra informationen på, dvs. sökindex och tabelldata kan mycket väl slås ihop för denna typ av data. I MySQL fallet lagras tabell och index var för sig.
  • Det kan finnas effektivare sätt att indexera på då den primära nyckeln passar utmärkt för ett "hash" index. MySQL och InnoDB är begränsat till B-Tree