Skip to content

Commit

Permalink
Merge branch 'o19s-introduce_basic_admin_screen' into smui_v3_13_3
Browse files Browse the repository at this point in the history
# Conflicts:
#	e2e/yarn.lock
  • Loading branch information
pbartusch committed Dec 17, 2021
2 parents 7c36b18 + 18dfb82 commit 3c15043
Show file tree
Hide file tree
Showing 30 changed files with 2,226 additions and 1,273 deletions.
22 changes: 22 additions & 0 deletions app/controllers/ApiController.scala
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,19 @@ class ApiController @Inject()(authActionFactory: AuthActionFactory,
}
}

def getSolrIndex(solrIndexId: String) = authActionFactory.getAuthenticatedAction(Action).async {
Future {
Ok(Json.toJson(searchManagementRepository.getSolrIndex(SolrIndexId(solrIndexId))))
}
}

def deleteSolrIndex(solrIndexId: String) = authActionFactory.getAuthenticatedAction(Action).async {
Future {
searchManagementRepository.deleteSolrIndex(solrIndexId)
Ok(Json.toJson(ApiResult(API_RESULT_OK, "Deleting Solr Index successful", None)))
}
}

def downloadAllRulesTxtFiles = authActionFactory.getAuthenticatedAction(Action) { req =>
Ok.chunked(
createStreamResultInBackground(
Expand Down Expand Up @@ -302,6 +315,15 @@ class ApiController @Inject()(authActionFactory: AuthActionFactory,
}
}

// I am requiring the solrIndexId because it is more RESTful, but it turns out we don't need it.
// Maybe validation some day?
def deleteSuggestedSolrField(solrIndexId: String, suggestedFieldId: String) = authActionFactory.getAuthenticatedAction(Action).async { request: Request[AnyContent] =>
Future {
searchManagementRepository.deleteSuggestedSolrField(SuggestedSolrFieldId(suggestedFieldId))
Ok(Json.toJson(ApiResult(API_RESULT_OK, "Deleting Suggested Field successful", None)))
}
}

// TODO consider making method .asynch
def importFromRulesTxt(solrIndexId: String) = authActionFactory.getAuthenticatedAction(Action)(parse.multipartFormData) { request =>
request.body
Expand Down
37 changes: 37 additions & 0 deletions app/models/SearchManagementRepository.scala
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import play.api.Logging
@javax.inject.Singleton
class SearchManagementRepository @Inject()(dbapi: DBApi, toggleService: FeatureToggleService)(implicit ec: DatabaseExecutionContext) extends Logging {


private val db = dbapi.database("default")

/**
Expand All @@ -29,10 +30,41 @@ class SearchManagementRepository @Inject()(dbapi: DBApi, toggleService: FeatureT
SolrIndex.loadNameById(solrIndexId)
}

def getSolrIndex(solrIndexId: SolrIndexId): SolrIndex = db.withConnection { implicit connection =>
SolrIndex.loadById(solrIndexId)
}

def addNewSolrIndex(newSolrIndex: SolrIndex): SolrIndexId = db.withConnection { implicit connection =>
SolrIndex.insert(newSolrIndex)
}

/**
* We check for any InputTags, CanonicalSpellings, and SearchInputs. We don't
* check for the existence of any SuggestedSolrFields.
*/
def deleteSolrIndex(solrIndexId: String): Int = db.withTransaction { implicit connection =>

val solrIndexIdId = SolrIndexId(solrIndexId)
val inputTags = InputTag.loadAll.filter(_.solrIndexId== Option(solrIndexIdId))
if (inputTags.size > 0) {
throw new Exception("Can't delete Solr Index that has " + inputTags.size + "tags existing");
}

val canonicalSpellings = CanonicalSpelling.loadAllForIndex(solrIndexIdId)
if (canonicalSpellings.size > 0) {
throw new Exception("Can't delete Solr Index that has " + canonicalSpellings.size + " canonical spellings existing");
}

val searchInputs = SearchInput.loadAllForIndex(solrIndexIdId)
if (searchInputs.size > 0) {
throw new Exception("Can't delete Solr Index that has " + searchInputs.size + " inputs existing");
}

val id = SolrIndex.delete(solrIndexId)

id
}

def listAllInputTags(): Seq[InputTag] = db.withConnection { implicit connection =>
InputTag.loadAll()
}
Expand Down Expand Up @@ -189,6 +221,11 @@ class SearchManagementRepository @Inject()(dbapi: DBApi, toggleService: FeatureT
def addNewSuggestedSolrField(solrIndexId: SolrIndexId, suggestedSolrFieldName: String): SuggestedSolrField = db.withConnection { implicit connection =>
SuggestedSolrField.insert(solrIndexId, suggestedSolrFieldName)
}
def deleteSuggestedSolrField(suggestedSolrFieldId: SuggestedSolrFieldId): Int = db.withTransaction { implicit connection =>
val id = SuggestedSolrField.delete(suggestedSolrFieldId);

id
}

def addNewDeploymentLogOk(solrIndexId: String, targetPlatform: String): Boolean = db.withConnection { implicit connection =>
SQL("insert into deployment_log(id, solr_index_id, target_platform, last_update, result) values ({id}, {solr_index_id}, {target_platform}, {last_update}, {result})")
Expand Down
13 changes: 12 additions & 1 deletion app/models/SolrIndex.scala
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import java.util.Date
import play.api.libs.json.{Json, OFormat}
import anorm.SqlParser._
import anorm._
import play.api.Logging

class SolrIndexId(id: String) extends Id(id)
object SolrIndexId extends IdObject[SolrIndexId](new SolrIndexId(_))
Expand Down Expand Up @@ -45,10 +46,20 @@ object SolrIndex {
allMatchingIndeces.head.name
}

def loadById(solrIndexId: SolrIndexId)(implicit connection: Connection): SolrIndex = {
val allMatchingIndeces = SQL"select * from #$TABLE_NAME where id = $solrIndexId".as(sqlParser.*)

allMatchingIndeces.head
}

def insert(newSolrIndex: SolrIndex)(implicit connection: Connection): SolrIndexId = {
SQL"insert into #$TABLE_NAME (id, name, description, last_update) values (${newSolrIndex.id}, ${newSolrIndex.name}, ${newSolrIndex.description}, ${new Date()})".execute()
newSolrIndex.id
}

def delete(id: String)(implicit connection: Connection): Int = {
SQL"delete from #$TABLE_NAME where id = $id".executeUpdate()
}


}
}
4 changes: 4 additions & 0 deletions app/models/SuggestedSolrField.scala
Original file line number Diff line number Diff line change
Expand Up @@ -50,5 +50,9 @@ object SuggestedSolrField {
field
}

def delete(id: SuggestedSolrFieldId)(implicit connection: Connection): Int = {
SQL"delete from #$TABLE_NAME where #$ID = $id".executeUpdate()
}


}
14 changes: 14 additions & 0 deletions conf/evolutions/default/8.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# --- !Ups

-- Ensure that we do not allow duplicate solr indexes with same name.
create unique index solr_index_field_name on solr_index (name);

-- Ensure that we do not allow duplicate suggested solr fields for the same solr index.
create unique index suggested_solr_field_name_solr_index on suggested_solr_field (solr_index_id, name);



# --- !Downs

drop index solr_index_field_name
drop index suggested_solr_field_name_solr_index;
3 changes: 3 additions & 0 deletions conf/routes
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,9 @@ GET /health controllers.HealthController.health
# TODO search-input URL path partially "behind" solrIndexId path component and partially not
GET /api/v1/featureToggles controllers.ApiController.getFeatureToggles
GET /api/v1/solr-index controllers.ApiController.listAllSolrIndeces
GET /api/v1/solr-index/:solrIndexId controllers.ApiController.getSolrIndex(solrIndexId: String)
PUT /api/v1/solr-index controllers.ApiController.addNewSolrIndex
DELETE /api/v1/solr-index/:solrIndexId controllers.ApiController.deleteSolrIndex(solrIndexId: String)
GET /api/v1/inputTags controllers.ApiController.listAllInputTags
GET /api/v1/:solrIndexId/search-input controllers.ApiController.listAllSearchInputs(solrIndexId: String)
GET /api/v1/search-input/:searchInputId controllers.ApiController.getDetailedSearchInput(searchInputId: String)
Expand All @@ -20,6 +22,7 @@ DELETE /api/v1/search-input/:searchInputId controllers.ApiC
POST /api/v1/:solrIndexId/rules-txt/:targetPlatform controllers.ApiController.updateRulesTxtForSolrIndexAndTargetPlatform(solrIndexId: String, targetPlatform: String)
GET /api/v1/:solrIndexId/suggested-solr-field controllers.ApiController.listAllSuggestedSolrFields(solrIndexId: String)
PUT /api/v1/:solrIndexId/suggested-solr-field controllers.ApiController.addNewSuggestedSolrField(solrIndexId: String)
DELETE /api/v1/:solrIndexId/suggested-solr-field/:suggestedFieldId controllers.ApiController.deleteSuggestedSolrField(solrIndexId: String, suggestedFieldId: String)
GET /api/v1/allRulesTxtFiles controllers.ApiController.downloadAllRulesTxtFiles
POST /api/v1/:solrIndexId/import-from-rules-txt controllers.ApiController.importFromRulesTxt(solrIndexId: String)
GET /api/v1/log/deployment-info controllers.ApiController.getLatestDeploymentResult(solrIndexId: String, targetSystem: String)
Expand Down
27 changes: 27 additions & 0 deletions e2e/cypress/integration/admin.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
//import { truncateTable } from '../src/sql';

context('SMUI app', () => {
beforeEach(() => {
//truncateTable('search_input');
cy.visit('/');
});

it('should be able to create a new Rules Collection', () => {
cy.contains('Admin').click();

var listingCount = 0;
cy.get('app-smui-admin-rules-collection-list .list-group-item').should(collections => {
listingCount = collections.length;
});

cy.get('#collectionName').type('testRulesCollection');
cy.get('#collectionSearchEngineName').type('test_search_engine');
cy.get('#createRulesCollectionBtn').click();

cy.wait(2000)

cy.get('app-smui-admin-rules-collection-list .list-group-item').should(collections => {
expect(collections).to.have.length(listingCount + 1);
});
});
});
Loading

0 comments on commit 3c15043

Please sign in to comment.