I try to understand the geoserver source code and therefore play around with it. For my task I want to find out where I can find the "methods" stated in the code below from the ClassProperties.java class in the org.geoserver.ows.util package. When printing the methods.getname() out I get this response:
List item
indexOf
indexOf
isFrozen
getMap
map
getCapabilities
getStyles
getLegendGraphic
capabilities
Although clazz.getMethods() gets these methods I can't find them in the code. where does Class clazz.getMethods() get them from?
ClassProperties.java
/* (c) 2014 Open Source Geospatial Foundation - all rights reserved
* (c) 2001 - 2013 OpenPlans
* This code is licensed under the GPL 2.0 license, available at the root
* application directory.
*/
package org.geoserver.ows.util;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
/**
* Provides lookup information about java bean properties in a class.
*
* #author Justin Deoliveira, OpenGEO
* #author Andrea Aime, OpenGEO
*
*/
public class ClassProperties {
private static final List<Method> EMPTY = new ArrayList<Method>(0);
private static final Set<String> COMMON_DERIVED_PROPERTIES = new HashSet<>(
Arrays.asList("prefixedName"));
List<Method> methods;
List<Method> getters;
List<Method> setters;
public ClassProperties(Class clazz) {
methods = Arrays.asList(clazz.getMethods());
From the class that's passed as a parameter to ClassProperties(Class clazz).
Obviously depending on the class, you'll get different methods.
The usage is simple:
ClassProperties cp = new ClassProperties(String.class);
ClassProperties cp2 = new ClassProperties(cp.getClass());
The first one would access String's methods, the second one would access the class' own methods.
If you can't see the class name in any way, the only way to find the class would be to search for all classes and check whether they have the same methods (not a very good idea).
Related
At the moment, I have the following HttpSecurityPolicy which is invoked on every request:
import io.quarkus.security.identity.SecurityIdentity;
import io.quarkus.vertx.http.runtime.security.HttpSecurityPolicy;
import io.smallrye.mutiny.Uni;
import io.vertx.ext.web.RoutingContext;
import javax.enterprise.context.ApplicationScoped;
#ApplicationScoped
public class SecurityHandler implements HttpSecurityPolicy {
#Override
public Uni<CheckResult> checkPermission(
final RoutingContext request,
final Uni<SecurityIdentity> identity,
final AuthorizationRequestContext requestContext) {
return ...
}
}
According to the HttpSecurityPolicy documentation, if I created a named policy, it can then be referenced in the application.properties path matching rules, which allows this policy to be applied to specific requests. Same thing is explained in the quarkus.http.auth.permission.-permissions-.policy documentation.
So then, is it possible to create a named mypolicy policy that I can later reference like:
quarkus.http.auth.permission.mypermission.policy=mypolicy
I've tried with #Named but is not working. I cannot use HttpSecurityPolicyBuildItem because I'm not developing an extension. It seems that Quarkus read all available policies in HttpSecurityProcessor, but I have no idea how I can add my policy to that policyMap.
Spring's Metrics and Management: MessageChannel Metric Features describes:
If it is a QueueChannel, you also see statistics for the receive operation as well as the count of messages that are currently buffered by this QueueChannel
However:
These legacy metrics will be removed in a future release. See Micrometer Integration.
Where it describes:
The Counter Meters for receive operations on pollable message channels have the following names or tags:
name: spring.integration.receive [...]
which sounds like it only counts how many messages have been received. The number of messages in the queue doesn't seem to be available, not even by calculating receive - send (because there is no send).
So, with Spring Integration and Micrometer, is it even possible to read the queue size? How?
I think we need to register a Gauge for this queue size value:
/**
* A gauge tracks a value that may go up or down. The value that is published for gauges is
* an instantaneous sample of the gauge at publishing time.
*
* #author Jon Schneider
*/
public interface Gauge extends Meter {
And here is a respective builder:
/**
* A convenience method for building a gauge from a supplying function, holding a strong
* reference to this function.
*
* #param name The gauge's name.
* #param f A function that yields a double value for the gauge.
* #return A new gauge builder.
* #since 1.1.0
*/
#Incubating(since = "1.1.0")
static Builder<Supplier<Number>> builder(String name, Supplier<Number> f) {
Feel free to raise a GH issue to improve things!
At the moment it is probably possible via an external Gauge instance with QueueChannel.getQueueSize() delegation.
Until Spring Integration 5.4 is released, this can be used:
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Configuration;
import org.springframework.integration.channel.QueueChannel;
import org.springframework.integration.support.management.metrics.MetricsCaptor;
import org.springframework.integration.support.management.micrometer.MicrometerMetricsCaptor;
import java.util.Collection;
#Configuration
#RequiredArgsConstructor
public class IntegrationMetricConfig {
private final ApplicationContext applicationContext;
private final Collection<QueueChannel> queues;
/**
* Temporary solution until <a href="https://github.com/spring-projects/spring-integration/pull/3349/files">Add
* gauges for queue channel size</a> is released. Remove this when updating to Spring Integration
* 5.4.
*/
#Autowired
public void queueSizeGauges() {
MetricsCaptor metricsCaptor = MicrometerMetricsCaptor.loadCaptor(this.applicationContext);
queues.forEach(queue -> {
metricsCaptor.gaugeBuilder("spring.integration.channel.queue.size", queue,
obj -> queue.getQueueSize())
.tag("name", queue.getComponentName() == null ? "unknown" : queue.getComponentName())
.tag("type", "channel")
.description("The size of the queue channel")
.build();
metricsCaptor.gaugeBuilder("spring.integration.channel.queue.remaining.capacity", this,
obj -> queue.getQueueSize())
.tag("name", queue.getComponentName() == null ? "unknown" : queue.getComponentName())
.tag("type", "channel")
.description("The remaining capacity of the queue channel")
.build();
});
}
}
I have a number of non spring-boot services which generate JVM metrics automatically using io.prometheus simpleclient_hotspot.
I am trying to obtain parity with these and the JVM metrics produced from my spring-boot services which are using micrometer's default settings.
Is there some additional configuration for micrometer which I need in order for it to generate metrics such as:
# TYPE jvm_info gauge
jvm_info{version="
...
jvm_memory_bytes_used
jvm_memory_pool_bytes_max
etc...
?
I appreciate micrometer out of the box is logging: jvm_memory_used_bytes which doesn't match the name of the same metric from simpleclient_hotspot :(
I would like to achieve consistency if possible, and jvm_info would be particularly useful from micrometer/spring-boot.
I recommend you look into NamingConvention found in the micrometer core library. There are several examples of using it to convert names to different monitoring systems (look for classes implenting NamingConvention). For example, if you're using Prometheus (which it looks like you might be), you could look at PrometheusNamingConvention as an example. It looks like you'll be interested in implementing/overriding the public String name(String name, Meter.Type type, #Nullable String baseUnit) method.
To answer my own question(s)
I ended up implementing this for JVM Version Info:
import io.micrometer.core.instrument.Gauge;
import io.micrometer.core.instrument.MeterRegistry;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
/**
* Migrated From simpleclient_hotspot/src/main/java/io/prometheus/client/hotspot/VersionInfoExports.java
* Because its not included in Micrometer.
*/
#Component
public class JvmVersionInfoExports {
private static final Logger LOGGER = LoggerFactory.getLogger(JvmVersionInfoExports.class);
public JvmVersionInfoExports(MeterRegistry meterRegistry) {
LOGGER.info("Adding JVM Metrics");
Gauge.builder("jvm_info", () -> 1L)
.description("JVM version info")
.tag("version", System.getProperty("java.runtime.version", "unknown"))
.tag("vendor", System.getProperty("java.vm.vendor", "unknown"))
.tag("runtime", System.getProperty("java.runtime.name", "unknown"))
.register(meterRegistry);
}
}
I ended up implementing this for OS Version Info:
import io.micrometer.core.instrument.Gauge;
import io.micrometer.core.instrument.MeterRegistry;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
#Component
public class OsVersionInfoExports {
private static final Logger LOGGER = LoggerFactory.getLogger(OsVersionInfoExports.class);
public OsVersionInfoExports(MeterRegistry meterRegistry) {
LOGGER.info("Adding OS Metrics");
Gauge.builder("os_info", () -> 1L)
.description("OS version info")
.tag("version", System.getProperty("os.version", "unknown"))
.tag("arch", System.getProperty("os.arch", "unknown"))
.tag("name", System.getProperty("os.name", "unknown"))
.register(meterRegistry);
}
}
Although theses misuse the Micrometer Gauge they provide me with the compatibility I need to track these details across services using a mix of Micrometer and Prometheus HotSpot libraries.
I want to declare and instantiate a HashMap in one go in JCodeModel.
I do:
jc.field(JMod.PRIVATE, HashMap.class, "initAttributes");
which declares it but doesn't instantiate it. How do I instantiate it?
Thanks
In the simplest case, you can just append the initialization directly to your creation of the field:
jc.field(JMod.PRIVATE, HashMap.class, "initAttributes")
.init(JExpr._new(codeModel.ref(HashMap.class)));
Some further hints:
Considering that you should usually program to an interface, it is a good practice to declare the variable using a type that is "as basic as possible". You should hardly ever declare a variable as
private HashMap map;
but basically always only as
private Map map;
because Map is the interface that is relevant here.
You can also add generics in JCodeModel. These usually involve some calls to narrow on certain types. It is a bit more effort, but it will generate code that can be compiled without causing warnings due to the raw types.
An example is shown here. (It uses String as the key type and Integer as the value type of the map. You may adjust this accordingly)
import java.util.HashMap;
import java.util.Map;
import com.sun.codemodel.CodeWriter;
import com.sun.codemodel.JClass;
import com.sun.codemodel.JCodeModel;
import com.sun.codemodel.JDefinedClass;
import com.sun.codemodel.JExpr;
import com.sun.codemodel.JMod;
import com.sun.codemodel.writer.SingleStreamCodeWriter;
public class InitializeFieldInCodeModel
{
public static void main(String[] args) throws Exception
{
JCodeModel codeModel = new JCodeModel();
JDefinedClass definedClass = codeModel._class("com.example.Example");
JClass keyType = codeModel.ref(String.class);
JClass valueType = codeModel.ref(Integer.class);
JClass mapClass =
codeModel.ref(Map.class).narrow(keyType, valueType);
JClass hashMapClass =
codeModel.ref(HashMap.class).narrow(keyType, valueType);
definedClass.field(JMod.PRIVATE, mapClass, "initAttributes")
.init(JExpr._new(hashMapClass));
CodeWriter codeWriter = new SingleStreamCodeWriter(System.out);
codeModel.build(codeWriter);
}
}
The generated class looks as follows:
package com.example;
import java.util.HashMap;
import java.util.Map;
public class Example {
private Map<String, Integer> initAttributes = new HashMap<String, Integer>();
}
When using the Spock #Stepwise annotation, is there any way to configure it to not fail the entire testsuite after a single test fails?
Decided to just create a new extension called #StepThrough. All I needed to do was subclass StepwiseExtension and take out the line of code that was failing the entire test suite. Pasted code below...
StepThrough.groovy
package com.test.SpockExtensions
import org.spockframework.runtime.extension.ExtensionAnnotation
import java.lang.annotation.ElementType
import java.lang.annotation.Retention
import java.lang.annotation.RetentionPolicy
import java.lang.annotation.Target
/**
* Created by jchertkov on 6/22/15.
*/
#Target(ElementType.TYPE)
#Retention(RetentionPolicy.RUNTIME)
#ExtensionAnnotation(StepThroughExtension.class)
public #interface StepThrough {}
StepThroughExtension.groovy
package com.test.SpockExtensions
import org.spockframework.runtime.extension.builtin.StepwiseExtension
import org.spockframework.runtime.model.SpecInfo
import java.lang.annotation.Annotation
/**
* Created by jchertkov on 6/22/15.
*/
public class StepThroughExtension extends StepwiseExtension {
public void visitSpecAnnotation(Annotation annotation, final SpecInfo spec) {
sortFeaturesInDeclarationOrder(spec);
includeFeaturesBeforeLastIncludedFeature(spec);
}
}
Notes:
I put the code into a package called com.test.SpockExtensions. You will need to do the same with whatever name you would like.
Java users - just change filetype from .groovy to .java