package fi.otavanopisto.muikku.plugins.schooldatapyramus.rest; import java.io.Serializable; import java.util.Calendar; import java.util.Date; import java.util.GregorianCalendar; import javax.enterprise.context.SessionScoped; import javax.inject.Inject; import javax.ws.rs.client.Client; import javax.ws.rs.client.Entity; import fi.otavanopisto.muikku.plugins.schooldatapyramus.rest.cache.CachedEntity; import fi.otavanopisto.muikku.plugins.schooldatapyramus.rest.cache.UserEntityCache; import fi.otavanopisto.muikku.plugins.schooldatapyramus.rest.qualifier.PyramusUser; import fi.otavanopisto.muikku.session.SessionController; import fi.otavanopisto.muikku.session.local.LocalSession; @SessionScoped @PyramusUser class UserPyramusClient implements PyramusClient, Serializable { private static final long serialVersionUID = -2643693371146903250L; private static final int EXPIRE_SLACK = 3; @Inject private ClientPool clientPool; @Inject private UserEntityCache entityCache; @Inject @LocalSession private SessionController sessionController; @Inject private PyramusRestClient restClient; @Override public <T> T post(String path, Entity<?> entity, Class<T> type) { Client client = obtainClient(); try { return restClient.post(client, getAccessToken(), path, entity, type); } finally { releaseClient(client); } } @Override public <T> T post(String path, T entity) { Client client = obtainClient(); try { return restClient.post(client, getAccessToken(), path, entity); } finally { releaseClient(client); } } @Override public <T> T put(String path, Entity<?> entity, Class<T> type) { Client client = obtainClient(); try { return restClient.put(client, getAccessToken(), path, entity, type); } finally { releaseClient(client); } } @Override public <T> T put(String path, T entity) { Client client = obtainClient(); try { return restClient.put(client, getAccessToken(), path, entity); } finally { releaseClient(client); } } @Override public <T> T get(String path, Class<T> type) { Client client = obtainClient(); try { CachedEntity<T> cachedEntity = entityCache.get(path, type); if (cachedEntity != null) { return cachedEntity.getData(); } T result = restClient.get(client, getAccessToken(), path, type); if (result != null) { entityCache.put(path, result); } return result; } finally { releaseClient(client); } } @Override public void delete(String path) { Client client = obtainClient(); try { restClient.delete(client, getAccessToken(), path); } finally { releaseClient(client); } } private String getAccessToken() { fi.otavanopisto.muikku.session.AccessToken accessToken = sessionController.getOAuthAccessToken("pyramus"); if (accessToken == null){ return null; } Date expires = accessToken.getExpires(); if(expires.before(new Date())){ Client client = obtainClient(); try { synchronized (this) { accessToken = sessionController.getOAuthAccessToken("pyramus"); if (accessToken == null){ return null; } expires = accessToken.getExpires(); if (expires.before(new Date())) { AccessToken refreshedAccessToken = restClient.refreshAccessToken(client, accessToken.getRefreshToken()); Calendar calendar = new GregorianCalendar(); calendar.setTime(new Date()); calendar.add(Calendar.SECOND, (refreshedAccessToken.getExpiresIn() - EXPIRE_SLACK)); sessionController.addOAuthAccessToken("pyramus", calendar.getTime(), refreshedAccessToken.getAccessToken(), refreshedAccessToken.getRefreshToken()); return refreshedAccessToken.getAccessToken(); } else { return accessToken.getToken(); } } } finally { releaseClient(client); } } return accessToken.getToken(); } private Client obtainClient() { return clientPool.obtainClient(); } private void releaseClient(Client client) { clientPool.releaseClient(client); } }