How do I extract a list of Objects from a java stream? - java-8

Note that there are 3 levels of nesting here -
I am trying to retrieve a list of filters from a filtersubgroup list which is in a filtersupergroup list.
the filter has a property - fieldname.
I managed to extract the list of field names from the data structure using the following method :
public static List<String> extractFilterFieldsAsAList(QuerySearchRequestDTO requestDTO) {
return requestDTO.getFilter().parallelStream()
.map(new Function<FilterSuperGroup, String>() {
#Override
public String apply(FilterSuperGroup filterSuperGroup) {
return filterSuperGroup.getFilterSubGroup().parallelStream()
.map(new Function<FilterSubGroup, String>() {
#Override
public String apply(FilterSubGroup filterSubGroup) {
return filterSubGroup.getFilter().parallelStream()
.map(new Function<Filter, String>() {
#Override
public String apply(Filter t) {
// TODO Auto-generated method stub
return t.getFieldName();
}
}).collect(Collectors.joining(" "));
}
}).collect(Collectors.joining(" "));
}
}).collect(Collectors.toList());
}
Question: However, in another scenario (BELOW) I need a List as the output.
I want to replace findAny().get() with something that doesn't break the stream nesting. findAny().get() is obviously incorrect as it returns only one element from each nest. How do I fix this?
public static List<Filter> prepareFilterListFromRequest(QuerySearchRequestDTO requestDTO) {
List<Filter> listToReturn = new ArrayList<>();
listToReturn.addAll(requestDTO.getFilter().stream()
.map(new Function<FilterSuperGroup, List<Filter>>() {
#Override
public List<Filter> apply(FilterSuperGroup filterSuperGroup) {
return filterSuperGroup.getFilterSubGroup().parallelStream()
.map(new Function<FilterSubGroup, Filter>() {
#Override
public Filter apply(FilterSubGroup filterSubGroup) {
// TODO Auto-generated method stub
return filterSubGroup.getFilter().stream()
.map(new Function<Filter, Filter>() {
#Override
public Filter apply(Filter t) {
// TODO Auto-generated method stub
return t;
}
}).findAny().get();
}
}).collect(Collectors.toList());
}
}).findAny().get()
);
return listToReturn;
}

Related

Using Baggage in OpenTelemetry Spring application

I have a spring boot application where i have instrumented my code using automatic instrumentation.
Now in my application i am trying to attach a baggage in the traces or some specific span.
I know it uses contextPropagation. but i am not able to implement how contextPropagator, baggage and span work together.
Here is my relevant code implementation:
#WithSpan
private void doSomeWorkNewSpan() {
logger.info("Doing some work In New span");
Span span = Span.current();
ContextPropagators contextPropagators = new ContextPropagators() {
#Override
public TextMapPropagator getTextMapPropagator() {
return null;
}
};
Context context = new Context() {
#Override
public <V> V get(ContextKey<V> contextKey) {
return null;
}
#Override
public <V> Context with(ContextKey<V> contextKey, V v) {
return null;
}
};
Baggage baggage = new Baggage() {
#Override
public int size() {
return 0;
}
#Override
public void forEach(BiConsumer<? super String, ? super BaggageEntry> biConsumer) {
}
#Override
public Map<String, BaggageEntry> asMap() {
return null;
}
#Override
public String getEntryValue(String s) {
return null;
}
#Override
public BaggageBuilder toBuilder() {
return null;
}
};
baggage.storeInContext(context);
// span.storeInContext();
span.setAttribute("crun","yes");
span.addEvent("app.processing2.start", atttributes("321"));
span.addEvent("app.processing2.end", atttributes("321"));
}
private Attributes atttributes(String id) {
return Attributes.of(AttributeKey.stringKey("app.id"), id);
}

Adding a new field to body of the request from Netflix Zuul Pre-filter

