Author: yurize
Date: Mon Feb 6 18:45:52 2012
New Revision: 1241106
URL: http://svn.apache.org/viewvc?rev=1241106&view=rev
Log:
Adds SSL serving capabilites. By [email protected]
https://reviews.apache.org/r/3584/
Modified:
incubator/wave/trunk/server-config.xml
incubator/wave/trunk/server.config.example
incubator/wave/trunk/src/org/waveprotocol/box/server/CoreSettings.java
incubator/wave/trunk/src/org/waveprotocol/box/server/robots/agent/AbstractBaseRobotAgent.java
incubator/wave/trunk/src/org/waveprotocol/box/server/robots/agent/AbstractCliRobotAgent.java
incubator/wave/trunk/src/org/waveprotocol/box/server/robots/agent/welcome/WelcomeRobot.java
incubator/wave/trunk/src/org/waveprotocol/box/server/robots/operations/GravatarProfilesFetcher.java
incubator/wave/trunk/src/org/waveprotocol/box/server/rpc/ServerRpcProvider.java
incubator/wave/trunk/src/org/waveprotocol/box/webclient/client/WebClient.java
incubator/wave/trunk/test/org/waveprotocol/box/server/robots/agent/AbstractRobotAgentTest.java
incubator/wave/trunk/test/org/waveprotocol/box/server/rpc/RpcTest.java
Modified: incubator/wave/trunk/server-config.xml
URL:
http://svn.apache.org/viewvc/incubator/wave/trunk/server-config.xml?rev=1241106&r1=1241105&r2=1241106&view=diff
==============================================================================
--- incubator/wave/trunk/server-config.xml (original)
+++ incubator/wave/trunk/server-config.xml Mon Feb 6 18:45:52 2012
@@ -23,6 +23,9 @@
<property name="wavelet_load_executor_thread_count" value="2" />
<property name="delta_persist_executor_thread_count" value="2" />
<property name="disable_registration" value="false" />
+ <property name="enable_ssl" value="false" />
+ <property name="ssl_keystore_path" value="./wiab.ks" />
+ <property name="ssl_keystore_password" value="" />
<!-- Properties for server.federation.config -->
@@ -85,6 +88,9 @@
<token key="WAVELET_LOAD_EXECUTOR_THREAD_COUNT"
value="${wavelet_load_executor_thread_count}" />
<token key="DELTA_PERSIST_EXECUTOR_THREAD_COUNT"
value="${delta_persist_executor_thread_count}" />
<token key="DISABLE_REGISTRATION" value="${disable_registration}" />
+ <token key="ENABLE_SSL" value="${enable_ssl}" />
+ <token key="SSL_KEYSTORE_PATH" value="${ssl_keystore_path}" />
+ <token key="SSL_KEYSTORE_PASSWORD" value="${ssl_keystore_password}"
/>"
</replacetokens>
</filterchain>
</copy>
Modified: incubator/wave/trunk/server.config.example
URL:
http://svn.apache.org/viewvc/incubator/wave/trunk/server.config.example?rev=1241106&r1=1241105&r2=1241106&view=diff
==============================================================================
--- incubator/wave/trunk/server.config.example (original)
+++ incubator/wave/trunk/server.config.example Mon Feb 6 18:45:52 2012
@@ -114,3 +114,12 @@ waveserver_disable_signer_verification =
# When true, only the admin user can use the RegistrationRobot to add new
accounts
# Default value: false
disable_registration = @DISABLE_REGISTRATION@
+
+# Enable SSL for all address/port combinations listed (makes the next 2
settings non-optional)
+enable_ssl = @ENABLE_SSL@
+
+# Path to keystore containg the ssl certificates to server
+ssl_keystore_path = @SSL_KEYSTORE_PATH@
+
+#Password to the keystore
+ssl_keystore_password = @SSL_KEYSTORE_PASSWORD@
Modified: incubator/wave/trunk/src/org/waveprotocol/box/server/CoreSettings.java
URL:
http://svn.apache.org/viewvc/incubator/wave/trunk/src/org/waveprotocol/box/server/CoreSettings.java?rev=1241106&r1=1241105&r2=1241106&view=diff
==============================================================================
--- incubator/wave/trunk/src/org/waveprotocol/box/server/CoreSettings.java
(original)
+++ incubator/wave/trunk/src/org/waveprotocol/box/server/CoreSettings.java Mon
Feb 6 18:45:52 2012
@@ -54,6 +54,9 @@ public class CoreSettings {
public static final String WAVELET_LOAD_EXECUTOR_THREAD_COUNT =
"wavelet_load_executor_thread_count";
public static final String DELTA_PERSIST_EXECUTOR_THREAD_COUNT =
"delta_persist_executor_thread_count";
public static final String DISABLE_REGISTRATION = "disable_registration";
+ public static final String ENABLE_SSL = "enable_ssl";
+ public static final String SSL_KEYSTORE_PATH = "ssl_keystore_path";
+ public static final String SSL_KEYSTORE_PASSWORD = "ssl_keystore_password";
@Setting(name = WAVE_SERVER_DOMAIN)
private static String waveServerDomain;
@@ -171,8 +174,19 @@ public class CoreSettings {
defaultValue = "2")
private static int deltaPersistExecutorThreadCount;
-
@Setting(name = DISABLE_REGISTRATION,
description = "Prevents the register page from being available to
anyone", defaultValue = "false")
private static boolean disableRegistration;
+
+ @Setting(name = ENABLE_SSL,
+ description = "Enables SSL protocol on all address/port combinations",
defaultValue = "false")
+ private static boolean enableSsl;
+
+ @Setting(name = SSL_KEYSTORE_PATH,
+ description = "Path to the keystore containing SSL certificase to
server", defaultValue = "./wiab.ks")
+ private static String sslKeystorePath;
+
+ @Setting(name = SSL_KEYSTORE_PASSWORD,
+ description = "Password to the SSL keystore", defaultValue = "")
+ private static String sslKeystorePassword;
}
Modified:
incubator/wave/trunk/src/org/waveprotocol/box/server/robots/agent/AbstractBaseRobotAgent.java
URL:
http://svn.apache.org/viewvc/incubator/wave/trunk/src/org/waveprotocol/box/server/robots/agent/AbstractBaseRobotAgent.java?rev=1241106&r1=1241105&r2=1241106&view=diff
==============================================================================
---
incubator/wave/trunk/src/org/waveprotocol/box/server/robots/agent/AbstractBaseRobotAgent.java
(original)
+++
incubator/wave/trunk/src/org/waveprotocol/box/server/robots/agent/AbstractBaseRobotAgent.java
Mon Feb 6 18:45:52 2012
@@ -1,164 +1,170 @@
-/**
- * Copyright 2011 Google Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-package org.waveprotocol.box.server.robots.agent;
-
-import com.google.inject.Inject;
-import com.google.inject.Injector;
-import com.google.inject.Key;
-import com.google.inject.name.Named;
-import com.google.inject.name.Names;
-import com.google.wave.api.AbstractRobot;
-
-import org.waveprotocol.box.server.CoreSettings;
-import org.waveprotocol.box.server.persistence.AccountStore;
-import org.waveprotocol.box.server.persistence.PersistenceException;
-import org.waveprotocol.box.server.robots.register.RobotRegistrar;
-import
org.waveprotocol.box.server.robots.util.RobotsUtil.RobotRegistrationException;
-import org.waveprotocol.wave.model.id.TokenGenerator;
-import org.waveprotocol.wave.model.wave.InvalidParticipantAddress;
-import org.waveprotocol.wave.model.wave.ParticipantId;
-
-import java.util.List;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-
-/**
- * The base for robot agents that run on the WIAB server.
- *
- * @author [email protected] (Yuri Zelikov)
- */
-@SuppressWarnings("serial")
-public abstract class AbstractBaseRobotAgent extends AbstractRobot {
-
- public static class ServerFrontendAddressHolder {
-
- private final List<String> addresses;
-
- @Inject
- ServerFrontendAddressHolder(
- @Named(CoreSettings.HTTP_FRONTEND_ADDRESSES) List<String> addresses) {
- this.addresses = addresses;
- }
-
- public List<String> getAddresses() {
- return addresses;
- }
- }
-
- public static final String AGENT_PREFIX_URI = "/agent";
- private static final Logger LOG =
Logger.getLogger(AbstractBaseRobotAgent.class.getName());
-
- /** The wave server domain. */
- private final String waveDomain;
-
- /** Account store with user and robot accounts. */
- private final AccountStore accountStore;
-
- /** The robot registrar. */
- private final RobotRegistrar robotRegistrar;
-
- private final ServerFrontendAddressHolder frontendAddressHolder;
-
- /**
- * Constructor. Initializes the agent to serve on the URI provided by
- * {@link #getRobotUri()} and ensures that the agent is registered in the
- * Account store.
- *
- * @param injector the injector instance.
- */
- public AbstractBaseRobotAgent(Injector injector) {
- this(injector.getInstance(Key.get(String.class,
Names.named(CoreSettings.WAVE_SERVER_DOMAIN))),
- injector.getInstance(TokenGenerator.class), injector
- .getInstance(ServerFrontendAddressHolder.class), injector
- .getInstance(AccountStore.class),
injector.getInstance(RobotRegistrar.class));
- }
-
- /**
- * Constructor. Initializes the agent to serve on the URI provided by
- * {@link #getRobotUri()} and ensures that the agent is registered in the
- * Account store.
- */
- AbstractBaseRobotAgent(String waveDomain, TokenGenerator tokenGenerator,
- ServerFrontendAddressHolder frontendAddressHolder, AccountStore
accountStore,
- RobotRegistrar robotRegistator) {
- this.waveDomain = waveDomain;
- this.frontendAddressHolder = frontendAddressHolder;
- this.robotRegistrar = robotRegistator;
- this.accountStore = accountStore;
- ensureRegistered(tokenGenerator, getFrontEndAddress());
- }
-
- /**
- * Ensures that the robot agent is registered in the {@link AccountStore}.
- */
- private void ensureRegistered(TokenGenerator tokenGenerator, String
serverFrontendAddress) {
- ParticipantId robotId = null;
- try {
- robotId = ParticipantId.of(getRobotId() + "@" + waveDomain);
- } catch (InvalidParticipantAddress e) {
- LOG.log(Level.SEVERE, "Failed to register the agent:" + getRobotId(), e);
- return;
- }
- try {
- String location = "http://" + serverFrontendAddress + getRobotUri();
- // In order to re-register the agents if the server frontend address has
changed.
- robotRegistrar.registerOrUpdate(robotId, location);
-
- } catch (RobotRegistrationException e) {
- LOG.log(Level.SEVERE, "Failed to register the agent:" + getRobotId(), e);
- } catch (PersistenceException e) {
- LOG.log(Level.SEVERE, "Failed to register the agent:" + getRobotId(), e);
- }
- }
-
- @Override
- protected String getRobotProfilePageUrl() {
- return null;
- }
-
- /**
- * Returns the wave domain.
- */
- public String getWaveDomain() {
- return waveDomain;
- }
-
- /**
- * Returns the front end address.
- */
- public String getFrontEndAddress() {
- return frontendAddressHolder.getAddresses().get(0);
- }
-
- /**
- * Returns the account store.
- */
- protected AccountStore getAccountStore() {
- return accountStore;
- }
-
- /**
- * Returns the robot URI.
- */
- public abstract String getRobotUri();
-
- /**
- * Returns the robot participant id.
- */
- public abstract String getRobotId();
-}
+/**
+ * Copyright 2011 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.waveprotocol.box.server.robots.agent;
+
+import com.google.inject.Inject;
+import com.google.inject.Injector;
+import com.google.inject.Key;
+import com.google.inject.name.Named;
+import com.google.inject.name.Names;
+import com.google.wave.api.AbstractRobot;
+
+import org.waveprotocol.box.server.CoreSettings;
+import org.waveprotocol.box.server.persistence.AccountStore;
+import org.waveprotocol.box.server.persistence.PersistenceException;
+import org.waveprotocol.box.server.robots.register.RobotRegistrar;
+import
org.waveprotocol.box.server.robots.util.RobotsUtil.RobotRegistrationException;
+import org.waveprotocol.wave.model.id.TokenGenerator;
+import org.waveprotocol.wave.model.wave.InvalidParticipantAddress;
+import org.waveprotocol.wave.model.wave.ParticipantId;
+
+import java.util.List;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+/**
+ * The base for robot agents that run on the WIAB server.
+ *
+ * @author [email protected] (Yuri Zelikov)
+ */
+@SuppressWarnings("serial")
+public abstract class AbstractBaseRobotAgent extends AbstractRobot {
+
+ public static class ServerFrontendAddressHolder {
+
+ private final List<String> addresses;
+
+ @Inject
+ ServerFrontendAddressHolder(
+ @Named(CoreSettings.HTTP_FRONTEND_ADDRESSES) List<String> addresses) {
+ this.addresses = addresses;
+ }
+
+ public List<String> getAddresses() {
+ return addresses;
+ }
+ }
+
+ public static final String AGENT_PREFIX_URI = "/agent";
+ private static final Logger LOG =
Logger.getLogger(AbstractBaseRobotAgent.class.getName());
+
+ /** The wave server domain. */
+ private final String waveDomain;
+
+ /** Account store with user and robot accounts. */
+ private final AccountStore accountStore;
+
+ /** SSL enabled flag? */
+ private final Boolean isSSLEnabled;
+
+ /** The robot registrar. */
+ private final RobotRegistrar robotRegistrar;
+
+ private final ServerFrontendAddressHolder frontendAddressHolder;
+
+ /**
+ * Constructor. Initializes the agent to serve on the URI provided by
+ * {@link #getRobotUri()} and ensures that the agent is registered in the
+ * Account store.
+ *
+ * @param injector the injector instance.
+ */
+ public AbstractBaseRobotAgent(Injector injector) {
+ this(injector.getInstance(Key.get(String.class,
Names.named(CoreSettings.WAVE_SERVER_DOMAIN))),
+ injector.getInstance(TokenGenerator.class), injector
+ .getInstance(ServerFrontendAddressHolder.class), injector
+ .getInstance(AccountStore.class),
injector.getInstance(RobotRegistrar.class),
+ injector.getInstance(Key.get(Boolean.class,
Names.named(CoreSettings.ENABLE_SSL))));
+ }
+
+ /**
+ * Constructor. Initializes the agent to serve on the URI provided by
+ * {@link #getRobotUri()} and ensures that the agent is registered in the
+ * Account store.
+ */
+ AbstractBaseRobotAgent(String waveDomain, TokenGenerator tokenGenerator,
+ ServerFrontendAddressHolder frontendAddressHolder, AccountStore
accountStore,
+ RobotRegistrar robotRegistator, Boolean sslEnabled) {
+ this.waveDomain = waveDomain;
+ this.frontendAddressHolder = frontendAddressHolder;
+ this.robotRegistrar = robotRegistator;
+ this.accountStore = accountStore;
+ this.isSSLEnabled = sslEnabled;
+ ensureRegistered(tokenGenerator, getFrontEndAddress());
+ }
+
+ /**
+ * Ensures that the robot agent is registered in the {@link AccountStore}.
+ */
+ private void ensureRegistered(TokenGenerator tokenGenerator, String
serverFrontendAddress) {
+ ParticipantId robotId = null;
+ try {
+ robotId = ParticipantId.of(getRobotId() + "@" + waveDomain);
+ } catch (InvalidParticipantAddress e) {
+ LOG.log(Level.SEVERE, "Failed to register the agent:" + getRobotId(), e);
+ return;
+ }
+ try {
+ String location = serverFrontendAddress + getRobotUri();
+ // In order to re-register the agents if the server frontend address has
changed.
+ robotRegistrar.registerOrUpdate(robotId, location);
+
+ } catch (RobotRegistrationException e) {
+ LOG.log(Level.SEVERE, "Failed to register the agent:" + getRobotId(), e);
+ } catch (PersistenceException e) {
+ LOG.log(Level.SEVERE, "Failed to register the agent:" + getRobotId(), e);
+ }
+ }
+
+ @Override
+ protected String getRobotProfilePageUrl() {
+ return null;
+ }
+
+ /**
+ * Returns the wave domain.
+ */
+ public String getWaveDomain() {
+ return waveDomain;
+ }
+
+ /**
+ * Returns the front end address with correct prefix.
+ */
+ public String getFrontEndAddress() {
+ //TODO(alown): should this really only get the first one?
+ return (this.isSSLEnabled ? "https://" : "http://") +
frontendAddressHolder.getAddresses().get(0);
+ }
+
+ /**
+ * Returns the account store.
+ */
+ protected AccountStore getAccountStore() {
+ return accountStore;
+ }
+
+ /**
+ * Returns the robot URI.
+ */
+ public abstract String getRobotUri();
+
+ /**
+ * Returns the robot participant id.
+ */
+ public abstract String getRobotId();
+}
Modified:
incubator/wave/trunk/src/org/waveprotocol/box/server/robots/agent/AbstractCliRobotAgent.java
URL:
http://svn.apache.org/viewvc/incubator/wave/trunk/src/org/waveprotocol/box/server/robots/agent/AbstractCliRobotAgent.java?rev=1241106&r1=1241105&r2=1241106&view=diff
==============================================================================
---
incubator/wave/trunk/src/org/waveprotocol/box/server/robots/agent/AbstractCliRobotAgent.java
(original)
+++
incubator/wave/trunk/src/org/waveprotocol/box/server/robots/agent/AbstractCliRobotAgent.java
Mon Feb 6 18:45:52 2012
@@ -1,269 +1,270 @@
-/**
- * Copyright 2011 Google Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-package org.waveprotocol.box.server.robots.agent;
-
-import static
org.waveprotocol.box.server.robots.agent.RobotAgentUtil.appendLine;
-import static
org.waveprotocol.box.server.robots.agent.RobotAgentUtil.lastEnteredLineOf;
-
-import com.google.inject.Injector;
-import com.google.inject.Key;
-import com.google.inject.name.Names;
-import com.google.wave.api.Blip;
-import com.google.wave.api.event.DocumentChangedEvent;
-import com.google.wave.api.event.WaveletSelfAddedEvent;
-
-import org.apache.commons.cli.CommandLine;
-import org.apache.commons.cli.CommandLineParser;
-import org.apache.commons.cli.HelpFormatter;
-import org.apache.commons.cli.Option;
-import org.apache.commons.cli.OptionBuilder;
-import org.apache.commons.cli.Options;
-import org.apache.commons.cli.ParseException;
-import org.apache.commons.cli.PosixParser;
-import org.waveprotocol.box.server.CoreSettings;
-import org.waveprotocol.box.server.persistence.AccountStore;
-import org.waveprotocol.box.server.robots.register.RobotRegistrar;
-import org.waveprotocol.box.server.robots.register.RobotRegistrarImpl;
-import org.waveprotocol.wave.model.id.TokenGenerator;
-
-import java.io.PrintWriter;
-import java.io.StringWriter;
-
-/**
- * The base for robot agents that run on the WIAB server and interact with
users
- * by entering commands as text in the blips.
- *
- * @author [email protected] (Yuri Zelikov)
- */
-@SuppressWarnings("serial")
-public abstract class AbstractCliRobotAgent extends AbstractBaseRobotAgent {
-
- /** The options for the command. */
- private final Options options;
- private final CommandLineParser parser;
- private final HelpFormatter helpFormatter;
-
- /**
- * Constructor. Initializes the agent to serve on the URI provided by
- * {@link #getRobotUri()} and ensures that the agent is registered in the
- * Account store.
- *
- * @param injector the injector instance.
- */
- public AbstractCliRobotAgent(Injector injector) {
- this(injector.getInstance(Key.get(String.class,
Names.named(CoreSettings.WAVE_SERVER_DOMAIN))),
- injector.getInstance(TokenGenerator.class), injector
- .getInstance(ServerFrontendAddressHolder.class), injector
- .getInstance(AccountStore.class),
injector.getInstance(RobotRegistrarImpl.class));
- }
-
- /**
- * Constructor. Initializes the agent to serve on the URI provided by
- * {@link #getRobotUri()} and ensures that the agent is registered in the
- * Account store.
- */
- AbstractCliRobotAgent(String waveDomain, TokenGenerator tokenGenerator,
- ServerFrontendAddressHolder frontendAddressHolder, AccountStore
accountStore,
- RobotRegistrar robotRegistrar) {
- super(waveDomain, tokenGenerator, frontendAddressHolder, accountStore,
robotRegistrar);
- parser = new PosixParser();
- helpFormatter = new HelpFormatter();
- options = initOptions();
- }
-
- /**
- * Displays a short description when the robot is added to a wave.
- */
- @Override
- public void onWaveletSelfAdded(WaveletSelfAddedEvent event) {
- String robotAddress = event.getWavelet().getRobotAddress();
- // Display a short description.
- appendLine(event.getBlip(), "\n" + robotAddress + ": I am listening.\n" +
getShortDescription()
- + "\nFor help type " + "\"" + getCommandName()
- + " -help\" on a new line and hit \"Enter\".");
- }
-
- @Override
- public void onDocumentChanged(DocumentChangedEvent event) {
- Blip blip = event.getBlip();
- String modifiedBy = event.getModifiedBy();
- CommandLine commandLine = null;
- try {
- commandLine = preprocessCommand(blip.getContent());
- } catch (IllegalArgumentException e) {
- appendLine(blip, e.getMessage());
- }
- if (commandLine != null) {
- if (commandLine.hasOption("help")
- // Or if only options.
- || (commandLine.getArgs().length - commandLine.getOptions().length
<= 1)) {
- appendLine(blip, getFullDescription());
- } else {
- String robotMessage = maybeExecuteCommand(commandLine, modifiedBy);
- appendLine(blip, robotMessage);
- }
- }
- }
-
- /**
- * Validates and parses the input for the command.
- *
- * @param blipContent the blip contents.
- * @return the command line {@link CommandLine} object with parsed data from
- * the blip contents or null in case the content doesn't contain a
- * command.
- * @throws IllegalArgumentException if illegal arguments passed to the
- * command.
- */
- protected CommandLine preprocessCommand(String blipContent) throws
IllegalArgumentException {
- CommandLine commandLine = null;
- String lastLine = lastEnteredLineOf(blipContent);
- if (lastLine != null) {
- try {
- commandLine = parse(lastLine.split(" "));
- } catch (ParseException e) {
- throw new IllegalArgumentException(e);
- }
- String[] args = commandLine.getArgs();
- if (!args[0].equals(getCommandName())) {
- return null;
- }
- int argsNum = args.length - commandLine.getOptions().length - 1;
- // If there are only options in the command - then it is also invalid and
- // have to display usage anyway.
- if ((argsNum > 0)
- && (argsNum < getMinNumOfArguments() || argsNum >
getMaxNumOfArguments())) {
- String message = null;
- if (getMinNumOfArguments() == getMaxNumOfArguments()) {
- message =
- String.format("Invalid number of arguments. Expected: %d , actual:
%d %s",
- getMinNumOfArguments(), argsNum, getUsage());
- } else {
- message =
- String.format(
- "Invalid number of arguments. Expected between %d and %d,
actual: %d. %s",
- getMinNumOfArguments(), getMaxNumOfArguments(), argsNum,
getUsage());
- }
- throw new IllegalArgumentException(message);
- }
- }
- return commandLine;
- }
-
- @Override
- protected String getRobotProfilePageUrl() {
- return null;
- }
-
- /**
- * Returns the command options usage.
- */
- public String getUsage() {
- StringWriter stringWriter = new StringWriter();
- PrintWriter pw = new PrintWriter(stringWriter);
- // HelpFormatter doesn't provide other ways to access defaultWidth, so we
- // forced to access it in a deprecated way.
- // TODO (user) Update this code to remove access of deprecated fields when
- // it will be possible.
- helpFormatter.printHelp(pw, helpFormatter.defaultWidth, getCommandName() +
" "
- + getCmdLineSyntax() + " \n", null, options,
helpFormatter.defaultLeftPad,
- helpFormatter.defaultDescPad, "", false);
- pw.flush();
- String usageStr = stringWriter.toString();
- return usageStr;
- }
-
- /**
- * Initializes basic options. Override if more options needed.
- *
- * @return the command options.
- */
- protected Options initOptions() {
- // Create Options.
- Options options = new Options();
- // The robot has only "help" option.
- @SuppressWarnings("static-access")
- Option help = OptionBuilder.withDescription("Displays help for the
command.").create("help");
- options.addOption(help);
- return options;
- }
-
- protected CommandLine parse(String... args) throws ParseException {
- return getParser().parse(getOptions(), args);
- }
-
- /**
- * Returns the command line parser.
- */
- protected CommandLineParser getParser() {
- return parser;
- }
-
- /**
- * Returns the command options.
- */
- protected Options getOptions() {
- return options;
- }
-
- /**
- * Attempts to execute the command.
- *
- * @param commandLine the commandLine with arguments and/or options entered
by
- * the user.
- * @param modifiedBy the user that entered the content.
- * @return the result message: success or failure.
- */
- protected abstract String maybeExecuteCommand(CommandLine commandLine,
String modifiedBy);
-
- /**
- * Returns the short description of the robot.
- */
- public abstract String getShortDescription();
-
- /**
- * Returns the full robot description.
- */
- public abstract String getFullDescription();
-
- /**
- * Returns the command name for the robot.
- */
- public abstract String getCommandName();
-
- /**
- * Returns the command line syntax.
- */
- public abstract String getCmdLineSyntax();
-
- /**
- * Returns the command use example.
- */
- public abstract String getExample();
-
- /**
- * Returns the minimum number of arguments this command accepts. Should be
- * greater than zero and less or equal to {@link #getMaxNumOfArguments()}.
- */
- public abstract int getMinNumOfArguments();
-
- /**
- * Returns the maximum number of arguments this command accepts.
- */
- public abstract int getMaxNumOfArguments();
-}
+/**
+ * Copyright 2011 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.waveprotocol.box.server.robots.agent;
+
+import static
org.waveprotocol.box.server.robots.agent.RobotAgentUtil.appendLine;
+import static
org.waveprotocol.box.server.robots.agent.RobotAgentUtil.lastEnteredLineOf;
+
+import com.google.inject.Injector;
+import com.google.inject.Key;
+import com.google.inject.name.Names;
+import com.google.wave.api.Blip;
+import com.google.wave.api.event.DocumentChangedEvent;
+import com.google.wave.api.event.WaveletSelfAddedEvent;
+
+import org.apache.commons.cli.CommandLine;
+import org.apache.commons.cli.CommandLineParser;
+import org.apache.commons.cli.HelpFormatter;
+import org.apache.commons.cli.Option;
+import org.apache.commons.cli.OptionBuilder;
+import org.apache.commons.cli.Options;
+import org.apache.commons.cli.ParseException;
+import org.apache.commons.cli.PosixParser;
+import org.waveprotocol.box.server.CoreSettings;
+import org.waveprotocol.box.server.persistence.AccountStore;
+import org.waveprotocol.box.server.robots.register.RobotRegistrar;
+import org.waveprotocol.box.server.robots.register.RobotRegistrarImpl;
+import org.waveprotocol.wave.model.id.TokenGenerator;
+
+import java.io.PrintWriter;
+import java.io.StringWriter;
+
+/**
+ * The base for robot agents that run on the WIAB server and interact with
users
+ * by entering commands as text in the blips.
+ *
+ * @author [email protected] (Yuri Zelikov)
+ */
+@SuppressWarnings("serial")
+public abstract class AbstractCliRobotAgent extends AbstractBaseRobotAgent {
+
+ /** The options for the command. */
+ private final Options options;
+ private final CommandLineParser parser;
+ private final HelpFormatter helpFormatter;
+
+ /**
+ * Constructor. Initializes the agent to serve on the URI provided by
+ * {@link #getRobotUri()} and ensures that the agent is registered in the
+ * Account store.
+ *
+ * @param injector the injector instance.
+ */
+ public AbstractCliRobotAgent(Injector injector) {
+ this(injector.getInstance(Key.get(String.class,
Names.named(CoreSettings.WAVE_SERVER_DOMAIN))),
+ injector.getInstance(TokenGenerator.class), injector
+ .getInstance(ServerFrontendAddressHolder.class), injector
+ .getInstance(AccountStore.class),
injector.getInstance(RobotRegistrarImpl.class),
+ injector.getInstance(Key.get(Boolean.class,
Names.named(CoreSettings.ENABLE_SSL))));
+ }
+
+ /**
+ * Constructor. Initializes the agent to serve on the URI provided by
+ * {@link #getRobotUri()} and ensures that the agent is registered in the
+ * Account store.
+ */
+ AbstractCliRobotAgent(String waveDomain, TokenGenerator tokenGenerator,
+ ServerFrontendAddressHolder frontendAddressHolder, AccountStore
accountStore,
+ RobotRegistrar robotRegistrar, Boolean sslEnabled) {
+ super(waveDomain, tokenGenerator, frontendAddressHolder, accountStore,
robotRegistrar, sslEnabled);
+ parser = new PosixParser();
+ helpFormatter = new HelpFormatter();
+ options = initOptions();
+ }
+
+ /**
+ * Displays a short description when the robot is added to a wave.
+ */
+ @Override
+ public void onWaveletSelfAdded(WaveletSelfAddedEvent event) {
+ String robotAddress = event.getWavelet().getRobotAddress();
+ // Display a short description.
+ appendLine(event.getBlip(), "\n" + robotAddress + ": I am listening.\n" +
getShortDescription()
+ + "\nFor help type " + "\"" + getCommandName()
+ + " -help\" on a new line and hit \"Enter\".");
+ }
+
+ @Override
+ public void onDocumentChanged(DocumentChangedEvent event) {
+ Blip blip = event.getBlip();
+ String modifiedBy = event.getModifiedBy();
+ CommandLine commandLine = null;
+ try {
+ commandLine = preprocessCommand(blip.getContent());
+ } catch (IllegalArgumentException e) {
+ appendLine(blip, e.getMessage());
+ }
+ if (commandLine != null) {
+ if (commandLine.hasOption("help")
+ // Or if only options.
+ || (commandLine.getArgs().length - commandLine.getOptions().length
<= 1)) {
+ appendLine(blip, getFullDescription());
+ } else {
+ String robotMessage = maybeExecuteCommand(commandLine, modifiedBy);
+ appendLine(blip, robotMessage);
+ }
+ }
+ }
+
+ /**
+ * Validates and parses the input for the command.
+ *
+ * @param blipContent the blip contents.
+ * @return the command line {@link CommandLine} object with parsed data from
+ * the blip contents or null in case the content doesn't contain a
+ * command.
+ * @throws IllegalArgumentException if illegal arguments passed to the
+ * command.
+ */
+ protected CommandLine preprocessCommand(String blipContent) throws
IllegalArgumentException {
+ CommandLine commandLine = null;
+ String lastLine = lastEnteredLineOf(blipContent);
+ if (lastLine != null) {
+ try {
+ commandLine = parse(lastLine.split(" "));
+ } catch (ParseException e) {
+ throw new IllegalArgumentException(e);
+ }
+ String[] args = commandLine.getArgs();
+ if (!args[0].equals(getCommandName())) {
+ return null;
+ }
+ int argsNum = args.length - commandLine.getOptions().length - 1;
+ // If there are only options in the command - then it is also invalid and
+ // have to display usage anyway.
+ if ((argsNum > 0)
+ && (argsNum < getMinNumOfArguments() || argsNum >
getMaxNumOfArguments())) {
+ String message = null;
+ if (getMinNumOfArguments() == getMaxNumOfArguments()) {
+ message =
+ String.format("Invalid number of arguments. Expected: %d , actual:
%d %s",
+ getMinNumOfArguments(), argsNum, getUsage());
+ } else {
+ message =
+ String.format(
+ "Invalid number of arguments. Expected between %d and %d,
actual: %d. %s",
+ getMinNumOfArguments(), getMaxNumOfArguments(), argsNum,
getUsage());
+ }
+ throw new IllegalArgumentException(message);
+ }
+ }
+ return commandLine;
+ }
+
+ @Override
+ protected String getRobotProfilePageUrl() {
+ return null;
+ }
+
+ /**
+ * Returns the command options usage.
+ */
+ public String getUsage() {
+ StringWriter stringWriter = new StringWriter();
+ PrintWriter pw = new PrintWriter(stringWriter);
+ // HelpFormatter doesn't provide other ways to access defaultWidth, so we
+ // forced to access it in a deprecated way.
+ // TODO (user) Update this code to remove access of deprecated fields when
+ // it will be possible.
+ helpFormatter.printHelp(pw, helpFormatter.defaultWidth, getCommandName() +
" "
+ + getCmdLineSyntax() + " \n", null, options,
helpFormatter.defaultLeftPad,
+ helpFormatter.defaultDescPad, "", false);
+ pw.flush();
+ String usageStr = stringWriter.toString();
+ return usageStr;
+ }
+
+ /**
+ * Initializes basic options. Override if more options needed.
+ *
+ * @return the command options.
+ */
+ protected Options initOptions() {
+ // Create Options.
+ Options options = new Options();
+ // The robot has only "help" option.
+ @SuppressWarnings("static-access")
+ Option help = OptionBuilder.withDescription("Displays help for the
command.").create("help");
+ options.addOption(help);
+ return options;
+ }
+
+ protected CommandLine parse(String... args) throws ParseException {
+ return getParser().parse(getOptions(), args);
+ }
+
+ /**
+ * Returns the command line parser.
+ */
+ protected CommandLineParser getParser() {
+ return parser;
+ }
+
+ /**
+ * Returns the command options.
+ */
+ protected Options getOptions() {
+ return options;
+ }
+
+ /**
+ * Attempts to execute the command.
+ *
+ * @param commandLine the commandLine with arguments and/or options entered
by
+ * the user.
+ * @param modifiedBy the user that entered the content.
+ * @return the result message: success or failure.
+ */
+ protected abstract String maybeExecuteCommand(CommandLine commandLine,
String modifiedBy);
+
+ /**
+ * Returns the short description of the robot.
+ */
+ public abstract String getShortDescription();
+
+ /**
+ * Returns the full robot description.
+ */
+ public abstract String getFullDescription();
+
+ /**
+ * Returns the command name for the robot.
+ */
+ public abstract String getCommandName();
+
+ /**
+ * Returns the command line syntax.
+ */
+ public abstract String getCmdLineSyntax();
+
+ /**
+ * Returns the command use example.
+ */
+ public abstract String getExample();
+
+ /**
+ * Returns the minimum number of arguments this command accepts. Should be
+ * greater than zero and less or equal to {@link #getMaxNumOfArguments()}.
+ */
+ public abstract int getMinNumOfArguments();
+
+ /**
+ * Returns the maximum number of arguments this command accepts.
+ */
+ public abstract int getMaxNumOfArguments();
+}
Modified:
incubator/wave/trunk/src/org/waveprotocol/box/server/robots/agent/welcome/WelcomeRobot.java
URL:
http://svn.apache.org/viewvc/incubator/wave/trunk/src/org/waveprotocol/box/server/robots/agent/welcome/WelcomeRobot.java?rev=1241106&r1=1241105&r2=1241106&view=diff
==============================================================================
---
incubator/wave/trunk/src/org/waveprotocol/box/server/robots/agent/welcome/WelcomeRobot.java
(original)
+++
incubator/wave/trunk/src/org/waveprotocol/box/server/robots/agent/welcome/WelcomeRobot.java
Mon Feb 6 18:45:52 2012
@@ -1,124 +1,124 @@
-/**
- * Copyright 2011 Google Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-package org.waveprotocol.box.server.robots.agent.welcome;
-
-import static
org.waveprotocol.box.server.robots.agent.RobotAgentUtil.appendLine;
-
-import com.google.common.base.Preconditions;
-import com.google.common.collect.Sets;
-import com.google.inject.Inject;
-import com.google.inject.Injector;
-import com.google.inject.Key;
-import com.google.inject.Singleton;
-import com.google.inject.name.Names;
-import com.google.wave.api.Wavelet;
-
-import org.waveprotocol.box.server.CoreSettings;
-import org.waveprotocol.box.server.account.RobotAccountData;
-import org.waveprotocol.box.server.persistence.PersistenceException;
-import org.waveprotocol.box.server.robots.agent.AbstractBaseRobotAgent;
-import org.waveprotocol.box.server.robots.agent.passwd.PasswordRobot;
-import org.waveprotocol.box.server.robots.util.RobotsUtil;
-import org.waveprotocol.wave.model.id.InvalidIdException;
-import org.waveprotocol.wave.model.id.WaveId;
-import org.waveprotocol.wave.model.id.WaveletId;
-import org.waveprotocol.wave.model.wave.ParticipantId;
-
-import java.io.IOException;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-
-
-/**
- * The robot that adds a "Welcome" wave to the inbox of new users.
- *
- * @author [email protected] (Yuri Zelikov)
- */
-@SuppressWarnings("serial")
-@Singleton
-public class WelcomeRobot extends AbstractBaseRobotAgent {
-
-
- private static final Logger LOG =
Logger.getLogger(PasswordRobot.class.getName());
- public static final String ROBOT_URI = AGENT_PREFIX_URI + "/welcome";
-
- /** The id of the wave that serves as a template for the welcome wave. */
- private WaveId welcomeWaveId = null;
-
- @Inject
- public WelcomeRobot(Injector injector) {
- super(injector);
- String welcomeWaveIdStr =
- injector.getInstance(Key.get(String.class,
Names.named(CoreSettings.WELCOME_WAVE_ID)));
- if (!"UNDEFINED".equals(welcomeWaveIdStr)) {
- try {
- welcomeWaveId = WaveId.ofChecked(getWaveDomain(), welcomeWaveIdStr);
- } catch (InvalidIdException e) {
- LOG.log(Level.WARNING, "Problem parsing welcome wave id: " +
welcomeWaveIdStr);
- }
- }
- }
-
- /**
- * Greets new users by creating a new wave with welcome message and
- * adding it to the inbox of the new user.
- *
- * @param id the participant id of the new user.
- * @throws IOException if there is a problem submitting the new wave.
- */
- public void greet(ParticipantId id) throws IOException {
- Preconditions.checkNotNull(id);
- RobotAccountData account = null;
- String rpcUrl = "http://" + getFrontEndAddress() + "/robot/rpc";
- try {
- account =
- getAccountStore()
- .getAccount(ParticipantId.ofUnsafe(getRobotId() + "@" +
getWaveDomain())).asRobot();
- } catch (PersistenceException e) {
- LOG.log(Level.WARNING, "Cannot fetch account data for robot id: " +
getRobotId(), e);
- }
- if (account != null) {
- setupOAuth(account.getId().getAddress(), account.getConsumerSecret(),
rpcUrl);
- Wavelet newWelcomeWavelet = newWave(getWaveDomain(),
Sets.newHashSet(id.getAddress()));
- if (welcomeWaveId != null) {
- Wavelet templateWelcomeWavelet =
- fetchWavelet(welcomeWaveId, WaveletId.of(getWaveDomain(),
"conv+root"), rpcUrl);
- RobotsUtil.copyBlipContents(templateWelcomeWavelet.getRootBlip(),
- newWelcomeWavelet.getRootBlip());
- } else {
- appendLine(newWelcomeWavelet.getRootBlip(), "Welcome to " +
getWaveDomain() + "!");
- }
- submit(newWelcomeWavelet, rpcUrl);
- }
- }
-
- @Override
- public String getRobotUri() {
- return ROBOT_URI;
- }
-
- @Override
- public String getRobotId() {
- return "welcome-bot";
- }
-
- @Override
- protected String getRobotName() {
- return "Welcome-Bot";
- }
-}
+/**
+ * Copyright 2011 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.waveprotocol.box.server.robots.agent.welcome;
+
+import static
org.waveprotocol.box.server.robots.agent.RobotAgentUtil.appendLine;
+
+import com.google.common.base.Preconditions;
+import com.google.common.collect.Sets;
+import com.google.inject.Inject;
+import com.google.inject.Injector;
+import com.google.inject.Key;
+import com.google.inject.Singleton;
+import com.google.inject.name.Names;
+import com.google.wave.api.Wavelet;
+
+import org.waveprotocol.box.server.CoreSettings;
+import org.waveprotocol.box.server.account.RobotAccountData;
+import org.waveprotocol.box.server.persistence.PersistenceException;
+import org.waveprotocol.box.server.robots.agent.AbstractBaseRobotAgent;
+import org.waveprotocol.box.server.robots.agent.passwd.PasswordRobot;
+import org.waveprotocol.box.server.robots.util.RobotsUtil;
+import org.waveprotocol.wave.model.id.InvalidIdException;
+import org.waveprotocol.wave.model.id.WaveId;
+import org.waveprotocol.wave.model.id.WaveletId;
+import org.waveprotocol.wave.model.wave.ParticipantId;
+
+import java.io.IOException;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+
+/**
+ * The robot that adds a "Welcome" wave to the inbox of new users.
+ *
+ * @author [email protected] (Yuri Zelikov)
+ */
+@SuppressWarnings("serial")
+@Singleton
+public class WelcomeRobot extends AbstractBaseRobotAgent {
+
+
+ private static final Logger LOG =
Logger.getLogger(PasswordRobot.class.getName());
+ public static final String ROBOT_URI = AGENT_PREFIX_URI + "/welcome";
+
+ /** The id of the wave that serves as a template for the welcome wave. */
+ private WaveId welcomeWaveId = null;
+
+ @Inject
+ public WelcomeRobot(Injector injector) {
+ super(injector);
+ String welcomeWaveIdStr =
+ injector.getInstance(Key.get(String.class,
Names.named(CoreSettings.WELCOME_WAVE_ID)));
+ if (!"UNDEFINED".equals(welcomeWaveIdStr)) {
+ try {
+ welcomeWaveId = WaveId.ofChecked(getWaveDomain(), welcomeWaveIdStr);
+ } catch (InvalidIdException e) {
+ LOG.log(Level.WARNING, "Problem parsing welcome wave id: " +
welcomeWaveIdStr);
+ }
+ }
+ }
+
+ /**
+ * Greets new users by creating a new wave with welcome message and
+ * adding it to the inbox of the new user.
+ *
+ * @param id the participant id of the new user.
+ * @throws IOException if there is a problem submitting the new wave.
+ */
+ public void greet(ParticipantId id) throws IOException {
+ Preconditions.checkNotNull(id);
+ RobotAccountData account = null;
+ String rpcUrl = getFrontEndAddress() + "/robot/rpc";
+ try {
+ account =
+ getAccountStore()
+ .getAccount(ParticipantId.ofUnsafe(getRobotId() + "@" +
getWaveDomain())).asRobot();
+ } catch (PersistenceException e) {
+ LOG.log(Level.WARNING, "Cannot fetch account data for robot id: " +
getRobotId(), e);
+ }
+ if (account != null) {
+ setupOAuth(account.getId().getAddress(), account.getConsumerSecret(),
rpcUrl);
+ Wavelet newWelcomeWavelet = newWave(getWaveDomain(),
Sets.newHashSet(id.getAddress()));
+ if (welcomeWaveId != null) {
+ Wavelet templateWelcomeWavelet =
+ fetchWavelet(welcomeWaveId, WaveletId.of(getWaveDomain(),
"conv+root"), rpcUrl);
+ RobotsUtil.copyBlipContents(templateWelcomeWavelet.getRootBlip(),
+ newWelcomeWavelet.getRootBlip());
+ } else {
+ appendLine(newWelcomeWavelet.getRootBlip(), "Welcome to " +
getWaveDomain() + "!");
+ }
+ submit(newWelcomeWavelet, rpcUrl);
+ }
+ }
+
+ @Override
+ public String getRobotUri() {
+ return ROBOT_URI;
+ }
+
+ @Override
+ public String getRobotId() {
+ return "welcome-bot";
+ }
+
+ @Override
+ protected String getRobotName() {
+ return "Welcome-Bot";
+ }
+}
Modified:
incubator/wave/trunk/src/org/waveprotocol/box/server/robots/operations/GravatarProfilesFetcher.java
URL:
http://svn.apache.org/viewvc/incubator/wave/trunk/src/org/waveprotocol/box/server/robots/operations/GravatarProfilesFetcher.java?rev=1241106&r1=1241105&r2=1241106&view=diff
==============================================================================
---
incubator/wave/trunk/src/org/waveprotocol/box/server/robots/operations/GravatarProfilesFetcher.java
(original)
+++
incubator/wave/trunk/src/org/waveprotocol/box/server/robots/operations/GravatarProfilesFetcher.java
Mon Feb 6 18:45:52 2012
@@ -28,12 +28,12 @@ import org.waveprotocol.box.server.robot
* gravatar.com and adding their wave address to the main profile. It is
* impossible to create a main profile with wave address since gravatar
requires
* email address verification.
- *
+*
* @author [email protected] (Yuri Zelikov)
*/
public class GravatarProfilesFetcher implements ProfilesFetcher {
- private static final String GRAVATAR_URL = "http://www.gravatar.com/avatar/";
+ private static final String GRAVATAR_URL =
"https://secure.gravatar.com/avatar/";
public static GravatarProfilesFetcher create() {
return new GravatarProfilesFetcher();
Modified:
incubator/wave/trunk/src/org/waveprotocol/box/server/rpc/ServerRpcProvider.java
URL:
http://svn.apache.org/viewvc/incubator/wave/trunk/src/org/waveprotocol/box/server/rpc/ServerRpcProvider.java?rev=1241106&r1=1241105&r2=1241106&view=diff
==============================================================================
---
incubator/wave/trunk/src/org/waveprotocol/box/server/rpc/ServerRpcProvider.java
(original)
+++
incubator/wave/trunk/src/org/waveprotocol/box/server/rpc/ServerRpcProvider.java
Mon Feb 6 18:45:52 2012
@@ -44,12 +44,15 @@ import com.glines.socketio.server.transp
import com.glines.socketio.server.transport.XHRPollingTransport;
import com.glines.socketio.server.transport.jetty.JettyWebSocketTransport;
+import org.eclipse.jetty.http.ssl.SslContextFactory;
+import org.eclipse.jetty.server.ssl.SslSocketConnector;
import org.eclipse.jetty.server.Connector;
import org.eclipse.jetty.server.Server;
-import org.eclipse.jetty.server.nio.SelectChannelConnector;
+import org.eclipse.jetty.server.bio.SocketConnector;
import org.eclipse.jetty.server.session.HashSessionManager;
import org.eclipse.jetty.servlet.DefaultServlet;
import org.eclipse.jetty.servlet.ServletHolder;
+import org.eclipse.jetty.servlets.GzipFilter;
import org.eclipse.jetty.util.resource.ResourceCollection;
import org.eclipse.jetty.webapp.WebAppContext;
import org.eclipse.jetty.websocket.WebSocket;
@@ -108,6 +111,9 @@ public class ServerRpcProvider {
private final SessionManager sessionManager;
private final org.eclipse.jetty.server.SessionManager jettySessionManager;
private Server httpServer = null;
+ private final boolean sslEnabled;
+ private final String sslKeystorePath;
+ private final String sslKeystorePassword;
// Mapping from incoming protocol buffer type -> specific handler.
private final Map<Descriptors.Descriptor, RegisteredServiceMethod>
registeredServices =
@@ -305,7 +311,8 @@ public class ServerRpcProvider {
*/
public ServerRpcProvider(InetSocketAddress[] httpAddresses, Integer
flashsocketPolicyPort,
String[] resourceBases, ExecutorService threadPool, SessionManager
sessionManager,
- org.eclipse.jetty.server.SessionManager jettySessionManager, String
sessionStoreDir) {
+ org.eclipse.jetty.server.SessionManager jettySessionManager, String
sessionStoreDir,
+ boolean sslEnabled, String sslKeystorePath, String sslKeystorePassword) {
this.httpAddresses = httpAddresses;
this.flashsocketPolicyPort = flashsocketPolicyPort;
this.resourceBases = resourceBases;
@@ -313,6 +320,9 @@ public class ServerRpcProvider {
this.sessionManager = sessionManager;
this.jettySessionManager = jettySessionManager;
this.sessionStoreDir = sessionStoreDir;
+ this.sslEnabled = sslEnabled;
+ this.sslKeystorePath = sslKeystorePath;
+ this.sslKeystorePassword = sslKeystorePassword;
}
/**
@@ -320,28 +330,35 @@ public class ServerRpcProvider {
*/
public ServerRpcProvider(InetSocketAddress[] httpAddresses, Integer
flashsocketPolicyPort,
String[] resourceBases, SessionManager sessionManager,
- org.eclipse.jetty.server.SessionManager jettySessionManager, String
sessionStoreDir) {
+ org.eclipse.jetty.server.SessionManager jettySessionManager, String
sessionStoreDir,
+ boolean sslEnabled, String sslKeystorePath, String sslKeystorePassword) {
this(httpAddresses, flashsocketPolicyPort, resourceBases,
Executors.newCachedThreadPool(),
- sessionManager, jettySessionManager, sessionStoreDir);
+ sessionManager, jettySessionManager, sessionStoreDir, sslEnabled,
sslKeystorePath,
+ sslKeystorePassword);
}
@Inject
public ServerRpcProvider(@Named(CoreSettings.HTTP_FRONTEND_ADDRESSES)
List<String> httpAddresses,
@Named(CoreSettings.FLASHSOCKET_POLICY_PORT) Integer
flashsocketPolicyPort,
@Named(CoreSettings.RESOURCE_BASES) List<String> resourceBases,
- SessionManager sessionManager, org.eclipse.jetty.server.SessionManager
jettySessionManager, @Named(CoreSettings.SESSIONS_STORE_DIRECTORY) String
sessionStoreDir) {
+ SessionManager sessionManager, org.eclipse.jetty.server.SessionManager
jettySessionManager,
+ @Named(CoreSettings.SESSIONS_STORE_DIRECTORY) String sessionStoreDir,
+ @Named(CoreSettings.ENABLE_SSL) boolean sslEnabled,
+ @Named(CoreSettings.SSL_KEYSTORE_PATH) String sslKeystorePath,
+ @Named(CoreSettings.SSL_KEYSTORE_PASSWORD) String sslKeystorePassword) {
this(parseAddressList(httpAddresses), flashsocketPolicyPort, resourceBases
- .toArray(new String[0]), sessionManager, jettySessionManager,
sessionStoreDir);
+ .toArray(new String[0]), sessionManager, jettySessionManager,
sessionStoreDir,
+ sslEnabled, sslKeystorePath, sslKeystorePassword);
}
public void startWebSocketServer(final Injector injector) {
httpServer = new Server();
- List<SelectChannelConnector> connectors =
getSelectChannelConnectors(httpAddresses);
+ List<SocketConnector> connectors = getSocketConnectors(httpAddresses);
if (connectors.isEmpty()) {
LOG.severe("No valid http end point address provided!");
}
- for (SelectChannelConnector connector : connectors) {
+ for (SocketConnector connector : connectors) {
httpServer.addConnector(connector);
}
final WebAppContext context = new WebAppContext();
@@ -378,6 +395,7 @@ public class ServerRpcProvider {
context.addEventListener(contextListener);
context.addFilter(GuiceFilter.class, "/*",
EnumSet.allOf(DispatcherType.class));
+ context.addFilter(GzipFilter.class, "/webclient/*",
EnumSet.allOf(DispatcherType.class));
httpServer.setHandler(context);
httpServer.start();
@@ -492,14 +510,37 @@ public class ServerRpcProvider {
}
/**
- * @return a list of {@link SelectChannelConnector} each bound to a host:port
+ * @return a list of {@link SocketConnector} each bound to a host:port
* pair form the list addresses.
*/
- private List<SelectChannelConnector> getSelectChannelConnectors(
+ private List<SocketConnector> getSocketConnectors(
InetSocketAddress[] httpAddresses) {
- List<SelectChannelConnector> list = Lists.newArrayList();
+ List<SocketConnector> list = Lists.newArrayList();
+ String[] excludeCiphers = {"SSL_RSA_EXPORT_WITH_RC4_40_MD5",
"SSL_RSA_EXPORT_WITH_DES40_CBC_SHA",
+ "SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA",
"SSL_RSA_WITH_DES_CBC_SHA",
+ "SSL_DHE_RSA_WITH_DES_CBC_SHA",
"TLS_DHE_RSA_WITH_AES_128_CBC_SHA",
+ "SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA",
"TLS_DHE_RSA_WITH_AES_256_CBC_SHA"};
+ SslContextFactory sslContextFactory = null;
+
+ if (sslEnabled) {
+ Preconditions.checkState(sslKeystorePath != null &&
!sslKeystorePath.isEmpty(),
+ "SSL Keystore path left blank");
+ Preconditions.checkState(sslKeystorePassword != null &&
!sslKeystorePassword.isEmpty(),
+ "SSL Keystore password left blank");
+
+ sslContextFactory = new SslContextFactory(sslKeystorePath);
+ sslContextFactory.setKeyStorePassword(sslKeystorePassword);
+ sslContextFactory.setAllowRenegotiate(false);
+ sslContextFactory.setExcludeCipherSuites(excludeCiphers);
+ }
+
for (InetSocketAddress address : httpAddresses) {
- SelectChannelConnector connector = new SelectChannelConnector();
+ SocketConnector connector;
+ if (sslEnabled) {
+ connector = new SslSocketConnector(sslContextFactory);
+ } else {
+ connector = new SocketConnector();
+ }
connector.setHost(address.getAddress().getHostAddress());
connector.setPort(address.getPort());
connector.setMaxIdleTime(0);
Modified:
incubator/wave/trunk/src/org/waveprotocol/box/webclient/client/WebClient.java
URL:
http://svn.apache.org/viewvc/incubator/wave/trunk/src/org/waveprotocol/box/webclient/client/WebClient.java?rev=1241106&r1=1241105&r2=1241106&view=diff
==============================================================================
---
incubator/wave/trunk/src/org/waveprotocol/box/webclient/client/WebClient.java
(original)
+++
incubator/wave/trunk/src/org/waveprotocol/box/webclient/client/WebClient.java
Mon Feb 6 18:45:52 2012
@@ -269,10 +269,10 @@ public class WebClient implements EntryP
}
/**
- * Returns <code>ws://yourhost[:port]/</code>.
+ * Returns <code>ws(s)://yourhost[:port]/</code>.
*/
// XXX check formatting wrt GPE
- private native String getWebSocketBaseUrl(String moduleBase) /*-{return "ws"
+ /:\/\/[^\/]+/.exec(moduleBase)[0] + "/";}-*/;
+ private native String getWebSocketBaseUrl(String moduleBase) /*-{return
((window.location.protocol == "https:") ? "wss" : "ws") +
/:\/\/[^\/]+/.exec(moduleBase)[0] + "/";}-*/;
private native boolean useSocketIO() /*-{ return !window.WebSocket }-*/;
Modified:
incubator/wave/trunk/test/org/waveprotocol/box/server/robots/agent/AbstractRobotAgentTest.java
URL:
http://svn.apache.org/viewvc/incubator/wave/trunk/test/org/waveprotocol/box/server/robots/agent/AbstractRobotAgentTest.java?rev=1241106&r1=1241105&r2=1241106&view=diff
==============================================================================
---
incubator/wave/trunk/test/org/waveprotocol/box/server/robots/agent/AbstractRobotAgentTest.java
(original)
+++
incubator/wave/trunk/test/org/waveprotocol/box/server/robots/agent/AbstractRobotAgentTest.java
Mon Feb 6 18:45:52 2012
@@ -43,8 +43,8 @@ public class AbstractRobotAgentTest exte
public FakeRobotAgent(String waveDomain, TokenGenerator tokenGenerator,
ServerFrontendAddressHolder frontendAddressHolder, AccountStore
accountStore,
- RobotRegistrar registrar) {
- super(waveDomain, tokenGenerator, frontendAddressHolder, accountStore,
registrar);
+ RobotRegistrar registrar, Boolean sslEnabled) {
+ super(waveDomain, tokenGenerator, frontendAddressHolder, accountStore,
registrar, sslEnabled);
}
@Override
@@ -122,7 +122,7 @@ public class AbstractRobotAgentTest exte
RobotRegistrar registar = mock(RobotRegistrar.class);
agent =
new FakeRobotAgent("example.com", tokenGenerator,
frontendAddressHolder, accountStore,
- registar);
+ registar, false);
}
public void testPreprocessCommandValidInput() throws Exception {
Modified: incubator/wave/trunk/test/org/waveprotocol/box/server/rpc/RpcTest.java
URL:
http://svn.apache.org/viewvc/incubator/wave/trunk/test/org/waveprotocol/box/server/rpc/RpcTest.java?rev=1241106&r1=1241105&r2=1241106&view=diff
==============================================================================
--- incubator/wave/trunk/test/org/waveprotocol/box/server/rpc/RpcTest.java
(original)
+++ incubator/wave/trunk/test/org/waveprotocol/box/server/rpc/RpcTest.java Mon
Feb 6 18:45:52 2012
@@ -68,7 +68,7 @@ public class RpcTest extends TestCase {
*/
server =
new ServerRpcProvider(new InetSocketAddress[] {new
InetSocketAddress("localhost", 0)}, 0,
- new String[] {"./war"}, sessionManager, null, null);
+ new String[] {"./war"}, sessionManager, null, null, false, null,
null);
Injector injector = Guice.createInjector(new AbstractModule() {
@Override
protected void configure() {