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