1 package org.opendaylight.controller.forwardingrulesmanager.consumer.impl;
3 import java.util.HashMap;
6 import java.util.Map.Entry;
9 import org.opendaylight.controller.clustering.services.IClusterContainerServices;
10 import org.opendaylight.controller.md.sal.common.api.data.DataCommitHandler;
11 import org.opendaylight.controller.md.sal.common.api.data.DataCommitHandler.DataCommitTransaction;
12 import org.opendaylight.controller.md.sal.common.api.data.DataModification;
13 import org.opendaylight.controller.sal.common.util.Rpcs;
14 import org.opendaylight.controller.sal.core.IContainer;
15 import org.opendaylight.controller.sal.utils.ServiceHelper;
16 import org.opendaylight.controller.sal.utils.Status;
17 import org.opendaylight.controller.sal.utils.StatusCode;
18 import org.opendaylight.yang.gen.v1.urn.opendaylight.table.config.rev131024.Tables;
19 import org.opendaylight.yang.gen.v1.urn.opendaylight.table.config.rev131024.tables.Table;
20 import org.opendaylight.yang.gen.v1.urn.opendaylight.table.service.rev131026.SalTableService;
21 import org.opendaylight.yang.gen.v1.urn.opendaylight.table.service.rev131026.UpdateTableInputBuilder;
22 import org.opendaylight.yang.gen.v1.urn.opendaylight.table.service.rev131026.table.update.UpdatedTableBuilder;
23 import org.opendaylight.yang.gen.v1.urn.opendaylight.table.types.rev131026.table.features.TableFeatures;
24 import org.opendaylight.yangtools.yang.binding.DataObject;
25 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
26 import org.opendaylight.yangtools.yang.common.RpcResult;
27 import org.slf4j.Logger;
28 import org.slf4j.LoggerFactory;
30 public class TableFeaturesConsumerImpl {
31 protected static final Logger logger = LoggerFactory.getLogger(TableFeaturesConsumerImpl.class);
32 private SalTableService tableService;
33 private TableDataCommitHandler commitHandler;
34 private final IClusterContainerServices clusterContainerService = null;
35 private IContainer container;
36 private static final String NAMEREGEX = "^[a-zA-Z0-9]+$";
37 private boolean inContainerMode; // being used by global instance only
39 public TableFeaturesConsumerImpl() {
40 InstanceIdentifier<? extends DataObject> path = InstanceIdentifier.builder(Tables.class).child(Table.class)
42 tableService = FRMConsumerImpl.getProviderSession().getRpcService(SalTableService.class);
44 if (null == tableService) {
45 logger.error("Consumer SAL Service is down or NULL. FRM may not function as intended");
46 System.out.println("Consumer SAL Service is down or NULL.");
50 System.out.println("-------------------------------------------------------------------");
51 commitHandler = new TableDataCommitHandler();
52 FRMConsumerImpl.getDataProviderService().registerCommitHandler(path, commitHandler);
53 container = (IContainer) ServiceHelper.getGlobalInstance(IContainer.class, this);
57 * Updates TableFeatures to the southbound plugin and our internal database
62 private void updateTableFeatures(InstanceIdentifier<?> path, TableFeatures dataObject) {
64 UpdateTableInputBuilder input = new UpdateTableInputBuilder();
65 UpdatedTableBuilder updatedtablebuilder = new UpdatedTableBuilder();
66 updatedtablebuilder.fieldsFrom(dataObject);
67 List<TableFeatures> features = updatedtablebuilder.build().getTableFeatures();
68 for (TableFeatures feature : features) {
69 if (feature != null && feature.getMaxEntries() != null) {
70 logger.error("Max Entries field is read-only, cannot be changed");
74 input.setUpdatedTable(updatedtablebuilder.build());
76 // We send table feature update request to the sounthbound plugin
77 tableService.updateTable(input.build());
80 @SuppressWarnings("unchecked")
81 private void commitToPlugin(internalTransaction transaction) {
83 for (@SuppressWarnings("unused")
84 Entry<InstanceIdentifier<?>, TableFeatures> entry : transaction.updates.entrySet()) {
85 System.out.println("Coming update cc in TableDatacommitHandler");
86 updateTableFeatures(entry.getKey(), entry.getValue());
91 private final class TableDataCommitHandler implements DataCommitHandler<InstanceIdentifier<?>, DataObject> {
93 @SuppressWarnings("unchecked")
95 public DataCommitTransaction requestCommit(DataModification<InstanceIdentifier<?>, DataObject> modification) {
96 // We should verify transaction
97 System.out.println("Coming in TableFeaturesDatacommitHandler");
98 internalTransaction transaction = new internalTransaction(modification);
99 transaction.prepareUpdate();
104 private final class internalTransaction implements DataCommitTransaction<InstanceIdentifier<?>, DataObject> {
106 private final DataModification<InstanceIdentifier<?>, DataObject> modification;
109 public DataModification<InstanceIdentifier<?>, DataObject> getModification() {
113 public internalTransaction(DataModification<InstanceIdentifier<?>, DataObject> modification) {
114 this.modification = modification;
117 Map<InstanceIdentifier<?>, TableFeatures> updates = new HashMap<>();
120 * We create a plan which table features will be updated.
123 void prepareUpdate() {
125 Set<Entry<InstanceIdentifier<?>, DataObject>> puts = modification.getUpdatedConfigurationData().entrySet();
126 for (Entry<InstanceIdentifier<?>, DataObject> entry : puts) {
128 // validating the DataObject
130 Status status = validate(container, (TableFeatures) entry);
131 if (!status.isSuccess()) {
132 logger.warn("Invalid Configuration for table features The failure is {}", entry,
133 status.getDescription());
134 String error = "Invalid Configuration (" + status.getDescription() + ")";
138 if (entry.getValue() instanceof TableFeatures) {
139 TableFeatures tablefeatures = (TableFeatures) entry.getValue();
140 preparePutEntry(entry.getKey(), tablefeatures);
146 private void preparePutEntry(InstanceIdentifier<?> key, TableFeatures tablefeatures) {
147 if (tablefeatures != null) {
149 System.out.println("Coming update in TableFeaturesDatacommitHandler");
150 updates.put(key, tablefeatures);
155 * We are OK to go with execution of plan
159 public RpcResult<Void> finish() throws IllegalStateException {
161 commitToPlugin(this);
162 // We return true if internal transaction is successful.
163 // return Rpcs.getRpcResult(true, null, Collections.emptySet());
164 return Rpcs.getRpcResult(true, null, null);
169 * We should rollback our preparation
173 public RpcResult<Void> rollback() throws IllegalStateException {
174 // NOOP - we did not modified any internal state during
175 // requestCommit phase
176 // return Rpcs.getRpcResult(true, null, Collections.emptySet());
177 return Rpcs.getRpcResult(true, null, null);
181 public Status validate(IContainer container, TableFeatures dataObject) {
183 String tablename = dataObject.getName();
184 if (tablename == null || tablename.trim().isEmpty() || !tablename.matches(NAMEREGEX)
185 || tablename.length() != 32) {
186 return new Status(StatusCode.BADREQUEST, "Invalid table name");
189 return new Status(StatusCode.SUCCESS);