Gå til innhold

Pifu IMS MA

Management Agent for PIFU IMS

Type: ECMA 2.2

Versjonsnummer: 1.4.0

Dato: 05.02.2019

Målsystem Versjon: 1.4.0

Objecttyper: person, group, membershipgroup, orgLevel#1(orgunit), orgLevel#0(organization)

Beskrivelse

Management agenten henter data på PIFU IMS-format fra xml-fil. Xml-filen blir generert i forkant av selve PIFU MA-kjøringen. Agenten støtter import både fra SATS og Extens. Siden det ikke finnes noen generelle IST-støttede metoder for å skrive tilbake data til SATS/Extens, er det ikke implementert eksport for denne agenten.

Hvilke PIFU IMS-attributtene som importeres til CS, styres av filen CSAttributes.json som ligger i MaData-mappen for agenten. Dersom agenten heter PIFU MA må filen ligge i mappen "C:\Program Files\Microsoft Forefront Identity Manager\2010\Synchronization Service\MaData\PIFU MA". Eksempelfil ligger i install-mappen sammen med xml for agenten

En fullstendig oversikt med alle attributter som er tilgjengelig i uttrekket for de forskjellige objekttypene, finner man i starten av log-filen(se under). Det er totalt ca 670 attributter(!) så det er ikke å anbefale å ta med alle.

Full import File Path Fullstendig sti fil input-filen. For eksempel c:\pifu\pifudata.xml

Use PersonCode as person-id Huk av denne hvis en annen identifikator enn fødselsnummer ønskes benyttet som anker for person. For SATS er det da Person-feltet som brukes, for Extens brukes Webbrukerid.

Dagens Buddy benytter fødselsnummer som anker. Dersom dette endres (for eksempel ved bytte fra midlertidig fødselsnummer til ekte fødslesnummer), blir det opprettet et nytt personobjekt i CS og det gamle objektet slettet med de problemer det medfører: ny brukerident, den gamle deaktivert osv.

Verdien i Person-feltet i SATS er unik, blir ikke gjenbrukt og endres ikke. Person-feltet derfor en god kandidat som anker. Ved endring i fødselsnummer vil personen fremdeles ha samme CS-objekt og det skjer ingen endring av brukerident.

Webbrukerid i Extens er unik og uavhengig av fødselsnummerendringer, men dessverre er det mulig å endre denne. I følge IST finnes ikke noe varig og unikt felt i Extens, webbrukerid er det nærmeste man kommer. Extensfylkene må selv vurdere om de vil bruke fødselsnummer eller webbrukerid som anker.

Enable Validation (validates before parsing)

Huk av denne for å sjekke at uttrekket er gyldig xml og i henhold til xml-skjemaet for PIFU IMS. Det anbefales å slå av valideringen hos IST via uttrekkskommandoen (se PIFU IMS uttrekk fra Extens/Sats), og heller validere uttrekket ved å huke av her.

Parametre for gruppegenerering

Under Global Parameters er det mulig å konfigurere hvilke gruppetyper som skal genereres. PIFU MA-en kan generere to hovedvarianter av grupper: Group og Membership group.

Group

Avhukingen under vil generere de samme gruppetypene som kom fra ABC Enterprise:

Membership group

Avhukingen under vil generere alle elever-gruppe, alle lærere-gruppe og alle ansatte-gruppe for hele organisasjonen, og tilsvarende for hver skole:

Logging

Logging fra agenten konfigureres i fila log.config som ligger i mappen "C:\Program Files\Microsoft Forefront Identity Manager\2010\Synchronization Service\MaData\PIFU MA". Standard er at logging skjer til mappen "C:\Logs\VIGOBAS\Pifu MA".

Validering

Det er to vanlige feil i xml-uttrekket. Den ene er tegn som er ugyldige i xml, for eksempel i epost-adresser. Når validering er slått på for agenten, vil en slik feil få kjøringen til å stoppe umiddelbart. Det logges en feil i Windows Application-loggen med event ID 6801:

The extensible extension returned an unsupported error.
 The stack trace is:

 "System.Xml.XmlException: '', hexadecimal value 0x1F, is an invalid character. Line 253322, position 21.

Det er laget et lite CLI-program CleanXML.exe som finner alle ugyldige tegn i uttrekket, fjerner feilene og skriver linjene med feil til en logg-fil. CleanXML.exe ligger i installmappen til PIFU-agenten.

