Kotlin: Keeping multiple profiles inside #ActiveProfiles annotation? - spring

I know that in java, multiple active profiles can be kept using -
#ActiveProfiles({"profile1", "profile2"})
But I need a similar construct for kotlin. Above doesnt work with kotlin and gives error saying - Unexpected tokens (use ';' to separate expressions on the same line). I also tried #ActiveProfiles(profile = arrayOf("profile1", "profile2")) and also tried #Profile("profile1 & profile2"). Nothing seems to work. Please help.

If you check the source of #ActiveProfiles you'll see the following constructor:
/**
* Alias for {#link #profiles}.
* <p>This attribute may <strong>not</strong> be used in conjunction with
* {#link #profiles}, but it may be used <em>instead</em> of {#link #profiles}.
*/
#AliasFor("profiles")
String[] value() default {};
This means its expecting an array of strings for 'profiles' -> just create an array as you normally do it in Kotlin and pass it to the constructor like that:
#ActiveProfiles(profiles = arrayOf("profile1", "profile1"))

The shortest form would be:
#ActiveProfiles(profiles = ["profile1", "profile2"])

Related

Eliminating vurnabilities in the Spring SpEL

I'm testing the Spring SpEL and I thinking if it is possible to somehow limit what kind of SpEL query can be provided, to avoid some unwanted code injection? I just want to get values from some object, so is it possible to block other types of operations? I can't find such functionality in the Spring documentation.
For instance, I just want to allow to check if the value from the test object equals XYZ.
Test test = new Test("XYZ", 999);
ExpressionParser expressionParser = new SpelExpressionParser();
Expression expression = expressionParser.parseExpression("value eq 'XYZ'");
System.out.println(expression.getValue(new StandardEvaluationContext(test)));
However, I would like to limit which expressions are valid. I don't what to evaluate expressions which allow to execute some code, for instance:
Expression expression = expressionParser.parseExpression("''.getClass().forName('java.lang.Runtime').getMethods()[6]");
As #ArtemBilan mentioned in the comment, the solution to limit the SpEL language syntax and eliminate unwanted code execution is to use the SimpleEvaluationContext class, for instance:
SimpleEvaluationContext context = SimpleEvaluationContext.forReadOnlyDataBinding()
.withInstanceMethods()
.withRootObject(test)
.build();

SetAccessor and SetAccessorProperty, any difference?

