//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//

=== Custom Appender

A Decanter Appender is an OSGi EventAdmin EventHandler: it's listening of `decanter/collect/*` EventAdmin topics, and
receives the monitoring data coming from the collectors.

It's responsible to store the data into a target backend.

To enable a new Decanter Appender, you just have to register an EventHandler OSGi service.

For instance, if you want to create a very simple SystemOutAppender that displays the monitoring data (coming from the
collectors) to System.out, you can create the following SystemOutAppender class implementing EventHandler interface:

----
package org.apache.karaf.decanter.sample.appender.systemout;

import org.osgi.service.event.Event;
import org.osgi.service.event.EventHandler;

import java.util.HashMap;

public class SystemOutAppender implements EventHandler {

    @Override
    public void handleEvent(Event event) {
        for (String name : event.getPropertyNames()) {
            System.out.println(name + ":" + event.getProperty(name));
        }
    }

}

----

Now, we create a BundleActivator that register our SystemOutAppender as an EventHandler OSGi service:

----
package org.apache.karaf.decanter.sample.appender.systemout;

import org.osgi.framework.BundleActivator;
import org.osgi.framework.BundleContext;
import org.osgi.framework.Constants;
import org.osgi.framework.ServiceRegistration;
import org.osgi.service.event.EventConstants;
import org.osgi.service.event.EventHandler;
import java.util.HashMap;
import java.util.Dictionary;

public class Activator implements BundleActivator {

  private ServiceRegistration registration;

  public void start(BundleContext bundleContext) {
    SystemOutAppender appender = new SystemOutAppender();
    Dictionary<String, String> properties = new Hashtable<>();
    properties.put(EventConstants.EVENT_TOPIC, "decanter/collect/*");
    registration =  bundleContext.registerService(EventHandler.class, appender, properties);
  }

  public void stop(BundleContext bundleContext) {
    if (registration != null) registration.unregister();
  }

}
----

You can see that our SystemOutAppender will listen on any `decanter/collect/*` topics.

We can now package our appender bundle using the following Maven `pom.xml`:

----
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">)

    <modelVersion>4.0.0</modelVersion>

    <groupId>org.apache.karaf.decanter.sample.appender</groupId>
    <artifactId>org.apache.karaf.decanter.sample.appender.systemout</artifactId>
    <version>1.1.0-SNAPSHOT</version>
    <packaging>bundle</packaging>
    <name>Apache Karaf :: Decanter :: Sample :: Appender :: SystemOut</name>

    <dependencies>

        <!-- OSGi -->
        <dependency>
            <groupId>org.osgi</groupId>
            <artifactId>org.osgi.core</artifactId>
            <version>4.3.1</version>
        </dependency>
        <dependency>
            <groupId>org.osgi</groupId>
            <artifactId>org.osgi.compendium</artifactId>
            <version>4.3.1</version>
        </dependency>


    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.felix</groupId>
                <artifactId>maven-bundle-plugin</artifactId>
                <version>2.4.0</version>
                <inherited>true</inherited>
                <extensions>true</extensions>
                <configuration>
                    <instructions>
                        <Bundle-SymbolicName>${project.artifactId}</Bundle-SymbolicName>
                        <Bundle-Version>${project.version}</Bundle-Version>
                        <Bundle-Activator>org.apache.karaf.decanter.sample.appender.systemout.Activator</Bundle-Activator>
                        <Import-Package>
                            *
                        </Import-Package>
                    </instructions>
                </configuration>
            </plugin>
        </plugins>
    </build>

</project>
----

Once built, you can enable this appender by deploying the bundle in Karaf (using the deploy folder or the `bundle:install` command).
