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

Fix #617 Registerable and discoverable Camel services #618

Merged
merged 4 commits into from
Jan 20, 2020

Conversation

ppalaga
Copy link
Contributor

@ppalaga ppalaga commented Jan 14, 2020

No description provided.

Copy link
Contributor

@lburgazzoli lburgazzoli left a comment

Choose a reason for hiding this comment

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

It would be nice to have some build time properties to control factory files to be included/excluded like:

quarkus.camel.factories.discovery.include = **/*
quarkus.camel.factories.discovery.exclude = org/apache/camel/something/*,org/apache/camel/xyz/**/*

so if a user know that some services/features are not needed, we can filter them out and avoid creating classes/instances.

archives,
"META-INF/services/org/apache/camel/component",
"META-INF/services/org/apache/camel/language",
"META-INF/services/org/apache/camel/dataformat")
Copy link
Contributor

Choose a reason for hiding this comment

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

we need to fine tune language and data-format as we can store into the registry only singleton services (this requires also some changes to the FastCamelContext as it assumes languages and dataformats are stored in the registry)

Copy link
Contributor

Choose a reason for hiding this comment

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

Yes we do have this problem as today but this is a good change to fix it

Copy link
Contributor Author

Choose a reason for hiding this comment

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

we need to fine tune language and data-format

Not sure how should we tune?

as we can store into the registry only singleton services

You seem to imply language and data-format are not singleton services, but could you plz. define "singleton services"?

Copy link
Contributor

Choose a reason for hiding this comment

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

The "tuning" here is about to carefully select which language/dataformat can be bound to the registry.

As example camel creates components only once so every time you use a schema, then you'll end up using the same component instance.

For languages and dataformat that's not always true and this is because you can use the same dataformat multiple time in the same route with a different configuration.

archives,
"META-INF/services/org/apache/camel/configurer")
.filter(entry -> entry.getValue().getProperty("class") != null)
.map(entry -> CamelServiceBuildItem.registeredOnly(
Copy link
Contributor

Choose a reason for hiding this comment

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

As future evolution, may be better not to expose such instances to the user through the registry, maybe better to try to bind them to the components at build time

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I wonder how can we cover the case you mentioned on the chat - manually bind a second instance of a component under a different name?

Copy link
Contributor

Choose a reason for hiding this comment

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

I mean that we should not even bind them to the registry but scan the registry for components and bind related configurers through a recorder during STATIC_INIT

Copy link
Contributor Author

Choose a reason for hiding this comment

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

the registry for components and bind related configurers through a recorder during STATIC_INIT

Yes, that would be easy to do. But when a user adds a second instance of a component under a different name at runtime, our configurer setting code would not catch it.

Copy link
Contributor

Choose a reason for hiding this comment

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

yep but as the second instance is probably configured at runtime, the component will fallback to the "factory finder" way which is reasonable

@ppalaga
Copy link
Contributor Author

ppalaga commented Jan 16, 2020

It would be nice to have some build time properties to control factory files to be included/excluded like:

quarkus.camel.factories.discovery.include = **/*
quarkus.camel.factories.discovery.exclude = org/apache/camel/something/*,org/apache/camel/xyz/**/*

I wonder how the set of services defined by the extensions should be composed with these user facing selectors?

A. (extension-includes + user-includes) - user-excludes

or

B. extension-includes + (user-includes - user-excludes)

A. seems to make more sense. WDYT?

@lburgazzoli
Copy link
Contributor

A. (extension-includes + user-includes) - user-excludes

Yes something like that should work

@ppalaga ppalaga changed the title Fix #Build time FactoryFinders Fix #617 Registerable and discoverable Camel services Jan 17, 2020
@ppalaga
Copy link
Contributor Author

ppalaga commented Jan 17, 2020

d82e823 implements the requested build time config.

The includes/excludes need to be defined incl. the META-INF/services/... prefix. I hope that's not an issue.

I vote for creating a new issue for the fine-tuning of the languages and data-formats.

I'd also create a new issue for replacing the current usage of CamelServiceFilterBuildItem with the new CamelServicePatternBuildItem because those ServiceFilters are just excludes.

@ppalaga ppalaga marked this pull request as ready for review January 17, 2020 15:25
@ppalaga
Copy link
Contributor Author

ppalaga commented Jan 17, 2020

4720897 rebased


public PathFilter build() {
final List<String> incl = includePatterns;
includePatterns = null; // avoid leaking the collection trough reuse of the builder
Copy link
Contributor

Choose a reason for hiding this comment

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

not a huge issue in our case but my understanding is that invoking build() multiple time on the same builder should produce the same result

Copy link
Contributor Author

@ppalaga ppalaga Jan 17, 2020

Choose a reason for hiding this comment

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

invoking build() multiple time on the same builder should produce the same result

If the collection is not set to null here the following sequence would be possible:

PathFilter.Builder b = new PathFilter.Builder();
b.include("foo/bar");
PathFilter pf1 = b.build();
b.include("bar/baz");
PathFilter pf2 = b.build();

where pf1 and pf2 would have set the same list instance in their includePatterns fields. That would be really unwanted. That's a true reference leak that harms the immutability of PathFilter.

I hold re-using builders for rather unusual and so I find breaking the re-use better than copying the list in the PathFilter constructor as a way to ensure immutability.

Copy link
Contributor

Choose a reason for hiding this comment

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

At least document it as I think no-one expect the builder to be re-set once you invoke build()

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Copy link
Member

Choose a reason for hiding this comment

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

Well another, in my opinion, cleaner option is to copy the collection in each object built making it immutable. A variation of this is used in most of the framework that generates builders, like Lombok and similars one.

My 2c.

@lburgazzoli
Copy link
Contributor

lburgazzoli commented Jan 17, 2020

I vote for creating a new issue for the fine-tuning of the languages and data-formats.

if you have time, it would be nice to at least remove them from the registry and use the default camel discovery for languages and dataformats, we can fine tune them later one but at least we are on the safe side

@ppalaga
Copy link
Contributor Author

ppalaga commented Jan 17, 2020

remove them from the registry and use the default camel discovery for languages and dataformats

Done in 73f59ef

@lburgazzoli
Copy link
Contributor

ok to test

@lburgazzoli
Copy link
Contributor

conflicts

@ppalaga
Copy link
Contributor Author

ppalaga commented Jan 18, 2020

7e11340 rebased

@ppalaga
Copy link
Contributor Author

ppalaga commented Jan 20, 2020

ok to test

1 similar comment
@oscerd
Copy link
Contributor

oscerd commented Jan 20, 2020

ok to test

@lburgazzoli
Copy link
Contributor

The build seems to be running

https://builds.apache.org/view/C/view/Apache%20Camel/job/camel-quarkus-pr/538/

even if it does not show up here

@ppalaga
Copy link
Contributor Author

ppalaga commented Jan 20, 2020

This should be fixed by the Do not register languages and dataformats ... commit of #618

@ppalaga
Copy link
Contributor Author

ppalaga commented Jan 20, 2020

869af41 rebased and fixed a subtle bug that prevented the Dozer tests from passing

@ppalaga
Copy link
Contributor Author

ppalaga commented Jan 20, 2020

ok to test

1 similar comment
@lburgazzoli
Copy link
Contributor

ok to test

@lburgazzoli lburgazzoli merged commit a2e1dc2 into apache:master Jan 20, 2020
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.

None yet

4 participants