[gce] File based items are not updated (#13545)
* [gce] Correcting non updated input channels Signed-off-by: clinique <gael@lhopital.org>
This commit is contained in:
parent
61b9e74c95
commit
bdbd5a1ede
|
@ -38,6 +38,4 @@ public class GCEBindingConstants {
|
||||||
public static final String EVENT_SHORT_PRESS = "SHORT_PRESS";
|
public static final String EVENT_SHORT_PRESS = "SHORT_PRESS";
|
||||||
public static final String EVENT_LONG_PRESS = "LONG_PRESS";
|
public static final String EVENT_LONG_PRESS = "LONG_PRESS";
|
||||||
public static final String EVENT_PULSE = "PULSE";
|
public static final String EVENT_PULSE = "PULSE";
|
||||||
|
|
||||||
// Adressable thing
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -110,7 +110,7 @@ public class Ipx800DeviceConnector extends Thread {
|
||||||
/**
|
/**
|
||||||
* Stop the device thread
|
* Stop the device thread
|
||||||
*/
|
*/
|
||||||
public void destroyAndExit() {
|
public void dispose() {
|
||||||
interrupt();
|
interrupt();
|
||||||
disconnect();
|
disconnect();
|
||||||
}
|
}
|
||||||
|
@ -161,7 +161,7 @@ public class Ipx800DeviceConnector extends Thread {
|
||||||
try {
|
try {
|
||||||
Thread.sleep(DEFAULT_RECONNECT_TIMEOUT_MS);
|
Thread.sleep(DEFAULT_RECONNECT_TIMEOUT_MS);
|
||||||
} catch (InterruptedException e) {
|
} catch (InterruptedException e) {
|
||||||
destroyAndExit();
|
dispose();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -29,7 +29,6 @@ import java.util.concurrent.ScheduledFuture;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||||
import org.eclipse.jdt.annotation.Nullable;
|
|
||||||
import org.openhab.binding.gce.internal.action.Ipx800Actions;
|
import org.openhab.binding.gce.internal.action.Ipx800Actions;
|
||||||
import org.openhab.binding.gce.internal.config.AnalogInputConfiguration;
|
import org.openhab.binding.gce.internal.config.AnalogInputConfiguration;
|
||||||
import org.openhab.binding.gce.internal.config.DigitalInputConfiguration;
|
import org.openhab.binding.gce.internal.config.DigitalInputConfiguration;
|
||||||
|
@ -56,7 +55,6 @@ import org.openhab.core.thing.ThingStatusDetail;
|
||||||
import org.openhab.core.thing.binding.BaseThingHandler;
|
import org.openhab.core.thing.binding.BaseThingHandler;
|
||||||
import org.openhab.core.thing.binding.ThingHandlerService;
|
import org.openhab.core.thing.binding.ThingHandlerService;
|
||||||
import org.openhab.core.thing.binding.builder.ChannelBuilder;
|
import org.openhab.core.thing.binding.builder.ChannelBuilder;
|
||||||
import org.openhab.core.thing.binding.builder.ThingBuilder;
|
|
||||||
import org.openhab.core.thing.type.ChannelKind;
|
import org.openhab.core.thing.type.ChannelKind;
|
||||||
import org.openhab.core.thing.type.ChannelTypeUID;
|
import org.openhab.core.thing.type.ChannelTypeUID;
|
||||||
import org.openhab.core.types.Command;
|
import org.openhab.core.types.Command;
|
||||||
|
@ -78,14 +76,11 @@ public class Ipx800v3Handler extends BaseThingHandler implements Ipx800EventList
|
||||||
|
|
||||||
private final Logger logger = LoggerFactory.getLogger(Ipx800v3Handler.class);
|
private final Logger logger = LoggerFactory.getLogger(Ipx800v3Handler.class);
|
||||||
|
|
||||||
private @NonNullByDefault({}) Ipx800Configuration configuration;
|
private Optional<Ipx800DeviceConnector> connector = Optional.empty();
|
||||||
private @NonNullByDefault({}) Ipx800DeviceConnector connector;
|
|
||||||
private @NonNullByDefault({}) StatusFileInterpreter statusFile;
|
|
||||||
|
|
||||||
private Optional<M2MMessageParser> parser = Optional.empty();
|
private Optional<M2MMessageParser> parser = Optional.empty();
|
||||||
private Optional<ScheduledFuture<?>> refreshJob = Optional.empty();
|
private Optional<ScheduledFuture<?>> refreshJob = Optional.empty();
|
||||||
|
|
||||||
private final Map<String, @Nullable PortData> portDatas = new HashMap<>();
|
private final Map<String, PortData> portDatas = new HashMap<>();
|
||||||
|
|
||||||
private class LongPressEvaluator implements Runnable {
|
private class LongPressEvaluator implements Runnable {
|
||||||
private final ZonedDateTime referenceTime;
|
private final ZonedDateTime referenceTime;
|
||||||
|
@ -115,36 +110,37 @@ public class Ipx800v3Handler extends BaseThingHandler implements Ipx800EventList
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void initialize() {
|
public void initialize() {
|
||||||
configuration = getConfigAs(Ipx800Configuration.class);
|
|
||||||
|
|
||||||
logger.debug("Initializing IPX800 handler for uid '{}'", getThing().getUID());
|
logger.debug("Initializing IPX800 handler for uid '{}'", getThing().getUID());
|
||||||
|
|
||||||
statusFile = new StatusFileInterpreter(configuration.hostname, this);
|
Ipx800Configuration config = getConfigAs(Ipx800Configuration.class);
|
||||||
|
StatusFileInterpreter statusFile = new StatusFileInterpreter(config.hostname, this);
|
||||||
|
|
||||||
if (thing.getProperties().isEmpty()) {
|
if (thing.getProperties().isEmpty()) {
|
||||||
discoverAttributes();
|
updateProperties(Map.of(Thing.PROPERTY_VENDOR, "GCE Electronics", Thing.PROPERTY_FIRMWARE_VERSION,
|
||||||
|
statusFile.getElement(StatusEntry.VERSION), Thing.PROPERTY_MAC_ADDRESS,
|
||||||
|
statusFile.getElement(StatusEntry.CONFIG_MAC)));
|
||||||
}
|
}
|
||||||
|
|
||||||
List<Channel> channels = new ArrayList<>(getThing().getChannels());
|
List<Channel> channels = new ArrayList<>(getThing().getChannels());
|
||||||
ThingBuilder thingBuilder = editThing();
|
|
||||||
PortDefinition.asStream().forEach(portDefinition -> {
|
PortDefinition.asStream().forEach(portDefinition -> {
|
||||||
int nbElements = statusFile.getMaxNumberofNodeType(portDefinition);
|
int nbElements = statusFile.getMaxNumberofNodeType(portDefinition);
|
||||||
for (int i = 0; i < nbElements; i++) {
|
for (int i = 0; i < nbElements; i++) {
|
||||||
createChannels(portDefinition, i, channels);
|
ChannelUID portChannelUID = createChannels(portDefinition, i, channels);
|
||||||
|
portDatas.put(portChannelUID.getId(), new PortData());
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
thingBuilder.withChannels(channels);
|
|
||||||
updateThing(thingBuilder.build());
|
|
||||||
|
|
||||||
connector = new Ipx800DeviceConnector(configuration.hostname, configuration.portNumber, getThing().getUID());
|
updateThing(editThing().withChannels(channels).build());
|
||||||
parser = Optional.of(new M2MMessageParser(connector, this));
|
|
||||||
|
connector = Optional.of(new Ipx800DeviceConnector(config.hostname, config.portNumber, getThing().getUID()));
|
||||||
|
parser = Optional.of(new M2MMessageParser(connector.get(), this));
|
||||||
|
|
||||||
updateStatus(ThingStatus.UNKNOWN);
|
updateStatus(ThingStatus.UNKNOWN);
|
||||||
|
|
||||||
refreshJob = Optional.of(scheduler.scheduleWithFixedDelay(statusFile::read, 3000, configuration.pullInterval,
|
refreshJob = Optional.of(
|
||||||
TimeUnit.MILLISECONDS));
|
scheduler.scheduleWithFixedDelay(statusFile::read, 3000, config.pullInterval, TimeUnit.MILLISECONDS));
|
||||||
|
|
||||||
connector.start();
|
connector.get().start();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -152,25 +148,15 @@ public class Ipx800v3Handler extends BaseThingHandler implements Ipx800EventList
|
||||||
refreshJob.ifPresent(job -> job.cancel(true));
|
refreshJob.ifPresent(job -> job.cancel(true));
|
||||||
refreshJob = Optional.empty();
|
refreshJob = Optional.empty();
|
||||||
|
|
||||||
if (connector != null) {
|
connector.ifPresent(Ipx800DeviceConnector::dispose);
|
||||||
connector.destroyAndExit();
|
connector = Optional.empty();
|
||||||
}
|
|
||||||
parser = Optional.empty();
|
parser = Optional.empty();
|
||||||
|
|
||||||
portDatas.values().stream().forEach(portData -> {
|
portDatas.values().stream().forEach(PortData::dispose);
|
||||||
if (portData != null) {
|
|
||||||
portData.dispose();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
super.dispose();
|
super.dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void discoverAttributes() {
|
|
||||||
updateProperties(Map.of(Thing.PROPERTY_VENDOR, "GCE Electronics", Thing.PROPERTY_FIRMWARE_VERSION,
|
|
||||||
statusFile.getElement(StatusEntry.VERSION), Thing.PROPERTY_MAC_ADDRESS,
|
|
||||||
statusFile.getElement(StatusEntry.CONFIG_MAC)));
|
|
||||||
}
|
|
||||||
|
|
||||||
private void addIfChannelAbsent(ChannelBuilder channelBuilder, List<Channel> channels) {
|
private void addIfChannelAbsent(ChannelBuilder channelBuilder, List<Channel> channels) {
|
||||||
Channel newChannel = channelBuilder.build();
|
Channel newChannel = channelBuilder.build();
|
||||||
if (channels.stream().noneMatch(c -> c.getUID().equals(newChannel.getUID()))) {
|
if (channels.stream().noneMatch(c -> c.getUID().equals(newChannel.getUID()))) {
|
||||||
|
@ -178,7 +164,7 @@ public class Ipx800v3Handler extends BaseThingHandler implements Ipx800EventList
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void createChannels(PortDefinition portDefinition, int portIndex, List<Channel> channels) {
|
private ChannelUID createChannels(PortDefinition portDefinition, int portIndex, List<Channel> channels) {
|
||||||
String ndx = Integer.toString(portIndex + 1);
|
String ndx = Integer.toString(portIndex + 1);
|
||||||
String advancedChannelTypeName = portDefinition.toString()
|
String advancedChannelTypeName = portDefinition.toString()
|
||||||
+ (portDefinition.isAdvanced(portIndex) ? "Advanced" : "");
|
+ (portDefinition.isAdvanced(portIndex) ? "Advanced" : "");
|
||||||
|
@ -210,9 +196,12 @@ public class Ipx800v3Handler extends BaseThingHandler implements Ipx800EventList
|
||||||
.withLabel("Relay " + ndx).withType(channelType), channels);
|
.withLabel("Relay " + ndx).withType(channelType), channels);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
addIfChannelAbsent(ChannelBuilder.create(new ChannelUID(groupUID, ndx + "-duration"), "Number:Time")
|
addIfChannelAbsent(ChannelBuilder.create(new ChannelUID(groupUID, ndx + "-duration"), "Number:Time")
|
||||||
.withType(new ChannelTypeUID(BINDING_ID, CHANNEL_LAST_STATE_DURATION))
|
.withType(new ChannelTypeUID(BINDING_ID, CHANNEL_LAST_STATE_DURATION))
|
||||||
.withLabel("Previous state duration " + ndx), channels);
|
.withLabel("Previous state duration " + ndx), channels);
|
||||||
|
|
||||||
|
return mainChannelUID;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -258,7 +247,7 @@ public class Ipx800v3Handler extends BaseThingHandler implements Ipx800EventList
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
logger.debug("About to update port '{}' with data '{}'", port, value);
|
logger.debug("About to update port '{}' with data '{}'", port, value);
|
||||||
State state = UnDefType.UNDEF;
|
State state = UnDefType.NULL;
|
||||||
switch (portDefinition) {
|
switch (portDefinition) {
|
||||||
case COUNTER:
|
case COUNTER:
|
||||||
state = new DecimalType(value);
|
state = new DecimalType(value);
|
||||||
|
@ -268,7 +257,7 @@ public class Ipx800v3Handler extends BaseThingHandler implements Ipx800EventList
|
||||||
break;
|
break;
|
||||||
case ANALOG:
|
case ANALOG:
|
||||||
state = new DecimalType(value);
|
state = new DecimalType(value);
|
||||||
updateState(channelId + PROPERTY_SEPARATOR + CHANNEL_VOLTAGE,
|
updateIfLinked(channelId + PROPERTY_SEPARATOR + CHANNEL_VOLTAGE,
|
||||||
new QuantityType<>(value * ANALOG_SAMPLING, Units.VOLT));
|
new QuantityType<>(value * ANALOG_SAMPLING, Units.VOLT));
|
||||||
break;
|
break;
|
||||||
case CONTACT:
|
case CONTACT:
|
||||||
|
@ -303,9 +292,9 @@ public class Ipx800v3Handler extends BaseThingHandler implements Ipx800EventList
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
updateState(channelId, state);
|
updateIfLinked(channelId, state);
|
||||||
if (!portData.isInitializing()) {
|
if (!portData.isInitializing()) {
|
||||||
updateState(channelId + PROPERTY_SEPARATOR + CHANNEL_LAST_STATE_DURATION,
|
updateIfLinked(channelId + PROPERTY_SEPARATOR + CHANNEL_LAST_STATE_DURATION,
|
||||||
new QuantityType<>(sinceLastChange / 1000, Units.SECOND));
|
new QuantityType<>(sinceLastChange / 1000, Units.SECOND));
|
||||||
}
|
}
|
||||||
portData.setData(value, now);
|
portData.setData(value, now);
|
||||||
|
@ -317,6 +306,12 @@ public class Ipx800v3Handler extends BaseThingHandler implements Ipx800EventList
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void updateIfLinked(String channelId, State state) {
|
||||||
|
if (isLinked(channelId)) {
|
||||||
|
updateState(channelId, state);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
protected void triggerPushButtonChannel(Channel channel, String event) {
|
protected void triggerPushButtonChannel(Channel channel, String event) {
|
||||||
logger.debug("Triggering event '{}' on channel '{}'", event, channel.getUID());
|
logger.debug("Triggering event '{}' on channel '{}'", event, channel.getUID());
|
||||||
triggerChannel(channel.getUID().getId() + PROPERTY_SEPARATOR + TRIGGER_CONTACT, event);
|
triggerChannel(channel.getUID().getId() + PROPERTY_SEPARATOR + TRIGGER_CONTACT, event);
|
||||||
|
@ -342,32 +337,10 @@ public class Ipx800v3Handler extends BaseThingHandler implements Ipx800EventList
|
||||||
logger.debug("Can not handle command '{}' on channel '{}'", command, channelUID);
|
logger.debug("Can not handle command '{}' on channel '{}'", command, channelUID);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void channelLinked(ChannelUID channelUID) {
|
|
||||||
logger.debug("channelLinked: {}", channelUID);
|
|
||||||
final String channelId = channelUID.getId();
|
|
||||||
if (isValidPortId(channelUID)) {
|
|
||||||
Channel channel = thing.getChannel(channelUID);
|
|
||||||
if (channel != null) {
|
|
||||||
PortData data = new PortData();
|
|
||||||
portDatas.put(channelId, data);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean isValidPortId(ChannelUID channelUID) {
|
private boolean isValidPortId(ChannelUID channelUID) {
|
||||||
return channelUID.getIdWithoutGroup().chars().allMatch(Character::isDigit);
|
return channelUID.getIdWithoutGroup().chars().allMatch(Character::isDigit);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void channelUnlinked(ChannelUID channelUID) {
|
|
||||||
super.channelUnlinked(channelUID);
|
|
||||||
PortData portData = portDatas.remove(channelUID.getId());
|
|
||||||
if (portData != null) {
|
|
||||||
portData.dispose();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void resetCounter(int counter) {
|
public void resetCounter(int counter) {
|
||||||
parser.ifPresent(p -> p.resetCounter(counter));
|
parser.ifPresent(p -> p.resetCounter(counter));
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,7 +15,6 @@ package org.openhab.binding.gce.internal.model;
|
||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||||
import org.eclipse.jdt.annotation.Nullable;
|
|
||||||
import org.openhab.binding.gce.internal.handler.Ipx800DeviceConnector;
|
import org.openhab.binding.gce.internal.handler.Ipx800DeviceConnector;
|
||||||
import org.openhab.binding.gce.internal.handler.Ipx800EventListener;
|
import org.openhab.binding.gce.internal.handler.Ipx800EventListener;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
|
@ -35,11 +34,11 @@ public class M2MMessageParser {
|
||||||
|
|
||||||
private final Logger logger = LoggerFactory.getLogger(M2MMessageParser.class);
|
private final Logger logger = LoggerFactory.getLogger(M2MMessageParser.class);
|
||||||
private final Ipx800DeviceConnector connector;
|
private final Ipx800DeviceConnector connector;
|
||||||
private final @Nullable Ipx800EventListener listener;
|
private final Ipx800EventListener listener;
|
||||||
|
|
||||||
private String expectedResponse = "";
|
private String expectedResponse = "";
|
||||||
|
|
||||||
public M2MMessageParser(Ipx800DeviceConnector connector, @Nullable Ipx800EventListener listener) {
|
public M2MMessageParser(Ipx800DeviceConnector connector, Ipx800EventListener listener) {
|
||||||
this.connector = connector;
|
this.connector = connector;
|
||||||
this.listener = listener;
|
this.listener = listener;
|
||||||
connector.setParser(this);
|
connector.setParser(this);
|
||||||
|
@ -87,10 +86,8 @@ public class M2MMessageParser {
|
||||||
|
|
||||||
private void setStatus(String port, double value) {
|
private void setStatus(String port, double value) {
|
||||||
logger.debug("Received {} : {}", port, value);
|
logger.debug("Received {} : {}", port, value);
|
||||||
if (listener != null) {
|
|
||||||
listener.dataReceived(port, value);
|
listener.dataReceived(port, value);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
public void setExpectedResponse(String expectedResponse) {
|
public void setExpectedResponse(String expectedResponse) {
|
||||||
if (expectedResponse.endsWith("s")) { // GetInputs or GetOutputs
|
if (expectedResponse.endsWith("s")) { // GetInputs or GetOutputs
|
||||||
|
@ -125,10 +122,8 @@ public class M2MMessageParser {
|
||||||
|
|
||||||
public void errorOccurred(Exception e) {
|
public void errorOccurred(Exception e) {
|
||||||
logger.warn("Error received from connector : {}", e.getMessage());
|
logger.warn("Error received from connector : {}", e.getMessage());
|
||||||
if (listener != null) {
|
|
||||||
listener.errorOccurred(e);
|
listener.errorOccurred(e);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
public void resetPLC() {
|
public void resetPLC() {
|
||||||
connector.send("Reset");
|
connector.send("Reset");
|
||||||
|
|
|
@ -17,6 +17,7 @@ import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.util.Comparator;
|
import java.util.Comparator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Optional;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
import java.util.stream.IntStream;
|
import java.util.stream.IntStream;
|
||||||
|
|
||||||
|
@ -25,7 +26,6 @@ import javax.xml.parsers.DocumentBuilderFactory;
|
||||||
import javax.xml.parsers.ParserConfigurationException;
|
import javax.xml.parsers.ParserConfigurationException;
|
||||||
|
|
||||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||||
import org.eclipse.jdt.annotation.Nullable;
|
|
||||||
import org.openhab.binding.gce.internal.handler.Ipx800EventListener;
|
import org.openhab.binding.gce.internal.handler.Ipx800EventListener;
|
||||||
import org.openhab.core.io.net.http.HttpUtil;
|
import org.openhab.core.io.net.http.HttpUtil;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
|
@ -44,47 +44,53 @@ import org.xml.sax.SAXException;
|
||||||
@NonNullByDefault
|
@NonNullByDefault
|
||||||
public class StatusFileInterpreter {
|
public class StatusFileInterpreter {
|
||||||
private static final String URL_TEMPLATE = "http://%s/globalstatus.xml";
|
private static final String URL_TEMPLATE = "http://%s/globalstatus.xml";
|
||||||
|
|
||||||
private final Logger logger = LoggerFactory.getLogger(StatusFileInterpreter.class);
|
private final Logger logger = LoggerFactory.getLogger(StatusFileInterpreter.class);
|
||||||
private final String hostname;
|
private final DocumentBuilder builder;
|
||||||
private @Nullable Document doc;
|
private final String url;
|
||||||
private final Ipx800EventListener listener;
|
private final Ipx800EventListener listener;
|
||||||
|
|
||||||
|
private Optional<Document> doc = Optional.empty();
|
||||||
|
|
||||||
public static enum StatusEntry {
|
public static enum StatusEntry {
|
||||||
VERSION,
|
VERSION,
|
||||||
CONFIG_MAC;
|
CONFIG_MAC;
|
||||||
}
|
}
|
||||||
|
|
||||||
public StatusFileInterpreter(String hostname, Ipx800EventListener listener) {
|
public StatusFileInterpreter(String hostname, Ipx800EventListener listener) {
|
||||||
this.hostname = hostname;
|
this.url = String.format(URL_TEMPLATE, hostname);
|
||||||
this.listener = listener;
|
this.listener = listener;
|
||||||
}
|
|
||||||
|
|
||||||
public void read() {
|
|
||||||
try {
|
|
||||||
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
|
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
|
||||||
// see https://cheatsheetseries.owasp.org/cheatsheets/XML_External_Entity_Prevention_Cheat_Sheet.html
|
// see https://cheatsheetseries.owasp.org/cheatsheets/XML_External_Entity_Prevention_Cheat_Sheet.html
|
||||||
|
try {
|
||||||
factory.setFeature("http://xml.org/sax/features/external-general-entities", false);
|
factory.setFeature("http://xml.org/sax/features/external-general-entities", false);
|
||||||
factory.setFeature("http://xml.org/sax/features/external-parameter-entities", false);
|
factory.setFeature("http://xml.org/sax/features/external-parameter-entities", false);
|
||||||
factory.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", false);
|
factory.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", false);
|
||||||
factory.setXIncludeAware(false);
|
factory.setXIncludeAware(false);
|
||||||
factory.setExpandEntityReferences(false);
|
factory.setExpandEntityReferences(false);
|
||||||
DocumentBuilder builder = factory.newDocumentBuilder();
|
builder = factory.newDocumentBuilder();
|
||||||
String statusPage = HttpUtil.executeUrl("GET", String.format(URL_TEMPLATE, hostname), 5000);
|
} catch (ParserConfigurationException e) {
|
||||||
|
logger.warn("Error initializing StatusFileInterpreter :{}", e.getMessage());
|
||||||
|
throw new IllegalArgumentException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void read() {
|
||||||
|
try {
|
||||||
|
String statusPage = HttpUtil.executeUrl("GET", url, 5000);
|
||||||
InputStream inputStream = new ByteArrayInputStream(statusPage.getBytes());
|
InputStream inputStream = new ByteArrayInputStream(statusPage.getBytes());
|
||||||
Document document = builder.parse(inputStream);
|
Document document = builder.parse(inputStream);
|
||||||
document.getDocumentElement().normalize();
|
document.getDocumentElement().normalize();
|
||||||
doc = document;
|
|
||||||
pushDatas();
|
|
||||||
inputStream.close();
|
inputStream.close();
|
||||||
} catch (IOException | SAXException | ParserConfigurationException e) {
|
this.doc = Optional.of(document);
|
||||||
|
pushDatas();
|
||||||
|
} catch (IOException | SAXException e) {
|
||||||
logger.warn("Unable to read IPX800 status page : {}", e.getMessage());
|
logger.warn("Unable to read IPX800 status page : {}", e.getMessage());
|
||||||
doc = null;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void pushDatas() {
|
private void pushDatas() {
|
||||||
Element root = getRoot();
|
getRoot().ifPresent(root -> {
|
||||||
if (root != null) {
|
|
||||||
PortDefinition.asStream().forEach(portDefinition -> {
|
PortDefinition.asStream().forEach(portDefinition -> {
|
||||||
List<Node> xmlNodes = getMatchingNodes(root.getChildNodes(), portDefinition.getNodeName());
|
List<Node> xmlNodes = getMatchingNodes(root.getChildNodes(), portDefinition.getNodeName());
|
||||||
xmlNodes.forEach(xmlNode -> {
|
xmlNodes.forEach(xmlNode -> {
|
||||||
|
@ -94,40 +100,29 @@ public class StatusFileInterpreter {
|
||||||
listener.dataReceived(String.format("%s%d", portDefinition.getPortName(), portNum), value);
|
listener.dataReceived(String.format("%s%d", portDefinition.getPortName(), portNum), value);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getElement(StatusEntry entry) {
|
public String getElement(StatusEntry entry) {
|
||||||
Element root = getRoot();
|
return getRoot().map(root -> root.getElementsByTagName(entry.name().toLowerCase()).item(0).getTextContent())
|
||||||
if (root != null) {
|
.orElse("");
|
||||||
return root.getElementsByTagName(entry.name().toLowerCase()).item(0).getTextContent();
|
|
||||||
} else {
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<Node> getMatchingNodes(NodeList nodeList, String criteria) {
|
private List<Node> getMatchingNodes(NodeList nodeList, String criteria) {
|
||||||
return IntStream.range(0, nodeList.getLength()).boxed().map(nodeList::item)
|
return IntStream.range(0, nodeList.getLength()).boxed().map(nodeList::item)
|
||||||
.filter(node -> node.getNodeName().startsWith(criteria))
|
.filter(node -> node.getNodeName().startsWith(criteria)).sorted(Comparator.comparing(Node::getNodeName))
|
||||||
.sorted(Comparator.comparing(o -> o.getNodeName())).collect(Collectors.toList());
|
.collect(Collectors.toList());
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getMaxNumberofNodeType(PortDefinition portDefinition) {
|
public int getMaxNumberofNodeType(PortDefinition portDefinition) {
|
||||||
Element root = getRoot();
|
return getRoot().map(root -> getMatchingNodes(root.getChildNodes(), portDefinition.getNodeName()).size())
|
||||||
if (root != null) {
|
.orElse(0);
|
||||||
List<Node> filteredNodes = getMatchingNodes(root.getChildNodes(), portDefinition.getNodeName());
|
|
||||||
return filteredNodes.size();
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private @Nullable Element getRoot() {
|
private Optional<Element> getRoot() {
|
||||||
if (doc == null) {
|
if (doc.isEmpty()) {
|
||||||
read();
|
read();
|
||||||
}
|
}
|
||||||
if (doc != null) {
|
return Optional.ofNullable(doc.map(Document::getDocumentElement).orElse(null));
|
||||||
return doc.getDocumentElement();
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue