KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > jboss > mq > sm > file > OldStateManager


1 /*
2 * JBoss, Home of Professional Open Source
3 * Copyright 2005, JBoss Inc., and individual contributors as indicated
4 * by the @authors tag. See the copyright.txt in the distribution for a
5 * full listing of individual contributors.
6 *
7 * This is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU Lesser General Public License as
9 * published by the Free Software Foundation; either version 2.1 of
10 * the License, or (at your option) any later version.
11 *
12 * This software is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this software; if not, write to the Free
19 * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
20 * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
21 */

22 package org.jboss.mq.sm.file;
23
24 import java.io.BufferedInputStream JavaDoc;
25 import java.io.File JavaDoc;
26 import java.io.FileOutputStream JavaDoc;
27 import java.io.IOException JavaDoc;
28 import java.io.InputStream JavaDoc;
29 import java.io.PrintStream JavaDoc;
30 import java.net.URL JavaDoc;
31 import java.util.ArrayList JavaDoc;
32 import java.util.Collection JavaDoc;
33 import java.util.Enumeration JavaDoc;
34 import java.util.HashSet JavaDoc;
35 import java.util.Set JavaDoc;
36
37 import javax.jms.InvalidClientIDException JavaDoc;
38 import javax.jms.JMSException JavaDoc;
39 import javax.jms.JMSSecurityException JavaDoc;
40
41 import org.jboss.mq.DurableSubscriptionID;
42 import org.jboss.mq.SpyJMSException;
43 import org.jboss.mq.SpyTopic;
44 import org.jboss.mq.server.JMSDestinationManager;
45 import org.jboss.mq.server.JMSTopic;
46 import org.jboss.mq.sm.StateManager;
47 import org.jboss.mq.xml.XElement;
48 import org.jboss.mq.xml.XElementException;
49 import org.jboss.system.ServiceMBeanSupport;
50 import org.jboss.system.server.ServerConfigLocator;
51
52 /**
53  * This class is a simple User Manager. It handles credential issues.
54  *
55  * <p>This is the old state manager.
56  *
57  * @jmx:mbean extends="org.jboss.system.ServiceMBean"
58  *
59  * @author Norbert Lataille (Norbert.Lataille@m4x.org)
60  * @author <a HREF="hiram.chirino@jboss.org">Hiram Chirino</a>
61  * @author <a HREF="mailto:pra@tim.se">Peter Antman</a>
62  * @version $Revision: 37459 $
63  */

