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

#418 config profile support #554

Merged
merged 8 commits into from
Jun 11, 2020

Conversation

Emily-Jiang
Copy link
Member

@Emily-Jiang Emily-Jiang commented Apr 16, 2020

A proposal to support standard way to provide profile-specific properties that would be used only if a profile is specified. This for example enables an application to include configuration for different environments and development stages while only one of them is active (e.g. dev, test, prod).

----
@Inject @ConfigProperty(name="vehicle.name") String vechileName;
----

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 some normative text covering what conforming implementations are required to do.

Copy link
Contributor

Choose a reason for hiding this comment

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

Detailed description of resolution rules and interplay between ordinals and other config sources are needed here and these rules also tested within the TCK.

Copy link
Member Author

@Emily-Jiang Emily-Jiang Apr 24, 2020

Choose a reason for hiding this comment

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

+1 @smillidge , I will add more TCKs for the config source ordinal rules once we are happy with the rules. See here for more explaination.

@Emily-Jiang
Copy link
Member Author

I am working on TCKs. Please continue to comment on the behaviour.

Copy link
Contributor

@dmlloyd dmlloyd left a comment

Choose a reason for hiding this comment

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

Discussion needs to be concluded.

spec/src/main/asciidoc/configprofile.asciidoc Outdated Show resolved Hide resolved
spec/src/main/asciidoc/configprofile.asciidoc Outdated Show resolved Hide resolved
spec/src/main/asciidoc/configprofile.asciidoc Outdated Show resolved Hide resolved
spec/src/main/asciidoc/configprofile.asciidoc Outdated Show resolved Hide resolved
spec/src/main/asciidoc/configprofile.asciidoc Outdated Show resolved Hide resolved
Config Profile indicates the project phase, such as dev, testing, live, etc.
=== Specify Config Profile

The config profile can be specified via a system property `mp.config.profile`. It can be set when starting your microservice, e.g.
Copy link
Contributor

Choose a reason for hiding this comment

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

We should also allow builders to set the profile for the Config they are building. Using a system property is nice on a global level but it doesn't make sense if an application uses a custom config or even more custom configs.

A new method like this in ConfigBuilder would allow it:

ConfigBuilder withProfile(String profileName)

Copy link
Contributor

Choose a reason for hiding this comment

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

It ought to be possible to set the config profile via a configuration property IMO.

Copy link
Member Author

@Emily-Jiang Emily-Jiang Apr 24, 2020

Choose a reason for hiding this comment

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

Since when reading config sources, we need to figure out the config profile value, using system properties is much simplier. What will happen if set different value for mp.config.profile in different config sources, which makes the situation very complicated.

Copy link
Contributor

Choose a reason for hiding this comment

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

We could also allow setting the profile using env var. But setting it via a config property introduces recursion, adds too many places where it can be set which can make the configuration very confusing.

Implementations can still support additional unspecified ways to set the profile.

Copy link
Contributor

Choose a reason for hiding this comment

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

Highest config source wins, as usual. We do support self-configuration in other areas, so I don't think this is so unusual.

Comment on lines 119 to 125
* Set the config profile.
* Once the config profile is set, the config property {@code %profile.config.name} overrides the property {@code config.name}
* in the same config source.
* The config value for the property {@code config.name} is retrieved from a config source with the highest ordinal.
* The value is set by the property {@code %profile.config.name} if exists. Otherwise, the value is taken from the property {@code config.name}.
* @param profile the config profile
* @return
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
* Set the config profile.
* Once the config profile is set, the config property {@code %profile.config.name} overrides the property {@code config.name}
* in the same config source.
* The config value for the property {@code config.name} is retrieved from a config source with the highest ordinal.
* The value is set by the property {@code %profile.config.name} if exists. Otherwise, the value is taken from the property {@code config.name}.
* @param profile the config profile
* @return
* Set the configuration profile.
* Once the configuration profile is set, the configuration property {@code %profile.config.name} overrides the property {@code config.name}
* in the same configuration source.
* The configuration value for the property {@code config.name} is retrieved from a configuration source with the highest ordinal.
* The value is set by the property {@code %profile.config.name} if exists. Otherwise, the value is taken from the property {@code config.name}.
* @param profile the configuration profile name (must not be {@code null})
* @return this builder

Also the resolution of #553 would affect the wording here.

Copy link
Member Author

Choose a reason for hiding this comment

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

