Skip to content

Commit

Permalink
MORE2-2 extend API to new RelativeEvents
Browse files Browse the repository at this point in the history
* adapt OpenAPI
* adapt Transformers
* handle downwards compatibility (default types for existing database values)
* add some tests
HINT: switch to new model in UI first as 'type' property of schedule events is now required for Observation API calls
  • Loading branch information
Thomas Kurz committed Oct 27, 2023
1 parent 3e4d2ed commit d3cd937
Show file tree
Hide file tree
Showing 25 changed files with 560 additions and 38 deletions.
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
package io.redlink.more.studymanager.model;

import io.redlink.more.studymanager.model.scheduler.Event;
import io.redlink.more.studymanager.model.scheduler.ScheduleEvent;

import java.time.Instant;

public class Intervention {
Expand All @@ -8,7 +11,7 @@ public class Intervention {
private String title;
private String purpose;
private Integer studyGroupId;
private Event schedule;
private ScheduleEvent schedule;
private Instant created;
private Instant modified;

Expand Down Expand Up @@ -57,11 +60,11 @@ public Intervention setStudyGroupId(Integer studyGroupId) {
return this;
}

public Event getSchedule() {
public ScheduleEvent getSchedule() {
return schedule;
}

public Intervention setSchedule(Event schedule) {
public Intervention setSchedule(ScheduleEvent schedule) {
this.schedule = schedule;
return this;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package io.redlink.more.studymanager.model;

import io.redlink.more.studymanager.core.properties.ObservationProperties;
import io.redlink.more.studymanager.model.scheduler.ScheduleEvent;

import java.time.Instant;

Expand All @@ -13,7 +14,7 @@ public class Observation {
private String type;
private Integer studyGroupId;
private ObservationProperties properties;
private Event schedule;
private ScheduleEvent schedule;
private Instant created;
private Instant modified;
private Boolean hidden;
Expand Down Expand Up @@ -91,11 +92,11 @@ public Observation setProperties(ObservationProperties properties) {
return this;
}

public Event getSchedule() {
public ScheduleEvent getSchedule() {
return schedule;
}

public Observation setSchedule(Event schedule) {
public Observation setSchedule(ScheduleEvent schedule) {
this.schedule = schedule;
return this;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
package io.redlink.more.studymanager.model.scheduler;

import com.fasterxml.jackson.annotation.JsonCreator;
import io.redlink.more.studymanager.api.v1.model.DurationDTO;

public class Duration {

private Integer value;

/**
* unit of time to offset
*/
public enum Unit {
MINUTE("MINUTE"),

HOUR("HOUR"),

DAY("DAY");

private String value;

Unit(String value) {
this.value = value;
}

public String getValue() {
return value;
}

@Override
public String toString() {
return String.valueOf(value);
}

@JsonCreator
public static Unit fromValue(String value) {
for (Unit b : Unit.values()) {
if (b.value.equals(value)) {
return b;
}
}
throw new IllegalArgumentException("Unexpected value '" + value + "'");
}

public static Unit fromDurationDTOUnit(DurationDTO.UnitEnum unit) {
switch (unit) {
case MINUTE:
return MINUTE;
case HOUR:
return HOUR;
case DAY:
return DAY;
default:
throw new IllegalArgumentException("Unexpected value '" + unit + "'");
}
}

public static DurationDTO.UnitEnum toDurationDTOUnit(Unit unit) {
switch (unit) {
case MINUTE:
return DurationDTO.UnitEnum.MINUTE;
case HOUR:
return DurationDTO.UnitEnum.HOUR;
case DAY:
return DurationDTO.UnitEnum.DAY;
default:
throw new IllegalArgumentException("Unexpected value '" + unit + "'");
}
}
}

private Unit unit;

public Duration() {
}

public Integer getValue() {
return value;
}

public Duration setValue(Integer value) {
this.value = value;
return this;
}

public Unit getUnit() {
return unit;
}

public Duration setUnit(Unit unit) {
this.unit = unit;
return this;
}

public static DurationDTO toDurationDTO(Duration duration) {
if (duration != null)
return new DurationDTO()
.value(duration.getValue())
.unit(Unit.toDurationDTOUnit(duration.unit));
else return null;
}

public static Duration fromDurationDTO(DurationDTO dto) {
if (dto != null)
return new Duration()
.setValue(dto.getValue())
.setUnit(Unit.fromDurationDTOUnit(dto.getUnit()));
else return null;
}

@Override
public String toString() {
return "Duration{" +
"offset=" + value +
", unit=" + unit +
'}';
}
}
Original file line number Diff line number Diff line change
@@ -1,12 +1,19 @@
package io.redlink.more.studymanager.model;
package io.redlink.more.studymanager.model.scheduler;

import java.time.Instant;

public class Event {
public class Event implements ScheduleEvent {
public static final String TYPE = "Event";
private String type;
private Instant dateStart;
private Instant dateEnd;
private RecurrenceRule recurrenceRule;

@Override
public String getType() {
return TYPE;
}

public Instant getDateStart() {
return dateStart;
}
Expand All @@ -33,4 +40,6 @@ public Event setRRule(RecurrenceRule recurrenceRule) {
this.recurrenceRule = recurrenceRule;
return this;
}


}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package io.redlink.more.studymanager.model;
package io.redlink.more.studymanager.model.scheduler;

import java.time.Instant;
import java.util.List;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package io.redlink.more.studymanager.model.scheduler;

public class RelativeDate {

private Duration offset;
private String time;

public RelativeDate() {
}

public Duration getOffset() {
return offset;
}

public RelativeDate setOffset(Duration offset) {
this.offset = offset;
return this;
}

public String getTime() {
return time;
}

public RelativeDate setTime(String time) {
this.time = time;
return this;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
package io.redlink.more.studymanager.model.scheduler;

import io.redlink.more.studymanager.api.v1.model.RelativeDateDTO;
import io.redlink.more.studymanager.api.v1.model.RelativeRecurrenceRuleDTO;

public class RelativeEvent implements ScheduleEvent {

public static final String TYPE = "RelativeEvent";

private String type;

private RelativeDate dtstart;

private RelativeDate dtend;

private RelativeRecurrenceRule rrrule;

public RelativeEvent() {
}

@Override
public String getType() {
return TYPE;
}

public RelativeEvent setType(String type) {
this.type = type;
return this;
}

public RelativeDate getDtstart() {
return dtstart;
}

public RelativeEvent setDtstart(RelativeDate dtstart) {
this.dtstart = dtstart;
return this;
}

public RelativeDate getDtend() {
return dtend;
}

public RelativeEvent setDtend(RelativeDate dtend) {
this.dtend = dtend;
return this;
}

public RelativeRecurrenceRule getRrrule() {
return rrrule;
}

public RelativeEvent setRrrule(RelativeRecurrenceRule rrrule) {
this.rrrule = rrrule;
return this;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package io.redlink.more.studymanager.model.scheduler;

public class RelativeRecurrenceRule {

private Duration frequency;

private Duration endAfter;

public RelativeRecurrenceRule() {
}

public Duration getFrequency() {
return frequency;
}

public RelativeRecurrenceRule setFrequency(Duration frequency) {
this.frequency = frequency;
return this;
}

public Duration getEndAfter() {
return endAfter;
}

public RelativeRecurrenceRule setEndAfter(Duration endAfter) {
this.endAfter = endAfter;
return this;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package io.redlink.more.studymanager.model.scheduler;

import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonSubTypes;
import com.fasterxml.jackson.annotation.JsonTypeInfo;

@JsonIgnoreProperties(
value = "type", // ignore manually set type, it will be automatically generated by Jackson during serialization
allowSetters = true // allows the type to be set during deserialization
)
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.PROPERTY, property = "type", visible = true, defaultImpl = Event.class)
@JsonSubTypes({
@JsonSubTypes.Type(value = Event.class, name = Event.TYPE),
@JsonSubTypes.Type(value = RelativeEvent.class, name = RelativeEvent.TYPE)
})
public interface ScheduleEvent {
public String getType();
}
Loading

0 comments on commit d3cd937

Please sign in to comment.