Bruk: CleanXML <sti til input og output-fil> <input-fil: fil som skal renses> <output-fil: fil med renset xml>

Loggfil er error.txt og ligger i samme mappe som input og output-filene. I Notepad++ ser man de ugyldige tegnene:

Den andre feilen er ugyldige eller manglende data i henhold til xml-skjemaet for PIFU IMS. Valideringen på agenten vil finne alle slike feil i uttrekket og så stoppe før selve kjøringen. Fim-ma-debug.txt inneholder feilene:

Warning : The XML file did not validate due to 
Error: Validation error on line : 10931920 position : 30. msg : The 'http://pifu.no/xsd/pifu-ims_sas/pifu-ims_sas-1.1:begin' element is invalid 
- The value '' is invalid according to its datatype 'Date' - The string '' is not a valid Date value.
Error: Validation error on line : 10931959 position : 30. msg : The 'http://pifu.no/xsd/pifu-ims_sas/pifu-ims_sas-1.1:begin' element is invalid 
- The value '' is invalid according to its datatype 'Date' - The string '' is not a valid Date value.

Feilene logges også i Windows Application-loggen med event ID 6801.

Ved å gå inn i uttrekksfilen - xml-editoren foxe kan anbefales - kan man finne linjer som feiler, og hvilken person eller gruppe som feilen(e) er knyttet til.

Flow

Der hvor det ikke ligger noe MV-attributt. er det ikke satt opp noen direkteflyt i MA-en. Men CS-attributtet er tilgjengelig, og kan være benyttet i en avansert flyt. Tabellene inneholder de attributtene som blir hentet inn i CS dersom man benytter CSAttributes.sjon-eksempelfilen.

Person

Import

CS Object Type CS Attribute Mapping Type MV Object Type MV Attribute Advanced Rule
person EduPersonEntitlement Direct person eduPersonEntitlement
person EnhetUserType Direct person enhetUserType
person ID Direct person basSASID
person MemberOf@orgLevel#0 Direct person basOrgRef
person MemberOf@orgLevel#1 Direct person eduPersonOrgUnitDN
person personMobilePrivate Direct person mobile
person personPostalAddressPrivate.locality Direct person
person personPostalAddressPrivate.pcode Direct person
person personPostalAddressPrivate.street Direct person
person personTelephonePrivate Direct person homePhone
person pifuXml#demographics.bday Direct person basBirthDate
person pifuXml#demographics.gender Direct person
person pifuXml#email Direct person email
person pifuXml#name.fn Direct person displayName
person pifuXml#name.n.family Direct person lastName
person pifuXml#name.n.given Direct person firstName
person primaryOrgUnit Direct person eduPersonPrimaryOrgUnit
person primaryClassGroup Direct person
person primaryRole Direct person eduPersonPrimaryAffiliation
person Roles Direct person eduPersonAffiliation
person ssn Direct person basSSN
person ssnValidation Direct person basSSNValidation
person studentID Direct person
person workforceID Direct person
person pifuXml#demographics.bday Advanced person basBirthDate PifuMA_formatBirthDate
person enhetUserType Advanced person department PifuMA_enhetUserTypeToDepartment

Avanserte flytregler

PifuMA_formatBirthDate
import datetime
from datetime import *
date = datetime.strptime(source['pifuXml#demographics.bday'].Value, '%d.%m.%Y %H:%M:%S')
target['basBirthDate'].Value = date.strftime('%Y-%m-%d')

PifuMA_enhetUserTypeToDepartment
# -*- coding: utf-8 -*-
import string

import clr
clr.AddReference('System.Data')
from System.Data.SqlClient import SqlConnection, SqlParameter

conn_string = 'data source=localhost; initial catalog=FIMSynchronizationService; trusted_connection=True'
command_txt ="select displayName FROM mms_metaverse WITH (nolock) WHERE(basUniqeID = @orgunit_id and object_type='organizationalUnit')"

target['department'].Delete()

enhetUserTypes = dict(e.ToString().split(';') for e in source['enhetUserType'].Values)

if target['eduPersonPrimaryAffiliation'].IsPresent:
    primaryRole = target['eduPersonPrimaryAffiliation'].Value
    if primaryRole in enhetUserTypes:
        primaryOrgUnit= enhetUserTypes[primaryRole]

        connection = SqlConnection(conn_string)
        connection.Open()
        command = connection.CreateCommand()
        command.CommandText = command_txt
        command.Parameters.Add(SqlParameter('orgunit_id', primaryOrgUnit))

        reader = command.ExecuteReader()

        if reader.HasRows:
            reader.Read()
            department= reader['displayName']

            target['department'].Value = department

        connection.Close()

