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