diff options
Diffstat (limited to 'common-app-api')
12 files changed, 455 insertions, 67 deletions
diff --git a/common-app-api/pom.xml b/common-app-api/pom.xml index 469effc65a..bbb608a017 100644 --- a/common-app-api/pom.xml +++ b/common-app-api/pom.xml @@ -403,12 +403,6 @@ </exclusion> </exclusions> </dependency> - <dependency> - <groupId>org.onap.sdc.common</groupId> - <artifactId>onap-configuration-management-api</artifactId> - <version>${project.version}</version> - <scope>compile</scope> - </dependency> </dependencies> <build> diff --git a/common-app-api/src/main/java/org/openecomp/sdc/be/config/ConfigurationManager.java b/common-app-api/src/main/java/org/openecomp/sdc/be/config/ConfigurationManager.java index 03cbc5952a..7241decd62 100644 --- a/common-app-api/src/main/java/org/openecomp/sdc/be/config/ConfigurationManager.java +++ b/common-app-api/src/main/java/org/openecomp/sdc/be/config/ConfigurationManager.java @@ -20,6 +20,8 @@ package org.openecomp.sdc.be.config; import com.google.common.annotations.VisibleForTesting; +import java.util.HashMap; +import java.util.Map; import org.openecomp.sdc.be.config.validation.ArtifactConfigValidator; import org.openecomp.sdc.common.api.ArtifactTypeEnum; import org.openecomp.sdc.common.api.BasicConfiguration; @@ -29,14 +31,11 @@ import org.openecomp.sdc.common.api.FileChangeCallback; import org.openecomp.sdc.common.config.EcompErrorConfiguration; import org.openecomp.sdc.common.config.IEcompConfigurationManager; -import java.util.HashMap; -import java.util.Map; - public class ConfigurationManager implements FileChangeCallback, IEcompConfigurationManager { private static ConfigurationManager instance; final Map<String, Object> configurations = new HashMap<>(); - private ConfigurationSource configurationSource; + ConfigurationSource configurationSource = null; @VisibleForTesting public ConfigurationManager() { @@ -68,7 +67,7 @@ public class ConfigurationManager implements FileChangeCallback, IEcompConfigura final Object configurationObj = configurations.get(getKey(Configuration.class)); if (configurationObj instanceof Configuration) { final ArtifactConfigValidator artifactConfigValidator = new ArtifactConfigValidator((Configuration) configurationObj, - ArtifactTypeEnum.getBaseArtifacts()); + ArtifactTypeEnum.getBaseArtifacts()); artifactConfigValidator.validate(); } } diff --git a/common-app-api/src/main/java/org/openecomp/sdc/common/http/client/api/HttpClientFactory.java b/common-app-api/src/main/java/org/openecomp/sdc/common/http/client/api/HttpClientFactory.java index 599c43ac67..d45deb328b 100644 --- a/common-app-api/src/main/java/org/openecomp/sdc/common/http/client/api/HttpClientFactory.java +++ b/common-app-api/src/main/java/org/openecomp/sdc/common/http/client/api/HttpClientFactory.java @@ -23,17 +23,15 @@ import org.apache.http.client.HttpRequestRetryHandler; import org.apache.http.client.UserTokenHandler; import org.apache.http.client.config.RequestConfig; import org.apache.http.conn.HttpClientConnectionManager; -import org.apache.http.impl.client.HttpClientBuilder; +import org.apache.http.impl.client.CloseableHttpClient; import org.apache.http.impl.client.HttpClients; -import org.onap.config.api.JettySSLUtils; import org.openecomp.sdc.common.api.Constants; import org.openecomp.sdc.common.http.config.ClientCertificate; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; +import org.openecomp.sdc.common.log.wrappers.Logger; public class HttpClientFactory { - private static final Logger LOGGER = LoggerFactory.getLogger(HttpClientFactory.class); + private static final Logger logger = Logger.getLogger(HttpClientFactory.class.getName()); private static final UserTokenHandler userTokenHandler = context -> null; private final HttpConnectionMngFactory connectionMngFactory; @@ -42,25 +40,13 @@ public class HttpClientFactory { } HttpClient createClient(String protocol, HttpClientConfigImmutable config) { - LOGGER.debug("Create {} client based on {}", protocol, config); - final ClientCertificate clientCertificate = Constants.HTTPS.equals(protocol) ? config.getClientCertificate() : null; - final HttpClientConnectionManager connectionManager = connectionMngFactory.getOrCreate(clientCertificate); - final RequestConfig requestConfig = createClientTimeoutConfiguration(config); - - try { - final HttpClientBuilder httpClientBuilder = HttpClients.custom() - .setDefaultRequestConfig(requestConfig) - .setConnectionManager(connectionManager) - .setUserTokenHandler(userTokenHandler) - .setRetryHandler(resolveRetryHandler(config)); - if (clientCertificate != null) { - httpClientBuilder.setSSLContext(JettySSLUtils.getSslContext()); - } - return new HttpClient(httpClientBuilder.build(), config); - } catch (Exception e) { - LOGGER.error("Failed to createClient", e); - throw new RuntimeException(e); - } + logger.debug("Create {} client based on {}", protocol, config); + ClientCertificate clientCertificate = Constants.HTTPS.equals(protocol) ? config.getClientCertificate() : null; + HttpClientConnectionManager connectionManager = connectionMngFactory.getOrCreate(clientCertificate); + RequestConfig requestConfig = createClientTimeoutConfiguration(config); + CloseableHttpClient client = HttpClients.custom().setDefaultRequestConfig(requestConfig).setConnectionManager(connectionManager) + .setUserTokenHandler(userTokenHandler).setRetryHandler(resolveRetryHandler(config)).build(); + return new HttpClient(client, config); } private HttpRequestRetryHandler resolveRetryHandler(HttpClientConfigImmutable config) { diff --git a/common-app-api/src/main/java/org/openecomp/sdc/common/http/client/api/HttpResponse.java b/common-app-api/src/main/java/org/openecomp/sdc/common/http/client/api/HttpResponse.java index bd5990eed5..573c97f130 100644 --- a/common-app-api/src/main/java/org/openecomp/sdc/common/http/client/api/HttpResponse.java +++ b/common-app-api/src/main/java/org/openecomp/sdc/common/http/client/api/HttpResponse.java @@ -19,12 +19,8 @@ */ package org.openecomp.sdc.common.http.client.api; -import lombok.AllArgsConstructor; -import lombok.Getter; import org.apache.commons.lang3.StringUtils; -@Getter -@AllArgsConstructor public class HttpResponse<T> { private final T response; @@ -32,11 +28,39 @@ public class HttpResponse<T> { private final String description; public HttpResponse(T response, int statusCode) { - this(response, statusCode, StringUtils.EMPTY); + this.response = response; + this.statusCode = statusCode; + this.description = StringUtils.EMPTY; + } + + public HttpResponse(T response, int statusCode, String description) { + this.response = response; + this.statusCode = statusCode; + this.description = description; + } + + public T getResponse() { + return response; + } + + public int getStatusCode() { + return statusCode; + } + + public String getDescription() { + return description; } @Override public String toString() { - return "HttpResponse [response=" + response + ", statusCode=" + statusCode + ", description=" + description + "]"; + StringBuilder builder = new StringBuilder(); + builder.append("HttpResponse [response="); + builder.append(response); + builder.append(", statusCode="); + builder.append(statusCode); + builder.append(", description="); + builder.append(description); + builder.append("]"); + return builder.toString(); } } diff --git a/common-app-api/src/main/java/org/openecomp/sdc/common/listener/AppContextListener.java b/common-app-api/src/main/java/org/openecomp/sdc/common/listener/AppContextListener.java index d85dab0db6..70a94fd460 100644 --- a/common-app-api/src/main/java/org/openecomp/sdc/common/listener/AppContextListener.java +++ b/common-app-api/src/main/java/org/openecomp/sdc/common/listener/AppContextListener.java @@ -39,7 +39,6 @@ public class AppContextListener implements ServletContextListener { private static Logger log = Logger.getLogger(AppContextListener.class.getName()); - @Override public void contextInitialized(ServletContextEvent context) { log.debug("ServletContextListener initialized "); log.debug("After read values from Manifest {}", getManifestInfo(context.getServletContext())); @@ -58,7 +57,6 @@ public class AppContextListener implements ServletContextListener { ExternalConfiguration.listenForChanges(); } - @Override public void contextDestroyed(ServletContextEvent context) { log.debug("ServletContextListener destroyed"); ExternalConfiguration.stopListenForFileChanges(); diff --git a/common-app-api/src/main/java/org/openecomp/sdc/common/log/interceptors/ApacheClientLogRequestInterceptor.java b/common-app-api/src/main/java/org/openecomp/sdc/common/log/interceptors/ApacheClientLogRequestInterceptor.java new file mode 100644 index 0000000000..82bf295762 --- /dev/null +++ b/common-app-api/src/main/java/org/openecomp/sdc/common/log/interceptors/ApacheClientLogRequestInterceptor.java @@ -0,0 +1,63 @@ +package org.openecomp.sdc.common.log.interceptors; + +import java.io.IOException; +import java.net.URI; +import org.apache.http.HttpException; +import org.apache.http.HttpMessage; +import org.apache.http.HttpRequest; +import org.apache.http.HttpRequestInterceptor; +import org.apache.http.HttpResponse; +import org.apache.http.protocol.HttpContext; +import org.onap.logging.filter.base.AbstractMetricLogFilter; +import org.onap.logging.ref.slf4j.ONAPLogConstants; +import org.openecomp.sdc.common.log.elements.LogFieldsMdcHandler; + +public class ApacheClientLogRequestInterceptor extends AbstractMetricLogFilter<HttpRequest, HttpResponse, HttpMessage> implements + HttpRequestInterceptor { + + private String previousInvocationId; + + @Override + protected void addHeader(HttpMessage httpMessage, String s, String s1) { + httpMessage.addHeader(s, s1); + } + + @Override + protected String getTargetServiceName(HttpRequest httpRequest) { + return httpRequest.getRequestLine().getUri(); + } + + @Override + protected String getServiceName(HttpRequest httpRequest) { + return URI.create(httpRequest.getRequestLine().getUri()).getPath(); + } + + @Override + protected int getHttpStatusCode(HttpResponse httpResponse) { + return httpResponse.getStatusLine().getStatusCode(); + } + + @Override + protected String getResponseCode(HttpResponse httpResponse) { + return String.valueOf(httpResponse.getStatusLine().getStatusCode()); + } + + @Override + protected String getTargetEntity(HttpRequest httpRequest) { + //fallback to default value that provided by AbstractMetricLogFilter + return null; + } + + @Override + protected void additionalPre(HttpRequest httpRequest, HttpMessage httpMessage) { + String outgoingInvocationId = httpMessage.getFirstHeader(ONAPLogConstants.Headers.INVOCATION_ID).getValue(); + LogFieldsMdcHandler.getInstance().setOutgoingInvocationId(outgoingInvocationId); + LogFieldsMdcHandler.getInstance().setKeyInvocationId(previousInvocationId); + } + + @Override + public void process(HttpRequest httpRequest, HttpContext httpContext) throws HttpException, IOException { + previousInvocationId = LogFieldsMdcHandler.getInstance().getKeyInvocationId(); + super.pre(httpRequest, httpRequest); + } +} diff --git a/common-app-api/src/main/java/org/openecomp/sdc/common/log/interceptors/ApacheClientLogResponseInterceptor.java b/common-app-api/src/main/java/org/openecomp/sdc/common/log/interceptors/ApacheClientLogResponseInterceptor.java new file mode 100644 index 0000000000..26c7c2540b --- /dev/null +++ b/common-app-api/src/main/java/org/openecomp/sdc/common/log/interceptors/ApacheClientLogResponseInterceptor.java @@ -0,0 +1,51 @@ +package org.openecomp.sdc.common.log.interceptors; + +import java.io.IOException; +import java.net.URI; +import org.apache.http.HttpException; +import org.apache.http.HttpMessage; +import org.apache.http.HttpRequest; +import org.apache.http.HttpResponse; +import org.apache.http.HttpResponseInterceptor; +import org.apache.http.protocol.HttpContext; +import org.onap.logging.filter.base.AbstractMetricLogFilter; + +public class ApacheClientLogResponseInterceptor extends AbstractMetricLogFilter<HttpRequest, HttpResponse, HttpMessage> implements + HttpResponseInterceptor { + + @Override + protected void addHeader(HttpMessage httpMessage, String s, String s1) { + httpMessage.addHeader(s, s1); + } + + @Override + protected String getTargetServiceName(HttpRequest httpRequest) { + return httpRequest.getRequestLine().getUri(); + } + + @Override + protected String getServiceName(HttpRequest httpRequest) { + return URI.create(httpRequest.getRequestLine().getUri()).getPath(); + } + + @Override + protected int getHttpStatusCode(HttpResponse httpResponse) { + return httpResponse.getStatusLine().getStatusCode(); + } + + @Override + protected String getResponseCode(HttpResponse httpResponse) { + return String.valueOf(httpResponse.getStatusLine().getStatusCode()); + } + + @Override + protected String getTargetEntity(HttpRequest httpRequest) { + //fallback to default value that provided by AbstractMetricLogFilter + return null; + } + + @Override + public void process(HttpResponse httpResponse, HttpContext httpContext) throws HttpException, IOException { + super.post(null, httpResponse); + } +} diff --git a/common-app-api/src/main/java/org/openecomp/sdc/common/util/StreamUtils.java b/common-app-api/src/main/java/org/openecomp/sdc/common/util/StreamUtils.java new file mode 100644 index 0000000000..37769fbaef --- /dev/null +++ b/common-app-api/src/main/java/org/openecomp/sdc/common/util/StreamUtils.java @@ -0,0 +1,132 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ +package org.openecomp.sdc.common.util; + +import java.util.ArrayList; +import java.util.List; +import java.util.Spliterator; +import java.util.Spliterators.AbstractSpliterator; +import java.util.function.Consumer; +import java.util.function.Predicate; +import java.util.stream.Stream; +import java.util.stream.StreamSupport; + +/** + * Utility Class For Actions On Streams + * + * @author mshitrit + */ +public final class StreamUtils { + + private StreamUtils() { + throw new UnsupportedOperationException(); + } + + /** + * Breaks the stream when the predicate is not met.<br> Does not evaluate elements after the stream breaks.<br> This method evaluates the + * stream.<br> + * + * @param stream + * @param predicate + * @return + */ + public static <T> Stream<T> takeWhilePlusOneNoEval(Stream<T> stream, Predicate<T> predicate) { + List<T> results = new ArrayList<>(); + Consumer<T> listAdder = results::add; + stream.map(e -> { + listAdder.accept(e); + return e; + }).filter(e -> !predicate.test(e)).findFirst(); + return results.stream(); + } + + public static <T> Stream<T> takeWhile(Stream<T> stream, Predicate<T> predicate) { + return StreamSupport.stream(takeWhile(stream.spliterator(), predicate), false); + } + + public static <T> Stream<T> takeWhilePlusOne(Stream<T> stream, Predicate<T> predicate) { + return StreamSupport.stream(takeWhile(stream.spliterator(), new StopAfterFailPredicate<>(predicate)), false); + } + + private static <T> Spliterator<T> takeWhile(Spliterator<T> splitr, Predicate<T> predicate) { + return new MySplitIterator<>(splitr, predicate); + } + + public static class MySplitIterator<T> extends AbstractSpliterator<T> implements Spliterator<T> { + + boolean stillGoing = true; + private Spliterator<T> innerItr; + private Predicate<T> innerPred; + + private MySplitIterator(Spliterator<T> splitItr, Predicate<T> pred) { + super(splitItr.estimateSize(), 0); + innerItr = splitItr; + innerPred = pred; + } + + @Override + public boolean tryAdvance(Consumer<? super T> action) { + boolean canAdvance = true; + if (stillGoing) { + stillGoing = innerItr.tryAdvance(createConsumerWrapper(action)); + } else { + canAdvance = false; + } + return canAdvance; + } + + private Consumer<? super T> createConsumerWrapper(Consumer<? super T> action) { + return new Consumer<T>() { + @Override + public void accept(T t) { + stillGoing = innerPred.test(t); + if (stillGoing) { + action.accept(t); + } + } + }; + } + } + + public static class StopAfterFailPredicate<T> implements Predicate<T> { + + boolean hasNotFailed; + Predicate<T> innerPredicate; + + private StopAfterFailPredicate(Predicate<T> pred) { + hasNotFailed = true; + innerPredicate = pred; + } + + ; + + @Override + public boolean test(T t) { + boolean isPassed; + if (hasNotFailed) { + isPassed = true; + hasNotFailed = innerPredicate.test(t); + } else { + isPassed = false; + } + return isPassed; + } + } +} diff --git a/common-app-api/src/main/java/org/openecomp/sdc/fe/config/ConfigurationManager.java b/common-app-api/src/main/java/org/openecomp/sdc/fe/config/ConfigurationManager.java index 798bacf9a3..0d5cf62cb1 100644 --- a/common-app-api/src/main/java/org/openecomp/sdc/fe/config/ConfigurationManager.java +++ b/common-app-api/src/main/java/org/openecomp/sdc/fe/config/ConfigurationManager.java @@ -34,8 +34,8 @@ public class ConfigurationManager implements FileChangeCallback, IEcompConfigura private static final Logger log = Logger.getLogger(ConfigurationManager.class.getName()); private static ConfigurationManager instance; - private final ConfigurationSource configurationSource; - private final Map<String, Object> configurations = new HashMap<>(); + ConfigurationSource configurationSource = null; + Map<String, Object> configurations = new HashMap<>(); public ConfigurationManager(ConfigurationSource configurationSource) { super(); @@ -101,7 +101,6 @@ public class ConfigurationManager implements FileChangeCallback, IEcompConfigura return (Configuration) configurations.get(getKey(Configuration.class)); } - @Override public void reconfigure(BasicConfiguration obj) { // diff --git a/common-app-api/src/test/java/org/openecomp/sdc/common/http/client/api/HttpClientFactoryTest.java b/common-app-api/src/test/java/org/openecomp/sdc/common/http/client/api/HttpClientFactoryTest.java index feb49d0cc8..4958202811 100644 --- a/common-app-api/src/test/java/org/openecomp/sdc/common/http/client/api/HttpClientFactoryTest.java +++ b/common-app-api/src/test/java/org/openecomp/sdc/common/http/client/api/HttpClientFactoryTest.java @@ -20,11 +20,11 @@ package org.openecomp.sdc.common.http.client.api; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; +import org.junit.Test; +import org.junit.runner.RunWith; import org.mockito.Mock; import org.mockito.Mockito; -import org.mockito.junit.jupiter.MockitoExtension; +import org.mockito.junit.MockitoJUnitRunner; import org.onap.sdc.security.SecurityUtil; import org.openecomp.sdc.common.http.config.BasicAuthorization; import org.openecomp.sdc.common.http.config.ClientCertificate; @@ -36,15 +36,15 @@ import java.util.Map; import static junit.framework.TestCase.assertNotNull; -@ExtendWith(MockitoExtension.class) -class HttpClientFactoryTest { +@RunWith(MockitoJUnitRunner.class) +public class HttpClientFactoryTest { @Mock - private HttpConnectionMngFactory httpConnectionMngFactory; + HttpConnectionMngFactory httpConnectionMngFactory; @Test - void validateNewClientCreationReturnsValidClient() { - final HttpClient httpClient = new HttpClientFactory(httpConnectionMngFactory).createClient("Http", prepareTestClientConfigImmutable()); + public void validateNewClientCreationReturnsValidClient() throws HttpExecuteException { + HttpClient httpClient = new HttpClientFactory(httpConnectionMngFactory).createClient("Http",prepareTestClientConfigImmutable()); assertNotNull(httpClient); httpClient.close(); } diff --git a/common-app-api/src/test/java/org/openecomp/sdc/common/http/client/api/HttpResponseTest.java b/common-app-api/src/test/java/org/openecomp/sdc/common/http/client/api/HttpResponseTest.java index 85246a1b45..d96f071e3c 100644 --- a/common-app-api/src/test/java/org/openecomp/sdc/common/http/client/api/HttpResponseTest.java +++ b/common-app-api/src/test/java/org/openecomp/sdc/common/http/client/api/HttpResponseTest.java @@ -21,38 +21,38 @@ package org.openecomp.sdc.common.http.client.api; import org.apache.http.HttpStatus; -import org.junit.jupiter.api.Test; +import org.junit.Test; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; -class HttpResponseTest { +public class HttpResponseTest { @Test - void validateNoDescriptionConstructor() { + public void validateNoDescriptionConstructor() { final String testResponse = "test response"; HttpResponse<String> httpResponseTest = new HttpResponse<>(testResponse, HttpStatus.SC_OK); - assertEquals(httpResponseTest.getStatusCode(), HttpStatus.SC_OK); - assertEquals(httpResponseTest.getResponse(), testResponse); - assertEquals(httpResponseTest.getDescription(), ""); + assertEquals(httpResponseTest.getStatusCode(),HttpStatus.SC_OK); + assertEquals(httpResponseTest.getResponse(),testResponse); + assertEquals(httpResponseTest.getDescription(),""); } @Test - void validateAllArgsConstructor() { + public void validateAllArgsConstructor() { final String testResponse = "test response"; final String testDescription = "test description"; HttpResponse<String> httpResponseTest = new HttpResponse<>(testResponse, HttpStatus.SC_OK, testDescription); - assertEquals(httpResponseTest.getStatusCode(), HttpStatus.SC_OK); - assertEquals(httpResponseTest.getResponse(), testResponse); - assertEquals(httpResponseTest.getDescription(), testDescription); + assertEquals(httpResponseTest.getStatusCode(),HttpStatus.SC_OK); + assertEquals(httpResponseTest.getResponse(),testResponse); + assertEquals(httpResponseTest.getDescription(),testDescription); } @Test - void validateToStringConstructor() { + public void validateToStringConstructor() { final String testResponse = "test response"; final String testDescription = "test description"; diff --git a/common-app-api/src/test/java/org/openecomp/sdc/common/util/StreamUtilsTests.java b/common-app-api/src/test/java/org/openecomp/sdc/common/util/StreamUtilsTests.java new file mode 100644 index 0000000000..5ee8f42b6b --- /dev/null +++ b/common-app-api/src/test/java/org/openecomp/sdc/common/util/StreamUtilsTests.java @@ -0,0 +1,142 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.sdc.common.util; + +import fj.data.Either; +import static org.junit.Assert.assertEquals; +import org.junit.Test; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.function.Function; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +import static org.junit.Assert.assertTrue; + +public class StreamUtilsTests { + @Test + public void testTakeWhilePredicateNotMet() { + List<Either<Integer, Boolean>> list = buildListWith10Integers(); + + assertEquals(10, StreamUtils.takeWhile(list.stream(), Either::isLeft).count()); + } + + @Test + public void testTakeWhilePredicateIsMet() { + List<Either<Integer, Boolean>> list = buildListWith10Integers(); + addToBooleansToList(list); + + final Stream<Either<Integer, Boolean>> takeWhileStream = StreamUtils.takeWhile(list.stream(), Either::isLeft); + assertEquals(0, takeWhileStream.filter(Either::isRight).count()); + } + + @Test + public <T> void testTakeErrorEvalOnlyOnce() { + List<Integer> bucket = new ArrayList<>(); + // API + Function<Integer, Either<Integer, Boolean>> cons = num -> { + Either<Integer, Boolean> ret; + bucket.add(num); + if (num > 5) { + ret = Either.right(false); + } else { + ret = Either.left(num); + } + ; + return ret; + }; + + List<Integer> num1to10 = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10); + Stream<Either<Integer, Boolean>> streamEithers = num1to10.stream().map(cons::apply); + List<Either<Integer, Boolean>> collect = StreamUtils.takeWhilePlusOneNoEval(streamEithers, Either::isLeft) + .collect(Collectors.toList()); + assertTrue(bucket.size() <= 6); + assertTrue(collect.size() <= 6); + assertEquals(1, collect.stream().filter(Either::isRight).count()); + + } + + @Test + public void testTakeWhilePlusOnePredicateNotMet() { + List<Either<Integer, Boolean>> list = buildListWith10Integers(); + + assertEquals(10, StreamUtils.takeWhilePlusOne(list.stream(), Either::isLeft).count()); + } + + @Test + public void testTakeWhilePlusOnePredicateIsMet() { + List<Either<Integer, Boolean>> list = buildListWith10Integers(); + addToBooleansToList(list); + + final Stream<Either<Integer, Boolean>> takeWhilePlusOneStream = StreamUtils.takeWhilePlusOne(list.stream(), + Either::isLeft); + assertEquals(1, takeWhilePlusOneStream.filter(Either::isRight).count()); + } + + private void addToBooleansToList(List<Either<Integer, Boolean>> list) { + list.add(Either.right(false)); + list.add(Either.right(false)); + } + + private List<Either<Integer, Boolean>> buildListWith10Integers() { + List<Either<Integer, Boolean>> list = new ArrayList<>(); + for (int i = 0; i < 10; i++) { + list.add(Either.left(i)); + } + return list; + } + + @Test + public void myTest() { + List<Integer> list = new ArrayList<>(); + for (int i = 0; i < 10; i++) { + list.add(i); + } + + List<Either<Integer, Boolean>> container = new ArrayList<>(); + list.stream().map(e -> myBusinessLogic(e, container)).filter(Either::isRight).findAny(); + // Actual Results are in container + assertEquals(6, container.size()); + + } + + private Either<Integer, Boolean> myBusinessLogic(int e, List<Either<Integer, Boolean>> cobtainerList) { + Either<Integer, Boolean> eitherElement = similuteDBAccess(e); + // Keep The results in external List + cobtainerList.add(eitherElement); + + return eitherElement; + } + + private Either<Integer, Boolean> similuteDBAccess(int e) { + Either<Integer, Boolean> eitherElement; + if (e < 5) { + // DB Success + eitherElement = Either.left(e); + } else { + // DB Fail + eitherElement = Either.right(true); + } + return eitherElement; + } +} |