Group

Import

CS Object Type CS Attribute Mapping Type MV Object Type MV Attribute Advanced Rule
group grepcode Direct group
group grepcodeShortForm Direct group
group groupType Direct group type
group groupTypeAsString Direct group
group ID Direct group basUniqueID
group MemberOf@orgLevel#0 Direct group
group MemberOf@orgLevel#1 Direct group
group MemberRole.Learner Direct group member
group MemberRole.Instructor Direct group
group Members Direct group
group pifuXml#description.short Direct group
group pifuXml#description.long Direct group
group pifuXml#description.full Direct group
group schoolName Direct group
group RoleType Direct group
group groupType, pifuXml#description.short, pifuXml#description.long, schoolName Advanced group displayName PifuMA_displayNameGroup

Avanserte flytregler

PifuMA_displayNameGroup
if source['groupType'].Value == '4':
    target['displayName'].Value = source['pifuXml#description.short'].Value
elif source['groupType'].Value == '5':
    target['DisplayName'].Value = 'Programområdet ' +source['pifuXml#description.short'].Value + ' ved ' + source['schoolName'].Value
elif source['groupType'].Value == '6':
    target['displayName'].Value = 'Utdanningsprogrammet ' +source['pifuXml#description.short'].Value + ' ved ' + source['schoolName'].Value
elif source['groupType'].Value == '7':
    target['displayName'].Value = 'Faget ' +source['pifuXml#description.long'].Value + ' ved ' + source['schoolName'].Value
else:
    target['displayName'].Value = source['pifuXml#description.long'].Value

MembershipGroup

Import

CS Object Type CS Attribute Mapping Type MV Object Type MV Attribute Advanced Rule
membershipGroup grepcode Direct group
membershipGroup grepcodeShortForm Direct group
membershipGroup ID Direct group basUniqueID
membershipGroup MemberOf@orgLevel#0 Direct group
membershipGroup MemberOf@orgLevel#1 Direct group
membershipGroup Members Direct group member
membershipGroup pifuXml#description.short Direct group
membershipGroup pifuXml#description.long Direct group
membershipGroup pifuXml#description.full Direct group description
membershipGroup schoolName Direct group
membershipGroup RoleType Direct group
membershipGroup Advanced group type Constant: 'MembershipGroup'
membershipGroup membershipGroupType, pifuXml#description.short, pifuXml#description.long, schoolName Advanced group displayName PifuMA_displayNameMembershipGroup

Avanserte flytregler

PifuMA_displayNameMembershipGroup
if source["RoleType"].Value == 'Learner':
    target["DisplayName"].Value = "Alle elever ved " + source["pifuXml#description.short"].Value
if source["RoleType"].Value == 'Instructor':
    target["DisplayName"].Value = "Alle lærere ved " + source["pifuXml#description.short"].Value
if source["RoleType"].Value == 'Member':
    target["DisplayName"].Value = "Alle administrativt ansatte ved " + source["pifuXml#description.short"].Value

orgLevel#1 (OrgUnit)

Import

CS Object Type CS Attribute Mapping Type MV Object Type MV Attribute Advanced Rule
orgLevel#1 ID Direct organizationUnit basUniqueID
orgLevel#1 orgEmail Direct organizationUnit mail
orgLevel#1 organizationNumber Direct organizationUnit basOrgUnitNumber
orgLevel#1 pifuXml#description.short Direct organizationUnit basParentOrgUnitRef
orgLevel#1 pifuXml#description.long Direct organizationUnit displayName
orgLevel#1 MemberOf@orgLevel#0 Direct organizationUnit description
orgLevel#1 VigoNumber Direct organizationUnit basVigoNumber

orgLevel#0 (Organization)

Import

CS Object Type CS Attribute Mapping Type MV Object Type MV Attribute Advanced Rule
orgLevel#0 ID Direct organization basUniqueID
orgLevel#0 organizationNumber Direct organization basOrgNumber
orgLevel#0 pifuXml#description.full Direct organization description
orgLevel#0 pifuXml#description.short Direct organization displayName
orgLevel#0 pifuXml#description.short Direct organization basOrgLegalName
orgLevel#0 Advanced organization mail Constant: 'postmottak@buddy.no'

