From b2a9a8adbcf036780bf47c5c94dbf65a088ab540 Mon Sep 17 00:00:00 2001 From: Liam Fallon Date: Thu, 18 Jan 2018 10:55:53 +0000 Subject: Fix Tech Debt/JUnit on control loop event POJOs Mainly making fields private, fixing field and methods to follow Java guidelines, and adding getter and setter methods. Unit test added for all classes in org.onap.policy.controlloop Issue-ID: POLICY-455 Change-Id: I445b7cfaf9eb921a230bbb72b06ff4455fe003ce Signed-off-by: Liam Fallon --- .../onap/policy/controlloop/ControlLoopEvent.java | 118 ++++++++++++--- .../controlloop/ControlLoopNotification.java | 163 ++++++++++++++++++--- .../policy/controlloop/ControlLoopOperation.java | 84 ++++++++++- .../controlloop/ControlLoopOperationWrapper.java | 20 ++- .../controlloop/PhysicalControlLoopEvent.java | 6 - .../PhysicalControlLoopNotification.java | 4 - .../controlloop/VirtualControlLoopEvent.java | 33 ++++- .../VirtualControlLoopNotification.java | 37 ++++- .../policy/controlloop/util/Serialization.java | 73 +++++---- 9 files changed, 429 insertions(+), 109 deletions(-) (limited to 'controlloop/common/model-impl/events/src/main') diff --git a/controlloop/common/model-impl/events/src/main/java/org/onap/policy/controlloop/ControlLoopEvent.java b/controlloop/common/model-impl/events/src/main/java/org/onap/policy/controlloop/ControlLoopEvent.java index df099ed5e..1d85ccb77 100644 --- a/controlloop/common/model-impl/events/src/main/java/org/onap/policy/controlloop/ControlLoopEvent.java +++ b/controlloop/common/model-impl/events/src/main/java/org/onap/policy/controlloop/ControlLoopEvent.java @@ -27,17 +27,17 @@ public abstract class ControlLoopEvent implements Serializable { private static final long serialVersionUID = 2391252138583119195L; - public String closedLoopControlName; - public String version = "1.0.2"; - public UUID requestID; - public String closedLoopEventClient; - public ControlLoopTargetType target_type; - public String target; - public String from; - public String policyScope; - public String policyName; - public String policyVersion; - public ControlLoopEventStatus closedLoopEventStatus; + private String closedLoopControlName; + private String version = "1.0.2"; + private UUID requestID; + private String closedLoopEventClient; + private ControlLoopTargetType targetType; + private String target; + private String from; + private String policyScope; + private String policyName; + private String policyVersion; + private ControlLoopEventStatus closedLoopEventStatus; public ControlLoopEvent() { @@ -50,7 +50,7 @@ public abstract class ControlLoopEvent implements Serializable { this.closedLoopControlName = event.closedLoopControlName; this.requestID = event.requestID; this.closedLoopEventClient = event.closedLoopEventClient; - this.target_type = event.target_type; + this.targetType = event.targetType; this.target = event.target; this.from = event.from; this.policyScope = event.policyScope; @@ -59,11 +59,95 @@ public abstract class ControlLoopEvent implements Serializable { this.closedLoopEventStatus = event.closedLoopEventStatus; } - public boolean isEventStatusValid() { - if (this.closedLoopEventStatus == null) { - return false; - } - return true; + public boolean isEventStatusValid() { + return this.closedLoopEventStatus != null; + } + + public String getClosedLoopControlName() { + return closedLoopControlName; + } + + public void setClosedLoopControlName(String closedLoopControlName) { + this.closedLoopControlName = closedLoopControlName; + } + + public String getVersion() { + return version; + } + + public void setVersion(String version) { + this.version = version; + } + + public UUID getRequestID() { + return requestID; + } + + public void setRequestID(UUID requestID) { + this.requestID = requestID; + } + + public String getClosedLoopEventClient() { + return closedLoopEventClient; + } + + public void setClosedLoopEventClient(String closedLoopEventClient) { + this.closedLoopEventClient = closedLoopEventClient; + } + + public ControlLoopTargetType getTargetType() { + return targetType; + } + + public void setTargetType(ControlLoopTargetType targetType) { + this.targetType = targetType; + } + + public String getTarget() { + return target; + } + + public void setTarget(String target) { + this.target = target; + } + + public String getFrom() { + return from; + } + + public void setFrom(String from) { + this.from = from; + } + + public String getPolicyScope() { + return policyScope; + } + + public void setPolicyScope(String policyScope) { + this.policyScope = policyScope; } + public String getPolicyName() { + return policyName; + } + + public void setPolicyName(String policyName) { + this.policyName = policyName; + } + + public String getPolicyVersion() { + return policyVersion; + } + + public void setPolicyVersion(String policyVersion) { + this.policyVersion = policyVersion; + } + + public ControlLoopEventStatus getClosedLoopEventStatus() { + return closedLoopEventStatus; + } + + public void setClosedLoopEventStatus(ControlLoopEventStatus closedLoopEventStatus) { + this.closedLoopEventStatus = closedLoopEventStatus; + } } diff --git a/controlloop/common/model-impl/events/src/main/java/org/onap/policy/controlloop/ControlLoopNotification.java b/controlloop/common/model-impl/events/src/main/java/org/onap/policy/controlloop/ControlLoopNotification.java index 8e29b1de3..8e7a50fac 100644 --- a/controlloop/common/model-impl/events/src/main/java/org/onap/policy/controlloop/ControlLoopNotification.java +++ b/controlloop/common/model-impl/events/src/main/java/org/onap/policy/controlloop/ControlLoopNotification.java @@ -31,32 +31,155 @@ public abstract class ControlLoopNotification implements Serializable { private static final long serialVersionUID = 7538596984567127915L; - public String closedLoopControlName; - public String version = "1.0.2"; - public UUID requestID; - public String closedLoopEventClient; - public ControlLoopTargetType target_type; - public String target; - public String from; - public String policyScope; - public String policyName; - public String policyVersion; - public ControlLoopNotificationType notification; - public String message; - public ZonedDateTime notificationTime = ZonedDateTime.now(ZoneOffset.UTC);; - public Integer OPS_CL_timer; - public List history = new LinkedList(); + private String closedLoopControlName; + private String version = "1.0.2"; + private UUID requestID; + private String closedLoopEventClient; + private ControlLoopTargetType targetType; + private String target; + private String from; + private String policyScope; + private String policyName; + private String policyVersion; + private ControlLoopNotificationType notification; + private String message; + private ZonedDateTime notificationTime = ZonedDateTime.now(ZoneOffset.UTC); + private Integer opsCLTimer; + private List history = new LinkedList<>(); public ControlLoopNotification() { } public ControlLoopNotification(ControlLoopEvent event) { - this.closedLoopControlName = event.closedLoopControlName; - this.requestID = event.requestID; - this.closedLoopEventClient = event.closedLoopEventClient; - this.target_type = event.target_type; - this.target = event.target; + if (event == null) { + return; + } + + this.setClosedLoopControlName(event.getClosedLoopControlName()); + this.setRequestID(event.getRequestID()); + this.setClosedLoopEventClient(event.getClosedLoopEventClient()); + this.setTargetType(event.getTargetType()); + this.setTarget(event.getTarget()); + } + + public String getClosedLoopControlName() { + return closedLoopControlName; + } + + public void setClosedLoopControlName(String closedLoopControlName) { + this.closedLoopControlName = closedLoopControlName; + } + + public String getVersion() { + return version; + } + + public void setVersion(String version) { + this.version = version; + } + + public UUID getRequestID() { + return requestID; + } + + public void setRequestID(UUID requestID) { + this.requestID = requestID; + } + + public String getClosedLoopEventClient() { + return closedLoopEventClient; + } + + public void setClosedLoopEventClient(String closedLoopEventClient) { + this.closedLoopEventClient = closedLoopEventClient; + } + + public ControlLoopTargetType getTargetType() { + return targetType; + } + + public void setTargetType(ControlLoopTargetType targetType) { + this.targetType = targetType; + } + + public String getTarget() { + return target; + } + + public void setTarget(String target) { + this.target = target; + } + + public String getFrom() { + return from; + } + + public void setFrom(String from) { + this.from = from; + } + + public String getPolicyScope() { + return policyScope; + } + + public void setPolicyScope(String policyScope) { + this.policyScope = policyScope; + } + + public String getPolicyName() { + return policyName; + } + + public void setPolicyName(String policyName) { + this.policyName = policyName; + } + + public String getPolicyVersion() { + return policyVersion; + } + + public void setPolicyVersion(String policyVersion) { + this.policyVersion = policyVersion; + } + + public ControlLoopNotificationType getNotification() { + return notification; + } + + public void setNotification(ControlLoopNotificationType notification) { + this.notification = notification; } + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public ZonedDateTime getNotificationTime() { + return notificationTime; + } + + public void setNotificationTime(ZonedDateTime notificationTime) { + this.notificationTime = notificationTime; + } + + public Integer getOpsCLTimer() { + return opsCLTimer; + } + + public void setOpsCLTimer(Integer opsCLTimer) { + this.opsCLTimer = opsCLTimer; + } + + public List getHistory() { + return history; + } + + public void setHistory(List history) { + this.history = history; + } } diff --git a/controlloop/common/model-impl/events/src/main/java/org/onap/policy/controlloop/ControlLoopOperation.java b/controlloop/common/model-impl/events/src/main/java/org/onap/policy/controlloop/ControlLoopOperation.java index ce721b43d..d024b7cec 100644 --- a/controlloop/common/model-impl/events/src/main/java/org/onap/policy/controlloop/ControlLoopOperation.java +++ b/controlloop/common/model-impl/events/src/main/java/org/onap/policy/controlloop/ControlLoopOperation.java @@ -30,20 +30,24 @@ public class ControlLoopOperation implements Serializable { */ private static final long serialVersionUID = 8662706581293017099L; - public String actor; - public String operation; - public String target; - public Instant start = Instant.now(); - public Instant end; - public String subRequestId; - public String outcome; - public String message; + private String actor; + private String operation; + private String target; + private Instant start = Instant.now(); + private Instant end; + private String subRequestId; + private String outcome; + private String message; public ControlLoopOperation() { } public ControlLoopOperation(ControlLoopOperation op) { + if (op == null) { + return; + } + this.actor = op.actor; this.operation = op.operation; this.target = op.target; @@ -62,6 +66,70 @@ public class ControlLoopOperation implements Serializable { return "actor="+actor+",operation="+operation+",target="+target+",start="+start+",end="+end+",subRequestId="+subRequestId+",outcome="+outcome+",message="+message; } + public String getActor() { + return actor; + } + + public void setActor(String actor) { + this.actor = actor; + } + + public String getOperation() { + return operation; + } + + public void setOperation(String operation) { + this.operation = operation; + } + + public String getTarget() { + return target; + } + + public void setTarget(String target) { + this.target = target; + } + + public Instant getStart() { + return start; + } + + public void setStart(Instant start) { + this.start = start; + } + + public Instant getEnd() { + return end; + } + + public void setEnd(Instant end) { + this.end = end; + } + + public String getSubRequestId() { + return subRequestId; + } + + public void setSubRequestId(String subRequestId) { + this.subRequestId = subRequestId; + } + + public String getOutcome() { + return outcome; + } + + public void setOutcome(String outcome) { + this.outcome = outcome; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + @Override public String toString() { return "ControlLoopOperation [actor=" + actor + ", operation=" + operation + ", target=" + target + ", start=" diff --git a/controlloop/common/model-impl/events/src/main/java/org/onap/policy/controlloop/ControlLoopOperationWrapper.java b/controlloop/common/model-impl/events/src/main/java/org/onap/policy/controlloop/ControlLoopOperationWrapper.java index fb3942b63..f957808d1 100644 --- a/controlloop/common/model-impl/events/src/main/java/org/onap/policy/controlloop/ControlLoopOperationWrapper.java +++ b/controlloop/common/model-impl/events/src/main/java/org/onap/policy/controlloop/ControlLoopOperationWrapper.java @@ -24,8 +24,8 @@ import java.util.UUID; public class ControlLoopOperationWrapper { - public UUID requestID; - public ControlLoopOperation operation; + private UUID requestID; + private ControlLoopOperation operation; public ControlLoopOperationWrapper() { @@ -35,4 +35,20 @@ public class ControlLoopOperationWrapper { this.requestID = requestID; this.operation = operation; } + + public UUID getRequestID() { + return requestID; + } + + public void setRequestID(UUID requestID) { + this.requestID = requestID; + } + + public ControlLoopOperation getOperation() { + return operation; + } + + public void setOperation(ControlLoopOperation operation) { + this.operation = operation; + } } diff --git a/controlloop/common/model-impl/events/src/main/java/org/onap/policy/controlloop/PhysicalControlLoopEvent.java b/controlloop/common/model-impl/events/src/main/java/org/onap/policy/controlloop/PhysicalControlLoopEvent.java index aca072eaa..12ced939e 100644 --- a/controlloop/common/model-impl/events/src/main/java/org/onap/policy/controlloop/PhysicalControlLoopEvent.java +++ b/controlloop/common/model-impl/events/src/main/java/org/onap/policy/controlloop/PhysicalControlLoopEvent.java @@ -21,10 +21,6 @@ package org.onap.policy.controlloop; public class PhysicalControlLoopEvent extends ControlLoopEvent { - - /** - * - */ private static final long serialVersionUID = -7282930271094849487L; public PhysicalControlLoopEvent() { @@ -36,6 +32,4 @@ public class PhysicalControlLoopEvent extends ControlLoopEvent { return; } } - - } diff --git a/controlloop/common/model-impl/events/src/main/java/org/onap/policy/controlloop/PhysicalControlLoopNotification.java b/controlloop/common/model-impl/events/src/main/java/org/onap/policy/controlloop/PhysicalControlLoopNotification.java index c904d6740..9c63665ae 100644 --- a/controlloop/common/model-impl/events/src/main/java/org/onap/policy/controlloop/PhysicalControlLoopNotification.java +++ b/controlloop/common/model-impl/events/src/main/java/org/onap/policy/controlloop/PhysicalControlLoopNotification.java @@ -21,10 +21,6 @@ package org.onap.policy.controlloop; public class PhysicalControlLoopNotification extends ControlLoopNotification { - - /** - * - */ private static final long serialVersionUID = 8105197217140032892L; public PhysicalControlLoopNotification() { diff --git a/controlloop/common/model-impl/events/src/main/java/org/onap/policy/controlloop/VirtualControlLoopEvent.java b/controlloop/common/model-impl/events/src/main/java/org/onap/policy/controlloop/VirtualControlLoopEvent.java index 932da84fc..c512b6796 100644 --- a/controlloop/common/model-impl/events/src/main/java/org/onap/policy/controlloop/VirtualControlLoopEvent.java +++ b/controlloop/common/model-impl/events/src/main/java/org/onap/policy/controlloop/VirtualControlLoopEvent.java @@ -30,9 +30,9 @@ public class VirtualControlLoopEvent extends ControlLoopEvent { * */ private static final long serialVersionUID = -5752405682246066226L; - public Instant closedLoopAlarmStart; - public Instant closedLoopAlarmEnd; - public Map AAI = new HashMap<>(); + private Instant closedLoopAlarmStart; + private Instant closedLoopAlarmEnd; + private Map aai = new HashMap<>(); public VirtualControlLoopEvent() { } @@ -42,11 +42,34 @@ public class VirtualControlLoopEvent extends ControlLoopEvent { if (event == null) { return; } - if (event.AAI != null) { - this.AAI = new HashMap<>(event.AAI); + if (event.aai != null) { + this.aai = new HashMap<>(event.aai); } this.closedLoopAlarmStart = event.closedLoopAlarmStart; this.closedLoopAlarmEnd = event.closedLoopAlarmEnd; } + public Instant getClosedLoopAlarmStart() { + return closedLoopAlarmStart; + } + + public void setClosedLoopAlarmStart(Instant closedLoopAlarmStart) { + this.closedLoopAlarmStart = closedLoopAlarmStart; + } + + public Instant getClosedLoopAlarmEnd() { + return closedLoopAlarmEnd; + } + + public void setClosedLoopAlarmEnd(Instant closedLoopAlarmEnd) { + this.closedLoopAlarmEnd = closedLoopAlarmEnd; + } + + public Map getAAI() { + return aai; + } + + public void setAAI(Map aai) { + this.aai = aai; + } } diff --git a/controlloop/common/model-impl/events/src/main/java/org/onap/policy/controlloop/VirtualControlLoopNotification.java b/controlloop/common/model-impl/events/src/main/java/org/onap/policy/controlloop/VirtualControlLoopNotification.java index 7415fccf0..c99e3a1b0 100644 --- a/controlloop/common/model-impl/events/src/main/java/org/onap/policy/controlloop/VirtualControlLoopNotification.java +++ b/controlloop/common/model-impl/events/src/main/java/org/onap/policy/controlloop/VirtualControlLoopNotification.java @@ -31,9 +31,9 @@ public class VirtualControlLoopNotification extends ControlLoopNotification { */ private static final long serialVersionUID = 5354756047932144017L; - public Map AAI = new HashMap<>(); - public Instant closedLoopAlarmStart; - public Instant closedLoopAlarmEnd; + private Map aai = new HashMap<>(); + private Instant closedLoopAlarmStart; + private Instant closedLoopAlarmEnd; public VirtualControlLoopNotification() { } @@ -43,11 +43,34 @@ public class VirtualControlLoopNotification extends ControlLoopNotification { if (event == null) { return; } - if (event.AAI != null) { - this.AAI = new HashMap<>(event.AAI); + if (event.getAAI() != null) { + this.setAAI(new HashMap<>(event.getAAI())); } - this.closedLoopAlarmStart = event.closedLoopAlarmStart; - this.closedLoopAlarmEnd = event.closedLoopAlarmEnd; + this.closedLoopAlarmStart = event.getClosedLoopAlarmStart(); + this.closedLoopAlarmEnd = event.getClosedLoopAlarmEnd(); } + public Map getAAI() { + return aai; + } + + public void setAAI(Map aAI) { + this.aai = aAI; + } + + public Instant getClosedLoopAlarmStart() { + return closedLoopAlarmStart; + } + + public void setClosedLoopAlarmStart(Instant closedLoopAlarmStart) { + this.closedLoopAlarmStart = closedLoopAlarmStart; + } + + public Instant getClosedLoopAlarmEnd() { + return closedLoopAlarmEnd; + } + + public void setClosedLoopAlarmEnd(Instant closedLoopAlarmEnd) { + this.closedLoopAlarmEnd = closedLoopAlarmEnd; + } } diff --git a/controlloop/common/model-impl/events/src/main/java/org/onap/policy/controlloop/util/Serialization.java b/controlloop/common/model-impl/events/src/main/java/org/onap/policy/controlloop/util/Serialization.java index 858dc82b9..d2a51f770 100644 --- a/controlloop/common/model-impl/events/src/main/java/org/onap/policy/controlloop/util/Serialization.java +++ b/controlloop/common/model-impl/events/src/main/java/org/onap/policy/controlloop/util/Serialization.java @@ -35,17 +35,15 @@ import com.google.gson.GsonBuilder; import com.google.gson.JsonDeserializationContext; import com.google.gson.JsonDeserializer; import com.google.gson.JsonElement; -import com.google.gson.JsonParseException; import com.google.gson.JsonPrimitive; import com.google.gson.JsonSerializationContext; import com.google.gson.JsonSerializer; - public final class Serialization { + private Serialization() { + } - public static class notificationTypeAdapter implements JsonSerializer, JsonDeserializer { - - + public static class NotificationTypeAdapter implements JsonSerializer, JsonDeserializer { @Override public JsonElement serialize(ControlLoopNotificationType src, Type typeOfSrc, JsonSerializationContext context) { @@ -54,14 +52,12 @@ public final class Serialization { @Override public ControlLoopNotificationType deserialize(JsonElement json, Type typeOfT, - JsonDeserializationContext context) throws JsonParseException { + JsonDeserializationContext context) { return ControlLoopNotificationType.toType(json.getAsString()); } - } - - public static class targetTypeAdapter implements JsonSerializer, JsonDeserializer { + public static class TargetTypeAdapter implements JsonSerializer, JsonDeserializer { @Override public JsonElement serialize(ControlLoopTargetType src, Type typeOfSrc, JsonSerializationContext context) { @@ -70,19 +66,17 @@ public final class Serialization { @Override public ControlLoopTargetType deserialize(JsonElement json, Type typeOfT, - JsonDeserializationContext context) throws JsonParseException { + JsonDeserializationContext context) { return ControlLoopTargetType.toType(json.getAsString()); } - } - - public static class gsonUTCAdapter implements JsonSerializer, JsonDeserializer { - private static final Logger logger = LoggerFactory.getLogger(gsonUTCAdapter.class); + + public static class GSONUTCAdapter implements JsonSerializer, JsonDeserializer { + private static final Logger logger = LoggerFactory.getLogger(GSONUTCAdapter.class); public static final DateTimeFormatter format = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSSSSSxxx"); - @Override - public ZonedDateTime deserialize(JsonElement element, Type type, JsonDeserializationContext context) - throws JsonParseException { + @Override + public ZonedDateTime deserialize(JsonElement element, Type type, JsonDeserializationContext context) { try { return ZonedDateTime.parse(element.getAsString(), format); } catch (Exception e) { @@ -91,17 +85,16 @@ public final class Serialization { return null; } - @Override + @Override public JsonElement serialize(ZonedDateTime datetime, Type type, JsonSerializationContext context) { return new JsonPrimitive(datetime.format(format)); } } - - public static class gsonInstantAdapter implements JsonSerializer, JsonDeserializer { + + public static class GSONInstantAdapter implements JsonSerializer, JsonDeserializer { @Override - public Instant deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) - throws JsonParseException { + public Instant deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) { return Instant.ofEpochMilli(json.getAsLong()); } @@ -109,30 +102,30 @@ public final class Serialization { public JsonElement serialize(Instant src, Type typeOfSrc, JsonSerializationContext context) { return new JsonPrimitive(src.toEpochMilli()); } - + } - - final static public Gson gson = new GsonBuilder().disableHtmlEscaping() - .registerTypeAdapter(ZonedDateTime.class, new gsonUTCAdapter()) - .registerTypeAdapter(Instant.class, new gsonInstantAdapter()) - .registerTypeAdapter(ControlLoopNotificationType.class, new notificationTypeAdapter()) - .registerTypeAdapter(ControlLoopTargetType.class, new targetTypeAdapter()) + + public static final Gson gson = new GsonBuilder().disableHtmlEscaping() + .registerTypeAdapter(ZonedDateTime.class, new GSONUTCAdapter()) + .registerTypeAdapter(Instant.class, new GSONInstantAdapter()) + .registerTypeAdapter(ControlLoopNotificationType.class, new NotificationTypeAdapter()) + .registerTypeAdapter(ControlLoopTargetType.class, new TargetTypeAdapter()) .create(); - - final static public Gson gsonPretty = new GsonBuilder().disableHtmlEscaping() + + public static final Gson gsonPretty = new GsonBuilder().disableHtmlEscaping() .setPrettyPrinting() - .registerTypeAdapter(ZonedDateTime.class, new gsonUTCAdapter()) - .registerTypeAdapter(Instant.class, new gsonInstantAdapter()) - .registerTypeAdapter(ControlLoopNotificationType.class, new notificationTypeAdapter()) - .registerTypeAdapter(ControlLoopTargetType.class, new targetTypeAdapter()) + .registerTypeAdapter(ZonedDateTime.class, new GSONUTCAdapter()) + .registerTypeAdapter(Instant.class, new GSONInstantAdapter()) + .registerTypeAdapter(ControlLoopNotificationType.class, new NotificationTypeAdapter()) + .registerTypeAdapter(ControlLoopTargetType.class, new TargetTypeAdapter()) .create(); - - final static public Gson gsonJunit = new GsonBuilder().disableHtmlEscaping() + + public static final Gson gsonJunit = new GsonBuilder().disableHtmlEscaping() .setPrettyPrinting() - .registerTypeAdapter(ZonedDateTime.class, new gsonUTCAdapter()) - .registerTypeAdapter(Instant.class, new gsonInstantAdapter()) - .registerTypeAdapter(ControlLoopTargetType.class, new targetTypeAdapter()) + .registerTypeAdapter(ZonedDateTime.class, new GSONUTCAdapter()) + .registerTypeAdapter(Instant.class, new GSONInstantAdapter()) + .registerTypeAdapter(ControlLoopTargetType.class, new TargetTypeAdapter()) .create(); } -- cgit 1.2.3-korg