Skip to content

Commit

Permalink
Implemented new getAvailableMethods and cache endpoints.
Browse files Browse the repository at this point in the history
  • Loading branch information
Rui-Jesus committed Jun 7, 2024
1 parent ab6a824 commit aa1bb51
Show file tree
Hide file tree
Showing 5 changed files with 139 additions and 4 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -32,10 +32,7 @@
import pt.ua.dicoogle.sdk.datastructs.Report;
import pt.ua.dicoogle.sdk.datastructs.SearchResult;
import pt.ua.dicoogle.sdk.datastructs.dim.DimLevel;
import pt.ua.dicoogle.sdk.mlprovider.MLDataset;
import pt.ua.dicoogle.sdk.mlprovider.MLInference;
import pt.ua.dicoogle.sdk.mlprovider.MLInferenceRequest;
import pt.ua.dicoogle.sdk.mlprovider.MLProviderInterface;
import pt.ua.dicoogle.sdk.mlprovider.*;
import pt.ua.dicoogle.sdk.settings.ConfigurationHolder;
import pt.ua.dicoogle.sdk.task.JointQueryTask;
import pt.ua.dicoogle.sdk.task.Task;
Expand Down Expand Up @@ -876,6 +873,19 @@ public Task<MLDataset> datastore(final DatastoreRequest datasetRequest) {
return prepareTask;
}

public Task<Boolean> cache(String provider, final MLDicomDataset dataset) {
String taskName = "MLPredictionTask" + UUID.randomUUID();
MLProviderInterface mlInterface = getMachineLearningProviderByName(provider, true);
if (mlInterface == null) {
logger.error("MLProvider with name {} not found", provider);
return null;
}

Task<Boolean> task = mlInterface.cache(dataset);
task.setName(taskName);
return task;
}

// Methods for Web UI

/** Retrieve all web UI plugin descriptors for the given slot id.
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
package pt.ua.dicoogle.server.web.servlets.mlprovider;

import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.apache.commons.io.IOUtils;
import org.restlet.data.Status;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import pt.ua.dicoogle.plugins.PluginController;
import pt.ua.dicoogle.sdk.mlprovider.MLDicomDataset;
import pt.ua.dicoogle.server.web.utils.ResponseUtil;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

public class CacheServlet extends HttpServlet {

private static final Logger log = LoggerFactory.getLogger(DatastoreServlet.class);

@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

String dataString = IOUtils.toString(req.getReader());
if (dataString == null) {
resp.sendError(404, "Empty POST body");
return;
}

String provider = req.getParameter("provider");

if(provider == null || provider.isEmpty()){
ResponseUtil.sendError(resp, Status.CLIENT_ERROR_BAD_REQUEST.getCode(), "Provider provided was invalid");
return;
}

ObjectMapper mapper = new ObjectMapper();
mapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
MLDicomDataset dataset;
try {
dataset = mapper.readValue(dataString, MLDicomDataset.class);
PluginController.getInstance().cache(provider, dataset);
} catch (Exception e) {
log.error("Error parsing json string", e);
ResponseUtil.sendError(resp, Status.CLIENT_ERROR_BAD_REQUEST.getCode(), "Malformed request");
}
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
package pt.ua.dicoogle.server.web.servlets.mlprovider;

import com.fasterxml.jackson.databind.ObjectMapper;
import pt.ua.dicoogle.plugins.PluginController;
import pt.ua.dicoogle.sdk.mlprovider.MLMethod;
import pt.ua.dicoogle.sdk.mlprovider.MLProviderInterface;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Set;

public class ImplementedMethodsServlet extends HttpServlet {

@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
ObjectMapper mapper = new ObjectMapper();

String provider = request.getParameter("provider");

if(provider == null || provider.isEmpty()){
response.sendError(404, "Provider provided was invalid");
return;

}

MLProviderInterface mlPlugin = PluginController.getInstance().getMachineLearningProviderByName(provider, true);
Set<MLMethod> implementedMethods = mlPlugin.getImplementedMethods();
response.setContentType("application/json");
PrintWriter out = response.getWriter();
mapper.writeValue(out, implementedMethods);
out.close();
out.flush();
}

}
19 changes: 19 additions & 0 deletions sdk/src/main/java/pt/ua/dicoogle/sdk/mlprovider/MLMethod.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package pt.ua.dicoogle.sdk.mlprovider;

/**
* This enum lists the available methods of the MLProvider interface.
* This is used when requesting the available methods of a provider.
* It is a ENUM instead for example of a String to restrict the possible values.
*/
public enum MLMethod {
INFER,
BULK_INFER,
DATASTORE,
CACHE,
LIST_MODELS,
CREATE_MODEL,
MODEL_INFO,
TRAIN_MODEL,
STOP_TRAINING,
DELETE_MODEL,
}
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,16 @@ public abstract class MLProviderInterface implements DicooglePlugin {
*/
public abstract void dataStore(MLDataset dataset);

/**
* This method is similar to dataStore in that is also used to upload data to a provider.
* The main difference is that this method should be used to cache DICOM objects on the provider,
* so that the provider can for example run the inference tasks locally.
* Only DICOM objects can be cached.
* @param dataset a DICOM dataset to cache.
* @return a task to the cache operation. Returns true if the dataset was cached.
*/
public abstract Task<Boolean> cache(MLDicomDataset dataset);

/**
* This method creates a model using a specific dataset
*/
Expand Down Expand Up @@ -100,6 +110,12 @@ public abstract class MLProviderInterface implements DicooglePlugin {
*/
public abstract boolean isAvailable();

/**
* This method can be used to determine which of the methods of this interface are implemented.
* @return a list of the methods implemented.
*/
public abstract Set<MLMethod> getImplementedMethods();

public Set<MLDataType> getAcceptedDataTypes() {
return acceptedDataTypes;
}
Expand Down

0 comments on commit aa1bb51

Please sign in to comment.