blob: 6e517a0b839d1a32dcdb6bbb4843c1db864a6d5d [file] [log] [blame]
Yuta HIGUCHI24057822017-08-02 15:03:51 -07001/*
2 * Copyright 2017-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.d.config;
17
18import static com.google.common.base.Preconditions.checkArgument;
19import java.util.Optional;
20
21import org.onosproject.net.DeviceId;
22import org.onosproject.yang.model.KeyLeaf;
23import org.onosproject.yang.model.ListKey;
24import org.onosproject.yang.model.NodeKey;
25import org.onosproject.yang.model.ResourceId;
Yuta HIGUCHIe057dee2017-09-15 13:56:10 -070026import org.onosproject.yang.model.SchemaId;
Yuta HIGUCHI24057822017-08-02 15:03:51 -070027
28import com.google.common.annotations.Beta;
29
30/**
31 * Utility related to device ResourceId.
32 */
33@Beta
34public abstract class DeviceResourceIds {
35
36 // assuming following device tree structure
37 // - "/"
38 // +- devices
39 // +- device (=device root node:ListKey)
40
41
Yuta HIGUCHI24057822017-08-02 15:03:51 -070042 /**
43 * SchemaId namespace for DCS defined nodes.
44 */
45 public static final String DCS_NAMESPACE = "org.onosproject.dcs";
46
Yuta HIGUCHI825401e2018-02-27 13:23:25 -080047 // FIXME '/' is problematic name from RFC 7950/7951 point of view
Yuta HIGUCHI24057822017-08-02 15:03:51 -070048 /**
49 * SchemaId name for root node.
50 */
51 public static final String ROOT_NAME = "/";
52 /**
53 * SchemaId name for devices node.
54 */
55 public static final String DEVICES_NAME = "devices";
Yuta HIGUCHIe057dee2017-09-15 13:56:10 -070056 public static final SchemaId DEVICES_SCHEMA = new SchemaId(DEVICES_NAME, DCS_NAMESPACE);
Yuta HIGUCHI24057822017-08-02 15:03:51 -070057 /**
58 * SchemaId name for device node.
59 */
60 public static final String DEVICE_NAME = "device";
Yuta HIGUCHIe057dee2017-09-15 13:56:10 -070061 public static final SchemaId DEVICE_SCHEMA = new SchemaId(DEVICE_NAME, DCS_NAMESPACE);
Yuta HIGUCHI24057822017-08-02 15:03:51 -070062 /**
63 * KeyLeaf {@code name}, which holds DeviceId information on device node.
64 */
65 public static final String DEVICE_ID_KL_NAME = "device-id";
66
67 /**
Yuta HIGUCHIe057dee2017-09-15 13:56:10 -070068 * Absolute ResourceId pointing at root node.
69 * @deprecated Use {@link ResourceIds#ROOT_ID} instead
Yuta HIGUCHI24057822017-08-02 15:03:51 -070070 */
Yuta HIGUCHIe057dee2017-09-15 13:56:10 -070071 @Deprecated
72 public static final ResourceId ROOT_ID = ResourceIds.ROOT_ID;
Yuta HIGUCHI24057822017-08-02 15:03:51 -070073
Yuta HIGUCHIe057dee2017-09-15 13:56:10 -070074 /**
75 * Absolute ResourceId pointing at 'devices' node.
76 */
Yuta HIGUCHIea1fe522017-09-01 14:24:02 -070077 public static final ResourceId DEVICES_ID = ResourceId.builder()
78 .addBranchPointSchema(ROOT_NAME, DCS_NAMESPACE)
79 .addBranchPointSchema(DEVICES_NAME, DCS_NAMESPACE)
80 .build();
81
82
Yuta HIGUCHI24057822017-08-02 15:03:51 -070083 static final NodeKey<?> ROOT_NODE =
84 NodeKey.builder().schemaId(ROOT_NAME, DCS_NAMESPACE).build();
85
86 /**
87 * nodeKeys index for root node.
88 */
Yuta HIGUCHIe057dee2017-09-15 13:56:10 -070089 @Deprecated
Yuta HIGUCHI24057822017-08-02 15:03:51 -070090 static final int ROOT_INDEX = 0;
91 /**
Yuta HIGUCHIe057dee2017-09-15 13:56:10 -070092 * nodeKeys index relative from root for devices node.
Yuta HIGUCHI24057822017-08-02 15:03:51 -070093 */
94 static final int DEVICES_INDEX = 1;
95 /**
Yuta HIGUCHIe057dee2017-09-15 13:56:10 -070096 * nodeKeys index relative from root for device node.
Yuta HIGUCHI24057822017-08-02 15:03:51 -070097 */
98 static final int DEVICE_INDEX = 2;
99
100 /**
Yuta HIGUCHIe057dee2017-09-15 13:56:10 -0700101 * Converts root relative ResourceId used by DynamicConfigEvent.
102 *
103 * @param rootRelative resource Id
104 * @return absolute ResourceId.
105 */
106 @Beta
107 public static ResourceId toAbsolute(ResourceId rootRelative) {
108 if (ResourceIds.startsWithRootNode(rootRelative)) {
109 return rootRelative;
110 }
111 return ResourceIds.concat(ResourceIds.ROOT_ID, rootRelative);
112 }
113
114 /**
Yuta HIGUCHI24057822017-08-02 15:03:51 -0700115 * Tests if specified path points to root node of a Device.
116 *
117 * @param path to test.
118 * @return true if path points to root node of a Device.
119 */
120 public static boolean isDeviceRootNode(ResourceId path) {
Yuta HIGUCHIe057dee2017-09-15 13:56:10 -0700121 if (ResourceIds.startsWithRootNode(path)) {
122 return path.nodeKeys().size() == 3 &&
123 isUnderDeviceRootNode(path);
124 } else {
125 return path.nodeKeys().size() == 2 &&
126 isUnderDeviceRootNode(path);
127 }
Yuta HIGUCHI24057822017-08-02 15:03:51 -0700128 }
129
130 /**
Yuta HIGUCHIe057dee2017-09-15 13:56:10 -0700131 * Tests if specified path points to root node of a Device or it's subtree.
Yuta HIGUCHI24057822017-08-02 15:03:51 -0700132 *
133 * @param path to test.
134 * @return true if path points to root node of a Device.
135 */
136 public static boolean isUnderDeviceRootNode(ResourceId path) {
Yuta HIGUCHIe057dee2017-09-15 13:56:10 -0700137 int rootIdx = ResourceIds.startsWithRootNode(path) ? 0 : -1;
138 return path.nodeKeys().size() >= rootIdx + 3 &&
139 DEVICE_SCHEMA.equals(path.nodeKeys().get(rootIdx + DEVICE_INDEX).schemaId()) &&
140 (path.nodeKeys().get(rootIdx + DEVICE_INDEX) instanceof ListKey) &&
141 DEVICES_SCHEMA.equals(path.nodeKeys().get(rootIdx + DEVICES_INDEX).schemaId()); }
Yuta HIGUCHI24057822017-08-02 15:03:51 -0700142
143 /**
144 * Tests if specified path points to root or devices node.
145 *
146 * @param path to test.
147 * @return true if path points to root node of a Device.
148 */
149 public static boolean isRootOrDevicesNode(ResourceId path) {
150 return isDevicesNode(path) ||
151 isRootNode(path);
152 }
153
154 public static boolean isDevicesNode(ResourceId path) {
Yuta HIGUCHIe057dee2017-09-15 13:56:10 -0700155 int rootIdx = ResourceIds.startsWithRootNode(path) ? 0 : -1;
156 return path.nodeKeys().size() == rootIdx + 2 &&
157 DEVICES_SCHEMA.equals(path.nodeKeys().get(rootIdx + DEVICES_INDEX).schemaId());
Yuta HIGUCHI24057822017-08-02 15:03:51 -0700158 }
159
160 public static boolean isRootNode(ResourceId path) {
161 return path.nodeKeys().size() == 1 &&
162 ROOT_NODE.equals(path.nodeKeys().get(ROOT_INDEX));
163 }
164
165 /**
166 * Transforms device resource path to DeviceId.
167 *
168 * @param path pointing to somewhere in the subtree of a device
169 * @return DeviceId
170 * @throws IllegalArgumentException if the path was not part of devices tree
171 */
172 public static DeviceId toDeviceId(ResourceId path) {
173 checkArgument(isUnderDeviceRootNode(path), path);
174 // FIXME if we decide to drop any of intermediate nodes
175 // "/" - "devices" - "device"
Yuta HIGUCHIe057dee2017-09-15 13:56:10 -0700176 int rootIdx = ResourceIds.startsWithRootNode(path) ? 0 : -1;
177 return toDeviceId(path.nodeKeys().get(rootIdx + DEVICE_INDEX));
Yuta HIGUCHI24057822017-08-02 15:03:51 -0700178 }
179
180 /**
181 * Transforms root node of a device to corresponding DeviceId.
182 *
183 * @param deviceRoot NodeKey of a device root node
184 * @return DeviceId
185 * @throws IllegalArgumentException if not a device node
186 */
187 public static DeviceId toDeviceId(NodeKey<?> deviceRoot) {
Yuta HIGUCHIe057dee2017-09-15 13:56:10 -0700188 if (!DEVICE_SCHEMA.equals(deviceRoot.schemaId())) {
Yuta HIGUCHI24057822017-08-02 15:03:51 -0700189 throw new IllegalArgumentException(deviceRoot + " is not a device node");
190 }
191
192 if (deviceRoot instanceof ListKey) {
193 ListKey device = (ListKey) deviceRoot;
194 Optional<DeviceId> did = device.keyLeafs().stream()
195 // TODO If we decide to define ONOS schema for device ID,
196 // use whole schemaId to filter, not only by name
197 .filter(kl -> DEVICE_ID_KL_NAME.equals(kl.leafSchema().name()))
198 .map(KeyLeaf::leafValAsString)
199 .map(DeviceId::deviceId)
200 .findFirst();
201
202 if (did.isPresent()) {
203 return did.get();
204 }
205 throw new IllegalArgumentException("device-id not found in " + deviceRoot);
206 }
207 throw new IllegalArgumentException("Unexpected type " + deviceRoot.getClass());
208 }
209
210 /**
211 * Transforms DeviceId into a ResourceId pointing to device root node.
212 *
213 * @param deviceId to transform
Yuta HIGUCHIe057dee2017-09-15 13:56:10 -0700214 * @return absolute ResourceId
Yuta HIGUCHI24057822017-08-02 15:03:51 -0700215 */
216 public static ResourceId toResourceId(DeviceId deviceId) {
217 return ResourceId.builder()
218 .addBranchPointSchema(ROOT_NAME, DCS_NAMESPACE)
219 .addBranchPointSchema(DEVICES_NAME, DCS_NAMESPACE)
220 .addBranchPointSchema(DEVICE_NAME, DCS_NAMESPACE)
221 .addKeyLeaf(DEVICE_ID_KL_NAME, DCS_NAMESPACE, deviceId.toString())
222 .build();
223 }
224
225}