element set name optional, skio additional search info, add LVI test

This commit is contained in:
Jörg Prante 2023-01-14 23:04:44 +01:00
parent dcea5cc021
commit f2a57d9ce3
7 changed files with 74 additions and 53 deletions

View file

@ -7,9 +7,28 @@ dependencies {
test { test {
useJUnitPlatform() useJUnitPlatform()
failFast = true failFast = false
ignoreFailures = true
jvmArgs '--add-exports=java.base/jdk.internal.misc=ALL-UNNAMED',
'--add-exports=java.base/jdk.internal.ref=ALL-UNNAMED',
'--add-exports=java.base/sun.nio.ch=ALL-UNNAMED',
'--add-exports=jdk.unsupported/sun.misc=ALL-UNNAMED',
'--add-exports=jdk.compiler/com.sun.tools.javac.file=ALL-UNNAMED',
'--add-opens=jdk.compiler/com.sun.tools.javac=ALL-UNNAMED',
'--add-opens=java.base/java.lang=ALL-UNNAMED',
'--add-opens=java.base/java.lang.reflect=ALL-UNNAMED',
'--add-opens=java.base/java.io=ALL-UNNAMED',
'--add-opens=java.base/java.nio=ALL-UNNAMED',
'--add-opens=java.base/java.util=ALL-UNNAMED'
systemProperty 'java.util.logging.config.file', 'src/test/resources/logging.properties'
systemProperty 'io.netty.tryReflectionSetAccessible', 'true'
testLogging { testLogging {
events 'STARTED', 'PASSED', 'FAILED', 'SKIPPED' events 'STARTED', 'PASSED', 'FAILED', 'SKIPPED'
showStandardStreams = true
}
reports {
html.required = false
junitXml.outputLocation.set(layout.buildDirectory.dir("test-junit-xml"))
} }
afterSuite { desc, result -> afterSuite { desc, result ->
if (!desc.parent) { if (!desc.parent) {

View file

@ -397,7 +397,7 @@ public class JDKZClient implements Client, Closeable {
private String resultSetName = "default"; private String resultSetName = "default";
private String elementSetName = "F"; private String elementSetName = null;
private String encoding = "ANSEL"; private String encoding = "ANSEL";
@ -407,7 +407,7 @@ public class JDKZClient implements Client, Closeable {
private List<String> databases = Collections.singletonList(""); private List<String> databases = Collections.singletonList("");
private Integer preferredMessageSize = 1024 * 1024; private Integer preferredMessageSize = 10 * 1024 * 1024;
private InitListener initListener; private InitListener initListener;

View file

@ -89,7 +89,7 @@ public class InitOperation extends AbstractOperation<InitializeResponse, Initial
if (initResp.implementationName != null) { if (initResp.implementationName != null) {
targetInfo = initResp.implementationName.toString(); targetInfo = initResp.implementationName.toString();
if (initResp.implementationVersion != null) { if (initResp.implementationVersion != null) {
targetInfo += " - " + initResp.implementationVersion.toString(); targetInfo += " - " + initResp.implementationVersion;
} }
} else { } else {
targetInfo = "server"; targetInfo = "server";

View file

@ -62,10 +62,12 @@ public class PresentOperation extends AbstractOperation<PresentResponse, Present
presentRequest.resultSetId.value.value = new ASN1GeneralString(resultSetName); presentRequest.resultSetId.value.value = new ASN1GeneralString(resultSetName);
presentRequest.resultSetStartPoint = new ASN1Integer(offset); presentRequest.resultSetStartPoint = new ASN1Integer(offset);
presentRequest.numberOfRecordsRequested = new ASN1Integer(length); presentRequest.numberOfRecordsRequested = new ASN1Integer(length);
presentRequest.recordComposition = new PresentRequestRecordComposition(); if (elementSetName != null) {
presentRequest.recordComposition.simple = new ElementSetNames(); presentRequest.recordComposition = new PresentRequestRecordComposition();
presentRequest.recordComposition.simple.cGenericElementSetName = new InternationalString(); presentRequest.recordComposition.simple = new ElementSetNames();
presentRequest.recordComposition.simple.cGenericElementSetName.value = new ASN1GeneralString(elementSetName); presentRequest.recordComposition.simple.cGenericElementSetName = new InternationalString();
presentRequest.recordComposition.simple.cGenericElementSetName.value = new ASN1GeneralString(elementSetName);
}
presentRequest.preferredRecordSyntax = new ASN1ObjectIdentifier(makeOID(preferredRecordSyntax)); presentRequest.preferredRecordSyntax = new ASN1ObjectIdentifier(makeOID(preferredRecordSyntax));
long millis = System.currentTimeMillis(); long millis = System.currentTimeMillis();
write(presentRequest); write(presentRequest);

View file

@ -1,11 +1,8 @@
package org.xbib.z3950.common.operations; package org.xbib.z3950.common.operations;
import org.xbib.asn1.ASN1Any;
import org.xbib.asn1.ASN1Boolean; import org.xbib.asn1.ASN1Boolean;
import org.xbib.asn1.ASN1Exception;
import org.xbib.asn1.ASN1GeneralString; import org.xbib.asn1.ASN1GeneralString;
import org.xbib.asn1.ASN1Integer; import org.xbib.asn1.ASN1Integer;
import org.xbib.asn1.ASN1Sequence;
import org.xbib.asn1.io.BERReader; import org.xbib.asn1.io.BERReader;
import org.xbib.asn1.io.BERWriter; import org.xbib.asn1.io.BERWriter;
import org.xbib.cql.CQLParser; import org.xbib.cql.CQLParser;
@ -15,7 +12,6 @@ import org.xbib.z3950.common.pqf.PQFParser;
import org.xbib.z3950.common.pqf.PQFRPNGenerator; import org.xbib.z3950.common.pqf.PQFRPNGenerator;
import org.xbib.z3950.common.v3.DatabaseName; import org.xbib.z3950.common.v3.DatabaseName;
import org.xbib.z3950.common.v3.InternationalString; import org.xbib.z3950.common.v3.InternationalString;
import org.xbib.z3950.common.v3.OtherInformation1;
import org.xbib.z3950.common.v3.PresentStatus; import org.xbib.z3950.common.v3.PresentStatus;
import org.xbib.z3950.common.v3.Query; import org.xbib.z3950.common.v3.Query;
import org.xbib.z3950.common.v3.RPNQuery; import org.xbib.z3950.common.v3.RPNQuery;
@ -24,31 +20,27 @@ import org.xbib.z3950.common.v3.SearchResponse;
import java.io.IOException; import java.io.IOException;
import java.io.StringReader; import java.io.StringReader;
import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map;
import java.util.logging.Level; import java.util.logging.Level;
import java.util.logging.Logger; import java.util.logging.Logger;
/** /**
* Base class for Z39.50 Search operation. * Z39.50 Search operation.
*/ */
public class SearchOperation extends AbstractOperation<SearchResponse, SearchRequest> { public class SearchOperation extends AbstractOperation<SearchResponse, SearchRequest> {
private static final Logger logger = Logger.getLogger(SearchOperation.class.getName()); private static final Logger logger = Logger.getLogger(SearchOperation.class.getName());
private int count = -1;
private boolean status = false;
private final Map<ASN1Any, Integer> results;
private final String resultSetName; private final String resultSetName;
private final List<String> databases; private final List<String> databases;
private final String host; private final String host;
private int count;
private boolean status;
public SearchOperation(BERReader reader, BERWriter writer, public SearchOperation(BERReader reader, BERWriter writer,
String resultSetName, String resultSetName,
List<String> databases, List<String> databases,
@ -57,7 +49,8 @@ public class SearchOperation extends AbstractOperation<SearchResponse, SearchReq
this.resultSetName = resultSetName; this.resultSetName = resultSetName;
this.databases = databases; this.databases = databases;
this.host = host; this.host = host;
this.results = new HashMap<>(); this.count = -1;
this.status = false;
} }
public boolean executePQF(String pqf) throws IOException { public boolean executePQF(String pqf) throws IOException {
@ -109,35 +102,10 @@ public class SearchOperation extends AbstractOperation<SearchResponse, SearchReq
if (presentStatus != null && presentStatus.value != null && presentStatus.value.get() == 5) { if (presentStatus != null && presentStatus.value != null && presentStatus.value.get() == 5) {
throw new IOException("present status is failure"); throw new IOException("present status is failure");
} }
if (response.s_additionalSearchInfo != null && response.s_additionalSearchInfo.value[0] != null) {
OtherInformation1 info = response.s_additionalSearchInfo.value[0];
ASN1Sequence targetSeq = (ASN1Sequence) info.information.c_externallyDefinedInfo.getSingleASN1Type();
ASN1Any[] targets = targetSeq.get();
DatabaseName dbName;
for (int i = 0; i < targets.length; i++) {
ASN1Sequence target = (ASN1Sequence) targets[i];
try {
ASN1Any[] details = target.get();
dbName = new DatabaseName(details[0].berEncode(), false);
if (!dbName.value.value.get().equalsIgnoreCase(databases.get(i))) {
String message = "database name listed in additional search info " +
"doesn't match database name in names set";
throw new IOException(host + ": " + message);
}
ASN1Integer res = (ASN1Integer) details[1];
results.put(target, res.get());
} catch (ASN1Exception ex) {
logger.log(Level.WARNING, ex.getMessage(), ex);
// non-fatal, e.g. String message = "Error in accessing additional search info.";
results.put(target, -1);
}
}
}
} else { } else {
logger.log(Level.WARNING, "no search response returned for host " + host + " " + databases); logger.log(Level.WARNING, "no search response returned for host " + host + " " + databases);
} }
} catch (IOException e) { } catch (IOException e) {
// add host in IOException message
throw new IOException(host + ": " + e.getMessage(), e); throw new IOException(host + ": " + e.getMessage(), e);
} }
return status; return status;
@ -151,10 +119,6 @@ public class SearchOperation extends AbstractOperation<SearchResponse, SearchReq
return status; return status;
} }
public Map<ASN1Any, Integer> getResults() {
return results;
}
private RPNQuery createRPNQueryFromCQL(String query) { private RPNQuery createRPNQueryFromCQL(String query) {
CQLRPNGenerator generator = new CQLRPNGenerator(); CQLRPNGenerator generator = new CQLRPNGenerator();
CQLParser parser = new CQLParser(query); CQLParser parser = new CQLParser(query);

View file

@ -16,7 +16,7 @@ class COPACTest {
String database = "COPAC" String database = "COPAC"
String query = "@attr 1=1 smith" String query = "@attr 1=1 smith"
// "1.2.840.10003.5.10"; // MARC // "1.2.840.10003.5.10"; // MARC
String preferredRecordSyntax = "1.2.840.10003.5.109.10" // xml String preferredRecordSyntax = "xml" // "1.2.840.10003.5.109.10" // xml
int from = 1 int from = 1
int length = 1 int length = 1
JDKZClient client = JDKZClient.builder() JDKZClient client = JDKZClient.builder()

View file

@ -0,0 +1,36 @@
package org.xbib.z3950.groovy
import groovy.util.logging.Log
import org.junit.jupiter.api.Disabled
import org.junit.jupiter.api.Test
import org.xbib.z3950.client.jdk.JDKZClient
import java.util.logging.Level
@Log
@Disabled("internal test")
class LVITest {
@Test
void testLVI() {
String host = "localhost"
int port = 2100
String database = "lvi"
String query = "@attr 1=4 linux"
String preferredRecordSyntax = "xml"
int from = 1
int size = 1
JDKZClient client = JDKZClient.builder()
.setHost(host)
.setPort(port)
.setDatabases(Collections.singletonList(database))
.setPreferredRecordSyntax(preferredRecordSyntax)
.build()
client.withCloseable {cl ->
cl.searchPQF(query, from, size,
(status, total, returned, elapsedMillis) -> log.log(Level.INFO, "total records = " + total),
record -> log.log(Level.INFO, "found record " + record),
() -> log.log(Level.WARNING, "timeout"))
}
}
}