package fi.otavanopisto.muikku.plugins.schooldatapyramus.rest; import java.io.Serializable; import java.lang.reflect.Array; import java.util.logging.Level; import java.util.logging.Logger; import javax.annotation.PostConstruct; import javax.enterprise.context.Dependent; import javax.inject.Inject; import javax.ws.rs.client.Client; import javax.ws.rs.client.Entity; import javax.ws.rs.client.Invocation.Builder; import javax.ws.rs.client.WebTarget; import javax.ws.rs.core.Form; import javax.ws.rs.core.MediaType; import javax.ws.rs.core.Response; import fi.otavanopisto.muikku.controller.PluginSettingsController; import fi.otavanopisto.muikku.plugins.schooldatapyramus.SchoolDataPyramusPluginDescriptor; import fi.otavanopisto.muikku.schooldata.SchoolDataBridgeInternalException; import fi.otavanopisto.muikku.schooldata.SchoolDataBridgeUnauthorizedException; @Dependent class PyramusRestClient implements Serializable { private static final long serialVersionUID = 1L; @Inject private Logger logger; @Inject private PluginSettingsController pluginSettingsController; @PostConstruct public void clientInit() { url = pluginSettingsController.getPluginSetting(SchoolDataPyramusPluginDescriptor.PLUGIN_NAME, "rest.url"); clientId = pluginSettingsController.getPluginSetting(SchoolDataPyramusPluginDescriptor.PLUGIN_NAME, "rest.clientId"); clientSecret = pluginSettingsController.getPluginSetting(SchoolDataPyramusPluginDescriptor.PLUGIN_NAME, "rest.clientSecret"); redirectUrl = pluginSettingsController.getPluginSetting(SchoolDataPyramusPluginDescriptor.PLUGIN_NAME, "rest.redirectUrl"); } public <T> T post(Client client, String accssToken, String path, Entity<?> entity, Class<T> type) { WebTarget target = client.target(url + path); Builder request = target.request(); request.header("Authorization", "Bearer " + accssToken); Response response = request.post(entity); try { return createResponse(response, type, path); } finally { response.close(); } } @SuppressWarnings("unchecked") public <T> T post(Client client, String accssToken, String path, T entity) { WebTarget target = client.target(url + path); Builder request = target.request(); request.header("Authorization", "Bearer " + accssToken); Response response = request.post(Entity.entity(entity, MediaType.APPLICATION_JSON)); try { return (T) createResponse(response, entity.getClass(), path); } finally { response.close(); } } public <T> T put(Client client, String accssToken, String path, Entity<?> entity, Class<T> type) { WebTarget target = client.target(url + path); Builder request = target.request(); request.header("Authorization", "Bearer " + accssToken); Response response = request.put(entity); try { return createResponse(response, type, path); } finally { response.close(); } } @SuppressWarnings("unchecked") public <T> T put(Client client, String accssToken, String path, T entity) { WebTarget target = client.target(url + path); Builder request = target.request(); request.header("Authorization", "Bearer " + accssToken); Response response = request.put(Entity.entity(entity, MediaType.APPLICATION_JSON)); try { return (T) createResponse(response, entity.getClass(), path); } finally { response.close(); } } public <T> T get(Client client, String accessToken, String path, Class<T> type) { WebTarget target = client.target(url + path); Builder request = target.request(); request.accept(MediaType.APPLICATION_JSON_TYPE); request.header("Authorization", "Bearer " + accessToken); Response response = request.get(); try { return createResponse(response, type, path); } catch (Throwable t) { // TODO Remove catch once Pyramus 403 issue is resolved logger.log(Level.SEVERE, String.format("Pyramus GET request into %s failed", path), t); return null; } finally { response.close(); } } public void delete(Client client, String accssToken, String path) { WebTarget target = client.target(url + path); Builder request = target.request(); request.header("Authorization", "Bearer " + accssToken); Response response = request.delete(); try { switch (response.getStatus()) { case 200: case 204: case 404: break; case 403: logger.warning(String.format("Pyramus DELETE for path %s unauthorized (%d)", path, response.getStatus())); throw new SchoolDataBridgeUnauthorizedException(String.format("Received http error %d when requesting %s", response.getStatus(), path)); default: logger.warning(String.format("Pyramus DELETE for path %s failed (%d)", path, response.getStatus())); throw new SchoolDataBridgeInternalException(String.format("Received http error %d (%s) when requesting %s", response.getStatus(), response.getEntity(), path)); } } finally { response.close(); } } public AccessToken createAccessToken(Client client, String code) { Form form = new Form() .param("grant_type", "authorization_code") .param("code", code) .param("redirect_uri", redirectUrl) .param("client_id", clientId) .param("client_secret", clientSecret); WebTarget target = client.target(url + "/oauth/token"); Builder request = target.request(); return request.post(Entity.form(form), AccessToken.class); } public AccessToken refreshAccessToken(Client client, String refreshToken){ Form form = new Form() .param("grant_type", "refresh_token") .param("refresh_token", refreshToken) .param("redirect_uri", redirectUrl) .param("client_id", clientId) .param("client_secret", clientSecret); WebTarget target = client.target(url + "/oauth/token"); Builder request = target.request(); return request.post(Entity.form(form), AccessToken.class); } @SuppressWarnings("unchecked") private <T> T createResponse(Response response, Class<T> type, String path) { switch (response.getStatus()) { case 200: return response.readEntity(type); case 204: if (type.isArray()) { return (T) Array.newInstance(type.getComponentType(), 0); } else { return null; } case 403: logger.warning(String.format("Pyramus call for path %s unauthorized (%d)", path, response.getStatus())); throw new SchoolDataBridgeUnauthorizedException(String.format("Received http error %d (%s) when requesting %s", response.getStatus(), response.getEntity(), path)); case 404: return null; default: logger.warning(String.format("Pyramus call for path %s failed (%d)", path, response.getStatus())); throw new SchoolDataBridgeInternalException(String.format("Received http error %d (%s) when requesting %s", response.getStatus(), response.getEntity(), path)); } } private String url; private String clientId; private String clientSecret; private String redirectUrl; }