From 96affd1029ef06917c3605b235cf678308939662 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sim=C3=A3o=20Mata?= Date: Thu, 30 Jan 2020 18:08:43 +0100 Subject: [PATCH] New endpoint to force targets refresh --- .../director/http/AdminResource.scala | 17 +++++++++------ .../director/repo/DeviceRoleGeneration.scala | 5 +++++ .../director/http/AdminResourceSpec.scala | 21 ++++++++++++++++++- .../http/AutoUpdateResourceSpec.scala | 7 +++---- .../director/util/DirectorSpec.scala | 3 ++- 5 files changed, 41 insertions(+), 12 deletions(-) diff --git a/src/main/scala/com/advancedtelematic/director/http/AdminResource.scala b/src/main/scala/com/advancedtelematic/director/http/AdminResource.scala index de7d6f5..5dbb208 100644 --- a/src/main/scala/com/advancedtelematic/director/http/AdminResource.scala +++ b/src/main/scala/com/advancedtelematic/director/http/AdminResource.scala @@ -15,11 +15,12 @@ import com.advancedtelematic.libats.messaging.MessageBusPublisher import com.advancedtelematic.libats.messaging_datatype.DataType.DeviceId import com.advancedtelematic.libtuf.data.ClientCodecs._ import com.advancedtelematic.libtuf.data.TufCodecs._ -import com.advancedtelematic.libtuf.data.TufDataType.TargetName +import com.advancedtelematic.libtuf.data.TufDataType.{RepoId, TargetName} import com.advancedtelematic.libtuf_server.keyserver.KeyserverClient import de.heikoseeberger.akkahttpcirce.FailFastCirceSupport._ import slick.jdbc.MySQLProfile.api._ import PaginationParametersDirectives._ +import com.advancedtelematic.director.repo.DeviceRoleGeneration import scala.concurrent.ExecutionContext @@ -37,6 +38,7 @@ class AdminResource(extractNamespace: Directive1[Namespace], val keyserverClient val deviceRegistration = new DeviceRegistration(keyserverClient) val repositoryCreation = new RepositoryCreation(keyserverClient) + val deviceRoleGeneration = new DeviceRoleGeneration(keyserverClient) def repoRoute(ns: Namespace): Route = pathPrefix("repo") { @@ -54,7 +56,7 @@ class AdminResource(extractNamespace: Directive1[Namespace], val keyserverClient } } - def devicePath(ns: Namespace): Route = + def devicePath(ns: Namespace, repoId: RepoId): Route = pathPrefix(DeviceId.Path) { device => pathPrefix("ecus") { pathPrefix(EcuIdPath) { ecuId => @@ -77,9 +79,12 @@ class AdminResource(extractNamespace: Directive1[Namespace], val keyserverClient } } } ~ - (pathEnd & get) { - val f = deviceRegistration.findDeviceEcuInfo(ns, device) - complete(f) + get { + val f = deviceRegistration.findDeviceEcuInfo(ns, device) + complete(f) + } ~ + (path("targets.json") & put) { + complete(deviceRoleGeneration.forceTargetsRefresh(ns, repoId, device).map(StatusCodes.Created -> _)) } } @@ -112,7 +117,7 @@ class AdminResource(extractNamespace: Directive1[Namespace], val keyserverClient complete(f) } } ~ - devicePath(ns) + devicePath(ns, repoId) } } } diff --git a/src/main/scala/com/advancedtelematic/director/repo/DeviceRoleGeneration.scala b/src/main/scala/com/advancedtelematic/director/repo/DeviceRoleGeneration.scala index 861e2f0..2bfa844 100644 --- a/src/main/scala/com/advancedtelematic/director/repo/DeviceRoleGeneration.scala +++ b/src/main/scala/com/advancedtelematic/director/repo/DeviceRoleGeneration.scala @@ -55,6 +55,11 @@ class DeviceRoleGeneration(keyserverClient: KeyserverClient)(implicit val db: Da } } + def forceTargetsRefresh(ns: Namespace, repoId: RepoId, deviceId: DeviceId): Future[JsonSignedPayload] = { + val refresher = roleRefresher(ns, deviceId) + refresher.refreshTargets(repoId).map(_.content) + } + def findFreshDeviceRole[T : TufRole](ns: Namespace, repoId: RepoId, deviceId: DeviceId): Future[JsonSignedPayload] = { implicit val refresher = roleRefresher(ns, deviceId) roleGeneration(ns, deviceId).findRole[T](repoId).map(_.content) diff --git a/src/test/scala/com/advancedtelematic/director/http/AdminResourceSpec.scala b/src/test/scala/com/advancedtelematic/director/http/AdminResourceSpec.scala index 91b0b92..1e0438f 100644 --- a/src/test/scala/com/advancedtelematic/director/http/AdminResourceSpec.scala +++ b/src/test/scala/com/advancedtelematic/director/http/AdminResourceSpec.scala @@ -16,7 +16,7 @@ import com.advancedtelematic.libats.data.DataType.Namespace import com.advancedtelematic.libats.data.{EcuIdentifier, PaginationResult} import com.advancedtelematic.libats.messaging_datatype.DataType.{DeviceId, UpdateId} import com.advancedtelematic.libtuf.data.ClientCodecs._ -import com.advancedtelematic.libtuf.data.ClientDataType.RootRole +import com.advancedtelematic.libtuf.data.ClientDataType.{RootRole, TargetsRole} import com.advancedtelematic.libtuf.data.TufCodecs._ import com.advancedtelematic.libtuf.data.TufDataType.{HardwareIdentifier, SignedPayload, TargetFilename, TufKey, TufKeyPair} import de.heikoseeberger.akkahttpcirce.FailFastCirceSupport._ @@ -159,4 +159,23 @@ class AdminResourceSpec extends DirectorSpec resp.head.image.filepath shouldBe targetUpdate.target } } + + testWithRepo("PUT devices/id/targets.json forces refresh of devices targets.json") { implicit ns => + val dev = registerAdminDeviceOk() + + Get(apiUri(s"device/${dev.deviceId.show}/targets.json")).namespaced ~> routes ~> check { + status shouldBe StatusCodes.OK + responseAs[SignedPayload[TargetsRole]].signed.version shouldBe 1 + } + + Put(apiUri(s"admin/devices/${dev.deviceId.show}/targets.json")).namespaced ~> routes ~> check { + status shouldBe StatusCodes.Created + responseAs[SignedPayload[TargetsRole]].signed.version shouldBe 2 + } + + Get(apiUri(s"device/${dev.deviceId.show}/targets.json")).namespaced ~> routes ~> check { + status shouldBe StatusCodes.OK + responseAs[SignedPayload[TargetsRole]].signed.version shouldBe 2 + } + } } diff --git a/src/test/scala/com/advancedtelematic/director/http/AutoUpdateResourceSpec.scala b/src/test/scala/com/advancedtelematic/director/http/AutoUpdateResourceSpec.scala index da43b83..37ca064 100644 --- a/src/test/scala/com/advancedtelematic/director/http/AutoUpdateResourceSpec.scala +++ b/src/test/scala/com/advancedtelematic/director/http/AutoUpdateResourceSpec.scala @@ -1,12 +1,11 @@ package com.advancedtelematic.director.http import akka.http.scaladsl.model.StatusCodes -import com.advancedtelematic.director.db.{DbSignedRoleRepositorySupport, RepoNamespaceRepositorySupport} -import com.advancedtelematic.director.util.{DeviceManifestSpec, DirectorSpec, RepositorySpec, RouteResourceSpec} -import com.advancedtelematic.libtuf.data.TufDataType.TargetName import cats.syntax.show._ -import de.heikoseeberger.akkahttpcirce.FailFastCirceSupport._ +import com.advancedtelematic.director.util.{DefaultPatience, DirectorSpec, RepositorySpec, RouteResourceSpec} import com.advancedtelematic.libtuf.data.ClientCodecs._ +import com.advancedtelematic.libtuf.data.TufDataType.TargetName +import de.heikoseeberger.akkahttpcirce.FailFastCirceSupport._ class AutoUpdateResourceSpec extends DirectorSpec with RouteResourceSpec diff --git a/src/test/scala/com/advancedtelematic/director/util/DirectorSpec.scala b/src/test/scala/com/advancedtelematic/director/util/DirectorSpec.scala index 5fb5e31..30edf48 100644 --- a/src/test/scala/com/advancedtelematic/director/util/DirectorSpec.scala +++ b/src/test/scala/com/advancedtelematic/director/util/DirectorSpec.scala @@ -30,7 +30,8 @@ object NamespacedTests extends NamespacedTests abstract class DirectorSpec extends FunSuite with Matchers with ScalaFutures - with NamespacedTests { + with NamespacedTests + with DefaultPatience { Security.addProvider(new BouncyCastleProvider())