updated.

Copy link
Member Author

Choose a reason for hiding this comment

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

When I tried to add tests for this spi, I suggest against the idea adding this method, because it will create more confusions. Setting mp.config.profile is better set via the config sources to avoid unnecessary conflicts of setting profile via a method or via a property.

spec/src/main/asciidoc/configprofile.asciidoc Outdated Show resolved Hide resolved
Config Profile indicates the project phase, such as dev, testing, live, etc.
=== Specify Config Profile

The config profile can be specified via a system property `mp.config.profile`. It can be set when starting your microservice, e.g.
Copy link
Contributor

Choose a reason for hiding this comment

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

We could also allow setting the profile using env var. But setting it via a config property introduces recursion, adds too many places where it can be set which can make the configuration very confusing.

Implementations can still support additional unspecified ways to set the profile.

spec/src/main/asciidoc/configprofile.asciidoc Outdated Show resolved Hide resolved
spec/src/main/asciidoc/configprofile.asciidoc Outdated Show resolved Hide resolved
spec/src/main/asciidoc/configprofile.asciidoc Outdated Show resolved Hide resolved
spec/src/main/asciidoc/configprofile.asciidoc Outdated Show resolved Hide resolved
Signed-off-by: Emily Jiang <[email protected]>
@Emily-Jiang Emily-Jiang force-pushed the config-profile-issue branch from 1ce434f to e1d5ef2 Compare May 7, 2020 17:24
java -jar myapp.jar -Dmp.config.profile=testing
----

The property `mp.config.profile` is only read once on microservice starting. Any changes after that is ignored. Furthermore, the value specifies a single profile. Only one profile can be active at a time.
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
The property `mp.config.profile` is only read once on microservice starting. Any changes after that is ignored. Furthermore, the value specifies a single profile. Only one profile can be active at a time.
The property `mp.config.profile` shouldn't change after the JVM is started. It's only read once during JVM start up. If the property is modified afterwards the behavior is undefined and any changes to its value made later can be ignored by the implementation. Furthermore, the value specifies a single profile. Only one profile can be active at a time.

We shouldn't refer to "microservices" which is a vague term and not all MP implementations are used to build microservices. Rather I'd refer to a running JVM instead of a microservice.

Copy link
Member Author

Choose a reason for hiding this comment

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

updated.

Copy link
Member Author

Choose a reason for hiding this comment

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

I had a further thought on this. I am going to change to application starting instead of JVM startup as it is more accurate to say application starting due to some application server might have multiple applications installed on the same server.

Copy link
Contributor

Choose a reason for hiding this comment

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

How about on Config creation?

Copy link
Member Author

Choose a reason for hiding this comment

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

How about on Config creation?

This will be from implementation point of view though, which is different from user perspective. Some implementations might create the config a lot earlier.

Copy link
Contributor

Choose a reason for hiding this comment

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

We can all agree that the profile is read one time. But it doesn't make sense to specify exactly when it must be read; all we can really say for sure is that the implementation will (of a necessity) read the profile property before the application reads or injects configuration properties. Since that's all the spec can reasonably require, that's exactly what should be specified. Obviously this doesn't happen during JVM startup; it might not happen during application startup either.

@Emily-Jiang
Copy link
Member Author

@OndroMih we talked about setting mp.config.profile in last week's hangout. The TCKs can be fixed using multiple test suites. However, the more we talked about, it makes more sense to make the property mp.config.profile to be specified at normal config sources. It is a static property. We define this from a use case pespective. As for implementations, it is not complicated as you can build config as normal. However when you look up a particular config property, you can use interceptor to resolve the value, which was demonstrated by @radcortez .

@OndroMih
Copy link
Contributor

OndroMih commented Jun 1, 2020

