View Javadoc

1   /*****************************************************************
2    * Licensed to the Apache Software Foundation (ASF) under one   *
3    * or more contributor license agreements.  See the NOTICE file *
4    * distributed with this work for additional information        *
5    * regarding copyright ownership.  The ASF licenses this file   *
6    * to you under the Apache License, Version 2.0 (the            *
7    * "License"); you may not use this file except in compliance   *
8    * with the License.  You may obtain a copy of the License at   *
9    *                                                              *
10   *   http://www.apache.org/licenses/LICENSE-2.0                 *
11   *                                                              *
12   * Unless required by applicable law or agreed to in writing,   *
13   * software distributed under the License is distributed on an  *
14   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY       *
15   * KIND, either express or implied.  See the License for the    *
16   * specific language governing permissions and limitations      *
17   * under the License.                                           *
18   ****************************************************************/
19  
20  package org.apache.james.remotemanager;
21  
22  import org.apache.avalon.cornerstone.services.connection.ConnectionHandler;
23  import org.apache.avalon.excalibur.pool.DefaultPool;
24  import org.apache.avalon.excalibur.pool.HardResourceLimitingPool;
25  import org.apache.avalon.excalibur.pool.ObjectFactory;
26  import org.apache.avalon.excalibur.pool.Pool;
27  import org.apache.avalon.excalibur.pool.Poolable;
28  import org.apache.avalon.framework.activity.Initializable;
29  import org.apache.avalon.framework.service.ServiceException;
30  import org.apache.avalon.framework.service.ServiceManager;
31  import org.apache.avalon.framework.configuration.Configuration;
32  import org.apache.avalon.framework.configuration.ConfigurationException;
33  import org.apache.avalon.framework.logger.LogEnabled;
34  
35  import org.apache.james.core.AbstractJamesService;
36  import org.apache.james.services.MailServer;
37  import org.apache.james.services.UsersRepository;
38  import org.apache.james.services.UsersStore;
39  import org.apache.james.util.watchdog.Watchdog;
40  import org.apache.james.util.watchdog.WatchdogFactory;
41  
42  import java.util.HashMap;
43  
44  /***
45   * Provides a really rude network interface to administer James.
46   * Allow to add accounts.
47   * TODO: -improve protocol
48   *       -add remove user
49   *       -much more...
50   * @version 1.0.0, 24/04/1999
51   */
52  public class RemoteManager
53      extends AbstractJamesService implements RemoteManagerMBean {
54  
55      /***
56       * A HashMap of (user id, passwords) for James administrators
57       */
58      private HashMap adminAccounts = new HashMap();
59  
60      /***
61       * The UsersStore that contains all UsersRepositories managed by this RemoteManager
62       */
63      private UsersStore usersStore;
64  
65      /***
66       * The current UsersRepository being managed/viewed/modified
67       */
68      private UsersRepository users;
69  
70      /***
71       * The service prompt to be displayed when waiting for input.
72       */
73      private String prompt = "";
74      
75      /***
76       * The reference to the internal MailServer service
77       */
78      private MailServer mailServer;
79  
80      /***
81       * The pool used to provide RemoteManager Handler objects
82       */
83      private Pool theHandlerPool = null;
84  
85      /***
86       * The pool used to provide RemoteManager Handler objects
87       */
88      private ObjectFactory theHandlerFactory = new RemoteManagerHandlerFactory();
89  
90      /***
91       * The factory used to generate Watchdog objects
92       */
93      private WatchdogFactory theWatchdogFactory;
94  
95      /***
96       * The configuration data to be passed to the handler
97       */
98      private RemoteManagerHandlerConfigurationData theConfigData
99          = new RemoteManagerHandlerConfigurationDataImpl();
100 
101     /***
102      * @see org.apache.avalon.framework.service.Serviceable#service(ServiceManager)
103      */
104     public void service( final ServiceManager componentManager )
105         throws ServiceException {
106         super.service(componentManager);
107         mailServer = (MailServer)componentManager.
108             lookup( MailServer.ROLE );
109         usersStore = (UsersStore)componentManager.
110             lookup( UsersStore.ROLE );
111         users = (UsersRepository) componentManager.lookup(UsersRepository.ROLE);
112         if (users == null) {
113             throw new ServiceException("","The user repository could not be found.");
114         }
115     }
116 
117     /***
118      * @see org.apache.avalon.framework.configuration.Configurable#configure(Configuration)
119      */
120     public void configure( final Configuration configuration )
121         throws ConfigurationException {
122 
123         super.configure(configuration);
124         if (isEnabled()) {
125             Configuration handlerConfiguration = configuration.getChild("handler");
126             Configuration admin = handlerConfiguration.getChild( "administrator_accounts" );
127             Configuration[] accounts = admin.getChildren( "account" );
128             for ( int i = 0; i < accounts.length; i++ ) {
129                 adminAccounts.put( accounts[ i ].getAttribute( "login" ),
130                                    accounts[ i ].getAttribute( "password" ) );
131             }
132             Configuration promtConfiguration = handlerConfiguration.getChild("prompt", false);
133             if (promtConfiguration != null) prompt = promtConfiguration.getValue();
134             if (prompt == null) prompt = ""; 
135             else if (!prompt.equals("") && !prompt.endsWith(" ")) prompt += " "; 
136         }
137     }
138 
139     /***
140      * @see org.apache.avalon.framework.activity.Initializable#initialize()
141      */
142     public void initialize() throws Exception {
143         super.initialize();
144         if (!isEnabled()) {
145             return;
146         }
147 
148         if (connectionLimit != null) {
149             theHandlerPool = new HardResourceLimitingPool(theHandlerFactory, 5, connectionLimit.intValue());
150             getLogger().debug("Using a bounded pool for RemoteManager handlers with upper limit " + connectionLimit.intValue());
151         } else {
152             // NOTE: The maximum here is not a real maximum.  The handler pool will continue to
153             //       provide handlers beyond this value.
154             theHandlerPool = new DefaultPool(theHandlerFactory, null, 5, 30);
155             getLogger().debug("Using an unbounded pool for RemoteManager handlers.");
156         }
157         if (theHandlerPool instanceof LogEnabled) {
158             ((LogEnabled)theHandlerPool).enableLogging(getLogger());
159         }
160         if (theHandlerPool instanceof Initializable) {
161             ((Initializable)theHandlerPool).initialize();
162         }
163 
164         theWatchdogFactory = getWatchdogFactory();
165     }
166 
167     /***
168      * @see org.apache.james.core.AbstractJamesService#getDefaultPort()
169      */
170      protected int getDefaultPort() {
171         return 4555;
172      }
173 
174     /***
175      * @see org.apache.james.core.AbstractJamesService#getServiceType()
176      */
177     public String getServiceType() {
178         return "Remote Manager Service";
179     }
180 
181     /***
182      * @see org.apache.avalon.cornerstone.services.connection.AbstractHandlerFactory#newHandler()
183      */
184     protected ConnectionHandler newHandler()
185             throws Exception {
186         RemoteManagerHandler theHandler = (RemoteManagerHandler)theHandlerPool.get();
187         theHandler.enableLogging(getLogger());
188 
189         Watchdog theWatchdog = theWatchdogFactory.getWatchdog(theHandler.getWatchdogTarget());
190 
191         theHandler.setConfigurationData(theConfigData);
192         theHandler.setWatchdog(theWatchdog);
193         return theHandler;
194     }
195 
196     /***
197      * @see org.apache.avalon.cornerstone.services.connection.ConnectionHandlerFactory#releaseConnectionHandler(ConnectionHandler)
198      */
199     public void releaseConnectionHandler( ConnectionHandler connectionHandler ) {
200         if (!(connectionHandler instanceof RemoteManagerHandler)) {
201             throw new IllegalArgumentException("Attempted to return non-RemoteManagerHandler to pool.");
202         }
203         theHandlerPool.put((Poolable)connectionHandler);
204     }
205 
206     /***
207      * The factory for producing handlers.
208      */
209     private static class RemoteManagerHandlerFactory
210         implements ObjectFactory {
211 
212         /***
213          * @see org.apache.avalon.excalibur.pool.ObjectFactory#newInstance()
214          */
215         public Object newInstance() throws Exception {
216             return new RemoteManagerHandler();
217         }
218 
219         /***
220          * @see org.apache.avalon.excalibur.pool.ObjectFactory#getCreatedClass()
221          */
222         public Class getCreatedClass() {
223             return RemoteManagerHandler.class;
224         }
225 
226         /***
227          * @see org.apache.avalon.excalibur.pool.ObjectFactory#decommision(Object)
228          */
229         public void decommission( Object object ) throws Exception {
230             return;
231         }
232     }
233 
234     /***
235      * A class to provide RemoteManager handler configuration to the handlers
236      */
237     private class RemoteManagerHandlerConfigurationDataImpl
238         implements RemoteManagerHandlerConfigurationData {
239 
240         /***
241          * @see org.apache.james.remotemanager.RemoteManagerHandlerConfigurationData#getHelloName()
242          */
243         public String getHelloName() {
244             return RemoteManager.this.helloName;
245         }
246 
247         /***
248          * @see org.apache.james.remotemanager.RemoteManagerHandlerConfigurationData#getMailServer()
249          */
250         public MailServer getMailServer() {
251             return RemoteManager.this.mailServer;
252         }
253 
254         /***
255          * @see org.apache.james.remotemanager.RemoteManagerHandlerConfigurationData#getUsersRepository()
256          */
257         public UsersRepository getUsersRepository() {
258             return RemoteManager.this.users;
259         }
260 
261         /***
262          * @see org.apache.james.remotemanager.RemoteManagerHandlerConfigurationData#getUsersStore()
263          */
264         public UsersStore getUserStore() {
265             return RemoteManager.this.usersStore;
266         }
267 
268         /***
269          * @see org.apache.james.remotemanager.RemoteManagerHandlerConfigurationData#getAdministrativeAccountData()
270          */
271         public HashMap getAdministrativeAccountData() {
272             return RemoteManager.this.adminAccounts;
273         }
274 
275         /***
276          * @see org.apache.james.remotemanager.RemoteManagerHandlerConfigurationData#getPrompt()
277          */
278         public String getPrompt() {
279             return RemoteManager.this.prompt;
280         }
281 
282     }
283 }