@Override public void run() { try { JSONStringer js = new JSONStringer(); js.object(); js.key("role").value(m_config.m_replicationRole.ordinal()); js.key("active").value(m_rvdb.getReplicationActive()); js.endObject(); ZooKeeper zk = m_rvdb.getHostMessenger().getZK(); // rejoining nodes figure out the replication role from other nodes if (!m_isRejoin) { try { zk.create( VoltZK.replicationconfig, js.toString().getBytes("UTF-8"), Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT); } catch (KeeperException.NodeExistsException e) { } String discoveredReplicationConfig = new String(zk.getData(VoltZK.replicationconfig, false, null), "UTF-8"); JSONObject discoveredjsObj = new JSONObject(discoveredReplicationConfig); ReplicationRole discoveredRole = ReplicationRole.get((byte) discoveredjsObj.getLong("role")); if (!discoveredRole.equals(m_config.m_replicationRole)) { VoltDB.crashGlobalVoltDB( "Discovered replication role " + discoveredRole + " doesn't match locally specified replication role " + m_config.m_replicationRole, true, null); } // See if we should bring the server up in WAN replication mode m_rvdb.setReplicationRole(discoveredRole); } else { String discoveredReplicationConfig = new String(zk.getData(VoltZK.replicationconfig, false, null), "UTF-8"); JSONObject discoveredjsObj = new JSONObject(discoveredReplicationConfig); ReplicationRole discoveredRole = ReplicationRole.get((byte) discoveredjsObj.getLong("role")); boolean replicationActive = discoveredjsObj.getBoolean("active"); // See if we should bring the server up in WAN replication mode m_rvdb.setReplicationRole(discoveredRole); m_rvdb.setReplicationActive(replicationActive); } } catch (Exception e) { VoltDB.crashGlobalVoltDB("Error discovering replication role", false, e); } }
@Override public void run() { // if I'm the leader, send out the catalog if (m_rvdb.m_myHostId == m_rvdb.m_hostIdWithStartupCatalog) { try { // If no catalog was supplied provide an empty one. if (m_rvdb.m_pathToStartupCatalog == null) { try { File emptyJarFile = CatalogUtil.createTemporaryEmptyCatalogJarFile(); if (emptyJarFile == null) { VoltDB.crashLocalVoltDB("Failed to generate empty catalog."); } m_rvdb.m_pathToStartupCatalog = emptyJarFile.getAbsolutePath(); } catch (IOException e) { VoltDB.crashLocalVoltDB( "I/O exception while creating empty catalog jar file.", false, e); } } // Get the catalog bytes and byte count. byte[] catalogBytes = readCatalog(m_rvdb.m_pathToStartupCatalog); // Export needs a cluster global unique id for the initial catalog version long catalogUniqueId = UniqueIdGenerator.makeIdFromComponents( System.currentTimeMillis(), 0, MpInitiator.MP_INIT_PID); hostLog.debug(String.format("Sending %d catalog bytes", catalogBytes.length)); long catalogTxnId; catalogTxnId = TxnEgo.makeZero(MpInitiator.MP_INIT_PID).getTxnId(); // Need to get the deployment bytes from the starter catalog context byte[] deploymentBytes = m_rvdb.getCatalogContext().getDeploymentBytes(); // publish the catalog bytes to ZK CatalogUtil.updateCatalogToZK( m_rvdb.getHostMessenger().getZK(), 0, catalogTxnId, catalogUniqueId, catalogBytes, deploymentBytes); } catch (IOException e) { VoltDB.crashGlobalVoltDB("Unable to distribute catalog.", false, e); } catch (org.apache.zookeeper_voltpatches.KeeperException e) { VoltDB.crashGlobalVoltDB("Unable to publish catalog.", false, e); } catch (InterruptedException e) { VoltDB.crashGlobalVoltDB("Interrupted while publishing catalog.", false, e); } } }
/** * Create the completion node for the snapshot identified by the txnId. It assumes that all hosts * will race to call this, so it doesn't fail if the node already exists. * * @param nonce Nonce of the snapshot * @param txnId * @param hostId The local host ID * @param isTruncation Whether or not this is a truncation snapshot * @param truncReqId Optional unique ID fed back to the monitor for identification * @return true if the node is created successfully, false if the node already exists. */ public static ZKUtil.StringCallback createSnapshotCompletionNode( String path, String nonce, long txnId, boolean isTruncation, String truncReqId) { if (!(txnId > 0)) { VoltDB.crashGlobalVoltDB("Txnid must be greather than 0", true, null); } byte nodeBytes[] = null; try { JSONStringer stringer = new JSONStringer(); stringer.object(); stringer.key("txnId").value(txnId); stringer.key("isTruncation").value(isTruncation); stringer.key("didSucceed").value(false); stringer.key("hostCount").value(-1); stringer.key("path").value(path); stringer.key("nonce").value(nonce); stringer.key("truncReqId").value(truncReqId); stringer.key("exportSequenceNumbers").object().endObject(); stringer.endObject(); JSONObject jsonObj = new JSONObject(stringer.toString()); nodeBytes = jsonObj.toString(4).getBytes(Charsets.UTF_8); } catch (Exception e) { VoltDB.crashLocalVoltDB("Error serializing snapshot completion node JSON", true, e); } ZKUtil.StringCallback cb = new ZKUtil.StringCallback(); final String snapshotPath = VoltZK.completed_snapshots + "/" + txnId; VoltDB.instance() .getHostMessenger() .getZK() .create(snapshotPath, nodeBytes, Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT, cb, null); return cb; }
@Override public void run() { // If running commercial code (of value) and not rejoining, enforce licensing. // Make the leader the only license enforcer. boolean isLeader = (m_rvdb.m_myHostId == 0); if (m_config.m_isEnterprise && isLeader && !m_isRejoin) { if (!MiscUtils.validateLicense( m_rvdb.getLicenseApi(), m_deployment.getCluster().getHostcount(), m_rvdb.getReplicationRole())) { // validateLicense logs. Exit call is here for testability. VoltDB.crashGlobalVoltDB("VoltDB license constraints are not met.", false, null); } } }