Skip to content

Commit 1ac6da6

Browse files
committed
Merge branch 'tenantid'
2 parents a3fead8 + 192425f commit 1ac6da6

File tree

10 files changed

+126
-33
lines changed

10 files changed

+126
-33
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,3 +28,4 @@ hs_err_pid*
2828
import
2929
target
3030
gen
31+
.factorypath

cf-java-logging-support-core/src/main/java/com/sap/hcp/cf/logging/common/Fields.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ public interface Fields {
1212
public String WRITTEN_AT = "written_at";
1313
public String WRITTEN_TS = "written_ts";
1414
public String CORRELATION_ID = "correlation_id";
15+
public String TENANT_ID = "tenant_id";
1516
public String COMPONENT_ID = "component_id";
1617
public String COMPONENT_NAME = "component_name";
1718
public String COMPONENT_TYPE = "component_type";
@@ -50,4 +51,6 @@ public interface Fields {
5051
public String RESPONSE_CONTENT_TYPE = "response_content_type";
5152
public String REFERER = "referer";
5253
public String X_FORWARDED_FOR = "x_forwarded_for";
54+
55+
5356
}

cf-java-logging-support-core/src/main/java/com/sap/hcp/cf/logging/common/HttpHeaders.java

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
package com.sap.hcp.cf.logging.common;
22

3+
import java.util.*;
4+
35
public interface HttpHeaders {
46

57
public String CONTENT_LENGTH = "content-length";
@@ -8,5 +10,22 @@ public interface HttpHeaders {
810
public String X_FORWARDED_FOR = "x-forwarded-for";
911
public String X_VCAP_REQUEST_ID = "x-vcap-request-id";
1012
public String CORRELATION_ID = "X-CorrelationID";
13+
public String TENANT_ID = "tenantid";
14+
15+
public List<String> PROPAGATED_HEADERS = Arrays.asList(
16+
CORRELATION_ID,
17+
TENANT_ID
18+
);
1119

20+
public Map<String, List<String>> ALIASES = new HashMap<String, List<String>>() {
21+
{
22+
put(CONTENT_LENGTH, Arrays.asList(CONTENT_LENGTH));
23+
put(CONTENT_TYPE, Arrays.asList((CONTENT_TYPE)));
24+
put(REFERER, Arrays.asList(REFERER));
25+
put(X_FORWARDED_FOR, Arrays.asList(X_FORWARDED_FOR));
26+
put(X_VCAP_REQUEST_ID, Arrays.asList(X_VCAP_REQUEST_ID));
27+
put(CORRELATION_ID, Arrays.asList(CORRELATION_ID, X_VCAP_REQUEST_ID));
28+
put(TENANT_ID, Arrays.asList(TENANT_ID));
29+
}
30+
};
1231
}

cf-java-logging-support-core/src/main/java/com/sap/hcp/cf/logging/common/LogContext.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ public class LogContext {
1919
private static Map<String, String> CTX_FIELDS = new HashMap<String, String>() {
2020
{
2121
put(Fields.CORRELATION_ID, Defaults.UNKNOWN);
22+
put(Fields.TENANT_ID, Defaults.UNKNOWN);
2223
put(Fields.REQUEST_ID, null);
2324
put(Fields.COMPONENT_ID, Defaults.UNKNOWN);
2425
put(Fields.COMPONENT_NAME, Defaults.UNKNOWN);
@@ -33,6 +34,7 @@ public class LogContext {
3334
};
3435

3536
public static final String HTTP_HEADER_CORRELATION_ID = HttpHeaders.CORRELATION_ID;
37+
public static final String HTTP_HEADER_TENANT_ID = HttpHeaders.TENANT_ID;
3638

3739
public static void loadContextFields(boolean override) {
3840
/*
@@ -80,6 +82,10 @@ public static void initializeContext(String correlationIdFromHeader) {
8082
setOrGenerateCorrelationId(correlationIdFromHeader);
8183
}
8284

85+
public static String get(String key) {
86+
return MDC.get(key);
87+
}
88+
8389
public static String add(String key, String value) {
8490
MDC.put(key, value);
8591
return value;
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
package com.sap.hcp.cf.logging.common;
2+
3+
import java.util.HashMap;
4+
import java.util.Map;
5+
6+
public class LogContextAdapter {
7+
8+
private static Map<String, String> HEADER_2_FIELDS = new HashMap<String, String>() {
9+
{
10+
put(HttpHeaders.CORRELATION_ID, Fields.CORRELATION_ID);
11+
put(HttpHeaders.TENANT_ID, Fields.TENANT_ID);
12+
}
13+
};
14+
15+
public static String getValue(String header) {
16+
String field = getField(header);
17+
if (field != null) {
18+
return LogContext.get(field);
19+
} else {
20+
return Defaults.UNKNOWN;
21+
}
22+
}
23+
24+
public static String getField(String header) {
25+
return HEADER_2_FIELDS.get(header);
26+
}
27+
}

cf-java-logging-support-jersey/src/main/java/com/sap/hcp/cf/logging/jersey/filter/ClientRequestUtils.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
import com.sap.hcp.cf.logging.common.HttpHeaders;
66
import com.sap.hcp.cf.logging.common.LogContext;
7+
import com.sap.hcp.cf.logging.common.LogContextAdapter;
78

89
public class ClientRequestUtils {
910

@@ -12,7 +13,9 @@ public static Invocation.Builder propagate(Invocation.Builder builder, javax.ws.
1213
LogContext.initializeContext(reqHeaders != null ? reqHeaders.getHeaderString(HttpHeaders.CORRELATION_ID)
1314
: null);
1415
}
15-
builder.header(HttpHeaders.CORRELATION_ID, LogContext.getCorrelationId());
16+
for (String header: HttpHeaders.PROPAGATED_HEADERS) {
17+
builder.header(header, LogContextAdapter.getValue(header));
18+
}
1619
return builder;
1720
}
1821

cf-java-logging-support-jersey/src/main/java/com/sap/hcp/cf/logging/jersey/filter/RequestHandler.java

Lines changed: 17 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,7 @@
22

33
import java.net.URI;
44

5-
import com.sap.hcp.cf.logging.common.Defaults;
6-
import com.sap.hcp.cf.logging.common.Fields;
7-
import com.sap.hcp.cf.logging.common.HttpHeaders;
8-
import com.sap.hcp.cf.logging.common.LogContext;
9-
import com.sap.hcp.cf.logging.common.LogOptionalFieldsSettings;
10-
import com.sap.hcp.cf.logging.common.LongValue;
11-
import com.sap.hcp.cf.logging.common.RequestRecord;
12-
import com.sap.hcp.cf.logging.common.RequestRecordBuilder;
5+
import com.sap.hcp.cf.logging.common.*;
136

147
public class RequestHandler {
158
final LogOptionalFieldsSettings logOptionalFieldsSettings;
@@ -21,21 +14,7 @@ public RequestHandler() {
2114

2215
public RequestRecord handle(RequestContextAdapter adapter) {
2316

24-
/*
25-
* -- This might be an outgoing call and we may already have a
26-
* correlation -- id in the LogContext
27-
*/
28-
String correlationId = LogContext.getCorrelationId();
29-
if (correlationId == null) {
30-
correlationId = getCorrelationIdFromHeader(adapter);
31-
LogContext.initializeContext(correlationId);
32-
/*
33-
* -- it was not in the header, then propagate
34-
*/
35-
if (correlationId == null) {
36-
adapter.setHeader(HttpHeaders.CORRELATION_ID, LogContext.getCorrelationId());
37-
}
38-
}
17+
propagateHeaders(adapter);
3918

4019
boolean isSensitiveConnectionData = logOptionalFieldsSettings.isLogSensitiveConnectionData();
4120
boolean isLogRemoteUserField = logOptionalFieldsSettings.isLogRemoteUserField();
@@ -59,6 +38,21 @@ public RequestRecord handle(RequestContextAdapter adapter) {
5938

6039
}
6140

41+
private void propagateHeaders(RequestContextAdapter adapter) {
42+
/*
43+
* This might be an outgoing call and we may already have a
44+
* correlation id in the LogContext
45+
*/
46+
if (LogContextAdapter.getValue(HttpHeaders.CORRELATION_ID) == null) {
47+
LogContext.initializeContext(getCorrelationIdFromHeader(adapter));
48+
}
49+
for (String header: HttpHeaders.PROPAGATED_HEADERS) {
50+
if (adapter.getHeader(header) == null) {
51+
adapter.setHeader(header, LogContextAdapter.getValue(header));
52+
}
53+
}
54+
}
55+
6256
private String getValue(String value) {
6357
return value != null ? value : Defaults.UNKNOWN;
6458
}

cf-java-logging-support-jersey/src/test/java/com/sap/hcp/cf/logging/jersey/filter/RequestMetricsClientFilterTest.java

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,24 @@
11
package com.sap.hcp.cf.logging.jersey.filter;
22

33
import static com.sap.hcp.cf.logging.common.LogContext.HTTP_HEADER_CORRELATION_ID;
4+
import static com.sap.hcp.cf.logging.common.LogContext.HTTP_HEADER_TENANT_ID;
45
import static org.hamcrest.Matchers.greaterThan;
56
import static org.hamcrest.Matchers.greaterThanOrEqualTo;
67
import static org.hamcrest.core.Is.is;
78
import static org.hamcrest.core.IsNot.not;
89
import static org.hamcrest.core.IsNull.nullValue;
910
import static org.junit.Assert.assertThat;
11+
import static org.mockito.Mockito.mock;
12+
import static org.mockito.Mockito.when;
1013

1114
import java.util.HashSet;
1215
import java.util.Set;
1316

17+
import javax.ws.rs.client.Invocation;
1418
import javax.ws.rs.core.Application;
1519
import javax.ws.rs.core.Response;
1620

21+
import com.sap.hcp.cf.logging.common.LogContext;
1722
import org.glassfish.jersey.client.ClientConfig;
1823
import org.glassfish.jersey.server.ResourceConfig;
1924
import org.junit.Test;
@@ -69,6 +74,7 @@ public void ChainedResourcePerformanceLogTest() {
6974
correlationIds.add(id);
7075
}
7176
assertThat(correlationIds.size(), is(1));
77+
assertThat(getField(Fields.TENANT_ID), is(Defaults.UNKNOWN));
7278
}
7379

7480
@Test
@@ -85,6 +91,7 @@ public void PerformanceLogTest() {
8591
assertThat(getField(Fields.DIRECTION), is(Direction.OUT.toString()));
8692
assertThat(getField(Fields.METHOD), is(TestResource.EXPECTED_REQUEST_METHOD));
8793
assertThat(getField(Fields.LAYER), is(ClientRequestContextAdapter.LAYER_NAME));
94+
assertThat(getField(Fields.TENANT_ID), is(Defaults.UNKNOWN));
8895
}
8996

9097
@Test
@@ -93,6 +100,14 @@ public void ResponseTimeTest() {
93100
final Response response = target("testresource").request().delete();
94101

95102
assertThat(new Double(getField(Fields.RESPONSE_TIME_MS)), greaterThan(TestResource.EXPECTED_REQUEST_TIME));
103+
assertThat(getField(Fields.TENANT_ID), is(Defaults.UNKNOWN));
96104

97105
}
106+
@Test
107+
public void TenantPropagationTest() {
108+
LogContext.add(Fields.TENANT_ID, "tenant1");
109+
@SuppressWarnings("unused")
110+
final Response response = ClientRequestUtils.propagate(target("testchainedresource").request(), null).get();
111+
assertThat(getField(Fields.TENANT_ID), is("tenant1"));
112+
}
98113
}

cf-java-logging-support-servlet/src/main/java/com/sap/hcp/cf/logging/servlet/filter/RequestRecordFactory.java

Lines changed: 20 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,9 @@
44

55
import javax.servlet.http.HttpServletRequest;
66

7-
import com.sap.hcp.cf.logging.common.Defaults;
8-
import com.sap.hcp.cf.logging.common.Fields;
9-
import com.sap.hcp.cf.logging.common.HttpHeaders;
10-
import com.sap.hcp.cf.logging.common.LogOptionalFieldsSettings;
11-
import com.sap.hcp.cf.logging.common.RequestRecord;
7+
import com.sap.hcp.cf.logging.common.*;
8+
9+
import java.util.List;
1210

1311
public class RequestRecordFactory {
1412

@@ -22,7 +20,7 @@ public RequestRecord create(HttpServletRequest request) {
2220
boolean isSensitiveConnectionData = logOptionalFieldsSettings.isLogSensitiveConnectionData();
2321
boolean isLogRemoteUserField = logOptionalFieldsSettings.isLogRemoteUserField();
2422
boolean isLogRefererField = logOptionalFieldsSettings.isLogRefererField();
25-
return requestRecord("[SERVLET]").addTag(Fields.REQUEST, getFullRequestUri(request))
23+
RequestRecordBuilder rrb = requestRecord("[SERVLET]").addTag(Fields.REQUEST, getFullRequestUri(request))
2624
.addTag(Fields.METHOD, request.getMethod())
2725
.addTag(Fields.PROTOCOL, getValue(request.getProtocol()))
2826
.addContextTag(Fields.REQUEST_ID, getHeader(request, HttpHeaders.X_VCAP_REQUEST_ID))
@@ -33,8 +31,11 @@ public RequestRecord create(HttpServletRequest request) {
3331
.addOptionalTag(isSensitiveConnectionData, Fields.X_FORWARDED_FOR,
3432
getHeader(request, HttpHeaders.X_FORWARDED_FOR))
3533
.addOptionalTag(isLogRemoteUserField, Fields.REMOTE_USER, getValue(request.getRemoteUser()))
36-
.addOptionalTag(isLogRefererField, Fields.REFERER, getHeader(request, HttpHeaders.REFERER))
37-
.build();
34+
.addOptionalTag(isLogRefererField, Fields.REFERER, getHeader(request, HttpHeaders.REFERER));
35+
for(String header: HttpHeaders.PROPAGATED_HEADERS) {
36+
rrb.addContextTag(LogContextAdapter.getField(header), getHeader(request, header));
37+
}
38+
return rrb.build();
3839
}
3940

4041
private String getFullRequestUri(HttpServletRequest request) {
@@ -44,7 +45,17 @@ private String getFullRequestUri(HttpServletRequest request) {
4445
}
4546

4647
private String getHeader(HttpServletRequest request, String headerName) {
47-
return getValue(request.getHeader(headerName));
48+
List<String> headers = HttpHeaders.ALIASES.get(headerName);
49+
if (headers == null) {
50+
return getValue(request.getHeader(headerName));
51+
}
52+
for (String header: headers) {
53+
String value = request.getHeader(header);
54+
if (value != null) {
55+
return value;
56+
}
57+
}
58+
return Defaults.UNKNOWN;
4859
}
4960

5061
private String getValue(String value) {

cf-java-logging-support-servlet/src/test/java/com/sap/hcp/cf/logging/servlet/filter/RequestLoggingFilterTest.java

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ public class RequestLoggingFilterTest {
4242

4343
private static final String REQUEST_ID = "1234-56-7890-xxx";
4444
private static final String CORRELATION_ID = "xxx-56-7890-xxx";
45+
private static final String TENANT_ID = "tenant1";
4546
private static final String REQUEST = "/foobar";
4647
private static final String QUERY_STRING = "baz=bla";
4748
private static final String FULL_REQUEST = REQUEST + "?" + QUERY_STRING;
@@ -134,6 +135,7 @@ public void doFilter(ServletRequest request, ServletResponse response)
134135
assertThat(getField(Fields.COMPONENT_ID), is(Defaults.UNKNOWN));
135136
assertThat(getField(Fields.CONTAINER_ID), is(Defaults.UNKNOWN));
136137
assertThat(getField(Fields.REQUEST_SIZE_B), is("1"));
138+
assertThat(getField(Fields.TENANT_ID), is(Defaults.UNKNOWN));
137139
}
138140

139141
@Test
@@ -159,6 +161,7 @@ public void testWithActivatedOptionalFields() throws IOException, ServletExcepti
159161
assertThat(getField(Fields.COMPONENT_ID), is(Defaults.UNKNOWN));
160162
assertThat(getField(Fields.CONTAINER_ID), is(Defaults.UNKNOWN));
161163
assertThat(getField(Fields.REFERER), is(REFERER));
164+
assertThat(getField(Fields.TENANT_ID), is(Defaults.UNKNOWN));
162165
}
163166

164167
@Test
@@ -184,6 +187,7 @@ public void testWithSuppressedOptionalFields() throws IOException, ServletExcept
184187
assertThat(getField(Fields.REMOTE_HOST), is(Defaults.REDACTED));
185188
assertThat(getField(Fields.COMPONENT_ID), is(Defaults.UNKNOWN));
186189
assertThat(getField(Fields.CONTAINER_ID), is(Defaults.UNKNOWN));
190+
assertThat(getField(Fields.TENANT_ID), is(Defaults.UNKNOWN));
187191
}
188192

189193
@Test
@@ -194,8 +198,18 @@ public void testExplicitCorrelationId() throws IOException, ServletException {
194198
new RequestLoggingFilter().doFilter(mockReq, mockResp, mockFilterChain);
195199
assertThat(getField(Fields.CORRELATION_ID), is(CORRELATION_ID));
196200
assertThat(getField(Fields.CORRELATION_ID), not(REQUEST_ID));
201+
assertThat(getField(Fields.TENANT_ID), is(Defaults.UNKNOWN));
197202
}
198203

204+
@Test
205+
public void testExplicitTenantId() throws IOException, ServletException {
206+
when(mockReq.getHeader(HttpHeaders.TENANT_ID)).thenReturn(TENANT_ID);
207+
when(mockReq.getHeader(HttpHeaders.X_VCAP_REQUEST_ID)).thenReturn(REQUEST_ID);
208+
FilterChain mockFilterChain = mock(FilterChain.class);
209+
new RequestLoggingFilter().doFilter(mockReq, mockResp, mockFilterChain);
210+
assertThat(getField(Fields.TENANT_ID), is(TENANT_ID));
211+
}
212+
199213
protected String getField(String fieldName) throws JSONObjectException, IOException {
200214
return JSON.std.mapFrom(getLastLine()).get(fieldName).toString();
201215
}

0 commit comments

Comments
 (0)