All Downloads are FREE. Search and download functionalities are using the official Maven repository.

brooklyn.entity.osgi.karaf.KarafContainer.groovy Maven / Gradle / Ivy

package brooklyn.entity.osgi.karaf

import java.util.concurrent.TimeUnit

import brooklyn.entity.Entity
import brooklyn.entity.basic.Attributes
import brooklyn.entity.basic.SoftwareProcessEntity
import brooklyn.entity.java.UsesJava
import brooklyn.entity.java.UsesJmx
import brooklyn.event.adapter.ConfigSensorAdapter
import brooklyn.event.adapter.JmxPostProcessors
import brooklyn.event.adapter.JmxSensorAdapter
import brooklyn.event.adapter.legacy.ValueProvider
import brooklyn.event.basic.BasicAttributeSensor
import brooklyn.event.basic.BasicConfigKey
import brooklyn.event.basic.BasicAttributeSensorAndConfigKey
import brooklyn.event.basic.PortAttributeSensorAndConfigKey
import brooklyn.event.basic.MapConfigKey
import brooklyn.util.flags.SetFromFlag

/**
 * This sets up a Karaf OSGi container
 */
public class KarafContainer extends SoftwareProcessEntity implements UsesJava, UsesJmx {
    
    // TODO Better way of setting/overriding defaults for config keys that are defined in super class SoftwareProcessEntity
    
    public static final String KARAF_ADMIN = "org.apache.karaf:type=admin,name=%s"
    public static final String KARAF_FEATURES = "org.apache.karaf:type=features,name=%s"

    @SetFromFlag("karafName")
    public static final BasicAttributeSensorAndConfigKey KARAF_NAME = [ String, "karaf.name", "Karaf instance name", "root" ]

    // TODO too complicated? Used by KarafContainer; was in JavaApp; where should it be in brave new world?
    public static final MapConfigKey NAMED_PROPERTY_FILES = [ Map, "karaf.runtime.files", "Property files to be generated, referenced by name relative to runDir" ]

    @SetFromFlag("jmxUser")
    public static final BasicAttributeSensorAndConfigKey JMX_USER = [ Attributes.JMX_USER, "karaf" ]
    
    @SetFromFlag("jmxPassword")
    public static final BasicAttributeSensorAndConfigKey JMX_PASSWORD = [ Attributes.JMX_PASSWORD, "karaf" ]
        
    @SetFromFlag("jmxPort")
    public static final PortAttributeSensorAndConfigKey JMX_PORT = new PortAttributeSensorAndConfigKey(UsesJmx.JMX_PORT, "1099+")

    @SetFromFlag("rmiServerPort")
    public static final PortAttributeSensorAndConfigKey RMI_SERVER_PORT = new PortAttributeSensorAndConfigKey(UsesJmx.RMI_SERVER_PORT, "44444+")
    @Deprecated // since 0.4 use RMI_SERVER_PORT
    public static final PortAttributeSensorAndConfigKey RMI_PORT = RMI_SERVER_PORT;
    
    @SetFromFlag("jmxContext")
    public static final BasicAttributeSensorAndConfigKey JMX_CONTEXT = [ UsesJmx.JMX_CONTEXT, "karaf-"+KARAF_NAME.configKey.defaultValue ]

    @SetFromFlag("version")
    public static final BasicConfigKey SUGGESTED_VERSION = [ SoftwareProcessEntity.SUGGESTED_VERSION, "2.2.9" ]
    
    public static final BasicAttributeSensor KARAF_INSTANCES = [ Map, "karaf.admin.instances", "Karaf admin instances" ]
    public static final BasicAttributeSensor KARAF_ROOT = [ Boolean, "karaf.admin.isRoot", "Karaf admin isRoot" ]
    public static final BasicAttributeSensor KARAF_JAVA_OPTS = [String, "karaf.admin.java_opts", "Karaf Java opts" ]
    public static final BasicAttributeSensor KARAF_INSTALL_LOCATION  = [ String, "karaf.admin.location", "Karaf install location" ]
    public static final BasicAttributeSensor KARAF_PID = [ Integer, "karaf.admin.pid", "Karaf instance PID" ]
    public static final BasicAttributeSensor KARAF_SSH_PORT = [ Integer, "karaf.admin.ssh_port", "Karaf SSH Port" ]
    public static final BasicAttributeSensor KARAF_RMI_REGISTRY_PORT = [ Integer, "karaf.admin.rmi_registry_port", "Karaf instance RMI registry port" ]
    public static final BasicAttributeSensor KARAF_RMI_SERVER_PORT = [ Integer, "karaf.admin.rmi_server_port", "Karaf RMI (JMX) server port" ]
    public static final BasicAttributeSensor KARAF_STATE = [ String, "karaf.admin.state", "Karaf instance state" ]

