Skip to content

Commit

Permalink
feat(triplestore): Update Lucene index on startup (#1362)
Browse files Browse the repository at this point in the history
* feat: Update Lucene index on startup.

* feat(triplestore): Update Lucene index when an rdfs:label changes.
  • Loading branch information
Benjamin Geer authored Jul 2, 2019
1 parent 683a35b commit 3812196
Show file tree
Hide file tree
Showing 5 changed files with 71 additions and 21 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import akka.actor.{Actor, ActorLogging, ActorSelection, Timers}
import org.knora.webapi._
import org.knora.webapi.messages.app.appmessages.AppState.AppState
import org.knora.webapi.messages.app.appmessages._
import org.knora.webapi.messages.store.triplestoremessages.{CheckRepositoryRequest, CheckRepositoryResponse, RepositoryStatus}
import org.knora.webapi.messages.store.triplestoremessages.{CheckRepositoryRequest, CheckRepositoryResponse, RepositoryStatus, SearchIndexUpdateRequest, SparqlUpdateResponse}
import org.knora.webapi.messages.v2.responder.SuccessResponseV2
import org.knora.webapi.messages.v2.responder.ontologymessages.LoadOntologiesRequestV2
import org.knora.webapi.responders.RESPONDER_MANAGER_ACTOR_PATH
Expand Down Expand Up @@ -65,15 +65,17 @@ class ApplicationStateActor extends Actor with Timers with ActorLogging {
case AppState.Stopped => // do nothing
case AppState.StartingUp => self ! SetAppState(AppState.WaitingForRepository)
case AppState.WaitingForRepository => self ! CheckRepository() // check DB
case AppState.RepositoryReady => self ! SetAppState(AppState.CreatingCaches)
case AppState.RepositoryReady => self ! SetAppState(AppState.CreatingCaches)
case AppState.CreatingCaches => self ! CreateCaches()
case AppState.CachesReady => self ! SetAppState(AppState.LoadingOntologies)
case AppState.LoadingOntologies if skipOntologies => self ! SetAppState(AppState.OntologiesReady) // skipping loading of ontologies
case AppState.CachesReady => self ! SetAppState(AppState.UpdatingSearchIndex)
case AppState.UpdatingSearchIndex => self ! UpdateSearchIndex()
case AppState.SearchIndexReady => self ! SetAppState(AppState.LoadingOntologies)
case AppState.LoadingOntologies if skipOntologies => self ! SetAppState(AppState.OntologiesReady) // skipping loading of ontologies
case AppState.LoadingOntologies if !skipOntologies => self ! LoadOntologies() // load ontologies
case AppState.OntologiesReady => self ! SetAppState(AppState.Running)
case AppState.Running => printWelcomeMsg()
case AppState.MaintenanceMode => // do nothing
case value => throw UnsupportedValueException(s"The value: $value is not supported.")
case other => throw UnsupportedValueException(s"The value: $other is not supported.")
}
}
case GetAppState() => {
Expand Down Expand Up @@ -130,15 +132,25 @@ class ApplicationStateActor extends Actor with Timers with ActorLogging {
self ! SetAppState(AppState.CachesReady)
}

case UpdateSearchIndex() => {
storeManager ! SearchIndexUpdateRequest()
}

case SparqlUpdateResponse() => {
self ! SetAppState(AppState.SearchIndexReady)
}

/* load ontologies request */
case LoadOntologies() => {
responderManager ! LoadOntologiesRequestV2(KnoraSystemInstances.Users.SystemUser)
responderManager ! LoadOntologiesRequestV2(KnoraSystemInstances.Users.SystemUser)
}

/* load ontologies response */
case SuccessResponseV2(msg) => {
case SuccessResponseV2(_) => {
self ! SetAppState(AppState.OntologiesReady)
}

case other => throw UnexpectedMessageException(s"ApplicationStateActor received an unexpected message $other of type ${other.getClass.getCanonicalName}")
}

override def postStop(): Unit = {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,11 @@ case class CheckRepository() extends ApplicationStateRequest
*/
case class CreateCaches() extends ApplicationStateRequest

/**
* Message for updating the triplestore's full-text search index. Used only inside the actor itself.
*/
case class UpdateSearchIndex() extends ApplicationStateRequest

/**
* Message for initiating loading of ontologies. Used only inside the actor itself.
*/
Expand All @@ -116,6 +121,7 @@ case class LoadOntologies() extends ApplicationStateRequest
*/
object AppState extends Enumeration {
type AppState = Value
val Stopped, StartingUp, WaitingForRepository, RepositoryReady, CreatingCaches, CachesReady, LoadingOntologies, OntologiesReady, MaintenanceMode, Running = Value
val Stopped, StartingUp, WaitingForRepository, RepositoryReady, CreatingCaches, CachesReady,
UpdatingSearchIndex, SearchIndexReady, LoadingOntologies, OntologiesReady, MaintenanceMode, Running = Value
}

Original file line number Diff line number Diff line change
Expand Up @@ -227,6 +227,14 @@ case class CheckRepositoryRequest() extends TriplestoreRequest
*/
case class CheckRepositoryResponse(repositoryStatus: RepositoryStatus, msg: String)

/**
* Updates the triplestore's full-text search index.
*
* @param subjectIri if a subject has changed, update the index for that subject. Otherwise, updates
* the index to add any subjects not yet indexed.
*/
case class SearchIndexUpdateRequest(subjectIri: Option[String] = None) extends TriplestoreRequest


//////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Components of messages
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -341,6 +341,16 @@ class ResourcesResponderV2(responderData: ResponderData) extends ResponderWithSt

case None => ()
}

// If the resource's label was changed, update the full-text search index.
_ <- updateResourceMetadataRequestV2.maybeLabel match {
case Some(_) =>
for {
_ <- (storeManager ? SearchIndexUpdateRequest(Some(updateResourceMetadataRequestV2.resourceIri))).mapTo[SparqlUpdateResponse]
} yield ()

case None => FastFuture.successful(())
}
} yield SuccessResponseV2("Resource metadata updated")
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,7 @@ class HttpTriplestoreConnector extends Actor with ActorLogging {
case InsertTriplestoreContent(rdfDataObjects) => try2Message(sender(), insertDataIntoTriplestore(rdfDataObjects), log)
case HelloTriplestore(msg) if msg == triplestoreType => sender ! HelloTriplestore(triplestoreType)
case CheckRepositoryRequest() => try2Message(sender(), checkRepository(), log)
case SearchIndexUpdateRequest(subjectIri) => try2Message(sender(), updateLuceneIndex(subjectIri), log)
case other => sender ! Status.Failure(UnexpectedMessageException(s"Unexpected message $other of type ${other.getClass.getCanonicalName}"))
}

