package org.ourgrid.system.units; import java.security.KeyPair; import java.util.LinkedHashMap; import java.util.Map; import java.util.regex.Matcher; import java.util.regex.Pattern; import br.edu.ufcg.lsd.commune.container.servicemanager.client.ClientModule; import br.edu.ufcg.lsd.commune.context.ModuleContext; import br.edu.ufcg.lsd.commune.identification.InvalidIdentificationException; import br.edu.ufcg.lsd.commune.network.signature.SignatureProperties; import br.edu.ufcg.lsd.commune.network.signature.Util; import br.edu.ufcg.lsd.commune.network.xmpp.XMPPProperties; public abstract class AbstractUnit implements Unit { protected String jabberUser; private boolean isRunning = false; private String location; private String moduleName; private String publicKey; private String privateKey; private String hostMachine; private ModuleContext context; protected String propertiesFile; protected AbstractUnit( String moduleName) throws Exception { this.moduleName = moduleName; } protected AbstractUnit(String moduleName, String propertiesFile) throws Exception { this.propertiesFile = propertiesFile; this.moduleName = moduleName; } protected void contextCreated() throws Exception { setLocation(); initKeys(); createComponent(); } protected void setLocation() { this.location = getJabberID( getJabberUserName(), getJabberServerHostname(), getModuleName()); } protected abstract void createComponent(); protected ModuleContext getContext() { return context; } protected void setContext(ModuleContext context) { this.context = context; } protected Map<String, String> getNewProperties() { Map<String, String> contextProperties = new LinkedHashMap<String, String>(); contextProperties.put(XMPPProperties.PROP_USERNAME, jabberUser); contextProperties.put(XMPPProperties.PROP_PASSWORD, jabberUser); contextProperties.put(SignatureProperties.PROP_PUBLIC_KEY, publicKey); contextProperties.put(SignatureProperties.PROP_PRIVATE_KEY, privateKey); return contextProperties; } public void initKeys() throws Exception { genKeyPair(); isRunning = true; System.out.println( "STARTING: " + this.toString() ); } public boolean runningLocally() { return getHostMachine() == null; } protected abstract void deploy(); private void genKeyPair() { KeyPair pair = Util.generateKeyPair(); publicKey = Util.encodeArrayToBase64String( pair.getPublic().getEncoded() ); privateKey = Util.encodeArrayToBase64String( pair.getPrivate().getEncoded() ); } public abstract ClientModule getUIManager() throws Exception; public void stop() throws Exception { System.out.println( "AbstractUnit.stop(1)" ); checkIfUnitIsRunning(); System.out.println( "AbstractUnit.stop(2)" ); getUIManager().stop(); System.out.println( "AbstractUnit.stop(3)" ); this.isRunning = false; } public void kill() throws Exception { checkIfUnitIsRunning(); getUIManager().stop(); this.isRunning = false; } public String getJabberServerHostname() { return getContext().getProperty(XMPPProperties.PROP_XMPP_SERVERNAME); } protected abstract ModuleContext createContext(); public String getJabberUserName() { return getContext().getProperty(XMPPProperties.PROP_USERNAME); } public final String getLoginAndServer() { return jabberUser + "@" + getJabberServerHostname(); } public void waitUntilWorkIsDone() throws Exception { } public boolean stillIdle() throws Exception { return false; } public final boolean isRunning() throws Exception { return runningLocally() ? this.isRunning : getUIManager().getContainerDAO().isStarted(); } public final String getLocation() { return this.location; } public String getModuleName() { return this.moduleName; } protected void checkIfUnitIsRunning() throws Exception { if ( !isRunning() ) throw new UnitException( "Unit is not running" ); } protected void checkIfUnitIsStopped() throws Exception { if ( isRunning() ) throw new UnitException( "Cannot set this property after unit was started" ); } public void setHostMachine( String hostMachine ) throws Exception { this.hostMachine = hostMachine; } public String getHostMachine() { return this.hostMachine; } @Override public String toString() { return this.getClass().getSimpleName() + " - " + this.getJabberUserName() + "@" + this.getJabberServerHostname() + ", machine: " + (getHostMachine() == null ? "same jvm" : getHostMachine()); } /** * Returns the full Jabber ID based on the given data * * @param login the user login * @param server the server name * @param resource the resource * @return the full Jabber ID */ private String getJabberID( String login, String server, String resource ) { if ( login == null || server == null ) { throw new InvalidIdentificationException( "Undefined XMPP login or server name. Check the XMPP properties '" + XMPPProperties.PROP_USERNAME + "' and '" + XMPPProperties.PROP_XMPP_SERVERNAME + "' on the configuration file" ); } String fullID = login + "@" + server + (resource != null ? "/" + resource : ""); if ( !validate( fullID ) ) { throw new InvalidIdentificationException( "Invalid XMPP identification: " + fullID ); } return fullID; } /** * Validates the given identification * * @param fullID the full identification * @returns true if the id is valid, false if it isn't. */ private boolean validate( String fullID ) { if ( fullID != null ) { Pattern p = Pattern.compile( "[a-zA-Z_0-9-\\.]+@[a-zA-Z_0-9-\\.]+[/a-zA-Z_0-9-\\.]*" ); Matcher m = p.matcher( fullID ); return m.matches(); } return false; } public void setContextFilePath(String filePath) { propertiesFile = filePath; context = createContext(); } }