diff --git a/aws/fargate/startup.sh b/aws/fargate/startup.sh index c3ddd061e2..353ea43aa3 100644 --- a/aws/fargate/startup.sh +++ b/aws/fargate/startup.sh @@ -9,12 +9,7 @@ else echo "batchRunType env is not defined" exit 1 else - if [ "$batchRunType" = "UpdateIncompleteLinkList" ]; then - - echo "UpdateIncompleteLinkList" - java $javaParameter -cp /digiroad2.jar fi.liikennevirasto.digiroad2.util.UpdateIncompleteLinkList - elif [ "$batchRunType" = "DataFixture" ] && [[ ! -z "$trafficSignGroup" ]]; then - + if [ "$batchRunType" = "DataFixture" ] && [[ ! -z "$trafficSignGroup" ]]; then echo "DataFixture with trafficSignGroup" if [[ ! -z "$batchAction" ]]; then java $javaParameter -cp /digiroad2.jar fi.liikennevirasto.digiroad2.util.DataFixture "$batchAction" "$trafficSignGroup" diff --git a/digiroad2-api-common/src/main/scala/fi/liikennevirasto/digiroad2/Digiroad2Context.scala b/digiroad2-api-common/src/main/scala/fi/liikennevirasto/digiroad2/Digiroad2Context.scala index ea10adc2d2..dc217683be 100644 --- a/digiroad2-api-common/src/main/scala/fi/liikennevirasto/digiroad2/Digiroad2Context.scala +++ b/digiroad2-api-common/src/main/scala/fi/liikennevirasto/digiroad2/Digiroad2Context.scala @@ -187,12 +187,6 @@ class SpeedLimitSaveProjected[T](speedLimitProvider: SpeedLimitService) extends } } -class LinkPropertyUpdater(roadLinkService: RoadLinkService) extends Actor { - def receive = { - case w: RoadLinkChangeSet => roadLinkService.updateRoadLinkChanges(w) - case _ => println("linkPropertyUpdater: Received unknown message") - } -} class ProhibitionSaveProjected[T](prohibitionProvider: ProhibitionService) extends Actor { def receive = { @@ -368,9 +362,6 @@ object Digiroad2Context { eventbus.subscribe(speedLimitUpdater, "speedLimits:persistUnknownLimits") eventbus.subscribe(speedLimitUpdater, "speedLimits:update") - val linkPropertyUpdater = system.actorOf(Props(classOf[LinkPropertyUpdater], roadLinkService), name = "linkPropertyUpdater") - eventbus.subscribe(linkPropertyUpdater, "linkProperties:changed") - val prohibitionSaveProjected = system.actorOf(Props(classOf[ProhibitionSaveProjected[PersistedLinearAsset]], prohibitionService), name = "prohibitionSaveProjected") eventbus.subscribe(prohibitionSaveProjected, "prohibition:saveProjectedProhibition") diff --git a/digiroad2-api-common/src/main/scala/fi/liikennevirasto/digiroad2/util/UpdateIncompleteLinkList.scala b/digiroad2-api-common/src/main/scala/fi/liikennevirasto/digiroad2/util/UpdateIncompleteLinkList.scala deleted file mode 100644 index 70d7633d40..0000000000 --- a/digiroad2-api-common/src/main/scala/fi/liikennevirasto/digiroad2/util/UpdateIncompleteLinkList.scala +++ /dev/null @@ -1,58 +0,0 @@ -package fi.liikennevirasto.digiroad2.util - -import fi.liikennevirasto.digiroad2.Digiroad2Context -import fi.liikennevirasto.digiroad2.dao.Queries -import fi.liikennevirasto.digiroad2.postgis.PostGISDatabase -import org.slf4j.LoggerFactory -import slick.driver.JdbcDriver.backend.Database.dynamicSession -import slick.jdbc.StaticQuery.interpolation - -import scala.sys.exit - -object UpdateIncompleteLinkList { - val logger = LoggerFactory.getLogger(getClass) - def main(args:Array[String]) : Unit = { - val batchMode = Digiroad2Properties.batchMode - if (!batchMode) { - println("*******************************************************************************************") - println("TURN ENV batchMode true TO RUN UpdateIncompleteLinkList") - println("*******************************************************************************************") - exit() - } - try { - UpdateIncompleteLinkList.runUpdate() - } finally { - Digiroad2Context.system.terminate() - exit() - } - } - - private def runUpdate(): Unit = { - logger.info("*** Delete incomplete links") - clearIncompleteLinks() - logger.info("*** Get municipalities") - val municipalities: Seq[Int] = PostGISDatabase.withDynSession { - Queries.getMunicipalities - } - - var counter = 0 - municipalities.foreach { municipality => - val timer1 = System.currentTimeMillis() - logger.info("*** Processing municipality: " + municipality) - val roadLinks = Digiroad2Context.roadLinkService.getRoadLinksFromVVH(municipality) - counter += 1 - logger.info("*** Processed " + roadLinks.length + " road links with municipality " + municipality) - logger.info(s" number of succeeding municipalities $counter from all ${municipalities.size}") - logger.info("processing took: %.3f sec".format((System.currentTimeMillis() - timer1) * 0.001)) - } - val awaitTime = 1000L * 60L * 60 - logger.info("await 60 minutes to make sure akka inbox is fully processed") - Thread.sleep(awaitTime) - } - - private def clearIncompleteLinks(): Unit = { - PostGISDatabase.withDynTransaction { - sqlu"""truncate table incomplete_link""".execute - } - } -} diff --git a/digiroad2-api-oth/src/test/scala/fi/liikennevirasto/digiroad2/dataimport/CsvDataImporterSpec.scala b/digiroad2-api-oth/src/test/scala/fi/liikennevirasto/digiroad2/dataimport/CsvDataImporterSpec.scala index 71cecf7d36..b22bffada1 100644 --- a/digiroad2-api-oth/src/test/scala/fi/liikennevirasto/digiroad2/dataimport/CsvDataImporterSpec.scala +++ b/digiroad2-api-oth/src/test/scala/fi/liikennevirasto/digiroad2/dataimport/CsvDataImporterSpec.scala @@ -54,7 +54,7 @@ class CsvDataImporterSpec extends AuthenticatedApiSpec with BeforeAndAfter { val roadLink = Seq(RoadLink(1, Seq(Point(2, 2), Point(4, 4)), 3.5, Municipality, 1, TrafficDirection.BothDirections, Motorway, None, None, Map("MUNICIPALITYCODE" -> BigInt(408)))) when(mockRoadLinkService.getClosestRoadlinkForCarTrafficFromVVH(any[User], any[Point], any[Boolean])).thenReturn(roadLink) - when(mockRoadLinkService.enrichRoadLinksFromVVH(any[Seq[VVHRoadlink]], any[Seq[ChangeInfo]])).thenReturn(roadLink) + when(mockRoadLinkService.enrichRoadLinksFromVVH(any[Seq[VVHRoadlink]])).thenReturn(roadLink) def runWithRollback(test: => Unit): Unit = sTestTransactions.runWithRollback()(test) diff --git a/digiroad2-api-oth/src/test/scala/fi/liikennevirasto/digiroad2/dataimport/MassTransitStopCsvImporterSpec.scala b/digiroad2-api-oth/src/test/scala/fi/liikennevirasto/digiroad2/dataimport/MassTransitStopCsvImporterSpec.scala index 08e3391f77..496547b55f 100644 --- a/digiroad2-api-oth/src/test/scala/fi/liikennevirasto/digiroad2/dataimport/MassTransitStopCsvImporterSpec.scala +++ b/digiroad2-api-oth/src/test/scala/fi/liikennevirasto/digiroad2/dataimport/MassTransitStopCsvImporterSpec.scala @@ -48,7 +48,7 @@ class MassTransitStopCsvImporterSpec extends AuthenticatedApiSpec with BeforeAnd val roadLink = Seq(RoadLink(1, Seq(Point(2, 2), Point(4, 4)), 3.5, Municipality, 1, TrafficDirection.BothDirections, Motorway, None, None)) when(mockRoadLinkService.getClosestRoadlinkForCarTrafficFromVVH(any[User], any[Point], any[Boolean])).thenReturn(roadLink) - when(mockRoadLinkService.enrichRoadLinksFromVVH(any[Seq[VVHRoadlink]], any[Seq[ChangeInfo]])).thenReturn(roadLink) + when(mockRoadLinkService.enrichRoadLinksFromVVH(any[Seq[VVHRoadlink]])).thenReturn(roadLink) def runWithRollback(test: => Unit): Unit = sTestTransactions.runWithRollback()(test) diff --git a/digiroad2-oracle/src/main/scala/fi/liikennevirasto/digiroad2/client/CacheClient.scala b/digiroad2-oracle/src/main/scala/fi/liikennevirasto/digiroad2/client/CacheClient.scala index 64fa3eb061..2d3748ae6c 100644 --- a/digiroad2-oracle/src/main/scala/fi/liikennevirasto/digiroad2/client/CacheClient.scala +++ b/digiroad2-oracle/src/main/scala/fi/liikennevirasto/digiroad2/client/CacheClient.scala @@ -48,6 +48,7 @@ class CacheClient { case e: Exception => logger.error("Retrieval of cached value failed", e); throw e } } + } object Caching extends CacheClient { @@ -66,5 +67,11 @@ object Caching extends CacheClient { f } } + + def flush(): Boolean = { + val result = client.flush() + result.get() + } + } diff --git a/digiroad2-oracle/src/main/scala/fi/liikennevirasto/digiroad2/service/RoadLinkService.scala b/digiroad2-oracle/src/main/scala/fi/liikennevirasto/digiroad2/service/RoadLinkService.scala index 077d1cb024..0a17d66f52 100644 --- a/digiroad2-oracle/src/main/scala/fi/liikennevirasto/digiroad2/service/RoadLinkService.scala +++ b/digiroad2-oracle/src/main/scala/fi/liikennevirasto/digiroad2/service/RoadLinkService.scala @@ -20,6 +20,7 @@ import fi.liikennevirasto.digiroad2._ import fi.liikennevirasto.digiroad2.client.Caching import fi.liikennevirasto.digiroad2.dao.RoadLinkDAO.LinkAttributesDao import fi.liikennevirasto.digiroad2.util.ChangeLanesAccordingToVvhChanges.vvhClient +import fi.liikennevirasto.digiroad2.util.UpdateIncompleteLinkList.generateProperties import org.joda.time.format.{DateTimeFormat, ISODateTimeFormat} import org.joda.time.{DateTime, DateTimeZone} import org.slf4j.LoggerFactory @@ -220,10 +221,10 @@ class RoadLinkService(val vvhClient: VVHClient, val eventbus: DigiroadEventBus, val (changeInfos, complementaryLinks, vvhRoadLinks)= Await.result(fut, Duration.Inf) if (newTransaction) withDynTransaction { - (enrichRoadLinksFromVVH(vvhRoadLinks ++ complementaryLinks, changeInfos), changeInfos) + (enrichRoadLinksFromVVH(vvhRoadLinks ++ complementaryLinks), changeInfos) } else - (enrichRoadLinksFromVVH(vvhRoadLinks ++ complementaryLinks, changeInfos), changeInfos) + (enrichRoadLinksFromVVH(vvhRoadLinks ++ complementaryLinks), changeInfos) } @@ -258,6 +259,7 @@ class RoadLinkService(val vvhClient: VVHClient, val eventbus: DigiroadEventBus, fetchChangedVVHRoadlinksBetweenDates(since, until) } + /** * This method returns road links by municipality. * @@ -461,7 +463,7 @@ class RoadLinkService(val vvhClient: VVHClient, val eventbus: DigiroadEventBus, ) withDynTransaction { LogUtils.time(logger, "TEST LOG enrichRoadLinksFromVVH")( - (enrichRoadLinksFromVVH(links, changes), changes) + (enrichRoadLinksFromVVH(links), changes) ) } } @@ -469,7 +471,7 @@ class RoadLinkService(val vvhClient: VVHClient, val eventbus: DigiroadEventBus, def getRoadLinksAndChangesFromVVHWithPolygon(polygon :Polygon): (Seq[RoadLink], Seq[ChangeInfo])= { val (changes, links) = Await.result(vvhClient.roadLinkChangeInfo.fetchByPolygonF(polygon).zip(vvhClient.roadLinkData.fetchByPolygonF(polygon)), atMost = Duration.Inf) withDynTransaction { - (enrichRoadLinksFromVVH(links, changes), changes) + (enrichRoadLinksFromVVH(links), changes) } } @@ -483,7 +485,7 @@ class RoadLinkService(val vvhClient: VVHClient, val eventbus: DigiroadEventBus, val (complementaryLinks, changes, links) = Await.result(futures, Duration.Inf) withDynTransaction { - (enrichRoadLinksFromVVH(links ++ complementaryLinks, changes), changes) + (enrichRoadLinksFromVVH(links ++ complementaryLinks), changes) } } @@ -537,10 +539,10 @@ class RoadLinkService(val vvhClient: VVHClient, val eventbus: DigiroadEventBus, if(newTransaction){ withDynTransaction { - (enrichRoadLinksFromVVH(links ++ complementaryLinks, changes), changes) + (enrichRoadLinksFromVVH(links ++ complementaryLinks), changes) } } - else (enrichRoadLinksFromVVH(links ++ complementaryLinks, changes), changes) + else (enrichRoadLinksFromVVH(links ++ complementaryLinks), changes) } @@ -576,8 +578,8 @@ class RoadLinkService(val vvhClient: VVHClient, val eventbus: DigiroadEventBus, else enrichRoadLinksFromVVH(links ++ complementaryLinks) } - def reloadRoadLinksWithComplementaryAndChangesFromVVH(municipalities: Int): (Seq[RoadLink], Seq[ChangeInfo], Seq[RoadLink])= { - val fut = for{ + def reloadRoadLinksWithComplementaryAndChangesFromVVH(municipalities: Int): (Seq[RoadLink], Seq[ChangeInfo], Seq[RoadLink]) = { + val fut = for { f1Result <- vvhClient.complementaryData.fetchWalkwaysByMunicipalitiesF(municipalities) f2Result <- vvhClient.roadLinkChangeInfo.fetchByMunicipalityF(municipalities) f3Result <- vvhClient.roadLinkData.fetchByMunicipalityF(municipalities) @@ -586,9 +588,23 @@ class RoadLinkService(val vvhClient: VVHClient, val eventbus: DigiroadEventBus, val (complementaryLinks, changes, links) = Await.result(fut, Duration.Inf) withDynTransaction { - (enrichRoadLinksFromVVH(links, changes), changes, enrichRoadLinksFromVVH(complementaryLinks, changes)) + (enrichRoadLinksFromVVH(links), changes, enrichRoadLinksFromVVH(complementaryLinks)) } } + + def getLinksWithComplementaryAndGenerateProperties(municipalities: Int): (Seq[RoadLink], Seq[ChangeInfo], Seq[RoadLink])= { + val fut = for{ + f1Result <- vvhClient.complementaryData.fetchWalkwaysByMunicipalitiesF(municipalities) + f2Result <- vvhClient.roadLinkChangeInfo.fetchByMunicipalityF(municipalities) + f3Result <- vvhClient.roadLinkData.fetchByMunicipalityF(municipalities) + } yield (f1Result, f2Result, f3Result) + + val (complementaryLinks, changes, links) = Await.result(fut, Duration.Inf) + + withDynTransaction { + (generateProperties(links, changes), changes, generateProperties(complementaryLinks, changes)) + } + } /** * This method returns road links and change data by municipality. @@ -626,10 +642,10 @@ class RoadLinkService(val vvhClient: VVHClient, val eventbus: DigiroadEventBus, val ((links, links2), changes) = Await.result(links1F.zip(links2F).zip(changeF), atMost = Duration.apply(120, TimeUnit.SECONDS)) if(newTransaction) withDynTransaction { - (enrichRoadLinksFromVVH(links ++ links2, changes), changes) + (enrichRoadLinksFromVVH(links ++ links2), changes) } else - (enrichRoadLinksFromVVH(links ++ links2, changes), changes) + (enrichRoadLinksFromVVH(links ++ links2), changes) } /** @@ -990,30 +1006,6 @@ class RoadLinkService(val vvhClient: VVHClient, val eventbus: DigiroadEventBus, } } - /** - * Updates road link data in OTH db. Used by Digiroad2Context LinkPropertyUpdater Akka actor. - */ - def updateRoadLinkChanges(roadLinkChangeSet: RoadLinkChangeSet): Unit = { - - withDynTransaction { - LogUtils.time(logger, s"updateRoadLinkChanges updateIncompleteLinks incompleteLinks: ${roadLinkChangeSet.incompleteLinks.size},") { - updateIncompleteLinks(roadLinkChangeSet.incompleteLinks) - } - } - - withDynTransaction { - LogUtils.time(logger, s"updateRoadLinkChanges updateAutoGeneratedProperties adjustedRoadLinks: ${roadLinkChangeSet.adjustedRoadLinks.size},") { - updateAutoGeneratedProperties(roadLinkChangeSet.adjustedRoadLinks) - } - } - - withDynTransaction { - LogUtils.time(logger, s"updateRoadLinkChanges fillRoadLinkAttributes roadLinks: ${roadLinkChangeSet.roadLinks.size}, changes: ${roadLinkChangeSet.changes.size},") { - fillRoadLinkAttributes(roadLinkChangeSet.roadLinks, roadLinkChangeSet.changes) - } - } - } - def updateAutoGeneratedProperties(adjustedRoadLinks: Seq[AdjustedRoadLinksAndVVHRoadLink]): Unit = { def createUsernameForAutogenerated(modifiedBy: Option[String]): Option[String] = { modifiedBy match { @@ -1116,7 +1108,7 @@ class RoadLinkService(val vvhClient: VVHClient, val eventbus: DigiroadEventBus, /** * Updates incomplete road link list (incomplete = functional class or link type missing). Used by RoadLinkService.updateRoadLinkChanges. */ - protected def updateIncompleteLinks(incompleteLinks: Seq[IncompleteLink]): Unit = { + def updateIncompleteLinks(incompleteLinks: Seq[IncompleteLink]): Unit = { val insertLinkPropertyPS = dynamicSession.prepareStatement( s"""insert into incomplete_link(id, link_id, municipality_code, administrative_class) @@ -1300,7 +1292,7 @@ class RoadLinkService(val vvhClient: VVHClient, val eventbus: DigiroadEventBus, } }.toMap } - + def resolveChanges(changesToBeProcessed: Seq[ChangeInfo]): Unit = { changesToBeProcessed.foreach { change => ChangeType.apply(change.changeType) match { @@ -1342,64 +1334,12 @@ class RoadLinkService(val vvhClient: VVHClient, val eventbus: DigiroadEventBus, .sortWith(_.vvhTimeStamp < _.vvhTimeStamp) resolveChanges(changesToBeProcessed) } - - /** - * This method performs formatting operations to given vvh road links: - * - auto-generation of functional class and link type by feature class - * - information transfer from old link to new link from change data - * It also passes updated links and incomplete links to be saved to db by actor. - * - * @param allVvhRoadLinks - * @param changes - * @return Road links - */ - def enrichRoadLinksFromVVH(allVvhRoadLinks: Seq[VVHRoadlink], changes: Seq[ChangeInfo] = Nil): Seq[RoadLink] = { - val vvhRoadLinks = allVvhRoadLinks.filterNot(_.featureClass == FeatureClass.WinterRoads) - def autoGenerateProperties(roadLink: RoadLink): RoadLink = { - val vvhRoadLink = vvhRoadLinks.find(_.linkId == roadLink.linkId) - vvhRoadLink.get.featureClass match { - case FeatureClass.TractorRoad => roadLink.copy(functionalClass = 7, linkType = TractorRoad, modifiedBy = Some("automatic_generation"), modifiedAt = Some(DateTimePropertyFormat.print(DateTime.now()))) - case FeatureClass.DrivePath | FeatureClass.CarRoad_IIIb => roadLink.copy(functionalClass = 6, linkType = SingleCarriageway, modifiedBy = Some("automatic_generation"), modifiedAt = Some(DateTimePropertyFormat.print(DateTime.now()))) - case FeatureClass.CycleOrPedestrianPath => roadLink.copy(functionalClass = 8, linkType = CycleOrPedestrianPath, modifiedBy = Some("automatic_generation"), modifiedAt = Some(DateTimePropertyFormat.print(DateTime.now()))) - case FeatureClass.SpecialTransportWithoutGate => roadLink.copy(functionalClass = UnknownFunctionalClass.value, linkType = SpecialTransportWithoutGate, modifiedBy = Some("auto_generation"), modifiedAt = Some(DateTimePropertyFormat.print(DateTime.now()))) - case FeatureClass.SpecialTransportWithGate => roadLink.copy(functionalClass = UnknownFunctionalClass.value, linkType = SpecialTransportWithGate, modifiedBy = Some("auto_generation"), modifiedAt = Some(DateTimePropertyFormat.print(DateTime.now()))) - case FeatureClass.CarRoad_IIIa => vvhRoadLink.get.administrativeClass match { - case State => roadLink.copy(functionalClass = 4, linkType = SingleCarriageway, modifiedBy = Some("automatic_generation"), modifiedAt = Some(DateTimePropertyFormat.print(DateTime.now()))) - case Municipality | Private => roadLink.copy(functionalClass = 5, linkType = SingleCarriageway, modifiedBy = Some("automatic_generation"), modifiedAt = Some(DateTimePropertyFormat.print(DateTime.now()))) - case _ => roadLink - } - case _ => roadLink //similar logic used in roadaddressbuilder - } - } - def toIncompleteLink(roadLink: RoadLink): IncompleteLink = { - val vvhRoadLink = vvhRoadLinks.find(_.linkId == roadLink.linkId) - IncompleteLink(roadLink.linkId, vvhRoadLink.get.municipalityCode, roadLink.administrativeClass) - } - def canBeAutoGenerated(roadLink: RoadLink): Boolean = { - vvhRoadLinks.find(_.linkId == roadLink.linkId).get.featureClass match { - case FeatureClass.AllOthers => false - case _ => true - } - } - - val roadLinkDataByLinkId: Seq[RoadLink] = LogUtils.time(logger,"TEST LOG roadLinkDataByLinkId"){getRoadLinkDataByLinkIds(vvhRoadLinks)} - val (incompleteLinks, completeLinks) = roadLinkDataByLinkId.partition(isIncomplete) - val (linksToAutoGenerate, incompleteOtherLinks) = incompleteLinks.partition(canBeAutoGenerated) - val autoGeneratedLinks = linksToAutoGenerate.map(autoGenerateProperties) - val (changedLinks, stillIncompleteLinks) = LogUtils.time(logger,"TEST LOG fillIncompleteLinksWithPreviousLinkData"){ fillIncompleteLinksWithPreviousLinkData(incompleteOtherLinks, changes)} - val changedPartiallyIncompleteLinks = stillIncompleteLinks.filter(isPartiallyIncomplete) - val stillIncompleteLinksInUse = stillIncompleteLinks.filter(_.constructionType == ConstructionType.InUse) - - val adjustedRoadLinks = autoGeneratedLinks ++ changedLinks ++ changedPartiallyIncompleteLinks - val vvhRoadLinksGroupBy = allVvhRoadLinks.groupBy(_.linkId) - val pair = adjustedRoadLinks.map(r=>AdjustedRoadLinksAndVVHRoadLink(r,vvhRoadLinksGroupBy(r.linkId).last)) - - eventbus.publish("linkProperties:changed", RoadLinkChangeSet(pair, stillIncompleteLinksInUse.map(toIncompleteLink), changes, roadLinkDataByLinkId)) - completeLinks ++ autoGeneratedLinks ++ changedLinks ++ stillIncompleteLinks + def enrichRoadLinksFromVVH(allVvhRoadLinks: Seq[VVHRoadlink]): Seq[RoadLink] = { + LogUtils.time(logger,"TEST LOG roadLinkDataByLinkId"){getRoadLinkDataByLinkIds(allVvhRoadLinks)} } - + /** * Uses old road link ids from change data to fetch their OTH overridden properties from db. * Used by RoadLinkSErvice.fillIncompleteLinksWithPreviousLinkData. @@ -1739,7 +1679,7 @@ class RoadLinkService(val vvhClient: VVHClient, val eventbus: DigiroadEventBus, ) } - private def getCachedRoadLinksAndChanges(municipalityCode: Int): (Seq[RoadLink], Seq[ChangeInfo]) = { + def getCachedRoadLinksAndChanges(municipalityCode: Int): (Seq[RoadLink], Seq[ChangeInfo]) = { val (roadLinks, changes, _) = getCachedRoadLinks(municipalityCode) (roadLinks, changes) } @@ -1756,6 +1696,7 @@ class RoadLinkService(val vvhClient: VVHClient, val eventbus: DigiroadEventBus, reloadRoadLinksWithComplementaryAndChangesFromVVH(municipalityCode) )("links:" + municipalityCode) } + /** * Call reloadRoadNodesFromVVH */ diff --git a/digiroad2-oracle/src/main/scala/fi/liikennevirasto/digiroad2/util/DataFixture.scala b/digiroad2-oracle/src/main/scala/fi/liikennevirasto/digiroad2/util/DataFixture.scala index e9efcd8912..bc0b4606d0 100644 --- a/digiroad2-oracle/src/main/scala/fi/liikennevirasto/digiroad2/util/DataFixture.scala +++ b/digiroad2-oracle/src/main/scala/fi/liikennevirasto/digiroad2/util/DataFixture.scala @@ -2335,6 +2335,10 @@ object DataFixture { MainLanePopulationProcess.initialProcess() case Some("redundant_traffic_direction_removal") => withDynTransaction(redundantTrafficDirectionRemoval.deleteRedundantTrafficDirectionFromDB()) + case Some("update_incomplete_link_list") => + UpdateIncompleteLinkList.runUpdate() + case Some("refresh_road_link_cache") => + RefreshRoadLinkCache.refreshCache() case _ => println("Usage: DataFixture test | import_roadlink_data |" + " split_speedlimitchains | split_linear_asset_chains | dropped_assets_csv | dropped_manoeuvres_csv |" + " unfloat_linear_assets | expire_split_assets_without_mml | generate_values_for_lit_roads | get_addresses_to_masstransitstops_from_vvh |" + @@ -2351,7 +2355,8 @@ object DataFixture { " load_municipalities_verification_info | import_private_road_info | normalize_user_roles | get_state_roads_with_overridden_functional_class | get_state_roads_with_undefined_functional_class |" + " add_obstacles_shapefile | merge_municipalities | transform_lorry_parking_into_datex2 | fill_new_roadLinks_info | update_last_modified_assets_info | import_cycling_walking_info |" + " create_roadWorks_using_traffic_signs | extract_csv_private_road_association_info | restore_expired_assets_from_TR_import | move_old_expired_assets | new_road_address_from_viite | change_lanes_according_to_VVH_changes |" + - " validate_lane_changes_according_to_VVH_changes | populate_new_link_with_main_lanes | initial_main_lane_population | redundant_traffic_direction_removal") + " validate_lane_changes_according_to_VVH_changes | populate_new_link_with_main_lanes | initial_main_lane_population | redundant_traffic_direction_removal | update_incomplete_link_list |" + + " refresh_road_link_cache |") } } } diff --git a/digiroad2-oracle/src/main/scala/fi/liikennevirasto/digiroad2/util/RefreshRoadLinkCache.scala b/digiroad2-oracle/src/main/scala/fi/liikennevirasto/digiroad2/util/RefreshRoadLinkCache.scala new file mode 100644 index 0000000000..56f8cc599a --- /dev/null +++ b/digiroad2-oracle/src/main/scala/fi/liikennevirasto/digiroad2/util/RefreshRoadLinkCache.scala @@ -0,0 +1,42 @@ +package fi.liikennevirasto.digiroad2.util + +import fi.liikennevirasto.digiroad2.client.Caching +import fi.liikennevirasto.digiroad2.client.vvh.VVHClient +import fi.liikennevirasto.digiroad2.dao.Queries +import fi.liikennevirasto.digiroad2.postgis.PostGISDatabase +import fi.liikennevirasto.digiroad2.service.RoadLinkService +import fi.liikennevirasto.digiroad2.{DummyEventBus, DummySerializer} +import org.slf4j.{Logger, LoggerFactory} + + + +object RefreshRoadLinkCache { + val logger: Logger = LoggerFactory.getLogger(getClass) + lazy val vvhClient: VVHClient = { + new VVHClient(Digiroad2Properties.vvhRestApiEndPoint) + } + + lazy val roadLinkService: RoadLinkService = { + new RoadLinkService(vvhClient, new DummyEventBus, new DummySerializer) + } + + def refreshCache(): Unit = { + if (Digiroad2Properties.caching){ + val municipalities: Seq[Int] = PostGISDatabase.withDynSession { + Queries.getMunicipalities + } + val flushSuccess = LogUtils.time(logger, "Flushing cache"){ + Caching.flush() + } + + if (flushSuccess) { + val roadLinks = municipalities.flatMap(municipality => { + roadLinkService.getRoadLinksAndComplementaryLinksFromVVHByMunicipality(municipality) + }) + logger.info("Cached " + roadLinks.size + " roadlinks with overrided properties from database") + } + else logger.error("Flushing cache failed") + } + else logger.error("Caching disabled in properties, can't refresh cache") + } +} diff --git a/digiroad2-oracle/src/main/scala/fi/liikennevirasto/digiroad2/util/UpdateIncompleteLinkList.scala b/digiroad2-oracle/src/main/scala/fi/liikennevirasto/digiroad2/util/UpdateIncompleteLinkList.scala new file mode 100644 index 0000000000..12c7978e72 --- /dev/null +++ b/digiroad2-oracle/src/main/scala/fi/liikennevirasto/digiroad2/util/UpdateIncompleteLinkList.scala @@ -0,0 +1,144 @@ +package fi.liikennevirasto.digiroad2.util + +import fi.liikennevirasto.digiroad2.asset.DateParser.DateTimePropertyFormat +import fi.liikennevirasto.digiroad2.asset._ +import fi.liikennevirasto.digiroad2.client.vvh.{ChangeInfo, FeatureClass, VVHClient, VVHRoadlink} +import fi.liikennevirasto.digiroad2.dao.Queries +import fi.liikennevirasto.digiroad2.linearasset.RoadLink +import fi.liikennevirasto.digiroad2.postgis.PostGISDatabase +import fi.liikennevirasto.digiroad2.service.{AdjustedRoadLinksAndVVHRoadLink, IncompleteLink, RoadLinkChangeSet, RoadLinkService} +import fi.liikennevirasto.digiroad2.{DummyEventBus, DummySerializer} +import org.joda.time.DateTime +import org.slf4j.LoggerFactory +import slick.driver.JdbcDriver.backend.Database.dynamicSession +import slick.jdbc.StaticQuery.interpolation + +object UpdateIncompleteLinkList { + val logger = LoggerFactory.getLogger(getClass) + + lazy val vvhClient: VVHClient = { + new VVHClient(Digiroad2Properties.vvhRestApiEndPoint) + } + + lazy val roadLinkService: RoadLinkService = { + new RoadLinkService(vvhClient, new DummyEventBus, new DummySerializer) + } + + def runUpdate(): Unit = { + logger.info("*** Delete incomplete links") + clearIncompleteLinks() + logger.info("*** Get municipalities") + val municipalities: Seq[Int] = PostGISDatabase.withDynSession { + Queries.getMunicipalities + } + + var counter = 0 + municipalities.foreach { municipality => + val timer1 = System.currentTimeMillis() + logger.info("*** Processing municipality: " + municipality) + val roadLinks = getRoadLinksFromVvhAndUpdateProperties(municipality) + counter += 1 + logger.info("*** Processed " + roadLinks.length + " road links with municipality " + municipality) + logger.info(s" number of succeeding municipalities $counter from all ${municipalities.size}") + logger.info("processing took: %.3f sec".format((System.currentTimeMillis() - timer1) * 0.001)) + } + } + + def getRoadLinksFromVvhAndUpdateProperties(municipality: Int): Seq[RoadLink] = { + val (links, _, complementaryLinks) = LogUtils.time(logger, "Get roadlinks and update properties for municipality " + municipality)( + roadLinkService.getLinksWithComplementaryAndGenerateProperties(municipality)) + + links ++ complementaryLinks + } + + private def clearIncompleteLinks(): Unit = { + PostGISDatabase.withDynTransaction { + sqlu"""truncate table incomplete_link""".execute + } + } + + /** + * This method performs formatting operations to given vvh road links: + * - auto-generation of functional class and link type by feature class + * - information transfer from old link to new link from change data + * + * @param allVvhRoadLinks + * @param changes + * @return Road links + */ + def generateProperties(allVvhRoadLinks: Seq[VVHRoadlink], changes: Seq[ChangeInfo] = Nil): Seq[RoadLink] = { + val vvhRoadLinks = allVvhRoadLinks.filterNot(_.featureClass == FeatureClass.WinterRoads) + + def autoGenerateProperties(roadLink: RoadLink): RoadLink = { + val vvhRoadLink = vvhRoadLinks.find(_.linkId == roadLink.linkId) + vvhRoadLink.get.featureClass match { + case FeatureClass.TractorRoad => roadLink.copy(functionalClass = 7, linkType = TractorRoad, modifiedBy = Some("automatic_generation"), modifiedAt = Some(DateTimePropertyFormat.print(DateTime.now()))) + case FeatureClass.DrivePath | FeatureClass.CarRoad_IIIb => roadLink.copy(functionalClass = 6, linkType = SingleCarriageway, modifiedBy = Some("automatic_generation"), modifiedAt = Some(DateTimePropertyFormat.print(DateTime.now()))) + case FeatureClass.CycleOrPedestrianPath => roadLink.copy(functionalClass = 8, linkType = CycleOrPedestrianPath, modifiedBy = Some("automatic_generation"), modifiedAt = Some(DateTimePropertyFormat.print(DateTime.now()))) + case FeatureClass.SpecialTransportWithoutGate => roadLink.copy(functionalClass = UnknownFunctionalClass.value, linkType = SpecialTransportWithoutGate, modifiedBy = Some("auto_generation"), modifiedAt = Some(DateTimePropertyFormat.print(DateTime.now()))) + case FeatureClass.SpecialTransportWithGate => roadLink.copy(functionalClass = UnknownFunctionalClass.value, linkType = SpecialTransportWithGate, modifiedBy = Some("auto_generation"), modifiedAt = Some(DateTimePropertyFormat.print(DateTime.now()))) + case FeatureClass.CarRoad_IIIa => vvhRoadLink.get.administrativeClass match { + case State => roadLink.copy(functionalClass = 4, linkType = SingleCarriageway, modifiedBy = Some("automatic_generation"), modifiedAt = Some(DateTimePropertyFormat.print(DateTime.now()))) + case Municipality | Private => roadLink.copy(functionalClass = 5, linkType = SingleCarriageway, modifiedBy = Some("automatic_generation"), modifiedAt = Some(DateTimePropertyFormat.print(DateTime.now()))) + case _ => roadLink + } + case _ => roadLink //similar logic used in roadaddressbuilder + } + } + + def toIncompleteLink(roadLink: RoadLink): IncompleteLink = { + val vvhRoadLink = vvhRoadLinks.find(_.linkId == roadLink.linkId) + IncompleteLink(roadLink.linkId, vvhRoadLink.get.municipalityCode, roadLink.administrativeClass) + } + + def canBeAutoGenerated(roadLink: RoadLink): Boolean = { + vvhRoadLinks.find(_.linkId == roadLink.linkId).get.featureClass match { + case FeatureClass.AllOthers => false + case _ => true + } + } + + val roadLinkDataByLinkId: Seq[RoadLink] = LogUtils.time(logger, "TEST LOG roadLinkDataByLinkId") { + roadLinkService.getRoadLinkDataByLinkIds(vvhRoadLinks) + } + val (incompleteLinks, completeLinks) = roadLinkDataByLinkId.partition(roadLinkService.isIncomplete) + val (linksToAutoGenerate, incompleteOtherLinks) = incompleteLinks.partition(canBeAutoGenerated) + val autoGeneratedLinks = linksToAutoGenerate.map(autoGenerateProperties) + val (changedLinks, stillIncompleteLinks) = LogUtils.time(logger, "TEST LOG fillIncompleteLinksWithPreviousLinkData") { + roadLinkService.fillIncompleteLinksWithPreviousLinkData(incompleteOtherLinks, changes) + } + val changedPartiallyIncompleteLinks = stillIncompleteLinks.filter(roadLinkService.isPartiallyIncomplete) + val stillIncompleteLinksInUse = stillIncompleteLinks.filter(_.constructionType == ConstructionType.InUse) + + val adjustedRoadLinks = autoGeneratedLinks ++ changedLinks ++ changedPartiallyIncompleteLinks + val vvhRoadLinksGroupBy = allVvhRoadLinks.groupBy(_.linkId) + val pair = adjustedRoadLinks.map(r => AdjustedRoadLinksAndVVHRoadLink(r, vvhRoadLinksGroupBy(r.linkId).last)) + + val changeSet = RoadLinkChangeSet(pair, stillIncompleteLinksInUse.map(toIncompleteLink), changes, roadLinkDataByLinkId) + LogUtils.time(logger, "TEST LOG UpdateRoadLinkChanges") { + updateRoadLinkChanges(changeSet) + } + + completeLinks ++ autoGeneratedLinks ++ changedLinks ++ stillIncompleteLinks + } + + /** + * Updates road link data in OTH db. + */ + def updateRoadLinkChanges(roadLinkChangeSet: RoadLinkChangeSet): Unit = { + + LogUtils.time(logger, s"updateIncompleteLinks incompleteLinks: ${roadLinkChangeSet.incompleteLinks.size},") { + roadLinkService.updateIncompleteLinks(roadLinkChangeSet.incompleteLinks) + } + + LogUtils.time(logger, s"updateAutoGeneratedProperties adjustedRoadLinks: ${roadLinkChangeSet.adjustedRoadLinks.size},") { + roadLinkService.updateAutoGeneratedProperties(roadLinkChangeSet.adjustedRoadLinks) + } + + LogUtils.time(logger, s"fillRoadLinkAttributes roadLinks: ${roadLinkChangeSet.roadLinks.size}, changes: ${roadLinkChangeSet.changes.size},") { + roadLinkService.fillRoadLinkAttributes(roadLinkChangeSet.roadLinks, roadLinkChangeSet.changes) + } + + } + +} diff --git a/digiroad2-oracle/src/test/scala/fi/liikennevirasto/digiroad2/service/RoadLinkServiceSpec.scala b/digiroad2-oracle/src/test/scala/fi/liikennevirasto/digiroad2/service/RoadLinkServiceSpec.scala index f694febeea..c87246abdc 100644 --- a/digiroad2-oracle/src/test/scala/fi/liikennevirasto/digiroad2/service/RoadLinkServiceSpec.scala +++ b/digiroad2-oracle/src/test/scala/fi/liikennevirasto/digiroad2/service/RoadLinkServiceSpec.scala @@ -3,13 +3,14 @@ package fi.liikennevirasto.digiroad2.service import fi.liikennevirasto.digiroad2.asset.DateParser._ import fi.liikennevirasto.digiroad2.asset.LinkGeomSource.NormalLinkInterface import fi.liikennevirasto.digiroad2.asset.TrafficDirection.{AgainstDigitizing, BothDirections, TowardsDigitizing} -import fi.liikennevirasto.digiroad2.asset.{CycleOrPedestrianPath, _} +import fi.liikennevirasto.digiroad2.asset._ import fi.liikennevirasto.digiroad2.client.vvh.FeatureClass.AllOthers import fi.liikennevirasto.digiroad2.client.vvh._ import fi.liikennevirasto.digiroad2.dao.RoadLinkDAO import fi.liikennevirasto.digiroad2.dao.RoadLinkDAO.LinkAttributesDao import fi.liikennevirasto.digiroad2.linearasset.RoadLink import fi.liikennevirasto.digiroad2.postgis.PostGISDatabase +import fi.liikennevirasto.digiroad2.util.UpdateIncompleteLinkList.generateProperties import fi.liikennevirasto.digiroad2.util.{TestTransactions, VVHSerializer} import fi.liikennevirasto.digiroad2.{DigiroadEventBus, DummyEventBus, DummySerializer, Point} import org.joda.time.DateTime @@ -219,22 +220,17 @@ class RoadLinkServiceSpec extends FunSuite with Matchers with BeforeAndAfter { val mockVVHRoadLinkClient = MockitoSugar.mock[VVHRoadLinkClient] val mockVVHChangeInfoClient = MockitoSugar.mock[VVHChangeInfoClient] - val service = new TestService(mockVVHClient) - when(mockVVHClient.roadLinkData).thenReturn(mockVVHRoadLinkClient) - when(mockVVHClient.roadLinkChangeInfo).thenReturn(mockVVHChangeInfoClient) - when(mockVVHChangeInfoClient.fetchByBoundsAndMunicipalitiesF(boundingBox, Set())).thenReturn(Promise.successful(Nil).future) - when(mockVVHRoadLinkClient.fetchByMunicipalitiesAndBoundsF(boundingBox, Set())) - .thenReturn(Promise.successful(List( - VVHRoadlink(123l, 91, Nil, Municipality, TrafficDirection.TowardsDigitizing, FeatureClass.DrivePath), - VVHRoadlink(456l, 91, Nil, Municipality, TrafficDirection.TowardsDigitizing, FeatureClass.TractorRoad), - VVHRoadlink(789l, 91, Nil, Municipality, TrafficDirection.TowardsDigitizing, FeatureClass.AllOthers), - VVHRoadlink(111l, 91, Nil, Municipality, TrafficDirection.TowardsDigitizing, FeatureClass.CycleOrPedestrianPath), - VVHRoadlink(222l, 91, Nil, Municipality, TrafficDirection.TowardsDigitizing, FeatureClass.SpecialTransportWithoutGate), - VVHRoadlink(333l, 91, Nil, Municipality, TrafficDirection.TowardsDigitizing, FeatureClass.SpecialTransportWithGate))).future) + val vvhRoadLinks = List( + VVHRoadlink(123l, 91, Nil, Municipality, TrafficDirection.TowardsDigitizing, FeatureClass.DrivePath), + VVHRoadlink(456l, 91, Nil, Municipality, TrafficDirection.TowardsDigitizing, FeatureClass.TractorRoad), + VVHRoadlink(789l, 91, Nil, Municipality, TrafficDirection.TowardsDigitizing, FeatureClass.AllOthers), + VVHRoadlink(111l, 91, Nil, Municipality, TrafficDirection.TowardsDigitizing, FeatureClass.CycleOrPedestrianPath), + VVHRoadlink(222l, 91, Nil, Municipality, TrafficDirection.TowardsDigitizing, FeatureClass.SpecialTransportWithoutGate), + VVHRoadlink(333l, 91, Nil, Municipality, TrafficDirection.TowardsDigitizing, FeatureClass.SpecialTransportWithGate)) sqlu"""delete from incomplete_link where municipality_code = 91""".execute sqlu"""insert into incomplete_link(id, link_id, municipality_code) values(3123123123, 456, 91)""".execute - val roadLinks = service.getRoadLinksFromVVH(boundingBox) + val roadLinks = generateProperties(vvhRoadLinks) roadLinks.find(_.linkId == 123).get.functionalClass should be(6) roadLinks.find(_.linkId == 123).get.linkType should be(SingleCarriageway) @@ -258,37 +254,6 @@ class RoadLinkServiceSpec extends FunSuite with Matchers with BeforeAndAfter { } } - test("Changes should cause event") { - PostGISDatabase.withDynTransaction { - val mockEventBus = MockitoSugar.mock[DigiroadEventBus] - val boundingBox = BoundingRectangle(Point(123, 345), Point(567, 678)) - val mockVVHClient = MockitoSugar.mock[VVHClient] - val mockVVHRoadLinkClient = MockitoSugar.mock[VVHRoadLinkClient] - val mockVVHChangeInfoClient = MockitoSugar.mock[VVHChangeInfoClient] - - val vvhRoadLinks = List( - VVHRoadlink(123l, 91, Nil, Municipality, TrafficDirection.TowardsDigitizing, FeatureClass.DrivePath, linkSource = LinkGeomSource.NormalLinkInterface), - VVHRoadlink(789l, 91, Nil, Municipality, TrafficDirection.TowardsDigitizing, FeatureClass.AllOthers, linkSource = LinkGeomSource.NormalLinkInterface)) - when(mockVVHClient.roadLinkData).thenReturn(mockVVHRoadLinkClient) - when(mockVVHClient.roadLinkChangeInfo).thenReturn(mockVVHChangeInfoClient) - when(mockVVHRoadLinkClient.fetchByMunicipalitiesAndBoundsF(boundingBox, Set())).thenReturn(Promise.successful(vvhRoadLinks).future) - when(mockVVHChangeInfoClient.fetchByBoundsAndMunicipalitiesF(boundingBox, Set())).thenReturn(Promise.successful(Nil).future) - - val service = new TestService(mockVVHClient, mockEventBus) - val result = service.getRoadLinksFromVVH(boundingBox) - val exactModifiedAtValue = result.head.modifiedAt - - val roadLink:RoadLink = RoadLink(123, List(), 0.0, Municipality, 6, TrafficDirection.TowardsDigitizing, SingleCarriageway, exactModifiedAtValue, Some("automatic_generation"), constructionType = ConstructionType.InUse, linkSource = LinkGeomSource.NormalLinkInterface) - val adjustedRoadLinks = Seq(AdjustedRoadLinksAndVVHRoadLink(adjustedRoadLink = roadLink, vVHRoadLink = VVHRoadlink(123l, 91, Nil, Municipality, TrafficDirection.TowardsDigitizing, FeatureClass.DrivePath, linkSource = LinkGeomSource.NormalLinkInterface))) - val changeSet: RoadLinkChangeSet = RoadLinkChangeSet(adjustedRoadLinks, List(IncompleteLink(789,91,Municipality)), List(), service.getRoadLinkDataByLinkIds(vvhRoadLinks)) - - verify(mockEventBus).publish( - org.mockito.ArgumentMatchers.eq("linkProperties:changed"), - org.mockito.ArgumentMatchers.eq(changeSet)) - - dynamicSession.rollback() - } - } //this fail at fifth consecutive test suite run test("Remove road link from incomplete link list once functional class and link type are specified") { PostGISDatabase.withDynTransaction { @@ -345,9 +310,7 @@ class RoadLinkServiceSpec extends FunSuite with Matchers with BeforeAndAfter { before.head.linkType should be(Freeway) before.head.trafficDirection should be(TrafficDirection.BothDirections) - when(mockVVHRoadLinkClient.fetchByMunicipalitiesAndBoundsF(boundingBox, Set())).thenReturn(Promise.successful(Seq(newRoadLink)).future) - when(mockVVHChangeInfoClient.fetchByBoundsAndMunicipalitiesF(boundingBox, Set())).thenReturn(Promise.successful(Seq(changeInfo)).future) - val after = service.getRoadLinksFromVVH(boundingBox) + val after = service.enrichRoadLinksFromVVH(Seq(oldRoadLink, newRoadLink)) after.head.functionalClass should be(3) after.head.linkType should be(Freeway) after.head.trafficDirection should be(TrafficDirection.BothDirections) @@ -390,7 +353,7 @@ class RoadLinkServiceSpec extends FunSuite with Matchers with BeforeAndAfter { when(mockVVHRoadLinkClient.fetchByMunicipalitiesAndBoundsF(boundingBox, Set())).thenReturn(Promise.successful(Seq(newRoadLink)).future) when(mockVVHChangeInfoClient.fetchByBoundsAndMunicipalitiesF(boundingBox, Set())).thenReturn(Promise.successful(changeInfo).future) - val after = service.getRoadLinksFromVVH(boundingBox) + val after = generateProperties(Seq(newRoadLink) ++ oldRoadLinks) after.head.functionalClass should be(3) after.head.linkType should be(Freeway) after.head.trafficDirection should be(TrafficDirection.TowardsDigitizing) @@ -435,7 +398,7 @@ class RoadLinkServiceSpec extends FunSuite with Matchers with BeforeAndAfter { when(mockVVHRoadLinkClient.fetchByMunicipalitiesAndBoundsF(boundingBox, Set())).thenReturn(Promise.successful(Seq(newRoadLink)).future) when(mockVVHChangeInfoClient.fetchByBoundsAndMunicipalitiesF(boundingBox, Set())).thenReturn(Promise.successful(changeInfo).future) - val after = service.getRoadLinksFromVVH(boundingBox) + val after = generateProperties(Seq(newRoadLink)) after.head.functionalClass should be(UnknownFunctionalClass.value) after.head.linkType should be(UnknownLinkType) after.head.trafficDirection should be(TrafficDirection.BothDirections) @@ -476,7 +439,7 @@ class RoadLinkServiceSpec extends FunSuite with Matchers with BeforeAndAfter { when(mockVVHRoadLinkClient.fetchByMunicipalitiesAndBoundsF(boundingBox, Set())).thenReturn(Promise.successful(Seq(newRoadLink)).future) when(mockVVHChangeInfoClient.fetchByBoundsAndMunicipalitiesF(boundingBox, Set())).thenReturn(Promise.successful(changeInfo).future) - val after = service.getRoadLinksFromVVH(boundingBox) + val after = generateProperties(Seq(newRoadLink), changeInfo) after.head.functionalClass should be(3) after.head.linkType should be(Freeway) after.head.trafficDirection should be(TrafficDirection.BothDirections) @@ -517,7 +480,7 @@ class RoadLinkServiceSpec extends FunSuite with Matchers with BeforeAndAfter { when(mockVVHRoadLinkClient.fetchByMunicipalitiesAndBoundsF(boundingBox, Set())).thenReturn(Promise.successful(newRoadLinks).future) when(mockVVHChangeInfoClient.fetchByBoundsAndMunicipalitiesF(boundingBox, Set())).thenReturn(Promise.successful(changeInfo).future) - val after = service.getRoadLinksFromVVH(boundingBox) + val after = generateProperties(newRoadLinks, changeInfo) after.length should be(2) after.foreach { link => link.functionalClass should be(3) @@ -560,7 +523,7 @@ class RoadLinkServiceSpec extends FunSuite with Matchers with BeforeAndAfter { when(mockVVHRoadLinkClient.fetchByMunicipalitiesAndBoundsF(boundingBox, Set())).thenReturn(Promise.successful(Seq(newRoadLink)).future) when(mockVVHChangeInfoClient.fetchByBoundsAndMunicipalitiesF(boundingBox, Set())).thenReturn(Promise.successful(Seq(changeInfo)).future) - val after = service.getRoadLinksFromVVH(boundingBox) + val after = generateProperties(Seq(newRoadLink), Seq(changeInfo)) after.head.functionalClass should be(3) after.head.linkType should be(UnknownLinkType) after.head.trafficDirection should be(TrafficDirection.BothDirections) @@ -604,7 +567,7 @@ class RoadLinkServiceSpec extends FunSuite with Matchers with BeforeAndAfter { when(mockVVHRoadLinkClient.fetchByMunicipalitiesAndBoundsF(boundingBox, Set())).thenReturn(Promise.successful(Seq(newRoadLink)).future) when(mockVVHChangeInfoClient.fetchByBoundsAndMunicipalitiesF(boundingBox, Set())).thenReturn(Promise.successful(Seq(changeInfo)).future) - val after = service.getRoadLinksFromVVH(boundingBox) + val after = generateProperties(Seq(newRoadLink), Seq(changeInfo)) after.head.functionalClass should be(6) after.head.linkType should be(Freeway) after.head.trafficDirection should be(TrafficDirection.BothDirections) @@ -643,7 +606,8 @@ class RoadLinkServiceSpec extends FunSuite with Matchers with BeforeAndAfter { } } - test("Only road links with construction type 'in use' should be saved to incomplete_link table (not 'under construction' or 'planned')") { + //Ignored because "linkProperties:changed" event not in use currently + ignore("Only road links with construction type 'in use' should be saved to incomplete_link table (not 'under construction' or 'planned')") { PostGISDatabase.withDynTransaction { val mockVVHClient = MockitoSugar.mock[VVHClient] val mockVVHRoadLinkClient = MockitoSugar.mock[VVHRoadLinkClient] @@ -681,7 +645,8 @@ class RoadLinkServiceSpec extends FunSuite with Matchers with BeforeAndAfter { } } - test("Should not save links to incomplete_link when the road source is not normal") { + //Ignored because "linkProperties:changed" event not in use currently + ignore("Should not save links to incomplete_link when the road source is not normal") { PostGISDatabase.withDynTransaction { val mockVVHClient = MockitoSugar.mock[VVHClient] val mockVVHRoadLinkClient = MockitoSugar.mock[VVHRoadLinkClient] @@ -833,12 +798,9 @@ class RoadLinkServiceSpec extends FunSuite with Matchers with BeforeAndAfter { test("Should not return roadLinks because it has FeatureClass Winter Roads") { PostGISDatabase.withDynTransaction { val mockVVHClient = MockitoSugar.mock[VVHClient] - val mockVVHRoadLinkClient = MockitoSugar.mock[VVHRoadLinkClient] - when(mockVVHClient.roadLinkData).thenReturn(mockVVHRoadLinkClient) - when(mockVVHRoadLinkClient.fetchByLinkIds(Set(1611447l))) - .thenReturn(Seq(VVHRoadlink(1611447, 91, Nil, Municipality, TrafficDirection.UnknownDirection, FeatureClass.WinterRoads))) + val vvhRoadLinks = Seq(VVHRoadlink(1611447, 91, Nil, Municipality, TrafficDirection.UnknownDirection, FeatureClass.WinterRoads)) val service = new RoadLinkTestService(mockVVHClient) - val roadLinks = service.getRoadLinksByLinkIdsFromVVH(Set(1611447l)) + val roadLinks = generateProperties(vvhRoadLinks) roadLinks.length should be (0) dynamicSession.rollback() } @@ -848,14 +810,12 @@ class RoadLinkServiceSpec extends FunSuite with Matchers with BeforeAndAfter { test("Should only return roadLinks that doesn't have FeatureClass Winter Roads") { PostGISDatabase.withDynTransaction { val mockVVHClient = MockitoSugar.mock[VVHClient] - val mockVVHRoadLinkClient = MockitoSugar.mock[VVHRoadLinkClient] - when(mockVVHClient.roadLinkData).thenReturn(mockVVHRoadLinkClient) - when(mockVVHRoadLinkClient.fetchByMunicipality(91)) - .thenReturn(Seq(VVHRoadlink(1611447, 91, Nil, Municipality, TrafficDirection.UnknownDirection, FeatureClass.WinterRoads), - VVHRoadlink(1611448, 91, Nil, Municipality, TrafficDirection.UnknownDirection, FeatureClass.AllOthers), - VVHRoadlink(1611449, 91, Nil, Municipality, TrafficDirection.UnknownDirection, FeatureClass.AllOthers))) + val vvhRoadLinks = Seq( + VVHRoadlink(1611447, 91, Nil, Municipality, TrafficDirection.UnknownDirection, FeatureClass.WinterRoads), + VVHRoadlink(1611448, 91, Nil, Municipality, TrafficDirection.UnknownDirection, FeatureClass.AllOthers), + VVHRoadlink(1611449, 91, Nil, Municipality, TrafficDirection.UnknownDirection, FeatureClass.AllOthers)) val service = new RoadLinkTestService(mockVVHClient) - val roadLinks = service.getRoadLinksFromVVHByMunicipality(91) + val roadLinks = generateProperties(vvhRoadLinks) roadLinks.length should be (2) roadLinks.sortBy(_.linkId) roadLinks.head.linkId should be(1611448) diff --git a/digiroad2-oracle/src/test/scala/fi/liikennevirasto/digiroad2/util/AssetDataImporterSpec.scala b/digiroad2-oracle/src/test/scala/fi/liikennevirasto/digiroad2/util/AssetDataImporterSpec.scala index 97ab3c7a02..5b72cc2242 100644 --- a/digiroad2-oracle/src/test/scala/fi/liikennevirasto/digiroad2/util/AssetDataImporterSpec.scala +++ b/digiroad2-oracle/src/test/scala/fi/liikennevirasto/digiroad2/util/AssetDataImporterSpec.scala @@ -404,21 +404,23 @@ class AssetDataImporterSpec extends FunSuite with Matchers { Property(2222, "esterakennelma", "single_choice", false, Seq(PropertyValue("2", None)))) val mValue = 10 val vvhRoadLinks = Seq(VVHRoadlink(5170455, 853, Seq(Point(15,0), Point(15,20), Point(15,40)),Municipality, TrafficDirection.BothDirections, FeatureClass.TractorRoad, attributes = CommonAttributes)) + val roadLinks = Seq(RoadLink(5170455, Seq(Point(15,0), Point(15,20), Point(15,40)), 40 ,Municipality, 7, TrafficDirection.BothDirections, TractorRoad, None, None, Map("MUNICIPALITYCODE" -> BigInt(853)))) val mockVVHClient = MockitoSugar.mock[VVHClient] val mockVVHRoadLinkClient = MockitoSugar.mock[VVHRoadLinkClient] val mockVVHChangeInfoClient = MockitoSugar.mock[VVHChangeInfoClient] + val mockRoadLinkService = MockitoSugar.mock[RoadLinkService] when(mockVVHClient.roadLinkData).thenReturn(mockVVHRoadLinkClient) when(mockVVHClient.roadLinkChangeInfo).thenReturn(mockVVHChangeInfoClient) when(mockVVHRoadLinkClient.fetchByMunicipalitiesAndBoundsF(any[BoundingRectangle], any[Set[Int]])).thenReturn(Future(vvhRoadLinks)) when(mockVVHChangeInfoClient.fetchByBoundsAndMunicipalitiesF(any[BoundingRectangle], any[Set[Int]])).thenReturn(Future(Seq())) + when(mockRoadLinkService.getRoadLinksFromVVH(BoundingRectangle(Point(10.0,10.0), Point(30.0,30.0)))).thenReturn(roadLinks) val floatingObstacle = Obstacle(1, oldLinkId, obstaclePoint.x, obstaclePoint.y, mValue, true, 0, 0, pointAssetProperties, Some("unit_test"), linkSource = NormalLinkInterface) val beforeCallMethodDatetime = DateTime.now() - val roadLinkService = new RoadLinkService(mockVVHClient, new DummyEventBus, new DummySerializer) - val resultObstacle = assetDataImporter.updateObstacleToRoadLink(floatingObstacle, roadLinkService) + val resultObstacle = assetDataImporter.updateObstacleToRoadLink(floatingObstacle, mockRoadLinkService) resultObstacle.floating should be (false) resultObstacle.linkId should be (linkId) @@ -477,20 +479,27 @@ class AssetDataImporterSpec extends FunSuite with Matchers { VVHRoadlink(5170455, municipality, Seq(Point(15,0), Point(15,20), Point(15,40)),Municipality, TrafficDirection.BothDirections, FeatureClass.TractorRoad, attributes = CommonAttributes), VVHRoadlink(linkId, municipality, Seq(Point(20.333,0), Point(20.333,20), Point(20.333,20)),Municipality, TrafficDirection.BothDirections, FeatureClass.CycleOrPedestrianPath, attributes = CommonAttributes) ) + val roadLinks = Seq(RoadLink(5170455, Seq(Point(15, 0), Point(15, 20), Point(15, 40)), 40, Municipality, 7, + TrafficDirection.BothDirections, TractorRoad, None, None, Map("MUNICIPALITYCODE" -> BigInt(853))), + RoadLink(5170458, Seq(Point(20.333, 0), Point(20.333, 20), Point(20.333, 20)), 20, Municipality, 8, TrafficDirection.BothDirections, + CycleOrPedestrianPath, None, None, Map("MUNICIPALITYCODE" -> BigInt(853)))) + + val mockVVHClient = MockitoSugar.mock[VVHClient] val mockVVHRoadLinkClient = MockitoSugar.mock[VVHRoadLinkClient] val mockVVHChangeInfoClient = MockitoSugar.mock[VVHChangeInfoClient] + val mockRoadLinkService = MockitoSugar.mock[RoadLinkService] when(mockVVHClient.roadLinkData).thenReturn(mockVVHRoadLinkClient) when(mockVVHClient.roadLinkChangeInfo).thenReturn(mockVVHChangeInfoClient) when(mockVVHRoadLinkClient.fetchByMunicipalitiesAndBoundsF(any[BoundingRectangle], any[Set[Int]])).thenReturn(Future(vvhRoadLinks)) when(mockVVHChangeInfoClient.fetchByBoundsAndMunicipalitiesF(any[BoundingRectangle], any[Set[Int]])).thenReturn(Future(Seq())) + when(mockRoadLinkService.getRoadLinksFromVVH(BoundingRectangle(Point(10.0,10.0), Point(30.0,30.0)))).thenReturn(roadLinks) val floatingObstacle = Obstacle(1, oldLinkId, obstaclePoint.x, obstaclePoint.y, mValue, true, 0, 0, pointAssetProperties, Some("unit_test"), linkSource = NormalLinkInterface) val beforeCallMethodDatetime = DateTime.now() - val roadLinkService = new RoadLinkService(mockVVHClient, new DummyEventBus, new DummySerializer) - val resultObstacle = assetDataImporter.updateObstacleToRoadLink(floatingObstacle, roadLinkService) + val resultObstacle = assetDataImporter.updateObstacleToRoadLink(floatingObstacle, mockRoadLinkService) resultObstacle.floating should be (false) resultObstacle.linkId should be (linkId) @@ -547,20 +556,29 @@ class AssetDataImporterSpec extends FunSuite with Matchers { VVHRoadlink(linkId, municipality, Seq(Point(20.02,0), Point(20.02,20), Point(20.02,20)),Municipality, TrafficDirection.BothDirections, FeatureClass.CycleOrPedestrianPath, attributes = CommonAttributes), VVHRoadlink(5170456, municipality, Seq(Point(20.1,0), Point(20.1,20), Point(20.1,20)),Municipality, TrafficDirection.BothDirections, FeatureClass.DrivePath, attributes = CommonAttributes) ) + val roadLinks = Seq( + RoadLink(5170455, Seq(Point(15, 0), Point(15, 20), Point(15, 40)), 40, Municipality, 7, + TrafficDirection.BothDirections, TractorRoad, None, None, Map("MUNICIPALITYCODE" -> BigInt(853))), + RoadLink(5170458, Seq(Point(20.02,0), Point(20.02,20), Point(20.02,20)), 20, Municipality, 8, TrafficDirection.BothDirections, + CycleOrPedestrianPath, None, None, Map("MUNICIPALITYCODE" -> BigInt(853))), + RoadLink(5170456, Seq(Point(20.1,0), Point(20.1,20), Point(20.1,20)), 20, Municipality, 6, TrafficDirection.BothDirections, + SingleCarriageway, None, None, Map("MUNICIPALITYCODE" -> BigInt(853)))) + val mockVVHClient = MockitoSugar.mock[VVHClient] val mockVVHRoadLinkClient = MockitoSugar.mock[VVHRoadLinkClient] val mockVVHChangeInfoClient = MockitoSugar.mock[VVHChangeInfoClient] + val mockRoadLinkService = MockitoSugar.mock[RoadLinkService] when(mockVVHClient.roadLinkData).thenReturn(mockVVHRoadLinkClient) when(mockVVHClient.roadLinkChangeInfo).thenReturn(mockVVHChangeInfoClient) when(mockVVHRoadLinkClient.fetchByMunicipalitiesAndBoundsF(any[BoundingRectangle], any[Set[Int]])).thenReturn(Future(vvhRoadLinks)) when(mockVVHChangeInfoClient.fetchByBoundsAndMunicipalitiesF(any[BoundingRectangle], any[Set[Int]])).thenReturn(Future(Seq())) + when(mockRoadLinkService.getRoadLinksFromVVH(BoundingRectangle(Point(10.0,10.0), Point(30.0,30.0)))).thenReturn(roadLinks) val floatingObstacle = Obstacle(1, oldLinkId, obstaclePoint.x, obstaclePoint.y, mValue, true, 0, 0, pointAssetProperties, Some("unit_test"), linkSource = NormalLinkInterface) val beforeCallMethodDatetime = DateTime.now() - val roadLinkService = new RoadLinkService(mockVVHClient, new DummyEventBus, new DummySerializer) - val resultObstacle = assetDataImporter.updateObstacleToRoadLink(floatingObstacle, roadLinkService) + val resultObstacle = assetDataImporter.updateObstacleToRoadLink(floatingObstacle, mockRoadLinkService) resultObstacle.floating should be (false) resultObstacle.linkId should be (linkId) @@ -586,19 +604,29 @@ class AssetDataImporterSpec extends FunSuite with Matchers { VVHRoadlink(5170458, municipality, Seq(Point(20.02,0), Point(20.02,10), Point(20.02,20)),Municipality, TrafficDirection.BothDirections, FeatureClass.CycleOrPedestrianPath, attributes = CommonAttributes), VVHRoadlink(5170456, municipality, Seq(Point(20.02,20), Point(20.09,20), Point(20.09,30)),Municipality, TrafficDirection.BothDirections, FeatureClass.DrivePath, attributes = CommonAttributes) ) + val roadLinks = Seq( + RoadLink(5170455, Seq(Point(15, 0), Point(15, 20), Point(15, 40)), 40, Municipality, 7, + TrafficDirection.BothDirections, TractorRoad, None, None, Map("MUNICIPALITYCODE" -> BigInt(853))), + RoadLink(5170458, Seq(Point(20.02,0), Point(20.02,20), Point(20.02,20)), 20, Municipality, 8, TrafficDirection.BothDirections, + CycleOrPedestrianPath, None, None, Map("MUNICIPALITYCODE" -> BigInt(853))), + RoadLink(5170456, Seq(Point(20.02,20), Point(20.09,20), Point(20.09,30)), 10, Municipality, 6, TrafficDirection.BothDirections, + SingleCarriageway, None, None, Map("MUNICIPALITYCODE" -> BigInt(853)))) + val mockVVHClient = MockitoSugar.mock[VVHClient] val mockVVHRoadLinkClient = MockitoSugar.mock[VVHRoadLinkClient] val mockVVHChangeInfoClient = MockitoSugar.mock[VVHChangeInfoClient] + val mockRoadLinkService = MockitoSugar.mock[RoadLinkService] when(mockVVHClient.roadLinkData).thenReturn(mockVVHRoadLinkClient) when(mockVVHClient.roadLinkChangeInfo).thenReturn(mockVVHChangeInfoClient) when(mockVVHRoadLinkClient.fetchByMunicipalitiesAndBoundsF(any[BoundingRectangle], any[Set[Int]])).thenReturn(Future(vvhRoadLinks)) when(mockVVHChangeInfoClient.fetchByBoundsAndMunicipalitiesF(any[BoundingRectangle], any[Set[Int]])).thenReturn(Future(Seq())) - val roadLinkService = new RoadLinkService(mockVVHClient, new DummyEventBus, new DummySerializer) + when(mockRoadLinkService.getRoadLinksFromVVH(BoundingRectangle(Point(10.0,10.0),Point(30.0,30.0)))).thenReturn(roadLinks) + val floatingObstacle = Obstacle(1, oldLinkId, obstaclePoint.x, obstaclePoint.y, mValue, true, 0, 0, pointAssetProperties, Some("unit_test"), linkSource = NormalLinkInterface) - val resultObstacle = assetDataImporter.updateObstacleToRoadLink(floatingObstacle, roadLinkService) + val resultObstacle = assetDataImporter.updateObstacleToRoadLink(floatingObstacle, mockRoadLinkService) resultObstacle.floating should be (false) @@ -678,20 +706,27 @@ class AssetDataImporterSpec extends FunSuite with Matchers { VVHRoadlink(5170455, municipality, Seq(Point(15,0), Point(15,20), Point(15,40)),Municipality, TrafficDirection.BothDirections, FeatureClass.TractorRoad, attributes = CommonAttributes), VVHRoadlink(5170458, municipality, Seq(Point(0,15), Point(20,15), Point(40,15)),Municipality, TrafficDirection.BothDirections, FeatureClass.AllOthers, attributes = CommonAttributes) ) + val roadLinks = Seq( + RoadLink(5170455, Seq(Point(15, 0), Point(15, 20), Point(15, 40)), 40, Municipality, 7, + TrafficDirection.BothDirections, TractorRoad, None, None, Map("MUNICIPALITYCODE" -> BigInt(853))), + RoadLink(5170458, Seq(Point(0,15), Point(20,15), Point(40,15)), 20, Municipality, 99, TrafficDirection.BothDirections, + UnknownLinkType, None, None, Map("MUNICIPALITYCODE" -> BigInt(853)))) + val mockVVHClient = MockitoSugar.mock[VVHClient] val mockVVHRoadLinkClient = MockitoSugar.mock[VVHRoadLinkClient] val mockVVHChangeInfoClient = MockitoSugar.mock[VVHChangeInfoClient] + val mockRoadLinkService = MockitoSugar.mock[RoadLinkService] when(mockVVHClient.roadLinkData).thenReturn(mockVVHRoadLinkClient) when(mockVVHClient.roadLinkChangeInfo).thenReturn(mockVVHChangeInfoClient) when(mockVVHRoadLinkClient.fetchByMunicipalitiesAndBoundsF(any[BoundingRectangle], any[Set[Int]])).thenReturn(Future(vvhRoadLinks)) when(mockVVHChangeInfoClient.fetchByBoundsAndMunicipalitiesF(any[BoundingRectangle], any[Set[Int]])).thenReturn(Future(Seq())) + when(mockRoadLinkService.getRoadLinksFromVVH(BoundingRectangle(Point(10.0,10.0),Point(30.0,30.0)))).thenReturn(roadLinks) val floatingObstacle = Obstacle(1, oldLinkId, obstaclePoint.x, obstaclePoint.y, mValue, true, 0, 0, pointAssetProperties, Some("unit_test"), linkSource = NormalLinkInterface) val beforeCallMethodDatetime = DateTime.now() - val roadLinkService = new RoadLinkService(mockVVHClient, new DummyEventBus, new DummySerializer) - val resultObstacle = assetDataImporter.updateObstacleToRoadLink(floatingObstacle, roadLinkService) + val resultObstacle = assetDataImporter.updateObstacleToRoadLink(floatingObstacle, mockRoadLinkService) resultObstacle.floating should be (false) resultObstacle.linkId should be (linkId)