H2O Mojo model from DRFModel - h2o

Having a trained DRFModel instance in scala, what's the best way of generating the corresponding MojoModel object for scoring? from the api s I've seen so far, mostly are around exporting to a file and then loading back up using the MojoModel.load(path) for instance but no direct conversion?

The model instance currently cannot be converted to mojo instance without going through MojoWriter.
MojoWriter provides method
abstract public void writeTo(OutputStream os);
You can use it to write the mojo to a byte array (using a ByteArrayOutputStream) and then use it as a source of the mojo data:
ByteArrayOutputStream os = new ByteArrayOutputStream();
model.getMojo().writeTo(os);
MojoModel mojoModel = MojoModel.load(MojoReaderBackendFactory.createReaderBackend(
new ByteArrayInputStream(os.toByteArray()), MojoReaderBackendFactory.CachingStrategy.MEMORY));

Related

Does OpenCSV support write to CSV from bean with a map [duplicate]

I'm using opencsv for read/write csv files using opencsv annotations.
My bean is having fields not just primitives, but a java HashMap as well.
Now what i want to do is
public class MyBean {
#CsvBindByName(column = "ID")
private int id;
#CsvBindByName(column = "PROPERTIES")
private Map<String, String> sampleMap = new HashMap<String, String>();
TO
ID, property1, property2...
1, value1, value2.....
I'd like to get this working in both read/write.
as i understand, the default MappingStrategy doesn't work in this case. Also Creating Custom MappingStrategy doesn't makes sense for HashMap field. because we don't know the complete field list until we iterate all the map.
Another way to get column names is that just read one bean from the list of beans. And get access to HashMap then create the header.(Hashmap keys are fixed across beans in my case)
MappingStrategy only concerned about Class level meta data. Like fields etc.
public static Field[] getAllFields(Class<?> cls) {
List allFieldsList = getAllFieldsList(cls);
return (Field[])allFieldsList.toArray(new Field[allFieldsList.size()]);
}
getting access to the real data for creating csv header doesn't look like a natural way to do.
Any advice on how to solve this?
Please point me out to any other libraries out there that can do read/write into beans having Map field.
Cheers!
Sadly openCSV does not support this. A quick google showed me that SuperCSV comes close but it puts everything in a map whereas you want to control what goes in the map and what does not. There may be others out there but most require a one to one between the fields in the object and the columns in the csv file.
This was something that I wanted to develop for years and contribute because the company I currently work for has need for that but they do not want to pay me to develop it and I have higher priorities for openCSV when free time is available.
A possible but limited workaround would be to create what I would call a Data Transfer Object. Have a custom object that has all the values you would have and have it return the object of the type you want (or a translator that will convert the DTO that has all fields to the object you want with the map and some fields). The problem with this solution is that it forces you to know in advance what are all possible entries you have in the map.

How to access/read objects inside Itemreader/StaxEventItemReader correctly?

I am new to the spring batch and I have an application where for example an xml-file of flights is read and saved to a database. The whole process is already working, but due to a certain use case I also need to access the data inside the reader object (ItemReader), should it is possible.
Down there is the reader-method. It is not about this method in particular, but as mentioned it is about ItemReader.
#Bean
public StaxEventItemReader<Flight> flightReader() {
StaxEventItemReader<Flight> reader = new StaxEventItemReader<Obj>();
reader.setResource(ressource);
reader.setFragmentRootElementName("flight");
Map<String, String> aliases = new HashMap<String, String>();
aliases.put("flight", Flight.class);
XStreamMarshaller xStreamMarshaller = new XStreamMarshaller();
xStreamMarshaller.setAliases(aliases);
reader.setUnmarshaller(xStreamMarshaller);
return reader;
}
How can I access the flight objects inside the reader (StaxEventItemReader) object?
I actually tried to use the read() method (Spring doc ItemReader), but I am always getting NullPointerExceptions.
If the read() method is the correct way, how can you access the flight objects inside ItemReader correctly?
If not, are there other ways?
There is more than one way to access the items. It really depends on what you want to do with them:
If you only want to have a look without manipulating the items, you can implement an ItemReadListener with its afterRead method, and add the listener to your step.
The items are passed to the processor. So you can operate on them there.
You can extend the class StaxEventItemReader and override the read method to include additional logic.
If you prefer composition over inheritance, you can write a new reader that uses a StaxEventItemReader as a delegate.

is ToXMLContentHandler thread-safe?

I am currently using Apache-Tika to parse my documents. While parsing the documents I am using AutoDetectParser, ToXMLContentHandler, Metadata classes of Apache Tika in this way:
InputStream stream = new FileInputStream(file);
parser.parse(stream, handler, metadata);
String filecontentInXMLFormat = handler.toString();
I have created the beans of AutoDetectParser, ToXMLContentHandler, Metadata using Springs, so the same class objects will be used when multiple documents are getting parsed through the same code flow.
So for example, if the second document comes in inside the code flow, will the "handler" object contain the data of the first document?
So, is the ToXMLContentHandler class "iorg.apache.tika.sax.ToXMLContentHandler" and Metadata class "org.apache.tika.metadata.Metadata" thread safe?

How to create a dynamic property value in an OSGi DS service registration

Here's a bit of code from the Apache CXF documentation:
CustomMessageBodyReaderWriter provider1 = new CustomMessageBodyReaderWriter();
provider.setCustomProperty(true);
Dictionary properties = new Hashtable();
properties.put("org.apache.cxf.rs.provider", provider);
bundleContext.registerService(
new String[]{"org.books.BookService"}, new BookServiceImpl(), properties);
Note that this piece of an activator method registers an OSGi service where one of the property values is an object created and configured at runtime.
Now, what if I wanted this to be a CXF dOSGi component? The only way I know to specify service registration properties for DS #Components requires the property value to be a string in the 'properties' slot in the #Component. Is there some way to have executable code involved?
CXF is not using the service properties correctly. The spec says :
Properties hold information as key/value pairs. The key must be a
String object and the value should be a type recognized by Filter
objects (see Filters on page 138 for a list). Multiple values for the
same key are supported with arrays ([]) and Collection objects. The
values of properties should be limited to primitive or standard Java
types to prevent unwanted inter bundle dependencies. ...
The service properties are intended to provide information about the
service. The properties should not be used to participate in the
actual function of the service. Modifying the properties for the
service registration is a potentially expensive operation. For
example, a Framework may pre-process the properties into an index
during registration to speed up later look-ups.
Anyway, AFAIK, it's not possible with the current DS to create such properties. You can however :
The 'DS way', use an immediate component which creates the real component with a ComponentFactory
Use an immediate component, and register your service with the raw osgi API
If you use felix SCR, you can use a ExtComponentContext to override your component properties
Update:
an example of a ComponentFactory :
#Component(factory = "bookService")
public class BookServiceImpl implements BookService {
...
}
And a component using this factory :
#Component
public class BookServiceManager {
#Reference(target = "(component.factory=bookService)")
private ComponentFactory bookServiceFactory;
#Activate
public void start() {
CustomMessageBodyReaderWriter provider1 = new CustomMessageBodyReaderWriter();
provider.setCustomProperty(true);
Dictionary properties = new Hashtable();
properties.put("org.apache.cxf.rs.provider", provider);
bookServiceFactory.newInstance(properties);
}
}
To be honest, with this use-case, I prefer using the raw OSGi API. But this approach can be useful if you want DS to manage your #Reference in your ComponentFactory. When the dependencies are not satisfied, the ComponentFactory and all its ComponentInstance will be deactivated.
I am currently working on a 2.0 version of CXF-DOSGi which will allow to set provder instances as intents. You can then publish an instance of CustomMessageBodyReaderWriter under an intent name and refer to it from your remote service by listing the required intents.

Custom Spring MVC HTTP Patch requests with Spring Data Rest functionality

What is the best practice for supporting HTTP PATCH in custom Spring MVC controllers? Particularly when using HATEOAS/HAL? Is there an easier way to merge objects without having to check for the presence of every single field in the request json (or writing and maintaining DTOs), ideally with automatic unmarshalling of links to resources?
I know this functionality exists in Spring Data Rest, but is it possible to leverage this for use in custom controllers?
I do not think you can use the spring-data-rest functionality here.
spring-data-rest is using json-patch library internally. Basically I think the workflow would be as follows:
read your entity
convert it to json using the objectMapper
apply the patch (here you need json-patch) (I think your controller should take a list of JsonPatchOperation as input)
merge the patched json into your entity
I think the hard part is the fourth point. But if you do not have to have a generic solution it could be easier.
If you want to get an impression of what spring-data-rest does - look at org.springframework.data.rest.webmvc.config.JsonPatchHandler
EDIT
The patch mechanism in spring-data-rest changed significantly in the latest realeases. Most importantly it is no longer using the json-patch library and is now implementing json patch support from scratch.
I could manage to reuse the main patch functionality in a custom controller method.
The following snippet illustrates the approach based on spring-data-rest 2.6
import org.springframework.data.rest.webmvc.IncomingRequest;
import org.springframework.data.rest.webmvc.json.patch.JsonPatchPatchConverter;
import org.springframework.data.rest.webmvc.json.patch.Patch;
//...
private final ObjectMapper objectMapper;
//...
#PatchMapping(consumes = "application/json-patch+json")
public ResponseEntity<Void> patch(ServletServerHttpRequest request) {
MyEntity entityToPatch = someRepository.findOne(id)//retrieve current state of your entity/object to patch
Patch patch = convertRequestToPatch(request);
patch.apply(entityToPatch, MyEntity.class);
someRepository.save(entityToPatch);
//...
}
private Patch convertRequestToPatch(ServletServerHttpRequest request) {
try {
InputStream inputStream = new IncomingRequest(request).getBody();
return new JsonPatchPatchConverter(objectMapper).convert(objectMapper.readTree(inputStream));
} catch (IOException e) {
throw new UncheckedIOException(e);
}
}

Resources