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 * &#064;Mock
045 * private TimeService time;
046 *
047 * &#064;BeforeMethod
048 * public void setUp() throws Exception {
049 *     MockitoAnnotations.initMocks(this);
050 * }
051 *
052 * &#064;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}