AMBARI-20807 Log Search REST API calls for configuration should send proper error responses (mgergely)
Change-Id: I23595470db557a5fa746fd02cb51caa35d96a44f Project: http://git-wip-us.apache.org/repos/asf/ambari/repo Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/e8e997a3 Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/e8e997a3 Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/e8e997a3 Branch: refs/heads/branch-feature-AMBARI-12556 Commit: e8e997a36e38a38ac7ca4695377ba800a8427f87 Parents: 1b7c023 Author: Miklos Gergely <mgerg...@hortonworks.com> Authored: Tue Apr 25 15:53:37 2017 +0200 Committer: Miklos Gergely <mgerg...@hortonworks.com> Committed: Tue Apr 25 15:53:37 2017 +0200 ---------------------------------------------------------------------- .../ambari/logsearch/common/MessageEnums.java | 3 +- .../ambari/logsearch/conf/SecurityConfig.java | 15 +++ .../logsearch/manager/ShipperConfigManager.java | 19 ---- .../logsearch/rest/ShipperConfigResource.java | 4 +- .../web/filters/LogSearchConfigStateFilter.java | 102 +++++++++++++++++++ .../scripts/logsearch_config_aggregator.py | 77 -------------- .../LOGSEARCH/0.5.0/package/scripts/params.py | 3 - 7 files changed, 121 insertions(+), 102 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/ambari/blob/e8e997a3/ambari-logsearch/ambari-logsearch-server/src/main/java/org/apache/ambari/logsearch/common/MessageEnums.java ---------------------------------------------------------------------- diff --git a/ambari-logsearch/ambari-logsearch-server/src/main/java/org/apache/ambari/logsearch/common/MessageEnums.java b/ambari-logsearch/ambari-logsearch-server/src/main/java/org/apache/ambari/logsearch/common/MessageEnums.java index 4f1725f..9dd8b34 100644 --- a/ambari-logsearch/ambari-logsearch-server/src/main/java/org/apache/ambari/logsearch/common/MessageEnums.java +++ b/ambari-logsearch/ambari-logsearch-server/src/main/java/org/apache/ambari/logsearch/common/MessageEnums.java @@ -33,7 +33,8 @@ public enum MessageEnums { ZNODE_NOT_READY("logsearch.zk.znode.error", "ZNode is not available."), ZK_CONFIG_NOT_READY("logsearch.zk.config.error", "Collection configuration has not uploaded yet"), SOLR_COLLECTION_NOT_READY("logsearch.solr.collection.error", "Solr has not accessible yet for collection."), - + CONFIGURATION_NOT_AVAILABLE("logsearch.config.not_available", "Log Search configuration is not available"), + // Common Validations INVALID_PASSWORD("logsearch.validation.invalid_password", "Invalid password"), INVALID_INPUT_DATA("logsearch.validation.invalid_input_data", "Invalid input data"), http://git-wip-us.apache.org/repos/asf/ambari/blob/e8e997a3/ambari-logsearch/ambari-logsearch-server/src/main/java/org/apache/ambari/logsearch/conf/SecurityConfig.java ---------------------------------------------------------------------- diff --git a/ambari-logsearch/ambari-logsearch-server/src/main/java/org/apache/ambari/logsearch/conf/SecurityConfig.java b/ambari-logsearch/ambari-logsearch-server/src/main/java/org/apache/ambari/logsearch/conf/SecurityConfig.java index 2f9cba4..973dc4b 100644 --- a/ambari-logsearch/ambari-logsearch-server/src/main/java/org/apache/ambari/logsearch/conf/SecurityConfig.java +++ b/ambari-logsearch/ambari-logsearch-server/src/main/java/org/apache/ambari/logsearch/conf/SecurityConfig.java @@ -19,6 +19,8 @@ package org.apache.ambari.logsearch.conf; import com.google.common.collect.Lists; + +import org.apache.ambari.logsearch.conf.global.LogSearchConfigState; import org.apache.ambari.logsearch.conf.global.SolrCollectionState; import org.apache.ambari.logsearch.web.authenticate.LogsearchAuthFailureHandler; import org.apache.ambari.logsearch.web.authenticate.LogsearchAuthSuccessHandler; @@ -26,6 +28,7 @@ import org.apache.ambari.logsearch.web.authenticate.LogsearchLogoutSuccessHandle import org.apache.ambari.logsearch.web.filters.LogsearchAuditLogsStateFilter; import org.apache.ambari.logsearch.web.filters.LogsearchAuthenticationEntryPoint; import org.apache.ambari.logsearch.web.filters.LogsearchCorsFilter; +import org.apache.ambari.logsearch.web.filters.LogSearchConfigStateFilter; import org.apache.ambari.logsearch.web.filters.LogsearchKRBAuthenticationFilter; import org.apache.ambari.logsearch.web.filters.LogsearchJWTFilter; import org.apache.ambari.logsearch.web.filters.LogsearchSecurityContextFormationFilter; @@ -82,6 +85,9 @@ public class SecurityConfig extends WebSecurityConfigurerAdapter { @Named("solrUserConfigState") private SolrCollectionState solrUserConfigState; + @Inject + private LogSearchConfigState logSearchConfigState; + @Override protected void configure(HttpSecurity http) throws Exception { http @@ -108,6 +114,7 @@ public class SecurityConfig extends WebSecurityConfigurerAdapter { .addFilterAfter(logsearchUserConfigFilter(), LogsearchSecurityContextFormationFilter.class) .addFilterAfter(logsearchAuditLogFilter(), LogsearchSecurityContextFormationFilter.class) .addFilterAfter(logsearchServiceLogFilter(), LogsearchSecurityContextFormationFilter.class) + .addFilterAfter(logSearchConfigStateFilter(), LogsearchSecurityContextFormationFilter.class) .addFilterBefore(corsFilter(), LogsearchSecurityContextFormationFilter.class) .addFilterBefore(logsearchJwtFilter(), LogsearchSecurityContextFormationFilter.class) .logout() @@ -175,6 +182,10 @@ public class SecurityConfig extends WebSecurityConfigurerAdapter { public LogsearchUserConfigStateFilter logsearchUserConfigFilter() { return new LogsearchUserConfigStateFilter(userConfigRequestMatcher(), solrUserConfigState, solrUserPropsConfig); } + + public LogSearchConfigStateFilter logSearchConfigStateFilter() { + return new LogSearchConfigStateFilter(logsearchConfigRequestMatcher(), logSearchConfigState); + } @Bean public RequestMatcher requestMatcher() { @@ -206,4 +217,8 @@ public class SecurityConfig extends WebSecurityConfigurerAdapter { return new AntPathRequestMatcher("/api/v1/userconfig/**"); } + public RequestMatcher logsearchConfigRequestMatcher() { + return new AntPathRequestMatcher("/api/v1/shipper/**"); + } + } http://git-wip-us.apache.org/repos/asf/ambari/blob/e8e997a3/ambari-logsearch/ambari-logsearch-server/src/main/java/org/apache/ambari/logsearch/manager/ShipperConfigManager.java ---------------------------------------------------------------------- diff --git a/ambari-logsearch/ambari-logsearch-server/src/main/java/org/apache/ambari/logsearch/manager/ShipperConfigManager.java b/ambari-logsearch/ambari-logsearch-server/src/main/java/org/apache/ambari/logsearch/manager/ShipperConfigManager.java index 251619b..c0c1167 100644 --- a/ambari-logsearch/ambari-logsearch-server/src/main/java/org/apache/ambari/logsearch/manager/ShipperConfigManager.java +++ b/ambari-logsearch/ambari-logsearch-server/src/main/java/org/apache/ambari/logsearch/manager/ShipperConfigManager.java @@ -21,7 +21,6 @@ package org.apache.ambari.logsearch.manager; import java.util.List; -import org.apache.ambari.logsearch.conf.global.LogSearchConfigState; import org.apache.ambari.logsearch.configurer.LogSearchConfigConfigurer; import org.apache.log4j.Logger; @@ -34,9 +33,6 @@ import javax.ws.rs.core.Response; public class ShipperConfigManager extends JsonManagerBase { private static final Logger logger = Logger.getLogger(ShipperConfigManager.class); - - @Inject - private LogSearchConfigState logSearchConfigState; @Inject private LogSearchConfigConfigurer logSearchConfigConfigurer; @@ -47,29 +43,14 @@ public class ShipperConfigManager extends JsonManagerBase { } public List<String> getServices(String clusterName) { - if (!logSearchConfigState.isLogSearchConfigAvailable()) { - logger.warn("Log Search Config not available yet"); - return null; - } - return LogSearchConfigConfigurer.getConfig().getServices(clusterName); } public String getInputConfig(String clusterName, String serviceName) { - if (!logSearchConfigState.isLogSearchConfigAvailable()) { - logger.warn("Log Search Config not available yet"); - return null; - } - return LogSearchConfigConfigurer.getConfig().getInputConfig(clusterName, serviceName); } public Response setInputConfig(String clusterName, String serviceName, String inputConfig) { - if (!logSearchConfigState.isLogSearchConfigAvailable()) { - logger.warn("Log Search Config not available yet"); - return Response.serverError().build(); - } - try { LogSearchConfigConfigurer.getConfig().setInputConfig(clusterName, serviceName, inputConfig); return Response.ok().build(); http://git-wip-us.apache.org/repos/asf/ambari/blob/e8e997a3/ambari-logsearch/ambari-logsearch-server/src/main/java/org/apache/ambari/logsearch/rest/ShipperConfigResource.java ---------------------------------------------------------------------- diff --git a/ambari-logsearch/ambari-logsearch-server/src/main/java/org/apache/ambari/logsearch/rest/ShipperConfigResource.java b/ambari-logsearch/ambari-logsearch-server/src/main/java/org/apache/ambari/logsearch/rest/ShipperConfigResource.java index 38821bc..47e6ba2 100644 --- a/ambari-logsearch/ambari-logsearch-server/src/main/java/org/apache/ambari/logsearch/rest/ShipperConfigResource.java +++ b/ambari-logsearch/ambari-logsearch-server/src/main/java/org/apache/ambari/logsearch/rest/ShipperConfigResource.java @@ -55,7 +55,7 @@ public class ShipperConfigResource { } @GET - @Path("/input/{clusterName}/{serviceName}") + @Path("/input/{clusterName}/services/{serviceName}") @Produces({"application/json"}) @ApiOperation(GET_SHIPPER_CONFIG) public String getShipperConfig(@PathParam("clusterName") String clusterName, @PathParam("serviceName") String serviceName) { @@ -63,7 +63,7 @@ public class ShipperConfigResource { } @PUT - @Path("/input/{clusterName}/{serviceName}") + @Path("/input/{clusterName}/services/{serviceName}") @Produces("text/plain") @ApiOperation(SET_SHIPPER_CONFIG) public Response setShipperConfig(String body, @PathParam("clusterName") String clusterName, @PathParam("serviceName") http://git-wip-us.apache.org/repos/asf/ambari/blob/e8e997a3/ambari-logsearch/ambari-logsearch-server/src/main/java/org/apache/ambari/logsearch/web/filters/LogSearchConfigStateFilter.java ---------------------------------------------------------------------- diff --git a/ambari-logsearch/ambari-logsearch-server/src/main/java/org/apache/ambari/logsearch/web/filters/LogSearchConfigStateFilter.java b/ambari-logsearch/ambari-logsearch-server/src/main/java/org/apache/ambari/logsearch/web/filters/LogSearchConfigStateFilter.java new file mode 100644 index 0000000..9b6cdfe --- /dev/null +++ b/ambari-logsearch/ambari-logsearch-server/src/main/java/org/apache/ambari/logsearch/web/filters/LogSearchConfigStateFilter.java @@ -0,0 +1,102 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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.apache.ambari.logsearch.web.filters; + +import java.io.IOException; + +import javax.servlet.Filter; +import javax.servlet.FilterChain; +import javax.servlet.FilterConfig; +import javax.servlet.ServletException; +import javax.servlet.ServletRequest; +import javax.servlet.ServletResponse; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.apache.ambari.logsearch.common.MessageEnums; +import org.apache.ambari.logsearch.common.VResponse; +import org.apache.ambari.logsearch.conf.global.LogSearchConfigState; +import org.apache.ambari.logsearch.util.RESTErrorUtil; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.security.web.util.matcher.RequestMatcher; + +import com.fasterxml.jackson.databind.ObjectMapper; + +/** + * Filter to decide whether the server us ready to serve requests which require Log Search configuration available. + */ +public class LogSearchConfigStateFilter implements Filter { + private static final Logger LOG = LoggerFactory.getLogger(LogSearchConfigStateFilter.class); + + private static final String CONFIG_NOT_AVAILABLE = "Configuration is not available"; + + private final RequestMatcher requestMatcher; + private final LogSearchConfigState logSearchConfigState; + + public LogSearchConfigStateFilter(RequestMatcher requestMatcher, LogSearchConfigState logSearchConfigState) { + this.requestMatcher = requestMatcher; + this.logSearchConfigState = logSearchConfigState; + } + + @Override + public void init(FilterConfig filterConfig) throws ServletException { + } + + @Override + public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) + throws IOException, ServletException { + HttpServletRequest request = (HttpServletRequest) servletRequest; + if (requestMatcher.matches(request)) { + VResponse errorResponse = getErrorResponse(); + if (errorResponse != null) { + LOG.info("{} request is filtered out: {}", request.getRequestURL(), errorResponse.getMsgDesc()); + HttpServletResponse resp = (HttpServletResponse) servletResponse; + resp.setStatus(500); + resp.setContentType("application/json"); + resp.getWriter().print(createStringFromErrorMessageObject(errorResponse)); + return; + } + } + + filterChain.doFilter(servletRequest, servletResponse); + } + + private VResponse getErrorResponse() { + if (!logSearchConfigState.isLogSearchConfigAvailable()) { + return RESTErrorUtil.createMessageResponse(CONFIG_NOT_AVAILABLE, MessageEnums.CONFIGURATION_NOT_AVAILABLE); + } + + return null; + } + + private String createStringFromErrorMessageObject(VResponse responseObject) { + try { + ObjectMapper mapper = new ObjectMapper(); + return mapper.writeValueAsString(responseObject); + } catch (Exception e) { + throw RESTErrorUtil.createRESTException("Cannot parse response object on backend", MessageEnums.ERROR_CREATING_OBJECT); + } + } + + @Override + public void destroy() { + } +} http://git-wip-us.apache.org/repos/asf/ambari/blob/e8e997a3/ambari-server/src/main/resources/common-services/LOGSEARCH/0.5.0/package/scripts/logsearch_config_aggregator.py ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/resources/common-services/LOGSEARCH/0.5.0/package/scripts/logsearch_config_aggregator.py b/ambari-server/src/main/resources/common-services/LOGSEARCH/0.5.0/package/scripts/logsearch_config_aggregator.py deleted file mode 100644 index c14900e..0000000 --- a/ambari-server/src/main/resources/common-services/LOGSEARCH/0.5.0/package/scripts/logsearch_config_aggregator.py +++ /dev/null @@ -1,77 +0,0 @@ -""" -Licensed to the Apache Software Foundation (ASF) under one -or more contributor license agreements. See the NOTICE file -distributed with this work for additional information -regarding copyright ownership. The ASF licenses this file -to you 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. - -""" -from resource_management import Logger - -def __parse_component_mappings(component_mappings): - components = list() - component_mappings_list = component_mappings.split(';') - if component_mappings_list and len(component_mappings_list) > 0: - metadata_list = map(lambda x : x.split(':'), component_mappings_list) - if metadata_list and len(metadata_list) > 0: - for metadata in metadata_list: - if (len(metadata) == 2): - logids = metadata[1].split(',') - components.extend(logids) - Logger.info("Found logids for logsearch component %s - (%s) " % (metadata[0], metadata[1])) - return components - -def get_logsearch_meta_configs(configurations): - logsearch_meta_configs = {} - for key, value in configurations.iteritems(): # iter on both keys and values - if str(key).endswith('logsearch-conf'): - logsearch_meta_configs[key] = value - Logger.info("Found logsearch config entry : " + key) - return logsearch_meta_configs - -def get_logfeeder_metadata(logsearch_meta_configs): - """ - get logfeeder pattern metadata list, an element: (e.g.) : - ['service_config_name' : 'pattern json content'] - """ - logfeeder_contents = {} - for key, value in logsearch_meta_configs.iteritems(): - if 'content' in logsearch_meta_configs[key] and logsearch_meta_configs[key]['content'].strip(): - logfeeder_contents[key] = logsearch_meta_configs[key]['content'] - Logger.info("Found logfeeder pattern content in " + key) - return logfeeder_contents - -def get_logsearch_metadata(logsearch_meta_configs): - """ - get logsearch metadata list, an element (e.g.) : - ['service_name_key' : {component1 : [logid1, logid2]}, {component2 : [logid1, logid2]}] - """ - logsearch_service_component_mappings = {} - for key, value in logsearch_meta_configs.iteritems(): - if 'service_name' in logsearch_meta_configs[key] and 'component_mappings' in logsearch_meta_configs[key]: - service_name = logsearch_meta_configs[key]['service_name'] - component_mappings = __parse_component_mappings(logsearch_meta_configs[key]['component_mappings']) - if service_name.strip() and component_mappings: - logsearch_service_component_mappings[service_name] = component_mappings - if 'service_component_mappings' in logsearch_meta_configs[key]: - service_component_mappings = logsearch_meta_configs[key]['service_component_mappings'] - if service_component_mappings.strip(): - for service_component_mapping in service_component_mappings.split('|'): - tokens = service_component_mapping.split('=') - service_name = tokens[0] - component_mappings = __parse_component_mappings(tokens[1]) - if service_name.strip() and component_mappings: - logsearch_service_component_mappings[service_name] = component_mappings - - return logsearch_service_component_mappings - http://git-wip-us.apache.org/repos/asf/ambari/blob/e8e997a3/ambari-server/src/main/resources/common-services/LOGSEARCH/0.5.0/package/scripts/params.py ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/resources/common-services/LOGSEARCH/0.5.0/package/scripts/params.py b/ambari-server/src/main/resources/common-services/LOGSEARCH/0.5.0/package/scripts/params.py index bfe0c0d..6738c5c 100644 --- a/ambari-server/src/main/resources/common-services/LOGSEARCH/0.5.0/package/scripts/params.py +++ b/ambari-server/src/main/resources/common-services/LOGSEARCH/0.5.0/package/scripts/params.py @@ -21,7 +21,6 @@ limitations under the License. import os from ambari_commons.constants import AMBARI_SUDO_BINARY -from logsearch_config_aggregator import get_logfeeder_metadata, get_logsearch_metadata, get_logsearch_meta_configs from resource_management.libraries.functions.default import default from resource_management.libraries.functions.format import format from resource_management.libraries.functions.is_empty import is_empty @@ -79,8 +78,6 @@ java64_home = config['hostLevelParams']['java_home'] cluster_name = str(config['clusterName']) configurations = config['configurations'] # need reference inside logfeeder jinja templates -logserch_meta_configs = get_logsearch_meta_configs(configurations) -logsearch_metadata = get_logsearch_metadata(logserch_meta_configs) # for now just pick first collector if 'metrics_collector_hosts' in config['clusterHostInfo']: