From d2fe2332d38afa3c1106ce64fcecda944bfff425 Mon Sep 17 00:00:00 2001 From: Harikrishna Patnala Date: Tue, 14 Mar 2017 14:53:11 +0530 Subject: [PATCH] CLOUDSTACK-9833: Move configuration parameters from Config.java to use ConfigDepot Following parameters are moved to configdepot. snapshot.max.hourly snapshot.max.daily snapshot.max.weekly snapshot.max.monthly enable.secure.session.cookie json.content.type --- .../cloudstack/api/ApiServerService.java | 3 -- server/src/com/cloud/api/ApiServer.java | 41 +++++++++---------- server/src/com/cloud/api/ApiServlet.java | 22 +++++----- .../src/com/cloud/configuration/Config.java | 23 +---------- .../storage/snapshot/SnapshotManager.java | 15 ++++--- .../storage/snapshot/SnapshotManagerImpl.java | 19 ++++++--- 6 files changed, 55 insertions(+), 68 deletions(-) diff --git a/api/src/org/apache/cloudstack/api/ApiServerService.java b/api/src/org/apache/cloudstack/api/ApiServerService.java index aeeb7b613ca..2b5768261b5 100644 --- a/api/src/org/apache/cloudstack/api/ApiServerService.java +++ b/api/src/org/apache/cloudstack/api/ApiServerService.java @@ -43,7 +43,4 @@ public interface ApiServerService { public Class getCmdClass(String cmdName); - public String getJSONContentType(); - - public boolean isSecureSessionCookieEnabled(); } diff --git a/server/src/com/cloud/api/ApiServer.java b/server/src/com/cloud/api/ApiServer.java index 75bf380b135..6413716b32e 100644 --- a/server/src/com/cloud/api/ApiServer.java +++ b/server/src/com/cloud/api/ApiServer.java @@ -96,6 +96,8 @@ import org.apache.cloudstack.api.response.ExceptionResponse; import org.apache.cloudstack.api.response.ListResponse; import org.apache.cloudstack.api.response.LoginCmdResponse; import org.apache.cloudstack.context.CallContext; +import org.apache.cloudstack.framework.config.ConfigKey; +import org.apache.cloudstack.framework.config.Configurable; import org.apache.cloudstack.framework.config.dao.ConfigurationDao; import org.apache.cloudstack.framework.config.impl.ConfigurationVO; import org.apache.cloudstack.framework.events.EventBus; @@ -180,13 +182,11 @@ import java.util.regex.Matcher; import java.util.regex.Pattern; @Component -public class ApiServer extends ManagerBase implements HttpRequestHandler, ApiServerService { +public class ApiServer extends ManagerBase implements HttpRequestHandler, ApiServerService, Configurable { private static final Logger s_logger = Logger.getLogger(ApiServer.class.getName()); private static final Logger s_accessLogger = Logger.getLogger("apiserver." + ApiServer.class.getName()); private static boolean encodeApiResponse = false; - private boolean enableSecureCookie = false; - private String jsonContentType = HttpUtils.JSON_CONTENT_TYPE; /** * Non-printable ASCII characters - numbers 0 to 31 and 127 decimal @@ -227,6 +227,12 @@ public class ApiServer extends ManagerBase implements HttpRequestHandler, ApiSer private static ExecutorService s_executor = new ThreadPoolExecutor(10, 150, 60, TimeUnit.SECONDS, new LinkedBlockingQueue(), new NamedThreadFactory( "ApiServer")); + + static final ConfigKey EnableSecureSessionCookie = new ConfigKey("Advanced", Boolean.class, "enable.secure.session.cookie", "false", + "Session cookie is marked as secure if this is enabled. Secure cookies only work when HTTPS is used.", false); + + static final ConfigKey JSONcontentType = new ConfigKey(String.class, "json.content.type", "Advanced", "application/json; charset=UTF-8", + "Http response content type for .js files (default is text/javascript)", false, ConfigKey.Scope.Global, null); @Inject private MessageBus messageBus; @@ -366,14 +372,6 @@ public class ApiServer extends ManagerBase implements HttpRequestHandler, ApiSer } setEncodeApiResponse(Boolean.valueOf(configDao.getValue(Config.EncodeApiResponse.key()))); - final String jsonType = configDao.getValue(Config.JSONDefaultContentType.key()); - if (jsonType != null) { - jsonContentType = jsonType; - } - final Boolean enableSecureSessionCookie = Boolean.valueOf(configDao.getValue(Config.EnableSecureSessionCookie.key())); - if (enableSecureSessionCookie != null) { - enableSecureCookie = enableSecureSessionCookie; - } if (apiPort != null) { final ListenerThread listenerThread = new ListenerThread(this, apiPort); @@ -1143,7 +1141,7 @@ public class ApiServer extends ManagerBase implements HttpRequestHandler, ApiSer final BasicHttpEntity body = new BasicHttpEntity(); if (HttpUtils.RESPONSE_TYPE_JSON.equalsIgnoreCase(responseType)) { // JSON response - body.setContentType(getJSONContentType()); + body.setContentType(JSONcontentType.value()); if (responseText == null) { body.setContent(new ByteArrayInputStream("{ \"error\" : { \"description\" : \"Internal Server Error\" } }".getBytes(HttpUtils.UTF_8))); } @@ -1163,6 +1161,16 @@ public class ApiServer extends ManagerBase implements HttpRequestHandler, ApiSer } } + @Override + public String getConfigComponentName() { + return ApiServer.class.getSimpleName(); + } + + @Override + public ConfigKey[] getConfigKeys() { + return new ConfigKey[] { EnableSecureSessionCookie, JSONcontentType }; + } + // FIXME: the following two threads are copied from // http://svn.apache.org/repos/asf/httpcomponents/httpcore/trunk/httpcore/src/examples/org/apache/http/examples/ElementalHttpServer.java // we have to cite a license if we are using this code directly, so we need to add the appropriate citation or @@ -1366,13 +1374,4 @@ public class ApiServer extends ManagerBase implements HttpRequestHandler, ApiSer ApiServer.encodeApiResponse = encodeApiResponse; } - @Override - public boolean isSecureSessionCookieEnabled() { - return enableSecureCookie; - } - - @Override - public String getJSONContentType() { - return jsonContentType; - } } diff --git a/server/src/com/cloud/api/ApiServlet.java b/server/src/com/cloud/api/ApiServlet.java index 6c836984618..7a607fde773 100644 --- a/server/src/com/cloud/api/ApiServlet.java +++ b/server/src/com/cloud/api/ApiServlet.java @@ -158,7 +158,7 @@ public class ApiServlet extends HttpServlet { try { if (HttpUtils.RESPONSE_TYPE_JSON.equalsIgnoreCase(responseType)) { - resp.setContentType(apiServer.getJSONContentType()); + resp.setContentType(ApiServer.JSONcontentType.value()); } else if (HttpUtils.RESPONSE_TYPE_XML.equalsIgnoreCase(responseType)){ resp.setContentType(HttpUtils.XML_CONTENT_TYPE); } @@ -189,12 +189,10 @@ public class ApiServlet extends HttpServlet { } } session = req.getSession(true); - if (apiServer.isSecureSessionCookieEnabled()) { + if (ApiServer.EnableSecureSessionCookie.value()) { resp.setHeader("SET-COOKIE", String.format("JSESSIONID=%s;Secure;HttpOnly;Path=/client", session.getId())); if (s_logger.isDebugEnabled()) { - if (s_logger.isDebugEnabled()) { - s_logger.debug("Session cookie is marked secure!"); - } + s_logger.debug("Session cookie is marked secure!"); } } } @@ -231,7 +229,7 @@ public class ApiServlet extends HttpServlet { sessionKeyCookie.setMaxAge(0); resp.addCookie(sessionKeyCookie); } - HttpUtils.writeHttpResponse(resp, responseString, httpResponseCode, responseType, apiServer.getJSONContentType()); + HttpUtils.writeHttpResponse(resp, responseString, httpResponseCode, responseType, ApiServer.JSONcontentType.value()); return; } } @@ -256,7 +254,7 @@ public class ApiServlet extends HttpServlet { auditTrailSb.append(" " + HttpServletResponse.SC_UNAUTHORIZED + " " + "unable to verify user credentials"); final String serializedResponse = apiServer.getSerializedApiError(HttpServletResponse.SC_UNAUTHORIZED, "unable to verify user credentials", params, responseType); - HttpUtils.writeHttpResponse(resp, serializedResponse, HttpServletResponse.SC_UNAUTHORIZED, responseType, apiServer.getJSONContentType()); + HttpUtils.writeHttpResponse(resp, serializedResponse, HttpServletResponse.SC_UNAUTHORIZED, responseType, ApiServer.JSONcontentType.value()); return; } @@ -267,7 +265,7 @@ public class ApiServlet extends HttpServlet { s_logger.info("missing command, ignoring request..."); auditTrailSb.append(" " + HttpServletResponse.SC_BAD_REQUEST + " " + "no command specified"); final String serializedResponse = apiServer.getSerializedApiError(HttpServletResponse.SC_BAD_REQUEST, "no command specified", params, responseType); - HttpUtils.writeHttpResponse(resp, serializedResponse, HttpServletResponse.SC_BAD_REQUEST, responseType, apiServer.getJSONContentType()); + HttpUtils.writeHttpResponse(resp, serializedResponse, HttpServletResponse.SC_BAD_REQUEST, responseType, ApiServer.JSONcontentType.value()); return; } final User user = entityMgr.findById(User.class, userId); @@ -283,7 +281,7 @@ public class ApiServlet extends HttpServlet { auditTrailSb.append(" " + HttpServletResponse.SC_UNAUTHORIZED + " " + "unable to verify user credentials"); final String serializedResponse = apiServer.getSerializedApiError(HttpServletResponse.SC_UNAUTHORIZED, "unable to verify user credentials", params, responseType); - HttpUtils.writeHttpResponse(resp, serializedResponse, HttpServletResponse.SC_UNAUTHORIZED, responseType, apiServer.getJSONContentType()); + HttpUtils.writeHttpResponse(resp, serializedResponse, HttpServletResponse.SC_UNAUTHORIZED, responseType, ApiServer.JSONcontentType.value()); return; } } else { @@ -297,7 +295,7 @@ public class ApiServlet extends HttpServlet { // Add the HTTP method (GET/POST/PUT/DELETE) as well into the params map. params.put("httpmethod", new String[] {req.getMethod()}); final String response = apiServer.handleRequest(params, responseType, auditTrailSb); - HttpUtils.writeHttpResponse(resp, response != null ? response : "", HttpServletResponse.SC_OK, responseType, apiServer.getJSONContentType()); + HttpUtils.writeHttpResponse(resp, response != null ? response : "", HttpServletResponse.SC_OK, responseType, ApiServer.JSONcontentType.value()); } else { if (session != null) { try { @@ -310,13 +308,13 @@ public class ApiServlet extends HttpServlet { final String serializedResponse = apiServer.getSerializedApiError(HttpServletResponse.SC_UNAUTHORIZED, "unable to verify user credentials and/or request signature", params, responseType); - HttpUtils.writeHttpResponse(resp, serializedResponse, HttpServletResponse.SC_UNAUTHORIZED, responseType, apiServer.getJSONContentType()); + HttpUtils.writeHttpResponse(resp, serializedResponse, HttpServletResponse.SC_UNAUTHORIZED, responseType, ApiServer.JSONcontentType.value()); } } catch (final ServerApiException se) { final String serializedResponseText = apiServer.getSerializedApiError(se, params, responseType); resp.setHeader("X-Description", se.getDescription()); - HttpUtils.writeHttpResponse(resp, serializedResponseText, se.getErrorCode().getHttpCode(), responseType, apiServer.getJSONContentType()); + HttpUtils.writeHttpResponse(resp, serializedResponseText, se.getErrorCode().getHttpCode(), responseType, ApiServer.JSONcontentType.value()); auditTrailSb.append(" " + se.getErrorCode() + " " + se.getDescription()); } catch (final Exception ex) { s_logger.error("unknown exception writing api response", ex); diff --git a/server/src/com/cloud/configuration/Config.java b/server/src/com/cloud/configuration/Config.java index 05c58da2cd8..551c61ea2e4 100644 --- a/server/src/com/cloud/configuration/Config.java +++ b/server/src/com/cloud/configuration/Config.java @@ -489,10 +489,7 @@ public enum Config { null), // Snapshots - SnapshotHourlyMax("Snapshots", SnapshotManager.class, Integer.class, "snapshot.max.hourly", "8", "Maximum hourly snapshots for a volume", null), - SnapshotDailyMax("Snapshots", SnapshotManager.class, Integer.class, "snapshot.max.daily", "8", "Maximum daily snapshots for a volume", null), - SnapshotWeeklyMax("Snapshots", SnapshotManager.class, Integer.class, "snapshot.max.weekly", "8", "Maximum weekly snapshots for a volume", null), - SnapshotMonthlyMax("Snapshots", SnapshotManager.class, Integer.class, "snapshot.max.monthly", "8", "Maximum monthly snapshots for a volume", null), + SnapshotPollInterval( "Snapshots", SnapshotManager.class, @@ -1500,24 +1497,6 @@ public enum Config { "Percentage (as a value between 0 and 1) of connected agents after which agent load balancing will start happening", null), - JSONDefaultContentType( - "Advanced", - ManagementServer.class, - String.class, - "json.content.type", - "application/json; charset=UTF-8", - "Http response content type for JSON", - null), - - EnableSecureSessionCookie( - "Advanced", - ManagementServer.class, - Boolean.class, - "enable.secure.session.cookie", - "false", - "Session cookie's secure flag is enabled if true. Use this only when using HTTPS", - null), - DefaultMaxDomainUserVms("Domain Defaults", ManagementServer.class, Long.class, "max.domain.user.vms", "40", "The default maximum number of user VMs that can be deployed for a domain", null), DefaultMaxDomainPublicIPs("Domain Defaults", ManagementServer.class, Long.class, "max.domain.public.ips", "40", "The default maximum number of public IPs that can be consumed by a domain", null), DefaultMaxDomainTemplates("Domain Defaults", ManagementServer.class, Long.class, "max.domain.templates", "40", "The default maximum number of templates that can be deployed for a domain", null), diff --git a/server/src/com/cloud/storage/snapshot/SnapshotManager.java b/server/src/com/cloud/storage/snapshot/SnapshotManager.java index 0bbc03585e3..87937898803 100644 --- a/server/src/com/cloud/storage/snapshot/SnapshotManager.java +++ b/server/src/com/cloud/storage/snapshot/SnapshotManager.java @@ -25,19 +25,24 @@ import com.cloud.exception.ResourceAllocationException; import com.cloud.storage.Snapshot; import com.cloud.storage.SnapshotVO; import com.cloud.storage.Volume; +import org.apache.cloudstack.framework.config.ConfigKey; /** * * */ public interface SnapshotManager { - - public static final int HOURLYMAX = 8; - public static final int DAILYMAX = 8; - public static final int WEEKLYMAX = 8; - public static final int MONTHLYMAX = 12; public static final int DELTAMAX = 16; + static final ConfigKey SnapshotHourlyMax = new ConfigKey(Integer.class, "snapshot.max.hourly", "Snapshots", "8", + "Maximum recurring hourly snapshots to be retained for a volume. If the limit is reached, early snapshots from the start of the hour are deleted so that newer ones can be saved. This limit does not apply to manual snapshots. If set to 0, recurring hourly snapshots can not be scheduled.", false, ConfigKey.Scope.Global, null); + static final ConfigKey SnapshotDailyMax = new ConfigKey(Integer.class, "snapshot.max.daily", "Snapshots", "8", + "Maximum recurring daily snapshots to be retained for a volume. If the limit is reached, snapshots from the start of the day are deleted so that newer ones can be saved. This limit does not apply to manual snapshots. If set to 0, recurring daily snapshots can not be scheduled.", false, ConfigKey.Scope.Global, null); + static final ConfigKey SnapshotWeeklyMax = new ConfigKey(Integer.class, "snapshot.max.weekly", "Snapshots", "8", + "Maximum recurring weekly snapshots to be retained for a volume. If the limit is reached, snapshots from the beginning of the week are deleted so that newer ones can be saved. This limit does not apply to manual snapshots. If set to 0, recurring weekly snapshots can not be scheduled.", false, ConfigKey.Scope.Global, null); + static final ConfigKey SnapshotMonthlyMax = new ConfigKey(Integer.class, "snapshot.max.monthly", "Snapshots", "8", + "Maximum recurring monthly snapshots to be retained for a volume. If the limit is reached, snapshots from the beginning of the month are deleted so that newer ones can be saved. This limit does not apply to manual snapshots. If set to 0, recurring monthly snapshots can not be scheduled.", false, ConfigKey.Scope.Global, null); + void deletePoliciesForVolume(Long volumeId); /** diff --git a/server/src/com/cloud/storage/snapshot/SnapshotManagerImpl.java b/server/src/com/cloud/storage/snapshot/SnapshotManagerImpl.java index f3ea88bdcbe..2ffc8acc618 100755 --- a/server/src/com/cloud/storage/snapshot/SnapshotManagerImpl.java +++ b/server/src/com/cloud/storage/snapshot/SnapshotManagerImpl.java @@ -111,6 +111,8 @@ import org.apache.cloudstack.engine.subsystem.api.storage.StorageStrategyFactory import org.apache.cloudstack.engine.subsystem.api.storage.VolumeDataFactory; import org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo; import org.apache.cloudstack.engine.subsystem.api.storage.ZoneScope; +import org.apache.cloudstack.framework.config.ConfigKey; +import org.apache.cloudstack.framework.config.Configurable; import org.apache.cloudstack.framework.config.dao.ConfigurationDao; import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao; import org.apache.cloudstack.storage.datastore.db.SnapshotDataStoreDao; @@ -128,7 +130,7 @@ import java.util.Map; import java.util.TimeZone; @Component -public class SnapshotManagerImpl extends MutualExclusiveIdsManagerBase implements SnapshotManager, SnapshotApiService { +public class SnapshotManagerImpl extends MutualExclusiveIdsManagerBase implements SnapshotManager, SnapshotApiService, Configurable { private static final Logger s_logger = Logger.getLogger(SnapshotManagerImpl.class); @Inject VMTemplateDao _templateDao; @@ -1176,10 +1178,10 @@ public class SnapshotManagerImpl extends MutualExclusiveIdsManagerBase implement String value = _configDao.getValue(Config.BackupSnapshotWait.toString()); - Type.HOURLY.setMax(NumbersUtil.parseInt(_configDao.getValue("snapshot.max.hourly"), HOURLYMAX)); - Type.DAILY.setMax(NumbersUtil.parseInt(_configDao.getValue("snapshot.max.daily"), DAILYMAX)); - Type.WEEKLY.setMax(NumbersUtil.parseInt(_configDao.getValue("snapshot.max.weekly"), WEEKLYMAX)); - Type.MONTHLY.setMax(NumbersUtil.parseInt(_configDao.getValue("snapshot.max.monthly"), MONTHLYMAX)); + Type.HOURLY.setMax(SnapshotHourlyMax.value()); + Type.DAILY.setMax(SnapshotDailyMax.value()); + Type.WEEKLY.setMax(SnapshotWeeklyMax.value()); + Type.MONTHLY.setMax(SnapshotMonthlyMax.value()); _totalRetries = NumbersUtil.parseInt(_configDao.getValue("total.retries"), 4); _pauseInterval = 2 * NumbersUtil.parseInt(_configDao.getValue("ping.interval"), 60); @@ -1319,5 +1321,12 @@ public class SnapshotManagerImpl extends MutualExclusiveIdsManagerBase implement } + @Override + public String getConfigComponentName() { + return SnapshotManager.class.getSimpleName(); + } + @Override + public ConfigKey[] getConfigKeys() { + return new ConfigKey[] { SnapshotHourlyMax, SnapshotDailyMax, SnapshotMonthlyMax, SnapshotWeeklyMax}; } }