EMMA Coverage Report (generated Mon Aug 23 17:21:34 CEST 2010)
[all classes][dmg.cells.nucleus]

COVERAGE SUMMARY FOR SOURCE FILE [CDC.java]

nameclass, %method, %block, %line, %
CDC.java100% (1/1)71%  (10/14)65%  (108/167)67%  (36.9/55)

COVERAGE BREAKDOWN BY CLASS AND METHOD

nameclass, %method, %block, %line, %
     
class CDC100% (1/1)71%  (10/14)65%  (108/167)76%  (41.9/55)
clear (): void 0%   (0/1)0%   (0/8)0%   (0/5)
createSession (): void 0%   (0/1)0%   (0/14)0%   (0/5)
createSession (String): void 0%   (0/1)0%   (0/13)0%   (0/2)
setSession (String): void 0%   (0/1)0%   (0/4)0%   (0/2)
getMessageContext (CellMessage): String 100% (1/1)60%  (24/40)70%  (7/10)
setMessageContext (CellMessage): void 100% (1/1)87%  (13/15)96%  (3.9/4)
apply (): void 100% (1/1)90%  (19/21)86%  (6/7)
<static initializer> 100% (1/1)100% (5/5)100% (1/1)
CDC (): void 100% (1/1)100% (18/18)100% (6/6)
clearMessageContext (): void 100% (1/1)100% (4/4)100% (3/3)
getSession (): String 100% (1/1)100% (3/3)100% (1/1)
setCellsContext (CellNucleus): void 100% (1/1)100% (6/6)100% (2/2)
setCellsContext (String, String): void 100% (1/1)100% (7/7)100% (3/3)
setMdc (String, String): void 100% (1/1)100% (9/9)100% (4/4)