We talked about supporting mp.config.profile property in any config source with @Emily-Jiang at the hangout on 21st May (after last @Emily-Jiang's comment on this PR) and we came to an agreement documented in the hangout minutes:

#418 - Config Profile - Ondro mentioned that Payara won’t be able to cope with the mp.config.profile specified on ordinary configsources. Emily suggests to go back to env or system property to start with and then add more support.

The reasoning is that we don't need it to implement tests and we don't yet have a usecase that would justify standardizing this.

I suggest that we initially approve that mp.config.profile is only specified by as an ENV var or a system property. We also won't support specifying the profile in the config builder as there's also no usecase for it. If somebody finds a good usecase for specifying the property using any config source or in the builder, we should discuss it separately and add it with another PR any time later.

@radcortez
Copy link
Contributor

radcortez commented Jun 1, 2020

I suggest that we initially approve that mp.config.profile is only specified by as an ENV var or a system property.

I'm sorry, but I strongly disagree with this. This is not about requiring the property for testing or anything else, is about us being consistent with the spec we are proposing.

We have a spec that is all about Configuration and we try to convince our users to use it and have their own ConfigSources and manage their configuration. When we need to set our own configuration we are not even able to follow our own spec.

How can we possibly justif to an end user that we are not able to support this?

@smillidge
Copy link
Contributor

Well then you are going to have to properly specify what occurs in a runtime that supports multiple deployments. What happens if the system properties config source has one value for profile. Application A has another and Application B another. Which profile value takes precedence? I assume that it is the ConfigSource with the higher Ordinal value i.e. System Properties?

@radcortez
Copy link
Contributor

radcortez commented Jun 1, 2020

We follow the exact same rules as we have specified for loading configurations.

Forget about profile for a second. In that scenario, if I have foo.bar specified, which one gets loaded?

assertThat(ConfigProvider.getConfig().getValue("vehicle.name", String.class), is(equalTo("bus")));
}


Copy link
Contributor

Choose a reason for hiding this comment

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

Remove additional blank line.

Copy link
Member Author

Choose a reason for hiding this comment

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

done

Comment on lines 100 to 101


Copy link
Contributor

Choose a reason for hiding this comment

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

Remove additional blank lines.

*/
public class TestConfigProfileTest extends Arquillian {


Copy link
Contributor

Choose a reason for hiding this comment

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

Remove additional blank line.

Copy link
Member Author

Choose a reason for hiding this comment

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

done


}


Copy link
Contributor

Choose a reason for hiding this comment

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

Remove additional blank line.

Copy link
Member Author

Choose a reason for hiding this comment

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

done

Comment on lines 98 to 99


Copy link
Contributor

Choose a reason for hiding this comment

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

Remove additional blank lines.

*/
public class TestCustomConfigProfile extends Arquillian {


Copy link
Contributor

Choose a reason for hiding this comment

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

Remove additional blank line.

Copy link
Member Author

Choose a reason for hiding this comment

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

done


}


Copy link
Contributor

Choose a reason for hiding this comment

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

Remove additional blank line.

Comment on lines 102 to 103


Copy link
Contributor

Choose a reason for hiding this comment

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

Remove additional blank lines.

Copy link
Member Author

Choose a reason for hiding this comment

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

done

Comment on lines 69 to 70


Copy link
Contributor

Choose a reason for hiding this comment

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

Remove additional blank lines.

Copy link
Member Author

Choose a reason for hiding this comment

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

done


}


Copy link
Contributor

Choose a reason for hiding this comment

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

Remove additional blank line.

Copy link
Member Author

Choose a reason for hiding this comment

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

done

assertThat(ConfigProvider.getConfig().getValue("vehicle.name", String.class), is(equalTo("bike")));
}


Copy link
Contributor

Choose a reason for hiding this comment

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

Remove additional blank line.

Comment on lines 98 to 99


Copy link
Contributor

Choose a reason for hiding this comment

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

Remove additional blank lines.

Copy link
Member Author

Choose a reason for hiding this comment

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

done

*/
public class InvalidConfigProfileTest extends Arquillian {


Copy link
Contributor

Choose a reason for hiding this comment

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

Remove additional blank line.

Copy link
Member Author

Choose a reason for hiding this comment

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

done


}


Copy link
Contributor

Choose a reason for hiding this comment

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

Remove additional blank line.

Comment on lines 88 to 89


Copy link
Contributor

Choose a reason for hiding this comment

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

Remove additional blank lines.

Copy link
Member Author

Choose a reason for hiding this comment

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

done

Comment on lines 100 to 101


Copy link
Contributor

Choose a reason for hiding this comment

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

Remove additional blank lines.

Copy link
Member Author

Choose a reason for hiding this comment

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

done

Copy link
Contributor

@radcortez radcortez left a comment

Choose a reason for hiding this comment

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

Just a few minor issues, with a couple of typos and extra lines around files.

Everything else seems fine to me.

Signed-off-by: Emily Jiang <[email protected]>
@Emily-Jiang
Copy link
Member Author