PIFU IMS-uttrekk

Siste versjon av PIFU-IMS er lagt ut på følgende lenke.

Person

<person>
<sourcedid>
  <source>akershus-fk.no</source>
  <id>01010199999</id>
</sourcedid>
<userid useridtype="personNIN">03020199999</userid>
<userid useridtype="username">KANO52</userid>
<userid useridtype="studentID">739020</userid>
<name>
  <fn>Kari Norkvinne</fn>
  <n>
    <family>Norkvinne</family>
    <given>Kari</given>
  </n>
</name>
<demographics>
  <gender>1</gender>
  <bday>2001-02-03</bday>
</demographics>
<email>karino@gmail.com</email>
<tel teltype="1">+4755443322</tel>
<tel teltype="3">+4799887766</tel>
<adr>
  <street>Oppegårdveien 700</street>
  <locality>LANGHUS</locality>
  <pcode>1405</pcode>
</adr>
<extension>
  <pifu_email type="personEmailPrivate">karino@gmail.com</pifu_email>
  <pifu_tel type="personTelephonePrivate">+4755443322</pifu_tel>
  <pifu_tel type="personMobilePrivate">+4799887766</pifu_tel>
  <pifu_adr type="personPostalAddressPrivate">
    <adr>
      <street>Oppegårdveien 700</street>
      <locality>LANGHUS</locality>
      <pcode>1405</pcode>
    </adr>
  </pifu_adr>
</extension>
</person>

Group

I PIFU-IMS benyttes group-objekter til å modellere både organisasjon(skoleeier), organisasjonsenhet(skole) og "normale" skolegrupper som basisgrupper, kontaktlæergrupper og undervisningsgrupper. Også grep-kodene som er obligatorisk/anbefalt i Feide 1.6 (trinn, utdanningsprogram, programområde og fag) har egne gruppeobjekter.

Organisasjon (skoleier)

Denne gruppetypen legges inn i CS som orgLevel#0-objekt

<group>
<sourcedid>
  <source>akershus-fk.no</source>
  <id>02</id>
</sourcedid>
<grouptype>
  <scheme>pifu-ims-go-org</scheme>
  <typevalue level="1">skoleeier</typevalue>
</grouptype>
<description>
  <short>Akershus fylkeskommune</short>
</description>
<relationship relation="1">
  <sourcedid>
    <source>akershus-fk.no</source>
    <id>02</id>
  </sourcedid>
  <label>Akershus fylkeskommune</label>
</relationship>
<extension>
  <pifu_id type="organizationNumber">
    <pifu_value>958381492</pifu_value>
    <pifu_scope>Enhetsregisteret</pifu_scope>
    <pifu_unique>1</pifu_unique>
  </pifu_id>
  <pifu_id type="countyNumber">
    <pifu_value>02</pifu_value>
    <pifu_scope>http://hotell.difi.no/?dataset=difi/geo/fylke</pifu_scope>
    <pifu_unique>0</pifu_unique>
  </pifu_id>
</extension>
</group>

organisasjonsenhet(skole)

Denne gruppetypen legges inn i CS som orgLevel#1-objekt

<group>
<sourcedid>
  <source>akershus-fk.no</source>
  <id>02023</id>
</sourcedid>
<grouptype>
  <scheme>pifu-ims-go-org</scheme>
  <typevalue level="2">skole</typevalue>
</grouptype>
<description>
  <short>Ski videregående skole</short>
</description>
<relationship relation="1">
  <sourcedid>
    <source>akershus-fk.no</source>
    <id>02</id>
  </sourcedid>
  <label>Akershus fylkeskommune</label>
</relationship>
<extension>
  <pifu_id type="organizationNumber">
    <pifu_value>974587696</pifu_value>
    <pifu_scope>Enhetsregisteret</pifu_scope>
    <pifu_unique>1</pifu_unique>
  </pifu_id>
  <pifu_id type="vigoNumber">
    <pifu_value>02023</pifu_value>
    <pifu_scope>vigo</pifu_scope>
    <pifu_unique>1</pifu_unique>
  </pifu_id>
  <pifu_name type="name">
    <pifu_value>Ski videregående skole</pifu_value>
  </pifu_name>
  <pifu_email type="orgEmail">post@ski.vgs.no</pifu_email>
  <pifu_url type="orgURL">http://www.ski.vgs.no</pifu_url>
  <pifu_tel type="orgTelephone">+4764913600</pifu_tel>
  <pifu_adr type="orgPostalAddress">
    <adr>
      <street>Gymnasveien</street>
      <locality>SKI</locality>
      <pcode>1401</pcode>
    </adr>
  </pifu_adr>
