Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Create a separate Guice module for OpenPaaS communication #1261

Merged
merged 21 commits into from
Nov 5, 2024

Conversation

HoussemNasri
Copy link
Member

@HoussemNasri HoussemNasri commented Oct 24, 2024

Closes #1223

TODO

@@ -312,7 +313,8 @@ protected void configure() {
new TeamMailboxModule(),
new TMailMailboxSortOrderProviderModule(),
new TmailEventModule(),
new TmailEventDeadLettersModule());
new TmailEventDeadLettersModule(),
new OpenPaasModule());
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

22:23:34.258 [ERROR] c.l.t.OpenPaasModule - Could not find configuration file 'openpaas.properties'
22:23:34.271 [ERROR] o.a.j.GuiceJamesServer - Fatal error while starting James
java.io.FileNotFoundException: openpaas

Likely we should make the OpenPaaS module optional?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fully agree.

If unspecified we shall fallback to the main rabbitMQ connection and rely on / vhost.

Comment on lines +48 to +50
LOGGER.error("Could not find configuration file '{}.properties'",
OPENPAAS_CONFIGURATION_NAME);
throw new RuntimeException(e);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We shall likely do a module chooser to start or not the openpaas extension?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you confirm if this is accurate: The extension loads only if openpaas.properties is present in the classpath. If any OpenPaas configurations (e.g., apiURL or admin details) are missing, it will fail. If the RabbitMQ URI is not configured, it falls back to rabbitmq.properties (question: for the fallback, should we use all configurations in rabbitmq.properties or just the URI?)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If any OpenPaas configurations (e.g., apiURL or admin details) are missing, it will fail.

Wrong.

For Distributed if AMQP settings are missing we are falling back to the mail RabbitMQChannelPool

For Memory we are failing

(This likely means we need a little DistributedOpenPaaSAMQPFallbackModule and MemoryOpenPaaSAMQPFallbackModule to encode this difference)

For the fallback we use the RabbitMQChannelPool object already instanciated, let's not read rabbitmq.properties ourselves.

@Provides
@Named(OPENPAAS_INJECTION_KEY)
@Singleton
public RabbitMQConfiguration provideRabbitMQConfiguration(OpenPaasConfiguration openPaasConfiguration, RabbitMQConfiguration fallbackRabbitMQConfiguration) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here we would connect twice to RabbitMQ.

Is there a way to connect only once when we fallback?

Also on top of memory-app there would be no fallback as we do not use RabbitMQ at all...

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here we would connect twice to RabbitMQ.

Can you please elaborate on this part?

- Inject openpass-specific RabbitMQ configuration to OpenPaasContactsConsumer
@HoussemNasri HoussemNasri self-assigned this Oct 28, 2024
@Provides
@Named(OPENPAAS_INJECTION_KEY)
@Singleton
public RabbitMQConfiguration provideRabbitMQConfiguration(
Copy link
Member

@chibenwa chibenwa Oct 28, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it possible to write something like:

    public RabbitMQChannelPool provideRabbitMQOpenPaaSFallback(OpenPaasConfiguration openPaasConfiguration, RabbitMQChannelPool channelPool, @Named("openpaas") Provider<RabbitMQCHannelPool> openPaaSChannelPool) {
    return openPaasConfiguration.maybeRabbitMqUri()
        .map(any -> openPaaSChannelPool.get())
        .orElse(channelPool);

Copy link
Member Author

@HoussemNasri HoussemNasri Oct 29, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think we can. The provider takes another provider annotated with @nAmed("openpaas"), if we annotate this provider with the same annotation, which is the attended use case we will get a BINDING_ALREADY_SET error. We could skip the annotation but that will still conflict with the default RabbitMQChannelPool provider declared elsewhere.

The only solution I see is to define a new injection key, i.e., @nAmed("openpaas_with_fallback"), provided by DistributedOpenPaasAmqpFallbackModule.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think we can.

Create more intermediary abstractions to break the dependency loops. Or use other named annotations.

Please find something. Be inventive and try things.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It was decided not to implement the fallback in this PR, keeping it open so I can return to it when working on the fallback.

import com.linagora.tmail.encrypted.MailboxManagerClassProbe;
import com.linagora.tmail.module.LinagoraTestJMAPServerModule;

public class MemoryServerWithoutOpenPaasTest {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think all the other tests check what happens without the openpaas module enabled.

As it stands this test is useless.

We shall rather check the exception we get when we try to start tmail with the openpaas extension without configuring RabbitMQ...

@chibenwa
Copy link
Member

To test that RabbitMQ and OpenPaaS rabbitMQ are different we could leverage a "Probe"

We can create a TestProbe with injections on RabbitMQChannelPool and @Named("openpaas") RabbitMQChannelPool that exposes a boolean method to show if those are the sames or not.

Comment on lines 48 to 52

@BeforeAll
static void setUp() {
System.setSecurityManager(new NoExitSecurityManager());
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@afterall remember to unset the security manager or test isolation is broken.

Comment on lines 55 to 62
void serverShouldThrowWithOpenPaasEnabled() throws Exception {
try {
jamesServerExtension.start(null);
fail("James server didn't exit or fail!");
} catch (Exception e) {
LOGGER.error("Expected failure", e);
}
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

disable auto start on the extention, get a non-started guice-james-server as a parameter and start it manually in the tests

.build())
.server(configuration -> DistributedServer.createServer(configuration)
.overrideWith(new LinagoraTestJMAPServerModule())
.overrideWith(binder -> Multibinder.newSetBinder(binder, GuiceProbe.class).addBinding().to(UsersRepositoryClassProbe.class)))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this module override needed?

Copy link
Member Author

@HoussemNasri HoussemNasri Nov 4, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Probably not, we don't use jmap in this test. The test passes even after removing the module. It is hard to tell for sure which modules or extensions are needed and which are not.

I removed it.

@chibenwa chibenwa merged commit bba278e into linagora:master Nov 5, 2024
5 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Create a separate Guice module for OpenPaaS communication
4 participants