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

Wavefront Proxy validation error with default uri implementation #3903

Closed
rrourke opened this issue Jun 13, 2023 · 13 comments
Closed

Wavefront Proxy validation error with default uri implementation #3903

rrourke opened this issue Jun 13, 2023 · 13 comments
Assignees
Labels
bug A general bug registry: wavefront A Wavefront (Tanzu Observability) Registry related issue
Milestone

Comments

@rrourke
Copy link

rrourke commented Jun 13, 2023

Using the Wavefront Proxy I keep getting a uri error

  <dependency>
      <groupId>io.micrometer</groupId>
      <artifactId>micrometer-registry-wavefront</artifactId>
      <version>1.10.6</version>
  </dependency>
! io.micrometer.core.instrument.config.validate.ValidationException: wavefront.uri was 'proxy://xxx.yyy.com:2878' but it must be a valid URL
! at io.micrometer.core.instrument.config.validate.Validated$Invalid.get(Validated.java:304)

No matter how I try set up the url it reports its incorrect even though the uri is correct.

@shakuzen shakuzen added registry: wavefront A Wavefront (Tanzu Observability) Registry related issue waiting for feedback We need additional information before we can continue and removed waiting-for-triage labels Jun 14, 2023
@shakuzen
Copy link
Member

I tried to reproduce the issue you mentioned in a unit test, but it passes without issue. Could you please provide a unit test demonstrating how to reproduce the error you are seeing?

@Test
void proxyConfigIsValid() {
    WavefrontConfig config = new WavefrontConfig() {
        @Override
        public String get(String key) {
            return null;
        }

        @Override
        public String uri() {
            return "proxy://example.com:2878";
        }
    };
    assertThat(config.validate().isValid()).isTrue();
}

@shakuzen
Copy link
Member

I also tried one without overriding the default uri method using a properties file as follows:

@Test
void proxyConfigIsValid() throws IOException {
    Properties wavefrontProps = new Properties();
    wavefrontProps.load(this.getClass().getResourceAsStream("/wavefront.properties"));
    WavefrontConfig config = wavefrontProps::getProperty;
    assertThat(config.validate().isValid()).isTrue();
}

With the wavefront.properties containing:

wavefront.uri=proxy://example.com:2878

@mrniko
Copy link

mrniko commented Jun 14, 2023

@shakuzen

Can you try the config below?

        WavefrontConfig config = new WavefrontConfig() {

            @Override
            public String get(String key) {
                if (key.endsWith(".uri")) {
                    return "proxy://example.com:2878";
                }
                return null;
            }
        };

@rrourke rrourke closed this as completed Jun 14, 2023
@jonatan-ivanov jonatan-ivanov added invalid An issue that we don't feel is valid and removed registry: wavefront A Wavefront (Tanzu Observability) Registry related issue waiting for feedback We need additional information before we can continue labels Jun 14, 2023
@jonatan-ivanov jonatan-ivanov closed this as not planned Won't fix, can't repro, duplicate, stale Jun 14, 2023
@jonatan-ivanov
Copy link
Member

