Elasticsearch index create on plugin initialization - java

I'm experimenting with elasticsearch plugins creation and I'm trying to create an index (if missing) on plugin startup.
I wanted to ask what is the best place to add the code snippet for code creation? I have added it at an injected binding with Client as constructor parameter but i get the following error:
no known master node, scheduling a retry [2015-05-26
12:03:27,289][ERROR][bootstrap ] {1.4.1}:
Initialization Failed ... 1) UncategorizedExecutionException[Failed
execution]
ExecutionException[java.lang.NullPointerException]
NullPointerException
My guess is that Client is not ready yet to handle index creation requests, my code snippet is the following:
public class IndexCreator {
private final String indexName;
private final ESLogger LOG;
#Inject
public IndexCreator(Settings settings, Client client) {
this.LOG = Loggers.getLogger(getClass(), settings);
this.indexName = settings.get("metis.index.name", ".metis");
String indexName = ".metis-registry";
IndicesExistsResponse resp = client.admin().indices().prepareExists(indexName).get();
if (!resp.isExists()) {
client.admin().indices().prepareCreate(indexName).get();
}
} }
And I add this as binding to my module
public class MyModule extends AbstractModule {
private final Settings settings;
public MyModule(Settings settings) {
this.settings = Preconditions.checkNotNull(settings);
}
#Override
protected void configure() {
bind(IndexCreator.class).asEagerSingleton();
} }
But it produces the over-mentioned error, any ideas? related post on groups here

Related

How to configure multiple couchbase data source using springboot-data-couchbase?

I am trying configuring multiple couchbase data source using springboot-data-couchbase.
This is a way I tried to attach two couchbase sources with 2 repositories.
#Configuration
#EnableCouchbaseRepositories("com.xyz.abc")
public class AbcDatasource extends AbstractCouchbaseConfiguration {
#Override
protected List<String> getBootstrapHosts() {
return Collections.singletonList("ip_address_of_couchbase");
}
//bucket_name
#Override
protected String getBucketName() {
return "bucket_name";
}
//password
#Override
protected String getBucketPassword() {
return "user_password";
}
#Override
#Bean(destroyMethod = "disconnect", name = "COUCHBASE_CLUSTER_2")
public Cluster couchbaseCluster() throws Exception {
return CouchbaseCluster.create(couchbaseEnvironment(), "ip_address_of_couchbase");
}
#Bean( name = "BUCKET2")
public Bucket bucket2() throws Exception {
return this.couchbaseCluster().openBucket("bucket2", "somepassword");
}
#Bean( name = "BUCKET2_TEMPLATE")
public CouchbaseTemplate newTemplateForBucket2() throws Exception {
CouchbaseTemplate template = new CouchbaseTemplate(
couchbaseClusterInfo(), //reuse the default bean
bucket2(), //the bucket is non-default
mappingCouchbaseConverter(), translationService()
);
template.setDefaultConsistency(getDefaultConsistency());
return template;
}
#Override
public void configureRepositoryOperationsMapping(RepositoryOperationsMapping baseMapping) {
baseMapping
.mapEntity(SomeDAOUsedInSomeRepository.class, newTemplateForBucket2());
}
}
similarly:
#Configuration
#EnableCouchbaseRepositories("com.xyz.mln")
public class MlnDatasource extends AbstractCouchbaseConfiguration {...}
Now the problem is there is no straight forward way to specify namespace based datasource by attaching different beans to these configurations like in springdata-jpa as springdata-jpa support this feature do using entity-manager-factory-ref and transaction-manager-ref.
Due to which only one configuration is being picked whoever comes first.
Any suggestion is greatly appreciated.
Related question: Use Spring Data Couchbase to connect to different Couchbase clusters
#anshul you are almost there.
Make one of the Data Source as #primary which will be used as by default bucket.
Wherever you want to use the other bucket .Just use specific bean in your service class with the qualifier below is the example:
#Qualifier(value = "BUCKET1_TEMPLATE")
#Autowired
CouchbaseTemplate couchbaseTemplate;
Now you can use this template to perform all couch related operations on the desired bucket.

Mapping Openfire Custom plugin with aSmack Client

