--- /dev/null
+/*\r
+ * Copyright 2007, 2008, 2009 Electronic Business Systems Ltd.\r
+ *\r
+ * This file is part of GSS.\r
+ *\r
+ * GSS is free software: you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation, either version 3 of the License, or\r
+ * (at your option) any later version.\r
+ *\r
+ * GSS is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+ * GNU General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU General Public License\r
+ * along with GSS. If not, see <http://www.gnu.org/licenses/>.\r
+ */\r
+package gr.ebs.gss.server.domain;\r
+\r
+import java.io.Serializable;\r
+import java.util.Date;\r
+\r
+import javax.persistence.Column;\r
+import javax.persistence.Entity;\r
+import javax.persistence.GeneratedValue;\r
+import javax.persistence.Id;\r
+import javax.persistence.JoinColumn;\r
+import javax.persistence.ManyToOne;\r
+import javax.persistence.Temporal;\r
+import javax.persistence.TemporalType;\r
+\r
+/**\r
+ * This class holds information about bandwidth usage by users.\r
+ * This information is broken down in time periods.\r
+ */\r
+@Entity\r
+public class AccountingInfo implements Serializable{\r
+\r
+ /**\r
+ * The persistence ID of the object.\r
+ */\r
+ @SuppressWarnings("unused")\r
+ @Id\r
+ @GeneratedValue\r
+ private Long id;\r
+\r
+ /**\r
+ * The user whose usage we are noting. We can never change it after\r
+ * creation.\r
+ */\r
+ @ManyToOne\r
+ @JoinColumn(updatable = false, nullable = false)\r
+ private User user;\r
+\r
+ /**\r
+ * The start of the time period. We can never change it after\r
+ * creation.\r
+ */\r
+ @Temporal(TemporalType.TIMESTAMP)\r
+ @Column(updatable = false, nullable = false)\r
+ private Date dateFrom;\r
+\r
+\r
+ /**\r
+ * The end of the time period. We can never change it after\r
+ * creation.\r
+ */\r
+ @Temporal(TemporalType.TIMESTAMP)\r
+ @Column(updatable = false, nullable = false)\r
+ private Date dateTo;\r
+\r
+\r
+ /**\r
+ * The usage itself, in bytes.\r
+ */\r
+ @Column(nullable = false)\r
+ private long bandwidthUsed = 0;\r
+\r
+\r
+ /**\r
+ * Default constructor. Required by Hibernate,\r
+ * but shouldn't be called.\r
+ */\r
+ @SuppressWarnings("unused")\r
+ private AccountingInfo() {\r
+ }\r
+\r
+\r
+ /**\r
+ * Constructor\r
+ */\r
+ public AccountingInfo(User _user, Date _dateFrom, Date _dateTo) {\r
+ user = _user;\r
+ dateFrom = _dateFrom;\r
+ dateTo = _dateTo;\r
+ }\r
+\r
+\r
+ /**\r
+ * Retrieve the user\r
+ * @return the user\r
+ */\r
+ public User getUser() {\r
+ return user;\r
+ }\r
+\r
+\r
+ /**\r
+ * Retrieve the start of the time period.\r
+ * @return the start of the time period\r
+ */\r
+ public Date getDateFrom() {\r
+ return dateFrom;\r
+ }\r
+\r
+\r
+ /**\r
+ * Retrieve the end of the time period.\r
+ * @return the end of the time period\r
+ */\r
+ public Date getDateTo() {\r
+ return dateTo;\r
+ }\r
+\r
+\r
+ /**\r
+ * Retrieve the bandwidth used.\r
+ * @return the bandwidth used\r
+ */\r
+ public long getBandwidthUsed() {\r
+ return bandwidthUsed;\r
+ }\r
+\r
+\r
+ /**\r
+ * Update bandwidth used upwards or downwards with new amount.\r
+ * @param bandwidthDiff The amount by which to update;\r
+ * positive for increase, negative for decrease.\r
+ */\r
+ public void updateBandwidth(long bandwidthDiff) {\r
+ bandwidthUsed += bandwidthDiff;\r
+ }\r
+\r
+}\r
* @param name the name of the new file
* @param mimeType the MIME type of the file
* @param stream the input stream with the file contents
+ * @return The FileHeaderDTO created
* @throws DuplicateNameException if the specified name already exists in
* the parent folder, as either a folder or file
* @throws ObjectNotFoundException if the user or parent folder was not
* @throws InsufficientPermissionsException
* @throws QuotaExceededException
*/
- public void createFile(Long userId, Long folderId, String name, String mimeType,
+ public FileHeaderDTO createFile(Long userId, Long folderId, String name, String mimeType,
InputStream stream) throws DuplicateNameException, ObjectNotFoundException,
GSSIOException, InsufficientPermissionsException, QuotaExceededException;
* @param fileId the ID of the file header object
* @param mimeType the content type of the file
* @param resourceInputStream a stream of the file contents
+ * @return The FileHeaderDTO created
* @throws ObjectNotFoundException if the user or file was not found, with
* the exception message mentioning the precise problem
* @throws GSSIOException if there was an error while storing the file contents
* @throws InsufficientPermissionsException
* @throws QuotaExceededException
*/
- public void updateFileContents(Long userId, Long fileId, String mimeType,
+ public FileHeaderDTO updateFileContents(Long userId, Long fileId, String mimeType,
InputStream resourceInputStream) throws ObjectNotFoundException,
GSSIOException, InsufficientPermissionsException, QuotaExceededException;
* @param name the name of the new file
* @param mimeType the MIME type of the file
* @param uploadedFile the uploaded file
+ * @return The FileHeaderDTO created
* @throws DuplicateNameException if the specified name already exists in
* the parent folder, as either a folder or file
* @throws ObjectNotFoundException if the user or parent folder was not
* @throws InsufficientPermissionsException
* @throws QuotaExceededException
*/
- public void createFile(Long userId, Long folderId, String name, String mimeType, File uploadedFile)
+ public FileHeaderDTO createFile(Long userId, Long folderId, String name, String mimeType, File uploadedFile)
throws DuplicateNameException, ObjectNotFoundException, GSSIOException,
InsufficientPermissionsException, QuotaExceededException;
* @param fileId the ID of the file header object
* @param mimeType the content type of the file
* @param uploadedFile the already uploadedFile
+ * @return The FileHeaderDTO updated
* @throws ObjectNotFoundException if the user or file was not found, with
* the exception message mentioning the precise problem
* @throws GSSIOException when an IO exception occurs
* @throws InsufficientPermissionsException
* @throws QuotaExceededException
*/
- public void updateFileContents(Long userId, Long fileId, String mimeType,
+ public FileHeaderDTO updateFileContents(Long userId, Long fileId, String mimeType,
File uploadedFile) throws ObjectNotFoundException, GSSIOException,
InsufficientPermissionsException, QuotaExceededException;
* Update the user with the values from the supplied object.
*/
public void updateUser(User user);
+
+ /**
+ * Update accounting information for given user.
+ *
+ * @param user The user to update
+ * @param date Date of transaction
+ * @param bandwidthDiff Bandwidth used; positive for addition,
+ * negative for subtraction (e.g. to rollback)
+ */
+ public void updateAccounting(User user, Date date, long bandwidthDiff);
}
}
@Override
- public void createFile(Long userId, Long folderId, String name, String mimeType, InputStream stream)
+ public FileHeaderDTO createFile(Long userId, Long folderId, String name, String mimeType, InputStream stream)
throws DuplicateNameException, ObjectNotFoundException, GSSIOException,
InsufficientPermissionsException, QuotaExceededException {
File file = null;
// Supply a more accurate problem description.
throw new GSSIOException("Problem creating file",ioe);
}
- createFile(userId, folderId, name, mimeType, file);
+ return createFile(userId, folderId, name, mimeType, file);
}
/* (non-Javadoc)
}
@Override
- public void updateFileContents(Long userId, Long fileId, String mimeType, InputStream resourceInputStream) throws ObjectNotFoundException, GSSIOException, InsufficientPermissionsException, QuotaExceededException {
+ public FileHeaderDTO updateFileContents(Long userId, Long fileId, String mimeType, InputStream resourceInputStream) throws ObjectNotFoundException, GSSIOException, InsufficientPermissionsException, QuotaExceededException {
File file = null;
try {
file = uploadFile(resourceInputStream, userId);
// Supply a more accurate problem description.
throw new GSSIOException("Problem creating file",ioe);
}
- updateFileContents(userId, fileId, mimeType, file);
+ return updateFileContents(userId, fileId, mimeType, file);
}
@Override
}
}
- public void createFile(Long userId, Long folderId, String name, String mimeType, File fileObject)
+ public FileHeaderDTO createFile(Long userId, Long folderId, String name, String mimeType, File fileObject)
throws DuplicateNameException, ObjectNotFoundException, GSSIOException,
InsufficientPermissionsException, QuotaExceededException {
// Validate.
}
dao.flush();
indexFile(file.getId(), false);
+
+ return file.getDTO();
}
/* (non-Javadoc)
* @see gr.ebs.gss.server.ejb.ExternalAPI#updateFileContents(java.lang.Long, java.lang.Long, java.lang.String, java.io.InputStream)
*/
- public void updateFileContents(Long userId, Long fileId, String mimeType, File fileObject) throws ObjectNotFoundException, GSSIOException, InsufficientPermissionsException, QuotaExceededException {
+ public FileHeaderDTO updateFileContents(Long userId, Long fileId, String mimeType, File fileObject) throws ObjectNotFoundException, GSSIOException, InsufficientPermissionsException, QuotaExceededException {
if (userId == null)
throw new ObjectNotFoundException("No user specified");
if (fileId == null)
}
indexFile(fileId, false);
+ return file.getDTO();
}
/**
if (StringUtils.isEmpty(mimeType) || "application/octet-stream".equals(mimeType))
body.setMimeType(identifyMimeType(name));
else
- body.setMimeType(mimeType);
+ body.setMimeType(mimeType);
body.setAuditInfo(auditInfo);
body.setFileSize(uploadedFile.length());
body.setOriginalFilename(name);
return user;
}
+ @Override
+ public void updateAccounting(User user, Date date, long bandwidthDiff) {
+ dao.updateAccounting(user, date, bandwidthDiff);
+ }
+
}
* @param name the name of the new file
* @param mimeType the MIME type of the file
* @param stream the input stream with the file contents
+ * @return The FileHeaderDTO created
* @throws DuplicateNameException if the specified name already exists in
* the parent folder, as either a folder or file
* @throws ObjectNotFoundException if the user or parent folder was not
* @throws GSSIOException if there was an error while storing the file contents
* @throws InsufficientPermissionsException
*/
- public void createFile(Long userId, Long folderId, String name, String mimeType, InputStream stream) throws DuplicateNameException, ObjectNotFoundException, GSSIOException, InsufficientPermissionsException, QuotaExceededException;
+ public FileHeaderDTO createFile(Long userId, Long folderId, String name, String mimeType, InputStream stream) throws DuplicateNameException, ObjectNotFoundException, GSSIOException, InsufficientPermissionsException, QuotaExceededException;
/**
* Deletes the specified file in the specified user's namespace.
* @param fileId the ID of the file header object
* @param mimeType the content type of the file
* @param resourceInputStream a stream of the file contents
+ * @return The FileHeaderDTO updated
* @throws ObjectNotFoundException if the user or file was not found, with
* the exception message mentioning the precise problem
* @throws GSSIOException if there was an error while storing the file contents
* @throws InsufficientPermissionsException
*/
- public void updateFileContents(Long userId, Long fileId, String mimeType, InputStream resourceInputStream) throws ObjectNotFoundException, GSSIOException, InsufficientPermissionsException, QuotaExceededException;
+ public FileHeaderDTO updateFileContents(Long userId, Long fileId, String mimeType, InputStream resourceInputStream) throws ObjectNotFoundException, GSSIOException, InsufficientPermissionsException, QuotaExceededException;
/**
* Copy the provided file to the specified destination.
import gr.ebs.gss.server.domain.Nonce;
import gr.ebs.gss.server.domain.User;
+import java.util.Date;
import java.util.List;
import java.util.Set;
* @throws ObjectNotFoundException if the file body was not found
*/
public FileBody getFileVersion(Long fileId, int version) throws ObjectNotFoundException;
+
+ /**
+ * Update accounting info for given user.
+ * Adds bandwidth used to appropriate time period bucket.
+ * Bucket is created if needed.
+ *
+ * @param user The user to update
+ * @param date Date of transaction
+ * @param bandwidthDiff Bandwidth used; positive for addition,
+ * negative for subtraction (e.g. to rollback)
+ */
+ public void updateAccounting(User user, Date date, long bandwidthDiff);
}
package gr.ebs.gss.server.ejb;
import gr.ebs.gss.client.exceptions.ObjectNotFoundException;
+import gr.ebs.gss.server.domain.AccountingInfo;
import gr.ebs.gss.server.domain.FileBody;
import gr.ebs.gss.server.domain.FileHeader;
import gr.ebs.gss.server.domain.FileUploadStatus;
import gr.ebs.gss.server.domain.User;
import java.util.ArrayList;
+import java.util.Calendar;
+import java.util.Date;
+import java.util.GregorianCalendar;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
@Stateless
public class GSSDAOBean implements GSSDAO {
+ private static final int BANDWIDTH_TIME_PERIOD_FIELD = Calendar.MONTH;
+ private static final int BANDWIDTH_TIME_PERIOD_AMOUNT = 1;
+
/**
* The entity manager for the persistence unit
*/
throw new ObjectNotFoundException("No version " + version + " found for file #" + fileId);
}
}
+
+ @Override
+ public void updateAccounting(User user, Date date, long bandwidthDiff) {
+ AccountingInfo ai = null;
+ try {
+ ai = (AccountingInfo) manager.createQuery("select ai from AccountingInfo ai " +
+ "where ai.user=:user and ai.dateFrom<=:date and ai.dateTo>:date")
+ .setParameter("user", user)
+ .setParameter("date", date)
+ .getSingleResult();
+ }
+ catch (NoResultException e) {
+ ai = null;
+ }
+
+ if (ai==null) {
+ // The right entry does not exist; must be created.
+ // This is where we set the initial time period.
+ // We now start from the user's creation, we can change this to something else.
+ Calendar creationDate = new GregorianCalendar();
+ creationDate.setTime(user.getAuditInfo().getCreationDate());
+ int offset = 0;
+ Calendar dateFrom;
+ Calendar dateTo;
+ long timeInMillis = date.getTime();
+ do {
+ dateFrom = (Calendar) creationDate.clone();
+ dateFrom.add(BANDWIDTH_TIME_PERIOD_FIELD, offset);
+ dateTo = (Calendar) dateFrom.clone();
+ dateTo.add(BANDWIDTH_TIME_PERIOD_FIELD, 1);
+ offset += BANDWIDTH_TIME_PERIOD_AMOUNT;
+ }
+ while (!(dateFrom.getTimeInMillis()<=timeInMillis && dateTo.getTimeInMillis()>timeInMillis));
+
+ ai = new AccountingInfo(user, dateFrom.getTime(), dateTo.getTime());
+ manager.persist(ai);
+ }
+
+ // Do the update.
+ ai.updateBandwidth(bandwidthDiff);
+ }
+
}
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.util.ArrayList;
+import java.util.Date;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
copy(file, renderResult, ostream, req, oldBody);
else
copy(file, renderResult, writer, req, oldBody);
+ if (file!=null) getService().updateAccounting(user, new Date(), contentLength);
} catch (ObjectNotFoundException e) {
resp.sendError(HttpServletResponse.SC_NOT_FOUND);
return;
copy(file, ostream, range, req, oldBody);
else
copy(file, writer, range, req, oldBody);
+ getService().updateAccounting(user, new Date(), contentLength);
} catch (ObjectNotFoundException e) {
resp.sendError(HttpServletResponse.SC_NOT_FOUND);
return;
copy(file, ostream, ranges.iterator(), contentType, req, oldBody);
else
copy(file, writer, ranges.iterator(), contentType, req, oldBody);
+ getService().updateAccounting(user, new Date(), contentLength);
} catch (ObjectNotFoundException e) {
resp.sendError(HttpServletResponse.SC_NOT_FOUND);
return;
} catch (IOException ex) {
throw new GSSIOException(ex, false);
}
+ FileHeaderDTO fileDTO = null;
if (file == null)
- getService().createFile(user.getId(), folder.getId(), fileName, contentType, uploadedFile);
+ fileDTO = getService().createFile(user.getId(), folder.getId(), fileName, contentType, uploadedFile);
else
- getService().updateFileContents(user.getId(), file.getId(), contentType, uploadedFile);
+ fileDTO = getService().updateFileContents(user.getId(), file.getId(), contentType, uploadedFile);
+ getService().updateAccounting(user, new Date(), fileDTO.getFileSize());
getService().removeFileUploadProgress(user.getId(), fileName);
}
}
String name = getLastElement(path);
String mimeType = context.getMimeType(name);
// FIXME: Add attributes
+ FileHeaderDTO fileDTO = null;
if (exists)
- getService().updateFileContents(user.getId(), file.getId(), mimeType, resourceInputStream);
+ fileDTO = getService().updateFileContents(user.getId(), file.getId(), mimeType, resourceInputStream);
else
- getService().createFile(user.getId(), folder.getId(), name, mimeType, resourceInputStream);
+ fileDTO = getService().createFile(user.getId(), folder.getId(), name, mimeType, resourceInputStream);
+ getService().updateAccounting(user, new Date(), fileDTO.getFileSize());
getService().removeFileUploadProgress(user.getId(), file.getName());
} catch(ObjectNotFoundException e) {
result = false;
import java.io.File;
import java.io.IOException;
+import java.util.Date;
import java.util.List;
import java.util.Set;
@Override
public void createFile(@WebParam(name="userId")Long userId, @WebParam(name="folderId")Long folderId, @WebParam(name="name")String name, @WebParam(name="mimeType")String mimeType, @WebParam(name="stream")DataHandler stream) throws DuplicateNameException, ObjectNotFoundException, GSSIOException, InsufficientPermissionsException, QuotaExceededException {
try {
- api.createFile(userId, folderId, name, mimeType, stream.getInputStream());
+ FileHeaderDTO file = api.createFile(userId, folderId, name, mimeType, stream.getInputStream());
+ User user = api.getUser(userId);
+ api.updateAccounting(user, new Date(), file.getFileSize());
} catch (IOException e) {
throw new GSSIOException(e);
}
@Override
public void updateFileContents(@WebParam(name="userId") Long userId, @WebParam(name="fileId") Long fileId, @WebParam(name="mimeType") String mimeType, @WebParam(name="resourceStream") DataHandler resourceInputStream) throws ObjectNotFoundException, GSSIOException, InsufficientPermissionsException, QuotaExceededException {
try {
- api.updateFileContents(userId, fileId, mimeType, resourceInputStream.getInputStream());
+ FileHeaderDTO file = api.updateFileContents(userId, fileId, mimeType, resourceInputStream.getInputStream());
+ User user = api.getUser(userId);
+ api.updateAccounting(user, new Date(), file.getFileSize());
} catch (IOException e) {
throw new GSSIOException(e);
}
String name = getLastElement(path);
String mimeType = getServletContext().getMimeType(name);
// FIXME: Add attributes
+ FileHeaderDTO fileDTO = null;
if (exists)
- getService().updateFileContents(user.getId(), file.getId(), mimeType, resourceInputStream);
+ fileDTO = getService().updateFileContents(user.getId(), file.getId(), mimeType, resourceInputStream);
else
- getService().createFile(user.getId(), folder.getId(), name, mimeType, resourceInputStream);
+ fileDTO = getService().createFile(user.getId(), folder.getId(), name, mimeType, resourceInputStream);
+ getService().updateAccounting(user, new Date(), fileDTO.getFileSize());
} catch (ObjectNotFoundException e) {
result = false;
} catch (InsufficientPermissionsException e) {
copy(file, renderResult, ostream, req, null);
else
copy(file, renderResult, writer, req, null);
+ getService().updateAccounting(user, new Date(), contentLength);
}
} else {
if (ranges == null || ranges.isEmpty())
copy(file, ostream, range, req, null);
else
copy(file, writer, range, req, null);
+ getService().updateAccounting(user, new Date(), contentLength);
}
} else {