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

Di server #846

Merged
merged 43 commits into from
Jan 21, 2022
Merged

Di server #846

merged 43 commits into from
Jan 21, 2022

Conversation

sbayer55
Copy link
Member

@sbayer55 sbayer55 commented Jan 7, 2022

Description

Refactor Data Prepper Server to use dependency injection

Issues Resolved

  • Remove circular dependency between Data Prepper and Data Prepper Server

Check List

  • New functionality includes testing.
  • New functionality has been documented.
    • New functionality has javadoc added
  • Commits are signed with a real name per the DCO

By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license.
For more information on following Developer Certificate of Origin and signing off your commits, please check here.

@sbayer55 sbayer55 requested a review from a team as a code owner January 7, 2022 17:10
@codecov-commenter
Copy link

codecov-commenter commented Jan 7, 2022

Codecov Report

Merging #846 (90d9e80) into main (40d52f6) will decrease coverage by 0.80%.
The diff coverage is 85.71%.

Impacted file tree graph

@@             Coverage Diff              @@
##               main     #846      +/-   ##
============================================
- Coverage     92.21%   91.40%   -0.81%     
- Complexity      660      672      +12     
============================================
  Files            80       82       +2     
  Lines          1940     1955      +15     
  Branches        164      165       +1     
============================================
- Hits           1789     1787       -2     
- Misses          110      129      +19     
+ Partials         41       39       -2     
Impacted Files Coverage Δ
...n/dataprepper/parser/model/MetricRegistryType.java 100.00% <ø> (+33.33%) ⬆️
...mazon/dataprepper/plugin/DefaultPluginFactory.java 97.50% <ø> (-0.07%) ⬇️
...peline/server/CloudWatchMeterRegistryProvider.java 72.22% <33.33%> (-8.74%) ⬇️
...mazon/dataprepper/parser/config/MetricsConfig.java 79.48% <73.33%> (-20.52%) ⬇️
...ataprepper/pipeline/server/HttpServerProvider.java 82.60% <82.60%> (ø)
...per/parser/config/DataPrepperAppConfiguration.java 100.00% <100.00%> (ø)
...zon/dataprepper/parser/config/DataPrepperArgs.java 90.32% <100.00%> (ø)
...dataprepper/pipeline/server/DataPrepperServer.java 100.00% <100.00%> (+10.16%) ⬆️
...aprepper/pipeline/server/ListPipelinesHandler.java 100.00% <100.00%> (ø)
...pper/pipeline/server/PrometheusMetricsHandler.java 100.00% <100.00%> (ø)
... and 7 more

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 40d52f6...90d9e80. Read the comment docs.

@Bean
public Optional<MeterRegistry> prometheusMeterRegistry(
final DataPrepperConfiguration dataPrepperConfiguration,
final Optional<Authenticator> optionalAuthenticator,
Copy link
Member

Choose a reason for hiding this comment

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

Taking an Optional as an argument is not a good practice. You have no non-null guarantees here, so you should do a null check, which somewhat defeats the purpose.

I noticed this in a few places. Please change these to just take the argument in without the Optional wrapper.

Copy link
Member Author

Choose a reason for hiding this comment

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

Depending on your Data Prepper configuration and Pipeline an Authenticator Bean may not be created / available. By default, if a requested bean is not available Spring will abort startup throwing an exception. We have three options in how to handle a case like this:

  1. Always create an Authenticator, then use it based on configuration.
  2. Wrapping the dependency as an Optional - JSR-330 compliant and would require the lease amount of refactoring if we switch to another DI framework like Dagger
  3. Use the Spring native functionality @Autowired(required = false)

Another good example to consider is when creating the CloudWatchMeterRegistry. If the CloudWatchMeterRegistry is not configured, creating an instance of it cloud cause an exception to be thrown,

https://github.com/sbayer55/data-prepper/blob/di-server/data-prepper-core/src/main/java/com/amazon/dataprepper/parser/config/MetricsConfig.java#L120

Copy link
Contributor

Choose a reason for hiding this comment

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

@sbayer55, why not go with option 1? That sounds like it decouples DP with a dependency framework and won't require passing optionals around.

Copy link
Member Author

Choose a reason for hiding this comment

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

Option 1 presents issues with classes like CloudWatchMeterRegistry that would need additional refactoring. Option 3 is a happy middle ground. We remove the need for optionals while limiting the scope of this PR.

@@ -55,4 +57,9 @@ public DataPrepperConfiguration dataPrepperConfiguration(
return new DataPrepperConfiguration();
}
}