    protected JmxSensorAdapter jmxAdapter
    
    public KarafContainer(Map properties=[:], Entity owner=null) {
        super(properties, owner)
    }

//    @Override
//    public KarafSshDriver newDriver(SshMachineLocation machine) {
//        return new KarafSshDriver(this, machine)
//    }

    @Override
    public Class getDriverInterface() {
        return KarafDriver.class;
    }

    @Override
    protected void connectSensors() {
        super.connectSensors();

        //FIXME should have a better way of setting config -- firstly, not here!
        //preferred style is to have config auto-applied to attributes, and have default values in their definition, not here
        //use of "properties.{user,password}" is non-standard; is that requried? use default jmxUser, jmxPassword flags?
        setAttribute(JMX_CONTEXT, String.format("karaf-%s", getConfig(KARAF_NAME.configKey)))
        
        sensorRegistry.register(new ConfigSensorAdapter());
        jmxAdapter = sensorRegistry.register(new JmxSensorAdapter(period: 500*TimeUnit.MILLISECONDS));
        
        jmxAdapter.objectName(String.format(KARAF_ADMIN, getConfig(KARAF_NAME.configKey))).with {
            attribute("Instances").subscribe(KARAF_INSTANCES, JmxPostProcessors.tabularDataToMap())
        }
        
        // INSTANCES aggregates data for the other sensors.
        sensorRegistry.addSensor(SERVICE_UP, { getInstanceAttribute("State")?.equals("Started") } as ValueProvider)
        sensorRegistry.addSensor(KARAF_ROOT, { getInstanceAttribute("Is Root") } as ValueProvider)
        sensorRegistry.addSensor(KARAF_JAVA_OPTS, { getInstanceAttribute("JavaOpts") } as ValueProvider)
        sensorRegistry.addSensor(KARAF_INSTALL_LOCATION, { getInstanceAttribute("Location") } as ValueProvider)
        sensorRegistry.addSensor(KARAF_NAME, { getInstanceAttribute("Name") } as ValueProvider)
        sensorRegistry.addSensor(KARAF_PID, { getInstanceAttribute("Pid") } as ValueProvider)
        sensorRegistry.addSensor(KARAF_SSH_PORT, { getInstanceAttribute("Ssh Port") } as ValueProvider)
        sensorRegistry.addSensor(KARAF_RMI_REGISTRY_PORT, { getInstanceAttribute("RMI Registry Port") } as ValueProvider)
        sensorRegistry.addSensor(KARAF_RMI_SERVER_PORT, { getInstanceAttribute("RMI Server Port") } as ValueProvider)
        sensorRegistry.addSensor(KARAF_STATE, { getInstanceAttribute("State") } as ValueProvider)
    }

    protected  T getInstanceAttribute(String attribute) {
        return getAttribute(KARAF_INSTANCES)?.get(attribute)
    }

    @Override
    public void postStart() {
		super.postStart()
        deployConfiguration(getConfig(NAMED_PROPERTY_FILES))
    }
    
    @Override
    protected void preStop() {
        if(jmxAdapter!=null){
            jmxAdapter.deactivateAdapter();
        }
        super.preStop();
    }

    protected void deployConfiguration(Map> propertyFiles) {
        Map result = [:]
        
        // FIXME Store securely; may contain credentials!
        for (Map.Entry> entry in propertyFiles) {
            String file = entry.key
            Map contents = entry.value

            Properties props = new Properties()
            for (Map.Entry prop in contents) {
                props.setProperty(prop.key, prop.value)
            }
            
            File local = File.createTempFile(id, ".cfg")
            local.deleteOnExit() // just in case
            FileOutputStream fos = new FileOutputStream(local)
            try {
                props.store(fos, "Auto-generated by Brooklyn; " + file)
                fos.flush()
                File remote = new File(driver.runDir, file)
                driver.copyFile local, remote
            } finally {
                fos.close()
                local.delete()
            }
        }
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy