View Javadoc

1   package cz.cuni.amis.pogamut.base.agent.jmx.proxy;
2   
3   import java.util.logging.Logger;
4   
5   import javax.management.MBeanServerConnection;
6   import javax.management.MalformedObjectNameException;
7   import javax.management.ObjectName;
8   import javax.management.remote.JMXConnector;
9   import javax.management.remote.JMXConnectorFactory;
10  import javax.management.remote.JMXServiceURL;
11  
12  import cz.cuni.amis.introspection.Folder;
13  import cz.cuni.amis.introspection.jmx.DynamicMBeanToFolderAdapter;
14  import cz.cuni.amis.introspection.jmx.DynamicProxy;
15  import cz.cuni.amis.pogamut.base.agent.IAgent;
16  import cz.cuni.amis.pogamut.base.agent.IAgentId;
17  import cz.cuni.amis.pogamut.base.agent.exceptions.AgentException;
18  import cz.cuni.amis.pogamut.base.agent.impl.AbstractAgent;
19  import cz.cuni.amis.pogamut.base.agent.impl.AgentId;
20  import cz.cuni.amis.pogamut.base.agent.jmx.AgentJMXComponents;
21  import cz.cuni.amis.pogamut.base.agent.jmx.adapter.AgentMBeanAdapter;
22  import cz.cuni.amis.pogamut.base.agent.state.level0.IAgentState;
23  import cz.cuni.amis.pogamut.base.component.bus.IComponentBus;
24  import cz.cuni.amis.pogamut.base.component.exception.ComponentCantStartException;
25  import cz.cuni.amis.pogamut.base.utils.jmx.FolderToIJMXEnabledAdapter;
26  import cz.cuni.amis.pogamut.base.utils.jmx.flag.FlagJMXProxy;
27  import cz.cuni.amis.pogamut.base.utils.logging.IAgentLogger;
28  import cz.cuni.amis.pogamut.base.utils.logging.jmx.AgentLoggerJMXProxy;
29  import cz.cuni.amis.utils.Lazy;
30  import cz.cuni.amis.utils.exception.PogamutJMXException;
31  import cz.cuni.amis.utils.flag.ImmutableFlag;
32  
33  // TODO: [RUDA] finish implementation
34  /**
35   * Makes it possible to control agent running in remote JVM through JMX protocol.
36   * @author ik
37   */
38  public class AgentJMXProxy implements IAgent {
39  
40      FlagJMXProxy<IAgentState> agentFlag = null;
41      DynamicProxy proxy = null;
42      private Lazy<IAgentLogger> agentLogger = new Lazy<IAgentLogger>() {
43          @Override
44          protected IAgentLogger create() {
45          	// TODO: jak je to s agentname a jmx? je treba mit AgentNameJMXProxy?
46              return new AgentLoggerJMXProxy(new AgentId(), mbsc, agentName);
47          }
48      };
49      private Lazy<Folder> folder = new Lazy<Folder>() {
50      	@Override
51          protected Folder create() {
52              try {
53                  ObjectName introspectionRoot = FolderToIJMXEnabledAdapter.getFolderObjectNameForParent(agentName, AbstractAgent.INTROSPECTION_ROOT_NAME);
54                  DynamicProxy proxy = new DynamicProxy(introspectionRoot, mbsc);
55                  // convert the proxy to standard Folder
56                  return new DynamicMBeanToFolderAdapter(proxy);
57              } catch (MalformedObjectNameException ex) {
58                  throw new RuntimeException(ex);
59              }
60          }
61      };
62      
63      private MBeanServerConnection mbsc = null;
64      private ObjectName agentName = null;
65  	private AgentIdJMXProxy agentId;
66  
67      public AgentJMXProxy(String agentJmxAddress) {
68          // connect through RMI and get the proxy
69          String[] strs = agentJmxAddress.split("\\" + AgentJMXComponents.JMX_SERVER_AGENT_NAME_DELIM);
70          String jmxService = strs[0];
71          String objectName = strs[1];
72          try {
73  	        JMXServiceURL url = new JMXServiceURL(jmxService);
74  	        JMXConnector jmxc = JMXConnectorFactory.connect(url, null);
75  	        mbsc = jmxc.getMBeanServerConnection();
76  	        agentName = ObjectName.getInstance(objectName);
77  	        proxy = new DynamicProxy(agentName, mbsc);
78  	        agentFlag = new FlagJMXProxy<IAgentState>(agentName, mbsc, AgentMBeanAdapter.AGENT_STATE_FLAG_NAME);
79  	        agentId = new AgentIdJMXProxy(this);
80          } catch (Exception e) {
81          	throw new PogamutJMXException("Can't create AgentJMXProxy.", e, this);
82          }
83      }   
84      
85      public MBeanServerConnection getMBeanServerConnection() {
86      	return mbsc;
87      }
88      
89      public ObjectName getObjectName() {
90      	return agentName;
91      }
92  
93      @Override
94      public IAgentLogger getLogger() {
95          return agentLogger.get();
96      }
97      
98      public Logger getLog() {
99      	return getLogger().getCategory(getComponentId().getToken());
100     }
101 
102     @Override
103     public ImmutableFlag<IAgentState> getState() {
104         return agentFlag.getImmutable();
105     }
106 
107     /**
108      * All exceptions are wrapped in RuntimeException.
109      * @param actionName
110      * @return
111      */
112     protected Object callNoException(String actionName) {
113         try {
114             return call(actionName);
115         } catch (AgentException ex) {
116             throw new RuntimeException(ex);
117         }
118     }
119 
120 
121     /**
122      * All exceptions are wrapped in RuntimeException.
123      * @param actionName
124      * @return
125      */
126     protected Object callNoException(String actionName, Object[] params, String[] sig) {
127         try {
128             return proxy.invoke(actionName, params, sig);
129         } catch (Exception ex) {
130             throw new RuntimeException(ex);
131         }
132     }
133 
134     protected Object call(String actionName) throws AgentException {
135         try {
136             return proxy.invoke(actionName, null, null);
137         } catch (Exception ex) {
138             throw new AgentException("JMX communication exception. Error executing method :" + actionName + ".", ex, this);
139         }
140     }
141 
142     protected Object getAttributeNoException(String atr) {
143         try {
144             return proxy.getAttribute(atr);
145         } catch (Exception ex) {
146             throw new RuntimeException("Atribute retrieval error.", ex);
147         }
148     }
149 
150     @Override
151     public void start() throws AgentException {
152         call("start");
153     }
154     
155     @Override
156 	public void startPaused() throws ComponentCantStartException {
157 		call("startPaused");
158 	}
159 
160     @Override
161     public void pause() throws AgentException {
162         call("pause");
163     }
164 
165     @Override
166     public void resume() throws AgentException {
167         call("resume");
168     }
169 
170     @Override
171     public void stop() {
172         callNoException("stop");
173     }
174 
175     @Override
176     public void kill() {
177         callNoException("kill");
178     }
179 
180     @Override
181     public IAgentId getComponentId() {
182         return agentId;
183     }
184     
185     public String getName() {
186     	return getComponentId().getName().getFlag();
187     }
188 
189     @Override
190     public Folder getIntrospection() {
191         return folder.getVal();
192     }
193 
194 	@Override
195 	public IComponentBus getEventBus() {
196 		throw new UnsupportedOperationException("not supported");
197 	}
198 
199 }