/* * Copyright (c) 2013 Big Switch Networks, Inc. * * Licensed under the Eclipse Public License, Version 1.0 (the * "License"); you may not use this file except in compliance with the * License. You may obtain a copy of the License at * * http://www.eclipse.org/legal/epl-v10.html * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or * implied. See the License for the specific language governing * permissions and limitations under the License. */ package org.sdnplatform.ovsdb.internal; import java.util.ArrayList; import java.util.Iterator; import java.util.Random; import java.util.Map.Entry; import java.util.Set; import org.jboss.netty.buffer.ChannelBuffer; public class JSONSetCIPMsg extends JSONMsg { private ArrayList<String> ciplist; private OVSDBImpl ovs; private int id; private String setcipstr; private ArrayList<String> existingCIP; private String bridgeuuid; public JSONSetCIPMsg(ArrayList<String> cntrIP, OVSDBImpl ovsdbImpl, int msgId) throws OVSDBBridgeUnknown { this.ciplist = cntrIP; this.ovs = ovsdbImpl; this.id = msgId; this.setcipstr = null; this.existingCIP = new ArrayList<String>(); buildSetCntlIPString(); } private void buildSetCntlIPString() throws OVSDBBridgeUnknown { setcipstr = "{\"method\":\"transact\",\"id\":" + id + ",\"params\":" + "[\"Open_vSwitch\","; buildRowsExistingCIPs(); buildRowsController(); buildRowsBridge(); buildInserts(); buildComment(); } private void buildRowsExistingCIPs() { Iterator<Entry<String, OVSController>> iter = ovs.controller.entrySet() .iterator(); while (iter.hasNext()) { Entry<String, OVSController> e = iter.next(); String uuid = e.getKey(); OVSController c = e.getValue(); String ecip = c.getNew().getTarget(); if (ecip != null) { existingCIP.add(uuid); setcipstr += "{\"rows\":[{\"target\":\""+ ecip +"\"}]," + "\"until\":\"==\",\"where\":[[\"_uuid\",\"==\"," + "[\"uuid\",\""+ uuid +"\"]]],\"timeout\":0,\"op\":" + "\"wait\",\"table\":\"Controller\",\"columns\":" + "[\"target\"]},"; } } } private void buildRowsController() throws OVSDBBridgeUnknown { if (existingCIP.size() == 0) { log.warn("no existing controller-IPs on sw {}", ovs.getDpid()); return; } if (existingCIP.size() > 1) { setcipstr += "{\"rows\":[{\"controller\":[\"set\",["; for (int i=0; i<existingCIP.size(); i++) { setcipstr += "[\"uuid\",\""+ existingCIP.get(i) +"\"]"; if ((i+1) == existingCIP.size()) { setcipstr += "]]}]"; } else { setcipstr += ","; } } } else { setcipstr += "{\"rows\":[{\"controller\":[" + "\"uuid\",\""+ existingCIP.get(0) +"\"]}]"; } bridgeuuid = getOvsbr0Bridgeuuid(); if (bridgeuuid == null) { throw new RuntimeException("ovs.bridge.get("+ bridgeuuid + ")" + " returned Null ub set-controller-ip message"); } setcipstr += ",\"until\":\"==\",\"where\":[[\"_uuid\",\"==\"," + "[\"uuid\",\""+ bridgeuuid +"\"]]]," + "\"timeout\":0,\"op\":\"wait\",\"table\":\"Bridge\",\"columns\":" + "[\"controller\"]},"; } private void buildRowsBridge() { String dbuuid = null; Set<String> dbset = ovs.open_vswitch.keySet(); if (dbset.size() > 1) { log.warn("More than one database in ovs @ dpid {}", ovs.getDpid()); } else if (dbset.size() == 0) { throw new RuntimeException("no OVSDB database Open_vSwitch found"); } dbuuid = dbset.iterator().next(); if (ovs.bridge.size() == 1) { setcipstr += "{\"rows\":[{\"bridges\":[\"uuid\",\"" + bridgeuuid + "\"]}],\"until\":\"==\",\"where\":[[\"_uuid\",\"==\",[\"uuid\"" + ",\""+ dbuuid +"\"]]],\"timeout\":0,\"op\":\"wait\",\"table" + "\":\"Open_vSwitch\",\"columns\":[\"bridges\"]},"; } else { setcipstr += "{\"rows\":[{\"bridges\":[\"set\",["; Iterator<String> iter = ovs.bridge.keySet().iterator(); while (iter.hasNext()) { setcipstr += "[\"uuid\",\"" + iter.next() + "\"]"; if (iter.hasNext()) { setcipstr += ","; } else { setcipstr += "]]}],"; } } setcipstr += "\"until\":\"==\",\"where\":[[\"_uuid\",\"==\"," + "[\"uuid\"" + ",\""+ dbuuid +"\"]]],\"timeout\":0,\"op\":\"wait\",\"table" + "\":\"Open_vSwitch\",\"columns\":[\"bridges\"]},"; } } private void buildInserts() { ArrayList<String> fakerowlist = new ArrayList<String>(); Random rint = new Random(ovs.getDpid()); for (int i=0; i<ciplist.size(); i++) { String fakerow = "row" + String.format("%8x", rint.nextInt()) + "_" + String.format("%4x", (short)rint.nextInt()) + "_" + String.format("%4x", (short)rint.nextInt()) + "_" + String.format("%4x", (short)rint.nextInt()) + "_" + String.format("%8x", rint.nextInt()) + String.format("%4x", (short)rint.nextInt()); fakerow = fakerow.replace(' ', 'd'); setcipstr += "{\"uuid-name\":\""+ fakerow +"\",\"op\":\"insert\"" + ",\"table\":\"Controller\",\"row\":{\"target\":" + "\""+ ciplist.get(i) +"\"}},"; fakerowlist.add(fakerow); } // insert where setcipstr += "{\"where\":[[\"_uuid\",\"==\",[\"uuid\",\""+ bridgeuuid + "\"]]],\"op\":\"update\",\"table\":\"Bridge\"," + "\"row\":{\"controller\":"; if (fakerowlist.size() == 1) { setcipstr += "[\"named-uuid\",\""+ fakerowlist.get(0) +"\"]}},"; } else { setcipstr += "[\"set\",["; for (int k=0; k<fakerowlist.size(); k++) { setcipstr += "[\"named-uuid\",\""+ fakerowlist.get(k) +"\"]"; if (k+1 == fakerowlist.size()) { setcipstr += "]]}},"; } else { setcipstr += ","; } } } } private void buildComment() { setcipstr += "{\"comment\":\"ovs-vsctl: ovs-vsctl --no-wait " + "set-controller ovs-br0 tcp:192.168." + "200.199\",\"op\":\"comment\"}]}"; } private String getOvsbr0Bridgeuuid() throws OVSDBBridgeUnknown { Iterator<Entry<String, OVSBridge>> iter = ovs.bridge.entrySet() .iterator(); while (iter.hasNext()) { Entry<String, OVSBridge> e = iter.next(); String bruuid = e.getKey(); OVSBridge br = e.getValue(); if (br.getNew().getName().equals("ovs-br0")) { return bruuid; } } return null; } @Override public void writeTo(ChannelBuffer buf) { if (log.isDebugEnabled()) { log.debug("sent set-cntl-IP message to sw@: {} MSG: {} ", ovs.getHexDpid(), setcipstr); } buf.writeBytes(setcipstr.getBytes()); } @Override public int getLengthU() { return setcipstr.length(); } }