package eu.europeana.cloud.service.uis.persistent.dao; import java.util.ArrayList; import java.util.List; import com.datastax.driver.core.PreparedStatement; import com.datastax.driver.core.ResultSet; import com.datastax.driver.core.Row; import com.datastax.driver.core.exceptions.NoHostAvailableException; import eu.europeana.cloud.cassandra.CassandraConnectionProvider; import eu.europeana.cloud.common.model.CloudId; import eu.europeana.cloud.common.model.IdentifierErrorInfo; import eu.europeana.cloud.common.model.LocalId; import eu.europeana.cloud.service.uis.exception.CloudIdAlreadyExistException; import eu.europeana.cloud.service.uis.exception.CloudIdDoesNotExistException; import eu.europeana.cloud.service.uis.exception.DatabaseConnectionException; import eu.europeana.cloud.service.uis.status.IdentifierErrorTemplate; /** * Dao providing access to database operations on Cloud id database * * @author Yorgos.Mamakis@ kb.nl * */ public class CassandraCloudIdDAO { private String hostList; private String keyspaceName; private String port; private CassandraConnectionProvider dbService; private PreparedStatement insertStatement; private PreparedStatement insertIfNoExistsStatement; private PreparedStatement searchStatementNonActive; private PreparedStatement deleteStatement; /** * The Cloud Id Dao * * @param dbService * The service exposing the connection and session */ public CassandraCloudIdDAO(CassandraConnectionProvider dbService) { this.dbService = dbService; this.hostList = dbService.getHosts(); this.port = dbService.getPort(); this.keyspaceName = dbService.getKeyspaceName(); prepareStatements(); } private void prepareStatements() { insertIfNoExistsStatement = dbService .getSession() .prepare( "INSERT INTO Cloud_Id(cloud_id,provider_id,record_id,deleted) VALUES(?,?,?,false) IF NOT EXISTS"); insertStatement = dbService .getSession() .prepare( "INSERT INTO Cloud_Id(cloud_id,provider_id,record_id,deleted) VALUES(?,?,?,false)"); insertStatement.setConsistencyLevel(dbService.getConsistencyLevel()); searchStatementNonActive = dbService.getSession().prepare( "SELECT * FROM Cloud_Id WHERE cloud_id=?"); searchStatementNonActive.setConsistencyLevel(dbService .getConsistencyLevel()); deleteStatement = dbService .getSession() .prepare( "UPDATE Cloud_Id SET deleted=true WHERE cloud_Id=? AND provider_id=? AND record_id=?"); deleteStatement.setConsistencyLevel(dbService.getConsistencyLevel()); } public List<CloudId> searchById(boolean deleted, String... args) throws DatabaseConnectionException, CloudIdDoesNotExistException { try { ResultSet rs = dbService.getSession().execute(searchStatementNonActive.bind(args[0])); if (!rs.iterator().hasNext()) { throw new CloudIdDoesNotExistException(new IdentifierErrorInfo( IdentifierErrorTemplate.CLOUDID_DOES_NOT_EXIST.getHttpCode(), IdentifierErrorTemplate.CLOUDID_DOES_NOT_EXIST.getErrorInfo(args[0]))); } List<CloudId> cloudIds = new ArrayList<>(); for (Row row : rs.all()) { if (row.getBool("deleted") == deleted) { CloudId cId = new CloudId(); cId.setId(args[0]); LocalId lId = new LocalId(); lId.setProviderId(row.getString("provider_Id")); lId.setRecordId(row.getString("record_Id")); cId.setLocalId(lId); cloudIds.add(cId); } } return cloudIds; } catch (NoHostAvailableException e) { throw new DatabaseConnectionException(new IdentifierErrorInfo( IdentifierErrorTemplate.DATABASE_CONNECTION_ERROR.getHttpCode(), IdentifierErrorTemplate.DATABASE_CONNECTION_ERROR.getErrorInfo(hostList, port, e.getMessage()))); } } public List<CloudId> searchActive(String... args) throws DatabaseConnectionException, CloudIdDoesNotExistException { return searchById(false, args[0]); } /** * Search for all the Cloud Identifiers regardless if they are deleted or * not * * @param args * The cloudId to search on * @return A list of cloudIds * @throws DatabaseConnectionException */ public List<CloudId> searchAll(String args) throws DatabaseConnectionException { ResultSet rs = dbService.getSession().execute(searchStatementNonActive.bind(args)); List<Row> results = rs.all(); List<CloudId> cloudIds = new ArrayList<>(); for (Row row : results) { CloudId cId = new CloudId(); cId.setId(args); LocalId lId = new LocalId(); lId.setProviderId(row.getString("provider_Id")); lId.setRecordId(row.getString("record_Id")); cId.setLocalId(lId); cloudIds.add(cId); } return cloudIds; } public List<CloudId> insert(boolean insertOnlyIfNoExist, String... args) throws DatabaseConnectionException, CloudIdDoesNotExistException, CloudIdAlreadyExistException { ResultSet rs = null; try { if (insertOnlyIfNoExist) { rs = dbService.getSession().execute(insertIfNoExistsStatement.bind(args[0], args[1], args[2])); Row row = rs.one(); if (row.getBool("[applied]") == false) { throw new CloudIdAlreadyExistException(new IdentifierErrorInfo( IdentifierErrorTemplate.CLOUDID_ALREADY_EXIST.getHttpCode(), IdentifierErrorTemplate.CLOUDID_ALREADY_EXIST.getErrorInfo(args[0]))); } } else { dbService.getSession().execute(insertStatement.bind(args[0], args[1], args[2])); } } catch (NoHostAvailableException e) { throw new DatabaseConnectionException(new IdentifierErrorInfo( IdentifierErrorTemplate.DATABASE_CONNECTION_ERROR.getHttpCode(), IdentifierErrorTemplate.DATABASE_CONNECTION_ERROR.getErrorInfo(hostList, port, e.getMessage()))); } CloudId cId = new CloudId(); LocalId lId = new LocalId(); lId.setProviderId(args[1]); lId.setRecordId(args[2]); cId.setLocalId(lId); cId.setId(args[0]); List<CloudId> cIds = new ArrayList<>(); cIds.add(cId); return cIds; } public void delete(String... args) throws DatabaseConnectionException { try { dbService.getSession().execute( deleteStatement.bind(args[0], args[1], args[2])); } catch (NoHostAvailableException e) { throw new DatabaseConnectionException( new IdentifierErrorInfo( IdentifierErrorTemplate.DATABASE_CONNECTION_ERROR .getHttpCode(), IdentifierErrorTemplate.DATABASE_CONNECTION_ERROR .getErrorInfo(hostList, port, e.getMessage()))); } } public void update(String... obj) throws DatabaseConnectionException { throw new UnsupportedOperationException( "This method is not implemented for the Cloud Id"); } public String getHostList() { return hostList; } public String getKeyspace() { return keyspaceName; } public String getPort() { return this.port; } }