V8's ObjectTemplate provides us two ways to attach a so-called accessor property to the object under instantiation.
The first one is ObjectTemplate::SetAccessor:
/**
* Sets an accessor on the object template.
*
* Whenever the property with the given name is accessed on objects
* created from this ObjectTemplate the getter and setter callbacks
* are called instead of getting and setting the property directly
* on the JavaScript object.
*
* \param name The name of the property for which an accessor is added.
* \param getter The callback to invoke when getting the property.
* \param setter The callback to invoke when setting the property.
* \param data A piece of data that will be passed to the getter and setter
* callbacks whenever they are invoked.
* \param settings Access control settings for the accessor. This is a bit
* field consisting of one of more of
* DEFAULT = 0, ALL_CAN_READ = 1, or ALL_CAN_WRITE = 2.
* The default is to not allow cross-context access.
* ALL_CAN_READ means that all cross-context reads are allowed.
* ALL_CAN_WRITE means that all cross-context writes are allowed.
* The combination ALL_CAN_READ | ALL_CAN_WRITE can be used to allow all
* cross-context access.
* \param attribute The attributes of the property for which an accessor
* is added.
* \param signature The signature describes valid receivers for the accessor
* and is used to perform implicit instance checks against them. If the
* receiver is incompatible (i.e. is not an instance of the constructor as
* defined by FunctionTemplate::HasInstance()), an implicit TypeError is
* thrown and no callback is invoked.
*/
void SetAccessor(
Local<String> name, AccessorGetterCallback getter,
AccessorSetterCallback setter = nullptr,
Local<Value> data = Local<Value>(), AccessControl settings = DEFAULT, // note the data is on the template level.
PropertyAttribute attribute = None, // not on the instance level.
Local<AccessorSignature> signature = Local<AccessorSignature>(),
SideEffectType getter_side_effect_type = SideEffectType::kHasSideEffect,
SideEffectType setter_side_effect_type = SideEffectType::kHasSideEffect);
and the second one is Template::SetAccessorProperty:
void SetAccessorProperty(
Local<Name> name, // The latter one is called data property.
Local<FunctionTemplate> getter = Local<FunctionTemplate>(),
Local<FunctionTemplate> setter = Local<FunctionTemplate>(),
PropertyAttribute attribute = None,
AccessControl settings = DEFAULT);
Having two very similar APIs confuses me a lot.
Unfortunately there is no docs describing their differences, so I have to do experiment on my own. I found that the combination of Holder() and SetAccessor() will break, while other combinations of Holder() or This() and SetAccessor() or SetAccessorProperty() work fine. On a previous post I ran into this failing combination and was fooled to believe what's went wrong is Holder() or This(). But after the experiment I now believe that it is SetAccessor went wrong.
My question is, whether SetAccessor is a deprecated API? If so, all we have to do is stop using it. If not so, please explain a little bit their differences, esspecially in causing this failure. Many thanks to the warm-hearted and experienced V8 developers!
I agree that the names can be a bit confusing; neither is deprecated. The difference is as follows:
SetAccessor creates a "magic" data property: it looks like a data property to JavaScript (getOwnPropertyDescriptor returns {value: ..., ...}), but when reading/writing the property, the C++ callbacks you specified will be called. For a built-in example, think of Array.prototype.length (where in particular the setter has to do additional work when you use a .length assignment to shorten an array).
SetAccessorProperty creates a regular accessor property, i.e. getOwnPropertyDescriptor returns {get: ..., set: ..., ...}. A built-in example would be Int32Array.prototype.__proto__.byteLength. The name "SetAccessorProperty" reflects the fact that the JS spec calls these properties "accessor properties".
Chances are that in many cases, this difference doesn't matter: interfacing JavaScript code can read and/or write properties either way. But sometimes you might have a reason to care about the distinction, and in that case V8's API gives you that flexibility.

How can I manually evaluate the expression in a Spring #Value annotation?

