summaryrefslogtreecommitdiffstats
path: root/src/main/java/org/openslx/imagemaster/db/mappers
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/java/org/openslx/imagemaster/db/mappers')
-rw-r--r--src/main/java/org/openslx/imagemaster/db/mappers/DbImage.java234
-rw-r--r--src/main/java/org/openslx/imagemaster/db/mappers/DbOperatingSystem.java36
-rw-r--r--src/main/java/org/openslx/imagemaster/db/mappers/DbOrganization.java137
-rw-r--r--src/main/java/org/openslx/imagemaster/db/mappers/DbPendingSatellite.java17
-rw-r--r--src/main/java/org/openslx/imagemaster/db/mappers/DbUser.java108
5 files changed, 532 insertions, 0 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
new file mode 100644
index 0000000..027ddf6
--- /dev/null
+++ b/src/main/java/org/openslx/imagemaster/db/mappers/DbImage.java
@@ -0,0 +1,234 @@
+package org.openslx.imagemaster.db.mappers;
+
+import java.util.List;
+
+import org.openslx.bwlp.thrift.iface.ImagePublishData;
+import org.openslx.imagemaster.Globals;
+import org.openslx.imagemaster.serverconnection.UploadingImage;
+import org.openslx.imagemaster.util.Util;
+
+/**
+ * Representing an image in the database.
+ * Is used to modify/update database entries.
+ */
+public class DbImage
+{
+
+ public final String uuid;
+ public final int revision;
+ public final String title;
+ /**
+ * Relative path of image file (relative to Globals.getImageDir())
+ */
+ public final String relativePath;
+ public final long createTime;
+ public final long updateTime;
+ public final int ownerId;
+ public final String ownerLogin;
+ public final int operatingSystem;
+ public final boolean isValid;
+ public final boolean isDeleted;
+ public final String longDescription;
+ public final long fileSize;
+ public final int[] blockStatus;
+
+ public DbImage( String uuid )
+ {
+ this.uuid = uuid;
+ this.revision = 0;
+ this.title = null;
+ this.relativePath = null;
+ this.createTime = 0;
+ this.updateTime = 0;
+ this.ownerId = 0;
+ this.ownerLogin = null;
+ this.operatingSystem = 0;
+ this.isValid = false;
+ this.isDeleted = false;
+ this.longDescription = null;
+ this.fileSize = 0;
+ this.blockStatus = null;
+ }
+
+ public DbImage( String uuid, int imageVersion, String imageName, String imagePath,
+ long imageCreateTime, long imageUpdateTime, int imageOwnerId, String imageOwnerLogin, int contentOperatingSystem,
+ boolean isValid, boolean isDeleted, String longDescription,
+ long fileSize, String missingBlocksList )
+ {
+ this.uuid = uuid;
+ this.revision = imageVersion;
+ this.title = imageName;
+ this.relativePath = imagePath;
+ this.createTime = imageCreateTime;
+ this.updateTime = imageUpdateTime;
+ this.ownerId = imageOwnerId;
+ this.ownerLogin = imageOwnerLogin;
+ this.operatingSystem = contentOperatingSystem;
+ this.isValid = isValid;
+ this.isDeleted = isDeleted;
+ this.longDescription = longDescription;
+ this.fileSize = fileSize;
+
+ String[] parts = missingBlocksList.split( ";" );
+ blockStatus = new int[ Util.getNumberOfBlocks( fileSize, Globals.blockSize ) ]; // initialize array to ones
+ for ( int i = 0; i < blockStatus.length; ++i ) {
+ blockStatus[i] = UploadingImage.VALID;
+ }
+ for ( String block : parts ) { // Now mark missing blocks (if any)
+ int i = Util.tryToParseInt( block, -1 );
+ if ( i >= 0 && i < blockStatus.length )
+ blockStatus[i] = UploadingImage.MISSING;
+ }
+ }
+
+ /**
+ * Check if image with imageData already exists. (Only checks the UUID.)
+ *
+ * @param imageData
+ * @return
+ */
+ public static boolean exists( String uuid )
+ {
+ return getImageByUuid( uuid ) != null;
+ }
+
+ /**
+ * Insert a new image into database
+ *
+ * @param imageData
+ * The metadata of the image
+ * @param filepath
+ * Local storage path of image
+ * @return Affected rows
+ */
+ public static int insert( ImagePublishData imageData, String filepath )
+ {
+ int numBlocks = Util.getNumberOfBlocks( imageData.fileSize, Globals.blockSize );
+ String missingBlocksList = "";
+ for ( int i = 0; i < numBlocks; i++ ) {
+ missingBlocksList = missingBlocksList + String.valueOf( i ) + ";";
+ }
+ DbUser user = DbUser.forLogin( imageData.ownerLogin );
+ int owner = 0;
+ if ( user != null )
+ owner = user.userId;
+
+ return MySQL
+ .update(
+ "INSERT IGNORE INTO image (uuid, revision, title, path, createtime, updatetime, ownerid, operatingsystem, isvalid, isdeleted, description, filesize, missingblocks) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)",
+ imageData.uuid, imageData.revision, imageData.title, filepath,
+ imageData.createTime, imageData.updateTime, owner,
+ imageData.operatingSystem, imageData.isValid,
+ imageData.isDeleted, imageData.description, imageData.fileSize,
+ missingBlocksList );
+ }
+
+ /**
+ * Updates the missing blocks of an uploading image.
+ *
+ * @param missingBlocks
+ * @return
+ */
+ public int updateMissingBlocks( List<Integer> missingBlocks )
+ {
+ String missingBlocksList = "";
+ if ( missingBlocks != null ) {
+ for ( Integer block : missingBlocks ) {
+ missingBlocksList = missingBlocksList + String.valueOf( block ) + ";";
+ }
+ }
+ return MySQL.update( "UPDATE image SET image.missingblocks = ? WHERE image.uuid = ?", missingBlocksList, uuid );
+ }
+
+ /**
+ * Marks an image as _deleted_ in the database.
+ *
+ * @return
+ */
+ public int delete()
+ {
+ return MySQL.update( "UPDATE image SET image.isdeleted = 1 WHERE image.uuid = ?", this.uuid );
+ }
+
+ /**
+ * Returns all images from database where blocks are still missing.
+ *
+ * @return
+ */
+ public static List<DbImage> getUploadingImages()
+ {
+ return MySQL
+ .findAll(
+ DbImage.class,
+ "SELECT image.uuid, image.revision, image.title, image.path, image.createtime, image.updatetime, image.ownerid, user.login, image.operatingsystem, image.isvalid, image.isdeleted, image.description, image.filesize, image.missingblocks"
+ + " FROM image"
+ + " INNER JOIN user ON (image.ownerid = user.userid)"
+ + " WHERE missingBlocks != ''" );
+ }
+
+ /**
+ * Returns the image that is corrsponding to a specified uuid.
+ *
+ * @param uuid
+ * @return
+ */
+ public static DbImage getImageByUuid( String uuid )
+ {
+ return MySQL
+ .findUniqueOrNull(
+ DbImage.class,
+ "SELECT image.uuid, image.revision, image.title, image.path, image.createtime, image.updatetime, image.ownerid, user.login, image.operatingsystem, image.isvalid, image.isdeleted, image.description, image.filesize, image.missingblocks"
+ + " FROM image"
+ + " INNER JOIN user ON (image.ownerid = user.userid)"
+ + " WHERE uuid = ?",
+ uuid );
+ }
+
+ /**
+ * Return all public images as ImageData list, which can be directly
+ * used by the thrift API.
+ *
+ * @param start
+ * @param limit
+ * @return
+ */
+ public static List<ImageData> asImageDataList( int start, int limit )
+ {
+ return MySQL
+ .findAll(
+ ImageData.class,
+ "SELECT image.uuid, image.revision, image.title, image.createtime, image.updatetime, user.login, image.operatingsystem, image.isvalid, image.isdeleted, image.description, image.filesize"
+ + " FROM image"
+ + " INNER JOIN user ON (image.ownerid = user.userid)"
+ + " ORDER BY uuid, revision"
+ + " LIMIT " + start + ", " + limit );
+ }
+
+ /**
+ * Creates an instance of the thrift ImageData class of this DbImage object.
+ *
+ * @return The corresponding image data
+ */
+ public ImageData getImageData()
+ {
+ String owner = "unknown";
+ DbUser user = DbUser.forLogin( this.ownerId );
+ if ( user != null )
+ owner = user.getLogin();
+ return new ImageData(
+ this.uuid, this.revision, this.title, this.createTime,
+ this.updateTime, owner, this.operatingSystem, this.isValid,
+ this.isDeleted, this.longDescription, this.fileSize );
+ }
+
+ /**
+ * Get absolute path of this image
+ *
+ * @return absolute path
+ */
+ public String getAbsolutePath()
+ {
+ return Globals.getImageDir() + "/" + this.relativePath;
+ }
+
+}
diff --git a/src/main/java/org/openslx/imagemaster/db/mappers/DbOperatingSystem.java b/src/main/java/org/openslx/imagemaster/db/mappers/DbOperatingSystem.java
new file mode 100644
index 0000000..1504e50
--- /dev/null
+++ b/src/main/java/org/openslx/imagemaster/db/mappers/DbOperatingSystem.java
@@ -0,0 +1,36 @@
+package org.openslx.imagemaster.db.mappers;
+
+import java.util.List;
+
+import org.openslx.bwlp.thrift.iface.OperatingSystem;
+import org.openslx.imagemaster.db.MySQL;
+import org.openslx.util.TimeoutReference;
+
+public class DbOperatingSystem
+{
+
+ private static TimeoutReference<List<OperatingSystem>> cached = new TimeoutReference<List<OperatingSystem>>(
+ 30000, null );
+
+ private DbOperatingSystem()
+ {
+ }
+
+ public static List<OperatingSystem> getAll()
+ {
+ List<OperatingSystem> list = cached.get();
+ if ( list != null )
+ return list;
+ list = MySQL.findAll(
+ OperatingSystem.class,
+ "SELECT osid, displayname, NULL, architecture"
+ + " FROM operatingsystem" );
+ for ( OperatingSystem os : list ) {
+ os.virtualizerOsId = MySQL.findMap( String.class, String.class,
+ "SELECT virtid, virtoskeyword FROM os_x_virt WHERE osid = ?", os.osId );
+ }
+ cached.set( list );
+ return list;
+ }
+
+}
diff --git a/src/main/java/org/openslx/imagemaster/db/mappers/DbOrganization.java b/src/main/java/org/openslx/imagemaster/db/mappers/DbOrganization.java
new file mode 100644
index 0000000..cf1a20a
--- /dev/null
+++ b/src/main/java/org/openslx/imagemaster/db/mappers/DbOrganization.java
@@ -0,0 +1,137 @@
+package org.openslx.imagemaster.db.mappers;
+
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.log4j.Logger;
+import org.openslx.bwlp.thrift.iface.Organization;
+import org.openslx.imagemaster.db.Database;
+import org.openslx.imagemaster.db.MysqlConnection;
+import org.openslx.imagemaster.db.MysqlStatement;
+
+/**
+ * Represents an organization in the database.
+ * Is used to authenticate the organization.
+ */
+public class DbOrganization
+{
+ private static final Logger LOGGER = Logger.getLogger( DbOrganization.class );
+
+ private static final String organizationBaseSql = "SELECT"
+ + " o.organizationid, o.name, o.authmethod, o.publickey"
+ + " FROM organization o";
+
+ private static final String suffixListFromOrgSql = "SELECT suffix FROM organization_suffix"
+ + " WHERE organizationid = :organizationid";
+
+ private static Organization fromResultSet( MysqlConnection connection, ResultSet rs ) throws SQLException
+ {
+ String organizationId = rs.getString( "organizationid" );
+ String ecpUrl = rs.getString( "authmethod" );
+ if ( ecpUrl != null && !ecpUrl.startsWith( "http" ) ) {
+ ecpUrl = null;
+ }
+ return new Organization( organizationId, rs.getString( "name" ), ecpUrl, getSuffixList( connection,
+ organizationId ) );
+ }
+
+ /**
+ * Get organization by id. Returns null if not found.
+ *
+ * @param organizationId
+ * @return
+ * @throws SQLException
+ */
+ public static Organization fromOrganizationId( String organizationId ) throws SQLException
+ {
+ try ( MysqlConnection connection = Database.getConnection() ) {
+ MysqlStatement stmt = connection.prepareStatement( organizationBaseSql + " WHERE o.organizationid = :organizationid" );
+ stmt.setString( "organizationid", organizationId );
+ ResultSet rs = stmt.executeQuery();
+ if ( !rs.next() )
+ return null;
+ return fromResultSet( connection, rs );
+ } catch ( SQLException e ) {
+ LOGGER.error( "Query failed in DbOrganization.fromOrganizationId()", e );
+ throw e;
+ }
+ }
+
+ public static Organization fromSuffix( String suffix ) throws SQLException
+ {
+ try ( MysqlConnection connection = Database.getConnection() ) {
+ MysqlStatement stmt = connection.prepareStatement( organizationBaseSql
+ + " INNER JOIN organization_suffix s USING (organizationid)"
+ + " WHERE s.suffix = :suffix" );
+ stmt.setString( "suffix", suffix );
+ ResultSet rs = stmt.executeQuery();
+ if ( !rs.next() )
+ return null;
+ return fromResultSet( connection, rs );
+ } catch ( SQLException e ) {
+ LOGGER.error( "Query failed in DbOrganization.fromSuffix()", e );
+ throw e;
+ }
+ }
+
+ private static List<String> suffixForOrg( MysqlStatement stmt, String organizationId ) throws SQLException
+ {
+ stmt.setString( "organizationid", organizationId );
+ ResultSet rs = stmt.executeQuery();
+ List<String> list = new ArrayList<>();
+ while ( rs.next() ) {
+ list.add( rs.getString( "suffix" ) );
+ }
+ return list;
+ }
+
+ /**
+ * Return all known satellites/organizations as List of {@link OrganizationData}, which can be
+ * used directly by the thrift API.
+ *
+ * @return list of all known organizations/satellites
+ * @throws SQLException
+ */
+ public static List<Organization> getAll() throws SQLException
+ {
+ try ( MysqlConnection connection = Database.getConnection() ) {
+ MysqlStatement stmt = connection.prepareStatement( organizationBaseSql );
+ ResultSet rsOrg = stmt.executeQuery();
+ MysqlStatement stmtSuffix = connection.prepareStatement( suffixListFromOrgSql );
+ List<Organization> list = new ArrayList<>();
+ while ( rsOrg.next() ) {
+ String organizationId = rsOrg.getString( "organizationid" );
+ String ecpUrl = rsOrg.getString( "authmethod" );
+ if ( ecpUrl != null && !ecpUrl.startsWith( "http" ) ) {
+ ecpUrl = null;
+ }
+ List<String> suffixList = suffixForOrg( stmtSuffix, organizationId );
+ list.add( new Organization( organizationId, rsOrg.getString( "name" ), ecpUrl, suffixList ) );
+ }
+ return list;
+ } catch ( SQLException e ) {
+ LOGGER.error( "Query failed in DbOrganization.getAll()", e );
+ throw e;
+ }
+ }
+
+ public static DbOrganization fromPrefix( String prefix )
+ {
+ return null;
+ }
+
+ public static List<String> getSuffixList( MysqlConnection connection, String organizationId ) throws SQLException
+ {
+ List<String> list = new ArrayList<>();
+ MysqlStatement stmt = connection.prepareStatement( suffixListFromOrgSql );
+ stmt.setString( "organizationid", organizationId );
+ ResultSet rs = stmt.executeQuery();
+ while ( rs.next() ) {
+ list.add( rs.getString( "suffix" ) );
+ }
+ return list;
+ }
+
+}
diff --git a/src/main/java/org/openslx/imagemaster/db/mappers/DbPendingSatellite.java b/src/main/java/org/openslx/imagemaster/db/mappers/DbPendingSatellite.java
new file mode 100644
index 0000000..15cdbb9
--- /dev/null
+++ b/src/main/java/org/openslx/imagemaster/db/mappers/DbPendingSatellite.java
@@ -0,0 +1,17 @@
+package org.openslx.imagemaster.db.mappers;
+
+import org.apache.log4j.Logger;
+import org.openslx.imagemaster.db.MySQL;
+
+public class DbPendingSatellite
+{
+
+ private static final Logger LOG = Logger.getLogger( DbPendingSatellite.class );
+
+ public static boolean add( String organizationId, String address, String modulus, String exponent )
+ {
+ String publickey = "mod:" + modulus + " exp:" + exponent;
+ return MySQL.update( "INSERT INTO pending_satellite (dateline, organizationid, address, publickey)"
+ + " VALUES (UNIX_TIMESTAMP(), ?, ?, ?)", organizationId, address, publickey ) != 0;
+ }
+}
diff --git a/src/main/java/org/openslx/imagemaster/db/mappers/DbUser.java b/src/main/java/org/openslx/imagemaster/db/mappers/DbUser.java
new file mode 100644
index 0000000..ed55d8a
--- /dev/null
+++ b/src/main/java/org/openslx/imagemaster/db/mappers/DbUser.java
@@ -0,0 +1,108 @@
+package org.openslx.imagemaster.db.mappers;
+
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.log4j.Logger;
+import org.openslx.bwlp.thrift.iface.Role;
+import org.openslx.bwlp.thrift.iface.TNotFoundException;
+import org.openslx.bwlp.thrift.iface.UserInfo;
+import org.openslx.imagemaster.db.Database;
+import org.openslx.imagemaster.db.MysqlConnection;
+import org.openslx.imagemaster.db.MysqlStatement;
+import org.openslx.imagemaster.db.models.LocalUser;
+import org.openslx.imagemaster.util.Sha512Crypt;
+
+/**
+ * Represents a user that can login against the masterserver.
+ */
+public class DbUser
+{
+
+ private static final Logger LOGGER = Logger.getLogger( DbUser.class );
+
+ private static final String localUserSql = "SELECT"
+ + " user.userid, user.login, user.password, user.organizationid, user.firstname, user.lastname, user.email,"
+ + " organization.address FROM user"
+ + " LEFT JOIN organization USING (organizationid)";
+
+ private static LocalUser localFromRs( ResultSet rs ) throws SQLException
+ {
+ return new LocalUser( rs.getInt( "userid" ), rs.getString( "login" ), rs.getString( "password" ),
+ rs.getString( "organizationid" ), rs.getString( "firstname" ), rs.getString( "lastname" ), rs.getString( "email" ),
+ Role.TUTOR );
+ }
+
+ /**
+ * Query database for user with given login
+ *
+ * @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
+ {
+ try ( MysqlConnection connection = Database.getConnection() ) {
+ MysqlStatement stmt = connection.prepareStatement( localUserSql
+ + " WHERE user.login = :login" );
+ stmt.setString( "login", login );
+ ResultSet rs = stmt.executeQuery();
+ if ( !rs.next() )
+ return null;
+ return localFromRs( rs );
+ } catch ( SQLException e ) {
+ LOGGER.error( "Query failed in DbUser.forLogin()", e );
+ throw e;
+ }
+ }
+
+ public static UserInfo getUserInfo( final String login ) throws SQLException, TNotFoundException
+ {
+ LocalUser user = forLogin( login );
+ if ( user == null )
+ throw new TNotFoundException();
+ return user.toUserInfo();
+ }
+
+ /**
+ * Query database for user with given userId
+ *
+ * @param userid
+ * @return instance of DbUser for matching entry from DB, or null if not
+ * found
+ * @throws SQLException
+ */
+ public static LocalUser forLogin( final int userId ) throws SQLException
+ {
+ try ( MysqlConnection connection = Database.getConnection() ) {
+ MysqlStatement stmt = connection.prepareStatement( localUserSql
+ + " WHERE user.userid = :userid" );
+ stmt.setInt( "userid", userId );
+ ResultSet rs = stmt.executeQuery();
+ if ( !rs.next() )
+ return null;
+ return localFromRs( rs );
+ } catch ( SQLException e ) {
+ LOGGER.error( "Query failed in DbUser.forLogin()", e );
+ throw e;
+ }
+ }
+
+ public static LocalUser forLogin( String login, String password ) throws SQLException
+ {
+ LocalUser user = forLogin( login );
+ if ( user == null || !Sha512Crypt.verifyPassword( password, user.password ) )
+ return null;
+ return user;
+ }
+
+ public static List<UserInfo> findUser( String organizationId, String searchTerm )
+ {
+ // TODO Implement
+ return new ArrayList<>( 0 );
+ }
+
+}