Mapping Openfire Custom plugin with aSmack Client - java

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;
}
}

Related

Database driven feature toggle

I would want to enable my new feature based on a database value . If the database value is set for the feature , the new code should be enabled. Else it should toggle and flow to the old code. is there a way to accomplish this in Java/Spring ? I do not want to hit the database frequently.I am thinking of one call at the start of the request . Are there any examples to this ? If so please let me know. Thanks
Create Feature class implementation:
public enum CustomFeatures implements Feature {
#Label("Activates customFeature")
MY_CUSTOM_FEATURE;
public boolean isActive() {
return FeatureContext.getFeatureManager().isActive(this);
}
}
Create feature provider:
#Bean
public FeatureProvider featureProvider() {
return new EnumBasedFeatureProvider(CustomFeatures.class);
}
Create entity and repository:
#Entity
public class Feature {
private String name;
private Boolean active;
// getters-setters
}
Create #Component which will query database and sets new feature sate
#Component
public class FeatureToggler {
private final FeatureRepository featureRepository;
private final FeatureManager featureManager;
private FeatureToggler(FeatureRepository featureRepository, FeatureManager featureManager) {
this.featureRepository = featureRepository;
this.featureManager = featureManager;
}
#Schedule(fixedRate=60000)
public void refreshFeatureToggles() {
featureManager.setFeatureState(new FeatureState(CustomFeatures.MY_CUSTOM_FEATURE, featureRepository.findByName().isActive);
}
}
Now you could use check if feature enabled like this:
if(CustomFeatures.MY_CUSTOM_FEATURE.isActive()) {
}
Or use Spring aspect..

Elasticsearch index create on plugin initialization

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

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 RMI - When to create a Stub, start Registry and specify Codebase?

When to create a Stub, start Registry and specify Codebase?
I have created a RMI application. My simple application works. I have the RemoteObjInterface.class's package in my buildpath for the Client and the Server packages. I first start the Server application and then the Client application.
However, I have looked at other examples in the internet and I see them starting the registry, creating a Stub and specifying a codebase.
The following is my program:
The "RemoteObjInterface.class" is my Interface, "RemoteObjImplementation.class" is my Server and "Client.class" is my Client.
public interface RemoteObjInterface extends Remote {
public String someMethod() throws RemoteException;
}
public class RemoteObjImplementation extends UnicastRemoteObject implements
RemoteObjInterface {
private static final long serialVersionUID = 1L;
private static final int PORT = 1099;
private static Registry registry;
public RemoteObjImplementation() throws RemoteException {
super();
}
#Override
public String someMethod() throws RemoteException {
return new String("Hello");
}
public static void main(String args[]) {
Registry registry = LocateRegistry.createRegistry(PORT);
registry.bind(RemoteObjInterface.class.getSimpleName(),
new RemoteObjImplementation());
}
}
public class Client {
private static final String HOST = "localhost";
private static final int PORT = 1099;
private static Registry registry;
public static void main(String[] args) throws Exception {
registry = LocateRegistry.getRegistry(HOST, PORT);
RemoteObjInterface remoteApi = (RemoteObjInterface) registry.lookup(RemoteObjInterface.class.getSimpleName());
System.out.println("Message = " +
remoteApi.someMethod();
}
}
When to create a Stub
Creating a stub is a side-effect of exporting the remote object, which in turn is a side-effect of constructing it if it extends UnicastRemoteObject.
start Registry
When you want to start it. Before you start calling bind() or rebind() for example.
and specify Codebase?
You don't need to use this feature at all, it is optional. If you want your clients to be able to download classes dynamically rather than distributing them to the client ahead of time, specify the java.rmi.server.codebase system property in the server JVM before you export any remote objects (including Registries), and make sure it points to a URL that is accessible by both the Registry and the client.

GWT RequestFactory - adding custom methods to proxy classes?

Is is possible to add a method to GWT RequestFactory's proxy class? Let's say I have this:
#ProxyFor(value = MyEntity.class)
interface MyEntityProxy extends EntityProxy {
String getData(); // got it on server side
}
GetData() is backed at server side, that's fine. What if I'd like to add a method like this:
#ProxyFor(value = MyEntity.class)
interface MyEntityProxy extends EntityProxy {
String getData(); // got it on server side
String getDataAndAppendQwerty(); // want this one on client side
}
I want to manually implement getDataAndAppendQwerty(). It's 100% client-side code and the question is just where should I put the implementation.
The answer would be AutoBean categories, but they're not (yet) surfaced in RequestFactory.
I don't know of an easy way. You could use a wrapper and delegate
public class MyEntityProxyExt implements MyEntityProxy {
private final MyEntityProxy proxy;
public MyEntityProxyExt(MyEntityProxy proxy) {
this.proxy = proxy;
}
#Override
public String getData() {
return proxy.getData();
}
public Object getDataAndAppendQwerty() {
return proxy.getData() + "qwerty";
}
}
but you'd have to manually wrap all your proxy objects on the client when you get them back from the server.

Categories

Resources