From 4f9bf5575d5c3541cb2a01bc60c25c5920d36f4a Mon Sep 17 00:00:00 2001 From: Patrick Huang Date: Wed, 3 Dec 2014 10:51:04 +1000 Subject: [PATCH] rhbz1120457 - add expiry queue and consumer, refactoring... - extract strings so that it's localizable - remove netty connector and acceptor and use in vm ones - add comments --- etc/scripts/cargowait.sh | 8 +- etc/scripts/functional-test-db-snapshot.sh | 6 + .../ManageLanguageTeamMemberPage.java | 23 +++- .../language/JoinLanguageTeamTest.java | 3 +- .../src/test/resources/conf/standalone.xml | 37 +----- .../org/zanata/action/LanguageTeamAction.java | 35 +++--- .../notification/DeadLetterQueueReceiver.java | 103 +---------------- .../EmailQueueMessageReceiver.java | 25 ++-- .../notification/ExpiryQueueReceiver.java | 58 ++++++++++ ...missionChangeJmsMessagePayloadHandler.java | 6 +- .../zanata/notification/MessageUnwrapper.java | 107 ++++++++++++++++++ .../notification/NotificationManager.java | 21 +++- .../src/main/resources/messages.properties | 9 +- .../arquillian/standalone-arquillian.xml | 16 +-- 14 files changed, 276 insertions(+), 181 deletions(-) create mode 100644 zanata-war/src/main/java/org/zanata/notification/ExpiryQueueReceiver.java create mode 100644 zanata-war/src/main/java/org/zanata/notification/MessageUnwrapper.java diff --git a/etc/scripts/cargowait.sh b/etc/scripts/cargowait.sh index e55f01a385..79ee8226fc 100755 --- a/etc/scripts/cargowait.sh +++ b/etc/scripts/cargowait.sh @@ -6,13 +6,13 @@ extraArgs= while getopts "nhd:" opt; do case ${opt} in n) - echo ">> -n specified. Will NOT run maven goal 'clean'" >&2 + echo ">> -n specified. Will NOT run maven goal 'clean'." >&2 clean='' ;; h) - echo ">> run this script at zanata server module base dir to prepare a functional test war and start cargo in waiting mode" >&2 - echo ">>>> -n if you don't want to run maven clean goal" >&2 - echo ">>>> -d if you don't want to pass in extra arguments when running functional test" >&2 + echo ">> run this script to prepare a functional test war and start cargo in waiting mode" >&2 + echo ">>>> -n if you don't want to run maven clean goal. Useful when you have run functional-test-db.snapshot.sh." >&2 + echo ">>>> -d if you want to pass in extra arguments when running functional test" >&2 exit 0; ;; d) diff --git a/etc/scripts/functional-test-db-snapshot.sh b/etc/scripts/functional-test-db-snapshot.sh index d2332e33ce..837f2cccc1 100755 --- a/etc/scripts/functional-test-db-snapshot.sh +++ b/etc/scripts/functional-test-db-snapshot.sh @@ -1,5 +1,11 @@ #!/bin/bash +# once you have run cargowait.sh script and cargo has started, you can run this +# script to take a snapshot of current database and store it as +# target/database.sql. +# subsequent cargowait.sh execution can then use -n option (no clean) to make +# use of this script. + scriptBaseDir=$(dirname $0) functionalTestTarget=${scriptBaseDir}/../../functional-test/target diff --git a/functional-test/src/main/java/org/zanata/page/administration/ManageLanguageTeamMemberPage.java b/functional-test/src/main/java/org/zanata/page/administration/ManageLanguageTeamMemberPage.java index b02ee81983..65c52a5978 100644 --- a/functional-test/src/main/java/org/zanata/page/administration/ManageLanguageTeamMemberPage.java +++ b/functional-test/src/main/java/org/zanata/page/administration/ManageLanguageTeamMemberPage.java @@ -28,6 +28,7 @@ import org.openqa.selenium.By; import org.openqa.selenium.NoSuchElementException; import org.openqa.selenium.WebDriver; +import org.openqa.selenium.WebElement; import org.zanata.page.BasePage; import org.zanata.util.Checkbox; import org.zanata.util.TableRow; @@ -38,6 +39,7 @@ import java.util.HashSet; import java.util.List; import java.util.Set; +import javax.annotation.Nullable; /** * @author Patrick Huang permissionToAdd = Sets.newHashSet(permissions); permissionToAdd.add(TeamPermission.Translator); - for (TeamPermission permission : permissionToAdd) { + for (final TeamPermission permission : permissionToAdd) { log.info("Set checked as {}", permission.name()); - Checkbox.of(tryGetFirstRowInSearchPersonResult(personName) - .getCells() - .get(permission.columnIndex) - .findElement(By.tagName("input"))) - .check(); + waitForAMoment().until(new Predicate() { + @Override + public boolean apply(@Nullable WebDriver webDriver) { + TableRow tableRow = + tryGetFirstRowInSearchPersonResult(personName); + WebElement input = + tableRow.getCells().get(permission.columnIndex) + .findElement(By.tagName("input")); + Checkbox checkbox = Checkbox.of(input); + checkbox.check(); + return checkbox.checked(); + } + }); } log.info("Click Add Selected"); waitForWebElement(addSelectedButton).click(); @@ -188,3 +198,4 @@ public static enum TeamPermission { } } + diff --git a/functional-test/src/test/java/org/zanata/feature/language/JoinLanguageTeamTest.java b/functional-test/src/test/java/org/zanata/feature/language/JoinLanguageTeamTest.java index 850a9728ec..14781e0b40 100644 --- a/functional-test/src/test/java/org/zanata/feature/language/JoinLanguageTeamTest.java +++ b/functional-test/src/test/java/org/zanata/feature/language/JoinLanguageTeamTest.java @@ -73,6 +73,7 @@ public void translatorJoinsLanguageTeam() throws Exception { WiserMessage emailMessage = hasEmailRule.getMessages().get(0); assertThat(getEmailContent(emailMessage)) .contains( - "Administrator(admin@example.com) has changed your permission"); + "Administrator(admin@example.com) has changed your permissions"); } } + diff --git a/functional-test/src/test/resources/conf/standalone.xml b/functional-test/src/test/resources/conf/standalone.xml index 578c643c88..0cd967ae9d 100644 --- a/functional-test/src/test/resources/conf/standalone.xml +++ b/functional-test/src/test/resources/conf/standalone.xml @@ -243,18 +243,9 @@ 102400 2 - - - - - - - - - @@ -286,20 +277,10 @@ - - + @@ -312,18 +293,14 @@ true + + + true + true - - @@ -458,9 +435,6 @@ port="${jboss.http.port,env.JBOSS_HTTP_PORT:8180}" /> - - - + diff --git a/zanata-war/src/main/java/org/zanata/action/LanguageTeamAction.java b/zanata-war/src/main/java/org/zanata/action/LanguageTeamAction.java index 9a89cd5fab..830b826e7e 100644 --- a/zanata-war/src/main/java/org/zanata/action/LanguageTeamAction.java +++ b/zanata-war/src/main/java/org/zanata/action/LanguageTeamAction.java @@ -43,6 +43,7 @@ import org.zanata.dao.LocaleMemberDAO; import org.zanata.dao.PersonDAO; import org.zanata.events.LanguageTeamPermissionChangedEvent; +import org.zanata.i18n.Messages; import org.zanata.model.HAccount; import org.zanata.model.HLocale; import org.zanata.model.HLocaleMember; @@ -76,6 +77,9 @@ public class LanguageTeamAction implements Serializable { @In(required = false, value = JpaIdentityStore.AUTHENTICATED_USER) private HAccount authenticatedAccount; + @In + private Messages msgs; + @Getter @Setter private String language; @@ -87,7 +91,7 @@ public class LanguageTeamAction implements Serializable { public List getSearchResults() { if (searchResults == null) { - searchResults = new ArrayList(); + searchResults = new ArrayList<>(); } return searchResults; @@ -144,10 +148,8 @@ public void joinTribe() { true, true, true); log.info("{} joined tribe {}", authenticatedAccount.getUsername(), this.language); - // FIXME use localizable string - FacesMessages.instance().add( - "You are now a member of the {0} language team", - getLocale().retrieveNativeName()); + FacesMessages.instance().add(msgs.format("jsf.MemberOfTeam", + getLocale().retrieveNativeName())); } catch (Exception e) { FacesMessages.instance().add(Severity.ERROR, e.getMessage()); } @@ -164,14 +166,13 @@ public void leaveTribe() { authenticatedAccount.getPerson().getId()); log.info("{} left tribe {}", authenticatedAccount.getUsername(), this.language); - // FIXME use localizable string - FacesMessages.instance().add("You have left the {0} language team", - getLocale().retrieveNativeName()); + FacesMessages.instance().add(msgs.format("jsf.LeftTeam", + getLocale().retrieveNativeName())); } @Restrict("#{s:hasPermission(languageTeamAction.locale, 'manage-language-team')}") public void saveTeamCoordinator(HLocaleMember member) { - savePermission(member, "Team Coordinator", member.isCoordinator()); + savePermission(member, msgs.get("jsf.Translator"), member.isCoordinator()); if (Events.exists()) { HPerson doneByPerson = authenticatedAccount.getPerson(); LanguageTeamPermissionChangedEvent changedEvent = @@ -188,7 +189,7 @@ public void saveTeamCoordinator(HLocaleMember member) { @Restrict("#{s:hasPermission(languageTeamAction.locale, 'manage-language-team')}") public void saveTeamReviewer(HLocaleMember member) { - savePermission(member, "Team Reviewer", member.isReviewer()); + savePermission(member, msgs.get("jsf.Reviewer"), member.isReviewer()); if (Events.exists()) { HPerson doneByPerson = authenticatedAccount.getPerson(); LanguageTeamPermissionChangedEvent changedEvent = @@ -205,7 +206,7 @@ public void saveTeamReviewer(HLocaleMember member) { @Restrict("#{s:hasPermission(languageTeamAction.locale, 'manage-language-team')}") public void saveTeamTranslator(HLocaleMember member) { - savePermission(member, "Team Translator", member.isTranslator()); + savePermission(member, msgs.get("jsf.Translator"), member.isTranslator()); if (Events.exists()) { HPerson doneByPerson = authenticatedAccount.getPerson(); LanguageTeamPermissionChangedEvent changedEvent = @@ -227,13 +228,12 @@ private void savePermission(HLocaleMember member, String permissionDesc, HPerson person = member.getPerson(); if (isPermissionGranted) { FacesMessages.instance().add( - "{0} has been made a " + permissionDesc, - person.getAccount().getUsername()); + msgs.format("jsf.AddedAPermission", + person.getAccount().getUsername(), permissionDesc)); } else { - // TODO i18n FacesMessages.instance().add( - "{0} has been removed as " + permissionDesc, - person.getAccount().getUsername()); + msgs.format("jsf.RemovedAPermission", + person.getAccount().getUsername(), permissionDesc)); } } @@ -275,7 +275,7 @@ public void searchForTeamMembers() { this.personDAO.findAllContainingName(this.searchTerm); for (HPerson person : results) { HLocaleMember localeMember = getLocaleMember(person.getId()); - boolean isMember = localeMember == null ? false : true; + boolean isMember = localeMember != null; boolean isReviewer = false; boolean isTranslator = false; boolean isCoordinator = false; @@ -341,3 +341,4 @@ private void refreshSelected() { } } + diff --git a/zanata-war/src/main/java/org/zanata/notification/DeadLetterQueueReceiver.java b/zanata-war/src/main/java/org/zanata/notification/DeadLetterQueueReceiver.java index 145b7711d5..f2e1459d6e 100644 --- a/zanata-war/src/main/java/org/zanata/notification/DeadLetterQueueReceiver.java +++ b/zanata-war/src/main/java/org/zanata/notification/DeadLetterQueueReceiver.java @@ -20,29 +20,19 @@ */ package org.zanata.notification; -import java.io.Serializable; -import java.util.Collections; -import java.util.List; -import java.util.Map; -import java.util.concurrent.Callable; - import javax.ejb.ActivationConfigProperty; import javax.ejb.MessageDriven; import javax.jms.Message; import javax.jms.MessageListener; -import javax.jms.ObjectMessage; -import javax.jms.TextMessage; -import lombok.AccessLevel; -import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.jboss.seam.annotations.Name; -import com.google.common.base.Objects; -import com.google.common.collect.ImmutableMap; - /** + * Consumer of Dead Letter Queue (all unsuccessful message will be dropped into + * the DLQ and handled here). + * * @author Patrick Huang pahuang@redhat.com */ @@ -65,90 +55,9 @@ public class DeadLetterQueueReceiver implements MessageListener { @Override public void onMessage(Message message) { - log.error("dead message: {}", DeadMessageUnwrapper.unwrap(message)); + // right now we just log the content of the message + log.error("dead message: {}", MessageUnwrapper.unwrap(message)); } - @RequiredArgsConstructor(access = AccessLevel.PRIVATE) - static class DeadMessageUnwrapper { - private final Serializable payload; - private final Map properties; - - static DeadMessageUnwrapper unwrap(final Message message) { - - Serializable payload = extractPayload(message); - Map properties = extractProperties(message); - // we may want to add more interested properties. e.g. reply address - return new DeadMessageUnwrapper(payload, properties); - } - - private static Map extractProperties(final Message message) { - List propNames = - tryDoOrNullOnException(new Callable>() { - @Override - public List call() throws Exception { - return Collections.list(message.getPropertyNames()); - } - }); - - ImmutableMap.Builder builder = - ImmutableMap.builder(); - for (String propName : propNames) { - builder.put(propName, getPropertyValue(message, propName)); - } - return builder.build(); - } - - private static Object getPropertyValue(final Message message, - final String propertyName) { - return tryDoOrNullOnException(new Callable() { - @Override - public Object call() throws Exception { - return message.getObjectProperty(propertyName); - } - }); - } - - /** - * try to extract message payload by message type. - * - * @return message payload - */ - private static Serializable extractPayload(final Message message) { - // note: this is NOT a complete list of message types - if (message instanceof ObjectMessage) { - return tryDoOrNullOnException(new Callable() { - @Override - public Serializable call() throws Exception { - return ((ObjectMessage) message).getObject(); - } - }); - } else if (message instanceof TextMessage) { - return tryDoOrNullOnException(new Callable() { - @Override - public Serializable call() throws Exception { - return ((TextMessage) message).getText(); - } - }); - } else { - // generally this is not going to give us much information - return message.toString(); - } - } - - static T tryDoOrNullOnException(Callable callable) { - try { - return callable.call(); - } catch (Exception e) { - return null; - } - } - - @Override - public String toString() { - return Objects.toStringHelper(this) - .add("payload", payload) - .add("properties", properties) - .toString(); - } - } } + diff --git a/zanata-war/src/main/java/org/zanata/notification/EmailQueueMessageReceiver.java b/zanata-war/src/main/java/org/zanata/notification/EmailQueueMessageReceiver.java index 86e7e720c9..a5293540c0 100644 --- a/zanata-war/src/main/java/org/zanata/notification/EmailQueueMessageReceiver.java +++ b/zanata-war/src/main/java/org/zanata/notification/EmailQueueMessageReceiver.java @@ -44,6 +44,11 @@ import static org.zanata.notification.NotificationManager.MessagePropertiesKey; /** + * JMS EmailsQueue consumer. It will base on + * org.zanata.notification.NotificationManager.MessagePropertiesKey#objectType + * value to find a message payload handler. The objectType value is normally the + * canonical name of the event class. + * * @author Patrick Huang pahuang@redhat.com */ @@ -65,8 +70,7 @@ public class EmailQueueMessageReceiver implements MessageListener { .emptyMap(); @In("languageTeamPermissionChangeJmsMessagePayloadHandler") - private LanguageTeamPermissionChangeJmsMessagePayloadHandler - languageTeamHandler; + private LanguageTeamPermissionChangeJmsMessagePayloadHandler languageTeamHandler; @Override public void onMessage(Message message) { @@ -98,13 +102,15 @@ public void onMessage(Message message) { public Map getHandlers() { if (handlers.isEmpty()) { synchronized (this) { - handlers = - ImmutableMap - . builder() - .put(LanguageTeamPermissionChangedEvent.class - .getCanonicalName(), - languageTeamHandler) - .build(); + if (handlers.isEmpty()) { + handlers = + ImmutableMap + . builder() + .put(LanguageTeamPermissionChangedEvent.class + .getCanonicalName(), + languageTeamHandler) + .build(); + } } log.info("email queue payload handlers: {}", handlers); } @@ -115,3 +121,4 @@ public static interface JmsMessagePayloadHandler { void handle(Serializable data); } } + diff --git a/zanata-war/src/main/java/org/zanata/notification/ExpiryQueueReceiver.java b/zanata-war/src/main/java/org/zanata/notification/ExpiryQueueReceiver.java new file mode 100644 index 0000000000..f658d6790b --- /dev/null +++ b/zanata-war/src/main/java/org/zanata/notification/ExpiryQueueReceiver.java @@ -0,0 +1,58 @@ +/* + * Copyright 2014, Red Hat, Inc. and individual contributors as indicated by the + * @author tags. See the copyright.txt file in the distribution for a full + * listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it under the + * terms of the GNU Lesser General Public License as published by the Free + * Software Foundation; either version 2.1 of the License, or (at your option) + * any later version. + * + * This software is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more + * details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this software; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA, or see the FSF + * site: http://www.fsf.org. + */ +package org.zanata.notification; + +import javax.ejb.ActivationConfigProperty; +import javax.ejb.MessageDriven; +import javax.jms.Message; +import javax.jms.MessageListener; + +import org.jboss.seam.annotations.Name; +import lombok.extern.slf4j.Slf4j; + +@MessageDriven(activationConfig = { + @ActivationConfigProperty( + propertyName = "destinationType", + propertyValue = "javax.jms.Queue" + ), + @ActivationConfigProperty( + propertyName = "destination", + propertyValue = "jms/queue/ExpiryQueue" + ), + @ActivationConfigProperty( + propertyName = "maxSession", + propertyValue = "1") +}) +/** + * Consumer for JMS ExpiryQueue. + * + * @author Patrick Huang + * pahuang@redhat.com + */ +@Name("expiryQueueReceiver") +@Slf4j +public class ExpiryQueueReceiver implements MessageListener { + @Override + public void onMessage(Message message) { + log.warn("JMS message expired: {}", MessageUnwrapper.unwrap(message)); + } +} + diff --git a/zanata-war/src/main/java/org/zanata/notification/LanguageTeamPermissionChangeJmsMessagePayloadHandler.java b/zanata-war/src/main/java/org/zanata/notification/LanguageTeamPermissionChangeJmsMessagePayloadHandler.java index 8e16d15118..bcbb744f5f 100644 --- a/zanata-war/src/main/java/org/zanata/notification/LanguageTeamPermissionChangeJmsMessagePayloadHandler.java +++ b/zanata-war/src/main/java/org/zanata/notification/LanguageTeamPermissionChangeJmsMessagePayloadHandler.java @@ -37,7 +37,10 @@ import lombok.extern.slf4j.Slf4j; /** - * We can only have application or stateless scope beans in here. + * Handles language team permissions change JMS message. This will build and + * send out an email to the person affected. + * N.B. We can only have application or + * stateless scope beans in here. * * @see EmailQueueMessageReceiver * @author Patrick Huang pahuang@redhat.com + */ +@RequiredArgsConstructor(access = AccessLevel.PRIVATE) +class MessageUnwrapper { + private final Serializable payload; + private final Map properties; + + static MessageUnwrapper unwrap(final Message message) { + + Serializable payload = extractPayload(message); + Map properties = extractProperties(message); + // we may want to add more interested properties. e.g. reply address + return new MessageUnwrapper(payload, properties); + } + + private static Map extractProperties(final Message message) { + List propNames = + tryDoOrNullOnException(new Callable>() { + @Override + public List call() throws Exception { + return Collections.list(message.getPropertyNames()); + } + }); + + ImmutableMap.Builder builder = + ImmutableMap.builder(); + for (String propName : propNames) { + builder.put(propName, getPropertyValue(message, propName)); + } + return builder.build(); + } + + private static Object getPropertyValue(final Message message, + final String propertyName) { + return tryDoOrNullOnException(new Callable() { + @Override + public Object call() throws Exception { + return message.getObjectProperty(propertyName); + } + }); + } + + /** + * try to extract message payload by message type. + * + * @return message payload + */ + private static Serializable extractPayload(final Message message) { + // note: this is NOT a complete list of message types + if (message instanceof ObjectMessage) { + return tryDoOrNullOnException(new Callable() { + @Override + public Serializable call() throws Exception { + return ((ObjectMessage) message).getObject(); + } + }); + } else if (message instanceof TextMessage) { + return tryDoOrNullOnException(new Callable() { + @Override + public Serializable call() throws Exception { + return ((TextMessage) message).getText(); + } + }); + } else { + // generally this is not going to give us much information + return message.toString(); + } + } + + static T tryDoOrNullOnException(Callable callable) { + try { + return callable.call(); + } catch (Exception e) { + return null; + } + } + + @Override + public String toString() { + return Objects.toStringHelper(this) + .add("payload", payload) + .add("properties", properties) + .toString(); + } +} + diff --git a/zanata-war/src/main/java/org/zanata/notification/NotificationManager.java b/zanata-war/src/main/java/org/zanata/notification/NotificationManager.java index 30846e2f4a..d4fca9ba7f 100644 --- a/zanata-war/src/main/java/org/zanata/notification/NotificationManager.java +++ b/zanata-war/src/main/java/org/zanata/notification/NotificationManager.java @@ -39,6 +39,12 @@ import com.google.common.base.Throwables; +/** + * Centralized place to handle all events that needs to send out notifications. + * + * @author Patrick Huang pahuang@redhat.com + */ @Name("notificationManager") @Scope(ScopeType.APPLICATION) @Startup @@ -46,6 +52,7 @@ public class NotificationManager implements Serializable { private static final long serialVersionUID = -1L; + // JMS EmailQueue Producer. @In private QueueSender mailQueueSender; @@ -53,7 +60,8 @@ public class NotificationManager implements Serializable { private QueueSession queueSession; @Observer(LanguageTeamPermissionChangedEvent.LANGUAGE_TEAM_PERMISSION_CHANGED) - public void onLanguageTeamPermissionChanged( + public + void onLanguageTeamPermissionChanged( final LanguageTeamPermissionChangedEvent event) { try { ObjectMessage message = @@ -61,13 +69,20 @@ public void onLanguageTeamPermissionChanged( message.setObjectProperty(MessagePropertiesKey.objectType.name(), event.getClass().getCanonicalName()); mailQueueSender.send(message); - } - catch (JMSException e) { + } catch (JMSException e) { throw Throwables.propagate(e); } } + /* + * we use this as property key in the JMS message to denote what type of + * message/event this is and the queue consumer can base on this value to + * find appropriate handler to handle the message payload. + * + * @seeorg.zanata.notification.EmailQueueMessageReceiver + */ static enum MessagePropertiesKey { objectType } } + diff --git a/zanata-war/src/main/resources/messages.properties b/zanata-war/src/main/resources/messages.properties index dd2543acc0..a895c143b1 100644 --- a/zanata-war/src/main/resources/messages.properties +++ b/zanata-war/src/main/resources/messages.properties @@ -707,6 +707,10 @@ jsf.AlreadyInTeam=Already in Team jsf.Reviewer=Reviewer jsf.Translator=Translator jsf.RequestRoleAs=Request the following roles in the "{0}" language team: +jsf.MemberOfTeam=You are now a member of the {0} language team +jsf.LeftTeam=You have left the {0} language team +jsf.AddedAPermission={0} has been made a {1} +jsf.RemovedAPermission={0} has been removed as {1} #------ [home] > Help ------ @@ -1176,10 +1180,10 @@ jsf.email.JoinGroupRequest.ResponseInstructions=Click the link below to go act o jsf.email.group.maintainer.ReceivedReason=You are maintainer in group "{0}" #------ language team permission changed email -jsf.email.languageteam.permission.Subject=Your permission in language team "{0}" has changed +jsf.email.languageteam.permission.Subject=Your permissions in language team "{0}" have changed jsf.email.languageteam.permission.ReceivedReason=You are a team member in the "{0}" language team jsf.email.languageteam.permission.DearName=Dear {0}, -jsf.email.languageteam.permission.Changed={0}({1}) has changed your permission in language team "{2}". +jsf.email.languageteam.permission.Changed={0}({1}) has changed your permissions in language team "{2}". jsf.email.languageteam.permission.old.prefix=You were: jsf.email.languageteam.permission.old.notInTeam=not a team member. jsf.email.languageteam.permission.new.prefix=You are now: @@ -1272,3 +1276,4 @@ javax.faces.validator.LongRangeValidator.TYPE=value is not of the correct type javax.faces.validator.NOT_IN_RANGE=value must be between {0} and {1} javax.faces.converter.STRING=value could not be converted to a string + diff --git a/zanata-war/src/test/resources/arquillian/standalone-arquillian.xml b/zanata-war/src/test/resources/arquillian/standalone-arquillian.xml index f3f478e40f..5767d041f4 100644 --- a/zanata-war/src/test/resources/arquillian/standalone-arquillian.xml +++ b/zanata-war/src/test/resources/arquillian/standalone-arquillian.xml @@ -239,18 +239,9 @@ 102400 2 - - - - - - - - - @@ -285,7 +276,7 @@ - + @@ -298,6 +289,10 @@ true + + + true + true @@ -468,3 +463,4 @@ +