From 233e99fdb616b0faadd6b579a2a265278f99b702 Mon Sep 17 00:00:00 2001 From: muyangye Date: Tue, 29 Aug 2023 01:29:43 -0700 Subject: [PATCH 1/7] implement new round processor --- .../jvm/TransformationJvmInit.java | 4 +- .../jvm/processor/math/RoundProcessor.java | 81 +++++++++++++++++++ 2 files changed, 84 insertions(+), 1 deletion(-) create mode 100644 streampipes-extensions/streampipes-processors-transformation-jvm/src/main/java/org/apache/streampipes/processors/transformation/jvm/processor/math/RoundProcessor.java diff --git a/streampipes-extensions/streampipes-processors-transformation-jvm/src/main/java/org/apache/streampipes/processors/transformation/jvm/TransformationJvmInit.java b/streampipes-extensions/streampipes-processors-transformation-jvm/src/main/java/org/apache/streampipes/processors/transformation/jvm/TransformationJvmInit.java index dc39f429d7..62c886f22d 100644 --- a/streampipes-extensions/streampipes-processors-transformation-jvm/src/main/java/org/apache/streampipes/processors/transformation/jvm/TransformationJvmInit.java +++ b/streampipes-extensions/streampipes-processors-transformation-jvm/src/main/java/org/apache/streampipes/processors/transformation/jvm/TransformationJvmInit.java @@ -41,6 +41,7 @@ import org.apache.streampipes.processors.transformation.jvm.processor.fieldrename.FiledRenameProcessor; import org.apache.streampipes.processors.transformation.jvm.processor.hasher.FieldHasherProcessor; import org.apache.streampipes.processors.transformation.jvm.processor.mapper.FieldMapperProcessor; +import org.apache.streampipes.processors.transformation.jvm.processor.math.RoundProcessor; import org.apache.streampipes.processors.transformation.jvm.processor.measurementconverter.MeasurementUnitConverterProcessor; import org.apache.streampipes.processors.transformation.jvm.processor.state.labeler.number.NumberLabelerProcessor; import org.apache.streampipes.processors.transformation.jvm.processor.stringoperator.counter.StringCounterProcessor; @@ -90,7 +91,8 @@ public SpServiceDefinition provideServiceDefinition() { new StringToStateProcessor(), new StringCounterProcessor(), new BooleanOperatorProcessor(), - new FiledRenameProcessor()) + new FiledRenameProcessor(), + new RoundProcessor()) .registerMessagingFormats( new JsonDataFormatFactory(), new CborDataFormatFactory(), diff --git a/streampipes-extensions/streampipes-processors-transformation-jvm/src/main/java/org/apache/streampipes/processors/transformation/jvm/processor/math/RoundProcessor.java b/streampipes-extensions/streampipes-processors-transformation-jvm/src/main/java/org/apache/streampipes/processors/transformation/jvm/processor/math/RoundProcessor.java new file mode 100644 index 0000000000..663d762ae1 --- /dev/null +++ b/streampipes-extensions/streampipes-processors-transformation-jvm/src/main/java/org/apache/streampipes/processors/transformation/jvm/processor/math/RoundProcessor.java @@ -0,0 +1,81 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 org.apache.streampipes.processors.transformation.jvm.processor.math; + +import org.apache.streampipes.commons.exceptions.SpRuntimeException; +import org.apache.streampipes.extensions.api.pe.context.EventProcessorRuntimeContext; +import org.apache.streampipes.extensions.api.pe.routing.SpOutputCollector; +import org.apache.streampipes.model.graph.DataProcessorDescription; +import org.apache.streampipes.model.runtime.Event; +import org.apache.streampipes.model.schema.PropertyScope; +import org.apache.streampipes.sdk.builder.ProcessingElementBuilder; +import org.apache.streampipes.sdk.builder.StreamRequirementsBuilder; +import org.apache.streampipes.sdk.helpers.EpRequirements; +import org.apache.streampipes.sdk.helpers.Labels; +import org.apache.streampipes.sdk.helpers.OutputStrategies; +import org.apache.streampipes.wrapper.params.compat.ProcessorParams; +import org.apache.streampipes.wrapper.standalone.StreamPipesDataProcessor; + +import java.math.BigDecimal; +import java.math.RoundingMode; +import java.util.List; + +public class RoundProcessor extends StreamPipesDataProcessor { + + private List fieldsToBeRounded; + private int numDigits; + + private static final String FIELDS = "fields"; + private static final String NUM_DIGITS = "num-digits"; + + @Override + public DataProcessorDescription declareModel() { + return ProcessingElementBuilder + .create("package.org.apache.streampipes.processors.transformation.jvm.processor.math", "Round", "Round numeric values") + .requiredStream(StreamRequirementsBuilder + .create() + .requiredPropertyWithNaryMapping(EpRequirements.numberReq(), Labels.from(FIELDS, "Fields to Be Rounded", "fields to be rounded"), PropertyScope.NONE) + .build()) + .requiredIntegerParameter(Labels.from(NUM_DIGITS, "Number of Digits", "How many digits after decimal point to round/keep?")) + .outputStrategy(OutputStrategies.keep()) + .build(); + } + + @Override + public void onInvocation(ProcessorParams parameters, SpOutputCollector spOutputCollector, EventProcessorRuntimeContext runtimeContext) throws SpRuntimeException { + fieldsToBeRounded = parameters.extractor().mappingPropertyValues(FIELDS); + numDigits = parameters.extractor().singleValueParameter(NUM_DIGITS, Integer.class); + } + + @Override + public void onEvent(Event event, SpOutputCollector collector) throws SpRuntimeException { + for (String fieldToBeRounded : fieldsToBeRounded) { + double value = event.getFieldBySelector(fieldToBeRounded).getAsPrimitive().getAsDouble(); + double roundedValue = BigDecimal.valueOf(value).setScale(numDigits, RoundingMode.HALF_UP).doubleValue(); + event.removeFieldBySelector(fieldToBeRounded); + // Needs to remove "s0::“ in the beginning since addField uses runtime name + event.addField(fieldToBeRounded.substring(4), roundedValue); + } + collector.collect(event); + } + + @Override + public void onDetach() { + } +} \ No newline at end of file From ae587e1227408b9edbc174f166f3bf2e49162db5 Mon Sep 17 00:00:00 2001 From: muyangye Date: Tue, 29 Aug 2023 19:39:44 -0700 Subject: [PATCH 2/7] add English locale, icon, and documentation --- .../jvm/TransformationJvmInit.java | 2 +- .../{math => round}/RoundProcessor.java | 18 +++--- .../documentation.md | 53 ++++++++++++++++++ .../icon.png | Bin 0 -> 55365 bytes .../strings.en | 25 +++++++++ 5 files changed, 90 insertions(+), 8 deletions(-) rename streampipes-extensions/streampipes-processors-transformation-jvm/src/main/java/org/apache/streampipes/processors/transformation/jvm/processor/{math => round}/RoundProcessor.java (84%) create mode 100644 streampipes-extensions/streampipes-processors-transformation-jvm/src/main/resources/org.apache.streampipes.processors.transformation.jvm.round/documentation.md create mode 100644 streampipes-extensions/streampipes-processors-transformation-jvm/src/main/resources/org.apache.streampipes.processors.transformation.jvm.round/icon.png create mode 100644 streampipes-extensions/streampipes-processors-transformation-jvm/src/main/resources/org.apache.streampipes.processors.transformation.jvm.round/strings.en diff --git a/streampipes-extensions/streampipes-processors-transformation-jvm/src/main/java/org/apache/streampipes/processors/transformation/jvm/TransformationJvmInit.java b/streampipes-extensions/streampipes-processors-transformation-jvm/src/main/java/org/apache/streampipes/processors/transformation/jvm/TransformationJvmInit.java index 62c886f22d..4476b59c31 100644 --- a/streampipes-extensions/streampipes-processors-transformation-jvm/src/main/java/org/apache/streampipes/processors/transformation/jvm/TransformationJvmInit.java +++ b/streampipes-extensions/streampipes-processors-transformation-jvm/src/main/java/org/apache/streampipes/processors/transformation/jvm/TransformationJvmInit.java @@ -41,7 +41,7 @@ import org.apache.streampipes.processors.transformation.jvm.processor.fieldrename.FiledRenameProcessor; import org.apache.streampipes.processors.transformation.jvm.processor.hasher.FieldHasherProcessor; import org.apache.streampipes.processors.transformation.jvm.processor.mapper.FieldMapperProcessor; -import org.apache.streampipes.processors.transformation.jvm.processor.math.RoundProcessor; +import org.apache.streampipes.processors.transformation.jvm.processor.round.RoundProcessor; import org.apache.streampipes.processors.transformation.jvm.processor.measurementconverter.MeasurementUnitConverterProcessor; import org.apache.streampipes.processors.transformation.jvm.processor.state.labeler.number.NumberLabelerProcessor; import org.apache.streampipes.processors.transformation.jvm.processor.stringoperator.counter.StringCounterProcessor; diff --git a/streampipes-extensions/streampipes-processors-transformation-jvm/src/main/java/org/apache/streampipes/processors/transformation/jvm/processor/math/RoundProcessor.java b/streampipes-extensions/streampipes-processors-transformation-jvm/src/main/java/org/apache/streampipes/processors/transformation/jvm/processor/round/RoundProcessor.java similarity index 84% rename from streampipes-extensions/streampipes-processors-transformation-jvm/src/main/java/org/apache/streampipes/processors/transformation/jvm/processor/math/RoundProcessor.java rename to streampipes-extensions/streampipes-processors-transformation-jvm/src/main/java/org/apache/streampipes/processors/transformation/jvm/processor/round/RoundProcessor.java index 663d762ae1..257d4ab824 100644 --- a/streampipes-extensions/streampipes-processors-transformation-jvm/src/main/java/org/apache/streampipes/processors/transformation/jvm/processor/math/RoundProcessor.java +++ b/streampipes-extensions/streampipes-processors-transformation-jvm/src/main/java/org/apache/streampipes/processors/transformation/jvm/processor/round/RoundProcessor.java @@ -16,11 +16,12 @@ * */ -package org.apache.streampipes.processors.transformation.jvm.processor.math; +package org.apache.streampipes.processors.transformation.jvm.processor.round; import org.apache.streampipes.commons.exceptions.SpRuntimeException; import org.apache.streampipes.extensions.api.pe.context.EventProcessorRuntimeContext; import org.apache.streampipes.extensions.api.pe.routing.SpOutputCollector; +import org.apache.streampipes.model.DataProcessorType; import org.apache.streampipes.model.graph.DataProcessorDescription; import org.apache.streampipes.model.runtime.Event; import org.apache.streampipes.model.schema.PropertyScope; @@ -28,7 +29,9 @@ import org.apache.streampipes.sdk.builder.StreamRequirementsBuilder; import org.apache.streampipes.sdk.helpers.EpRequirements; import org.apache.streampipes.sdk.helpers.Labels; +import org.apache.streampipes.sdk.helpers.Locales; import org.apache.streampipes.sdk.helpers.OutputStrategies; +import org.apache.streampipes.sdk.utils.Assets; import org.apache.streampipes.wrapper.params.compat.ProcessorParams; import org.apache.streampipes.wrapper.standalone.StreamPipesDataProcessor; @@ -47,12 +50,15 @@ public class RoundProcessor extends StreamPipesDataProcessor { @Override public DataProcessorDescription declareModel() { return ProcessingElementBuilder - .create("package.org.apache.streampipes.processors.transformation.jvm.processor.math", "Round", "Round numeric values") + .create("org.apache.streampipes.processors.transformation.jvm.round") + .category(DataProcessorType.TRANSFORM) + .withLocales(Locales.EN) + .withAssets(Assets.DOCUMENTATION, Assets.ICON) .requiredStream(StreamRequirementsBuilder .create() - .requiredPropertyWithNaryMapping(EpRequirements.numberReq(), Labels.from(FIELDS, "Fields to Be Rounded", "fields to be rounded"), PropertyScope.NONE) + .requiredPropertyWithNaryMapping(EpRequirements.numberReq(), Labels.withId(FIELDS), PropertyScope.NONE) .build()) - .requiredIntegerParameter(Labels.from(NUM_DIGITS, "Number of Digits", "How many digits after decimal point to round/keep?")) + .requiredIntegerParameter(Labels.withId(NUM_DIGITS)) .outputStrategy(OutputStrategies.keep()) .build(); } @@ -68,9 +74,7 @@ public void onEvent(Event event, SpOutputCollector collector) throws SpRuntimeEx for (String fieldToBeRounded : fieldsToBeRounded) { double value = event.getFieldBySelector(fieldToBeRounded).getAsPrimitive().getAsDouble(); double roundedValue = BigDecimal.valueOf(value).setScale(numDigits, RoundingMode.HALF_UP).doubleValue(); - event.removeFieldBySelector(fieldToBeRounded); - // Needs to remove "s0::“ in the beginning since addField uses runtime name - event.addField(fieldToBeRounded.substring(4), roundedValue); + event.updateFieldBySelector(fieldToBeRounded, roundedValue); } collector.collect(event); } diff --git a/streampipes-extensions/streampipes-processors-transformation-jvm/src/main/resources/org.apache.streampipes.processors.transformation.jvm.round/documentation.md b/streampipes-extensions/streampipes-processors-transformation-jvm/src/main/resources/org.apache.streampipes.processors.transformation.jvm.round/documentation.md new file mode 100644 index 0000000000..15d47a5fec --- /dev/null +++ b/streampipes-extensions/streampipes-processors-transformation-jvm/src/main/resources/org.apache.streampipes.processors.transformation.jvm.round/documentation.md @@ -0,0 +1,53 @@ + + +## Number Rounder + +

+ +

+ +*** + +## Description + +This processor rounds numeric values to the given digit/precision. + +*** + +## Required input + +This processor requires an event that provides numbers. + +*** + +## Configuration + +### Fields to Be Rounded + +Select which fields of the event should be rounded. + +### Number of Digits + +Specify the number of digits after the decimal point to round/keep, e.g., if number is 2.8935 and #digits is 3, +the result will be 2.894. + +## Output + +The output of this processor is the same event with the fields selected by the ``Fiels to Be Rounded`` parameter rounded +to ``Number of Digits`` digits. \ No newline at end of file diff --git a/streampipes-extensions/streampipes-processors-transformation-jvm/src/main/resources/org.apache.streampipes.processors.transformation.jvm.round/icon.png b/streampipes-extensions/streampipes-processors-transformation-jvm/src/main/resources/org.apache.streampipes.processors.transformation.jvm.round/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..f4f8a24e3814e178eeb37c8b30bb2f4e96a3a455 GIT binary patch literal 55365 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

UCARSP=I&T~l5;I6% z`Lyv47K^S3ttSMe@~XaxO1z<4*z(fIO7drzKDEn8@@{Dwy7ar@S$o-qw(H17tz?tL zw5tp8307%q{Xsm0*zSH-IC!2$okA#(8e7-0jsMhwzo$9#P0;RyG@ z<@pzc3<;AAycwtPjxmhiKJNv%Eq(Tr&rQ6x&!24sidpID-$Fno$jIIz>+QrK@5bLh z@C#zL79G$ioNkZMVsW`}7wXWzbqnsIvi?qs+ z>|6ad4>`y8G3^r(m8_mOyUeyKJLR=UQFb5Ym$NgjSIax7QZzoCVrY@i)qDS}j6FT_ zQp?vy8!d~M9UGf(B>l(agnpChCW*Gisd1s4Sz(dg5`)l@5Y}0o$e>QB8*CHbzc&KA z3M?C*MhMF4T3A>}eR^F|Uj7I=9^t=+==SZ~H~0@=_Z%J{=Vsi>5F7|xG^f#G(JJN} zzxyPLH&J`Ww9~oL6mH~~94QklFd02uRdHQOY&9T3X-(|tr{kvMAuuv4ff*v-R(Xyx<^%zJ@wuF-mXIy4^A zuoYw%bxyoS ze~7s6cO>Rf_T%O2) z#gdoTx}Hv7@V3#;7;>=ZpG+htA^mIqzVERj%b)9TZqH-F;Ms+iy(AFIjEik3VI6Ad z?k+t!fyqTKq67OkvgnOTdKQ@8K&yqKPJsx4*#bw@++jTDcMroi%`LAe6fB69cZalS z^1|f+wq11jg`QwNzS9#97W7i_{!Ib-vIm^SkN6H-79Kb%6(iel`RHTcOXew;+_x)H zZBuR9x9-mw{EK?)vL`ch&vKnoo?tiEF1B&FONldb0HxqTAX&%TC$w|W$9cF(%*`J@ ztSUEHC*K9c4`YT9ahMKB6)B6Yul_FYCtB!3N_Q;L99i`;9ys@nRoQDCO5cffm_HWS zPq4GI!_h17WCvrEObX9HW%?bmosPft9^IB8`J)|NWIec(GbUEl#606PO8ZoHj$@TSVU zxru?-J$ID^LIsc{i$wMF{RdGa9n_T%nXuO|3r5)jia z-Txhe0Ono7tATsJhaskC7>0yc&f z3sgm!I&do{Xs5M>qhiNIp6!xhSif^T1{na&#()M;bPuW0!jO`UTn8U5SBEuNf>uED zHN4Ns{&FFlEdu!zRf-4}u&Ia$5ty)8>O2gd=x3ly4ERPOT|g1j!dPRjNy)=f z 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%0DvVRX2G(#p zQ5}kZNWC}GGHrZPlu_unC^LZH>D=k^yGtLoT|WsY%a zYPsH)9W7OF4NsR)({g3H?DO)WwSWc_R_mwKpEmxE*2iunTZ;q+gdEh*VpuD;G8a=?f<;~EC2((frT^OlTi)A_KAQmd+1UEO6& z>~~ykV$m1r^BG85=}bewqJUPEFY*H^WHg{rw)p4F*n#nu5$yV?2DFmO{}&gjDtoUl z&*`h8-e7qh=QXbSHtuyXA>@0@=QBHx<#2g&o^$44jHRc`vhMNnfT^H<6l0$zgT8yYriTxye7i$T4E;aRsEgk?oUe6TSP>+fI(N$|sNd1^<6 z*bn*m%O}4+nAA`7vdpyW9zLY|#rR>;MGdnNljOk`tOZ~Cj$N%;Zm8hmCrm2q6w+@& zPx)R)&XVLhAVy1UX6GoM7bJcg0Bn2%P122uoMa0?L&M@z>TFyIFA-Qv-DD%#NU_tO z9w&C{BytD0OfYVmb>|Cc(T_E}G!t?_r?cXxU&-;^EB3}o?H;CbB}}|0YLS5$G$qiy z>4jG#sqYj}zE%vzjmtlQ#Q`pE1dofOt|Q|fXGcN{;O3@pd{PZK=KyqPWBJa?p)3OC zs??W5en)aD?n_F_6r5&uIkeH;S#=S;eD;N?^mF^m)isLhUoNJ-{#{hwc3eskDJVks zFboi?ITD21+z5FwX;l!SA~roXBI@NX(GNGdEFsiqj)PD@1_*(w%`*2k-F%)fR&k8e zmsS4NhVm<7vr3gyfzgSazF8%`jJ}? zn`?D(B?g*6;%SS3b@#3p!RBf~O;(f> zpARknI`Ha7>m7NmFOlK$xoqX7*5{^v&O9<|DPW+{gj*7pAG~$5^GBaRy0#)yKz!Z9 z8DW;ISdvF^nlGK5d*LpeM10J&?wH8v<3n{?<}sc&C>cm_8w&gp%#=P`wp6+OFm0Gg zNTaM{j;r3dt0A?mq$9iJ=OxWINk;swGxYBcsPlD=(<=9Hd={-uVdt3}o*PawI?N^n zq0W9r<)WTbEgsOx`LpUOJc&k(3m=M5ED9uDKpP}l=$~C~AxgW?2~e?n0`mzB3Q~gP z7Sj`McpiB!qy0$9&)xBFi+t6y2gRksj*aUg)sp9NQ|hUfM8u?YlT=O6btJDeMCHI{n|OlZPh>9-i-B0n$|?< z$nFGcTZ>+d=`~29#5;RK{@#4Kd8kMEdyu?FOcaL^&O`RPg1>D;K)K52MD%>0Qe|Xz z9e%ZMDV_$oH3nPFmZ{w0?vR1yhxhsn2&YMRx%VLno2j4Gh%yjmuk2fZ3Z=kJ2pmeN z>AyQUY%z9@>U~vb{nDkpO0$8B6W>)hv5igsGO4Mx4i7qx**UN%Aby1iUlFm@JM)M1 zoV){@@vM-aAPxliK#^$ANGKbgK5n9)Z62;jG7{9m-a`yVjwl$Qv^g#QZq*^ugs-`n zb0`J`iyCwl=N*F%FChmADcDCU$;$MU)9oRTxvi+&&^~{v6IaRJjh~6_yN62vzY5)? zhE@P8w#Hq)c_85n{{c3LfUv`}@p;Xk-j$gws`ybZgfjm;O%T^d^F$U7+K|vlC@u3M zp0e#JHGw1geqQgIvd=~o1VDYPklCNe;OpHU(6iBpB`)%}KbA+)`?-a&jHR}ZN?EEv zg~T-K=+T1fXyhe*nR;4yu5>F6;&fb`tN-sg|3AI-f1jp^?#B}s@>d5rR(TZp5qZ}Z z{%`(A|K&d{p>r$zb;?hy8cvL+P$;gZ25M#p4^pW3o{6%UZaswo-_hZZ0v*?XzE`0W zqR`L(d=Z6m%Yw4_pT``+SMtwY{2|9Ie5H@3`{&X4S@fcRA5G5@P5K-uVDtZTfVJ%z z3p2O>en9?#hh{iH=s#z0w6HdHa6D~o_ur4{J)WO~V^)!4OkFL^cI~&dvb8^KciP01 zvVBGPA~pPy?LWU%#v`=M%p6P|Dbh0KbsmEFE$4rJt8L+GYGt5=liD~~*xFE}WyJ$8 g-U|7@k2(6kkC74=Z%1Z09z#)6KBSbac Date: Thu, 31 Aug 2023 09:38:40 -0700 Subject: [PATCH 3/7] fix checkstyle --- .../jvm/TransformationJvmInit.java | 2 +- .../jvm/processor/round/RoundProcessor.java | 72 +++++++++---------- 2 files changed, 37 insertions(+), 37 deletions(-) diff --git a/streampipes-extensions/streampipes-processors-transformation-jvm/src/main/java/org/apache/streampipes/processors/transformation/jvm/TransformationJvmInit.java b/streampipes-extensions/streampipes-processors-transformation-jvm/src/main/java/org/apache/streampipes/processors/transformation/jvm/TransformationJvmInit.java index 4476b59c31..337a0ca105 100644 --- a/streampipes-extensions/streampipes-processors-transformation-jvm/src/main/java/org/apache/streampipes/processors/transformation/jvm/TransformationJvmInit.java +++ b/streampipes-extensions/streampipes-processors-transformation-jvm/src/main/java/org/apache/streampipes/processors/transformation/jvm/TransformationJvmInit.java @@ -41,8 +41,8 @@ import org.apache.streampipes.processors.transformation.jvm.processor.fieldrename.FiledRenameProcessor; import org.apache.streampipes.processors.transformation.jvm.processor.hasher.FieldHasherProcessor; import org.apache.streampipes.processors.transformation.jvm.processor.mapper.FieldMapperProcessor; -import org.apache.streampipes.processors.transformation.jvm.processor.round.RoundProcessor; import org.apache.streampipes.processors.transformation.jvm.processor.measurementconverter.MeasurementUnitConverterProcessor; +import org.apache.streampipes.processors.transformation.jvm.processor.round.RoundProcessor; import org.apache.streampipes.processors.transformation.jvm.processor.state.labeler.number.NumberLabelerProcessor; import org.apache.streampipes.processors.transformation.jvm.processor.stringoperator.counter.StringCounterProcessor; import org.apache.streampipes.processors.transformation.jvm.processor.stringoperator.state.StringToStateProcessor; diff --git a/streampipes-extensions/streampipes-processors-transformation-jvm/src/main/java/org/apache/streampipes/processors/transformation/jvm/processor/round/RoundProcessor.java b/streampipes-extensions/streampipes-processors-transformation-jvm/src/main/java/org/apache/streampipes/processors/transformation/jvm/processor/round/RoundProcessor.java index 257d4ab824..842f0940fd 100644 --- a/streampipes-extensions/streampipes-processors-transformation-jvm/src/main/java/org/apache/streampipes/processors/transformation/jvm/processor/round/RoundProcessor.java +++ b/streampipes-extensions/streampipes-processors-transformation-jvm/src/main/java/org/apache/streampipes/processors/transformation/jvm/processor/round/RoundProcessor.java @@ -40,46 +40,46 @@ import java.util.List; public class RoundProcessor extends StreamPipesDataProcessor { + private List fieldsToBeRounded; + private int numDigits; - private List fieldsToBeRounded; - private int numDigits; + private static final String FIELDS = "fields"; + private static final String NUM_DIGITS = "num-digits"; - private static final String FIELDS = "fields"; - private static final String NUM_DIGITS = "num-digits"; + @Override + public DataProcessorDescription declareModel() { + return ProcessingElementBuilder + .create("org.apache.streampipes.processors.transformation.jvm.round") + .category(DataProcessorType.TRANSFORM) + .withLocales(Locales.EN) + .withAssets(Assets.DOCUMENTATION, Assets.ICON) + .requiredStream(StreamRequirementsBuilder + .create() + .requiredPropertyWithNaryMapping(EpRequirements.numberReq(), Labels.withId(FIELDS), PropertyScope.NONE) + .build()) + .requiredIntegerParameter(Labels.withId(NUM_DIGITS)) + .outputStrategy(OutputStrategies.keep()) + .build(); + } - @Override - public DataProcessorDescription declareModel() { - return ProcessingElementBuilder - .create("org.apache.streampipes.processors.transformation.jvm.round") - .category(DataProcessorType.TRANSFORM) - .withLocales(Locales.EN) - .withAssets(Assets.DOCUMENTATION, Assets.ICON) - .requiredStream(StreamRequirementsBuilder - .create() - .requiredPropertyWithNaryMapping(EpRequirements.numberReq(), Labels.withId(FIELDS), PropertyScope.NONE) - .build()) - .requiredIntegerParameter(Labels.withId(NUM_DIGITS)) - .outputStrategy(OutputStrategies.keep()) - .build(); - } - - @Override - public void onInvocation(ProcessorParams parameters, SpOutputCollector spOutputCollector, EventProcessorRuntimeContext runtimeContext) throws SpRuntimeException { - fieldsToBeRounded = parameters.extractor().mappingPropertyValues(FIELDS); - numDigits = parameters.extractor().singleValueParameter(NUM_DIGITS, Integer.class); - } + @Override + public void onInvocation(ProcessorParams parameters, SpOutputCollector spOutputCollector, + EventProcessorRuntimeContext runtimeContext) throws SpRuntimeException { + fieldsToBeRounded = parameters.extractor().mappingPropertyValues(FIELDS); + numDigits = parameters.extractor().singleValueParameter(NUM_DIGITS, Integer.class); + } - @Override - public void onEvent(Event event, SpOutputCollector collector) throws SpRuntimeException { - for (String fieldToBeRounded : fieldsToBeRounded) { - double value = event.getFieldBySelector(fieldToBeRounded).getAsPrimitive().getAsDouble(); - double roundedValue = BigDecimal.valueOf(value).setScale(numDigits, RoundingMode.HALF_UP).doubleValue(); - event.updateFieldBySelector(fieldToBeRounded, roundedValue); - } - collector.collect(event); + @Override + public void onEvent(Event event, SpOutputCollector collector) throws SpRuntimeException { + for (String fieldToBeRounded : fieldsToBeRounded) { + double value = event.getFieldBySelector(fieldToBeRounded).getAsPrimitive().getAsDouble(); + double roundedValue = BigDecimal.valueOf(value).setScale(numDigits, RoundingMode.HALF_UP).doubleValue(); + event.updateFieldBySelector(fieldToBeRounded, roundedValue); } + collector.collect(event); + } - @Override - public void onDetach() { - } + @Override + public void onDetach() { + } } \ No newline at end of file From 9afa9082f345aebad6aa445455c682e6905f087b Mon Sep 17 00:00:00 2001 From: muyangye Date: Fri, 1 Sep 2023 18:13:34 -0700 Subject: [PATCH 4/7] support different rounding modes --- .../jvm/processor/round/RoundProcessor.java | 22 ++++++++++++++++++- .../strings.en | 5 ++++- 2 files changed, 25 insertions(+), 2 deletions(-) diff --git a/streampipes-extensions/streampipes-processors-transformation-jvm/src/main/java/org/apache/streampipes/processors/transformation/jvm/processor/round/RoundProcessor.java b/streampipes-extensions/streampipes-processors-transformation-jvm/src/main/java/org/apache/streampipes/processors/transformation/jvm/processor/round/RoundProcessor.java index 842f0940fd..a0688e575f 100644 --- a/streampipes-extensions/streampipes-processors-transformation-jvm/src/main/java/org/apache/streampipes/processors/transformation/jvm/processor/round/RoundProcessor.java +++ b/streampipes-extensions/streampipes-processors-transformation-jvm/src/main/java/org/apache/streampipes/processors/transformation/jvm/processor/round/RoundProcessor.java @@ -30,6 +30,7 @@ import org.apache.streampipes.sdk.helpers.EpRequirements; import org.apache.streampipes.sdk.helpers.Labels; import org.apache.streampipes.sdk.helpers.Locales; +import org.apache.streampipes.sdk.helpers.Options; import org.apache.streampipes.sdk.helpers.OutputStrategies; import org.apache.streampipes.sdk.utils.Assets; import org.apache.streampipes.wrapper.params.compat.ProcessorParams; @@ -37,14 +38,29 @@ import java.math.BigDecimal; import java.math.RoundingMode; +import java.util.HashMap; import java.util.List; +import java.util.Map; public class RoundProcessor extends StreamPipesDataProcessor { private List fieldsToBeRounded; private int numDigits; + private String roundingMode; private static final String FIELDS = "fields"; private static final String NUM_DIGITS = "num-digits"; + private static final String ROUNDING_MODE = "rounding-mode"; + private static final Map ROUNDING_MODE_MAP = new HashMap() { + { + put("UP", RoundingMode.UP); + put("DOWN", RoundingMode.DOWN); + put("CEILING", RoundingMode.CEILING); + put("FLOOR", RoundingMode.FLOOR); + put("HALF_UP", RoundingMode.HALF_UP); + put("HALF_DOWN", RoundingMode.HALF_DOWN); + put("HALF_EVEN", RoundingMode.HALF_EVEN); + } + }; @Override public DataProcessorDescription declareModel() { @@ -58,6 +74,8 @@ public DataProcessorDescription declareModel() { .requiredPropertyWithNaryMapping(EpRequirements.numberReq(), Labels.withId(FIELDS), PropertyScope.NONE) .build()) .requiredIntegerParameter(Labels.withId(NUM_DIGITS)) + .requiredSingleValueSelection(Labels.withId(ROUNDING_MODE), + Options.from(ROUNDING_MODE_MAP.keySet().toArray(new String[0]))) .outputStrategy(OutputStrategies.keep()) .build(); } @@ -67,13 +85,15 @@ public void onInvocation(ProcessorParams parameters, SpOutputCollector spOutputC EventProcessorRuntimeContext runtimeContext) throws SpRuntimeException { fieldsToBeRounded = parameters.extractor().mappingPropertyValues(FIELDS); numDigits = parameters.extractor().singleValueParameter(NUM_DIGITS, Integer.class); + roundingMode = parameters.extractor().selectedSingleValue(ROUNDING_MODE, String.class); } @Override public void onEvent(Event event, SpOutputCollector collector) throws SpRuntimeException { for (String fieldToBeRounded : fieldsToBeRounded) { double value = event.getFieldBySelector(fieldToBeRounded).getAsPrimitive().getAsDouble(); - double roundedValue = BigDecimal.valueOf(value).setScale(numDigits, RoundingMode.HALF_UP).doubleValue(); + double roundedValue = + BigDecimal.valueOf(value).setScale(numDigits, ROUNDING_MODE_MAP.get(roundingMode)).doubleValue(); event.updateFieldBySelector(fieldToBeRounded, roundedValue); } collector.collect(event); diff --git a/streampipes-extensions/streampipes-processors-transformation-jvm/src/main/resources/org.apache.streampipes.processors.transformation.jvm.round/strings.en b/streampipes-extensions/streampipes-processors-transformation-jvm/src/main/resources/org.apache.streampipes.processors.transformation.jvm.round/strings.en index f3ff9a91ba..43705faf15 100644 --- a/streampipes-extensions/streampipes-processors-transformation-jvm/src/main/resources/org.apache.streampipes.processors.transformation.jvm.round/strings.en +++ b/streampipes-extensions/streampipes-processors-transformation-jvm/src/main/resources/org.apache.streampipes.processors.transformation.jvm.round/strings.en @@ -22,4 +22,7 @@ fields.title=Fields to Be Rounded fields.description=The fields which should be rounded num-digits.title=Number of Digits -num-digits.description=How many digits after decimal point to round/keep? \ No newline at end of file +num-digits.description=How many digits after decimal point to round/keep? + +rounding-mode.title=Mode of Rounding +rounding-mode.description=See https://docs.oracle.com/javase/8/docs/api/java/math/RoundingMode.html \ No newline at end of file From ce658e62fe6fcb02e29d5c5bb7029bd5c368ed5b Mon Sep 17 00:00:00 2001 From: muyangye Date: Fri, 1 Sep 2023 18:59:18 -0700 Subject: [PATCH 5/7] add rounding mode in documentation --- .../documentation.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/streampipes-extensions/streampipes-processors-transformation-jvm/src/main/resources/org.apache.streampipes.processors.transformation.jvm.round/documentation.md b/streampipes-extensions/streampipes-processors-transformation-jvm/src/main/resources/org.apache.streampipes.processors.transformation.jvm.round/documentation.md index 15d47a5fec..a1478363b0 100644 --- a/streampipes-extensions/streampipes-processors-transformation-jvm/src/main/resources/org.apache.streampipes.processors.transformation.jvm.round/documentation.md +++ b/streampipes-extensions/streampipes-processors-transformation-jvm/src/main/resources/org.apache.streampipes.processors.transformation.jvm.round/documentation.md @@ -47,6 +47,11 @@ Select which fields of the event should be rounded. Specify the number of digits after the decimal point to round/keep, e.g., if number is 2.8935 and #digits is 3, the result will be 2.894. +### Mode of Rounding + +Specify the mode of rounding. All supported modes +are [here](https://docs.oracle.com/javase/8/docs/api/java/math/RoundingMode.html). + ## Output The output of this processor is the same event with the fields selected by the ``Fiels to Be Rounded`` parameter rounded From 5b9aa41d7d938fb55a75dfca9025858d1cd9f06f Mon Sep 17 00:00:00 2001 From: muyangye Date: Sun, 17 Sep 2023 17:23:52 -0700 Subject: [PATCH 6/7] fix time display --- ui/src/app/data-explorer/data-explorer.module.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ui/src/app/data-explorer/data-explorer.module.ts b/ui/src/app/data-explorer/data-explorer.module.ts index e902f19a35..1b19a70f60 100644 --- a/ui/src/app/data-explorer/data-explorer.module.ts +++ b/ui/src/app/data-explorer/data-explorer.module.ts @@ -109,7 +109,7 @@ export const MY_NATIVE_FORMATS = { day: 'numeric', hour: 'numeric', minute: 'numeric', - hour12: false, + hourCycle: 'h23', }, datePickerInput: { year: 'numeric', From 83d386cce950707959f82821032a2e57ce03bd0e Mon Sep 17 00:00:00 2001 From: muyangye Date: Sat, 30 Sep 2023 03:16:09 -0700 Subject: [PATCH 7/7] let NaryMapping selection account for property scope --- .../static-mapping-nary.component.ts | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/ui/src/app/core-ui/static-properties/static-mapping-nary/static-mapping-nary.component.ts b/ui/src/app/core-ui/static-properties/static-mapping-nary/static-mapping-nary.component.ts index 42b6208d97..98e9c80447 100644 --- a/ui/src/app/core-ui/static-properties/static-mapping-nary/static-mapping-nary.component.ts +++ b/ui/src/app/core-ui/static-properties/static-mapping-nary/static-mapping-nary.component.ts @@ -19,6 +19,7 @@ import { Component, EventEmitter, OnInit, Output } from '@angular/core'; import { StaticMappingComponent } from '../static-mapping/static-mapping'; import { MappingPropertyNary } from '@streampipes/platform-services'; +import { DisplayRecommendedPipe } from '../filter/display-recommended.pipe'; @Component({ selector: 'sp-app-static-mapping-nary', @@ -31,7 +32,7 @@ export class StaticMappingNaryComponent { @Output() inputEmitter: EventEmitter = new EventEmitter(); - constructor() { + constructor(private displayRecommendedPipe: DisplayRecommendedPipe) { super(); } @@ -40,7 +41,12 @@ export class StaticMappingNaryComponent if (!this.staticProperty.selectedProperties) { this.selectNone(); } else { - this.availableProperties.forEach(ep => { + let recommendedProperties = this.displayRecommendedPipe.transform( + this.availableProperties, + this.staticProperty.propertyScope, + this.displayRecommended, + ); + recommendedProperties.forEach(ep => { if ( this.staticProperty.selectedProperties.indexOf( ep.propertySelector, @@ -85,7 +91,12 @@ export class StaticMappingNaryComponent selectAll() { this.selectNone(); - this.availableProperties.forEach(ep => { + let recommendedProperties = this.displayRecommendedPipe.transform( + this.availableProperties, + this.staticProperty.propertyScope, + this.displayRecommended, + ); + recommendedProperties.forEach(ep => { ep['checked'] = true; this.addProperty(ep); });