blob: 8d10d2e2e3f9a54efd13788529b6cdeed34dc3c8 [file] [log] [blame]
slowrdb071b22017-07-07 11:10:25 -07001/*
Brian O'Connora09fe5b2017-08-03 21:12:30 -07002 * Copyright 2016-present Open Networking Foundation
slowrdb071b22017-07-07 11:10:25 -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 */
16package org.onosproject.artemis.impl;
17
18import com.google.common.collect.Sets;
19import 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.Reference;
23import org.apache.felix.scr.annotations.ReferenceCardinality;
24import org.apache.felix.scr.annotations.Service;
25import org.onosproject.core.ApplicationId;
26import org.onosproject.core.CoreService;
27import org.onosproject.net.config.ConfigFactory;
28import org.onosproject.net.config.NetworkConfigEvent;
29import org.onosproject.net.config.NetworkConfigListener;
30import org.onosproject.net.config.NetworkConfigRegistry;
31import org.onosproject.net.config.NetworkConfigService;
32import org.onosproject.net.config.basics.SubjectFactories;
33import org.onosproject.routing.bgp.BgpInfoService;
34import org.slf4j.Logger;
35import org.slf4j.LoggerFactory;
36
37import java.util.Map;
38import java.util.Optional;
39import java.util.Set;
40import java.util.Timer;
41
42/**
43 * Artemis Component.
44 */
45@Component(immediate = true)
46@Service
47public class ArtemisManager implements ArtemisService {
48 private static final String ARTEMIS_APP_ID = "org.onosproject.artemis";
49 private static final Class<ArtemisConfig> CONFIG_CLASS = ArtemisConfig.class;
50
51 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
52 private NetworkConfigRegistry registry;
53
54 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
55 private NetworkConfigService configService;
56
57 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
58 private CoreService coreService;
59
60 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
61 private BgpInfoService bgpInfoService;
62
63 private final Logger log = LoggerFactory.getLogger(getClass());
64
65 private ApplicationId appId;
66 public static boolean logging = false;
67
68 private Set<PrefixHandler> prefixHandlers = Sets.newHashSet();
69 private Deaggregator deaggr;
70 private Timer timer;
71
72 private final InternalNetworkConfigListener configListener =
73 new InternalNetworkConfigListener();
74
75 private ConfigFactory<ApplicationId, ArtemisConfig> artemisConfigFactory =
76 new ConfigFactory<ApplicationId, ArtemisConfig>(
77 SubjectFactories.APP_SUBJECT_FACTORY, ArtemisConfig.class, "artemis") {
78 @Override
79 public ArtemisConfig createConfig() {
80 return new ArtemisConfig();
81 }
82 };
83
84 @Activate
85 protected void activate() {
86 appId = coreService.registerApplication(ARTEMIS_APP_ID);
87 configService.addListener(configListener);
88 registry.registerConfigFactory(artemisConfigFactory);
89 log.info("Artemis Started");
90 }
91
92 @Deactivate
93 protected void deactivate() {
94 configService.removeListener(configListener);
95 registry.unregisterConfigFactory(artemisConfigFactory);
96 prefixHandlers.forEach(PrefixHandler::stopPrefixMonitors);
97 log.info("Artemis Stopped");
98 }
99
100 /**
101 * Helper function to start and stop monitors on configuration changes.
102 */
103 private void setUpConfiguration() {
104 ArtemisConfig config = configService.getConfig(appId, CONFIG_CLASS);
105
106 if (config == null) {
107 log.warn("No artemis config available!");
108 return;
109 }
110
111 final Set<ArtemisConfig.ArtemisPrefixes> prefixes = config.monitoredPrefixes();
112 final Integer frequency = config.detectionFrequency();
113 final Map<String, Set<String>> monitors = config.activeMonitors();
114
115 Set<PrefixHandler> toRemove = Sets.newHashSet(prefixHandlers);
116
117 for (ArtemisConfig.ArtemisPrefixes curr : prefixes) {
118 final Optional<PrefixHandler> handler = prefixHandlers
119 .stream()
120 .filter(prefixHandler -> prefixHandler.getPrefix().equals(curr.prefix()))
121 .findFirst();
122
123 if (handler.isPresent()) {
124 PrefixHandler oldHandler = handler.get();
125 oldHandler.changeMonitors(monitors);
126
127 // remove the ones we are going to keep from toRemove list
128 toRemove.remove(oldHandler);
129 } else {
130 // Add new handler
131 PrefixHandler newHandler = new PrefixHandler(curr.prefix(), monitors);
132 newHandler.startPrefixMonitors();
133 prefixHandlers.add(newHandler);
134 }
135 }
136
137 // stop and remove old monitors that do not exist on new configuration
138 toRemove.forEach(PrefixHandler::stopPrefixMonitors);
139 prefixHandlers.removeAll(toRemove);
140
141 // new timer task with updated bgp speakers
142 deaggr = new Deaggregator(bgpInfoService);
143 deaggr.setPrefixes(prefixes);
144
145 if (timer != null) {
146 timer.cancel();
147 }
148 timer = new Timer();
149 timer.scheduleAtFixedRate(deaggr, frequency, frequency);
150 }
151
152 @Override
153 public void setLogger(boolean value) {
154 logging = value;
155 }
156
157 private class InternalNetworkConfigListener implements NetworkConfigListener {
158
159 @Override
160 public void event(NetworkConfigEvent event) {
161 switch (event.type()) {
162 case CONFIG_REGISTERED:
163 break;
164 case CONFIG_UNREGISTERED:
165 break;
166 case CONFIG_ADDED:
167 case CONFIG_UPDATED:
168 case CONFIG_REMOVED:
169 if (event.configClass() == CONFIG_CLASS) {
170 setUpConfiguration();
171 }
172 break;
173 default:
174 break;
175 }
176 }
177 }
178}