use of org.neo4j.logging.Log in project neo4j by neo4j.
the class NetworkSenderReceiverTest method senderThatStartsAfterReceiverShouldEventuallyConnectSuccessfully.
@Test
public void senderThatStartsAfterReceiverShouldEventuallyConnectSuccessfully() throws Throwable {
/*
* This test verifies that a closed channel from a sender to a receiver is removed from the connections
* mapping in the sender. It starts a sender, connects it to a receiver and sends a message.
*
* We should be testing this without resorting to using a NetworkReceiver. But, as prophets Mick Jagger and
* Keith Richards mention in their scriptures, you can't always get what you want. In this case,
* NetworkSender creates on its own the things required to communicate with the outside world, and this
* means it creates actual sockets. To interact with it then, we need to setup listeners for those sockets
* and respond properly. Hence, NetworkReceiver. Yes, this means that this test requires to open actual
* network sockets.
*
* Read on for further hacks in place.
*/
NetworkSender sender = null;
NetworkReceiver receiver = null;
try {
LogProvider logProviderMock = mock(LogProvider.class);
Log logMock = mock(Log.class);
when(logProviderMock.getLog(Matchers.<Class>any())).thenReturn(logMock);
final Semaphore sem = new Semaphore(0);
/*
* A semaphore AND a boolean? Weird, you may think, as the purpose is clearly to step through the
* connection setup/teardown process. So, let's discuss what happens here more clearly.
*
* The sender and receiver are started. Trapped by the semaphore release on listeningAt()
* The sender sends through the first message, it is received by the receiver. Trapped by the semaphore
* release on listeningAt() which is triggered on the first message receive on the receiver
* The receiver is stopped, trapped by the overridden stop() method of the logging service.
* The sender sends a message through, which will trigger the ChannelClosedException. This is where it
* gets tricky. See, normally, since we waited for the semaphore on NetworkReceiver.stop() and an
* happensBefore edge exists and all these good things, it should be certain that the Receiver is
* actually stopped and the message would fail to be sent. That would be too easy though. In reality,
* netty will not wait for all listening threads to stop before returning, so the receiver is not
* guaranteed to not be listening for incoming connections when stop() returns. This happens rarely,
* but the result is that the message "HelloWorld2" should fail with an exception (triggering the warn
* method on the logger) but it doesn't. So we can't block, but we must retry until we know the
* message failed to be sent and the exception happened, which is what this test is all about. We do
* that with a boolean that is tested upon continuously with sent messages until the error happens.
* Then we proceed with...
* The receiver is started. Trapped by the listeningAt() callback.
* The sender sends a message.
* The receiver receives it, trapped by the dummy processor added to the receiver.
*/
final AtomicBoolean senderChannelClosed = new AtomicBoolean(false);
doAnswer(new Answer<Object>() {
@Override
public Object answer(InvocationOnMock invocation) throws Throwable {
senderChannelClosed.set(true);
return null;
}
}).when(logMock).warn(anyString());
receiver = new NetworkReceiver(mock(NetworkReceiver.Monitor.class), new NetworkReceiver.Configuration() {
@Override
public HostnamePort clusterServer() {
return new HostnamePort("127.0.0.1:1235");
}
@Override
public int defaultPort() {
return 5001;
}
@Override
public String name() {
return null;
}
}, NullLogProvider.getInstance()) {
@Override
public void stop() throws Throwable {
super.stop();
sem.release();
}
};
sender = new NetworkSender(mock(NetworkSender.Monitor.class), new NetworkSender.Configuration() {
@Override
public int port() {
return 1235;
}
@Override
public int defaultPort() {
return 5001;
}
}, receiver, logProviderMock);
sender.init();
sender.start();
receiver.addNetworkChannelsListener(new NetworkReceiver.NetworkChannelsListener() {
@Override
public void listeningAt(URI me) {
sem.release();
}
@Override
public void channelOpened(URI to) {
}
@Override
public void channelClosed(URI to) {
}
});
final AtomicBoolean received = new AtomicBoolean(false);
receiver.addMessageProcessor(new MessageProcessor() {
@Override
public boolean process(Message<? extends MessageType> message) {
received.set(true);
sem.release();
return true;
}
});
receiver.init();
receiver.start();
// wait for start from listeningAt() in the NetworkChannelsListener
sem.acquire();
sender.process(Message.to(TestMessage.helloWorld, URI.create("cluster://127.0.0.1:1235"), "Hello World"));
// wait for process from the MessageProcessor
sem.acquire();
receiver.stop();
// wait for overridden stop method in receiver
sem.acquire();
/*
* This is the infernal loop of doom. We keep sending messages until one fails with a ClosedChannelException
* which we have no better way to grab other than through the logger.warn() call which will occur.
*
* This code will hang if the warn we rely on is removed or if the receiver never stops - in general, if
* the closed channel exception is not thrown. This is not an ideal failure mode but it's the best we can
* do, given that NetworkSender is provided with very few things from its environment.
*/
while (!senderChannelClosed.get()) {
sender.process(Message.to(TestMessage.helloWorld, URI.create("cluster://127.0.0.1:1235"), "Hello World2"));
/*
* This sleep is not necessary, it's just nice. If it's ommitted, everything will work, but we'll
* spam messages over the network as fast as possible. Even when the race between send and
* receiver.stop() does not occur, we will still send 3-4 messages through at full speed. If it
* does occur, then we are looking at hundreds. So we just back off a bit and let things work out.
*/
Thread.sleep(5);
}
receiver.start();
// wait for receiver.listeningAt()
sem.acquire();
received.set(false);
sender.process(Message.to(TestMessage.helloWorld, URI.create("cluster://127.0.0.1:1235"), "Hello World3"));
// wait for receiver.process();
sem.acquire();
assertTrue(received.get());
} finally {
if (sender != null) {
sender.stop();
sender.shutdown();
}
if (receiver != null) {
receiver.stop();
receiver.shutdown();
}
}
}
use of org.neo4j.logging.Log in project neo4j by neo4j.
the class StateTransitionLogger method stateTransition.
@Override
public void stateTransition(StateTransition transition) {
Log log = logProvider.getLog(transition.getOldState().getClass());
if (log.isDebugEnabled()) {
if (transition.getOldState() == HeartbeatState.heartbeat) {
return;
}
// The bulk of the message
String state = transition.getOldState().getClass().getSuperclass().getSimpleName();
StringBuilder line = new StringBuilder(state).append(": ").append(transition);
// Who was this message from?
if (transition.getMessage().hasHeader(FROM)) {
line.append(" from:").append(transition.getMessage().getHeader(FROM));
}
if (transition.getMessage().hasHeader(INSTANCE)) {
line.append(" instance:").append(transition.getMessage().getHeader(INSTANCE));
}
if (transition.getMessage().hasHeader(CONVERSATION_ID)) {
line.append(" conversation-id:").append(transition.getMessage().getHeader(CONVERSATION_ID));
}
Object payload = transition.getMessage().getPayload();
if (payload != null) {
if (payload instanceof Payload) {
try {
payload = atomicBroadcastSerializer.receive((Payload) payload);
} catch (Throwable e) {
// Ignore
}
}
line.append(" payload:").append(Strings.prettyPrint(payload));
}
// Throttle
String msg = line.toString();
if (msg.equals(lastLogMessage)) {
return;
}
// Log it
log.debug(line.toString());
lastLogMessage = msg;
}
}
use of org.neo4j.logging.Log in project neo4j by neo4j.
the class DefaultWinnerStrategyTest method shouldNotPickAWinnerIfAllVotesAreForIneligibleCandidates.
@Test
public void shouldNotPickAWinnerIfAllVotesAreForIneligibleCandidates() {
// given
InstanceId instanceOne = new InstanceId(1);
InstanceId instanceTwo = new InstanceId(2);
ClusterContext clusterContext = mock(ClusterContext.class);
final Log log = mock(Log.class);
LogProvider logProvider = new LogProvider() {
@Override
public Log getLog(Class loggingClass) {
return log;
}
@Override
public Log getLog(String name) {
return log;
}
};
when(clusterContext.getLog(DefaultWinnerStrategy.class)).thenReturn(logProvider.getLog(DefaultWinnerStrategy.class));
// when
Collection<Vote> votes = Arrays.asList(new Vote(instanceOne, new NotElectableElectionCredentials()), new Vote(instanceTwo, new NotElectableElectionCredentials()));
DefaultWinnerStrategy strategy = new DefaultWinnerStrategy(clusterContext);
org.neo4j.cluster.InstanceId winner = strategy.pickWinner(votes);
// then
assertNull(winner);
}
use of org.neo4j.logging.Log in project neo4j by neo4j.
the class PersonalUserManagerTest method setup.
@Before
public void setup() {
evilUserManager = new EvilUserManager(new InternalFlatFileRealm(new InMemoryUserRepository(), new InMemoryRoleRepository(), new BasicPasswordPolicy(), new RateLimitedAuthenticationStrategy(Clock.systemUTC(), 3), new InternalFlatFileRealmIT.TestJobScheduler(), new InMemoryUserRepository(), new InMemoryUserRepository()));
log = spy(Log.class);
userManager = new PersonalUserManager(evilUserManager, SecurityContext.AUTH_DISABLED, new SecurityLog(log));
}
use of org.neo4j.logging.Log in project neo4j by neo4j.
the class MultiRealmAuthManagerTest method createAuthManager.
private MultiRealmAuthManager createAuthManager(boolean logSuccessfulAuthentications) throws Throwable {
Log log = logProvider.getLog(this.getClass());
InternalFlatFileRealm internalFlatFileRealm = new InternalFlatFileRealm(users, new InMemoryRoleRepository(), mock(PasswordPolicy.class), authStrategy, mock(JobScheduler.class), CommunitySecurityModule.getInitialUserRepository(config, NullLogProvider.getInstance(), fsRule.get()), EnterpriseSecurityModule.getDefaultAdminRepository(config, NullLogProvider.getInstance(), fsRule.get()));
manager = new MultiRealmAuthManager(internalFlatFileRealm, Collections.singleton(internalFlatFileRealm), new MemoryConstrainedCacheManager(), new SecurityLog(log), logSuccessfulAuthentications);
manager.init();
return manager;
}
Aggregations