Gefiltertes Importieren der Moduldaten - Archi-Lab/prox-project-service GitHub Wiki

Gefiltertes Importieren Moduldaten

Anlegen der Model Klassen StudyCourse und Module

Um Module importieren zu können, wurden die Model Klassen Module und StudyCourse vom Module-Service übernommen und auf den Projektkontext angepasst:

public class StudyCourse extends AbstractEntity {

  private ExternalStudyCourseID externalStudyCourseID;

  private StudyCourseName name;

  private AcademicDegree academicDegree;

  @ManyToMany(cascade = {CascadeType.PERSIST, CascadeType.MERGE})
  private Set<Module> modules = new HashSet<>();

  @OneToMany(mappedBy = "parentStudyCourse", cascade = CascadeType.ALL, orphanRemoval = true)
  private Set<StudyCourse> studyDirections = new HashSet<>();

  @ManyToOne
  private StudyCourse parentStudyCourse;
  
  ...
}

public class Module extends AbstractEntity {

  private ExternalModuleID externalModuleID;

  private ModuleName name;
  
  @ManyToMany(cascade = {CascadeType.PERSIST, CascadeType.MERGE}, mappedBy = "modules")
  private Set<StudyCourse> studyCourses = new HashSet<>();

  ...
}

Neben der vererbten UUID der Klasse AbstractEntitiy, wird eine externe ID für jeden Studiengang und jedes Modul hinzugefügt. In dieser externen ID wird der Self-Link der angefragten Ressource gespeichert. Dies ist dadurch begründet, dass beim Abfragen der REST-Resource des Module-Service nur der Self-Link der Ressource vorhanden ist. Dieser dient als Referenz auf die Ressource, um zu testen, ob sich eine bestimmte Ressource verändert hat, wenn diese neu vom Module-Service bezogen wird. Dieser Self Link enthält leider auch das Protocol und die Domain. Da sich diese theoretisch ändern können werden diese von dem Self-Link abgetrennt, damit dieser relative Link eine geringe Chance hat, ungültig zu werden. Würden Ressourcen Serviceübergreifend mittels einer Message Queue importiert werden, würden IDs in den Events enthalten sein, sodass diese auch als interne IDs verwendet werden könnten. Dies würde externe IDs überflüssig machen.

Verknüpfung Projekt mit Modulen

Nachdem die Module in den Project-Service importiert werden, sollen diese mit Projekten verknüpft werden können. Dafür muss das Projekt-Model eine Beziehung zu Modulen bereitstellen. Dies resultiert in einer n-m Beziehung:

public class Project extends AbstractEntity {

  private ProjectName name;

  private ProjectDescription description;

  private ProjectStatus status;

  @ManyToMany
  private List<Module> modules = new ArrayList<>();
  
  ...
}

Importieren aller Module mitsamt dazugehörigen Studiengängen

Um Module schlussendlich in Project-Service referenzieren zu können, werden Module vom Module-Service mittels einer synchronen REST-Abfrage importiert. Genutzt wird dabei die Library Traverson. Die begründete Entscheidnung für die Library Traverson kann hier nachgelesen werden. Der Importiervorgang kann dabei in zwei Phasen unterteilt werden.

In einer ersten Phase werden Module mittels der Klasse ModuleClient angefragt. Dabei wird zuerst eine PagedResource unter Berücksichtigung der Suchkriterien angefragt. Jede Seite der PagedResource wird einzeln angefragt und abgearbeitet. Es wird jeweils eine begrenzte Anzahl an Modulen pro Seite verarbeitet. Für jedes Modul werden anschließend die dazugehörigen Studiengänge bezogen.

In einer zweiten Phase werden Module mittels der Klasse ModuleService persistiert. Wenn ein Modul vorhanden ist, wird es aktualisiert, ansonsten wird es neu hinzugefügt.

Umstellen der Beziehung zwischen Modulen und Studiengängen

Aufgrund der schlechten Datenkonsistenz und Haltung der aus HOPS bezogenen Daten können Module nicht sauber Studiengängen zugeordenet werden. Beispielsweise ist ein Modul Bachelorarbeit für drei Studiengänge definiert und zugleich existiert ein Modul Bachelorarbeit, welches nur für einen Studiengang definiert ist. Um die Daten sauber nutzen zu können, wurde die Beziehung von Modulen zu Studiengängen zu einer 1-n Beziehung umgeändert. Dabei werden Module unidirektional von Studiengängen referenziert.

public class StudyCourse extends AbstractEntity {
	...
  
	@OneToMany
	private List<Module> modules = new ArrayList<>();

	...
}

public class Module extends AbstractEntity {

  private ExternalModuleID externalModuleID;

  private ModuleName name;
}

Umstellen des Imports auf verändertes Datenmodell

Da Module nun keine Referenz mehr auf die dazugehörigen Studiengänge aufweisen, müssen Module und Studiengänge nun über die StudyCourses-Ressource anstatt über die Module-Ressource importiert werden. Angefragt werden die Studiengänge nun mithilfe der Klasse StudyCourseClient und mithilfe der Klasse StudyCourseService persistiert.

⚠️ **GitHub.com Fallback** ⚠️