Skip to content

Commit

Permalink
Implement the MAC address guessing service
Browse files Browse the repository at this point in the history
- Retrieve all current network interfaces, remove virtual and loopback address, then pick the first one
- Fix some bracket () so intellij will shutup
  • Loading branch information
fangwu-septeni committed Nov 13, 2017
1 parent 7140d60 commit 413e446
Show file tree
Hide file tree
Showing 4 changed files with 32 additions and 13 deletions.
Expand Up @@ -17,8 +17,8 @@ package com.septech.snowflake4s

trait MachineIdentifier {

def getId(): String
def getId: String

def getWorkerId(): String
def getWorkerId: String

}
Expand Up @@ -61,8 +61,8 @@ private[snowflake4s] class Snowflake @Inject()(identifier: MachineIdentifier) ex
final private val sequenceMask: Long = -1L ^ (-1L << sequenceBits)
final private var lastTimestamp: Long = -1L

final private val MACHINE_ID: Long = identifier.getId().toLong
final private val WORKER_ID: Long = identifier.getWorkerId().toLong
final private val MACHINE_ID: Long = identifier.getId.toLong
final private val WORKER_ID: Long = identifier.getWorkerId.toLong

override def generate(): String = bulkGenerate(1).headOption.fold[String](throw new GenerateException)(id => id)

Expand Down
Expand Up @@ -27,21 +27,40 @@ import scala.util.Try

private[snowflake4s] class MachineMACAddress extends MachineIdentifier {

override def getId(): String = Try {
val localNetworkInterface = NetworkInterface.getByInetAddress(InetAddress.getLocalHost)
override def getId: String = Try {
val localNetworkInterface = MachineMACAddress.guessBestInterface

localNetworkInterface
.getHardwareAddress.toList
.map(byte => Integer.parseInt(String.format("%02x", byte.asInstanceOf[Object]), 16))
.foldLeft(0L) { case (acc, item) => acc * 256 + item }
localNetworkInterface.get // NPE here
.getHardwareAddress
.map(byte => byte & 0xFF)
.foldLeft(0L) { (acc, item) => (acc << 8) + item }
.toString
} match {
case Failure(_) => throw new MacAddressException()
case Success(address) => address
}

override def getWorkerId() = {
override def getWorkerId: String = {
ManagementFactory.getRuntimeMXBean.getName.split("@").headOption
.fold(throw new RuntimeException("Can not get process id of application"))(pid => pid)
}
}

private object MachineMACAddress {
import scala.collection.JavaConverters._

def getAvailableInterfaces: Map[String, NetworkInterface] =
NetworkInterface.getNetworkInterfaces.asScala
.foldLeft(Map.empty[String, NetworkInterface]){ (map, intf) =>
if (isValidInterface(intf))
map + ((intf.getName, intf))
else
map
}

def guessBestInterface: Option[NetworkInterface] =
getAvailableInterfaces.headOption.map(_._2)

private def isValidInterface(intf: NetworkInterface): Boolean =
Option(intf.getHardwareAddress).isDefined && intf.isUp && !intf.isVirtual
}
Expand Up @@ -6,11 +6,11 @@ private[snowflake4s] class MaskConfig extends MachineIdentifier {
private val defaultMachineId: Long = 1L
private val defaultWorkerId: Long = 1L

override def getId(): String = {
override def getId: String = {
Option(System.getProperty("snowflake4s.twitter.machine_id")).getOrElse(defaultMachineId.toString)
}

def getWorkerId(): String = {
def getWorkerId: String = {
Option(System.getProperty("snowflake4s.twitter.worker_id")).getOrElse(defaultWorkerId.toString)
}

Expand Down

0 comments on commit 413e446

Please sign in to comment.