/** * Creates a new sessionId based on the given one, usually by appending a randomly selected memcached node id. * If the memcachedNodes were configured using a single node without nodeId, the sessionId is returned unchanged. */ @Nonnull public String createSessionId( @Nonnull final String sessionId ) { return isEncodeNodeIdInSessionId() ? _sessionIdFormat.createSessionId(sessionId, _nodeIdService.getMemcachedNodeId() ) : sessionId; }
/** * Can be used to determine if the given sessionId can be used to interact with memcached. * @see #canHitMemcached(String) */ public boolean isValidForMemcached(final String sessionId) { if ( isEncodeNodeIdInSessionId() ) { final String nodeId = _sessionIdFormat.extractMemcachedId( sessionId ); if ( nodeId == null ) { LOG.debug( "The sessionId does not contain a nodeId so that the memcached node could not be identified." ); return false; } } return true; }
/** * Returns a new session id if node information shall be encoded in the session id * and the encoded nodeId given one is <code>null</code> or not available. * @param sessionId the session id that is checked. * @return a new session id or <code>null</code>. */ public String getNewSessionIdIfNodeFromSessionIdUnavailable( @Nonnull final String sessionId ) { if ( isEncodeNodeIdInSessionId() ) { final String nodeId = _sessionIdFormat.extractMemcachedId( sessionId ); final String newNodeId = _nodeIdService.getNewNodeIdIfUnavailable( nodeId ); if ( newNodeId != null ) { return _sessionIdFormat.createNewSessionId( sessionId, newNodeId); } } return null; }
@Test( dataProvider = "nodesAndExpectedEncodedInSessionIdDataProvider" ) public void testIsEncodeNodeIdInSessionId( final String memcachedNodes, final String failoverNodes, final boolean expectedIsEncodeNodeIdInSessionId ) { final MemcachedNodesManager result = createFor( memcachedNodes, null, null, _mcc ); assertNotNull(result); assertEquals(result.isEncodeNodeIdInSessionId(), expectedIsEncodeNodeIdInSessionId); }
/** * Changes the sessionId by setting the given jvmRoute and replacing the memcachedNodeId if it's currently * set to a failoverNodeId. * @param sessionId the current session id * @param jvmRoute the new jvmRoute to set. * @return the session id with maybe new jvmRoute and/or new memcachedId. */ public String changeSessionIdForTomcatFailover( @Nonnull final String sessionId, final String jvmRoute ) { final String newSessionId = jvmRoute != null && !jvmRoute.trim().isEmpty() ? _sessionIdFormat.changeJvmRoute( sessionId, jvmRoute ) : _sessionIdFormat.stripJvmRoute(sessionId); if ( isEncodeNodeIdInSessionId() ) { final String nodeId = _sessionIdFormat.extractMemcachedId( newSessionId ); if(_failoverNodeIds != null && _failoverNodeIds.contains(nodeId)) { final String newNodeId = _nodeIdService.getAvailableNodeId( nodeId ); if ( newNodeId != null ) { return _sessionIdFormat.createNewSessionId( newSessionId, newNodeId); } } } return newSessionId; }
/** * Mark the memcached node encoded in the given sessionId as available or not. If nodeIds shall * not be encoded in the sessionId or if the given sessionId does not contain a nodeId no * action will be taken. * * @param sessionId the sessionId that may contain a node id. * @param available specifies if the possibly referenced node is available or not. * * @return the extracted nodeId or <code>null</code>. * * @see #isEncodeNodeIdInSessionId() */ public String setNodeAvailableForSessionId(final String sessionId, final boolean available) { if ( _nodeIdService != null && isEncodeNodeIdInSessionId() ) { final String nodeId = _sessionIdFormat.extractMemcachedId(sessionId); if ( nodeId != null ) { _nodeIdService.setNodeAvailable(nodeId, available); return nodeId; } else { LOG.warn("Got sessionId without nodeId: " + sessionId); } } return null; }
/** * Can be used to determine if the given sessionId can be used to interact with memcached. * This also checks if the related memcached is available. * @see #isValidForMemcached(String) */ public boolean canHitMemcached(final String sessionId) { if ( isEncodeNodeIdInSessionId() ) { final String nodeId = _sessionIdFormat.extractMemcachedId( sessionId ); if ( nodeId == null ) { LOG.debug( "The sessionId does not contain a nodeId so that the memcached node could not be identified." ); return false; } if ( !_nodeIdService.isNodeAvailable( nodeId ) ) { LOG.debug( "The node "+ nodeId +" is not available, therefore " + sessionId + " cannot be loaded from this memcached." ); return false; } } return true; }
if (connectionType.isSASL()) { final AuthDescriptor authDescriptor = new AuthDescriptor(new String[]{"PLAIN"}, new PlainCallbackHandler(username, password)); return memcachedNodesManager.isEncodeNodeIdInSessionId() ? new SuffixLocatorBinaryConnectionFactory( memcachedNodesManager, memcachedNodesManager.getSessionIdFormat(), statistics, operationTimeout, maxReconnectDelay, return memcachedNodesManager.isEncodeNodeIdInSessionId() ? new SuffixLocatorBinaryConnectionFactory( memcachedNodesManager, memcachedNodesManager.getSessionIdFormat(), statistics, operationTimeout, maxReconnectDelay ) : new BinaryConnectionFactory() { return memcachedNodesManager.isEncodeNodeIdInSessionId() ? new SuffixLocatorConnectionFactory( memcachedNodesManager, memcachedNodesManager.getSessionIdFormat(), statistics, operationTimeout, maxReconnectDelay ) : new DefaultConnectionFactory() {
private MemcachedClient createMemcachedClient( final String memcachedNodes, final InetSocketAddress address ) throws IOException, InterruptedException { final MemcachedNodesManager nodesManager = MemcachedNodesManager.createFor(memcachedNodes, null, null, _storageClientCallback); final ConnectionFactory cf = nodesManager.isEncodeNodeIdInSessionId() ? new SuffixLocatorConnectionFactory( nodesManager, nodesManager.getSessionIdFormat(), Statistics.create(), 1000, 1000 ) : new DefaultConnectionFactory(); final MemcachedClient result = new MemcachedClient( cf, Arrays.asList( address ) ); // Wait a little bit, so that the memcached client can connect and is ready when test starts Thread.sleep( 100 ); return result; }
/** * Test for issue #105: Make memcached node optional for single-node setup * http://code.google.com/p/memcached-session-manager/issues/detail?id=105 */ @Test public void testConfigurationFormatMemcachedNodesFeature105() throws LifecycleException { _service.setMemcachedNodes( "127.0.0.1:11211" ); _service.startInternal(new MemcachedStorageClient(_memcachedMock)); assertEquals(_service.getMemcachedNodesManager().getCountNodes(), 1); assertEquals(_service.getMemcachedNodesManager().isEncodeNodeIdInSessionId(), false); assertEquals(_service.getMemcachedNodesManager().isValidForMemcached("123456"), true); _service.shutdown(); _service.setMemcachedNodes( "n1:127.0.0.1:11211" ); _service.startInternal(new MemcachedStorageClient(_memcachedMock)); assertEquals(_service.getMemcachedNodesManager().getCountNodes(), 1); assertEquals(_service.getMemcachedNodesManager().isEncodeNodeIdInSessionId(), true); assertEquals(_service.getMemcachedNodesManager().isValidForMemcached("123456"), false); assertEquals(_service.getMemcachedNodesManager().isValidForMemcached("123456-n1"), true); }
@BeforeMethod public void setUp(final Method testMethod) throws Throwable { final InetSocketAddress address = new InetSocketAddress( "localhost", MEMCACHED_PORT ); _daemon = createDaemon( address ); _daemon.start(); final String[] testGroups = testMethod.getAnnotation(Test.class).groups(); final String nodePrefix = testGroups.length == 0 || !GROUP_WITHOUT_NODE_ID.equals(testGroups[0]) ? NODE_ID + ":" : ""; _memcachedNodes = nodePrefix + "localhost:" + MEMCACHED_PORT; try { _tomcat1 = startTomcat( TC_PORT_1, JVM_ROUTE_1 ); _tomcat2 = startTomcat( TC_PORT_2, JVM_ROUTE_2 ); } catch ( final Throwable e ) { LOG.error( "could not start tomcat.", e ); throw e; } final MemcachedNodesManager nodesManager = MemcachedNodesManager.createFor(_memcachedNodes, null, null, _storageClientCallback); final ConnectionFactory cf = nodesManager.isEncodeNodeIdInSessionId() ? new SuffixLocatorConnectionFactory( nodesManager, nodesManager.getSessionIdFormat(), Statistics.create(), 1000, 1000 ) : new DefaultConnectionFactory(); _client = new MemcachedClient( cf, Arrays.asList( address ) ); _httpClient = new DefaultHttpClient(); }
/** * Creates a new sessionId based on the given one, usually by appending a randomly selected memcached node id. * If the memcachedNodes were configured using a single node without nodeId, the sessionId is returned unchanged. */ @Nonnull public String createSessionId( @Nonnull final String sessionId ) { return isEncodeNodeIdInSessionId() ? _sessionIdFormat.createSessionId(sessionId, _nodeIdService.getMemcachedNodeId() ) : sessionId; }
if ( !_memcachedNodesManager.isEncodeNodeIdInSessionId() ) { return null;
/** * Can be used to determine if the given sessionId can be used to interact with memcached. * @see #canHitMemcached(String) */ public boolean isValidForMemcached(final String sessionId) { if ( isEncodeNodeIdInSessionId() ) { final String nodeId = _sessionIdFormat.extractMemcachedId( sessionId ); if ( nodeId == null ) { LOG.debug( "The sessionId does not contain a nodeId so that the memcached node could not be identified." ); return false; } } return true; }
/** * Returns a new session id if node information shall be encoded in the session id * and the encoded nodeId given one is <code>null</code> or not available. * @param sessionId the session id that is checked. * @return a new session id or <code>null</code>. */ public String getNewSessionIdIfNodeFromSessionIdUnavailable( @Nonnull final String sessionId ) { if ( isEncodeNodeIdInSessionId() ) { final String nodeId = _sessionIdFormat.extractMemcachedId( sessionId ); final String newNodeId = _nodeIdService.getNewNodeIdIfUnavailable( nodeId ); if ( newNodeId != null ) { return _sessionIdFormat.createNewSessionId( sessionId, newNodeId); } } return null; }
/** * Changes the sessionId by setting the given jvmRoute and replacing the memcachedNodeId if it's currently * set to a failoverNodeId. * @param sessionId the current session id * @param jvmRoute the new jvmRoute to set. * @return the session id with maybe new jvmRoute and/or new memcachedId. */ public String changeSessionIdForTomcatFailover( @Nonnull final String sessionId, final String jvmRoute ) { final String newSessionId = jvmRoute != null && !jvmRoute.trim().isEmpty() ? _sessionIdFormat.changeJvmRoute( sessionId, jvmRoute ) : _sessionIdFormat.stripJvmRoute(sessionId); if ( isEncodeNodeIdInSessionId() ) { final String nodeId = _sessionIdFormat.extractMemcachedId( newSessionId ); if(_failoverNodeIds != null && _failoverNodeIds.contains(nodeId)) { final String newNodeId = _nodeIdService.getAvailableNodeId( nodeId ); if ( newNodeId != null ) { return _sessionIdFormat.createNewSessionId( newSessionId, newNodeId); } } } return newSessionId; }
/** * Mark the memcached node encoded in the given sessionId as available or not. If nodeIds shall * not be encoded in the sessionId or if the given sessionId does not contain a nodeId no * action will be taken. * * @param sessionId the sessionId that may contain a node id. * @param available specifies if the possibly referenced node is available or not. * * @return the extracted nodeId or <code>null</code>. * * @see #isEncodeNodeIdInSessionId() */ public String setNodeAvailableForSessionId(final String sessionId, final boolean available) { if ( _nodeIdService != null && isEncodeNodeIdInSessionId() ) { final String nodeId = _sessionIdFormat.extractMemcachedId(sessionId); if ( nodeId != null ) { _nodeIdService.setNodeAvailable(nodeId, available); return nodeId; } else { LOG.warn("Got sessionId without nodeId: " + sessionId); } } return null; }
/** * Can be used to determine if the given sessionId can be used to interact with memcached. * This also checks if the related memcached is available. * @see #isValidForMemcached(String) */ public boolean canHitMemcached(final String sessionId) { if ( isEncodeNodeIdInSessionId() ) { final String nodeId = _sessionIdFormat.extractMemcachedId( sessionId ); if ( nodeId == null ) { LOG.debug( "The sessionId does not contain a nodeId so that the memcached node could not be identified." ); return false; } if ( !_nodeIdService.isNodeAvailable( nodeId ) ) { LOG.debug( "The node "+ nodeId +" is not available, therefore " + sessionId + " cannot be loaded from this memcached." ); return false; } } return true; }
if (connectionType.isSASL()) { final AuthDescriptor authDescriptor = new AuthDescriptor(new String[]{"PLAIN"}, new PlainCallbackHandler(username, password)); return memcachedNodesManager.isEncodeNodeIdInSessionId() ? new SuffixLocatorBinaryConnectionFactory( memcachedNodesManager, memcachedNodesManager.getSessionIdFormat(), statistics, operationTimeout, maxReconnectDelay, return memcachedNodesManager.isEncodeNodeIdInSessionId() ? new SuffixLocatorBinaryConnectionFactory( memcachedNodesManager, memcachedNodesManager.getSessionIdFormat(), statistics, operationTimeout, maxReconnectDelay ) : new BinaryConnectionFactory() { return memcachedNodesManager.isEncodeNodeIdInSessionId() ? new SuffixLocatorConnectionFactory( memcachedNodesManager, memcachedNodesManager.getSessionIdFormat(), statistics, operationTimeout, maxReconnectDelay ) : new DefaultConnectionFactory() {
if ( !_memcachedNodesManager.isEncodeNodeIdInSessionId() ) { return null;