throws AuthorizationException,
ResourceRequestDeniedException {
if (!HashUtil.isInitialized()) {
throw new AuthorizationException("Cannot give an authorization " +
"decision without a properly initialized hashing system");
}
if (dn == null) {
throw new IllegalArgumentException("dn is null");
}
if (rights == null) {
throw new IllegalArgumentException("rights is null");
}
if (bindings == null) {
throw new IllegalArgumentException("bindings is null");
}
if (elapsedMins == null) {
throw new IllegalArgumentException("elapsedMins is null");
} else if (elapsedMins.longValue() < 0) {
throw new IllegalArgumentException("elapsedMins is negative");
}
if (reservedMins == null) {
throw new IllegalArgumentException("reservedMins is null");
} else if (reservedMins.longValue() < 0) {
throw new IllegalArgumentException("reservedMins is negative");
}
if (chargeRatio <= 0) {
throw new IllegalArgumentException("expecting charge ratio to be positive");
}
final StringBuffer buf = new StringBuffer("\n\nConsidering caller: '");
buf.append(dn)
.append("'.\nCurrent elapsed minutes: ")
.append(elapsedMins)
.append(".\nCurrent reserved minutes: ")
.append(reservedMins)
.append(".\nNumber of VMs in request: ")
.append(bindings.length)
.append(".\nCharge ratio for request: ")
.append(chargeRatio)
.append(".\nNumber of VMs caller is already currently running: ")
.append(numWorkspaces)
.append(".\nRights:\n")
.append(rights)
.append("\n\n");
final int maxCurrentPolicy = (int) rights.getMaxWorkspaceNumber();
if (maxCurrentPolicy > 0) {
if (numWorkspaces + bindings.length > maxCurrentPolicy) {
final StringBuffer newbuf =
new StringBuffer("\nDenied: Request for ");
newbuf.append(bindings.length)
.append(" workspaces");
if (numWorkspaces != 0) {
newbuf.append(", together with number of currently " +
"running workspaces (")
.append(numWorkspaces)
.append("),");
}
newbuf.append(" exceeds the maximum, which is ")
.append(maxCurrentPolicy)
.append(" concurrently running workspaces.");
final String msg = newbuf.toString();
buf.append(msg);
logger.warn(buf.toString());
throw new ResourceRequestDeniedException(msg);
}
}
long requestDur = 0;
for (int i = 0; i < bindings.length; i++) {
final VirtualMachineDeployment dep = bindings[i].getDeployment();
if (dep == null) {
final String msg = "ERROR: No deployment information in " +
"binding, can't make decision.";
buf.append(msg);
logger.error(buf.toString());
throw new AuthorizationException(msg);
}
final long seconds = dep.getMinDuration();
requestDur += seconds / 60;
}
final Double doubleRequestDur = requestDur * chargeRatio;
requestDur = doubleRequestDur.longValue();
if (bindings.length > 1) {
buf.append("Duration total of all requests in group: ");
} else {
buf.append("Duration request: ");
}
buf.append(requestDur)
.append("\n");
// zero or below means no check should be made
if (rights.getMaxCPUs() > 0) {
final long maxCPUs = rights.getMaxCPUs();
for (int i = 0; i < bindings.length; i++) {
final VirtualMachineDeployment dep = bindings[i].getDeployment();
if (dep == null) {
final String msg = "ERROR: No deployment information in " +
"binding, can't make decision.";
buf.append(msg);
logger.error(buf.toString());
throw new AuthorizationException(msg);
}
final long currentCPUs = dep.getIndividualCPUCount();
if (currentCPUs > maxCPUs) {
buf.append("\nDenied: Requested CPU count (")
.append(currentCPUs)
.append(") + is greater or equal to maximum CPU count (")
.append(maxCPUs)
.append(").\n");
logger.warn(buf.toString());
throw new ResourceRequestDeniedException(
"You requested too many CPUs (" +
currentCPUs + "), the " +
"maximum is " +
maxCPUs + " CPUs.");
}
}
}
// zero or below means no check should be made
if (rights.getMaxReservedMinutes() > 0) {
final long max = rights.getMaxReservedMinutes();
final long current = reservedMins.longValue();
if (requestDur + current > max) {
buf.append("\nDenied: Request duration (")
.append(requestDur)
.append(") + current reserved tally (")
.append(current)
.append(") + is greater or equal to maximum reserved (")
.append(max)
.append(").\n");
logger.warn(buf.toString());
throw new ResourceRequestDeniedException(
"Your request is for too much time (" +
requestDur + "), the " +
"maximum reserved at once is " +
max + " minutes. You currently have " +
current + " other reserved minutes.");
}
}
// zero or below means no check should be made
if (rights.getMaxElapsedReservedMinutes() > 0) {
final long max = rights.getMaxElapsedReservedMinutes();
final long currentElapsed = elapsedMins.longValue();
final long currentReserved = reservedMins.longValue();
final long tally = currentElapsed + currentReserved;
if (requestDur + tally > max) {
buf.append("\nDenied: Request duration (")
.append(requestDur)
.append(") + current reserved+elapsed tally (")
.append(tally)
.append(") + is greater or equal to maximum reserved+elapsed (")
.append(max)
.append(").\n");
logger.warn(buf.toString());
throw new ResourceRequestDeniedException(
"Your request is for too much time (" +
requestDur + "), this would exceed the " +
"maximum you can have both used in the " +
"past and have reserved currently. " +
"This maximum is " +
max + " minutes. You currently have " +
currentElapsed + " elapsed minutes " +
"and " + currentReserved +
" reserved minutes and the request for " +
requestDur + " minutes would exceed this.");
}
}
final String dnhash;
if (rights.isDirHashMode()) {
try {
dnhash = HashUtil.hashDN(dn);
} catch (NoSuchAlgorithmException e) {
final String msg = "ERROR: DN hash required but it " +
"is not available: " + e.getMessage();
buf.append(msg);
logger.error(buf.toString());
throw new AuthorizationException(msg);
}
} else {
dnhash = null;
}
for (int i = 0; i < bindings.length; i++) {
final VirtualMachinePartition[] parts =
bindings[i].getPartitions();
if (parts == null) {
final String msg = "ERROR: No partition information in " +
"binding, can't make decision.";
buf.append(msg);
logger.error(buf.toString());
throw new AuthorizationException(msg);
}
checkImages(parts, rights, buf, dn, dnhash);
}