/*
 * 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 io.prestosql.plugin.hive.authentication;

import org.apache.hadoop.security.UserGroupInformation;

import javax.annotation.concurrent.GuardedBy;
import javax.security.auth.Subject;
import javax.security.auth.kerberos.KerberosTicket;

import static com.google.common.base.Preconditions.checkArgument;
import static io.prestosql.plugin.hive.authentication.KerberosTicketUtils.getTicketGrantingTicket;
import static java.util.Objects.requireNonNull;
import static org.apache.hadoop.security.UserGroupInformationShim.getSubject;

public class CachingKerberosHadoopAuthentication
        implements HadoopAuthentication
{
    private final KerberosHadoopAuthentication delegate;

    private final Object lock = new Object();
    @GuardedBy("lock")
    private UserGroupInformation userGroupInformation;
    @GuardedBy("lock")
    private long nextRefreshTime = Long.MIN_VALUE;

    public CachingKerberosHadoopAuthentication(KerberosHadoopAuthentication delegate)
    {
        this.delegate = requireNonNull(delegate, "hadoopAuthentication is null");
    }

    @Override
    public UserGroupInformation getUserGroupInformation()
    {
        synchronized (lock) {
            if (refreshIsNeeded()) {
                refreshUgi();
            }
            return userGroupInformation;
        }
    }

    @GuardedBy("lock")
    private void refreshUgi()
    {
        userGroupInformation = delegate.getUserGroupInformation();
        nextRefreshTime = calculateNextRefreshTime(userGroupInformation);
    }

    @GuardedBy("lock")
    private boolean refreshIsNeeded()
    {
        return nextRefreshTime < System.currentTimeMillis() || userGroupInformation == null;
    }

    private static long calculateNextRefreshTime(UserGroupInformation userGroupInformation)
    {
        Subject subject = getSubject(userGroupInformation);
        checkArgument(subject != null, "subject must be present in kerberos based UGI");
        KerberosTicket tgtTicket = getTicketGrantingTicket(subject);
        return KerberosTicketUtils.getRefreshTime(tgtTicket);
    }
}

@@ -1242,54 +1242,8 @@
 e;%0A%0A
-    private final Object lock = new Object();%0A
     
@@ -1246,36 +1246,36 @@
     @GuardedBy(%22
-lock
+this
 %22)%0A    private U
@@ -1324,36 +1324,36 @@
     @GuardedBy(%22
-lock
+this
 %22)%0A    private l
@@ -1375,25 +1375,8 @@
 Time
- = Long.MIN_VALUE
 ;%0A%0A 
@@ -1580,16 +1580,29 @@
  public 
+synchronized 
 UserGrou
@@ -1658,110 +1658,91 @@
     
-synchronized (lock) %7B%0A            if (refreshIsNeeded()) %7B%0A                refreshUgi();%0A            %7D
+if (nextRefreshTime %3C System.currentTimeMillis() %7C%7C userGroupInformation == null) %7B
 %0A   
@@ -1750,23 +1750,16 @@
         
-return 
 userGrou
@@ -1774,95 +1774,39 @@
 tion
-;%0A        %7D%0A    %7D%0A%0A    @GuardedBy(%22lock%22)%0A    private void refreshUgi()%0A    %7B%0A        u
+ = requireNonNull(delegate.getU
 serG
@@ -1820,19 +1820,21 @@
 ormation
- = 
+(), %22
 delegate
@@ -1859,18 +1859,32 @@
 mation()
-;%0A
+ is null%22);%0A    
         
@@ -1957,140 +1957,28 @@
     
-%7D%0A%0A
     
-@GuardedBy(%22lock%22)%0A    private boolean refreshIsNeeded()%0A    %7B%0A        return nextRefreshTime %3C System.currentTimeMillis() %7C%7C
+%7D%0A        return
  use
@@ -1994,24 +1994,16 @@
 ormation
- == null
 ;%0A    %7D%0A

Simplify CachingKerberosHadoopAuthentication