/**
* Copyright 2005-2014 Restlet
*
* The contents of this file are subject to the terms of one of the following
* open source licenses: Apache 2.0 or or EPL 1.0 (the "Licenses"). You can
* select the license that you prefer but you may not use this file except in
* compliance with one of these Licenses.
*
* You can obtain a copy of the Apache 2.0 license at
* http://www.opensource.org/licenses/apache-2.0
*
* You can obtain a copy of the EPL 1.0 license at
* http://www.opensource.org/licenses/eclipse-1.0
*
* See the Licenses for the specific language governing permissions and
* limitations under the Licenses.
*
* Alternatively, you can obtain a royalty free commercial license with less
* limitations, transferable or non-transferable, directly at
* http://restlet.com/products/restlet-framework
*
* Restlet is a registered trademark of Restlet S.A.S.
*/
package org.restlet.ext.apispark.internal;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.restlet.Context;
import org.restlet.Restlet;
import org.restlet.engine.util.StringUtils;
import org.restlet.ext.apispark.FirewallConfig;
import org.restlet.ext.apispark.internal.agent.AgentConfigurationException;
import org.restlet.ext.apispark.internal.agent.bean.ModulesSettings;
import org.restlet.ext.apispark.internal.agent.module.AnalyticsModule;
import org.restlet.ext.apispark.internal.agent.module.AuthenticationModule;
import org.restlet.ext.apispark.internal.agent.module.AuthorizationModule;
import org.restlet.ext.apispark.internal.agent.module.FirewallModule;
import org.restlet.ext.apispark.internal.agent.module.ModulesSettingsModule;
import org.restlet.ext.apispark.internal.agent.module.ReverseProxyModule;
import org.restlet.ext.apispark.internal.firewall.FirewallFilter;
import org.restlet.ext.apispark.internal.firewall.rule.FirewallRule;
import org.restlet.ext.apispark.internal.utils.RestletChain;
import org.restlet.routing.Filter;
import org.restlet.routing.Redirector;
public class ApiSparkFilter extends Filter {
/** Internal logger. */
protected static Logger LOGGER = Logger.getLogger(ApiSparkFilter.class
.getName());
/** Default next restlet of filter. */
private Restlet agentFirstRestlet;
/** First restlet of the agent filter. */
private Restlet filterNext;
/** Last restlet of the agent filter. */
private Restlet agentLastRestlet;
/** Modules settings of the agent */
private ModulesSettings modulesSettings;
/** List of firewall rules set by user at creation */
private List<FirewallRule> firewallRules;
/** Is user set firewall enabled */
private boolean firewallEnabled;
/** APISpark connection configuration */
private ApiSparkConfig apiSparkConfig;
/** APISpark connection enabled */
private boolean agentEnabled;
/** Restlet context */
private Context context;
/**
* Create a new ApiSparkFilter with the specified configuration.
*
* @param context
* The current context.
* @param apiSparkConfig
* The ApiSparkService configuration.
*/
public ApiSparkFilter(Context context, ApiSparkConfig apiSparkConfig,
boolean agentEnabled, boolean firewallEnabled,
List<FirewallRule> firewallRules) {
super(context);
this.firewallRules = firewallRules;
this.firewallEnabled = firewallEnabled;
this.apiSparkConfig = apiSparkConfig;
this.agentEnabled = agentEnabled;
this.context = context;
validateRedirection(apiSparkConfig);
if (agentEnabled) {
validateAgentConfiguration(apiSparkConfig);
modulesSettings = ModulesSettingsModule.getModulesSettings(
apiSparkConfig, null);
}
refreshApiSparkFilter();
}
/**
* Retrieves the modules settings from the service and updates the filter.
*/
public void refreshApiSparkFilterIfRevisionChanged() {
try {
ModulesSettings newModulesSettings = ModulesSettingsModule
.getModulesSettings(apiSparkConfig, modulesSettings);
if (newModulesSettings != null) {
modulesSettings = newModulesSettings;
LOGGER.info("Updating modules settings");
refreshApiSparkFilter();
}
} catch (Exception e) {
LOGGER.log(Level.WARNING,
"Unable to retrieve agent settings from apispark", e);
}
}
/**
* Updates the filter with its modules settings.
*/
public void refreshApiSparkFilter() {
boolean authenticationEnabled = false;
RestletChain restletChain = new RestletChain();
if (agentEnabled) {
if (modulesSettings.isAuthenticationModuleEnabled()) {
LOGGER.info("Add authentication module");
authenticationEnabled = true;
restletChain.add(new AuthenticationModule(apiSparkConfig,
modulesSettings, context));
}
if (modulesSettings.isAuthorizationModuleEnabled()) {
if (!modulesSettings.isAuthenticationModuleEnabled()) {
throw new AgentConfigurationException(
"The authorization module requires the authentication module which is not enabled");
}
LOGGER.info("Add authorization module");
restletChain.add(new AuthorizationModule(apiSparkConfig,
modulesSettings, context));
}
if (modulesSettings.isFirewallModuleEnabled()) {
firewallEnabled = true;
FirewallModule firewallModule = new FirewallModule(
apiSparkConfig, modulesSettings);
FirewallConfig firewallConfig = new FirewallConfig(
firewallRules);
firewallModule.updateFirewallConfig(firewallConfig);
}
if (modulesSettings.isAnalyticsModuleEnabled()) {
LOGGER.info("Add analytics module");
restletChain.add(new AnalyticsModule(apiSparkConfig,
modulesSettings, context));
}
}
if (firewallEnabled) {
LOGGER.info("Add firewall module");
restletChain.add(new FirewallFilter(context, firewallRules));
}
if (apiSparkConfig.isReverseProxyEnabled()) {
LOGGER.info("Add redirection module");
String redirectorUrl = apiSparkConfig.getReverseProxyTargetUrl()
+ "{rr}";
Redirector redirector = new ReverseProxyModule(context,
redirectorUrl, authenticationEnabled);
restletChain.add(redirector);
}
if (restletChain.getFirst() == null) {
LOGGER.warning("No modules are enabled.");
}
agentFirstRestlet = restletChain.getFirst();
agentLastRestlet = restletChain.getLast();
}
@Override
public Restlet getNext() {
return agentFirstRestlet != null ? agentFirstRestlet : filterNext;
}
@Override
public void setNext(Restlet next) {
filterNext = next;
// If the agent has any restlet components, set the next on the last
// one.
if (agentLastRestlet != null) {
if (agentLastRestlet instanceof Filter) {
Filter filter = (Filter) agentLastRestlet;
filter.setNext(next);
}
}
}
/**
* Terminates the agent if the service's configuration is not correctly set.
*
* @param config
* The service's configuration
*/
public void validateAgentConfiguration(ApiSparkConfig config) {
if (config.getAgentCellId() == null) {
throw new IllegalArgumentException(
"The cell identifier is mandatory");
}
if (config.getAgentCellId() == null) {
throw new IllegalArgumentException(
"The cell version identifier is mandatory");
}
if (StringUtils.isNullOrEmpty(config.getAgentServiceUrl())) {
throw new IllegalArgumentException(
"The agent service url is mandatory");
}
if (StringUtils.isNullOrEmpty(config.getAgentLogin())) {
throw new IllegalArgumentException("The agent login is mandatory");
}
if (StringUtils.isNullOrEmpty(config.getAgentPassword())) {
throw new IllegalArgumentException(
"The agent password key is mandatory");
}
}
/**
* Validates the redirection URL
*
* @param config
* The service's configuration
*/
public void validateRedirection(ApiSparkConfig config) {
if (config.isReverseProxyEnabled()
&& StringUtils.isNullOrEmpty(config.getReverseProxyTargetUrl())) {
throw new IllegalArgumentException(
"The redirection url is mandatory when redirection is enabled");
}
}
}