@Test( dataProvider = com.linkedin.restli.internal.common.TestConstants.RESTLI_PROTOCOL_1_2_PREFIX + "clientDataDataProvider") public void testUpdate(RestClient restClient, RootBuilderWrapper<Long, Greeting> builders) throws RemoteInvocationException, CloneNotSupportedException { // GET Request<Greeting> request = builders.get().id(1L).build(); Response<Greeting> greetingResponse1 = restClient.sendRequest(request).getResponse(); String response1 = greetingResponse1.getEntity().getMessage(); Assert.assertNotNull(response1); // POST Greeting greeting = new Greeting(greetingResponse1.getEntity().data().copy()); greeting.setMessage(response1 + "Again"); Request<EmptyRecord> writeRequest = builders.update().id(1L).input(greeting).build(); Response<EmptyRecord> updateResponse = restClient.sendRequest(writeRequest).getResponse(); Assert.assertNull(updateResponse.getHeader(RestConstants.HEADER_CONTENT_TYPE)); // GET again, to verify that our POST worked. Request<Greeting> request2 = builders.get().id(1L).build(); Response<Greeting> greetingResponse2 = restClient.sendRequest(request2).getResponse(); String response2 = greetingResponse2.getEntity().getMessage(); Assert.assertEquals(response2, response1 + "Again"); }
/** * a more concrete example of custom action<br> * resource level determines the granularity of the action<br> * mismatching the resource level in the request throws exception and will respond HTTP 400 * * @param resource Instance of the resource class. This is not part of the action method and is * needed because this implementation is not an actual resource. */ @Action(name = "updateTone", resourceLevel = ResourceLevel.ENTITY) // The base resource parameter gets special handling in the generator. It is set to the actual // resource class instance, and is not part of the generated REST method. public Greeting updateTone( BaseResource resource, @ActionParam("newTone") @Optional Tone newTone, @ActionParam("delOld") @Optional("false") Boolean delOld) { // the way to get entity key in action Long key = resource.getContext().getPathKeys().get(_resourceName + "Id"); Greeting g = _db.get(key); if (g == null) { // HTTP 404 return g; } // delete existing Greeting and assign new key if (delOld) { _db.remove(key); key = _idSeq.incrementAndGet(); g.setId(key); } Tone t; // newTone is an optional parameter // omitting it in request results a null value if (newTone == null) { t = DEFAULT_TONE; } else { t = newTone; } g.setTone(t); _db.put(key, g); return g; }
private static List<Greeting> generateCreate(int num) { List<Greeting> creates = new ArrayList<Greeting>(); for (int i = 0; i < num; ++i) { Greeting greeting = new Greeting(); greeting.setMessage("create message").setTone(Tone.FRIENDLY); creates.add(greeting); } return creates; }
private static Map<Long, Greeting> generateUpdates(Long[] ids) { Map<Long, Greeting> updates = new HashMap<Long, Greeting>(); for (long l : ids) { Greeting greeting = new Greeting(); greeting.setId(l).setMessage("update message").setTone(Tone.SINCERE); updates.put(l, greeting); } return updates; }
// These CRUD annotations are MANDATORY for the code generator because we want to generate // implementations which do not use the templates, e.g. Task @RestMethod.Create public CreateResponse create( Greeting entity, @QueryParam("isNullId") @Optional("false") boolean isNullId) { entity.setId(_idSeq.incrementAndGet()); _db.put(entity.getId(), entity); if (isNullId) { return new CreateResponse(null, HttpStatus.S_201_CREATED); } return new CreateResponse(entity.getId()); }
public GreetingsResourceImpl(String resourceName) { for (int i = 0; i < INITIAL_SIZE; i++) { Greeting g = new Greeting() .setId(_idSeq.incrementAndGet()) .setMessage(INITIAL_MESSAGES[i]) .setTone(INITIAL_TONES[i]); _db.put(g.getId(), g); } _resourceName = resourceName; }
// TODO modify this method to accept a CollectionRequest as it's first parameter once our server // code has been // updated to work with the new representation of BatchUpdateRequests and // BatchPartialUpdateRequests. As of now // we are still converting to the old representation using // CollectionRequestUtil.convertToBatchRequest private static void checkInput( DataMap dataMap, Map<Long, Greeting> inputMap, Set<String> uriIds) { Assert.assertEquals(dataMap.size(), uriIds.size()); for (String key : dataMap.keySet()) { DataMap inputDM = dataMap.getDataMap(key); Greeting expectedGreeting = inputMap.get(Long.parseLong(key)); Assert.assertTrue(uriIds.contains(key)); Assert.assertTrue(inputDM.equals(expectedGreeting.data())); } }
@Test( dataProvider = com.linkedin.restli.internal.common.TestConstants.RESTLI_PROTOCOL_1_2_PREFIX + "clientDataDataProvider") public void testGet(RestClient restClient, RootBuilderWrapper<Long, Greeting> builders) throws RemoteInvocationException { Request<Greeting> request = builders.get().id(1L).build(); Response<Greeting> response = restClient.sendRequest(request).getResponse(); Greeting greeting = response.getEntity(); Assert.assertEquals(greeting.getId(), new Long(1)); }
@RestMethod.GetAll public List<Greeting> getAll(@PagingContextParam PagingContext ctx) { // Deterministic behaviour of getAll to make it easier to test as part of the integration test // suite // Just return those greetings that have "GetAll" present in their message List<Greeting> greetings = new ArrayList<Greeting>(); for (Greeting greeting : _db.values()) { if (greeting.getMessage().contains("GetAll")) { greetings.add(greeting); } } return greetings; }
@Test( dataProvider = com.linkedin.restli.internal.common.TestConstants.RESTLI_PROTOCOL_1_2_PREFIX + "buildersClientDataDataProvider") public void testCreateId(RestClient restClient, RestliRequestOptions requestOptions) throws RemoteInvocationException { Greeting greeting = new Greeting(); greeting.setMessage("Hello there!"); greeting.setTone(Tone.FRIENDLY); final GreetingsRequestBuilders builders = new GreetingsRequestBuilders(requestOptions); CreateIdRequest<Long, Greeting> createRequest = builders.create().input(greeting).build(); Response<IdResponse<Long>> response = restClient.sendRequest(createRequest).getResponse(); Assert.assertNull(response.getHeader(RestConstants.HEADER_CONTENT_TYPE)); @SuppressWarnings("unchecked") long id = response.getEntity().getId(); @SuppressWarnings("deprecation") String stringId = response.getId(); Assert.assertEquals(id, Long.parseLong(stringId)); Request<Greeting> getRequest = builders.get().id(id).build(); Response<Greeting> getResponse = restClient.sendRequest(getRequest).getResponse(); Greeting responseGreeting = getResponse.getEntity(); Assert.assertEquals(responseGreeting.getMessage(), greeting.getMessage()); Assert.assertEquals(responseGreeting.getTone(), greeting.getTone()); }
@Test( dataProvider = com.linkedin.restli.internal.common.TestConstants.RESTLI_PROTOCOL_1_2_PREFIX + "clientDataDataProvider") public void testFinder(RestClient restClient, RootBuilderWrapper<Long, Greeting> builders) throws RemoteInvocationException { Request<CollectionResponse<Greeting>> request = builders.findBy("Search").setQueryParam("tone", Tone.SINCERE).paginate(1, 2).build(); Response<CollectionResponse<Greeting>> response = restClient.sendRequest(request).getResponse(); CollectionResponse<Greeting> collectionResponse = response.getEntity(); List<Greeting> greetings = collectionResponse.getElements(); for (Greeting g : greetings) { Assert.assertEquals(g.getTone(), Tone.SINCERE); } collectionResponse.getPaging().getLinks(); }
@Finder("search") public List<Greeting> search( @PagingContextParam PagingContext ctx, @QueryParam("tone") @Optional Tone tone) { List<Greeting> greetings = new ArrayList<Greeting>(); int idx = 0; int start = ctx.getStart(); int stop = start + ctx.getCount(); for (Greeting g : _db.values()) { if (idx++ >= ctx.getStart()) { if (tone == null || g.getTone().equals(tone)) { greetings.add(g); } if (idx == stop) { break; } } } return greetings; }
@Finder("searchWithTones") public List<Greeting> searchWithTones( @PagingContextParam PagingContext ctx, @QueryParam("tones") @Optional Tone[] tones) { Set<Tone> toneSet = new HashSet<Tone>(Arrays.asList(tones)); List<Greeting> greetings = new ArrayList<Greeting>(); int idx = 0; int start = ctx.getStart(); int stop = start + ctx.getCount(); for (Greeting g : _db.values()) { if (idx++ >= ctx.getStart()) { if (tones == null || toneSet.contains(g.getTone())) { greetings.add(g); } if (idx == stop) { break; } } } return greetings; }
@Test( dataProvider = com.linkedin.restli.internal.common.TestConstants.RESTLI_PROTOCOL_1_2_PREFIX + "clientDataDataProvider") public void testAction(RestClient restClient, RootBuilderWrapper<Long, Greeting> builders) throws RemoteInvocationException { Request<Greeting> request = builders .<Greeting>action("SomeAction") .id(1L) .setActionParam("A", 1) .setActionParam("B", "") .setActionParam("C", new TransferOwnershipRequest()) .setActionParam("D", new TransferOwnershipRequest()) .setActionParam("E", 3) .build(); Response<Greeting> response = restClient.sendRequest(request).getResponse(); Greeting greeting = response.getEntity(); Assert.assertEquals(greeting.getMessage(), "This is a newly created greeting"); }
@Test( dataProvider = com.linkedin.restli.internal.common.TestConstants.RESTLI_PROTOCOL_1_2_PREFIX + "requestBuilderDataProvider") public void testPostsWithCharset(RootBuilderWrapper<Long, Greeting> builders) throws RemoteInvocationException { RestClient restClient = new RestClient(CLIENT, URI_PREFIX); Request<Greeting> request = builders .<Greeting>action("SomeAction") .id(1L) .setActionParam("A", 1) .setActionParam("B", "") .setActionParam("C", new TransferOwnershipRequest()) .setActionParam("D", new TransferOwnershipRequest()) .setActionParam("E", 3) .setHeader("Content-Type", "application/json; charset=UTF-8") .build(); Response<Greeting> response = restClient.sendRequest(request).getResponse(); Greeting actionGreeting = response.getEntity(); Assert.assertEquals(actionGreeting.getMessage(), "This is a newly created greeting"); Greeting createGreeting = new Greeting(); createGreeting.setMessage("Hello there!"); createGreeting.setTone(Tone.FRIENDLY); Request<EmptyRecord> createRequest = builders .create() .input(createGreeting) .setHeader("Content-Type", "application/json; charset=UTF-8") .build(); Response<EmptyRecord> emptyRecordResponse = restClient.sendRequest(createRequest).getResponse(); Assert.assertNull(emptyRecordResponse.getHeader(RestConstants.HEADER_CONTENT_TYPE)); }
private static Collection<ScatterGatherBuilder.RequestInfo<Greeting>> buildScatterGatherGetRequests(ScatterGatherBuilder<Greeting> sg, Long[] ids) throws ServiceUnavailableException { Request<BatchResponse<Greeting>> request = new GreetingsBuilders() .batchGet() .ids(ids) .fields(Greeting.fields().message()) .setParam("foo", "bar") .build(); return sg.buildRequestsV2((BatchGetRequest<Greeting>) request, new RequestContext()) .getRequestInfo(); }
@Finder("searchWithFacets") public CollectionResult<Greeting, SearchMetadata> searchWithFacets( @PagingContextParam PagingContext ctx, @QueryParam("tone") @Optional Tone tone) { List<Greeting> greetings = search(ctx, tone); Map<Tone, Integer> toneCounts = new HashMap<Tone, Integer>(); for (Greeting g : greetings) { if (!toneCounts.containsKey(g.getTone())) { toneCounts.put(g.getTone(), 0); } toneCounts.put(g.getTone(), toneCounts.get(g.getTone()) + 1); } SearchMetadata metadata = new SearchMetadata(); metadata.setFacets(new ToneFacetArray()); for (Map.Entry<Tone, Integer> entry : toneCounts.entrySet()) { ToneFacet f = new ToneFacet(); f.setTone(entry.getKey()); f.setCount(entry.getValue()); metadata.getFacets().add(f); } return new CollectionResult<Greeting, SearchMetadata>(greetings, null, metadata); }