CDS: Add stress test RPC to the cars model
[controller.git] / opendaylight / config / config-manager-facade-xml / src / main / java / org / opendaylight / controller / config / facade / xml / strategy / MergeEditConfigStrategy.java
1 /*
2  * Copyright (c) 2015 Cisco Systems, Inc. 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.config.facade.xml.strategy;
10
11 import static java.util.Arrays.asList;
12
13 import java.util.ArrayList;
14 import java.util.List;
15 import java.util.Map;
16 import java.util.Map.Entry;
17 import javax.management.Attribute;
18 import javax.management.ObjectName;
19 import org.opendaylight.controller.config.facade.xml.exception.ConfigHandlingException;
20 import org.opendaylight.controller.config.facade.xml.mapping.attributes.fromxml.AttributeConfigElement;
21 import org.opendaylight.controller.config.facade.xml.mapping.config.ServiceRegistryWrapper;
22 import org.opendaylight.controller.config.util.ConfigTransactionClient;
23 import org.opendaylight.controller.config.util.xml.DocumentedException;
24 import org.slf4j.Logger;
25 import org.slf4j.LoggerFactory;
26
27 public class MergeEditConfigStrategy extends AbstractEditConfigStrategy {
28
29     private static final Logger LOG = LoggerFactory.getLogger(MergeEditConfigStrategy.class);
30
31     public MergeEditConfigStrategy() {
32
33     }
34
35     @Override
36     void handleMissingInstance(Map<String, AttributeConfigElement> configuration, ConfigTransactionClient ta,
37                                String module, String instance, ServiceRegistryWrapper services) throws
38         ConfigHandlingException {
39         throw new ConfigHandlingException(
40                 String.format("Unable to handle missing instance, no missing instances should appear at this point, missing: %s : %s ",
41                         module,
42                         instance),
43                 DocumentedException.ErrorType.application,
44                 DocumentedException.ErrorTag.operation_failed,
45                 DocumentedException.ErrorSeverity.error);
46     }
47
48     @Override
49     void executeStrategy(Map<String, AttributeConfigElement> configuration, ConfigTransactionClient ta, ObjectName on, ServiceRegistryWrapper services) throws
50         ConfigHandlingException {
51
52         for (Entry<String, AttributeConfigElement> configAttributeEntry : configuration.entrySet()) {
53             try {
54                 AttributeConfigElement ace = configAttributeEntry.getValue();
55
56                 if (!ace.getResolvedValue().isPresent()) {
57                     LOG.debug("Skipping attribute {} for {}", configAttributeEntry.getKey(), on);
58                     continue;
59                 }
60
61                 Object toBeMergedIn = ace.getResolvedValue().get();
62                 // Get the existing values so we can merge the new values with them.
63                 Attribute currentAttribute = ta.getAttribute(on, ace.getJmxName());
64                 Object oldValue = (currentAttribute != null ? currentAttribute.getValue() : null);
65                 // Merge value with currentValue
66                 toBeMergedIn = merge(oldValue, toBeMergedIn);
67                 ta.setAttribute(on, ace.getJmxName(), new Attribute(ace.getJmxName(), toBeMergedIn));
68                 LOG.debug("Attribute {} set to {} for {}", configAttributeEntry.getKey(), toBeMergedIn, on);
69             } catch (Exception e) {
70                 LOG.error("Error while merging objectnames of {}", on, e);
71                 throw new ConfigHandlingException(String.format("Unable to set attributes for %s, Error with attribute %s : %s ",
72                         on,
73                         configAttributeEntry.getKey(),
74                         configAttributeEntry.getValue()),
75                         DocumentedException.ErrorType.application,
76                         DocumentedException.ErrorTag.operation_failed,
77                         DocumentedException.ErrorSeverity.error);
78             }
79         }
80     }
81
82     /**
83      * Merge value into current value
84      * Currently, this is only implemented for arrays of ObjectNames, but that is the
85      * most common case for which it is needed.
86      */
87     protected Object merge(Object oldValue, Object toBeMergedIn) {
88         if (oldValue instanceof ObjectName[] && toBeMergedIn instanceof ObjectName[]) {
89             toBeMergedIn = mergeObjectNameArrays((ObjectName[]) oldValue, (ObjectName[]) toBeMergedIn);
90         }
91         return toBeMergedIn;
92     }
93
94     /**
95      * Merge value into current values
96      * This implements for arrays of ObjectNames, but that is the
97      * most common case for which it is needed.
98      *
99      * @param oldValue - the new values to be merged into existing values
100      * @param toBeMergedIn - the existing values
101      *
102      * @return an ObjectName[] consisting the elements of currentValue with an elements from values not already present in currentValue added
103      *
104      */
105     protected ObjectName[] mergeObjectNameArrays(ObjectName[] oldValue, ObjectName[] toBeMergedIn) {
106         List<ObjectName> newValueList = new ArrayList<>();
107         newValueList.addAll(asList(oldValue));
108         /*
109          It is guaranteed that old values do not contain transaction name.
110          Since toBeMergedIn is filled using service references translated by ServiceRegistryWrapper, it
111          is also guaranteed that this list will not contain transaction names.
112          Run through the list of values to be merged.  If we don't have them already, add them to the list.
113          */
114         for (ObjectName objName : toBeMergedIn) {
115             if (!newValueList.contains(objName)) {
116                 newValueList.add(objName);
117             }
118         }
119         return newValueList.toArray(new ObjectName[newValueList.size()]);
120     }
121 }