1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34 package fr.paris.lutece.plugins.appointment.modules.solr.service;
35
36 import java.io.IOException;
37 import java.time.LocalDateTime;
38 import java.util.Comparator;
39 import java.util.List;
40 import java.util.Queue;
41 import java.util.concurrent.ConcurrentHashMap;
42 import java.util.concurrent.ConcurrentLinkedQueue;
43 import java.util.concurrent.ConcurrentMap;
44 import java.util.concurrent.atomic.AtomicBoolean;
45
46 import javax.inject.Inject;
47
48 import org.apache.solr.client.solrj.SolrServerException;
49 import fr.paris.lutece.plugins.appointment.business.planning.WeekDefinition;
50 import fr.paris.lutece.plugins.appointment.business.rule.ReservationRule;
51 import fr.paris.lutece.plugins.appointment.business.slot.Slot;
52 import fr.paris.lutece.plugins.appointment.service.AppointmentExecutorService;
53 import fr.paris.lutece.plugins.appointment.service.FormService;
54 import fr.paris.lutece.plugins.appointment.service.ReservationRuleService;
55 import fr.paris.lutece.plugins.appointment.service.SlotService;
56 import fr.paris.lutece.plugins.appointment.service.listeners.IFormListener;
57 import fr.paris.lutece.plugins.appointment.service.listeners.ISlotListener;
58 import fr.paris.lutece.plugins.appointment.service.listeners.IWeekDefinitionListener;
59 import fr.paris.lutece.plugins.appointment.web.dto.AppointmentFormDTO;
60 import fr.paris.lutece.portal.service.util.AppLogService;
61
62
63
64
65
66
67
68 public class SolrAppointmentListener implements IFormListener, ISlotListener, IWeekDefinitionListener
69 {
70 private static ConcurrentMap<Integer, AtomicBoolean> _lockIndexerIsRuning = new ConcurrentHashMap<>( );
71 private static ConcurrentMap<Integer, AtomicBoolean> _lockIndexToLunch = new ConcurrentHashMap<>( );
72 private static Queue<Slot> _queueSlotToIndex = new ConcurrentLinkedQueue<>( );
73 private static AtomicBoolean _bIndexIsRunning = new AtomicBoolean( false );
74 @Inject
75 private SolrAppointmentIndexer _solrAppointmentIndexer;
76
77
78
79
80
81
82
83 private void reindexForm( final int nIdForm )
84 {
85 AtomicBoolean bIndexIsRunning = getIndexRuningLock( nIdForm );
86 AtomicBoolean bIndexToLunch = getIndexToLunchLock( nIdForm );
87 bIndexToLunch.set( true );
88 if ( bIndexIsRunning.compareAndSet( false, true ) )
89 {
90 AppointmentExecutorService.INSTANCE.execute( ( ) -> {
91
92 StringBuilder sbLogs = new StringBuilder( );
93 try
94 {
95 sbLogs = new StringBuilder( );
96 while ( bIndexToLunch.compareAndSet( true, false ) )
97 {
98 AppointmentFormDTO appointmentForm = FormService.buildAppointmentFormWithoutReservationRule( nIdForm );
99 _solrAppointmentIndexer.deleteFormAndListSlots( nIdForm, sbLogs );
100 if ( appointmentForm.getIsActive( ) )
101 {
102 _solrAppointmentIndexer.writeFormAndListSlots( appointmentForm, sbLogs );
103 }
104 }
105 }
106 catch( IOException | SolrServerException e )
107 {
108 AppLogService.error( "Error during SolrAppointmentListener reindexForm: " + sbLogs, e );
109 }
110 finally
111 {
112 bIndexIsRunning.set( false );
113 }
114 } );
115 }
116 }
117
118
119
120
121
122
123
124 private void reindexSlot( Slot slot )
125 {
126 if ( _bIndexIsRunning.compareAndSet( false, true ) )
127 {
128
129 AppointmentExecutorService.INSTANCE.execute( ( ) -> {
130
131 StringBuilder sbLogs = new StringBuilder( );
132 try
133 {
134 _solrAppointmentIndexer.writeSlotAndForm( slot, sbLogs, _queueSlotToIndex );
135 }
136 catch( IOException e )
137 {
138 AppLogService.error( "Error during SolrAppointmentListener reindexSlot: " + sbLogs, e );
139 }
140 finally
141 {
142 _bIndexIsRunning.set( false );
143 if ( !_queueSlotToIndex.isEmpty( ) )
144 {
145 reindexSlot( _queueSlotToIndex.poll( ) );
146 }
147 }
148 } );
149 }
150 else
151 {
152
153 _queueSlotToIndex.add( slot );
154 }
155
156 }
157
158
159
160
161
162
163
164 private void deleteForm( int nIdForm )
165 {
166 StringBuilder sbLogs = new StringBuilder( );
167 try
168 {
169 _solrAppointmentIndexer.deleteFormAndListSlots( nIdForm, sbLogs );
170 }
171 catch( IOException | SolrServerException e )
172 {
173 AppLogService.error( "Error during SolrAppointmentListener deleteForm: " + sbLogs, e );
174 }
175 }
176
177 private static synchronized AtomicBoolean getIndexRuningLock( int nkey )
178 {
179 _lockIndexerIsRuning.putIfAbsent( nkey, new AtomicBoolean( false ) );
180 return _lockIndexerIsRuning.get( nkey );
181 }
182
183 private static synchronized AtomicBoolean getIndexToLunchLock( int nkey )
184 {
185 _lockIndexToLunch.putIfAbsent( nkey, new AtomicBoolean( false ) );
186 return _lockIndexToLunch.get( nkey );
187 }
188
189 @Override
190 public void notifySlotChange( int nIdSlot )
191 {
192 Slot slot = SlotService.findSlotById( nIdSlot );
193 reindexSlot( slot );
194 }
195
196 @Override
197 public void notifySlotCreation( int nIdSlot )
198 {
199 notifySlotChange( nIdSlot );
200 }
201
202 @Override
203 public void notifySlotRemoval( Slot slot )
204 {
205 if ( FormUtil.isPeriodValidToIndex( slot.getIdForm( ), slot.getDate( ), slot.getDate( ) ) )
206 {
207 reindexForm( slot.getIdForm( ) );
208 }
209 }
210
211 @Override
212 public void notifySlotEndingTimeHasChanged( int nIdSlot, int nIdFom, LocalDateTime endingDateTime )
213 {
214
215 if ( FormUtil.isPeriodValidToIndex( nIdFom, endingDateTime.toLocalDate( ), endingDateTime.toLocalDate( ) ) )
216 {
217
218 reindexForm( nIdFom );
219 }
220
221 }
222
223 @Override
224 public void notifyFormChange( int nIdForm )
225 {
226 reindexForm( nIdForm );
227 }
228
229 @Override
230 public void notifyFormCreation( int nIdForm )
231 {
232 reindexForm( nIdForm );
233 }
234
235 @Override
236 public void notifyFormRemoval( int nIdForm )
237 {
238 deleteForm( nIdForm );
239 }
240
241 @Override
242 public void notifyWeekAssigned( WeekDefinition week )
243 {
244
245 ReservationRule rule = ReservationRuleService.findReservationRuleById( week.getIdReservationRule( ) );
246 if ( FormUtil.isPeriodValidToIndex( rule.getIdForm( ), week.getDateOfApply( ), week.getEndingDateOfApply( ) ) )
247 {
248
249 reindexForm( rule.getIdForm( ) );
250 }
251
252 }
253
254 @Override
255 public void notifyWeekUnassigned( WeekDefinition week )
256 {
257
258 notifyWeekAssigned( week );
259 }
260
261 @Override
262 public void notifyListWeeksChanged( int nIdForm, List<WeekDefinition> listWeek )
263 {
264
265 WeekDefinition weekWithDateMin = listWeek.stream( ).min( Comparator.comparing( WeekDefinition::getDateOfApply ) ).orElse( null );
266 WeekDefinition weekWithDateMax = listWeek.stream( ).max( Comparator.comparing( WeekDefinition::getEndingDateOfApply ) ).orElse( null );
267 if ( weekWithDateMin != null && weekWithDateMax != null
268 && FormUtil.isPeriodValidToIndex( nIdForm, weekWithDateMin.getDateOfApply( ), weekWithDateMax.getEndingDateOfApply( ) ) )
269 {
270
271 reindexForm( nIdForm );
272 }
273 }
274
275 }