001package voyeur;
002/*-
003 * ##########################################################################
004 * Local Area Network Voyeur
005 * %%
006 * Copyright (C) 2019 - 2022 Allen D. Ball
007 * %%
008 * Licensed under the Apache License, Version 2.0 (the "License");
009 * you may not use this file except in compliance with the License.
010 * You may obtain a copy of the License at
011 *
012 *      http://www.apache.org/licenses/LICENSE-2.0
013 *
014 * Unless required by applicable law or agreed to in writing, software
015 * distributed under the License is distributed on an "AS IS" BASIS,
016 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
017 * See the License for the specific language governing permissions and
018 * limitations under the License.
019 * ##########################################################################
020 */
021import java.net.NetworkInterface;
022import java.util.Collections;
023import java.util.Comparator;
024import java.util.concurrent.ConcurrentSkipListSet;
025import lombok.extern.log4j.Log4j2;
026import org.springframework.boot.context.event.ApplicationReadyEvent;
027import org.springframework.context.event.EventListener;
028import org.springframework.scheduling.annotation.Scheduled;
029import org.springframework.stereotype.Service;
030
031/**
032 * Network interface {@link java.util.Set} and {@link Service}.
033 *
034 * @author {@link.uri mailto:ball@hcf.dev Allen D. Ball}
035 */
036@Service
037@Log4j2
038public class NetworkInterfaces extends ConcurrentSkipListSet<NetworkInterface> {
039    private static final long serialVersionUID = -7886800390686536953L;
040
041    private static final Comparator<NetworkInterface> COMPARATOR =
042        Comparator
043        .<NetworkInterface>comparingInt(t -> isLoopback(t) ? -1 : 1)
044        .thenComparing(t -> t.getName().replaceAll("[\\p{Digit}]", ""))
045        .thenComparingInt(t -> t.getIndex());
046
047    private static boolean isLoopback(NetworkInterface ni) {
048        var isLoopback = false;
049
050        try {
051            isLoopback = ni.isLoopback();
052        } catch (Exception exception) {
053        }
054
055        return isLoopback;
056    }
057
058    /**
059     * Sole constructor.
060     */
061    public NetworkInterfaces() { super(COMPARATOR); }
062
063    @EventListener(ApplicationReadyEvent.class)
064    @Scheduled(fixedDelay = 60 * 1000)
065    public void update() throws Exception {
066        var list = Collections.list(NetworkInterface.getNetworkInterfaces());
067
068        addAll(list);
069        retainAll(list);
070    }
071}