/* * 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.flink.streaming.api.operators; import org.apache.flink.api.common.JobExecutionResult; import org.apache.flink.api.common.functions.FoldFunction; import org.apache.flink.api.common.functions.util.ListCollector; import org.apache.flink.api.common.typeinfo.BasicTypeInfo; import org.apache.flink.api.common.typeutils.base.IntSerializer; import org.apache.flink.api.java.functions.KeySelector; import org.apache.flink.streaming.api.environment.StreamExecutionEnvironment; import org.apache.flink.streaming.api.functions.source.SourceFunction; import org.apache.flink.streaming.api.functions.windowing.FoldApplyWindowFunction; import org.apache.flink.streaming.api.functions.windowing.WindowFunction; import org.apache.flink.streaming.api.graph.StreamGraph; import org.apache.flink.streaming.api.graph.StreamGraphGenerator; import org.apache.flink.streaming.api.transformations.OneInputTransformation; import org.apache.flink.streaming.api.transformations.SourceTransformation; import org.apache.flink.streaming.api.transformations.StreamTransformation; import org.apache.flink.streaming.api.windowing.windows.TimeWindow; import org.apache.flink.streaming.runtime.operators.windowing.AccumulatingProcessingTimeWindowOperator; import org.apache.flink.streaming.runtime.operators.windowing.functions.InternalIterableWindowFunction; import org.apache.flink.util.Collector; import org.junit.Test; import org.junit.Assert; import java.util.ArrayList; import java.util.List; public class FoldApplyWindowFunctionTest { /** * Tests that the FoldWindowFunction gets the output type serializer set by the * StreamGraphGenerator and checks that the FoldWindowFunction computes the correct result. */ @Test public void testFoldWindowFunctionOutputTypeConfigurable() throws Exception{ StreamExecutionEnvironment env = new DummyStreamExecutionEnvironment(); List<StreamTransformation<?>> transformations = new ArrayList<>(); int initValue = 1; FoldApplyWindowFunction<Integer, TimeWindow, Integer, Integer, Integer> foldWindowFunction = new FoldApplyWindowFunction<>( initValue, new FoldFunction<Integer, Integer>() { private static final long serialVersionUID = -4849549768529720587L; @Override public Integer fold(Integer accumulator, Integer value) throws Exception { return accumulator + value; } }, new WindowFunction<Integer, Integer, Integer, TimeWindow>() { @Override public void apply(Integer integer, TimeWindow window, Iterable<Integer> input, Collector<Integer> out) throws Exception { for (Integer in: input) { out.collect(in); } } }, BasicTypeInfo.INT_TYPE_INFO ); AccumulatingProcessingTimeWindowOperator<Integer, Integer, Integer> windowOperator = new AccumulatingProcessingTimeWindowOperator<>( new InternalIterableWindowFunction<>( foldWindowFunction), new KeySelector<Integer, Integer>() { private static final long serialVersionUID = -7951310554369722809L; @Override public Integer getKey(Integer value) throws Exception { return value; } }, IntSerializer.INSTANCE, IntSerializer.INSTANCE, 3000, 3000 ); SourceFunction<Integer> sourceFunction = new SourceFunction<Integer>(){ private static final long serialVersionUID = 8297735565464653028L; @Override public void run(SourceContext<Integer> ctx) throws Exception { } @Override public void cancel() { } }; SourceTransformation<Integer> source = new SourceTransformation<>("", new StreamSource<>(sourceFunction), BasicTypeInfo.INT_TYPE_INFO, 1); transformations.add(new OneInputTransformation<>(source, "test", windowOperator, BasicTypeInfo.INT_TYPE_INFO, 1)); StreamGraph streamGraph = StreamGraphGenerator.generate(env, transformations); List<Integer> result = new ArrayList<>(); List<Integer> input = new ArrayList<>(); List<Integer> expected = new ArrayList<>(); input.add(1); input.add(2); input.add(3); for (int value : input) { initValue += value; } expected.add(initValue); foldWindowFunction.apply(0, new TimeWindow(0, 1), input, new ListCollector<Integer>(result)); Assert.assertEquals(expected, result); } public static class DummyStreamExecutionEnvironment extends StreamExecutionEnvironment { @Override public JobExecutionResult execute(String jobName) throws Exception { return null; } } }