2 * Copyright (c) 2015 CableLabs 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.packetcable.provider;
11 import static com.google.common.base.Preconditions.checkNotNull;
13 import com.google.common.base.Optional;
14 import com.google.common.collect.Maps;
15 import com.google.common.collect.Sets;
16 import com.google.common.util.concurrent.CheckedFuture;
17 import com.google.common.util.concurrent.Futures;
19 import java.net.InetAddress;
20 import java.net.UnknownHostException;
21 import java.text.DateFormat;
22 import java.text.SimpleDateFormat;
23 import java.util.ArrayList;
24 import java.util.Collections;
25 import java.util.Date;
26 import java.util.List;
28 import java.util.Objects;
30 import java.util.concurrent.ConcurrentHashMap;
31 import java.util.concurrent.ExecutionException;
32 import java.util.concurrent.Executor;
33 import java.util.concurrent.Executors;
34 import java.util.concurrent.Future;
36 import javax.annotation.Nonnull;
37 import javax.annotation.concurrent.ThreadSafe;
39 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
40 import org.opendaylight.controller.md.sal.binding.api.DataTreeChangeListener;
41 import org.opendaylight.controller.md.sal.binding.api.DataTreeIdentifier;
42 import org.opendaylight.controller.md.sal.binding.api.DataTreeModification;
43 import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
44 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
45 import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException;
46 import org.opendaylight.controller.packetcable.provider.validation.DataValidator;
47 import org.opendaylight.controller.packetcable.provider.validation.ValidationException;
48 import org.opendaylight.controller.packetcable.provider.validation.Validator;
49 import org.opendaylight.controller.packetcable.provider.validation.impl.CcapsValidatorProviderFactory;
50 import org.opendaylight.controller.packetcable.provider.validation.impl.QosValidatorProviderFactory;
51 import org.opendaylight.controller.sal.binding.api.BindingAwareBroker.ProviderContext;
52 import org.opendaylight.controller.sal.binding.api.BindingAwareBroker.RoutedRpcRegistration;
53 import org.opendaylight.controller.sal.binding.api.BindingAwareBroker.RpcRegistration;
54 import org.opendaylight.controller.sal.binding.api.BindingAwareProvider;
55 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpPrefix;
56 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Prefix;
57 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.DateAndTime;
58 import org.opendaylight.yang.gen.v1.urn.packetcable.rev170224.pcmm.serviceclass.name.profile.ServiceClassNameProfile;
59 import org.opendaylight.yang.gen.v1.urn.packetcable.rev170224.pcmm.serviceclass.name.profile.ServiceClassNameProfileBuilder;
60 import org.opendaylight.yang.gen.v1.urn.packetcable.rev170224.AppContext;
61 import org.opendaylight.yang.gen.v1.urn.packetcable.rev170224.CcapContext;
62 import org.opendaylight.yang.gen.v1.urn.packetcable.rev170224.CcapPollConnectionInput;
63 import org.opendaylight.yang.gen.v1.urn.packetcable.rev170224.CcapPollConnectionOutput;
64 import org.opendaylight.yang.gen.v1.urn.packetcable.rev170224.CcapPollConnectionOutputBuilder;
65 import org.opendaylight.yang.gen.v1.urn.packetcable.rev170224.CcapSetConnectionInput;
66 import org.opendaylight.yang.gen.v1.urn.packetcable.rev170224.CcapSetConnectionOutput;
67 import org.opendaylight.yang.gen.v1.urn.packetcable.rev170224.CcapSetConnectionOutputBuilder;
68 import org.opendaylight.yang.gen.v1.urn.packetcable.rev170224.Ccaps;
69 import org.opendaylight.yang.gen.v1.urn.packetcable.rev170224.PacketcableService;
70 import org.opendaylight.yang.gen.v1.urn.packetcable.rev170224.Qos;
71 import org.opendaylight.yang.gen.v1.urn.packetcable.rev170224.QosPollGatesInput;
72 import org.opendaylight.yang.gen.v1.urn.packetcable.rev170224.QosPollGatesOutput;
73 import org.opendaylight.yang.gen.v1.urn.packetcable.rev170224.QosPollGatesOutputBuilder;
74 import org.opendaylight.yang.gen.v1.urn.packetcable.rev170224.QosSetGateInput;
75 import org.opendaylight.yang.gen.v1.urn.packetcable.rev170224.QosSetGateOutput;
76 import org.opendaylight.yang.gen.v1.urn.packetcable.rev170224.QosSetGateOutputBuilder;
77 import org.opendaylight.yang.gen.v1.urn.packetcable.rev170224.QosDeleteGateInput;
78 import org.opendaylight.yang.gen.v1.urn.packetcable.rev170224.QosDeleteGateOutput;
79 import org.opendaylight.yang.gen.v1.urn.packetcable.rev170224.QosDeleteGateOutputBuilder;
80 import org.opendaylight.yang.gen.v1.urn.packetcable.rev170224.QosGateInfoInput;
81 import org.opendaylight.yang.gen.v1.urn.packetcable.rev170224.QosGateInfoOutput;
82 import org.opendaylight.yang.gen.v1.urn.packetcable.rev170224.QosGateInfoOutputBuilder;
83 import org.opendaylight.yang.gen.v1.urn.packetcable.rev170224.ServiceClassName;
84 import org.opendaylight.yang.gen.v1.urn.packetcable.rev170224.ServiceFlowDirection;
85 import org.opendaylight.yang.gen.v1.urn.packetcable.rev170224.ccap.attributes.ConnectionBuilder;
86 import org.opendaylight.yang.gen.v1.urn.packetcable.rev170224.ccaps.Ccap;
87 import org.opendaylight.yang.gen.v1.urn.packetcable.rev170224.ccaps.CcapBuilder;
88 import org.opendaylight.yang.gen.v1.urn.packetcable.rev170224.pcmm.qos.gate.spec.GateSpec;
89 import org.opendaylight.yang.gen.v1.urn.packetcable.rev170224.pcmm.qos.gate.spec.GateSpecBuilder;
90 import org.opendaylight.yang.gen.v1.urn.packetcable.rev170224.pcmm.qos.gates.Apps;
91 import org.opendaylight.yang.gen.v1.urn.packetcable.rev170224.pcmm.qos.gates.apps.App;
92 import org.opendaylight.yang.gen.v1.urn.packetcable.rev170224.pcmm.qos.gates.apps.AppBuilder;
93 import org.opendaylight.yang.gen.v1.urn.packetcable.rev170224.pcmm.qos.gates.apps.AppKey;
94 import org.opendaylight.yang.gen.v1.urn.packetcable.rev170224.pcmm.qos.gates.apps.app.Subscribers;
95 import org.opendaylight.yang.gen.v1.urn.packetcable.rev170224.pcmm.qos.gates.apps.app.SubscribersBuilder;
96 import org.opendaylight.yang.gen.v1.urn.packetcable.rev170224.pcmm.qos.gates.apps.app.subscribers.Subscriber;
97 import org.opendaylight.yang.gen.v1.urn.packetcable.rev170224.pcmm.qos.gates.apps.app.subscribers.SubscriberBuilder;
98 import org.opendaylight.yang.gen.v1.urn.packetcable.rev170224.pcmm.qos.gates.apps.app.subscribers.SubscriberKey;
99 import org.opendaylight.yang.gen.v1.urn.packetcable.rev170224.pcmm.qos.gates.apps.app.subscribers.subscriber.Gates;
100 import org.opendaylight.yang.gen.v1.urn.packetcable.rev170224.pcmm.qos.gates.apps.app.subscribers.subscriber.GatesBuilder;
101 import org.opendaylight.yang.gen.v1.urn.packetcable.rev170224.pcmm.qos.gates.apps.app.subscribers.subscriber.gates.Gate;
102 import org.opendaylight.yang.gen.v1.urn.packetcable.rev170224.pcmm.qos.gates.apps.app.subscribers.subscriber.gates.GateBuilder;
103 import org.opendaylight.yang.gen.v1.urn.packetcable.rev170224.pcmm.qos.gates.apps.app.subscribers.subscriber.gates.GateKey;
104 import org.opendaylight.yang.gen.v1.urn.packetcable.rev170224.pcmm.qos.traffic.profile.TrafficProfile;
105 import org.opendaylight.yang.gen.v1.urn.packetcable.rev170224.pcmm.qos.traffic.profile.TrafficProfileBuilder;
106 import org.opendaylight.yang.gen.v1.urn.packetcable.rev170224.pcmm.qos.traffic.profile.traffic.profile.TrafficProfileChoice;
107 import org.opendaylight.yang.gen.v1.urn.packetcable.rev170224.pcmm.qos.traffic.profile.traffic.profile.traffic.profile.choice.FlowSpecChoiceBuilder;
108 import org.opendaylight.yang.gen.v1.urn.packetcable.rev170224.pcmm.qos.traffic.profile.traffic.profile.traffic.profile.choice.ServiceClassNameChoiceBuilder;
109 import org.opendaylight.yang.gen.v1.urn.packetcable.rev170224.pcmm.qos.traffic.profile.traffic.profile.traffic.profile.choice.FlowSpecChoice;
110 import org.opendaylight.yang.gen.v1.urn.packetcable.rev170224.pcmm.qos.traffic.profile.traffic.profile.traffic.profile.choice.ServiceClassNameChoice;
111 import org.opendaylight.yang.gen.v1.urn.packetcable.rev170224.pcmm.flow.spec.profile.FlowSpecProfile;
112 import org.opendaylight.yang.gen.v1.urn.packetcable.rev170224.pcmm.serviceclass.name.profile.ServiceClassNameProfile;
113 import org.opendaylight.yang.gen.v1.urn.packetcable.rev170224.qos.set.gate.response.SetResponseType;
114 import org.opendaylight.yang.gen.v1.urn.packetcable.rev170224.qos.set.gate.response.set.response.type.SetSuccessful;
115 import org.opendaylight.yang.gen.v1.urn.packetcable.rev170224.qos.set.gate.response.set.response.type.SetSuccessfulBuilder;
116 import org.opendaylight.yang.gen.v1.urn.packetcable.rev170224.qos.set.gate.response.set.response.type.SetFailure;
117 import org.opendaylight.yang.gen.v1.urn.packetcable.rev170224.qos.set.gate.response.set.response.type.SetFailureBuilder;
118 import org.opendaylight.yang.gen.v1.urn.packetcable.rev170224.qos.delete.gate.response.delete.response.type.DeleteSuccessful;
119 import org.opendaylight.yang.gen.v1.urn.packetcable.rev170224.qos.delete.gate.response.delete.response.type.DeleteSuccessfulBuilder;
120 import org.opendaylight.yang.gen.v1.urn.packetcable.rev170224.qos.delete.gate.response.delete.response.type.DeleteFailure;
121 import org.opendaylight.yang.gen.v1.urn.packetcable.rev170224.qos.delete.gate.response.delete.response.type.DeleteFailureBuilder;
122 import org.opendaylight.yang.gen.v1.urn.packetcable.rev170224.qos.gate.info.response.info.response.type.InfoSuccessful;
123 import org.opendaylight.yang.gen.v1.urn.packetcable.rev170224.qos.gate.info.response.info.response.type.InfoSuccessfulBuilder;
124 import org.opendaylight.yang.gen.v1.urn.packetcable.rev170224.qos.gate.info.response.info.response.type.InfoFailure;
125 import org.opendaylight.yang.gen.v1.urn.packetcable.rev170224.qos.gate.info.response.info.response.type.InfoFailureBuilder;
126 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.packetcable.packetcable.policy.server.impl.rev140131.PacketcableProviderModule;
127 import org.opendaylight.yang.gen.v1.urn.packetcable.rev170224.FailureType;
128 import org.opendaylight.yangtools.concepts.ListenerRegistration;
129 import org.opendaylight.yangtools.yang.binding.DataObject;
130 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
131 import org.opendaylight.yangtools.yang.common.RpcResult;
132 import org.opendaylight.yangtools.yang.common.RpcResultBuilder;
133 import org.pcmm.gates.IGateSpec.Direction;
134 import org.pcmm.gates.impl.DOCSISFlowSpecTrafficProfile;
135 import org.pcmm.gates.impl.DOCSISServiceClassNameTrafficProfile;
136 import org.pcmm.rcd.IPCMMClient;
137 import org.slf4j.Logger;
138 import org.slf4j.LoggerFactory;
141 * Called by ODL framework to start this bundle.
143 * This class is responsible for processing messages received from ODL's restconf interface.
144 * TODO - Remove some of these state maps and move some of this into the PCMMService
145 * TODO Don't implement PacketcableService, move that into an inner class
148 public class PacketcableProvider implements BindingAwareProvider, AutoCloseable, PacketcableService {
150 private static final Logger logger = LoggerFactory.getLogger(PacketcableProvider.class);
152 // keys to the /restconf/config/packetcable:ccaps and /restconf/config/packetcable:qos config datastore
153 private static final InstanceIdentifier<Ccaps> ccapsIID = InstanceIdentifier.builder(Ccaps.class).build();
154 private static final InstanceIdentifier<Qos> qosIID = InstanceIdentifier.builder(Qos.class).build();
156 // TODO - Revisit these maps and remove the ones no longer necessary
157 private final Map<String, Ccap> ccapMap = new ConcurrentHashMap<>();
158 private final Map<String, Gate> gateMap = new ConcurrentHashMap<>();
159 private final Map<String, String> gateCcapMap = new ConcurrentHashMap<>();
160 private final Map<Subnet, Ccap> subscriberSubnetsMap = new ConcurrentHashMap<>();
161 private final Map<ServiceClassName, List<Ccap>> downstreamScnMap = new ConcurrentHashMap<>();
162 private final Map<ServiceClassName, List<Ccap>> upstreamScnMap = new ConcurrentHashMap<>();
164 private final Executor executor = Executors.newSingleThreadExecutor();
167 * Holds a PCMMService object for each CCAP being managed.
169 private final Map<String, PCMMService> pcmmServiceMap = new ConcurrentHashMap<>();
172 * The ODL object used to broker messages throughout the framework
174 private DataBroker dataBroker;
175 private MdsalUtils mdsalUtils;
177 //Routed RPC Registration
178 private RoutedRpcRegistration<PacketcableService> routedRpcRegistration;
180 // unrouted RPC Registration
181 private RpcRegistration rpcRegistration;
183 // Data change listeners/registrations
184 private final CcapsDataTreeChangeListener ccapsDataTreeChangeListener = new CcapsDataTreeChangeListener();
185 private final QosDataTreeChangeListener qosDataTreeChangeListener = new QosDataTreeChangeListener();
187 private ListenerRegistration<DataTreeChangeListener> ccapsDataTreeChangeListenerRegistration;
188 private ListenerRegistration<DataTreeChangeListener> qosDataTreeChangeListenerRegistration;
193 public PacketcableProvider() {
194 logger.info("Starting Packetcable Provider");
198 public void onSessionInitiated(ProviderContext session) {
199 logger.info("Packetcable Session Initiated");
200 logger.info("logging levels: error={}, warn={}, info={}, debug={}, trace={}",
201 logger.isErrorEnabled(), logger.isWarnEnabled(),
202 logger.isInfoEnabled(), logger.isDebugEnabled(), logger.isTraceEnabled());
204 dataBroker = session.getSALService(DataBroker.class);
206 mdsalUtils = new MdsalUtils(dataBroker);
207 final DataTreeIdentifier<Ccap> ccapsDataTreeIid =
208 new DataTreeIdentifier<>(LogicalDatastoreType.CONFIGURATION, ccapsIID.child(Ccap.class));
210 final DataTreeIdentifier<Gate> appDataTreeIid =
211 new DataTreeIdentifier<>(LogicalDatastoreType.CONFIGURATION,
212 qosIID.child(Apps.class).child(App.class).child(Subscribers.class).child(Subscriber.class).child(Gates.class).child(Gate.class));
214 ccapsDataTreeChangeListenerRegistration =
215 dataBroker.registerDataTreeChangeListener(ccapsDataTreeIid, new CcapsDataTreeChangeListener());
217 qosDataTreeChangeListenerRegistration = dataBroker.registerDataTreeChangeListener(appDataTreeIid, new QosDataTreeChangeListener());
219 rpcRegistration = session.addRpcImplementation(PacketcableService.class, this);
220 logger.info("onSessionInitiated().rpcRegistration: {}", rpcRegistration);
221 routedRpcRegistration = session.addRoutedRpcImplementation(PacketcableService.class, this);
222 logger.info("onSessionInitiated().routedRpcRegistration: {}", routedRpcRegistration);
227 * Implemented from the AutoCloseable interface.
230 public void close() throws ExecutionException, InterruptedException {
231 if (ccapsDataTreeChangeListenerRegistration != null) {
232 ccapsDataTreeChangeListenerRegistration.close();
235 if (qosDataTreeChangeListenerRegistration != null) {
236 qosDataTreeChangeListenerRegistration.close();
239 if (rpcRegistration != null) {
240 rpcRegistration.close();
244 private void updateCcapMaps(final Ccap ccap) {
245 // add ccap to the subscriberSubnets map
246 for (final IpPrefix ipPrefix : ccap.getSubscriberSubnets()) {
248 subscriberSubnetsMap.put(Subnet.createInstance(getIpPrefixStr(ipPrefix)), ccap);
249 } catch (UnknownHostException e) {
250 logger.error("updateSubscriberSubnets: {}:{} FAILED: {}", ipPrefix, ccap, e.getMessage());
253 // ccap to upstream SCN map
254 for (final ServiceClassName scn : ccap.getUpstreamScns()) {
255 if (upstreamScnMap.containsKey(scn)) {
256 upstreamScnMap.get(scn).add(ccap);
258 final List<Ccap> ccapList = new ArrayList<>();
260 upstreamScnMap.put(scn, ccapList);
263 // ccap to downstream SCN map
264 for (final ServiceClassName scn : ccap.getDownstreamScns()) {
265 if (downstreamScnMap.containsKey(scn)) {
266 downstreamScnMap.get(scn).add(ccap);
268 final List<Ccap> ccapList = new ArrayList<>();
270 downstreamScnMap.put(scn, ccapList);
275 private String getIpPrefixStr(final IpPrefix ipPrefix) {
276 final Ipv4Prefix ipv4 = ipPrefix.getIpv4Prefix();
278 return ipv4.getValue();
280 return ipPrefix.getIpv6Prefix().getValue();
284 public InetAddress getInetAddress(final String subId) {
286 return InetAddress.getByName(subId);
287 } catch (UnknownHostException e) {
288 logger.error("getInetAddress: {} FAILED: {}", subId, e.getMessage());
293 private Ccap findCcapForSubscriberId(final InetAddress inetAddr) {
294 // TODO replace this with a loading cache, https://github.com/google/guava/wiki/CachesExplained
295 Ccap matchedCcap = null;
296 int longestPrefixLen = -1;
297 for (final Map.Entry<Subnet, Ccap> entry : subscriberSubnetsMap.entrySet()) {
298 final Subnet subnet = entry.getKey();
299 if (subnet.isInNet(inetAddr)) {
300 int prefixLen = subnet.getPrefixLen();
301 if (prefixLen > longestPrefixLen) {
302 matchedCcap = entry.getValue();
303 longestPrefixLen = prefixLen;
310 private ServiceFlowDirection findScnOnCcap(final ServiceClassName scn, final Ccap ccap) {
314 if (upstreamScnMap.containsKey(scn)) {
315 final List<Ccap> ccapList = upstreamScnMap.get(scn);
316 if (ccapList.contains(ccap)) {
317 return ServiceFlowDirection.Us;
319 } else if (downstreamScnMap.containsKey(scn)) {
320 final List<Ccap> ccapList = downstreamScnMap.get(scn);
321 if (ccapList.contains(ccap)) {
322 return ServiceFlowDirection.Ds;
328 private void removeCcapFromAllMaps(final Ccap ccap) {
329 // remove the ccap from all maps
330 // subscriberSubnets map
331 for (final Map.Entry<Subnet, Ccap> entry : subscriberSubnetsMap.entrySet()) {
332 if (entry.getValue() == ccap) {
333 subscriberSubnetsMap.remove(entry.getKey());
336 // ccap to upstream SCN map
337 for (final Map.Entry<ServiceClassName, List<Ccap>> entry : upstreamScnMap.entrySet()) {
338 final List<Ccap> ccapList = entry.getValue();
339 ccapList.remove(ccap);
340 if (ccapList.isEmpty()) {
341 upstreamScnMap.remove(entry.getKey());
344 // ccap to downstream SCN map
345 for (final Map.Entry<ServiceClassName, List<Ccap>> entry : downstreamScnMap.entrySet()) {
346 final List<Ccap> ccapList = entry.getValue();
347 ccapList.remove(ccap);
348 if (ccapList.isEmpty()) {
349 downstreamScnMap.remove(entry.getKey());
353 final PCMMService service = pcmmServiceMap.remove(ccap.getCcapId());
354 if (service != null) {
359 // ValidationException does not need to be thrown again
360 @SuppressWarnings("ThrowableResultOfMethodCallIgnored")
361 private <T extends DataObject> void saveErrors(@Nonnull DataTreeModification<T> change, ValidationException exception) {
363 final WriteTransaction writeTransaction = dataBroker.newWriteOnlyTransaction();
365 InstanceIdentifier<T> iid = change.getRootPath().getRootIdentifier();
366 //final ValidationException exception = exceptionMap.get(change);
367 final T badData = change.getRootNode().getDataAfter();
369 if (badData instanceof Ccap) {
370 final Ccap ccap = (Ccap) badData;
372 final Ccap opperationalCcap =
373 new CcapBuilder().setCcapId(ccap.getCcapId()).setError(exception.getErrorMessages()).build();
375 @SuppressWarnings("unchecked") final InstanceIdentifier<Ccap> ccapIID = (InstanceIdentifier<Ccap>) change;
376 writeTransaction.put(LogicalDatastoreType.OPERATIONAL, ccapIID, opperationalCcap);
377 } else if (badData instanceof Gate) {
378 final Gate gate = (Gate) badData;
380 final Gate operationalGate =
381 new GateBuilder().setGateId(gate.getGateId()).setError(exception.getErrorMessages()).build();
383 final Gates operationalGates =
384 new GatesBuilder().setGate(Collections.singletonList(operationalGate)).build();
386 final SubscriberKey subscriberKey = InstanceIdentifier.keyOf(iid.firstIdentifierOf(Subscriber.class));
387 final Subscriber operationalSubscriber =
388 new SubscriberBuilder().setSubscriberId(subscriberKey.getSubscriberId())
389 .setGates(operationalGates)
392 final Subscribers operationalSubscribers =
393 new SubscribersBuilder().setSubscriber(Collections.singletonList(operationalSubscriber))
396 final InstanceIdentifier<App> appIID = iid.firstIdentifierOf(App.class);
397 final AppKey appKey = InstanceIdentifier.keyOf(appIID);
398 final App operationalApp =
399 new AppBuilder().setAppId(appKey.getAppId()).setSubscribers(operationalSubscribers).build();
402 writeTransaction.put(LogicalDatastoreType.OPERATIONAL, appIID, operationalApp);
404 // If you get here a developer forgot to add a type above
405 logger.error("Unexpected type requested for error saving: {}", badData);
406 throw new IllegalStateException("Unsupported type for error saving");
409 CheckedFuture<Void, TransactionCommitFailedException> future = writeTransaction.submit();
413 } catch (TransactionCommitFailedException e) {
414 logger.error("Failed to write errors to operational datastore", e);
419 * Removes Ccaps if all Ccap instances are removed
421 private class CcapsCleaner extends AbstractCleaner<Ccaps> {
423 public CcapsCleaner(final InstanceIdentifier<?> removedIID) {
424 super(removedIID, Ccaps.class, LogicalDatastoreType.OPERATIONAL);
428 protected boolean shouldClean(final Ccaps ccaps) {
429 return ccaps.getCcap().isEmpty();
435 * Removes Subscriber if all Gate instances are removed
437 private class SubscriberCleaner extends AbstractCleaner<Subscriber> {
439 public SubscriberCleaner(InstanceIdentifier<Gate> removedGateIID) {
440 super(removedGateIID, Subscriber.class, LogicalDatastoreType.OPERATIONAL);
444 protected boolean shouldClean(final Subscriber subscriber) {
445 return subscriber.getGates().getGate().isEmpty();
449 protected void postRemove(InstanceIdentifier<Subscriber> subscriberIID) {
450 executor.execute(new AppCleaner(subscriberIID));
456 * Removes App if all Subscribers are removed.
458 private class AppCleaner extends AbstractCleaner<App> {
460 public AppCleaner(InstanceIdentifier<Subscriber> removedSubscriberIID) {
461 super(removedSubscriberIID, App.class, LogicalDatastoreType.OPERATIONAL);
465 boolean shouldClean(final App app) {
466 return app.getSubscribers().getSubscriber().isEmpty();
470 void postRemove(final InstanceIdentifier<App> appIID) {
471 //unregister app rpc path
472 logger.info("Un-Registering App Routed RPC Path...");
473 routedRpcRegistration.unregisterPath(AppContext.class, appIID);
474 executor.execute(new AppsCleaner(appIID));
480 * Removes Apps if all App instances are removed.
482 private class AppsCleaner extends AbstractCleaner<Apps> {
484 public AppsCleaner(InstanceIdentifier<App> removedAppIID) {
485 super(removedAppIID, Apps.class, LogicalDatastoreType.OPERATIONAL);
489 protected boolean shouldClean(final Apps apps) {
490 return apps.getApp().isEmpty();
496 * Helper class to do the heavy lifting in removing object. Lets subclasses decide with
497 * {@link #shouldClean(DataObject)}. <br>
499 * Subclasses can react after an instance is removed by overriding {@link #postRemove(InstanceIdentifier)}
502 * The type that will be removed
504 private abstract class AbstractCleaner<T extends DataObject> implements Runnable {
505 final InstanceIdentifier<?> removedIID;
506 final Class<T> tClass;
507 final LogicalDatastoreType datastoreType;
509 public AbstractCleaner(InstanceIdentifier<?> removedIID, Class<T> tClass, LogicalDatastoreType datastoreType) {
510 this.removedIID = checkNotNull(removedIID);
511 this.tClass = checkNotNull(tClass);
512 this.datastoreType = checkNotNull(datastoreType);
517 InstanceIdentifier<T> tIID = removedIID.firstIdentifierOf(tClass);
519 Optional<T> optional = mdsalUtils.read(datastoreType, tIID);
520 if (optional.isPresent()) {
522 if (shouldClean(optional.get())) {
523 if (mdsalUtils.delete(datastoreType, tIID)) {
532 logger.error("Expected to find InstanceIdentifier<{}> but was not found: {}", tClass.getSimpleName(),
538 * If returns true the object will be removed from the datastore
541 * The object that might be removed.
542 * @return true if it should be removed.
544 abstract boolean shouldClean(final T object);
547 * Called after an instance is removed.
550 * the InstanceIdentifier of the removed object
552 void postRemove(InstanceIdentifier<T> tIID) {
556 void removeFailed(InstanceIdentifier<T> tIID) {
557 logger.error("Failed to remove {}", tIID);
563 * Listener for the packetcable:ccaps tree
565 private class CcapsDataTreeChangeListener extends AbstractDataTreeChangeListener<Ccap> {
567 private final Set<InstanceIdentifier<Ccap>> updateQueue = Sets.newConcurrentHashSet();
569 public CcapsDataTreeChangeListener() {
570 super(Ccap.class,new DataValidator(new CcapsValidatorProviderFactory().build()));
574 protected void handleCreatedData(final DataTreeModification<Ccap> change) {
575 final Ccap ccap = change.getRootNode().getDataAfter();
576 InstanceIdentifier<Ccap> iid = change.getRootPath().getRootIdentifier();
579 if (pcmmServiceMap.containsKey(ccap.getCcapId())) {
580 logger.error("Already monitoring CCAP - " + ccap);
583 final PCMMService pcmmService = new PCMMService(IPCMMClient.CLIENT_TYPE, ccap);
584 // TODO - may want to use the AMID but for the client type but probably not???
586 final PCMMService pcmmService = new PCMMService(
587 thisCcap.getAmId().getAmType().shortValue(), thisCcap);
589 ConnectionBuilder connectionBuilder = new ConnectionBuilder();
590 String message = pcmmService.addCcap();
591 if (message.contains("200 OK")) {
592 pcmmServiceMap.put(ccap.getCcapId(), pcmmService);
593 ccapMap.put(ccap.getCcapId(), ccap);
594 updateCcapMaps(ccap);
595 logger.info("Created CCAP: {}/{} : {}", iid, ccap, message);
596 logger.info("Created CCAP: {} : {}", iid, message);
598 connectionBuilder.setConnected(true).setError(Collections.<String>emptyList());
600 logger.error("Create CCAP Failed: {} : {}", iid, message);
602 connectionBuilder.setConnected(false).setError(Collections.singletonList(message));
606 logger.info("Registering CCAP Routed RPC Path...");
607 routedRpcRegistration.registerPath(CcapContext.class, iid);
609 Optional<Ccap> optionalCcap = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL, iid);
611 final CcapBuilder responseCcapBuilder;
612 if (optionalCcap.isPresent()) {
613 responseCcapBuilder = new CcapBuilder(optionalCcap.get());
615 responseCcapBuilder = new CcapBuilder();
616 responseCcapBuilder.setCcapId(ccap.getCcapId());
619 responseCcapBuilder.setConnection(connectionBuilder.build());
621 mdsalUtils.put(LogicalDatastoreType.OPERATIONAL, iid, responseCcapBuilder.build());
625 protected void handleUpdatedData(final DataTreeModification<Ccap> change) {
626 InstanceIdentifier<Ccap> iid = change.getRootPath().getRootIdentifier();
628 // If this notification is coming from our modification ignore it.
629 if (updateQueue.contains(iid)) {
630 updateQueue.remove(iid);
634 final Ccap updatedCcap = change.getRootNode().getDataAfter();
637 logger.info("Registering CCAP Routed RPC Path...");
638 routedRpcRegistration.registerPath(CcapContext.class, iid);
640 // restore the original data
641 updateQueue.add(iid);
642 mdsalUtils.put(LogicalDatastoreType.CONFIGURATION, iid, updatedCcap);
646 protected void handleRemovedData(final DataTreeModification<Ccap> change) {
648 InstanceIdentifier<Ccap> iid = change.getRootPath().getRootIdentifier();
649 final Ccap nukedCcap = change.getRootNode().getDataBefore();
650 removeCcapFromAllMaps(nukedCcap);
652 //unregister ccap rpc path
653 logger.info("Un-Registering CCAP Routed RPC Path...");
654 routedRpcRegistration.unregisterPath(CcapContext.class, iid);
656 mdsalUtils.delete(LogicalDatastoreType.OPERATIONAL, iid);
658 // clean up ccaps level if it is now empty
659 executor.execute(new CcapsCleaner(iid));
663 protected void handleInvalidData(final DataTreeModification<Ccap> change, ValidationException validationException){
664 // bad data write errors to operational datastore
665 saveErrors(change, validationException);
670 private class QosDataTreeChangeListener extends AbstractDataTreeChangeListener<Gate> {
672 private final Set<InstanceIdentifier<Gate>> updateQueue = Sets.newConcurrentHashSet();
674 public QosDataTreeChangeListener() {
675 super(Gate.class,new DataValidator(new QosValidatorProviderFactory().build()));
679 protected void handleCreatedData(final DataTreeModification<Gate> change) {
681 InstanceIdentifier<Gate> gateIID = change.getRootPath().getRootIdentifier();
682 final Gate newGate = change.getRootNode().getDataAfter();
684 final String newGatePathStr = makeGatePathString(gateIID);
686 // if a new app comes along add RPC registration
687 final InstanceIdentifier<App> appIID = gateIID.firstIdentifierOf(App.class);
688 // TBD verify if App ID exists first
690 //register appID RPC path
691 logger.info("Registering App Routed RPC Path...");
692 routedRpcRegistration.registerPath(AppContext.class, appIID);
694 final InstanceIdentifier<Subscriber> subscriberIID = gateIID.firstIdentifierOf(Subscriber.class);
695 final SubscriberKey subscriberKey = InstanceIdentifier.keyOf(subscriberIID);
696 final InetAddress subscriberAddr = getInetAddress(subscriberKey.getSubscriberId());
697 if (subscriberAddr == null) {
698 final String msg = String.format("subscriberId must be a valid ipaddress: %s",
699 subscriberKey.getSubscriberId());
701 saveGateError(gateIID, newGatePathStr, msg);
705 final Ccap ccap = findCcapForSubscriberId(subscriberAddr);
707 final String msg = String.format("Unable to find Ccap for subscriber %s: @ %s",
708 subscriberKey.getSubscriberId(), newGatePathStr);
710 saveGateError(gateIID, newGatePathStr, msg);
714 final PCMMService pcmmService = pcmmServiceMap.get(ccap.getCcapId());
715 if (pcmmService == null) {
717 String.format("Unable to locate PCMM Service for CCAP: %s ; with subscriber: %s", ccap,
718 subscriberKey.getSubscriberId());
720 saveGateError(gateIID, newGatePathStr, msg);
725 // set up gate builder with known fields (and some empty ones)
727 final GateBuilder gateBuilder = new GateBuilder();
728 gateBuilder.setGateId(newGate.getGateId())
729 .setGatePath(newGatePathStr)
730 .setCcapId(ccap.getCcapId())
731 .setClassifiers(newGate.getClassifiers())
732 .setGateSpec(newGate.getGateSpec())
733 .setCopsGateState("")
734 .setCopsGateTimeInfo("")
735 .setCopsGateUsageInfo("");
737 ServiceFlowDirection scnDirection = null;
739 if (newGate.getTrafficProfile().getTrafficProfileChoice() instanceof ServiceClassNameChoice) {
740 final ServiceClassName scn =
741 ((ServiceClassNameChoice)newGate.getTrafficProfile()
742 .getTrafficProfileChoice())
743 .getServiceClassNameProfile()
744 .getServiceClassName();
745 scnDirection = findScnOnCcap(scn, ccap);
746 if (scnDirection == null) {
748 String.format("SCN %s not found on CCAP %s for %s", scn, ccap.getCcapId(), newGatePathStr);
750 saveGateError(gateIID, newGatePathStr, msg);
753 ServiceClassNameProfileBuilder scnBuilder = new ServiceClassNameProfileBuilder();
754 scnBuilder.setServiceClassName(scn);
755 ServiceClassNameProfile scnProfile = scnBuilder.build();
756 ServiceClassNameChoiceBuilder scncBuilder = new ServiceClassNameChoiceBuilder();
757 scncBuilder.setServiceClassNameProfile(scnProfile);
758 ServiceClassNameChoice scnChoice = scncBuilder.build();
759 TrafficProfileBuilder trafficProfileBuilder = new TrafficProfileBuilder();
760 trafficProfileBuilder.setTrafficProfileChoice(scnChoice);
761 TrafficProfile trafficProfile = trafficProfileBuilder.build();
762 gateBuilder.setTrafficProfile(trafficProfile);
765 gateBuilder.setTrafficProfile(newGate.getTrafficProfile());
769 // since we may be modifying the contents of the original request GateSpec
770 // to update flow direction (based on the ccap SCN configuration) we need to
771 // rebuild the requested gate spec and replace the existing one in the gate builder
773 final GateSpecBuilder gateSpecBuilder = new GateSpecBuilder();
774 gateSpecBuilder.setDirection(scnDirection);
775 gateSpecBuilder.setDscpTosMask(newGate.getGateSpec().getDscpTosMask());
776 gateSpecBuilder.setDscpTosOverwrite(newGate.getGateSpec().getDscpTosOverwrite());
777 gateSpecBuilder.setSessionClassId(newGate.getGateSpec().getSessionClassId());
778 gateSpecBuilder.setInactivityTimer(newGate.getGateSpec().getInactivityTimer());
779 final GateSpec gateSpec = gateSpecBuilder.build();
780 gateBuilder.setGateSpec(gateSpec);
783 // build the gate to be requested
785 gateBuilder.setTimestamp(getNowTimeStamp());
787 final Gate requestGate = gateBuilder.build();
790 // send gate request to Ccap
792 PCMMService.GateSendStatus status =
793 pcmmService.sendGateSet(newGatePathStr, subscriberAddr, requestGate);
794 if (status.didSucceed()) {
795 gateMap.put(newGatePathStr, requestGate);
796 gateCcapMap.put(newGatePathStr, ccap.getCcapId());
799 // inquire as to the status, and implementation info of the requested gate
801 PCMMService.GateSendStatus infoStatus = pcmmService.sendGateInfo(newGatePathStr);
803 if (infoStatus.didSucceed()) {
805 // update builder with info for operational storage
807 gateBuilder.setCopsGateState(
808 infoStatus.getCopsGateState() + "/" + infoStatus.getCopsGateStateReason())
809 .setCopsGateTimeInfo(infoStatus.getCopsGateTimeInfo())
810 .setCopsGateUsageInfo(infoStatus.getCopsGateUsageInfo())
811 .setCopsGateId(status.getCopsGateId());
813 List<String> errors = new ArrayList<>(2);
815 // Keep GateSetErrors
816 if (gateBuilder.getError() != null) {
817 errors.addAll(gateBuilder.getError());
820 errors.add(infoStatus.getMessage());
821 gateBuilder.setError(errors);
825 gateBuilder.setError(Collections.singletonList(status.getMessage()));
828 Gate operationalGate = gateBuilder.build();
829 mdsalUtils.put(LogicalDatastoreType.OPERATIONAL, gateIID, operationalGate);
832 private void saveGateError(@Nonnull final InstanceIdentifier<Gate> gateIID, @Nonnull final String gatePathStr,
833 @Nonnull final String error) {
834 checkNotNull(gateIID);
837 final GateBuilder gateBuilder = new GateBuilder();
838 gateBuilder.setGateId(InstanceIdentifier.keyOf(gateIID).getGateId())
839 .setGatePath(gatePathStr)
841 .setCopsGateState("N/A");
843 gateBuilder.setError(Collections.singletonList(error));
845 Gate operationalGate = gateBuilder.build();
847 mdsalUtils.put(LogicalDatastoreType.OPERATIONAL, gateIID, operationalGate);
851 protected void handleUpdatedData(final DataTreeModification<Gate> change) {
852 InstanceIdentifier<Gate> gateIID = change.getRootPath().getRootIdentifier();
854 // If this notification is coming from our modification ignore it.
855 if (updateQueue.contains(gateIID)) {
856 updateQueue.remove(gateIID);
860 final Gate updatedGate = change.getRootNode().getDataAfter();
862 // restores the original data
863 updateQueue.add(gateIID);
864 mdsalUtils.put(LogicalDatastoreType.CONFIGURATION, gateIID, updatedGate);
868 protected void handleRemovedData(final DataTreeModification<Gate> change) {
869 InstanceIdentifier<Gate> removedGateIID = change.getRootPath().getRootIdentifier();
870 final Gate newGate = change.getRootNode().getDataBefore();
872 mdsalUtils.delete(LogicalDatastoreType.OPERATIONAL, removedGateIID);
874 executor.execute(new SubscriberCleaner(removedGateIID));
876 final String gatePathStr = makeGatePathString(removedGateIID);
878 if (gateMap.containsKey(gatePathStr)) {
879 final Gate thisGate = gateMap.remove(gatePathStr);
880 final String gateId = thisGate.getGateId();
881 final String ccapId = gateCcapMap.remove(gatePathStr);
882 final Ccap thisCcap = ccapMap.get(ccapId);
883 final PCMMService service = pcmmServiceMap.get(thisCcap.getCcapId());
884 if (service != null) {
885 service.sendGateDelete(gatePathStr);
886 logger.info("onDataChanged(): removed QoS gate {} for {}/{}/{}: ", gateId, ccapId, gatePathStr,thisGate);
888 logger.warn("Unable to send to locate PCMMService to send gate delete message with CCAP - "
896 protected void handleInvalidData(final DataTreeModification<Gate> change, ValidationException validationException){
897 // bad data write errors to operational datastore
898 saveErrors(change, validationException);
901 private String makeGatePathString(InstanceIdentifier<Gate> iid) {
902 final InstanceIdentifier<App> appIID = iid.firstIdentifierOf(App.class);
903 final AppKey appKey = InstanceIdentifier.keyOf(appIID);
905 final InstanceIdentifier<Subscriber> subscriberIID = iid.firstIdentifierOf(Subscriber.class);
906 final SubscriberKey subscriberKey = InstanceIdentifier.keyOf(subscriberIID);
908 final GateKey gateKey = InstanceIdentifier.keyOf(iid);
910 return appKey.getAppId() + "/" + subscriberKey.getSubscriberId() + "/" + gateKey.getGateId();
915 public Future<RpcResult<CcapSetConnectionOutput>> ccapSetConnection(CcapSetConnectionInput input) {
916 // TODO refactor this method into smaller parts
918 InstanceIdentifier<Ccap> ccapIid = (InstanceIdentifier<Ccap>) input.getCcapId();
919 List<String> outputError = new ArrayList<String>();
920 String rpcResponse = null;
921 Boolean inputIsConnected = input.getConnection().isConnected();
922 Boolean effectiveIsConnected = null;
923 String ccapId = input.getCcapId().firstIdentifierOf(Ccap.class).firstKeyOf(Ccap.class).getCcapId();
924 PCMMService pcmmService = pcmmServiceMap.get(ccapId);
926 if (!inputIsConnected) {
927 // set connected false
928 if (pcmmService.getPcmmPdpSocket()) {
929 outputError.add(ccapId + ": CCAP COPS socket is already closed");
930 effectiveIsConnected = false;
932 //if (!pcmmService.getPcmmCcapClientIsConnected()) {
933 outputError.add(ccapId + ": CCAP client is disconnected with error: "
934 + pcmmService.getPcmmCcapClientConnectErrMsg());
936 pcmmService.ccapClient.disconnect();
937 effectiveIsConnected = false;
940 // set connected true
941 if (!pcmmService.getPcmmPdpSocket() && pcmmService.getPcmmCcapClientIsConnected()) {
942 outputError.add(ccapId + ": CCAP COPS socket is already open");
943 outputError.add(ccapId + ": CCAP client is connected");
944 effectiveIsConnected = true;
946 if (pcmmService.getPcmmCcapClientIsConnected()) {
947 pcmmService.ccapClient.disconnect();
949 pcmmService.ccapClient.connect();
950 if (pcmmService.getPcmmCcapClientIsConnected()) {
951 effectiveIsConnected = true;
952 outputError.add(ccapId + ": CCAP client is connected");
954 effectiveIsConnected = false;
955 outputError.add(ccapId + ": CCAP client is disconnected with error: "
956 + pcmmService.getPcmmCcapClientConnectErrMsg());
961 DateAndTime connectionDateAndTime = getNowTimeStamp();
962 org.opendaylight.yang.gen.v1.urn.packetcable.rev170224.ccap.set.connection.output.ccap.ConnectionBuilder
963 connectionRpcOutput =
964 new org.opendaylight.yang.gen.v1.urn.packetcable.rev170224.ccap.set.connection.output.ccap.ConnectionBuilder()
965 .setConnected(effectiveIsConnected)
966 .setError(outputError)
967 .setTimestamp(connectionDateAndTime);
969 org.opendaylight.yang.gen.v1.urn.packetcable.rev170224.ccap.set.connection.output.CcapBuilder ccapRpcOutput =
970 new org.opendaylight.yang.gen.v1.urn.packetcable.rev170224.ccap.set.connection.output.CcapBuilder().setCcapId(
971 ccapId).setConnection(connectionRpcOutput.build());
974 ConnectionBuilder connectionOps = new ConnectionBuilder().setConnected(effectiveIsConnected)
975 .setError(outputError)
976 .setTimestamp(connectionDateAndTime);
978 CcapBuilder responseCcapBuilder = new CcapBuilder().setCcapId(ccapId).setConnection(connectionOps.build());
981 mdsalUtils.put(LogicalDatastoreType.OPERATIONAL, ccapIid, responseCcapBuilder.build());
984 DateAndTime rpcDateAndTime = getNowTimeStamp();
985 rpcResponse = ccapId + ": CCAP set complete";
986 CcapSetConnectionOutputBuilder outputBuilder =
987 new CcapSetConnectionOutputBuilder().setCcap(ccapRpcOutput.build())
988 .setResponse(rpcResponse)
989 .setTimestamp(rpcDateAndTime);
991 return Futures.immediateFuture(RpcResultBuilder.success(outputBuilder.build()).build());
997 public Future<RpcResult<CcapPollConnectionOutput>> ccapPollConnection(CcapPollConnectionInput input) {
998 // TODO refactor this method into smaller parts
1000 InstanceIdentifier<Ccap> ccapIid = (InstanceIdentifier<Ccap>) input.getCcapId();
1001 List<String> outputError = new ArrayList<String>();
1003 String ccapId = input.getCcapId().firstIdentifierOf(Ccap.class).firstKeyOf(Ccap.class).getCcapId();
1004 PCMMService pcmmService = pcmmServiceMap.get(ccapId);
1005 Boolean effectiveIsConnected = true;
1006 String response = null;
1007 org.opendaylight.yang.gen.v1.urn.packetcable.rev170224.ccap.poll.connection.output.ccap.ConnectionBuilder
1008 connectionRpcOutput =
1009 new org.opendaylight.yang.gen.v1.urn.packetcable.rev170224.ccap.poll.connection.output.ccap.ConnectionBuilder();
1011 if (pcmmService != null) {
1012 if (pcmmService.getPcmmPdpSocket()) {
1013 outputError.add(ccapId + ": CCAP Cops socket is closed");
1014 if (!pcmmService.getPcmmCcapClientIsConnected()) {
1015 outputError.add(ccapId + ": CCAP client is disconnected with error: "
1016 + pcmmService.getPcmmCcapClientConnectErrMsg());
1018 effectiveIsConnected = false;
1020 //outputError.add(String.format(ccapId+": CCAP Cops socket is open"));
1021 if (!pcmmService.getPcmmCcapClientIsConnected()) {
1022 outputError.add(ccapId + ": CCAP client is disconnected with error: "
1023 + pcmmService.getPcmmCcapClientConnectErrMsg());
1024 effectiveIsConnected = false;
1026 outputError.add(ccapId + ": CCAP client is connected");
1029 DateAndTime connectionDateAndTime = getNowTimeStamp();
1032 ConnectionBuilder connectionOps = new ConnectionBuilder().setConnected(effectiveIsConnected)
1033 .setError(outputError)
1034 .setTimestamp(connectionDateAndTime);
1036 CcapBuilder responseCcapBuilder = new CcapBuilder().setCcapId(ccapId).setConnection(connectionOps.build());
1038 connectionRpcOutput =
1039 new org.opendaylight.yang.gen.v1.urn.packetcable.rev170224.ccap.poll.connection.output.ccap.ConnectionBuilder()
1040 .setConnected(effectiveIsConnected)
1041 .setError(outputError)
1042 .setTimestamp(connectionDateAndTime);
1044 mdsalUtils.put(LogicalDatastoreType.OPERATIONAL, ccapIid, responseCcapBuilder.build());
1045 response = ccapId + ": CCAP poll complete";
1047 //pcmmService is null, do not poll
1048 response = ccapId + ": CCAP connection null; no poll performed";
1051 DateAndTime rpcDateAndTime = getNowTimeStamp();
1053 org.opendaylight.yang.gen.v1.urn.packetcable.rev170224.ccap.poll.connection.output.CcapBuilder ccapRpcOutput =
1054 new org.opendaylight.yang.gen.v1.urn.packetcable.rev170224.ccap.poll.connection.output.CcapBuilder().setCcapId(
1055 ccapId).setConnection(connectionRpcOutput.build());
1057 CcapPollConnectionOutputBuilder outputBuilder =
1058 new CcapPollConnectionOutputBuilder().setCcap(ccapRpcOutput.build())
1059 .setResponse(response)
1060 .setTimestamp(rpcDateAndTime);
1062 return Futures.immediateFuture(RpcResultBuilder.success(outputBuilder.build()).build());
1067 private App readAppFromOperationalDatastore(InstanceIdentifier<App> appIid) {
1068 Optional<App> optionalApp = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL, appIid);
1069 AppBuilder thisAppBuilder = new AppBuilder(optionalApp.get());
1070 App thisApp = thisAppBuilder.build();
1071 logger.info("readAppFromConfigDatastore() retrived App: " + thisApp.getAppId());
1075 private Gate readGateFromOperationalDatastore(InstanceIdentifier<Gate> gateIid) {
1076 Optional<Gate> optionalGate = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL, gateIid);
1077 if (optionalGate.isPresent()) {
1078 GateBuilder gateBuilder = new GateBuilder(optionalGate.get());
1079 Gate thisGate = gateBuilder.build();
1086 private Subscriber readSubscriberFromOperationalDatastore(InstanceIdentifier<Subscriber> subscriberIid) {
1087 Optional<Subscriber> optionalSubscriber = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL, subscriberIid);
1088 if (optionalSubscriber.isPresent()) {
1089 SubscriberBuilder subscriberBuilder = new SubscriberBuilder(optionalSubscriber.get());
1090 Subscriber thisSubscriber = subscriberBuilder.build();
1091 return thisSubscriber;
1100 public Future<RpcResult<QosSetGateOutput>> qosSetGate(QosSetGateInput input) {
1101 logger.debug("RPC call to qosSetGate()");
1103 String inputAppIid = input.getAppId();
1104 String inputSubscriberId = input.getSubscriberId();
1105 org.opendaylight.yang.gen.v1.urn.packetcable.rev170224.qos.set.gate.input.Gates gates = input.getGates();
1106 List<org.opendaylight.yang.gen.v1.urn.packetcable.rev170224.qos.set.gate.input.gates.Gate> gate = gates.getGate();
1107 QosSetGateOutputBuilder outputBuilder = new QosSetGateOutputBuilder();
1109 String inputGateId = gate.get(0).getGateId();
1110 Boolean retryOption = false;
1111 InstanceIdentifier<Gate> gateIID = qosIID.builder()
1113 .child(App.class, new AppKey(inputAppIid))
1114 .child(Subscribers.class)
1115 .child(Subscriber.class, new SubscriberKey(inputSubscriberId))
1117 .child(Gate.class, new GateKey(inputGateId))
1120 Gate newGate = readGateFromOperationalDatastore(gateIID);
1121 final String newGatePathStr = "/" + inputAppIid + "/" + inputSubscriberId + "/" + inputGateId;
1123 final InetAddress subscriberAddr = getInetAddress(inputSubscriberId);
1124 if (subscriberAddr == null) {
1125 final String msg = String.format("SubscriberId must be a valid ipaddress: %s",
1128 SetFailureBuilder fb = new SetFailureBuilder();
1129 final FailureType ft = FailureType.Unsent;
1132 final SetFailure f = fb.build();
1133 outputBuilder.setSetResponseType(f);
1134 return Futures.immediateFuture(RpcResultBuilder.success(outputBuilder.build()).build());
1137 final Ccap ccap = findCcapForSubscriberId(subscriberAddr);
1140 String.format("qosSetGate(): Error finding CCAP for %s", newGatePathStr);
1142 SetFailureBuilder fb = new SetFailureBuilder();
1143 final FailureType ft = FailureType.Unsent;
1146 final SetFailure f = fb.build();
1147 outputBuilder.setSetResponseType(f);
1148 return Futures.immediateFuture(RpcResultBuilder.success(outputBuilder.build()).build());
1151 logger.debug("Mapped {} to {}", inputSubscriberId, ccap.getCcapId());
1153 final PCMMService pcmmService = pcmmServiceMap.get(ccap.getCcapId());
1154 if (pcmmService == null) {
1156 String.format("Unable to locate PCMM Service for CCAP: %s ; with subscriber: %s", ccap, inputSubscriberId);
1158 SetFailureBuilder fb = new SetFailureBuilder();
1159 final FailureType ft = FailureType.Unsent;
1162 final SetFailure f = fb.build();
1163 outputBuilder.setSetResponseType(f);
1164 return Futures.immediateFuture(RpcResultBuilder.success(outputBuilder.build()).build());
1167 final GateBuilder gateBuilder = new GateBuilder();
1168 gateBuilder.setGateId(inputGateId)
1169 .setGatePath(newGatePathStr)
1170 .setCcapId(ccap.getCcapId())
1171 .setCopsGateId(gate.get(0).getCopsGateId())
1172 .setTimestamp(getNowTimeStamp())
1173 .setTimestamp(getNowTimeStamp())
1174 .setGateSpec(gate.get(0).getGateSpec())
1175 .setTrafficProfile(gate.get(0).getTrafficProfile())
1176 .setClassifiers(gate.get(0).getClassifiers());
1178 newGate = gateBuilder.build();
1180 if (gate.get(0).getCopsGateId() != null) {
1184 PCMMService.GateSendStatus status = null;
1185 synchronized (pcmmService) {
1186 logger.info("Sending gate: Path {} inputSubscriberId {} cops-gate-id {}",
1187 newGatePathStr, inputSubscriberId, gate.get(0).getCopsGateId());
1189 status = pcmmService.sendGateSet(newGatePathStr, subscriberAddr, newGate);
1192 if (status.didSucceed()) {
1194 gateMap.put(newGatePathStr, newGate);
1195 gateCcapMap.put(newGatePathStr, ccap.getCcapId());
1196 Long copsGateId = 0L;
1197 SetSuccessfulBuilder sb = new SetSuccessfulBuilder();
1199 if (status.getCopsGateId() != null) {
1200 logger.debug("newGate.getCopsGateId() = {} ", status.getCopsGateId());
1201 copsGateId = Long.decode(status.getCopsGateId());
1202 sb.setCopsGateId(copsGateId);
1203 if (status.getCopsGateId() != null) {
1204 gateBuilder.setCopsGateId(status.getCopsGateId());
1206 if (status.getCopsGateState() != null) {
1207 gateBuilder.setCopsGateState(status.getCopsGateState());
1209 if (status.getCopsGateTimeInfo() != null) {
1210 gateBuilder.setCopsGateTimeInfo(status.getCopsGateTimeInfo());
1212 if (status.getCopsGateUsageInfo() != null) {
1213 gateBuilder.setCopsGateUsageInfo(status.getCopsGateUsageInfo());
1217 mdsalUtils.put(LogicalDatastoreType.OPERATIONAL, gateIID, gateBuilder.build());
1219 final SetSuccessful s = sb.build();
1220 outputBuilder.setSetResponseType(s);
1221 return Futures.immediateFuture(RpcResultBuilder.success(outputBuilder.build()).build());
1224 if (retryOption == true) {
1225 // Try one more time with blank Cops Gate Id in case the gate has timed out unexpectedly
1226 logger.info("qosSetGate error msg: {} reason: {}", status.getMessage(), status.getCopsGateStateReason());
1227 final GateBuilder retryGateBuilder = new GateBuilder();
1228 retryGateBuilder.setGateId(inputGateId)
1229 .setGatePath(newGatePathStr)
1230 .setCcapId(ccap.getCcapId())
1231 .setTimestamp(getNowTimeStamp())
1232 .setTimestamp(getNowTimeStamp())
1233 .setGateSpec(gate.get(0).getGateSpec())
1234 .setTrafficProfile(gate.get(0).getTrafficProfile())
1235 .setClassifiers(gate.get(0).getClassifiers());
1237 newGate = retryGateBuilder.build();
1239 synchronized (pcmmService) {
1240 logger.info("Sending gate: Path {} inputSubscriberId {} with cops-gate-id undefined",
1243 status = pcmmService.sendGateSet(newGatePathStr, subscriberAddr, newGate);
1246 if (status.didSucceed()) {
1248 gateMap.put(newGatePathStr, newGate);
1249 gateCcapMap.put(newGatePathStr, ccap.getCcapId());
1250 Long copsGateId = 0L;
1251 SetSuccessfulBuilder sb = new SetSuccessfulBuilder();
1253 if (status.getCopsGateId() != null) {
1254 logger.debug("newGate.getCopsGateId() = {} ", status.getCopsGateId());
1255 copsGateId = Long.decode(status.getCopsGateId());
1256 sb.setCopsGateId(copsGateId);
1257 if (status.getCopsGateId() != null) {
1258 gateBuilder.setCopsGateId(status.getCopsGateId());
1260 if (status.getCopsGateState() != null) {
1261 gateBuilder.setCopsGateState(status.getCopsGateState());
1263 if (status.getCopsGateTimeInfo() != null) {
1264 gateBuilder.setCopsGateTimeInfo(status.getCopsGateTimeInfo());
1266 if (status.getCopsGateUsageInfo() != null) {
1267 gateBuilder.setCopsGateUsageInfo(status.getCopsGateUsageInfo());
1271 mdsalUtils.put(LogicalDatastoreType.OPERATIONAL, gateIID, gateBuilder.build());
1273 final SetSuccessful s = sb.build();
1274 outputBuilder.setSetResponseType(s);
1275 return Futures.immediateFuture(RpcResultBuilder.success(outputBuilder.build()).build());
1278 SetFailureBuilder fb = new SetFailureBuilder();
1279 final FailureType ft = FailureType.Failed;
1281 fb.setMessage(status.getMessage());
1282 final SetFailure f = fb.build();
1283 outputBuilder.setSetResponseType(f);
1284 logger.error("qosSetGate error msg: {} reason: {}", status.getMessage(), status.getCopsGateStateReason());
1285 return Futures.immediateFuture(RpcResultBuilder.success(outputBuilder.build()).build());
1291 public Future<RpcResult<QosDeleteGateOutput>> qosDeleteGate(QosDeleteGateInput input) {
1292 logger.debug("RPC call to qosDeleteGate()");
1295 String inputAppIid = input.getAppId();
1296 String inputSubscriberId = input.getSubscriberId();
1297 String inputGateId = input.getGateId();
1298 String strGateId = null;
1300 InstanceIdentifier<Gate> gateIID = qosIID.builder()
1302 .child(App.class, new AppKey(inputAppIid))
1303 .child(Subscribers.class)
1304 .child(Subscriber.class, new SubscriberKey(inputSubscriberId))
1306 .child(Gate.class, new GateKey(inputGateId))
1309 Gate newGate = readGateFromOperationalDatastore(gateIID);
1310 QosDeleteGateOutputBuilder outputBuilder = new QosDeleteGateOutputBuilder();
1311 final String newGatePathStr = "/" + inputAppIid + "/" + inputSubscriberId + "/" + inputGateId;
1313 if (newGate != null) {
1314 strGateId = newGate.getCopsGateId();
1315 if ((strGateId == null) || (strGateId.length() == 0) || (strGateId.equals("null"))){
1317 String.format("qosDeleteGate(): Unknown CopsGateId %s", newGatePathStr);
1319 DeleteFailureBuilder fb = new DeleteFailureBuilder();
1320 final FailureType ft = FailureType.Unsent;
1323 final DeleteFailure f = fb.build();
1324 outputBuilder.setDeleteResponseType(f);
1325 return Futures.immediateFuture(RpcResultBuilder.success(outputBuilder.build()).build());
1328 logger.debug("PacketcableProvider: gateId = {} ", strGateId);
1333 String.format("qosDeleteGate(): Error deleting gate %s", newGatePathStr);
1335 DeleteFailureBuilder fb = new DeleteFailureBuilder();
1336 final FailureType ft = FailureType.Unsent;
1339 final DeleteFailure f = fb.build();
1340 outputBuilder.setDeleteResponseType(f);
1341 return Futures.immediateFuture(RpcResultBuilder.success(outputBuilder.build()).build());
1344 final InetAddress subscriberAddr = getInetAddress(inputSubscriberId);
1345 if (subscriberAddr == null) {
1346 final String msg = String.format("SubscriberId must be a valid ipaddress: %s",
1349 DeleteFailureBuilder fb = new DeleteFailureBuilder();
1350 final FailureType ft = FailureType.Unsent;
1353 final DeleteFailure f = fb.build();
1354 outputBuilder.setDeleteResponseType(f);
1355 return Futures.immediateFuture(RpcResultBuilder.success(outputBuilder.build()).build());
1358 final Ccap ccap = findCcapForSubscriberId(subscriberAddr);
1360 final String msg = String.format("Unable to find Ccap for subscriber %s:",
1363 DeleteFailureBuilder fb = new DeleteFailureBuilder();
1364 final FailureType ft = FailureType.Unsent;
1367 final DeleteFailure f = fb.build();
1368 outputBuilder.setDeleteResponseType(f);
1369 return Futures.immediateFuture(RpcResultBuilder.success(outputBuilder.build()).build());
1372 logger.debug("Mapped {} to {}", inputSubscriberId, ccap.getCcapId());
1374 final PCMMService pcmmService = pcmmServiceMap.get(ccap.getCcapId());
1375 if (pcmmService == null) {
1377 String.format("Unable to locate PCMM Service for CCAP: %s ; with subscriber: %s", ccap, inputSubscriberId);
1379 DeleteFailureBuilder fb = new DeleteFailureBuilder();
1380 final FailureType ft = FailureType.Unsent;
1383 final DeleteFailure f = fb.build();
1384 outputBuilder.setDeleteResponseType(f);
1385 return Futures.immediateFuture(RpcResultBuilder.success(outputBuilder.build()).build());
1388 Boolean status = false;
1389 synchronized (pcmmService) {
1390 status = pcmmService.sendGateDelete(newGatePathStr);
1393 if (status == true) {
1394 Long copsGateId = 0L;
1395 copsGateId = Long.decode(strGateId);
1397 logger.info("qosDeleteGate(): Successfully deleted gate {}", newGatePathStr);
1398 mdsalUtils.delete(LogicalDatastoreType.OPERATIONAL, gateIID);
1399 DeleteSuccessfulBuilder sb = new DeleteSuccessfulBuilder();
1400 sb.setCopsGateId(copsGateId);
1401 final DeleteSuccessful s = sb.build();
1402 outputBuilder.setDeleteResponseType(s);
1403 return Futures.immediateFuture(RpcResultBuilder.success(outputBuilder.build()).build());
1406 final String msg = String.format("qosDeleteGate(): Error deleting gate %s", newGatePathStr);
1408 DeleteFailureBuilder fb = new DeleteFailureBuilder();
1409 final FailureType ft = FailureType.Failed;
1412 final DeleteFailure f = fb.build();
1413 outputBuilder.setDeleteResponseType(f);
1414 return Futures.immediateFuture(RpcResultBuilder.success(outputBuilder.build()).build());
1419 public Future<RpcResult<QosGateInfoOutput>> qosGateInfo(QosGateInfoInput input) {
1420 logger.debug("RPC call to qosGateInfo()");
1422 String inputAppIid = input.getAppId();
1423 String inputSubscriberId = input.getSubscriberId();
1424 String inputGateId = input.getGateId();
1425 QosGateInfoOutputBuilder outputBuilder = new QosGateInfoOutputBuilder();
1426 InstanceIdentifier<Gate> gateIID = qosIID.builder()
1428 .child(App.class, new AppKey(inputAppIid))
1429 .child(Subscribers.class)
1430 .child(Subscriber.class, new SubscriberKey(inputSubscriberId))
1432 .child(Gate.class, new GateKey(inputGateId))
1435 Gate infoGate = readGateFromOperationalDatastore(gateIID);
1436 final String newGatePathStr = "/" + inputAppIid + "/" + inputSubscriberId + "/" + inputGateId;
1438 final InetAddress subscriberAddr = getInetAddress(inputSubscriberId);
1439 if (subscriberAddr == null) {
1440 final String msg = String.format("SubscriberId must be a valid ipaddress: %s",
1443 InfoFailureBuilder fb = new InfoFailureBuilder();
1444 final FailureType ft = FailureType.Unsent;
1447 final InfoFailure f = fb.build();
1448 outputBuilder.setInfoResponseType(f);
1449 return Futures.immediateFuture(RpcResultBuilder.success(outputBuilder.build()).build());
1452 final Ccap ccap = findCcapForSubscriberId(subscriberAddr);
1454 final String msg = String.format("Unable to find Ccap for subscriber %s:",
1457 InfoFailureBuilder fb = new InfoFailureBuilder();
1458 final FailureType ft = FailureType.Unsent;
1461 final InfoFailure f = fb.build();
1462 outputBuilder.setInfoResponseType(f);
1463 return Futures.immediateFuture(RpcResultBuilder.success(outputBuilder.build()).build());
1466 logger.debug("Mapped {} to {}", inputSubscriberId, ccap.getCcapId());
1468 final PCMMService pcmmService = pcmmServiceMap.get(ccap.getCcapId());
1469 if (pcmmService == null) {
1471 String.format("Unable to locate PCMM Service for CCAP: %s ; with subscriber: %s",
1472 ccap, inputSubscriberId);
1474 InfoFailureBuilder fb = new InfoFailureBuilder();
1475 final FailureType ft = FailureType.Unsent;
1478 final InfoFailure f = fb.build();
1479 outputBuilder.setInfoResponseType(f);
1480 return Futures.immediateFuture(RpcResultBuilder.success(outputBuilder.build()).build());
1483 PCMMService.GateSendStatus status = null;
1485 synchronized (pcmmService) {
1486 status = pcmmService.sendGateInfo(newGatePathStr);
1489 if (status.didSucceed()) {
1490 DateAndTime gateDateAndTime = getNowTimeStamp();
1491 List<String> gateOutputError = Collections.emptyList();
1492 gateOutputError = Collections.singletonList(status.getMessage());
1493 GateBuilder gateBuilder = new GateBuilder();
1495 gateBuilder.setGateId(inputGateId)
1496 .setGatePath(newGatePathStr)
1497 .setCcapId(ccap.getCcapId())
1498 .setCopsGateState(status.getCopsGateState() + "/" + status.getCopsGateStateReason())
1499 .setCopsGateTimeInfo(status.getCopsGateTimeInfo())
1500 .setCopsGateUsageInfo(status.getCopsGateUsageInfo())
1501 .setCopsGateId(status.getCopsGateId())
1502 .setError(gateOutputError)
1503 .setTimestamp(gateDateAndTime);
1505 infoGate = gateBuilder.build();
1507 mdsalUtils.put(LogicalDatastoreType.OPERATIONAL, gateIID, infoGate);
1509 org.opendaylight.yang.gen.v1.urn.packetcable.rev170224.qos.gate.info.response.info.response.type.info.successful.gates.GateBuilder responseGateBuilder
1510 = new org.opendaylight.yang.gen.v1.urn.packetcable.rev170224.qos.gate.info.response.info.response.type.info.successful.gates.GateBuilder();
1511 responseGateBuilder.fieldsFrom(infoGate);
1512 responseGateBuilder.setGateId(inputGateId);
1513 responseGateBuilder.setGatePath(newGatePathStr);
1514 org.opendaylight.yang.gen.v1.urn.packetcable.rev170224.qos.gate.info.response.info.response.type.info.successful.gates.Gate responseGate =
1515 responseGateBuilder.build();
1516 List<org.opendaylight.yang.gen.v1.urn.packetcable.rev170224.qos.gate.info.response.info.response.type.info.successful.gates.Gate> responseGateList =
1517 new ArrayList<org.opendaylight.yang.gen.v1.urn.packetcable.rev170224.qos.gate.info.response.info.response.type.info.successful.gates.Gate>();
1518 responseGateList.add(responseGate);
1519 org.opendaylight.yang.gen.v1.urn.packetcable.rev170224.qos.gate.info.response.info.response.type.info.successful.GatesBuilder responseGatesBuilder =
1520 new org.opendaylight.yang.gen.v1.urn.packetcable.rev170224.qos.gate.info.response.info.response.type.info.successful.GatesBuilder();
1521 responseGatesBuilder.setGate(responseGateList);
1522 org.opendaylight.yang.gen.v1.urn.packetcable.rev170224.qos.gate.info.response.info.response.type.info.successful.Gates responseGates =
1523 responseGatesBuilder.build();
1525 InfoSuccessfulBuilder sb = new InfoSuccessfulBuilder();
1526 sb.setGates(responseGates);
1527 final InfoSuccessful s = sb.build();
1528 outputBuilder.setInfoResponseType(s);
1529 return Futures.immediateFuture(RpcResultBuilder.success(outputBuilder.build()).build());
1533 String.format("qosGateInfo(): error msg: %s reason: %s", status.getMessage(), status.getCopsGateStateReason());
1535 InfoFailureBuilder fb = new InfoFailureBuilder();
1536 final FailureType ft = FailureType.Failed;
1539 final InfoFailure f = fb.build();
1540 outputBuilder.setInfoResponseType(f);
1541 return Futures.immediateFuture(RpcResultBuilder.success(outputBuilder.build()).build());
1546 public Future<RpcResult<QosPollGatesOutput>> qosPollGates(QosPollGatesInput input) {
1547 // TODO refactor this method into smaller parts
1549 InstanceIdentifier<App> appIid = (InstanceIdentifier<App>) input.getAppId();
1550 //logger.info("qospollgates appIid : "+appIid.toString());
1551 App app = readAppFromOperationalDatastore(appIid);
1552 //logger.info("qospollgates app : "+app.toString());
1553 AppKey appKey = InstanceIdentifier.keyOf(appIid);
1554 String inputSubscriberId = input.getSubscriberId();
1555 String inputGateId = input.getGateId();
1556 List<String> gateOutputError = Collections.emptyList();
1557 String subscriberId = null;
1558 String gateId = null;
1559 String ccapId = null;
1560 String gatePathStr = null;
1561 String opsCopsGateId = null;
1562 Gate opsGate = null;
1564 String rpcResponse = null;
1566 org.opendaylight.yang.gen.v1.urn.packetcable.rev170224.qos.poll.gates.output.GateBuilder gateOutputBuilder =
1567 new org.opendaylight.yang.gen.v1.urn.packetcable.rev170224.qos.poll.gates.output.GateBuilder();
1569 GateBuilder gateBuilder = new GateBuilder();
1571 if (inputSubscriberId != null) {
1572 if (inputGateId != null) {
1573 //Subscriber Id and Gate Id provided, only one gate to be poolled
1575 //generate the gateiid
1576 InstanceIdentifier<Gate> gateIid = appIid.builder()
1577 .child(Subscribers.class)
1578 .child(Subscriber.class, new SubscriberKey(inputSubscriberId))
1580 .child(Gate.class, new GateKey(inputGateId))
1584 opsGate = readGateFromOperationalDatastore(gateIid);
1586 //does the gate exists in the Operational DS?
1587 if (opsGate == null) {
1588 gatePathStr = appKey.getAppId() + "/" + inputSubscriberId + "/" + inputGateId;
1589 rpcResponse = gatePathStr + ": gate does not exist in the system; gate poll not performed";
1591 opsCopsGateId = opsGate.getCopsGateId();
1592 gatePathStr = opsGate.getGatePath();
1594 if ((!Objects.equals(opsCopsGateId, "")) && (!Objects.equals(opsCopsGateId, null))) {
1595 ccapId = findCcapForSubscriberId(getInetAddress(inputSubscriberId)).getCcapId();
1596 PCMMService pcmmService = pcmmServiceMap.get(ccapId);
1597 //is the CCAP socket open?
1598 if (!pcmmService.getPcmmPdpSocket() && pcmmService.getPcmmCcapClientIsConnected()) {
1599 PCMMService.GateSendStatus status = pcmmService.sendGateInfo(gatePathStr);
1600 DateAndTime gateDateAndTime = getNowTimeStamp();
1601 //logger.info("qospollgates Gate Status : GateID/"+status.getCopsGateId());
1602 //logger.info("qospollgates Gate Status : Message/"+status.getMessage());
1603 //logger.info("qospollgates Gate Status : DidSucceed/"+status.didSucceed());
1604 gateOutputError = Collections.singletonList(status.getMessage());
1606 gateOutputBuilder.setGatePath(gatePathStr)
1608 .setCopsGateState(status.getCopsGateState() + "/" + status.getCopsGateStateReason())
1609 .setCopsGateTimeInfo(status.getCopsGateTimeInfo())
1610 .setCopsGateUsageInfo(status.getCopsGateUsageInfo())
1611 .setCopsGateId(status.getCopsGateId())
1612 .setError(gateOutputError)
1613 .setTimestamp(gateDateAndTime);
1615 gateBuilder.setGateId(inputGateId)
1616 .setGatePath(gatePathStr)
1618 .setCopsGateState(status.getCopsGateState() + "/" + status.getCopsGateStateReason())
1619 .setCopsGateTimeInfo(status.getCopsGateTimeInfo())
1620 .setCopsGateUsageInfo(status.getCopsGateUsageInfo())
1621 .setCopsGateId(status.getCopsGateId())
1622 .setError(gateOutputError)
1623 .setTimestamp(gateDateAndTime);
1625 mdsalUtils.put(LogicalDatastoreType.OPERATIONAL, gateIid, gateBuilder.build());
1626 rpcResponse = gatePathStr + ": gate poll complete";
1629 ccapId + ": CCAP socket is down or client disconnected; gate poll not performed";
1632 rpcResponse = gatePathStr + ": gate not active; gate poll not performed";
1636 //inputGateId is null; pool all gates for the subscriber if the sub exists
1638 //generate active subIid
1639 InstanceIdentifier<Subscriber> subIid = appIid.builder()
1640 .child(Subscribers.class)
1641 .child(Subscriber.class, new SubscriberKey(inputSubscriberId))
1643 //does the subscriber provided exists in the Operational Datastore?
1644 Subscriber sub = readSubscriberFromOperationalDatastore(subIid);
1646 //If Subscriber exsits poll all gates for the subscriber
1647 subscriberId = sub.getSubscriberId();
1648 List<Gate> gateList = sub.getGates().getGate();
1649 for (Gate gate : gateList) {
1650 //generate active gateIid
1651 gateId = gate.getGateId();
1652 InstanceIdentifier<Gate> gateIid =
1653 subIid.builder().child(Gates.class).child(Gate.class, new GateKey(gateId)).build();
1655 opsGate = readGateFromOperationalDatastore(gateIid);
1656 opsCopsGateId = opsGate.getCopsGateId();
1657 //generate active gatePathStr
1658 gatePathStr = appKey.getAppId() + "/" + subscriberId + "/" + gateId;
1660 if ((!Objects.equals(opsCopsGateId, "")) && (!Objects.equals(opsCopsGateId, null))) {
1661 ccapId = findCcapForSubscriberId(getInetAddress(subscriberId)).getCcapId();
1662 PCMMService pcmmService = pcmmServiceMap.get(ccapId);
1663 //is the CCAP socket open?
1664 if (!pcmmService.getPcmmPdpSocket() && pcmmService.getPcmmCcapClientIsConnected()) {
1665 PCMMService.GateSendStatus status = pcmmService.sendGateInfo(gatePathStr);
1666 DateAndTime gateDateAndTime = getNowTimeStamp();
1668 gateBuilder.setGateId(gateId)
1669 .setGatePath(gatePathStr)
1672 status.getCopsGateState() + "/" + status.getCopsGateStateReason())
1673 .setCopsGateTimeInfo(status.getCopsGateTimeInfo())
1674 .setCopsGateUsageInfo(status.getCopsGateUsageInfo())
1675 .setCopsGateId(status.getCopsGateId())
1676 .setError(gateOutputError)
1677 .setTimestamp(gateDateAndTime);
1679 mdsalUtils.put(LogicalDatastoreType.OPERATIONAL, gateIid, gateBuilder.build());
1682 "qospollgates: {}: CCAP Cops socket is down or client disconnected; gate poll not performed",
1686 //TODO define what happens if a gate is not active.. is nothing ok?
1687 logger.info("qospollgates: {}: gate not active; gate poll not performed", gatePathStr);
1690 rpcResponse = inputSubscriberId + "/: subscriber subtree poll in progress";
1693 inputSubscriberId + "/: subscriber is not defined in the system, gate poll not performed";
1698 // inputSubId is null
1699 if (inputGateId != null) {
1700 gatePathStr = appKey.getAppId() + "/" + inputSubscriberId + "/" + inputGateId;
1701 rpcResponse = gatePathStr + ": Subscriber ID not provided; gate poll not performed";
1703 //poll all gates for the appId
1704 PollAllGatesForApp pollAllGatesForApp = new PollAllGatesForApp(appIid,app);
1705 Thread t = new Thread(pollAllGatesForApp);
1707 rpcResponse = appKey.getAppId() + "/: gate subtree poll in progress";
1711 DateAndTime rpcDateAndTime = getNowTimeStamp();
1713 QosPollGatesOutputBuilder outputBuilder = new QosPollGatesOutputBuilder().setTimestamp(rpcDateAndTime)
1714 .setResponse(rpcResponse)
1715 .setGate(gateOutputBuilder.build());
1716 return Futures.immediateFuture(RpcResultBuilder.success(outputBuilder.build()).build());
1718 private class PollAllGatesForApp implements Runnable {
1720 private InstanceIdentifier <App> appIid;
1723 private PollAllGatesForApp (InstanceIdentifier <App> appIid, App app) {
1725 this.appIid = appIid;
1731 org.opendaylight.yang.gen.v1.urn.packetcable.rev170224.qos.poll.gates.output.GateBuilder gateOutputBuilder =
1732 new org.opendaylight.yang.gen.v1.urn.packetcable.rev170224.qos.poll.gates.output.GateBuilder();
1734 GateBuilder gateBuilder = new GateBuilder();
1737 AppKey appKey = InstanceIdentifier.keyOf(appIid);
1739 Subscribers subs = app.getSubscribers();
1740 logger.info("qospollgates subscribers: " + subs.toString());
1742 List<Subscriber> subList = subs.getSubscriber();
1743 logger.info("qospollgates subList: " + subList.toString());
1745 for (Subscriber sub : subList) {
1746 //generate active subIid
1747 String subscriberId = sub.getSubscriberId();
1748 InstanceIdentifier<Subscriber> subIid = appIid.builder()
1749 .child(Subscribers.class)
1750 .child(Subscriber.class, new SubscriberKey(subscriberId))
1753 List<Gate> gateList = sub.getGates().getGate();
1755 for (Gate gate : gateList) {
1756 //logger.info("qospollgates active gate: "+gate);
1758 //generate active gateIid
1759 String gateId = gate.getGateId();
1760 InstanceIdentifier<Gate> gateIid =
1761 subIid.builder().child(Gates.class).child(Gate.class, new GateKey(gateId)).build();
1764 Gate opsGate = readGateFromOperationalDatastore(gateIid);
1765 String opsCopsGateId = opsGate.getCopsGateId();
1766 //generate active gatePathStr
1767 String gatePathStr = appKey.getAppId() + "/" + subscriberId + "/" + gateId;
1769 if ((!Objects.equals(opsCopsGateId, "")) && (!Objects.equals(opsCopsGateId, null))) {
1770 String ccapId = findCcapForSubscriberId(getInetAddress(subscriberId)).getCcapId();
1771 PCMMService pcmmService = pcmmServiceMap.get(ccapId);
1772 //is the CCAP socket open?
1773 if (!pcmmService.getPcmmPdpSocket() && pcmmService.getPcmmCcapClientIsConnected()) {
1774 PCMMService.GateSendStatus status = pcmmService.sendGateInfo(gatePathStr);
1775 DateAndTime gateDateAndTime = getNowTimeStamp();
1776 List<String> gateOutputError = Collections.singletonList(status.getMessage());
1779 gateBuilder.setGateId(gateId)
1780 .setGatePath(gatePathStr)
1783 status.getCopsGateState() + "/" + status.getCopsGateStateReason())
1784 .setCopsGateTimeInfo(status.getCopsGateTimeInfo())
1785 .setCopsGateUsageInfo(status.getCopsGateUsageInfo())
1786 .setCopsGateId(status.getCopsGateId())
1787 .setError(gateOutputError)
1788 .setTimestamp(gateDateAndTime);
1790 mdsalUtils.put(LogicalDatastoreType.OPERATIONAL, gateIid, gateBuilder.build());
1793 "qospollgates: {}: CCAP socket is down or client disconnected; gate poll not performed",
1797 //TODO define what happens if a gate is not active.. is nothing ok
1798 logger.info("qospollgates: {}: gate not active; gate poll not performed", gatePathStr);
1806 private DateAndTime getNowTimeStamp() {
1807 DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSXXX");
1808 return new DateAndTime(dateFormat.format(new Date()));