Index: api/src/main/java/org/hippoecm/hst/diagnosis/Task.java =================================================================== --- api/src/main/java/org/hippoecm/hst/diagnosis/Task.java (revision 55452) +++ api/src/main/java/org/hippoecm/hst/diagnosis/Task.java (working copy) @@ -1,95 +0,0 @@ -/** - * Copyright 2012-2013 Hippo B.V. (http://www.onehippo.com) - * - * Licensed 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.hippoecm.hst.diagnosis; - -import java.util.Collection; -import java.util.Enumeration; -import java.util.Map; - -/** - * A unit of execution. - * A task may start a subtask, and may contain multiple child subtasks. - * Each task may have attributes map of necessary data needed for diagnostics. - * By the way, the root task should be given by the container. - */ -public interface Task { - - /** - * returns the task name - */ - String getName(); - - /** - * Returns attribute map which is unmodifiable. So, do not try to put or remove items directly from the returned map. - */ - Map getAttributeMap(); - - /** - * Enumerates the attribute names - */ - public Enumeration getAttributeNames(); - - /** - * Set an attribute for the task. The object value should have a proper #toString method - * as by default, the #toString method is used for displaying the object in the diagnostics. - * @param key attribute name - * @param value attribute value - */ - void setAttribute(String key, Object value); - - /** - * Retrieve the attribute value by the attribute name. When not found, null - * is returned - */ - Object getAttribute(String key); - - /** - * Removes the attribute by the attribute name. When an Object was - * removed for key, this object is returned. Otherwise null is returned. - */ - Object removeAttribute(String key); - - /** - * @return Returns the parent task and null if this is the root task - */ - Task getParentTask(); - - /** - * Starts and returns a child subtask with the name. - * @param name - */ - Task startSubtask(String name); - - /** - * Stops the task - */ - void stop(); - - /** - * Returns the child tasks collection - */ - Collection getChildTasks(); - - /** - * Returns true if the task was started but not stopped. - */ - boolean isRunning(); - - /** - * Returns the task execution duration time in milliseconds - */ - long getDurationTimeMillis(); -} Index: commons/src/main/java/org/hippoecm/hst/diagnosis/DefaultTaskImpl.java =================================================================== --- commons/src/main/java/org/hippoecm/hst/diagnosis/DefaultTaskImpl.java (revision 55452) +++ commons/src/main/java/org/hippoecm/hst/diagnosis/DefaultTaskImpl.java (working copy) @@ -1,159 +0,0 @@ -/** - * Copyright 2012-2013 Hippo B.V. (http://www.onehippo.com) - * - * Licensed 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.hippoecm.hst.diagnosis; - -import java.util.Collection; -import java.util.Collections; -import java.util.Enumeration; -import java.util.LinkedHashMap; -import java.util.LinkedList; -import java.util.List; -import java.util.Map; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * DefaultTaskImpl - */ -class DefaultTaskImpl implements Task { - - private static final Logger log = LoggerFactory.getLogger(DefaultTaskImpl.class); - - private final String name; - private Map attributes; - - private final Task parentTask; - private List childTasks; - - private long startTimeMillis; - private long durationTimeMillis = -1L; - private boolean stopped; - - DefaultTaskImpl(final Task parentTask, final String name) { - this.parentTask = parentTask; - this.name = name; - this.startTimeMillis = System.currentTimeMillis(); - } - - @Override - public String getName() { - return name; - } - - @Override - public Map getAttributeMap() { - if (attributes == null) { - return Collections.emptyMap(); - } - - return Collections.unmodifiableMap(attributes); - } - - @Override - public Enumeration getAttributeNames() { - if (attributes != null) { - return Collections.enumeration(attributes.keySet()); - } else { - List emptyAttrNames = Collections.emptyList(); - return Collections.enumeration(emptyAttrNames); - } - } - - @Override - public void setAttribute(String key, Object value) { - if (attributes == null) { - // keep order of insertion thus Linked - attributes = new LinkedHashMap (); - } - - attributes.put(key, value); - } - - @Override - public Object getAttribute(String key) { - if (attributes == null) { - return null; - } - - return attributes.get(key); - } - - @Override - public Object removeAttribute(String key) { - if (attributes != null) { - return attributes.remove(key); - } - - return null; - } - - @Override - public Task getParentTask() { - return parentTask; - } - - @Override - public Task startSubtask(String name) { - if (stopped) { - throw new IllegalStateException("The task was already stopped."); - } - - if (childTasks == null) { - childTasks = new LinkedList(); - } - - Task childTask = new DefaultTaskImpl(this, name); - childTasks.add(childTask); - HDC.setCurrentTask(childTask); - return childTask; - } - - @Override - public void stop() { - if (stopped) { - log.warn("Task '{}' was already stopped.", name); - return; - } - - stopped = true; - durationTimeMillis = System.currentTimeMillis() - startTimeMillis; - HDC.setCurrentTask(parentTask); - } - - @Override - public Collection getChildTasks() { - if (childTasks == null) { - return Collections.emptyList(); - } - - return Collections.unmodifiableCollection(childTasks); - } - - @Override - public boolean isRunning() { - return !stopped; - } - - @Override - public long getDurationTimeMillis() { - if (!stopped) { - log.warn("Task '{}' was not stopped hence duration time unknown.", name); - } - return durationTimeMillis; - } - -} Index: commons/src/main/java/org/hippoecm/hst/diagnosis/HDC.java =================================================================== --- commons/src/main/java/org/hippoecm/hst/diagnosis/HDC.java (revision 55452) +++ commons/src/main/java/org/hippoecm/hst/diagnosis/HDC.java (working copy) @@ -1,71 +0,0 @@ -/** - * Copyright 2012-2013 Hippo B.V. (http://www.onehippo.com) - * - * Licensed 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.hippoecm.hst.diagnosis; - - -/** - * Hierarchical Diagnostic Context - */ -public class HDC { - - public static final Task NOOP_TASK = new NOOPTaskImpl(); - - private static ThreadLocal tlRootTask = new ThreadLocal(); - private static ThreadLocal tlCurrentTask = new ThreadLocal(); - - private HDC() { - } - - public static Task start(String name) { - Task rootTask = tlRootTask.get(); - - if (rootTask != null) { - throw new IllegalStateException("The root task was already started."); - } - - rootTask = new DefaultTaskImpl(null, name); - tlRootTask.set(rootTask); - return rootTask; - } - - public static boolean isStarted() { - return (tlRootTask.get() != null); - } - - public static Task getRootTask() { - Task rootTask = tlRootTask.get(); - return (rootTask != null ? rootTask : NOOP_TASK); - } - - public static Task getCurrentTask() { - Task current = tlCurrentTask.get(); - - if (current != null) { - return current; - } - - return getRootTask(); - } - - public static void setCurrentTask(Task currentTask) { - tlCurrentTask.set(currentTask); - } - - public static void cleanUp() { - tlCurrentTask.remove(); - tlRootTask.remove(); - } -} Index: commons/src/main/java/org/hippoecm/hst/diagnosis/NOOPTaskImpl.java =================================================================== --- commons/src/main/java/org/hippoecm/hst/diagnosis/NOOPTaskImpl.java (revision 55452) +++ commons/src/main/java/org/hippoecm/hst/diagnosis/NOOPTaskImpl.java (working copy) @@ -1,95 +0,0 @@ -/** - * Copyright 2012-2013 Hippo B.V. (http://www.onehippo.com) - * - * Licensed 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.hippoecm.hst.diagnosis; - -import java.util.Collection; -import java.util.Collections; -import java.util.Enumeration; -import java.util.List; -import java.util.Map; - -/** - * NOOPTaskImpl - */ -class NOOPTaskImpl implements Task { - - private boolean stopped; - - NOOPTaskImpl() { - } - - @Override - public String getName() { - return ""; - } - - @Override - public Map getAttributeMap() { - return Collections.emptyMap(); - } - - @Override - public Enumeration getAttributeNames() { - List emptyAttrNames = Collections.emptyList(); - return Collections.enumeration(emptyAttrNames); - } - - @Override - public void setAttribute(String key, Object value) { - } - - @Override - public Object getAttribute(String key) { - return null; - } - - @Override - public Object removeAttribute(String key) { - return null; - } - - @Override - public Task getParentTask() { - return null; - } - - @Override - public Task startSubtask(String name) { - HDC.setCurrentTask(this); - return this; - } - - @Override - public void stop() { - stopped = true; - } - - @Override - public Collection getChildTasks() { - return Collections.emptyList(); - } - - @Override - public boolean isRunning() { - return !stopped; - } - - @Override - public long getDurationTimeMillis() { - return 0L; - } - -} Index: commons/src/main/java/org/hippoecm/hst/util/TaskLogFormatter.java =================================================================== --- commons/src/main/java/org/hippoecm/hst/util/TaskLogFormatter.java (revision 55452) +++ commons/src/main/java/org/hippoecm/hst/util/TaskLogFormatter.java (working copy) @@ -23,7 +23,10 @@ /** * Utility class to get a pretty printed hierarchical task log + * + * @deprecated Use {@link org.hippoecm.hst.diagnosis.TaskLogFormatUtils} instead. */ +@Deprecated public class TaskLogFormatter { private static final Logger log = LoggerFactory.getLogger(TaskLogFormatter.class); Index: commons/src/test/java/org/hippoecm/hst/diagnosis/TestHDC.java =================================================================== --- commons/src/test/java/org/hippoecm/hst/diagnosis/TestHDC.java (revision 55452) +++ commons/src/test/java/org/hippoecm/hst/diagnosis/TestHDC.java (working copy) @@ -1,233 +0,0 @@ -/** - * Copyright 2012-2013 Hippo B.V. (http://www.onehippo.com) - * - * Licensed 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.hippoecm.hst.diagnosis; - -import org.hippoecm.hst.util.TaskLogFormatter; -import org.junit.Test; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertTrue; - -/** - * TestHDC - */ -public class TestHDC { - - private static Logger log = LoggerFactory.getLogger(TestHDC.class); - - private Valve1 valve1 = new Valve1(); - private Valve2 valve2 = new Valve2(); - private Component1 comp1 = new Component1(); - private Component2 comp2 = new Component2(); - private Query query1 = new Query(); - private Query query2 = new Query(); - - @Test - public void testDefaultExample() throws Exception { - // first, the HST container will start the root task first somewhere. e.g., HstFilter or InitializationValve - Task rootTask = HDC.start("request-processing"); - - // when invoking each valve, HST container can start a subtask - { - Task valveTask = HDC.getCurrentTask().startSubtask("valve1"); - valve1.execute(); - // if the container started a subtask, then it should stop the task. - // in reality, it should use try ~ finally to guarantee this call. - valveTask.stop(); - } - - { - Task valveTask = HDC.getCurrentTask().startSubtask("valve2"); - valve2.execute(); - valveTask.stop(); - } - - // also the container will stop the root task. - rootTask.stop(); - - // all the task execution information can be collected and reported later (maybe in another valve before cleanupValve) - final String logSummary = logSummary(); - assertTrue(logSummary.contains("valve2")); - - final String logSummaryWithDepth0 = logSummary(0); - assertFalse(logSummaryWithDepth0.contains("valve2")); - - final String logSummaryWithDepthMinus1 = logSummary(-1); - assertTrue(logSummaryWithDepthMinus1.contains("valve2")); - - final String logSummaryWithDepth1 = logSummary(1); - assertTrue(logSummaryWithDepth1.contains("valve2")); - - // clean up all the stored thread context information.. - HDC.cleanUp(); - } - - @Test - public void testNOOPExample() throws Exception { - - // when invoking each valve, HST container can start a subtask - { - Task valveTask = HDC.getCurrentTask().startSubtask("valve1"); - valve1.execute(); - // if the container started a subtask, then it should stop the task. - // in reality, it should use try ~ finally to guarantee this call. - valveTask.stop(); - } - - { - Task valveTask = HDC.getCurrentTask().startSubtask("valve2"); - valve2.execute(); - valveTask.stop(); - } - - // all the task execution information can be collected and reported later (maybe in another valve before cleanupValve) - final String logSummary = logSummary(); - - assertFalse(logSummary.contains("valve2")); - - // clean up all the stored thread context information.. - HDC.cleanUp(); - } - - @Test - public void testRootTaskOnlyExample() throws Exception { - // first, the HST container will start the root task first somewhere. e.g., HstFilter or InitializationValve - Task rootTask = HDC.start("request-processing"); - HDC.setCurrentTask(HDC.NOOP_TASK); - - // when invoking each valve, HST container can start a subtask - { - Task valveTask = HDC.getCurrentTask().startSubtask("valve1"); - valve1.execute(); - // if the container started a subtask, then it should stop the task. - // in reality, it should use try ~ finally to guarantee this call. - valveTask.stop(); - } - - { - Task valveTask = HDC.getCurrentTask().startSubtask("valve2"); - valve2.execute(); - valveTask.stop(); - } - - // also the container will stop the root task. - rootTask.stop(); - - // all the task execution information can be collected and reported later (maybe in another valve before cleanupValve) - final String logSummary = logSummary(); - - assertFalse(logSummary.contains("valve2")); - - // clean up all the stored thread context information.. - HDC.cleanUp(); - } - - - private String logSummary() { - Task rootTask = HDC.getRootTask(); - return TaskLogFormatter.getTaskLog(rootTask); - } - - private String logSummary(final int depth) { - Task rootTask = HDC.getRootTask(); - return TaskLogFormatter.getTaskLog(rootTask, depth); - } - - - private void sleepRandom(long max) { - try { - Thread.sleep(Math.abs(Math.round(Math.random() * max))); - } catch (InterruptedException e) { - } - } - - class Valve1 { - public void execute() { - sleepRandom(10); - - // A valve can also start a subtask from its current context task. - Task compTask = HDC.getCurrentTask().startSubtask("comp1"); - Task compTaskA = HDC.getCurrentTask().startSubtask("comp1A"); - comp1.execute(); - compTaskA.stop(); - comp1.execute(); - compTask.stop(); - - - - sleepRandom(10); - - compTask = HDC.getCurrentTask().startSubtask("comp2"); - comp2.execute(); - compTask.stop(); - - sleepRandom(10); - } - } - - class Valve2 { - public void execute() { - sleepRandom(10); - - Task compTask = HDC.getCurrentTask().startSubtask("comp1"); - comp1.execute(); - compTask.stop(); - - sleepRandom(10); - - compTask = HDC.getCurrentTask().startSubtask("comp2"); - comp2.execute(); - compTask.stop(); - - sleepRandom(10); - } - } - - // Normally component developers do not need to manage tasks by themselves - // because the task context for each component will be provided by the container. - // e.g., by HstComponentInvoker or an AOP for HstComponentInvoker, etc. - // so, the following component examples doesn't contain task management codes. - class Component1 { - public void execute() { - sleepRandom(10); - query1.execute("//element[jcr:contains(., 'hippo')]"); - sleepRandom(10); - } - } - - class Component2 { - public void execute() { - sleepRandom(10); - query2.execute("//element[jcr:contains(., 'cms')]"); - sleepRandom(10); - } - } - - // HST Content Beans may manage its task context. e.g., HstQuery, HippoBeansIterator, etc. - class Query { - public void execute(String statement) { - sleepRandom(10); - Task queryTask = HDC.getCurrentTask().startSubtask("query"); - sleepRandom(10); - queryTask.setAttribute("statement", statement); - queryTask.stop(); - sleepRandom(10); - } - } - -} Index: components/core/src/main/java/org/hippoecm/hst/core/container/DiagnosticReportingValve.java =================================================================== --- components/core/src/main/java/org/hippoecm/hst/core/container/DiagnosticReportingValve.java (revision 55452) +++ components/core/src/main/java/org/hippoecm/hst/core/container/DiagnosticReportingValve.java (working copy) @@ -18,7 +18,7 @@ import org.hippoecm.hst.configuration.hosting.VirtualHosts; import org.hippoecm.hst.configuration.hosting.VirtualHostsService; import org.hippoecm.hst.diagnosis.Task; -import org.hippoecm.hst.util.TaskLogFormatter; +import org.hippoecm.hst.diagnosis.TaskLogFormatUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -42,9 +42,9 @@ } final int diagnosticsDepth = virtualHostsService.getDiagnosticsDepth(); - log.info("Diagnostic Summary:\n{}", TaskLogFormatter.getTaskLog(rootTask, diagnosticsDepth)); + log.info("Diagnostic Summary:\n{}", TaskLogFormatUtils.getTaskLog(rootTask, diagnosticsDepth)); } else { - log.info("Diagnostic Summary:\n{}", TaskLogFormatter.getTaskLog(rootTask)); + log.info("Diagnostic Summary:\n{}", TaskLogFormatUtils.getTaskLog(rootTask)); } } } Index: pom.xml =================================================================== --- pom.xml (revision 55452) +++ pom.xml (working copy) @@ -82,7 +82,7 @@ 1.5.3 - 2.0.0 + 2.1.0-SNAPSHOT 3.0.0 2.0.0 2.0.0