blob: 15208a26d827eb2228b2657105ea3a6147f12e2d [file] [log] [blame]
hirokif4ed5212018-05-26 22:39:38 -07001/*
2 * Copyright 2018-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 */
16
17package org.onosproject.odtn.utils.tapi;
18
19import java.util.List;
20import java.util.UUID;
21import org.apache.commons.lang.NotImplementedException;
22import org.onlab.util.XmlString;
23import org.onosproject.config.DynamicConfigService;
Jordan Halterman686c8582018-07-31 18:19:33 -070024import org.onosproject.config.FailedException;
hirokif4ed5212018-05-26 22:39:38 -070025import org.onosproject.config.Filter;
hiroki96ab3c22018-12-11 14:10:52 -080026import org.onosproject.yang.gen.v1.tapicommon.rev20181210.tapicommon.Uuid;
hirokif4ed5212018-05-26 22:39:38 -070027import org.onosproject.yang.model.DataNode;
28import org.onosproject.yang.model.DefaultModelObjectData;
29import org.onosproject.yang.model.DefaultResourceData;
30import org.onosproject.yang.model.ModelConverter;
31import org.onosproject.yang.model.ModelObject;
32import org.onosproject.yang.model.ModelObjectData;
33import org.onosproject.yang.model.ModelObjectId;
34import org.onosproject.yang.model.ResourceData;
35
36import static org.onlab.osgi.DefaultServiceDirectory.getService;
37import static org.onosproject.odtn.utils.YangToolUtil.toCharSequence;
38import static org.onosproject.odtn.utils.YangToolUtil.toCompositeData;
39import static org.onosproject.odtn.utils.YangToolUtil.toXmlCompositeStream;
40
41import org.onosproject.yang.model.ResourceId;
42import org.slf4j.Logger;
43
44import static org.slf4j.LoggerFactory.getLogger;
45
46/**
47 * Utility abstract class to deal with TAPI ModelObject with DCS.
48 *
49 * @param <T> modelObject to be dealt with
50 */
51public abstract class TapiObjectHandler<T extends ModelObject> {
52
53 public static final String ONOS_CP = "onos-cp";
54 public static final String DEVICE_ID = "device-id";
55 public static final String ODTN_PORT_TYPE = "odtn-port-type";
56
57 protected final Logger log = getLogger(getClass());
58
59 protected ModelConverter modelConverter;
60 protected DynamicConfigService dcs;
61
62 protected T obj;
63
64 /**
65 * Get modelObject uuid.
66 *
67 * @return Uuid
68 */
69 public Uuid getId() {
70 return getIdDetail();
71 }
72
73 /**
74 * Generate and set modelObject uuid.
75 */
76 public void setId() {
77 Uuid uuid = Uuid.of(UUID.randomUUID().toString());
78 setIdDetail(uuid);
79 }
80
81 /**
82 * Set modelObject uuid.
83 *
84 * @param uuid Uuid
85 */
86 public void setId(Uuid uuid) {
87 setIdDetail(uuid);
88 }
89
90 /**
91 * Get modelObject uuid, to be implemented in sub classes.
92 *
93 * @return Uuid
94 */
95 protected abstract Uuid getIdDetail();
96
97 /**
98 * Set modelObject uuid, to be implemented in sub classes.
99 *
100 * @param uuid Uuid
101 */
102 protected abstract void setIdDetail(Uuid uuid);
103
104 /**
105 * Generate DCS modelObjectId for parent node.
106 *
107 * @return ModelObjectId of parent node
108 */
109 public abstract ModelObjectId getParentModelObjectId();
110
111 /**
112 * Get modelObject instance.
113 *
114 * @return ModelObject of target node
115 */
116 public T getModelObject() {
117 return obj;
118 }
119
120 /**
121 * Set modelObject instance.
122 *
123 * @param newObj ModelObject to be set
124 */
125 public void setModelObject(T newObj) {
126 obj = newObj;
127 }
128
129 /**
130 * Get modelObjectData instance.
131 *
132 * @return ModelObjectData of target node
133 */
134 public ModelObjectData getModelObjectData() {
135 ModelObject obj = getModelObject();
136 ModelObjectId objId = getParentModelObjectId();
137
138 return DefaultModelObjectData.builder()
139 .addModelObject(obj)
140 .identifier(objId)
141 .build();
142 }
143
144 /**
145 * Get modelObjectData instance for child node.
146 * <p>
147 * This modelObjectData is needed for read / update / delete operation
148 * to extract ResourceId of this modelObject itself.
149 * It's just workaround, fix in DCS needed.
150 *
151 * @return ModelObjectData of build target
152 */
153 public ModelObjectData getChildModelObjectData() {
154 throw new NotImplementedException();
155 }
156
157 /**
158 * Get DataNode instance.
159 *
160 * @return DataNode of target node
161 */
162 public DataNode getDataNode() {
163 ResourceData rData = toResourceData(getModelObjectData());
164 if (rData.dataNodes().size() > 1) {
Ray Milkey2ee45852018-06-04 10:06:09 -0700165 throw new IllegalStateException("Multiple dataNode found.");
hirokif4ed5212018-05-26 22:39:38 -0700166 }
167 return rData.dataNodes().get(0);
168 }
169
170 /**
171 * Read modelObject from Dcs store.
172 *
173 * @return ModelObject
174 */
175 public T read() {
176 return readOnDcs();
177 }
178
179 /**
180 * Add modelObject to Dcs store.
181 */
182 public void add() {
183 createOnDcs();
184 }
185
186 /**
187 * Delete modelObject from Dcs store.
188 */
189 public void remove() {
190 deleteOnDcs();
191 }
192
193 private void dcsSetup() {
194 dcs = getService(DynamicConfigService.class);
195 modelConverter = getService(ModelConverter.class);
196 }
197
198 @SuppressWarnings("unchecked")
199 private T readOnDcs() {
200 dcsSetup();
201 ResourceData rData1 = toResourceData(getChildModelObjectData());
202 ResourceData rData2 = toResourceData(getModelObjectData());
203 DataNode rNode = dcs.readNode(rData1.resourceId(), Filter.builder().build());
204 obj = toModelObject(rNode, rData2.resourceId());
205 return obj;
206 }
207
208 private void createOnDcs() {
209 dcsSetup();
210 ResourceData rData = toResourceData(getModelObjectData());
211 addResourceDataToDcs(rData, rData.resourceId());
212 }
213
214 private void deleteOnDcs() {
215 dcsSetup();
216 ResourceData rData = toResourceData(getChildModelObjectData());
217 dcs.deleteNode(rData.resourceId());
218 }
219
220 private void addResourceDataToDcs(ResourceData input, ResourceId rid) {
221 if (input == null || input.dataNodes() == null) {
222 return;
223 }
224 List<DataNode> dataNodes = input.dataNodes();
225 for (DataNode node : dataNodes) {
Jordan Halterman686c8582018-07-31 18:19:33 -0700226 try {
227 dcs.createNode(rid, node);
228 } catch (FailedException e) {
Andrea Campanella6d774232018-12-21 12:18:21 +0100229 log.warn("Failed to add resource {}", rid);
230 log.debug("Exception", e);
Jordan Halterman686c8582018-07-31 18:19:33 -0700231 }
hirokif4ed5212018-05-26 22:39:38 -0700232 }
233 }
234
235 @SuppressWarnings("unchecked")
236 protected T toModelObject(DataNode rNode, ResourceId rId) {
237 dcsSetup();
238 ResourceData rData = toResourceData(rNode, rId);
239 ModelObjectData modelObjectData = modelConverter.createModel(rData);
240 if (modelObjectData.modelObjects().size() > 1) {
Ray Milkey2ee45852018-06-04 10:06:09 -0700241 throw new IllegalStateException("Multiple modelObject found.");
hirokif4ed5212018-05-26 22:39:38 -0700242 }
243 return (T) modelObjectData.modelObjects().get(0);
244 }
245
246 private ResourceData toResourceData(DataNode rNode, ResourceId rId) {
247 return DefaultResourceData.builder()
248 .addDataNode(rNode)
249 .resourceId(rId)
250 .build();
251 }
252
253 private ResourceData toResourceData(ModelObjectData data) {
254 dcsSetup();
255 ResourceData rData = modelConverter.createDataNode(data);
256
257 // for debug
258 CharSequence strNode = toCharSequence(toXmlCompositeStream(toCompositeData(rData)));
Andrea Campanellafa8bf1f2018-11-26 11:57:45 -0800259 log.debug("XML:\n{}", XmlString.prettifyXml(strNode));
hirokif4ed5212018-05-26 22:39:38 -0700260
261 return rData;
262 }
263
264}