-
Notifications
You must be signed in to change notification settings - Fork 111
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
MANGO-1817 - fix build methods in IpNetworkBuilder to get the Local IP Address, Broadcast Address and Subnet Mask #109
base: master
Are you sure you want to change the base?
Conversation
kishorevenki
commented
Jan 8, 2025
- MANGO-1817 - fix build methods to get IP Address, Broadcast Address and SubnetMask that are assigned to a NIC
- MANGO-1818 - Deprecate withReuseAddress in IpNetworkBuilder as this flag would be set based on the OS
- MANGO-1832 - Add new method to build the network from the interface name in IpNetworkBuilder
- Add Unit Tests for the above feature IpNetworkBuilderTest
- Remove usage withReuseAddress in ahoc/IPMasterTest and adhoc/MultipleLocalDevices
…P address, Broadcast and SubnetMask assigned to the NIC. MANGO-1818 - Deprecate withReuseAddress in IpNetworkBuilder as this flag would be set based on the OS MANGO-1832 - Add new method to build the network from the interface name in IpNetworkBuilder Add Unit Tests for the above feature IpNetworkBuilderTest Remove usage withReuseAddress in ahoc/IPMasterTest and adhoc/MultipleLocalDevices Change BACnet4J revision from 6.0.1-SNAPSHOT to 6.1.0-SNAPSHOT
src/main/java/com/serotonin/bacnet4j/npdu/ip/IpNetworkBuilder.java
Outdated
Show resolved
Hide resolved
Generally formatting and approach looks good, I can't comment on the accuracy of the logic as I would need to dig deeper into this. I'm pushing for integration into our TeamCity CI server so we can get the test checks done on this PR instead of having each of us check it out and run them locally. |
src/main/java/com/serotonin/bacnet4j/npdu/ip/IpNetworkBuilder.java
Outdated
Show resolved
Hide resolved
src/main/java/com/serotonin/bacnet4j/npdu/ip/IpNetworkBuilder.java
Outdated
Show resolved
Hide resolved
this.broadcastAddress = IpNetworkUtils.getLocalBroadcastAddressString(localBindAddress); | ||
this.subnetMask = IpNetworkUtils.getSubnetMask(localBindAddress); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If we are trying not to break existing usages of this code I think it would be wise to check if these fields are already set.
e.g.
if (this.broadcastAddress == null) {
this.broadcastAddress = IpNetworkUtils.getLocalBroadcastAddressString(localBindAddress);
}
if (this.subnetMask == null) {
this.subnetMask = IpNetworkUtils.getSubnetMask(localBindAddress);
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The operating systems would send the broadcast packets to the socket if and only if there is a socket opened for that specific broadcast address and that broadcast address & subnet mask is configured in the NIC. If the user happens to set it incorrectly, handling broadcast would become difficult. The same is applicable for local bind address.
Hence it would be right approach if the BACnet4J is initialized with the right set of network parameters. As per the above comments there are chances that the network could be built with wrong set of parameters. Hence checking of null would not be advisable. Further to avoid any confusion to the end user, building the network with NIC name is created. This method is simple and error free. For example
IpNetwork network = new IpNetworkBuilder().withInterfaceName("LAN1").build();
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
there are chances that the network could be built with wrong set of parameters.
Correct, but we have always provided the opportunity to configure this wrong. I am simply requesting that we maintain existing behavior and no not override properties which were explicitly configured by the programmer.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This has still not been addressed.
@@ -60,7 +60,7 @@ public IpNetworkBuilder withLocalBindAddress(final String localBindAddress) { | |||
public IpNetworkBuilder withBroadcast(final String broadcastAddress, final int networkPrefixLength) { | |||
this.broadcastAddress = broadcastAddress; | |||
this.subnetMask = toIpAddrString(IpNetworkUtils.createMask(networkPrefixLength)); | |||
|
|||
this.localBindAddress = IpNetworkUtils.getIPAddressString(this.broadcastAddress); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Check if localBindAddress
is already set (as per above comment)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same as above said response
@@ -83,7 +83,7 @@ public IpNetworkBuilder withSubnet(final String subnetAddress, final int network | |||
final long subnet = IpNetworkUtils.bytesToLong(BACnetUtils.dottedStringToBytes(subnetAddress)); | |||
|
|||
this.broadcastAddress = toIpAddrString(subnet | negMask); | |||
|
|||
this.localBindAddress = IpNetworkUtils.getIPAddressString(this.broadcastAddress); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Check if localBindAddress
is already set (as per above comment)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same as above said response
assertEquals(IPAddress,builder.getLocalBindAddress()); | ||
assertEquals(interfaceDetails.get(interfaceIndex).get(2), builder.getBroadcastAddress()); | ||
assertEquals(interfaceDetails.get(interfaceIndex).get(3), builder.getSubnetMask()); | ||
System.out.println(IPAddress); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Remove System.out
logging
Random rand = new Random(); | ||
Map<Integer, List<String>> interfaceDetails = IpNetworkUtils.getLocalInterfaceAddresses(); | ||
List<Integer> keys = new ArrayList<>(interfaceDetails.keySet()); | ||
final int interfaceIndex = keys.get(rand.nextInt(keys.size())); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Repeated code between tests, move to a @Before
method
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Am I following this correctly - we are getting a random local interface address? This will make the test very unrepeatable.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The intent of the random is to verify that network can be built on any interface. Assume if there are 4 NIC, this test would choose any NIC randomly and verify the right parameters are set. Otherwise it can be hard-coded as 0 as well.
}catch (final Exception e) { | ||
// Should never happen, so just wrap in a RuntimeException | ||
throw new RuntimeException(e); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just add a throws
declaration to the test method.
Exception exception = assertThrows(RuntimeException.class,() -> { | ||
final IpNetworkBuilder builder = new IpNetworkBuilder().withLocalBindAddress(IPAddress); | ||
}); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Formatting
this.broadcastAddress = IpNetworkUtils.getLocalBroadcastAddressString(localBindAddress); | ||
this.subnetMask = IpNetworkUtils.getSubnetMask(localBindAddress); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
there are chances that the network could be built with wrong set of parameters.
Correct, but we have always provided the opportunity to configure this wrong. I am simply requesting that we maintain existing behavior and no not override properties which were explicitly configured by the programmer.
@kishorevenki you have not addressed the majority of my comments? Do you want to discuss? |
…of List of strings. Improvement - Improve the methods in IpNetworkUtils.java Improvement - Improve the formatting of the comments using HTML List, parameter and return definition Improvement - Improve the build methods in IPMaster.java Improvement - pom.xml - Change the source and target java version to 21 from 1.8 to accommodate record type
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There are still comments which you have not addressed or discussed with me. Thank you for using the record though, it makes it much easier to follow.
pom.xml
Outdated
<source>21</source> | ||
<target>21</target> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We definitely cannot target Java 21, since Mango only requires Java 17. We should discuss which version to target (I would be in favor of using Java 17).
this.broadcastAddress = IpNetworkUtils.getLocalBroadcastAddressString(localBindAddress); | ||
this.subnetMask = IpNetworkUtils.getSubnetMask(localBindAddress); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This has still not been addressed.
/** | ||
* Convenient method to get the deails of Network Interface card | ||
* <p> | ||
* Values of the following parameters of each NIC are stored in record format: | ||
* <ul> | ||
* <li> index (int) - NIC Card Index assigned by the OS | ||
* <li> Name of the NIC (String) | ||
* <li> IP4 Address assigned to the NIC (String) | ||
* <li> Broadcast Address of the NIC (String) | ||
* <li> SubnetMask of the NIC calculated based on the NetworkPrefixLength (String) | ||
* <li> Network Prefix Length of the NIC (int) | ||
* </ul> | ||
* @return the list of records of all NIC available in this device | ||
*/ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A lot of these tags are not closed. Your IDE should be configured to warn about this.
.withBroadcast("255.255.255.255", 24) | ||
Random rand = new Random(); | ||
List<IpNetworkUtils.InterfaceInfo> interfaceDetails = IpNetworkUtils.getLocalInterfaceAddresses(); | ||
final IpNetworkUtils.InterfaceInfo efaceInfo = interfaceDetails.get(rand.nextInt(interfaceDetails.size())); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Using a random real network interface makes this test not repeatable.
@Before public void initialize(){ | ||
Random rand = new Random(); | ||
interfaceDetails = IpNetworkUtils.getLocalInterfaceAddresses(); | ||
efaceInfo = interfaceDetails.get(rand.nextInt(interfaceDetails.size())); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Using a random real network interface makes this test not repeatable.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also, lets not use the name efaceInfo
, variable names should be understandable. Use interfaceInfo
instead.
* <li> Integer format of the Network Prefix Length of the NIC </li> | ||
* </ul> | ||
*/ | ||
public static record InterfaceInfo(int index, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Using static
is redundant for records. Your IDE should warn about this.
Exception exception = assertThrows(RuntimeException.class,() -> { | ||
final IpNetworkBuilder builder = new IpNetworkBuilder().withLocalBindAddress(IPAddress);}); | ||
String actualMsg = exception.getMessage(); | ||
System.out.println(actualMsg); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Remove System.out logging
Quality Gate passedIssues Measures |
fix - test failure in IpNetworkBuilderTest.java improvement in comments incoporate review comments