diff options
Diffstat (limited to 'src/main/java/org/openslx/imagemaster/db/mappers')
3 files changed, 217 insertions, 17 deletions
diff --git a/src/main/java/org/openslx/imagemaster/db/mappers/DbImage.java b/src/main/java/org/openslx/imagemaster/db/mappers/DbImage.java index 2f5394c..f4c3ddc 100644 --- a/src/main/java/org/openslx/imagemaster/db/mappers/DbImage.java +++ b/src/main/java/org/openslx/imagemaster/db/mappers/DbImage.java @@ -1,7 +1,17 @@ package org.openslx.imagemaster.db.mappers; -import org.openslx.bwlp.thrift.iface.ImagePublishData; +import java.sql.ResultSet; +import java.sql.SQLException; +import org.apache.log4j.Logger; +import org.openslx.bwlp.thrift.iface.ImagePublishData; +import org.openslx.bwlp.thrift.iface.InvocationError; +import org.openslx.bwlp.thrift.iface.TInvocationException; +import org.openslx.imagemaster.Globals; +import org.openslx.imagemaster.db.Database; +import org.openslx.imagemaster.db.MysqlConnection; +import org.openslx.imagemaster.db.MysqlStatement; +import org.openslx.util.Util; /** * Representing an image in the database. @@ -10,10 +20,83 @@ import org.openslx.bwlp.thrift.iface.ImagePublishData; public class DbImage { + private static final Logger LOGGER = Logger.getLogger( DbImage.class ); + public static ImagePublishData getImageVersion( String imageVersionId ) { - // TODO Auto-generated method stub return null; } + public static void createImageBase( ImagePublishData img ) throws TInvocationException + { + // Input seems valid + try ( MysqlConnection connection = Database.getConnection() ) { + MysqlStatement stmt = connection.prepareStatement( "SELECT virtid FROM imagebase WHERE imagebaseid = :baseid" ); + stmt.setString( "baseid", img.imageBaseId ); + ResultSet rs = stmt.executeQuery(); + if ( rs.next() ) { + if ( !img.virtId.equals( rs.getString( "virtid" ) ) ) { + throw new TInvocationException( InvocationError.INVALID_DATA, "Virtualizer id mismatch" ); + } + MysqlStatement stmt2 = connection.prepareStatement( "UPDATE imagebase SET" + + " displayname = :displayname, updaterid = :updaterid," + + " description = :description, osid = :osid, updatetime = UNIX_TIMESTAMP()," + + " istemplate = :istemplate WHERE imagebaseid = :baseid" ); + stmt2.setString( "baseid", img.imageBaseId ); + stmt2.setString( "displayname", img.imageName ); + stmt2.setString( "updaterid", img.user.userId ); + stmt2.setString( "description", img.description ); + stmt2.setInt( "osid", img.osId ); + stmt2.setBoolean( "istemplate", img.isTemplate ); + stmt2.executeUpdate(); + } else { + MysqlStatement stmt2 = connection.prepareStatement( "INSERT INTO imagebase" + + " (imagebaseid, latestversionid, displayname, description, osid," + + " virtid, createtime, updatetime, ownerid, updaterid, istemplate)" + + " VALUES " + + " (:imagebaseid, NULL, :displayname, :description, :osid," + + " :virtid, :createtime, UNIX_TIMESTAMP(), :ownerid, :updaterid, :istemplate)" ); + stmt2.setString( "imagebaseid", img.imageBaseId ); + stmt2.setString( "displayname", img.imageName ); + stmt2.setString( "description", img.description ); + stmt2.setInt( "osid", img.osId ); + stmt2.setString( "virtid", img.virtId ); + stmt2.setLong( "createtime", img.createTime ); + stmt2.setString( "ownerid", img.user.userId ); + stmt2.setString( "updaterid", img.user.userId ); + stmt2.setBoolean( "istemplate", img.isTemplate ); + stmt2.executeUpdate(); + } + connection.commit(); + } catch ( SQLException e ) { + LOGGER.error( "Query failed in DbImage.createImageBase()", e ); + throw new TInvocationException( InvocationError.INTERNAL_SERVER_ERROR, "Database boo-boo" ); + } + } + + public static void createImageVersion( ImagePublishData img, String relLocalPath ) throws SQLException + { + try ( MysqlConnection connection = Database.getConnection() ) { + // Insert version + MysqlStatement verStmt = connection.prepareStatement( "INSERT INTO imageversion" + + " (imageversionid, imagebaseid, createtime, expiretime, filesize," + + " filepath, uploaderid, isvalid, isprocessed, mastersha1, virtualizerconfig)" + + " VALUES " + + " (:imageversionid, :imagebaseid, :createtime, :expiretime, :filesize," + + " :filepath, :uploaderid, 0, 0, NULL, NULL)" ); + verStmt.setString( "imageversionid", img.imageVersionId ); + verStmt.setString( "imagebaseid", img.imageBaseId ); + verStmt.setLong( "createtime", img.createTime ); + verStmt.setLong( "expiretime", Util.unixTime() + Globals.getImageValiditySeconds() ); + verStmt.setLong( "filesize", img.fileSize ); + verStmt.setString( "filepath", relLocalPath ); + verStmt.setString( "uploaderid", img.user.userId ); + verStmt.execute(); + connection.commit(); + } catch ( SQLException e ) { + LOGGER.error( "Query failed in DbImage.createImageVersion()", e ); + throw e; + } + } + } diff --git a/src/main/java/org/openslx/imagemaster/db/mappers/DbImageBlock.java b/src/main/java/org/openslx/imagemaster/db/mappers/DbImageBlock.java new file mode 100644 index 0000000..7986d87 --- /dev/null +++ b/src/main/java/org/openslx/imagemaster/db/mappers/DbImageBlock.java @@ -0,0 +1,112 @@ +package org.openslx.imagemaster.db.mappers; + +import java.sql.SQLException; +import java.util.List; +import java.util.concurrent.ArrayBlockingQueue; + +import org.apache.log4j.Logger; +import org.openslx.filetransfer.FileRange; +import org.openslx.filetransfer.util.ChunkStatus; +import org.openslx.filetransfer.util.FileChunk; +import org.openslx.imagemaster.db.Database; +import org.openslx.imagemaster.db.MysqlConnection; +import org.openslx.imagemaster.db.MysqlStatement; + +public class DbImageBlock +{ + + private static final Logger LOGGER = Logger.getLogger( DbImageBlock.class ); + + private static AsyncThread asyncBlockUpdate = null; + + private static synchronized void initAsyncThread() + { + if ( asyncBlockUpdate == null ) { + asyncBlockUpdate = new AsyncThread(); + asyncBlockUpdate.start(); + } + } + + public static void asyncUpdate( String imageVersionId, FileChunk chunk ) throws InterruptedException + { + initAsyncThread(); + asyncBlockUpdate.put( new ChunkUpdate( imageVersionId, chunk.range, chunk.getStatus() != ChunkStatus.COMPLETE ) ); + } + + private static class AsyncThread extends Thread + { + private final ArrayBlockingQueue<ChunkUpdate> queue = new ArrayBlockingQueue<>( 100 ); + + public void put( ChunkUpdate chunk ) throws InterruptedException + { + queue.put( chunk ); + } + + @Override + public void run() + { + try { + while ( !interrupted() ) { + ChunkUpdate chunk = queue.take(); + Thread.sleep( 100 ); + try ( MysqlConnection connection = Database.getConnection() ) { + MysqlStatement stmt = connection.prepareStatement( "UPDATE imageblock SET ismissing = :ismissing" + + " WHERE imageversionid = :imageversionid AND startbyte = :startbyte AND blocksize = :blocksize" ); + do { + stmt.setBoolean( "ismissing", chunk.isMissing ); + stmt.setString( "imageversionid", chunk.imageVersionId ); + stmt.setLong( "startbyte", chunk.range.startOffset ); + stmt.setInt( "blocksize", chunk.range.getLength() ); + stmt.executeUpdate(); + chunk = queue.poll(); + } while ( chunk != null ); + connection.commit(); + } catch ( SQLException e ) { + LOGGER.error( "Query failed in DbImageBlock.AsyncThread.run()", e ); + continue; + } + Thread.sleep( 2000 ); + } + } catch ( InterruptedException e ) { + LOGGER.debug( "async thread interrupted" ); + interrupt(); + } + } + } + + private static class ChunkUpdate + { + public final String imageVersionId; + public final FileRange range; + public final boolean isMissing; + + public ChunkUpdate( String imageVersionId, FileRange range, boolean isMissing ) + { + this.imageVersionId = imageVersionId; + this.range = range; + this.isMissing = isMissing; + } + } + + public static void insertChunkList( String imageVersionId, List<FileChunk> all, boolean missing ) throws SQLException + { + try ( MysqlConnection connection = Database.getConnection() ) { + MysqlStatement stmt = connection.prepareStatement( "INSERT IGNORE INTO imageblock" + + " (imageversionid, startbyte, blocksize, blocksha1, ismissing) VALUES" + + " (:imageversionid, :startbyte, :blocksize, :blocksha1, :ismissing)" ); + stmt.setString( "imageversionid", imageVersionId ); + stmt.setBoolean( "ismissing", missing ); + for ( FileChunk chunk : all ) { + stmt.setLong( "startbyte", chunk.range.startOffset ); + stmt.setInt( "blocksize", chunk.range.getLength() ); + stmt.setBinary( "blocksha1", chunk.getSha1Sum() ); + stmt.executeUpdate(); + } + connection.commit(); + } catch ( SQLException e ) { + LOGGER.error( "Query failed in DbImageBlock.insertChunkList()", e ); + throw e; + } + } + +} diff --git a/src/main/java/org/openslx/imagemaster/db/mappers/DbUser.java b/src/main/java/org/openslx/imagemaster/db/mappers/DbUser.java index 9cde273..b6040e7 100644 --- a/src/main/java/org/openslx/imagemaster/db/mappers/DbUser.java +++ b/src/main/java/org/openslx/imagemaster/db/mappers/DbUser.java @@ -35,14 +35,14 @@ public class DbUser } /** - * Query database for user with given login + * Query database for user with given user id * * @param login (global user-id, login@org for test-accounts) * @return instance of DbUser for matching entry from DB, or null if not * found * @throws SQLException if the query fails */ - public static LocalUser forLogin( final String login ) throws SQLException + public static LocalUser forUserId( final String login ) throws SQLException { try ( MysqlConnection connection = Database.getConnection() ) { MysqlStatement stmt = connection.prepareStatement( localUserSql @@ -58,22 +58,22 @@ public class DbUser } } - public static UserInfo getUserInfo( final String login ) throws SQLException, TNotFoundException - { - LocalUser user = forLogin( login ); - if ( user == null ) - throw new TNotFoundException(); - return user.toUserInfo(); - } - - public static LocalUser forLogin( String login, String password ) throws SQLException + public static LocalUser forUserId( String login, String password ) throws SQLException { - LocalUser user = forLogin( login ); + LocalUser user = forUserId( login ); if ( user == null || !Sha512Crypt.verifyPassword( password, user.password ) ) return null; return user; } + public static UserInfo getUserInfo( final String login ) throws SQLException, TNotFoundException + { + LocalUser user = forUserId( login ); + if ( user == null ) + throw new TNotFoundException(); + return user.toUserInfo(); + } + public static List<UserInfo> findUser( String organizationId, String searchTerm ) { // TODO Implement @@ -82,17 +82,22 @@ public class DbUser public static boolean exists( UserInfo user ) { + return exists( user, false ); + } + + public static boolean exists( UserInfo user, boolean withIdentity ) + { if ( user == null ) return false; - return exists( user.userId ); + return exists( user.userId, withIdentity ); } - private static boolean exists( String userId ) + private static boolean exists( String userId, boolean withIdentitiy ) { if ( userId == null ) return false; try { - return forLogin( userId ) != null; + return forUserId( userId ) != null; } catch ( SQLException e ) { return false; } |