/** * Execute a transaction method given a complete URI. * @param method the transaction method * @param headers HTTP header values to send * @param uri a properly urlencoded URI * @return the HTTP response code * @throws IOException */ public int executeURI(HttpMethod method, Header[] headers, String uri) throws IOException { method.setURI(new URI(uri, true)); for (Map.Entry<String, String> e: extraHeaders.entrySet()) { method.addRequestHeader(e.getKey(), e.getValue()); } if (headers != null) { for (Header header: headers) { method.addRequestHeader(header); } } long startTime = System.currentTimeMillis(); int code = httpClient.executeMethod(method); long endTime = System.currentTimeMillis(); if (LOG.isDebugEnabled()) { LOG.debug(method.getName() + " " + uri + " " + code + " " + method.getStatusText() + " in " + (endTime - startTime) + " ms"); } return code; }
/** * Execute a transaction method given only the path. Will select at random * one of the members of the supplied cluster definition and iterate through * the list until a transaction can be successfully completed. The * definition of success here is a complete HTTP transaction, irrespective * of result code. * @param cluster the cluster definition * @param method the transaction method * @param headers HTTP header values to send * @param path the properly urlencoded path * @return the HTTP response code * @throws IOException */ public int executePathOnly(Cluster cluster, HttpMethod method, Header[] headers, String path) throws IOException { IOException lastException; if (cluster.nodes.size() < 1) { throw new IOException("Cluster is empty"); } int start = (int)Math.round((cluster.nodes.size() - 1) * Math.random()); int i = start; do { cluster.lastHost = cluster.nodes.get(i); try { StringBuilder sb = new StringBuilder(); sb.append("http://"); sb.append(cluster.lastHost); sb.append(path); URI uri = new URI(sb.toString(), true); return executeURI(method, headers, uri.toString()); } catch (IOException e) { lastException = e; } } while (++i != start && i < cluster.nodes.size()); throw lastException; }
/** * If http(s) scheme, check scheme specific part begins '//'. * @throws URIException * @see <A href="http://www.faqs.org/rfcs/rfc1738.html">Section 3.1. * Common Internet Scheme Syntax</A> */ protected void checkHttpSchemeSpecificPartSlashPrefix(final URI base, final String scheme, final String schemeSpecificPart) throws URIException { if (scheme == null || scheme.length() <= 0) { return; } if (!scheme.equals("http") && !scheme.equals("https")) { return; } if (schemeSpecificPart == null || !schemeSpecificPart.startsWith("//")) { // only acceptable if schemes match if (base == null || !scheme.equals(base.getScheme())) { throw new URIException( "relative URI with scheme only allowed for " + "scheme matching base"); } return; } if (schemeSpecificPart.length() <= 2) { throw new URIException("http scheme specific part is " + "too short: " + schemeSpecificPart); } }
/** * Execute a transaction method given a complete URI. * @param method the transaction method * @param headers HTTP header values to send * @param uri a properly urlencoded URI * @return the HTTP response code * @throws IOException */ public int executeURI(HttpMethod method, Header[] headers, String uri) throws IOException { method.setURI(new URI(uri, true)); if (headers != null) { for (Header header: headers) { method.addRequestHeader(header); } } long startTime = System.currentTimeMillis(); int code = httpClient.executeMethod(method); long endTime = System.currentTimeMillis(); if (LOG.isDebugEnabled()) { LOG.debug(method.getName() + " " + uri + " " + code + " " + method.getStatusText() + " in " + (endTime - startTime) + " ms"); } return code; }
/** * Typical web service client class to get a string representation of the * response. * * @param requestUrl * Relative request URL * @param mapperClass * Class to which the response should cast to. * @return JAXB deserialized response */ protected Object getForObject( final String requestUrl, Class< ? > mapperClass, String parameters ) { Object domainObject = null; HttpClient client = new HttpClient(); try { PostMethod request = new PostMethod(); request.setURI( new URI( getAbsoluteUrl( requestUrl + REQUEST_URL_SUFFIX + parameters ), false ) ); request.addRequestHeader( CONTENT_TYPE, APPLICATION_XML ); String apiToken = jenkinsClientProperties.getJenkinsApiToken(); if ( !apiToken.isEmpty() ) { request.setDoAuthentication( true ); } domainObject = sendRequestToJenkins( mapperClass, domainObject, client, request, apiToken ); } catch ( Exception e ) { LOGGER.error( e.getMessage() ); } return domainObject; }
/** * Perform build Operations Via GET * * @param requestUrl * Relative request URL * @param mapperClass * Class to which the response should cast to. * @return JAXB deserialized response */ protected Object performBuildOperationsViaGet( final String requestUrl, Class< ? > mapperClass ) { Object domainObject = null; HttpClient client = new HttpClient(); try { GetMethod request = new GetMethod(); request.setURI( new URI( getAbsoluteUrl( requestUrl ), false ) ); request.addRequestHeader( CONTENT_TYPE, APPLICATION_XML ); String apiToken = jenkinsClientProperties.getJenkinsApiToken(); if ( !apiToken.isEmpty() ) { request.setDoAuthentication( true ); } domainObject = sendRequestToJenkins( mapperClass, domainObject, client, request, apiToken ); } catch ( Exception e ) { LOGGER.error( e.getMessage() ); } return domainObject; }
private String getHost(HttpMethod httpMethod, Object[] args) { try { final URI url = httpMethod.getURI(); if (url.isAbsoluteURI()) { return getEndpoint(url.getHost(), url.getPort()); } if (isDebug) { logger.debug("URI is not absolute. {}", url.getURI()); } // if not found schema, use httpConnection. final HttpConnection httpConnection = getHttpConnection(args); if (httpConnection != null) { final String host = httpConnection.getHost(); final int port = getPort(httpConnection); return getEndpoint(host, port); } } catch (URIException e) { // unexpected error, perhaps of user fault. logger.error("[HttpClient3] Fail get URI", e); } return null; }
private String getHttpUrl(String host, int port, URI uri, HttpConnection httpConnection) throws URIException { final Protocol protocol = httpConnection.getProtocol(); if (protocol == null) { return uri.getURI(); } final StringBuilder sb = new StringBuilder(); final String scheme = protocol.getScheme(); sb.append(scheme).append("://"); sb.append(host); // if port is default port number. if (port != SKIP_DEFAULT_PORT) { sb.append(':').append(port); } sb.append(uri.getURI()); return sb.toString(); }
@Nullable private static HttpMethod handleCertificateExceptionAndRetry(@NotNull IOException e, @NotNull String host, @NotNull HttpClient client, @NotNull URI uri, @NotNull ThrowableConvertor<String, HttpMethod, IOException> methodCreator) throws IOException { if (!isCertificateException(e)) { throw e; } if (isTrusted(host)) { // creating a special configuration that allows connections to non-trusted HTTPS hosts // see the javadoc to EasySSLProtocolSocketFactory for details Protocol easyHttps = new Protocol("https", (ProtocolSocketFactory)new EasySSLProtocolSocketFactory(), 443); HostConfiguration hc = new HostConfiguration(); hc.setHost(host, 443, easyHttps); String relativeUri = new URI(uri.getPathQuery(), false).getURI(); // it is important to use relative URI here, otherwise our custom protocol won't work. // we have to recreate the method, because HttpMethod#setUri won't overwrite the host, // and changing host by hands (HttpMethodBase#setHostConfiguration) is deprecated. HttpMethod method = methodCreator.convert(relativeUri); client.executeMethod(hc, method); return method; } throw e; }
public static String encodeAuthority(String uri) throws URIException { int start = uri.indexOf("//"); if(start == -1) return uri; start++; int end = uri.indexOf("/",start+1); if(end == -1) end = uri.indexOf("?",start+1); if(end == -1) end = uri.indexOf("#",start+1); if(end == -1) end = uri.length(); String before = uri.substring(0, start+1); String authority= uri.substring(start+1,end); String after = uri.substring(end); authority = URIUtil.encode(authority, URI.allowed_authority); return before+authority+after; }
public static String encodePath(String uri) throws URIException { int doubleSlashIndex = uri.indexOf("//"); boolean hasAuthority = doubleSlashIndex >= 0; int start = -1; if(hasAuthority) { start = uri.indexOf("/",doubleSlashIndex+2); } else { start = uri.indexOf(":"); } if(start == -1) return uri; int end = uri.indexOf("?",start+1); if(end == -1) end = uri.indexOf("#",start+1); if(end == -1) end = uri.length(); String before = uri.substring(0, start+1); String path= uri.substring(start+1,end); String after = uri.substring(end); path = URIUtil.encode(path, URI.allowed_abs_path); return before+path+after; }
@Test public void testParamValidity_GetLogCollection() throws Exception { //Mandatory only URI uri = methodMaker.getLogCollectionMethod(serviceUrl, datasetId, null).getURI(); assertContainsURLParam(uri, "datasetid", datasetId); assertDoesntContainURLParam(uri, "mosaicsvc"); //Optional Params uri = methodMaker.getLogCollectionMethod(serviceUrl, datasetId, true).getURI(); assertContainsURLParam(uri, "datasetid", datasetId); assertContainsURLParam(uri, "mosaicsvc", "yes"); uri = methodMaker.getLogCollectionMethod(serviceUrl, datasetId, false).getURI(); assertContainsURLParam(uri, "datasetid", datasetId); assertContainsURLParam(uri, "mosaicsvc", "no"); }
/** * Test doing geochemistry filter and getting all values */ @Test public void testYilgarnGeochemistryFilter() throws Exception{ final String kmlBlob = "kmlBlob"; final String serviceUrl = "http://service/wfs"; final String geologicName = "filter info"; final int maxFeatures = 0; final String bbox = null; final String expectedGML = "<gml/>"; context.checking(new Expectations() {{ oneOf(mockWfsService).getWfsResponseAsKml(with(equal(serviceUrl)), with(equal("gsml:GeologicUnit")), with(any(String.class)), with(equal(maxFeatures)), with(equal((String)null)));will(returnValue(new WFSTransformedResponse(expectedGML, kmlBlob, mockMethod))); allowing(mockMethod).getURI();will(returnValue(new URI(serviceUrl, true))); }}); ModelAndView modelAndView = controller.doYilgarnGeochemistryFilter(serviceUrl, geologicName, bbox, maxFeatures); Assert.assertNotNull(modelAndView); Map<String, Object> model = modelAndView.getModel(); Assert.assertEquals(true, model.get("success")); Assert.assertNotNull(model.get("data")); }
/** * Test doing geochemistry filter and getting the count of all values */ @Test public void testYilgarnGeochemistryFilterCount() throws Exception{ final String serviceUrl = "http://service/wfs"; final String geologicName = "filter info"; final int maxFeatures = 134; final String bbox = null; final int numberOfFeatures = 123; context.checking(new Expectations() {{ oneOf(mockWfsService).getWfsFeatureCount(with(equal(serviceUrl)), with(equal("gsml:GeologicUnit")), with(any(String.class)), with(equal(maxFeatures)), with((String) null));will(returnValue(new WFSCountResponse(numberOfFeatures))); allowing(mockMethod).getURI();will(returnValue(new URI(serviceUrl, true))); }}); ModelAndView modelAndView = controller.doYilgarnGeochemistryCount(serviceUrl, geologicName, bbox, maxFeatures); Assert.assertNotNull(modelAndView); Map<String, Object> model = modelAndView.getModel(); Assert.assertEquals(true, model.get("success")); Assert.assertNotNull(model.get("data")); Assert.assertEquals(new Integer(numberOfFeatures), model.get("data")); }
/** * Test doing geochemistry filter and getting the count of all values fails gracefully */ @Test public void testYilgarnGeochemistryFilterCountError() throws Exception{ final String serviceUrl = "http://service/wfs"; final String geologicName = "filter info"; final int maxFeatures = 134; final String bbox = null; context.checking(new Expectations() {{ oneOf(mockWfsService).getWfsFeatureCount(with(equal(serviceUrl)), with(equal("gsml:GeologicUnit")), with(any(String.class)), with(equal(maxFeatures)), with((String) null));will(throwException(new PortalServiceException(mockMethod, new ConnectException()))); allowing(mockMethod).getURI();will(returnValue(new URI(serviceUrl, true))); }}); ModelAndView modelAndView = controller.doYilgarnGeochemistryCount(serviceUrl, geologicName, bbox, maxFeatures); Assert.assertNotNull(modelAndView); Map<String, Object> model = modelAndView.getModel(); Assert.assertEquals(false, model.get("success")); }
/** * Test that all classes are invoked correctly and return valid JSON */ @Test public void testGetAllFeatures() throws Exception { final String gmlBlob = "gmlBlob"; final String kmlBlob = "kmlBlob"; final String wfsUrl = "http://service/wfs"; final String featureType = "type:name"; final int maxFeatures = 1234; final String srs = null; //dont specify this final String bboxJsonString = null; context.checking(new Expectations() {{ oneOf(mockWfsService).getWfsResponseAsKml(with(equal(wfsUrl)), with(equal(featureType)), with(any(String.class)), with(equal(maxFeatures)), with(equal(srs)));will(returnValue(new WFSTransformedResponse(gmlBlob, kmlBlob, mockMethod))); allowing(mockMethod).getURI();will(returnValue(new URI("http://service.wfs/wfs", false))); }}); ModelAndView modelAndView = wfsController.requestAllFeatures(wfsUrl, featureType, bboxJsonString, maxFeatures); ModelMap dataObj = (ModelMap) modelAndView.getModel().get("data"); Assert.assertTrue((Boolean) modelAndView.getModel().get("success")); Assert.assertNotNull(dataObj); Assert.assertEquals(gmlBlob, dataObj.get("gml")); Assert.assertEquals(kmlBlob, dataObj.get("kml")); }
@Test public void testGetAllFeaturesInBbox() throws Exception { final String gmlBlob = "gmlBlob"; final String kmlBlob = "kmlBlob"; final String wfsUrl = "http://service/wfs"; final String featureType = "type:name"; final int maxFeatures = 1234; final String srs = null; //dont specify this final String bboxJsonString = "{\"bboxSrs\":\"http://www.opengis.net/gml/srs/epsg.xml%234326\",\"lowerCornerPoints\":[-5,-6],\"upperCornerPoints\":[7,8]}"; context.checking(new Expectations() {{ oneOf(mockWfsService).getWfsResponseAsKml(with(equal(wfsUrl)), with(equal(featureType)), with(any(String.class)), with(equal(maxFeatures)), with(equal(srs)));will(returnValue(new WFSTransformedResponse(gmlBlob, kmlBlob, mockMethod))); allowing(mockMethod).getURI();will(returnValue(new URI("http://service.wfs/wfs", false))); }}); ModelAndView modelAndView = wfsController.requestAllFeatures(wfsUrl, featureType, bboxJsonString, maxFeatures); ModelMap dataObj = (ModelMap) modelAndView.getModel().get("data"); Assert.assertTrue((Boolean) modelAndView.getModel().get("success")); Assert.assertNotNull(dataObj); Assert.assertEquals(gmlBlob, dataObj.get("gml")); Assert.assertEquals(kmlBlob, dataObj.get("kml")); }
@Test public void testRequestFeature() throws Exception { final String gmlBlob = "gmlBlob"; final String kmlBlob = "kmlBlob"; final String wfsUrl = "http://service/wfs"; final String featureType = "type:name"; final String featureId = "feature-id"; context.checking(new Expectations() {{ oneOf(mockWfsService).getWfsResponseAsKml(wfsUrl, featureType, featureId);will(returnValue(new WFSTransformedResponse(gmlBlob, kmlBlob, mockMethod))); allowing(mockMethod).getURI();will(returnValue(new URI("http://service.wfs/wfs", false))); }}); ModelAndView modelAndView = wfsController.requestFeature(wfsUrl, featureType, featureId); ModelMap dataObj = (ModelMap) modelAndView.getModel().get("data"); Assert.assertTrue((Boolean) modelAndView.getModel().get("success")); Assert.assertNotNull(dataObj); Assert.assertEquals(gmlBlob, dataObj.get("gml")); Assert.assertEquals(kmlBlob, dataObj.get("kml")); }
@Test public void testRequestFeatureByProperty() throws Exception { final String gmlBlob = "gmlBlob"; final String kmlBlob = "kmlBlob"; final String wfsUrl = "http://service/wfs"; final String featureType = "type:name"; final String featureProperty = "feature/property"; final String propertyValue = "comparison value"; final String filterString = new SimplePropertyFilter(featureProperty, propertyValue).getFilterStringAllRecords(); context.checking(new Expectations() {{ oneOf(mockWfsService).getWfsResponseAsKml(wfsUrl, featureType, filterString, null, null);will(returnValue(new WFSTransformedResponse(gmlBlob, kmlBlob, mockMethod))); allowing(mockMethod).getURI();will(returnValue(new URI("http://service.wfs/wfs", false))); }}); ModelAndView modelAndView = wfsController.requestFeatureByProperty(wfsUrl, featureType, featureProperty, propertyValue); ModelMap dataObj = (ModelMap) modelAndView.getModel().get("data"); Assert.assertTrue((Boolean) modelAndView.getModel().get("success")); Assert.assertNotNull(dataObj); Assert.assertEquals(gmlBlob, dataObj.get("gml")); Assert.assertEquals(kmlBlob, dataObj.get("kml")); }
/** * Test wfsFeaturePopup will all optional parameters specified * @throws Exception */ @Test public void testWFSFeaturePopup() throws Exception { final String serviceUrl = "http://example.com/wfs"; final String typeName = "wfs:typeName"; final String featureId = "idString"; final String convertedData = "gmlToKMLResult"; final String wfsResponse = "wfsResponseString"; final ByteBufferedServletOutputStream outputStream = new ByteBufferedServletOutputStream(convertedData.getBytes().length); context.checking(new Expectations() {{ allowing(mockMethod).getURI();will(returnValue(new URI(serviceUrl, false))); allowing(mockResponse).setContentType(with(any(String.class))); oneOf(mockWfsService).getWfsResponseAsHtml(serviceUrl, typeName, featureId);will(returnValue(new WFSTransformedResponse(wfsResponse, convertedData, mockMethod))); oneOf(mockResponse).getOutputStream();will(returnValue(outputStream)); }}); wfsController.wfsFeaturePopup(mockResponse, serviceUrl, typeName, featureId); Assert.assertArrayEquals(convertedData.getBytes(), outputStream.toByteArray()); }
/** * Test doing a mine filter and getting all mines * @throws Exception */ @Test public void testDoMineFilterSpecificError() throws Exception { final String mineName = "testMine"; final String serviceURL = "http://testblah.com"; final HttpMethodBase mockMethod = context.mock(HttpMethodBase.class); context.checking(new Expectations() {{ allowing(mockMethod).getURI();will(returnValue(new URI(serviceURL, true))); oneOf(mineralOccurrenceService).getMinesGml(serviceURL, mineName, null, 0);will(throwException(new PortalServiceException(mockMethod))); }}); ModelAndView modelAndView = this.earthResourcesFilterController.doMineFilter(serviceURL, mineName, null, 0); //Ensure that we get a response that says failure testMAVResponse(modelAndView, new Boolean(false), null, null); }
/** * Test doing a mine filter and getting all mines * @throws Exception */ @Test public void testDoMineFilterAllMines() throws Exception { final String serviceURL = "http://localhost?"; final String mineName = ""; //to get all mines final HttpMethodBase mockMethod = context.mock(HttpMethodBase.class); final String expectedKML = "<kml/>"; final String expectedGML = "<gml/>"; context.checking(new Expectations() {{ allowing(mockMethod).getURI();will(returnValue(new URI(serviceURL, true))); oneOf(mineralOccurrenceService).getMinesGml(serviceURL, mineName, null, 0);will(returnValue(new WFSTransformedResponse(expectedGML, expectedKML, mockMethod))); }}); //call with updateCSWRecords dud url ModelAndView modelAndView = this.earthResourcesFilterController.doMineFilter(serviceURL, mineName, null, 0); //Ensure that we get a valid response testMAVResponse(modelAndView, new Boolean(true), expectedGML, expectedKML); }
/** * Test doing a mine filter and getting all mines * @throws Exception */ @Test public void testDoMineFilterSingleMine() throws Exception { final String serviceURL = "http://localhost?"; final String mineName = "mineName"; //to get all mines final HttpMethodBase mockMethod = context.mock(HttpMethodBase.class); final String expectedKML = "<kml/>"; final String expectedGML = "<gml/>"; context.checking(new Expectations() {{ allowing(mockMethod).getURI();will(returnValue(new URI(serviceURL, true))); oneOf(mineralOccurrenceService).getMinesGml(serviceURL, mineName, null, 0);will(returnValue(new WFSTransformedResponse(expectedGML, expectedKML, mockMethod))); }}); //call with updateCSWRecords dud url ModelAndView modelAndView = this.earthResourcesFilterController.doMineFilter(serviceURL, mineName, null, 0); //Ensure that we get a valid response testMAVResponse(modelAndView, new Boolean(true), expectedGML, expectedKML); }
/** * Tests that hylogger filter uses the correct functions when the underlying hylogger lookup returns no results. * * @throws Exception the exception */ @Test public void testHyloggerFilterNoDatasets() throws Exception { final String serviceUrl = "http://fake.com/wfs"; final String nameFilter = "filterBob"; final String custodianFilter = "filterCustodian"; final String filterDate = "1986-10-09"; final int maxFeatures = 10; final FilterBoundingBox bbox = new FilterBoundingBox("EPSG:4326", new double[] {1., 2.}, new double[] {3., 4.}); final boolean onlyHylogger = true; final HttpMethodBase mockHttpMethodBase = context.mock(HttpMethodBase.class); final URI httpMethodURI = new URI("http://example.com", true); context.checking(new Expectations() {{ oneOf(mockBoreholeService).discoverHyloggerBoreholeIDs(with(equal(mockCSWService)),with(any(CSWRecordsFilterVisitor.class))); will(returnValue(new ArrayList<String>())); allowing(mockHttpMethodBase).getURI(); will(returnValue(httpMethodURI)); }}); ModelAndView response = this.nvclController.doBoreholeFilter(serviceUrl, nameFilter, custodianFilter, filterDate, maxFeatures, bbox, onlyHylogger); Assert.assertFalse((Boolean) response.getModel().get("success")); }
/** * If http(s) scheme, check scheme specific part begins '//'. * @throws URIException * @see http://www.faqs.org/rfcs/rfc1738.html Section 3.1. Common Internet * Scheme Syntax */ protected void checkHttpSchemeSpecificPartSlashPrefix(final URI base, final String scheme, final String schemeSpecificPart) throws URIException { if (scheme == null || scheme.length() <= 0) { return; } if (!scheme.equals("http") && !scheme.equals("https")) { return; } if ( schemeSpecificPart == null || !schemeSpecificPart.startsWith("//")) { // only acceptable if schemes match if (base == null || !scheme.equals(base.getScheme())) { throw new URIException( "relative URI with scheme only allowed for " + "scheme matching base"); } return; } if (schemeSpecificPart.length() <= 2) { throw new URIException("http scheme specific part is " + "too short: " + schemeSpecificPart); } }
private JsonArray sendSearchRequest(String solrQuery, Function<InputStreamReader, JsonArray> function) throws IOException { JsonArray docsJson; GetMethod getMethod = new GetMethod(); HttpClient httpClient = new HttpClient(); try { getMethod.setURI(new URI(solrQuery, false)); int statusCode = httpClient.executeMethod(getMethod); docsJson = function.apply(new InputStreamReader(getMethod.getResponseBodyAsStream())); if (statusCode != HttpStatus.SC_OK) { LOG.warning("Failed to execute query: " + solrQuery); throw new IOException("Search request status is not OK: " + statusCode); } } finally { getMethod.releaseConnection(); } return docsJson; }
@Test public void testGetAssignablesMethodString() throws Exception { HttpMethod method = factory.getAssignablesMethod("http://some.test", 5, "Some Magic Query", 6); URI uri = method.getURI(); assertEquals("some.test", uri.getHost()); assertEquals("/api/v1/Users/5/Assignables", uri.getPath()); assertTrue(Arrays.toString(method.getRequestHeaders()).contains("Accept: application/json")); List<String> params = Arrays.asList(StringUtils.split(uri.getQuery(), '&')); assertEquals(4, params.size()); assertTrue(params.contains("take=6")); assertTrue(params.contains("orderByDesc=CreateDate")); assertTrue(params.contains("where=Name contains 'Some Magic Query'")); assertTrue(params.contains("include=" + Arrays.toString(Assignable.FIELDS))); }
@Test public void testGetAssignablesMethodNumber() throws Exception { HttpMethod method = factory.getAssignablesMethod("http://some.test", 5, "2695", 6); URI uri = method.getURI(); assertEquals("some.test", uri.getHost()); assertEquals("/api/v1/Users/5/Assignables", uri.getPath()); assertTrue(Arrays.toString(method.getRequestHeaders()).contains("Accept: application/json")); List<String> params = Arrays.asList(StringUtils.split(uri.getQuery(), '&')); assertEquals(4, params.size()); assertTrue(params.contains("take=6")); assertTrue(params.contains("orderByDesc=CreateDate")); assertTrue(params.contains("where=Id eq 2695")); assertTrue(params.contains("include=" + Arrays.toString(Assignable.FIELDS))); }