blob: b70a2912d283a8235ec6bf78b20a0fd2d0ef7600 [file] [log] [blame]
Thomas Vachuska6d697f12015-03-08 20:59:50 -07001/*
2 * Copyright 2015 Open Networking Laboratory
3 *
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.store.cfg;
17
18import org.apache.felix.scr.annotations.Activate;
19import org.apache.felix.scr.annotations.Component;
20import org.apache.felix.scr.annotations.Deactivate;
21import org.apache.felix.scr.annotations.Reference;
22import org.apache.felix.scr.annotations.ReferenceCardinality;
23import org.apache.felix.scr.annotations.Service;
24import org.onlab.util.KryoNamespace;
25import org.onosproject.cfg.ComponentConfigEvent;
26import org.onosproject.cfg.ComponentConfigStore;
27import org.onosproject.cfg.ComponentConfigStoreDelegate;
28import org.onosproject.cluster.ClusterService;
29import org.onosproject.store.AbstractStore;
30import org.onosproject.store.cluster.messaging.ClusterCommunicationService;
31import org.onosproject.store.ecmap.EventuallyConsistentMap;
32import org.onosproject.store.ecmap.EventuallyConsistentMapEvent;
33import org.onosproject.store.ecmap.EventuallyConsistentMapImpl;
34import org.onosproject.store.ecmap.EventuallyConsistentMapListener;
35import org.onosproject.store.impl.WallclockClockManager;
36import org.onosproject.store.serializers.KryoNamespaces;
37import org.slf4j.Logger;
38
39import static org.onosproject.cfg.ComponentConfigEvent.Type.PROPERTY_SET;
40import static org.onosproject.cfg.ComponentConfigEvent.Type.PROPERTY_UNSET;
41import static org.onosproject.store.ecmap.EventuallyConsistentMapEvent.Type.PUT;
42import static org.onosproject.store.ecmap.EventuallyConsistentMapEvent.Type.REMOVE;
43import static org.slf4j.LoggerFactory.getLogger;
44
45/**
46 * Manages inventory of component configurations in a distributed data store
47 * that uses optimistic replication and gossip based anti-entropy techniques.
48 */
49@Component(immediate = true)
50@Service
51public class GossipComponentConfigStore
52 extends AbstractStore<ComponentConfigEvent, ComponentConfigStoreDelegate>
53 implements ComponentConfigStore {
54
55 private static final String SEP = "#";
56
57 private final Logger log = getLogger(getClass());
58
59 private EventuallyConsistentMap<String, String> properties;
60
61 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
62 protected ClusterCommunicationService clusterCommunicator;
63
64 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
65 protected ClusterService clusterService;
66
67 @Activate
68 public void activate() {
69 KryoNamespace.Builder serializer = KryoNamespace.newBuilder()
70 .register(KryoNamespaces.API);
71
72 properties = new EventuallyConsistentMapImpl<>("cfg", clusterService,
73 clusterCommunicator,
74 serializer,
75 new WallclockClockManager<>());
76 properties.addListener(new InternalPropertiesListener());
77 log.info("Started");
78 }
79
80 @Deactivate
81 public void deactivate() {
82 log.info("Stopped");
83 }
84
85 @Override
86 public void setProperty(String componentName, String name, String value) {
87 properties.put(key(componentName, name), value);
88
89 }
90
91 @Override
92 public void unsetProperty(String componentName, String name) {
93 properties.remove(key(componentName, name));
94 }
95
96 /**
97 * Listener to component configuration properties distributed map changes.
98 */
99 private final class InternalPropertiesListener
100 implements EventuallyConsistentMapListener<String, String> {
101
102 @Override
103 public void event(EventuallyConsistentMapEvent<String, String> event) {
104 String[] keys = event.key().split(SEP);
105 String value = event.value();
106 if (event.type() == PUT) {
107 delegate.notify(new ComponentConfigEvent(PROPERTY_SET, keys[0], keys[1], value));
108 } else if (event.type() == REMOVE) {
109 delegate.notify(new ComponentConfigEvent(PROPERTY_UNSET, keys[0], keys[1], null));
110 }
111 }
112 }
113
114 // Generates a key from component name and property name.
115 private String key(String componentName, String name) {
116 return componentName + SEP + name;
117 }
118
119}