Skip to content

Commit

Permalink
restore beacon's /info from log if beacon is down
Browse files Browse the repository at this point in the history
  • Loading branch information
redmitry committed Mar 13, 2024
1 parent 46083bf commit 7f208c3
Show file tree
Hide file tree
Showing 3 changed files with 86 additions and 35 deletions.
2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@
<dependency>
<groupId>es.bsc.inb.ga4gh</groupId>
<artifactId>beacon-v2-validator-code</artifactId>
<version>0.0.4</version>
<version>0.0.7</version>
</dependency>

</dependencies>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
import es.bsc.inb.ga4gh.beacon.network.log.BeaconLogEntity;
import es.bsc.inb.ga4gh.beacon.network.log.BeaconLogEntity.METHOD;
import es.bsc.inb.ga4gh.beacon.network.log.BeaconLogEntity.REQUEST_TYPE;
import es.bsc.inb.ga4gh.beacon.network.log.BeaconLogLevel;
import es.bsc.inb.ga4gh.beacon.network.model.BeaconNetworkInfoResponse;
import es.bsc.inb.ga4gh.beacon.validator.BeaconMetadataSchema;
import es.bsc.inb.ga4gh.beacon.validator.BeaconMetadataValidator;
Expand Down Expand Up @@ -175,20 +176,40 @@ private void updateBeacons(NetworkConfigChangedEvent event) {
*/
private void updateBeacon(String endpoint) {
final List<BeaconValidationMessage> err = new ArrayList();
if (updateMetadata(endpoint, BeaconMetadataSchema.BEACON_INFO_RESPONSE_SCHEMA, err)) {
final String beaconId = getBeaconId(endpoint); // beaconId can't be null
for (BeaconMetadataSchema schema : BeaconMetadataSchema.values()) {
if (BeaconMetadataSchema.BEACON_INFO_RESPONSE_SCHEMA != schema) {
final int nerrors = err.size();
updateMetadata(endpoint, schema, err);
if (beaconId != null && nerrors != err.size()) {
metadata.get(schema).remove(beaconId);
if (updateMetadata(endpoint, BeaconMetadataSchema.BEACON_INFO_RESPONSE_SCHEMA,
BeaconLogLevel.METADATA, err)) { // always write "/info" metadata
String beacon_id = getBeaconId(endpoint);
if (err.isEmpty()) {
// beaconId can't be null if no errors in metadata!
for (BeaconMetadataSchema schema : BeaconMetadataSchema.values()) {
if (BeaconMetadataSchema.BEACON_INFO_RESPONSE_SCHEMA != schema) {
final int nerrors = err.size();
updateMetadata(endpoint, schema, BeaconLogLevel.LEVEL, err);
if (beacon_id != null && nerrors != err.size()) {
metadata.get(schema).remove(beacon_id);
}
}
}
}
if (err.isEmpty()) {
errors.remove(endpoint);
} else {
if (err.isEmpty()) {
errors.remove(endpoint);
} else {
errors.put(endpoint, err);
}
} else if (beacon_id == null) {
// the beacon is not accessible and never was loaded (beacon_id == null)
final BeaconLogEntity log_entity = log.getLastResponse(endpoint
+ validator.ENDPOINTS.get(BeaconMetadataSchema.BEACON_INFO_RESPONSE_SCHEMA));
if (log_entity != null) {
final BeaconInformationalResponse response = validator.parseMetadata(log_entity.getResponse(),
BeaconMetadataSchema.BEACON_INFO_RESPONSE_SCHEMA);
beacon_id = getBeaconId(response);
if (beacon_id != null) {
final Map<String, BeaconInformationalResponse> map = (Map<String,
BeaconInformationalResponse>)metadata.get(BeaconMetadataSchema.BEACON_INFO_RESPONSE_SCHEMA);
map.put(beacon_id, response);
endpoints.put(beacon_id, endpoint);
}
}
errors.put(endpoint, err);
}
}
Expand All @@ -204,6 +225,7 @@ private void updateBeacon(String endpoint) {
* @return false if no changes in metadata happened, true otherwise
*/
private boolean updateMetadata(String endpoint, BeaconMetadataSchema schema,
BeaconLogLevel level,
List<BeaconValidationMessage> errors) {

boolean changed = true;
Expand Down Expand Up @@ -231,24 +253,18 @@ private boolean updateMetadata(String endpoint, BeaconMetadataSchema schema,
err = validator.validate(schema, value);
if (err.isEmpty()) {
final BeaconInformationalResponse response = validator.parseMetadata(json, schema);
if (response != null) {
final String beacon_id = getBeaconId(response);
if (beacon_id != null) {
hashes.put(metadata_endpoint, json.hashCode());
final BeaconInformationalResponseMeta rmeta = response.getMeta();
if (rmeta != null) {
final String beacon_id = rmeta.getBeaconId();
if (beacon_id != null) {
endpoints.put(beacon_id, endpoint);
final Map<String, BeaconInformationalResponse> map = (Map<String, BeaconInformationalResponse>)metadata.get(schema);
map.put(beacon_id, response);
}
} else { // should never happen if json schema is correct!
log_entry.setMessage("missed BeaconInformationalResponseMeta in response");
err.add(new BeaconValidationMessage(
BeaconValidationErrorType.CONTENT_ERROR,
null, metadata_endpoint, null,
log_entry.getMessage()));

}
endpoints.put(beacon_id, endpoint);
final Map<String, BeaconInformationalResponse> map = (Map<String, BeaconInformationalResponse>)metadata.get(schema);
map.put(beacon_id, response);
} else { // should never happen if json schema is correct!
log_entry.setMessage("missed beaconId in response");
err.add(new BeaconValidationMessage(
BeaconValidationErrorType.CONTENT_ERROR,
null, metadata_endpoint, null,
log_entry.getMessage()));
}
} else {
log_entry.setMessage(err.get(err.size() - 1).message);
Expand All @@ -263,7 +279,7 @@ private boolean updateMetadata(String endpoint, BeaconMetadataSchema schema,
}
}

log.log(log_entry);
log.log(log_entry, level);

return changed;
}
Expand Down Expand Up @@ -301,6 +317,16 @@ public Map<String, List<BeaconValidationMessage>> getErrors() {
return errors;
}

private String getBeaconId(BeaconInformationalResponse response) {
if (response != null) {
final BeaconInformationalResponseMeta rmeta = response.getMeta();
if (rmeta != null) {
return rmeta.getBeaconId();
}
}
return null;
}

private String getBeaconId(String endpoint) {
for (Map.Entry<String, String> entry : endpoints.entrySet()) {
if (endpoint.equals(entry.getValue())) {
Expand Down
33 changes: 29 additions & 4 deletions src/main/java/es/bsc/inb/ga4gh/beacon/network/log/BeaconLog.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/**
* *****************************************************************************
* Copyright (C) 2023 ELIXIR ES, Spanish National Bioinformatics Institute (INB)
* Copyright (C) 2024 ELIXIR ES, Spanish National Bioinformatics Institute (INB)
* and Barcelona Supercomputing Center (BSC)
*
* Modifications to the initial code base are copyright of their respective
Expand Down Expand Up @@ -30,6 +30,9 @@
import jakarta.inject.Singleton;
import jakarta.persistence.EntityManager;
import jakarta.persistence.EntityTransaction;
import jakarta.persistence.Query;
import jakarta.persistence.TypedQuery;
import java.net.URI;

/**
* @author Dmitry Repchevsky
Expand All @@ -41,15 +44,37 @@ public class BeaconLog {
@Inject
private EntityManager em;

public BeaconLogEntity getLastResponse(String url) {
final EntityTransaction tx = em.getTransaction();
try {
tx.begin();
final TypedQuery<BeaconLogEntity> query =
em.createQuery("SELECT l FROM log l WHERE code < 300 AND url = :url ORDER BY l.id DESC",
BeaconLogEntity.class);
query.setParameter("url", url);
query.setMaxResults(1);
final BeaconLogEntity entry = query.getSingleResult();
tx.commit();
return entry;
} catch (Exception ex) {
tx.rollback();
}
return null;
}

public void log(BeaconLogEntity record) {
log(record, BeaconLogLevel.LEVEL);
}

public void log(BeaconLogEntity record, BeaconLogLevel level) {

if (BeaconLogLevel.LEVEL == BeaconLogLevel.NONE ||
(BeaconLogLevel.LEVEL == BeaconLogLevel.METADATA &&
if (level == BeaconLogLevel.NONE ||
(level == BeaconLogLevel.METADATA &&
record.getType() != REQUEST_TYPE.METADATA)) {
return;
}

if (BeaconLogLevel.LEVEL.compareTo(BeaconLogLevel.RESPONSES) < 0 &&
if (level.compareTo(BeaconLogLevel.RESPONSES) < 0 &&
record.getType() == REQUEST_TYPE.QUERY) {
record.setMessage(null);
record.setResponse(null);
Expand Down

0 comments on commit 7f208c3

Please sign in to comment.