in path-manager/app/services/PathStore.scala [132:181]
def updateCanonicalWithAlias(newPath: String, id: Long): Either[String, Map[String, List[PathRecord]]] = {
//This takes the canonical path and makes it an alias. And then adds a new canonical path for newPath.
logger.debug(s"Updating $CANONICAL_PATH_TYPE path [$newPath] for [$id] and creating $ALIAS_PATH_TYPE to old path.")
if (PathValidator.isInvalid(newPath)) {
Left(s"invalid path [$newPath]")
} else {
val newPathRecord = Option(Dynamo.pathsTable.getItem("path", newPath)).map(PathRecord(_))
val pathsForId = Dynamo.pathsTable.getIndex("id-index").query(new KeyAttribute("identifier", id)).asScala.map{ PathRecord(_) }
val canonicalPathForId = pathsForId.find(_.`type`==CANONICAL_PATH_TYPE)
if(newPathRecord.exists(_.identifier != id)) {
logger.warn(s"Failed to update path [$newPath], already claimed by id [${newPathRecord.map{_.identifier}.get}], submitting id [$id]")
Left("path already in use")
} else {
canonicalPathForId.map { existingRecord: PathRecord =>
val existingPath = existingRecord.path
val existingAliases = pathsForId.filter(_.`type` == ALIAS_PATH_TYPE)
val updatedRecords = if (existingPath != newPath) {
val newCanonicalRecord = existingRecord.copy(path = newPath, ceasedToBeCanonicalAt = None)
logger.debug(s"Aliasing old path for item [$id]. old path[$existingPath] new path [$newPath]")
val resultingAliasRecord = PathRecord(
Dynamo.pathsTable.updateItem(new UpdateItemSpec()
.withPrimaryKey("path", existingPath)
.withAttributeUpdate(
new AttributeUpdate("type").put(ALIAS_PATH_TYPE),
new AttributeUpdate("ceasedToBeCanonicalAt").put(System.currentTimeMillis) // so we can keep the aliases order
)
.withReturnValues(ReturnValue.ALL_NEW) // this means we can call getItem below
).getItem
)
putPathItemAndAwaitIndexUpdate(newCanonicalRecord) //TODO this and the update above should be a transaction (in case the latter fails)
List(newCanonicalRecord, resultingAliasRecord)
} else {
List(existingRecord)
}
logger.debug(s"updated $CANONICAL_PATH_TYPE path [$newPath] and added $ALIAS_PATH_TYPE to [$existingPath] id [$id] successfully")
(updatedRecords ++ existingAliases).groupBy(_.`type`)
}.toRight{
logger.warn(s"Failed to update path [$newPath], no existing path found for id [$id]")
s"unable to find $CANONICAL_PATH_TYPE record for $id"
}
}
}
}