import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
+import java.util.Timer;
+import java.util.TimerTask;
+import java.util.concurrent.TimeUnit;
+
import javax.annotation.concurrent.GuardedBy;
import org.opendaylight.controller.config.yang.pcep.topology.provider.ListenerStateRuntimeMXBean;
import org.opendaylight.controller.config.yang.pcep.topology.provider.ListenerStateRuntimeRegistration;
import org.opendaylight.protocol.pcep.PCEPSessionListener;
import org.opendaylight.protocol.pcep.PCEPTerminationReason;
import org.opendaylight.protocol.pcep.TerminationReason;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpAddressBuilder;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddressBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.Message;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.MessageHeader;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.Object;
private boolean synced = false;
private PCEPSession session;
private SyncOptimization syncOptimization;
+ private boolean triggeredResyncInProcess;
private ListenerStateRuntimeRegistration registration;
private final SessionListenerState listenerState;
updatePccNode(ctx, new PathComputationClientBuilder().setStateSync(pccSyncState).build());
if (pccSyncState != PccSyncState.Synchronized) {
this.synced = false;
+ this.triggeredResyncInProcess = true;
}
// All set, commit the modifications
Futures.addCallback(ctx.trans.submit(), new FutureCallback<Void>() {
});
}
+ protected boolean isTriggeredSyncInProcess() {
+ return this.triggeredResyncInProcess;
+ }
+
@GuardedBy("this")
private void tearDown(final PCEPSession session) {
this.serverSessionManager.releaseNodeState(this.nodeState, session, isLspDbPersisted());
if (onMessage(ctx, message)) {
LOG.info("Unhandled message {} on session {}", message, session);
+ //cancel not supported, submit empty transaction
+ ctx.trans.submit();
return;
}
this.listenerState.updateStatefulSentMsg(message);
final PCEPRequest req = new PCEPRequest(metadata);
this.requests.put(requestId, req);
+ final int rpcTimeout = serverSessionManager.getRpcTimeout();
+ LOG.trace("RPC response timeout value is {} seconds", rpcTimeout);
+ if (rpcTimeout > 0) {
+ setupTimeoutHandler(requestId, req, rpcTimeout);
+ }
f.addListener(new FutureListener<Void>() {
@Override
return req.getFuture();
}
+ private void setupTimeoutHandler(final S requestId, final PCEPRequest req, final int timeout) {
+ final Timer timer = req.getTimer();
+ timer.schedule(new TimerTask() {
+ @Override
+ public void run() {
+ synchronized (AbstractTopologySessionListener.this) {
+ AbstractTopologySessionListener.this.requests.remove(requestId);
+ }
+ req.done();
+ LOG.info("Request {} timed-out waiting for response", requestId);
+ }
+ }, TimeUnit.SECONDS.toMillis(timeout));
+ LOG.trace("Set up response timeout handler for request {}", requestId);
+ }
+
/**
* Update an LSP in the data store
*
// just one path should be reported
Preconditions.checkState(rlb.getPath().size() == 1);
final org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.rsvp.rev150820.LspId reportedLspId = rlb.getPath().get(0).getLspId();
- // check previous report for existing paths
- final List<Path> updatedPaths = new ArrayList<>(previous.getPath());
- LOG.debug("Found previous paths {} to this lsp name {}", updatedPaths, name);
- for (final Path path : previous.getPath()) {
- //we found reported path in previous reports
- if (path.getLspId().getValue() == 0 || path.getLspId().equals(reportedLspId)) {
- LOG.debug("Match on lsp-id {}", path.getLspId().getValue() );
- // path that was reported previously and does have the same lsp-id, path will be updated
- final boolean r = updatedPaths.remove(path);
- LOG.trace("Request removed? {}", r);
+ final List<Path> updatedPaths;
+ //lspId = 0 and remove = false -> tunnel is down, still exists but no path is signaled
+ //remove existing tunnel's paths now, as explicit path remove will not come
+ if (!remove && reportedLspId.getValue() == 0) {
+ updatedPaths = new ArrayList<>();
+ LOG.debug("Remove previous paths {} to this lsp name {}", previous.getPath(), name);
+ } else {
+ // check previous report for existing paths
+ updatedPaths = new ArrayList<>(previous.getPath());
+ LOG.debug("Found previous paths {} to this lsp name {}", updatedPaths, name);
+ for (final Path path : previous.getPath()) {
+ //we found reported path in previous reports
+ if (path.getLspId().getValue() == 0 || path.getLspId().equals(reportedLspId)) {
+ LOG.debug("Match on lsp-id {}", path.getLspId().getValue() );
+ // path that was reported previously and does have the same lsp-id, path will be updated
+ final boolean r = updatedPaths.remove(path);
+ LOG.trace("Request removed? {}", r);
+ }
}
}
// if the path does not exist in previous report, add it to path list, it's a new ERO
// Update synchronization flag
this.synced = true;
+ if(this.triggeredResyncInProcess) {
+ this.triggeredResyncInProcess = false;
+ }
updatePccNode(ctx, new PathComputationClientBuilder().setStateSync(PccSyncState.Synchronized).build());
// The node has completed synchronization, cleanup metadata no longer reported back
return this.pccIdentifier.child(ReportedLsp.class, new ReportedLspKey(name));
}
- protected final InstanceIdentifier<PathComputationClient> getPccIdentifier() {
- return this.pccIdentifier;
- }
-
/**
* Remove LSP from the database.
*