I'm trying to add a new field to request's body, in a Zuul Pre-filter.
I'm using one of the Neflix's Zuul sample projects from here, and my filter's implementation is very similar to UppercaseRequestEntityFilter from this sample.
I was able to apply a transformation such as uppercase, or even to completely modify the request, the only inconvenient is that I'm not able to modify the content of body's request that has a length more than the original length of the body's request.
This is my filter's implementation:
#Component
public class MyRequestEntityFilter extends ZuulFilter {
public String filterType() {
return "pre";
}
public int filterOrder() {
return 10;
}
public boolean shouldFilter() {
RequestContext context = getCurrentContext();
return true;
}
public Object run() {
try {
RequestContext context = getCurrentContext();
InputStream in = (InputStream) context.get("requestEntity");
if (in == null) {
in = context.getRequest().getInputStream();
}
String body = StreamUtils.copyToString(in, Charset.forName("UTF-8"));
body = body.replaceFirst("qqq", "qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq");
// body = body.toUpperCase();
context.set("requestEntity", new ServletInputStreamWrapper(body.getBytes("UTF-8")));
}
catch (IOException e) {
rethrowRuntimeException(e);
}
return null;
}
}
This is the request that I'm doing:
This is the response that I'm receiving:
I was able to obtain what I wanted, using the implementation of PrefixRequestEntityFilter, from sample-zuul-examples:
#Component
public class MyRequestEntityFilter extends ZuulFilter {
public String filterType() {
return "pre";
}
public int filterOrder() {
return 10;
}
public boolean shouldFilter() {
RequestContext context = getCurrentContext();
return true;
}
public Object run() {
try {
RequestContext context = getCurrentContext();
InputStream in = (InputStream) context.get("requestEntity");
if (in == null) {
in = context.getRequest().getInputStream();
}
String body = StreamUtils.copyToString(in, Charset.forName("UTF-8"));
body = body.replaceFirst("qqq", "qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq");
byte[] bytes = body.getBytes("UTF-8");
context.setRequest(new HttpServletRequestWrapper(getCurrentContext().getRequest()) {
#Override
public ServletInputStream getInputStream() throws IOException {
return new ServletInputStreamWrapper(bytes);
}
#Override
public int getContentLength() {
return bytes.length;
}
#Override
public long getContentLengthLong() {
return bytes.length;
}
});
}
catch (IOException e) {
rethrowRuntimeException(e);
}
return null;
}
}

Subscribers onnext does not contain complete item

We are working with project reactor and having a huge problem right now. This is how we produce (publish our data):
public Flux<String> getAllFlux() {
return Flux.<String>create(sink -> {
new Thread(){
public void run(){
Iterator<Cache.Entry<String, MyObject>> iterator = getAllIterator();
ObjectMapper mapper = new ObjectMapper();
while(iterator.hasNext()) {
try {
sink.next(mapper.writeValueAsString(iterator.next().getValue()));
} catch (IOException e) {
e.printStackTrace();
}
}
sink.complete();
}
} .start();
});
}
As you can see we are taking data from an iterator and are publishing each item in that iterator as a json string. Our subscriber does the following:
flux.subscribe(new Subscriber<String>() {
private Subscription s;
int amount = 1; // the amount of received flux payload at a time
int onNextAmount;
String completeItem="";
ObjectMapper mapper = new ObjectMapper();
#Override
public void onSubscribe(Subscription s) {
System.out.println("subscribe");
this.s = s;
this.s.request(amount);
}
#Override
public void onNext(String item) {
MyObject myObject = null;
try {
System.out.println(item);
myObject = mapper.readValue(completeItem, MyObject.class);
System.out.println(myObject.toString());
} catch (IOException e) {
System.out.println(item);
System.out.println("failed: " + e.getLocalizedMessage());
}
onNextAmount++;
if (onNextAmount % amount == 0) {
this.s.request(amount);
}
}
#Override
public void onError(Throwable t) {
System.out.println(t.getLocalizedMessage())
}
#Override
public void onComplete() {
System.out.println("completed");
});
}
As you can see we are simply printing the String item which we receive and parsing it into an object using jackson wrapper. The problem we got now is that for most of our items everything works fine:
{"itemId": "someId", "itemDesc", "some description"}
But for some items the String is cut off like this for example:
{"itemId": "some"
And the next item after that would be
"Id", "itemDesc", "some description"}
There is no pattern for those cuts. It is completely random and it is different everytime we run that code. Ofcourse our jackson is gettin an error Unexpected end of Input with that behaviour.
So what is causing such a behaviour and how can we solve it?
Solution:
Send the Object inside the flux instead of the String:
public Flux<ItemIgnite> getAllFlux() {
return Flux.create(sink -> {
new Thread(){
public void run(){
Iterator<Cache.Entry<String, ItemIgnite>> iterator = getAllIterator();
while(iterator.hasNext()) {
sink.next(iterator.next().getValue());
}
}
} .start();
});
}
and use the following produces type:
#RequestMapping(value="/allFlux", method=RequestMethod.GET, produces="application/stream+json")
The key here is to use stream+json and not only json.