My SpringBoot application has a bunch of #Value annotations. When the application is deployed to our Kubernetes cluster, it ends up using a properties file that is interpolated through a couple of different mechanisms. When it finally gets there, if developers make simple mistakes, the container can fail to start up, simply because they didn't set all the properties correctly. It's not easy to discover that this is what happened, until well after the mistake is made.
Note that virtually all of these #Value annotations will use the "${}" syntax, as opposed to "#{}". The primary concern is reading particular properties from a properties file, not Spring bean properties.
So, what I want to write is a little validation script (a small Java class), which does something like this:
Obtain the path to the generated properties file
Load that properties file into a Properties object
Scan the classpath for all classes (with a base package), and all fields in those classes, for #Value annotations
For each found #Value annotation, do some simple validation and evaluate the expression
If the validation or the evaluation fails, print an error message with all relevant details.
This script will run before the "kubectl rollout" happens. If we see these error messages before the rollout, we will save time diagnosing these problems.
I've been able to achieve everything so far except doing something with the loaded properties file and evaluating the expression. I know that Spring uses a bean postprocessor, but I don't know how I can manually call that.
Any idea how to fulfill that missing link?
Update:
I still don't have an answer to this.
I was thinking that perhaps the answer would be found in a BeanPostProcessor in the Spring codebase, so I cloned the spring-framework repo. I found a couple of potential ones, being "AutowiredAnnotationBeanPostProcessor", "BeanFactoryPostProcessor", "CommonAnnotationBeanPostProcessor", and "BeanPostProcessor", but I just don't see anything in any of these that looks like evaluating the expression in the Value annotation. I would have tried setting a breakpoint in the "value()" method of the annotation, but of course you can't set a breakpoint in a method like that.
Update:
To be clear, this expression is not a "Spring EL" expression. Those reference bean properties (or loaded properties) and begin with "#{". I'm working with expressions that just reference properties, which begin with "${". I did try parsing the expression with Spring EL, but it just thinks there's nothing there.
I've managed to figure this out. The key is the "PropertyPlaceholderHelper.replacePlaceholders(String, Properties)" method. Using that, I developed something like this:
PropertyPlaceholderHelper propertyPlaceholderHelper =
new PropertyPlaceholderHelper("${", "}", ":", true);
ClassPathScanningCandidateComponentProvider scanner = new ClassPathScanningCandidateComponentProvider(true);
boolean foundAtLeastOneUnfoundProperty = false;
for (BeanDefinition bd : scanner.findCandidateComponents(basePackage)) {
String beanClassName = bd.getBeanClassName();
Class<?> clazz = Class.forName(beanClassName);
for (Field field : clazz.getDeclaredFields()) {
Value valueAnnotation = field.getAnnotation(Value.class);
if (valueAnnotation != null) {
Matcher matcher = propertyRefPattern.matcher(valueAnnotation.value());
if (matcher.matches()) {
String resultingValue = propertyPlaceholderHelper.replacePlaceholders(valueAnnotation.value(), properties);
if (resultingValue.equals(valueAnnotation.value())) {
// This means that the property was not found.
System.out.println("ERROR: Expression \"" + valueAnnotation.value() +
"\" on field \"" + field.getName() + "\" in class \"" + beanClassName +
"\" references a property which is not defined.");
foundAtLeastOneUnfoundProperty = true;
}
}
}
}
}

Where is the syntax for TypeScript comments documented?

