View Javadoc

1   /*
2    * Copyright 2007-2009 Hippo
3    *
4    * Licensed under the Apache License, Version 2.0 (the  "License"); 
5    * you may not use this file except in compliance with the License. 
6    * You may obtain a copy of the License at
7    *
8    * http://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" 
12   * BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
13   * See the License for the specific language governing permissions and 
14   * limitations under the License.
15   */
16  package nl.hippo.client.event;
17  
18  import java.util.Properties;
19  import javax.jms.JMSException;
20  import javax.jms.Session;
21  import javax.jms.Topic;
22  import javax.jms.TopicConnection;
23  import javax.jms.TopicConnectionFactory;
24  import javax.jms.TopicSession;
25  import javax.jms.TopicSubscriber;
26  import javax.naming.InitialContext;
27  import javax.naming.NamingException;
28  
29  import nl.hippo.client.api.ClientException;
30  import nl.hippo.client.event.service.UpdateNotificationConfig;
31  
32  public class JmsTopicManager {
33  
34      private UpdateNotificationConfig config;
35      private TopicConnection connection;
36      private TopicSession session;
37      private Topic topic;
38      private TopicSubscriber subscriber;
39      private String jtmLoglabel;
40  
41      public JmsTopicManager(UpdateNotificationConfig config) throws ClientException {
42          this.config = config;
43          if(config.getLoglabel() == null) { 
44              jtmLoglabel = "";
45          } else {
46              jtmLoglabel = config.getLoglabel();
47          }
48      }
49  
50      public TopicConnection getConnection() {
51          return connection;
52      }
53  
54      public Topic getTopic() {
55          return topic;
56      }
57  
58      public TopicSession getSession() {
59          return session;
60      }
61  
62      public TopicSubscriber getSubscriber() {
63          return subscriber;
64      }
65      
66      public String getLoglabel() {
67          return jtmLoglabel;
68      }
69  
70      public synchronized void start() {
71          EventLogger.log.info(jtmLoglabel + "Initialize JMS");
72  
73          boolean success = shutDown() && initialize();
74          while (!success) {
75              EventLogger.log.warn(jtmLoglabel + "Initializing JMS failed, will retry in " + config.getReconnectDelay()
76                      + " milliseconds.");
77              try {
78                  Thread.sleep(config.getReconnectDelay());
79              } catch (InterruptedException e1) {
80                  //Ignore this
81              }
82              success = shutDown() && initialize();
83          }
84  
85          try {
86              connection.setExceptionListener(new JmsReconnector(this));
87          } catch (JMSException e) {
88              EventLogger.log.warn(jtmLoglabel + "Failed to set JMS Exception listener: " + e.getMessage());
89          }
90  
91          EventLogger.log.info(jtmLoglabel + "JMS initialization successful");
92      }
93  
94      private synchronized boolean initialize() {
95          TopicConnectionFactory factory = null;
96          InitialContext context = null;
97  
98          Properties jndiProps = config.getJndiProperties();
99          try {
100             if (jndiProps.getProperty(UpdateNotificationConfig.JNDI_INITIAL_CONTEXT_FACTORY) == null) {
101                 context = new InitialContext();
102             } else {
103                 context = new InitialContext(jndiProps);
104             }
105         } catch (NamingException e) {
106             StringBuffer buf = new StringBuffer().append(jtmLoglabel).append("Failed to create JNDI initial context: ").append(
107                     e.getExplanation()).append("\n").append("using JNDI properties: " + jndiProps);
108             EventLogger.log.error(buf.toString());
109             return false;
110         }
111 
112         try {
113             factory = (TopicConnectionFactory) context.lookup(config.getConnectionFactory());
114         } catch (NamingException e) {
115             EventLogger.log.warn(jtmLoglabel + "Failed to lookup JMS Topic connection factory: " + e.getExplanation());
116             return false;
117         }
118 
119         try {
120             topic = (Topic) context.lookup(config.getTopic());
121         } catch (NamingException e) {
122             EventLogger.log.warn(jtmLoglabel + "Failed to lookup JMS Topic: " + e.getExplanation());
123             return false;
124         }
125 
126         try {
127             if (config.getUserName() == null) {
128                 connection = factory.createTopicConnection();
129             } else {
130                 connection = factory.createTopicConnection(config.getUserName(), config.getPassword());
131             }
132         } catch (JMSException e) {
133             EventLogger.log.warn(jtmLoglabel + "Failed to create JMS Topic connection: " + e.getMessage());
134             return false;
135         }
136 
137         try {
138             session = connection.createTopicSession(false, Session.AUTO_ACKNOWLEDGE);
139         } catch (JMSException e) {
140             EventLogger.log.warn(jtmLoglabel + "Failed to create JMS Topic session: " + e.getMessage());
141             return false;
142         }
143 
144         try {
145             subscriber = session.createSubscriber(topic);
146         } catch (JMSException e) {
147             EventLogger.log.warn(jtmLoglabel + "Failed to create JMS Topic subscriber: " + e.getMessage());
148             return false;
149         }
150 
151         try {
152             connection.start();
153         } catch (JMSException e) {
154             EventLogger.log.warn(jtmLoglabel + "Failed to start JMS connection: " + e.getMessage());
155             return false;
156         }
157 
158         try {
159             session.recover();
160         } catch (JMSException e) {
161             EventLogger.log.warn(jtmLoglabel + "Failed to recover JMS session: " + e.getMessage());
162             return false;
163         }
164 
165         return true;
166     }
167 
168     public void stop() {
169         EventLogger.log.info(jtmLoglabel + "Stopping JMS");
170         if (shutDown()) {
171             EventLogger.log.info(jtmLoglabel + "JMS shutdown successful");
172         }
173     }
174 
175     private synchronized boolean shutDown() {
176         boolean success = true;
177 
178         if (subscriber != null) {
179             try {
180                 subscriber.close();
181                 subscriber = null;
182             } catch (JMSException e) {
183                 EventLogger.log.warn(jtmLoglabel + "Failed to close JMS subscriber: " + e.getMessage());
184                 success = false;
185             }
186         }
187 
188         topic = null;
189 
190         if (session != null) {
191             try {
192                 session.close();
193                 session = null;
194             } catch (JMSException e) {
195                 EventLogger.log.warn(jtmLoglabel + "Failed to close JMS session: " + e.getMessage());
196                 success = false;
197             }
198         }
199 
200         if (connection != null) {
201             try {
202                 connection.close();
203                 connection = null;
204             } catch (JMSException e) {
205                 EventLogger.log.warn(jtmLoglabel + "Failed to close JMS connection: " + e.getMessage());
206                 success = false;
207             }
208         }
209 
210         return success;
211     }
212 
213 }