package kr.co.inger.hotwind.request_check.impl; import java.io.Serializable; import java.util.Map; import javax.servlet.http.HttpServletRequest; import kr.co.inger.hotwind.guice.Guicer; import kr.co.inger.hotwind.request_check.CheckRequest; import kr.co.inger.hotwind.request_check.RequestProvider; import kr.co.inger.hotwind.request_check.backend.RequestCheckKvStore; import kr.co.inger.hotwind.request_check.session.AccessTokenedSession; import kr.co.inger.hotwind.request_check.session.AccessTokenedSessionProvider; import org.aopalliance.intercept.MethodInvocation; import org.apache.commons.lang.ObjectUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.google.common.base.Strings; public class CheckRequestProc { private static Logger logger = LoggerFactory .getLogger(CheckRequestProc.class); public Object invoke(MethodInvocation invocation, CheckRequest annot) throws Throwable { // 일단 저장소를 얻고. RequestCheckKvStore store = getRequestCheckKvStore(); // 캐쉬에서 해당 메서드에 전달하는 맵이나 값이나 인자의 이름 중에 label와 일치하는 값이 캐쉬에 있는지? boolean found = false; BoxRef<String> storeKeyRef = new BoxRef<String>(); // if (checkHttpHeader(invocation, annot, store, storeKeyRef)) { found = true; } else if (checkHttpRequestParam(invocation, annot, store, storeKeyRef)) { found = true; } else if (!Strings.isNullOrEmpty(annot.targetField())) { // path-param와 같이 인자로 그대로 전달되는 경우를 위해서. for (Object arg : invocation.getArguments()) { if (checkAsKeyItself(store, arg)) { found = true; storeKeyRef.setRef(ObjectUtils.toString(arg)); break; } } } // if (found) { Map<String, Serializable> session = bindSession(invocation, store, storeKeyRef); // Object result = invocation.proceed(); // preserve. updateStoredSession(store, storeKeyRef, session); // return result; } else { throw new Exception(annot.errorMessage()); } } private void updateStoredSession(RequestCheckKvStore store, BoxRef<String> storeKeyRef, Map<String, Serializable> session) { if (session != null && store != null && storeKeyRef != null && storeKeyRef.getRef() != null) { // final String key = storeKeyRef.getRef(); if (store.isExists(key)) { store.update(key, session); } else { logger.debug(String.format( "update-stored-session skip, not found. -- %s", key)); } } } private RequestCheckKvStore requestCheckKvStore = null; private RequestCheckKvStore getRequestCheckKvStore() throws Exception { if (requestCheckKvStore == null) { try { requestCheckKvStore = Guicer.get().getInstance( RequestCheckKvStore.class); } catch (Exception exc) { logger.error("No binding for RequestCheckKvStore interface!!!"); throw exc; } } // return requestCheckKvStore; } private Map<String, Serializable> bindSession(MethodInvocation invocation, RequestCheckKvStore store, BoxRef<String> storeKeyRef) { if (invocation.getThis() instanceof RequestProvider && storeKeyRef.getRef() != null) { // final String accesstoken = storeKeyRef.getRef(); // Map<String, Serializable> session = (Map<String, Serializable>) store .fetch(accesstoken); // RequestProvider rp = (RequestProvider) invocation.getThis(); HttpServletRequest req = rp.getHttpServletRequest(); if (null != req .getAttribute(AccessTokenedSessionProvider.SESSION_SAVE_KEY)) { AccessTokenedSession ats = (AccessTokenedSession) req .getAttribute(AccessTokenedSessionProvider.SESSION_SAVE_KEY); ats.setAccesstoken(accesstoken); ats.setInnerMap(session); } else { AccessTokenedSession ats = new AccessTokenedSession(); ats.setAccesstoken(accesstoken); ats.setInnerMap(session); req.setAttribute(AccessTokenedSessionProvider.SESSION_SAVE_KEY, ats); } return session; } else { logger.warn("SKIP set AccessTokenedSession, your JAX-RS resource class isn't a RequestProvider or session-key not-found."); return null; } } private boolean checkAsKeyItself(RequestCheckKvStore store, Object arg) { if (store.isExists(ObjectUtils.toString(arg))) { logger.debug(String.format( "arg itself is in request-check-kv-store. (%s)", arg)); return true; } else return false; } private boolean checkHttpHeader(MethodInvocation invocation, final CheckRequest annot, RequestCheckKvStore store, BoxRef<String> storeKeyRef) { try { Object obj = invocation.getThis(); if (obj instanceof RequestProvider && !Strings.isNullOrEmpty(annot.httpHeaderName())) { RequestProvider rp = (RequestProvider) obj; HttpServletRequest r = rp.getHttpServletRequest(); final String k = annot.httpHeaderName(); final String val = (String) r.getHeader(k); if (checkAsKeyItself(store, val)) { logger.debug(String.format( "http-header has %s = %s, and request-checked ok.", annot.httpHeaderName(), val)); storeKeyRef.setRef(val); return true; } } } catch (Exception exc) { logger.warn( "http-header lookup FAIL! please implement RequestProvider in your JAX-RS resource class.", exc); } return false; } private boolean checkHttpRequestParam(MethodInvocation invocation, final CheckRequest annot, RequestCheckKvStore store, BoxRef<String> storeKeyRef) { try { Object obj = invocation.getThis(); if (!Strings.isNullOrEmpty(annot.targetField()) && obj instanceof RequestProvider) { RequestProvider rp = (RequestProvider) obj; HttpServletRequest r = rp.getHttpServletRequest(); final String v = r.getParameter(annot.targetField()); if (checkAsKeyItself(store, v)) { logger.debug(String .format("http-request has %s = %s, and request-checked ok.", annot.targetField(), v)); storeKeyRef.setRef(v); return true; } } } catch (Exception exc) { logger.warn( "http-parameter lookup FAIL! please implement RequestProvider in your JAX-RS resource class.", exc); } // return false; } }