View Javadoc

1   package org.apache.maven.continuum.notification;
2   
3   /*
4    * Licensed to the Apache Software Foundation (ASF) under one
5    * or more contributor license agreements.  See the NOTICE file
6    * distributed with this work for additional information
7    * regarding copyright ownership.  The ASF licenses this file
8    * to you under the Apache License, Version 2.0 (the
9    * "License"); you may not use this file except in compliance
10   * with the License.  You may obtain a copy of the License at
11   *
12   *   http://www.apache.org/licenses/LICENSE-2.0
13   *
14   * Unless required by applicable law or agreed to in writing,
15   * software distributed under the License is distributed on an
16   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17   * KIND, either express or implied.  See the License for the
18   * specific language governing permissions and limitations
19   * under the License.
20   */
21  
22  import org.apache.continuum.dao.ProjectDao;
23  import org.apache.continuum.dao.ProjectGroupDao;
24  import org.apache.continuum.model.project.ProjectScmRoot;
25  import org.apache.maven.continuum.model.project.BuildDefinition;
26  import org.apache.maven.continuum.model.project.BuildResult;
27  import org.apache.maven.continuum.model.project.Project;
28  import org.apache.maven.continuum.model.project.ProjectGroup;
29  import org.apache.maven.continuum.model.project.ProjectNotifier;
30  import org.apache.maven.continuum.notification.manager.NotifierManager;
31  import org.apache.maven.continuum.store.ContinuumStoreException;
32  import org.slf4j.Logger;
33  import org.slf4j.LoggerFactory;
34  
35  import java.util.ArrayList;
36  import java.util.HashMap;
37  import java.util.List;
38  import java.util.Map;
39  
40  /**
41   * @author <a href="mailto:trygvis@inamo.no">Trygve Laugst&oslash;l</a>
42   * @version $Id: DefaultContinuumNotificationDispatcher.java 1372260 2012-08-13 04:29:09Z brett $
43   * @plexus.component role="org.apache.maven.continuum.notification.ContinuumNotificationDispatcher"
44   * role-hint="default"
45   */
46  public class DefaultContinuumNotificationDispatcher
47      implements ContinuumNotificationDispatcher
48  {
49      private static final Logger log = LoggerFactory.getLogger( DefaultContinuumNotificationDispatcher.class );
50  
51      /**
52       * @plexus.requirement
53       */
54      private NotifierManager notifierManager;
55  
56      /**
57       * @plexus.requirement
58       */
59      private ProjectDao projectDao;
60  
61      /**
62       * @plexus.requirement
63       */
64      private ProjectGroupDao projectGroupDao;
65  
66      // ----------------------------------------------------------------------
67      // ContinuumNotificationDispatcher Implementation
68      // ----------------------------------------------------------------------
69  
70      public void buildStarted( Project project, BuildDefinition buildDefinition )
71      {
72          sendNotification( MESSAGE_ID_BUILD_STARTED, project, buildDefinition, null );
73      }
74  
75      public void checkoutStarted( Project project, BuildDefinition buildDefinition )
76      {
77          sendNotification( MESSAGE_ID_CHECKOUT_STARTED, project, buildDefinition, null );
78      }
79  
80      public void checkoutComplete( Project project, BuildDefinition buildDefinition )
81      {
82          sendNotification( MESSAGE_ID_CHECKOUT_COMPLETE, project, buildDefinition, null );
83      }
84  
85      public void runningGoals( Project project, BuildDefinition buildDefinition, BuildResult buildResult )
86      {
87          sendNotification( MESSAGE_ID_RUNNING_GOALS, project, buildDefinition, buildResult );
88      }
89  
90      public void goalsCompleted( Project project, BuildDefinition buildDefinition, BuildResult buildResult )
91      {
92          sendNotification( MESSAGE_ID_GOALS_COMPLETED, project, buildDefinition, buildResult );
93      }
94  
95      public void buildComplete( Project project, BuildDefinition buildDefinition, BuildResult buildResult )
96      {
97          sendNotification( MESSAGE_ID_BUILD_COMPLETE, project, buildDefinition, buildResult );
98      }
99  
100     public void prepareBuildComplete( ProjectScmRoot projectScmRoot )
101     {
102         sendNotification( MESSAGE_ID_PREPARE_BUILD_COMPLETE, projectScmRoot );
103     }
104 
105     // ----------------------------------------------------------------------
106     //
107     // ----------------------------------------------------------------------
108 
109     private void sendNotification( String messageId, Project project, BuildDefinition buildDefinition,
110                                    BuildResult buildResult )
111     {
112         // ----------------------------------------------------------------------
113         // The objects are reread from the store to make sure they're getting the "final"
114         // state of the objects. Ideally this should be done on a per notifier basis or the
115         // objects should be made read only.
116         // ----------------------------------------------------------------------
117 
118         try
119         {
120             // TODO: remove re-reading?
121             // Here we need to get all the project details
122             //  - builds are used to detect if the state has changed (TODO: maybe previousState field is better)
123             //  - notifiers are used to send the notification
124             //  - scm results are used to detect if scm failed
125             project = projectDao.getProjectWithAllDetails( project.getId() );
126 
127             ProjectGroup projectGroup = projectGroupDao.getProjectGroupWithBuildDetailsByProjectGroupId(
128                 project.getProjectGroup().getId() );
129 
130             Map<String, List<ProjectNotifier>> notifiersMap = new HashMap<String, List<ProjectNotifier>>();
131 
132             getProjectNotifiers( project, notifiersMap );
133             getProjectGroupNotifiers( projectGroup, notifiersMap );
134 
135             for ( String notifierType : notifiersMap.keySet() )
136             {
137                 MessageContext context = new MessageContext();
138                 context.setProject( project );
139                 context.setBuildDefinition( buildDefinition );
140 
141                 if ( buildResult != null )
142                 {
143                     context.setBuildResult( buildResult );
144                 }
145 
146                 List<ProjectNotifier> projectNotiiers = notifiersMap.get( notifierType );
147                 context.setNotifier( projectNotiiers );
148 
149                 sendNotification( messageId, context );
150             }
151         }
152         catch ( ContinuumStoreException e )
153         {
154             log.error( "Error while population the notification context.", e );
155         }
156     }
157 
158     private void sendNotification( String messageId, ProjectScmRoot projectScmRoot )
159     {
160         try
161         {
162             ProjectGroup group = projectGroupDao.getProjectGroupWithBuildDetailsByProjectGroupId(
163                 projectScmRoot.getProjectGroup().getId() );
164 
165             Map<String, List<ProjectNotifier>> notifiersMap = new HashMap<String, List<ProjectNotifier>>();
166             getProjectGroupNotifiers( group, notifiersMap );
167 
168             for ( String notifierType : notifiersMap.keySet() )
169             {
170                 MessageContext context = new MessageContext();
171                 context.setProjectScmRoot( projectScmRoot );
172 
173                 List<ProjectNotifier> projectNotifiers = notifiersMap.get( notifierType );
174                 context.setNotifier( projectNotifiers );
175 
176                 sendNotification( messageId, context );
177             }
178 
179         }
180         catch ( ContinuumStoreException e )
181         {
182             log.error( "Error while population the notification context.", e );
183         }
184     }
185 
186     private void sendNotification( String messageId, MessageContext context )
187     {
188         String notifierType = context.getNotifiers().get( 0 ).getType();
189 
190         try
191         {
192             Notifier notifier = notifierManager.getNotifier( notifierType );
193 
194             notifier.sendMessage( messageId, context );
195         }
196         catch ( NotificationException e )
197         {
198             log.error( "Error while trying to use the " + notifierType + " notifier.", e );
199         }
200     }
201 
202     private void getProjectNotifiers( Project project, Map<String, List<ProjectNotifier>> notifiersMap )
203     {
204         if ( project.getNotifiers() != null )
205         {
206             // perform the project level notifications
207             for ( ProjectNotifier notifier : (List<ProjectNotifier>) project.getNotifiers() )
208             {
209                 List<ProjectNotifier> notifiers = notifiersMap.get( notifier.getType() );
210                 if ( notifiers == null )
211                 {
212                     notifiers = new ArrayList<ProjectNotifier>();
213                 }
214 
215                 if ( !notifier.isEnabled() )
216                 {
217                     log.info( notifier.getType() + " notifier (id=" + notifier.getId() + ") is disabled." );
218 
219                     continue;
220                 }
221 
222                 notifiers.add( notifier );
223                 notifiersMap.put( notifier.getType(), notifiers );
224             }
225         }
226     }
227 
228     private void getProjectGroupNotifiers( ProjectGroup projectGroup, Map<String, List<ProjectNotifier>> notifiersMap )
229     {
230         // perform the project group level notifications
231         if ( projectGroup.getNotifiers() != null )
232         {
233             for ( ProjectNotifier projectNotifier : (List<ProjectNotifier>) projectGroup.getNotifiers() )
234             {
235                 List<ProjectNotifier> projectNotifiers = notifiersMap.get( projectNotifier.getType() );
236                 if ( projectNotifiers == null )
237                 {
238                     projectNotifiers = new ArrayList<ProjectNotifier>();
239                 }
240 
241                 if ( !projectNotifier.isEnabled() )
242                 {
243                     log.info( projectNotifier.getType() + " projectNotifier (id=" + projectNotifier.getId() +
244                                   ") is disabled." );
245 
246                     continue;
247                 }
248 
249                 projectNotifiers.add( projectNotifier );
250                 notifiersMap.put( projectNotifier.getType(), projectNotifiers );
251             }
252         }
253     }
254 }