2 * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
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
9 package org.opendaylight.controller.config.facade.xml.strategy;
11 import static java.util.Arrays.asList;
13 import java.util.ArrayList;
14 import java.util.List;
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;
27 public class MergeEditConfigStrategy extends AbstractEditConfigStrategy {
29 private static final Logger LOG = LoggerFactory.getLogger(MergeEditConfigStrategy.class);
31 public MergeEditConfigStrategy() {
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 ",
43 DocumentedException.ErrorType.APPLICATION,
44 DocumentedException.ErrorTag.OPERATION_FAILED,
45 DocumentedException.ErrorSeverity.ERROR);
49 void executeStrategy(Map<String, AttributeConfigElement> configuration, ConfigTransactionClient ta, ObjectName on, ServiceRegistryWrapper services) throws
50 ConfigHandlingException {
52 for (Entry<String, AttributeConfigElement> configAttributeEntry : configuration.entrySet()) {
54 AttributeConfigElement ace = configAttributeEntry.getValue();
56 if (!ace.getResolvedValue().isPresent()) {
57 LOG.debug("Skipping attribute {} for {}", configAttributeEntry.getKey(), on);
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 ",
73 configAttributeEntry.getKey(),
74 configAttributeEntry.getValue()),
75 DocumentedException.ErrorType.APPLICATION,
76 DocumentedException.ErrorTag.OPERATION_FAILED,
77 DocumentedException.ErrorSeverity.ERROR);
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.
87 protected Object merge(Object oldValue, Object toBeMergedIn) {
88 if (oldValue instanceof ObjectName[] && toBeMergedIn instanceof ObjectName[]) {
89 toBeMergedIn = mergeObjectNameArrays((ObjectName[]) oldValue, (ObjectName[]) toBeMergedIn);
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.
99 * @param oldValue - the new values to be merged into existing values
100 * @param toBeMergedIn - the existing values
102 * @return an ObjectName[] consisting the elements of currentValue with an elements from values not already present in currentValue added
105 protected ObjectName[] mergeObjectNameArrays(ObjectName[] oldValue, ObjectName[] toBeMergedIn) {
106 List<ObjectName> newValueList = new ArrayList<>();
107 newValueList.addAll(asList(oldValue));
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.
114 for (ObjectName objName : toBeMergedIn) {
115 if (!newValueList.contains(objName)) {
116 newValueList.add(objName);
119 return newValueList.toArray(new ObjectName[newValueList.size()]);