I'm a newbie to XMPP so forgive me if this question sounds silly. I want to create a custom plugin and map it with my aSmack client on Android. I'm trying to apply my knowledge of Web Services but I'm not winning. So please guide my thinking toward the best approach, an example will be really helpful. Thanx in advance.
There are many types of plugins, let's talk in general pourpose.
Igniterealtime Plugin guide
You want to define a brand new IQ Stanza to manage an UserCustomParam.
Let's say:
<iq from="user1#myserver" to="myserver" type="get">
<usercustomparam xmls:"com.records.iq" retrive="favouritecolor">
</iq>
What you have to:
step 1:
define a plugin (class that implemements Plugin)
that adds a new handler
MyCustomHandler colorshandler;
IQRouter iqRouter = XMPPServer.getInstance().getIQRouter();
iqRouter.addHandler(colorshandler);
Step2: implements MyCustomHandler as you need (read on database, write on database, read server side and so on).
public class MyCustomHandler extends IQHandler {
public static final String NAMESPACE_TICKET_IQ = "com.records.iq";
public static final String TAG_TICKET_IQ = "usercustomparam ";
Now your server it's ready to manage your custom IQ request.
Time to go client side:
Step3: register to your ProviderManager an IQProvider
ProviderManager.addIQProvider("usercustomparam ","com.records.iq", new IQUserCustomParamProvider());
Step4: implements your IQUserCustomParamProvider as you need
public class IQUserCustomParamProvider extends IQProvider<IQUserCustomParam>
into Provider you'll parse the incoming IQ from server and you'll create a IQUserCustomParam with an instance param like
String favouriteColor
Step5: you need to implement IQUserCustomParam
public class IQUserCustomParam extends IQ
private final static String childElementName = "usercustomparam";
private final static String childElementNamespace = "com.records.iq";
public IQUserCustomParam (String color)
{
this(childElementName , childElementNamespace );
this.setType(IQ.Type.result);
this.setFavouriteColor(color);
}
Step 6: now set up it's completed, but you haven't defined yet when to accept IQUserCustomParam when it comes from server. So you need a StanzaFilter
public class IQUserCustomParamFilter implements StanzaFilter
Step 7: and you haven't defined yet what to do with IQUserCustomParam when it comes from server. So you need a StanzaListner
public class IQUserCustomParamListner implements StanzaListener
Step 8: finally you'll have to register the combo filter/listner on your connection:
AbstractXMPPConnection connection = ...;
connection.addAsyncStanzaListener(new PersonalConfigListner(this), new IQMUCConfigTicketFIlter();
if that helped, please don't forget to accept the answer!
This is a sample of plugin implementation:
First, you should implement the Plugin interface:
public class MotDPlugin implements Plugin
Then, this requires implementation of the intitalizePlugin and destroyPlugin methods, as shown below:
public void initializePlugin(PluginManager manager, File pluginDirectory) {
serverAddress = new JID(XMPPServer.getInstance().getServerInfo().getName());
router = XMPPServer.getInstance().getMessageRouter();
SessionEventDispatcher.addListener(listener);
}
public void destroyPlugin() {
SessionEventDispatcher.removeListener(listener);
listener = null;
serverAddress = null;
router = null;
}
The more about this sample, you may refer to the Openfire Plugin Development: Message of the Day.
Hope it helps.
There is a simple instance about plugin:
public class TestIQHandle extends IQHandler {
private static final String MODULE_NAME = "test plugin";
private static final String NAME_SPACE = "com:test:testplug";
private IQHandlerInfo info;
public TestIQHandle(){
super(MODULE_NAME);
info = new IQHandlerInfo("query", NAME_SPACE);
}
public TestIQHandle(String moduleName) {
super(moduleName);
info = new IQHandlerInfo("query", NAME_SPACE);
}
#Override
public IQ handleIQ(IQ packet) throws UnauthorizedException {
IQ reply = IQ.createResultIQ(packet);
Element groups = packet.getChildElement();
if(true){
System.out.println("=======invalid========");
}
if(!IQ.Type.get.equals(packet.getType())){
reply.setChildElement(groups.createCopy());
reply.setError(PacketError.Condition.bad_request);
return reply;
}
//StringUtils.substringBefore(packet.getFrom().toString(), "#");
return reply;
}
#Override
public IQHandlerInfo getInfo() {
// TODO Auto-generated method stub
return info;
}
}

Guice custom scope entry and exit in Java console application

I'm currently trying to implement injection in a Java console application using Guice. The application imports XML files in a database. Every import operation is done in an AbstractImporter, which can either be a UserImporter, a ScheduleImporter, etc.
public class ScheduleMigrator extends AbstractMigrator {
private final UserImporter userImporter;
private final ScheduleImporterFactory scheduleImporterFactory;
#Inject
public ScheduleMigrator(UserImporter userImporter,
ScheduleImporterFactory scheduleImporterFactory) {
this.userImporter = userImporter;
this.scheduleImporterFactory = scheduleImporterFactory;
}
public void migrate() {
// Migrate users
userImporter.run();
// Migrate schedules for each type
for (ScheduleType scheduleTypes : ScheduleType.values()) {
ScheduleImporter importer =
scheduleImporterFactory.create(scheduleTypes);
importer.run();
}
}
}
public class UserImporter extends AbstractImporter {
private final UserTransformer userTransformer;
private final ConfigurationService configurationService;
#Inject
public UserImporter(UserTransformer userTransformer,
ConfigurationService configurationService) {
this.userTransformer = userTransformer;
this.configurationService = configurationService;
}
public void run() {
// do stuff here
}
}
#Singleton
public class UserTransformer {
// ...code ommited...
}
#ImporterScoped
public class ConfigurationService {
// ...code ommited...
}
I have successfully created my own scope (#ImporterScoped) for classes that should only be available and instantiated only in an Importer. The scope was created by following the steps in the wiki. My problem is, how should I enter and exit the scope in ScheduleMigrator?
As you can see in ScheduleMigrator, each Importer is injected and its run() method is invoked. There are also factories (based on Guice's #AssistedInject feature). This is where I want each scope to start and end, UserImporter and ScheduleImporterFactory should run in their own scope.
This is a rough idea of what I'm trying to achieve:
importerScope.enter();
(new UserImporter()).run();
importerScope.exit();
Guice's documentation mentions the use of interceptors, but I'm a little lost on how it can be implemented.
Using AOP seems a very over-engineered approach and might introduce problems. When do I enter the scope? When do I exit? What happens if I instantiate two Importer objects?
Instead, I added a runScoped method in AbstractMigrator that takes a Runnable and executes it. Using injection I get the ImporterScope scope, enter and exit it appropriately.
protected void runScoped(Runnable function)
{
scenarioScope.enter();
try {
function.run();
}
finally {
scenarioScope.exit();
}
}
Usage:
runScoped(() -> {
ScheduleImporter importer =
scheduleImporterFactory.create(scheduleTypes);
importer.run();
});
This introduces one problem though. In ScheduleMigrator, I can't have Importers injected, because their instantiation would occur outside of a scope and Guice throws an OutOfScopeException. I had to wrap each Importer in a Provider.
private final Provider<UserImporter> userImporterProvider;
runScoped(() -> {
UserImporter importer = userImporterProvider.get();
importer.run();
});

Is there an equivalent of Guice Providers in Simple Injector?

Is there an equivalent injecting Guice Providers in Simple Injector?
I need to inject a dependency into a constructor that will let me create as many instances of a dependency as needed. In guice it would look like this...
public class RealBillingService implements BillingService {
private final Provider<CreditCardProcessor> processorProvider;
private final Provider<TransactionLog> transactionLogProvider;
#Inject
public RealBillingService(Provider<CreditCardProcessor> processorProvider,
Provider<TransactionLog> transactionLogProvider) {
this.processorProvider = processorProvider;
this.transactionLogProvider = transactionLogProvider;
}
public Receipt chargeOrder(PizzaOrder order, CreditCard creditCard) {
// each call to get creates a new instance in Guice as per scope configs
CreditCardProcessor processor = processorProvider.get();
TransactionLog transactionLog = transactionLogProvider.get();
/* use the processor and transaction log here */
}
}
So perhaps a C# equivalent could be this inside SimpleInjector?
private readonly MailSender _mailSenderProvider;
public MailService(Func<MailSender> mailSenderProvider)
{
_mailSenderProvider = mailSenderProvider;
}
public void SendMail()
{
var mailSender = _mailSenderProvider.Invoke();
mailSender.SendSomeMail("Hello world");
}
I tried injecting Func in my real code and got this...
{"No registration for type BootStrapper could be found and an implicit registration could not be made. The constructor of type BootStrapper contains the parameter of type Func with name 'storeType' that is not registered. Please ensure Func is registered in the container, or change the constructor of BootStrapper."}
You need to explicitly configure factory delegates with Simple Injector (see here)
var container = new Container();
container.Register<MailSender>();
container.RegisterSingle<Func<MailSender>>(() => container.GetInstance<MailSender>());
You may want to consider separating concerns by adding a new abstraction. If you define an IMailSender you can then create a MailSenderProxy that is responsible for ensuring a new MailSender instance for each message.
public interface IMailSender {
void Send(string message);
}
public class MailSender : IMailSender {
public void Send(string message) {
}
}
public class MailSenderProxy : IMailSender {
private readonly Func<IMailSender> mailSenderFactory;
public MailSenderProxy(Func<IMailSender> mailSenderFactory) {
this.mailSenderFactory = mailSenderFactory;
}
public void Send(string message) {
this.mailSenderFactory().Send(message);
}
}
This abstracts away the requirement of creating a new MailSender for each mail (this is possibly not something the MailService should know about)
public class MailService {
private readonly IMailSender sender;
public MailService(MailSender sender) {
this.sender = sender;
}
public void SendMail() {
this.sender.Send("Message");
}
}
The Container configuration would look something like this
var container = new Container();
container.Register<MailSender>();
container.RegisterSingle<Func<IMailSender>>(() =>
container.GetInstance<MailSender>());
container.Register<IMailSender, MailSenderProxy>();
container.Verify();
I found the following example in the SimpleInjector docs
http://simpleinjector.readthedocs.org/en/latest/howto.html#register-factory-delegates
public static void AllowResolvingFuncFactories(this ContainerOptions options)
{
options.Container.ResolveUnregisteredType += (s, e) =>
{
var type = e.UnregisteredServiceType;
if (!type.IsGenericType || type.GetGenericTypeDefinition() != typeof(Func<>))
{
return;
}
Type serviceType = type.GetGenericArguments().First();
InstanceProducer registration = options.Container.GetRegistration(serviceType, true);
Type funcType = typeof(Func<>).MakeGenericType(serviceType);
var factoryDelegate = Expression.Lambda(funcType,
registration.BuildExpression()).Compile();
e.Register(Expression.Constant(factoryDelegate));
};
}
Then on my container I call this...
// Allow types of Func<T> to be resolved
container.Options.AllowResolvingFuncFactories();
// 3. Optionally verify the container's configuration.
container.Verify();
Now I can inject Func< MyClass > and when I invoke the Func it returns as many instances as I want of that type.
All thanks to C# reified types and Simpleinjector's awesome api!

Java EJB Modify Schedule Property Values At Runtime

I have a Singleton class in Java and I have a timer using the #Schedule annotation. I wish to change the property of the Schedule at runtime. Below is the code:
#Startup
#Singleton
public class Listener {
public void setProperty() {
Method[] methods = this.getClass().getDeclaredMethods();
Method method = methods[0];
Annotation[] annotations = method.getDeclaredAnnotations();
Annotation annotation = annotations[0];
if(annotation instanceof Schedule) {
Schedule schedule = (Schedule) annotation;
System.out.println(schedule.second());
}
}
#PostConstruct
public void runAtStartUp() {
setProperty();
}
#Schedule(second = "3")
public void run() {
// do something
}
}
I wish to change the value at runtime of Schedule second based on the information from a Property file. Is this actually possibe? The Property file contains the configuration information. I tried to do #Schedule(second = SOME_VARIABLE) where private static String SOME_VARIABLE = readFromConfigFile(); This does not work. It expects a constant meaning a final and I don't want to set final.
I also saw this post: Modifying annotation attribute value at runtime in java
It shows this is not possible to do.
Any ideas?
EDIT:
#Startup
#Singleton
public class Listener {
javax.annotation.#Resource // the issue is this
private javax.ejb.TimerService timerService;
private static String SOME_VARIABLE = null;
#PostConstruct
public void runAtStartUp() {
SOME_VARIABLE = readFromFile();
timerService.createTimer(new Date(), TimeUnit.SECONDS.toMillis(Long.parse(SOME_VARIABLE)), null);
}
#Timeout
public void check(Timer timer) {
// some code runs every SOME_VARIABLE as seconds
}
}
The issue is injecting using #Resource. How can this be fixed?
The Exception is shown below:
No EJBContainer provider available The following providers: org.glassfish.ejb.embedded.EJBContainerProviderImpl Returned null from createEJBContainer call
javax.ejb.EJBException
org.glassfish.ejb.embedded.EJBContainerProviderImpl
at javax.ejb.embeddable.EJBContainer.reportError(EJBContainer.java:186)
at javax.ejb.embeddable.EJBContainer.createEJBContainer(EJBContainer.java:121)
at javax.ejb.embeddable.EJBContainer.createEJBContainer(EJBContainer.java:78)
#BeforeClass
public void setUpClass() throws Exception {
Container container = EJBContainer.createEJBContainer();
}
This occurs during unit testing using the Embeddable EJB Container. Some of the Apache Maven code is located on this post: Java EJB JNDI Beans Lookup Failed
I think the solution you are looking for was discussed here.
TomasZ is right you should use programmatic timers with TimerService for the situations when you want dynamically change schedule in run time.
Maybe you could use the TimerService. I have written some code but on my Wildfly 8 it seems to run multiple times even if its a Singleton.
Documentation http://docs.oracle.com/javaee/6/tutorial/doc/bnboy.html
Hope this helps:
#javax.ejb.Singleton
#javax.ejb.Startup
public class VariableEjbTimer {
#javax.annotation.Resource
javax.ejb.TimerService timerService;
#javax.annotation.PostConstruct
public void runAtStartUp() {
createTimer(2000L);
}
private void createTimer(long millis) {
//timerService.createSingleActionTimer(millis, new javax.ejb.TimerConfig());
timerService.createTimer(millis, millis, null);
}
#javax.ejb.Timeout
public void run(javax.ejb.Timer timer) {
long timeout = readFromConfigFile();
System.out.println("Timeout in " + timeout);
createTimer(timeout);
}
private long readFromConfigFile() {
return new java.util.Random().nextInt(5) * 1000L;
}
}

Categories

Resources