64 public class OldStateManager
65    extends ServiceMBeanSupport
66    implements StateManager, OldStateManagerMBean
67 {
68    XElement stateConfig;
69
70    private final Set JavaDoc loggedOnClientIds = new HashSet JavaDoc();
71    private String JavaDoc stateFile = "conf/default/jbossmq-state.xml";
72    private URL JavaDoc systemConfigURL;
73    
74    /**
75     * Constructor for the StateManager object
76     *
77     * @exception XElementException Description of Exception
78     */

79    public OldStateManager() throws XElementException
80    {
81       //loggedOnClientIds = new HashSet();
82
}
83
84    protected void createService() throws Exception JavaDoc {
85       // Get the system configuration URL
86
systemConfigURL = ServerConfigLocator.locate().getServerConfigURL();
87    }
88    
89    /**
90     * Sets the StateFile attribute of the StateManagerMBean object
91     *
92     * @jmx:managed-attribute
93     *
94     * @param newStateFile The new StateFile value
95     */

96    public void setStateFile(String JavaDoc newStateFile)
97    {
98       stateFile = newStateFile.trim();
99    }
100
101    /**
102     * @jmx:managed-attribute
103     */

104    public StateManager getInstance()
105    {
106       return this;
107    }
108
109    /**
110     * Sets the DurableSubscription attribute of the StateManager object
111     *
112     * @param server The new DurableSubscription value
113     * @param sub The new DurableSubscription value
114     * @param topic The new DurableSubscription value
115     * @exception JMSException Description of Exception
116     */

117    public void setDurableSubscription(JMSDestinationManager server, DurableSubscriptionID sub, SpyTopic topic)
118       throws JMSException JavaDoc
119    {
120       boolean debug = log.isDebugEnabled();
121       if (debug)
122          log.debug("Checking durable subscription: " + sub + ", on topic: " + topic);
123       try
124       {
125          //Set the known Ids
126
Enumeration JavaDoc enumeration = stateConfig.getElementsNamed("User");
127          while (enumeration.hasMoreElements())
128          {
129
130             // Match the User.Name
131
XElement user = (XElement)enumeration.nextElement();
132             if (!user.containsField("Id") || !user.getField("Id").equals(sub.getClientID()))
133             {
134                continue;
135             }
136
137             if (debug)
138                log.debug("Found a matching ClientID configuration section.");
139
140             XElement subscription = null;
141
142             // Match the User/DurableSubscription.Name
143
Enumeration JavaDoc enum2 = user.getElementsNamed("DurableSubscription");
144             while (enum2.hasMoreElements())
145             {
146                XElement t = (XElement)enum2.nextElement();
147                if (t.getField("Name").equals(sub.getSubscriptionName()))
148                {
149                   subscription = t;
150                   break;
151                }
152             }
153
154             // A new subscription
155
if (subscription == null)
156             {
157                if (debug)
158                   log.debug("The subscription was not previously registered.");
159                // it was not previously registered...
160
if (topic == null)
161                {
162                   return;
163                }
164
165                JMSTopic dest = (JMSTopic)server.getJMSDestination(topic);
166                dest.createDurableSubscription(sub);
167
168                subscription = new XElement("DurableSubscription");
169                subscription.addField("Name", sub.getSubscriptionName());
170                subscription.addField("TopicName", topic.getName());
171                user.addElement(subscription);
172
173                saveConfig();
174
175             }
176             // An existing subscription...it was previously registered...
177
// Check if it is an unsubscribe, or a change of subscription.
178
else
179             {
180                if (debug)
181                   log.debug("The subscription was previously registered.");
182                
183                // The client wants an unsubscribe
184
// TODO: we are not spec compliant since we neither check if
185
// the topic has an active subscriber or if there are messages
186
// destined for the client not yet acked by the session!!!
187
if (topic == null)
188                {
189                   // we have to change the subscription...
190
SpyTopic prevTopic = new SpyTopic(subscription.getField("TopicName"));
191                   JMSTopic dest = (JMSTopic)server.getJMSDestination(prevTopic);
192                   // TODO here we should check if the client still has
193
// an active consumer
194

195                   dest.destroyDurableSubscription(sub);
196
197                   //straight deletion, remove subscription
198
subscription.removeFromParent();
199                   saveConfig();
200                }
201                // The topic previously subscribed to is not the same as the
202
// one in the subscription request.
203
// TODO: we do currently no check if the selector has changed.
204
else if (!subscription.getField("TopicName").equals(topic.getName()))
205                {
206                   //new topic so we have to change it
207
if (debug)
208                      log.debug("But the topic was different, changing the subscription.");
209                   // we have to change the subscription...
210
SpyTopic prevTopic = new SpyTopic(subscription.getField("TopicName"));
211                   JMSTopic dest = (JMSTopic)server.getJMSDestination(prevTopic);
212                   dest.destroyDurableSubscription(sub);
213
214                   dest = (JMSTopic)server.getJMSDestination(topic);
215                   dest.createDurableSubscription(sub);
216
217                   //durable subscription has new topic
218
subscription.setField("TopicName", topic.getName());
219                   saveConfig();
220                }
221             }
222             return;
223          }
224
225          // Could not find that user..
226
throw new JMSException JavaDoc("ClientID '" + sub.getClientID() +
227                                 "' cannot create durable subscriptions.");
228       }
229       catch (IOException JavaDoc e)
230       {
231          JMSException JavaDoc newE = new SpyJMSException("Could not setup the durable subscription");
232          newE.setLinkedException(e);
233          throw newE;
234       }
235       catch (XElementException e)
236       {
237          JMSException JavaDoc newE = new SpyJMSException("Could not setup the durable subscription");
238          newE.setLinkedException(e);
239          throw newE;
240       }
241
242    }
243    
244    /**
245     * Get the destination a subscription is for.
246     */

247    public SpyTopic getDurableTopic(DurableSubscriptionID sub) throws JMSException JavaDoc
248    {
249       try {
250          XElement subscription = getSubscription(sub);
251          if (subscription == null)
252             throw new JMSException JavaDoc("No durable subscription found for subscription: " + sub.getSubscriptionName());
253          
254          return new SpyTopic(subscription.getField("TopicName"));
255       }catch(XElementException e)
256       {
257          JMSException JavaDoc newE = new SpyJMSException("Could not find durable subscription");
258          newE.setLinkedException(e);
259          throw newE;
260       }
261    }
262    
263    private XElement getSubscription(DurableSubscriptionID sub) throws JMSException JavaDoc,XElementException {
264       boolean debug = log.isDebugEnabled();
265
266       //Set the known Ids
267
XElement subscription = null;
268       Enumeration JavaDoc enumeration = stateConfig.getElementsNamed("User");
269       while (enumeration.hasMoreElements())
270       {
271             
272          // Match the User.Name
273
XElement user = (XElement)enumeration.nextElement();
274          if (!user.containsField("Id") || !user.getField("Id").equals(sub.getClientID()))
275          {
276             continue;
277          }
278
279          if (debug)
280             log.debug("Found a matching ClientID configuration section.");
281
282          //XElement subscription = null;
283

284          // Match the User/DurableSubscription.Name
285
Enumeration JavaDoc enum2 = user.getElementsNamed("DurableSubscription");
286          while (enum2.hasMoreElements())
287          {
288             XElement t = (XElement)enum2.nextElement();
289             if (t.getField("Name").equals(sub.getSubscriptionName()))
290             {
291                subscription = t;
292                //break;
293
return subscription;
294             }
295          }
296       }
297       // Nothing found will be null
298
return subscription;
299    }
300
301    /**
302     * Gets the StateFile attribute of the StateManagerMBean object
303     *
304     * @jmx:managed-attribute
305     *
306     * @return The StateFile value
307     */

308    public String JavaDoc getStateFile()
309    {
310       return stateFile;
311    }
312
313    /**
314     * #Description of the Method
315     *
316     * @param login Description of Parameter
317     * @param passwd Description of Parameter
318     * @return Description of the Returned Value
319     * @exception JMSException Description of Exception
320     */

321    public String JavaDoc checkUser(String JavaDoc login, String JavaDoc passwd) throws JMSException JavaDoc
322    {
323       try
324       {
325          synchronized (stateConfig)
326          {
327
328             Enumeration JavaDoc enumeration = stateConfig.getElementsNamed("User");
329             while (enumeration.hasMoreElements())
330             {
331                XElement element = (XElement)enumeration.nextElement();
332                String JavaDoc name = element.getField("Name");
333                if (!name.equals(login))
334                {
335                   continue;
336                }
337
338                String JavaDoc pw = element.getField("Password");
339                if (!passwd.equals(pw))
340                {
341                   throw new JMSException JavaDoc("Bad password");
342                }
343
344                String JavaDoc clientId = null;
345                if (element.containsField("Id"))
346                {
347                   clientId = element.getField("Id");
348                }
349
350                if (clientId != null)
351                {
352                   synchronized (loggedOnClientIds)
353                   {
354                      if (loggedOnClientIds.contains(clientId))
355                      {
356                         throw new JMSSecurityException JavaDoc
357                            ("The login id has an assigned client id. " +
358                             "That client id is already connected to the server!");
359                      }
360                      loggedOnClientIds.add(clientId);
361                   }
362                }
363
364                return clientId;
365             }
366             throw new JMSSecurityException JavaDoc("This user does not exist");
367          }
368       }
369       catch (XElementException e)
370       {
371          log.error(e);
372          throw new JMSException JavaDoc("Invalid server user configuration.");
373       }
374    }
375
376    /**
377     * Ad a logged in clientID to the statemanager.
378     *
379     * The clientID must not be active, and it must not be password protected.
380     *
381     * @param ID The feature to be added to the LoggedOnClientId
382     * attribute
383     * @exception JMSException Description of Exception
384     */

385    public void addLoggedOnClientId(String JavaDoc ID) throws JMSException JavaDoc
386    {
387
388       //Check : this ID must not be registered
389
synchronized (loggedOnClientIds)
390       {
391          if (loggedOnClientIds.contains(ID))
392          {
393             throw new InvalidClientIDException JavaDoc("This loggedOnClientIds is already registered !");
394          }
395       }
396
397       //Check : this ID must not be password protected
398
synchronized (stateConfig)
399       {
400          Enumeration JavaDoc enumeration = stateConfig.getElementsNamed("User");
401          while (enumeration.hasMoreElements())
402          {
403             XElement element = (XElement)enumeration.nextElement();
404             try
405             {
406                if (element.containsField("Id") && element.getField("Id").equals(ID))
407                {
408                   throw new InvalidClientIDException JavaDoc("This loggedOnClientIds is password protected !");
409                }
410             }
411             catch (XElementException ignore)
412             {
413             }
414          }
415
416       }
417       synchronized (loggedOnClientIds)
418       {
419          loggedOnClientIds.add(ID);
420       }
421    }
422
423    /**
424     * #Description of the Method
425     *
426     * @param ID Description of Parameter
427     */

428    public void removeLoggedOnClientId(String JavaDoc ID)
429    {
430       synchronized (loggedOnClientIds)
431       {
432          loggedOnClientIds.remove(ID);
433       }
434    }
435
436    /**
437     * #Description of the Method
438     *
439     * @exception Exception Description of Exception
440     */

441    public void startService() throws Exception JavaDoc
442    {
443
444       loadConfig();
445    }
446
447    public Collection JavaDoc getDurableSubscriptionIdsForTopic(SpyTopic topic)
448       throws JMSException JavaDoc
449    {
450       Collection JavaDoc durableSubs = new ArrayList JavaDoc();
451       try
452       {
453          Enumeration JavaDoc enumeration = stateConfig.getElementsNamed("User/DurableSubscription");
454          while (enumeration.hasMoreElements())
455          {
456             XElement element = (XElement)enumeration.nextElement();
457
458             String JavaDoc clientId = element.getField("../Id");
459             String JavaDoc name = element.getField("Name");
460             String JavaDoc topicName = element.getField("TopicName");
461             if (topic.getName().equals(topicName))
462             {
463                durableSubs.add(new DurableSubscriptionID(clientId, name, null));
464             } // end of if ()
465

466          }
467       }
468       catch (XElementException e)
469       {
470          JMSException JavaDoc jmse = new JMSException JavaDoc("Error in statemanager xml");
471          jmse.setLinkedException(e);
472          throw jmse;
473       } // end of try-catch
474
return durableSubs;
475    }
476    
477    /**
478     * #Description of the Method
479     *
480     * @param server Description of Parameter
481     * @exception XElementException Description of Exception
482     */

483    /*
484      public void initDurableSubscriptions(JMSServer server) throws XElementException
485      {
486
487      //Set the known Ids
488      Enumeration enum = stateConfig.getElementsNamed("User/DurableSubscription");
489      while (enum.hasMoreElements())
490      {
491      XElement element = (XElement)enum.nextElement();
492
493      String clientId = element.getField("../Id");
494      String name = element.getField("Name");
495      String topicName = element.getField("TopicName");
496
497      try
498      {
499
500      log.debug("Restarting Durable Subscription: " + clientId + "," + name + "," + topicName);
501      SpyTopic topic = new SpyTopic(topicName);
502      JMSTopic dest = (JMSTopic)server.getJMSDestination(topic);
503      if (dest == null)
504      {
505      log.warn("Subscription topic of not found: " + topicName);
506      log.warn("Subscription cannot be initialized: " + clientId + "," + name);
507      element.removeFromParent();
508      }
509      else
510      {
511      dest.createDurableSubscription(new DurableSubscriptionID(clientId, name));
512      }
513
514      }
515      catch (JMSException e)
516      {
517      log.error("Could not initialize a durable subscription for : Client Id=" + clientId + ", Name=" + name + ", Topic Name=" + topicName, e);
518      }
519      }
520
521      }
522    */

523    
524    /**
525     * @jmx:managed-operation
526     */

527    public void loadConfig() throws IOException JavaDoc, XElementException
528    {
529       URL JavaDoc configURL = new URL JavaDoc(systemConfigURL, stateFile);
530       if (log.isDebugEnabled()) {
531          log.debug("Loading config from: " + configURL);
532       }
533       
534       InputStream JavaDoc in = new BufferedInputStream JavaDoc(configURL.openStream());
535       try {
536          stateConfig = XElement.createFrom(in);
537       }
538       finally {
539          in.close();
540       }
541    }
542
543    /**
544     * @jmx:managed-operation
545     */

546    public void saveConfig() throws IOException JavaDoc
547    {
548       URL JavaDoc configURL = new URL JavaDoc(systemConfigURL, stateFile);
549       
550       if (configURL.getProtocol().equals("file")) {
551          File JavaDoc file = new File JavaDoc(configURL.getFile());
552          if (log.isDebugEnabled()) {
553             log.debug("Saving config to: " + file);
554          }
555
556          PrintStream JavaDoc stream = new PrintStream JavaDoc(new FileOutputStream JavaDoc(file));
557          try {
558             stream.print(stateConfig.toXML(true));
559          }
560          finally {
561             stream.close();
562          }
563       }
564       else {
565          log.error("Can not save configuration to non-file URL: " + configURL);
566       }
567    }
568
569    /**
570     * @jmx:managed-operation
571     */

572    public String JavaDoc displayStateConfig() throws Exception JavaDoc
573    {
574       return stateConfig.toString();
575    }
576
577    /*
578      Does not seem to be used
579    public class Identity
580    {
581       String login;
582       String passwd;
583       String loggedOnClientIds;
584
585       Identity(final String login,
586                final String passwd,
587                final String loggedOnClientIds)
588       {
589          this.login = login;
590          this.passwd = passwd;
591          this.loggedOnClientIds = loggedOnClientIds;
592       }
593
594    }
595    */

596 }
597
Popular Tags