Choose Class in Birt is empty eventhough I have added jar in Datasource

Even though while creating dataset choose class window is empty. I am using Luna Service Release 2 (4.4.2).
From: http://yaragalla.blogspot.com/2013/10/using-pojo-datasource-in-birt-43.html
In the dataset class the three methods, “public void open(Object obj, Map map)”, “public Object next()” and “public void close()” must be implemented.
Make sure you have implemented these.
Here is a sample that I tested with:
public class UserDataSet {
public Iterator<User> itr;
public List<User> getUsers() throws ParseException {
List<User> users = new ArrayList<>();
// Add to Users
....
return users;
}
public void open(Object obj, Map<String, Object> map) {
try {
itr = getUsers().iterator();
} catch (ParseException e) {
e.printStackTrace();
}
}
public Object next() {
if (itr.hasNext())
return itr.next();
return null;
}
public void close() {
}
}

Functionaljava: sorting a list of arbitrary types

I have a very simple Java bean, WatchedFile, which has a fileName field.
I would like to sort a fj.data.List of WatchedFile objects, but I'm struggling with defining an fj.Ord for the list's sort() method. This is what I came up with:
protected List<WatchedFile> getWatchedFileList(String path) throws IOException {
List<File> files = List.list(new File(path).listFiles());
return files
.map((file) -> new WatchedFile(file.getName(), false, file.length()))
.sort(Ord.ord(new F<WatchedFile, F<WatchedFile, Ordering>>()
{
#Override
public F<WatchedFile, Ordering> f(final WatchedFile watchedFile1)
{
return new F<WatchedFile, Ordering>()
{
#Override
public Ordering f(final WatchedFile watchedFile2)
{
int compareResult = watchedFile1.fileName.compareTo(watchedFile2.fileName);
return (compareResult < 0 ? Ordering.LT :
(compareResult > 0 ? Ordering.GT : Ordering.EQ));
}
};
}
}));
}
This is ugly! I'm sure there is a better way of instantiating an Ord object... Possibly utilizing some Java 8 magick?
protected List<WatchedFile> getWatchedFileList(String path) throws IOException {
List<File> files = Arrays.asList(new File(path).listFiles());
return files.stream()
.map(file -> new WatchedFile(file.getName(), false, file.length()))
.sorted((wf1, wf2)->wf1.fileName.compareTo(wf2.fileName))
.collect(Collectors.toList());
}
It’s recommended to have a method public String getFileName() in your class WatchedFile. In that case you can simply say:
protected List<WatchedFile> getWatchedFileList(String path) throws IOException {
List<File> files = Arrays.asList(new File(path).listFiles());
return files.stream()
.map(file -> new WatchedFile(file.getName(), false, file.length()))
.sorted(Comparator.comparing(WatchedFile::getFileName))
.collect(Collectors.toList());
}
And, using NIO2 for getting the directory entries, it may look like:
protected List<WatchedFile> getWatchedFileList(String path) throws IOException {
try {
return Files.list(Paths.get(path))
.map(p -> new WatchedFile(p.toString(), false, fileSize(p)))
.sorted(Comparator.comparing(WatchedFile::getFileName))
.collect(Collectors.toList());
} catch(UncheckedIOException ex) { throw ex.getCause(); }
}
private long fileSize(Path path) {
try { return Files.size(path); }
catch (IOException ex) { throw new UncheckedIOException(ex); }
}
If you want to stay within the “functional-java” API, a solution can look like:
protected List<WatchedFile> getWatchedFileList(String path) throws IOException {
List<File> files = List.list(new File(path).listFiles());
return files
.map(file -> new WatchedFile(file.getName(), false, file.length()))
.sort(Ord.stringOrd.comap(wf -> wf.fileName));
}
The key point is that you don’t need (shouldn’t) re-implement the way, Strings are compared. Instead, specify the function to get the property value to compare. Compare with Java 8 factory method Comparator.comparing used in the second code example.

Resources