+ public void onHandshakeFailure() {
+ LOG.info("OF handshake failed, doing cleanup.");
+ close();
+ }
+
+ /**
+ * used by tests
+ *
+ * @param featureOutput
+ * @param negotiatedVersion
+ */
+ protected void postHandshakeBasic(GetFeaturesOutput featureOutput,
+ Short negotiatedVersion) {
+ version = negotiatedVersion;
+ if (version == OFConstants.OFP_VERSION_1_0) {
+ // Because the GetFeaturesOutput contains information about the port
+ // in OF1.0 (that we would otherwise get from the PortDesc) we have
+ // to pass
+ // it up for parsing to convert into a NodeConnectorUpdate
+ //
+ // BUG-1988 - this must be the first item in queue in order not to
+ // get behind link-up message
+ enqueueMessage(featureOutput);
+ }
+
+ OFSessionUtil.registerSession(this, featureOutput, negotiatedVersion);
+ hsPool.shutdown();
+ hsPool.purge();
+ conductorState = CONDUCTOR_STATE.WORKING;
+ QueueKeeperFactory.plugQueue(queueProcessor, queue);
+ }
+
+ /*
+ * Send an OFPMP_DESC request message to the switch
+ */
+ private void requestDesc() {
+ MultipartRequestInputBuilder builder = new MultipartRequestInputBuilder();
+ builder.setType(MultipartType.OFPMPDESC);
+ builder.setVersion(getVersion());
+ builder.setFlags(new MultipartRequestFlags(false));
+ builder.setMultipartRequestBody(new MultipartRequestDescCaseBuilder()
+ .build());
+ builder.setXid(getSessionContext().getNextXid());
+ getConnectionAdapter().multipartRequest(builder.build());
+ }
+
+ private void requestPorts() {
+ MultipartRequestInputBuilder builder = new MultipartRequestInputBuilder();
+ builder.setType(MultipartType.OFPMPPORTDESC);
+ builder.setVersion(getVersion());
+ builder.setFlags(new MultipartRequestFlags(false));
+ builder.setMultipartRequestBody(new MultipartRequestPortDescCaseBuilder()
+ .build());
+ builder.setXid(getSessionContext().getNextXid());
+ getConnectionAdapter().multipartRequest(builder.build());
+ }
+
+ private void requestGroupFeatures() {
+ MultipartRequestInputBuilder mprInput = new MultipartRequestInputBuilder();
+ mprInput.setType(MultipartType.OFPMPGROUPFEATURES);
+ mprInput.setVersion(getVersion());
+ mprInput.setFlags(new MultipartRequestFlags(false));
+ mprInput.setXid(getSessionContext().getNextXid());
+
+ MultipartRequestGroupFeaturesCaseBuilder mprGroupFeaturesBuild = new MultipartRequestGroupFeaturesCaseBuilder();
+ mprInput.setMultipartRequestBody(mprGroupFeaturesBuild.build());
+
+ LOG.debug("Send group features statistics request :{}",
+ mprGroupFeaturesBuild);
+ getConnectionAdapter().multipartRequest(mprInput.build());
+
+ }
+
+ private void requestMeterFeatures() {
+ MultipartRequestInputBuilder mprInput = new MultipartRequestInputBuilder();
+ mprInput.setType(MultipartType.OFPMPMETERFEATURES);
+ mprInput.setVersion(getVersion());
+ mprInput.setFlags(new MultipartRequestFlags(false));
+ mprInput.setXid(getSessionContext().getNextXid());
+
+ MultipartRequestMeterFeaturesCaseBuilder mprMeterFeaturesBuild = new MultipartRequestMeterFeaturesCaseBuilder();
+ mprInput.setMultipartRequestBody(mprMeterFeaturesBuild.build());
+
+ LOG.debug("Send meter features statistics request :{}",
+ mprMeterFeaturesBuild);
+ getConnectionAdapter().multipartRequest(mprInput.build());
+
+ }
+
+ /**
+ * @param isBitmapNegotiationEnable the isBitmapNegotiationEnable to set
+ */
+ public void setBitmapNegotiationEnable(boolean isBitmapNegotiationEnable) {
+ this.isBitmapNegotiationEnable = isBitmapNegotiationEnable;
+ }
+
+ @Override
+ public void setId(int conductorId) {
+ this.conductorId = conductorId;
+ }
+
+ @Override
+ public void close() {
+ conductorState = CONDUCTOR_STATE.RIP;
+ if (handshakeContext != null) {
+ try {
+ handshakeContext.close();
+ } catch (Exception e) {
+ LOG.warn("Closing handshake context failed: {}", e.getMessage());
+ LOG.debug("Detail in hanshake context close:", e);
+ }
+ } else {
+ //This condition will occure when Old Helium openflowplugin implementation will be used.
+ shutdownPoolPolitely();
+ }
+ }
+
+ private void shutdownPoolPolitely() {
+ LOG.debug("Terminating handshake pool for node {}", connectionAdapter.getRemoteAddress());
+ hsPool.shutdown();
+ try {
+ hsPool.awaitTermination(1, TimeUnit.SECONDS);
+ } catch (InterruptedException e) {
+ LOG.debug("Error while awaiting termination of pool. Will force shutdown now.");
+ } finally {
+ hsPool.purge();
+ if (!hsPool.isTerminated()) {
+ hsPool.shutdownNow();
+ }
+ LOG.debug("is handshake pool for node {} is terminated : {}",
+ connectionAdapter.getRemoteAddress(), hsPool.isTerminated());
+ }
+ }
+
+ @Override
+ public void setHandshakeContext(HandshakeContext handshakeContext) {
+ this.handshakeContext = handshakeContext;
+ }
+
+ @VisibleForTesting
+ ThreadPoolExecutor getHsPool() {
+ return hsPool;