Skip to content
This repository was archived by the owner on Mar 27, 2023. It is now read-only.

Commit 4506161

Browse files
author
Michel Zimmer
committed
Refactor stats to be able to drop old data
1 parent 811be95 commit 4506161

File tree

9 files changed

+204
-54
lines changed

9 files changed

+204
-54
lines changed

.dockerignore

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,5 +2,4 @@
22
!project/build.properties
33
!project/plugins.sbt
44
!src/
5-
!build.sbt
6-
!Dockerfile
5+
!build.sbt

.sdkmanrc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
11
java=17.0.3-tem
2-
sbt=1.6.2
2+
sbt=1.7.1

Dockerfile

Lines changed: 5 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,7 @@
1-
FROM eclipse-temurin:17.0.3_7-jre-alpine as build
2-
RUN set -euxo pipefail; \
3-
apk update; \
4-
apk add --no-cache \
5-
bash \
6-
ca-certificates \
7-
;
8-
ADD https://github.com/sbt/sbt/releases/download/v1.6.2/sbt-1.6.2.tgz /tmp/sbt-1.6.2.tgz
9-
RUN set -euxo pipefail; \
10-
tar --extract --gzip --file /tmp/sbt-1.6.2.tgz --directory /opt; \
11-
rm -rf /tmp/sbt-1.6.2.tgz; \
12-
chown -hR root:root /opt/sbt
13-
WORKDIR /opt/sbt
14-
RUN set -euxo pipefail; \
15-
/opt/sbt/bin/sbt sbtVersion
16-
COPY --chown=root:root . /tmp/bandwhichd-server/
1+
FROM sbtscala/scala-sbt:eclipse-temurin-17.0.3_1.7.1_3.1.3 as build
172
WORKDIR /tmp/bandwhichd-server
18-
RUN /opt/sbt/bin/sbt assembly
3+
COPY --chown=sbtuser:sbtuser . ./
4+
RUN sbt assembly
195

206
FROM eclipse-temurin:17.0.3_7-jre-alpine
217
LABEL org.opencontainers.image.authors="neuland Open Source Maintainers <[email protected]>"
@@ -26,11 +12,11 @@ LABEL org.opencontainers.image.vendor="neuland – Büro für Informatik GmbH"
2612
LABEL org.opencontainers.image.licenses="Apache-2.0"
2713
LABEL org.opencontainers.image.title="bandwhichd-server"
2814
LABEL org.opencontainers.image.description="bandwhichd server collecting measurements and calculating statistics"
29-
LABEL org.opencontainers.image.version="0.6.0-rc2"
15+
LABEL org.opencontainers.image.version="0.6.0-rc3"
3016
USER guest
3117
ENTRYPOINT ["/opt/java/openjdk/bin/java"]
3218
CMD ["-jar", "/opt/bandwhichd-server.jar"]
3319
EXPOSE 8080
3420
HEALTHCHECK --interval=5s --timeout=1s --start-period=2s --retries=2 \
3521
CMD wget --spider http://localhost:8080/v1/health || exit 1
36-
COPY --from=build --chown=root:root /tmp/bandwhichd-server/target/scala-3.1.2/bandwhichd-server-assembly-0.6.0-rc2.jar /opt/bandwhichd-server.jar
22+
COPY --from=build --chown=root:root /tmp/bandwhichd-server/target/scala-3.1.3/bandwhichd-server-assembly-0.6.0-rc3.jar /opt/bandwhichd-server.jar

