rythm engine in parallel processing Issue - rythm

As per javadoc, RythmEngine class is not thread safe I.e. each time I have to build a new class which looks like an overhead. What is the best way to use rythm engine in multi threaded envioronment.
Below sample code is for illustration.
import java.io.File;
import java.util.Map;
import org.rythmengine.RythmEngine;
public class RythmEngineUtil {
static RythmEngine engine;
static {
Map<String, Object> conf;// = configure the object
engine = new RythmEngine(conf);
}
public static String render(File file, Map<String,Object> param){
return engine.render(file, param);
}
}

If you construct and init the engine when you app bootstrap, then that instance should be safely used in a multi-threaded environment

Related

Add custom database session variable to Spring Boot JPA queries?

I am trying to set SET SESSION encrypt.key='some_key' to database queries or connection.
Thing is I have following column definition in my model class
#ColumnTransformer(forColumn = "first_name",
read = "pgp_sym_decrypt(first_name, current_setting('encrypt.key'))",
write = "pgp_sym_encrypt(?, current_setting('encrypt.key'))")
#Column(name = "first_name", columnDefinition = "bytea")
private String firstName;
Above works when we set encrypt.key in postgres.conf file directly but out requirement is to have encrypt.key configurable from our spring properties file.
Things I tried.
AttributeConverter annotation with custom Converter class which only works with JPA, and LIKE operations are not supported.
I tried ContextEventListener where I executed SET SESSION query at application startup but that only works for few requests
Next I tried CustomTransactionManager extends JpaTransactionManager where I was doing following
#Override
protected void prepareSynchronization(DefaultTransactionStatus status,TransactionDefinition definition) {
super.prepareSynchronization(status, definition);
if (status.isNewTransaction()) {
final String query = "SET encrypt.key='" + encryptKey + "'";
entityManager.createNativeQuery(query).executeUpdate();
}
log.info("Encrypt Key : {}", entityManager.createNativeQuery("SElECT current_setting('encrypt.key')").getSingleResult());
}
}
Above does not work when I call normal JPA Repository methods and encrypt.key is not set as the CustomTransactionManager class in not called.
Any guidance in right direction would help me a lot
Since I created CustomTransactionManager extends JpaTransactionManager
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Primary;
import org.springframework.orm.jpa.JpaTransactionManager;
import org.springframework.stereotype.Component;
import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.support.DefaultTransactionStatus;
import javax.persistence.EntityManager;
#Component
#Slf4j
#Primary
#Qualifier(value = "transactionManager")
public class CustomTransactionManager extends JpaTransactionManager {
#Autowired
private EntityManager entityManager;
#Value("${database.encryption.key}")
private String encryptKey;
#Override
protected void prepareSynchronization(DefaultTransactionStatus status, TransactionDefinition definition) {
super.prepareSynchronization(status, definition);
if (status.isNewTransaction()) {
final String query = "SET SESSION encrypt.key='" + encryptKey + "'";
entityManager.createNativeQuery(query).executeUpdate();
}
}
}
Above was not getting called when I used normal JPA Repository methods.
For example,
public interface UserRepository extends JpaRepository<User, Long> {
Optional<User> findByFirstName(String firstName);
}
Adding #Transactional on Repository class did override framework logic where a shared transaction was getting created behind-the-scenes for all repository beans. This resulted in my CustomTransactionManager to be called even with repository methods.
I initially thought that adding Transactional annotation was overkill but found out that it gets created automatically at framework level as well so manually adding it had no additional footprint on its own but code/query you write inside CustomTransactionManager class will add required request footprint.
So I ended up adding #Transactional annotation on all repository classes whose domain(table) had encrypted columns.
For my use-case, this was the most flexible solution to have column level encryption on Azure postgres datbase service with Spring boot because we can not add custom environment variables there from Azure Portal, and directly adding to postgres.conf file also not possible due it being a SAAS service.

What are schemas for in Apache Beam?

