blob: 85e826f10c6da0c233ae07d9d85692fe29c703d6 [file] [log] [blame]
Madan Jampania4be1842016-05-24 15:56:02 -07001/*
Brian O'Connora09fe5b2017-08-03 21:12:30 -07002 * Copyright 2016-present Open Networking Foundation
Madan Jampania4be1842016-05-24 15:56:02 -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.store.cfg;
17
Thomas Vachuskab809b382018-02-12 15:53:01 -080018import com.google.common.collect.ImmutableSet;
Madan Jampania4be1842016-05-24 15:56:02 -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.Reference;
23import org.apache.felix.scr.annotations.ReferenceCardinality;
24import org.apache.felix.scr.annotations.Service;
25import org.onosproject.cfg.ComponentConfigEvent;
26import org.onosproject.cfg.ComponentConfigStore;
27import org.onosproject.cfg.ComponentConfigStoreDelegate;
28import org.onosproject.store.AbstractStore;
29import org.onosproject.store.serializers.KryoNamespaces;
30import org.onosproject.store.service.ConsistentMap;
31import org.onosproject.store.service.MapEvent;
32import org.onosproject.store.service.MapEventListener;
33import org.onosproject.store.service.Serializer;
34import org.onosproject.store.service.StorageService;
Thomas Vachuskab809b382018-02-12 15:53:01 -080035import org.onosproject.store.service.Versioned;
Madan Jampania4be1842016-05-24 15:56:02 -070036import org.slf4j.Logger;
37
Thomas Vachuskab809b382018-02-12 15:53:01 -080038import java.util.Objects;
39import java.util.Set;
40
Madan Jampania4be1842016-05-24 15:56:02 -070041import static org.onosproject.cfg.ComponentConfigEvent.Type.PROPERTY_SET;
42import static org.onosproject.cfg.ComponentConfigEvent.Type.PROPERTY_UNSET;
43import static org.onosproject.store.service.MapEvent.Type.INSERT;
44import static org.onosproject.store.service.MapEvent.Type.REMOVE;
45import static org.onosproject.store.service.MapEvent.Type.UPDATE;
46import static org.slf4j.LoggerFactory.getLogger;
47
48/**
49 * Manages inventory of component configurations in a distributed data store
50 * that provides strong sequential consistency guarantees.
51 */
Sho SHIMIZU5c396e32016-08-12 15:19:12 -070052@Component(immediate = true)
Madan Jampania4be1842016-05-24 15:56:02 -070053@Service
54public class DistributedComponentConfigStore
55 extends AbstractStore<ComponentConfigEvent, ComponentConfigStoreDelegate>
56 implements ComponentConfigStore {
57
58 private static final String SEP = "#";
59
60 private final Logger log = getLogger(getClass());
61
62 private ConsistentMap<String, String> properties;
63
64 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
65 protected StorageService storageService;
66
Thomas Vachuskab809b382018-02-12 15:53:01 -080067 private InternalPropertiesListener propertiesListener = new InternalPropertiesListener();
Madan Jampania4be1842016-05-24 15:56:02 -070068
69 @Activate
70 public void activate() {
71 properties = storageService.<String, String>consistentMapBuilder()
72 .withName("onos-component-cfg")
73 .withSerializer(Serializer.using(KryoNamespaces.API))
74 .withRelaxedReadConsistency()
75 .build();
76
77 properties.addListener(propertiesListener);
78 log.info("Started");
79 }
80
81 @Deactivate
82 public void deactivate() {
83 properties.removeListener(propertiesListener);
84 log.info("Stopped");
85 }
86
87 @Override
88 public void setProperty(String componentName, String name, String value) {
89 properties.put(key(componentName, name), value);
90
91 }
92
93 @Override
94 public void unsetProperty(String componentName, String name) {
95 properties.remove(key(componentName, name));
96 }
97
Thomas Vachuskab809b382018-02-12 15:53:01 -080098 @Override
99 public Set<String> getProperties(String componentName) {
100 ImmutableSet.Builder<String> names = ImmutableSet.builder();
101 properties.keySet().stream()
102 .filter((String k) -> Objects.equals(componentName, k.substring(0, k.indexOf(SEP))))
103 .map((String k) -> k.substring(k.indexOf(SEP) + 1))
104 .forEach(names::add);
105 return names.build();
106 }
107
108 @Override
109 public String getProperty(String componentName, String name) {
110 Versioned<String> v = properties.get(key(componentName, name));
111 return v != null ? v.value() : null;
112 }
113
Madan Jampania4be1842016-05-24 15:56:02 -0700114 /**
115 * Listener to component configuration properties distributed map changes.
116 */
117 private final class InternalPropertiesListener
118 implements MapEventListener<String, String> {
119
120 @Override
121 public void event(MapEvent<String, String> event) {
122 String[] keys = event.key().split(SEP);
123 if (event.type() == INSERT || event.type() == UPDATE) {
124 String value = event.newValue().value();
Thomas Vachuskad4955ae2016-08-23 14:56:37 -0700125 notifyDelegate(new ComponentConfigEvent(PROPERTY_SET, keys[0], keys[1], value));
Madan Jampania4be1842016-05-24 15:56:02 -0700126 } else if (event.type() == REMOVE) {
Thomas Vachuskad4955ae2016-08-23 14:56:37 -0700127 notifyDelegate(new ComponentConfigEvent(PROPERTY_UNSET, keys[0], keys[1], null));
Madan Jampania4be1842016-05-24 15:56:02 -0700128 }
129 }
130 }
131
132 // Generates a key from component name and property name.
133 private String key(String componentName, String name) {
134 return componentName + SEP + name;
135 }
136}