blob: 8fe8a11a44634caa70c293cada456dfd635c2bf3 [file] [log] [blame]
Thomas Vachuska4f1a60c2014-10-28 13:39:07 -07001/*
Jonathan Hart6a8fd1d2015-02-25 15:44:37 -08002 * Copyright 2015 Open Networking Laboratory
Thomas Vachuska4f1a60c2014-10-28 13:39:07 -07003 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
Brian O'Connorabafb502014-12-02 22:26:20 -080016package org.onosproject.store.trivial.impl;
Brian O'Connor66630c82014-10-02 21:08:19 -070017
Brian O'Connorb499b352015-02-03 16:46:15 -080018import com.google.common.collect.Maps;
Brian O'Connor66630c82014-10-02 21:08:19 -070019import org.apache.felix.scr.annotations.Activate;
20import org.apache.felix.scr.annotations.Component;
21import org.apache.felix.scr.annotations.Deactivate;
22import org.apache.felix.scr.annotations.Service;
Brian O'Connorabafb502014-12-02 22:26:20 -080023import org.onosproject.net.intent.Intent;
Brian O'Connorcff03322015-02-03 15:28:59 -080024import org.onosproject.net.intent.IntentData;
Brian O'Connorabafb502014-12-02 22:26:20 -080025import org.onosproject.net.intent.IntentEvent;
Brian O'Connor7775bda2015-02-06 15:01:18 -080026import org.onosproject.net.intent.IntentState;
Brian O'Connorabafb502014-12-02 22:26:20 -080027import org.onosproject.net.intent.IntentStore;
28import org.onosproject.net.intent.IntentStoreDelegate;
Ray Milkey5b3717e2015-02-05 11:44:08 -080029import org.onosproject.net.intent.Key;
Brian O'Connorabafb502014-12-02 22:26:20 -080030import org.onosproject.store.AbstractStore;
Brian O'Connor66630c82014-10-02 21:08:19 -070031import org.slf4j.Logger;
32
Thomas Vachuskac96058a2014-10-20 23:00:16 -070033import java.util.List;
34import java.util.Map;
Brian O'Connorb499b352015-02-03 16:46:15 -080035import java.util.stream.Collectors;
Thomas Vachuskac96058a2014-10-20 23:00:16 -070036
Brian O'Connorb499b352015-02-03 16:46:15 -080037import static com.google.common.base.Preconditions.checkNotNull;
Jonathan Hart6a8fd1d2015-02-25 15:44:37 -080038import static org.onosproject.net.intent.IntentState.*;
Thomas Vachuskac96058a2014-10-20 23:00:16 -070039import static org.slf4j.LoggerFactory.getLogger;
Brian O'Connor66630c82014-10-02 21:08:19 -070040
Jonathan Hart0d18df32015-03-21 08:42:59 -070041/**
42 * Simple single-instance implementation of the intent store.
43 */
Brian O'Connor66630c82014-10-02 21:08:19 -070044@Component(immediate = true)
45@Service
46public class SimpleIntentStore
tom85258ee2014-10-07 00:10:02 -070047 extends AbstractStore<IntentEvent, IntentStoreDelegate>
48 implements IntentStore {
Brian O'Connor66630c82014-10-02 21:08:19 -070049
50 private final Logger log = getLogger(getClass());
Brian O'Connorcff03322015-02-03 15:28:59 -080051
Ray Milkey5b3717e2015-02-05 11:44:08 -080052 private final Map<Key, IntentData> current = Maps.newConcurrentMap();
Jonathan Hart6a8fd1d2015-02-25 15:44:37 -080053 private final Map<Key, IntentData> pending = Maps.newConcurrentMap();
54
Brian O'Connor66630c82014-10-02 21:08:19 -070055 @Activate
56 public void activate() {
57 log.info("Started");
58 }
59
60 @Deactivate
61 public void deactivate() {
62 log.info("Stopped");
63 }
64
Brian O'Connor66630c82014-10-02 21:08:19 -070065 @Override
66 public long getIntentCount() {
Brian O'Connorb499b352015-02-03 16:46:15 -080067 return current.size();
Brian O'Connor66630c82014-10-02 21:08:19 -070068 }
69
70 @Override
71 public Iterable<Intent> getIntents() {
Brian O'Connorb499b352015-02-03 16:46:15 -080072 return current.values().stream()
73 .map(IntentData::intent)
74 .collect(Collectors.toList());
Brian O'Connor66630c82014-10-02 21:08:19 -070075 }
76
77 @Override
Ray Milkeyf9af43c2015-02-09 16:45:48 -080078 public IntentState getIntentState(Key intentKey) {
79 IntentData data = current.get(intentKey);
80 return (data != null) ? data.state() : null;
Brian O'Connor7775bda2015-02-06 15:01:18 -080081 }
82
83 @Override
Ray Milkeyf9af43c2015-02-09 16:45:48 -080084 public List<Intent> getInstallableIntents(Key intentKey) {
85 IntentData data = current.get(intentKey);
Jonathan Hart6a8fd1d2015-02-25 15:44:37 -080086 if (data != null) {
87 return data.installables();
88 }
89 return null;
90 }
91
Brian O'Connorcff03322015-02-03 15:28:59 -080092 @Override
Brian O'Connor03406a42015-02-03 17:28:57 -080093 public void write(IntentData newData) {
Jonathan Hart0d18df32015-03-21 08:42:59 -070094 checkNotNull(newData);
95
Jonathan Hart6a8fd1d2015-02-25 15:44:37 -080096 synchronized (this) {
97 // TODO this could be refactored/cleaned up
98 IntentData currentData = current.get(newData.key());
99 IntentData pendingData = pending.get(newData.key());
100
Jonathan Hart72175c22015-03-24 18:55:58 -0700101 if (IntentData.isUpdateAcceptable(currentData, newData)) {
Ray Milkey77a455f2015-03-27 10:08:17 -0700102 if (pendingData != null) {
103 if (pendingData.state() == PURGE_REQ) {
104 current.remove(newData.key(), newData);
105 } else {
106 current.put(newData.key(), new IntentData(newData));
107 }
Jonathan Hart6a8fd1d2015-02-25 15:44:37 -0800108
Ray Milkey77a455f2015-03-27 10:08:17 -0700109 if (pendingData.version().compareTo(newData.version()) <= 0) {
Jonathan Hart6a8fd1d2015-02-25 15:44:37 -0800110 // pendingData version is less than or equal to newData's
111 // Note: a new update for this key could be pending (it's version will be greater)
Ray Milkey77a455f2015-03-27 10:08:17 -0700112 pending.remove(newData.key());
113 }
Jonathan Hart6a8fd1d2015-02-25 15:44:37 -0800114 }
Jonathan Hart6a8fd1d2015-02-25 15:44:37 -0800115 notifyDelegateIfNotNull(IntentEvent.getEvent(newData));
116 }
Brian O'Connor03406a42015-02-03 17:28:57 -0800117 }
Jonathan Hart6a8fd1d2015-02-25 15:44:37 -0800118 }
119
120 private void notifyDelegateIfNotNull(IntentEvent event) {
121 if (event != null) {
122 notifyDelegate(event);
Brian O'Connor03406a42015-02-03 17:28:57 -0800123 }
124 }
125
126 @Override
127 public void batchWrite(Iterable<IntentData> updates) {
128 for (IntentData data : updates) {
129 write(data);
130 }
131 }
132
Brian O'Connor7775bda2015-02-06 15:01:18 -0800133 @Override
134 public Intent getIntent(Key key) {
135 IntentData data = current.get(key);
136 return (data != null) ? data.intent() : null;
137 }
138
Jonathan Hart6a8fd1d2015-02-25 15:44:37 -0800139 @Override
140 public IntentData getIntentData(Key key) {
Jonathan Hart0d18df32015-03-21 08:42:59 -0700141 IntentData currentData = current.get(key);
142 if (currentData == null) {
143 return null;
144 }
145 return new IntentData(currentData);
Jonathan Hart6a8fd1d2015-02-25 15:44:37 -0800146 }
Brian O'Connor03406a42015-02-03 17:28:57 -0800147
148 @Override
Brian O'Connorcff03322015-02-03 15:28:59 -0800149 public void addPending(IntentData data) {
Jonathan Hart6a8fd1d2015-02-25 15:44:37 -0800150 if (data.version() == null) { // recompiled intents will already have a version
151 data.setVersion(new SystemClockTimestamp());
152 }
153 synchronized (this) {
154 IntentData existingData = pending.get(data.key());
155 if (existingData == null ||
156 // existing version is strictly less than data's version
157 // Note: if they are equal, we already have the update
158 // TODO maybe we should still make this <= to be safe?
159 existingData.version().compareTo(data.version()) < 0) {
160 pending.put(data.key(), data);
161 checkNotNull(delegate, "Store delegate is not set")
162 .process(data);
163 notifyDelegateIfNotNull(IntentEvent.getEvent(data));
164 } else {
165 log.debug("IntentData {} is older than existing: {}",
166 data, existingData);
167 }
168 //TODO consider also checking the current map at this point
169 }
Brian O'Connorcff03322015-02-03 15:28:59 -0800170 }
Brian O'Connorcff03322015-02-03 15:28:59 -0800171
Jonathan Hart6a8fd1d2015-02-25 15:44:37 -0800172 @Override
173 public boolean isMaster(Key intentKey) {
174 return true;
175 }
176
177 @Override
178 public Iterable<Intent> getPending() {
179 return pending.values().stream()
180 .map(IntentData::intent)
181 .collect(Collectors.toList());
182 }
Brian O'Connor66630c82014-10-02 21:08:19 -0700183}