Is the syntax for TypeScript comments documented anywhere?
And by any chance, does it now support the C# /// system?
Current
The TypeScript team, and other TypeScript involved teams, created a TSDoc specification. https://tsdoc.org/
Example straight from the docs:
export class Statistics {
/**
* Returns the average of two numbers.
*
* #remarks
* This method is part of the {#link core-library#Statistics | Statistics subsystem}.
*
* #param x - The first input number
* #param y - The second input number
* #returns The arithmetic mean of `x` and `y`
*
* #beta
*/
public static getAverage(x: number, y: number): number {
return (x + y) / 2.0;
}
}
Past
TypeScript uses JSDoc. e.g.
/** This is a description of the foo function. */
function foo() {
}
To learn jsdoc : https://jsdoc.app/
But you don't need to use the type annotation extensions in JSDoc.
You can (and should) still use other jsdoc block tags like #returns etc.
Just an example. Focus on the types (not the content).
JSDoc version (notice types in docs):
/**
* Returns the sum of a and b
* #param {number} a
* #param {number} b
* #returns {number}
*/
function sum(a, b) {
return a + b;
}
TypeScript version (notice the re-location of types):
/**
* Takes two numbers and returns their sum
* #param a first input to sum
* #param b second input to sum
* #returns sum of a and b
*/
function sum(a: number, b: number): number {
return a + b;
}
Update November 2020
A website is now online with all the TSDoc syntax available (and that's awesome): https://tsdoc.org/
For reference, old answer:
The right syntax is now the one used by TSDoc. It will allow you to have your comments understood by Visual Studio Code or other documentation tools.
A good overview of the syntax is available here and especially here. The precise spec should be "soon" written up.
Another file worth checking out is this one where you will see useful standard tags.
Note: you should not use JSDoc, as explained on TSDoc main page: Why can't JSDoc be the standard? Unfortunately, the JSDoc grammar is not rigorously specified but rather inferred from the behavior of a particular implementation. The majority of the standard JSDoc tags are preoccupied with providing type annotations for plain JavaScript, which is an irrelevant concern for a strongly-typed language such as TypeScript. TSDoc addresses these limitations while also tackling a more sophisticated set of goals.
You can add information about parameters, returns, etc. as well using:
/**
* This is the foo function
* #param bar This is the bar parameter
* #returns returns a string version of bar
*/
function foo(bar: number): string {
return bar.toString()
}
This will cause editors like VS Code to display it as the following:
You can use comments like in regular JavaScript:
1 Introduction
[...] TypeScript syntax is a superset of ECMAScript 2015 (ES2015) syntax.
2 Basic Concepts
[...] This document describes the syntactic grammar added by TypeScript [...]
Source: TypeScript Language Specification
The only two mentions of the word "comments" in the spec are:
1 Introduction
[...] TypeScript also provides to JavaScript programmers a system of optional type annotations. These type annotations are like the JSDoc comments found in the Closure system, but in TypeScript they are integrated directly into the language syntax. This integration makes the code more readable and reduces the maintenance cost of synchronizing type annotations with their corresponding variables.
11.1.1 Source Files Dependencies
[...] A comment of the form /// <reference path="..."/> adds a dependency on the source file
specified in the path argument. The path is resolved relative to the directory of the containing source file.
TypeScript is a strict syntactical superset of JavaScript hence
Single line comments start with //
Multi-line comments start with /* and end with */

Where does Grail's errors property come from?

Grails has a bug with regards to databinding in that it throws a cast exception when you're dealing with bad numerical input. JIRA: http://jira.grails.org/browse/GRAILS-6766
To fix this I've written the following code to manually handle the numerical input on the POGO class Foo located in src/groovy
void setPrice(String priceStr)
{
this.priceString = priceStr
// Remove $ and ,
priceStr = priceStr.trim().replaceAll(java.util.regex.Matcher.quoteReplacement('$'),'').replaceAll(',','')
if (!priceStr.isDouble()) {
errors.reject(
'trade.price.invalidformat',
[priceString] as Object[],
'Price:[{0}] is an invalid price.')
errors.rejectValue(
'price',
'trade.price.invalidformat')
} else {
this.price = priceStr.toDouble();
}
}
The following throws a null reference exception on the errors.reject() line.
foo.price = "asdf" // throws null reference on errors.reject()
foo.validate()
However, I can say:
foo.validate()
foo.price = "asdf" // no Null exception
foo.hasErrors() // false
foo.validate()
foo.hasErrors() // true
Where does errors come from when validate() is called?
Is there a way to add the errors property without calling validate() first?
I can't exactly tell you why, but you need to call getErrors() explicitly instead of accessing it as errors like a property. For some reason, Groovy isn't calling the method for it. So change the reject lines in setPrice() to
getErrors().reject(
'trade.price.invalidformat',
[priceString] as Object[],
'Price:[{0}] is an invalid price.')
getErrors().rejectValue(
'price',
'trade.price.invalidformat')
That is the easiest way to make sure the Errors object exists in your method. You can check out the code that adds the validation related methods to your domain class.
The AST transformation handling #Validateable augments the class with, among other things
a field named errors
public methods getErrors, setErrors, clearErrors and hasErrors
The getErrors method lazily sets the errors field if it hasn't yet been set. So it looks like what's happening is that accesses to errors within the same class are treated as field accesses rather than Java Bean property accesses, and bypassing the lazy initialization.
So the fix appears to be to use getErrors() instead of just errors.
The errors are add to your validateable classes (domain classes and classes that have the annotation #Validateable) dinamically.
Allowing the developer to set a String instead of a number doesn't seem a good way to go. Also, your validation will work only for that particular class.
I think that a better approach is to register a custom property editor for numbers. Here's a example with dates, that enable the transform of String (comming from the form) to Date with a format like dd/MM/yyyy. The idea is the same, as you will enforce that your number is parseable (eg. Integer.parseInt() will throw exception).
In your domain class, use the numeric type instead of String, so by code developers will not be allowed to store not number values.

Resources