org.apache.cxf.ext.logging.event.DefaultLogEventMapper Maven / Gradle / Ivy
/**
* 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.cxf.ext.logging.event;
import java.security.AccessController;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.UUID;
import javax.security.auth.Subject;
import javax.xml.stream.XMLStreamReader;
import org.apache.cxf.binding.Binding;
import org.apache.cxf.configuration.security.AuthorizationPolicy;
import org.apache.cxf.endpoint.Endpoint;
import org.apache.cxf.helpers.CastUtils;
import org.apache.cxf.message.Message;
import org.apache.cxf.message.MessageUtils;
import org.apache.cxf.security.SecurityContext;
import org.apache.cxf.service.model.BindingOperationInfo;
import org.apache.cxf.service.model.EndpointInfo;
import org.apache.cxf.service.model.InterfaceInfo;
import org.apache.cxf.service.model.ServiceInfo;
import org.apache.cxf.service.model.ServiceModelUtil;
import org.apache.cxf.ws.addressing.AddressingProperties;
import org.apache.cxf.ws.addressing.ContextUtils;
public class DefaultLogEventMapper implements LogEventMapper {
private static final Set BINARY_CONTENT_MEDIA_TYPES;
static {
BINARY_CONTENT_MEDIA_TYPES = new HashSet();
BINARY_CONTENT_MEDIA_TYPES.add("application/octet-stream");
BINARY_CONTENT_MEDIA_TYPES.add("image/png");
BINARY_CONTENT_MEDIA_TYPES.add("image/jpeg");
BINARY_CONTENT_MEDIA_TYPES.add("image/gif");
}
private static final String MULTIPART_CONTENT_MEDIA_TYPE = "multipart";
public LogEvent map(Message message) {
final LogEvent event = new LogEvent();
event.setMessageId(getMessageId(message));
event.setExchangeId((String)message.getExchange().get(LogEvent.KEY_EXCHANGE_ID));
event.setType(getEventType(message));
if (!Boolean.TRUE.equals(message.get(Message.DECOUPLED_CHANNEL_MESSAGE))) {
// avoid logging the default responseCode 200 for the decoupled responses
Integer responseCode = (Integer)message.get(Message.RESPONSE_CODE);
if (responseCode != null) {
event.setResponseCode(responseCode.toString());
}
}
event.setEncoding(safeGet(message, Message.ENCODING));
event.setHttpMethod(safeGet(message, Message.HTTP_REQUEST_METHOD));
event.setContentType(safeGet(message, Message.CONTENT_TYPE));
Map headerMap = getHeaders(message);
event.setHeaders(headerMap);
String uri = getUri(message);
if (uri != null) {
event.setAddress(uri);
}
event.setPrincipal(getPrincipal(message));
event.setBinaryContent(isBinaryContent(message));
event.setMultipartContent(isMultipartContent(message));
setEpInfo(message, event);
return event;
}
private String getPrincipal(Message message) {
String principal = getJAASPrincipal();
if (principal != null) {
return principal;
}
SecurityContext sc = message.get(SecurityContext.class);
if (sc != null && sc.getUserPrincipal() != null) {
return sc.getUserPrincipal().getName();
}
AuthorizationPolicy authPolicy = message.get(AuthorizationPolicy.class);
if (authPolicy != null) {
return authPolicy.getUserName();
}
return null;
}
private String getJAASPrincipal() {
StringBuilder principals = new StringBuilder();
Iterator extends Object> principalIt = getJAASPrincipals();
while (principalIt.hasNext()) {
principals.append(principalIt.next());
if (principalIt.hasNext()) {
principals.append(",");
}
}
if (principals.length() == 0) {
return null;
}
return principals.toString();
}
private Iterator extends Object> getJAASPrincipals() {
Subject subject = Subject.getSubject(AccessController.getContext());
return subject != null && subject.getPrincipals() != null
? subject.getPrincipals().iterator() : Collections.emptyIterator();
}
private Map getHeaders(Message message) {
Map> headers = CastUtils.cast((Map, ?>)message.get(Message.PROTOCOL_HEADERS));
Map result = new HashMap<>();
if (headers == null) {
return result;
}
for (Map.Entry> entry : headers.entrySet()) {
if (entry.getValue().size() == 1) {
result.put(entry.getKey(), entry.getValue().get(0));
} else {
String[] valueAr = entry.getValue().toArray(new String[] {});
result.put(entry.getKey(), valueAr.toString());
}
}
return result;
}
private String getUri(Message message) {
String uri = safeGet(message, Message.REQUEST_URL);
if (uri == null) {
String address = safeGet(message, Message.ENDPOINT_ADDRESS);
uri = safeGet(message, Message.REQUEST_URI);
if (uri != null && uri.startsWith("/")) {
if (address != null && !address.startsWith(uri)) {
if (address.endsWith("/") && address.length() > 1) {
address = address.substring(0, address.length());
}
uri = address + uri;
}
} else {
uri = address;
}
}
String query = safeGet(message, Message.QUERY_STRING);
if (query != null) {
return uri + "?" + query;
} else {
return uri;
}
}
private boolean isBinaryContent(Message message) {
String contentType = safeGet(message, Message.CONTENT_TYPE);
return contentType != null && BINARY_CONTENT_MEDIA_TYPES.contains(contentType);
}
private boolean isMultipartContent(Message message) {
String contentType = safeGet(message, Message.CONTENT_TYPE);
return contentType != null && contentType.startsWith(MULTIPART_CONTENT_MEDIA_TYPE);
}
/**
* check if a Message is a Rest Message
*
* @param message
* @return
*/
private boolean isSOAPMessage(Message message) {
Binding binding = message.getExchange().getBinding();
return binding != null && binding.getClass().getSimpleName().equals("SoapBinding");
}
/**
* Get MessageId from WS Addressing properties
*
* @param message
* @return message id
*/
private String getMessageId(Message message) {
AddressingProperties addrProp = ContextUtils.retrieveMAPs(message, false,
MessageUtils.isOutbound(message), false);
return addrProp != null && addrProp.getMessageID() != null
? addrProp.getMessageID().getValue() : UUID.randomUUID().toString();
}
private String getOperationName(Message message) {
String operationName = null;
BindingOperationInfo boi = null;
boi = message.getExchange().getBindingOperationInfo();
if (null == boi) {
boi = getOperationFromContent(message);
}
if (null == boi) {
Message inMsg = message.getExchange().getInMessage();
if (null != inMsg) {
Message reqMsg = inMsg.getExchange().getInMessage();
if (null != reqMsg) {
boi = getOperationFromContent(reqMsg);
}
}
}
if (null != boi) {
operationName = boi.getName().toString();
}
return operationName;
}
private BindingOperationInfo getOperationFromContent(Message message) {
XMLStreamReader xmlReader = message.getContent(XMLStreamReader.class);
if (xmlReader != null) {
return ServiceModelUtil.getOperation(message.getExchange(), xmlReader.getName());
} else {
return null;
}
}
private Message getEffectiveMessage(Message message) {
boolean isRequestor = MessageUtils.isRequestor(message);
boolean isOutbound = MessageUtils.isOutbound(message);
if (isRequestor) {
return isOutbound ? message : message.getExchange().getOutMessage();
} else {
return isOutbound ? message.getExchange().getInMessage() : message;
}
}
private String getRestOperationName(Message curMessage) {
Message message = getEffectiveMessage(curMessage);
String httpMethod = safeGet(message, Message.HTTP_REQUEST_METHOD);
if (httpMethod == null) {
return "";
}
String path = "";
String requestUri = safeGet(message, Message.REQUEST_URI);
if (requestUri != null) {
String basePath = safeGet(message, Message.BASE_PATH);
int baseUriLength = (basePath != null) ? basePath.length() : 0;
path = requestUri.substring(baseUriLength);
if (path.isEmpty()) {
path = "/";
}
}
return new StringBuffer().append(httpMethod).append('[').append(path).append(']').toString();
}
private static String safeGet(Message message, String key) {
if (!message.containsKey(key)) {
return null;
}
Object value = message.get(key);
return (value instanceof String) ? value.toString() : null;
}
/**
* Gets the event type from message.
*
* @param message the message
* @return the event type
*/
private EventType getEventType(Message message) {
boolean isRequestor = MessageUtils.isRequestor(message);
boolean isFault = MessageUtils.isFault(message);
if (!isFault) {
isFault = !isSOAPMessage(message) && isRESTFault(message);
}
boolean isOutbound = MessageUtils.isOutbound(message);
if (isOutbound) {
if (isFault) {
return EventType.FAULT_OUT;
} else {
return isRequestor ? EventType.REQ_OUT : EventType.RESP_OUT;
}
} else {
if (isFault) {
return EventType.FAULT_IN;
} else {
return isRequestor ? EventType.RESP_IN : EventType.REQ_IN;
}
}
}
/**
* For REST we also consider a response to be a fault if the operation is not found or the response code
* is an error
*
* @param message
* @return
*/
private boolean isRESTFault(Message message) {
Object opName = message.getExchange().get("org.apache.cxf.resource.operation.name");
if (opName == null) {
return true;
} else {
Integer responseCode = (Integer)message.get(Message.RESPONSE_CODE);
return (responseCode != null) && (responseCode >= 400);
}
}
private void setEpInfo(Message message, final LogEvent event) {
EndpointInfo endpoint = getEPInfo(message);
event.setPortName(endpoint.getName());
event.setPortTypeName(endpoint.getName());
String opName = isSOAPMessage(message) ? getOperationName(message) : getRestOperationName(message);
event.setOperationName(opName);
if (endpoint.getService() != null) {
setServiceInfo(endpoint.getService(), event);
}
}
private void setServiceInfo(ServiceInfo service, LogEvent event) {
event.setServiceName(service.getName());
InterfaceInfo iface = service.getInterface();
event.setPortTypeName(iface.getName());
}
private EndpointInfo getEPInfo(Message message) {
Endpoint ep = message.getExchange().getEndpoint();
return (ep == null) ? new EndpointInfo() : ep.getEndpointInfo();
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy