Skip to content

Commit

Permalink
Adding possibility to blacklist codespaces for each subscription
Browse files Browse the repository at this point in the history
  • Loading branch information
lassetyr committed Jan 25, 2024
1 parent adb1516 commit f37d0e9
Show file tree
Hide file tree
Showing 7 changed files with 236 additions and 12 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,142 @@
/*
* Licensed under the EUPL, Version 1.2 or – as soon they will be approved by
* the European Commission - subsequent versions of the EUPL (the "Licence");
* You may not use this work except in compliance with the Licence.
* You may obtain a copy of the Licence at:
*
* https://joinup.ec.europa.eu/software/page/eupl
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the Licence is distributed on an "AS IS" basis,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the Licence for the specific language governing permissions and
* limitations under the Licence.
*/

package no.rutebanken.anshar.routes.siri.processor;

import no.rutebanken.anshar.metrics.PrometheusMetricsService;
import no.rutebanken.anshar.routes.siri.transformer.ApplicationContextHolder;
import no.rutebanken.anshar.routes.siri.transformer.ValueAdapter;
import no.rutebanken.anshar.subscription.SiriDataType;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import uk.org.siri.siri21.DatedVehicleJourneyRef;
import uk.org.siri.siri21.EstimatedTimetableDeliveryStructure;
import uk.org.siri.siri21.EstimatedVersionFrameStructure;
import uk.org.siri.siri21.FramedVehicleJourneyRefStructure;
import uk.org.siri.siri21.LineRef;
import uk.org.siri.siri21.Siri;

import java.util.List;

import static no.rutebanken.anshar.routes.siri.transformer.MappingNames.REMOVE_INVALID_CODESPACE;

