blob: 358b4009b8c01e1c6343d6f00d43dfb051f59adb [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
47 /**
48 * SchemaId name for root node.
49 */
50 public static final String ROOT_NAME = "/";
51 /**
52 * SchemaId name for devices node.
53 */
54 public static final String DEVICES_NAME = "devices";
Yuta HIGUCHIe057dee2017-09-15 13:56:10 -070055 public static final SchemaId DEVICES_SCHEMA = new SchemaId(DEVICES_NAME, DCS_NAMESPACE);
Yuta HIGUCHI24057822017-08-02 15:03:51 -070056 /**
57 * SchemaId name for device node.
58 */
59 public static final String DEVICE_NAME = "device";
Yuta HIGUCHIe057dee2017-09-15 13:56:10 -070060 public static final SchemaId DEVICE_SCHEMA = new SchemaId(DEVICE_NAME, DCS_NAMESPACE);
Yuta HIGUCHI24057822017-08-02 15:03:51 -070061 /**
62 * KeyLeaf {@code name}, which holds DeviceId information on device node.
63 */
64 public static final String DEVICE_ID_KL_NAME = "device-id";
65
66 /**
Yuta HIGUCHIe057dee2017-09-15 13:56:10 -070067 * Absolute ResourceId pointing at root node.
68 * @deprecated Use {@link ResourceIds#ROOT_ID} instead
Yuta HIGUCHI24057822017-08-02 15:03:51 -070069 */
Yuta HIGUCHIe057dee2017-09-15 13:56:10 -070070 @Deprecated
71 public static final ResourceId ROOT_ID = ResourceIds.ROOT_ID;
Yuta HIGUCHI24057822017-08-02 15:03:51 -070072
Yuta HIGUCHIe057dee2017-09-15 13:56:10 -070073 /**
74 * Absolute ResourceId pointing at 'devices' node.
75 */
Yuta HIGUCHIea1fe522017-09-01 14:24:02 -070076 public static final ResourceId DEVICES_ID = ResourceId.builder()
77 .addBranchPointSchema(ROOT_NAME, DCS_NAMESPACE)
78 .addBranchPointSchema(DEVICES_NAME, DCS_NAMESPACE)
79 .build();
80
81
Yuta HIGUCHI24057822017-08-02 15:03:51 -070082 static final NodeKey<?> ROOT_NODE =
83 NodeKey.builder().schemaId(ROOT_NAME, DCS_NAMESPACE).build();
84
85 /**
86 * nodeKeys index for root node.
87 */
Yuta HIGUCHIe057dee2017-09-15 13:56:10 -070088 @Deprecated
Yuta HIGUCHI24057822017-08-02 15:03:51 -070089 static final int ROOT_INDEX = 0;
90 /**
Yuta HIGUCHIe057dee2017-09-15 13:56:10 -070091 * nodeKeys index relative from root for devices node.
Yuta HIGUCHI24057822017-08-02 15:03:51 -070092 */
93 static final int DEVICES_INDEX = 1;
94 /**
Yuta HIGUCHIe057dee2017-09-15 13:56:10 -070095 * nodeKeys index relative from root for device node.
Yuta HIGUCHI24057822017-08-02 15:03:51 -070096 */
97 static final int DEVICE_INDEX = 2;
98
99 /**
Yuta HIGUCHIe057dee2017-09-15 13:56:10 -0700100 * Converts root relative ResourceId used by DynamicConfigEvent.
101 *
102 * @param rootRelative resource Id
103 * @return absolute ResourceId.
104 */
105 @Beta
106 public static ResourceId toAbsolute(ResourceId rootRelative) {
107 if (ResourceIds.startsWithRootNode(rootRelative)) {
108 return rootRelative;
109 }
110 return ResourceIds.concat(ResourceIds.ROOT_ID, rootRelative);
111 }
112
113 /**
Yuta HIGUCHI24057822017-08-02 15:03:51 -0700114 * Tests if specified path points to root node of a Device.
115 *
116 * @param path to test.
117 * @return true if path points to root node of a Device.
118 */
119 public static boolean isDeviceRootNode(ResourceId path) {
Yuta HIGUCHIe057dee2017-09-15 13:56:10 -0700120 if (ResourceIds.startsWithRootNode(path)) {
121 return path.nodeKeys().size() == 3 &&
122 isUnderDeviceRootNode(path);
123 } else {
124 return path.nodeKeys().size() == 2 &&
125 isUnderDeviceRootNode(path);
126 }
Yuta HIGUCHI24057822017-08-02 15:03:51 -0700127 }
128
129 /**
Yuta HIGUCHIe057dee2017-09-15 13:56:10 -0700130 * Tests if specified path points to root node of a Device or it's subtree.
Yuta HIGUCHI24057822017-08-02 15:03:51 -0700131 *
132 * @param path to test.
133 * @return true if path points to root node of a Device.
134 */
135 public static boolean isUnderDeviceRootNode(ResourceId path) {
Yuta HIGUCHIe057dee2017-09-15 13:56:10 -0700136 int rootIdx = ResourceIds.startsWithRootNode(path) ? 0 : -1;
137 return path.nodeKeys().size() >= rootIdx + 3 &&
138 DEVICE_SCHEMA.equals(path.nodeKeys().get(rootIdx + DEVICE_INDEX).schemaId()) &&
139 (path.nodeKeys().get(rootIdx + DEVICE_INDEX) instanceof ListKey) &&
140 DEVICES_SCHEMA.equals(path.nodeKeys().get(rootIdx + DEVICES_INDEX).schemaId()); }
Yuta HIGUCHI24057822017-08-02 15:03:51 -0700141
142 /**
143 * Tests if specified path points to root or devices node.
144 *
145 * @param path to test.
146 * @return true if path points to root node of a Device.
147 */
148 public static boolean isRootOrDevicesNode(ResourceId path) {
149 return isDevicesNode(path) ||
150 isRootNode(path);
151 }
152
153 public static boolean isDevicesNode(ResourceId path) {
Yuta HIGUCHIe057dee2017-09-15 13:56:10 -0700154 int rootIdx = ResourceIds.startsWithRootNode(path) ? 0 : -1;
155 return path.nodeKeys().size() == rootIdx + 2 &&
156 DEVICES_SCHEMA.equals(path.nodeKeys().get(rootIdx + DEVICES_INDEX).schemaId());
Yuta HIGUCHI24057822017-08-02 15:03:51 -0700157 }
158
159 public static boolean isRootNode(ResourceId path) {
160 return path.nodeKeys().size() == 1 &&
161 ROOT_NODE.equals(path.nodeKeys().get(ROOT_INDEX));
162 }
163
164 /**
165 * Transforms device resource path to DeviceId.
166 *
167 * @param path pointing to somewhere in the subtree of a device
168 * @return DeviceId
169 * @throws IllegalArgumentException if the path was not part of devices tree
170 */
171 public static DeviceId toDeviceId(ResourceId path) {
172 checkArgument(isUnderDeviceRootNode(path), path);
173 // FIXME if we decide to drop any of intermediate nodes
174 // "/" - "devices" - "device"
Yuta HIGUCHIe057dee2017-09-15 13:56:10 -0700175 int rootIdx = ResourceIds.startsWithRootNode(path) ? 0 : -1;
176 return toDeviceId(path.nodeKeys().get(rootIdx + DEVICE_INDEX));
Yuta HIGUCHI24057822017-08-02 15:03:51 -0700177 }
178
179 /**
180 * Transforms root node of a device to corresponding DeviceId.
181 *
182 * @param deviceRoot NodeKey of a device root node
183 * @return DeviceId
184 * @throws IllegalArgumentException if not a device node
185 */
186 public static DeviceId toDeviceId(NodeKey<?> deviceRoot) {
Yuta HIGUCHIe057dee2017-09-15 13:56:10 -0700187 if (!DEVICE_SCHEMA.equals(deviceRoot.schemaId())) {
Yuta HIGUCHI24057822017-08-02 15:03:51 -0700188 throw new IllegalArgumentException(deviceRoot + " is not a device node");
189 }
190
191 if (deviceRoot instanceof ListKey) {
192 ListKey device = (ListKey) deviceRoot;
193 Optional<DeviceId> did = device.keyLeafs().stream()
194 // TODO If we decide to define ONOS schema for device ID,
195 // use whole schemaId to filter, not only by name
196 .filter(kl -> DEVICE_ID_KL_NAME.equals(kl.leafSchema().name()))
197 .map(KeyLeaf::leafValAsString)
198 .map(DeviceId::deviceId)
199 .findFirst();
200
201 if (did.isPresent()) {
202 return did.get();
203 }
204 throw new IllegalArgumentException("device-id not found in " + deviceRoot);
205 }
206 throw new IllegalArgumentException("Unexpected type " + deviceRoot.getClass());
207 }
208
209 /**
210 * Transforms DeviceId into a ResourceId pointing to device root node.
211 *
212 * @param deviceId to transform
Yuta HIGUCHIe057dee2017-09-15 13:56:10 -0700213 * @return absolute ResourceId
Yuta HIGUCHI24057822017-08-02 15:03:51 -0700214 */
215 public static ResourceId toResourceId(DeviceId deviceId) {
216 return ResourceId.builder()
217 .addBranchPointSchema(ROOT_NAME, DCS_NAMESPACE)
218 .addBranchPointSchema(DEVICES_NAME, DCS_NAMESPACE)
219 .addBranchPointSchema(DEVICE_NAME, DCS_NAMESPACE)
220 .addKeyLeaf(DEVICE_ID_KL_NAME, DCS_NAMESPACE, deviceId.toString())
221 .build();
222 }
223
224}