bug 9724 : ListEvents API - add granularity till the hours, minutes and seconds level. The new format that startDate and endDate expect are yyyy-MM-dd HH:mm:ss. To honour backward compatibility these parameters can also be in the old format yyyy-MM-dd. I have added this to the parameter documentation. Also changed is the log message for throwing error in case of parsing exception.

status 9724: resolved fixed
This commit is contained in:
nit 2011-05-26 21:20:46 +05:30
parent 31018be095
commit 6256c88be6
4 changed files with 53 additions and 13 deletions

View File

@ -24,6 +24,7 @@ import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Pattern;
import org.apache.log4j.Logger;
@ -85,7 +86,9 @@ public abstract class BaseCmd {
public static final int RESOURCE_IN_USE_ERROR = 536;
public static final int NETWORK_RULE_CONFLICT_ERROR = 537;
public static final DateFormat INPUT_FORMAT = new SimpleDateFormat("yyyy-MM-dd");
public static final DateFormat INPUT_FORMAT = new SimpleDateFormat("yyyy-MM-dd");
public static final DateFormat NEW_INPUT_FORMAT = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
public static Pattern newInputDateFormat = Pattern.compile("[\\d]+-[\\d]+-[\\d]+ [\\d]+:[\\d]+:[\\d]+");
private static final DateFormat _outputFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ");
private Object _responseObject = null;

4
api/src/com/cloud/api/commands/ListEventsCmd.java Normal file → Executable file
View File

@ -54,7 +54,7 @@ public class ListEventsCmd extends BaseListCmd {
@Parameter(name=ApiConstants.DURATION, type=CommandType.INTEGER, description="the duration of the event")
private Integer duration;
@Parameter(name=ApiConstants.END_DATE, type=CommandType.DATE, description="the end date range of the list you want to retrieve (use format \"yyyy-MM-dd\")")
@Parameter(name=ApiConstants.END_DATE, type=CommandType.DATE, description="the end date range of the list you want to retrieve (use format \"yyyy-MM-dd\" or the new format \"yyyy-MM-dd HH:mm:ss\")")
private Date endDate;
@Parameter(name=ApiConstants.ENTRY_TIME, type=CommandType.INTEGER, description="the time the event was entered")
@ -63,7 +63,7 @@ public class ListEventsCmd extends BaseListCmd {
@Parameter(name=ApiConstants.LEVEL, type=CommandType.STRING, description="the event level (INFO, WARN, ERROR)")
private String level;
@Parameter(name=ApiConstants.START_DATE, type=CommandType.DATE, description="the start date range of the list you want to retrieve (use format \"yyyy-MM-dd\")")
@Parameter(name=ApiConstants.START_DATE, type=CommandType.DATE, description="the start date range of the list you want to retrieve (use format \"yyyy-MM-dd\" or the new format \"yyyy-MM-dd HH:mm:ss\")")
private Date startDate;
@Parameter(name=ApiConstants.TYPE, type=CommandType.STRING, description="the event type (see event types)")

49
server/src/com/cloud/api/ApiDispatcher.java Normal file → Executable file
View File

@ -21,13 +21,17 @@ import java.lang.reflect.Field;
import java.text.DateFormat;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.StringTokenizer;
import java.util.regex.Matcher;
import org.apache.log4j.Logger;
import com.cloud.api.BaseCmd.CommandType;
import com.cloud.api.commands.ListEventsCmd;
import com.cloud.async.AsyncCommandQueued;
import com.cloud.async.AsyncJobManager;
import com.cloud.exception.AccountLimitException;
@ -212,7 +216,7 @@ public class ApiDispatcher {
if (s_logger.isDebugEnabled()) {
s_logger.debug("Invalid date parameter " + paramObj + " passed to command " + cmd.getCommandName());
}
throw new ServerApiException(BaseCmd.PARAM_ERROR, "Unable to parse date " + paramObj + " for command " + cmd.getCommandName() + ", please pass dates in the format yyyy-MM-dd");
throw new ServerApiException(BaseCmd.PARAM_ERROR, "Unable to parse date " + paramObj + " for command " + cmd.getCommandName() + ", please pass dates in the format mentioned in the api documentation");
} catch (CloudRuntimeException cloudEx) {
// FIXME: Better error message? This only happens if the API command is not executable, which typically means
// there was
@ -232,9 +236,32 @@ public class ApiDispatcher {
field.set(cmdObj, Boolean.valueOf(paramObj.toString()));
break;
case DATE:
DateFormat format = BaseCmd.INPUT_FORMAT;
synchronized (format) {
field.set(cmdObj, format.parse(paramObj.toString()));
// This piece of code is for maintaining backward compatibility and support both the date formats(Bug 9724)
// Do the date massaging for ListEventsCmd only
if(cmdObj instanceof ListEventsCmd){
boolean isObjInNewDateFormat = isObjInNewDateFormat(paramObj.toString());
if (isObjInNewDateFormat){
DateFormat newFormat = BaseCmd.NEW_INPUT_FORMAT;
synchronized (newFormat) {
field.set(cmdObj, newFormat.parse(paramObj.toString()));
}
}else{
DateFormat format = BaseCmd.INPUT_FORMAT;
synchronized (format) {
Date date = format.parse(paramObj.toString());
if (field.getName().equals("startDate")){
date = massageDate(date, 0, 0, 0);
}else if (field.getName().equals("endDate")){
date = massageDate(date, 23, 59, 59);
}
field.set(cmdObj, date);
}
}
}else{
DateFormat format = BaseCmd.INPUT_FORMAT;
synchronized (format) {
field.set(cmdObj, format.parse(paramObj.toString()));
}
}
break;
case FLOAT:
@ -282,4 +309,18 @@ public class ApiDispatcher {
throw new CloudRuntimeException("Internal error initializing parameters for command " + cmdObj.getCommandName() + " [field " + field.getName() + " is not accessible]");
}
}
private static boolean isObjInNewDateFormat(String string) {
Matcher matcher = BaseCmd.newInputDateFormat.matcher(string);
return matcher.matches();
}
private static Date massageDate(Date date, int hourOfDay, int minute, int second) {
Calendar cal = Calendar.getInstance();
cal.setTime(date);
cal.set(Calendar.HOUR_OF_DAY, hourOfDay);
cal.set(Calendar.MINUTE, minute);
cal.set(Calendar.SECOND, second);
return cal.getTime();
}
}

View File

@ -2124,15 +2124,11 @@ public class ManagementServerImpl implements ManagementServer {
sc.setParameters("type", type);
}
if (startDate != null && endDate != null) {
startDate = massageDate(startDate, 0, 0, 0);
endDate = massageDate(endDate, 23, 59, 59);
if (startDate != null && endDate != null) {
sc.setParameters("createDateB", startDate, endDate);
} else if (startDate != null) {
startDate = massageDate(startDate, 0, 0, 0);
} else if (startDate != null) {
sc.setParameters("createDateG", startDate);
} else if (endDate != null) {
endDate = massageDate(endDate, 23, 59, 59);
sc.setParameters("createDateL", endDate);
}