1package dmg.cells.nucleus;
2 
3import java.io.Serializable;
4 
5import org.slf4j.MDC;
6import org.dcache.commons.util.NDC;
7 
8import dmg.util.TimebasedCounter;
9 
10/**
11 * The Cell Diagnostic Context, a utility class for working with the
12 * Log4j NDC and MDC.
13 *
14 * Notice that the MDC is automatically inherited by child threads
15 * upon creation. Thus the domain, cell name, and session identifier
16 * is inherited. The same is not true for the NDC, which needs to be
17 * explicitly copied. Special care must be taken when using shared
18 * thread pools, as this can span several cells. For those the MDC
19 * should be initialised per task, not per thread.
20 *
21 * The class serves two purposes:
22 *
23 * - It contains a number of static methods for manipulating the MDC
24 *   and NDC.
25 *
26 * - CDC instances capture the Cells related MDC values and the NDC.
27 *   These can be apply to other threads. This is useful when using
28 *   worker threads that should inherit the context of the task
29 *   creation point.
30 *
31 */
32public class CDC
33{
34    public final static String MDC_DOMAIN = "cells.domain";
35    public final static String MDC_CELL = "cells.cell";
36    public final static String MDC_SESSION = "cells.session";
37 
38    private final static TimebasedCounter _sessionCounter =
39        new TimebasedCounter();
40 
41    private final NDC _ndc;
42    private final String _session;
43    private final String _cell;
44    private final String _domain;
45 
46    /**
47     * Captures the cells diagnostic context of the calling thread.
48     */
49    public CDC()
50    {
51        _session = MDC.get(MDC_SESSION);
52        _cell = MDC.get(MDC_CELL);
53        _domain = MDC.get(MDC_DOMAIN);
54        _ndc = NDC.cloneNdc();
55    }
56 
57    /**
58     * Wrapper around <code>MDC.put</code> and
59     * <code>MDC.remove</code>. <code>value</code> is allowed to e
60     * null.
61     */
62    static private void setMdc(String key, String value)
63    {
64        if (value != null) {
65            MDC.put(key, value);
66        } else {
67            MDC.remove(key);
68        }
69    }
70 
71    /**
72     * Applies the cells diagnostic context to the calling thread.  If
73     * <code>clone</code> is false, then the <code>apply</code> can
74     * only be called once for this CDC. If <code>clone</code> is
75     * true, then the CDC may be applied several times, however the
76     * operation is more expensive.
77     */
78    public void apply()
79    {
80        setMdc(MDC_DOMAIN, _domain);
81        setMdc(MDC_CELL, _cell);
82        setMdc(MDC_SESSION, _session);
83        if (_ndc == null) {
84            NDC.clear();
85        } else {
86            NDC.set(_ndc);
87        }
88    }
89 
90    /**
91     * Returns the session identifier stored in the MDC of the calling
92     * thread.
93     */
94    static public String getSession()
95    {
96        return MDC.get(MDC_SESSION);
97    }
98 
99    /**
100     * Sets the session in the MDC for the calling thread.
101     *
102     * @param session Session identifier.
103     */
104    static public void setSession(String session)
105    {
106        setMdc(MDC_SESSION, session);
107    }
108 
109    /**
110     * Creates and sets a new session identifier. The session
111     * identifier is based on static TimedbasedCounter and is thus
112     * with a high probability unique in this JVM.
113     *
114     * As long as each JVM uses its own prefix, the identifier will be
115     * unique over multible JVMs.
116     *
117     * @see dmg.util.TimedbasedCounter
118     */
119    static public void createSession(String prefix)
120    {
121        setSession(prefix + "-" + _sessionCounter.next());
122    }
123 
124    /**
125     * Creates and sets a new session identifier. Uses the domain name
126     * stored in he MDC of the calling thread as a prefix. This
127     * guarantees uniqueness among a cells system (but see
128     * documentation of TimebasedCounter for the limits).
129     *
130     * @throws IllegalStateException if domain name is not set in MDC
131     * @see dmg.util.TimedbasedCounter
132     */
133    static public void createSession()
134    {
135        Object domain = MDC.get(MDC_DOMAIN);
136        if (domain == null)
137            throw new IllegalStateException("Missing domain name in MDC");
138 
139        createSession(domain.toString());
140    }
141 
142    /**
143     * Setup the cell diagnostic context of the calling
144     * thread. Threads created from the calling thread automatically
145     * inherit this information.
146     */
147    static public void setCellsContext(CellNucleus cell)
148    {
149        setCellsContext(cell.getCellName(), cell.getCellDomainName());
150    }
151 
152    /**
153     * Setup the cell diagnostic context of the calling
154     * thread. Threads created from the calling thread automatically
155     * inherit this information.
156     */
157    static public void setCellsContext(String cellName, String domainName)
158    {
159        setMdc(MDC_CELL, cellName);
160        setMdc(MDC_DOMAIN, domainName);
161    }
162 
163    /**
164     * Returns the message description added to the NDC as part of the
165     * message related diagnostic context.
166     */
167    static protected String getMessageContext(CellMessage envelope)
168    {
169        StringBuilder s = new StringBuilder();
170 
171        Object session = envelope.getSession();
172        if (session != null) {
173            s.append(session).append(' ');
174        }
175 
176        s.append(envelope.getSourceAddress().getCellName());
177 
178        Object msg = envelope.getMessageObject();
179        if (msg instanceof HasDiagnosticContext) {
180            String context =
181                ((HasDiagnosticContext) msg).getDiagnosticContext();
182            s.append(' ').append(context);
183        }
184 
185        return s.toString();
186    }
187 
188    /**
189     * Setup message related diagnostic context for the calling
190     * thread. Adds information about a message to the MDC and NDC.
191     *
192     * @see clearMessageContext
193     */
194    static public void setMessageContext(CellMessage envelope)
195    {
196        Object session = envelope.getSession();
197        NDC.push(getMessageContext(envelope));
198        setMdc(MDC_SESSION, (session == null) ? null : session.toString());
199    }
200 
201    /**
202     * Clears the diagnostic context entries added by
203     * <code>setMessageContext</code>.  For this to work, the NDC has
204     * to be in the same state as when <code>setMessageContext</code>
205     * returned.
206     *
207     * @see setMessageContext
208     */
209    static public void clearMessageContext()
210    {
211        MDC.remove(MDC_SESSION);
212        NDC.pop();
213    }
214 
215    /**
216     * Clears all cells related MDC entries and the NDC.
217     */
218    static public void clear()
219    {
220        MDC.remove(MDC_DOMAIN);
221        MDC.remove(MDC_CELL);
222        MDC.remove(MDC_SESSION);
223        NDC.clear();
224    }
225}

[all classes][dmg.cells.nucleus]
EMMA 2.0.5312 (C) Vladimir Roubtsov