Expand Down Expand Up @@ -346,6 +347,29 @@ class HttpTriplestoreConnector extends Actor with ActorLogging {
} yield response
}

/**
* Updates the Lucene full-text search index.
*/
private def updateLuceneIndex(subjectIri: Option[IRI] = None): Try[SparqlUpdateResponse] = {
val indexUpdateSparqlString = subjectIri match {
case Some(definedSubjectIri) =>
// A subject's content has changed. Update the index for that subject.
s"""PREFIX luc: <http://www.ontotext.com/owlim/lucene#>
|INSERT DATA { luc:fullTextSearchIndex luc:addToIndex <$definedSubjectIri> . }
""".stripMargin

case None =>
// Add new subjects to the index.
"""PREFIX luc: <http://www.ontotext.com/owlim/lucene#>
|INSERT DATA { luc:fullTextSearchIndex luc:updateIndex _:b1 . }
""".stripMargin
}

for {
_ <- getTriplestoreHttpResponse(indexUpdateSparqlString, isUpdate = true)
} yield SparqlUpdateResponse()
}

/**
* Performs a SPARQL update operation.
*
Expand All @@ -361,12 +385,7 @@ class HttpTriplestoreConnector extends Actor with ActorLogging {

// If we're using GraphDB, update the full-text search index.
_ = if (triplestoreType == TriplestoreTypes.HttpGraphDBSE | triplestoreType == TriplestoreTypes.HttpGraphDBFree) {
val indexUpdateSparqlString =
"""
PREFIX luc: <http://www.ontotext.com/owlim/lucene#>
INSERT DATA { luc:fullTextSearchIndex luc:updateIndex _:b1 . }
"""
getTriplestoreHttpResponse(indexUpdateSparqlString, isUpdate = true)
updateLuceneIndex()
}
} yield SparqlUpdateResponse()
}
Expand Down Expand Up @@ -458,12 +477,7 @@ class HttpTriplestoreConnector extends Actor with ActorLogging {

if (triplestoreType == TriplestoreTypes.HttpGraphDBSE || triplestoreType == TriplestoreTypes.HttpGraphDBFree) {
/* need to update the lucene index */
val indexUpdateSparqlString =
"""
PREFIX luc: <http://www.ontotext.com/owlim/lucene#>
INSERT DATA { luc:fullTextSearchIndex luc:updateIndex _:b1 . }
"""
getTriplestoreHttpResponse(indexUpdateSparqlString, isUpdate = true)
updateLuceneIndex()
}

log.debug("==>> Loading Data End")
Expand Down Expand Up @@ -610,7 +624,7 @@ class HttpTriplestoreConnector extends Actor with ActorLogging {
}

val took = System.currentTimeMillis() - start
log.info(s"[${statusCode}] GraphDB Query took: ${took}ms")
log.info(s"[$statusCode] GraphDB Query took: ${took}ms")

responseEntityStr
} finally {
Expand Down

0 comments on commit 3812196

Please sign in to comment.