Is it appropriate to have EntityManager in a bundle class? - database

I want to know if it is efficient in JSF to define EntityManager and TypedQuery in a bundle class that is supposed to read messages from database?
What if I create an instance of a #Stateless bean and use its functions that return query results inside the bundle class?
UPDATE: Included some code:
protected class DBControl extends Control{
#Override
public ResourceBundle newBundle
(String baseName, Locale locale, String format, ClassLoader loader, boolean reload)
throws IllegalAccessException, InstantiationException, IOException
{
return new ArticleResources(locale);
}
protected class ArticleResources extends ListResourceBundle{
private Locale locale;
public ArticleResources (Locale locale){
this.locale = locale;
}
String language = locale.getLanguage();
#Override
protected Object[][] getContents(){
TypedQuery<ArticleLcl> query = em.createNamedQuery("ArticleLcl.findForLocale", ArticleLcl.class);
query.setParameter("lang", language);
List<ArticleLcl> articles = query.getResultList();
Object[][] allArticles = new Object[articles.size()][3];
int i = 0;
for(Iterator<ArticleLcl> it = articles.iterator(); it.hasNext();){
ArticleLcl article = it.next();
allArticles[i] = new Object[]{article.getArticleId().getArticleId().toString(),article.getArticleTitle()};
messages.put(article.getArticleId().getArticleId().toString(),article.getArticleTitle());
i++;
}
return allArticles;
}
}
By the way this code does not work and my entity manager is null. But I wonder am I doing the right thing?

Related

Apache Camel Generic Router - pass exchange properties to static class methods

I am trying to create a generic router whose processor and other attributes are populated from a static class. Here is sample code.
public class GenericRouter extends RouteBuilder( {
#Override
public void configure() throws Exception {
from("direct:generic-route")
.process(Util.getProcesss(“${exchangeProperty[processKey]"))
.ToD(Util.getUrl(“${exchangeProperty[urlKey]"));
}
}
Public class Util{
Map<String,Object> routerResources;
static {
//load routerResources
}
public static Processor getProcessor(String processorKey){
return (Processor)routerResources.get(processorKey);
}
public static Processor getUrl(String urlKey){
return (String)routerResources.get(urlKey);
}
}
The generic router is expected to post a rest call. the properties "urlKey" and "processorUrl" are already available in exchange. I finding it difficult to pass exchange properties to static Util class methods.
If you want to access properties of an exchange in plain java you can use .process or .exchange. If you need to access body or headers you can use e.getMessage().getBody() and e.getMessage().getHeader()
from("direct:generic-route")
.process( e -> {
String processKey = e.getProperty("processKey", String.class);
Processor processor = Util.getProcessor(processKey);
processor.process(e);
})
.setProperty("targetURL").exchange( e -> {
String urlKey = e.getProperty("urlKey", String.class);
return Util.getUrl(urlKey);
})
.toD("${exchangeProperty.targetURL}");
Also make sure you fix the return type of this method:
public static Processor getUrl(String urlKey){
return (String)routerResources.get(urlKey);
}
As a side note, you can actually use map stored in body, header or property through simple language.
public class ExampleTest extends CamelTestSupport {
#Test
public void example(){
template.sendBodyAndHeader("direct:example", null, "urlKey", "urlA");
}
#Override
protected RoutesBuilder createRouteBuilder() throws Exception {
return new RouteBuilder() {
#Override
public void configure() throws Exception {
Map<String, String> urlMap = new HashMap<>();
urlMap.put("urlA", "direct:pointA");
urlMap.put("urlB", "direct:pointB");
from("direct:example")
.setProperty("urlMap").constant(urlMap)
.log("url: ${exchangeProperty.urlMap['${headers.urlKey}']}");
}
};
}
}

Spring-boot & multiple database connections: autowire service does not work

I'm writing an Spring-boot application that needs to connect to at least 2 databases.
I have 1 project per database in order to define their domains, 1 project per database in order to define their services and 1 Vaadin project for the UI.
- a business domain entity sample
#Entity
#Table(name="T_PARAMETER")
public class Parameter extends BaseIdEntity implements Serializable {
#Column(name="par_cls")
#NotNull
private String parameterClass;
#Column(name="par_cd")
#NotNull
private String parameterCode;
#Column(name="par_lan")
#NotNull
private String language;
#Column(name="par_sht_val")
#NotNull
private String parameterValueShort;
#Column(name="par_lng_val")
#NotNull
private String parameterValueLong;
- a authentication domain entity sample
#Entity
#Table(name="t_user", schema="authenticate")
public class User extends BaseIdEntity implements Serializable {
#Id
#Column(name="user_cd")
private String userCode;
#Column(name="pwd")
#NotNull
private String password;
#Column(name="new_pwd_req")
#NotNull
private boolean passwordRequired;
#Column(name="acc_lck")
#NotNull
private boolean accountLocked;
There are repositories onto these 2 entities beans, they just extends the JpaRepository as hereunder:
public interface ParameterRepository extends JpaRepository<Parameter,Integer>{}
the services are defined as hereunder:
#Service
#Transactional(transactionManager="authenticateTransactionManager")
public class ServiceParameterImpl implements ServiceParameter {
private final static Logger log = LoggerFactory.getLogger(ServiceParameterImpl.class);
#Autowired
private ParameterRepository parameterRepository;
#Override
#Transactional(readOnly=true,transactionManager="authenticateTransactionManager")
public List<Parameter> findParameterHeader(String filter) {
.../...
The client application as:
#SpringBootApplication
#Configuration
#EnableAutoConfiguration(exclude = { DataSourceAutoConfiguration.class
, HibernateJpaAutoConfiguration.class
, DataSourceTransactionManagerAutoConfiguration.class })
#ComponentScan(
basePackages= {
"org.associative.ui"
,"org.associative.service"
})
#Import({AssociativityConfiguration.class, AuthenticateConfiguration.class})
public class Application {
private final static Logger log = LoggerFactory.getLogger(Application.class);
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
and configurations:
#Configuration
#EnableTransactionManagement
#EntityScan(basePackages= "org.associative.domain.associativity")
#EnableJpaRepositories(
basePackages = "org.associative.domain.associativity.repository"
, entityManagerFactoryRef = "associativityEntityManager"
, transactionManagerRef = "associativityTransactionManager"
)
#ConfigurationProperties(prefix = "db.associativity")
public class AssociativityConfiguration {
private final static Logger log = LoggerFactory.getLogger(AssociativityConfiguration.class);
#Autowired
private Environment env;
private final static String ASSOCIATIVITY_DRIVER_CLASS_NAME = "db.associativity.classname";
private final static String ASSOCIATIVITY_URL = "db.associativity.connectionUrl";
private final static String ASSOCIATIVITY_USERNAME = "db.associativity.username";
private final static String ASSOCIATIVITY_PASSWORD = "db.associativity.password";
private final static String HIBERNATE_DIALECT = "hibernate.dialect";
#Bean(name = "associativityDataSource")
public DataSource datasource() {
DataSource dataSource = DataSourceBuilder.create()
.driverClassName(env.getProperty(ASSOCIATIVITY_DRIVER_CLASS_NAME))
.url(env.getProperty(ASSOCIATIVITY_URL))
.username(env.getProperty(ASSOCIATIVITY_USERNAME))
.password(env.getProperty(ASSOCIATIVITY_PASSWORD)).build();
if (log.isTraceEnabled())
log.trace(String.format("associativityConfiguration datasource:%s", dataSource.toString()));
return dataSource;
}
#Bean(name = "associativityEntityManager")
#PersistenceContext(unitName = "associativity")
public LocalContainerEntityManagerFactoryBean entityManagerFactory(
EntityManagerFactoryBuilder builder,
#Qualifier("associativityDataSource") DataSource dataSource) {
Map<String, Object> jpaProperties = new HashMap<>();
jpaProperties.put(HIBERNATE_DIALECT, env.getProperty(HIBERNATE_DIALECT));
LocalContainerEntityManagerFactoryBean em = builder.dataSource(dataSource)
.packages("org.associative.domain.authenticate").persistenceUnit("pu_associativity").properties(jpaProperties)
.build();
em.setJpaPropertyMap(jpaProperties);
HibernateJpaVendorAdapter adapter = new HibernateJpaVendorAdapter();
em.setJpaVendorAdapter(adapter); // not mandatory definition
return em;
}
#Bean(name = "associativityTransactionManager")
public PlatformTransactionManager associativityTransactionManager(
#Qualifier("associativityEntityManager") EntityManagerFactory entityManagerFactory) {
JpaTransactionManager transactionManager = new JpaTransactionManager();
transactionManager.setEntityManagerFactory(entityManagerFactory);
return transactionManager;
}
}
and
#Configuration
#EnableTransactionManagement
#EntityScan(basePackages= "org.associative.domain.authenticate")
#EnableJpaRepositories(
basePackages = "org.associative.domain.authenticate.repository"
, entityManagerFactoryRef = "authenticateEntityManager"
, transactionManagerRef = "authenticateTransactionManager"
)
#ConfigurationProperties(prefix="db.authenticate")
public class AuthenticateConfiguration {
private final static Logger log = LoggerFactory.getLogger(AuthenticateConfiguration.class);
#Autowired
private Environment env;
private final static String AUTHENTICATE_DRIVER_CLASS_NAME= "db.authenticate.classname";
private final static String AUTHENTICATE_URL = "db.authenticate.connectionUrl";
private final static String AUTHENTICATE_USERNAME = "db.authenticate.username";
private final static String AUTHENTICATE_PASSWORD = "db.authenticate.password";
private final static String HIBERNATE_DIALECT = "hibernate.dialect";
#Primary
#Bean(name = "authenticateDataSource")
public DataSource datasource() {
DataSource dataSource = DataSourceBuilder.create()
.driverClassName(env.getProperty(AUTHENTICATE_DRIVER_CLASS_NAME))
.url(env.getProperty(AUTHENTICATE_URL))
.username(env.getProperty(AUTHENTICATE_USERNAME))
.password(env.getProperty(AUTHENTICATE_PASSWORD))
.build();
if ( log.isTraceEnabled()) log.trace(String.format("authenticateDataSource datasource:%s", dataSource.toString()));
return dataSource;
}
#Primary
#Bean(name="authenticateEntityManager")
#PersistenceContext(unitName = "authenticate")
//https://raymondhlee.wordpress.com/tag/enablejparepositories/
public LocalContainerEntityManagerFactoryBean entityManagerFactory(
EntityManagerFactoryBuilder builder, #Qualifier("authenticateDataSource")DataSource dataSource) {
Map<String,Object> jpaProperties = new HashMap<>();
jpaProperties.put(HIBERNATE_DIALECT, env.getProperty(HIBERNATE_DIALECT));
LocalContainerEntityManagerFactoryBean em = builder
.dataSource(dataSource)
.packages("org.associative.domain.authenticate")
.persistenceUnit("pu_authenticate")
.properties(jpaProperties)
.build();
em.setJpaPropertyMap(jpaProperties);
HibernateJpaVendorAdapter adapter = new HibernateJpaVendorAdapter();
em.setJpaVendorAdapter(adapter); // not mandatory definition
return em;
}
#Primary
#Bean(name="authenticateTransactionManager")
public PlatformTransactionManager authenticateTransactionManager(
#Qualifier("authenticateEntityManager")EntityManagerFactory entityManagerFactory){
JpaTransactionManager transactionManager = new JpaTransactionManager();
transactionManager.setEntityManagerFactory(entityManagerFactory);
return transactionManager;
}
}
I'm facing an issue when a service is built by using autowiring in the construction of my client interface:
#SpringUI
public class ParameterListView extends CssLayout implements Serializable {
private final static Logger log = LoggerFactory.getLogger(ParameterListView.class);
#Autowired
private ParameterController controller;
#PostConstruct
private void initView() {
if ( log.isTraceEnabled() ) log.trace(String.format("initView:%s", "no param"));
Grid<Parameter> grid = new Grid<>();
this.addComponent(grid);
grid.setItems(controller.getParameterHeader(""));
grid.addColumn(Parameter::getParameterClass);
grid.addColumn(Parameter::getParameterValueShort);
grid.addColumn(Parameter::getParameterValueLong);
2017-12-01 14:20:07.151 ERROR o.s.b.SpringApplication Application startup failed
org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'parameterControllerImpl': Unsatisfied
dependency expressed through field 'serviceParameter'; nested
exception is
org.springframework.beans.factory.UnsatisfiedDependencyException:
Error creating bean with name 'serviceParameterImpl': Unsatisfied
dependency expressed through field 'parameterRepository'; nested
exception is org.springframework.beans.factory.BeanCreationException:
Error creating bean with name 'parameterRepository': Invocation of
init method failed; nested exception is
java.lang.IllegalArgumentException: Not a managed type: class
org.associative.domain.associativity.Parameter
I already spent a lot of time in order to solve the multiple database connections because I was thinking this issue comes from a definition problem but I'm not sure now.
So, what should I look to in order to solve this.
Thank you very much.
The last line of your stack trace is a clue: Not a managed type: class org.associative.domain.associativity.Parameter. Hibernate doesn't know about your Parameter entity.
In the LocalContainerEntityManagerFactoryBean you set packages to scan to org.associative.domain.authenticate. Your Parameter entity is not under this package.
This should fix the problem:
.packages("org.associative.domain.authenticate", "org.associative.domain.associativity")

MappingException: Ambiguous field mapping detected

Using Spring boot 1.5.6.RELEASE.
I have the following mongo document base class:
#Document(collection="validation_commercial")
public abstract class Tier {
#Id
private String id;
#DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME)
private Date created;
#Field("tran")
private Tran tran;
public Tier() {
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public Date getCreated() {
return created;
}
public void setCreated(Date created) {
this.created = created;
}
public Tran getTran() {
return tran;
}
public void setTran(Tran tran) {
this.tran = tran;
}
}
which is then extended:
public class Tier1 extends Tier {
#Field("tier1")
private Tier1Programs tier1;
public Tier1() {
this.tier1 = new Tier1Programs();
}
public Tier1Programs getTier1() {
return tier1;
}
public void setTier1(Tier1Programs tier1) {
this.tier1 = tier1;
}
}
which in turn is extended:
public class Tier2 extends Tier1 {
#Field("tier2")
private Tier2Programs tier2;
public Tier2() {
this.tier2 = new Tier2Programs();
}
public Tier2Programs getTier2() {
return tier2;
}
public void setTier2(Tier2Programs tier2) {
this.tier2 = tier2;
}
}
There is a Tier1 Supervisor (Spring Boot Application) that uses the Tier1 class within the MongoRepository interface:
public interface Tier1Repository extends MongoRepository<Tier1,String>{}
for retrieving and saving - no issue.
I then have a Tier2 Supervisor (Spring Boot Application) that uses a Tier1 Repository (for retrieving the Tier1 document and a Tier2 Repository for saving the Tier2 document:
#Repository("tier1Repository")
public interface Tier1Repository extends MongoRepository<Tier1,String>{}
#Repository("tier2Repository")
public interface Tier2Repository extends MongoRepository<Tier2,String>{}
My service is:
#Service
public class TierService {
#Qualifier("tier1Repository")
#Autowired
private final Tier1Repository tier1Repository;
#Qualifier("tier2Repository")
#Autowired
private final Tier2Repository tier2Repository;
public TierService(#Qualifier("tier1Repository") Tier1Repository tier1Repository, #Qualifier("tier2Repository") Tier2Repository tier2Repository) {
this.tier1Repository = tier1Repository;
this.tier2Repository = tier2Repository;
}
public Tier1 findOne(String id) {
return tier1Repository.findOne(id);
}
public void SaveTier(Tier2 tier) {
tier2Repository.save(tier);
}
public Tier1Repository getTier1Repository() {
return tier1Repository;
}
public Tier2Repository getTier2Repository() {
return tier2Repository;
}
}
and finally the app:
#EnableAutoConfiguration(exclude = {DataSourceAutoConfiguration.class,
DataSourceTransactionManagerAutoConfiguration.class, JdbcTemplateAutoConfiguration.class})
#Configuration
#ComponentScan(basePackages = {"com.k12commercial.tier2supervisor"})
#ImportResource("classpath:application-context.xml")
public class Application implements CommandLineRunner {
#Autowired
private IReceiver raBidNetPriceReceiver;
#Autowired
private UdyDataSourceFactory udyDSRegistry;
public static void main(String[] args) throws InterruptedException {
try {
SpringApplication.run(Application.class, args);
} catch (Exception e) {
e.printStackTrace();
}
}
#Override
public void run(String... args) throws Exception {
raBidNetPriceReceiver.processTierMessages();
exit(0);
}
}
When I run the Tier2 Supervisor from the command line I get the following error:
org.springframework.beans.factory.UnsatisfiedDependencyException:
Error creating bean with name 'tierService' defined in URL
[jar:file:/opt/java-commandline/tier2supervisor-1.0.jar!/BOOT-INF/classes!/com/k12commercial/tier2supervisor/service/TierService.class]: Unsatisfied dependency expressed through constructor parameter 1; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'tier2Repository': Invocation of init method failed; nested exception is org.springframework.data.mapping.model.MappingException: Ambiguous field mapping detected! Both private final java.lang.reflect.Type org.springframework.data.util.TypeDiscoverer.type and private final java.lang.Class org.springframework.data.util.ClassTypeInformation.type map to the same field name type! Disambiguate using #Field annotation!
I am not sure if the issue is Tier2 extending Tier1 (did try putting #Document tag above Tier1 and Tier2 with no change). I think I have marked the relevant fields so don't understand the need to disambiguate. I thought the issue was having 2 repositories (Spring Boot not knowing which one to DI) so removed the Tier1Repository - didn't work. Tried better qualifying the repositories but still got the same error. I made Tier1 and Tier2 #Transient and that got rid of the message but also removed the tier1 section in the mongo document - so wrong correction.
Thinking it is an annotation fix but not seeing it...
Please advise - thank you.
Sorry for the delay (I got pulled away to work on something else) and thank you to those who responded.
The issue was I had a MongoTemplate in my Tier level programs e.g.Tier2Programs (sub library) which Spring Boot was trying to autowire.
By moving the Mongo (CRUD) requirements to the supervisor level (I also replaced the Repositories with one MongoTemplate to simplify) I removed the ambiguity. (I also removed the Service class).
The code is contained with the RaBidNetReciever class
#Component
public class RaBidNetPriceReceiver extends BaseReceiver implements IReceiver, ApplicationEventPublisherAware {
private static final Logger LOGGER = LoggerFactory.getLogger(RaBidNetPriceReceiver.class);
private final RabbitTemplate raBidNetPriceRabbitTemplate;
public RaBidNetPriceReceiver(MongoTemplate mongoTemplate, RabbitTemplate raBidNetPriceRabbitTemplate) {
super(mongoTemplate);
this.raBidNetPriceRabbitTemplate = raBidNetPriceRabbitTemplate;
}
#Transactional
public void processTierMessages() {
try {
while (true) {
gson = getGsonBuilder().create();
byte[] body = (byte[]) raBidNetPriceRabbitTemplate.receiveAndConvert();
if (body == null) {
setFinished(true);
break;
}
tier1Message = gson.fromJson(new String(body), Tier1Message.class);
// document a 'Tier1' type so retrieve Tier1 first...
Tier1 tier1 = mongoTemplate.findById(tier1Message.getId(), Tier1.class);
Tier2Message tier2Message = new Tier2Message(tier1Message.getTran(), tier1Message.getId());
Tier2Process tierProcess = getTierProcess(tier2Message.getTran().getK12ArchitectureId());
Tier2 tier2 = new Tier2();
tier2.setId(tier1.getId());
tier2.setTier1Programs(tier1.getTier1Programs());
tier2.setCreated(tier1.getCreated());
tier2.setTran(tier1.getTran());
tierProcess.setTier(tier2);
tier2 = tier2.getTier2Programs().getRaBidNetPriceProgram().process(tierProcess);
mongoTemplate.save(tier2);
if (tier2.getTier2Programs().getRaBidNetPriceProgram().isFinished()) {
// publish event
publisher.publishEvent(new ProgramEvent(this, "FINISHED", tier2Message));
}
}
} catch (Exception e) {
LOGGER.error("id: " + tier1Message.getId() + " " + e.getMessage());
}
}
#Override
public void setApplicationEventPublisher(ApplicationEventPublisher applicationEventPublisher) {
this.publisher = applicationEventPublisher;
}
}
Thank you,

Does Flink SQL support Java Map types?

I'm trying to access a key from a map using Flink's SQL API. It fails with the error Exception in thread "main" org.apache.flink.table.api.TableException: Type is not supported: ANY
Please advise how i can fix it.
Here is my event class
public class EventHolder {
private Map<String,String> event;
public Map<String, String> getEvent() {
return event;
}
public void setEvent(Map<String, String> event) {
this.event = event;
}
}
Here is the main class which submits the flink job
public class MapTableSource {
public static void main(String[] args) throws Exception {
final StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();
DataStream<EventHolder> mapEventStream = env.fromCollection(getMaps());
// register a table and use SQL
StreamTableEnvironment tableEnv = TableEnvironment.getTableEnvironment(env);
tableEnv.registerDataStream("mapEvent", mapEventStream);
//tableEnv.registerFunction("orderSizeType", new OrderSizeType());
Table alerts = tableEnv.sql(
"select event['key'] from mapEvent ");
DataStream<String> alertStream = tableEnv.toAppendStream(alerts, String.class);
alertStream.filter(new FilterFunction<String>() {
private static final long serialVersionUID = -2438621539037257735L;
#Override
public boolean filter(String value) throws Exception {
System.out.println("Key value is:"+value);
return value!=null;
}
});
env.execute("map-tablsource-job");
}
private static List<EventHolder> getMaps(){
List<EventHolder> list = new ArrayList<>();
for(int i=0;i<5;i++){
EventHolder holder = new EventHolder();
Map<String,String> map = new HashMap<>();
map.put("key", "value");
holder.setEvent(map);
list.add(holder);
}
return list;
}
}
When I run it I'm getting the exception
Exception in thread "main" org.apache.flink.table.api.TableException: Type is not supported: ANY
at org.apache.flink.table.api.TableException$.apply(exceptions.scala:53)
at org.apache.flink.table.calcite.FlinkTypeFactory$.toTypeInfo(FlinkTypeFactory.scala:341)
at org.apache.flink.table.plan.logical.LogicalRelNode$$anonfun$12.apply(operators.scala:530)
at org.apache.flink.table.plan.logical.LogicalRelNode$$anonfun$12.apply(operators.scala:529)
at scala.collection.TraversableLike$$anonfun$map$1.apply(TraversableLike.scala:245)
at scala.collection.TraversableLike$$anonfun$map$1.apply(TraversableLike.scala:245)
at scala.collection.Iterator$class.foreach(Iterator.scala:742)
at scala.collection.AbstractIterator.foreach(Iterator.scala:1194)
at scala.collection.IterableLike$class.foreach(IterableLike.scala:72)
at scala.collection.AbstractIterable.foreach(Iterable.scala:54)
at scala.collection.TraversableLike$class.map(TraversableLike.scala:245)
at scala.collection.AbstractTraversable.map(Traversable.scala:104)
at org.apache.flink.table.plan.logical.LogicalRelNode.<init>(operators.scala:529)
at org.apache.flink.table.api.TableEnvironment.sql(TableEnvironment.scala:503)
at com.c.p.flink.MapTableSource.main(MapTableSource.java:25)
I'm using flink 1.3.1
I think the problem lies in fromCollection. Flink is not able to extract the needed type information because of Java limitations (i.e. type erasure). Therefore you map is treated as black box with SQL ANY type. You can verify the types of your table by using tableEnv.scan("mapEvent").printSchema(). You can specify the type information in fromCollection with Types.MAP(Types.STRING, Types.STRING).
I solved a similar issue with the following:
//Should probably make MapVal more generic, but works for this example
public class MapVal extends ScalarFunction {
public String eval(Map<String, String> obj, String key) {
return obj.get(key);
}
}
public class Car {
private String make;
private String model;
private int year;
private Map<String, String> attributes;
//getters/setters...
}
//After registering Stream and TableEnv etc
tableEnv.registerFunction("mapval", new MapVal());
Table cars = tableEnv
.scan("Cars")
.select("make, model, year, attributes.mapval('name')");

Configuration of custom Log4j appender doesn't work

I have created a custom appender (will be used for Linux). For creating of this appender I used this article How write custom log4j appender
public class SolrAppender extends AppenderSkeleton {
private String path = null;
public void setPath(String path) { this.path = path; }
public String getPath() { return this.path; }
#Override
public boolean requiresLayout() {
return true;
}
#Override
public void close() {
}
#Override
public void activateOptions() {
super.activateOptions();
}
#Override
public synchronized void append(LoggingEvent event) {
SolrServer server = new HttpSolrServer(path);
SolrInputDocument document = new SolrInputDocument();
//some logic
UpdateResponse response = server.add(document);
server.commit();
}
Configuration of this appender is
# Solr appender
log4j.appender.SOLR = ricardo.solr.appender.QueryParser.SolrAppender
log4j.appender.SOLR.layout = org.apache.log4j.SimpleLayout
log4j.appender.SOLR.path = http://XX.XXX.XX.XX:8985/application/core
Appender works correct if path is hardcoded. Why path is not set via configuration?
From what I've seen so far, the name of a property of an appender, in the configuration, should start with an upper case character, so 'Path' instead of 'path', so you should use:
log4j.appender.SOLR.Path = http://XX.XXX.XX.XX:8985/application/core
Not sure why it's not the case for 'layout', though.

Resources