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 License. 004 * 005 * You can obtain a copy of the License at legal/CDDLv1.0.txt. See the License for the 006 * specific language governing permission and limitations under the License. 007 * 008 * When distributing Covered Software, include this CDDL Header Notice in each file and include 009 * the License file at legal/CDDLv1.0.txt. If applicable, add the following below the CDDL 010 * Header, with the fields enclosed by brackets [] replaced by your own identifying 011 * information: "Portions copyright [year] [name of copyright owner]". 012 * 013 * Copyright 2015 ForgeRock AS. 014 */ 015 016package org.forgerock.util.time; 017 018/** 019 * Provides time related methods for computing durations, for providing the now 020 * instant and other use cases. 021 * <p> 022 * Why using a service interface instead of JVM provided time methods? 023 * <p> 024 * Simply because you gain better control over the time understood by the 025 * application. For example, if you would have to code an expiration time logic, 026 * you would check periodically if the computed expiration timestamp is greater 027 * than the now timestamp. So far, so good. 028 * <p> 029 * When it comes to testing, things gets worst: you typically have to use 030 * {@link Thread#sleep(long)} to wait for a given amount of time so that your 031 * expiration date is reached. That makes tests much longer to execute and 032 * somehow brittle when you're testing short timeouts. 033 * <p> 034 * Using a {@link TimeService} helps you to keep your code readable and provides 035 * a way to better control how the time is flowing for your application 036 * (especially useful in the tests). 037 * <p> 038 * For example, {@link #now()} is used in place of 039 * {@link System#currentTimeMillis()}. in your code and you can easily mock it 040 * and make it return controlled values. Here is an example with <a 041 * href="https://code.google.com/p/mockito/">Mockito</a>: 042 * 043 * <pre> 044 * @Mock 045 * private TimeService time; 046 * 047 * @BeforeMethod 048 * public void setUp() throws Exception { 049 * MockitoAnnotations.initMocks(this); 050 * } 051 * 052 * @Test 053 * public shouldAdvanceInTime() throws Exception { 054 * // Mimics steps in the future at each call 055 * when(time.now()).thenReturn(0L, 1000L, 10000L); 056 * 057 * assertThat(time.now()).isEqualTo(0L); 058 * assertThat(time.now()).isEqualTo(1000L); 059 * assertThat(time.now()).isEqualTo(10000L); 060 * } 061 * </pre> 062 * 063 * TimeService provides a {@linkplain #SYSTEM default service implementation} 064 * using the System provided time methods for ease of use. 065 * 066 * @see System#currentTimeMillis() 067 * @since 1.3.4 068 */ 069public interface TimeService { 070 071 /** 072 * {@link TimeService} implementation based on {@link System}. 073 * 074 * @see System#currentTimeMillis() 075 * @since 1.3.4 076 */ 077 TimeService SYSTEM = new TimeService() { 078 @Override 079 public long now() { 080 return System.currentTimeMillis(); 081 } 082 083 @Override 084 public long since(final long past) { 085 return now() - past; 086 } 087 }; 088 089 /** 090 * Returns a value that represents "now" since the epoch. 091 * 092 * @return a value that represents "now" since the epoch. 093 * @since 1.3.4 094 */ 095 long now(); 096 097 /** 098 * Computes the elapsed time between {@linkplain #now() now} and {@code past}. 099 * 100 * @param past 101 * time value to compare to now. 102 * @return the elapsed time 103 * @since 1.3.4 104 */ 105 long since(long past); 106 107}