I was reading the docs about SCHEMAS in Apache BEAM but i can not understand what its purpose is, how and why or in which cases should i need to use them. What is the difference between using schemas or using a class that extends the Serializable interface?
The docs has an example:
#DefaultSchema(JavaFieldSchema.class)
public class TransactionPojo {
public String bank;
public double purchaseAmount;
}
PCollection<TransactionPojos> transactionPojos = readTransactionsAsPojo();
But it doesn't explain how readTransactionsAsPojo function is built. I think there are a lot of missing explanation about this.
There are several reasons to use Beam Schema, some of them are below:
You won't need to specify a Coder for objects with schema;
If you have the objects with the same schema, but represented in a different way (like, JavaBean and Pojo in your example), then Beam Schema will allow to use the same Schema PTransforms for the PCollections of these objects;
With Schema-aware PCollections it's much easier to write joins since it will require much less code boilerplate;
To use BeamSQL over PCollection it will require you to have a Beam Schema. Like, you can read Avro files with a schema that will be automatically converted into Beam Schema and then you apply a Beam SQL transform over these Avro records.
Also, I'd recommend to watch these talk from Beam Summit 2019 about Schema-aware PCollections and Beam SQL.
Still there is NO answer as how readTransactionsAsPojo() has been implemented
PCollection<TransactionPojos> transactionPojos = readTransactionsAsPojo();
Keeping document abstract and not having complete code in repo, is hard to understand!!
A sample code which worked for me
package com.beam.test;
import com.beam.test.schema.Address;
import com.beam.test.schema.Purchase;
import org.apache.beam.sdk.Pipeline;
import org.apache.beam.sdk.io.TextIO;
import org.apache.beam.sdk.options.PipelineOptions;
import org.apache.beam.sdk.options.PipelineOptionsFactory;
import org.apache.beam.sdk.transforms.Create;
import org.apache.beam.sdk.transforms.DoFn;
import org.apache.beam.sdk.transforms.ParDo;
import org.apache.beam.sdk.values.PCollection;
import java.util.ArrayList;
import java.util.List;
public class SchemaExample {
public static void main(String[] args) {
PipelineOptions options= PipelineOptionsFactory.create();
Pipeline pipeline=Pipeline.create(options);
pipeline.apply("Create input:", TextIO.read().from("path\to\input\file.txt"))
.apply(ParDo.of(new ConvertToPurchase())).
apply(ParDo.of(new DoFn<Purchase, Void>() {
#ProcessElement
public void processElement(#Element Purchase purchase){
System.out.println(purchase.getUserId()+":"+purchase.getAddress().getHouseName());
}
}));
pipeline.run().waitUntilFinish();
}
static class ConvertToPurchase extends DoFn<String,Purchase>{
#ProcessElement
public void processElement(#Element String input,OutputReceiver<Purchase> outputReceiver){
String[] inputArr=input.split(",");
Purchase purchase=new Purchase(inputArr[0],new Address(inputArr[1],inputArr[2]));
outputReceiver.output(purchase);
}
}
}
package com.beam.test.schema;
import org.apache.beam.sdk.schemas.JavaBeanSchema;
import org.apache.beam.sdk.schemas.annotations.DefaultSchema;
import org.apache.beam.sdk.schemas.annotations.SchemaCreate;
#DefaultSchema(JavaBeanSchema.class)
public class Purchase {
private String userId;
private Address address;
public String getUserId(){
return userId;
}
public Address getAddress(){
return address;
}
#SchemaCreate
public Purchase(String userId, Address address){
this.userId=userId;
this.address=address;
}
}
package com.beam.test.schema;
import org.apache.beam.sdk.schemas.JavaBeanSchema;
import org.apache.beam.sdk.schemas.annotations.DefaultSchema;
import org.apache.beam.sdk.schemas.annotations.SchemaCreate;
#DefaultSchema(JavaBeanSchema.class)
public class Address {
private String houseName;
private String postalCode;
public String getHouseName(){
return houseName;
}
public String getPostalCode(){
return postalCode;
}
#SchemaCreate
public Address(String houseName,String postalCode){
this.houseName=houseName;
this.postalCode=postalCode;
}
}
My test file contains data in below format
user1,abc,1234
user2,def,3456

Wildfly throws "Unable to find a constructor that takes a String param or a valueOf() or fromString() method for javax.ws.rs.QueryParam" error

