numass-framework/numass-client/src/main/java/inr/numass/client/NumassClient.java

265 lines
8.5 KiB
Java
Raw Normal View History

2018-03-06 16:59:09 +03:00
/*
2015-12-18 16:20:47 +03:00
* Copyright 2015 Alexander Nozik.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package inr.numass.client;
2016-10-12 10:55:09 +03:00
import hep.dataforge.io.envelopes.DefaultEnvelopeReader;
2017-07-31 20:19:55 +03:00
import hep.dataforge.io.envelopes.DefaultEnvelopeType;
2016-10-12 10:55:09 +03:00
import hep.dataforge.io.envelopes.Envelope;
import hep.dataforge.io.envelopes.EnvelopeBuilder;
import hep.dataforge.io.messages.Responder;
2015-12-18 16:20:47 +03:00
import hep.dataforge.meta.Meta;
import hep.dataforge.meta.MetaBuilder;
import hep.dataforge.values.Value;
import hep.dataforge.values.Values;
2017-07-08 22:04:29 +03:00
import inr.numass.data.storage.NumassStorage;
2018-03-06 16:59:09 +03:00
import org.jetbrains.annotations.NotNull;
2016-10-09 14:04:26 +03:00
import org.slf4j.LoggerFactory;
import org.zeroturnaround.zip.ZipUtil;
import java.io.*;
2015-12-18 16:20:47 +03:00
import java.net.Socket;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
import java.nio.file.StandardOpenOption;
2016-04-16 22:41:21 +03:00
import java.time.Instant;
2015-12-18 16:20:47 +03:00
import java.util.Arrays;
2016-10-09 20:13:25 +03:00
import java.util.Collection;
2015-12-18 16:20:47 +03:00
import java.util.HashMap;
import java.util.Map;
2018-03-06 16:59:09 +03:00
import java.util.concurrent.CompletableFuture;
import static hep.dataforge.io.messages.MessagesKt.*;
2015-12-18 16:20:47 +03:00
/**
* @author darksnake
*/
2016-10-09 20:13:25 +03:00
public class NumassClient implements AutoCloseable, Responder {
2015-12-18 16:20:47 +03:00
Socket socket;
public NumassClient(String address, int port) throws IOException {
socket = new Socket(address, port);
2016-04-13 18:13:59 +03:00
socket.setSoTimeout(300);
2015-12-18 16:20:47 +03:00
}
2016-10-09 20:13:25 +03:00
public NumassClient(Meta meta) throws IOException {
this(meta.getString("ip", "192.168.111.1"), meta.getInt("port", 8335));
}
2015-12-18 16:20:47 +03:00
@Override
public void close() throws IOException {
if (!socket.isClosed()) {
2018-03-06 16:59:09 +03:00
write(getTerminator(), socket.getOutputStream());
2015-12-18 16:20:47 +03:00
}
socket.close();
}
2016-10-09 14:04:26 +03:00
@Override
public Envelope respond(Envelope message) {
2015-12-18 16:20:47 +03:00
try {
write(message, socket.getOutputStream());
return read(socket.getInputStream());
} catch (IOException ex) {
LoggerFactory.getLogger(getClass()).error("Error in envelope exchange", ex);
2018-03-06 16:59:09 +03:00
return errorResponseBase(message, ex).build();
2015-12-18 16:20:47 +03:00
}
}
private Envelope read(InputStream is) throws IOException {
return new DefaultEnvelopeReader().readWithData(is);
}
private void write(Envelope envelope, OutputStream os) throws IOException {
DefaultEnvelopeType.Companion.getINSTANCE().getWriter().write(os, envelope);
2015-12-18 16:20:47 +03:00
os.flush();
}
private EnvelopeBuilder requestActionBase(String type, String action) {
2018-03-06 16:59:09 +03:00
return requestBase(type).setMetaValue("action", action);
2015-12-18 16:20:47 +03:00
}
public Meta getCurrentRun() {
return respond(requestActionBase("numass.run", "get").build()).getMeta();
2015-12-18 16:20:47 +03:00
}
public Meta startRun(String name) {
2016-10-09 14:04:26 +03:00
return respond(requestActionBase("numass.run", "start")
2018-03-05 10:41:45 +03:00
.setMetaValue("path", name)
.build()).getMeta();
2015-12-18 16:20:47 +03:00
}
public Meta resetRun() {
2016-10-09 14:04:26 +03:00
return respond(requestActionBase("numass.run", "reset")
.build()).getMeta();
2015-12-18 16:20:47 +03:00
}
public Meta sendNumassData(String path, String fileName) {
try {
File file = new File(fileName);
ByteBuffer buffer;
String zipName = null;
if (file.isDirectory()) {
2018-03-28 16:59:40 +03:00
File tmpFile = File.createTempFile(file.getName(), NumassStorage.NUMASS_ZIP_EXTENSION);
2015-12-18 16:20:47 +03:00
tmpFile.deleteOnExit();
ZipUtil.pack(file, tmpFile);
zipName = file.getName();
file = tmpFile;
}
2018-03-28 16:59:40 +03:00
if (file.toString().endsWith(NumassStorage.NUMASS_ZIP_EXTENSION)) {
2015-12-18 16:20:47 +03:00
FileChannel channel = FileChannel.open(file.toPath(), StandardOpenOption.READ);
buffer = ByteBuffer.allocate((int) channel.size());
channel.read(buffer);
if (zipName == null) {
2018-03-28 16:59:40 +03:00
zipName = file.getName().replace(NumassStorage.NUMASS_ZIP_EXTENSION, "");
2015-12-18 16:20:47 +03:00
}
} else {
2018-03-06 16:59:09 +03:00
return getErrorMeta(new FileNotFoundException(fileName));
2015-12-18 16:20:47 +03:00
}
2018-03-06 16:59:09 +03:00
Envelope bin = requestBase("numass.data")
.setMetaValue("action", "push")
.setMetaValue("path", path)
.setMetaValue("name", zipName)
2015-12-18 16:20:47 +03:00
.setData(buffer)
.build();
return respond(bin).getMeta();
2015-12-18 16:20:47 +03:00
} catch (IOException ex) {
2018-03-06 16:59:09 +03:00
return getErrorMeta(ex);
2015-12-18 16:20:47 +03:00
}
}
/**
* Get state map for given state names from the root state loader. If
* stateNames is empty, return all states.
*
2016-10-09 14:04:26 +03:00
* @param stateNames
2015-12-18 16:20:47 +03:00
* @return
*/
public Map<String, Value> getStates(String... stateNames) {
EnvelopeBuilder env = requestActionBase("numass.state", "get");
if (stateNames.length > 0) {
2018-03-05 10:41:45 +03:00
env.setMetaValue("name", Arrays.asList(stateNames));
2015-12-18 16:20:47 +03:00
}
Meta response = respond(env.build()).getMeta();
2015-12-18 16:20:47 +03:00
if (response.getBoolean("success", true)) {
Map<String, Value> res = new HashMap<>();
2018-03-06 16:59:09 +03:00
response.getMetaList("state").forEach((stateMeta) -> {
2015-12-18 16:20:47 +03:00
res.put(stateMeta.getString("name"), stateMeta.getValue("value"));
});
return res;
} else {
return null;
}
}
/**
* Set a single state and return resulting envelope meta
*
* @param name
* @param value
* @return
*/
public Meta setState(String name, Object value) {
EnvelopeBuilder env = requestActionBase("numass.state", "set");
env.putMetaNode(new MetaBuilder("state")
.setValue("name", name)
.setValue("value", value)
.build());
return respond(env.build()).getMeta();
2015-12-18 16:20:47 +03:00
}
/**
* Set states and return resulting meta
*
* @param stateMap
* @return
*/
public Meta setState(Map<String, Value> stateMap) {
EnvelopeBuilder env = requestActionBase("numass.state", "set");
2018-03-06 16:59:09 +03:00
stateMap.entrySet().forEach((state) -> {
2015-12-18 16:20:47 +03:00
env.putMetaNode(new MetaBuilder("state")
.setValue("name", state.getKey())
.setValue("value", state.getValue())
.build());
2016-04-12 22:38:43 +03:00
});
return respond(env.build()).getMeta();
2015-12-18 16:20:47 +03:00
}
2016-04-16 22:41:21 +03:00
public Meta addNote(String text, Instant time) {
EnvelopeBuilder env = requestActionBase("numass.notes", "push");
2018-03-05 10:41:45 +03:00
env.setMetaValue("note.text", text);
2016-04-16 22:41:21 +03:00
if (time != null) {
2018-03-05 10:41:45 +03:00
env.setMetaValue("note.time", time);
2016-04-16 22:41:21 +03:00
}
return respond(env.build()).getMeta();
2016-04-16 22:41:21 +03:00
}
public Meta getNotes(int limit) {
EnvelopeBuilder env = requestActionBase("numass.notes", "pull");
if (limit > 0) {
2018-03-05 10:41:45 +03:00
env.setMetaValue("limit", limit);
2016-04-16 22:41:21 +03:00
}
return respond(env.build()).getMeta();
2016-04-16 22:41:21 +03:00
}
2016-10-09 20:13:25 +03:00
/**
* Create remote storage with given meta
*
* @param path full path relative to root storage
* @param meta
* @return
*/
public Envelope createStorage(String path, Meta meta) {
throw new UnsupportedOperationException();
}
/**
* Create remote loader
*
* @param shelf full path to the shelf
* @param name the name of the loader
* @param meta loader meta
* @return
*/
public Envelope createLoader(String shelf, String name, Meta meta) {
throw new UnsupportedOperationException();
}
/**
* Send points to existing point loader
*
* @param shelf
* @param loaderName
* @param points
* @return
*/
public Envelope sendDataPoints(String shelf, String loaderName, Collection<Values> points) {
2016-10-09 20:13:25 +03:00
throw new UnsupportedOperationException();
}
2018-03-06 16:59:09 +03:00
@NotNull
@Override
public CompletableFuture<Envelope> respondInFuture(@NotNull Envelope message) {
return CompletableFuture.supplyAsync(() -> respond(message));
}
2015-12-18 16:20:47 +03:00
}