build.sbt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@ lazy val root = (project in file("."))
22
.settings(
33
organization := "de.neuland-bfi",
44
name := "bandwhichd-server",
5-
version := "0.6.0-rc2",
6-
scalaVersion := "3.1.2",
5+
version := "0.6.0-rc3",
6+
scalaVersion := "3.1.3",
77
Compile / scalaSource := baseDirectory.value / "src" / "main" / "scala",
88
Test / scalaSource := baseDirectory.value / "src" / "test" / "scala",
99
Test / fork := true,

project/build.properties

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
sbt.version=1.6.2
1+
sbt.version=1.7.1

src/main/scala/de/neuland/bandwhichd/server/domain/stats/Host.scala

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -30,21 +30,21 @@ case class UnidentifiedHost(
3030
}
3131

3232
object UnidentifiedHost {
33-
type HostId = HostId.HostHostId
33+
type HostId = HostId.Host
3434
}
3535

3636
sealed trait IdentifiedHost[+I <: HostId] extends AnyHost[I]
3737

38-
sealed trait MachineIdHost extends IdentifiedHost[HostId.MachineIdHostId] {
38+
sealed trait MachineIdHost extends IdentifiedHost[HostId.MachineId] {
3939
def hostId: MachineIdHost.HostId
4040
}
4141

4242
object MachineIdHost {
43-
type HostId = HostId.MachineIdHostId
43+
type HostId = HostId.MachineId
4444
}
4545

4646
case class MonitoredHost(
47-
hostId: HostId.MachineIdHostId,
47+
hostId: HostId.MachineId,
4848
agentIds: Set[AgentId],
4949
hostname: Hostname,
5050
additionalHostnames: Set[Hostname],
Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
package de.neuland.bandwhichd.server.domain.stats
22

3-
import com.comcast.ip4s.{Host, Hostname, IDN}
4-
import de.neuland.bandwhichd.server.domain.MachineId
3+
import com.comcast.ip4s.{Host => Ip4sHost, Hostname, IDN}
4+
import de.neuland.bandwhichd.server.domain.{MachineId => BandwhichdMachineId}
55

66
import java.nio.charset.StandardCharsets
77
import java.nio.charset.StandardCharsets.UTF_8
@@ -13,19 +13,19 @@ sealed trait HostId {
1313
}
1414

1515
object HostId {
16-
case class MachineIdHostId(machineId: MachineId) extends HostId {
16+
case class MachineId(machineId: BandwhichdMachineId) extends HostId {
1717
override def uuid: UUID =
1818
machineId.value
1919
}
2020

21-
case class HostHostId(host: Host) extends HostId {
21+
case class Host(host: Ip4sHost) extends HostId {
2222
override def uuid: UUID =
2323
UUID.nameUUIDFromBytes(host.toString.getBytes(UTF_8))
2424
}
2525

26-
def apply(machineId: MachineId): MachineIdHostId =
27-
MachineIdHostId(machineId)
26+
def apply(machineId: BandwhichdMachineId): MachineId =
27+
MachineId(machineId)
2828

29-
def apply(host: Host): HostHostId =
30-
HostHostId(host)
29+
def apply(host: Ip4sHost): Host =
30+
Host(host)
3131
}

src/main/scala/de/neuland/bandwhichd/server/domain/stats/Stats.scala

Lines changed: 42 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -28,14 +28,31 @@ class Stats[L <: HostId, H <: AnyHost[L], R <: HostId] private (
2828

2929
def connections: Set[(L, R)] =
3030
bundles.values.flatMap { bundle =>
31-
bundle.remoteHostIds.map { remoteHostId =>
31+
bundle.connections.keys.map { remoteHostId =>
3232
bundle.host.hostId -> remoteHostId
3333
}
3434
}.toSet
35+
36+
def dropBefore(timestamp: Timing.Timestamp): Stats[L, H, R] =
37+
new Stats(
38+
bundles
39+
.filterNot { case (_, bundle) =>
40+
bundle.lastSeenAt.instant.isBefore(timestamp.instant)
41+
}
42+
.view
43+
.mapValues(bundle =>
44+
bundle.copy(
45+
connections = bundle.connections.filterNot { case (_, connection) =>
46+
connection.lastSeenAt.instant.isBefore(timestamp.instant)
47+
}
48+
)
49+
)
50+
.toMap
51+
)
3552
}
3653

3754
type AnyStats = Stats[HostId, AnyHost[HostId], HostId]
38-
type MonitoredStats = Stats[HostId.MachineIdHostId, MonitoredHost, HostId]
55+
type MonitoredStats = Stats[HostId.MachineId, MonitoredHost, HostId]
3956

4057
object Stats {
4158
val defaultTimeframeDuration: Duration = Duration.ofHours(2)
@@ -69,10 +86,10 @@ object Stats {
6986
interfaces,
7087
_
7188
) =>
72-
val hostId: HostId.MachineIdHostId = HostId(machineId)
89+
val hostId: HostId.MachineId = HostId(machineId)
7390

7491
val maybeBundle
75-
: Option[Bundle[HostId.MachineIdHostId, MonitoredHost, HostId]] =
92+
: Option[Bundle[HostId.MachineId, MonitoredHost, HostId]] =
7693
stats.bundles
7794
.get(hostId)
7895
.orElse {
@@ -93,7 +110,7 @@ object Stats {
93110
interfaces = interfaces.toSet
94111
),
95112
lastSeenAt = timing,
96-
remoteHostIds = Set.empty
113+
connections = Map.empty
97114
)
98115
} { bundle =>
99116
bundle.copy(
@@ -121,7 +138,7 @@ object Stats {
121138
new Stats(
122139
stats.bundles + (bundle.host.hostId -> bundle.copy(
123140
lastSeenAt = timing.end,
124-
remoteHostIds = bundle.remoteHostIds ++ connections.map {
141+
connections = bundle.connections ++ connections.map {
125142
connection =>
126143

127144
val remoteHost: Host = connection.remoteSocket.value.host
@@ -148,7 +165,9 @@ object Stats {
148165
_.host.hostId
149166
)
150167

151-
remoteHostId
168+
remoteHostId -> Bundle.Connection(
169+
lastSeenAt = timing.end
170+
)
152171
}
153172
))
154173
)
@@ -163,10 +182,10 @@ object Stats {
163182
new Stats(
164183
stats.bundles.view.mapValues { bundle =>
165184
bundle.copy(
166-
remoteHostIds = bundle.remoteHostIds.filter {
167-
_ match
168-
case _: HostId.MachineIdHostId => true
169-
case HostId.HostHostId(ipAddress: IpAddress) =>
185+
connections = bundle.connections.filter {
186+
_._1 match
187+
case _: HostId.MachineId => true
188+
case HostId.Host(ipAddress: IpAddress) =>
170189
stats.monitoredNetworks.exists(_.contains(ipAddress))
171190
case _ => false
172191
}
@@ -176,20 +195,26 @@ object Stats {
176195

177196
def unidentifiedRemoteHosts: Set[UnidentifiedHost] =
178197
stats.bundles.values.flatMap { bundle =>
179-
bundle.remoteHostIds.flatMap {
180-
_ match
181-
case HostId.HostHostId(host) => Some(UnidentifiedHost(host))
182-
case HostId.MachineIdHostId(_) => None
198+
bundle.connections.flatMap {
199+
_._1 match
200+
case HostId.Host(host) => Some(UnidentifiedHost(host))
201+
case HostId.MachineId(_) => None
183202
}
184203
}.toSet
185204

186205
def allHosts: Set[AnyHost[HostId]] =
187206
stats.hosts ++ stats.unidentifiedRemoteHosts
188207
}
189208

190-
private case class Bundle[L <: HostId, H <: AnyHost[L], R <: HostId](
209+
private[Stats] case class Bundle[L <: HostId, H <: AnyHost[L], R <: HostId](
191210
host: H,
192211
lastSeenAt: Timing.Timestamp,
193-
remoteHostIds: Set[R]
212+
connections: Map[R, Bundle.Connection]
194213
)
214+
215+
private[Stats] object Bundle {
216+
private[Stats] case class Connection(
217+
lastSeenAt: Timing.Timestamp
218+
)
219+
}
195220
}

0 commit comments

Comments
 (0)