Skip to content

Commit

Permalink
fix(telemetry): fix MetricsPostProcessor dependency injection (spinna…
Browse files Browse the repository at this point in the history
…ker#4224)

Allow registry implementations to be processed by other BeanPostProcessors
Fix armory-plugins/armory-observability-plugin#32
  • Loading branch information
massimo-pacher-tw authored Feb 28, 2022
1 parent 9586ec7 commit d168010
Show file tree
Hide file tree
Showing 5 changed files with 139 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
import java.util.function.BiConsumer;
import java.util.function.Function;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;
import org.springframework.stereotype.Component;

Expand All @@ -31,6 +32,7 @@ public class TaskSchedulerMetricsPostProcessor
extends AbstractMetricsPostProcessor<ThreadPoolTaskScheduler> {

@Autowired
@Lazy
public TaskSchedulerMetricsPostProcessor(Registry registry) {
super(ThreadPoolTaskScheduler.class, registry);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
import java.util.function.BiConsumer;
import java.util.function.Function;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.stereotype.Component;

Expand All @@ -32,6 +33,7 @@ public class ThreadPoolMetricsPostProcessor
extends AbstractMetricsPostProcessor<ThreadPoolTaskExecutor> {

@Autowired
@Lazy
public ThreadPoolMetricsPostProcessor(Registry registry) {
super(ThreadPoolTaskExecutor.class, registry);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
import java.lang.reflect.Field;
import org.apache.commons.pool2.impl.GenericObjectPool;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Component;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
Expand All @@ -29,6 +30,7 @@
public class RedisPoolMetricsPostProcessor extends AbstractMetricsPostProcessor<JedisPool> {

@Autowired
@Lazy
public RedisPoolMetricsPostProcessor(Registry registry) {
super(JedisPool.class, registry);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
/*
* Copyright 2019 Google, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License")
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package com.netflix.spinnaker.orca;

import static org.junit.jupiter.api.Assertions.assertEquals;

import io.micrometer.core.instrument.MeterRegistry;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.TestPropertySource;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest(classes = {Main.class})
@ContextConfiguration(classes = {MeterRegistryProcessorTestConfiguration.class})
@TestPropertySource(
properties = {"spring.config.location=classpath:orca-test.yml", "redis.enabled: false"})
public class MeterRegistryProcessorIntTest {

@Autowired TestBeanPostProcessor testBeanPostProcessor;

@Test
public void test() {
assertEquals(true, testBeanPostProcessor.invoked);
}

/*
Helper bean post processor used as spy
*/
public static class TestBeanPostProcessor implements BeanPostProcessor {
boolean invoked = false;

public TestBeanPostProcessor() {}

@Override
public final Object postProcessBeforeInitialization(Object bean, String beanName)
throws BeansException {

if (bean instanceof MeterRegistry) {
invoked = true;
}

return bean;
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
/*
* Copyright 2022 Netflix, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package com.netflix.spinnaker.orca;

import com.netflix.spinnaker.orca.notifications.AlwaysUnlockedNotificationClusterLock;
import com.netflix.spinnaker.orca.notifications.NotificationClusterLock;
import com.netflix.spinnaker.orca.pipeline.persistence.ExecutionRepository;
import com.netflix.spinnaker.orca.pipeline.persistence.InMemoryExecutionRepository;
import com.netflix.spinnaker.q.memory.InMemoryQueue;
import com.netflix.spinnaker.q.metrics.EventPublisher;
import com.netflix.spinnaker.q.metrics.MonitorableQueue;
import io.micrometer.core.instrument.MeterRegistry;
import io.micrometer.core.instrument.composite.CompositeMeterRegistry;
import io.micrometer.core.instrument.simple.SimpleMeterRegistry;
import java.time.Clock;
import java.time.Duration;
import java.util.Collections;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.boot.test.context.TestConfiguration;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Primary;

@TestConfiguration
public class MeterRegistryProcessorTestConfiguration {

@Bean
NotificationClusterLock notificationClusterLock() {
return new AlwaysUnlockedNotificationClusterLock();
}

@Bean
ExecutionRepository executionRepository() {
return new InMemoryExecutionRepository();
}

@Bean
@Primary
MonitorableQueue queue(Clock clock, EventPublisher publisher) {
return new InMemoryQueue(
clock, Duration.ofMinutes(1), Collections.emptyList(), false, publisher);
}

@Bean
MeterRegistry meterRegistry() {
return new CompositeMeterRegistry(
io.micrometer.core.instrument.Clock.SYSTEM,
Collections.singleton(new SimpleMeterRegistry()));
}

@Bean
BeanPostProcessor testBeanPostProcessor() {
return new MeterRegistryProcessorIntTest.TestBeanPostProcessor();
}
}

0 comments on commit d168010

Please sign in to comment.