@mrniko Did you try it? To me it is still valid (but I would not recommend doing this since it's a bit hacky.)

@rrourke Were you able to figure out what was wrong? Could you please share, it might be useful to others.

@rrourke
Copy link
Author

rrourke commented Jun 14, 2023

Hi @jonatan-ivanov @mrniko is the author of the sdk I was using. Would have to ask him but I think maybe was using an older version in his sdk but will see what he says.

@mrniko
Copy link

mrniko commented Jun 15, 2023

@jonatan-ivanov

Here is the WavefrontConfig which works for all parameters except uri.

        WavefrontConfig config = new WavefrontConfig() {

            @Override
            public String uri() {
                return uri;
            }

            @Override
            public String get(String key) {
                if (key.endsWith(".step")) {
                    return step;
                }
                if (key.endsWith(".batchSize")) {
                    return batchSize;
                }
                if (key.endsWith(".numThreads")) {
                    return numThreads;
                }
                if (key.endsWith(".uri")) {
                    return uri;
                }
                if (key.endsWith(".source")) {
                    return source;
                }
                if (key.endsWith(".apiToken")) {
                    return apiToken;
                }
                return null;
            }
        };

Does your answer mean that it's better to always return null in public String get(String key) method implementation?

@jonatan-ivanov
Copy link
Member

Here is the WavefrontConfig which works for all parameters except uri.

I see two issues with your example:

  1. It does not compile
  2. You have uri implemented and key.endsWith(".uri") in get

If I fix the compilation issues and substitute them with real values, it works for me, I don't get errors.

Does your answer mean that it's better to always return null in public String get(String key) method implementation?

Did you see what @shakuzen did above in #3903 (comment)?
You can do the same with a Map and you can implement the different methods and return null in get.

@shakuzen
Copy link
Member

Does your answer mean that it's better to always return null in public String get(String key) method implementation?

The get method is used by the default implementations of the other methods. If you are overriding the implementations of the other methods, then your implementation of that method will be used instead. This arrangement enables you to back the config values with an arbitrary source, like a Properties object (which is backed by e.g. a .properties file) or a Map or some external configuration by retrieving values from those in the implementation of the get method.

In your example, it looks like you already have everything in fields. You could override the implementation of each method to directly return the respective field. If you do that, there's no benefit to doing anything in the get implementation, because you'll have overridden all the other methods so get isn't called anymore.

As Jonatan mentioned, the example you provided passes the test. In the second example, it would depend what the value of uri is, but if it is the same value as in other examples, it would work also.

@mrniko
Copy link

mrniko commented Jun 15, 2023

@shakuzen

Sorry, my mistake.

The config provided in this example won't work - #3903 (comment) if uri() method isn't overriden. Can you check that?

@shakuzen
Copy link
Member

The config provided in this example won't work - #3903 (comment) if uri() method isn't overriden. Can you check that?

I did try it, and the following test passes. Does that not pass for you? What are we missing?

@Test
void proxyConfigIsValid() {
    WavefrontConfig config = new WavefrontConfig() {

        @Override
        public String get(String key) {
            if (key.endsWith(".uri")) {
                return "proxy://example.com:2878";
            }
            return null;
        }
    };
    assertThat(config.validate().isValid()).isTrue();
}

@mrniko
Copy link

mrniko commented Jun 15, 2023

Thank you for the provided test. Unfortunately, the test below will fail.

        WavefrontConfig config = new WavefrontConfig() {
            @Override
            public String get(String key) {
                if (key.endsWith(".uri")) {
                    return "proxy://example.com:2878";
                }
                return null;
            }
        };

        WavefrontMeterRegistry r = new WavefrontMeterRegistry(config, Clock.SYSTEM);

@shakuzen
Copy link
Member

Thanks for the complete test that reproduces it. Indeed that does not work due to the validation we're doing in the default uri method. We can consider relaxing that validation, but in the meantime, you will indeed need to override the uri method to avoid the issue with a Wavefront proxy config.

@shakuzen shakuzen reopened this Jun 15, 2023
@shakuzen shakuzen added waiting for team An issue we need members of the team to review registry: wavefront A Wavefront (Tanzu Observability) Registry related issue and removed invalid An issue that we don't feel is valid labels Jun 15, 2023
@shakuzen shakuzen changed the title Wavefront Proxy uri validation error Wavefront Proxy uri validation error with default uri implementation Jun 15, 2023
@shakuzen shakuzen changed the title Wavefront Proxy uri validation error with default uri implementation Wavefront Proxy validation error with default uri implementation Jun 15, 2023
@shakuzen shakuzen added bug A general bug and removed waiting for team An issue we need members of the team to review labels Jul 6, 2023
@shakuzen shakuzen added this to the 1.9.x milestone Jul 6, 2023
@shakuzen shakuzen self-assigned this Jul 6, 2023
@shakuzen shakuzen modified the milestones: 1.9.x, 1.9.13 Jul 6, 2023
@mrniko
Copy link

mrniko commented Jul 6, 2023

@shakuzen

Thank you!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug A general bug registry: wavefront A Wavefront (Tanzu Observability) Registry related issue
Projects
None yet
Development

No branches or pull requests

4 participants