Repository: predictionio-sdk-java Updated Branches: refs/heads/develop 2747475a0 -> 0780fcd55
http://git-wip-us.apache.org/repos/asf/predictionio-sdk-java/blob/0780fcd5/client/src/main/java/org/apache/predictionio/sdk/java/EngineClient.java ---------------------------------------------------------------------- diff --git a/client/src/main/java/org/apache/predictionio/sdk/java/EngineClient.java b/client/src/main/java/org/apache/predictionio/sdk/java/EngineClient.java new file mode 100644 index 0000000..5534a7d --- /dev/null +++ b/client/src/main/java/org/apache/predictionio/sdk/java/EngineClient.java @@ -0,0 +1,135 @@ +/* + * 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.predictionio.sdk.java; + +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; +import com.google.gson.JsonObject; +import com.ning.http.client.RequestBuilder; +import java.io.IOException; +import java.util.Map; +import java.util.concurrent.ExecutionException; +import org.joda.time.DateTime; + +/** + * EngineClient contains generic methods sendQuery() and sendQueryAsFuture() for sending queries. + * + * @version 0.8.3 + * @since 0.8.0 + */ +public class EngineClient extends BaseClient { + + private static final String defaultEngineUrl = "http://localhost:8000"; + + /** + * Instantiates a PredictionIO RESTful API Engine Client using default values for API URL and + * default values in BaseClient. + * + * <p>The default API URL is http://localhost:8000. + */ + public EngineClient() { + super(defaultEngineUrl); + } + + /** + * Instantiates a PredictionIO RESTful API Engine Client using default values in BaseClient. + * + * @param engineUrl the URL of the PredictionIO API + */ + public EngineClient(String engineUrl) { + super(engineUrl); + } + + /** + * Instantiates a PredictionIO RESTful API Engine Client using default values in BaseClient for + * parameters that are not specified. + * + * @param engineUrl the URL of the PredictionIO API + * @param threadLimit maximum number of simultaneous threads (connections) to the API + */ + public EngineClient(String engineUrl, int threadLimit) { + super(engineUrl, threadLimit); + } + + /** + * Instantiates a PredictionIO RESTful API Engine Client using default values in BaseClient for + * parameters that are not specified. + * + * @param engineUrl the URL of the PredictionIO API + * @param threadLimit maximum number of simultaneous threads (connections) to the API + * @param queueSize size of the queue + */ + public EngineClient(String engineUrl, int threadLimit, int queueSize) { + super(engineUrl, threadLimit, queueSize); + } + + /** + * Instantiates a PredictionIO RESTful API Engine Client. + * + * @param engineUrl the URL of the PredictionIO API + * @param threadLimit maximum number of simultaneous threads (connections) to the API + * @param queueSize size of the queue + * @param timeout timeout in seconds for the connections + */ + public EngineClient(String engineUrl, int threadLimit, int queueSize, int timeout) { + super(engineUrl, threadLimit, queueSize, timeout); + } + + /** + * Sends a query asynchronously. + */ + public FutureAPIResponse sendQueryAsFuture(Map<String, Object> query) + throws ExecutionException, InterruptedException, IOException { + RequestBuilder builder = new RequestBuilder("POST"); + builder.setUrl(apiUrl + "/queries.json"); + + // handle DateTime separately + GsonBuilder gsonBuilder = new GsonBuilder(); + gsonBuilder.registerTypeAdapter(DateTime.class, new DateTimeAdapter()); + Gson gson = gsonBuilder.create(); + + String requestJsonString = gson.toJson(query); + builder.setBody(requestJsonString); + builder.setHeader("Content-Type", "application/json"); + builder.setHeader("Content-Length", "" + requestJsonString.length()); + return new FutureAPIResponse(client.executeRequest(builder.build(), getHandler())); + } + + /** + * Sends a query synchronously. + */ + public JsonObject sendQuery(Map<String, Object> query) + throws ExecutionException, InterruptedException, IOException { + return sendQuery(sendQueryAsFuture(query)); + } + + /** + * Gets query result from a previously sent asynchronous request. + */ + public JsonObject sendQuery(FutureAPIResponse response) + throws ExecutionException, InterruptedException, IOException { + int status = response.get().getStatus(); + String message = response.get().getMessage(); + + if (status != HTTP_OK) { + throw new IOException(status + " " + message); + } + return ((JsonObject) parser.parse(message)); + } + +} http://git-wip-us.apache.org/repos/asf/predictionio-sdk-java/blob/0780fcd5/client/src/main/java/org/apache/predictionio/sdk/java/Event.java ---------------------------------------------------------------------- diff --git a/client/src/main/java/org/apache/predictionio/sdk/java/Event.java b/client/src/main/java/org/apache/predictionio/sdk/java/Event.java new file mode 100644 index 0000000..9fe29db --- /dev/null +++ b/client/src/main/java/org/apache/predictionio/sdk/java/Event.java @@ -0,0 +1,166 @@ +/* + * 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.predictionio.sdk.java; + +import com.google.common.collect.Maps; +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; +import java.util.Map; +import org.joda.time.DateTime; + +/** + * Event class for PredictionIO Event objects. + * + * @version 0.8.3 + * @since 0.8.0 + */ + +public class Event { + + // mandatory fields + private String event; + private String entityType; + private String entityId; + + // optional fields + private String targetEntityType; + private String targetEntityId; + private Map<String, Object> properties = Maps.newHashMap(); + private DateTime eventTime; + + /** + * Instantiate an event object. + */ + public Event() { + } + + /** + * Returns the name of the event. + */ + public String getEvent() { + return event; + } + + /** + * Returns the entity type. entityType-entityId forms the unique identifier of the entity. + */ + public String getEntityType() { + return entityType; + } + + /** + * Returns the entity id. entityType-entityId forms the unique identifier of the entity. + */ + public String getEntityId() { + return entityId; + } + + /** + * Returns the target entity type, or null if the field is not set. + */ + public String getTargetEntityType() { + return targetEntityType; + } + + /** + * Returns the target entity id, or null if the field is not set. + */ + public String getTargetEntityId() { + return targetEntityId; + } + + /** + * Returns the set of properties as a map. + */ + public Map<String, Object> getProperties() { + return properties; + } + + /** + * Returns the event time, or null if the field is not set. + */ + public DateTime getEventTime() { + return eventTime; + } + + // builder methods for convenience + + /** + * Sets the name of the event. + */ + public Event event(String event) { + this.event = event; + return this; + } + + /** + * Sets the entity type. entityType-entityId forms the unique identifier of the entity. + */ + public Event entityType(String entityType) { + this.entityType = entityType; + return this; + } + + /** + * Sets the entity id. entityType-entityId forms the unique identifier of the entity. + */ + public Event entityId(String entityId) { + this.entityId = entityId; + return this; + } + + public Event targetEntityType(String targetEntityType) { + this.targetEntityType = targetEntityType; + return this; + } + + public Event targetEntityId(String targetEntityId) { + this.targetEntityId = targetEntityId; + return this; + } + + public Event property(String key, Object value) { + this.properties.put(key, value); + return this; + } + + public Event properties(Map<String, Object> properties) { + this.properties.putAll(properties); + return this; + } + + public Event eventTime(DateTime eventTime) { + this.eventTime = eventTime; + return this; + } + + // toJsonString and toString methods + + public String toJsonString() { + return toString(); + } + + @Override + public String toString() { + // handle DateTime separately + GsonBuilder gsonBuilder = new GsonBuilder(); + gsonBuilder.registerTypeAdapter(DateTime.class, new DateTimeAdapter()); + Gson gson = gsonBuilder.create(); + return gson.toJson(this); // works when there are no generic types + } +} http://git-wip-us.apache.org/repos/asf/predictionio-sdk-java/blob/0780fcd5/client/src/main/java/org/apache/predictionio/sdk/java/EventClient.java ---------------------------------------------------------------------- diff --git a/client/src/main/java/org/apache/predictionio/sdk/java/EventClient.java b/client/src/main/java/org/apache/predictionio/sdk/java/EventClient.java new file mode 100644 index 0000000..b1e93ba --- /dev/null +++ b/client/src/main/java/org/apache/predictionio/sdk/java/EventClient.java @@ -0,0 +1,663 @@ +/* + * 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.predictionio.sdk.java; + +import com.google.common.collect.Maps; +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; +import com.google.gson.JsonArray; +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; +import com.ning.http.client.Request; +import com.ning.http.client.RequestBuilder; +import java.io.IOException; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import java.util.concurrent.ExecutionException; +import org.joda.time.DateTime; + +/** + * EventClient contains the generic methods createEvent() and getEvent() for importing and accessing + * events, as well as helper methods such as setUser(), unsetItem() and userActionItem() for + * convenience. Methods with an "AsFuture" suffix are asynchronous. + * + * <p>Multiple simultaneous asynchronous requests is made possible by the high performance backend + * provided by the <a href="https://github.com/AsyncHttpClient/async-http-client">Async Http + * Client</a>. + * + * @version 0.8.3 + * @since 0.8.0 + */ +public class EventClient extends BaseClient { + + private static final String defaultEventUrl = "http://localhost:7070"; + + private final String accessKey; + + /** + * Instantiate a PredictionIO RESTful API Event Client using default values for API URL and + * default values in {@link BaseClient}. + * + * <p>The default API URL is http://localhost:7070. + * + * @param accessKey the access key that this client will use to communicate with the API + */ + public EventClient(String accessKey) { + this(accessKey, defaultEventUrl); + } + + /** + * Instantiate a PredictionIO RESTful API Event Client using default values in {@link + * BaseClient}. + * + * @param accessKey the access key that this client will use to communicate with the API + * @param eventUrl the URL of the PredictionIO API + */ + public EventClient(String accessKey, String eventUrl) { + super(eventUrl); + this.accessKey = accessKey; + } + + /** + * Instantiate a PredictionIO RESTful API Event Client using default values in {@link BaseClient} + * for parameters that are not specified. + * + * @param accessKey the access key that this client will use to communicate with the API + * @param eventUrl the URL of the PredictionIO API + * @param threadLimit maximum number of simultaneous threads (connections) to the API + */ + public EventClient(String accessKey, String eventUrl, int threadLimit) { + super(eventUrl, threadLimit); + this.accessKey = accessKey; + } + + /** + * Instantiate a PredictionIO RESTful API Event Client using default values in {@link BaseClient} + * for parameters that are not specified. + * + * @param accessKey the access key that this client will use to communicate with the API + * @param eventUrl the URL of the PredictionIO API + * @param threadLimit maximum number of simultaneous threads (connections) to the API + * @param queueSize size of the queue + */ + public EventClient(String accessKey, String eventUrl, int threadLimit, int queueSize) { + super(eventUrl, threadLimit, queueSize); + this.accessKey = accessKey; + } + + /** + * Instantiate a PredictionIO RESTful API Event Client. + * + * @param accessKey the access key that this client will use to communicate with the API + * @param eventUrl the URL of the PredictionIO API + * @param threadLimit maximum number of simultaneous threads (connections) to the API + * @param queueSize size of the queue + * @param timeout timeout in seconds for the connections + */ + public EventClient(String accessKey, String eventUrl, int threadLimit, int queueSize, + int timeout) { + super(eventUrl, threadLimit, queueSize, timeout); + this.accessKey = accessKey; + } + + /** + * Sends an asynchronous create event request to the API. + * + * @param event an instance of {@link Event} that will be turned into a request + */ + public FutureAPIResponse createEventAsFuture(Event event) throws IOException { + RequestBuilder builder = new RequestBuilder("POST"); + builder.setUrl(apiUrl + "/events.json?accessKey=" + accessKey); + String requestJsonString = event.toJsonString(); + builder.setBody(requestJsonString); + builder.setHeader("Content-Type", "application/json"); + builder.setHeader("Content-Length", "" + requestJsonString.length()); + return new FutureAPIResponse(client.executeRequest(builder.build(), getHandler())); + } + + /** + * Sends a synchronous create event request to the API. + * + * @param event an instance of {@link Event} that will be turned into a request + * @return event ID from the server + * @throws ExecutionException indicates an error in the HTTP backend + * @throws InterruptedException indicates an interruption during the HTTP operation + * @throws IOException indicates an error from the API response + */ + public String createEvent(Event event) + throws ExecutionException, InterruptedException, IOException { + return createEvent(createEventAsFuture(event)); + } + + /** + * Synchronize a previously sent asynchronous create event request. + * + * @param response an instance of {@link FutureAPIResponse} returned from {@link + * #createEventAsFuture} + * @return event ID from the server + * @throws ExecutionException indicates an error in the HTTP backend + * @throws InterruptedException indicates an interruption during the HTTP operation + * @throws IOException indicates an error from the API response + */ + public String createEvent(FutureAPIResponse response) + throws ExecutionException, InterruptedException, IOException { + int status = response.get().getStatus(); + String message = response.get().getMessage(); + + if (status != HTTP_CREATED) { + throw new IOException(status + " " + message); + } + return ((JsonObject) parser.parse(message)).get("eventId").getAsString(); + } + + /** + * Sends an asynchronous create events (batch) request to the API. + * + * @param events a List of {@link Event} that will be turned into a request + */ + public FutureAPIResponse createEventsAsFuture(List<Event> events) throws IOException { + RequestBuilder builder = new RequestBuilder("POST"); + builder.setUrl(apiUrl + "/batch/events.json?accessKey=" + accessKey); + + GsonBuilder gsonBuilder = new GsonBuilder(); + gsonBuilder.registerTypeAdapter(DateTime.class, new DateTimeAdapter()); + Gson gson = gsonBuilder.create(); + String requestJsonString = gson.toJson(events); + + builder.setBody(requestJsonString); + builder.setHeader("Content-Type", "application/json"); + builder.setHeader("Content-Length", "" + requestJsonString.length()); + return new FutureAPIResponse(client.executeRequest(builder.build(), getHandler())); + } + + /** + * Sends a synchronous create events (batch) request to the API. + * + * @param events a List of {@link Event} that will be turned into a request + * @return event ID from the server + * @throws ExecutionException indicates an error in the HTTP backend + * @throws InterruptedException indicates an interruption during the HTTP operation + * @throws IOException indicates an error from the API response + */ + public List<String> createEvents(List<Event> events) + throws ExecutionException, InterruptedException, IOException { + return createEvents(createEventsAsFuture(events)); + } + + /** + * Synchronize a previously sent asynchronous create events (batch) request. + * + * @param response an instance of {@link FutureAPIResponse} returned from {@link + * #createEventAsFuture} + * @return List of event IDs from the server + * @throws ExecutionException indicates an error in the HTTP backend + * @throws InterruptedException indicates an interruption during the HTTP operation + * @throws IOException indicates an error from the API response + */ + public List<String> createEvents(FutureAPIResponse response) + throws ExecutionException, InterruptedException, IOException { + int status = response.get().getStatus(); + String message = response.get().getMessage(); + + if (status != HTTP_OK) { + throw new IOException(status + " " + message); + } + List<String> eventIds = new LinkedList<String>(); + + for (JsonElement elem : (JsonArray) parser.parse(message)) { + eventIds.add(((JsonObject) elem).get("eventId").getAsString()); + } + return eventIds; + } + + /** + * Sends an asynchronous get event request to the API. + * + * @param eid ID of the event to get + */ + public FutureAPIResponse getEventAsFuture(String eid) throws IOException { + Request request = (new RequestBuilder("GET")) + .setUrl(apiUrl + "/events/" + eid + ".json?accessKey=" + accessKey) + .build(); + return new FutureAPIResponse(client.executeRequest(request, getHandler())); + } + + /** + * Sends a synchronous get event request to the API. + * + * @param eid ID of the event to get + * @throws ExecutionException indicates an error in the HTTP backend + * @throws InterruptedException indicates an interruption during the HTTP operation + * @throws IOException indicates an error from the API response + */ + public Event getEvent(String eid) + throws ExecutionException, InterruptedException, IOException { + return getEvent(getEventAsFuture(eid)); + } + + /** + * Synchronize a previously sent asynchronous get item request. + * + * @param response an instance of {@link FutureAPIResponse} returned from {@link + * #getEventAsFuture} + * @throws ExecutionException indicates an error in the HTTP backend + * @throws InterruptedException indicates an interruption during the HTTP operation + * @throws IOException indicates an error from the API response + */ + public Event getEvent(FutureAPIResponse response) + throws ExecutionException, InterruptedException, IOException { + int status = response.get().getStatus(); + String message = response.get().getMessage(); + + if (status == HTTP_OK) { + // handle DateTime separately + GsonBuilder gsonBuilder = new GsonBuilder(); + gsonBuilder.registerTypeAdapter(DateTime.class, new DateTimeAdapter()); + Gson gson = gsonBuilder.create(); + + return gson.fromJson(message, Event.class); + } else { + throw new IOException(message); + } + } + + //////////////////////////////////// + // + // helper methods for convenience + // + //////////////////////////////////// + + /** + * Sends a set user properties request. Implicitly creates the user if it's not already there. + * Properties could be empty. + * + * @param uid ID of the user + * @param properties a map of all the properties to be associated with the user, could be empty + * @param eventTime timestamp of the event + * @return ID of this event + */ + public FutureAPIResponse setUserAsFuture(String uid, Map<String, Object> properties, + DateTime eventTime) throws IOException { + return createEventAsFuture(new Event() + .event("$set") + .entityType("user") + .entityId(uid) + .eventTime(eventTime) + .properties(properties)); + } + + /** + * Sends a set user properties request. Same as {@link #setUserAsFuture(String, Map, DateTime) + * setUserAsFuture(String, Map<String, Object>, DateTime)} except event time is not + * specified and recorded as the time when the function is called. + */ + public FutureAPIResponse setUserAsFuture(String uid, Map<String, Object> properties) + throws IOException { + return setUserAsFuture(uid, properties, new DateTime()); + } + + /** + * Sets properties of a user. Implicitly creates the user if it's not already there. Properties + * could be empty. + * + * @param uid ID of the user + * @param properties a map of all the properties to be associated with the user, could be empty + * @param eventTime timestamp of the event + * @return ID of this event + */ + public String setUser(String uid, Map<String, Object> properties, DateTime eventTime) + throws ExecutionException, InterruptedException, IOException { + return createEvent(setUserAsFuture(uid, properties, eventTime)); + } + + /** + * Sets properties of a user. Same as {@link #setUser(String, Map, DateTime)} except event time is + * not specified and recorded as the time when the function is called. + */ + public String setUser(String uid, Map<String, Object> properties) + throws ExecutionException, InterruptedException, IOException { + return setUser(uid, properties, new DateTime()); + } + + /** + * Sends an unset user properties request. The list must not be empty. + * + * @param uid ID of the user + * @param properties a list of all the properties to unset + * @param eventTime timestamp of the event + */ + public FutureAPIResponse unsetUserAsFuture(String uid, List<String> properties, + DateTime eventTime) throws IOException { + if (properties.isEmpty()) { + throw new IllegalStateException("property list cannot be empty"); + } + // converts the list into a map (to empty string) before creating the event object + Map<String, Object> propertiesMap = Maps.newHashMap(); + for (String property : properties) { + propertiesMap.put(property, ""); + } + return createEventAsFuture(new Event() + .event("$unset") + .entityType("user") + .entityId(uid) + .eventTime(eventTime) + .properties(propertiesMap)); + } + + /** + * Sends an unset user properties request. Same as {@link #unsetUserAsFuture(String, List, + * DateTime) unsetUserAsFuture(String, List<String>, DateTime)} except event time is not + * specified and recorded as the time when the function is called. + */ + public FutureAPIResponse unsetUserAsFuture(String uid, List<String> properties) + throws IOException { + return unsetUserAsFuture(uid, properties, new DateTime()); + } + + /** + * Unsets properties of a user. The list must not be empty. + * + * @param uid ID of the user + * @param properties a list of all the properties to unset + * @param eventTime timestamp of the event + * @return ID of this event + */ + public String unsetUser(String uid, List<String> properties, DateTime eventTime) + throws ExecutionException, InterruptedException, IOException { + return createEvent(unsetUserAsFuture(uid, properties, eventTime)); + } + + /** + * Unsets properties of a user. Same as {@link #unsetUser(String, List, DateTime) + * unsetUser(String, List<String>, DateTime)} except event time is not specified and + * recorded as the time when the function is called. + */ + public String unsetUser(String uid, List<String> properties) + throws ExecutionException, InterruptedException, IOException { + return unsetUser(uid, properties, new DateTime()); + } + + /** + * Sends a delete user request. + * + * @param uid ID of the user + * @param eventTime timestamp of the event + */ + public FutureAPIResponse deleteUserAsFuture(String uid, DateTime eventTime) + throws IOException { + return createEventAsFuture(new Event() + .event("$delete") + .entityType("user") + .entityId(uid) + .eventTime(eventTime)); + } + + /** + * Sends a delete user request. Event time is recorded as the time when the function is called. + * + * @param uid ID of the user + */ + public FutureAPIResponse deleteUserAsFuture(String uid) + throws IOException { + return deleteUserAsFuture(uid, new DateTime()); + } + + /** + * Deletes a user. + * + * @param uid ID of the user + * @param eventTime timestamp of the event + * @return ID of this event + */ + public String deleteUser(String uid, DateTime eventTime) + throws ExecutionException, InterruptedException, IOException { + return createEvent(deleteUserAsFuture(uid, eventTime)); + } + + /** + * Deletes a user. Event time is recorded as the time when the function is called. + * + * @param uid ID of the user + * @return ID of this event + */ + public String deleteUser(String uid) + throws ExecutionException, InterruptedException, IOException { + return deleteUser(uid, new DateTime()); + } + + + /** + * Sends a set item properties request. Implicitly creates the item if it's not already there. + * Properties could be empty. + * + * @param iid ID of the item + * @param properties a map of all the properties to be associated with the item, could be empty + * @param eventTime timestamp of the event + * @return ID of this event + */ + public FutureAPIResponse setItemAsFuture(String iid, Map<String, Object> properties, + DateTime eventTime) throws IOException { + return createEventAsFuture(new Event() + .event("$set") + .entityType("item") + .entityId(iid) + .eventTime(eventTime) + .properties(properties)); + } + + /** + * Sends a set item properties request. Same as {@link #setItemAsFuture(String, Map, DateTime) + * setItemAsFuture(String, Map<String, Object>, DateTime)} except event time is not + * specified and recorded as the time when the function is called. + */ + public FutureAPIResponse setItemAsFuture(String iid, Map<String, Object> properties) + throws IOException { + return setItemAsFuture(iid, properties, new DateTime()); + } + + /** + * Sets properties of a item. Implicitly creates the item if it's not already there. Properties + * could be empty. + * + * @param iid ID of the item + * @param properties a map of all the properties to be associated with the item, could be empty + * @param eventTime timestamp of the event + * @return ID of this event + */ + public String setItem(String iid, Map<String, Object> properties, DateTime eventTime) + throws ExecutionException, InterruptedException, IOException { + return createEvent(setItemAsFuture(iid, properties, eventTime)); + } + + /** + * Sets properties of a item. Same as {@link #setItem(String, Map, DateTime) setItem(String, + * Map<String, Object>, DateTime)} except event time is not specified and recorded as the + * time when the function is called. + */ + public String setItem(String iid, Map<String, Object> properties) + throws ExecutionException, InterruptedException, IOException { + return setItem(iid, properties, new DateTime()); + } + + /** + * Sends an unset item properties request. The list must not be empty. + * + * @param iid ID of the item + * @param properties a list of all the properties to unset + * @param eventTime timestamp of the event + */ + public FutureAPIResponse unsetItemAsFuture(String iid, List<String> properties, + DateTime eventTime) throws IOException { + if (properties.isEmpty()) { + throw new IllegalStateException("property list cannot be empty"); + } + // converts the list into a map (to empty string) before creating the event object + Map<String, Object> propertiesMap = Maps.newHashMap(); + for (String property : properties) { + propertiesMap.put(property, ""); + } + return createEventAsFuture(new Event() + .event("$unset") + .entityType("item") + .entityId(iid) + .eventTime(eventTime) + .properties(propertiesMap)); + } + + /** + * Sends an unset item properties request. Same as {@link #unsetItemAsFuture(String, List, + * DateTime) unsetItemAsFuture(String, List<String>, DateTime)} except event time is not + * specified and recorded as the time when the function is called. + */ + public FutureAPIResponse unsetItemAsFuture(String iid, List<String> properties) + throws IOException { + return unsetItemAsFuture(iid, properties, new DateTime()); + } + + /** + * Unsets properties of a item. The list must not be empty. + * + * @param iid ID of the item + * @param properties a list of all the properties to unset + * @param eventTime timestamp of the event + * @return ID of this event + */ + public String unsetItem(String iid, List<String> properties, DateTime eventTime) + throws ExecutionException, InterruptedException, IOException { + return createEvent(unsetItemAsFuture(iid, properties, eventTime)); + } + + /** + * Unsets properties of a item. Same as {@link #unsetItem(String, List, DateTime) + * unsetItem(String, List<String>, DateTime)} except event time is not specified and + * recorded as the time when the function is called. + */ + public String unsetItem(String iid, List<String> properties) + throws ExecutionException, InterruptedException, IOException { + return unsetItem(iid, properties, new DateTime()); + } + + /** + * Sends a delete item request. + * + * @param iid ID of the item + * @param eventTime timestamp of the event + */ + public FutureAPIResponse deleteItemAsFuture(String iid, DateTime eventTime) + throws IOException { + return createEventAsFuture(new Event() + .event("$delete") + .entityType("item") + .entityId(iid) + .eventTime(eventTime)); + } + + /** + * Sends a delete item request. Event time is recorded as the time when the function is called. + * + * @param iid ID of the item + */ + public FutureAPIResponse deleteItemAsFuture(String iid) + throws IOException { + return deleteItemAsFuture(iid, new DateTime()); + } + + /** + * Deletes a item. + * + * @param iid ID of the item + * @param eventTime timestamp of the event + * @return ID of this event + */ + public String deleteItem(String iid, DateTime eventTime) + throws ExecutionException, InterruptedException, IOException { + return createEvent(deleteItemAsFuture(iid, eventTime)); + } + + /** + * Deletes a item. Event time is recorded as the time when the function is called. + * + * @param iid ID of the item + * @return ID of this event + */ + public String deleteItem(String iid) + throws ExecutionException, InterruptedException, IOException { + return deleteItem(iid, new DateTime()); + } + + /** + * Sends a user-action-on-item request. + * + * @param action name of the action performed + * @param uid ID of the user + * @param iid ID of the item + * @param properties a map of properties associated with this action + * @param eventTime timestamp of the event + */ + public FutureAPIResponse userActionItemAsFuture(String action, String uid, String iid, + Map<String, Object> properties, DateTime eventTime) throws IOException { + return createEventAsFuture(new Event() + .event(action) + .entityType("user") + .entityId(uid) + .targetEntityType("item") + .targetEntityId(iid) + .properties(properties) + .eventTime(eventTime)); + } + + /** + * Sends a user-action-on-item request. Similar to {@link #userActionItemAsFuture(String, String, + * String, Map, DateTime) #userActionItemAsFuture(String, String, String, Map<String, + * Object\gt;, DateTime)} except event time is not specified and recorded as the time when the + * function is called. + */ + public FutureAPIResponse userActionItemAsFuture(String action, String uid, String iid, + Map<String, Object> properties) throws IOException { + return userActionItemAsFuture(action, uid, iid, properties, new DateTime()); + } + + /** + * Records a user-action-on-item event. + * + * @param action name of the action performed + * @param uid ID of the user + * @param iid ID of the item + * @param properties a map of properties associated with this action + * @param eventTime timestamp of the event + * @return ID of this event + */ + public String userActionItem(String action, String uid, String iid, + Map<String, Object> properties, DateTime eventTime) + throws ExecutionException, InterruptedException, IOException { + return createEvent(userActionItemAsFuture(action, uid, iid, properties, eventTime)); + } + + /** + * Records a user-action-on-item event. Similar to {@link #userActionItem(String, String, String, + * Map, DateTime) userActionItem(String, String, String, Map<String, Object>, DateTime)} + * except event time is not specified and recorded as the time when the function is called. + */ + public String userActionItem(String action, String uid, String iid, + Map<String, Object> properties) + throws ExecutionException, InterruptedException, IOException { + return userActionItem(action, uid, iid, properties, new DateTime()); + } + +} http://git-wip-us.apache.org/repos/asf/predictionio-sdk-java/blob/0780fcd5/client/src/main/java/org/apache/predictionio/sdk/java/FileExporter.java ---------------------------------------------------------------------- diff --git a/client/src/main/java/org/apache/predictionio/sdk/java/FileExporter.java b/client/src/main/java/org/apache/predictionio/sdk/java/FileExporter.java new file mode 100644 index 0000000..e309d01 --- /dev/null +++ b/client/src/main/java/org/apache/predictionio/sdk/java/FileExporter.java @@ -0,0 +1,80 @@ +/* + * 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.predictionio.sdk.java; + + +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.IOException; +import java.util.Map; +import org.joda.time.DateTime; + +public class FileExporter { + + private FileOutputStream out; + + public FileExporter(String pathname) throws FileNotFoundException { + out = new FileOutputStream(pathname); + } + + /** + * Create and write a json-encoded event to the underlying file. + * + * @param eventName Name of the event. + * @param entityType The entity type. + * @param entityId The entity ID. + * @param targetEntityType The target entity type (optional). + * @param targetEntityId The target entity ID (optional). + * @param properties Properties (optional). + * @param eventTime The time of the event (optional). + */ + public void createEvent(String eventName, String entityType, String entityId, + String targetEntityType, String targetEntityId, Map<String, Object> properties, + DateTime eventTime) throws IOException { + + if (eventTime == null) { + eventTime = new DateTime(); + } + + Event event = new Event() + .event(eventName) + .entityType(entityType) + .entityId(entityId) + .eventTime(eventTime); + + if (targetEntityType != null) { + event.targetEntityType(targetEntityType); + } + + if (targetEntityId != null) { + event.targetEntityId(targetEntityId); + } + + if (properties != null) { + event.properties(properties); + } + + out.write(event.toJsonString().getBytes("UTF8")); + out.write('\n'); + } + + public void close() throws IOException { + out.close(); + } + +} http://git-wip-us.apache.org/repos/asf/predictionio-sdk-java/blob/0780fcd5/client/src/main/java/org/apache/predictionio/sdk/java/FutureAPIResponse.java ---------------------------------------------------------------------- diff --git a/client/src/main/java/org/apache/predictionio/sdk/java/FutureAPIResponse.java b/client/src/main/java/org/apache/predictionio/sdk/java/FutureAPIResponse.java new file mode 100644 index 0000000..cd6cb56 --- /dev/null +++ b/client/src/main/java/org/apache/predictionio/sdk/java/FutureAPIResponse.java @@ -0,0 +1,91 @@ +/* + * 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.predictionio.sdk.java; + +import com.google.common.util.concurrent.ListenableFuture; +import com.ning.http.client.extra.ListenableFutureAdapter; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.Executor; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.TimeoutException; + +/** + * APIResponse as a listenable future. + * + * @version 0.8.3 + * @since 0.2 + */ + +public class FutureAPIResponse implements ListenableFuture<APIResponse> { + + private ListenableFuture<APIResponse> apiResponse; + + public FutureAPIResponse(com.ning.http.client.ListenableFuture<APIResponse> apiResponse) { + this.apiResponse = ListenableFutureAdapter.asGuavaFuture(apiResponse); + } + + // implements ListenableFuture<APIResponse> + + public void addListener(Runnable listener, Executor executor) { + this.apiResponse.addListener(listener, executor); + } + + // implements Future<APIResponse> + + public boolean cancel(boolean mayInterruptIfRunning) { + return this.apiResponse.cancel(mayInterruptIfRunning); + } + + public APIResponse get() throws ExecutionException, InterruptedException { + return this.apiResponse.get(); + } + + public APIResponse get(long timeout, TimeUnit unit) + throws ExecutionException, InterruptedException, TimeoutException { + return this.apiResponse.get(timeout, unit); + } + + public boolean isCancelled() { + return this.apiResponse.isCancelled(); + } + + public boolean isDone() { + return this.apiResponse.isDone(); + } + + public ListenableFuture<APIResponse> getAPIResponse() { + // get the underlying APIResponse + return this.apiResponse; + } + + public int getStatus() { + try { + return this.apiResponse.get().getStatus(); + } catch (InterruptedException | ExecutionException e) { + return 0; + } + } + + public String getMessage() { + try { + return this.apiResponse.get().getMessage(); + } catch (InterruptedException | ExecutionException e) { + return e.getMessage(); + } + } +} http://git-wip-us.apache.org/repos/asf/predictionio-sdk-java/blob/0780fcd5/client/src/main/java/org/apache/predictionio/sdk/java/package-info.java ---------------------------------------------------------------------- diff --git a/client/src/main/java/org/apache/predictionio/sdk/java/package-info.java b/client/src/main/java/org/apache/predictionio/sdk/java/package-info.java new file mode 100644 index 0000000..1b2bd67 --- /dev/null +++ b/client/src/main/java/org/apache/predictionio/sdk/java/package-info.java @@ -0,0 +1,27 @@ +/* + * 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. + */ + +/** + * This package contains classes that provide convenient access of Apache PredictionIO RESTful API. + * + * To create an app and perform predictions, please download Apache PredictionIO from + * <a href="http://predictionio.apache.org" target="_blank">http://predictionio.apache.org</a>. + * + * Most functionality is provided by the {@link org.apache.predictionio.sdk.java.EventClient} and + * {@link org.apache.predictionio.sdk.java.EngineClient} class. + */ +package org.apache.predictionio.sdk.java; http://git-wip-us.apache.org/repos/asf/predictionio-sdk-java/blob/0780fcd5/client/src/test/java/io/prediction/FileExporterTest.java ---------------------------------------------------------------------- diff --git a/client/src/test/java/io/prediction/FileExporterTest.java b/client/src/test/java/io/prediction/FileExporterTest.java deleted file mode 100644 index a5c7759..0000000 --- a/client/src/test/java/io/prediction/FileExporterTest.java +++ /dev/null @@ -1,116 +0,0 @@ -package io.prediction; - -import com.google.gson.Gson; -import com.google.gson.GsonBuilder; -import org.joda.time.DateTime; -import org.junit.Rule; -import org.junit.Test; -import org.junit.rules.TemporaryFolder; -import static org.junit.Assert.*; - -import java.io.BufferedReader; -import java.io.File; -import java.io.FileReader; -import java.io.IOException; -import java.util.HashMap; -import java.util.Map; - -public class FileExporterTest { - - @Rule - public TemporaryFolder folder = new TemporaryFolder(); - - @Test - public void testIt() throws IOException { - - String pathname = folder.getRoot().getCanonicalPath() + "/testIt.out"; - - FileExporter exporter = new FileExporter(pathname); - - Map<String, Object> properties = new HashMap<>(); - properties.put("birthday", new DateTime("1758-05-06T00:00:00+00:00")); - - DateTime then = new DateTime("1794-07-27T00:00:00+00:00"); - - exporter.createEvent("event-1", "entity-type-1", "entity-id-1", - null, null, null, null); - - exporter.createEvent("event-2", "entity-type-2", "entity-id-2", - "target-entity-type-2", null, null, null); - - exporter.createEvent("event-3", "entity-type-3", "entity-id-3", - null, "target-entity-id-3", null, null); - - exporter.createEvent("event-4", "entity-type-4", "entity-id-4", - null, null, properties, then); - - exporter.createEvent("event-5", "entity-type-5", "entity-id-5", - "target-entity-type-5", "target-entity-id-5", properties, then); - - exporter.close(); - - File out = new File(pathname); - assertTrue(pathname + " exists", out.exists()); - - BufferedReader reader = new BufferedReader(new FileReader(pathname)); - - GsonBuilder gsonBuilder = new GsonBuilder(); - gsonBuilder.registerTypeAdapter(DateTime.class, new DateTimeAdapter()); - Gson gson = gsonBuilder.create(); - - String json1 = reader.readLine(); - Event event1 = gson.fromJson(json1, Event.class); - assertEquals("event-1", event1.getEvent()); - assertEquals("entity-type-1", event1.getEntityType()); - assertEquals("entity-id-1", event1.getEntityId()); - assertNull(event1.getTargetEntityType()); - assertNull(event1.getTargetEntityId()); - assertTrue(event1.getProperties().isEmpty()); - assertEquals(new DateTime().getMillis(), event1.getEventTime().getMillis(), 1000); - - String json2 = reader.readLine(); - Event event2 = gson.fromJson(json2, Event.class); - assertEquals("event-2", event2.getEvent()); - assertEquals("entity-type-2", event2.getEntityType()); - assertEquals("entity-id-2", event2.getEntityId()); - assertEquals("target-entity-type-2", event2.getTargetEntityType()); - assertNull(event2.getTargetEntityId()); - assertTrue(event2.getProperties().isEmpty()); - assertEquals(new DateTime().getMillis(), event2.getEventTime().getMillis(), 1000); - - String json3 = reader.readLine(); - Event event3 = gson.fromJson(json3, Event.class); - assertEquals("event-3", event3.getEvent()); - assertEquals("entity-type-3", event3.getEntityType()); - assertEquals("entity-id-3", event3.getEntityId()); - assertNull(event3.getTargetEntityType()); - assertEquals("target-entity-id-3", event3.getTargetEntityId()); - assertTrue(event3.getProperties().isEmpty()); - assertEquals(new DateTime().getMillis(), event3.getEventTime().getMillis(), 1000); - - String json4 = reader.readLine(); - Event event4 = gson.fromJson(json4, Event.class); - assertEquals("event-4", event4.getEvent()); - assertEquals("entity-type-4", event4.getEntityType()); - assertEquals("entity-id-4", event4.getEntityId()); - assertNull(event4.getTargetEntityType()); - assertNull(event4.getTargetEntityId()); - assertEquals(1, event4.getProperties().size()); - assertEquals(properties.get("birthday"), new DateTime(event4.getProperties().get("birthday"))); - assertEquals(then.getMillis(), event4.getEventTime().getMillis()); - - String json5 = reader.readLine(); - Event event5 = gson.fromJson(json5, Event.class); - assertEquals("event-5", event5.getEvent()); - assertEquals("entity-type-5", event5.getEntityType()); - assertEquals("entity-id-5", event5.getEntityId()); - assertEquals("target-entity-type-5", event5.getTargetEntityType()); - assertEquals("target-entity-id-5", event5.getTargetEntityId()); - assertEquals(1, event5.getProperties().size()); - assertEquals(properties.get("birthday"), new DateTime(event5.getProperties().get("birthday"))); - assertEquals(then.getMillis(), event4.getEventTime().getMillis()); - - String empty = reader.readLine(); - assertNull("no more data", empty); - } -} http://git-wip-us.apache.org/repos/asf/predictionio-sdk-java/blob/0780fcd5/client/src/test/java/org/apache/predictionio/sdk/java/FileExporterTest.java ---------------------------------------------------------------------- diff --git a/client/src/test/java/org/apache/predictionio/sdk/java/FileExporterTest.java b/client/src/test/java/org/apache/predictionio/sdk/java/FileExporterTest.java new file mode 100644 index 0000000..076332c --- /dev/null +++ b/client/src/test/java/org/apache/predictionio/sdk/java/FileExporterTest.java @@ -0,0 +1,135 @@ +/* + * 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.predictionio.sdk.java; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; + +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; +import java.io.BufferedReader; +import java.io.File; +import java.io.FileReader; +import java.io.IOException; +import java.util.HashMap; +import java.util.Map; +import org.joda.time.DateTime; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.TemporaryFolder; + +public class FileExporterTest { + + @Rule + public TemporaryFolder folder = new TemporaryFolder(); + + @Test + public void testIt() throws IOException { + + String pathname = folder.getRoot().getCanonicalPath() + "/testIt.out"; + + FileExporter exporter = new FileExporter(pathname); + + Map<String, Object> properties = new HashMap<>(); + properties.put("birthday", new DateTime("1758-05-06T00:00:00+00:00")); + + DateTime then = new DateTime("1794-07-27T00:00:00+00:00"); + + exporter.createEvent("event-1", "entity-type-1", "entity-id-1", + null, null, null, null); + + exporter.createEvent("event-2", "entity-type-2", "entity-id-2", + "target-entity-type-2", null, null, null); + + exporter.createEvent("event-3", "entity-type-3", "entity-id-3", + null, "target-entity-id-3", null, null); + + exporter.createEvent("event-4", "entity-type-4", "entity-id-4", + null, null, properties, then); + + exporter.createEvent("event-5", "entity-type-5", "entity-id-5", + "target-entity-type-5", "target-entity-id-5", properties, then); + + exporter.close(); + + File out = new File(pathname); + assertTrue(pathname + " exists", out.exists()); + + BufferedReader reader = new BufferedReader(new FileReader(pathname)); + + GsonBuilder gsonBuilder = new GsonBuilder(); + gsonBuilder.registerTypeAdapter(DateTime.class, new DateTimeAdapter()); + Gson gson = gsonBuilder.create(); + + String json1 = reader.readLine(); + Event event1 = gson.fromJson(json1, Event.class); + assertEquals("event-1", event1.getEvent()); + assertEquals("entity-type-1", event1.getEntityType()); + assertEquals("entity-id-1", event1.getEntityId()); + assertNull(event1.getTargetEntityType()); + assertNull(event1.getTargetEntityId()); + assertTrue(event1.getProperties().isEmpty()); + assertEquals(new DateTime().getMillis(), event1.getEventTime().getMillis(), 1000); + + String json2 = reader.readLine(); + Event event2 = gson.fromJson(json2, Event.class); + assertEquals("event-2", event2.getEvent()); + assertEquals("entity-type-2", event2.getEntityType()); + assertEquals("entity-id-2", event2.getEntityId()); + assertEquals("target-entity-type-2", event2.getTargetEntityType()); + assertNull(event2.getTargetEntityId()); + assertTrue(event2.getProperties().isEmpty()); + assertEquals(new DateTime().getMillis(), event2.getEventTime().getMillis(), 1000); + + String json3 = reader.readLine(); + Event event3 = gson.fromJson(json3, Event.class); + assertEquals("event-3", event3.getEvent()); + assertEquals("entity-type-3", event3.getEntityType()); + assertEquals("entity-id-3", event3.getEntityId()); + assertNull(event3.getTargetEntityType()); + assertEquals("target-entity-id-3", event3.getTargetEntityId()); + assertTrue(event3.getProperties().isEmpty()); + assertEquals(new DateTime().getMillis(), event3.getEventTime().getMillis(), 1000); + + String json4 = reader.readLine(); + Event event4 = gson.fromJson(json4, Event.class); + assertEquals("event-4", event4.getEvent()); + assertEquals("entity-type-4", event4.getEntityType()); + assertEquals("entity-id-4", event4.getEntityId()); + assertNull(event4.getTargetEntityType()); + assertNull(event4.getTargetEntityId()); + assertEquals(1, event4.getProperties().size()); + assertEquals(properties.get("birthday"), new DateTime(event4.getProperties().get("birthday"))); + assertEquals(then.getMillis(), event4.getEventTime().getMillis()); + + String json5 = reader.readLine(); + Event event5 = gson.fromJson(json5, Event.class); + assertEquals("event-5", event5.getEvent()); + assertEquals("entity-type-5", event5.getEntityType()); + assertEquals("entity-id-5", event5.getEntityId()); + assertEquals("target-entity-type-5", event5.getTargetEntityType()); + assertEquals("target-entity-id-5", event5.getTargetEntityId()); + assertEquals(1, event5.getProperties().size()); + assertEquals(properties.get("birthday"), new DateTime(event5.getProperties().get("birthday"))); + assertEquals(then.getMillis(), event4.getEventTime().getMillis()); + + String empty = reader.readLine(); + assertNull("no more data", empty); + } +} http://git-wip-us.apache.org/repos/asf/predictionio-sdk-java/blob/0780fcd5/examples/import/pom.xml ---------------------------------------------------------------------- diff --git a/examples/import/pom.xml b/examples/import/pom.xml index fef7ec1..5694070 100644 --- a/examples/import/pom.xml +++ b/examples/import/pom.xml @@ -1,17 +1,32 @@ +<!-- +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. +--> + <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> - <groupId>io.prediction.samples</groupId> + <groupId>org.apache.predictionio.samples</groupId> <artifactId>sample-import</artifactId> - <version>0.9.5</version> + <version>0.13.0</version> <packaging>jar</packaging> <name>PredictionIO Java SDK Examples: Import</name> <dependencies> <dependency> - <groupId>io.prediction</groupId> + <groupId>org.apache.predictionio</groupId> <artifactId>client</artifactId> - <version>0.9.5</version> + <version>0.13.0</version> </dependency> </dependencies> @@ -52,7 +67,7 @@ <configuration> <archive> <manifest> - <mainClass>io.prediction.samples.SampleImport</mainClass> + <mainClass>org.apache.predictionio.samples.SampleImport</mainClass> </manifest> </archive> <descriptorRefs> http://git-wip-us.apache.org/repos/asf/predictionio-sdk-java/blob/0780fcd5/examples/import/src/main/java/io/prediction/samples/SampleImport.java ---------------------------------------------------------------------- diff --git a/examples/import/src/main/java/io/prediction/samples/SampleImport.java b/examples/import/src/main/java/io/prediction/samples/SampleImport.java deleted file mode 100644 index f4a3eec..0000000 --- a/examples/import/src/main/java/io/prediction/samples/SampleImport.java +++ /dev/null @@ -1,147 +0,0 @@ -package io.prediction.samples; - -import com.google.common.util.concurrent.FutureCallback; -import com.google.common.util.concurrent.Futures; -import com.google.common.util.concurrent.ListenableFuture; - -import io.prediction.APIResponse; -import io.prediction.EventClient; -import io.prediction.FutureAPIResponse; - -import java.io.BufferedReader; -import java.io.FileReader; -import java.io.IOException; -import java.io.Reader; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.StringTokenizer; -import java.util.TreeSet; -import java.util.concurrent.ExecutionException; - -/** - * Sample data import client using MovieLens data set. - * - * @author Cong Qin, Donald Szeto, Tom Chan - */ -public class SampleImport { - private static final int HTTP_CREATED = 201; - - public static void main(String[] args) { - /* set appurl to your API server */ - String appurl = "http://localhost:7070"; - /* Handle command line arguments */ - String accessKey = null; - String inputFile = null; - try { - accessKey = args[0]; - inputFile = args[1]; - } catch (ArrayIndexOutOfBoundsException e) { - System.err.println("You must provide access key (1st arg) and input file name (2nd arg)"); - System.exit(1); - } - - EventClient client = null; - Reader fileReader = null; - - /* Read input MovieLens data and send requests to API */ - List<FutureAPIResponse> listOfFutures = new ArrayList<>(); // keeping track of requests - try { - /* Create a client with the access key */ - client = new EventClient(accessKey, appurl); - - /* Data structure */ - Set<String> uids = new TreeSet<String>(); - Set<String> iids = new TreeSet<String>(); - - /* Get API status */ - System.out.println(client.getStatus()); - - /* Open data file for reading */ - fileReader = new FileReader(inputFile); - BufferedReader reader = new BufferedReader(fileReader); - - /* Some local variables */ - String line; - int i = 0; - FutureAPIResponse future; - Map<String, Object> userProperties = new HashMap<>(); // empty properties for user - - while ((line = reader.readLine()) != null) { - /* Break the line up */ - StringTokenizer st = new StringTokenizer(line); - - /* The 1st field is User ID, the 2nd field is Item ID, and the 3rd field is rating */ - String uid = st.nextToken(); - String iid = st.nextToken(); - int rate = Integer.parseInt(st.nextToken()); - - /* Add user and item if they are not seen before */ - if (uids.add(uid)) { - // event time is omitted since we're not using it - future = client.setUserAsFuture(uid, userProperties); - listOfFutures.add(future); - Futures.addCallback(future.getAPIResponse(), getFutureCallback("user " + uid)); - } - if (iids.add(iid)) { - Map<String, Object> itemProperties = new HashMap<>(); - List<String> genre = new ArrayList<>(); - genre.add("comedy"); - itemProperties.put("genre", genre); - future = client.setItemAsFuture(iid, itemProperties); - listOfFutures.add(future); - Futures.addCallback(future.getAPIResponse(), getFutureCallback("item " + iid)); - } - - /* User rates the movie. We do this asynchronously */ - Map<String, Object> properties = new HashMap<>(); // properties with rating - properties.put("rating", rate); - future = client.userActionItemAsFuture("rate", uid, iid, properties); - listOfFutures.add(future); - Futures.addCallback(future.getAPIResponse(), getFutureCallback("event " + uid + " rates " + iid + " with " + rate)); - } - } catch (Exception e) { - System.err.println("Error: " + e.getMessage()); - e.printStackTrace(); - } finally { - if (fileReader != null) { - try { - fileReader.close(); - } catch (IOException e) { - System.err.println("Error: " + e.getMessage()); - } - } - // wait for the import result - ListenableFuture<List<APIResponse>> futures = Futures.allAsList(listOfFutures); - try { - List<APIResponse> responses = futures.get(); - for (APIResponse response : responses) { - if (response.getStatus() != HTTP_CREATED) { - System.err.println("Error importing some record, first error message is: " - + response.getMessage()); - // only print the first error - break; - } - } - } catch (InterruptedException | ExecutionException e) { - System.err.println("Error importing some record, error message: " + e.getStackTrace()); - } - if (client != null) { - client.close(); - } - } - } - - private static FutureCallback<APIResponse> getFutureCallback(final String name) { - return new FutureCallback<APIResponse>() { - public void onSuccess(APIResponse response) { - System.out.println(name + " added: " + response.getMessage()); - } - public void onFailure(Throwable thrown) { - System.out.println("failed to add " + name + ": " + thrown.getMessage()); - } - }; - } -} http://git-wip-us.apache.org/repos/asf/predictionio-sdk-java/blob/0780fcd5/examples/import/src/main/java/org/apache/predictionio/samples/SampleImport.java ---------------------------------------------------------------------- diff --git a/examples/import/src/main/java/org/apache/predictionio/samples/SampleImport.java b/examples/import/src/main/java/org/apache/predictionio/samples/SampleImport.java new file mode 100644 index 0000000..ba177ff --- /dev/null +++ b/examples/import/src/main/java/org/apache/predictionio/samples/SampleImport.java @@ -0,0 +1,165 @@ +/* + * 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.predictionio.samples; + +import com.google.common.util.concurrent.FutureCallback; +import com.google.common.util.concurrent.Futures; +import com.google.common.util.concurrent.ListenableFuture; +import java.io.BufferedReader; +import java.io.FileReader; +import java.io.IOException; +import java.io.Reader; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.StringTokenizer; +import java.util.TreeSet; +import java.util.concurrent.ExecutionException; +import org.apache.predictionio.APIResponse; +import org.apache.predictionio.EventClient; +import org.apache.predictionio.FutureAPIResponse; + +/** + * Sample data import client using MovieLens data set. + * + * @author Cong Qin, Donald Szeto, Tom Chan + */ +public class SampleImport { + + private static final int HTTP_CREATED = 201; + + public static void main(String[] args) { + /* set appurl to your API server */ + String appurl = "http://localhost:7070"; + /* Handle command line arguments */ + String accessKey = null; + String inputFile = null; + try { + accessKey = args[0]; + inputFile = args[1]; + } catch (ArrayIndexOutOfBoundsException e) { + System.err.println("You must provide access key (1st arg) and input file name (2nd arg)"); + System.exit(1); + } + + EventClient client = null; + Reader fileReader = null; + + /* Read input MovieLens data and send requests to API */ + List<FutureAPIResponse> listOfFutures = new ArrayList<>(); // keeping track of requests + try { + /* Create a client with the access key */ + client = new EventClient(accessKey, appurl); + + /* Data structure */ + Set<String> uids = new TreeSet<String>(); + Set<String> iids = new TreeSet<String>(); + + /* Get API status */ + System.out.println(client.getStatus()); + + /* Open data file for reading */ + fileReader = new FileReader(inputFile); + BufferedReader reader = new BufferedReader(fileReader); + + /* Some local variables */ + String line; + int i = 0; + FutureAPIResponse future; + Map<String, Object> userProperties = new HashMap<>(); // empty properties for user + + while ((line = reader.readLine()) != null) { + /* Break the line up */ + StringTokenizer st = new StringTokenizer(line); + + /* The 1st field is User ID, the 2nd field is Item ID, and the 3rd field is rating */ + String uid = st.nextToken(); + String iid = st.nextToken(); + int rate = Integer.parseInt(st.nextToken()); + + /* Add user and item if they are not seen before */ + if (uids.add(uid)) { + // event time is omitted since we're not using it + future = client.setUserAsFuture(uid, userProperties); + listOfFutures.add(future); + Futures.addCallback(future.getAPIResponse(), getFutureCallback("user " + uid)); + } + if (iids.add(iid)) { + Map<String, Object> itemProperties = new HashMap<>(); + List<String> genre = new ArrayList<>(); + genre.add("comedy"); + itemProperties.put("genre", genre); + future = client.setItemAsFuture(iid, itemProperties); + listOfFutures.add(future); + Futures.addCallback(future.getAPIResponse(), getFutureCallback("item " + iid)); + } + + /* User rates the movie. We do this asynchronously */ + Map<String, Object> properties = new HashMap<>(); // properties with rating + properties.put("rating", rate); + future = client.userActionItemAsFuture("rate", uid, iid, properties); + listOfFutures.add(future); + Futures.addCallback(future.getAPIResponse(), + getFutureCallback("event " + uid + " rates " + iid + " with " + rate)); + } + } catch (Exception e) { + System.err.println("Error: " + e.getMessage()); + e.printStackTrace(); + } finally { + if (fileReader != null) { + try { + fileReader.close(); + } catch (IOException e) { + System.err.println("Error: " + e.getMessage()); + } + } + // wait for the import result + ListenableFuture<List<APIResponse>> futures = Futures.allAsList(listOfFutures); + try { + List<APIResponse> responses = futures.get(); + for (APIResponse response : responses) { + if (response.getStatus() != HTTP_CREATED) { + System.err.println("Error importing some record, first error message is: " + + response.getMessage()); + // only print the first error + break; + } + } + } catch (InterruptedException | ExecutionException e) { + System.err.println("Error importing some record, error message: " + e.getStackTrace()); + } + if (client != null) { + client.close(); + } + } + } + + private static FutureCallback<APIResponse> getFutureCallback(final String name) { + return new FutureCallback<APIResponse>() { + public void onSuccess(APIResponse response) { + System.out.println(name + " added: " + response.getMessage()); + } + + public void onFailure(Throwable thrown) { + System.out.println("failed to add " + name + ": " + thrown.getMessage()); + } + }; + } +} http://git-wip-us.apache.org/repos/asf/predictionio-sdk-java/blob/0780fcd5/examples/quickstart_import/pom.xml ---------------------------------------------------------------------- diff --git a/examples/quickstart_import/pom.xml b/examples/quickstart_import/pom.xml index 67595f6..d168c72 100644 --- a/examples/quickstart_import/pom.xml +++ b/examples/quickstart_import/pom.xml @@ -1,17 +1,32 @@ +<!-- +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. +--> + <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> - <groupId>io.prediction.samples</groupId> + <groupId>org.apache.predictionio.samples</groupId> <artifactId>quickstart-import</artifactId> - <version>0.9.5</version> + <version>0.13.0</version> <packaging>jar</packaging> <name>PredictionIO Java SDK Examples: Quickstart Import</name> <dependencies> <dependency> - <groupId>io.prediction</groupId> + <groupId>org.apache.predictionio</groupId> <artifactId>client</artifactId> - <version>0.9.5</version> + <version>0.13.0</version> </dependency> </dependencies> @@ -52,7 +67,7 @@ <configuration> <archive> <manifest> - <mainClass>io.prediction.samples.QuickstartImport</mainClass> + <mainClass>org.apache.predictionio.samples.QuickstartImport</mainClass> </manifest> </archive> <descriptorRefs> http://git-wip-us.apache.org/repos/asf/predictionio-sdk-java/blob/0780fcd5/examples/quickstart_import/src/main/java/io/prediction/samples/QuickstartImport.java ---------------------------------------------------------------------- diff --git a/examples/quickstart_import/src/main/java/io/prediction/samples/QuickstartImport.java b/examples/quickstart_import/src/main/java/io/prediction/samples/QuickstartImport.java deleted file mode 100644 index 257e0ae..0000000 --- a/examples/quickstart_import/src/main/java/io/prediction/samples/QuickstartImport.java +++ /dev/null @@ -1,77 +0,0 @@ -package io.prediction.samples; - -import com.google.common.collect.ImmutableList; -import com.google.common.collect.ImmutableMap; - -import io.prediction.EventClient; - -import java.io.IOException; -import java.util.Map; -import java.util.Random; -import java.util.concurrent.ExecutionException; -import java.util.List; -import java.util.LinkedList; -import org.joda.time.DateTime; - -import io.prediction.Event; - - -public class QuickstartImport { - public static void main(String[] args) - throws ExecutionException, InterruptedException, IOException { - String accessKey = null; - try { - accessKey = args[0]; - } catch (ArrayIndexOutOfBoundsException e) { - System.err.println("You must provide access key as the parameter"); - System.exit(1); - } - EventClient client = new EventClient(accessKey); - Random rand = new Random(); - Map<String, Object> emptyProperty = ImmutableMap.of(); - - // generate 10 users, with user ids 1 to 10 - for (int user = 1; user <= 10; user++) { - System.out.println("Add user " + user); - client.setUser(""+user, emptyProperty); - } - - // generate 50 items, with item ids 1 to 50 - for (int item = 1; item <= 50; item++) { - System.out.println("Add item " + item); - client.setItem(""+item, emptyProperty); - } - - // each user randomly views 10 items - for (int user = 1; user <= 10; user++) { - for (int i = 1; i <= 10; i++) { - int item = rand.nextInt(50) + 1; - System.out.println("User " + user + " views item " + item); - client.userActionItem("view", ""+user, ""+item, emptyProperty); - } - } - - List<Event> events = new LinkedList<Event>(); - - // Use only 5 users because max batch size is 50 - // Throws IOException w/ details inside if this is exceeded - for (int user = 1; user <= 5; user++) { - for (int i = 1; i <= 10; i++) { - int item = rand.nextInt(50) + 1; - System.out.println("User " + user + " views item " + item); - events.add(new Event() - .event("view") - .entityType("user") - .entityId(""+user) - .targetEntityType("item") - .targetEntityId(""+item) - .properties(emptyProperty) - .eventTime(new DateTime())); - } - } - - client.createEvents(events); - - client.close(); - } -} http://git-wip-us.apache.org/repos/asf/predictionio-sdk-java/blob/0780fcd5/examples/quickstart_import/src/main/java/org/apache/predictionio/samples/QuickstartImport.java ---------------------------------------------------------------------- diff --git a/examples/quickstart_import/src/main/java/org/apache/predictionio/samples/QuickstartImport.java b/examples/quickstart_import/src/main/java/org/apache/predictionio/samples/QuickstartImport.java new file mode 100644 index 0000000..a0cea4c --- /dev/null +++ b/examples/quickstart_import/src/main/java/org/apache/predictionio/samples/QuickstartImport.java @@ -0,0 +1,91 @@ +/* + * 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.predictionio.samples; + +import com.google.common.collect.ImmutableMap; +import java.io.IOException; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import java.util.Random; +import java.util.concurrent.ExecutionException; +import org.apache.predictionio.Event; +import org.apache.predictionio.EventClient; +import org.joda.time.DateTime; + + +public class QuickstartImport { + + public static void main(String[] args) + throws ExecutionException, InterruptedException, IOException { + String accessKey = null; + try { + accessKey = args[0]; + } catch (ArrayIndexOutOfBoundsException e) { + System.err.println("You must provide access key as the parameter"); + System.exit(1); + } + EventClient client = new EventClient(accessKey); + Random rand = new Random(); + Map<String, Object> emptyProperty = ImmutableMap.of(); + + // generate 10 users, with user ids 1 to 10 + for (int user = 1; user <= 10; user++) { + System.out.println("Add user " + user); + client.setUser("" + user, emptyProperty); + } + + // generate 50 items, with item ids 1 to 50 + for (int item = 1; item <= 50; item++) { + System.out.println("Add item " + item); + client.setItem("" + item, emptyProperty); + } + + // each user randomly views 10 items + for (int user = 1; user <= 10; user++) { + for (int i = 1; i <= 10; i++) { + int item = rand.nextInt(50) + 1; + System.out.println("User " + user + " views item " + item); + client.userActionItem("view", "" + user, "" + item, emptyProperty); + } + } + + List<Event> events = new LinkedList<Event>(); + + // Use only 5 users because max batch size is 50 + // Throws IOException w/ details inside if this is exceeded + for (int user = 1; user <= 5; user++) { + for (int i = 1; i <= 10; i++) { + int item = rand.nextInt(50) + 1; + System.out.println("User " + user + " views item " + item); + events.add(new Event() + .event("view") + .entityType("user") + .entityId("" + user) + .targetEntityType("item") + .targetEntityId("" + item) + .properties(emptyProperty) + .eventTime(new DateTime())); + } + } + + client.createEvents(events); + + client.close(); + } +} http://git-wip-us.apache.org/repos/asf/predictionio-sdk-java/blob/0780fcd5/pom.xml ---------------------------------------------------------------------- diff --git a/pom.xml b/pom.xml index 1500ed8..d2f4938 100644 --- a/pom.xml +++ b/pom.xml @@ -1,20 +1,42 @@ <?xml version="1.0" encoding="UTF-8"?> + +<!-- +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. +--> + <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> - <groupId>io.prediction</groupId> - <artifactId>sdk</artifactId> - <version>0.9.6-SNAPSHOT</version> - <url>http://prediction.io</url> + <groupId>org.apache.predictionio</groupId> + <artifactId>predictionio-sdk-java</artifactId> + <version>0.13.0-SNAPSHOT</version> + <url>http://predictionio.apache.org</url> <packaging>pom</packaging> - <name>PredictionIO Java SDK</name> - <description>The PredictionIO Java SDK includes an API client and sample code.</description> + <name>Apache PredictionIO Java SDK</name> + <description>The Apache PredictionIO Java SDK includes an API client and sample code.</description> <parent> - <groupId>org.sonatype.oss</groupId> - <artifactId>oss-parent</artifactId> - <version>7</version> + <groupId>org.apache</groupId> + <artifactId>apache</artifactId> + <version>21</version> </parent> + <scm> + <connection>scm:git:https://github.com/apache/predictionio-sdk-java</connection> + <developerConnection>scm:git:https://git-wip-us.apache.org/repos/asf/predictionio-sdk-java.git</developerConnection> + <url>https://github.com/apache/predictionio-sdk-java</url> + </scm> + <dependencies> <dependency> <groupId>com.google.guava</groupId> @@ -23,22 +45,6 @@ </dependency> </dependencies> - <licenses> - <license> - <name>The Apache Software License, Version 2.0</name> - <url>http://www.apache.org/licenses/LICENSE-2.0.txt</url> - <distribution>repo</distribution> - </license> - </licenses> - - <developers> - <developer> - <id>predictionio</id> - <name>The PredictionIO Team</name> - <email>[email protected]</email> - </developer> - </developers> - <contributors> <contributor> <name>Cong Qin</name> @@ -46,69 +52,71 @@ </contributor> </contributors> - <scm> - <connection>scm:git:[email protected]:PredictionIO/PredictionIO-Java-SDK.git</connection> - <developerConnection>scm:git:[email protected]:PredictionIO/PredictionIO-Java-SDK.git</developerConnection> - <url>[email protected]:PredictionIO/PredictionIO-Java-SDK.git</url> - </scm> - <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <outputDirectory>${project.build.directory}</outputDirectory> + <project.root>${project.basedir}</project.root> </properties> <modules> <module>client</module> </modules> - <distributionManagement> - <snapshotRepository> - <id>ossrh</id> - <url>https://oss.sonatype.org/content/repositories/snapshots</url> - </snapshotRepository> - <repository> - <id>ossrh</id> - <url>https://oss.sonatype.org/service/local/staging/deploy/maven2/</url> - </repository> - </distributionManagement> - <build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> - <artifactId>maven-compiler-plugin</artifactId> - <version>3.0</version> - <configuration> - <encoding>UTF-8</encoding> - <source>1.7</source> - <target>1.7</target> - </configuration> + <artifactId>maven-checkstyle-plugin</artifactId> + <version>3.0.0</version> + <executions> + <execution> + <id>validate</id> + <phase>validate</phase> + <configuration> + <configLocation>google_checks.xml</configLocation> + <encoding>UTF-8</encoding> + <consoleOutput>true</consoleOutput> + <failsOnError>true</failsOnError> + <linkXRef>false</linkXRef> + </configuration> + <goals> + <goal>check</goal> + </goals> + </execution> + </executions> </plugin> <plugin> - <groupId>org.apache.maven.plugins</groupId> - <artifactId>maven-gpg-plugin</artifactId> + <groupId>org.codehaus.mojo</groupId> + <artifactId>findbugs-maven-plugin</artifactId> + <version>3.0.5</version> <executions> <execution> - <id>sign-artifacts</id> - <phase>verify</phase> + <id>validate</id> + <phase>validate</phase> <goals> - <goal>sign</goal> + <goal>check</goal> </goals> </execution> </executions> </plugin> <plugin> - <groupId>org.sonatype.plugins</groupId> - <artifactId>nexus-staging-maven-plugin</artifactId> - <version>1.6</version> - <extensions>true</extensions> + <groupId>org.apache.rat</groupId> + <artifactId>apache-rat-plugin</artifactId> + <version>0.12</version> <configuration> - <serverId>ossrh</serverId> - <nexusUrl>https://oss.sonatype.org/</nexusUrl> + <excludesFile>${project.root}/.rat-excludes</excludesFile> </configuration> + <executions> + <execution> + <id>validate</id> + <phase>validate</phase> + <goals> + <goal>check</goal> + </goals> + </execution> + </executions> </plugin> </plugins> </build> - </project>