public class CodespaceBlackListProcessor extends ValueAdapter implements PostProcessor {

private static final Logger logger = LoggerFactory.getLogger(CodespaceBlackListProcessor.class);
private final String codespace;
private final List<String> blacklist;

private PrometheusMetricsService metrics;

public CodespaceBlackListProcessor(String codespace, List<String> blacklist) {
this.codespace = codespace;
this.blacklist = blacklist;
}

@Override
protected String apply(String text) {
return null;
}

@Override
public void process(Siri siri) {
if (this.blacklist == null || this.blacklist.isEmpty()) {
//Nothing to do - return immediately
return;
}
if (siri != null && siri.getServiceDelivery() != null) {
List<EstimatedTimetableDeliveryStructure> etDeliveries = siri.getServiceDelivery().getEstimatedTimetableDeliveries();
if (etDeliveries != null) {
for (EstimatedTimetableDeliveryStructure etDelivery : etDeliveries) {
List<EstimatedVersionFrameStructure> estimatedJourneyVersionFrames = etDelivery.getEstimatedJourneyVersionFrames();
for (EstimatedVersionFrameStructure estimatedJourneyVersionFrame : estimatedJourneyVersionFrames) {
int size = estimatedJourneyVersionFrame.getEstimatedVehicleJourneies().size();

estimatedJourneyVersionFrame
.getEstimatedVehicleJourneies()
.removeIf(et -> isInvalidCodespace(et.getFramedVehicleJourneyRef()));

estimatedJourneyVersionFrame
.getEstimatedVehicleJourneies()
.removeIf(et -> isInvalidCodespace(et.getDatedVehicleJourneyRef()));

estimatedJourneyVersionFrame
.getEstimatedVehicleJourneies()
.removeIf(et -> isInvalidCodespace(et.getEstimatedVehicleJourneyCode()));

estimatedJourneyVersionFrame
.getEstimatedVehicleJourneies()
.removeIf(et -> isInvalidCodespace(et.getLineRef()));

if (estimatedJourneyVersionFrame.getEstimatedVehicleJourneies().size() != size) {
final int removedDataCount = size - estimatedJourneyVersionFrame.getEstimatedVehicleJourneies().size();
logger.info("Removed {} ET-messages on blacklisted codespaces.", removedDataCount);
getMetricsService()
.registerDataMapping(
SiriDataType.ESTIMATED_TIMETABLE,
codespace,
REMOVE_INVALID_CODESPACE,
removedDataCount
);
}
}
}
}
}

}

private boolean isInvalidCodespace(LineRef lineRef) {
if (lineRef != null) {
return toBeRemoved(lineRef.getValue());
}
return false;
}
private boolean isInvalidCodespace(String s) {
if (s != null) {
return toBeRemoved(s);
}
return false;
}
private boolean isInvalidCodespace(DatedVehicleJourneyRef datedVehicleJourneyRef) {
if (datedVehicleJourneyRef != null) {
return toBeRemoved(datedVehicleJourneyRef.getValue());
}
return false;
}

private boolean isInvalidCodespace(FramedVehicleJourneyRefStructure framedVehicleJourneyRef) {
if (framedVehicleJourneyRef != null) {
String datedVehicleJourneyRef = framedVehicleJourneyRef.getDatedVehicleJourneyRef();
return toBeRemoved(datedVehicleJourneyRef);
}
return false;
}

private boolean toBeRemoved(String reference) {
if (reference != null && reference.length() > 4) {
return blacklist.contains(
reference.substring(0,3)
);
}
return false;
}

void prepareMetrics() {
if (metrics == null) {
metrics = ApplicationContextHolder.getContext().getBean(PrometheusMetricsService.class);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -35,14 +35,14 @@
public class CodespaceWhiteListProcessor extends ValueAdapter implements PostProcessor {

private static final Logger logger = LoggerFactory.getLogger(CodespaceWhiteListProcessor.class);
private final String subscriptionIdentifier;
private final String codespace;
private final List<String> whitelist;

private PrometheusMetricsService metrics;

public CodespaceWhiteListProcessor(String subscriptionIdentifier, List<String> codespaceWhiteList) {
this.subscriptionIdentifier = subscriptionIdentifier;
this.whitelist = codespaceWhiteList;
public CodespaceWhiteListProcessor(String codespace, List<String> whitelist) {
this.codespace = codespace;
this.whitelist = whitelist;
}

@Override
Expand Down Expand Up @@ -86,7 +86,7 @@ public void process(Siri siri) {
getMetricsService()
.registerDataMapping(
SiriDataType.ESTIMATED_TIMETABLE,
subscriptionIdentifier,
codespace,
REMOVE_INVALID_CODESPACE,
removedDataCount
);
Expand Down Expand Up @@ -125,11 +125,11 @@ private boolean isInvalidCodespace(FramedVehicleJourneyRefStructure framedVehicl
return false;
}

private boolean toBeRemoved(String datedVehicleJourneyRef) {
for (String codespace : whitelist) {
if (!datedVehicleJourneyRef.startsWith(codespace)) {
return true;
}
private boolean toBeRemoved(String reference) {
if (reference != null && reference.length() > 4) {
return !whitelist.contains(
reference.substring(0,3)
);
}
return false;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
import no.rutebanken.anshar.routes.siri.adapters.Mapping;
import no.rutebanken.anshar.routes.siri.handlers.SiriHandler;
import no.rutebanken.anshar.routes.siri.processor.AddOrderToAllCallsPostProcessor;
import no.rutebanken.anshar.routes.siri.processor.CodespaceBlackListProcessor;
import no.rutebanken.anshar.routes.siri.processor.CodespaceProcessor;
import no.rutebanken.anshar.routes.siri.processor.CodespaceWhiteListProcessor;
import no.rutebanken.anshar.routes.siri.processor.EnsureIncreasingTimesForCancelledStopsProcessor;
Expand Down Expand Up @@ -184,6 +185,10 @@ void createSubscriptions() {
if (!subscriptionSetup.getCodespaceWhiteList().isEmpty()) {
valueAdapters.add(new CodespaceWhiteListProcessor(subscriptionSetup.getDatasetId(), subscriptionSetup.getCodespaceWhiteList()));
}
if (!subscriptionSetup.getCodespaceBlackList().isEmpty()) {
valueAdapters.add(new CodespaceBlackListProcessor(subscriptionSetup.getDatasetId(), subscriptionSetup.getCodespaceBlackList()));
}

subscriptionSetup.getMappingAdapters().addAll(valueAdapters);

if (subscriptionSetup.getSubscriptionMode() == SubscriptionSetup.SubscriptionMode.FETCHED_DELIVERY |
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@ public class SubscriptionSetup implements Serializable {
// transient to refresh config on each redeploy
private transient boolean reduceLogging;
private List<String> codespaceWhiteList = new ArrayList<>();
private List<String> codespaceBlackList = new ArrayList<>();

public boolean isUseProvidedCodespaceId() {
return useProvidedCodespaceId;
Expand Down Expand Up @@ -288,6 +289,7 @@ public JSONObject toJSON() {
obj.put("restartTime", getRestartTime());
obj.put("forwardPositionData", forwardPositionData());
obj.put("codespaceWhiteList", !getCodespaceWhiteList().isEmpty() ? getCodespaceWhiteList().toString():"");
obj.put("codespaceBlackList", !getCodespaceBlackList().isEmpty() ? getCodespaceBlackList().toString():"");

return obj;
}
Expand Down Expand Up @@ -449,6 +451,14 @@ public void setCodespaceWhiteList(List<String> codespaceWhiteList) {
this.codespaceWhiteList = codespaceWhiteList;
}

public List<String> getCodespaceBlackList() {
return codespaceBlackList;
}

public void setCodespaceBlackList(List<String> codespaceBlackList) {
this.codespaceBlackList = codespaceBlackList;
}

public enum ServiceType {SOAP, REST}

public enum SubscriptionMode {SUBSCRIBE, REQUEST_RESPONSE, POLLING_FETCHED_DELIVERY, FETCHED_DELIVERY, LITE, WEBSOCKET, BIG_DATA_EXPORT, VM_POSITION_FORWARDING, AVRO_PUBSUB, KAFKA_PUBSUB}
Expand Down
2 changes: 1 addition & 1 deletion src/main/resources/templates/stats.ftl
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@
<td colspan="9">
<table class="table table-striped">
<tr><th>Dataset ID</th><td><a href="${item.validationUrl}" target="_blank">${item.datasetId}</a></td></tr>
<tr><th>Whitelisted</th><td>${item.codespaceWhiteList}</td></tr>
<tr><th>Codespacefilter</th><td>Whitelisted: ${item.codespaceWhiteList}<br />Blacklisted: ${item.codespaceBlackList}</td></tr>
<tr><th>Vendor ID</th><td>${item.vendor}</td></tr>
<tr><th>Servicetype</th><td>${item.serviceType}</td></tr>
<tr><th>Inbound URL</th><td>${item.inboundUrl}</td></tr>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
package no.rutebanken.anshar.siri.processor;

import no.rutebanken.anshar.integration.SpringBootBaseTest;
import no.rutebanken.anshar.routes.siri.helpers.SiriObjectFactory;
import no.rutebanken.anshar.routes.siri.processor.CodespaceBlackListProcessor;
import org.junit.jupiter.api.Test;
import uk.org.siri.siri21.EstimatedVehicleJourney;
import uk.org.siri.siri21.FramedVehicleJourneyRefStructure;
import uk.org.siri.siri21.Siri;

import java.time.Instant;
import java.util.ArrayList;
import java.util.List;

import static org.junit.Assert.assertFalse;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;

public class CodespaceBlackListProcessorTest extends SpringBootBaseTest {

CodespaceBlackListProcessor processor = new CodespaceBlackListProcessor("testing-testing", List.of("TST", "ABC"));

@Test
public void testCodespaceNotOnBlacklistIsNotRemoved() {
Siri siri = createEt("RUT");
assertEquals(1, getEstimatedVehicleJourneies(siri).size());
processor.process(siri);
assertFalse(getEstimatedVehicleJourneies(siri).isEmpty());
}

@Test
public void testCodespaceOnBlacklistIsRemoved() {

Siri siri = createEt("TST");
assertEquals(1, getEstimatedVehicleJourneies(siri).size());
processor.process(siri);
assertTrue(getEstimatedVehicleJourneies(siri).isEmpty());

}
@Test
public void testInvalidCodespaceIsRemovedAndValidIsKept() {

Siri siri = createEt("RUT", "TST");
assertEquals(2, getEstimatedVehicleJourneies(siri).size());
processor.process(siri);
assertFalse(getEstimatedVehicleJourneies(siri).isEmpty());
assertEquals(1, getEstimatedVehicleJourneies(siri).size());
}

private static List<EstimatedVehicleJourney> getEstimatedVehicleJourneies(Siri tst) {
return tst.getServiceDelivery().getEstimatedTimetableDeliveries().get(0).getEstimatedJourneyVersionFrames().get(0).getEstimatedVehicleJourneies();
}

private Siri createEt(String... codespacePrefix) {

List<EstimatedVehicleJourney> etList = new ArrayList<>();
for (String prefix : codespacePrefix) {
EstimatedVehicleJourney et = new EstimatedVehicleJourney();
FramedVehicleJourneyRefStructure framedVehicleJourneyRef = new FramedVehicleJourneyRefStructure();
framedVehicleJourneyRef.setDatedVehicleJourneyRef(prefix + ":ServiceJourney:1234");
et.setFramedVehicleJourneyRef(framedVehicleJourneyRef);
etList.add(et);
}

return new SiriObjectFactory(Instant.now()).createETServiceDelivery(etList);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@

public class CodespaceWhiteListProcessorTest extends SpringBootBaseTest {

CodespaceWhiteListProcessor processor = new CodespaceWhiteListProcessor("testing-testing", List.of("RUT"));
CodespaceWhiteListProcessor processor = new CodespaceWhiteListProcessor("testing-testing", List.of("RUT", "ATB"));

@Test
public void testValidCodespaceIsNotRemoved() {
Expand Down

0 comments on commit f37d0e9

Please sign in to comment.