@Bean
public Optional<PluginModel> pluginModel(final DataPrepperConfiguration dataPrepperConfiguration) {
Copy link
Member

Choose a reason for hiding this comment

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

This value is the authentication. So this method should be renamed to authentication from pluginModel.

@Bean
public CompositeMeterRegistry systemMeterRegistry(
final List<MeterBinder> meterBinders,
final DataPrepperConfiguration dataPrepperConfiguration
final List<Optional<MeterRegistry>> optionalMeterRegistries
Copy link
Member

Choose a reason for hiding this comment

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

This List<Optional<MeterRegister>> should be just List<MeterRegistery>.

@@ -23,7 +23,7 @@
class PluginCreator {
private static final Logger LOG = LoggerFactory.getLogger(PluginCreator.class);

<T> T newPluginInstance(final Class<T> pluginClass,
public <T> T newPluginInstance(final Class<T> pluginClass,
Copy link
Member

Choose a reason for hiding this comment

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

This shouldn't be public. The class itself is already package protected, and keeping the method package protected is clearer.


final PrometheusMetricsHandler metricsHandler = new PrometheusMetricsHandler(meterRegistry);

final List<HttpContext> contextList = new ArrayList<>(2);
Copy link
Member

Choose a reason for hiding this comment

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

This bean creation has two distinct concerns involved: 1) Creating the MeterRegistry and 2) setting up the HttpServer to support it. It would be better to have a different construct handle the second concern. Perhaps there can be different beans for "server contexts" and then the HttpServer bean can assemble them all.

final Optional<PluginModel> optional = appConfiguration.pluginModel(configuration);

assertThat(optional.isPresent(), is(false));
verify(configuration, times(1)).getAuthentication();
Copy link
Member

Choose a reason for hiding this comment

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

FYI, verify already works only for one time. So you don't need times(1) - it is the default behavior.

@Bean
public Optional<MeterRegistry> prometheusMeterRegistry(
final DataPrepperConfiguration dataPrepperConfiguration,
final Optional<Authenticator> optionalAuthenticator,
Copy link
Contributor

Choose a reason for hiding this comment

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

@sbayer55, why not go with option 1? That sounds like it decouples DP with a dependency framework and won't require passing optionals around.

@cmanning09
Copy link
Contributor

Please update the PR description and fill in the template.

@cmanning09
Copy link
Contributor

@sbayer55 , please update the PR with a description of the change and fill in the template.

dlvenable
dlvenable previously approved these changes Jan 19, 2022
Copy link
Member

@dlvenable dlvenable left a comment

Choose a reason for hiding this comment

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

Thanks! This looks good!

Signed-off-by: Steven Bayer <[email protected]>
Signed-off-by: Steven Bayer <[email protected]>
Signed-off-by: Steven Bayer <[email protected]>
Signed-off-by: Steven Bayer <[email protected]>
Signed-off-by: Steven Bayer <[email protected]>
Signed-off-by: Steven Bayer <[email protected]>
Signed-off-by: Steven Bayer <[email protected]>
Signed-off-by: Steven Bayer <[email protected]>
Signed-off-by: Steven Bayer <[email protected]>
Signed-off-by: Steven Bayer <[email protected]>
Signed-off-by: Steven Bayer <[email protected]>
Signed-off-by: Steven Bayer <[email protected]>
Signed-off-by: Steven Bayer <[email protected]>
Signed-off-by: Steven Bayer <[email protected]>
Signed-off-by: Steven Bayer <[email protected]>
Signed-off-by: Steven Bayer <[email protected]>
Signed-off-by: Steven Bayer <[email protected]>
@sbayer55 sbayer55 merged commit ec417ad into opensearch-project:main Jan 21, 2022
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.

4 participants