Im using wildfly 9.0 to deploy my war file. I have java LocalDateTime, Java Money types defined in my REST GET endpoints.
When i deploy my war file, i get following error[1]. Based on this answer [2] I have written "ParamConverterProvider" implementations for both types.
It was working fine( I haven't seen same issue again till now) and now i get same issue.
Any clue?
[1]
Caused by: java.lang.RuntimeException: Unable to find a constructor that takes a String param or a valueOf() or fromString() method for javax.ws.rs.QueryParam(\"totalMoneyVolumeForPeriod\") on public javax.ws.rs.core.Response com.test.rest.StockEndpoint.getItems(java.lang.Integer,java.lang.Integer,java.lang.String,java.lang.String,java.lang.Long,org.javamoney.moneta.Money,java.util.Set,java.lang.String) for basetype: org.javamoney.moneta.Money"}}}}
[2]
jaxrs could not find my custom (de)serializers for joda.money type
Sample code
package com.test;
import java.lang.annotation.Annotation;
import java.lang.reflect.Type;
import java.math.BigDecimal;
import javax.money.Monetary;
import javax.ws.rs.ext.ParamConverter;
import javax.ws.rs.ext.ParamConverterProvider;
import javax.ws.rs.ext.Provider;
import org.javamoney.moneta.Money;
#Provider
public class MoneyConverterProvider implements ParamConverterProvider {
private final MoneyConverter converter = new MoneyConverter();
#Override
public <T> ParamConverter<T> getConverter(Class<T> rawType, Type genericType, Annotation[] annotations) {
if (!rawType.equals(Money.class)) return null;
return (ParamConverter<T>) converter;
}
public class MoneyConverter implements ParamConverter<Money> {
public Money fromString(String value) {
if (value == null ||value.isEmpty()) return null; // change this for production
return Money.of(new BigDecimal(value), Monetary.getCurrency("AUD"));
}
public String toString(Money value) {
if (value == null) return "";
return value.toString(); // change this for production
}
}
}
Application claas
package com.test;
import javax.ws.rs.core.Application;
import com.test.autogen*;
import io.swagger.jaxrs.config.BeanConfig;
import java.util.HashSet;
import java.util.Set;
import javax.ws.rs.ApplicationPath;
#ApplicationPath("/rest")
public class RestApplication extends Application {
public RestApplication() {
BeanConfig beanConfig = new BeanConfig();
//beanConfig.setVersion("1.0");
beanConfig.setSchemes(new String[] { "http" });
beanConfig.setTitle("My API");
beanConfig.setBasePath("/rest");
beanConfig.setResourcePackage("com.test.autogen");
beanConfig.setScan(true);
}
#Override
public Set<Class<?>> getClasses() {
HashSet<Class<?>> set = new HashSet<Class<?>>();
set.add(EmailEndpoint.class);
set.add(StockEndpoint.class);
set.add(io.swagger.jaxrs.listing.ApiListingResource.class);
set.add(io.swagger.jaxrs.listing.SwaggerSerializers.class);
return set;
}
}
When you are using classpath scanning, JAX-RS components annotated with #Path or #Provider will get picked up and registered. There are a couple way to use classpath scanning. The most common way is to just have an empty Application class annotated with #ApplicationPath
#ApplicationPath("/api")
public class MyApplication extends Application {}
This is enough for a JAX-RS application to be loaded, and to have the application's classpath scanned to components to register.
But, per the specification, once we override any of the Set<Object> getSingletons or Set<Class> getClasses methods of the Application class, and return a non-empty set, this automatically disables classpath scanning, as it is assumed we want to register everything ourselves.
So in previous cases, you were probably just using classpath scanning. In this case, you need to explicitly add the provider to the set of classes in your getClasses method, since you overrode the method to add other component classes.

Getting a reference to a Jersey REST resource method from the URL

