blob: 9bdb21f9e94067510eea0c07fe03021ff81762c8 [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
Pavlin Radoslavovfee80982014-04-10 12:12:04 -070042 public static class ChangedEvent {
Ray Milkey269ffb92014-04-03 14:43:30 -070043 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) {
Ray Milkeyb29e6262014-04-09 16:02:14 -0700120 if (intents.containsKey(intent.getId())) {
Ray Milkey269ffb92014-04-03 14:43:30 -0700121 removeIntent(intent.getId());
Ray Milkeyb29e6262014-04-09 16:02:14 -0700122 }
Ray Milkey269ffb92014-04-03 14:43:30 -0700123 intents.put(intent.getId(), intent);
124 events.add(new ChangedEvent(ChangedEventType.ADDED, intent));
125 }
Toshio Koidedf2eab92014-02-20 11:24:59 -0800126
Ray Milkey269ffb92014-04-03 14:43:30 -0700127 protected void removeIntent(String intentId) {
128 Intent intent = intents.remove(intentId);
Ray Milkeyb29e6262014-04-09 16:02:14 -0700129 if (intent == null) {
130 return;
131 }
Ray Milkey269ffb92014-04-03 14:43:30 -0700132 events.add(new ChangedEvent(ChangedEventType.REMOVED, intent));
133 }
Toshio Koidedf2eab92014-02-20 11:24:59 -0800134
Ray Milkey269ffb92014-04-03 14:43:30 -0700135 protected void setState(String intentId, IntentState state) {
136 Intent intent = intents.get(intentId);
Ray Milkeyb29e6262014-04-09 16:02:14 -0700137 if (intent == null) {
138 return;
139 }
Ray Milkey269ffb92014-04-03 14:43:30 -0700140 intent.setState(state);
141 events.add(new ChangedEvent(ChangedEventType.STATE_CHANGED, intent));
142 }
Toshio Koidedf2eab92014-02-20 11:24:59 -0800143
Ray Milkey269ffb92014-04-03 14:43:30 -0700144 //================================================================================
145 // helper methods (protected)
146 //================================================================================
Toshio Koidedf2eab92014-02-20 11:24:59 -0800147
Ray Milkey269ffb92014-04-03 14:43:30 -0700148 protected void handleAddOperation(IntentOperation operation) {
149 putIntent(operation.intent);
150 }
Toshio Koidedf2eab92014-02-20 11:24:59 -0800151
Ray Milkey269ffb92014-04-03 14:43:30 -0700152 protected void handleRemoveOperation(IntentOperation operation) {
153 Intent intent = getIntent(operation.intent.getId());
154 if (intent == null) {
155 // TODO error handling
Ray Milkey1aa71f82014-04-08 16:23:24 -0700156 return;
Ray Milkey269ffb92014-04-03 14:43:30 -0700157 } else {
158 setState(intent.getId(), IntentState.DEL_REQ);
159 }
160 }
Toshio Koidedf2eab92014-02-20 11:24:59 -0800161
Ray Milkey269ffb92014-04-03 14:43:30 -0700162 protected void handleErrorOperation(IntentOperation operation) {
163 //TODO put error message into the intent
Toshio Koidedf2eab92014-02-20 11:24:59 -0800164
Ray Milkey269ffb92014-04-03 14:43:30 -0700165 ErrorIntent errorIntent = (ErrorIntent) operation.intent;
166 Intent targetIntent = intents.get(errorIntent.getId());
167 if (targetIntent == null) {
168 // TODO error handling
169 return;
170 }
Toshio Koidedf2eab92014-02-20 11:24:59 -0800171
Ray Milkey269ffb92014-04-03 14:43:30 -0700172 switch (targetIntent.getState()) {
173 case CREATED:
174 case INST_REQ:
175 case INST_ACK:
176 case REROUTE_REQ:
177 setState(targetIntent.getId(), IntentState.INST_NACK);
178 break;
179 case DEL_REQ:
180 setState(targetIntent.getId(), IntentState.DEL_PENDING);
181 break;
182 case INST_NACK:
183 case DEL_PENDING:
184 case DEL_ACK:
185 // do nothing
186 break;
187 }
188 }
189
190 protected void notifyEvents() {
191 for (ChangedListener listener : listeners) {
192 listener.intentsChange(events);
193 }
194 events.clear();
195 }
Toshio Koideb609b3b2014-02-14 18:25:52 -0800196}