001/* 002 * The contents of this file are subject to the terms of the Common Development and 003 * Distribution License (the License). You may not use this file except in compliance with the 004 * License. 005 * 006 * You can obtain a copy of the License at legal/CDDLv1.0.txt. See the License for the 007 * specific language governing permission and limitations under the License. 008 * 009 * When distributing Covered Software, include this CDDL Header Notice in each file and include 010 * the License file at legal/CDDLv1.0.txt. If applicable, add the following below the CDDL 011 * Header, with the fields enclosed by brackets [] replaced by your own identifying 012 * information: "Portions copyright [year] [name of copyright owner]". 013 * 014 * Copyright 2014 ForgeRock AS. 015 */ 016 017package org.forgerock.openig.decoration.timer; 018 019import static org.forgerock.openig.log.LogSink.*; 020 021import org.forgerock.json.fluent.JsonValue; 022import org.forgerock.openig.decoration.Context; 023import org.forgerock.openig.decoration.Decorator; 024import org.forgerock.openig.decoration.helper.AbstractHandlerAndFilterDecorator; 025import org.forgerock.openig.filter.Filter; 026import org.forgerock.openig.handler.Handler; 027import org.forgerock.openig.decoration.helper.DecoratorHeaplet; 028import org.forgerock.openig.heap.Heap; 029import org.forgerock.openig.heap.HeapException; 030import org.forgerock.openig.heap.Name; 031import org.forgerock.openig.log.LogSink; 032import org.forgerock.openig.log.Logger; 033 034/** 035 * The {@literal timer} decorator can decorate both {@link Filter} and {@link Handler} instances. 036 * It will log {@literal started}, {@literal elapsed} and {@literal elapsed-within} events into the {@link LogSink} 037 * of the decorated heap object. 038 * <p> 039 * It has to be declared inside of the heap objects section: 040 * <pre> 041 * {@code 042 * { 043 * "name": "timer", 044 * "type": "TimerDecorator" 045 * } 046 * } 047 * </pre> 048 * <p> 049 * To decorate a component, just add the decorator declaration next to the {@code config} element: 050 * <pre> 051 * {@code 052 * { 053 * "type": "...", 054 * "timer": true, 055 * "config": { ... } 056 * } 057 * } 058 * </pre> 059 * 060 * There is no special configuration required for this decorator. 061 * 062 * A default {@literal timer} decorator is automatically created when OpenIG starts. 063 */ 064public class TimerDecorator extends AbstractHandlerAndFilterDecorator { 065 066 /** 067 * Key to retrieve a {@link TimerDecorator} instance from the {@link Heap}. 068 */ 069 public static final String TIMER_HEAP_KEY = "timer"; 070 071 @Override 072 protected Filter decorateFilter(final Filter delegate, final JsonValue decoratorConfig, final Context context) 073 throws HeapException { 074 if (decoratorConfig.asBoolean()) { 075 return new TimerFilter(delegate, getLogger(context)); 076 } 077 return delegate; 078 } 079 080 @Override 081 protected Handler decorateHandler(final Handler delegate, final JsonValue decoratorConfig, final Context context) 082 throws HeapException { 083 if (decoratorConfig.asBoolean()) { 084 return new TimerHandler(delegate, getLogger(context)); 085 } 086 return delegate; 087 } 088 089 /** 090 * Builds a new Logger dedicated for the heap object context. 091 * 092 * @param context 093 * Context of the heap object 094 * @return a new Logger dedicated for the heap object context. 095 * @throws HeapException 096 * when no logSink can be resolved (very unlikely to happen). 097 */ 098 private static Logger getLogger(final Context context) throws HeapException { 099 // Use the sink of the decorated component 100 Heap heap = context.getHeap(); 101 LogSink sink = heap.resolve(context.getConfig().get("logSink").defaultTo(LOGSINK_HEAP_KEY), LogSink.class); 102 Name name = context.getName(); 103 return new Logger(sink, name.decorated("Timer")); 104 } 105 106 /** 107 * Creates and initializes a TimerDecorator in a heap environment. 108 */ 109 public static class Heaplet extends DecoratorHeaplet { 110 @Override 111 public Decorator create() throws HeapException { 112 return new TimerDecorator(); 113 } 114 } 115}