Vojtech Szocs has uploaded a new change for review.
Change subject: webadmin,userportal: Frontend improvements
......................................................................
webadmin,userportal: Frontend improvements
The general idea behind this patch is code improvement.
1) Re-wrote "frontend" project's servlet unit tests from scratch
to make them more simple and readable while making them more
meaningful (focus on verifying effects of tested code, grouped
into small, isolated, logical test cases)
Some concepts applied in servlet unit test refactoring:
- "bottom-up" testing favored over "top-down" testing, since
the "top-down" approach is inherently more complicated and
therefore yields more complex and less readable test code
- "bottom-up" testing = testing of smaller, SRPy [1] methods
that make up bigger ones; the assumption is that when all
the smaller methods work as expected, the bigger ones should
work as expected too, because they are essentially composition
of smaller methods
- "top-down" testing = testing of big methods (like servlet's
doGet); the disadvantage is since big methods are composition
of smaller ones, the necessary test env./mock setup is more
complicated, plus it's harder to assert individual effects
of executing bigger method (compared to smaller ones)
- if some class doesn't allow "bottom-up" testing, it should
be refactored to contain small, SRPy methods that are easily
testable; as a result, unit tests will be more simple and
readable
- each test case should have human-readable description that
communicates *WHAT* the test actually does; unfortunately
Java test frameworks like JUnit doesn't support this in
an appropriate way -- lack of proper test case description
can lead to original test code being mutated in ways that
don't fit the original test case scenario, resulting in
bloated, unreadable tests
For instance, compare how readable is this (Java):
@Test
public void setHttpAttributes_withoutLoggedInUser() {
// test code
}
to BDD-style test code (JavaScript):
it('should set HTTP attributes in case user is not logged in', function() {
// test code
});
- the core of each test case is verifying effects of tested
code (asserts); verifying mock interactions should *NOT*
be overused as it can lead to fragile tests, which break
when code under test is changed despite the effects of its
execution remain the same
- sometimes it's hard to mock/stub code like:
* methods containing static method calls
* methods requiring complex mocking setup
(i.e. methods using BackendLocal runQuery API)
For above cases, it's always much easier to simply stub
that behavior with custom (mocked) results, instead of
trying to mock static methods or mock BackendLocal runQuery
API directly; the practical effect is essentially the same.
2) GWT host page servlet classes refactored according to 1).
- GwtDynamicHostPageServlet.{doGet,doPost} is now final
to avoid "hacking" into default servlet behavior; the
practice of overriding big methods (typically containing
general business logic workflow) leads to fragile code.
- GwtDynamicHostPageServlet.doGet is essentially template
method [2] containing hooks like setHttpAttributes that
can be overridden to customize the overall behavior.
3) Optimization in WebAdmin & UserPortal: Engine RPM version
is now embedded into GWT host page (HTML) as JS object:
var engineRpmVersion = {"value": "<version_goes_here>"};
This saves us one extra XHR request and makes the version
immediately available on client: "about" dialogs no longer
need to make XHR to display Engine version.
The real motivation for 3) is 4) - see below.
4) Client storage keys are now in following format:
<keyPrefix>_<version>_<actualKey>
<keyPrefix> is either "ENGINE_WebAdmin" or "ENGINE_UserPortal"
and <version> is Engine RPM version (as displayed in "about"
dialogs).
This change should reduce the probability of client storage
key name clashes in situations involving multiple Engine
web GUIs opened in the browser.
5) Improvement: GWT overlay types (overlaying native JS object)
for simple single-value JS objects like following:
var someObj = {"value": "<anything>"};
Can now simply extend JsSingleValueObject, see SSOTokenData
or EngineRpmVersionData for a working example.
6) Since in future we'll use REST API in both WebAdmin and
UserPortal, "engineSessionTimeout" JS object as well as
its overlay type (EngineSessionTimeoutData) was moved from
"..webadmin.plugin.restapi" to "..common.system" package.
7) Small cleanup: removed some unreferenced (dead) code.
[1] http://en.wikipedia.org/wiki/Single_responsibility_principle
[2] http://en.wikipedia.org/wiki/Template_method_pattern
Change-Id: I4864b2d4703ee548a570799ed3e87674602f5438
Signed-off-by: Vojtech Szocs <[email protected]>
---
M
frontend/webadmin/modules/frontend/src/main/java/org/ovirt/engine/ui/frontend/server/gwt/GwtDynamicHostPageServlet.java
M
frontend/webadmin/modules/frontend/src/main/java/org/ovirt/engine/ui/frontend/server/gwt/UserPortalHostPageServlet.java
M
frontend/webadmin/modules/frontend/src/main/java/org/ovirt/engine/ui/frontend/server/gwt/WebAdminHostPageServlet.java
M
frontend/webadmin/modules/frontend/src/main/resources/META-INF/resources/GwtHostPage.jsp
M
frontend/webadmin/modules/frontend/src/test/java/org/ovirt/engine/ui/frontend/server/gwt/AbstractGwtDynamicHostPageServletTest.java
M
frontend/webadmin/modules/frontend/src/test/java/org/ovirt/engine/ui/frontend/server/gwt/UserPortalHostPageServletTest.java
M
frontend/webadmin/modules/frontend/src/test/java/org/ovirt/engine/ui/frontend/server/gwt/WebAdminHostPageServletTest.java
M
frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/auth/SSOTokenData.java
A
frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/jsni/JsSingleValueObject.java
M
frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/system/BaseApplicationInit.java
M
frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/system/ClientStorageImpl.java
A
frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/system/ClientStorageKeyPrefix.java
A
frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/system/EngineRpmVersionData.java
A
frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/system/EngineSessionTimeoutData.java
M
frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/ReportsUrls.java
M
frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/dataprovider/AsyncDataProvider.java
M
frontend/webadmin/modules/userportal-gwtp/src/main/java/org/ovirt/engine/ui/userportal/gin/SystemModule.java
M
frontend/webadmin/modules/userportal-gwtp/src/main/java/org/ovirt/engine/ui/userportal/section/main/presenter/AboutPopupPresenterWidget.java
M
frontend/webadmin/modules/webadmin/src/main/java/org/ovirt/engine/ui/webadmin/gin/SystemModule.java
D
frontend/webadmin/modules/webadmin/src/main/java/org/ovirt/engine/ui/webadmin/plugin/restapi/EngineSessionTimeoutData.java
M
frontend/webadmin/modules/webadmin/src/main/java/org/ovirt/engine/ui/webadmin/section/main/presenter/AboutPopupPresenterWidget.java
M
frontend/webadmin/modules/webadmin/src/main/java/org/ovirt/engine/ui/webadmin/section/main/presenter/HeaderPresenterWidget.java
M
frontend/webadmin/modules/webadmin/src/main/java/org/ovirt/engine/ui/webadmin/system/ApplicationInit.java
23 files changed, 845 insertions(+), 669 deletions(-)
git pull ssh://gerrit.ovirt.org:29418/ovirt-engine refs/changes/36/36536/1
diff --git
a/frontend/webadmin/modules/frontend/src/main/java/org/ovirt/engine/ui/frontend/server/gwt/GwtDynamicHostPageServlet.java
b/frontend/webadmin/modules/frontend/src/main/java/org/ovirt/engine/ui/frontend/server/gwt/GwtDynamicHostPageServlet.java
index 805714a..d5c1a84 100644
---
a/frontend/webadmin/modules/frontend/src/main/java/org/ovirt/engine/ui/frontend/server/gwt/GwtDynamicHostPageServlet.java
+++
b/frontend/webadmin/modules/frontend/src/main/java/org/ovirt/engine/ui/frontend/server/gwt/GwtDynamicHostPageServlet.java
@@ -1,16 +1,13 @@
package org.ovirt.engine.ui.frontend.server.gwt;
import java.io.IOException;
-import java.io.UnsupportedEncodingException;
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Locale;
import javax.ejb.EJB;
-import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
-import javax.servlet.ServletRequest;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@@ -18,13 +15,15 @@
import org.apache.commons.lang.StringUtils;
import org.codehaus.jackson.map.ObjectMapper;
-import org.codehaus.jackson.node.ArrayNode;
import org.codehaus.jackson.node.ObjectNode;
import org.ovirt.engine.core.branding.BrandingFilter;
import org.ovirt.engine.core.branding.BrandingManager;
import org.ovirt.engine.core.common.businessentities.aaa.DbUser;
+import org.ovirt.engine.core.common.config.ConfigCommon;
import org.ovirt.engine.core.common.constants.SessionConstants;
import org.ovirt.engine.core.common.interfaces.BackendLocal;
+import org.ovirt.engine.core.common.queries.ConfigurationValues;
+import org.ovirt.engine.core.common.queries.GetConfigurationValueParameters;
import org.ovirt.engine.core.common.queries.VdcQueryParametersBase;
import org.ovirt.engine.core.common.queries.VdcQueryReturnValue;
import org.ovirt.engine.core.common.queries.VdcQueryType;
@@ -34,9 +33,8 @@
/**
* Renders the HTML host page of a GWT application.
- * <p>
+ * <p/>
* Embeds additional data (JavaScript objects) into the host page.
- * By default, information about the currently logged-in user is included via
{@code userInfo} object.
*/
public abstract class GwtDynamicHostPageServlet extends HttpServlet {
@@ -45,33 +43,26 @@
* determine if the values have changed.
*/
public enum MD5Attributes {
+
ATTR_SELECTOR_SCRIPT("selectorScript"), //$NON-NLS-1$
ATTR_USER_INFO("userInfo"), //$NON-NLS-1$
- ATTR_STYLES("brandingStyle"), //$NON-NLS-1$
+ ATTR_SSO_TOKEN("ssoToken"), //$NON-NLS-1$
ATTR_MESSAGES("messages"), //$NON-NLS-1$
ATTR_BASE_CONTEXT_PATH("baseContextPath"), //$NON-NLS-1$
- ATTR_LOCALE(LocaleFilter.LOCALE),
- ATTR_SSO_TOKEN("ssoToken"), //$NON-NLS-1$
- ATTR_APPLICATION_TYPE(BrandingFilter.APPLICATION_NAME),
- ATTR_DISPLAY_LOCALES("visibleLocales"); //$NON-NLS-1$
+ ATTR_DISPLAY_LOCALES("visibleLocales"), //$NON-NLS-1$
+ ATTR_ENGINE_SESSION_TIMEOUT("engineSessionTimeout"), //$NON-NLS-1$
+ ATTR_ENGINE_RPM_VERSION("engineRpmVersion"); //$NON-NLS-1$
- private final String attributeKey;
+ private final String key;
- /**
- * Constructor for enum.
- * @param key The key to store
- */
- private MD5Attributes(final String key) {
- this.attributeKey = key;
+ private MD5Attributes(String key) {
+ this.key = key;
}
- /**
- * Get the value of the attribute key.
- * @return A {@code String} containing the key.
- */
public String getKey() {
- return attributeKey;
+ return key;
}
+
}
private static final long serialVersionUID = 3946034162721073929L;
@@ -79,13 +70,12 @@
public static final String IF_NONE_MATCH_HEADER = "If-None-Match";
//$NON-NLS-1$
public static final String ETAG_HEADER = "Etag"; //$NON-NLS-1$
- private static final String HOST_JSP = "/GwtHostPage.jsp"; //$NON-NLS-1$
- private static final String UTF_CONTENT_TYPE = "text/html; charset=UTF-8";
//$NON-NLS-1$
+ static final String HOST_JSP = "/GwtHostPage.jsp"; //$NON-NLS-1$
+ static final String UTF_CONTENT_TYPE = "text/html; charset=UTF-8";
//$NON-NLS-1$
private BackendLocal backend;
- private ObjectMapper mapper;
-
+ protected ObjectMapper mapper;
private BrandingManager brandingManager;
@EJB(beanInterface = BackendLocal.class,
@@ -105,69 +95,24 @@
}
@Override
- protected void doGet(final HttpServletRequest request, final
HttpServletResponse response) throws IOException,
- ServletException {
+ protected final void doGet(HttpServletRequest request, HttpServletResponse
response) throws ServletException, IOException {
+ setHttpAttributes(request, getEngineSessionId(request));
- // Set attribute for selector script
- request.setAttribute(MD5Attributes.ATTR_SELECTOR_SCRIPT.getKey(),
getSelectorScriptName());
- // Set the messages that need to be replaced.
- request.setAttribute(MD5Attributes.ATTR_MESSAGES.getKey(),
- getBrandingMessages(getApplicationTypeFromRequest(request),
getLocaleFromRequest(request)));
- request.setAttribute(MD5Attributes.ATTR_BASE_CONTEXT_PATH.getKey(),
- getValueObject(ServletUtils.getBaseContextPath(request)));
- request.setAttribute(MD5Attributes.ATTR_DISPLAY_LOCALES.getKey(),
getValueObject(
-
StringUtils.join(UnsupportedLocaleHelper.getDisplayedLocales(LocaleFilter.getLocaleKeys()),
- ","))); //$NON-NLS-1$
- // Set attribute for userInfo object
- DbUser loggedInUser =
- getLoggedInUser(getEngineSessionId(request));
- if (loggedInUser != null) {
- request.setAttribute(MD5Attributes.ATTR_USER_INFO.getKey(),
getUserInfoObject(loggedInUser));
- String ssoToken = (String)
-
request.getSession().getAttribute(SessionConstants.HTTP_SESSION_ENGINE_SESSION_ID_KEY);
- if (ssoToken != null) {
- request.setAttribute(MD5Attributes.ATTR_SSO_TOKEN.getKey(),
getValueObject(ssoToken));
- }
+ // Calculate MD5 for use with If-None-Match request header
+ String md5sum = getMd5Sum(request);
+
+ if (request.getHeader(IF_NONE_MATCH_HEADER) != null
+ && request.getHeader(IF_NONE_MATCH_HEADER).equals(md5sum)) {
+ response.setStatus(HttpServletResponse.SC_NOT_MODIFIED);
+ } else {
+ response.setContentType(UTF_CONTENT_TYPE);
+ response.addHeader(ETAG_HEADER, md5sum);
+ request.getRequestDispatcher(HOST_JSP).include(request, response);
}
-
- try {
- // Calculate MD5 for use with If-None-Match request header
- String md5sum = getMd5Sum(request);
-
- if (request.getHeader(IF_NONE_MATCH_HEADER) != null
- && request.getHeader(IF_NONE_MATCH_HEADER).equals(md5sum))
{
- response.setStatus(HttpServletResponse.SC_NOT_MODIFIED);
- } else {
- RequestDispatcher dispatcher =
request.getRequestDispatcher(HOST_JSP);
- response.setContentType(UTF_CONTENT_TYPE);
- response.addHeader(ETAG_HEADER, md5sum);
- if (dispatcher != null) {
- dispatcher.include(request, response);
- }
- }
- } catch (NoSuchAlgorithmException ex) {
- throw new ServletException(ex);
- }
- }
-
- protected String getEngineSessionId(final HttpServletRequest request) {
- return (String) request.getSession()
-
.getAttribute(SessionConstants.HTTP_SESSION_ENGINE_SESSION_ID_KEY);
- }
-
- /**
- * Retrieves the application type from the request object, this can return
null if the
- * attribute containing the application type is empty.
- * @param request The {@code HttpServletRequest} object.
- * @return A string containing the application type.
- */
- private String getApplicationTypeFromRequest(final HttpServletRequest
request) {
- return (String) request.getAttribute(BrandingFilter.APPLICATION_NAME);
}
@Override
- protected void doPost(final HttpServletRequest req, final
HttpServletResponse resp) throws ServletException,
- IOException {
+ protected final void doPost(HttpServletRequest req, HttpServletResponse
resp) throws ServletException, IOException {
doGet(req, resp);
}
@@ -177,97 +122,42 @@
protected abstract String getSelectorScriptName();
/**
- * Get the user locale from the request. The {@code LocaleFilter} should
have populated the value.
- * @param request {@code ServletRequest} that contains the locale used to
look up the messages.
- * @return The {@code Locale} from the request. if not found defaults to
Locale.US
- */
- private Locale getLocaleFromRequest(final ServletRequest request) {
- Locale locale = (Locale) request.getAttribute(LocaleFilter.LOCALE);
//$NON-NLS-1$
- if (locale == null) {
- // If no locale defined, default back to the default.
- locale = LocaleFilter.DEFAULT_LOCALE;
- }
- return locale;
- }
-
- /**
- * Create a Javascript value object with the value being the passed in
value.
- * @param value The {@code String} value to use as the value of the object.
- * @return A String representation of the Javascript object.
- */
- private String getValueObject(final String value) {
- ObjectNode node = mapper.createObjectNode();
- node.put("value", value); //$NON-NLS-1$
- return node.toString();
- }
-
- /**
- * Get a JavaScript associative array string that define the branding
messages.
- * @param applicationName the application name.
- * @param locale {@code Locale} to use to look up the messages.
- * @return The messages as a {@code String}
- */
- private String getBrandingMessages(final String applicationName, final
Locale locale) {
- return brandingManager.getMessages(applicationName, locale);
- }
-
- /**
* @return {@code true} if all queries should be filtered according to
user permissions, {@code false} otherwise.
*/
protected abstract boolean filterQueries();
- protected void initQueryParams(VdcQueryParametersBase queryParams, String
sessionId) {
- queryParams.setSessionId(sessionId);
- queryParams.setHttpSessionId(sessionId);
- queryParams.setFiltered(filterQueries());
- }
+ protected void setHttpAttributes(HttpServletRequest request, String
engineSessionId) {
+ // Set selectorScript
+ request.setAttribute(MD5Attributes.ATTR_SELECTOR_SCRIPT.getKey(),
getSelectorScriptName());
- /**
- * Executes a backend {@linkplain BackendLocal#RunQuery query} and returns
its result value if successful.
- * <p>
- * Returns {@code null} otherwise.
- */
- protected Object runQuery(VdcQueryType queryType, VdcQueryParametersBase
queryParams, String sessionId) {
- initQueryParams(queryParams, sessionId);
- VdcQueryReturnValue result = backend.runQuery(queryType, queryParams);
- return result.getSucceeded() ? result.getReturnValue() : null;
- }
+ // Set userInfo and ssoToken
+ DbUser loggedInUser = getLoggedInUser(engineSessionId);
+ if (loggedInUser != null) {
+ request.setAttribute(MD5Attributes.ATTR_USER_INFO.getKey(),
getUserInfoObject(loggedInUser));
+ request.setAttribute(MD5Attributes.ATTR_SSO_TOKEN.getKey(),
getValueObject(engineSessionId));
+ }
- /**
- * Executes a backend {@linkplain BackendLocal#RunPublicQuery public
query} and returns its result value if
- * successful.
- * <p>
- * Returns {@code null} otherwise.
- */
- protected Object runPublicQuery(VdcQueryType queryType,
VdcQueryParametersBase queryParams, String sessionId) {
- initQueryParams(queryParams, sessionId);
- VdcQueryReturnValue result = backend.runPublicQuery(queryType,
queryParams);
- return result.getSucceeded() ? result.getReturnValue() : null;
- }
+ // Set messages
+ request.setAttribute(MD5Attributes.ATTR_MESSAGES.getKey(),
+ getBrandingMessages(getApplicationTypeFromRequest(request),
getLocaleFromRequest(request)));
- protected ObjectNode createObjectNode() {
- return mapper.createObjectNode();
- }
+ // Set baseContextPath
+ request.setAttribute(MD5Attributes.ATTR_BASE_CONTEXT_PATH.getKey(),
+ getValueObject(getBaseContextPath(request)));
- protected ArrayNode createArrayNode() {
- return mapper.createArrayNode();
- }
+ // Set visibleLocales
+ request.setAttribute(MD5Attributes.ATTR_DISPLAY_LOCALES.getKey(),
+ getValueObject(getDisplayLocales()));
- protected DbUser getLoggedInUser(String sessionId) {
- return (DbUser) runQuery(VdcQueryType.GetUserBySessionId, new
VdcQueryParametersBase(), sessionId);
- }
+ // Set engineSessionTimeout
+ Integer engineSessionTimeout =
getEngineSessionTimeout(engineSessionId);
+
request.setAttribute(MD5Attributes.ATTR_ENGINE_SESSION_TIMEOUT.getKey(),
+ getValueObject(String.valueOf(engineSessionTimeout)));
- protected ObjectNode getUserInfoObject(DbUser loggedInUser) {
- ObjectNode obj = createObjectNode();
- obj.put("id", loggedInUser.getId().toString()); //$NON-NLS-1$
- obj.put("userName", loggedInUser.getLoginName()); //$NON-NLS-1$
- obj.put("domain", loggedInUser.getDomain()); //$NON-NLS-1$
- return obj;
- }
-
- protected String getMd5Sum(HttpServletRequest request) throws
NoSuchAlgorithmException,
- UnsupportedEncodingException {
- return (new
HexBinaryAdapter()).marshal(getMd5Digest(request).digest());
+ // Set engineRpmVersion
+ String engineRpmVersion = getEngineRpmVersion(engineSessionId);
+ request.setAttribute(MD5Attributes.ATTR_ENGINE_RPM_VERSION.getKey(),
+ getValueObject(engineRpmVersion));
}
/**
@@ -276,27 +166,145 @@
* determine by the {@code MD5Attributes} enum.
*
* @param request The {@code HttpServletRequest} to use as the source
- * of the attribute values.
+ * of the attribute values.
* @return A {@code MessageDigest} which will be used to generate the
* string representation of the MD5 sum.
* @throws NoSuchAlgorithmException If the method cannot create the digest
- * object.
- * @throws UnsupportedEncodingException
+ * object.
*/
- protected MessageDigest getMd5Digest(final HttpServletRequest request)
- throws NoSuchAlgorithmException, UnsupportedEncodingException {
+ protected MessageDigest getMd5Digest(HttpServletRequest request) throws
NoSuchAlgorithmException {
MessageDigest digest = createMd5Digest();
- for (MD5Attributes attribute: MD5Attributes.values()) {
+
+ for (MD5Attributes attribute : MD5Attributes.values()) {
if (request.getAttribute(attribute.getKey()) != null) {
- digest.update(request.getAttribute(attribute.getKey()).
- toString().getBytes(StandardCharsets.UTF_8));
+
digest.update(request.getAttribute(attribute.getKey()).toString().getBytes(StandardCharsets.UTF_8));
}
}
+
return digest;
}
- protected MessageDigest createMd5Digest() throws NoSuchAlgorithmException {
+ MessageDigest createMd5Digest() throws NoSuchAlgorithmException {
return MessageDigest.getInstance("MD5"); //$NON-NLS-1$
}
+ String getBaseContextPath(HttpServletRequest request) {
+ return ServletUtils.getBaseContextPath(request);
+ }
+
+ String getDisplayLocales() {
+ return
StringUtils.join(UnsupportedLocaleHelper.getDisplayedLocales(LocaleFilter.getLocaleKeys()),
","); //$NON-NLS-1$
+ }
+
+ String getMd5Sum(HttpServletRequest request) throws ServletException {
+ try {
+ return new
HexBinaryAdapter().marshal(getMd5Digest(request).digest());
+ } catch (Exception ex) {
+ throw new ServletException(ex);
+ }
+ }
+
+ String getEngineSessionId(HttpServletRequest request) {
+ return (String)
request.getSession().getAttribute(SessionConstants.HTTP_SESSION_ENGINE_SESSION_ID_KEY);
+ }
+
+ /**
+ * Retrieves the application type from the request object, this can return
null if the
+ * attribute containing the application type is empty.
+ *
+ * @param request The {@code HttpServletRequest} object.
+ * @return A string containing the application type.
+ */
+ String getApplicationTypeFromRequest(HttpServletRequest request) {
+ return (String) request.getAttribute(BrandingFilter.APPLICATION_NAME);
+ }
+
+ /**
+ * Get the user locale from the request. The {@code LocaleFilter} should
have populated the value.
+ *
+ * @param request {@code HttpServletRequest} that contains the locale used
to look up the messages.
+ * @return The {@code Locale} from the request. if not found defaults to
Locale.US
+ */
+ Locale getLocaleFromRequest(HttpServletRequest request) {
+ Locale locale = (Locale) request.getAttribute(LocaleFilter.LOCALE);
//$NON-NLS-1$
+ if (locale == null) {
+ // If no locale defined, default back to the default.
+ locale = LocaleFilter.DEFAULT_LOCALE;
+ }
+ return locale;
+ }
+
+ DbUser getLoggedInUser(String sessionId) {
+ return (DbUser) runQuery(VdcQueryType.GetUserBySessionId, new
VdcQueryParametersBase(), sessionId);
+ }
+
+ Integer getEngineSessionTimeout(String sessionId) {
+ return (Integer) runPublicQuery(VdcQueryType.GetConfigurationValue,
new GetConfigurationValueParameters(
+ ConfigurationValues.UserSessionTimeOutInterval,
ConfigCommon.defaultConfigurationVersion), sessionId);
+ }
+
+ String getEngineRpmVersion(String sessionId) {
+ return (String) runQuery(VdcQueryType.GetConfigurationValue, new
GetConfigurationValueParameters(
+ ConfigurationValues.ProductRPMVersion,
ConfigCommon.defaultConfigurationVersion), sessionId);
+ }
+
+ /**
+ * Create a Javascript value object with the value being the passed in
value.
+ *
+ * @param value The {@code String} value to use as the value of the object.
+ * @return A String representation of the Javascript object.
+ */
+ ObjectNode getValueObject(String value) {
+ ObjectNode node = mapper.createObjectNode();
+ node.put("value", value); //$NON-NLS-1$
+ return node;
+ }
+
+ ObjectNode getUserInfoObject(DbUser loggedInUser) {
+ ObjectNode obj = mapper.createObjectNode();
+ obj.put("id", loggedInUser.getId().toString()); //$NON-NLS-1$
+ obj.put("userName", loggedInUser.getLoginName()); //$NON-NLS-1$
+ obj.put("domain", loggedInUser.getDomain()); //$NON-NLS-1$
+ return obj;
+ }
+
+ /**
+ * Get a JavaScript associative array string that define the branding
messages.
+ *
+ * @param applicationName the application name.
+ * @param locale {@code Locale} to use to look up the messages.
+ * @return The messages as a {@code String}
+ */
+ String getBrandingMessages(String applicationName, Locale locale) {
+ return brandingManager.getMessages(applicationName, locale);
+ }
+
+ void initQueryParams(VdcQueryParametersBase queryParams, String sessionId)
{
+ queryParams.setSessionId(sessionId);
+ queryParams.setHttpSessionId(sessionId);
+ queryParams.setFiltered(filterQueries());
+ }
+
+ /**
+ * Executes a backend query and returns its result value if successful.
+ * <p/>
+ * Returns {@code null} otherwise.
+ */
+ Object runQuery(VdcQueryType queryType, VdcQueryParametersBase
queryParams, String sessionId) {
+ initQueryParams(queryParams, sessionId);
+ VdcQueryReturnValue result = backend.runQuery(queryType, queryParams);
+ return result.getSucceeded() ? result.getReturnValue() : null;
+ }
+
+ /**
+ * Executes a backend public query and returns its result value if
successful.
+ * <p/>
+ * Returns {@code null} otherwise.
+ */
+ Object runPublicQuery(VdcQueryType queryType, VdcQueryParametersBase
queryParams, String sessionId) {
+ initQueryParams(queryParams, sessionId);
+ VdcQueryReturnValue result = backend.runPublicQuery(queryType,
queryParams);
+ return result.getSucceeded() ? result.getReturnValue() : null;
+ }
+
}
diff --git
a/frontend/webadmin/modules/frontend/src/main/java/org/ovirt/engine/ui/frontend/server/gwt/UserPortalHostPageServlet.java
b/frontend/webadmin/modules/frontend/src/main/java/org/ovirt/engine/ui/frontend/server/gwt/UserPortalHostPageServlet.java
index db7eaaf..825bdbe 100644
---
a/frontend/webadmin/modules/frontend/src/main/java/org/ovirt/engine/ui/frontend/server/gwt/UserPortalHostPageServlet.java
+++
b/frontend/webadmin/modules/frontend/src/main/java/org/ovirt/engine/ui/frontend/server/gwt/UserPortalHostPageServlet.java
@@ -1,6 +1,5 @@
package org.ovirt.engine.ui.frontend.server.gwt;
-
/**
* UserPortal GWT application host page servlet.
*/
@@ -17,4 +16,5 @@
protected boolean filterQueries() {
return true;
}
+
}
diff --git
a/frontend/webadmin/modules/frontend/src/main/java/org/ovirt/engine/ui/frontend/server/gwt/WebAdminHostPageServlet.java
b/frontend/webadmin/modules/frontend/src/main/java/org/ovirt/engine/ui/frontend/server/gwt/WebAdminHostPageServlet.java
index 64d1834..fff27eb 100644
---
a/frontend/webadmin/modules/frontend/src/main/java/org/ovirt/engine/ui/frontend/server/gwt/WebAdminHostPageServlet.java
+++
b/frontend/webadmin/modules/frontend/src/main/java/org/ovirt/engine/ui/frontend/server/gwt/WebAdminHostPageServlet.java
@@ -1,7 +1,5 @@
package org.ovirt.engine.ui.frontend.server.gwt;
-import java.io.IOException;
-import java.io.UnsupportedEncodingException;
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
@@ -9,9 +7,7 @@
import java.util.Collections;
import java.util.List;
-import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
import org.codehaus.jackson.node.ArrayNode;
import org.codehaus.jackson.node.ObjectNode;
@@ -33,16 +29,15 @@
private static final long serialVersionUID = -6393009825835028397L;
- protected static final String ATTR_APPLICATION_MODE = "applicationMode";
//$NON-NLS-1$
- protected static final String ATTR_PLUGIN_DEFS = "pluginDefinitions";
//$NON-NLS-1$
- protected static final String ATTR_ENGINE_SESSION_TIMEOUT =
"engineSessionTimeout"; //$NON-NLS-1$
- protected static final String ATTR_ENGINE_REPORTS_DASHBOARD_URL =
"ENGINE_REPORTS_DASHBOARD_URL"; //$NON-NLS-1$
- protected static final String ATTR_ENGINE_REPORTS_RIGHTCLICK_URL =
"ENGINE_REPORTS_RIGHTCLICK_URL"; //$NON-NLS-1$
- protected static final String ATTR_ENGINE_REPORTS_BASE_URL =
"ENGINE_REPORTS_BASE_URL"; //$NON-NLS-1$
+ static final String ATTR_APPLICATION_MODE = "applicationMode";
//$NON-NLS-1$
+ static final String ATTR_PLUGIN_DEFS = "pluginDefinitions"; //$NON-NLS-1$
+ static final String ATTR_ENGINE_REPORTS_DASHBOARD_URL =
"ENGINE_REPORTS_DASHBOARD_URL"; //$NON-NLS-1$
+ static final String ATTR_ENGINE_REPORTS_RIGHTCLICK_URL =
"ENGINE_REPORTS_RIGHTCLICK_URL"; //$NON-NLS-1$
+ static final String ATTR_ENGINE_REPORTS_BASE_URL =
"ENGINE_REPORTS_BASE_URL"; //$NON-NLS-1$
- protected String reportRedirectUrl;
- protected String reportRightClickRedirectUrl;
- protected String reportBaseUrl;
+ private String reportRedirectUrl;
+ private String reportRightClickRedirectUrl;
+ private String reportBaseUrl;
@Override
protected String getSelectorScriptName() {
@@ -59,96 +54,82 @@
super.init();
reportRedirectUrl = EngineLocalConfig.getInstance().expandString(
-
makeEngineLocaleConfigParam(ATTR_ENGINE_REPORTS_DASHBOARD_URL));
+
makeEngineLocaleConfigParam(ATTR_ENGINE_REPORTS_DASHBOARD_URL));
reportRightClickRedirectUrl =
EngineLocalConfig.getInstance().expandString(
-
makeEngineLocaleConfigParam(ATTR_ENGINE_REPORTS_RIGHTCLICK_URL));
+
makeEngineLocaleConfigParam(ATTR_ENGINE_REPORTS_RIGHTCLICK_URL));
reportBaseUrl = EngineLocalConfig.getInstance().expandString(
makeEngineLocaleConfigParam(ATTR_ENGINE_REPORTS_BASE_URL));
-
}
- private String makeEngineLocaleConfigParam(String input) {
+ String makeEngineLocaleConfigParam(String input) {
return "${" + input + "}"; //$NON-NLS-1$ //$NON-NLS-2$
}
- @Override
- protected void doGet(HttpServletRequest request, HttpServletResponse
response) throws IOException,
- ServletException {
- // Set attribute for applicationMode object
- Integer applicationMode =
getApplicationMode(getEngineSessionId(request));
- request.setAttribute(ATTR_APPLICATION_MODE,
getApplicationModeObject(applicationMode));
+ String getReportUrl() {
+ return reportRedirectUrl.substring(reportBaseUrl.length());
+ }
- // Set attribute for pluginDefinitions array
+ String getRightClickUrl() {
+ return reportRightClickRedirectUrl.substring(reportBaseUrl.length());
+ }
+
+ @Override
+ protected void setHttpAttributes(HttpServletRequest request, String
engineSessionId) {
+ super.setHttpAttributes(request, engineSessionId);
+
+ // Set applicationMode
+ Integer applicationMode = getApplicationMode(engineSessionId);
+ request.setAttribute(ATTR_APPLICATION_MODE,
getValueObject(String.valueOf(applicationMode)));
+
+ // Set pluginDefinitions
List<PluginData> pluginData = getPluginData();
request.setAttribute(ATTR_PLUGIN_DEFS,
getPluginDefinitionsArray(pluginData));
- // Set attribute for engineSessionTimeout object
- Integer engineSessionTimeout =
getEngineSessionTimeout(getEngineSessionId(request));
- request.setAttribute(ATTR_ENGINE_SESSION_TIMEOUT,
getEngineSessionTimeoutObject(engineSessionTimeout));
-
- // Set attribute for engineReportsUrl object
- request.setAttribute(ATTR_ENGINE_REPORTS_BASE_URL,
-
getReportInit(reportRedirectUrl.substring(reportBaseUrl.length()),
-
reportRightClickRedirectUrl.substring(reportBaseUrl.length())));
-
- super.doGet(request, response);
- }
-
- /**
- * Generate Javascript {@code ObjectNode} based on the reportUrl and
rightClickUrl passed in
- * @param reportUrl The parameter part of the reporting URL.
- * @param rightClickUrl The parameter part of the right click URL.
- * @return A {@code ObjectNode} containing the URLs.
- */
- private ObjectNode getReportInit(String reportUrl, String rightClickUrl) {
- ObjectNode obj = createObjectNode();
- obj.put("reportUrl", reportUrl); //$NON-NLS-1$
- obj.put("rightClickUrl", rightClickUrl); //$NON-NLS-1$
- return obj;
+ // Set ENGINE_REPORTS_BASE_URL
+ request.setAttribute(ATTR_ENGINE_REPORTS_BASE_URL,
getReportInitObject(getReportUrl(), getRightClickUrl()));
}
@Override
- protected MessageDigest getMd5Digest(HttpServletRequest request) throws
NoSuchAlgorithmException,
- UnsupportedEncodingException {
+ protected MessageDigest getMd5Digest(HttpServletRequest request) throws
NoSuchAlgorithmException {
MessageDigest digest = super.getMd5Digest(request);
- // Update based on applicationMode object
-
digest.update(request.getAttribute(ATTR_APPLICATION_MODE).toString().getBytes(StandardCharsets.UTF_8));
+ // Update applicationMode
+ ObjectNode applicationModeObject = (ObjectNode)
request.getAttribute(ATTR_APPLICATION_MODE);
+ if (applicationModeObject != null) {
+
digest.update(applicationModeObject.toString().getBytes(StandardCharsets.UTF_8));
+ }
- // Update based on pluginDefinitions array
-
digest.update(request.getAttribute(ATTR_PLUGIN_DEFS).toString().getBytes(StandardCharsets.UTF_8));
+ // Update pluginDefinitions
+ ArrayNode pluginDefinitionsArray = (ArrayNode)
request.getAttribute(ATTR_PLUGIN_DEFS);
+ if (pluginDefinitionsArray != null) {
+
digest.update(pluginDefinitionsArray.toString().getBytes(StandardCharsets.UTF_8));
+ }
- // Update based on engineSessionTimeout object
-
digest.update(request.getAttribute(ATTR_ENGINE_SESSION_TIMEOUT).toString().getBytes(StandardCharsets.UTF_8));
+ // Update ENGINE_REPORTS_BASE_URL
+ ObjectNode reportInitObject = (ObjectNode)
request.getAttribute(ATTR_ENGINE_REPORTS_BASE_URL);
+ if (reportInitObject != null) {
+
digest.update(reportInitObject.toString().getBytes(StandardCharsets.UTF_8));
+ }
- // Update based on report URL parameters.
-
digest.update(request.getAttribute(ATTR_ENGINE_REPORTS_BASE_URL).toString().getBytes());
return digest;
}
- protected Integer getApplicationMode(String sessionId) {
+ Integer getApplicationMode(String sessionId) {
return (Integer) runPublicQuery(VdcQueryType.GetConfigurationValue,
new
GetConfigurationValueParameters(ConfigurationValues.ApplicationMode,
ConfigCommon.defaultConfigurationVersion), sessionId);
}
- protected ObjectNode getApplicationModeObject(Integer applicationMode) {
- ObjectNode obj = createObjectNode();
- obj.put("value", String.valueOf(applicationMode)); //$NON-NLS-1$
- return obj;
- }
-
- protected List<PluginData> getPluginData() {
- List<PluginData> currentData = new ArrayList<PluginData>(
- PluginDataManager.getInstance().reloadAndGetCurrentData());
+ List<PluginData> getPluginData() {
+ List<PluginData> currentData = new
ArrayList<>(PluginDataManager.getInstance().reloadAndGetCurrentData());
Collections.sort(currentData);
return currentData;
}
- protected ArrayNode getPluginDefinitionsArray(List<PluginData> pluginData)
{
- ArrayNode arr = createArrayNode();
+ ArrayNode getPluginDefinitionsArray(List<PluginData> pluginData) {
+ ArrayNode arr = mapper.createArrayNode();
for (PluginData data : pluginData) {
- ObjectNode dataObj = createObjectNode();
+ ObjectNode dataObj = mapper.createObjectNode();
dataObj.put("name", data.getName()); //$NON-NLS-1$
dataObj.put("url", data.getUrl()); //$NON-NLS-1$
dataObj.put("config", data.mergeConfiguration()); //$NON-NLS-1$
@@ -158,15 +139,16 @@
return arr;
}
- protected Integer getEngineSessionTimeout(String sessionId) {
- return (Integer) runPublicQuery(VdcQueryType.GetConfigurationValue,
- new
GetConfigurationValueParameters(ConfigurationValues.UserSessionTimeOutInterval,
- ConfigCommon.defaultConfigurationVersion), sessionId);
- }
-
- protected ObjectNode getEngineSessionTimeoutObject(Integer
engineSessionTimeout) {
- ObjectNode obj = createObjectNode();
- obj.put("value", String.valueOf(engineSessionTimeout)); //$NON-NLS-1$
+ /**
+ * Generate Javascript {@code ObjectNode} based on the reportUrl and
rightClickUrl passed in
+ * @param reportUrl The parameter part of the reporting URL.
+ * @param rightClickUrl The parameter part of the right click URL.
+ * @return A {@code ObjectNode} containing the URLs.
+ */
+ ObjectNode getReportInitObject(String reportUrl, String rightClickUrl) {
+ ObjectNode obj = mapper.createObjectNode();
+ obj.put("reportUrl", reportUrl); //$NON-NLS-1$
+ obj.put("rightClickUrl", rightClickUrl); //$NON-NLS-1$
return obj;
}
diff --git
a/frontend/webadmin/modules/frontend/src/main/resources/META-INF/resources/GwtHostPage.jsp
b/frontend/webadmin/modules/frontend/src/main/resources/META-INF/resources/GwtHostPage.jsp
index 232e49f..d43af9d 100644
---
a/frontend/webadmin/modules/frontend/src/main/resources/META-INF/resources/GwtHostPage.jsp
+++
b/frontend/webadmin/modules/frontend/src/main/resources/META-INF/resources/GwtHostPage.jsp
@@ -13,28 +13,35 @@
<script type="text/javascript">
<c:if test="${requestScope['userInfo'] != null}">
var userInfo = <c:out value="${requestScope['userInfo']}"
escapeXml="false"/>;
+ </c:if>
+ <c:if test="${requestScope['ssoToken'] != null}">
var ssoToken = <c:out value="${requestScope['ssoToken']}"
escapeXml="false"/>;
</c:if>
+ <c:if test="${requestScope['messages'] != null}">
+ var messages = <c:out value="${requestScope['messages']}"
escapeXml="false"/>;
+ </c:if>
+ <c:if test="${requestScope['baseContextPath'] != null}">
+ var baseContextPath = <c:out
value="${requestScope['baseContextPath']}" escapeXml="false"/>;
+ </c:if>
+ <c:if test="${requestScope['visibleLocales'] != null}">
+ var visibleLocales = <c:out
value="${requestScope['visibleLocales']}" escapeXml="false"/>;
+ </c:if>
+ <c:if test="${requestScope['engineSessionTimeout'] != null}">
+ var engineSessionTimeout = <c:out
value="${requestScope['engineSessionTimeout']}" escapeXml="false"/>;
+ </c:if>
+ <c:if test="${requestScope['engineRpmVersion'] != null}">
+ var engineRpmVersion = <c:out
value="${requestScope['engineRpmVersion']}" escapeXml="false"/>;
+ </c:if>
+
+ // WebAdmin specific variables
<c:if test="${requestScope['applicationMode'] != null}">
var applicationMode = <c:out
value="${requestScope['applicationMode']}" escapeXml="false"/>;
</c:if>
<c:if test="${requestScope['pluginDefinitions'] != null}">
var pluginDefinitions = <c:out
value="${requestScope['pluginDefinitions']}" escapeXml="false"/>;
</c:if>
- <c:if test="${requestScope['engineSessionTimeout'] != null}">
- var engineSessionTimeout = <c:out
value="${requestScope['engineSessionTimeout']}" escapeXml="false"/>;
- </c:if>
- <c:if test="${requestScope['messages'] != null}">
- var messages = <c:out value="${requestScope['messages']}"
escapeXml="false"/>;
- </c:if>
- <c:if test="${requestScope['visibleLocales'] != null}">
- var visibleLocales = <c:out
value="${requestScope['visibleLocales']}" escapeXml="false"/>;
- </c:if>
- <c:if test="${requestScope['baseContextPath'] != null}">
- var baseContextPath = <c:out
value="${requestScope['baseContextPath']}" escapeXml="false"/>;
- </c:if>
<c:if test="${requestScope['ENGINE_REPORTS_BASE_URL'] != null}">
- var engineReportsUrls = <c:out
value="${requestScope['ENGINE_REPORTS_BASE_URL']}" escapeXml="false"/>;
+ var engineReportsUrls = <c:out
value="${requestScope['ENGINE_REPORTS_BASE_URL']}" escapeXml="false"/>;
</c:if>
</script>
</head>
diff --git
a/frontend/webadmin/modules/frontend/src/test/java/org/ovirt/engine/ui/frontend/server/gwt/AbstractGwtDynamicHostPageServletTest.java
b/frontend/webadmin/modules/frontend/src/test/java/org/ovirt/engine/ui/frontend/server/gwt/AbstractGwtDynamicHostPageServletTest.java
index a9ddff4..32181a6 100644
---
a/frontend/webadmin/modules/frontend/src/test/java/org/ovirt/engine/ui/frontend/server/gwt/AbstractGwtDynamicHostPageServletTest.java
+++
b/frontend/webadmin/modules/frontend/src/test/java/org/ovirt/engine/ui/frontend/server/gwt/AbstractGwtDynamicHostPageServletTest.java
@@ -1,53 +1,61 @@
package org.ovirt.engine.ui.frontend.server.gwt;
-import static org.hamcrest.CoreMatchers.instanceOf;
-import static org.hamcrest.CoreMatchers.is;
-import static org.junit.Assert.assertArrayEquals;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
+import static org.hamcrest.CoreMatchers.equalTo;
import static org.junit.Assert.assertThat;
import static org.mockito.Matchers.any;
-import static org.mockito.Matchers.anyString;
+import static org.mockito.Matchers.argThat;
import static org.mockito.Matchers.eq;
-import static org.mockito.Matchers.isA;
-import static org.mockito.Mockito.atLeast;
import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
-import java.io.IOException;
-import java.io.UnsupportedEncodingException;
+import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
-import java.security.NoSuchAlgorithmException;
-import java.util.ArrayList;
+import java.util.Locale;
+import javax.servlet.RequestDispatcher;
import javax.servlet.ServletContext;
-import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import org.codehaus.jackson.map.ObjectMapper;
+import org.codehaus.jackson.node.ArrayNode;
import org.codehaus.jackson.node.ObjectNode;
+import org.hamcrest.BaseMatcher;
+import org.hamcrest.Description;
+import org.hamcrest.Matcher;
import org.junit.Before;
import org.junit.Test;
-import org.mockito.ArgumentCaptor;
-import org.mockito.Captor;
import org.mockito.Mock;
+import org.mockito.invocation.InvocationOnMock;
+import org.mockito.stubbing.Answer;
+import org.ovirt.engine.core.branding.BrandingFilter;
import org.ovirt.engine.core.branding.BrandingManager;
-import org.ovirt.engine.core.branding.BrandingTheme;
import org.ovirt.engine.core.common.businessentities.aaa.DbUser;
-import org.ovirt.engine.core.common.interfaces.BackendLocal;
-import org.ovirt.engine.core.common.queries.GetConfigurationValueParameters;
-import org.ovirt.engine.core.common.queries.VdcQueryParametersBase;
-import org.ovirt.engine.core.common.queries.VdcQueryReturnValue;
-import org.ovirt.engine.core.common.queries.VdcQueryType;
+import org.ovirt.engine.core.common.constants.SessionConstants;
import org.ovirt.engine.core.compat.Guid;
+import org.ovirt.engine.core.utils.servlet.LocaleFilter;
+import
org.ovirt.engine.ui.frontend.server.gwt.GwtDynamicHostPageServlet.MD5Attributes;
public abstract class AbstractGwtDynamicHostPageServletTest<T extends
GwtDynamicHostPageServlet> {
- protected static final String SELECTOR_SCRIPT = "myapp.nocache.js";
//$NON-NLS-1$
+ protected static final String SELECTOR_SCRIPT_NAME = "myapp.nocache.js";
//$NON-NLS-1$
+ protected static final String APPLICATION_NAME = "MyApp"; //$NON-NLS-1$
+ protected static final String BRANDING_MESSAGES = "{\"msgKey\":
\"msgValue\"}"; //$NON-NLS-1$
+ protected static final String BASE_CONTEXT_PATH = "/myapp"; //$NON-NLS-1$
+ protected static final String DISPLAY_LOCALES = "en,jp"; //$NON-NLS-1$
+ protected static final String MD5_SUM = "test_md5_sum"; //$NON-NLS-1$
+
+ protected static final String ENGINE_SESSION_ID = "engine_session_id";
//$NON-NLS-1$
+ protected static final Integer ENGINE_SESSION_TIMEOUT = 60;
+ protected static final String ENGINE_RPM_VERSION = "x.y.z"; //$NON-NLS-1$
+
+ protected static final String USER_LOGIN_NAME = "admin"; //$NON-NLS-1$
+ protected static final String USER_DOMAIN = "internal"; //$NON-NLS-1$
+ protected static final Guid USER_GUID = Guid.newGuid();
@Mock
protected HttpServletRequest mockRequest;
@@ -56,194 +64,322 @@
protected HttpServletResponse mockResponse;
@Mock
- private HttpSession mockSession;
+ protected HttpSession mockSession;
@Mock
- private BackendLocal mockBackend;
+ protected ServletContext mockServletContext;
@Mock
- private BrandingManager mockBrandingManager;
+ protected RequestDispatcher mockRequestDispatcher;
@Mock
- private ServletContext mockServletContext;
+ protected BrandingManager mockBrandingManager;
@Mock
- private DbUser mockUser;
+ protected ObjectMapper mockObjectMapper;
@Mock
- private VdcQueryParametersBase mockQueryParams;
-
- @Mock
- private GetConfigurationValueParameters mockConfigQueryParams;
+ protected DbUser mockUser;
@Mock
protected MessageDigest mockDigest;
- @Mock
- private ObjectNode mockUserInfoObject;
-
- @Captor
- protected ArgumentCaptor<byte[]> byteArrayCaptor;
+ protected final ObjectMapper realObjectMapper = new ObjectMapper();
protected T testServlet;
@Before
- public void setUp() throws NoSuchAlgorithmException {
- when(mockRequest.getAttribute(GwtDynamicHostPageServlet.
- MD5Attributes.ATTR_SELECTOR_SCRIPT.getKey())).
- thenReturn(SELECTOR_SCRIPT);
+ public void setUp() throws Exception {
when(mockRequest.getSession()).thenReturn(mockSession);
-
when(mockRequest.getSession().getServletContext()).thenReturn(mockServletContext);
- when(mockSession.getId()).thenReturn("sessionId"); //$NON-NLS-1$
- when(mockUser.getId()).thenReturn(Guid.newGuid());
- when(mockUser.getLoginName()).thenReturn("admin"); //$NON-NLS-1$
- when(mockUser.getDomain()).thenReturn("internal"); //$NON-NLS-1$
- when(mockBrandingManager.getBrandingThemes()).thenReturn(new
ArrayList<BrandingTheme>()); //$NON-NLS-1$
- stubGetUserBySessionIdQuery();
- stubGetConfigurationValuePublicQuery();
- setUpTestServlet();
- }
+
when(mockRequest.getAttribute(BrandingFilter.APPLICATION_NAME)).thenReturn(APPLICATION_NAME);
+
when(mockRequest.getRequestDispatcher(GwtDynamicHostPageServlet.HOST_JSP))
+ .thenReturn(mockRequestDispatcher);
- protected void setUpTestServlet() throws NoSuchAlgorithmException {
+ when(mockSession.getServletContext()).thenReturn(mockServletContext);
+
when(mockSession.getAttribute(SessionConstants.HTTP_SESSION_ENGINE_SESSION_ID_KEY))
+ .thenReturn(ENGINE_SESSION_ID);
+
+ when(mockBrandingManager.getMessages(eq(APPLICATION_NAME),
any(Locale.class)))
+ .thenReturn(BRANDING_MESSAGES);
+
+ when(mockUser.getId()).thenReturn(USER_GUID);
+ when(mockUser.getLoginName()).thenReturn(USER_LOGIN_NAME);
+ when(mockUser.getDomain()).thenReturn(USER_DOMAIN);
+
+ // Ensure that mockObjectMapper delegates to realObjectMapper when
calling given methods.
+ when(mockObjectMapper.createObjectNode()).thenAnswer(new
Answer<ObjectNode>() {
+ @Override
+ public ObjectNode answer(InvocationOnMock invocation) throws
Throwable {
+ return realObjectMapper.createObjectNode();
+ }
+ });
+ when(mockObjectMapper.createArrayNode()).thenAnswer(new
Answer<ArrayNode>() {
+ @Override
+ public ArrayNode answer(InvocationOnMock invocation) throws
Throwable {
+ return realObjectMapper.createArrayNode();
+ }
+ });
+
testServlet = getTestServletSpy();
- testServlet.setBackend(mockBackend);
- testServlet.init(new ObjectMapper(), mockBrandingManager);
+ testServlet.init(mockObjectMapper, mockBrandingManager);
+
+ // Instead of mocking Engine BackendLocal API directly, we just adapt
methods that rely on it.
+ // This way, we avoid complex stubbing that would essentially have the
same effect in practice.
+
doReturn(mockUser).when(testServlet).getLoggedInUser(ENGINE_SESSION_ID);
+
doReturn(ENGINE_SESSION_TIMEOUT).when(testServlet).getEngineSessionTimeout(ENGINE_SESSION_ID);
+
doReturn(ENGINE_RPM_VERSION).when(testServlet).getEngineRpmVersion(ENGINE_SESSION_ID);
+
+ // Adapt tested methods that rely on static method calls (instead of
mocking static methods).
+
doReturn(BASE_CONTEXT_PATH).when(testServlet).getBaseContextPath(mockRequest);
+ doReturn(DISPLAY_LOCALES).when(testServlet).getDisplayLocales();
doReturn(mockDigest).when(testServlet).createMd5Digest();
+ doReturn(MD5_SUM).when(testServlet).getMd5Sum(mockRequest);
+
+ extraSetUp();
}
+ protected void extraSetUp() {
+ // No-op, override as necessary
+ }
+
+ /**
+ * @return {@link org.mockito.Mockito#spy Spy} of the tested servlet
instance for adapting specific methods.
+ */
protected abstract T getTestServletSpy();
+ /**
+ * Verify that all relevant HttpRequest attributes are set.
+ */
@Test
- public void testDoGet_WithoutUserInfoObject() throws IOException,
ServletException, NoSuchAlgorithmException {
- doReturn(null).when(testServlet).getLoggedInUser(anyString());
-
doReturn(mockDigest).when(testServlet).getMd5Digest(any(HttpServletRequest.class));
- testServlet.doGet(mockRequest, mockResponse);
-
verify(mockRequest).setAttribute(eq(GwtDynamicHostPageServlet.MD5Attributes.ATTR_SELECTOR_SCRIPT.getKey()),
- anyString());
- verify(mockRequest,
never()).setAttribute(eq(GwtDynamicHostPageServlet.MD5Attributes.ATTR_USER_INFO.getKey()),
- any(ObjectNode.class));
-
verify(mockRequest).setAttribute(GwtDynamicHostPageServlet.MD5Attributes.ATTR_MESSAGES.getKey(),
- null); //$NON-NLS-1$
+ public void setHttpAttributes() {
+
doReturn(SELECTOR_SCRIPT_NAME).when(testServlet).getSelectorScriptName();
+
+ testServlet.setHttpAttributes(mockRequest, ENGINE_SESSION_ID);
+
+
verify(mockRequest).setAttribute(eq(MD5Attributes.ATTR_SELECTOR_SCRIPT.getKey()),
+ eq(SELECTOR_SCRIPT_NAME));
+
verify(mockRequest).setAttribute(eq(MD5Attributes.ATTR_USER_INFO.getKey()),
+ argThat(getUserInfoObjectMatcher(USER_GUID.toString(),
USER_LOGIN_NAME, USER_DOMAIN)));
+
verify(mockRequest).setAttribute(eq(MD5Attributes.ATTR_SSO_TOKEN.getKey()),
+ argThat(getValueObjectMatcher(ENGINE_SESSION_ID)));
+
verify(mockRequest).setAttribute(eq(MD5Attributes.ATTR_MESSAGES.getKey()),
+ eq(BRANDING_MESSAGES));
+
verify(mockRequest).setAttribute(eq(MD5Attributes.ATTR_BASE_CONTEXT_PATH.getKey()),
+ argThat(getValueObjectMatcher(BASE_CONTEXT_PATH)));
+
verify(mockRequest).setAttribute(eq(MD5Attributes.ATTR_DISPLAY_LOCALES.getKey()),
+ argThat(getValueObjectMatcher(DISPLAY_LOCALES)));
+
verify(mockRequest).setAttribute(eq(MD5Attributes.ATTR_ENGINE_SESSION_TIMEOUT.getKey()),
+
argThat(getValueObjectMatcher(String.valueOf(ENGINE_SESSION_TIMEOUT))));
+
verify(mockRequest).setAttribute(eq(MD5Attributes.ATTR_ENGINE_RPM_VERSION.getKey()),
+ argThat(getValueObjectMatcher(ENGINE_RPM_VERSION)));
}
+ /**
+ * Verify that userInfo and ssoToken attributes are not set when the user
isn't logged in.
+ */
@Test
- public void testDoGet_WithUserInfoObject() throws IOException,
ServletException, NoSuchAlgorithmException {
- String userInfo = "{ \"foo\": \"bar\" }"; //$NON-NLS-1$
- when(mockUserInfoObject.toString()).thenReturn(userInfo);
-
when(mockRequest.getAttribute(GwtDynamicHostPageServlet.MD5Attributes.ATTR_USER_INFO.getKey())).
- thenReturn(mockUserInfoObject);
-
doReturn(mockDigest).when(testServlet).getMd5Digest(any(HttpServletRequest.class));
- testServlet.doGet(mockRequest, mockResponse);
-
verify(mockRequest).setAttribute(eq(GwtDynamicHostPageServlet.MD5Attributes.ATTR_SELECTOR_SCRIPT.getKey()),
- anyString());
-
verify(mockRequest).setAttribute(eq(GwtDynamicHostPageServlet.MD5Attributes.ATTR_USER_INFO.getKey()),
+ public void setHttpAttributes_withoutLoggedInUser() {
+ doReturn(null).when(testServlet).getLoggedInUser(ENGINE_SESSION_ID);
+
+ testServlet.setHttpAttributes(mockRequest, ENGINE_SESSION_ID);
+
+ verify(mockRequest,
never()).setAttribute(eq(MD5Attributes.ATTR_USER_INFO.getKey()),
any(ObjectNode.class));
-
verify(mockRequest).setAttribute(GwtDynamicHostPageServlet.MD5Attributes.ATTR_MESSAGES.getKey(),
- null); //$NON-NLS-1$
+ verify(mockRequest,
never()).setAttribute(eq(MD5Attributes.ATTR_SSO_TOKEN.getKey()),
+ any(ObjectNode.class));
}
+ /**
+ * Verify that MD5 digest is produced from relevant HttpRequest attributes.
+ */
@Test
- public void testDoGet_CalculateMd5_ResourceNotModifiedResponse() throws
IOException, ServletException,
- NoSuchAlgorithmException {
- String md5sum = "md5sum"; //$NON-NLS-1$
- doReturn(md5sum).when(testServlet).getMd5Sum(mockRequest);
-
when(mockRequest.getHeader(GwtDynamicHostPageServlet.IF_NONE_MATCH_HEADER)).thenReturn(md5sum);
+ public void getMd5Digest() throws Exception {
+ ObjectNode mockUserInfoObject = mock(ObjectNode.class);
+ ObjectNode mockSsoTokenObject = mock(ObjectNode.class);
+ ObjectNode mockBaseContextPathObject = mock(ObjectNode.class);
+ ObjectNode mockDisplayLocalesObject = mock(ObjectNode.class);
+ ObjectNode mockEngineSessionTimeoutObject = mock(ObjectNode.class);
+ ObjectNode mockEngineRpmVersionObject = mock(ObjectNode.class);
+
+
when(mockRequest.getAttribute(MD5Attributes.ATTR_SELECTOR_SCRIPT.getKey()))
+ .thenReturn(SELECTOR_SCRIPT_NAME);
+ when(mockRequest.getAttribute(MD5Attributes.ATTR_USER_INFO.getKey()))
+ .thenReturn(mockUserInfoObject);
+ when(mockRequest.getAttribute(MD5Attributes.ATTR_SSO_TOKEN.getKey()))
+ .thenReturn(mockSsoTokenObject);
+ when(mockRequest.getAttribute(MD5Attributes.ATTR_MESSAGES.getKey()))
+ .thenReturn(BRANDING_MESSAGES);
+
when(mockRequest.getAttribute(MD5Attributes.ATTR_BASE_CONTEXT_PATH.getKey()))
+ .thenReturn(mockBaseContextPathObject);
+
when(mockRequest.getAttribute(MD5Attributes.ATTR_DISPLAY_LOCALES.getKey()))
+ .thenReturn(mockDisplayLocalesObject);
+
when(mockRequest.getAttribute(MD5Attributes.ATTR_ENGINE_SESSION_TIMEOUT.getKey()))
+ .thenReturn(mockEngineSessionTimeoutObject);
+
when(mockRequest.getAttribute(MD5Attributes.ATTR_ENGINE_RPM_VERSION.getKey()))
+ .thenReturn(mockEngineRpmVersionObject);
+
+ MessageDigest result = testServlet.getMd5Digest(mockRequest);
+ assertThat(result, equalTo(mockDigest));
+
+
verify(mockDigest).update(SELECTOR_SCRIPT_NAME.getBytes(StandardCharsets.UTF_8));
+
verify(mockDigest).update(mockUserInfoObject.toString().getBytes(StandardCharsets.UTF_8));
+
verify(mockDigest).update(mockSsoTokenObject.toString().getBytes(StandardCharsets.UTF_8));
+
verify(mockDigest).update(BRANDING_MESSAGES.getBytes(StandardCharsets.UTF_8));
+
verify(mockDigest).update(mockBaseContextPathObject.toString().getBytes(StandardCharsets.UTF_8));
+
verify(mockDigest).update(mockDisplayLocalesObject.toString().getBytes(StandardCharsets.UTF_8));
+
verify(mockDigest).update(mockEngineSessionTimeoutObject.toString().getBytes(StandardCharsets.UTF_8));
+
verify(mockDigest).update(mockEngineRpmVersionObject.toString().getBytes(StandardCharsets.UTF_8));
+ }
+
+ /**
+ * Verify that MD5 digest will skip missing HttpRequest attributes.
+ */
+ @Test
+ public void getMd5Digest_missingRequestAttributes() throws Exception {
+ testServlet.getMd5Digest(mockRequest);
+
+ verify(mockDigest,
never()).update(SELECTOR_SCRIPT_NAME.getBytes(StandardCharsets.UTF_8));
+ }
+
+ protected Matcher<ObjectNode> getValueObjectMatcher(final String
expectedValue) {
+ return new BaseMatcher<ObjectNode>() {
+ @Override
+ public boolean matches(Object item) {
+ String actualValue = ((ObjectNode)
item).get("value").asText(); //$NON-NLS-1$
+ return expectedValue.equals(actualValue);
+ }
+
+ @Override
+ public void describeTo(Description description) {
+ description.appendText(String.format("{value: %s}",
expectedValue)); //$NON-NLS-1$
+ }
+ };
+ }
+
+ Matcher<ObjectNode> getUserInfoObjectMatcher(final String id, final String
userName, final String domain) {
+ return new BaseMatcher<ObjectNode>() {
+ @Override
+ public boolean matches(Object item) {
+ ObjectNode userInfoObject = (ObjectNode) item;
+ return id.equals(userInfoObject.get("id").asText())
//$NON-NLS-1$
+ &&
userName.equals(userInfoObject.get("userName").asText()) //$NON-NLS-1$
+ &&
domain.equals(userInfoObject.get("domain").asText()); //$NON-NLS-1$
+ }
+
+ @Override
+ public void describeTo(Description description) {
+ description.appendText(String.format("{id: %s, userName: %s,
domain: %s}", id, userName, domain)); //$NON-NLS-1$
+ }
+ };
+ }
+
+ /**
+ * Verify that HttpResponse is not altered when the client doesn't send
"If-None-Match" header.
+ */
+ @Test
+ public void doGet_withoutChecksumHeader() throws Exception {
testServlet.doGet(mockRequest, mockResponse);
+
+ verify(mockResponse).addHeader(GwtDynamicHostPageServlet.ETAG_HEADER,
MD5_SUM);
+ verify(mockRequestDispatcher).include(mockRequest, mockResponse);
+ }
+
+ /**
+ * Verify that HttpResponse is altered when the client sends
"If-None-Match" header (matching value).
+ */
+ @Test
+ public void doGet_withMatchingChecksumHeader() throws Exception {
+
when(mockRequest.getHeader(GwtDynamicHostPageServlet.IF_NONE_MATCH_HEADER)).thenReturn(MD5_SUM);
+
+ testServlet.doGet(mockRequest, mockResponse);
+
verify(mockResponse).setStatus(HttpServletResponse.SC_NOT_MODIFIED);
}
+ /**
+ * Verify that HttpResponse is altered when the client sends
"If-None-Match" header (non-matching value).
+ */
@Test
- public void testDoGet_CalculateMd5_ResourceModifiedEtagResponse() throws
IOException, ServletException,
- NoSuchAlgorithmException {
- String md5sum = "md5sum"; //$NON-NLS-1$
- doReturn(md5sum).when(testServlet).getMd5Sum(mockRequest);
-
when(mockRequest.getHeader(GwtDynamicHostPageServlet.IF_NONE_MATCH_HEADER)).thenReturn(null);
+ public void doGet_withNonMatchingChecksumHeader() throws Exception {
+
when(mockRequest.getHeader(GwtDynamicHostPageServlet.IF_NONE_MATCH_HEADER)).thenReturn(MD5_SUM
+ "x"); //$NON-NLS-1$
+
testServlet.doGet(mockRequest, mockResponse);
- verify(mockResponse).addHeader(GwtDynamicHostPageServlet.ETAG_HEADER,
md5sum);
+
+ verify(mockResponse).addHeader(GwtDynamicHostPageServlet.ETAG_HEADER,
MD5_SUM);
+ verify(mockRequestDispatcher).include(mockRequest, mockResponse);
}
+ /**
+ * Verify that Engine session ID is retrieved from HttpSession.
+ */
@Test
- public void testInitQueryParams() {
- String sessionId = "sessionId"; //$NON-NLS-1$
- testServlet.initQueryParams(mockQueryParams, sessionId);
- verify(mockQueryParams).setSessionId(sessionId);
- verify(mockQueryParams).setHttpSessionId(sessionId);
- verify(mockQueryParams).setFiltered(testServlet.filterQueries());
+ public void getEngineSessionId() {
+ String result = testServlet.getEngineSessionId(mockRequest);
+ assertThat(result, equalTo(ENGINE_SESSION_ID));
+
+
verify(mockSession).getAttribute(SessionConstants.HTTP_SESSION_ENGINE_SESSION_ID_KEY);
}
+ /**
+ * Verify that application type is retrieved from HttpRequest.
+ */
@Test
- public void testRunQuery_GetUserBySessionId() {
- String sessionId = "sessionId"; //$NON-NLS-1$
- VdcQueryType queryType = VdcQueryType.GetUserBySessionId;
- Object result = testServlet.runQuery(queryType, mockQueryParams,
sessionId);
- assertEquals(result, mockUser);
- verify(mockQueryParams).setSessionId(sessionId);
- verify(mockQueryParams).setHttpSessionId(sessionId);
- verify(mockQueryParams).setFiltered(testServlet.filterQueries());
- verify(mockBackend).runQuery(queryType, mockQueryParams);
+ public void getApplicationTypeFromRequest() {
+ String result = testServlet.getApplicationTypeFromRequest(mockRequest);
+ assertThat(result, equalTo(APPLICATION_NAME));
+
+ verify(mockRequest).getAttribute(BrandingFilter.APPLICATION_NAME);
}
+ /**
+ * Verify that locale is retrieved from HttpRequest if present.
+ */
@Test
- public void testRunPublicQuery_GetConfigurationValue() {
- String sessionId = "sessionId"; //$NON-NLS-1$
- VdcQueryType queryType = VdcQueryType.GetConfigurationValue;
- VdcQueryReturnValue returnIntValue = new VdcQueryReturnValue();
- returnIntValue.setSucceeded(true);
- returnIntValue.setReturnValue(Integer.valueOf(255));
- when(mockBackend.runPublicQuery(eq(VdcQueryType.GetConfigurationValue),
- eq(mockConfigQueryParams))).thenReturn(returnIntValue);
- Object result = testServlet.runPublicQuery(queryType,
mockConfigQueryParams, sessionId);
- assertThat(result, is(instanceOf(Integer.class)));
- verify(mockConfigQueryParams).setSessionId(sessionId);
- verify(mockConfigQueryParams).setHttpSessionId(sessionId);
- verify(mockConfigQueryParams).setFiltered(testServlet.filterQueries());
- verify(mockBackend).runPublicQuery(queryType, mockConfigQueryParams);
+ public void getLocaleFromRequest_requestWithLocale() {
+
when(mockRequest.getAttribute(LocaleFilter.LOCALE)).thenReturn(Locale.JAPANESE);
+
+ Locale result = testServlet.getLocaleFromRequest(mockRequest);
+ assertThat(result, equalTo(Locale.JAPANESE));
+
+ verify(mockRequest).getAttribute(LocaleFilter.LOCALE);
}
+ /**
+ * Verify that default locale is used when missing in HttpRequest.
+ */
@Test
- public void testGetUserInfoObject() {
+ public void getLocaleFromRequest_requestWithoutLocale() {
+ Locale result = testServlet.getLocaleFromRequest(mockRequest);
+ assertThat(result, equalTo(LocaleFilter.DEFAULT_LOCALE));
+ }
+
+ /**
+ * Verify that object node with "value" property is returned.
+ */
+ @Test
+ public void getValueObject() {
+ ObjectNode result = testServlet.getValueObject("foo"); //$NON-NLS-1$
+ assertThat(result.get("value").asText(), equalTo("foo"));
//$NON-NLS-1$ //$NON-NLS-2$
+ }
+
+ /**
+ * Verify that object node with user information is returned.
+ */
+ @Test
+ public void getUserInfoObject() {
ObjectNode result = testServlet.getUserInfoObject(mockUser);
- assertNotNull(result.get("id")); //$NON-NLS-1$
- assertEquals(result.get("userName").asText(), "admin"); //$NON-NLS-1$
//$NON-NLS-2$
- assertEquals(result.get("domain").asText(), "internal"); //$NON-NLS-1$
//$NON-NLS-2$
+ assertThat(result, getUserInfoObjectMatcher(USER_GUID.toString(),
USER_LOGIN_NAME, USER_DOMAIN));
}
+ /**
+ * Verify that branding messages are retrieved from BrandingManager.
+ */
@Test
- public void testGetMd5Digest_WithoutUserInfoObject() throws
NoSuchAlgorithmException, UnsupportedEncodingException {
- MessageDigest result = testServlet.getMd5Digest(mockRequest);
- assertEquals(result, mockDigest);
- verify(mockDigest, atLeast(1)).update(byteArrayCaptor.capture());
- assertArrayEquals(SELECTOR_SCRIPT.getBytes(),
byteArrayCaptor.getAllValues().get(0));
- }
+ public void getBrandingMessages() {
+ String result = testServlet.getBrandingMessages(APPLICATION_NAME,
Locale.JAPANESE);
+ assertThat(result, equalTo(BRANDING_MESSAGES));
- @Test
- public void testGetMd5Digest_WithUserInfoObject() throws
NoSuchAlgorithmException, UnsupportedEncodingException {
- String userInfo = "{ \"foo\": \"bar\" }"; //$NON-NLS-1$
- when(mockUserInfoObject.toString()).thenReturn(userInfo);
- when(mockRequest.getAttribute(GwtDynamicHostPageServlet.
- MD5Attributes.ATTR_USER_INFO.getKey())).
- thenReturn(mockUserInfoObject);
- MessageDigest result = testServlet.getMd5Digest(mockRequest);
- assertEquals(result, mockDigest);
- verify(mockDigest, atLeast(2)).update(byteArrayCaptor.capture());
- assertArrayEquals(SELECTOR_SCRIPT.getBytes(),
byteArrayCaptor.getAllValues().get(0));
- assertArrayEquals(userInfo.getBytes(),
byteArrayCaptor.getAllValues().get(1));
- }
-
- void stubGetUserBySessionIdQuery() {
- VdcQueryReturnValue returnValue = new VdcQueryReturnValue();
- returnValue.setSucceeded(true);
- returnValue.setReturnValue(mockUser);
- when(mockBackend.runQuery(eq(VdcQueryType.GetUserBySessionId),
- isA(VdcQueryParametersBase.class))).thenReturn(returnValue);
- }
-
- void stubGetConfigurationValuePublicQuery() {
- VdcQueryReturnValue returnValue = new VdcQueryReturnValue();
- returnValue.setSucceeded(true);
- returnValue.setReturnValue(Integer.valueOf(255));
- when(mockBackend.runPublicQuery(eq(VdcQueryType.GetConfigurationValue),
-
isA(GetConfigurationValueParameters.class))).thenReturn(returnValue);
+ verify(mockBrandingManager).getMessages(APPLICATION_NAME,
Locale.JAPANESE);
}
}
diff --git
a/frontend/webadmin/modules/frontend/src/test/java/org/ovirt/engine/ui/frontend/server/gwt/UserPortalHostPageServletTest.java
b/frontend/webadmin/modules/frontend/src/test/java/org/ovirt/engine/ui/frontend/server/gwt/UserPortalHostPageServletTest.java
index 2132741..bf3bde9 100644
---
a/frontend/webadmin/modules/frontend/src/test/java/org/ovirt/engine/ui/frontend/server/gwt/UserPortalHostPageServletTest.java
+++
b/frontend/webadmin/modules/frontend/src/test/java/org/ovirt/engine/ui/frontend/server/gwt/UserPortalHostPageServletTest.java
@@ -3,37 +3,33 @@
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import static org.mockito.Mockito.spy;
-import static org.ovirt.engine.core.utils.MockConfigRule.mockConfig;
-import java.util.ArrayList;
-
-import org.junit.ClassRule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.runners.MockitoJUnitRunner;
-import org.ovirt.engine.core.common.config.ConfigValues;
-import org.ovirt.engine.core.utils.MockConfigRule;
@RunWith(MockitoJUnitRunner.class)
public class UserPortalHostPageServletTest extends
AbstractGwtDynamicHostPageServletTest<UserPortalHostPageServlet> {
- @ClassRule
- public static MockConfigRule mcr =
- new
MockConfigRule(mockConfig(ConfigValues.UnsupportedLocalesFilterOverrides, new
ArrayList<String>()));
-
@Override
protected UserPortalHostPageServlet getTestServletSpy() {
return spy(new UserPortalHostPageServlet());
}
+ /**
+ * Verify UserPortal selector script name.
+ */
@Test
- public void testGetSelectorScriptName() {
- assertEquals(testServlet.getSelectorScriptName(),
- "userportal.nocache.js"); //$NON-NLS-1$
+ public void getSelectorScriptName() {
+ assertEquals(testServlet.getSelectorScriptName(),
"userportal.nocache.js"); //$NON-NLS-1$
}
+ /**
+ * Verify that queries should be filtered according to user's permissions.
+ */
@Test
- public void testFilterQueries() {
- assertTrue("Filter queries should be 'true'",
testServlet.filterQueries()); //$NON-NLS-1$
+ public void filterQueries() {
+ assertTrue("UserPortal queries should be filtered",
testServlet.filterQueries()); //$NON-NLS-1$
}
+
}
diff --git
a/frontend/webadmin/modules/frontend/src/test/java/org/ovirt/engine/ui/frontend/server/gwt/WebAdminHostPageServletTest.java
b/frontend/webadmin/modules/frontend/src/test/java/org/ovirt/engine/ui/frontend/server/gwt/WebAdminHostPageServletTest.java
index ae1b42a..5308322 100644
---
a/frontend/webadmin/modules/frontend/src/test/java/org/ovirt/engine/ui/frontend/server/gwt/WebAdminHostPageServletTest.java
+++
b/frontend/webadmin/modules/frontend/src/test/java/org/ovirt/engine/ui/frontend/server/gwt/WebAdminHostPageServletTest.java
@@ -1,73 +1,56 @@
package org.ovirt.engine.ui.frontend.server.gwt;
-import static org.junit.Assert.assertArrayEquals;
+import static org.hamcrest.CoreMatchers.equalTo;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
-import static org.mockito.Matchers.any;
-import static org.mockito.Matchers.anyListOf;
-import static org.mockito.Mockito.atLeast;
+import static org.junit.Assert.assertThat;
+import static org.mockito.Matchers.argThat;
+import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
-import static org.ovirt.engine.core.utils.MockConfigRule.mockConfig;
-import java.io.IOException;
-import java.io.UnsupportedEncodingException;
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
-import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.List;
-import javax.servlet.ServletException;
-
+import org.apache.commons.lang.StringUtils;
import org.codehaus.jackson.JsonNode;
-import org.codehaus.jackson.map.ObjectMapper;
import org.codehaus.jackson.node.ArrayNode;
import org.codehaus.jackson.node.ObjectNode;
-import org.junit.Before;
-import org.junit.ClassRule;
+import org.hamcrest.BaseMatcher;
+import org.hamcrest.Description;
+import org.hamcrest.Matcher;
import org.junit.Test;
import org.junit.runner.RunWith;
-import org.mockito.Mock;
import org.mockito.runners.MockitoJUnitRunner;
-import org.ovirt.engine.core.common.config.ConfigValues;
-import org.ovirt.engine.core.utils.MockConfigRule;
import org.ovirt.engine.ui.frontend.server.gwt.plugin.PluginData;
@RunWith(MockitoJUnitRunner.class)
public class WebAdminHostPageServletTest extends
AbstractGwtDynamicHostPageServletTest<WebAdminHostPageServlet> {
- private static final String APPLICATION_MODE = "{ \"value\": \"123\" }";
//$NON-NLS-1$
+ private static final Integer APPLICATION_MODE = 1;
+ private static final String REPORT_URL = "/report_url"; //$NON-NLS-1$
+ private static final String RIGHT_CLICK_URL = "/right_click_url";
//$NON-NLS-1$
- @ClassRule
- public static MockConfigRule mcr =
- new
MockConfigRule(mockConfig(ConfigValues.UnsupportedLocalesFilterOverrides, new
ArrayList<String>()));
+ private final List<PluginData> pluginDataList = new ArrayList<>();
- @Mock
- private ObjectNode mockApplicationModeObject;
+ @Override
+ protected void extraSetUp() {
+
doReturn(APPLICATION_MODE).when(testServlet).getApplicationMode(ENGINE_SESSION_ID);
+ doReturn(pluginDataList).when(testServlet).getPluginData();
+ doReturn(REPORT_URL).when(testServlet).getReportUrl();
+ doReturn(RIGHT_CLICK_URL).when(testServlet).getRightClickUrl();
- // Cannot use @Mock since ArrayNode is final
- private ArrayNode mockPluginDefinitionsArray;
-
- @Mock
- private ObjectNode mockEngineSessionTimeoutObject;
-
- @Before
- public void setUpMockRequest() {
- ObjectMapper mapper = new ObjectMapper();
- ObjectNode mockPluginDef = mapper.createObjectNode();
- mockPluginDef.put("foo", "bar"); //$NON-NLS-1$ //$NON-NLS-2$
- mockPluginDefinitionsArray = mapper.createArrayNode();
- mockPluginDefinitionsArray.add(mockPluginDef);
-
when(mockApplicationModeObject.toString()).thenReturn(APPLICATION_MODE);
-
when(mockRequest.getAttribute(WebAdminHostPageServlet.ATTR_APPLICATION_MODE)).thenReturn(mockApplicationModeObject);
-
when(mockRequest.getAttribute(WebAdminHostPageServlet.ATTR_PLUGIN_DEFS)).thenReturn(mockPluginDefinitionsArray);
-
when(mockRequest.getAttribute(WebAdminHostPageServlet.ATTR_ENGINE_SESSION_TIMEOUT)).thenReturn(mockEngineSessionTimeoutObject);
-
when(mockRequest.getAttribute(WebAdminHostPageServlet.ATTR_ENGINE_REPORTS_BASE_URL)).thenReturn("");
+ PluginData mockPluginData = mock(PluginData.class);
+ when(mockPluginData.getName()).thenReturn("TestPlugin"); //$NON-NLS-1$
+ when(mockPluginData.getUrl()).thenReturn("/test_plugin"); //$NON-NLS-1$
+
when(mockPluginData.mergeConfiguration()).thenReturn(realObjectMapper.createObjectNode());
+ when(mockPluginData.isEnabled()).thenReturn(true);
+ pluginDataList.add(mockPluginData);
}
@Override
@@ -75,81 +58,127 @@
return spy(new WebAdminHostPageServlet());
}
- @Override
- protected void setUpTestServlet() throws NoSuchAlgorithmException {
- super.setUpTestServlet();
- // Avoid touching PluginDataManager via getPluginData method
- doReturn(new
ArrayList<PluginData>()).when(testServlet).getPluginData();
- testServlet.reportBaseUrl = "";
- testServlet.reportRedirectUrl = "";
- testServlet.reportRightClickRedirectUrl = "";
- }
-
+ /**
+ * Verify WebAdmin selector script name.
+ */
@Test
- public void testGetSelectorScriptName() {
+ public void getSelectorScriptName() {
assertEquals(testServlet.getSelectorScriptName(),
"webadmin.nocache.js"); //$NON-NLS-1$
}
+ /**
+ * Verify that queries should NOT be filtered according to user's
permissions.
+ */
@Test
- public void testFilterQueries() {
- assertFalse(testServlet.filterQueries());
+ public void filterQueries() {
+ assertFalse("WebAdmin queries shouldn't be filtered",
testServlet.filterQueries()); //$NON-NLS-1$
}
+ /**
+ * Verify that additional HttpRequest attributes are set.
+ */
@Test
- public void testDoGet_ExtraAttributes_WithoutUserInfoObject() throws
IOException, ServletException {
-
doReturn(mockApplicationModeObject).when(testServlet).getApplicationModeObject(any(Integer.class));
-
doReturn(mockPluginDefinitionsArray).when(testServlet).getPluginDefinitionsArray(anyListOf(PluginData.class));
-
doReturn(mockEngineSessionTimeoutObject).when(testServlet).getEngineSessionTimeoutObject(any(Integer.class));
- testServlet.doGet(mockRequest, mockResponse);
-
verify(mockRequest).setAttribute(WebAdminHostPageServlet.ATTR_APPLICATION_MODE,
mockApplicationModeObject);
-
verify(mockRequest).setAttribute(WebAdminHostPageServlet.ATTR_PLUGIN_DEFS,
mockPluginDefinitionsArray);
-
verify(mockRequest).setAttribute(WebAdminHostPageServlet.ATTR_ENGINE_SESSION_TIMEOUT,
mockEngineSessionTimeoutObject);
+ public void setHttpAttributes_extraAttributes() {
+ testServlet.setHttpAttributes(mockRequest, ENGINE_SESSION_ID);
+
+
verify(mockRequest).setAttribute(eq(WebAdminHostPageServlet.ATTR_APPLICATION_MODE),
+
argThat(getValueObjectMatcher(String.valueOf(APPLICATION_MODE))));
+
verify(mockRequest).setAttribute(eq(WebAdminHostPageServlet.ATTR_PLUGIN_DEFS),
+ argThat(getPluginDataArrayMatcher(pluginDataList)));
+
verify(mockRequest).setAttribute(eq(WebAdminHostPageServlet.ATTR_ENGINE_REPORTS_BASE_URL),
+ argThat(getReportInitObjectMatcher(REPORT_URL,
RIGHT_CLICK_URL)));
}
+ /**
+ * Verify that MD5 digest is produced from additional HttpRequest
attributes.
+ */
@Test
- public void testGetMd5Digest_WithExtraObjects_WithoutUserInfoObject()
throws NoSuchAlgorithmException,
- UnsupportedEncodingException {
+ public void getMd5Digest_extraAttributes() throws Exception {
+ ObjectNode mockApplicationModeObject = mock(ObjectNode.class);
+ ObjectNode mockReportInitObject = mock(ObjectNode.class);
+
+ // Since ArrayNode is final, we'll use "real" ArrayNode instance.
+ // Trying to mock final classes can get us into real trouble.
+ ArrayNode realPluginDefinitionsArray =
realObjectMapper.createArrayNode();
+
+
when(mockRequest.getAttribute(WebAdminHostPageServlet.ATTR_APPLICATION_MODE))
+ .thenReturn(mockApplicationModeObject);
+
when(mockRequest.getAttribute(WebAdminHostPageServlet.ATTR_PLUGIN_DEFS))
+ .thenReturn(realPluginDefinitionsArray);
+
when(mockRequest.getAttribute(WebAdminHostPageServlet.ATTR_ENGINE_REPORTS_BASE_URL))
+ .thenReturn(mockReportInitObject);
+
MessageDigest result = testServlet.getMd5Digest(mockRequest);
- assertEquals(result, mockDigest);
- verify(mockDigest, atLeast(3)).update(byteArrayCaptor.capture());
- assertArrayEquals(SELECTOR_SCRIPT.getBytes(StandardCharsets.UTF_8),
byteArrayCaptor.getAllValues().get(0));
- assertArrayEquals(APPLICATION_MODE.getBytes(StandardCharsets.UTF_8),
byteArrayCaptor.getAllValues().get(1));
-
assertArrayEquals(mockPluginDefinitionsArray.toString().getBytes(StandardCharsets.UTF_8),
byteArrayCaptor.getAllValues().get(2));
+ assertThat(result, equalTo(mockDigest));
+
+
verify(mockDigest).update(mockApplicationModeObject.toString().getBytes(StandardCharsets.UTF_8));
+
verify(mockDigest).update(realPluginDefinitionsArray.toString().getBytes(StandardCharsets.UTF_8));
+
verify(mockDigest).update(mockReportInitObject.toString().getBytes(StandardCharsets.UTF_8));
}
- @Test
- public void testGetApplicationModeObject() {
- ObjectNode result =
testServlet.getApplicationModeObject(Integer.valueOf(255));
- assertEquals(result.get("value").asText(), "255"); //$NON-NLS-1$
//$NON-NLS-2$
+ Matcher<ArrayNode> getPluginDataArrayMatcher(final List<PluginData>
expectedPluginDataList) {
+ return new BaseMatcher<ArrayNode>() {
+ @Override
+ public boolean matches(Object item) {
+ ArrayNode actualArrayNode = (ArrayNode) item;
+
+ // Check array length.
+ if (actualArrayNode.size() != expectedPluginDataList.size()) {
+ return false;
+ }
+
+ // Check array elements.
+ for (int i = 0; i < expectedPluginDataList.size(); i++) {
+ PluginData expectedPluginData =
expectedPluginDataList.get(i);
+ JsonNode actualElementNode = actualArrayNode.get(i);
+
+ if
(!expectedPluginData.getName().equals(actualElementNode.get("name").asText()))
{ //$NON-NLS-1$
+ return false;
+ }
+ else if
(!expectedPluginData.getUrl().equals(actualElementNode.get("url").asText())) {
//$NON-NLS-1$
+ return false;
+ }
+ else if
(!expectedPluginData.mergeConfiguration().equals(actualElementNode.get("config")))
{ //$NON-NLS-1$
+ return false;
+ }
+ else if (expectedPluginData.isEnabled() !=
actualElementNode.get("enabled").asBoolean()) { //$NON-NLS-1$
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ @Override
+ public void describeTo(Description description) {
+ List<String> elements = new ArrayList<>();
+ for (PluginData expectedPluginData : expectedPluginDataList) {
+ elements.add(String.format("{name: %s, url: %s, config:
%s, enabled: %s}", //$NON-NLS-1$
+ expectedPluginData.getName(),
+ expectedPluginData.getUrl(),
+ expectedPluginData.mergeConfiguration().toString(),
+ String.valueOf(expectedPluginData.isEnabled())));
+ }
+
+ description.appendText("[" + StringUtils.join(elements, ",") +
"]"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+ }
+ };
}
- @Test
- public void testGetPluginDefinitionsArray() {
- int mockDataCount = 10;
- List<PluginData> pluginData = new ArrayList<PluginData>();
- for (int i = 0; i < mockDataCount; i++) {
- PluginData mockData = mock(PluginData.class);
- when(mockData.getName()).thenReturn("name" + i); //$NON-NLS-1$
- when(mockData.getUrl()).thenReturn("url" + i); //$NON-NLS-1$
-
when(mockData.mergeConfiguration()).thenReturn(mock(ObjectNode.class));
- when(mockData.isEnabled()).thenReturn(true);
- pluginData.add(mockData);
- }
- ArrayNode result = testServlet.getPluginDefinitionsArray(pluginData);
- assertEquals(result.size(), mockDataCount);
- for (int i = 0; i < mockDataCount; i++) {
- JsonNode item = result.get(i);
- assertEquals(item.get("name").asText(), "name" + i); //$NON-NLS-1$
//$NON-NLS-2$
- assertEquals(item.get("url").asText(), "url" + i); //$NON-NLS-1$
//$NON-NLS-2$
- assertTrue(item.get("config") instanceof ObjectNode); //$NON-NLS-1$
- assertEquals(item.get("enabled").asBoolean(), true); //$NON-NLS-1$
- }
- }
+ Matcher<ObjectNode> getReportInitObjectMatcher(final String reportUrl,
final String rightClickUrl) {
+ return new BaseMatcher<ObjectNode>() {
+ @Override
+ public boolean matches(Object item) {
+ ObjectNode reportInitObject = (ObjectNode) item;
+ return
reportUrl.equals(reportInitObject.get("reportUrl").asText()) //$NON-NLS-1$
+ &&
rightClickUrl.equals(reportInitObject.get("rightClickUrl").asText());
//$NON-NLS-1$
+ }
- @Test
- public void testGetEngineSessionTimeoutObject() {
- ObjectNode result =
testServlet.getEngineSessionTimeoutObject(Integer.valueOf(30));
- assertEquals(result.get("value").asText(), "30"); //$NON-NLS-1$
//$NON-NLS-2$
+ @Override
+ public void describeTo(Description description) {
+ description.appendText(String.format("{reportUrl: %s,
rightClickUrl: %s}", reportUrl, rightClickUrl)); //$NON-NLS-1$
+ }
+ };
}
}
diff --git
a/frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/auth/SSOTokenData.java
b/frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/auth/SSOTokenData.java
index 88c0fca..20e7028 100644
---
a/frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/auth/SSOTokenData.java
+++
b/frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/auth/SSOTokenData.java
@@ -1,24 +1,17 @@
package org.ovirt.engine.ui.common.auth;
-import com.google.gwt.core.client.JavaScriptObject;
+import org.ovirt.engine.ui.common.jsni.JsSingleValueObject;
/**
* Overlay type for {@code ssoToken} global JS object.
*/
-public final class SSOTokenData extends JavaScriptObject {
+public final class SSOTokenData extends JsSingleValueObject {
protected SSOTokenData() {
}
- public static native SSOTokenData instance() /*-{
- return $wnd.ssoToken;
- }-*/;
-
- public native String getValue() /*-{
- return this.value;
- }-*/;
-
- public String getToken() {
- return getValue();
+ public static String getToken() {
+ return getValueAsString("ssoToken"); //$NON-NLS-1$
}
+
}
diff --git
a/frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/jsni/JsSingleValueObject.java
b/frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/jsni/JsSingleValueObject.java
new file mode 100644
index 0000000..b5ea908
--- /dev/null
+++
b/frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/jsni/JsSingleValueObject.java
@@ -0,0 +1,18 @@
+package org.ovirt.engine.ui.common.jsni;
+
+import com.google.gwt.core.client.JavaScriptObject;
+
+/**
+ * Overlay for JS object containing single {@code value} property, e.g.
<code>{ value: anything }</code>
+ */
+public abstract class JsSingleValueObject extends JavaScriptObject {
+
+ protected JsSingleValueObject() {
+ }
+
+ public static native String getValueAsString(String objName) /*-{
+ var obj = $wnd[objName];
+ return obj && obj.value;
+ }-*/;
+
+}
diff --git
a/frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/system/BaseApplicationInit.java
b/frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/system/BaseApplicationInit.java
index 27f926d..570f299 100644
---
a/frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/system/BaseApplicationInit.java
+++
b/frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/system/BaseApplicationInit.java
@@ -201,7 +201,8 @@
}
});
- SSOTokenChangeEvent.fire(eventBus, SSOTokenData.instance().getToken());
+ SSOTokenChangeEvent.fire(eventBus, SSOTokenData.getToken());
+
// Indicate that the user should be logged in automatically
user.setAutoLogin(true);
}
diff --git
a/frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/system/ClientStorageImpl.java
b/frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/system/ClientStorageImpl.java
index a339d4a..287fde4 100644
---
a/frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/system/ClientStorageImpl.java
+++
b/frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/system/ClientStorageImpl.java
@@ -4,27 +4,29 @@
import com.google.gwt.storage.client.Storage;
import com.google.gwt.user.client.Cookies;
+import com.google.inject.Inject;
/**
- * Provides client-side key-value storage service.
- * <p>
- * Uses HTML5 {@linkplain Storage Web Storage} when supported by the browser.
Falls back to {@linkplain Cookies cookies}
- * when HTML5 Web Storage is not available.
- * <p>
- * Some facts and limitations:
- * <ul>
- * <li>typically, there can be max. 20 cookies per domain, each holding max.
4kB of data
- * <li>HTML5 local storage is persistent and shared by all browser windows/tabs
- * <li>HTML5 session storage is transient and accessible only to one browser
window/tab
- * </ul>
+ * Default implementation of {@link ClientStorage} interface.
*/
public class ClientStorageImpl implements ClientStorage {
// Fifty years
private static final long PERSISTENT_COOKIE_EXPIRATION = 1000 * 60 * 60 *
24 * 365 * 50;
+ private static final String SEPARATOR = "_"; //$NON-NLS-1$
+
private static final Storage localStorage =
Storage.getLocalStorageIfSupported();
private static final Storage sessionStorage =
Storage.getSessionStorageIfSupported();
+
+ private final String keyPrefix;
+ private final String version;
+
+ @Inject
+ public ClientStorageImpl(@ClientStorageKeyPrefix String keyPrefix) {
+ this.keyPrefix = keyPrefix;
+ this.version = EngineRpmVersionData.getVersion();
+ }
/**
* Returns the value for the given key from local (persistent) storage, or
{@code null} if there is no value for
@@ -32,9 +34,9 @@
*/
public String getLocalItem(String key) {
if (localStorage != null) {
- return localStorage.getItem(key);
+ return localStorage.getItem(getStorageItemKey(key));
} else {
- return Cookies.getCookie(key);
+ return Cookies.getCookie(getStorageItemKey(key));
}
}
@@ -43,10 +45,11 @@
*/
public void setLocalItem(String key, String value) {
if (localStorage != null) {
- localStorage.setItem(key, value);
+ localStorage.setItem(getStorageItemKey(key), value);
} else {
// Emulate persistent storage using cookies which have predefined
expiration date
- Cookies.setCookie(key, value, new Date(new Date().getTime() +
PERSISTENT_COOKIE_EXPIRATION));
+ Cookies.setCookie(getStorageItemKey(key), value,
+ new Date(new Date().getTime() +
PERSISTENT_COOKIE_EXPIRATION));
}
}
@@ -55,9 +58,9 @@
*/
public void removeLocalItem(String key) {
if (localStorage != null) {
- localStorage.removeItem(key);
+ localStorage.removeItem(getStorageItemKey(key));
} else {
- Cookies.removeCookie(key);
+ Cookies.removeCookie(getStorageItemKey(key));
}
}
@@ -67,9 +70,9 @@
*/
public String getSessionItem(String key) {
if (sessionStorage != null) {
- return sessionStorage.getItem(key);
+ return sessionStorage.getItem(getStorageItemKey(key));
} else {
- return Cookies.getCookie(key);
+ return Cookies.getCookie(getStorageItemKey(key));
}
}
@@ -78,10 +81,10 @@
*/
public void setSessionItem(String key, String value) {
if (sessionStorage != null) {
- sessionStorage.setItem(key, value);
+ sessionStorage.setItem(getStorageItemKey(key), value);
} else {
// Emulate transient storage using cookies which expire when the
browser session ends
- Cookies.setCookie(key, value);
+ Cookies.setCookie(getStorageItemKey(key), value);
}
}
@@ -90,10 +93,22 @@
*/
public void removeSessionItem(String key) {
if (sessionStorage != null) {
- sessionStorage.removeItem(key);
+ sessionStorage.removeItem(getStorageItemKey(key));
} else {
- Cookies.removeCookie(key);
+ Cookies.removeCookie(getStorageItemKey(key));
}
}
+ String getStorageItemKey(String key) {
+ assert key != null : "key cannot be null"; //$NON-NLS-1$
+
+ StringBuilder sb = new StringBuilder(keyPrefix).append(SEPARATOR);
+ if (version != null) {
+ sb.append(version).append(SEPARATOR);
+ }
+ sb.append(key);
+
+ return sb.toString();
+ }
+
}
diff --git
a/frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/system/ClientStorageKeyPrefix.java
b/frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/system/ClientStorageKeyPrefix.java
new file mode 100644
index 0000000..0cd036f
--- /dev/null
+++
b/frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/system/ClientStorageKeyPrefix.java
@@ -0,0 +1,19 @@
+package org.ovirt.engine.ui.common.system;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+import com.google.inject.BindingAnnotation;
+
+/**
+ * Binding annotation for String constant representing the
application-specific prefix
+ * of all {@link ClientStorage} key names.
+ */
+@BindingAnnotation
+@Target({ ElementType.FIELD, ElementType.PARAMETER, ElementType.METHOD })
+@Retention(RetentionPolicy.RUNTIME)
+public @interface ClientStorageKeyPrefix {
+
+}
diff --git
a/frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/system/EngineRpmVersionData.java
b/frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/system/EngineRpmVersionData.java
new file mode 100644
index 0000000..8cb6b20
--- /dev/null
+++
b/frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/system/EngineRpmVersionData.java
@@ -0,0 +1,17 @@
+package org.ovirt.engine.ui.common.system;
+
+import org.ovirt.engine.ui.common.jsni.JsSingleValueObject;
+
+/**
+ * Overlay type for {@code engineRpmVersion} global JS object.
+ */
+public final class EngineRpmVersionData extends JsSingleValueObject {
+
+ protected EngineRpmVersionData() {
+ }
+
+ public static String getVersion() {
+ return getValueAsString("engineRpmVersion"); //$NON-NLS-1$
+ }
+
+}
diff --git
a/frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/system/EngineSessionTimeoutData.java
b/frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/system/EngineSessionTimeoutData.java
new file mode 100644
index 0000000..7750cff
--- /dev/null
+++
b/frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/system/EngineSessionTimeoutData.java
@@ -0,0 +1,17 @@
+package org.ovirt.engine.ui.common.system;
+
+import org.ovirt.engine.ui.common.jsni.JsSingleValueObject;
+
+/**
+ * Overlay type for {@code engineSessionTimeout} global JS object.
+ */
+public final class EngineSessionTimeoutData extends JsSingleValueObject {
+
+ protected EngineSessionTimeoutData() {
+ }
+
+ public static String getValue() {
+ return getValueAsString("engineSessionTimeout"); //$NON-NLS-1$
+ }
+
+}
diff --git
a/frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/ReportsUrls.java
b/frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/ReportsUrls.java
index e0a9dc7..72b8a1b 100644
---
a/frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/ReportsUrls.java
+++
b/frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/ReportsUrls.java
@@ -18,4 +18,5 @@
public native String getRightClickUrl() /*-{
return this.rightClickUrl;
}-*/;
+
}
diff --git
a/frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/dataprovider/AsyncDataProvider.java
b/frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/dataprovider/AsyncDataProvider.java
index b11a5a4..59bfbdb 100644
---
a/frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/dataprovider/AsyncDataProvider.java
+++
b/frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/dataprovider/AsyncDataProvider.java
@@ -1675,20 +1675,6 @@
Frontend.getInstance().runQuery(VdcQueryType.GetGlusterVolumeRemoveBricksStatus,
parameters, aQuery);
}
- public void getRpmVersion(AsyncQuery aQuery) {
- aQuery.converterCallback = new IAsyncConverter() {
- @Override
- public Object Convert(Object source, AsyncQuery _asyncQuery)
- {
- return source != null ? (String) source : ""; //$NON-NLS-1$
- }
- };
- GetConfigurationValueParameters tempVar =
- new
GetConfigurationValueParameters(ConfigurationValues.ProductRPMVersion);
- tempVar.setVersion(getDefaultConfigurationVersion());
- getConfigFromCache(tempVar, aQuery);
- }
-
public void getUserMessageOfTheDayViaPublic(AsyncQuery aQuery) {
aQuery.converterCallback = new IAsyncConverter() {
@Override
diff --git
a/frontend/webadmin/modules/userportal-gwtp/src/main/java/org/ovirt/engine/ui/userportal/gin/SystemModule.java
b/frontend/webadmin/modules/userportal-gwtp/src/main/java/org/ovirt/engine/ui/userportal/gin/SystemModule.java
index e0a3de6..0a3a429 100644
---
a/frontend/webadmin/modules/userportal-gwtp/src/main/java/org/ovirt/engine/ui/userportal/gin/SystemModule.java
+++
b/frontend/webadmin/modules/userportal-gwtp/src/main/java/org/ovirt/engine/ui/userportal/gin/SystemModule.java
@@ -3,6 +3,7 @@
import org.ovirt.engine.ui.common.gin.BaseSystemModule;
import org.ovirt.engine.ui.common.section.DefaultLoginSectionPlace;
import org.ovirt.engine.ui.common.section.DefaultMainSectionPlace;
+import org.ovirt.engine.ui.common.system.ClientStorageKeyPrefix;
import org.ovirt.engine.ui.uicommonweb.auth.CurrentUserRole;
import org.ovirt.engine.ui.uicommonweb.place.UserPortalApplicationPlaces;
import org.ovirt.engine.ui.userportal.ApplicationConstants;
@@ -11,18 +12,20 @@
import org.ovirt.engine.ui.userportal.ApplicationResources;
import org.ovirt.engine.ui.userportal.ApplicationResourcesWithLookup;
import org.ovirt.engine.ui.userportal.ApplicationTemplates;
-import org.ovirt.engine.ui.userportal.auth.UserPortalCurrentUserRole;
import org.ovirt.engine.ui.userportal.auth.LoggedInExtendedPlaceGatekeeper;
+import org.ovirt.engine.ui.userportal.auth.UserPortalCurrentUserRole;
import org.ovirt.engine.ui.userportal.place.UserPortalPlaceManager;
import org.ovirt.engine.ui.userportal.section.DefaultMainSectionExtendedPlace;
+import org.ovirt.engine.ui.userportal.system.ApplicationInit;
import com.google.inject.Singleton;
-import org.ovirt.engine.ui.userportal.system.ApplicationInit;
/**
* GIN module containing UserPortal infrastructure and configuration bindings.
*/
public class SystemModule extends BaseSystemModule {
+
+ private static final String CLIENT_STORAGE_KEY_PREFIX =
"ENGINE_UserPortal"; //$NON-NLS-1$
@SuppressWarnings("deprecation")
@Override
@@ -47,6 +50,8 @@
.to(UserPortalApplicationPlaces.DEFAULT_MAIN_SECTION_BASIC_PLACE);
bindConstant().annotatedWith(DefaultMainSectionExtendedPlace.class)
.to(UserPortalApplicationPlaces.DEFAULT_MAIN_SECTION_EXTENDED_PLACE);
+ bindConstant().annotatedWith(ClientStorageKeyPrefix.class)
+ .to(CLIENT_STORAGE_KEY_PREFIX);
bindResourceConfiguration(ApplicationConstants.class,
ApplicationMessages.class,
ApplicationResources.class, ApplicationTemplates.class,
ApplicationDynamicMessages.class);
diff --git
a/frontend/webadmin/modules/userportal-gwtp/src/main/java/org/ovirt/engine/ui/userportal/section/main/presenter/AboutPopupPresenterWidget.java
b/frontend/webadmin/modules/userportal-gwtp/src/main/java/org/ovirt/engine/ui/userportal/section/main/presenter/AboutPopupPresenterWidget.java
index cbda6d8..b047988 100644
---
a/frontend/webadmin/modules/userportal-gwtp/src/main/java/org/ovirt/engine/ui/userportal/section/main/presenter/AboutPopupPresenterWidget.java
+++
b/frontend/webadmin/modules/userportal-gwtp/src/main/java/org/ovirt/engine/ui/userportal/section/main/presenter/AboutPopupPresenterWidget.java
@@ -1,9 +1,7 @@
package org.ovirt.engine.ui.userportal.section.main.presenter;
import org.ovirt.engine.ui.common.presenter.AbstractPopupPresenterWidget;
-import org.ovirt.engine.ui.frontend.AsyncQuery;
-import org.ovirt.engine.ui.frontend.INewAsyncCallback;
-import org.ovirt.engine.ui.uicommonweb.dataprovider.AsyncDataProvider;
+import org.ovirt.engine.ui.common.system.EngineRpmVersionData;
import com.google.gwt.event.shared.EventBus;
import com.google.inject.Inject;
@@ -28,18 +26,8 @@
protected void onReveal() {
super.onReveal();
- AsyncQuery _asyncQuery = new AsyncQuery();
- _asyncQuery.setModel(this);
- _asyncQuery.asyncCallback = new INewAsyncCallback() {
- @Override
- public void onSuccess(Object model, Object result) {
- String version = (String) result;
-
- getView().setVersion(version);
- }
- };
-
- AsyncDataProvider.getInstance().getRpmVersion(_asyncQuery);
+ String version = EngineRpmVersionData.getVersion();
+ getView().setVersion(version);
}
}
diff --git
a/frontend/webadmin/modules/webadmin/src/main/java/org/ovirt/engine/ui/webadmin/gin/SystemModule.java
b/frontend/webadmin/modules/webadmin/src/main/java/org/ovirt/engine/ui/webadmin/gin/SystemModule.java
index ecb8154..ba28e01 100644
---
a/frontend/webadmin/modules/webadmin/src/main/java/org/ovirt/engine/ui/webadmin/gin/SystemModule.java
+++
b/frontend/webadmin/modules/webadmin/src/main/java/org/ovirt/engine/ui/webadmin/gin/SystemModule.java
@@ -4,6 +4,7 @@
import org.ovirt.engine.ui.common.gin.BaseSystemModule;
import org.ovirt.engine.ui.common.section.DefaultLoginSectionPlace;
import org.ovirt.engine.ui.common.section.DefaultMainSectionPlace;
+import org.ovirt.engine.ui.common.system.ClientStorageKeyPrefix;
import org.ovirt.engine.ui.uicommonweb.auth.CurrentUserRole;
import org.ovirt.engine.ui.uicommonweb.place.WebAdminApplicationPlaces;
import org.ovirt.engine.ui.webadmin.ApplicationConstants;
@@ -19,6 +20,8 @@
* GIN module containing WebAdmin infrastructure and configuration bindings.
*/
public class SystemModule extends BaseSystemModule {
+
+ private static final String CLIENT_STORAGE_KEY_PREFIX = "ENGINE_WebAdmin";
//$NON-NLS-1$
@SuppressWarnings("deprecation")
@Override
@@ -40,6 +43,8 @@
.to(WebAdminApplicationPlaces.DEFAULT_LOGIN_SECTION_PLACE);
bindConstant().annotatedWith(DefaultMainSectionPlace.class)
.to(WebAdminApplicationPlaces.DEFAULT_MAIN_SECTION_PLACE);
+ bindConstant().annotatedWith(ClientStorageKeyPrefix.class)
+ .to(CLIENT_STORAGE_KEY_PREFIX);
bindResourceConfiguration(ApplicationConstants.class,
ApplicationMessages.class,
ApplicationResources.class, ApplicationTemplates.class,
ApplicationDynamicMessages.class);
diff --git
a/frontend/webadmin/modules/webadmin/src/main/java/org/ovirt/engine/ui/webadmin/plugin/restapi/EngineSessionTimeoutData.java
b/frontend/webadmin/modules/webadmin/src/main/java/org/ovirt/engine/ui/webadmin/plugin/restapi/EngineSessionTimeoutData.java
deleted file mode 100644
index 92a3f35..0000000
---
a/frontend/webadmin/modules/webadmin/src/main/java/org/ovirt/engine/ui/webadmin/plugin/restapi/EngineSessionTimeoutData.java
+++ /dev/null
@@ -1,21 +0,0 @@
-package org.ovirt.engine.ui.webadmin.plugin.restapi;
-
-import com.google.gwt.core.client.JavaScriptObject;
-
-/**
- * Overlay type for {@code engineSessionTimeout} global JS object.
- */
-public final class EngineSessionTimeoutData extends JavaScriptObject {
-
- protected EngineSessionTimeoutData() {
- }
-
- public static native EngineSessionTimeoutData instance() /*-{
- return $wnd.engineSessionTimeout;
- }-*/;
-
- public native String getValue() /*-{
- return this.value;
- }-*/;
-
-}
diff --git
a/frontend/webadmin/modules/webadmin/src/main/java/org/ovirt/engine/ui/webadmin/section/main/presenter/AboutPopupPresenterWidget.java
b/frontend/webadmin/modules/webadmin/src/main/java/org/ovirt/engine/ui/webadmin/section/main/presenter/AboutPopupPresenterWidget.java
index 272476a..c08e3df 100644
---
a/frontend/webadmin/modules/webadmin/src/main/java/org/ovirt/engine/ui/webadmin/section/main/presenter/AboutPopupPresenterWidget.java
+++
b/frontend/webadmin/modules/webadmin/src/main/java/org/ovirt/engine/ui/webadmin/section/main/presenter/AboutPopupPresenterWidget.java
@@ -1,9 +1,7 @@
package org.ovirt.engine.ui.webadmin.section.main.presenter;
import org.ovirt.engine.ui.common.presenter.AbstractPopupPresenterWidget;
-import org.ovirt.engine.ui.frontend.AsyncQuery;
-import org.ovirt.engine.ui.frontend.INewAsyncCallback;
-import org.ovirt.engine.ui.uicommonweb.dataprovider.AsyncDataProvider;
+import org.ovirt.engine.ui.common.system.EngineRpmVersionData;
import com.google.gwt.event.shared.EventBus;
import com.google.inject.Inject;
@@ -28,18 +26,8 @@
protected void onReveal() {
super.onReveal();
- AsyncQuery _asyncQuery = new AsyncQuery();
- _asyncQuery.setModel(this);
- _asyncQuery.asyncCallback = new INewAsyncCallback() {
- @Override
- public void onSuccess(Object model, Object result) {
- String version = (String) result;
-
- getView().setVersion(version);
- }
- };
-
- AsyncDataProvider.getInstance().getRpmVersion(_asyncQuery);
+ String version = EngineRpmVersionData.getVersion();
+ getView().setVersion(version);
}
}
diff --git
a/frontend/webadmin/modules/webadmin/src/main/java/org/ovirt/engine/ui/webadmin/section/main/presenter/HeaderPresenterWidget.java
b/frontend/webadmin/modules/webadmin/src/main/java/org/ovirt/engine/ui/webadmin/section/main/presenter/HeaderPresenterWidget.java
index bbd482f..f4dcd40 100644
---
a/frontend/webadmin/modules/webadmin/src/main/java/org/ovirt/engine/ui/webadmin/section/main/presenter/HeaderPresenterWidget.java
+++
b/frontend/webadmin/modules/webadmin/src/main/java/org/ovirt/engine/ui/webadmin/section/main/presenter/HeaderPresenterWidget.java
@@ -3,12 +3,10 @@
import org.ovirt.engine.ui.common.auth.CurrentUser;
import org.ovirt.engine.ui.common.presenter.AbstractHeaderPresenterWidget;
import org.ovirt.engine.ui.common.presenter.ScrollableTabBarPresenterWidget;
+import org.ovirt.engine.ui.common.system.EngineRpmVersionData;
import org.ovirt.engine.ui.common.system.HeaderOffsetChangeEvent;
import org.ovirt.engine.ui.common.utils.WebUtils;
import org.ovirt.engine.ui.common.widget.tab.TabWidgetHandler;
-import org.ovirt.engine.ui.frontend.AsyncQuery;
-import org.ovirt.engine.ui.frontend.INewAsyncCallback;
-import org.ovirt.engine.ui.uicommonweb.dataprovider.AsyncDataProvider;
import org.ovirt.engine.ui.webadmin.ApplicationDynamicMessages;
import
org.ovirt.engine.ui.webadmin.section.main.presenter.popup.configure.ConfigurePopupPresenterWidget;
@@ -42,8 +40,6 @@
@ContentSlot
public static final Type<RevealContentHandler<?>> TYPE_SetTabBar = new
Type<RevealContentHandler<?>>();
-
- private static final int MAIN_TABBAR_INITIAL_OFFSET = 240; //pixels.
private final SearchPanelPresenterWidget searchPanel;
private final ScrollableTabBarPresenterWidget tabBar;
@@ -84,10 +80,6 @@
HeaderOffsetChangeEvent.fire(this, left);
}
- private void setScrollDistance(int scrollDistance) {
- tabBar.setScrollDistance(scrollDistance);
- }
-
@Override
protected void onBind() {
super.onBind();
@@ -117,24 +109,18 @@
}
private void configureFeedbackUrl() {
- AsyncQuery _asyncQuery = new AsyncQuery();
- _asyncQuery.setModel(this);
- _asyncQuery.asyncCallback = new INewAsyncCallback() {
- @Override
- public void onSuccess(Object model, Object result) {
- String version = (String) result;
- feedbackUrl = dynamicMessages.feedbackUrl(version);
- if (feedbackUrl != null && feedbackUrl.length() > 0) {
- getView().setFeedbackText(feedbackLinkLabel,
dynamicMessages.feedbackLinkTooltip());
-
registerHandler(getView().getFeedbackLink().addClickHandler(new ClickHandler() {
- @Override
- public void onClick(ClickEvent event) {
- WebUtils.openUrlInNewWindow(feedbackLinkLabel,
feedbackUrl);
- }
- }));
+ String version = EngineRpmVersionData.getVersion();
+ feedbackUrl = dynamicMessages.feedbackUrl(version);
+
+ if (feedbackUrl != null && feedbackUrl.length() > 0) {
+ getView().setFeedbackText(feedbackLinkLabel,
dynamicMessages.feedbackLinkTooltip());
+ registerHandler(getView().getFeedbackLink().addClickHandler(new
ClickHandler() {
+ @Override
+ public void onClick(ClickEvent event) {
+ WebUtils.openUrlInNewWindow(feedbackLinkLabel,
feedbackUrl);
}
- }
- };
- AsyncDataProvider.getInstance().getRpmVersion(_asyncQuery);
+ }));
+ }
}
+
}
diff --git
a/frontend/webadmin/modules/webadmin/src/main/java/org/ovirt/engine/ui/webadmin/system/ApplicationInit.java
b/frontend/webadmin/modules/webadmin/src/main/java/org/ovirt/engine/ui/webadmin/system/ApplicationInit.java
index 0a94fdc..3f85a00 100644
---
a/frontend/webadmin/modules/webadmin/src/main/java/org/ovirt/engine/ui/webadmin/system/ApplicationInit.java
+++
b/frontend/webadmin/modules/webadmin/src/main/java/org/ovirt/engine/ui/webadmin/system/ApplicationInit.java
@@ -24,7 +24,7 @@
import org.ovirt.engine.ui.uicompat.EventArgs;
import org.ovirt.engine.ui.uicompat.IEventListener;
import org.ovirt.engine.ui.webadmin.ApplicationDynamicMessages;
-import org.ovirt.engine.ui.webadmin.plugin.restapi.EngineSessionTimeoutData;
+import org.ovirt.engine.ui.common.system.EngineSessionTimeoutData;
import org.ovirt.engine.ui.webadmin.plugin.restapi.RestApiSessionManager;
import org.ovirt.engine.ui.webadmin.uimode.UiModeData;
@@ -76,9 +76,9 @@
}
// Check for Engine user session timeout configuration
- EngineSessionTimeoutData engineSessionTimeoutData =
EngineSessionTimeoutData.instance();
- if (engineSessionTimeoutData != null) {
-
restApiSessionManager.setSessionTimeout(engineSessionTimeoutData.getValue());
+ String engineSessionTimeout = EngineSessionTimeoutData.getValue();
+ if (engineSessionTimeout != null) {
+ restApiSessionManager.setSessionTimeout(engineSessionTimeout);
}
// Initiate transition to requested application place
--
To view, visit http://gerrit.ovirt.org/36536
To unsubscribe, visit http://gerrit.ovirt.org/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: I4864b2d4703ee548a570799ed3e87674602f5438
Gerrit-PatchSet: 1
Gerrit-Project: ovirt-engine
Gerrit-Branch: master
Gerrit-Owner: Vojtech Szocs <[email protected]>
_______________________________________________
Engine-patches mailing list
[email protected]
http://lists.ovirt.org/mailman/listinfo/engine-patches