/**
   * Test for issue #49: Sessions not associated with a memcached node don't get associated as soon
   * as a memcached is available
   *
   * @throws InterruptedException
   * @throws IOException
   * @throws TimeoutException
   * @throws ExecutionException
   */
  @Test(enabled = true)
  public void testNotAssociatedSessionGetsAssociatedIssue49()
      throws InterruptedException, IOException, ExecutionException, TimeoutException {
    _daemon.stop();

    final SessionManager manager = _tomcat1.getManager();
    manager.setMaxInactiveInterval(5);
    manager.setSticky(true);
    final SessionIdFormat sessionIdFormat = new SessionIdFormat();

    final Session session = manager.createSession(null);
    assertNull(sessionIdFormat.extractMemcachedId(session.getId()));

    _daemon.start();

    // Wait so that the daemon will be available and the client can reconnect (async get didn't do
    // the trick)
    Thread.sleep(4000);

    final String newSessionId =
        manager.getMemcachedSessionService().changeSessionIdOnMemcachedFailover(session.getId());
    assertNotNull(newSessionId);
    assertEquals(newSessionId, session.getId());
    assertEquals(sessionIdFormat.extractMemcachedId(newSessionId), _memcachedNodeId);
  }
  @Override
  public void remove(Session session, boolean update) {
    Jedis jedis = null;
    Boolean error = true;

    log.trace("Removing session ID : " + session.getId());

    try {
      jedis = acquireConnection();
      jedis.del(session.getId());
      error = false;
    } finally {
      if (jedis != null) {
        returnConnection(jedis, error);
      }
    }
  }
  /**
   * Reinstantiates a serialized session from the data passed in. This will first call
   * createSession() so that we get a fresh instance with all the managers set and all the transient
   * fields validated. Then it calls Session.readObjectData(byte[]) to deserialize the object
   *
   * @param data - a byte array containing session data
   * @return a valid Session object, null if an error occurs
   */
  protected Session readSession(byte[] data, String sessionId) {
    try {
      ReplicationStream session_in = getReplicationStream(data);

      Session session = sessionId != null ? this.findSession(sessionId) : null;
      boolean isNew = (session == null);
      // clear the old values from the existing session
      if (session != null) {
        ReplicatedSession rs = (ReplicatedSession) session;
        rs.expire(false); // cleans up the previous values, since we are not doing removes
        session = null;
      } // end if

      if (session == null) {
        session = createSession(null, false, false);
        sessions.remove(session.getIdInternal());
      }

      boolean hasPrincipal = session_in.readBoolean();
      SerializablePrincipal p = null;
      if (hasPrincipal) p = (SerializablePrincipal) session_in.readObject();
      ((ReplicatedSession) session).readObjectData(session_in);
      if (hasPrincipal) session.setPrincipal(p.getPrincipal(getContainer().getRealm()));
      ((ReplicatedSession) session).setId(sessionId, isNew);
      ReplicatedSession rsession = (ReplicatedSession) session;
      rsession.setAccessCount(1);
      session.setManager(this);
      session.setValid(true);
      rsession.setLastAccessedTime(System.currentTimeMillis());
      rsession.setThisAccessedTime(System.currentTimeMillis());
      ((ReplicatedSession) session).setAccessCount(0);
      session.setNew(false);
      if (log.isTraceEnabled())
        log.trace(
            "Session loaded id="
                + sessionId
                + " actualId="
                + session.getId()
                + " exists="
                + this.sessions.containsKey(sessionId)
                + " valid="
                + rsession.isValid());
      return session;

    } catch (Exception x) {
      log.error("Failed to deserialize the session!", x);
    }
    return null;
  }
 @Override
 public ApiResponse signOutAll() {
   ApiResponse response = ApiResponse.createDefaultApiResponse();
   HttpServletRequest request = HttpUtil.getRequest();
   HttpSession httpSession = HttpUtil.getSession();
   if (request instanceof RequestFacade) {
     Field requestField = null;
     try {
       requestField = request.getClass().getDeclaredField("request");
     } catch (NoSuchFieldException e) {
       e.printStackTrace();
     }
     if (requestField != null) {
       requestField.setAccessible(true);
       Request req = null;
       try {
         req = (Request) requestField.get(request);
       } catch (IllegalAccessException e) {
         e.printStackTrace();
       }
       if (req != null) {
         Context context = req.getContext();
         Manager manager = context.getManager();
         Session[] sessions = manager.findSessions();
         if (sessions != null) {
           for (Session session : sessions) {
             if (!httpSession.getId().equals(session.getId())) {
               session.expire();
             }
           }
         }
       }
     }
   }
   return response;
 }
  public static ApplicationSession getApplicationSession(
      Session session, boolean calcSize, boolean addAttributes) {

    ApplicationSession sbean = null;
    if (session != null && session.isValid()) {
      sbean = new ApplicationSession();

      sbean.setId(session.getId());
      sbean.setCreationTime(new Date(session.getCreationTime()));
      sbean.setLastAccessTime(new Date(session.getLastAccessedTime()));
      sbean.setMaxIdleTime(session.getMaxInactiveInterval() * 1000);
      sbean.setManagerType(session.getManager().getClass().getName());
      // sbean.setInfo(session.getInfo());
      // TODO:fixmee

      boolean sessionSerializable = true;
      int attributeCount = 0;
      long size = 0;

      HttpSession httpSession = session.getSession();
      Set processedObjects = new HashSet(1000);

      // Exclude references back to the session itself
      processedObjects.add(httpSession);
      try {
        for (Enumeration e = httpSession.getAttributeNames(); e.hasMoreElements(); ) {
          String name = (String) e.nextElement();
          Object obj = httpSession.getAttribute(name);
          sessionSerializable = sessionSerializable && obj instanceof Serializable;

          long objSize = 0;
          if (calcSize) {
            try {
              objSize += Instruments.sizeOf(name, processedObjects);
              objSize += Instruments.sizeOf(obj, processedObjects);
            } catch (Throwable th) {
              logger.error("Cannot estimate size of attribute \"" + name + "\"", th);
              //
              // make sure we always re-throw ThreadDeath
              //
              if (e instanceof ThreadDeath) {
                throw (ThreadDeath) e;
              }
            }
          }

          if (addAttributes) {
            Attribute saBean = new Attribute();
            saBean.setName(name);
            saBean.setType(ClassUtils.getQualifiedName(obj.getClass()));
            saBean.setValue(obj);
            saBean.setSize(objSize);
            saBean.setSerializable(obj instanceof Serializable);
            sbean.addAttribute(saBean);
          }
          attributeCount++;
          size += objSize;
        }
        String lastAccessedIp =
            (String) httpSession.getAttribute(ApplicationSession.LAST_ACCESSED_BY_IP);
        if (lastAccessedIp != null) {
          sbean.setLastAccessedIp(lastAccessedIp);
        }
        try {
          sbean.setLastAccessedIpLocale(
              InetAddressLocator.getLocale(InetAddress.getByName(lastAccessedIp).getAddress()));
        } catch (Throwable e) {
          logger.error("Cannot determine Locale of " + lastAccessedIp);
          //
          // make sure we always re-throw ThreadDeath
          //
          if (e instanceof ThreadDeath) {
            throw (ThreadDeath) e;
          }
        }

      } catch (IllegalStateException e) {
        logger.info("Session appears to be invalidated, ignore");
      }

      sbean.setObjectCount(attributeCount);
      sbean.setSize(size);
      sbean.setSerializable(sessionSerializable);
    }

    return sbean;
  }
  /**
   * Save a session to the Store.
   *
   * @param session the session to be stored
   * @exception IOException if an input/output error occurs
   */
  public void save(Session session) throws IOException {
    String saveSql =
        "INSERT INTO "
            + sessionTable
            + " ("
            + sessionIdCol
            + ", "
            + sessionAppCol
            + ", "
            + sessionDataCol
            + ", "
            + sessionValidCol
            + ", "
            + sessionMaxInactiveCol
            + ", "
            + sessionLastAccessedCol
            + ") VALUES (?, ?, ?, ?, ?, ?)";
    ObjectOutputStream oos = null;
    ByteArrayOutputStream bos = null;
    ByteArrayInputStream bis = null;
    InputStream in = null;

    synchronized (this) {
      Connection _conn = getConnection();
      if (_conn == null) {
        return;
      }

      // If sessions already exist in DB, remove and insert again.
      // TODO:
      // * Check if ID exists in database and if so use UPDATE.
      remove(session.getId());

      try {
        bos = new ByteArrayOutputStream();
        oos = new ObjectOutputStream(new BufferedOutputStream(bos));

        ((StandardSession) session).writeObjectData(oos);
        oos.close();

        byte[] obs = bos.toByteArray();
        int size = obs.length;
        bis = new ByteArrayInputStream(obs, 0, size);
        in = new BufferedInputStream(bis, size);

        if (preparedSaveSql == null) {
          preparedSaveSql = _conn.prepareStatement(saveSql);
        }

        preparedSaveSql.setString(1, session.getId());
        preparedSaveSql.setString(2, getName());
        preparedSaveSql.setBinaryStream(3, in, size);
        preparedSaveSql.setString(4, session.isValid() ? "1" : "0");
        preparedSaveSql.setInt(5, session.getMaxInactiveInterval());
        preparedSaveSql.setLong(6, session.getLastAccessedTime());
        preparedSaveSql.execute();
      } catch (SQLException e) {
        log(sm.getString(getStoreName() + ".SQLException", e));
      } catch (IOException e) {;
      } finally {
        if (bis != null) {
          bis.close();
        }
        if (in != null) {
          in.close();
        }

        release(_conn);
      }
    }

    if (debug > 0) {
      log(sm.getString(getStoreName() + ".saving", session.getId(), sessionTable));
    }
  }
 public void save(Session session) {
   sessions.put(session.getId(), session);
 }
 public String getSessionId() {
   return tomcatSession.getId();
 }