Skip to content

Conversation

@pirgeo
Copy link
Contributor

@pirgeo pirgeo commented Apr 8, 2021

This is a PR in preparation for the Dynatrace API v2 exporter (#2295). It moves the current v1 implementation into the v1 package while keeping the interface unchanged, making this a compatible change.

@pivotal-issuemaster
Copy link

@pirgeo Please sign the Contributor License Agreement!

Click here to manually synchronize the status of this Pull Request.

See the FAQ for frequently asked questions.

@pirgeo pirgeo force-pushed the move-dynatrace-registry-v1 branch from b97024d to db46f58 Compare April 8, 2021 08:53
@shakuzen shakuzen requested a review from jonatan-ivanov April 8, 2021 09:05
@pivotal-issuemaster
Copy link

@pirgeo Thank you for signing the Contributor License Agreement!

@pirgeo pirgeo force-pushed the move-dynatrace-registry-v1 branch from 74a088c to b222b9d Compare April 9, 2021 15:07
check("technologyType", DynatraceConfig::technologyType).andThen(Validated::nonBlank)
);
// Currently only v1 is implemented. This check will be extended once more versions are added.
if (apiVersion() == DynatraceApiVersion.V1) {
Copy link
Member

Choose a reason for hiding this comment

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

Since this is an enum now, this check is not necessary, enums are type-safe and since there is only one value: V1 this can't be anything else than V1 unless somebody overrides it but in that case they will overwrite validate too.

What I would do here is the following:

  @Override
  default Validated<?> validate() {
      return checkAll(this,
              c -> StepRegistryConfig.validate(c),
              checkRequired("apiToken", DynatraceConfig::apiToken),
              checkRequired("uri", DynatraceConfig::uri),
              checkRequired("deviceId", DynatraceConfig::deviceId),
              check("technologyType", DynatraceConfig::technologyType).andThen(Validated::nonBlank),
              check("apiVersion", DynatraceConfig::apiVersion)
      );
  }

Because of the version is an enum, this will try to convert it (by calling apiVersion) and if that call won't be successful (e.g.: invalid value), it will make the result invalid. Please see my comment on the test class of this.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This is much easier, and I adopted it for the v1 exporter. However, for the v2 exporter, we will only require the API version and checking these four required parameters with a .andThen(v -> v.invalidateWhen(<check-version-here>) construct for v1 seems a bit hard to read. Is there another way to make this more concise?

Copy link
Member

Choose a reason for hiding this comment

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

InfluxConfix does something similar though, in this case, I would create a validateV1 and a validateV2 method (the current validate becomes validateV1). With them you can do:

@Override
default Validated<?> validate() {
    return apiVersion() == V1 ? validateV1() : validateV2();
}

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 split it out to a separate function, and also removed the invalidVersion test, as the test data is invalid and can never happen in a non-test environment. If the spring boot app is started with an application property of v-INVALID, for example, it will just crash on startup and provide all valid values (which is just V1) in this case.
Another way to get around this would be to explicitly validate the apiVersion before accessing it, something like the following:

@Override
default Validated<?> validate() {
    Validated<DynatraceApiVersion> apiVersionValidation = checkRequired("apiVersion", DynatraceConfig::apiVersion).apply(this);
    if (apiVersionValidation.isInvalid()) {
        return apiVersionValidation;
    }
    return apiVersion() == V1 ? validateV1() : validateV2();
}

which seems a bit unnecessary if this case never actually appears during use.

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 just realized that that is only the case when using micrometer with Spring Boot. I think the solution I posted above (with the additional step of validating the apiVersion) should work, if i just access the apiVersion() method without validation first I recieve a ValidationException. I added the additional validation step.

@pirgeo pirgeo force-pushed the move-dynatrace-registry-v1 branch from c7c40a3 to 2aca20e Compare April 12, 2021 09:08
@pirgeo
Copy link
Contributor Author

pirgeo commented Apr 20, 2021

Hi @jonatan-ivanov, I think I addressed all the comments above. Please let me know if there's anything missing so we can move on with this. Thanks!

@jonatan-ivanov jonatan-ivanov changed the base branch from master to move-dynatrace-registry-v1 April 20, 2021 22:45
@jonatan-ivanov jonatan-ivanov merged commit 4fd760d into micrometer-metrics:move-dynatrace-registry-v1 Apr 20, 2021
@jonatan-ivanov
Copy link
Member

@pirgeo Sorry for not getting back to you earlier. I merged your PR but not yet into master.
We are only merging smaller fixes to master between the RC1 and the GA version of 1.7.0. We can branch off 1.7.x but that means one more branch to maintain for us (we will do it after the release).

I'm going to try/fix a few things (validation*) on the move-dynatrace-registry-v1 branch but in the meantime, you can handle this branch as master and build the v2 feature on top of it.

validation*: I totally forgot that Java only supports private methods in interfaces from Java 9. I'm not sure we should have a public validateV1 method on the config interface.

@jonatan-ivanov
Copy link
Member

@pirgeo please let me know what do you think: 4f53492

@jonatan-ivanov
Copy link
Member

@pirgeo I also broke the circular dependency between the registry and the exporter: 1115208

@pirgeo
Copy link
Contributor Author

pirgeo commented Apr 21, 2021

@jonatan-ivanov Thanks a lot, these changes look good to me!

@arminru arminru deleted the move-dynatrace-registry-v1 branch April 27, 2021 14:53
jonatan-ivanov added a commit that referenced this pull request May 25, 2021
* Move Dynatrace metrics exporter for API v1 to a separate package (#2553)

* Move Dynatrace metrics exporter for API v1 to a separate package

* rename dynatrace exporter

* use an enum for Dynatrace API versions.

* make DynatraceNamingConvention public

* fix formatting

* rename classes to have version at the end, move enum to uppercase, remove thread factory from exporter

* move naming convention and delegate to the v1 implementation

* update config validation and tests

* rename variables in test files

* remove unused imports

* split out validation

* re-add the apiVersion check and test

* update misleading comment and remove duplicate apiVersion check

* Adding validation logic into validate in DynatraceConfig
Unfortunately Java 8 does not support private methods in interfaces (9+ does) and I'm not sure we should have a public validateV1 method

* Polishing Dynatrace V1 refactor

- javadoc
- ctor/method reordering (to be consistent and ease diffing)
- get the logger based on Class not by String
- start the threadpool at the last step in the ctor
- license
- static imports

* Breaking circular dependency between DynatraceMeterRegistry and DynatraceExporterV1

Co-authored-by: Georg Pirklbauer <[email protected]>
jonatan-ivanov added a commit that referenced this pull request Jun 8, 2021
* Move Dynatrace metrics exporter for API v1 to a separate package (#2553)

* Move Dynatrace metrics exporter for API v1 to a separate package

* rename dynatrace exporter

* use an enum for Dynatrace API versions.

* make DynatraceNamingConvention public

* fix formatting

* rename classes to have version at the end, move enum to uppercase, remove thread factory from exporter

* move naming convention and delegate to the v1 implementation

* update config validation and tests

* rename variables in test files

* remove unused imports

* split out validation

* re-add the apiVersion check and test

* update misleading comment and remove duplicate apiVersion check

* Adding validation logic into validate in DynatraceConfig
Unfortunately Java 8 does not support private methods in interfaces (9+ does) and I'm not sure we should have a public validateV1 method

* Polishing Dynatrace V1 refactor

- javadoc
- ctor/method reordering (to be consistent and ease diffing)
- get the logger based on Class not by String
- start the threadpool at the last step in the ctor
- license
- static imports

* Breaking circular dependency between DynatraceMeterRegistry and DynatraceExporterV1

* Add an exporter for the Dynatrace metrics API v2

Co-authored-by: Armin Ruech <[email protected]>

* remove a comma that might lead to invalid ingestion result parsing

* Address code review comments

* Use new library features to make the exporter code more concise

* Making dependency configuration calls consistent
(Parenthesis is not a must in Groovy)

* Clean-up comments in DynatraceConfig (no validation changes)

* Fixing license header in DynatraceExporterV2

* Converting config field to local variable in ctor of DynatraceMeterRegistry

* DynatraceExporterV2 refactor: renamings, method order/visibility

* Simplify DynatraceExporterV2

* Adding back partitioning for Dynatrace V1

* More formatting for DynatraceExporterV2

* Simplifying toMeterLine and createMeterLine methods

* Improving naming and error messages

* Fixing tests after refactor

* Implement fallback for config uri.

(cherry picked from commit 46f2b77b747b017ba37a0ef585b98d0dc65c3c02)

* add a warning on unlikely configurations and check if the token needs to be sent

(cherry picked from commit 2c43bddc5e260d44dbc0f8f0b479e08fd18c3771)
Co-authored-by: Georg Pirklbauer <[email protected]>

* Fix/improve DynatraceExporterV2Test, round one:
- Using MockClock instead of Thread.sleep
- Improve test setup
- Fix/improve tests for: Gauge, TimeGauge, Counter, FunctionCounter, Timer, FunctionTimer, LongTaskTimer, DistributionSummary

* Fix/improve DynatraceExporterV2Test, round two:
- Custom Meter
- Invalid cases (also dedupe)

* DynatraceExporterV2Test: static imports, nullable problems

* Initialize DynatraceExporterV2Test the JUnit way

* Improving DynatraceExporterV2Test and test the interaction with the http client

* Fixing overwriting user-defined percentiles.

* re-enabling empty tag tests

* Adding DynatraceMeterRegistryTest

* +javadoc

* Rename blank tag tests, part one

Co-authored-by: Georg Pirklbauer <[email protected]>

* Rename blank tag tests, part two

Co-authored-by: Georg Pirklbauer <[email protected]>

* Removing artificially added 0th percentile meters

Co-authored-by: Georg Pirklbauer <[email protected]>
Co-authored-by: Armin Ruech <[email protected]>
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