/*
 * Copyright 2013-2015 the original author or authors.
 *
 * 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.springframework.cloud.netflix.metrics;

import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.http.HttpRequest;
import org.springframework.http.client.ClientHttpResponse;
import org.springframework.util.StringUtils;
import org.springframework.web.servlet.HandlerMapping;

import com.google.common.collect.ImmutableMap;

/**
 * @author Jon Schneider
 */
public class DefaultMetricsTagProvider implements MetricsTagProvider {
	@Override
	public Map<String, String> clientHttpRequestTags(HttpRequest request,
			ClientHttpResponse response) {
		String urlTemplate = RestTemplateUrlTemplateHolder.getRestTemplateUrlTemplate();
		if (urlTemplate == null) {
			urlTemplate = "none";
		}

		String status;
		try {
			status = (response == null) ? "CLIENT_ERROR" : ((Integer) response
					.getRawStatusCode()).toString();
		}
		catch (IOException e) {
			status = "IO_ERROR";
		}

		String host = request.getURI().getHost();

		String strippedUrlTemplate = urlTemplate.replaceAll("^https?://[^/]+/", "");
		//@formatter:off
		return ImmutableMap.of("method", request.getMethod().name(),
				"uri", sanitizeUrlTemplate(strippedUrlTemplate),
				"status", status, "clientName",
				host != null ? host : "none");
		//@formatter:on
	}

	@Override
	public Map<String, String> httpRequestTags(HttpServletRequest request,
			HttpServletResponse response, Object handler, String caller) {
		Map<String, String> tags = new HashMap<>();

		tags.put("method", request.getMethod());
		tags.put("status", ((Integer) response.getStatus()).toString());

		String uri = (String) request
				.getAttribute(HandlerMapping.BEST_MATCHING_PATTERN_ATTRIBUTE);
		if (uri == null) {
			uri = request.getPathInfo();
		}
		if (!StringUtils.hasText(uri)) {
			uri = "/";
		}
		uri = sanitizeUrlTemplate(uri.substring(1));
		tags.put("uri", uri.isEmpty() ? "root" : uri);

		Object exception = request.getAttribute("exception");
		if (exception != null) {
			tags.put("exception", exception.getClass().getSimpleName());
		}

		if (caller != null) {
			tags.put("caller", caller);
		}

		return tags;
	}

	/**
	 * As is, the urlTemplate is not suitable for use with Atlas, as all interactions with
	 * Atlas take place via query parameters
	 */
	private String sanitizeUrlTemplate(String urlTemplate) {
		String sanitized = urlTemplate.replaceAll("/", "_").replaceAll("[{}]", "-");
		if (!StringUtils.hasText(sanitized)) {
			sanitized = "none";
		}
		return sanitized;
	}
}

@@ -681,16 +681,46 @@
 eption;%0A
+import java.util.Collections;%0A
 import j
@@ -737,16 +737,16 @@
 ashMap;%0A
-
 import j
@@ -1063,56 +1063,8 @@
 g;%0A%0A
-import com.google.common.collect.ImmutableMap;%0A%0A
 /**%0A
@@ -1657,17 +1657,64 @@
 Host();%0A
+%09%09if( host == null ) %7B%0A%09%09%09host = %22none%22;%0A%09%09%7D%0A%09%09
 %0A
-
 %09%09String
@@ -1790,49 +1790,65 @@
 ;%0A%09%09
-//@formatter:off%0A%09%09return ImmutableMap.of
+%0A%09%09Map%3CString, String%3E tags = new HashMap%3C%3E();%0A%09%09tags.put
 (%22me
@@ -1845,32 +1845,36 @@
 gs.put(%22method%22,
+    
  request.getMeth
@@ -1888,20 +1888,35 @@
 me()
-,%0A%09%09%09%09%22uri%22,
+);%0A%09%09tags.put(%22uri%22,       
  san
@@ -1952,22 +1952,30 @@
 emplate)
-,%0A%09%09%09%09
+);%0A%09%09tags.put(
 %22status%22
@@ -1979,17 +1979,33 @@
 us%22,
+    
  status
-, 
+);%0A%09%09tags.put(
 %22cli
@@ -2017,61 +2017,62 @@
 me%22,
+ host);
 %0A%09%09
+%0A
 %09%09
-host != null ? host : %22none%22);%0A%09%09//@formatter:on
+return Collections.unmodifiableMap(tags);
 %0A%09%7D%0A
@@ -3063,13 +3063,15 @@
 %0A%09pr
-ivate
+otected
  Str

remove Guava ImmutableMap in favour of Collections.unmodifiableMap() Make sanitizeUrlTemplate() protected for easy sub-classing