I'm doing some performance testing, and I want to be able to call a resource method without going through the network. I already have a framework for generating URLs, and I'd like to be able to reuse it.
For example, given the URL: www.example.com:8080/resource/method, I want to get a reference to the resource method that it calls, so that I can run it without making a network-level HTTP request. I.e., in the example below, I want to use the URL "www.frimastudio.com:8080/time" to get a reference to the method getServerTime() that I can then call directly.
Does Jersey (or something else?) provide a way to do this, or do I have to import the specific Resource class I want to call, instantiate it, etc.? Thanks in advance!
Yes jersey is RESTful API that allow routes configuration (only with annotations)
Example :
package com.frimastudio.webservice.controller.route;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import org.joda.time.DateTime;
import com.frimastudio.webservice.controller.representation.Time;
#Path("/time")
#Produces(MediaType.APPLICATION_JSON)
public class TimeResource
{
public TimeResource()
{
}
#GET
public Time getServerDate()
{
return new Time(new DateTime());
}
}
with Time being a Jackson representation :
package com.frimastudio.webservice.controller.representation;
import org.hibernate.validator.constraints.NotEmpty;
import org.joda.time.DateTime;
import com.fasterxml.jackson.annotation.JsonProperty;
public class Time
{
#NotEmpty
#JsonProperty
private String date;
public Time()
{
// Jackson deserialization
}
public Time(String date)
{
super();
this.date = date;
}
public Time(DateTime date)
{
super();
this.date = date.toString();
}
}
This doesn't seem to be possible, based on looking at the Jersey code. The lookup is performed by HttpMethodRule.Matcher, which is a private class used only to implement HttpMethodRule.accept.
Seems to me everything in accept up to if (s == MatchStatus.MATCH) { could be pulled into its own method and exposed to the user.

What is the difference between #BeforeClass and Spring #TestExecutionListener beforeTestClass()

What is the difference between using JUnit #BeforeClass and the Spring #TestExecutionListener beforeTestClass(TestContext testContext) "hook"? If there is a difference, which one to use under which circumstances?
Maven Dependencies:
spring-core:3.0.6.RELEASE
spring-context:3.0.6.RELEASE
spring-test:3.0.6.RELEASE
spring-data-commons-core:1.2.0.M1
spring-data-mongodb:1.0.0.M4
mongo-java-driver:2.7.3
junit:4.9
cglib:2.2
Using JUnit #BeforeClass annotation:
import org.junit.BeforeClass;
import org.junit.Test;
import org.junit.Assert;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.AbstractJUnit4SpringContextTests;
#ContextConfiguration(locations = { "classpath:test-config.xml" })
public class TestNothing extends AbstractJUnit4SpringContextTests {
#Autowired
PersonRepository repo;
#BeforeClass
public static void runBefore() {
System.out.println("#BeforeClass: set up.");
}
#Test
public void testInit() {
Assert.assertTrue(repo.findAll().size() == 0 );
}
}
=> #BeforeClass: set up.
=> Process finished with exit code 0
Using the Spring hook:
(1) Override beforeTestClass(TextContext testContext):
import org.springframework.test.context.TestContext;
import org.springframework.test.context.support.AbstractTestExecutionListener;
public class BeforeClassHook extends AbstractTestExecutionListener {
public BeforeClassHook() { }
#Override
public void beforeTestClass(TestContext testContext) {
System.out.println("BeforeClassHook.beforeTestClass(): set up.");
}
}
(2) Use #TestExecutionListeners annotation:
import org.springframework.test.context.TestExecutionListeners;
// other imports are the same
#ContextConfiguration(locations = { "classpath:test-config.xml" })
#TestExecutionListeners(BeforeClassHook.class)
public class TestNothing extends AbstractJUnit4SpringContextTests {
#Autowired
PersonRepository repo;
#Test
public void testInit() {
Assert.assertTrue(repo.findAll().size() == 0 );
}
}
=> BeforeClassHook.beforeTestClass(): set up.
=> Process finished with exit code 0
TestExecutionListeners are a way to externalize reusable code that instruments your tests.
As such, if you implement a TestExecutionListener you can reuse it across test class hierarchies and potentially across projects, depending on your needs.
On the flip side, a #BeforeClass method can naturally only be used within a single test class hierarchy.
Note, however, that JUnit also supports Rules: if you implement org.junit.rules.TestRule you can declare it as a #ClassRule to achieve the same thing... with the added benefit that a JUnit Rule can be reused just like a Spring TestExecutionListener.
So it really depends on your use case. If you only need to use the "before class" functionality in a single test class or a single test class hierarchy, then you'd be better off going the simple route of just implementing a #BeforeClass method. However, if you foresee that you will need the "before class" functionality in different test class hierarchies or across projects, you should consider implementing a custom TestExecutionListener or JUnit Rule.
The benefit of a Spring TestExecutionListener over a JUnit Rule is that a TestExecutionListener has access to the TestContext and therefore access to the Spring ApplicationContext which a JUnit Rule would not have access to. Furthermore, a TestExecutionListener can be automatically discovered and ordered.
Related Resources:
SPR-8854
Regards,
Sam (author of the Spring TestContext Framework)
The first solution with #BeforeClass doesn't have application context loaded. I did exteneded AbstractJUnit4SpringContextTests and defined #ContextConfiguration.
I think listner is the only way to get context loaded before #beforeclass method. Or even better extending SpringJUnit4ClassRunner class as mentioned here