Sync: md-sal augmentation re-model with broker. Traffic profile: Best Effort hooked up.
[packetcable.git] / packetcable-provider / src / main / java / org / opendaylight / controller / packetcable / provider / OpendaylightPacketcableProvider.java
1 package org.opendaylight.controller.packetcable.provider;
2
3 import java.math.BigInteger;
4 import java.net.InetAddress;
5 import java.net.UnknownHostException;
6 import java.util.Collection;
7 import java.util.concurrent.ExecutionException;
8 import java.util.concurrent.ExecutorService;
9 import java.util.concurrent.Executors;
10 import java.util.concurrent.Future;
11 import java.util.concurrent.atomic.AtomicReference;
12
13 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
14 import org.opendaylight.controller.md.sal.binding.api.DataChangeListener;
15 import org.opendaylight.controller.md.sal.common.api.data.AsyncDataBroker.DataChangeScope;
16 import org.opendaylight.controller.md.sal.common.api.data.AsyncDataChangeEvent;
17 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
18 import org.opendaylight.controller.packetcable.provider.processors.PCMMDataProcessor;
19 import org.opendaylight.controller.sal.binding.api.BindingAwareBroker.ConsumerContext;
20 import org.opendaylight.controller.sal.binding.api.BindingAwareBroker.ProviderContext;
21 import org.opendaylight.controller.sal.binding.api.BindingAwareBroker.RoutedRpcRegistration;
22 import org.opendaylight.controller.sal.binding.api.BindingAwareProvider;
23 import org.opendaylight.controller.sal.binding.api.NotificationProviderService;
24 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv4Address;
25 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv6Address;
26 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.PortNumber;
27 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.list.Action;
28 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.AddFlowInput;
29 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.AddFlowOutput;
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.AddFlowOutputBuilder;
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.RemoveFlowInput;
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.RemoveFlowOutput;
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.SalFlowService;
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.UpdateFlowInput;
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.UpdateFlowOutput;
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.flow.update.OriginalFlow;
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.flow.update.UpdatedFlow;
38 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.traffic.profile.rev140808.TrafficProfileBestEffortAttributes;
39 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.traffic.profile.rev140808.TrafficProfileDocsisServiceClassNameAttributes;
40 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.traffic.profile.rev140808.TrafficProfileFlowspecAttributes;
41 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.traffic.profile.rev140808.add.flow.input.instructions.instruction.instruction.apply.actions._case.apply.actions.action.action.BestEffortCase;
42 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.traffic.profile.rev140808.add.flow.input.instructions.instruction.instruction.apply.actions._case.apply.actions.action.action.DocsisServiceClassNameCase;
43 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.traffic.profile.rev140808.add.flow.input.instructions.instruction.instruction.apply.actions._case.apply.actions.action.action.FlowspecCase;
44 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.transaction.rev131103.TransactionId;
45 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.Match;
46 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.ApplyActionsCase;
47 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.Instruction;
48 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.Nodes;
49 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
50 import org.opendaylight.yang.gen.v1.urn.opendaylight.node.cmts.rev140120.CmtsCapableNode;
51 import org.opendaylight.yang.gen.v1.urn.opendaylight.node.cmts.rev140120.nodes.node.CmtsNode;
52 import org.opendaylight.yang.gen.v1.urn.opendaylight.packetcable.match.types.rev140120.SubscriberIdRpcAddFlow;
53 import org.opendaylight.yang.gen.v1.urn.opendaylight.packetcable.match.types.rev140120.TcpMatchRangesAttributes;
54 import org.opendaylight.yang.gen.v1.urn.opendaylight.packetcable.match.types.rev140120.TcpMatchRangesRpcAddFlow;
55 import org.opendaylight.yang.gen.v1.urn.opendaylight.packetcable.match.types.rev140120.UdpMatchRangesAttributes;
56 import org.opendaylight.yang.gen.v1.urn.opendaylight.packetcable.match.types.rev140120.UdpMatchRangesRpcAddFlow;
57 import org.opendaylight.yang.gen.v1.urn.opendaylight.packetcable.match.types.rev140120.UdpMatchRangesRpcRemoveFlow;
58 import org.opendaylight.yang.gen.v1.urn.opendaylight.packetcable.match.types.rev140120.UdpMatchRangesRpcUpdateFlowOriginal;
59 import org.opendaylight.yang.gen.v1.urn.opendaylight.packetcable.match.types.rev140120.UdpMatchRangesRpcUpdateFlowUpdated;
60 import org.opendaylight.yang.gen.v1.urn.opendaylight.packetcable.match.types.rev140120.tcp.match.ranges.attributes.TcpMatchRanges;
61 import org.opendaylight.yang.gen.v1.urn.opendaylight.packetcable.match.types.rev140120.udp.match.ranges.attributes.UpdMatchRanges;
62 import org.opendaylight.yangtools.concepts.CompositeObjectRegistration;
63 import org.opendaylight.yangtools.concepts.CompositeObjectRegistration.CompositeObjectRegistrationBuilder;
64 import org.opendaylight.yangtools.concepts.ListenerRegistration;
65 import org.opendaylight.yangtools.yang.binding.DataObject;
66 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
67 import org.opendaylight.yangtools.yang.binding.RpcService;
68 import org.opendaylight.yangtools.yang.common.RpcResult;
69 import org.opendaylight.yangtools.yang.common.RpcResultBuilder;
70 import org.pcmm.gates.IClassifier;
71 import org.pcmm.gates.IExtendedClassifier;
72 import org.pcmm.gates.ITrafficProfile;
73 import org.pcmm.gates.impl.ExtendedClassifier;
74 import org.pcmm.rcd.IPCMMPolicyServer;
75 import org.pcmm.rcd.IPCMMPolicyServer.IPSCMTSClient;
76 import org.pcmm.rcd.impl.PCMMPolicyServer;
77 import org.slf4j.Logger;
78 import org.slf4j.LoggerFactory;
79
80 import com.google.common.util.concurrent.Futures;
81
82 @SuppressWarnings("unused")
83 public class OpendaylightPacketcableProvider implements DataChangeListener,
84                 SalFlowService, OpenDaylightPacketCableProviderService,
85                 BindingAwareProvider, AutoCloseable {
86
87         private static final Logger logger = LoggerFactory.getLogger(OpendaylightPacketcableProvider.class);
88         private NotificationProviderService notificationProvider;
89         private DataBroker dataProvider;
90
91         private final ExecutorService executor;
92
93         // The following holds the Future for the current make toast task.
94         // This is used to cancel the current toast.
95         private final AtomicReference<Future<?>> currentConnectionsTasks = new AtomicReference<>();
96         private ProviderContext providerContext;
97         private NotificationProviderService notificationService;
98         private DataBroker dataBroker;
99         private ListenerRegistration<DataChangeListener> listenerRegistration;
100         private PCMMDataProcessor pcmmDataProcessor;
101         private IPCMMPolicyServer policyServer;
102
103         public OpendaylightPacketcableProvider() {
104                 executor = Executors.newCachedThreadPool();
105                 pcmmDataProcessor = new PCMMDataProcessor();
106                 policyServer=new PCMMPolicyServer();
107                 policyServer.startServer();
108         }
109
110         public void setNotificationProvider(final NotificationProviderService salService) {
111                 this.notificationProvider = salService;
112         }
113
114         public void setDataProvider(final DataBroker salDataProvider) {
115                 this.dataProvider = salDataProvider;
116         }
117
118         /**
119          * Implemented from the AutoCloseable interface.
120          */
121         @Override
122         public void close() throws ExecutionException, InterruptedException {
123                 executor.shutdown();
124                 // if (dataProvider != null) {
125                 // for (Iterator<InstanceIdentifier<CmtsInstance>> iter =
126                 // cmtsInstances.iterator(); iter.hasNext();) {
127                 // WriteTransaction tx = dataProvider.newWriteOnlyTransaction();
128                 // tx.delete(LogicalDatastoreType.OPERATIONAL, iter.next());
129                 // Futures.addCallback(tx.submit(), new FutureCallback<Void>() {
130                 // @Override
131                 // public void onSuccess(final Void result) {
132                 // logger.debug("Delete commit result: " + result);
133                 // }
134                 //
135                 // @Override
136                 // public void onFailure(final Throwable t) {
137                 // logger.error("Delete operation failed", t);
138                 // }
139                 // });
140                 // }
141                 // }
142         }
143
144         /**
145          * Implemented from the DataChangeListener interface.
146          */
147         @Override
148         public void onDataChanged(final AsyncDataChangeEvent<InstanceIdentifier<?>, DataObject> change) {
149                 DataObject dataObject = change.getUpdatedSubtree();
150                 logger.debug("OpendaylightPacketcableProvider.onDataChanged() :" + dataObject);
151         }
152
153         @Override
154         public Future<RpcResult<AddFlowOutput>> addFlow(AddFlowInput input) {
155                 Match match = input.getMatch();
156                 //XXX this wrong fix it  
157                 CmtsNode cmts = (CmtsNode) input.getNode();
158                 ///end wrong
159                 IClassifier classifier = buildClassifier(match);
160                 ITrafficProfile trafficProfie = null;
161                 for (Instruction i : input.getInstructions().getInstruction()) {
162                         if (i.getInstruction() instanceof ApplyActionsCase) {
163                                 ApplyActionsCase aac = (ApplyActionsCase) i.getInstruction();
164                                 for (Action a : aac.getApplyActions().getAction()) {
165                                         if (a.getAction() instanceof FlowspecCase) {
166                                                 // not implemented
167                                                 // trafficProfie = buildTrafficProfile(((FlowspecCase) a.getAction()).getFlowspec());
168                                         } else if (a.getAction() instanceof BestEffortCase) {
169                                                 trafficProfie = buildTrafficProfile(((BestEffortCase) a.getAction()).getBestEffort());
170                                                 break;
171                                         } else if (a.getAction() instanceof DocsisServiceClassNameCase) {
172                                                 trafficProfie = buildTrafficProfile(((DocsisServiceClassNameCase) a.getAction()).getDocsisServiceClassName());
173                                                 break;
174                                         }
175                                 }
176                         }
177                 }
178                 TransactionId transactionId=null;
179                 try {
180                         IPSCMTSClient requestCMTSConnection = policyServer.requestCMTSConnection(InetAddress.getByName(cmts.getAddress().getIpv4Address().getValue()));
181                         transactionId=new TransactionId(new BigInteger(String.valueOf(requestCMTSConnection.getTransactionId())));
182                 } catch (UnknownHostException e) {
183                         e.printStackTrace();
184                 }
185                 if(transactionId==null)
186                 {
187                         return Futures.immediateFuture(RpcResultBuilder.<AddFlowOutput>failed().build());
188                 }
189                 return Futures.immediateFuture(
190                                 RpcResultBuilder.success(
191                                                 new AddFlowOutputBuilder().setTransactionId(transactionId).build()
192                                                 ).build()
193                                                 );
194         }
195
196         @Override
197         public ITrafficProfile buildTrafficProfile(TrafficProfileDocsisServiceClassNameAttributes docsis) {
198                 return pcmmDataProcessor.process(docsis);
199         }
200
201         @Override
202         public ITrafficProfile buildTrafficProfile(TrafficProfileBestEffortAttributes bestEffort) {
203                 return pcmmDataProcessor.process(bestEffort);
204         }
205
206         @Override
207         public ITrafficProfile buildTrafficProfile(TrafficProfileFlowspecAttributes flowSpec) {
208                 return pcmmDataProcessor.process(flowSpec);
209         }
210
211         @Override
212         public IClassifier buildClassifier(Match match) {
213                 return pcmmDataProcessor.process(match);
214         }
215
216         @Override
217         public Future<RpcResult<RemoveFlowOutput>> removeFlow(RemoveFlowInput input) {
218                 UdpMatchRangesRpcRemoveFlow updRange = input.getMatch().getAugmentation(UdpMatchRangesRpcRemoveFlow.class);
219                 return null;
220         }
221
222         @Override
223         public Future<RpcResult<UpdateFlowOutput>> updateFlow(UpdateFlowInput input) {
224                 OriginalFlow foo = input.getOriginalFlow();
225                 UdpMatchRangesRpcUpdateFlowOriginal bar = foo.getMatch().getAugmentation(UdpMatchRangesRpcUpdateFlowOriginal.class);
226                 UpdatedFlow updated = input.getUpdatedFlow();
227                 UdpMatchRangesRpcUpdateFlowUpdated updatedRange = updated.getMatch().getAugmentation(UdpMatchRangesRpcUpdateFlowUpdated.class);
228
229                 return null;
230         }
231
232         @Override
233         public Collection<? extends RpcService> getImplementations() {
234                 // TODO Auto-generated method stub
235                 return null;
236         }
237
238         @Override
239         public Collection<? extends ProviderFunctionality> getFunctionality() {
240                 // TODO Auto-generated method stub
241                 return null;
242         }
243
244         @Override
245         public void onSessionInitiated(ProviderContext session) {
246                 providerContext = session;
247                 notificationService = session.getSALService(NotificationProviderService.class);
248                 dataBroker = session.getSALService(DataBroker.class);
249                 InstanceIdentifier<CmtsNode> listenTo = InstanceIdentifier.create(Nodes.class).child(Node.class).augmentation(CmtsCapableNode.class).child(CmtsNode.class);
250                 listenerRegistration = dataBroker.registerDataChangeListener(LogicalDatastoreType.CONFIGURATION, listenTo, this, DataChangeScope.BASE);
251         }
252
253         @Override
254         public void onSessionInitialized(ConsumerContext session) {
255                 // Noop
256
257         }
258
259         public void onSessionAdded(/* Whatever you need per CmtsConnection */) {
260                 CompositeObjectRegistrationBuilder<OpendaylightPacketcableProvider> builder = CompositeObjectRegistration.<OpendaylightPacketcableProvider> builderFor(this);
261                 /*
262                  * You will need a routedRpc registration per Cmts... I'm not doing the
263                  * accounting of storing them here, but you will need to so you can
264                  * close them when your provider is closed
265                  */
266                 RoutedRpcRegistration<SalFlowService> registration = providerContext.addRoutedRpcImplementation(SalFlowService.class, this);
267                 /*
268                  * You will need to get your identifier somewhere... this is your
269                  * nodeId. I would recommend adoption a convention like
270                  * "cmts:<ipaddress>" for CmtsCapableNodes
271                  * registration.registerPath(NodeContext.class, getIdentifier());
272                  */
273         }
274
275 }