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