View Javadoc
1   /*
2    * Copyright (c) MuleSoft, Inc.  All rights reserved.  http://www.mulesoft.com
3    * The software in this package is published under the terms of the CPAL v1.0
4    * license, a copy of which has been included with this distribution in the
5    * LICENSE.txt file.
6    */
7   package org.mule.management.agents;
8   
9   import org.mule.api.context.MuleContextBuilder;
10  import org.mule.component.simple.EchoComponent;
11  import org.mule.config.DefaultMuleConfiguration;
12  import org.mule.module.management.agent.FixedHostRmiClientSocketFactory;
13  import org.mule.module.management.agent.JmxAgent;
14  import org.mule.module.management.agent.RmiRegistryAgent;
15  import org.mule.tck.junit4.AbstractMuleContextTestCase;
16  
17  import java.util.Arrays;
18  import java.util.Collections;
19  import java.util.HashMap;
20  import java.util.Map;
21  
22  import javax.management.InstanceAlreadyExistsException;
23  import javax.management.MBeanRegistrationException;
24  import javax.management.MBeanServerConnection;
25  import javax.management.MalformedObjectNameException;
26  import javax.management.NotCompliantMBeanException;
27  import javax.management.remote.JMXConnector;
28  import javax.management.remote.JMXConnectorFactory;
29  import javax.management.remote.JMXServiceURL;
30  import javax.management.remote.rmi.RMIConnectorServer;
31  
32  import org.junit.Test;
33  
34  import static org.junit.Assert.assertTrue;
35  import static org.junit.Assert.fail;
36  
37  public class JmxAgentTestCase extends AbstractMuleContextTestCase
38  {
39      private static final String[] VALID_AUTH_TOKEN = {"mule", "mulepassword"};
40      private static final String DOMAIN = "JmxAgentTest";
41  
42      private JMXServiceURL serviceUrl;
43      private JmxAgent jmxAgent;
44  
45      @Override
46      protected void configureMuleContext(MuleContextBuilder contextBuilder)
47      {
48          super.configureMuleContext(contextBuilder);
49  
50          DefaultMuleConfiguration config = new DefaultMuleConfiguration();
51          config.setId(DOMAIN);
52          contextBuilder.setMuleConfiguration(config);
53      }
54  
55      @Override
56      protected void doSetUp() throws Exception
57      {
58          super.doSetUp();
59          serviceUrl = new JMXServiceURL(JmxAgent.DEFAULT_REMOTING_URI);
60          muleContext.getRegistry().registerAgent(new RmiRegistryAgent());
61          jmxAgent = muleContext.getRegistry().lookupObject(JmxAgent.class);
62          jmxAgent.setConnectorServerUrl(JmxAgent.DEFAULT_REMOTING_URI);
63      }
64  
65      @Override
66      protected void doTearDown()
67      {
68          if (jmxAgent != null)
69          {
70              jmxAgent.dispose();
71          }
72      }
73  
74      @Test
75      public void testDefaultProperties() throws Exception
76      {
77          jmxAgent.setCredentials(getValidCredentials());
78          muleContext.start();
79      }
80  
81      @Test
82      public void testSuccessfulRemoteConnection() throws Exception
83      {
84          configureProperties();
85          jmxAgent.setCredentials(getValidCredentials());
86          muleContext.start();
87  
88          JMXConnector connector = null;
89          try
90          {
91              Map<String, ?> props = Collections.singletonMap(JMXConnector.CREDENTIALS, VALID_AUTH_TOKEN);
92              connector = JMXConnectorFactory.connect(serviceUrl, props);
93              MBeanServerConnection connection = connector.getMBeanServerConnection();
94              // is it the right server?
95              assertTrue(Arrays.asList(connection.getDomains()).toString(),
96                      Arrays.asList(connection.getDomains()).contains("Mule." + DOMAIN));
97          }
98          finally
99          {
100             if (connector != null)
101             {
102                 connector.close();
103             }
104         }
105     }
106 
107     @Test
108     public void testNoCredentialsProvided() throws Exception
109     {
110         configureProperties();
111         jmxAgent.setCredentials(getValidCredentials());
112         muleContext.start();
113 
114         JMXConnector connector = null;
115         try
116         {
117             connector = JMXConnectorFactory.connect(serviceUrl);
118             fail("expected SecurityException");
119         }
120         catch (SecurityException e)
121         {
122             // expected
123         }
124         finally
125         {
126             if (connector != null)
127             {
128                 connector.close();
129             }
130         }
131     }
132 
133     @Test
134     public void testNonRestrictedAccess() throws Exception
135     {
136         configureProperties();
137         jmxAgent.setCredentials(null);
138         muleContext.start();
139 
140         JMXConnector connector = null;
141         try
142         {
143             connector = JMXConnectorFactory.connect(serviceUrl);
144             MBeanServerConnection connection = connector.getMBeanServerConnection();
145             // is it the right server?
146             assertTrue(Arrays.asList(connection.getDomains()).contains("Mule." + DOMAIN));
147         }
148         finally
149         {
150             if (connector != null)
151             {
152                 connector.close();
153             }
154         }
155     }
156 
157     protected Map<String, String> getValidCredentials()
158     {
159         final Map<String, String> credentials = new HashMap<String, String>(1);
160         credentials.put(VALID_AUTH_TOKEN[0], VALID_AUTH_TOKEN[1]);
161 
162         return credentials;
163     }
164 
165     protected void configureProperties()
166     {
167         // make multi-NIC dev box happy by sticking RMI clients to a single
168         // local ip address
169         Map<String, Object> props = new HashMap<String, Object>();
170         props.put(RMIConnectorServer.RMI_CLIENT_SOCKET_FACTORY_ATTRIBUTE,
171                   new FixedHostRmiClientSocketFactory("127.0.0.1"));
172         jmxAgent.setConnectorServerProperties(props);
173     }
174 
175     @Test
176     public void testServiceNameContainsColon() throws Exception
177     {
178         // create a service with an invalid name. It is registered in the registry as side effect
179         // so the JmxAgent will pick it up while registring services
180         getTestService("invalid:service:name", EchoComponent.class);
181 
182         // when registering services, the one we just put into the registry will be exposed
183         // to the local MBean server, too. If a MalformedObjectNameException is thrown during
184         // this operation, this test will fail
185         TestJmxAgent agent = new TestJmxAgent();
186         agent.setMuleContext(muleContext);
187         agent.initialise();
188 
189         agent.registerServiceServices();
190     }
191 
192     private static class TestJmxAgent extends JmxAgent
193     {
194         /**
195          * Open up method for test access
196          */
197         @Override
198         public void registerServiceServices() throws NotCompliantMBeanException, MBeanRegistrationException, InstanceAlreadyExistsException, MalformedObjectNameException
199         {
200             super.registerServiceServices();
201         }
202     }
203 }