aboutsummaryrefslogtreecommitdiffstats
path: root/ecomp-sdk-app/src/main/java/org/openecomp/policy/admin/PAPNotificationBroadcaster.java
blob: cff0828e201d00989b8115bfe70be9a530238611 (plain)
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
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
/*-
 * ============LICENSE_START=======================================================
 * ECOMP Policy Engine
 * ================================================================================
 * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
 * ================================================================================
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * 
 *      http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 * ============LICENSE_END=========================================================
 */

package org.openecomp.policy.admin;


import java.io.Serializable;
import java.util.LinkedList;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;


import org.openecomp.policy.common.logging.flexlogger.FlexLogger; 
import org.openecomp.policy.common.logging.flexlogger.Logger;

/**
 * Handle Notifications from the PAP that the PDP Groups have been changed.
 * We need a Server Push Broadcaster because there may be multiple Vaadin instances (i.e. Users) that need to be told when a change occurs.
 * 
 * Initially we only update the entire set of PDPGroups in one shot.
 * 
 * (Code copied from Book of Vaadin chapter on Server Push
 *
 */
public class PAPNotificationBroadcaster implements Serializable {
	/**
	 * 
	 */
	private static final long serialVersionUID = -2539940306348821754L;


	private static Logger logger	= FlexLogger.getLogger(PAPNotificationBroadcaster.class);

	
    static ExecutorService executorService = Executors.newSingleThreadExecutor();

    /**
     * Interface used by all classes that need to be notified when PAP sends an update message.
     * 
     *
     */
    public interface PAPNotificationBroadcastListener {
        void updateAllGroups();
    }
    
    
    
    /*
     * list of registered listeners
     */
    private static LinkedList<PAPNotificationBroadcastListener> listeners =
        new LinkedList<PAPNotificationBroadcastListener>();
    
    /**
     * Listener registers to hear about updates.
     * @param listener
     */
    public static synchronized void register(
    		PAPNotificationBroadcastListener listener) {
        listeners.add(listener);
    }
    
    
    /**
     * Listener is going away.
     * 
     * @param listener
     */
    public static synchronized void unregister(
    		PAPNotificationBroadcastListener listener) {
        listeners.remove(listener);
    }
    
    
    
    /**
     * Tell all listeners about an update.
     * 
     * @param message
     */
    public static synchronized void updateAllGroups() {
        for (final PAPNotificationBroadcastListener listener: listeners) {
  // Original code copied from example:
  //          executorService.execute(new Runnable() {
  //              @Override
  //              public void run() {
  // The problem with this is that the execute starts a new Thread, but the thing we are calling (the listener.updateAllGroups)
  // happens in this case to ALSO create a new thread, and it locks up because the shared threadpool queue is already locked by this method.
  // On application shutdown that left us with a blocked thread, so the process never goes away.
  // Since the listener.updateAllGroups does ALL of its work inside a new Runnable thread, there should be no need for this method to also create a thread.
  
        	/*
        	 * IMPORTANT:
        	 * All listeners MUST either execute with no possibility of blocking
        	 * OR must start their own threads to handle blocking and concurrent operations.
        	 */
        	if (logger.isDebugEnabled()) {
        		logger.debug("updateAllGroups");
        	}
            listener.updateAllGroups();
        }
    }
}