View Javadoc
1   /*
2    * Copyright 2016 the original author or authors.
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    *       http://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  
17  package org.openehealth.ipf.commons.ihe.fhir;
18  
19  import org.easymock.EasyMock;
20  import org.easymock.IArgumentMatcher;
21  import org.hl7.fhir.instance.model.Patient;
22  import org.hl7.fhir.instance.model.api.IBaseResource;
23  import org.junit.Assert;
24  import org.junit.Before;
25  import org.junit.Test;
26  
27  import java.util.ArrayList;
28  import java.util.HashMap;
29  import java.util.List;
30  import java.util.Map;
31  
32  import static org.easymock.EasyMock.eq;
33  import static org.junit.Assert.assertEquals;
34  
35  /**
36   *
37   */
38  public class LazyBundleProviderTest {
39  
40      private static final int MAX_SIZE = 50;
41      private RequestConsumer requestConsumer;
42      private AbstractBundleProvider bundleProvider;
43      private List<IBaseResource> response;
44  
45      @Before
46      public void setup() {
47          requestConsumer = EasyMock.createMock(RequestConsumer.class);
48          response = new ArrayList<>();
49          for (int i = 0; i < MAX_SIZE; i++) {
50              response.add(new Patient().setId(Integer.toString(i)));
51          }
52          Object payload = new Object();
53          Map<String, Object> headers = new HashMap<>();
54          bundleProvider = new LazyBundleProvider(requestConsumer, true, payload, headers);
55      }
56  
57      @Test
58      public void testGetSize() {
59          EasyMock.expect(requestConsumer.handleSizeRequest(eq(bundleProvider.getPayload()), hasRequestSizeParameter())).andReturn(MAX_SIZE);
60          EasyMock.replay(requestConsumer);
61          assertEquals(response.size(), bundleProvider.size().intValue());
62          EasyMock.verify(requestConsumer);
63      }
64  
65      @Test
66      public void testGetResources() {
67          EasyMock.expect(requestConsumer.handleBundleRequest(eq(bundleProvider.getPayload()), hasRequestSublistParameters(10, 30)))
68                  .andReturn(response.subList(10, 30));
69          EasyMock.replay(requestConsumer);
70          List<IBaseResource> result = bundleProvider.getResources(10, 30);
71          Assert.assertEquals(20, result.size());
72          Assert.assertEquals(response.subList(10, 30), result);
73          EasyMock.verify(requestConsumer);
74      }
75  
76      @Test
77      public void testGetResourcesAlreadyCached() {
78          EasyMock.expect(requestConsumer.handleBundleRequest(eq(bundleProvider.getPayload()), hasRequestSublistParameters(10, 30)))
79                  .andReturn(response.subList(10, 30));
80          EasyMock.replay(requestConsumer);
81  
82          // Now get a subset of what was already retrieved. No further calls to handleBundleRequest
83          bundleProvider.getResources(10, 30);
84          List<IBaseResource> result = bundleProvider.getResources(15, 20);
85  
86          Assert.assertEquals(5, result.size());
87          Assert.assertEquals(response.subList(15, 20), result);
88          EasyMock.verify(requestConsumer);
89      }
90  
91      @Test
92      public void testGetResourcesPartlyCached1() {
93          EasyMock.expect(requestConsumer.handleBundleRequest(eq(bundleProvider.getPayload()), hasRequestSublistParameters(10, 30)))
94                  .andReturn(response.subList(10, 30));
95          EasyMock.expect(requestConsumer.handleBundleRequest(eq(bundleProvider.getPayload()), hasRequestSublistParameters(30, 40)))
96                  .andReturn(response.subList(30, 40));
97          EasyMock.replay(requestConsumer);
98  
99          // First get elements 10 to 30, afterwards 20 to 40. The expectation is that with the second call only
100         // elements 30 to 40 are returned.
101         bundleProvider.getResources(10, 30);
102         List<IBaseResource> result = bundleProvider.getResources(20, 40);
103 
104         Assert.assertEquals(20, result.size());
105         Assert.assertEquals(response.subList(20, 40), result);
106         EasyMock.verify(requestConsumer);
107     }
108 
109     @Test
110     public void testGetResourcesPartlyCached2() {
111         EasyMock.expect(requestConsumer.handleBundleRequest(eq(bundleProvider.getPayload()), hasRequestSublistParameters(10, 30)))
112                 .andReturn(response.subList(10, 30));
113         EasyMock.expect(requestConsumer.handleBundleRequest(eq(bundleProvider.getPayload()), hasRequestSublistParameters(5, 10)))
114                 .andReturn(response.subList(5, 10));
115         EasyMock.expect(requestConsumer.handleBundleRequest(eq(bundleProvider.getPayload()), hasRequestSublistParameters(30, 35)))
116                 .andReturn(response.subList(30, 35));
117         EasyMock.replay(requestConsumer);
118 
119         // First get elements 10 to 30, afterwards 5 to 35. The expectation is that with the second call si split into
120         // getting elements 5 to 10 and 30 to 35.
121         bundleProvider.getResources(10, 30);
122         List<IBaseResource> result = bundleProvider.getResources(5, 35);
123 
124         Assert.assertEquals(30, result.size());
125         Assert.assertEquals(response.subList(5, 35), result);
126         EasyMock.verify(requestConsumer);
127     }
128 
129     @Test
130     public void testGetResourcesPartlyCached3() {
131         EasyMock.expect(requestConsumer.handleBundleRequest(eq(bundleProvider.getPayload()), hasRequestSublistParameters(10, 20)))
132                 .andReturn(response.subList(10, 20));
133         EasyMock.expect(requestConsumer.handleBundleRequest(eq(bundleProvider.getPayload()), hasRequestSublistParameters(30, 40)))
134                 .andReturn(response.subList(30, 40));
135         EasyMock.expect(requestConsumer.handleBundleRequest(eq(bundleProvider.getPayload()), hasRequestSublistParameters(20, 30)))
136                 .andReturn(response.subList(20, 30));
137         EasyMock.replay(requestConsumer);
138 
139         // First get elements 10 to 20, then 30 to 40, then 15 to 35. The expectation is that with the third call
140         // only elements 20 to 30 are fetched
141         bundleProvider.getResources(10, 20);
142         bundleProvider.getResources(30, 40);
143         List<IBaseResource> result = bundleProvider.getResources(15, 35);
144 
145         Assert.assertEquals(20, result.size());
146         Assert.assertEquals(response.subList(15, 35), result);
147         EasyMock.verify(requestConsumer);
148     }
149 
150 
151     private static Map<String, Object> hasRequestSizeParameter() {
152         EasyMock.reportMatcher(new HasRequestSizeParameter());
153         return null;
154     }
155 
156     private static class HasRequestSizeParameter implements IArgumentMatcher {
157 
158         @Override
159         public void appendTo(StringBuffer buffer) {
160             buffer.append("hasSizeParameter()");
161         }
162 
163         @Override
164         public boolean matches(Object argument) {
165             Map<String, Object> headers = (Map<String, Object>)argument;
166             return headers.containsKey(Constants.FHIR_REQUEST_SIZE_ONLY);
167         }
168     }
169 
170     private static Map<String, Object> hasRequestSublistParameters(int expectedFrom, int expectedTo) {
171         EasyMock.reportMatcher(new RequestSublistParameters(expectedFrom, expectedTo));
172         return null;
173     }
174 
175     private static class RequestSublistParameters implements IArgumentMatcher {
176 
177         private final int expectedFromIndex;
178         private final int expectedToIndex;
179 
180         public RequestSublistParameters(int expectedFromIndex, int expectedToIndex) {
181             this.expectedFromIndex = expectedFromIndex;
182             this.expectedToIndex = expectedToIndex;
183         }
184 
185         @Override
186         public void appendTo(StringBuffer buffer) {
187             buffer.append(String.format("hasRequestSublistParameter(%d,%d)", expectedFromIndex, expectedToIndex));
188         }
189 
190         @Override
191         public boolean matches(Object argument) {
192             Map<String, Object> headers = (Map<String, Object>)argument;
193             return headers.get(Constants.FHIR_FROM_INDEX).equals(expectedFromIndex) &&
194                     headers.get(Constants.FHIR_TO_INDEX).equals(expectedToIndex);
195         }
196     }
197 }