Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(triplestore): Update Lucene index on startup #1362

Merged
merged 4 commits into from
Jul 2, 2019
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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