001/**
002 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
003 *
004 * Copyright (c) 2006 Sun Microsystems Inc. All Rights Reserved
005 *
006 * The contents of this file are subject to the terms
007 * of the Common Development and Distribution License
008 * (the License). You may not use this file except in
009 * compliance with the License.
010 *
011 * You can obtain a copy of the License at
012 * https://opensso.dev.java.net/public/CDDLv1.0.html or
013 * opensso/legal/CDDLv1.0.txt
014 * See the License for the specific language governing
015 * permission and limitations under the License.
016 *
017 * When distributing Covered Code, include this CDDL
018 * Header Notice in each file and include the License file
019 * at opensso/legal/CDDLv1.0.txt.
020 * If applicable, add the following below the CDDL Header,
021 * with the fields enclosed by brackets [] replaced by
022 * your own identifying information:
023 * "Portions Copyrighted [year] [name of copyright owner]"
024 *
025 * $Id: InteractionManager.java,v 1.5 2008/08/06 17:28:10 exu Exp $
026 *
027 */
028
029package com.sun.identity.liberty.ws.interaction;
030
031import com.sun.identity.common.PeriodicCleanUpMap;
032import com.sun.identity.common.SystemTimerPool;
033import com.sun.identity.common.TaskRunnable;
034import com.sun.identity.common.TimerPool;
035import com.sun.identity.shared.debug.Debug;
036import com.sun.identity.shared.encode.URLEncDec;
037import com.sun.identity.liberty.ws.common.LogUtil;
038import com.sun.identity.liberty.ws.interaction.jaxb.InquiryElement;
039import com.sun.identity.liberty.ws.interaction.jaxb.InteractionResponseElement;
040import com.sun.identity.liberty.ws.interaction.jaxb.RedirectRequestElement;
041import com.sun.identity.liberty.ws.interaction.jaxb.StatusElement;
042import com.sun.identity.liberty.ws.interaction.jaxb.UserInteractionElement;
043import com.sun.identity.liberty.ws.soapbinding.Client;
044import com.sun.identity.liberty.ws.soapbinding.CorrelationHeader;
045import com.sun.identity.liberty.ws.soapbinding.Message;
046import com.sun.identity.liberty.ws.soapbinding.SOAPBindingConstants;
047import com.sun.identity.liberty.ws.soapbinding.SOAPBindingException;
048import com.sun.identity.liberty.ws.soapbinding.SOAPFault;
049import com.sun.identity.liberty.ws.soapbinding.SOAPFaultDetail;
050import com.sun.identity.liberty.ws.soapbinding.SOAPFaultException;
051import com.sun.identity.liberty.ws.soapbinding.Utils;
052import com.sun.identity.saml.common.SAMLUtils;
053import java.io.IOException;
054import java.math.BigInteger;
055import java.net.InetAddress;
056import java.net.MalformedURLException;
057import java.net.UnknownHostException;
058import java.net.URL;
059import java.util.ArrayList;
060import java.util.Collections;
061import java.util.ConcurrentModificationException;
062import java.util.Date;
063import java.util.Enumeration;
064import java.util.HashMap;
065import java.util.Iterator;
066import java.util.logging.Level;
067import java.util.List;
068import java.util.Map;
069import javax.servlet.http.HttpServletRequest;
070import javax.servlet.http.HttpServletResponse;
071import javax.xml.bind.JAXBException;
072import javax.xml.namespace.QName;
073import org.w3c.dom.Element;
074
075/**
076 *  This class provides the interface and implementation for supporting 
077 *  resource owner interaction.  <code>WSC</code> and <code>WSP</code> would
078 *  collaborate with the singleton object instance of this class to provide
079 *  and use resource owner interaction.  
080 *  @supported.api
081 */
082public class InteractionManager {
083
084    /**
085     *
086     * Name of URL query parameter to be used by <code>WSC</code> to include
087     * <code>returnToURL</code>, while redirecting user agent to
088     * <code>WSP</code>.
089     *
090     * @supported.all.api
091     */
092    public static final String RETURN_TO_URL = "ReturnToURL";
093
094    /**
095     * Name of suggested URL query parameter to be used by <code>WSC</code>
096     * to include an ID to refer to request message that led to user agent
097     * redirect.
098     *
099     * @supported.api
100     */
101    public static final String REQUEST_ID = "RequestID";
102
103    /**
104     * Name of URL query parameter to be used by <code>WSC</code> to include 
105     * <code>providerID</code> of <code>IDP</code>, that was used to
106     * authenticate user.
107     *
108     * @supported.api
109     */
110    public static final String IDP = "IDP";
111
112    /**
113     * Name of URL query parameter to be used by <code>WSP</code> to include 
114     * an ID to indicate that user agent is redirected back to
115     * <code>WSC</code> from <code>WSP</code>
116     *
117     * @supported.api
118     */
119    public static final String RESEND_MESSAGE = "ResendMessage";
120
121    /**
122     * Name space URI of interaction service 
123     * @supported.api
124     */
125    public static final String INTERACTION_NAMESPACE 
126            = "urn:liberty:is:2003-08"; 
127
128    /** 
129     * <code>QName</code> for <code>s:Server</code>
130     * <code>s</code> - soap name space prefix
131     */
132    public static final QName QNAME_SERVER
133            = new QName(SOAPBindingConstants.NS_SOAP, "Server");
134    /** 
135     * <code>QName</code> for <code>is:interactIfNeeded</code>
136     * <code>is</code> - name space prefix for interaction service
137     */
138    public static final QName QNAME_INTERACT_IF_NEEDED 
139            = new QName(INTERACTION_NAMESPACE, "interactIfNeeded", "is");
140
141    /** 
142     * <code>QName</code> for <code>is:doNotInteract</code>
143     * <code>is</code> - name space prefix for interaction service
144     */
145    public static final QName QNAME_DO_NOT_INTERACT
146            = new QName(INTERACTION_NAMESPACE, "doNotInteract", "is");
147
148    /** 
149     * <code>QName</code> for <code>is:doNotInteractForData</code>
150     * <code>is</code> - name space prefix for interaction service
151     */
152    public static final QName QNAME_DO_NOT_INTERACT_FOR_DATA
153            = new QName(INTERACTION_NAMESPACE, "doNotInteractForData", "is");
154
155    /** 
156     * <code>QName</code> for <code>is:interactionRequired</code>
157     * <code>is</code> - name space prefix for interaction service
158     */
159    public static final QName QNAME_INTERACTION_REQUIRED 
160            = new QName(INTERACTION_NAMESPACE, "interactionRequired");
161
162    /** 
163     * <code>QName</code> for <code>is:forData</code>
164     * <code>is</code> - name space prefix for interaction service
165     */
166    public static final QName QNAME_INTERACTION_REQUIRED_FOR_DATA 
167            = new QName(INTERACTION_NAMESPACE, "forData");
168
169    /** 
170     * <code>QName</code> for <code>is:timeNotSufficient</code>
171     * <code>is</code> - name space prefix for interaction service
172     */
173    public static final QName QNAME_INTERACTION_TIME_NOT_SUFFICEINT 
174            = new QName(INTERACTION_NAMESPACE, "timeNotSufficient");
175
176    /** 
177     * <code>QName</code> for <code>is:timeOut</code>
178     * <code>is</code> - name space prefix for interaction service
179     */
180    public static final QName QNAME_INTERACTION_TIMED_OUT 
181            = new QName(INTERACTION_NAMESPACE, "timeOut");
182
183    /** 
184     * <code>QName</code> for <code>is:interactIfNeeded</code>
185     * <code>is</code> - name space prefix for interaction service
186     */
187    public static final QName QNAME_INTERACTION_CAN_NOT_DETERMINE_REQUEST_HOST
188            = new QName(INTERACTION_NAMESPACE,
189                        "canNotDetermineRequestHostName");
190
191    /** 
192     * Constant string to indicate generic server error
193     */
194    public static final String SERVER_ERROR = "Server Error";
195
196    static final String TRANS_ID = "TransID";
197
198    private static InteractionManager interactionManager = null;
199    private static Debug debug = Debug.getInstance("libIDWSF");
200
201    private static final String REDIRECT_URL = "redirectURL";
202
203    private static final String FAULT_ACTOR 
204            = "http://schemas.xmlsoap.org/soap/actor/next";
205
206    private static final String INTERACTION_RB_NAME = "libInteraction";
207
208    private InteractionCache cache = new InteractionCache();
209    private com.sun.identity.liberty.ws.interaction.jaxb.ObjectFactory 
210             objectFactory;
211    private InteractionConfig interactionConfig;
212
213    /**
214     * Gets singleton object instance of <code>InteractionManager</code>
215     * @return singleton object instance of <code>InteractionManager</code>
216     *
217     * @supported.api
218     */
219    synchronized public static InteractionManager getInstance() {
220        if (interactionManager == null) {
221            interactionManager = new InteractionManager();
222        }
223        return interactionManager;
224    }
225
226    private InteractionManager() {
227        objectFactory = JAXBObjectFactory.getObjectFactory();
228        interactionConfig = InteractionConfig.getInstance();
229        if (debug.messageEnabled()) {
230            debug.message(
231                    "InteractionManager():constructed singleton instance");
232        }
233    }
234
235    /**
236     * Sends SOAP request to <code>WSP</code>.  
237     * This would be invoked at <code>WSC</code> side.
238     *
239     * @param requestMessage request message.
240     * @param connectTo SOAP URL to which to send the SOAP request
241     * @param certAlias SOAP Client Certificate Alias
242     * @param soapAction SOAP Action Attribute
243     * @param returnToURL URL to which to redirect user agent after
244     *                   <code>WSP</code> - resource owner interactions
245     * @param httpRequest HTTP request object of current user agent request
246     * @param httpResponse HTTP response object of current user agent request
247     * @return response SOAP response message sent by <code>WSP</code>.
248     *
249     * @throws InteractionException for generic interaction error
250     * @throws InteractionRedirectException if user agent is redirected to 
251     *                     <code>WSP</code> for resource owner interactions
252     * @throws SOAPBindingException  for generic SOAP binding errors
253     * @throws SOAPFaultException if the response message has SOAP fault
254     *
255     * @supported.api
256     */
257    public Message sendRequest(Message requestMessage, 
258            String connectTo,
259            String certAlias,
260            String soapAction,
261            String returnToURL,
262            HttpServletRequest httpRequest, 
263            HttpServletResponse httpResponse) 
264            throws InteractionException, InteractionRedirectException, 
265            SOAPBindingException, SOAPFaultException  {
266
267        if (debug.messageEnabled()) {
268            debug.message("InteractionManager.sendRequest():"
269                    + " entering with messageID="
270                    + requestMessage.getCorrelationHeader().getMessageID()
271                    + ":refToMessageID="
272                    + requestMessage.getCorrelationHeader().getRefToMessageID()
273                    + ":requestMessage=" + requestMessage);
274        }
275
276        // construct and set UserInteraction element in requestMessage
277        if (interactionConfig.wscIncludesUserInteractionHeader()) {
278            Enumeration locales = httpRequest.getLocales();
279            List acceptLanguages = new ArrayList();
280            while (locales.hasMoreElements()) {
281                acceptLanguages.add(locales.nextElement().toString());
282            }
283            if (debug.messageEnabled()) {
284                debug.message("InteractionManager.sendRequest():"
285                        + "Accept-Language specified by httpRequest="
286                        + acceptLanguages);
287            }
288            UserInteractionElement ue = createUserInteractionElement(
289                    acceptLanguages);
290            String id = SAMLUtils.generateID();
291            ue.setId(id);
292            if (ue != null) {
293                try {
294                    Element element = Utils.convertJAXBToElement(ue);
295                    requestMessage.setOtherSOAPHeader(
296                            element,
297                            id);
298
299                } catch (JAXBException je) {
300                    debug.error("InteractionManager.sendRequest():"
301                    + "not setting userInteractionHeader:"
302                    + "can not convert JAXBObject to Element", je);
303                } 
304            }
305        }
306
307        Message responseMessage = null;
308        try {
309            if (debug.messageEnabled()) {
310                debug.message("InteractionManager.sendRequest():"
311                        + "invoking soap Client.sendRequest():"
312                        + ":requestMessage=" + requestMessage
313                        + ":connecTo=" + connectTo);
314            }
315            if (LogUtil.isLogEnabled()) {
316                String[] objs =new String[1];
317                objs[0] = requestMessage.getCorrelationHeader()
318                        .getMessageID();
319                LogUtil.access(Level.INFO, LogUtil.IS_SENDING_MESSAGE,objs);
320            }
321            responseMessage = Client.sendRequest(requestMessage, 
322                connectTo, certAlias, soapAction);
323        } catch (SOAPFaultException sfe) {
324            if (debug.messageEnabled()) {
325                debug.message("InteractionManager.sendRequest():"
326                        + " catching SOAPFaultException="
327                        + sfe);
328            }
329            String redirectURL = getRedirectURL(sfe);
330            if(redirectURL == null) {
331               throw sfe;
332            }
333            String responseID = getResponseID(sfe);
334            responseMessage = handleRedirectRequest(requestMessage, 
335                    redirectURL, responseID, connectTo, certAlias, soapAction,
336                    returnToURL, httpRequest, httpResponse);
337        }
338        if (debug.messageEnabled()) {
339            debug.message("InteractionManager.sendRequest():"
340                    + " returning response message=" + responseMessage);
341        }
342        if (LogUtil.isLogEnabled()) {
343            String[] objs = new String[2];
344            objs[0] = responseMessage.getCorrelationHeader().getMessageID();
345            objs[1] = requestMessage.getCorrelationHeader().getMessageID();
346            LogUtil.access(Level.INFO,LogUtil.IS_RETURNING_RESPONSE_MESSAGE,
347                           objs);
348        }
349        return responseMessage;
350    }
351
352    /**
353     * Resends a previously cached SOAP request message to <code>WSP</code>.
354     * This would be invoked at <code>WSC</code> side. Message ID for the cached
355     * message should be provided as value of <code>REQUEST_ID</code> query
356     * parameter in <code>httpRequest</code>.
357     *
358     * @param returnToURL URL to which to redirect user agent after
359     *        <code>WSP</code> - resource owner interactions
360     * @param httpRequest HTTP request object of current user agent request
361     * @param httpResponse HTTP response object of current user agent request
362     * @return response SOAP message sent by <code>WSP</code>.
363     *
364     * @throws InteractionException for generic interaction error
365     * @throws InteractionRedirectException if user agent is redirected to 
366     *         <code>WSP</code> for resource owner interactions
367     * @throws SOAPBindingException if there are generic SOAP errors
368     * @throws SOAPFaultException if the response message has SOAP fault
369     *
370     * @see #REQUEST_ID
371     *
372     * @supported.api
373     */
374    public Message resendRequest(String returnToURL,
375            HttpServletRequest httpRequest,  
376            HttpServletResponse httpResponse) 
377            throws InteractionRedirectException, InteractionException, 
378            SOAPBindingException, SOAPFaultException {
379
380        return resendRequest(returnToURL, httpRequest, httpResponse, null);
381    }
382
383    /**
384     * Resends a SOAP request message to <code>WSP</code>.
385     * This would be invoked at <code>WSC</code> side.
386     *
387     * @param returnToURL URL to which to redirect user agent after
388     *                    <code>WSP</code> - resource owner interactions
389     * @param httpRequest HTTP request object of current user agent request
390     * @param httpResponse HTTP response object of current user agent request
391     * @param requestMessage SOAP message to be resent.
392     * @return response SOAP message sent by <code>WSP</code>.
393     *
394     * @throws InteractionException for generic interaction error
395     * @throws InteractionRedirectException if user agent is redirected to 
396     *                     <code>WSP</code> for resource owner interactions
397     * @throws SOAPBindingException  for generic SOAP errors
398     * @throws SOAPFaultException if the response message has SOAP fault
399     *
400     * @supported.api
401     */
402    public Message resendRequest(String returnToURL,
403            HttpServletRequest httpRequest,  
404            HttpServletResponse httpResponse, Message requestMessage) 
405            throws InteractionRedirectException, InteractionException, 
406            SOAPBindingException, SOAPFaultException {
407
408        if (debug.messageEnabled()) {
409            debug.message("InteractionManager.resendRequest():entering ");
410        }
411
412        //check for RESEND_MESSAGE parameter
413        String messageID = httpRequest.getParameter(RESEND_MESSAGE);
414        if (messageID == null) {
415            debug.error("InteractionManager.resend():"
416                    + " request without " + RESEND_MESSAGE + " in requestURL=" 
417                    + httpRequest.getRequestURL().toString());
418            String objs[] = {RESEND_MESSAGE};
419            throw new InteractionException(INTERACTION_RB_NAME, 
420                    "missing_query_parameter", objs);
421        }
422
423        //check whether WSP advised not to resend
424        if ( (messageID == "0") || (messageID.equals("false")) ) {
425            debug.error("InteractionManager.resend():"
426                    + " resend not allowed in requestURL=" 
427                    + httpRequest.getRequestURL().toString());
428            throw new InteractionException(INTERACTION_RB_NAME, 
429                    "wsp_advised_not_to_resend", null);
430        }
431
432        //check for original REQUEST_ID
433        messageID = httpRequest.getParameter(REQUEST_ID);
434        if (messageID == null) {
435            debug.error("InteractionManager.resend():"
436                    + " request without " +  REQUEST_ID + " in requestURL=" 
437                    +  httpRequest.getRequestURL().toString());
438            String[] objs = {REQUEST_ID};
439            throw new InteractionException(INTERACTION_RB_NAME, 
440                    "request_missing_query_parameter", objs);
441        }
442
443        String connectTo = getConnectTo(messageID);
444        if (connectTo == null) {
445            debug.error("InteractionManager.resend():"
446                    + " old connectTo not  found for messageID=" 
447                    + messageID);
448            throw new InteractionException(INTERACTION_RB_NAME, 
449                    "old_connectTo_not_found", null);
450        }
451
452        if (requestMessage == null) {
453            if (debug.messageEnabled()) {
454                debug.message("InteractionManager.resendRequest():"
455                        + "invoking with null requestMessage:"
456                        + "old cached message would be used");
457            }
458            Message oldMessage = getRequestMessage(messageID);
459            if (oldMessage == null) {
460                debug.error("InteractionManager.resend():"
461                        + " old message not  found for messageID=" 
462                        + messageID);
463                throw new InteractionException(INTERACTION_RB_NAME, 
464                        "old_message_not_found", null);
465            }
466            requestMessage = oldMessage;
467        } else {
468            if (debug.messageEnabled()) {
469                debug.message("InteractionManager.resendRequest():"
470                        + "invoking with non null requestMessage");
471            }
472        }
473
474        CorrelationHeader ch = new CorrelationHeader();
475        ch.setRefToMessageID(InteractionManager.getInstance()
476                .getRequestMessageID(messageID));
477        requestMessage.setCorrelationHeader(ch);
478
479        if (debug.messageEnabled()) {
480            debug.message("InteractionManager.resendRequest():"
481                    + "invoking InteractionManager.sendRequest():"
482                    + "with requestMessage=" + requestMessage
483                    + ":returnToURL=" + returnToURL);
484        }
485
486        if (LogUtil.isLogEnabled()) {
487            String[] objs =new String[2];
488            objs[0] = messageID;
489            objs[1] = ch.getMessageID();
490            LogUtil.access(Level.INFO,LogUtil.IS_RESENDING_MESSAGE,objs);
491        }
492        Message responseMessage = sendRequest(requestMessage, connectTo, 
493                getClientCert(messageID), getSoapAction(messageID),
494                returnToURL, httpRequest,  httpResponse);
495        if (debug.messageEnabled()) {
496            debug.message("InteractionManager.resendRequest():"
497                    + " returning responseMessage=" + responseMessage);
498        }
499        return responseMessage;
500    }
501
502    private Message handleRedirectRequest(Message requestMessage, 
503            String redirectURL, String messageID, String connectTo, 
504            String certAlias, String soapAction, String returnToURL, 
505            HttpServletRequest httpRequest,  HttpServletResponse httpResponse)
506            throws InteractionRedirectException, InteractionException {
507        
508        if (debug.messageEnabled()) {
509            debug.message("InteractionManager.handleRedirectRequest():"
510                    + "entering with redirectURL="
511                    + redirectURL);
512        }
513
514        //redirectURL should not have ReturnToURL parameter
515        if (!(redirectURL.indexOf(RETURN_TO_URL + "=") == -1)) {
516            debug.error(
517                    "InteractionManager.handleRedirectRequest():"
518                    + "Invalid redirectURL - illegal parameter " 
519                    + RETURN_TO_URL
520                    + " in redirectURL=" + redirectURL); 
521            String objs[] = {RETURN_TO_URL, REDIRECT_URL};
522            throw new InteractionException(INTERACTION_RB_NAME,
523                    "illegal_parameter_in_redirectURL", objs);
524        }
525
526        //redirectURL should not have IDP parameter
527        if (!(redirectURL.indexOf(IDP + "=") == -1)) {
528            debug.error(
529                    "InteractionManager.handleRedirectRequest():"
530                    + "Invalid redirectURL - illegal parameter:" 
531                    + IDP 
532                    + " in redirectURL=" + redirectURL); 
533            String objs[] = {IDP, REDIRECT_URL};
534            throw new InteractionException(INTERACTION_RB_NAME,
535                    "illegal_parameter_in_redirectURL", objs);
536        }
537
538        //redirectURL should be https
539        if (InteractionConfig.getInstance().wscEnforcesHttpsCheck()
540                    && (redirectURL.indexOf("https") != 0) ) {
541            debug.error(
542                    "InteractionManager.handleRedirectRequest():"
543                    + "Invalid Request " 
544                    + InteractionManager.REDIRECT_URL
545                    + " not https"
546                    + " in redirectURL=" + redirectURL); 
547            throw new InteractionException(INTERACTION_RB_NAME,
548                    "redirectURL_not_https", null);
549        }
550
551        //redirectURL should point to connectTo host
552        if (InteractionConfig.getInstance()
553                    .wspEnforcesReturnToHostEqualsRequestHost()
554                    && !checkRedirectHost(redirectURL, connectTo)) {
555            debug.error(
556                    "InteractionManager.handleRedirectRequest():"
557                    + "Invalid Request redirectToHost differs from " 
558                    + " connectToHost:"
559                    + " in redirectURL=" + redirectURL 
560                    + ":connectTo=" + connectTo); 
561            throw new InteractionException(INTERACTION_RB_NAME,
562                    "redirectURL_differs_from_connectTo", null);
563        }
564
565        String requestID = requestMessage.getCorrelationHeader().getMessageID();
566        setRequestMessage(requestID, requestMessage);
567        setConnectTo(requestID, connectTo);
568        setSoapAction(requestID, soapAction);
569        setClientCert(requestID, certAlias);
570        setRequestMessageID(requestID, messageID);
571        if (debug.messageEnabled()) {
572            debug.message("InteractionManager.handleRedirectRequest():cached "
573                    + " request message for messageID=" + messageID
574                    + ":requestID=" + requestID
575                    + ":requestMessage:" + (requestMessage == null) );
576        }
577
578        returnToURL = returnToURL + "?" + REQUEST_ID + "=" + requestID;
579        redirectURL = redirectURL +"&"+ RETURN_TO_URL + "="
580                + URLEncDec.encode(returnToURL);
581        if (debug.messageEnabled()) {
582            debug.message("InteractionManager.handleRedirectRequest():"
583                    + "redirecting user agent to redirectURL= "
584                    + redirectURL);
585        }
586        try {
587            httpResponse.sendRedirect(redirectURL);
588        } catch (IOException ioe) { //IOException
589            debug.error("InteractionManager.handleRedirectRequest():"
590                    + " catching IOException", ioe);
591            throw new InteractionException(INTERACTION_RB_NAME,
592                    "IOException_in_Interaction_Manager", null);
593        }
594        if (debug.messageEnabled()) {
595            debug.message("InteractionManager.handleRedirectRequest():"
596                    + "redirected user agent to redirectURL= "
597                    + redirectURL);
598        }
599        if (LogUtil.isLogEnabled()) {
600            String[] objs =new String[1];
601            objs[0] = requestID;
602            LogUtil.access(Level.INFO,LogUtil.IS_REDIRECTED_USER_AGENT,objs);
603        }
604        throw new InteractionRedirectException(requestID);
605        //return returnMessage;
606    }
607
608    /**
609     * Handles resource owner interactions on behalf of <code>WSP</code>.
610     * This is invoked at <code>WSP</code> side.
611     *
612     * @param requestMessage SOAP request that requires resource
613     *             owner interactions
614     * @param inquiryElement query that <code>WSP</code> wants to pose to
615     *        resource owner.
616     * @return SOAP message that contains <code>InteractionResponse</code>,
617     *         gathered by <code>InteractionManager</code>
618     *
619     * @throws InteractionException for generic interaction error
620     * @throws InteractionSOAPFaultException if a SOAP fault
621     *         has to be returned  to <code>WSC</code>
622     * @throws SOAPFaultException if the response message has SOAP fault
623     *
624     * @deprecated
625     *
626     */
627    public Message handleInteraction(Message requestMessage,
628            InquiryElement inquiryElement) throws InteractionException, 
629            InteractionSOAPFaultException, SOAPFaultException {
630        return handleInteraction(requestMessage, inquiryElement, null);
631    }
632
633    /**
634     * Handles resource owner interactions on behalf of <code>WSP</code>.
635     * This is invoked at <code>WSP</code> side.
636     *
637     * @param requestMessage SOAP request that requires resource
638     *             owner interactions
639     * @param inquiryElement query that <code>WSP</code> wants to pose to
640     *        resource owner 
641     * @param language language in which the query page needs to be rendered
642     * @return SOAP message that contains <code>InteractionResponse</code>,
643     *         gathered by <code>InteractionManager</code>
644     *
645     * @throws InteractionException for generic interaction error
646     * @throws InteractionSOAPFaultException if a SOAP fault
647     *         has to be returned  to <code>WSC</code>
648     * @throws SOAPFaultException if the response message has SOAP fault
649     *
650     * @supported.api
651     */
652    public Message handleInteraction(Message requestMessage,
653           InquiryElement inquiryElement, String language)
654           throws InteractionException, 
655           InteractionSOAPFaultException, SOAPFaultException {
656
657        if (debug.messageEnabled()) {
658            debug.message("InteractionManager.handleInteraction():entering");
659        }
660
661        //Check redirect is enabled for WSP
662        if (!interactionConfig.wspSupportsRedirect()) {
663            if (debug.warningEnabled()) {
664                debug.warning("InteractionManager.handleInteraction():"
665                        + " WSP requests for interaction:wspWillRedirect=" 
666                        + interactionConfig.wspSupportsRedirect());
667                debug.warning("InteractionManager.handleInteraction():"
668                        + "throwing InteractionException");
669            }
670            throw new InteractionException(INTERACTION_RB_NAME,
671                    "wsp_does_not_support_interaction", null);
672        }
673
674        //Check wsc provided UserInteraction header
675        UserInteractionElement ue 
676                = getUserInteractionElement(requestMessage);
677        if (ue == null) {
678            SOAPFaultException sfe = newRedirectFaultError(
679                    QNAME_INTERACTION_REQUIRED);
680            if (debug.warningEnabled()) {
681                debug.warning("InteractionManager.handleInteraction():"
682                        + " WSP requests for interaction - WSC did not "
683                        + " provide UserInteractionHeader");
684                debug.warning("InteractionManager.handleInteraction():"
685                        + "throwing InteractionSOAPFaultException="
686                        + sfe);
687            }
688            throw new InteractionSOAPFaultException(sfe);
689        }
690
691        //Check WSC is willing to redirect
692        if (ue.isRedirect() == false) {
693            SOAPFaultException sfe = newRedirectFaultError(
694                    QNAME_INTERACTION_REQUIRED);
695            if (debug.warningEnabled()) {
696                debug.warning("InteractionManager.handleInteraction():"
697                        + "WSP rquests for interaction - WSC  "
698                        + " says redirect=false");
699                debug.warning("InteractionManager.handleInteraction():"
700                        + "throwing InteractionSOAPFaultException="
701                        + sfe);
702            }
703            throw new InteractionSOAPFaultException(sfe);
704        }
705
706        //Check WSC allowed interaction
707        if (ue.getInteract().equals(QNAME_DO_NOT_INTERACT)) {
708            SOAPFaultException sfe = newRedirectFaultError(
709                    QNAME_INTERACTION_REQUIRED);
710            if (debug.warningEnabled()) {
711                debug.warning("InteractionManager.handleInteraction():"
712                        + "WSP rquests for interaction - WSC  "
713                        + " UserInteractionHeader says doNotInteract");
714                debug.warning("InteractionManager.handleInteraction():"
715                        + "throwing InteractionSOAPFaultException="
716                        + sfe);
717            }
718            throw new InteractionSOAPFaultException(sfe);
719        }
720
721        //Check WSC allowed interaction for data
722        if (interactionConfig.wspRedirectsForData()
723                    && ue.getInteract().equals(
724                    QNAME_DO_NOT_INTERACT_FOR_DATA)) {
725            SOAPFaultException sfe = newRedirectFaultError(
726                    QNAME_INTERACTION_REQUIRED_FOR_DATA);
727            if (debug.warningEnabled()) {
728                debug.warning("InteractionManager.handleInteraction():"
729                        + "WSP rquests interaction for data - WSC  "
730                        + " UserInteractionHeader says doNotInteractForData");
731                debug.warning("InteractionManager.handleInteraction():"
732                        + "throwing InteractionSOAPFaultException="
733                        + sfe);
734            }
735            throw new InteractionSOAPFaultException(sfe);
736        }
737
738        //Check WSP will not exceed maxInteractionTime specified by WSC
739        BigInteger uemi =  ue.getMaxInteractTime();
740        if ( (uemi != null) && (interactionConfig.getWSPRedirectTime() 
741                    > uemi.intValue()) ) {
742            SOAPFaultException sfe = newRedirectFaultError(
743                    QNAME_INTERACTION_TIME_NOT_SUFFICEINT); 
744            if (debug.warningEnabled()) {
745                debug.warning("InteractionManager.handleInteraction():"
746                        + "WSP inteaction time =" 
747                        + interactionConfig.getWSPRedirectTime() 
748                        + " exceeds WSC maxInteractTime= "
749                        + ue.getMaxInteractTime());
750                debug.warning("InteractionManager.handleInteraction():"
751                        + "throwing InteractionSOAPFaultException="
752                        + sfe);
753            }
754            throw new InteractionSOAPFaultException(sfe);
755        }
756
757        String requestMessageID 
758                = requestMessage.getCorrelationHeader().getMessageID();
759        SOAPFaultException sfe =
760                newRedirectFault(requestMessageID);
761        String redirectResponseID = getResponseID(sfe);
762        String requestIP 
763                = requestMessage.getIPAddress();
764        String requestHost = null;
765        if (interactionConfig.wspEnforcesReturnToHostEqualsRequestHost()) {
766            try {
767                InetAddress inetAddress = InetAddress.getByName(requestIP);
768                //requestHost = inetAddress.getCanonicalHostName();
769                requestHost = inetAddress.getHostName();
770                if (debug.messageEnabled()) {
771                    debug.message("InteractionManager.handleInteraction():"
772                            + " caching requestHost=" + requestHost
773                            + ", for redirectResponseID= " 
774                            + redirectResponseID);
775                }
776                setRequestHost(redirectResponseID, requestHost);
777            } catch (UnknownHostException uhe) {
778                debug.error("InteractionManager.handleInteraction():"
779                        + " can not resolve host name", uhe);
780                debug.error("InteractionManager.handleInteraction():"
781                        + " throwing InteractionSOAPFaultException", sfe);
782                SOAPFaultException sfe1 = newRedirectFaultError(
783                        QNAME_INTERACTION_CAN_NOT_DETERMINE_REQUEST_HOST); 
784                throw new InteractionSOAPFaultException(sfe1);
785            }
786        }
787
788        setInquiryElement(redirectResponseID, inquiryElement);
789        setRequestMessageID(redirectResponseID, requestMessageID);
790        setLanguage(redirectResponseID, language);
791        if (debug.messageEnabled()) {
792            debug.message("InteractionManager.handleInteraction():"
793                    + " throwing InteractionSOAPFaultException "
794                    + " to redirect user agent="
795                    + sfe);
796        }
797
798        throw new InteractionSOAPFaultException(sfe);
799        //return responseMessage;
800
801    }
802
803    private void setInquiryElement(String messageID, 
804            InquiryElement inquiryElement) {
805        CacheEntry cacheEntry = cache.getCacheEntry(messageID);
806        if ( cacheEntry == null) {
807            cacheEntry = new CacheEntry(messageID);
808            cache.putCacheEntry(messageID, cacheEntry);
809        }
810        cacheEntry.setInquiryElement(inquiryElement);
811
812    }
813
814    InquiryElement getInquiryElement(String messageID) {
815        InquiryElement inquiryElement = null;
816        CacheEntry cacheEntry = cache.getCacheEntry(messageID);
817        if ( cacheEntry != null) {
818            inquiryElement = cacheEntry.getInquiryElement();
819        }
820        return inquiryElement;
821    }
822
823    void setInteractionResponseElement(String messageID, 
824            InteractionResponseElement interactionResponse) {
825        CacheEntry cacheEntry = cache.getCacheEntry(messageID);
826        if ( cacheEntry == null) {
827            cacheEntry = new CacheEntry(messageID);
828            cache.putCacheEntry(messageID, cacheEntry);
829        }
830        cacheEntry.setInteractionResponseElement(interactionResponse);
831    }
832
833    /**
834     * Gets interaction response that was gathered from resource owner
835     * by <code>InteractionManager</code>
836     *
837     * @param requestMessage request message.
838     *
839     * @return interaction response that was gathered by
840     *         <code>InteractionManager</code>.
841     *
842     * @throws InteractionException for interaction error
843     *
844     * @supported.api
845     */
846    public InteractionResponseElement getInteractionResponseElement(
847            Message requestMessage) 
848            throws InteractionException {
849        InteractionResponseElement interactionResponseElement = null;
850        CorrelationHeader ch = requestMessage.getCorrelationHeader();
851        String messageID = ch.getRefToMessageID();
852        CacheEntry cacheEntry = null;
853        if (messageID != null) {
854            cacheEntry = cache.getCacheEntry(messageID);
855            if ( cacheEntry != null) {
856                interactionResponseElement 
857                        = cacheEntry.getInteractionResponseElement();
858            }
859            if (debug.messageEnabled()) {
860                debug.message("InteractionManager.getInteractionResponseElement():"
861                        + "for messageID=" + messageID + ":"
862                        + "responseElement="
863                        + (interactionResponseElement != null));
864            }
865        }
866        if (LogUtil.isLogEnabled()) {
867            String[] objs =new String[3];
868            objs[0] = ch.getMessageID();
869            objs[1] = ch.getRefToMessageID();
870            objs[2] = (cacheEntry == null) ? "NULL" : "NOT NULL";
871            LogUtil.access(Level.INFO,LogUtil.IS_RETURNING_RESPONSE_ELEMENT,
872                objs);
873        }
874        return interactionResponseElement;
875    }
876
877    private void setRequestMessage(String messageID, Message requestMessage) {
878        CacheEntry cacheEntry = cache.getCacheEntry(messageID);
879        if ( cacheEntry == null) {
880            cacheEntry = new CacheEntry(messageID);
881            cache.putCacheEntry(messageID, cacheEntry);
882        }
883        cacheEntry.setRequestMessage(requestMessage);
884        if (debug.messageEnabled()) {
885            debug.message("InteractionManager.setRequestMessage():"
886                    + " cached  request message for messageID="
887                    + messageID  
888                    + ":requestMessage:" + (requestMessage == null) );
889        }
890    }
891
892    private Message getRequestMessage(String messageID) {
893        Message requestMessage = null;
894        CacheEntry cacheEntry = cache.getCacheEntry(messageID);
895        if ( cacheEntry != null) {
896            requestMessage = cacheEntry.getRequestMessage();
897        }
898        if (debug.messageEnabled()) {
899            debug.message("InteractionManager.getRequestMessage():"
900                    + " looking up request message for messageID="
901                    + messageID  
902                    + ":requestMessage=" + (requestMessage == null) );
903        }
904        return requestMessage;
905    }
906
907    private void setRequestMessageID(String messageID,
908            String requestMessageID) {
909        CacheEntry cacheEntry = cache.getCacheEntry(messageID);
910        if ( cacheEntry == null) {
911            cacheEntry = new CacheEntry(messageID);
912            cache.putCacheEntry(messageID, cacheEntry);
913        }
914        cacheEntry.setRequestMessageID(requestMessageID);
915    }
916
917    String getRequestMessageID(String messageID) {
918        String requestMessageID = null;
919        CacheEntry cacheEntry = cache.getCacheEntry(messageID);
920        if ( cacheEntry != null) {
921            requestMessageID = cacheEntry.getRequestMessageID();
922        }
923        return requestMessageID;
924    }
925
926
927    void setReturnToURL(String messageID, String returnToURL) {
928        CacheEntry cacheEntry = cache.getCacheEntry(messageID);
929        if ( cacheEntry == null) {
930            cacheEntry = new CacheEntry(messageID);
931            cache.putCacheEntry(messageID, cacheEntry);
932        }
933        cacheEntry.setReturnToURL(returnToURL);
934    }
935
936    String getReturnToURL(String messageID) {
937        String returnToURL = null;
938        CacheEntry cacheEntry = cache.getCacheEntry(messageID);
939        if ( cacheEntry != null) {
940            returnToURL = cacheEntry.getReturnToURL();
941        }
942        return returnToURL;
943    }
944
945    void setRequestHost(String messageID, String requestHost) {
946        CacheEntry cacheEntry = cache.getCacheEntry(messageID);
947        if ( cacheEntry == null) {
948            cacheEntry = new CacheEntry(messageID);
949            cache.putCacheEntry(messageID, cacheEntry);
950        }
951        cacheEntry.setRequestHost(requestHost);
952    }
953
954    String getRequestHost(String messageID) {
955        String requestHost = null;
956        CacheEntry cacheEntry = cache.getCacheEntry(messageID);
957        if ( cacheEntry != null) {
958            requestHost = cacheEntry.getRequestHost();
959        }
960        return requestHost;
961    }
962
963    private void setConnectTo(String messageID, String ConnectTo) {
964        CacheEntry cacheEntry = cache.getCacheEntry(messageID);
965        if ( cacheEntry == null) {
966            cacheEntry = new CacheEntry(messageID);
967            cache.putCacheEntry(messageID, cacheEntry);
968        }
969        cacheEntry.setConnectTo(ConnectTo);
970    }
971
972   
973    private void setSoapAction(String messageID, String soapAction) {
974        CacheEntry cacheEntry = cache.getCacheEntry(messageID);
975        if ( cacheEntry == null) {
976            cacheEntry = new CacheEntry(messageID);
977            cache.putCacheEntry(messageID, cacheEntry);
978        }
979        cacheEntry.setSoapAction(soapAction);
980    }
981
982    private void setClientCert(String messageID, String certAlias) {
983        CacheEntry cacheEntry = cache.getCacheEntry(messageID);
984        if ( cacheEntry == null) {
985            cacheEntry = new CacheEntry(messageID);
986            cache.putCacheEntry(messageID, cacheEntry);
987        }
988        cacheEntry.setClientCert(certAlias);
989    }
990
991    private String getConnectTo(String messageID) {
992        String connectTo = null;
993        CacheEntry cacheEntry = cache.getCacheEntry(messageID);
994        if ( cacheEntry != null) {
995            connectTo = cacheEntry.getConnectTo();
996        }
997        return connectTo;
998    }
999
1000    private String getClientCert(String messageID) {
1001        String clientCert = null;
1002        CacheEntry cacheEntry = cache.getCacheEntry(messageID);
1003        if ( cacheEntry != null) {
1004            clientCert = cacheEntry.getClientCert();
1005        }
1006        return clientCert;
1007    }
1008
1009    private String getSoapAction(String messageID) {
1010        String soapAction = null;
1011        CacheEntry cacheEntry = cache.getCacheEntry(messageID);
1012        if ( cacheEntry != null) {
1013            soapAction = cacheEntry.getSoapAction();
1014        }
1015        return soapAction;
1016    }
1017
1018    private void setLanguage(String messageID, String language) {
1019        CacheEntry cacheEntry = cache.getCacheEntry(messageID);
1020        if ( cacheEntry == null) {
1021            cacheEntry = new CacheEntry(messageID);
1022            cache.putCacheEntry(messageID, cacheEntry);
1023        }
1024        cacheEntry.setLanguage(language);
1025    }
1026
1027    String getLanguage(String messageID) {
1028        String language = null;
1029        CacheEntry cacheEntry = cache.getCacheEntry(messageID);
1030        if ( cacheEntry != null) {
1031            language = cacheEntry.getLanguage();
1032        }
1033        return language;
1034    }
1035
1036    private UserInteractionElement createUserInteractionElement(
1037            List acceptLanguages) {
1038        UserInteractionElement ue = null; 
1039        try {
1040            ue =objectFactory.createUserInteractionElement();
1041
1042            ue.setInteract(interactionConfig
1043                    .getWSCSpecifiedInteractionChoice());
1044            ue.setRedirect(interactionConfig.wscSupportsRedirect());
1045            ue.setMaxInteractTime(
1046                    java.math.BigInteger.valueOf(interactionConfig
1047                    .getWSCSpecifiedMaxInteractionTime()));
1048            ue.getLanguage().addAll(acceptLanguages);
1049        } catch (JAXBException je) {
1050            debug.error("InteractionManager.createUserInteractionElement():"
1051                    + " can not create UserInteractionElement", je);
1052        }
1053        return ue;
1054    }
1055
1056    static UserInteractionElement getUserInteractionElement(
1057            Message message) {
1058        UserInteractionElement ue = null; 
1059        List list = message.getOtherSOAPHeaders();
1060        try {
1061            list = Utils.convertElementToJAXB(list);
1062        } catch (JAXBException je) {
1063            debug.error("InteractionManager.getUserInteractionElement():"
1064                    + "not able to get userInteractionElement:"
1065                    + "can not convert Element to JAXBObject", je);
1066            return null;
1067        }
1068        Iterator iter = list.iterator();
1069        while (iter.hasNext()) {
1070            Object obj = (Object)iter.next();
1071            if (obj instanceof UserInteractionElement) {
1072                ue = (UserInteractionElement)obj;
1073                break;
1074            }
1075        }
1076        return ue;
1077    }
1078
1079    private SOAPFaultException newRedirectFault(String messageID) {
1080        RedirectRequestElement re = null;
1081        try{
1082            re = objectFactory.createRedirectRequestElement();
1083
1084        } catch (JAXBException je) {
1085            debug.error("InteractionManager.newRedirectFault():"
1086                    + " can not create RedirectRequestElement", je);
1087        }
1088
1089        CorrelationHeader ch = new CorrelationHeader();
1090        String responseID = ch.getMessageID();
1091        ch.setRefToMessageID(messageID);
1092
1093        String redirectUrl = null;
1094        String lbRedirectUrl = interactionConfig.getLbWSPRedirectHandler();
1095        String wspRedirectUrl = interactionConfig.getWSPRedirectHandler();
1096        if(debug.messageEnabled()) {
1097            debug.message("InteractionManager.newRedirectURLFault():"
1098                    + "wspRedirectURL:" + wspRedirectUrl
1099                    + ", lbRedirectUrl:" + lbRedirectUrl);
1100        }
1101        if (lbRedirectUrl == null) {
1102            redirectUrl = wspRedirectUrl + "?" + TRANS_ID + "=" + responseID;
1103            if(debug.messageEnabled()) {
1104                debug.message("InteractionManager.newRedirectURLFault():"
1105                        + "lbRedirectURL is null, rediectUrl:"
1106                        + redirectUrl);
1107            }
1108        } else { //lbRedirectUrl defined
1109            redirectUrl = lbRedirectUrl + "?" + TRANS_ID + "=" + responseID
1110                    + "&" + InteractionConfig.HANDLER_HOST_ID 
1111                    + "=" + InteractionConfig.getInstance().getLocalServerId();
1112            if(debug.messageEnabled()) {
1113                debug.message("InteractionManager.newRedirectURLFault():"
1114                        + "lbRedirectURL is not null, rediectUrl:"
1115                        + redirectUrl);
1116            }
1117        }
1118        re.setRedirectURL(redirectUrl);
1119        List details = new ArrayList();
1120        try {
1121            details.add(Utils.convertJAXBToElement(re));
1122        } catch (JAXBException je) {
1123            debug.error("InteractionManager.newRedirectFault():"
1124                    + " can not create newRedirectFault:"
1125                    + " can not convert JAXBObject to Element", je);
1126        }
1127
1128        SOAPFault sf = new SOAPFault(
1129                QNAME_SERVER, 
1130                SERVER_ERROR,
1131                FAULT_ACTOR, new SOAPFaultDetail(details));
1132        Message sfmsg = new Message(sf);
1133        sfmsg.setCorrelationHeader(ch);
1134        SOAPFaultException sfe = new SOAPFaultException(sfmsg);
1135        return sfe;
1136    }
1137
1138    private SOAPFaultException newRedirectFaultError(QName errorCode) {
1139        StatusElement se = null;
1140        try{
1141            se = objectFactory.createStatusElement();
1142
1143        } catch (JAXBException je) {
1144            debug.error("InteractionManager.newRedirectFaultError():"
1145                    + " can not create StatusElement", je);
1146        }
1147
1148        se.setCode(errorCode);
1149        List details = new ArrayList();
1150        try {
1151            details.add(Utils.convertJAXBToElement(se));
1152        } catch (JAXBException je) {
1153            debug.error("InteractionManager.newRedirectFaultError():"
1154                    + "can not create new RedirectFaultError:" 
1155                    + "can not convert JAXBObject to Element", je);
1156        }
1157        SOAPFault sf = new SOAPFault(
1158                QNAME_SERVER, 
1159                SERVER_ERROR,
1160                FAULT_ACTOR, new SOAPFaultDetail(details));
1161        SOAPFaultException sfe = new SOAPFaultException(new Message(sf));
1162        return sfe;
1163    }
1164
1165    String getRedirectURL(SOAPFaultException sfe) throws SOAPFaultException {
1166        String redirectURL = null;
1167        List details = null;
1168        SOAPFaultDetail sfd =
1169                sfe.getSOAPFaultMessage().getSOAPFault().getDetail();
1170        if (sfd != null) {
1171            details = sfd.getOtherChildren();
1172        }
1173        try {
1174            details = Utils.convertElementToJAXB(details);
1175        } catch (JAXBException je) {
1176            debug.error("InteractionManager.getRedirectURL():"
1177                    + " can not get Redirect URL", je);
1178        }
1179
1180        if ( (details != null) && (details.size() > 0)
1181                    && (details.get(0) instanceof RedirectRequestElement)) {
1182            RedirectRequestElement rre 
1183                    = (RedirectRequestElement)details.get(0);
1184            if (rre != null) {
1185                redirectURL = rre.getRedirectURL();
1186            }
1187        }
1188        if (redirectURL == null) {
1189            throw sfe;
1190        }
1191        return redirectURL;
1192    }
1193
1194    private boolean checkRedirectHost(String redirectURL, String connectTo) {
1195        boolean answer = false;
1196        try {
1197            URL redirectToURL = new URL(redirectURL);
1198            URL connectToURL = new URL(connectTo);
1199            String redirectHost = redirectToURL.getHost();
1200            String connectToHost = connectToURL.getHost();
1201            if (redirectHost.equals(connectToHost)) {
1202                answer = true;
1203            }
1204        } catch (MalformedURLException mfe) {
1205            debug.error("InteractionManager.checkRedirectHost():"
1206                    + "redirectURL not a valid URL"
1207                    + " :redirectURL=" + redirectURL
1208                    + " :connectTo=" + connectTo, mfe);
1209        }
1210        return answer;
1211    }
1212
1213    String getResponseID(SOAPFaultException sfe) throws SOAPFaultException{
1214        String responseID = null;
1215        CorrelationHeader ch =
1216                sfe.getSOAPFaultMessage().getCorrelationHeader();
1217        if (ch == null) {
1218            debug.error("InteractionManager.getResponseID():"
1219                    + "null CorrelationHeader in SOAPFaultException");
1220            throw sfe;
1221        }
1222        responseID = ch.getMessageID();
1223        if (responseID == null) {
1224            debug.error("InteractionManager.getResponseID():"
1225                    + "null messageID in SOAPFaultException");
1226            throw sfe;
1227        }
1228        return responseID;
1229    }
1230
1231    static class InteractionCache {
1232
1233        private static final boolean VERBOSE_MESSAGE = false;
1234        private static final int SWEEP_INTERVAL = 60 * 1000;
1235        private static final int CACHE_ENTRY_MAX_IDLE_TIME = 120 * 1000;
1236
1237        PeriodicCleanUpMap cache = new PeriodicCleanUpMap(SWEEP_INTERVAL,
1238            CACHE_ENTRY_MAX_IDLE_TIME);
1239
1240        InteractionCache() {
1241            if (debug.messageEnabled()) {
1242                debug.message("InteactionCache.InteractionCache() "
1243                        + " - entering constructor");
1244            }
1245            if (debug.messageEnabled()) {
1246                debug.message("InteactionCache.InteractionCache() "
1247                        + " - starting sweeper thread");
1248                debug.message("InteractionCache.InteractionCache() "
1249                        + " SWEEP_INTERVAL = " + SWEEP_INTERVAL);
1250                debug.message("InteractionCache.InteractionCache() "
1251                        + " CACHE_ENTRY_MAX_IDLE_TIME = " 
1252                        + CACHE_ENTRY_MAX_IDLE_TIME);
1253            }
1254            SystemTimerPool.getTimerPool().schedule((TaskRunnable) cache,
1255                new Date(((System.currentTimeMillis() + SWEEP_INTERVAL) / 1000)
1256                * 1000));
1257            if (debug.messageEnabled()) {
1258                debug.message("InteactionCache.InteractionCache() "
1259                        + " - returning from constructor");
1260            }
1261        }
1262
1263        CacheEntry getCacheEntry(String messageID) {
1264            if (VERBOSE_MESSAGE && debug.messageEnabled()) {
1265                debug.message("InteractionCache.getCacheEntry():"
1266                        + "looking up cacheEntry  for messageID=" + messageID);
1267                debug.message("InteractionCache.getCacheEntry():"
1268                        + " cached messageIDs=" + cache.keySet());
1269            }
1270            CacheEntry entry = (CacheEntry)cache.get(messageID);
1271            if (entry != null) {
1272                cache.removeElement(messageID);
1273                cache.addElement(messageID);
1274            }
1275            return entry;
1276        }
1277
1278        void putCacheEntry(String messageID, CacheEntry cacheEntry) {
1279            cache.put(messageID, cacheEntry);
1280            if (VERBOSE_MESSAGE && debug.messageEnabled()) {
1281                debug.message("InteractionCache.putCacheEntry():"
1282                        + " cached cacheEntry for messageID=" + messageID);
1283            }
1284        }
1285
1286    }
1287
1288    static class CacheEntry {
1289        String messageID; //key
1290        String requestMessageID;
1291        Message requestMessage;
1292        InquiryElement inquiryElement;
1293        InteractionResponseElement interactionResponseElement;
1294        String connectTo;
1295        String certAlias;
1296        String soapAction;
1297        String returnToURL;
1298        String requestHost;
1299        String language;
1300
1301        CacheEntry(String messageID) {
1302            this.messageID= messageID;
1303        }
1304
1305        CacheEntry(String messageID, Message message) {
1306            this.messageID= messageID;
1307            this.requestMessage= message;
1308        }
1309
1310        void setRequestMessage(Message requestMessage) {
1311            this.requestMessage = requestMessage;
1312        }
1313
1314        Message getRequestMessage() {
1315            return requestMessage;
1316        }
1317
1318        void setRequestMessageID(String requestMessageID) {
1319            this.requestMessageID = requestMessageID;
1320        }
1321
1322        String getRequestMessageID() {
1323            return requestMessageID;
1324        }
1325
1326        void setInquiryElement(InquiryElement inquiryElement) {
1327            this.inquiryElement = inquiryElement;
1328        }
1329
1330        InquiryElement getInquiryElement() {
1331            return inquiryElement;
1332        }
1333
1334        void setInteractionResponseElement(
1335                InteractionResponseElement interactionResponseElement) {
1336            this.interactionResponseElement = interactionResponseElement;
1337        }
1338
1339        InteractionResponseElement getInteractionResponseElement() {
1340            return interactionResponseElement;
1341        }
1342
1343        void setConnectTo(String connectTo) {
1344            this.connectTo = connectTo;
1345        }
1346
1347        String getConnectTo() {
1348            return connectTo;
1349        }
1350
1351        void setClientCert(String certAlias) {
1352            this.certAlias = certAlias;
1353        }
1354
1355        String getClientCert() {
1356            return certAlias;
1357        }
1358
1359        void setSoapAction(String soapAction) {
1360            this.soapAction = soapAction;
1361        }
1362
1363        String getSoapAction() {
1364            return soapAction;
1365        }
1366
1367        void setReturnToURL(String returnToURL) {
1368            this.returnToURL = returnToURL;
1369        }
1370
1371        String getReturnToURL() {
1372            return returnToURL;
1373        }
1374
1375        void setRequestHost(String requestHost) {
1376            this.requestHost = requestHost;
1377        }
1378
1379        String getRequestHost() {
1380            return requestHost;
1381        }
1382
1383        void setLanguage(String language) {
1384            this.language = language;
1385        }
1386
1387        String getLanguage() {
1388            return language;
1389        }
1390
1391    }
1392
1393}
1394




























































Copyright © 2010-2017, ForgeRock All Rights Reserved.