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.Sets;
15 import com.google.common.util.concurrent.CheckedFuture;
16 import com.google.common.util.concurrent.Futures;
17 import java.net.InetAddress;
18 import java.net.UnknownHostException;
19 import java.text.DateFormat;
20 import java.text.SimpleDateFormat;
21 import java.util.ArrayList;
22 import java.util.Collections;
23 import java.util.Date;
24 import java.util.List;
26 import java.util.Objects;
28 import java.util.concurrent.ConcurrentHashMap;
29 import java.util.concurrent.ExecutionException;
30 import java.util.concurrent.Executor;
31 import java.util.concurrent.Executors;
32 import java.util.concurrent.Future;
33 import javax.annotation.Nonnull;
34 import javax.annotation.concurrent.ThreadSafe;
35 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
36 import org.opendaylight.controller.md.sal.binding.api.DataTreeChangeListener;
37 import org.opendaylight.controller.md.sal.binding.api.DataTreeIdentifier;
38 import org.opendaylight.controller.md.sal.binding.api.DataTreeModification;
39 import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
40 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
41 import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException;
42 import org.opendaylight.controller.packetcable.provider.validation.DataValidator;
43 import org.opendaylight.controller.packetcable.provider.validation.ValidationException;
44 import org.opendaylight.controller.packetcable.provider.validation.impl.CcapsValidatorProviderFactory;
45 import org.opendaylight.controller.packetcable.provider.validation.impl.QosValidatorProviderFactory;
46 import org.opendaylight.controller.sal.binding.api.BindingAwareBroker.RoutedRpcRegistration;
47 import org.opendaylight.controller.sal.binding.api.BindingAwareBroker.RpcRegistration;
48 import org.opendaylight.controller.sal.binding.api.RpcProviderRegistry;
49 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpPrefix;
50 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Prefix;
51 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.DateAndTime;
52 import org.opendaylight.yang.gen.v1.urn.packetcable.rev170224.AppContext;
53 import org.opendaylight.yang.gen.v1.urn.packetcable.rev170224.CcapContext;
54 import org.opendaylight.yang.gen.v1.urn.packetcable.rev170224.CcapPollConnectionInput;
55 import org.opendaylight.yang.gen.v1.urn.packetcable.rev170224.CcapPollConnectionOutput;
56 import org.opendaylight.yang.gen.v1.urn.packetcable.rev170224.CcapPollConnectionOutputBuilder;
57 import org.opendaylight.yang.gen.v1.urn.packetcable.rev170224.CcapSetConnectionInput;
58 import org.opendaylight.yang.gen.v1.urn.packetcable.rev170224.CcapSetConnectionOutput;
59 import org.opendaylight.yang.gen.v1.urn.packetcable.rev170224.CcapSetConnectionOutputBuilder;
60 import org.opendaylight.yang.gen.v1.urn.packetcable.rev170224.Ccaps;
61 import org.opendaylight.yang.gen.v1.urn.packetcable.rev170224.FailureType;
62 import org.opendaylight.yang.gen.v1.urn.packetcable.rev170224.PacketcableService;
63 import org.opendaylight.yang.gen.v1.urn.packetcable.rev170224.Qos;
64 import org.opendaylight.yang.gen.v1.urn.packetcable.rev170224.QosDeleteGateInput;
65 import org.opendaylight.yang.gen.v1.urn.packetcable.rev170224.QosDeleteGateOutput;
66 import org.opendaylight.yang.gen.v1.urn.packetcable.rev170224.QosDeleteGateOutputBuilder;
67 import org.opendaylight.yang.gen.v1.urn.packetcable.rev170224.QosGateInfoInput;
68 import org.opendaylight.yang.gen.v1.urn.packetcable.rev170224.QosGateInfoOutput;
69 import org.opendaylight.yang.gen.v1.urn.packetcable.rev170224.QosGateInfoOutputBuilder;
70 import org.opendaylight.yang.gen.v1.urn.packetcable.rev170224.QosPollGatesInput;
71 import org.opendaylight.yang.gen.v1.urn.packetcable.rev170224.QosPollGatesOutput;
72 import org.opendaylight.yang.gen.v1.urn.packetcable.rev170224.QosPollGatesOutputBuilder;
73 import org.opendaylight.yang.gen.v1.urn.packetcable.rev170224.QosSetGateInput;
74 import org.opendaylight.yang.gen.v1.urn.packetcable.rev170224.QosSetGateOutput;
75 import org.opendaylight.yang.gen.v1.urn.packetcable.rev170224.QosSetGateOutputBuilder;
76 import org.opendaylight.yang.gen.v1.urn.packetcable.rev170224.ServiceClassName;
77 import org.opendaylight.yang.gen.v1.urn.packetcable.rev170224.ServiceFlowDirection;
78 import org.opendaylight.yang.gen.v1.urn.packetcable.rev170224.ccap.attributes.ConnectionBuilder;
79 import org.opendaylight.yang.gen.v1.urn.packetcable.rev170224.ccaps.Ccap;
80 import org.opendaylight.yang.gen.v1.urn.packetcable.rev170224.ccaps.CcapBuilder;
81 import org.opendaylight.yang.gen.v1.urn.packetcable.rev170224.pcmm.qos.gate.spec.GateSpec;
82 import org.opendaylight.yang.gen.v1.urn.packetcable.rev170224.pcmm.qos.gate.spec.GateSpecBuilder;
83 import org.opendaylight.yang.gen.v1.urn.packetcable.rev170224.pcmm.qos.gates.Apps;
84 import org.opendaylight.yang.gen.v1.urn.packetcable.rev170224.pcmm.qos.gates.apps.App;
85 import org.opendaylight.yang.gen.v1.urn.packetcable.rev170224.pcmm.qos.gates.apps.AppBuilder;
86 import org.opendaylight.yang.gen.v1.urn.packetcable.rev170224.pcmm.qos.gates.apps.AppKey;
87 import org.opendaylight.yang.gen.v1.urn.packetcable.rev170224.pcmm.qos.gates.apps.app.Subscribers;
88 import org.opendaylight.yang.gen.v1.urn.packetcable.rev170224.pcmm.qos.gates.apps.app.SubscribersBuilder;
89 import org.opendaylight.yang.gen.v1.urn.packetcable.rev170224.pcmm.qos.gates.apps.app.subscribers.Subscriber;
90 import org.opendaylight.yang.gen.v1.urn.packetcable.rev170224.pcmm.qos.gates.apps.app.subscribers.SubscriberBuilder;
91 import org.opendaylight.yang.gen.v1.urn.packetcable.rev170224.pcmm.qos.gates.apps.app.subscribers.SubscriberKey;
92 import org.opendaylight.yang.gen.v1.urn.packetcable.rev170224.pcmm.qos.gates.apps.app.subscribers.subscriber.Gates;
93 import org.opendaylight.yang.gen.v1.urn.packetcable.rev170224.pcmm.qos.gates.apps.app.subscribers.subscriber.GatesBuilder;
94 import org.opendaylight.yang.gen.v1.urn.packetcable.rev170224.pcmm.qos.gates.apps.app.subscribers.subscriber.gates.Gate;
95 import org.opendaylight.yang.gen.v1.urn.packetcable.rev170224.pcmm.qos.gates.apps.app.subscribers.subscriber.gates.GateBuilder;
96 import org.opendaylight.yang.gen.v1.urn.packetcable.rev170224.pcmm.qos.gates.apps.app.subscribers.subscriber.gates.GateKey;
97 import org.opendaylight.yang.gen.v1.urn.packetcable.rev170224.pcmm.qos.traffic.profile.TrafficProfile;
98 import org.opendaylight.yang.gen.v1.urn.packetcable.rev170224.pcmm.qos.traffic.profile.TrafficProfileBuilder;
99 import org.opendaylight.yang.gen.v1.urn.packetcable.rev170224.pcmm.qos.traffic.profile.traffic.profile.traffic.profile.choice.ServiceClassNameChoice;
100 import org.opendaylight.yang.gen.v1.urn.packetcable.rev170224.pcmm.qos.traffic.profile.traffic.profile.traffic.profile.choice.ServiceClassNameChoiceBuilder;
101 import org.opendaylight.yang.gen.v1.urn.packetcable.rev170224.pcmm.serviceclass.name.profile.ServiceClassNameProfile;
102 import org.opendaylight.yang.gen.v1.urn.packetcable.rev170224.pcmm.serviceclass.name.profile.ServiceClassNameProfileBuilder;
103 import org.opendaylight.yang.gen.v1.urn.packetcable.rev170224.qos.delete.gate.response.delete.response.type.DeleteFailure;
104 import org.opendaylight.yang.gen.v1.urn.packetcable.rev170224.qos.delete.gate.response.delete.response.type.DeleteFailureBuilder;
105 import org.opendaylight.yang.gen.v1.urn.packetcable.rev170224.qos.delete.gate.response.delete.response.type.DeleteSuccessful;
106 import org.opendaylight.yang.gen.v1.urn.packetcable.rev170224.qos.delete.gate.response.delete.response.type.DeleteSuccessfulBuilder;
107 import org.opendaylight.yang.gen.v1.urn.packetcable.rev170224.qos.gate.info.response.info.response.type.InfoFailure;
108 import org.opendaylight.yang.gen.v1.urn.packetcable.rev170224.qos.gate.info.response.info.response.type.InfoFailureBuilder;
109 import org.opendaylight.yang.gen.v1.urn.packetcable.rev170224.qos.gate.info.response.info.response.type.InfoSuccessful;
110 import org.opendaylight.yang.gen.v1.urn.packetcable.rev170224.qos.gate.info.response.info.response.type.InfoSuccessfulBuilder;
111 import org.opendaylight.yang.gen.v1.urn.packetcable.rev170224.qos.set.gate.response.set.response.type.SetFailure;
112 import org.opendaylight.yang.gen.v1.urn.packetcable.rev170224.qos.set.gate.response.set.response.type.SetFailureBuilder;
113 import org.opendaylight.yang.gen.v1.urn.packetcable.rev170224.qos.set.gate.response.set.response.type.SetSuccessful;
114 import org.opendaylight.yang.gen.v1.urn.packetcable.rev170224.qos.set.gate.response.set.response.type.SetSuccessfulBuilder;
115 import org.opendaylight.yangtools.concepts.ListenerRegistration;
116 import org.opendaylight.yangtools.yang.binding.DataObject;
117 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
118 import org.opendaylight.yangtools.yang.common.RpcResult;
119 import org.opendaylight.yangtools.yang.common.RpcResultBuilder;
120 import org.pcmm.rcd.IPCMMClient;
121 import org.slf4j.Logger;
122 import org.slf4j.LoggerFactory;
125 * Called by ODL framework to start this bundle.
127 * This class is responsible for processing messages received from ODL's restconf interface.
128 * TODO - Remove some of these state maps and move some of this into the PCMMService
129 * TODO Don't implement PacketcableService, move that into an inner class
132 public class PacketcableProvider implements AutoCloseable, PacketcableService {
134 private static final Logger logger = LoggerFactory.getLogger(PacketcableProvider.class);
136 // keys to the /restconf/config/packetcable:ccaps and /restconf/config/packetcable:qos config datastore
137 private static final InstanceIdentifier<Ccaps> ccapsIID = InstanceIdentifier.builder(Ccaps.class).build();
138 private static final InstanceIdentifier<Qos> qosIID = InstanceIdentifier.builder(Qos.class).build();
140 // TODO - Revisit these maps and remove the ones no longer necessary
141 private final Map<String, Ccap> ccapMap = new ConcurrentHashMap<>();
142 private final Map<String, Gate> gateMap = new ConcurrentHashMap<>();
143 private final Map<String, String> gateCcapMap = new ConcurrentHashMap<>();
144 private final Map<Subnet, Ccap> subscriberSubnetsMap = new ConcurrentHashMap<>();
145 private final Map<ServiceClassName, List<Ccap>> downstreamScnMap = new ConcurrentHashMap<>();
146 private final Map<ServiceClassName, List<Ccap>> upstreamScnMap = new ConcurrentHashMap<>();
148 private final Executor executor = Executors.newSingleThreadExecutor();
151 * Holds a PCMMService object for each CCAP being managed.
153 private final Map<String, PCMMService> pcmmServiceMap = new ConcurrentHashMap<>();
156 * The ODL object used to broker messages throughout the framework
158 private final DataBroker dataBroker;
159 private final MdsalUtils mdsalUtils;
161 //Routed RPC Registration
162 private RoutedRpcRegistration<PacketcableService> routedRpcRegistration;
164 // unrouted RPC Registration
165 private RpcRegistration<PacketcableService> rpcRegistration;
167 // Data change listeners/registrations
168 private final CcapsDataTreeChangeListener ccapsDataTreeChangeListener = new CcapsDataTreeChangeListener();
169 private final QosDataTreeChangeListener qosDataTreeChangeListener = new QosDataTreeChangeListener();
171 private ListenerRegistration<DataTreeChangeListener> ccapsDataTreeChangeListenerRegistration;
172 private ListenerRegistration<DataTreeChangeListener> qosDataTreeChangeListenerRegistration;
174 private final RpcProviderRegistry rpcProviderRegistry;
179 public PacketcableProvider(final DataBroker dataBroker, final RpcProviderRegistry rpcProviderRegistry) {
180 logger.info("Starting Packetcable Provider");
181 this.dataBroker = dataBroker;
182 this.rpcProviderRegistry = rpcProviderRegistry;
183 mdsalUtils = new MdsalUtils(dataBroker);
187 logger.info("logging levels: error={}, warn={}, info={}, debug={}, trace={}",
188 logger.isErrorEnabled(), logger.isWarnEnabled(),
189 logger.isInfoEnabled(), logger.isDebugEnabled(), logger.isTraceEnabled());
191 final DataTreeIdentifier<Ccap> ccapsDataTreeIid =
192 new DataTreeIdentifier<>(LogicalDatastoreType.CONFIGURATION, ccapsIID.child(Ccap.class));
194 final DataTreeIdentifier<Gate> appDataTreeIid =
195 new DataTreeIdentifier<>(LogicalDatastoreType.CONFIGURATION,
196 qosIID.child(Apps.class).child(App.class).child(Subscribers.class).child(Subscriber.class).child(Gates.class).child(Gate.class));
198 ccapsDataTreeChangeListenerRegistration =
199 dataBroker.registerDataTreeChangeListener(ccapsDataTreeIid, new CcapsDataTreeChangeListener());
201 qosDataTreeChangeListenerRegistration = dataBroker.registerDataTreeChangeListener(appDataTreeIid, new QosDataTreeChangeListener());
203 rpcRegistration = rpcProviderRegistry.addRpcImplementation(PacketcableService.class, this);
204 routedRpcRegistration = rpcProviderRegistry.addRoutedRpcImplementation(PacketcableService.class, this);
206 logger.info("Packetcable Session Initiated");
210 * Implemented from the AutoCloseable interface.
213 public void close() throws ExecutionException, InterruptedException {
214 if (ccapsDataTreeChangeListenerRegistration != null) {
215 ccapsDataTreeChangeListenerRegistration.close();
218 if (qosDataTreeChangeListenerRegistration != null) {
219 qosDataTreeChangeListenerRegistration.close();
222 if (rpcRegistration != null) {
223 rpcRegistration.close();
226 if (routedRpcRegistration != null) {
227 routedRpcRegistration.close();
231 private void updateCcapMaps(final Ccap ccap) {
232 // add ccap to the subscriberSubnets map
233 for (final IpPrefix ipPrefix : ccap.getSubscriberSubnets()) {
235 subscriberSubnetsMap.put(Subnet.createInstance(getIpPrefixStr(ipPrefix)), ccap);
236 } catch (UnknownHostException e) {
237 logger.error("updateSubscriberSubnets: {}:{} FAILED: {}", ipPrefix, ccap, e.getMessage());
240 // ccap to upstream SCN map
241 for (final ServiceClassName scn : ccap.getUpstreamScns()) {
242 if (upstreamScnMap.containsKey(scn)) {
243 upstreamScnMap.get(scn).add(ccap);
245 final List<Ccap> ccapList = new ArrayList<>();
247 upstreamScnMap.put(scn, ccapList);
250 // ccap to downstream SCN map
251 for (final ServiceClassName scn : ccap.getDownstreamScns()) {
252 if (downstreamScnMap.containsKey(scn)) {
253 downstreamScnMap.get(scn).add(ccap);
255 final List<Ccap> ccapList = new ArrayList<>();
257 downstreamScnMap.put(scn, ccapList);
262 private String getIpPrefixStr(final IpPrefix ipPrefix) {
263 final Ipv4Prefix ipv4 = ipPrefix.getIpv4Prefix();
265 return ipv4.getValue();
267 return ipPrefix.getIpv6Prefix().getValue();
271 public InetAddress getInetAddress(final String subId) {
273 return InetAddress.getByName(subId);
274 } catch (UnknownHostException e) {
275 logger.error("getInetAddress: {} FAILED: {}", subId, e.getMessage());
280 private Ccap findCcapForSubscriberId(final InetAddress inetAddr) {
281 // TODO replace this with a loading cache, https://github.com/google/guava/wiki/CachesExplained
282 Ccap matchedCcap = null;
283 int longestPrefixLen = -1;
284 for (final Map.Entry<Subnet, Ccap> entry : subscriberSubnetsMap.entrySet()) {
285 final Subnet subnet = entry.getKey();
286 if (subnet.isInNet(inetAddr)) {
287 int prefixLen = subnet.getPrefixLen();
288 if (prefixLen > longestPrefixLen) {
289 matchedCcap = entry.getValue();
290 longestPrefixLen = prefixLen;
297 private ServiceFlowDirection findScnOnCcap(final ServiceClassName scn, final Ccap ccap) {
301 if (upstreamScnMap.containsKey(scn)) {
302 final List<Ccap> ccapList = upstreamScnMap.get(scn);
303 if (ccapList.contains(ccap)) {
304 return ServiceFlowDirection.Us;
306 } else if (downstreamScnMap.containsKey(scn)) {
307 final List<Ccap> ccapList = downstreamScnMap.get(scn);
308 if (ccapList.contains(ccap)) {
309 return ServiceFlowDirection.Ds;
315 private void removeCcapFromAllMaps(final Ccap ccap) {
316 // remove the ccap from all maps
317 // subscriberSubnets map
318 for (final Map.Entry<Subnet, Ccap> entry : subscriberSubnetsMap.entrySet()) {
319 if (entry.getValue() == ccap) {
320 subscriberSubnetsMap.remove(entry.getKey());
323 // ccap to upstream SCN map
324 for (final Map.Entry<ServiceClassName, List<Ccap>> entry : upstreamScnMap.entrySet()) {
325 final List<Ccap> ccapList = entry.getValue();
326 ccapList.remove(ccap);
327 if (ccapList.isEmpty()) {
328 upstreamScnMap.remove(entry.getKey());
331 // ccap to downstream SCN map
332 for (final Map.Entry<ServiceClassName, List<Ccap>> entry : downstreamScnMap.entrySet()) {
333 final List<Ccap> ccapList = entry.getValue();
334 ccapList.remove(ccap);
335 if (ccapList.isEmpty()) {
336 downstreamScnMap.remove(entry.getKey());
340 final PCMMService service = pcmmServiceMap.remove(ccap.getCcapId());
341 if (service != null) {
346 // ValidationException does not need to be thrown again
347 @SuppressWarnings("ThrowableResultOfMethodCallIgnored")
348 private <T extends DataObject> void saveErrors(@Nonnull DataTreeModification<T> change, ValidationException exception) {
350 final WriteTransaction writeTransaction = dataBroker.newWriteOnlyTransaction();
352 InstanceIdentifier<T> iid = change.getRootPath().getRootIdentifier();
353 //final ValidationException exception = exceptionMap.get(change);
354 final T badData = change.getRootNode().getDataAfter();
356 if (badData instanceof Ccap) {
357 final Ccap ccap = (Ccap) badData;
359 final Ccap opperationalCcap =
360 new CcapBuilder().setCcapId(ccap.getCcapId()).setError(exception.getErrorMessages()).build();
362 @SuppressWarnings("unchecked") final InstanceIdentifier<Ccap> ccapIID = (InstanceIdentifier<Ccap>) change;
363 writeTransaction.put(LogicalDatastoreType.OPERATIONAL, ccapIID, opperationalCcap);
364 } else if (badData instanceof Gate) {
365 final Gate gate = (Gate) badData;
367 final Gate operationalGate =
368 new GateBuilder().setGateId(gate.getGateId()).setError(exception.getErrorMessages()).build();
370 final Gates operationalGates =
371 new GatesBuilder().setGate(Collections.singletonList(operationalGate)).build();
373 final SubscriberKey subscriberKey = InstanceIdentifier.keyOf(iid.firstIdentifierOf(Subscriber.class));
374 final Subscriber operationalSubscriber =
375 new SubscriberBuilder().setSubscriberId(subscriberKey.getSubscriberId())
376 .setGates(operationalGates)
379 final Subscribers operationalSubscribers =
380 new SubscribersBuilder().setSubscriber(Collections.singletonList(operationalSubscriber))
383 final InstanceIdentifier<App> appIID = iid.firstIdentifierOf(App.class);
384 final AppKey appKey = InstanceIdentifier.keyOf(appIID);
385 final App operationalApp =
386 new AppBuilder().setAppId(appKey.getAppId()).setSubscribers(operationalSubscribers).build();
389 writeTransaction.put(LogicalDatastoreType.OPERATIONAL, appIID, operationalApp);
391 // If you get here a developer forgot to add a type above
392 logger.error("Unexpected type requested for error saving: {}", badData);
393 throw new IllegalStateException("Unsupported type for error saving");
396 CheckedFuture<Void, TransactionCommitFailedException> future = writeTransaction.submit();
400 } catch (TransactionCommitFailedException e) {
401 logger.error("Failed to write errors to operational datastore", e);
406 * Removes Ccaps if all Ccap instances are removed
408 private class CcapsCleaner extends AbstractCleaner<Ccaps> {
410 public CcapsCleaner(final InstanceIdentifier<?> removedIID) {
411 super(removedIID, Ccaps.class, LogicalDatastoreType.OPERATIONAL);
415 protected boolean shouldClean(final Ccaps ccaps) {
416 return ccaps.getCcap().isEmpty();
422 * Removes Subscriber if all Gate instances are removed
424 private class SubscriberCleaner extends AbstractCleaner<Subscriber> {
426 public SubscriberCleaner(InstanceIdentifier<Gate> removedGateIID) {
427 super(removedGateIID, Subscriber.class, LogicalDatastoreType.OPERATIONAL);
431 protected boolean shouldClean(final Subscriber subscriber) {
432 return subscriber.getGates().getGate().isEmpty();
436 protected void postRemove(InstanceIdentifier<Subscriber> subscriberIID) {
437 executor.execute(new AppCleaner(subscriberIID));
443 * Removes App if all Subscribers are removed.
445 private class AppCleaner extends AbstractCleaner<App> {
447 public AppCleaner(InstanceIdentifier<Subscriber> removedSubscriberIID) {
448 super(removedSubscriberIID, App.class, LogicalDatastoreType.OPERATIONAL);
452 boolean shouldClean(final App app) {
453 return app.getSubscribers().getSubscriber().isEmpty();
457 void postRemove(final InstanceIdentifier<App> appIID) {
458 //unregister app rpc path
459 logger.info("Un-Registering App Routed RPC Path...");
460 routedRpcRegistration.unregisterPath(AppContext.class, appIID);
461 executor.execute(new AppsCleaner(appIID));
467 * Removes Apps if all App instances are removed.
469 private class AppsCleaner extends AbstractCleaner<Apps> {
471 public AppsCleaner(InstanceIdentifier<App> removedAppIID) {
472 super(removedAppIID, Apps.class, LogicalDatastoreType.OPERATIONAL);
476 protected boolean shouldClean(final Apps apps) {
477 return apps.getApp().isEmpty();
483 * Helper class to do the heavy lifting in removing object. Lets subclasses decide with
484 * {@link #shouldClean(DataObject)}. <br>
486 * Subclasses can react after an instance is removed by overriding {@link #postRemove(InstanceIdentifier)}
489 * The type that will be removed
491 private abstract class AbstractCleaner<T extends DataObject> implements Runnable {
492 final InstanceIdentifier<?> removedIID;
493 final Class<T> tClass;
494 final LogicalDatastoreType datastoreType;
496 public AbstractCleaner(InstanceIdentifier<?> removedIID, Class<T> tClass, LogicalDatastoreType datastoreType) {
497 this.removedIID = checkNotNull(removedIID);
498 this.tClass = checkNotNull(tClass);
499 this.datastoreType = checkNotNull(datastoreType);
504 InstanceIdentifier<T> tIID = removedIID.firstIdentifierOf(tClass);
506 Optional<T> optional = mdsalUtils.read(datastoreType, tIID);
507 if (optional.isPresent()) {
509 if (shouldClean(optional.get())) {
510 if (mdsalUtils.delete(datastoreType, tIID)) {
519 logger.error("Expected to find InstanceIdentifier<{}> but was not found: {}", tClass.getSimpleName(),
525 * If returns true the object will be removed from the datastore
528 * The object that might be removed.
529 * @return true if it should be removed.
531 abstract boolean shouldClean(final T object);
534 * Called after an instance is removed.
537 * the InstanceIdentifier of the removed object
539 void postRemove(InstanceIdentifier<T> tIID) {
543 void removeFailed(InstanceIdentifier<T> tIID) {
544 logger.error("Failed to remove {}", tIID);
550 * Listener for the packetcable:ccaps tree
552 private class CcapsDataTreeChangeListener extends AbstractDataTreeChangeListener<Ccap> {
554 private final Set<InstanceIdentifier<Ccap>> updateQueue = Sets.newConcurrentHashSet();
556 public CcapsDataTreeChangeListener() {
557 super(Ccap.class,new DataValidator(new CcapsValidatorProviderFactory().build()));
561 protected void handleCreatedData(final DataTreeModification<Ccap> change) {
562 final Ccap ccap = change.getRootNode().getDataAfter();
563 InstanceIdentifier<Ccap> iid = change.getRootPath().getRootIdentifier();
566 if (pcmmServiceMap.containsKey(ccap.getCcapId())) {
567 logger.error("Already monitoring CCAP - " + ccap);
570 final PCMMService pcmmService = new PCMMService(IPCMMClient.CLIENT_TYPE, ccap);
571 // TODO - may want to use the AMID but for the client type but probably not???
573 final PCMMService pcmmService = new PCMMService(
574 thisCcap.getAmId().getAmType().shortValue(), thisCcap);
576 ConnectionBuilder connectionBuilder = new ConnectionBuilder();
577 String message = pcmmService.addCcap();
578 if (message.contains("200 OK")) {
579 pcmmServiceMap.put(ccap.getCcapId(), pcmmService);
580 ccapMap.put(ccap.getCcapId(), ccap);
581 updateCcapMaps(ccap);
582 logger.info("Created CCAP: {}/{} : {}", iid, ccap, message);
583 logger.info("Created CCAP: {} : {}", iid, message);
585 connectionBuilder.setConnected(true).setError(Collections.<String>emptyList());
587 logger.error("Create CCAP Failed: {} : {}", iid, message);
589 connectionBuilder.setConnected(false).setError(Collections.singletonList(message));
593 logger.info("Registering CCAP Routed RPC Path...");
594 routedRpcRegistration.registerPath(CcapContext.class, iid);
596 Optional<Ccap> optionalCcap = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL, iid);
598 final CcapBuilder responseCcapBuilder;
599 if (optionalCcap.isPresent()) {
600 responseCcapBuilder = new CcapBuilder(optionalCcap.get());
602 responseCcapBuilder = new CcapBuilder();
603 responseCcapBuilder.setCcapId(ccap.getCcapId());
606 responseCcapBuilder.setConnection(connectionBuilder.build());
608 mdsalUtils.put(LogicalDatastoreType.OPERATIONAL, iid, responseCcapBuilder.build());
612 protected void handleUpdatedData(final DataTreeModification<Ccap> change) {
613 InstanceIdentifier<Ccap> iid = change.getRootPath().getRootIdentifier();
615 // If this notification is coming from our modification ignore it.
616 if (updateQueue.contains(iid)) {
617 updateQueue.remove(iid);
621 final Ccap updatedCcap = change.getRootNode().getDataAfter();
624 logger.info("Registering CCAP Routed RPC Path...");
625 routedRpcRegistration.registerPath(CcapContext.class, iid);
627 // restore the original data
628 updateQueue.add(iid);
629 mdsalUtils.put(LogicalDatastoreType.CONFIGURATION, iid, updatedCcap);
633 protected void handleRemovedData(final DataTreeModification<Ccap> change) {
635 InstanceIdentifier<Ccap> iid = change.getRootPath().getRootIdentifier();
636 final Ccap nukedCcap = change.getRootNode().getDataBefore();
637 removeCcapFromAllMaps(nukedCcap);
639 //unregister ccap rpc path
640 logger.info("Un-Registering CCAP Routed RPC Path...");
641 routedRpcRegistration.unregisterPath(CcapContext.class, iid);
643 mdsalUtils.delete(LogicalDatastoreType.OPERATIONAL, iid);
645 // clean up ccaps level if it is now empty
646 executor.execute(new CcapsCleaner(iid));
650 protected void handleInvalidData(final DataTreeModification<Ccap> change, ValidationException validationException){
651 // bad data write errors to operational datastore
652 saveErrors(change, validationException);
657 private class QosDataTreeChangeListener extends AbstractDataTreeChangeListener<Gate> {
659 private final Set<InstanceIdentifier<Gate>> updateQueue = Sets.newConcurrentHashSet();
661 public QosDataTreeChangeListener() {
662 super(Gate.class,new DataValidator(new QosValidatorProviderFactory().build()));
666 protected void handleCreatedData(final DataTreeModification<Gate> change) {
668 InstanceIdentifier<Gate> gateIID = change.getRootPath().getRootIdentifier();
669 final Gate newGate = change.getRootNode().getDataAfter();
671 final String newGatePathStr = makeGatePathString(gateIID);
673 // if a new app comes along add RPC registration
674 final InstanceIdentifier<App> appIID = gateIID.firstIdentifierOf(App.class);
675 // TBD verify if App ID exists first
677 //register appID RPC path
678 logger.info("Registering App Routed RPC Path...");
679 routedRpcRegistration.registerPath(AppContext.class, appIID);
681 final InstanceIdentifier<Subscriber> subscriberIID = gateIID.firstIdentifierOf(Subscriber.class);
682 final SubscriberKey subscriberKey = InstanceIdentifier.keyOf(subscriberIID);
683 final InetAddress subscriberAddr = getInetAddress(subscriberKey.getSubscriberId());
684 if (subscriberAddr == null) {
685 final String msg = String.format("subscriberId must be a valid ipaddress: %s",
686 subscriberKey.getSubscriberId());
688 saveGateError(gateIID, newGatePathStr, msg);
692 final Ccap ccap = findCcapForSubscriberId(subscriberAddr);
694 final String msg = String.format("Unable to find Ccap for subscriber %s: @ %s",
695 subscriberKey.getSubscriberId(), newGatePathStr);
697 saveGateError(gateIID, newGatePathStr, msg);
701 final PCMMService pcmmService = pcmmServiceMap.get(ccap.getCcapId());
702 if (pcmmService == null) {
704 String.format("Unable to locate PCMM Service for CCAP: %s ; with subscriber: %s", ccap,
705 subscriberKey.getSubscriberId());
707 saveGateError(gateIID, newGatePathStr, msg);
712 // set up gate builder with known fields (and some empty ones)
714 final GateBuilder gateBuilder = new GateBuilder();
715 gateBuilder.setGateId(newGate.getGateId())
716 .setGatePath(newGatePathStr)
717 .setCcapId(ccap.getCcapId())
718 .setClassifiers(newGate.getClassifiers())
719 .setGateSpec(newGate.getGateSpec())
720 .setCopsGateState("")
721 .setCopsGateTimeInfo("")
722 .setCopsGateUsageInfo("");
724 ServiceFlowDirection scnDirection = null;
726 if (newGate.getTrafficProfile().getTrafficProfileChoice() instanceof ServiceClassNameChoice) {
727 final ServiceClassName scn =
728 ((ServiceClassNameChoice)newGate.getTrafficProfile()
729 .getTrafficProfileChoice())
730 .getServiceClassNameProfile()
731 .getServiceClassName();
732 scnDirection = findScnOnCcap(scn, ccap);
733 if (scnDirection == null) {
735 String.format("SCN %s not found on CCAP %s for %s", scn, ccap.getCcapId(), newGatePathStr);
737 saveGateError(gateIID, newGatePathStr, msg);
740 ServiceClassNameProfileBuilder scnBuilder = new ServiceClassNameProfileBuilder();
741 scnBuilder.setServiceClassName(scn);
742 ServiceClassNameProfile scnProfile = scnBuilder.build();
743 ServiceClassNameChoiceBuilder scncBuilder = new ServiceClassNameChoiceBuilder();
744 scncBuilder.setServiceClassNameProfile(scnProfile);
745 ServiceClassNameChoice scnChoice = scncBuilder.build();
746 TrafficProfileBuilder trafficProfileBuilder = new TrafficProfileBuilder();
747 trafficProfileBuilder.setTrafficProfileChoice(scnChoice);
748 TrafficProfile trafficProfile = trafficProfileBuilder.build();
749 gateBuilder.setTrafficProfile(trafficProfile);
752 gateBuilder.setTrafficProfile(newGate.getTrafficProfile());
756 // since we may be modifying the contents of the original request GateSpec
757 // to update flow direction (based on the ccap SCN configuration) we need to
758 // rebuild the requested gate spec and replace the existing one in the gate builder
760 final GateSpecBuilder gateSpecBuilder = new GateSpecBuilder();
761 gateSpecBuilder.setDirection(scnDirection);
762 gateSpecBuilder.setDscpTosMask(newGate.getGateSpec().getDscpTosMask());
763 gateSpecBuilder.setDscpTosOverwrite(newGate.getGateSpec().getDscpTosOverwrite());
764 gateSpecBuilder.setSessionClassId(newGate.getGateSpec().getSessionClassId());
765 gateSpecBuilder.setInactivityTimer(newGate.getGateSpec().getInactivityTimer());
766 final GateSpec gateSpec = gateSpecBuilder.build();
767 gateBuilder.setGateSpec(gateSpec);
770 // build the gate to be requested
772 gateBuilder.setTimestamp(getNowTimeStamp());
774 final Gate requestGate = gateBuilder.build();
777 // send gate request to Ccap
779 PCMMService.GateSendStatus status =
780 pcmmService.sendGateSet(newGatePathStr, subscriberAddr, requestGate);
781 if (status.didSucceed()) {
782 gateMap.put(newGatePathStr, requestGate);
783 gateCcapMap.put(newGatePathStr, ccap.getCcapId());
786 // inquire as to the status, and implementation info of the requested gate
788 PCMMService.GateSendStatus infoStatus = pcmmService.sendGateInfo(newGatePathStr);
790 if (infoStatus.didSucceed()) {
792 // update builder with info for operational storage
794 gateBuilder.setCopsGateState(
795 infoStatus.getCopsGateState() + "/" + infoStatus.getCopsGateStateReason())
796 .setCopsGateTimeInfo(infoStatus.getCopsGateTimeInfo())
797 .setCopsGateUsageInfo(infoStatus.getCopsGateUsageInfo())
798 .setCopsGateId(status.getCopsGateId());
800 List<String> errors = new ArrayList<>(2);
802 // Keep GateSetErrors
803 if (gateBuilder.getError() != null) {
804 errors.addAll(gateBuilder.getError());
807 errors.add(infoStatus.getMessage());
808 gateBuilder.setError(errors);
812 gateBuilder.setError(Collections.singletonList(status.getMessage()));
815 Gate operationalGate = gateBuilder.build();
816 mdsalUtils.put(LogicalDatastoreType.OPERATIONAL, gateIID, operationalGate);
819 private void saveGateError(@Nonnull final InstanceIdentifier<Gate> gateIID, @Nonnull final String gatePathStr,
820 @Nonnull final String error) {
821 checkNotNull(gateIID);
824 final GateBuilder gateBuilder = new GateBuilder();
825 gateBuilder.setGateId(InstanceIdentifier.keyOf(gateIID).getGateId())
826 .setGatePath(gatePathStr)
828 .setCopsGateState("N/A");
830 gateBuilder.setError(Collections.singletonList(error));
832 Gate operationalGate = gateBuilder.build();
834 mdsalUtils.put(LogicalDatastoreType.OPERATIONAL, gateIID, operationalGate);
838 protected void handleUpdatedData(final DataTreeModification<Gate> change) {
839 InstanceIdentifier<Gate> gateIID = change.getRootPath().getRootIdentifier();
841 // If this notification is coming from our modification ignore it.
842 if (updateQueue.contains(gateIID)) {
843 updateQueue.remove(gateIID);
847 final Gate updatedGate = change.getRootNode().getDataAfter();
849 // restores the original data
850 updateQueue.add(gateIID);
851 mdsalUtils.put(LogicalDatastoreType.CONFIGURATION, gateIID, updatedGate);
855 protected void handleRemovedData(final DataTreeModification<Gate> change) {
856 InstanceIdentifier<Gate> removedGateIID = change.getRootPath().getRootIdentifier();
857 final Gate newGate = change.getRootNode().getDataBefore();
859 mdsalUtils.delete(LogicalDatastoreType.OPERATIONAL, removedGateIID);
861 executor.execute(new SubscriberCleaner(removedGateIID));
863 final String gatePathStr = makeGatePathString(removedGateIID);
865 if (gateMap.containsKey(gatePathStr)) {
866 final Gate thisGate = gateMap.remove(gatePathStr);
867 final String gateId = thisGate.getGateId();
868 final String ccapId = gateCcapMap.remove(gatePathStr);
869 final Ccap thisCcap = ccapMap.get(ccapId);
870 final PCMMService service = pcmmServiceMap.get(thisCcap.getCcapId());
871 if (service != null) {
872 service.sendGateDelete(gatePathStr);
873 logger.info("onDataChanged(): removed QoS gate {} for {}/{}/{}: ", gateId, ccapId, gatePathStr,thisGate);
875 logger.warn("Unable to send to locate PCMMService to send gate delete message with CCAP - "
883 protected void handleInvalidData(final DataTreeModification<Gate> change, ValidationException validationException){
884 // bad data write errors to operational datastore
885 saveErrors(change, validationException);
888 private String makeGatePathString(InstanceIdentifier<Gate> iid) {
889 final InstanceIdentifier<App> appIID = iid.firstIdentifierOf(App.class);
890 final AppKey appKey = InstanceIdentifier.keyOf(appIID);
892 final InstanceIdentifier<Subscriber> subscriberIID = iid.firstIdentifierOf(Subscriber.class);
893 final SubscriberKey subscriberKey = InstanceIdentifier.keyOf(subscriberIID);
895 final GateKey gateKey = InstanceIdentifier.keyOf(iid);
897 return appKey.getAppId() + "/" + subscriberKey.getSubscriberId() + "/" + gateKey.getGateId();
902 public Future<RpcResult<CcapSetConnectionOutput>> ccapSetConnection(CcapSetConnectionInput input) {
903 // TODO refactor this method into smaller parts
905 InstanceIdentifier<Ccap> ccapIid = (InstanceIdentifier<Ccap>) input.getCcapId();
906 List<String> outputError = new ArrayList<>();
907 String rpcResponse = null;
908 Boolean inputIsConnected = input.getConnection().isConnected();
909 Boolean effectiveIsConnected = null;
910 String ccapId = input.getCcapId().firstIdentifierOf(Ccap.class).firstKeyOf(Ccap.class).getCcapId();
911 PCMMService pcmmService = pcmmServiceMap.get(ccapId);
913 if (!inputIsConnected) {
914 // set connected false
915 if (pcmmService.getPcmmPdpSocket()) {
916 outputError.add(ccapId + ": CCAP COPS socket is already closed");
917 effectiveIsConnected = false;
919 //if (!pcmmService.getPcmmCcapClientIsConnected()) {
920 outputError.add(ccapId + ": CCAP client is disconnected with error: "
921 + pcmmService.getPcmmCcapClientConnectErrMsg());
923 pcmmService.ccapClient.disconnect();
924 effectiveIsConnected = false;
927 // set connected true
928 if (!pcmmService.getPcmmPdpSocket() && pcmmService.getPcmmCcapClientIsConnected()) {
929 outputError.add(ccapId + ": CCAP COPS socket is already open");
930 outputError.add(ccapId + ": CCAP client is connected");
931 effectiveIsConnected = true;
933 if (pcmmService.getPcmmCcapClientIsConnected()) {
934 pcmmService.ccapClient.disconnect();
936 pcmmService.ccapClient.connect();
937 if (pcmmService.getPcmmCcapClientIsConnected()) {
938 effectiveIsConnected = true;
939 outputError.add(ccapId + ": CCAP client is connected");
941 effectiveIsConnected = false;
942 outputError.add(ccapId + ": CCAP client is disconnected with error: "
943 + pcmmService.getPcmmCcapClientConnectErrMsg());
948 DateAndTime connectionDateAndTime = getNowTimeStamp();
949 org.opendaylight.yang.gen.v1.urn.packetcable.rev170224.ccap.set.connection.output.ccap.ConnectionBuilder
950 connectionRpcOutput =
951 new org.opendaylight.yang.gen.v1.urn.packetcable.rev170224.ccap.set.connection.output.ccap.ConnectionBuilder()
952 .setConnected(effectiveIsConnected)
953 .setError(outputError)
954 .setTimestamp(connectionDateAndTime);
956 org.opendaylight.yang.gen.v1.urn.packetcable.rev170224.ccap.set.connection.output.CcapBuilder ccapRpcOutput =
957 new org.opendaylight.yang.gen.v1.urn.packetcable.rev170224.ccap.set.connection.output.CcapBuilder().setCcapId(
958 ccapId).setConnection(connectionRpcOutput.build());
961 ConnectionBuilder connectionOps = new ConnectionBuilder().setConnected(effectiveIsConnected)
962 .setError(outputError)
963 .setTimestamp(connectionDateAndTime);
965 CcapBuilder responseCcapBuilder = new CcapBuilder().setCcapId(ccapId).setConnection(connectionOps.build());
968 mdsalUtils.put(LogicalDatastoreType.OPERATIONAL, ccapIid, responseCcapBuilder.build());
971 DateAndTime rpcDateAndTime = getNowTimeStamp();
972 rpcResponse = ccapId + ": CCAP set complete";
973 CcapSetConnectionOutputBuilder outputBuilder =
974 new CcapSetConnectionOutputBuilder().setCcap(ccapRpcOutput.build())
975 .setResponse(rpcResponse)
976 .setTimestamp(rpcDateAndTime);
978 return Futures.immediateFuture(RpcResultBuilder.success(outputBuilder.build()).build());
984 public Future<RpcResult<CcapPollConnectionOutput>> ccapPollConnection(CcapPollConnectionInput input) {
985 // TODO refactor this method into smaller parts
987 InstanceIdentifier<Ccap> ccapIid = (InstanceIdentifier<Ccap>) input.getCcapId();
988 List<String> outputError = new ArrayList<>();
990 String ccapId = input.getCcapId().firstIdentifierOf(Ccap.class).firstKeyOf(Ccap.class).getCcapId();
991 PCMMService pcmmService = pcmmServiceMap.get(ccapId);
992 Boolean effectiveIsConnected = true;
993 String response = null;
994 org.opendaylight.yang.gen.v1.urn.packetcable.rev170224.ccap.poll.connection.output.ccap.ConnectionBuilder
995 connectionRpcOutput =
996 new org.opendaylight.yang.gen.v1.urn.packetcable.rev170224.ccap.poll.connection.output.ccap.ConnectionBuilder();
998 if (pcmmService != null) {
999 if (pcmmService.getPcmmPdpSocket()) {
1000 outputError.add(ccapId + ": CCAP Cops socket is closed");
1001 if (!pcmmService.getPcmmCcapClientIsConnected()) {
1002 outputError.add(ccapId + ": CCAP client is disconnected with error: "
1003 + pcmmService.getPcmmCcapClientConnectErrMsg());
1005 effectiveIsConnected = false;
1007 //outputError.add(String.format(ccapId+": CCAP Cops socket is open"));
1008 if (!pcmmService.getPcmmCcapClientIsConnected()) {
1009 outputError.add(ccapId + ": CCAP client is disconnected with error: "
1010 + pcmmService.getPcmmCcapClientConnectErrMsg());
1011 effectiveIsConnected = false;
1013 outputError.add(ccapId + ": CCAP client is connected");
1016 DateAndTime connectionDateAndTime = getNowTimeStamp();
1019 ConnectionBuilder connectionOps = new ConnectionBuilder().setConnected(effectiveIsConnected)
1020 .setError(outputError)
1021 .setTimestamp(connectionDateAndTime);
1023 CcapBuilder responseCcapBuilder = new CcapBuilder().setCcapId(ccapId).setConnection(connectionOps.build());
1025 connectionRpcOutput =
1026 new org.opendaylight.yang.gen.v1.urn.packetcable.rev170224.ccap.poll.connection.output.ccap.ConnectionBuilder()
1027 .setConnected(effectiveIsConnected)
1028 .setError(outputError)
1029 .setTimestamp(connectionDateAndTime);
1031 mdsalUtils.put(LogicalDatastoreType.OPERATIONAL, ccapIid, responseCcapBuilder.build());
1032 response = ccapId + ": CCAP poll complete";
1034 //pcmmService is null, do not poll
1035 response = ccapId + ": CCAP connection null; no poll performed";
1038 DateAndTime rpcDateAndTime = getNowTimeStamp();
1040 org.opendaylight.yang.gen.v1.urn.packetcable.rev170224.ccap.poll.connection.output.CcapBuilder ccapRpcOutput =
1041 new org.opendaylight.yang.gen.v1.urn.packetcable.rev170224.ccap.poll.connection.output.CcapBuilder().setCcapId(
1042 ccapId).setConnection(connectionRpcOutput.build());
1044 CcapPollConnectionOutputBuilder outputBuilder =
1045 new CcapPollConnectionOutputBuilder().setCcap(ccapRpcOutput.build())
1046 .setResponse(response)
1047 .setTimestamp(rpcDateAndTime);
1049 return Futures.immediateFuture(RpcResultBuilder.success(outputBuilder.build()).build());
1054 private App readAppFromOperationalDatastore(InstanceIdentifier<App> appIid) {
1055 Optional<App> optionalApp = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL, appIid);
1056 AppBuilder thisAppBuilder = new AppBuilder(optionalApp.get());
1057 App thisApp = thisAppBuilder.build();
1058 logger.info("readAppFromConfigDatastore() retrived App: " + thisApp.getAppId());
1062 private Gate readGateFromOperationalDatastore(InstanceIdentifier<Gate> gateIid) {
1063 Optional<Gate> optionalGate = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL, gateIid);
1064 if (optionalGate.isPresent()) {
1065 GateBuilder gateBuilder = new GateBuilder(optionalGate.get());
1066 Gate thisGate = gateBuilder.build();
1073 private Subscriber readSubscriberFromOperationalDatastore(InstanceIdentifier<Subscriber> subscriberIid) {
1074 Optional<Subscriber> optionalSubscriber = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL, subscriberIid);
1075 if (optionalSubscriber.isPresent()) {
1076 SubscriberBuilder subscriberBuilder = new SubscriberBuilder(optionalSubscriber.get());
1077 Subscriber thisSubscriber = subscriberBuilder.build();
1078 return thisSubscriber;
1087 public Future<RpcResult<QosSetGateOutput>> qosSetGate(QosSetGateInput input) {
1088 logger.debug("RPC call to qosSetGate()");
1090 String inputAppIid = input.getAppId();
1091 String inputSubscriberId = input.getSubscriberId();
1092 org.opendaylight.yang.gen.v1.urn.packetcable.rev170224.qos.set.gate.input.Gates gates = input.getGates();
1093 List<org.opendaylight.yang.gen.v1.urn.packetcable.rev170224.qos.set.gate.input.gates.Gate> gate = gates.getGate();
1094 QosSetGateOutputBuilder outputBuilder = new QosSetGateOutputBuilder();
1096 String inputGateId = gate.get(0).getGateId();
1097 Boolean retryOption = false;
1098 InstanceIdentifier<Gate> gateIID = qosIID.builder()
1100 .child(App.class, new AppKey(inputAppIid))
1101 .child(Subscribers.class)
1102 .child(Subscriber.class, new SubscriberKey(inputSubscriberId))
1104 .child(Gate.class, new GateKey(inputGateId))
1107 Gate newGate = readGateFromOperationalDatastore(gateIID);
1108 final String newGatePathStr = "/" + inputAppIid + "/" + inputSubscriberId + "/" + inputGateId;
1110 final InetAddress subscriberAddr = getInetAddress(inputSubscriberId);
1111 if (subscriberAddr == null) {
1112 final String msg = String.format("SubscriberId must be a valid ipaddress: %s",
1115 SetFailureBuilder fb = new SetFailureBuilder();
1116 final FailureType ft = FailureType.Unsent;
1119 final SetFailure f = fb.build();
1120 outputBuilder.setSetResponseType(f);
1121 return Futures.immediateFuture(RpcResultBuilder.success(outputBuilder.build()).build());
1124 final Ccap ccap = findCcapForSubscriberId(subscriberAddr);
1127 String.format("qosSetGate(): Error finding CCAP for %s", newGatePathStr);
1129 SetFailureBuilder fb = new SetFailureBuilder();
1130 final FailureType ft = FailureType.Unsent;
1133 final SetFailure f = fb.build();
1134 outputBuilder.setSetResponseType(f);
1135 return Futures.immediateFuture(RpcResultBuilder.success(outputBuilder.build()).build());
1138 logger.debug("Mapped {} to {}", inputSubscriberId, ccap.getCcapId());
1140 final PCMMService pcmmService = pcmmServiceMap.get(ccap.getCcapId());
1141 if (pcmmService == null) {
1143 String.format("Unable to locate PCMM Service for CCAP: %s ; with subscriber: %s", ccap, inputSubscriberId);
1145 SetFailureBuilder fb = new SetFailureBuilder();
1146 final FailureType ft = FailureType.Unsent;
1149 final SetFailure f = fb.build();
1150 outputBuilder.setSetResponseType(f);
1151 return Futures.immediateFuture(RpcResultBuilder.success(outputBuilder.build()).build());
1154 final GateBuilder gateBuilder = new GateBuilder();
1155 gateBuilder.setGateId(inputGateId)
1156 .setGatePath(newGatePathStr)
1157 .setCcapId(ccap.getCcapId())
1158 .setCopsGateId(gate.get(0).getCopsGateId())
1159 .setTimestamp(getNowTimeStamp())
1160 .setTimestamp(getNowTimeStamp())
1161 .setGateSpec(gate.get(0).getGateSpec())
1162 .setTrafficProfile(gate.get(0).getTrafficProfile())
1163 .setClassifiers(gate.get(0).getClassifiers());
1165 newGate = gateBuilder.build();
1167 if (gate.get(0).getCopsGateId() != null) {
1171 PCMMService.GateSendStatus status = null;
1172 synchronized (pcmmService) {
1173 logger.info("Sending gate: Path {} inputSubscriberId {} cops-gate-id {}",
1174 newGatePathStr, inputSubscriberId, gate.get(0).getCopsGateId());
1176 status = pcmmService.sendGateSet(newGatePathStr, subscriberAddr, newGate);
1179 if (status.didSucceed()) {
1181 gateMap.put(newGatePathStr, newGate);
1182 gateCcapMap.put(newGatePathStr, ccap.getCcapId());
1183 Long copsGateId = 0L;
1184 SetSuccessfulBuilder sb = new SetSuccessfulBuilder();
1186 if (status.getCopsGateId() != null) {
1187 logger.debug("newGate.getCopsGateId() = {} ", status.getCopsGateId());
1188 copsGateId = Long.decode(status.getCopsGateId());
1189 sb.setCopsGateId(copsGateId);
1190 if (status.getCopsGateId() != null) {
1191 gateBuilder.setCopsGateId(status.getCopsGateId());
1193 if (status.getCopsGateState() != null) {
1194 gateBuilder.setCopsGateState(status.getCopsGateState());
1196 if (status.getCopsGateTimeInfo() != null) {
1197 gateBuilder.setCopsGateTimeInfo(status.getCopsGateTimeInfo());
1199 if (status.getCopsGateUsageInfo() != null) {
1200 gateBuilder.setCopsGateUsageInfo(status.getCopsGateUsageInfo());
1204 mdsalUtils.put(LogicalDatastoreType.OPERATIONAL, gateIID, gateBuilder.build());
1206 final SetSuccessful s = sb.build();
1207 outputBuilder.setSetResponseType(s);
1208 return Futures.immediateFuture(RpcResultBuilder.success(outputBuilder.build()).build());
1211 if (retryOption == true) {
1212 // Try one more time with blank Cops Gate Id in case the gate has timed out unexpectedly
1213 logger.info("qosSetGate error msg: {} reason: {}", status.getMessage(), status.getCopsGateStateReason());
1214 final GateBuilder retryGateBuilder = new GateBuilder();
1215 retryGateBuilder.setGateId(inputGateId)
1216 .setGatePath(newGatePathStr)
1217 .setCcapId(ccap.getCcapId())
1218 .setTimestamp(getNowTimeStamp())
1219 .setTimestamp(getNowTimeStamp())
1220 .setGateSpec(gate.get(0).getGateSpec())
1221 .setTrafficProfile(gate.get(0).getTrafficProfile())
1222 .setClassifiers(gate.get(0).getClassifiers());
1224 newGate = retryGateBuilder.build();
1226 synchronized (pcmmService) {
1227 logger.info("Sending gate: Path {} inputSubscriberId {} with cops-gate-id undefined",
1230 status = pcmmService.sendGateSet(newGatePathStr, subscriberAddr, newGate);
1233 if (status.didSucceed()) {
1235 gateMap.put(newGatePathStr, newGate);
1236 gateCcapMap.put(newGatePathStr, ccap.getCcapId());
1237 Long copsGateId = 0L;
1238 SetSuccessfulBuilder sb = new SetSuccessfulBuilder();
1240 if (status.getCopsGateId() != null) {
1241 logger.debug("newGate.getCopsGateId() = {} ", status.getCopsGateId());
1242 copsGateId = Long.decode(status.getCopsGateId());
1243 sb.setCopsGateId(copsGateId);
1244 if (status.getCopsGateId() != null) {
1245 gateBuilder.setCopsGateId(status.getCopsGateId());
1247 if (status.getCopsGateState() != null) {
1248 gateBuilder.setCopsGateState(status.getCopsGateState());
1250 if (status.getCopsGateTimeInfo() != null) {
1251 gateBuilder.setCopsGateTimeInfo(status.getCopsGateTimeInfo());
1253 if (status.getCopsGateUsageInfo() != null) {
1254 gateBuilder.setCopsGateUsageInfo(status.getCopsGateUsageInfo());
1258 mdsalUtils.put(LogicalDatastoreType.OPERATIONAL, gateIID, gateBuilder.build());
1260 final SetSuccessful s = sb.build();
1261 outputBuilder.setSetResponseType(s);
1262 return Futures.immediateFuture(RpcResultBuilder.success(outputBuilder.build()).build());
1265 SetFailureBuilder fb = new SetFailureBuilder();
1266 final FailureType ft = FailureType.Failed;
1268 fb.setMessage(status.getMessage());
1269 final SetFailure f = fb.build();
1270 outputBuilder.setSetResponseType(f);
1271 logger.error("qosSetGate error msg: {} reason: {}", status.getMessage(), status.getCopsGateStateReason());
1272 return Futures.immediateFuture(RpcResultBuilder.success(outputBuilder.build()).build());
1278 public Future<RpcResult<QosDeleteGateOutput>> qosDeleteGate(QosDeleteGateInput input) {
1279 logger.debug("RPC call to qosDeleteGate()");
1282 String inputAppIid = input.getAppId();
1283 String inputSubscriberId = input.getSubscriberId();
1284 String inputGateId = input.getGateId();
1285 String strGateId = null;
1287 InstanceIdentifier<Gate> gateIID = qosIID.builder()
1289 .child(App.class, new AppKey(inputAppIid))
1290 .child(Subscribers.class)
1291 .child(Subscriber.class, new SubscriberKey(inputSubscriberId))
1293 .child(Gate.class, new GateKey(inputGateId))
1296 Gate newGate = readGateFromOperationalDatastore(gateIID);
1297 QosDeleteGateOutputBuilder outputBuilder = new QosDeleteGateOutputBuilder();
1298 final String newGatePathStr = "/" + inputAppIid + "/" + inputSubscriberId + "/" + inputGateId;
1300 if (newGate != null) {
1301 strGateId = newGate.getCopsGateId();
1302 if (strGateId == null || strGateId.length() == 0 || strGateId.equals("null")){
1304 String.format("qosDeleteGate(): Unknown CopsGateId %s", newGatePathStr);
1306 DeleteFailureBuilder fb = new DeleteFailureBuilder();
1307 final FailureType ft = FailureType.Unsent;
1310 final DeleteFailure f = fb.build();
1311 outputBuilder.setDeleteResponseType(f);
1312 return Futures.immediateFuture(RpcResultBuilder.success(outputBuilder.build()).build());
1315 logger.debug("PacketcableProvider: gateId = {} ", strGateId);
1320 String.format("qosDeleteGate(): Error deleting gate %s", newGatePathStr);
1322 DeleteFailureBuilder fb = new DeleteFailureBuilder();
1323 final FailureType ft = FailureType.Unsent;
1326 final DeleteFailure f = fb.build();
1327 outputBuilder.setDeleteResponseType(f);
1328 return Futures.immediateFuture(RpcResultBuilder.success(outputBuilder.build()).build());
1331 final InetAddress subscriberAddr = getInetAddress(inputSubscriberId);
1332 if (subscriberAddr == null) {
1333 final String msg = String.format("SubscriberId must be a valid ipaddress: %s",
1336 DeleteFailureBuilder fb = new DeleteFailureBuilder();
1337 final FailureType ft = FailureType.Unsent;
1340 final DeleteFailure f = fb.build();
1341 outputBuilder.setDeleteResponseType(f);
1342 return Futures.immediateFuture(RpcResultBuilder.success(outputBuilder.build()).build());
1345 final Ccap ccap = findCcapForSubscriberId(subscriberAddr);
1347 final String msg = String.format("Unable to find Ccap for subscriber %s:",
1350 DeleteFailureBuilder fb = new DeleteFailureBuilder();
1351 final FailureType ft = FailureType.Unsent;
1354 final DeleteFailure f = fb.build();
1355 outputBuilder.setDeleteResponseType(f);
1356 return Futures.immediateFuture(RpcResultBuilder.success(outputBuilder.build()).build());
1359 logger.debug("Mapped {} to {}", inputSubscriberId, ccap.getCcapId());
1361 final PCMMService pcmmService = pcmmServiceMap.get(ccap.getCcapId());
1362 if (pcmmService == null) {
1364 String.format("Unable to locate PCMM Service for CCAP: %s ; with subscriber: %s", ccap, inputSubscriberId);
1366 DeleteFailureBuilder fb = new DeleteFailureBuilder();
1367 final FailureType ft = FailureType.Unsent;
1370 final DeleteFailure f = fb.build();
1371 outputBuilder.setDeleteResponseType(f);
1372 return Futures.immediateFuture(RpcResultBuilder.success(outputBuilder.build()).build());
1375 Boolean status = false;
1376 synchronized (pcmmService) {
1377 status = pcmmService.sendGateDelete(newGatePathStr);
1380 if (status == true) {
1381 Long copsGateId = 0L;
1382 copsGateId = Long.decode(strGateId);
1384 logger.info("qosDeleteGate(): Successfully deleted gate {}", newGatePathStr);
1385 mdsalUtils.delete(LogicalDatastoreType.OPERATIONAL, gateIID);
1386 DeleteSuccessfulBuilder sb = new DeleteSuccessfulBuilder();
1387 sb.setCopsGateId(copsGateId);
1388 final DeleteSuccessful s = sb.build();
1389 outputBuilder.setDeleteResponseType(s);
1390 return Futures.immediateFuture(RpcResultBuilder.success(outputBuilder.build()).build());
1393 final String msg = String.format("qosDeleteGate(): Error deleting gate %s", newGatePathStr);
1395 DeleteFailureBuilder fb = new DeleteFailureBuilder();
1396 final FailureType ft = FailureType.Failed;
1399 final DeleteFailure f = fb.build();
1400 outputBuilder.setDeleteResponseType(f);
1401 return Futures.immediateFuture(RpcResultBuilder.success(outputBuilder.build()).build());
1406 public Future<RpcResult<QosGateInfoOutput>> qosGateInfo(QosGateInfoInput input) {
1407 logger.debug("RPC call to qosGateInfo()");
1409 String inputAppIid = input.getAppId();
1410 String inputSubscriberId = input.getSubscriberId();
1411 String inputGateId = input.getGateId();
1412 QosGateInfoOutputBuilder outputBuilder = new QosGateInfoOutputBuilder();
1413 InstanceIdentifier<Gate> gateIID = qosIID.builder()
1415 .child(App.class, new AppKey(inputAppIid))
1416 .child(Subscribers.class)
1417 .child(Subscriber.class, new SubscriberKey(inputSubscriberId))
1419 .child(Gate.class, new GateKey(inputGateId))
1422 Gate infoGate = readGateFromOperationalDatastore(gateIID);
1423 final String newGatePathStr = "/" + inputAppIid + "/" + inputSubscriberId + "/" + inputGateId;
1425 final InetAddress subscriberAddr = getInetAddress(inputSubscriberId);
1426 if (subscriberAddr == null) {
1427 final String msg = String.format("SubscriberId must be a valid ipaddress: %s",
1430 InfoFailureBuilder fb = new InfoFailureBuilder();
1431 final FailureType ft = FailureType.Unsent;
1434 final InfoFailure f = fb.build();
1435 outputBuilder.setInfoResponseType(f);
1436 return Futures.immediateFuture(RpcResultBuilder.success(outputBuilder.build()).build());
1439 final Ccap ccap = findCcapForSubscriberId(subscriberAddr);
1441 final String msg = String.format("Unable to find Ccap for subscriber %s:",
1444 InfoFailureBuilder fb = new InfoFailureBuilder();
1445 final FailureType ft = FailureType.Unsent;
1448 final InfoFailure f = fb.build();
1449 outputBuilder.setInfoResponseType(f);
1450 return Futures.immediateFuture(RpcResultBuilder.success(outputBuilder.build()).build());
1453 logger.debug("Mapped {} to {}", inputSubscriberId, ccap.getCcapId());
1455 final PCMMService pcmmService = pcmmServiceMap.get(ccap.getCcapId());
1456 if (pcmmService == null) {
1458 String.format("Unable to locate PCMM Service for CCAP: %s ; with subscriber: %s",
1459 ccap, inputSubscriberId);
1461 InfoFailureBuilder fb = new InfoFailureBuilder();
1462 final FailureType ft = FailureType.Unsent;
1465 final InfoFailure f = fb.build();
1466 outputBuilder.setInfoResponseType(f);
1467 return Futures.immediateFuture(RpcResultBuilder.success(outputBuilder.build()).build());
1470 PCMMService.GateSendStatus status = null;
1472 synchronized (pcmmService) {
1473 status = pcmmService.sendGateInfo(newGatePathStr);
1476 if (status.didSucceed()) {
1477 DateAndTime gateDateAndTime = getNowTimeStamp();
1478 List<String> gateOutputError = Collections.emptyList();
1479 gateOutputError = Collections.singletonList(status.getMessage());
1480 GateBuilder gateBuilder = new GateBuilder();
1482 gateBuilder.setGateId(inputGateId)
1483 .setGatePath(newGatePathStr)
1484 .setCcapId(ccap.getCcapId())
1485 .setCopsGateState(status.getCopsGateState() + "/" + status.getCopsGateStateReason())
1486 .setCopsGateTimeInfo(status.getCopsGateTimeInfo())
1487 .setCopsGateUsageInfo(status.getCopsGateUsageInfo())
1488 .setCopsGateId(status.getCopsGateId())
1489 .setError(gateOutputError)
1490 .setTimestamp(gateDateAndTime);
1492 infoGate = gateBuilder.build();
1494 mdsalUtils.put(LogicalDatastoreType.OPERATIONAL, gateIID, infoGate);
1496 org.opendaylight.yang.gen.v1.urn.packetcable.rev170224.qos.gate.info.response.info.response.type.info.successful.gates.GateBuilder responseGateBuilder
1497 = new org.opendaylight.yang.gen.v1.urn.packetcable.rev170224.qos.gate.info.response.info.response.type.info.successful.gates.GateBuilder();
1498 responseGateBuilder.fieldsFrom(infoGate);
1499 responseGateBuilder.setGateId(inputGateId);
1500 responseGateBuilder.setGatePath(newGatePathStr);
1501 org.opendaylight.yang.gen.v1.urn.packetcable.rev170224.qos.gate.info.response.info.response.type.info.successful.gates.Gate responseGate =
1502 responseGateBuilder.build();
1503 List<org.opendaylight.yang.gen.v1.urn.packetcable.rev170224.qos.gate.info.response.info.response.type.info.successful.gates.Gate> responseGateList =
1505 responseGateList.add(responseGate);
1506 org.opendaylight.yang.gen.v1.urn.packetcable.rev170224.qos.gate.info.response.info.response.type.info.successful.GatesBuilder responseGatesBuilder =
1507 new org.opendaylight.yang.gen.v1.urn.packetcable.rev170224.qos.gate.info.response.info.response.type.info.successful.GatesBuilder();
1508 responseGatesBuilder.setGate(responseGateList);
1509 org.opendaylight.yang.gen.v1.urn.packetcable.rev170224.qos.gate.info.response.info.response.type.info.successful.Gates responseGates =
1510 responseGatesBuilder.build();
1512 InfoSuccessfulBuilder sb = new InfoSuccessfulBuilder();
1513 sb.setGates(responseGates);
1514 final InfoSuccessful s = sb.build();
1515 outputBuilder.setInfoResponseType(s);
1516 return Futures.immediateFuture(RpcResultBuilder.success(outputBuilder.build()).build());
1520 String.format("qosGateInfo(): error msg: %s reason: %s", status.getMessage(), status.getCopsGateStateReason());
1522 InfoFailureBuilder fb = new InfoFailureBuilder();
1523 final FailureType ft = FailureType.Failed;
1526 final InfoFailure f = fb.build();
1527 outputBuilder.setInfoResponseType(f);
1528 return Futures.immediateFuture(RpcResultBuilder.success(outputBuilder.build()).build());
1533 public Future<RpcResult<QosPollGatesOutput>> qosPollGates(QosPollGatesInput input) {
1534 // TODO refactor this method into smaller parts
1536 InstanceIdentifier<App> appIid = (InstanceIdentifier<App>) input.getAppId();
1537 //logger.info("qospollgates appIid : "+appIid.toString());
1538 App app = readAppFromOperationalDatastore(appIid);
1539 //logger.info("qospollgates app : "+app.toString());
1540 AppKey appKey = InstanceIdentifier.keyOf(appIid);
1541 String inputSubscriberId = input.getSubscriberId();
1542 String inputGateId = input.getGateId();
1543 List<String> gateOutputError = Collections.emptyList();
1544 String subscriberId = null;
1545 String gateId = null;
1546 String ccapId = null;
1547 String gatePathStr = null;
1548 String opsCopsGateId = null;
1549 Gate opsGate = null;
1551 String rpcResponse = null;
1553 org.opendaylight.yang.gen.v1.urn.packetcable.rev170224.qos.poll.gates.output.GateBuilder gateOutputBuilder =
1554 new org.opendaylight.yang.gen.v1.urn.packetcable.rev170224.qos.poll.gates.output.GateBuilder();
1556 GateBuilder gateBuilder = new GateBuilder();
1558 if (inputSubscriberId != null) {
1559 if (inputGateId != null) {
1560 //Subscriber Id and Gate Id provided, only one gate to be poolled
1562 //generate the gateiid
1563 InstanceIdentifier<Gate> gateIid = appIid.builder()
1564 .child(Subscribers.class)
1565 .child(Subscriber.class, new SubscriberKey(inputSubscriberId))
1567 .child(Gate.class, new GateKey(inputGateId))
1571 opsGate = readGateFromOperationalDatastore(gateIid);
1573 //does the gate exists in the Operational DS?
1574 if (opsGate == null) {
1575 gatePathStr = appKey.getAppId() + "/" + inputSubscriberId + "/" + inputGateId;
1576 rpcResponse = gatePathStr + ": gate does not exist in the system; gate poll not performed";
1578 opsCopsGateId = opsGate.getCopsGateId();
1579 gatePathStr = opsGate.getGatePath();
1581 if (!Objects.equals(opsCopsGateId, "") && !Objects.equals(opsCopsGateId, null)) {
1582 ccapId = findCcapForSubscriberId(getInetAddress(inputSubscriberId)).getCcapId();
1583 PCMMService pcmmService = pcmmServiceMap.get(ccapId);
1584 //is the CCAP socket open?
1585 if (!pcmmService.getPcmmPdpSocket() && pcmmService.getPcmmCcapClientIsConnected()) {
1586 PCMMService.GateSendStatus status = pcmmService.sendGateInfo(gatePathStr);
1587 DateAndTime gateDateAndTime = getNowTimeStamp();
1588 //logger.info("qospollgates Gate Status : GateID/"+status.getCopsGateId());
1589 //logger.info("qospollgates Gate Status : Message/"+status.getMessage());
1590 //logger.info("qospollgates Gate Status : DidSucceed/"+status.didSucceed());
1591 gateOutputError = Collections.singletonList(status.getMessage());
1593 gateOutputBuilder.setGatePath(gatePathStr)
1595 .setCopsGateState(status.getCopsGateState() + "/" + status.getCopsGateStateReason())
1596 .setCopsGateTimeInfo(status.getCopsGateTimeInfo())
1597 .setCopsGateUsageInfo(status.getCopsGateUsageInfo())
1598 .setCopsGateId(status.getCopsGateId())
1599 .setError(gateOutputError)
1600 .setTimestamp(gateDateAndTime);
1602 gateBuilder.setGateId(inputGateId)
1603 .setGatePath(gatePathStr)
1605 .setCopsGateState(status.getCopsGateState() + "/" + status.getCopsGateStateReason())
1606 .setCopsGateTimeInfo(status.getCopsGateTimeInfo())
1607 .setCopsGateUsageInfo(status.getCopsGateUsageInfo())
1608 .setCopsGateId(status.getCopsGateId())
1609 .setError(gateOutputError)
1610 .setTimestamp(gateDateAndTime);
1612 mdsalUtils.put(LogicalDatastoreType.OPERATIONAL, gateIid, gateBuilder.build());
1613 rpcResponse = gatePathStr + ": gate poll complete";
1616 ccapId + ": CCAP socket is down or client disconnected; gate poll not performed";
1619 rpcResponse = gatePathStr + ": gate not active; gate poll not performed";
1623 //inputGateId is null; pool all gates for the subscriber if the sub exists
1625 //generate active subIid
1626 InstanceIdentifier<Subscriber> subIid = appIid.builder()
1627 .child(Subscribers.class)
1628 .child(Subscriber.class, new SubscriberKey(inputSubscriberId))
1630 //does the subscriber provided exists in the Operational Datastore?
1631 Subscriber sub = readSubscriberFromOperationalDatastore(subIid);
1633 //If Subscriber exsits poll all gates for the subscriber
1634 subscriberId = sub.getSubscriberId();
1635 List<Gate> gateList = sub.getGates().getGate();
1636 for (Gate gate : gateList) {
1637 //generate active gateIid
1638 gateId = gate.getGateId();
1639 InstanceIdentifier<Gate> gateIid =
1640 subIid.builder().child(Gates.class).child(Gate.class, new GateKey(gateId)).build();
1642 opsGate = readGateFromOperationalDatastore(gateIid);
1643 opsCopsGateId = opsGate.getCopsGateId();
1644 //generate active gatePathStr
1645 gatePathStr = appKey.getAppId() + "/" + subscriberId + "/" + gateId;
1647 if (!Objects.equals(opsCopsGateId, "") && !Objects.equals(opsCopsGateId, null)) {
1648 ccapId = findCcapForSubscriberId(getInetAddress(subscriberId)).getCcapId();
1649 PCMMService pcmmService = pcmmServiceMap.get(ccapId);
1650 //is the CCAP socket open?
1651 if (!pcmmService.getPcmmPdpSocket() && pcmmService.getPcmmCcapClientIsConnected()) {
1652 PCMMService.GateSendStatus status = pcmmService.sendGateInfo(gatePathStr);
1653 DateAndTime gateDateAndTime = getNowTimeStamp();
1655 gateBuilder.setGateId(gateId)
1656 .setGatePath(gatePathStr)
1659 status.getCopsGateState() + "/" + status.getCopsGateStateReason())
1660 .setCopsGateTimeInfo(status.getCopsGateTimeInfo())
1661 .setCopsGateUsageInfo(status.getCopsGateUsageInfo())
1662 .setCopsGateId(status.getCopsGateId())
1663 .setError(gateOutputError)
1664 .setTimestamp(gateDateAndTime);
1666 mdsalUtils.put(LogicalDatastoreType.OPERATIONAL, gateIid, gateBuilder.build());
1669 "qospollgates: {}: CCAP Cops socket is down or client disconnected; gate poll not performed",
1673 //TODO define what happens if a gate is not active.. is nothing ok?
1674 logger.info("qospollgates: {}: gate not active; gate poll not performed", gatePathStr);
1677 rpcResponse = inputSubscriberId + "/: subscriber subtree poll in progress";
1680 inputSubscriberId + "/: subscriber is not defined in the system, gate poll not performed";
1685 // inputSubId is null
1686 if (inputGateId != null) {
1687 gatePathStr = appKey.getAppId() + "/" + inputSubscriberId + "/" + inputGateId;
1688 rpcResponse = gatePathStr + ": Subscriber ID not provided; gate poll not performed";
1690 //poll all gates for the appId
1691 PollAllGatesForApp pollAllGatesForApp = new PollAllGatesForApp(appIid,app);
1692 Thread t = new Thread(pollAllGatesForApp);
1694 rpcResponse = appKey.getAppId() + "/: gate subtree poll in progress";
1698 DateAndTime rpcDateAndTime = getNowTimeStamp();
1700 QosPollGatesOutputBuilder outputBuilder = new QosPollGatesOutputBuilder().setTimestamp(rpcDateAndTime)
1701 .setResponse(rpcResponse)
1702 .setGate(gateOutputBuilder.build());
1703 return Futures.immediateFuture(RpcResultBuilder.success(outputBuilder.build()).build());
1705 private class PollAllGatesForApp implements Runnable {
1707 private final InstanceIdentifier <App> appIid;
1708 private final App app;
1710 private PollAllGatesForApp (InstanceIdentifier <App> appIid, App app) {
1712 this.appIid = appIid;
1718 org.opendaylight.yang.gen.v1.urn.packetcable.rev170224.qos.poll.gates.output.GateBuilder gateOutputBuilder =
1719 new org.opendaylight.yang.gen.v1.urn.packetcable.rev170224.qos.poll.gates.output.GateBuilder();
1721 GateBuilder gateBuilder = new GateBuilder();
1724 AppKey appKey = InstanceIdentifier.keyOf(appIid);
1726 Subscribers subs = app.getSubscribers();
1727 logger.info("qospollgates subscribers: " + subs.toString());
1729 List<Subscriber> subList = subs.getSubscriber();
1730 logger.info("qospollgates subList: " + subList.toString());
1732 for (Subscriber sub : subList) {
1733 //generate active subIid
1734 String subscriberId = sub.getSubscriberId();
1735 InstanceIdentifier<Subscriber> subIid = appIid.builder()
1736 .child(Subscribers.class)
1737 .child(Subscriber.class, new SubscriberKey(subscriberId))
1740 List<Gate> gateList = sub.getGates().getGate();
1742 for (Gate gate : gateList) {
1743 //logger.info("qospollgates active gate: "+gate);
1745 //generate active gateIid
1746 String gateId = gate.getGateId();
1747 InstanceIdentifier<Gate> gateIid =
1748 subIid.builder().child(Gates.class).child(Gate.class, new GateKey(gateId)).build();
1751 Gate opsGate = readGateFromOperationalDatastore(gateIid);
1752 String opsCopsGateId = opsGate.getCopsGateId();
1753 //generate active gatePathStr
1754 String gatePathStr = appKey.getAppId() + "/" + subscriberId + "/" + gateId;
1756 if (!Objects.equals(opsCopsGateId, "") && !Objects.equals(opsCopsGateId, null)) {
1757 String ccapId = findCcapForSubscriberId(getInetAddress(subscriberId)).getCcapId();
1758 PCMMService pcmmService = pcmmServiceMap.get(ccapId);
1759 //is the CCAP socket open?
1760 if (!pcmmService.getPcmmPdpSocket() && pcmmService.getPcmmCcapClientIsConnected()) {
1761 PCMMService.GateSendStatus status = pcmmService.sendGateInfo(gatePathStr);
1762 DateAndTime gateDateAndTime = getNowTimeStamp();
1763 List<String> gateOutputError = Collections.singletonList(status.getMessage());
1766 gateBuilder.setGateId(gateId)
1767 .setGatePath(gatePathStr)
1770 status.getCopsGateState() + "/" + status.getCopsGateStateReason())
1771 .setCopsGateTimeInfo(status.getCopsGateTimeInfo())
1772 .setCopsGateUsageInfo(status.getCopsGateUsageInfo())
1773 .setCopsGateId(status.getCopsGateId())
1774 .setError(gateOutputError)
1775 .setTimestamp(gateDateAndTime);
1777 mdsalUtils.put(LogicalDatastoreType.OPERATIONAL, gateIid, gateBuilder.build());
1780 "qospollgates: {}: CCAP socket is down or client disconnected; gate poll not performed",
1784 //TODO define what happens if a gate is not active.. is nothing ok
1785 logger.info("qospollgates: {}: gate not active; gate poll not performed", gatePathStr);
1793 private DateAndTime getNowTimeStamp() {
1794 DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSXXX");
1795 return new DateAndTime(dateFormat.format(new Date()));