@radcortez thanks for your feedback! I've addressed all of your comments, I think. Please double check and approve or fill more comments!

@radcortez
Copy link
Contributor

Thanks! +1

@Emily-Jiang
Copy link
Member Author

@dmlloyd @OndroMih @struberg in the past you requested some changes. I believed I have either addressed your comments or responded to your comments with reasons if your suggestion did not result into a update. I plan to merge this PR this Thursday EOD UK time as @radcortez has approved this PR. Please either approve the PR or fill your objection from an end user point of view with a detailed use case before EOD Thursday. I take silence as no objection. Thanks!

@Emily-Jiang Emily-Jiang changed the title #418 draft for config profile support #418 config profile support Jun 11, 2020
@Emily-Jiang Emily-Jiang merged commit c4d0e3c into microprofile:master Jun 11, 2020
@OndroMih
Copy link
Contributor

Hi @Emily-Jiang, I'd be grateful if you allowed for more than 2 days to react. I don't work 100% on MicroProfile and there are also otehr PRs open that it's very easy to miss a 2 day deadline. I only noticed your deadline after you'd merged this PR actually.

@struberg gave a very reasonable feedback a few days ago, which I'd like to discuss further. When I review the discussion, most of the time it's just @struberg's or my opinion against @radcortez or @dmlloyd, both from the Quarkus team. So I don't understand why proposals from the Quarkus team always win without further discussion.

Regarding support for setting the profile in any config source, I'm now OK with that since most of the people seem to support it or at least aren't against. Since that was the most important unresolved issue for me I'm OK with merging this PR. But I'm not OK with how it was finally merged with just an approval by a single person and with the lack of time to react before merging it.

@Emily-Jiang
Copy link
Member Author

Emily-Jiang commented Jun 11, 2020

@OndroMih this PR has been open for about 2 months. I have noted on the gitter and ask for feedback. Both @jbee and @radcortez were happy with the changes at today's hangout. By the way, you can always raise further issues if you are unhappy with any issues. I talked with @struberg regarding the postfix and prefix and eventually he was ok with the changes and he also supports the profile property specified in any config sources. I also want to say it is not done deal and you can always raise further issues. However, we need to move forward.

@radcortez
Copy link
Contributor

Hi, @OndroMih I understand your frustration, but please don't feel that your opinion is being disregarded. If that happened, I'm sure everyone else is willing to review the changes and make any adjustments.

Also, I would like to tell you that I have a tremendous amount of respect for you and I value your opinions (and everyone else for that matter in this group). I hope I can convince you that this is not a Quarkus team vs everyone else. To make it clear, I'm in the SmallRye team, which provides the Config implementation not only to Quarkus, but also to Wildlfy, JBoss EAP, Thorntail, and now Websphere, so Quarkus is not my only concern.

For instance, I advocate that the config property for the profile to follow the same rules as everything else. Quarkus doesn't support that and works in the same way you were proposing. On the other hand, I felt that this is was not consistent with our spec, so I've pushed back. In the end, Quarkus is probably going to have a similar issue with yours on how to implement it.

In the ConfigValue discussion, I've proposed a solution, you reviewed and made your proposal. I've updated the PR and it now reflects more of your proposal than mine. And that is fine because it made sense and we were able to collaborate on that.

I hope that you realize that I'm here to help and not to follow an agenda. Of course, we are not always going to agree and that is ok. As long as we can move forward its all good.

@OndroMih
Copy link
Contributor

Thanks for clarification, @radcortez and @Emily-Jiang. I respect both of you deeply but I was afraid that we're moving too fast with this because yhis is a huge change and the PR is huge by itself. I'm very busy these days and I can hardly find time to review one PR a week so having 3 or more PRs open at once is challanging to follow. I'd appreciate your understanding and give longer notice before merging. Since so many people eventually agreed with the final version of this PR, I'm OK with metging it although I don't fully agree with it. Especially my concerns about configuring the config by config itself may cause headaches to implementers and may also be confusing to users without much added value. Before we release the next version of Config I'd like to have a POC impl by both Quarkus and some app server, e. g. Payara, OpenLiberty or WildFly

@OndroMih
Copy link
Contributor

And BTW, I like the final version of the ConfigValue PR. Thanks, @radcortez. I believe we can still build on that and add additional capability to ConfigValue for more usecases.

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.

8 participants