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