Skip to content
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

Draft
wants to merge 4 commits into
base: master
Choose a base branch
from

Conversation

kishorevenki
Copy link

  • 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
@terrypacker
Copy link

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.

Comment on lines 46 to 47
this.broadcastAddress = IpNetworkUtils.getLocalBroadcastAddressString(localBindAddress);
this.subnetMask = IpNetworkUtils.getSubnetMask(localBindAddress);
Copy link

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);
}

Copy link
Author

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();

Copy link

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.

Copy link

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);
Copy link

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)

Copy link
Author

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);
Copy link

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)

Copy link
Author

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);
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove System.out logging

Comment on lines 60 to 63
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()));
Copy link

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

Copy link

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.

Copy link
Author

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.

Comment on lines 71 to 74
}catch (final Exception e) {
// Should never happen, so just wrap in a RuntimeException
throw new RuntimeException(e);
}
Copy link

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.

Comment on lines 101 to 103
Exception exception = assertThrows(RuntimeException.class,() -> {
final IpNetworkBuilder builder = new IpNetworkBuilder().withLocalBindAddress(IPAddress);
});
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Formatting

Comment on lines 46 to 47
this.broadcastAddress = IpNetworkUtils.getLocalBroadcastAddressString(localBindAddress);
this.subnetMask = IpNetworkUtils.getSubnetMask(localBindAddress);
Copy link

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.

@jazdw
Copy link

jazdw commented Jan 16, 2025

@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
@kishorevenki kishorevenki requested a review from jazdw January 21, 2025 14:10
Copy link

@jazdw jazdw left a 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
Comment on lines 51 to 52
<source>21</source>
<target>21</target>
Copy link

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).

Comment on lines 46 to 47
this.broadcastAddress = IpNetworkUtils.getLocalBroadcastAddressString(localBindAddress);
this.subnetMask = IpNetworkUtils.getSubnetMask(localBindAddress);
Copy link

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.

Comment on lines 181 to 194
/**
* 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
*/
Copy link

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()));
Copy link

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()));
Copy link

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.

Copy link

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,
Copy link

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);
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove System.out logging

fix - test failure in IpNetworkBuilderTest.java
improvement in comments
incoporate review comments
@kishorevenki kishorevenki requested a review from jazdw January 30, 2025 17:07
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants