blob: ce123e1c925126a8fdc47db98721e4cc1533395e [file] [log] [blame]
Bharat saraswalf53b29a2016-09-27 15:35:15 +05301/*
2 * Copyright 2016-present Open Networking Laboratory
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.yms.app.ysr;
18
Bharat saraswalf53b29a2016-09-27 15:35:15 +053019import org.onosproject.yangutils.datamodel.RpcNotificationContainer;
20import org.onosproject.yangutils.datamodel.YangInclude;
21import org.onosproject.yangutils.datamodel.YangModule;
22import org.onosproject.yangutils.datamodel.YangNode;
23import org.onosproject.yangutils.datamodel.YangSchemaNode;
24import org.onosproject.yangutils.datamodel.YangSubModule;
25import org.onosproject.yangutils.datamodel.exceptions.DataModelException;
Bharat saraswalf53b29a2016-09-27 15:35:15 +053026import org.onosproject.yms.ysr.YangModuleIdentifier;
27import org.onosproject.yms.ysr.YangModuleInformation;
28import org.onosproject.yms.ysr.YangModuleLibrary;
29import org.osgi.framework.BundleContext;
30import org.slf4j.Logger;
31import org.slf4j.LoggerFactory;
32
33import java.io.File;
34import java.io.FileInputStream;
35import java.io.IOException;
36import java.io.ObjectInputStream;
37import java.text.SimpleDateFormat;
38import java.util.ArrayList;
39import java.util.Collections;
40import java.util.HashSet;
41import java.util.Iterator;
42import java.util.List;
43import java.util.Set;
44import java.util.concurrent.ConcurrentHashMap;
45import java.util.concurrent.ConcurrentMap;
46import java.util.regex.Pattern;
47
48import static org.apache.commons.io.FileUtils.deleteDirectory;
49import static org.onosproject.yangutils.datamodel.utils.DataModelUtils.parseJarFile;
50import static org.onosproject.yangutils.utils.UtilConstants.DEFAULT;
51import static org.onosproject.yangutils.utils.UtilConstants.EMPTY_STRING;
52import static org.onosproject.yangutils.utils.UtilConstants.EVENT_STRING;
53import static org.onosproject.yangutils.utils.UtilConstants.OP_PARAM;
54import static org.onosproject.yangutils.utils.UtilConstants.PERIOD;
55import static org.onosproject.yangutils.utils.io.impl.YangIoUtils.getCapitalCase;
56import static org.osgi.framework.FrameworkUtil.getBundle;
57
58
59/**
60 * Representation of default YANG schema registry. Yang schema registry
61 * provides interface to an application to register its YANG schema
62 * with YMS. It provides YANG schema nodes to YDT, YNB and YSB.
63 */
64public class DefaultYangSchemaRegistry
65 implements YangSchemaRegistry {
66
67 private static final String SYSTEM = File.separator + "system" +
68 File.separator;
69 private static final String MAVEN = "mvn:";
70 private static final String HYPHEN = "-";
71 private static final String DELIMITER = ".";
72 private static final String SERVICE = "Service";
73 private static final String JAR = ".jar";
74 private static final String USER_DIRECTORY = "user.dir";
75 private static final String SLASH = File.separator;
76 private static final String AT = "@";
77 private static final String DATE_FORMAT = "yyyy-mm-dd";
78 private static final Logger log =
79 LoggerFactory.getLogger(DefaultYangSchemaRegistry.class);
Bharat saraswalf53b29a2016-09-27 15:35:15 +053080 private final ConcurrentMap<String, YsrAppContext> appObjectStore;
Bharat saraswalf53b29a2016-09-27 15:35:15 +053081 private final ConcurrentMap<String, YsrAppContext> yangSchemaStore;
Bharat saraswalf53b29a2016-09-27 15:35:15 +053082 private final ConcurrentMap<String, YsrAppContext>
83 yangSchemaStoreForRootInterface;
Bharat saraswalf53b29a2016-09-27 15:35:15 +053084 private final ConcurrentMap<String, YsrAppContext>
85 yangSchemaStoreForRootOpParam;
Bharat saraswalf53b29a2016-09-27 15:35:15 +053086 private final ConcurrentMap<String, YsrAppContext>
87 yangRootSchemaStoreForNotification;
Bharat saraswalf53b29a2016-09-27 15:35:15 +053088 private final ConcurrentMap<String, Class<?>> registerClassStore;
Bharat saraswalf53b29a2016-09-27 15:35:15 +053089 private final ConcurrentMap<YangModuleIdentifier, String> yangFileStore;
Bharat saraswalf53b29a2016-09-27 15:35:15 +053090 private final YangModuleLibrary library;
Gaurav Agrawalfcc6c192016-09-20 14:29:15 +053091 private YsrAppContext ysrAppContext;
92 private YsrAppContext ysrContextForSchemaStore;
93 private YsrAppContext ysrContextForAppStore;
94 private ClassLoader classLoader;
Bharat saraswalf53b29a2016-09-27 15:35:15 +053095
96 /**
97 * Creates an instance of default YANG schema registry.
98 *
99 * @param moduleId module set id of YSR module library
100 */
101 public DefaultYangSchemaRegistry(String moduleId) {
102 appObjectStore = new ConcurrentHashMap<>();
103 yangSchemaStore = new ConcurrentHashMap<>();
104 yangSchemaStoreForRootInterface = new ConcurrentHashMap<>();
105 yangSchemaStoreForRootOpParam = new ConcurrentHashMap<>();
106 yangRootSchemaStoreForNotification = new ConcurrentHashMap<>();
107 registerClassStore = new ConcurrentHashMap<>();
108 yangFileStore = new ConcurrentHashMap<>();
109 library = new DefaultYangModuleLibrary(moduleId);
110 }
111
112
113 @Override
Gaurav Agrawalfcc6c192016-09-20 14:29:15 +0530114 public void registerApplication(Object appObject, Class<?> serviceClass) {
Bharat saraswalf53b29a2016-09-27 15:35:15 +0530115
116 BundleContext bundleContext = getBundle(serviceClass)
117 .getBundleContext();
118 String jarPath = getJarPathFromBundleLocation(
119 bundleContext.getBundle().getLocation(),
120 bundleContext.getProperty(USER_DIRECTORY));
Bharat saraswalf53b29a2016-09-27 15:35:15 +0530121 processRegistration(serviceClass, appObject, jarPath);
Bharat saraswalf53b29a2016-09-27 15:35:15 +0530122 }
123
124 /**
125 * Process application registration.
126 *
127 * @param serviceClass service class
128 * @param appObject application object
129 * @param jarPath jar path
130 */
131 void processRegistration(Class<?> serviceClass, Object appObject,
132 String jarPath) {
133
134 // set class loader for service class.
135 setClassLoader(serviceClass.getClassLoader());
136
137 //Check if service should be registered?
138 if (appObject != null) {
139 verifyApplicationRegistration(appObject, serviceClass);
140 }
141 //Add app class to registered service store.
142 if (!registerClassStore.containsKey(serviceClass.getName())) {
143 updateServiceClass(serviceClass);
144 }
145
146 // process storing operations.
147 if (!verifyIfApplicationAlreadyRegistered(serviceClass)) {
148 List<YangNode> curNodes =
149 processJarParsingOperations(jarPath);
150
151 if (curNodes != null) {
152 for (YangNode schemaNode : curNodes) {
153 //Process application context for registrations.
154 processApplicationContext(schemaNode);
155 //Update YANG file store.
156 updateYangFileStore(schemaNode, jarPath);
157 //Process module library operation for current node list.
158 processModuleLibrary(schemaNode);
159 }
160 //Set jar path for app context.
161 ysrAppContext.jarPath(jarPath);
162 ysrContextForSchemaStore.jarPath(jarPath);
163 ysrContextForAppStore.jarPath(jarPath);
164 }
165 }
166
167 //Verifies if object is updated for app store.
168 updateApplicationObject(appObject, serviceClass);
169 }
170
171 /**
172 * Verifies if service class should be registered or not.
173 *
174 * @param appObject application object
175 * @param appClass application class
176 */
177 private void verifyApplicationRegistration(Object appObject,
178 Class<?> appClass) {
179 Class<?> managerClass = appObject.getClass();
180 Class<?>[] services = managerClass.getInterfaces();
181 List<Class<?>> classes = new ArrayList<>();
182 Collections.addAll(classes, services);
183 if (!classes.contains(appClass)) {
184 throw new RuntimeException("service class " + appClass.getName() +
185 "is not being implemented by " +
186 managerClass.getName());
187 }
188 }
189
190 /**
191 * Verifies if application is already registered with YMS.
192 *
193 * @param appClass application class
194 * @return true if application already registered
195 */
196 private boolean verifyIfApplicationAlreadyRegistered(Class<?> appClass) {
197 String simpleName = appClass.getSimpleName();
198 String appName = appClass.getName();
199 if (!appObjectStore.containsKey(appName)) {
200 if (simpleName.contains(OP_PARAM)) {
201 return yangSchemaStoreForRootOpParam
202 .containsKey(appName);
203 } else {
204 return yangSchemaStoreForRootInterface
205 .containsKey(appName);
206 }
207 }
208 return true;
209 }
210
211 /**
212 * Verifies if service is being implemented by some new object.
213 *
214 * @param appObject application's object
215 * @param appClass application's class
216 */
217 private void updateApplicationObject(Object appObject, Class<?> appClass) {
218 YsrAppContext appContext =
219 appObjectStore.get(appClass.getName());
220 if (appContext != null) {
221 YangSchemaNode schemaNode = appContext.curNode();
222 String name = getInterfaceClassName(schemaNode);
223 if (appContext.appObject() == null) {
224 //update in application store.
225 appContext.appObject(appObject);
226 //Update app object for schema store for root interface.
227 appContext = yangSchemaStoreForRootInterface.get(name);
228 if (appContext != null) {
229 appContext.appObject(appObject);
230 }
231 // Update app object for schema store for root op param
232 appContext = yangSchemaStoreForRootOpParam.get(name + OP_PARAM);
233 if (appContext != null) {
234 appContext.appObject(appObject);
235 }
236 }
237 }
238 }
239
240 @Override
241 public void unRegisterApplication(Object managerObject,
242 Class<?> serviceClass) {
243 YangSchemaNode curNode = null;
244 String serviceName = serviceClass.getName();
245
246 //Check if service should be unregistered?
247 if (managerObject != null) {
248 verifyApplicationRegistration(managerObject, serviceClass);
249 }
250 //Remove registered class from store.
251 registerClassStore.remove(serviceName);
252
253 //check if service is in app store.
254 if (appObjectStore.containsKey(serviceName)) {
255 curNode = retrieveNodeForUnregister(serviceName, appObjectStore,
256 managerObject);
257 } else if (yangSchemaStoreForRootInterface.containsKey(serviceName)) {
258 //check if service is in interface store.
259 curNode = retrieveNodeForUnregister(serviceName,
260 yangSchemaStoreForRootInterface,
261 managerObject);
262 } else if (yangSchemaStoreForRootOpParam.containsKey(serviceName)) {
263 //check if service is in op param store.
264 curNode = retrieveNodeForUnregister(serviceName,
265 yangSchemaStoreForRootOpParam,
266 managerObject);
267 }
268 if (curNode != null) {
269 String javaName = getInterfaceClassName(curNode);
270 removeFromYangSchemaStore(curNode);
271 removeFromYangNotificationStore(curNode);
272 removeFromAppSchemaStore(serviceName);
273 removeFromYangSchemaNodeForRootInterface(javaName);
274 removeFromYangSchemaNodeForRootOpParam(javaName);
275 removeYangFileInfoFromStore(curNode);
276 log.info(" service {} is unregistered.",
277 serviceClass.getSimpleName());
278 } else {
279 throw new RuntimeException(serviceClass.getSimpleName() +
280 " service was not registered.");
281 }
282 }
283
284 @Override
285 public Object getRegisteredApplication(YangSchemaNode schemaNode) {
286 if (schemaNode != null) {
287 String name = getInterfaceClassName(schemaNode);
288 if (yangSchemaStoreForRootInterface.containsKey(name)) {
289 return yangSchemaStoreForRootInterface.get(name)
290 .appObject();
291 }
292 log.error("{} not found.", name);
293 }
294 return null;
295 }
296
297 @Override
298 public YangSchemaNode getYangSchemaNodeUsingSchemaName(String schemaName) {
299 return getSchemaNodeUsingSchemaNameWithRev(schemaName);
300 }
301
302 @Override
303 public YangSchemaNode getYangSchemaNodeUsingAppName(String appName) {
304 YsrAppContext appContext = appObjectStore.get(appName);
305 if (appContext != null) {
306 return appContext.curNode();
307 }
308 log.error("{} not found.", appName);
309 return null;
310 }
311
312 @Override
313 public YangSchemaNode
314 getYangSchemaNodeUsingGeneratedRootNodeInterfaceFileName(String name) {
315 YsrAppContext appContext = yangSchemaStoreForRootInterface.get(name);
316 if (appContext != null) {
317 return appContext.curNode();
318 }
319 log.error("{} not found.", name);
320 return null;
321 }
322
323 @Override
324 public YangSchemaNode getYangSchemaNodeUsingGeneratedRootNodeOpPramFileName(
325 String name) {
326 YsrAppContext appContext = yangSchemaStoreForRootOpParam.get(name);
327 if (appContext != null) {
328 return appContext.curNode();
329 }
330 log.error("{} not found.", name);
331 return null;
332 }
333
334 @Override
335 public YangSchemaNode getRootYangSchemaNodeForNotification(String name) {
336 YsrAppContext appContext = yangRootSchemaStoreForNotification.get(name);
337 if (appContext != null) {
338 return appContext.curNode();
339 }
340 log.error("{} not found.", name);
341 return null;
342 }
343
344 @Override
345 public Class<?> getRegisteredClass(YangSchemaNode schemaNode,
346 String appName) {
347 String interfaceName = getInterfaceClassName(schemaNode);
348 String serviceName = getServiceName(schemaNode);
349 String defaultClass;
350 if (schemaNode instanceof RpcNotificationContainer) {
351 defaultClass = getOpParamClassName(schemaNode);
352 } else {
353 defaultClass = getDefaultClassName(schemaNode);
354 }
355 //If application class is registered.
356 if (registerClassStore.containsKey(appName)) {
357 return registerClassStore.get(appName);
358 } else if (registerClassStore.containsKey(interfaceName)) {
359 //If interface class is registered.
360 return registerClassStore.get(interfaceName);
361 } else if (registerClassStore.containsKey(serviceName)) {
362 //If service class is registered.
363 return registerClassStore.get(serviceName);
364 } else if (registerClassStore.containsKey(defaultClass)) {
365 //If default class is registered.
366 return registerClassStore.get(defaultClass);
367 }
368 return null;
369 }
370
371 /**
372 * Returns YANG file path for module identifier.
373 *
374 * @param moduleIdentifier module identifier
375 * @return YANG file path for module identifier
376 */
377 public String getYangFile(YangModuleIdentifier moduleIdentifier) {
378 if (yangFileStore.containsKey(moduleIdentifier)) {
379 return yangFileStore.get(moduleIdentifier);
380 }
381 log.error("YANG files for corresponding module identifier {} not " +
382 "found", moduleIdentifier);
383 return null;
384 }
385
386 /**
387 * Updates service class store.
388 *
389 * @param serviceClass service class
390 */
391 void updateServiceClass(Class<?> serviceClass) {
392 registerClassStore.put(serviceClass.getName(), serviceClass);
393 }
394
395 /**
396 * Updates application object store.
397 *
398 * @param appName application name
399 */
400 private void updateAppObjectStore(String appName) {
401 if (verifyClassExistence(appName)) {
402 appObjectStore.put(appName, ysrContextForAppStore);
403 }
404 }
405
406 /**
407 * Updates YANG schema object store.
408 *
409 * @param schemaNode application's schema node
410 */
411 private void updateYangSchemaStore(YangSchemaNode schemaNode) {
412 addSchemaNodeUsingSchemaNameWithRev(schemaNode);
413 }
414
415 /**
416 * Updates YANG schema notification object store.
417 *
418 * @param name application's notification name
419 */
420 private void updateYangNotificationStore(String name) {
421 if (verifyClassExistence(name)) {
422 yangRootSchemaStoreForNotification.put(name, ysrAppContext);
423 }
424 }
425
426 /**
427 * Updates YANG schema object store for root interface file name.
428 *
429 * @param name name of generated interface file for root
430 * node
431 */
432 private void updateYangSchemaForRootInterfaceFileNameStore(String name) {
433 if (verifyClassExistence(name)) {
434 yangSchemaStoreForRootInterface.put(name, ysrAppContext);
435 }
436 }
437
438 /**
439 * Updates YANG schema object store for root op param file name.
440 *
441 * @param name name of generated op param file for root node
442 */
443 private void updateYangSchemaForRootOpParamFileNameStore(String name) {
444 if (verifyClassExistence(name)) {
445 yangSchemaStoreForRootOpParam.put(name, ysrAppContext);
446 }
447 }
448
449 /**
450 * Updates yang file store for YANG node.
451 *
452 * @param node YANG node
453 * @param jarPath jar file path
454 */
455 private void updateYangFileStore(YangNode node, String jarPath) {
456 //FIXME: fix when yang tools support for file name.
457 //yangFileStore.put(getModuleIdentifier(node),
458 // getYangFilePath(jarPath, node.getFileName()));
459 }
460
461 /**
462 * Returns yang file path.
463 *
464 * @param jarPath jar path
465 * @param metaDataFileName name of yang file from metadata
466 * @return yang file path
467 */
468 private String getYangFilePath(String jarPath, String metaDataFileName) {
469 String[] metaData = metaDataFileName.split(SLASH);
470 return jarPath + SLASH + metaData[metaData.length - 1];
471 }
472
473 /**
474 * Process jar file for fetching YANG nodes.
475 *
476 * @param path jar file path
477 * @return YANG schema nodes
478 */
479 private List<YangNode> processJarParsingOperations(String path) {
480 //Deserialize data model and get the YANG node set.
481 try {
482 return parseJarFile(path + JAR, path);
483 } catch (IOException e) {
484 log.error(" failed to parse the jar file in path {} : {} ", path,
485 e.getMessage());
486 }
487 return null;
488 }
489
490 /**
491 * Process an application an updates the maps for YANG schema registry.
492 *
493 * @param appNode application YANG schema nodes
494 */
495 void processApplicationContext(YangSchemaNode appNode) {
496
497 String appName = getInterfaceClassName(appNode);
498
499 //Create a new instance of ysr app context for each node.
500 ysrAppContext = new YsrAppContext();
501 ysrContextForSchemaStore = new YsrAppContext();
502 ysrContextForAppStore = new YsrAppContext();
503
504 //add cur node to app context.
505 ysrAppContext.curNode(appNode);
506 ysrContextForAppStore.curNode(appNode);
507
508 //Updates maps wih schema nodes.
509 updateAppObjectStore(getServiceName(appNode));
510
511 // Updates schema store.
512 updateYangSchemaStore(appNode);
513 // update interface store.
514 updateYangSchemaForRootInterfaceFileNameStore(appName);
515 //update op param store.
516 updateYangSchemaForRootOpParamFileNameStore(getOpParamClassName(appNode));
517 //Checks if notification is present then update notification store map.
518 String eventSubject = null;
519 try {
520 if (appNode.isNotificationPresent()) {
521 eventSubject = getEventClassName(appNode);
522 }
523 } catch (DataModelException e) {
524 log.error("failed to search notification from schema map : {}",
525 e.getLocalizedMessage());
526 }
527 if (eventSubject != null) {
528 updateYangNotificationStore(eventSubject);
529 }
530 log.info("successfully registered this application {}{}", appName,
531 SERVICE);
Bharat saraswalf53b29a2016-09-27 15:35:15 +0530532 }
533
534 /**
535 * Returns jar path from bundle mvnLocationPath.
536 *
537 * @param mvnLocationPath mvnLocationPath of bundle
538 * @return path of jar
539 */
540 private String getJarPathFromBundleLocation(String mvnLocationPath,
541 String currentDirectory) {
542 String path = currentDirectory + SYSTEM;
543 String[] strArray = mvnLocationPath.split(MAVEN);
544 String[] split = strArray[1].split(File.separator);
545 String[] groupId = split[0].split(Pattern.quote(DELIMITER));
546
547 return path + groupId[0] + SLASH + groupId[1] + SLASH + split[1] +
548 SLASH + split[2] + SLASH + split[1] + HYPHEN + split[2];
549 }
550
551 /**
552 * Returns de-serializes YANG data-model nodes.
553 *
554 * @param serializedFileInfo serialized File Info
555 * @return de-serializes YANG data-model nodes
556 */
557 Set<YangSchemaNode> deSerializeDataModel(String serializedFileInfo) {
558
559 Set<YangSchemaNode> nodes = new HashSet<>();
560 Object readValue;
561 try {
562 FileInputStream fileInputStream =
563 new FileInputStream(serializedFileInfo);
564 ObjectInputStream objectInputStream =
565 new ObjectInputStream(fileInputStream);
566 readValue = objectInputStream.readObject();
567 if (readValue instanceof Set<?>) {
568 for (Object obj : (Set<?>) readValue) {
569 if (obj instanceof YangSchemaNode) {
570 nodes.add((YangSchemaNode) obj);
571 } else {
572 throw new RuntimeException(
573 "deserialize object is not an instance of " +
574 "YANG schema node" + obj);
575 }
576 }
577 } else {
578 throw new RuntimeException(
579 "deserialize object is not an instance of set of" +
580 "YANG schema node" + readValue);
581 }
582 objectInputStream.close();
583 fileInputStream.close();
584 } catch (IOException | ClassNotFoundException e) {
585 log.error(" {} not found.: {}", serializedFileInfo,
586 e.getLocalizedMessage());
587 }
588
589 return nodes;
590 }
591
592 /**
593 * Returns ysr app context.
594 *
595 * @return ysr app context
596 */
597 YsrAppContext ysrAppContext() {
598 return ysrAppContext;
599 }
600
601 /**
602 * Returns schema node based on the revision.
603 *
604 * @param name name of the schema node
605 * @return schema node based on the revision
606 */
607 private YangSchemaNode getSchemaNodeUsingSchemaNameWithRev(String name) {
608 YsrAppContext appContext;
609 YangSchemaNode schemaNode;
610 if (name.contains(AT)) {
611 String[] revArray = name.split(AT);
612 appContext = yangSchemaStore.get(revArray[0]);
613 schemaNode = appContext.getSchemaNodeForRevisionStore(name);
614 if (schemaNode != null) {
615 return schemaNode;
616 }
617 return appContext.curNode();
618 }
619 if (yangSchemaStore.containsKey(name)) {
620 appContext = yangSchemaStore.get(name);
621 if (appContext != null) {
622 Iterator<YangSchemaNode> iterator = appContext
623 .getYangSchemaNodeForRevisionStore().values()
624 .iterator();
625 if (iterator.hasNext()) {
626 return appContext.getYangSchemaNodeForRevisionStore()
627 .values().iterator().next();
628 } else {
629 return null;
630 }
631 }
632 }
633 log.error("{} not found.", name);
634 return null;
635 }
636
637 /**
638 * Adds schema node when different revision of node has received.
639 *
640 * @param schemaNode schema node
641 */
642 private void addSchemaNodeUsingSchemaNameWithRev(
643 YangSchemaNode schemaNode) {
644
645 String date = getDateInStringFormat(schemaNode);
646 String name = schemaNode.getName();
647 if (!date.equals(EMPTY_STRING)) {
648 name = name + AT + date;
649 }
650 //check if already present.
651 if (!yangSchemaStore.containsKey(schemaNode.getName())) {
652 ysrContextForSchemaStore.curNode(schemaNode);
653 //if revision is not present no need to add in revision store.
654 ysrContextForSchemaStore
655 .addSchemaNodeWithRevisionStore(name, schemaNode);
656 yangSchemaStore.put(schemaNode.getName(),
657 ysrContextForSchemaStore);
658 } else {
659 YsrAppContext appContext =
660 yangSchemaStore.get(schemaNode.getName());
661 appContext.addSchemaNodeWithRevisionStore(name, schemaNode);
662 appContext.curNode(schemaNode);
663 }
664 }
665
666 /**
667 * Returns date in string format.
668 *
669 * @param schemaNode schema node
670 * @return date in string format
671 */
672 String getDateInStringFormat(YangSchemaNode schemaNode) {
673 if (schemaNode != null) {
674 if (((YangNode) schemaNode).getRevision() != null) {
675 return new SimpleDateFormat(DATE_FORMAT)
676 .format(((YangNode) schemaNode).getRevision()
677 .getRevDate());
678 }
679 }
680 return EMPTY_STRING;
681 }
682
683 /**
684 * Removes schema node from schema map.
685 *
686 * @param removableNode schema node which needs to be removed
687 */
688 private void removeSchemaNode(YangSchemaNode removableNode) {
689
690 String name = removableNode.getName();
691 String date = getDateInStringFormat(removableNode);
692
693 if (!date.isEmpty()) {
694 name = removableNode.getName() + AT +
695 getDateInStringFormat(removableNode);
696 }
697 YsrAppContext appContext = yangSchemaStore
698 .get(removableNode.getName());
699 if (appContext != null &&
700 !appContext.getYangSchemaNodeForRevisionStore().isEmpty() &&
701 appContext.getYangSchemaNodeForRevisionStore().size() != 1) {
702 appContext.removeSchemaNodeForRevisionStore(name);
703 } else {
704 yangSchemaStore.remove(removableNode.getName());
705 }
706 }
707
708 /**
709 * Verifies if the manager object is already registered with notification
710 * handler.
711 *
712 * @param serviceClass service class
713 * @return true if the manager object is already registered with
714 * notification handler
715 */
Gaurav Agrawalfcc6c192016-09-20 14:29:15 +0530716 public boolean verifyNotificationObject(Class<?> serviceClass) {
Bharat saraswalf53b29a2016-09-27 15:35:15 +0530717 YangSchemaNode schemaNode = null;
718 String serviceName = serviceClass.getName();
719 if (appObjectStore.containsKey(serviceName)) {
720 schemaNode = getYangSchemaNodeUsingAppName(serviceName);
721 } else if (yangSchemaStoreForRootInterface.containsKey(serviceName)) {
722 schemaNode =
723 getYangSchemaNodeUsingGeneratedRootNodeInterfaceFileName(
724 serviceName);
725 } else if (yangSchemaStoreForRootOpParam.containsKey(serviceName)) {
726 schemaNode = getYangSchemaNodeUsingGeneratedRootNodeOpPramFileName(
727 serviceName);
728 }
729
730 if (schemaNode != null) {
731 String name = getEventClassName(schemaNode);
732
733 YsrAppContext appContext =
734 yangRootSchemaStoreForNotification.get(name);
735 if (appContext != null && !appContext.isNotificationRegistered()) {
736 appContext.setNotificationRegistered(true);
737 return true;
738 }
739 }
740 return false;
741 }
742
743 /**
744 * Returns schema node's generated interface class name.
745 *
746 * @param schemaNode schema node
747 * @return schema node's generated interface class name
748 */
749 private String getInterfaceClassName(YangSchemaNode schemaNode) {
750 return schemaNode.getJavaPackage() + PERIOD +
751 getCapitalCase(schemaNode.getJavaClassNameOrBuiltInType());
752 }
753
754 /**
755 * Returns schema node's generated op param class name.
756 *
757 * @param schemaNode schema node
758 * @return schema node's generated op param class name
759 */
760 private String getOpParamClassName(YangSchemaNode schemaNode) {
761 return getInterfaceClassName(schemaNode) + OP_PARAM;
762 }
763
764 /**
765 * Returns schema node's generated op param class name.
766 *
767 * @param schemaNode schema node
768 * @return schema node's generated op param class name
769 */
770 private String getDefaultClassName(YangSchemaNode schemaNode) {
771 return schemaNode.getJavaPackage() + PERIOD + getCapitalCase(DEFAULT) +
772 getCapitalCase(schemaNode.getJavaClassNameOrBuiltInType());
773 }
774
775 /**
776 * Returns schema node's generated event class name.
777 *
778 * @param schemaNode schema node
779 * @return schema node's generated event class name
780 */
781 private String getEventClassName(YangSchemaNode schemaNode) {
782 return getInterfaceClassName(schemaNode).toLowerCase() + PERIOD +
783 getCapitalCase(schemaNode.getJavaClassNameOrBuiltInType()) +
784 EVENT_STRING;
785 }
786
787 /**
788 * Returns schema node's generated service class name.
789 *
790 * @param schemaNode schema node
791 * @return schema node's generated service class name
792 */
793 private String getServiceName(YangSchemaNode schemaNode) {
794 return getInterfaceClassName(schemaNode) + SERVICE;
795 }
796
797 /**
798 * Returns YSR application context for schema map.
799 *
800 * @return YSR application context for schema map
801 */
802 YsrAppContext ysrContextForSchemaStore() {
803 return ysrContextForSchemaStore;
804 }
805
806 /**
807 * Sets YSR application context for schema map.
808 *
809 * @param context YSR application context for
810 * schema map
811 */
812 void ysrContextForSchemaStore(YsrAppContext context) {
813 ysrContextForSchemaStore = context;
814 }
815
816 /**
817 * Returns YSR app context for application store.
818 *
819 * @return YSR app context for application store
820 */
821 YsrAppContext ysrContextForAppStore() {
822 return ysrContextForAppStore;
823 }
824
825 /**
826 * Retrieves schema node from the store and deletes jar file path.
827 *
828 * @param appName application name
829 * @param store YSR stores
830 * @param appObject applications object
831 * @return schema node from the store
832 */
833 private YangSchemaNode retrieveNodeForUnregister(
834 String appName,
835 ConcurrentMap<String, YsrAppContext> store, Object appObject) {
836
837 YsrAppContext curContext = store.get(appName);
838 boolean isValidObject;
839 if (curContext != null) {
840 isValidObject = verifyAppObject(appObject, curContext.appObject());
841 if (isValidObject) {
842 YangSchemaNode curNode = curContext.curNode();
843 //Delete all the generated ysr information in application's
844 // package.
845 removeYsrGeneratedTemporaryResources(curContext.jarPath(),
846 appName);
847 return curNode;
848 }
849 }
850 return null;
851 }
852
853 /**
854 * Verifies the application object which needs to be unregistered.
855 *
856 * @param appObject current received application object
857 * @param context stored application object
858 * @return true if objects are equal
859 */
860 private boolean verifyAppObject(Object appObject, Object context) {
861 if (appObject != null && context != null) {
862 return appObject.equals(context);
863 }
864 return appObject == null && context == null;
865 }
866
867 /**
868 * Removes YSR generated temporary resources.
869 *
870 * @param rscPath resource path
871 * @param appName application name
872 */
873 private void removeYsrGeneratedTemporaryResources(String rscPath,
874 String appName) {
875 if (rscPath != null) {
876 File jarPath = new File(rscPath);
877 if (jarPath.exists()) {
878 try {
879 deleteDirectory(jarPath);
880 } catch (IOException e) {
881 log.error("failed to delete ysr resources for {} : {}",
882 appName, e.getLocalizedMessage());
883 }
884 }
885 }
886 }
887
888 /**
889 * Removes from YANG schema store.
890 *
891 * @param curNode schema node
892 */
893 private void removeFromYangSchemaStore(YangSchemaNode curNode) {
894 removeSchemaNode(curNode);
895 }
896
897 /**
898 * Removes from YANG schema notification store.
899 *
900 * @param curNode schema node
901 */
902 private void removeFromYangNotificationStore(YangSchemaNode curNode) {
903 yangRootSchemaStoreForNotification
904 .remove(getEventClassName(curNode));
905 }
906
907 /**
908 * Removes from app store.
909 *
910 * @param appName application name
911 */
912 private void removeFromAppSchemaStore(String appName) {
913 appObjectStore.remove(appName);
914 }
915
916 /**
917 * Removes from interface store.
918 *
919 * @param appName application name
920 */
921 private void removeFromYangSchemaNodeForRootInterface(String appName) {
922 yangSchemaStoreForRootInterface.remove(appName);
923 }
924
925 /**
926 * Removes from op param store.
927 *
928 * @param appName application name
929 */
930 private void removeFromYangSchemaNodeForRootOpParam(String appName) {
931 yangSchemaStoreForRootOpParam.remove(appName + OP_PARAM);
932 }
933
934 /**
935 * Removes YANG file information from file store.
936 *
937 * @param schemaNode schema node
938 */
939 private void removeYangFileInfoFromStore(YangSchemaNode schemaNode) {
940 yangFileStore.remove(getModuleIdentifier(schemaNode));
941 }
942
943 /**
944 * Verifies if class with given name exists.
945 *
946 * @param appName application name
947 * @return true if class exists
948 */
949 boolean verifyClassExistence(String appName) {
950 try {
951 classLoader.loadClass(appName);
952 return true;
953 } catch (ClassNotFoundException e) {
954 return false;
955 }
956 }
957
958 /**
Bharat saraswalf53b29a2016-09-27 15:35:15 +0530959 * Clears database for YSR.
960 */
961 public void flushYsrData() {
962 appObjectStore.clear();
963 yangSchemaStore.clear();
964 yangRootSchemaStoreForNotification.clear();
965 yangSchemaStoreForRootOpParam.clear();
966 yangSchemaStoreForRootInterface.clear();
967 registerClassStore.clear();
968 yangFileStore.clear();
969 }
970
971 /**
972 * Sets class loader of registered class.
973 *
974 * @param classLoader class loader of registered class
975 */
976 void setClassLoader(ClassLoader classLoader) {
977 this.classLoader = classLoader;
978 }
979
980 /**
981 * Process module library for a registered service.
982 *
983 * @param node YANG schema nodes
984 */
985 private void processModuleLibrary(YangNode node) {
986 YangModuleInformation moduleInformation =
987 new DefaultYangModuleInformation(getModuleIdentifier(node),
988 node.getNameSpace());
989 addSubModuleIdentifier(node, (
990 DefaultYangModuleInformation) moduleInformation);
991 //TODO: add feature list to module information.
992 ((DefaultYangModuleLibrary) library)
993 .addModuleInformation(moduleInformation);
994 }
995
996 /**
997 * Adds sub module identifier.
998 *
999 * @param node schema node
1000 * @param information module information
1001 */
1002 private void addSubModuleIdentifier(
1003 YangSchemaNode node, DefaultYangModuleInformation information) {
1004 List<YangInclude> includeList = new ArrayList<>();
1005 if (node instanceof YangModule) {
1006 includeList = ((YangModule) node).getIncludeList();
1007 } else if (node instanceof YangSubModule) {
1008 includeList = ((YangSubModule) node).getIncludeList();
1009 }
1010 for (YangInclude include : includeList) {
1011 information.addSubModuleIdentifiers(getModuleIdentifier(
1012 include.getIncludedNode()));
1013 }
1014 }
1015
1016 /**
1017 * Returns module identifier for schema node.
1018 *
1019 * @param schemaNode schema node
1020 * @return module identifier for schema node
1021 */
1022 private YangModuleIdentifier getModuleIdentifier(
1023 YangSchemaNode schemaNode) {
1024 return new DefaultYangModuleIdentifier(
1025 schemaNode.getName(), getDateInStringFormat(schemaNode));
1026 }
1027
1028 /**
1029 * Returns module library.
1030 *
1031 * @return module library
1032 */
1033 public YangModuleLibrary getLibrary() {
1034 return library;
1035 }
Bharat saraswalf53b29a2016-09-27 15:35:15 +05301036}