blob: 2124d253728d650fa76eb19177c3a768a54da5d4 [file] [log] [blame]
Jonathan Hartaa380972014-04-03 10:24:46 -07001package net.onrc.onos.core.intent;
Toshio Koideb609b3b2014-02-14 18:25:52 -08002
3import java.util.Collection;
4import java.util.EventListener;
5import java.util.HashMap;
6import java.util.HashSet;
Toshio Koideb609b3b2014-02-14 18:25:52 -08007import java.util.LinkedList;
Toshio Koideb609b3b2014-02-14 18:25:52 -08008import java.util.Map.Entry;
9
Jonathan Hartaa380972014-04-03 10:24:46 -070010import net.onrc.onos.core.intent.Intent.IntentState;
11import net.onrc.onos.core.intent.runtime.IntentStateList;
Toshio Koideb609b3b2014-02-14 18:25:52 -080012
13/**
14 * @author Toshio Koide (t-koide@onlab.us)
15 */
16public class IntentMap {
Ray Milkey269ffb92014-04-03 14:43:30 -070017 private HashSet<ChangedListener> listeners = new HashSet<>();
18 private HashMap<String, Intent> intents = new HashMap<>();
19 private LinkedList<ChangedEvent> events = new LinkedList<>();
Toshio Koidedf2eab92014-02-20 11:24:59 -080020
Ray Milkey269ffb92014-04-03 14:43:30 -070021 public enum ChangedEventType {
22 /**
23 * Added new intent.
24 */
25 ADDED,
Toshio Koideb609b3b2014-02-14 18:25:52 -080026
Ray Milkey269ffb92014-04-03 14:43:30 -070027 /**
28 * Removed existing intent.
29 * The specified intent is an instance of Intent class (not a child class)
30 * Only id and state are valid.
31 */
32 REMOVED,
Toshio Koideb609b3b2014-02-14 18:25:52 -080033
Ray Milkey269ffb92014-04-03 14:43:30 -070034 /**
35 * Changed state of existing intent.
36 * The specified intent is an instance of Intent class (not a child class)
37 * Only id and state are valid.
38 */
39 STATE_CHANGED,
40 }
Toshio Koideb609b3b2014-02-14 18:25:52 -080041
Ray Milkey269ffb92014-04-03 14:43:30 -070042 public class ChangedEvent {
43 public ChangedEvent(ChangedEventType eventType, Intent intent) {
44 this.eventType = eventType;
45 this.intent = intent;
46 }
Toshio Koideb609b3b2014-02-14 18:25:52 -080047
Ray Milkey269ffb92014-04-03 14:43:30 -070048 public ChangedEventType eventType;
49 public Intent intent;
50 }
Toshio Koideb609b3b2014-02-14 18:25:52 -080051
Ray Milkey269ffb92014-04-03 14:43:30 -070052 public interface ChangedListener extends EventListener {
53 void intentsChange(LinkedList<ChangedEvent> events);
54 }
Toshio Koideb609b3b2014-02-14 18:25:52 -080055
Ray Milkey269ffb92014-04-03 14:43:30 -070056 //================================================================================
57 // public methods
58 //================================================================================
Toshio Koideb609b3b2014-02-14 18:25:52 -080059
Ray Milkey269ffb92014-04-03 14:43:30 -070060 public void executeOperations(IntentOperationList operations) {
61 for (IntentOperation operation : operations) {
62 switch (operation.operator) {
63 case ADD:
64 handleAddOperation(operation);
65 break;
66 case REMOVE:
67 handleRemoveOperation(operation);
68 break;
69 case ERROR:
70 handleErrorOperation(operation);
71 break;
72 }
73 }
74 notifyEvents();
75 }
Toshio Koidedf2eab92014-02-20 11:24:59 -080076
Ray Milkey269ffb92014-04-03 14:43:30 -070077 public void purge() {
78 LinkedList<String> removeIds = new LinkedList<>();
79 for (Entry<String, Intent> entry : intents.entrySet()) {
80 Intent intent = entry.getValue();
81 if (intent.getState() == IntentState.DEL_ACK
82 || intent.getState() == IntentState.INST_NACK) {
83 removeIds.add(intent.getId());
84 }
85 }
86 for (String intentId : removeIds) {
87 removeIntent(intentId);
88 }
89 notifyEvents();
90 }
Toshio Koidedf2eab92014-02-20 11:24:59 -080091
Ray Milkey269ffb92014-04-03 14:43:30 -070092 public void changeStates(IntentStateList states) {
93 for (Entry<String, IntentState> state : states.entrySet()) {
94 setState(state.getKey(), state.getValue());
95 }
96 notifyEvents();
97 }
Toshio Koideb609b3b2014-02-14 18:25:52 -080098
Ray Milkey269ffb92014-04-03 14:43:30 -070099 public Intent getIntent(String intentId) {
100 return intents.get(intentId);
101 }
Toshio Koideb609b3b2014-02-14 18:25:52 -0800102
Ray Milkey269ffb92014-04-03 14:43:30 -0700103 public Collection<Intent> getAllIntents() {
104 return intents.values();
105 }
Toshio Koideb609b3b2014-02-14 18:25:52 -0800106
Ray Milkey269ffb92014-04-03 14:43:30 -0700107 public void addChangeListener(ChangedListener listener) {
108 listeners.add(listener);
109 }
Toshio Koidedf2eab92014-02-20 11:24:59 -0800110
Ray Milkey269ffb92014-04-03 14:43:30 -0700111 public void removeChangedListener(ChangedListener listener) {
112 listeners.remove(listener);
113 }
Toshio Koidedf2eab92014-02-20 11:24:59 -0800114
Ray Milkey269ffb92014-04-03 14:43:30 -0700115 //================================================================================
116 // methods that affect intents map (protected)
117 //================================================================================
Toshio Koidedf2eab92014-02-20 11:24:59 -0800118
Ray Milkey269ffb92014-04-03 14:43:30 -0700119 protected void putIntent(Intent intent) {
120 if (intents.containsKey(intent.getId()))
121 removeIntent(intent.getId());
122 intents.put(intent.getId(), intent);
123 events.add(new ChangedEvent(ChangedEventType.ADDED, intent));
124 }
Toshio Koidedf2eab92014-02-20 11:24:59 -0800125
Ray Milkey269ffb92014-04-03 14:43:30 -0700126 protected void removeIntent(String intentId) {
127 Intent intent = intents.remove(intentId);
128 if (intent == null) return;
129 events.add(new ChangedEvent(ChangedEventType.REMOVED, intent));
130 }
Toshio Koidedf2eab92014-02-20 11:24:59 -0800131
Ray Milkey269ffb92014-04-03 14:43:30 -0700132 protected void setState(String intentId, IntentState state) {
133 Intent intent = intents.get(intentId);
134 if (intent == null) return;
135 intent.setState(state);
136 events.add(new ChangedEvent(ChangedEventType.STATE_CHANGED, intent));
137 }
Toshio Koidedf2eab92014-02-20 11:24:59 -0800138
Ray Milkey269ffb92014-04-03 14:43:30 -0700139 //================================================================================
140 // helper methods (protected)
141 //================================================================================
Toshio Koidedf2eab92014-02-20 11:24:59 -0800142
Ray Milkey269ffb92014-04-03 14:43:30 -0700143 protected void handleAddOperation(IntentOperation operation) {
144 putIntent(operation.intent);
145 }
Toshio Koidedf2eab92014-02-20 11:24:59 -0800146
Ray Milkey269ffb92014-04-03 14:43:30 -0700147 protected void handleRemoveOperation(IntentOperation operation) {
148 Intent intent = getIntent(operation.intent.getId());
149 if (intent == null) {
150 // TODO error handling
Ray Milkey1aa71f82014-04-08 16:23:24 -0700151 return;
Ray Milkey269ffb92014-04-03 14:43:30 -0700152 } else {
153 setState(intent.getId(), IntentState.DEL_REQ);
154 }
155 }
Toshio Koidedf2eab92014-02-20 11:24:59 -0800156
Ray Milkey269ffb92014-04-03 14:43:30 -0700157 protected void handleErrorOperation(IntentOperation operation) {
158 //TODO put error message into the intent
Toshio Koidedf2eab92014-02-20 11:24:59 -0800159
Ray Milkey269ffb92014-04-03 14:43:30 -0700160 ErrorIntent errorIntent = (ErrorIntent) operation.intent;
161 Intent targetIntent = intents.get(errorIntent.getId());
162 if (targetIntent == null) {
163 // TODO error handling
164 return;
165 }
Toshio Koidedf2eab92014-02-20 11:24:59 -0800166
Ray Milkey269ffb92014-04-03 14:43:30 -0700167 switch (targetIntent.getState()) {
168 case CREATED:
169 case INST_REQ:
170 case INST_ACK:
171 case REROUTE_REQ:
172 setState(targetIntent.getId(), IntentState.INST_NACK);
173 break;
174 case DEL_REQ:
175 setState(targetIntent.getId(), IntentState.DEL_PENDING);
176 break;
177 case INST_NACK:
178 case DEL_PENDING:
179 case DEL_ACK:
180 // do nothing
181 break;
182 }
183 }
184
185 protected void notifyEvents() {
186 for (ChangedListener listener : listeners) {
187 listener.intentsChange(events);
188 }
189 events.clear();
190 }
Toshio Koideb609b3b2014-02-14 18:25:52 -0800191}