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).toInstance();
41 tableService = FRMConsumerImpl.getProviderSession().getRpcService(SalTableService.class);
43 if (null == tableService) {
44 logger.error("Consumer SAL Service is down or NULL. FRM may not function as intended");
45 System.out.println("Consumer SAL Service is down or NULL.");
49 System.out.println("-------------------------------------------------------------------");
50 commitHandler = new TableDataCommitHandler();
51 FRMConsumerImpl.getDataProviderService().registerCommitHandler(path, commitHandler);
52 container = (IContainer) ServiceHelper.getGlobalInstance(IContainer.class, this);
56 * Updates TableFeatures to the southbound plugin and our internal database
61 private void updateTableFeatures(InstanceIdentifier<?> path, TableFeatures dataObject) {
63 UpdateTableInputBuilder input = new UpdateTableInputBuilder();
64 UpdatedTableBuilder updatedtablebuilder = new UpdatedTableBuilder();
65 updatedtablebuilder.fieldsFrom(dataObject);
66 List<TableFeatures> features = updatedtablebuilder.build().getTableFeatures();
67 for (TableFeatures feature : features) {
68 if (feature != null && feature.getMaxEntries() != null) {
69 logger.error("Max Entries field is read-only, cannot be changed");
73 input.setUpdatedTable(updatedtablebuilder.build());
75 // We send table feature update request to the sounthbound plugin
76 tableService.updateTable(input.build());
79 @SuppressWarnings("unchecked")
80 private void commitToPlugin(internalTransaction transaction) {
82 for (@SuppressWarnings("unused")
83 Entry<InstanceIdentifier<?>, TableFeatures> entry : transaction.updates.entrySet()) {
84 System.out.println("Coming update cc in TableDatacommitHandler");
85 updateTableFeatures(entry.getKey(), entry.getValue());
90 private final class TableDataCommitHandler implements DataCommitHandler<InstanceIdentifier<?>, DataObject> {
92 @SuppressWarnings("unchecked")
94 public DataCommitTransaction requestCommit(DataModification<InstanceIdentifier<?>, DataObject> modification) {
95 // We should verify transaction
96 System.out.println("Coming in TableFeaturesDatacommitHandler");
97 internalTransaction transaction = new internalTransaction(modification);
98 transaction.prepareUpdate();
103 private final class internalTransaction implements DataCommitTransaction<InstanceIdentifier<?>, DataObject> {
105 private final DataModification<InstanceIdentifier<?>, DataObject> modification;
108 public DataModification<InstanceIdentifier<?>, DataObject> getModification() {
112 public internalTransaction(DataModification<InstanceIdentifier<?>, DataObject> modification) {
113 this.modification = modification;
116 Map<InstanceIdentifier<?>, TableFeatures> updates = new HashMap<>();
117 Map<InstanceIdentifier<?>, TableFeatures> createdEntries = new HashMap<>();
120 * We create a plan which table features will be updated.
123 void prepareUpdate() {
124 Set<Entry<InstanceIdentifier<?>, DataObject>> createdEntries = modification.getCreatedConfigurationData().entrySet();
126 Set<Entry<InstanceIdentifier<?>, DataObject>> puts = modification.getUpdatedConfigurationData().entrySet();
127 for (Entry<InstanceIdentifier<?>, DataObject> entry : puts) {
129 // validating the DataObject
131 Status status = validate(container, (TableFeatures) entry);
132 if (!status.isSuccess()) {
133 logger.warn("Invalid Configuration for table features The failure is {}", entry,
134 status.getDescription());
135 String error = "Invalid Configuration (" + status.getDescription() + ")";
139 if (entry.getValue() instanceof TableFeatures) {
140 TableFeatures tablefeatures = (TableFeatures) entry.getValue();
141 preparePutEntry(entry.getKey(), tablefeatures);
147 private void preparePutEntry(InstanceIdentifier<?> key, TableFeatures tablefeatures) {
148 if (tablefeatures != null) {
150 System.out.println("Coming update in TableFeaturesDatacommitHandler");
151 updates.put(key, tablefeatures);
156 * We are OK to go with execution of plan
160 public RpcResult<Void> finish() throws IllegalStateException {
162 commitToPlugin(this);
163 // We return true if internal transaction is successful.
164 // return Rpcs.getRpcResult(true, null, Collections.emptySet());
165 return Rpcs.getRpcResult(true, null, null);
170 * We should rollback our preparation
174 public RpcResult<Void> rollback() throws IllegalStateException {
175 // NOOP - we did not modified any internal state during
176 // requestCommit phase
177 // return Rpcs.getRpcResult(true, null, Collections.emptySet());
178 return Rpcs.getRpcResult(true, null, null);
182 public Status validate(IContainer container, TableFeatures dataObject) {
184 String tablename = dataObject.getName();
185 if (tablename == null || tablename.trim().isEmpty() || !tablename.matches(NAMEREGEX)
186 || tablename.length() != 32) {
187 return new Status(StatusCode.BADREQUEST, "Invalid table name");
190 return new Status(StatusCode.SUCCESS);