blob: 26dd3f5dd53a0c58f8de69af39dbcb8b139e2057 [file] [log] [blame]
Jian Lif2483072020-12-25 02:24:16 +09001/*
2 * Copyright 2020-present Open Networking Foundation
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.kubevirtnode.impl;
17
Jian Lif2483072020-12-25 02:24:16 +090018import com.google.common.base.Strings;
Jian Li3c3b1632021-04-28 17:24:56 +090019import org.onlab.packet.IpAddress;
Jian Lif2483072020-12-25 02:24:16 +090020import org.onosproject.cluster.ClusterService;
21import org.onosproject.cluster.LeadershipService;
22import org.onosproject.core.ApplicationId;
23import org.onosproject.core.CoreService;
24import org.onosproject.event.ListenerRegistry;
25import org.onosproject.kubevirtnode.api.KubevirtApiConfig;
26import org.onosproject.kubevirtnode.api.KubevirtApiConfigAdminService;
27import org.onosproject.kubevirtnode.api.KubevirtApiConfigEvent;
28import org.onosproject.kubevirtnode.api.KubevirtApiConfigListener;
29import org.onosproject.kubevirtnode.api.KubevirtApiConfigService;
30import org.onosproject.kubevirtnode.api.KubevirtApiConfigStore;
31import org.onosproject.kubevirtnode.api.KubevirtApiConfigStoreDelegate;
32import org.onosproject.store.service.StorageService;
33import org.osgi.service.component.annotations.Activate;
34import org.osgi.service.component.annotations.Component;
35import org.osgi.service.component.annotations.Deactivate;
36import org.osgi.service.component.annotations.Reference;
37import org.osgi.service.component.annotations.ReferenceCardinality;
38import org.slf4j.Logger;
39
40import java.util.concurrent.ExecutorService;
41
42import static com.google.common.base.Preconditions.checkArgument;
43import static com.google.common.base.Preconditions.checkNotNull;
44import static java.util.concurrent.Executors.newSingleThreadExecutor;
45import static org.onlab.util.Tools.groupedThreads;
46import static org.onosproject.kubevirtnode.util.KubevirtNodeUtil.endpoint;
Jian Li3c3b1632021-04-28 17:24:56 +090047import static org.onosproject.kubevirtnode.util.KubevirtNodeUtil.resolveHostname;
Jian Lif2483072020-12-25 02:24:16 +090048import static org.slf4j.LoggerFactory.getLogger;
49
Jian Liaaf44b52020-12-27 23:22:46 +090050/**
51 * Service administering the inventory of KubeVirt API configs.
52 */
Jian Lif2483072020-12-25 02:24:16 +090053@Component(
54 immediate = true,
55 service = {KubevirtApiConfigService.class, KubevirtApiConfigAdminService.class }
56)
57public class KubevirtApiConfigManager
58 extends ListenerRegistry<KubevirtApiConfigEvent, KubevirtApiConfigListener>
59 implements KubevirtApiConfigService, KubevirtApiConfigAdminService {
60
61 private final Logger log = getLogger(getClass());
62
Jian Li3c3b1632021-04-28 17:24:56 +090063 private static final int API_SERVER_PORT = 443;
64
Jian Lif2483072020-12-25 02:24:16 +090065 private static final String MSG_CONFIG = "KubeVirt API config %s %s";
66 private static final String MSG_CREATED = "created";
67 private static final String MSG_UPDATED = "updated";
68 private static final String MSG_REMOVED = "removed";
69
70 private static final String ERR_NULL_CONFIG = "KubeVirt API config cannot be null";
71 private static final String ERR_NULL_ENDPOINT = "KubeVirt API endpoint cannot be null";
72 private static final String ERR_UNIQUE_CONFIG = "KubeVirt API config should be unique";
73
74 @Reference(cardinality = ReferenceCardinality.MANDATORY)
75 protected CoreService coreService;
76
77 @Reference(cardinality = ReferenceCardinality.MANDATORY)
78 protected ClusterService clusterService;
79
80 @Reference(cardinality = ReferenceCardinality.MANDATORY)
81 protected LeadershipService leadershipService;
82
83 @Reference(cardinality = ReferenceCardinality.MANDATORY)
84 protected StorageService storageService;
85
86 @Reference(cardinality = ReferenceCardinality.MANDATORY)
87 protected KubevirtApiConfigStore configStore;
88
89 private final ExecutorService eventExecutor = newSingleThreadExecutor(
90 groupedThreads(this.getClass().getSimpleName(), "event-handler", log));
91
92 private final KubevirtApiConfigStoreDelegate delegate = new InternalApiConfigStoreDelegate();
93
94 private ApplicationId appId;
95
96 @Activate
97 protected void activate() {
98 appId = coreService.registerApplication(APP_ID);
99 configStore.setDelegate(delegate);
100
101 leadershipService.runForLeadership(appId.name());
102
103 log.info("Started");
104 }
105
106 @Deactivate
107 protected void deactivate() {
108 configStore.unsetDelegate(delegate);
109
110 leadershipService.withdraw(appId.name());
111 eventExecutor.shutdown();
112
113 log.info("Stopped");
114 }
115
116 @Override
117 public void createApiConfig(KubevirtApiConfig config) {
118 checkNotNull(config, ERR_NULL_CONFIG);
119 checkArgument(configStore.apiConfigs().size() == 0, ERR_UNIQUE_CONFIG);
120
Jian Li3c3b1632021-04-28 17:24:56 +0900121 KubevirtApiConfig newConfig = config;
122 if (config.apiServerFqdn() != null) {
123 IpAddress apiServerIp = resolveHostname(config.apiServerFqdn());
124 if (apiServerIp != null) {
125 newConfig = config.updateIpAddress(apiServerIp);
126 newConfig = newConfig.updatePort(API_SERVER_PORT);
127 } else {
128 log.warn("API server IP is not resolved for host {}", config.apiServerFqdn());
129 }
130 }
131
132 configStore.createApiConfig(newConfig);
133 log.info(String.format(MSG_CONFIG, endpoint(newConfig), MSG_CREATED));
Jian Lif2483072020-12-25 02:24:16 +0900134 }
135
136 @Override
137 public void updateApiConfig(KubevirtApiConfig config) {
138 checkNotNull(config, ERR_NULL_CONFIG);
139 configStore.updateApiConfig(config);
140 log.info(String.format(MSG_CONFIG, endpoint(config), MSG_UPDATED));
141 }
142
143 @Override
144 public KubevirtApiConfig removeApiConfig(String endpoint) {
145 checkArgument(!Strings.isNullOrEmpty(endpoint), ERR_NULL_ENDPOINT);
146 KubevirtApiConfig config = configStore.removeApiConfig(endpoint);
147 log.info(String.format(MSG_CONFIG, endpoint, MSG_REMOVED));
148 return config;
149 }
150
151 @Override
152 public KubevirtApiConfig apiConfig() {
153 return configStore.apiConfigs().stream().findAny().orElse(null);
154 }
155
156 private class InternalApiConfigStoreDelegate implements KubevirtApiConfigStoreDelegate {
157
158 @Override
159 public void notify(KubevirtApiConfigEvent event) {
160 if (event != null) {
161 log.trace("send KubeVirt API config event {}", event);
162 process(event);
163 }
164 }
165 }
166}