Skip to content

Commit

Permalink
Fix purge implementation (#101)
Browse files Browse the repository at this point in the history
Without the literal flag the mapToMongo function was
encoding the "$le" into a unicode string. That caused
the query against the mongo database to always return
an empty set, breaking the purge policy cleanup and
never removing any records.
  • Loading branch information
wstrucke authored and brharrington committed Nov 8, 2016
1 parent 030da30 commit 3df56ff
Show file tree
Hide file tree
Showing 3 changed files with 21 additions and 6 deletions.
14 changes: 14 additions & 0 deletions src/main/resources/edda.properties
Expand Up @@ -122,6 +122,20 @@ edda.collection.jitter.enabled=false
#
# edda.collection.$account.$collection.enabled=false

#
# Edda can automatically truncate old records from your backend data store
#
# Like other collections this setting can be specific to a collection,
# account, or both.
#
# There are three supported purge policies for record retention:
# NONE => Keep Forever (Default)
# LIVE => Only keep current records (mimics the AWS API)
# AGE;expiry=N => Remove records after expiry in milliseconds (N)
#
# edda.collection.purgeFrequency=86400000 # 24 hours in ms
# edda.collection.purgePolicy=AGE;expiry=2678400000 # 31 days in ms

#######################################################################
#
# Crawler Options
Expand Down
2 changes: 1 addition & 1 deletion src/main/scala/com/netflix/edda/Collection.scala
Expand Up @@ -529,7 +529,7 @@ abstract class Collection(val ctx: Collection.Context) extends Queryable {
case PurgePolicy.AGE => {
val options = purgePolicyOptions.asInstanceOf[Map[String,String]]
if( options.contains("expiry") ) {
val expiry = options("expiry").toLong;
val expiry = options("expiry").toLong
dataStore.get.remove(Map("ltime" -> Map("$lt" -> new DateTime( DateTime.now.getMillis - expiry ))))
}
else {
Expand Down
11 changes: 6 additions & 5 deletions src/main/scala/com/netflix/edda/mongo/MongoDatastore.scala
Expand Up @@ -105,17 +105,17 @@ object MongoDatastore {
def mapToMongo(map: Map[String, Any], literal: Boolean = false): DBObject = {
val obj = new BasicDBObject
if (literal) {
map.foreach(pair => obj.put(pair._1, scalaToMongo(pair._2)))
map.foreach(pair => obj.put(pair._1, scalaToMongo(pair._2, literal)))
} else {
map.foreach(pair => obj.put(mongoEncodeString(pair._1), scalaToMongo(pair._2)))
map.foreach(pair => obj.put(mongoEncodeString(pair._1), scalaToMongo(pair._2, literal)))
}
obj
}

/** converts a Scala basic type to a corresponding Mongo data type */
def scalaToMongo(obj: Any): AnyRef = {
def scalaToMongo(obj: Any, literal: Boolean = false): AnyRef = {
obj match {
case o: Map[_, _] => mapToMongo(o.asInstanceOf[Map[String, Any]])
case o: Map[_, _] => mapToMongo(o.asInstanceOf[Map[String, Any]], literal)
case o: Seq[_] => {
val mongo = new BasicDBList
o.foreach(item => mongo.add(scalaToMongo(item)))
Expand Down Expand Up @@ -365,7 +365,8 @@ class MongoDatastore(val name: String) extends Datastore {

override def remove(queryMap: Map[String, Any])(implicit req: RequestId) {
try {
primary.remove(mapToMongo(queryMap))
var opResult = primary.remove(mapToMongo(queryMap, true))
logger.info("{}{} removed {} records", Array(req, this, opResult.getN()))
} catch {
case e: Exception => {
if (logger.isErrorEnabled) logger.error(s"$req$this failed to remove records: $queryMap")
Expand Down

0 comments on commit 3df56ff

Please sign in to comment.