001package com.nimbusds.common.jsonrpc2;
002
003
004import com.thetransactioncompany.jsonrpc2.JSONRPC2ParamsType;
005import com.thetransactioncompany.jsonrpc2.JSONRPC2Request;
006import com.thetransactioncompany.jsonrpc2.JSONRPC2Response;
007import org.apache.logging.log4j.LogManager;
008import org.apache.logging.log4j.Logger;
009
010import java.util.Map;
011
012
013/**
014 * Helper methods for Log4j message generation.
015 */
016public class JSONRPC2LogUtility {
017
018
019        /**
020         * The logger.
021         */
022        private static final Logger log = LogManager.getLogger("JSON-RPC");
023        
024        
025        /**
026         * Logs (at INFO level) the name of the JSON-RPC 2.0 request and the 
027         * resulting response (success or error code + message). The message 
028         * may be optionally prefixed.
029         *
030         * <p>Format:
031         * 
032         * <pre>
033         * [prefix] request-method-name: Success | Error code: Message
034         * </pre>
035         *
036         * <p>Example:
037         *
038         * <pre>
039         * [CID dff6fb77-7f96-4b82-a0f9-0ac25cfb1852] ldap.getEntry: Success
040         *
041         * [CID dff6fb77-7f96-4b82-a0f9-0ac25cfb1852] ldap.getEntry: Error -1000: Invalid/expired LDAP connection identifier (CID)
042         * </pre>
043         *
044         * @param request  The JSON-RPC 2.0 request. Must not be {@code null}.
045         * @param response The resulting JSON-RPC 2.0 response. Must not be
046         *                 {@code null}.
047         * @param prefix   The log message prefix. If {@code null} the log 
048         *                 message will not be prefixed.
049         */
050        public static void log(final JSONRPC2Request request, 
051                               final JSONRPC2Response response, 
052                               final String prefix) {
053                
054                if (! log.isInfoEnabled())
055                        return;
056                
057                StringBuilder msg = new StringBuilder();
058                
059                if (prefix != null) {
060                        msg.append("[").append(prefix).append("] ");
061                }
062                
063                msg.append(request.getMethod());
064                
065                msg.append(": ");
066
067
068                if (response.indicatesSuccess()) {
069                        msg.append("Success");
070                } else {
071                        msg.append("Error ")
072                                .append(response.getError().getCode())
073                                .append(": ")
074                                .append(response.getError().getMessage());
075                }
076
077                log.info(msg.toString());
078        }
079        
080        
081        /**
082         * Logs (at INFO level) the name of the JSON-RPC 2.0 request and the 
083         * resulting response (success or error code + message).
084         *
085         * <p>Format:
086         * 
087         * <pre>
088         * request-method-name: Success | Error code: Message
089         * </pre>
090         *
091         * <p>Example:
092         *
093         * <pre>
094         * ldap.getEntry: Success
095         *
096         * ldap.getEntry: Error -1000 Invalid/expired LDAP connection identifier (CID)
097         * </pre>
098         *
099         * @param request  The JSON-RPC 2.0 request. Must not be {@code null}.
100         * @param response The resulting JSON-RPC 2.0 response. Must not be
101         *                 {@code null}.
102         */
103        public static void log(final JSONRPC2Request request, 
104                               final JSONRPC2Response response) {
105        
106                log(request, response, null);
107        }
108        
109        
110        /**
111         * Hides the value of the specified parameter in a JSON-RPC 2.0 request.
112         * The value is replaced by a string "[hidden]". If the specified 
113         * parameter is not found request is returned unmodified.
114         *
115         * <p>This method is intended for logging JSON-RPC 2.0 requests.
116         *
117         * @param request   The JSON-RPC 2.0 request. May be {@code null}.
118         * @param paramName The name of the parameter to hide. May be 
119         *                  {@code null}.
120         *
121         * @return The processed JSON-RPC 2.0 request.
122         */
123        public static JSONRPC2Request hideParameter(final JSONRPC2Request request, 
124                                                    final String paramName) {
125        
126                if (request == null)
127                        return null;
128        
129                if (request.getParamsType() != JSONRPC2ParamsType.OBJECT)
130                        return request;
131                
132                Map <String,Object> params = request.getNamedParams();
133                
134                if (params.containsKey(paramName))
135                        params.put(paramName, "[hidden]");
136                
137                return request;
138        }
139        
140        
141        /**
142         * Hides the "password" parameter value in a JSON-RPC 2.0 request. The
143         * value is replaced by a string "[hidden]". If no "password" parameter
144         * is contained the request is returned unmodified.
145         *
146         * <p>This method is intended for logging JSON-RPC 2.0 requests.
147         *
148         * @param request The JSON-RPC 2.0 request. May be {@code null}.
149         *
150         * @return The JSON-RPC 2.0 request with any password value hidden.
151         */
152        public static JSONRPC2Request hidePassword(final JSONRPC2Request request) {
153        
154                return hideParameter(request, "password");
155        }
156
157
158        /**
159         * Prevents public instantiation.
160         */
161        private JSONRPC2LogUtility() { }
162}