Solved Bug 6302-
[packetcable.git] / packetcable-policy-server / src / main / java / org / opendaylight / controller / packetcable / provider / AbstractDataTreeChangeListener.java
1 /*
2  * Copyright (c) 2015 CableLabs and others.  All rights reserved.
3  *
4  * This program and the accompanying materials are made available under the
5  * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6  * and is available at http://www.eclipse.org/legal/epl-v10.html
7  */
8
9 package org.opendaylight.controller.packetcable.provider;
10
11 import static com.google.common.base.Preconditions.checkNotNull;
12 import static org.opendaylight.controller.packetcable.provider.DataChangeUtils.collectTypeFromMap;
13 import static org.opendaylight.controller.packetcable.provider.DataChangeUtils.collectTypeFromSet;
14 import static org.opendaylight.controller.packetcable.provider.DataChangeUtils.logChange;
15 import static org.opendaylight.controller.packetcable.provider.DataChangeUtils.relativeComplement;
16
17 import com.google.common.collect.Maps;
18 import java.util.Map;
19 import java.util.NoSuchElementException;
20 import java.util.Set;
21 import java.util.Collection;
22
23 import org.eclipse.jdt.annotation.NonNull;
24 import org.opendaylight.controller.md.sal.binding.api.DataObjectModification;
25 import org.opendaylight.controller.md.sal.binding.api.DataTreeChangeListener;
26 import org.opendaylight.controller.md.sal.common.api.data.AsyncDataChangeEvent;
27 import org.opendaylight.controller.md.sal.binding.api.DataTreeModification;
28 import org.opendaylight.controller.packetcable.provider.validation.DataValidator;
29 import org.opendaylight.controller.packetcable.provider.validation.ValidationException;
30 import org.opendaylight.controller.packetcable.provider.validation.Validator;
31 import org.opendaylight.controller.packetcable.provider.validation.ValidatorProvider;
32 import org.opendaylight.yangtools.yang.binding.DataObject;
33 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
34 import org.slf4j.Logger;
35 import org.slf4j.LoggerFactory;
36
37 import javax.annotation.Nonnull;
38
39 /**
40  * @author rvail
41  * @author mmakati
42  */
43 public abstract class AbstractDataTreeChangeListener<T extends DataObject> implements DataTreeChangeListener<T> {
44
45     protected final Logger logger = LoggerFactory.getLogger(getClass());
46
47     private final Class<T> tClass;
48
49     private final DataValidator dataValidator;
50
51     public AbstractDataTreeChangeListener(Class<T> tClass,DataValidator dataValidator) {
52         this.tClass = checkNotNull(tClass);
53         this.dataValidator = checkNotNull(dataValidator);
54     }
55
56     private ValidationException validateData(final DataTreeModification<T> change){
57         InstanceIdentifier iid = change.getRootPath().getRootIdentifier();
58
59         try {
60             // getDataAfter should only remove null if the data was removed, but we don't validate on remove.
61             dataValidator.validate(iid, change.getRootNode().getDataAfter(), Validator.Extent.NODE_AND_SUBTREE);
62         }
63         catch (ValidationException e) {
64             logger.debug("invalid data: {}", change.getRootNode().getDataAfter(), e);
65             return e;
66         }
67         return null;
68     }
69
70     @Override
71     public void onDataTreeChanged(@Nonnull Collection<DataTreeModification<T>> changes)
72     {
73         Map<DataTreeModification<T>, ValidationException> exceptionMap = Maps.newHashMap();
74         for (final DataTreeModification<T> change : changes) {
75             final DataObjectModification<T> root = change.getRootNode();
76             switch (root.getModificationType()) {
77                 case SUBTREE_MODIFIED:
78                     try{
79                         ValidationException validationException = validateData(change);
80                         if(validationException != null){
81                             handleInvalidData(change,validationException);
82                         }
83                         else {
84                             handleUpdatedData(change);
85                         }
86                     }catch (NoSuchElementException e) {
87                         logger.error("Unable to find validator for data: {}", change.getRootNode().getDataAfter(), e);
88                     }
89                     break;
90                 case WRITE:
91                     try{
92                         ValidationException validationException = validateData(change);
93                         if(validationException != null){
94                             handleInvalidData(change,validationException);
95                         }
96                         else {
97                             // Treat an overwrite as an update
98                             boolean update = change.getRootNode().getDataBefore() != null;
99                             if (update) {
100                                 handleUpdatedData(change);
101                             } else {
102                                 handleCreatedData(change);
103                             }
104                         }
105                     }catch (NoSuchElementException e) {
106                         logger.error("Unable to find validator for data: {}", change.getRootNode().getDataAfter(), e);
107                     }
108                     break;
109                 case DELETE:
110                     handleRemovedData(change);
111                     break;
112                 default:
113                     break;
114             }
115         }
116     }
117     protected abstract void handleCreatedData(final DataTreeModification<T> change);
118
119     protected abstract void handleUpdatedData(final DataTreeModification<T> change);
120
121     protected abstract void handleRemovedData(final DataTreeModification<T> change);
122
123     protected abstract void handleInvalidData(final DataTreeModification<T> change, ValidationException validationException);
124
125
126 }