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
153
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 }