</extension>
</group>

Basisgruppe

<group>
    <sourcedid>
      <source>akershus-fk.no</source>
      <id>1_1STF_02023</id>
    </sourcedid>
    <grouptype>
      <scheme>pifu-ims-go-grp</scheme>
      <typevalue level="1">basisgruppe</typevalue>
    </grouptype>
    <description>
      <short>1STF</short>
      <long>SKI:1STF</long>
      <full>Basisgruppe 1STF ved Ski videregående skole</full>
    </description>
    <timeframe>
      <begin restrict="0">2016-08-01</begin>
      <end restrict="0">2017-06-30</end>
      <adminperiod>2016/2017</adminperiod>
    </timeframe>
    <relationship relation="1">
      <sourcedid>
        <source>akershus-fk.no</source>
        <id>02023</id>
      </sourcedid>
      <label>Ski videregående skole</label>
    </relationship>
    <extension>
      <pifu_name type="name">
        <pifu_value>1STF</pifu_value>
      </pifu_name>
      <pifu_name type="fullName">
        <pifu_value>Basisgruppe 1STF ved Ski videregående skole</pifu_value>
      </pifu_name>
    </extension>
</group>

Gruppe for trinn

<group>
    <sourcedid>
      <source>akershus-fk.no</source>
      <id>4_VG3_02023</id>
    </sourcedid>
    <grouptype>
      <scheme>pifu-ims-go-grp</scheme>
      <typevalue level="4">trinn</typevalue>
    </grouptype>
    <description>
      <short>Ski videregående skole trinn VG3</short>
    </description>
    <relationship relation="1">
      <sourcedid>
        <source>akershus-fk.no</source>
        <id>02023</id>
      </sourcedid>
      <label>Ski videregående skole</label>
    </relationship>
    <extension>
      <pifu_id type="grepCode">
        <pifu_value>http://psi.udir.no/laereplan/aarstrinn/vg3</pifu_value>
        <pifu_scope>grep - levende læreplaner</pifu_scope>
        <pifu_unique>0</pifu_unique>
      </pifu_id>
    </extension>
</group>

Gruppe for utdanningsprogram


<group>
    <sourcedid>
      <source>akershus-fk.no</source>
      <id>5_ID_02023</id>
    </sourcedid>
    <grouptype>
      <scheme>pifu-ims-go-grp</scheme>
      <typevalue level="5">utdanningsprogram</typevalue>
    </grouptype>
    <description>
      <short>Idrettsfag</short>
    </description>
    <relationship relation="1">
      <sourcedid>
        <source>akershus-fk.no</source>
        <id>02023</id>
      </sourcedid>
      <label>Ski videregående skole</label>
    </relationship>
    <extension>
      <pifu_id type="grepCodeShortForm">
        <pifu_value>ID</pifu_value>
        <pifu_scope>grep - levende læreplaner</pifu_scope>
        <pifu_unique>0</pifu_unique>
      </pifu_id>
      <pifu_id type="grepCode">
        <pifu_value>http://psi.udir.no/ontologi/utdanningsprogram/idrettsfag</pifu_value>
        <pifu_scope>grep - levende læreplaner</pifu_scope>
        <pifu_unique>0</pifu_unique>
      </pifu_id>
    </extension>
</group>

Membership

Knytningen mellom person og gruppe uttrykkes i membershipobjekter. Hva slags rolle personen har i denne gruppen er også med(roletype ="02" betyr at vedkommende er elev i denne gruppen).

<membership>
    <sourcedid>
      <source>akershus-fk.no</source>
      <id>1_1STF_02023</id>
    </sourcedid>
    <member>
      <sourcedid>
        <source>akershus-fk.no</source>
        <id>03020199999</id>
      </sourcedid>
      <idtype>1</idtype>
      <role roletype="02">
        <status>1</status>
        <timeframe>
          <begin restrict="0">2016-08-16</begin>
          <end restrict="0">2017-07-31</end>
        </timeframe>
      </role>
    </member>
    ...
</membership>

Det er bare et membershipobjekt per gruppe, dvs at alle gruppens medlemmer ligger i dette objektet.